docs(tasks): brief the report density and raw appendix round
Same-chart measurement against the upstream PL9 export: 847,632 chars and 8,044 table rows there, 309,357 and 1,478 here. The engine is not the gap -- twenty divisional charts, four KP tables, Ashtakavarga, the six Shadbala components, Avastha, Sahams and the annual pack all compute today. The report contract has nowhere to put them: REPORT_SECTION_KINDS has no table kind and CHART_IDS lists nine charts. The outgoing raw appendix also leaks 925 distinct engineering identifiers over 3,797 occurrences, including an internal function name, a third-party engine name and a third-party product's page numbers. The comparison report scores zero on every one of those. The decision record states plainly that two BUG-999 guards are overridden for the appendix channel only; the ordinary prose projection is untouched. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
This commit is contained in:
co-authored by
Claude Opus 5
parent
f77a1b5a33
commit
baeec66f8a
@@ -169,6 +169,7 @@
|
||||
|
||||
| 任务书 | 进度 | 主题 | 状态 | 落点 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `TASK-report-density-20260922.md` | — | **报告信息密度与原始附录(BUG-1003~1007)**:与源头仓 PL9 全量报告同资料实测:对照 847,632 字符 / 8,044 表格行,我方 309,357 / 1,478。缺口不在引擎——20 张分盘全表、KP 四表、Ashtakavarga 四类、Shadbala 六分量、Avastha、Sahams、年度都已算得出,但 `personal-report-contract.ts` 的 `REPORT_SECTION_KINDS` **没有表格类型**、`CHART_IDS` 只有 9 种,这些表在产品页报告里没有落脚字段。另测出对外原始附录泄漏 925 种 / 3,797 处工程标识符(`parameter_sensitive` 697、`cmd_full_reading` 68、`PyJHora`/`JHora` 35、`PL9` 页码 59),对照物同项为 0。**产品 2026-09-22 三点拍板**:层 1 按 8 组表 + 分盘扩到 16 张;层 2 原始附录直接给 C 端且先全显示;B 类大运族要显示。**决策记录已写明推翻 BUG-999 的两条红线**(专业参考不得作普通下载 fallback;`parameter_sensitive`/「参数敏感」命中整行剔除)——**仅限附录通道**,普通正文投影不动。硬红线:表格层服务端装配、writer 不得写表;对照物的替代大运族日期与 Shadbala 分量在源头仍未闭环(506 行 date mismatch、`production_tuning_allowed=false`),不得照搬升级。让步顺序与串行依赖(任务 3 → 任务 4 同改契约)见任务书 | **待领取** | 分支 `codex/report-density-20260922`;任务 1 参考实现已在该分支本地提交 `cf7e26e4`(未推送,29 passed) |
|
||||
| `TASK-report-sectioned-generation-20260830.md` | `PROGRESS-report-sectioned-20260830.md` | 分章节生成 | 已合入 | 见 PROGRESS |
|
||||
| `TASK-report-skill-parity-20260901.md` | `PROGRESS-report-skill-parity-20260901.md` | 内容对齐 skill 解读深度 | 已验收 | `90bad10d`、`ef1bd6df` |
|
||||
| `TASK-report-blocked-repairs-20260902.md` | `PROGRESS-report-blocked-repairs-20260902.md` | 全主题 blocked 修复 | 已验收 | `7faf8555` |
|
||||
|
||||
@@ -0,0 +1,192 @@
|
||||
# TASK-report-density-20260922 · 个人报告信息密度与原始附录
|
||||
|
||||
## 基线 commit
|
||||
|
||||
- 基线:`origin/staging` = `f77a1b5a`(2026-09-22 拉取)
|
||||
- 开发分支:`codex/report-density-20260922`,worktree `.worktrees/report-density-20260922`
|
||||
- 对照物:`/workspace/Yinan-印度占星报告/Yinan-Vedic-Astrology-Chart-Report-20260922-1642.md`,由**源头 skill 仓** `/workspace/yinduzhanxing` 的 `scripts/pl9_bilingual_batch_export.py` → `jyotish_engine.py` 生成。它对标商业软件 Parashara's Light 9 的 204 页报告。
|
||||
|
||||
## 事故实证
|
||||
|
||||
### 一、对照物与我方同一组出生资料实测
|
||||
|
||||
用同一组资料(1993-04-17 14:49:39 / lat 36.4133 / lon 114.2106 / tz 8 / Raman / mean / target-year 2026)分别跑对照物与我方 `render_pl9_markdown`:
|
||||
|
||||
| 指标 | 对照报告 | 我方 staging 实测 |
|
||||
|---|---:|---:|
|
||||
| 字符 | 847,632 | 309,357 |
|
||||
| 行数 | 13,287 | 3,559 |
|
||||
| 表格行 | 8,044 | 1,478 |
|
||||
| 含日期的表格行 | ~6,000 | 227 |
|
||||
| 分盘数值表 | 22 张(D1–D60) | 20 张(带中文盘名) |
|
||||
|
||||
我方**已有**且质量不低于对照物的:20 张分盘全表、KP 四表(Lord/Sub、显著星 ABCD、Ruling Planets、Cuspal Promise)、Ashtakavarga 四类(BAV / SAV / Sodhita / Prastara / Pinda)、Shadbala 六分量 + Declination 中间量、Bhava Bala、Avastha、Upagraha + 特殊上升点 + 敏感派生点、Sahams、Yoga/Dosha、Vimshottari 主大运表、Yogini 周期表、Kala Chakra、Narayana、Chara、年度 Mudda / Patyayini / Saham / Monthly Windows / 三年流月星历。
|
||||
|
||||
我方**缺**的:Vimshottari AD / PD 子行(对照物约 4,500 行)、10 个替代大运族周期表(Sthira / Drig / Shoola / Tribhagi / Tribhagi-40 / Satabdika / Shattrimshatsama / Niryaana / Navamsha / Lagna-Kendradi)、Sade Sati 三轮表、Bhavesh 十二宫主逐宫段、逐 MD/AD/PD 解释长文。
|
||||
|
||||
### 二、产品页报告的契约上限(层 1 的真正瓶颈)
|
||||
|
||||
`frontend/src/lib/personal-report-contract.ts`:
|
||||
|
||||
- `CHART_IDS`(符号定位第 48 行)只有 9 种:`D1 D2 D6 D8 D9 D10 D11 D24 D30`
|
||||
- `reportDocumentV2Schema.charts`(符号定位第 286 行)`.max(CHART_IDS.length)`,即上限 9 张
|
||||
- `evidenceAppendixSchema.techniqueAudit` 第 170 行 `.max(100)`;`calculationEvidence` 第 172 行 `.max(100)`
|
||||
- `REPORT_SECTION_KINDS`(`personal-report-plan.ts` 第 7 行)十种,**没有任何表格类型**
|
||||
|
||||
结论:上面第一节列出的"我方已有"的几十张表,在产品页报告里**没有可以落脚的字段**。它们只存在于引擎导出,不在用户打开的那份报告里。
|
||||
|
||||
### 三、原始附录的工程词泄漏
|
||||
|
||||
`scripts/professional_report_reference.py` → `build_professional_report_reference_packet` → `render_pl9_markdown` 的输出(312,050 字符)实测:
|
||||
|
||||
| 泄漏项 | 出现次数 |
|
||||
|---|---:|
|
||||
| 不同的 snake_case 标识符 | 925 种 |
|
||||
| snake_case 总出现 | 3,797 处(占 3,559 行中的 1,408 行) |
|
||||
| `parameter_sensitive` | 697 |
|
||||
| `pyjhora_behavior_only` | 321 |
|
||||
| `not_multiengine_parity` | 318 |
|
||||
| `unresolved_external_tuple_boundary` | 192 |
|
||||
| `cmd_full_reading`(内部函数名) | 68 |
|
||||
| `PyJHora` / `JHora` | 35 |
|
||||
| `PL9`(含"第 83-88 页"式页码) | 59 |
|
||||
|
||||
对照物同项扫描为 0。源头仓 `docs/research/pl9_reader_main_information_coverage_audit_2026_09_09.md` 记录他们已完成同类清理,用户版不出现 `blocked`、`parameter_sensitive`、`PyJHora`、`producer`、`schema`、`source_path`。
|
||||
|
||||
## 根因
|
||||
|
||||
1. **层 1**:报告契约是"结论 + 证据 id"的叙述式文档,`charts` 之外没有事实表字段。引擎算出的表无处可放,不是算不出来。
|
||||
2. **层 2**:`render_pl9_markdown` 同时服务内部审计与对外附录两种用途,状态词、内部 producer 名与第三方产品页码是审计需要的字面量,直接外流。
|
||||
3. **层 3(新发现的冲突)**:BUG-999(2026-09-22,同日)已建立 `frontend/src/lib/report-public-projection.ts`,按 allowlist 把普通报告投影成纯正文。其 `INTERNAL_KEY_TOKEN`(第 124 行)显式包含 `parameter_sensitive` **与中文「参数敏感」**,命中即整行剔除;`personal-report-longform-download.ts` 第 16 行已改为读 `GET /api/reports/:id` 并投影。该记录的防复发条款写明"专业参考不得再被普通下载当作 fallback"。
|
||||
|
||||
## 决策记录
|
||||
|
||||
产品负责人 2026-09-22 就三个问题拍板:
|
||||
|
||||
1. **层 1 表格清单按本文件第 1 项执行**(8 组表 + 分盘扩容)。
|
||||
2. **层 2 原始附录允许直接给 C 端用户**,先全部显示,不分研究/付费档。
|
||||
3. **B 类(引擎算得出但被自身标 blocked 的大运族)要显示出来**。
|
||||
|
||||
**本决策推翻 BUG-999 的两条红线,执行方按本节执行,不得以 BUG-999 为由拒改:**
|
||||
|
||||
- 推翻"专业参考不得再被普通下载当作 fallback":原始附录成为 C 端可下载产物,但必须是**独立入口**,不得替换 BUG-999 建立的普通正文投影。普通报告正文仍然只走 `projectOrdinaryReportDocument`。
|
||||
- 推翻"`parameter_sensitive` / 参数敏感 命中即整行剔除"**仅限原始附录这一条通道**。普通正文的剔除规则不变。原始附录改为把状态词翻译成用户语言后保留,而不是删除整行——删除会让整张表少掉状态列,比留着更难读。
|
||||
|
||||
未授权、不得顺手做的:不调整任何 `assertionLevel` / `claimStatus` 的升级规则;不把附录里的替代大运族日期写进正文结论;不改 BUG-999 的 XSS / 危险 URL / `jyotish-chart` 围栏合同。
|
||||
|
||||
## 硬红线
|
||||
|
||||
1. 表格层是**服务端确定性装配**,不是 Skill writer 生成。`skills/jyotish-personal-report/SKILL.md` 的"不得计算星盘"约束不变:writer 不得撰写、改写、补全任何表格单元格。
|
||||
2. 对照物的数字不得照搬。源头自己的台账 `docs/research/pl9_complete_replication_gap_matrix_2026_09_15.md` 列 5 项 open accuracy gap(3 项 P0:p33 declination/Kranti/KP cusp、p43-44 Shadbala 六分量、p61-120 Dasha 日期),`pl9_residual_loop_status_2026_09_18.md` 记 p109–p120 尚有 506 行 date mismatch、`production_tuning_allowed=false`、`formal_dasha_case_count=0`。替代大运族与 Shadbala 分量在源头仍未闭环,我方展示时必须保持既有状态标注,不得因为"对照物这么写"而升级。
|
||||
3. 不得学对照物的双向解释模板("When supported… When afflicted…"两边都写)。
|
||||
4. 不得动 `scripts/jyotish_api_server.py` 的类方法数与 `JyotishAPIHandler.__new__` 伪造点(AGENTS.md §6,`tests/test_api_server_growth_contract.py` 执行)。附录相关逻辑进 `scripts/` 独立模块。
|
||||
5. 原始附录里不得出现内部函数名、第三方引擎名、第三方产品页码。
|
||||
6. 出生资料不进仓:本轮所有实测用 `/tmp` scratchpad,任何真实出生数据不得写进测试、fixture、进度记录或 Bug 历史(AGENTS.md §8)。
|
||||
|
||||
## 任务分解
|
||||
|
||||
### 任务 1 · 原始附录工程词清洗(BUG-1003)
|
||||
|
||||
在 `scripts/` 新增独立模块,把 `render_pl9_markdown` 的对外副本清洗后再返回;内部审计路径与 CLI 保持原样。
|
||||
|
||||
替换范围:判断状态词(`parameter_sensitive` → 参数敏感、`pyjhora_behavior_only / not_multiengine_parity` → 仅单一外部参照,未做多引擎核对、`unresolved_external_tuple_boundary` → 外部边界未对齐、`partial_verified` → 部分核验、`raw_appendix_only` → 仅原始附录可见、`missing_in_local` → 本地暂无等)、内部标识符(`cmd_full_reading`)、第三方引擎名(`PyJHora` / `JHora` → 外部参照引擎)、第三方产品页码(`PL9 第 N 页` / `PL9 pN` / `PL9` → 外部参照资料)。
|
||||
|
||||
**保留**:原始字段名(`sign_cn`、`degree_in_sign`、`nakshatra_lord` 等)。附录的价值就是可以拿数字去和引擎对,改列名会让它更难核。
|
||||
|
||||
`blocked` / `executed` / `available` / `computed` 这类同时出现在英文散文里的词,只在"整个 markdown 单元格就是这个词"时替换,不得全局替换。
|
||||
|
||||
**验收标准**:
|
||||
- 清洗后 `PyJHora`、`JHora`、`PL9`、`cmd_full_reading`、本文件列出的七个判断状态词,在对外副本中出现次数为 0;
|
||||
- 行数不变(不得整行删除);
|
||||
- 原始字段名一行不少;
|
||||
- 英文散文句不被破坏(如 `Raw output is visible; this status alone does not promote it.` 原样);
|
||||
- 定向测试覆盖上述每一条。
|
||||
|
||||
**参考实现已在本 worktree 落地**:`scripts/reader_appendix_language.py` + `tests/test_reader_appendix_language.py`,已接入 `scripts/professional_report_reference.py` 的 markdown 分支,`python3 -m pytest tests/test_reader_appendix_language.py tests/test_professional_report_reference_api.py -q` 为 29 passed。执行方可直接采用或重写,但验收标准不变。
|
||||
|
||||
### 任务 2 · 原始附录的 C 端独立入口(BUG-1004)
|
||||
|
||||
按决策记录第 2 条,给报告页加**独立**的原始附录下载入口,与 BUG-999 的普通正文导出并列,不替换它。
|
||||
|
||||
**验收标准**:
|
||||
- 普通正文导出行为与 staging 基线逐字一致(`projectOrdinaryReportMarkdown` 的输出不变);
|
||||
- 原始附录入口产出任务 1 清洗后的全文,表格行数与引擎导出一致(当前实测 1,478 行,不得因投影而减少);
|
||||
- 入口文案对照 `frontend/docs/VOICE.md`,不写接口路径、状态码、"正在加载";
|
||||
- `frontend/tests/report-public-projection.test.ts` 既有断言不得弱化;新增断言覆盖"附录通道不经过普通正文投影"与"普通通道仍然剔除内部词"。
|
||||
|
||||
### 任务 3 · 报告契约增加事实表层(BUG-1005)
|
||||
|
||||
`personal-report-contract.ts` 增加 `factTables`(服务端装配,与 `charts` 同级,不进 Skill writer 的可写范围);`personal-report-plan.ts` 增加对应 section kind 只用于排序与位置;`report-evidence-bundle-v2.ts` 携带表数据;`personal-report-generation.ts` 从 workflow packet 装配。
|
||||
|
||||
首批 8 组表(已逐项确认 packet 中存在,来源键见括号):
|
||||
|
||||
1. Vimshottari 主大运全表 + 当前主运下的 AD / PD(`timing_and_predictive_systems.dasha.timeline[].antardasha_timeline[].pratyantar_dasha_timeline`)
|
||||
2. SAV / BAV(`strengths_and_scores.ashtakavarga`)
|
||||
3. Shadbala 六分量(`strengths_and_scores.shadbala`)
|
||||
4. 功能吉凶(`strengths_and_scores.functional_benefic_malefic`)
|
||||
5. Avastha(`advanced_systems.avasthas`)
|
||||
6. Upagraha + 特殊上升点 + 敏感派生点(`divisional_and_special_charts.upagrahas` / `special_lagnas` / `sensitive_points`)
|
||||
7. Sade Sati 三轮(`advanced_systems.yogas_doshas.sade_sati`)
|
||||
8. 当年 Varshaphala + Saham(`timing_and_predictive_systems.annual_tajika_pack`、`advanced_systems.sahams`)
|
||||
|
||||
**验收标准**:
|
||||
- 每张表的每一行都能追溯到 packet 中的真实键,不得手造 fixture(AGENTS.md §7.4,合同测试 fixture 必须来自真实引擎响应);
|
||||
- Skill writer 的 schema 不包含 `factTables`,writer 输出里出现表格视为 fail closed;
|
||||
- 每张表带 `claimStatus`,取值沿用既有枚举,不新增、不升级;
|
||||
- `tsc --noEmit` 0 错、`npm run lint` 0 error;
|
||||
- 前端测试总数不低于开工时 `origin/staging` 实测。
|
||||
|
||||
### 任务 4 · 分盘扩容到 16 张(BUG-1006)
|
||||
|
||||
`CHART_IDS` 从 9 种扩到 16 种:`D1 D2 D3 D4 D7 D9 D10 D11 D12 D16 D20 D24 D27 D30 D40 D60`。引擎已全部排得出且带中文盘名(`Vargas I` 段实测 20 张)。`charts` 上限随 `CHART_IDS.length` 自动到 16。
|
||||
|
||||
**验收标准**:
|
||||
- 16 张盘在报告页都能渲染,`VedicChartSvg` 不重叠(参照 BUG-616/617 的教训:`float` + 负 margin 曾让 22 张盘全部叠在一起);
|
||||
- 滚动不触发整篇重建(BUG-617);
|
||||
- `next build` 后 `/` 仍为 `○ Static`;首屏 gzip 变化在 ±2% 内,超出要在进度记录里给出原因;
|
||||
- 既有 `REPORT_DOCUMENT_V1_CHART_IDS`(D1/D9/D10)的存量 v1 报告仍可读。
|
||||
|
||||
### 任务 5 · B 类大运族对用户可见(BUG-1007)
|
||||
|
||||
Yogini / Kala Chakra 的周期表在附录中已经出得来(实测 Yogini 完整周期表、Kala Chakra 可用);Ashtottari 因适用性规则不满足而 blocked,**这是正确行为,不得为了"显示出来"而绕过适用性判定**。Mudda 已返回年度阶段,Patyayini 为 `missing_in_local`。
|
||||
|
||||
**验收标准**:
|
||||
- 附录中每个大运族都出现一行"是否适用 / 为什么不适用"的用户语言说明,不再只给一个状态词;
|
||||
- 适用性判定本身不得放宽;
|
||||
- 全部标注"第二时间轴,仅供交叉核对,不单独生成应期"。
|
||||
|
||||
## 让步顺序
|
||||
|
||||
资源不够时按此顺序砍,不得自行改变:
|
||||
|
||||
1. 先交任务 1 + 任务 2(原始附录清洗与入口)。这是用户今天就能拿到的东西,且修的是正在外流的工程词。
|
||||
2. 再交任务 3 的前 4 组表(Vimshottari 全表、SAV/BAV、Shadbala 六分量、功能吉凶)。
|
||||
3. 再交任务 4 的分盘扩容。
|
||||
4. 任务 3 的后 4 组表(Avastha、Upagraha、Sade Sati、年度)与任务 5 最后。
|
||||
|
||||
任务 3 与任务 4 都改 `personal-report-contract.ts`,**必须串行**,顺序为 3 → 4。任务 2 与任务 3 都改报告页组件,任务 2 先。
|
||||
|
||||
## 开工前置命令
|
||||
|
||||
```bash
|
||||
git fetch origin --prune
|
||||
git status -sb # 确认分支,主检出常被别的会话切走
|
||||
git worktree add -b codex/report-density-20260922 .worktrees/report-density-20260922 origin/staging
|
||||
python3 scripts/pre_work_check.py --remote-timeout 8 --command-timeout 45
|
||||
```
|
||||
|
||||
预检已知基线失败(与本轮无关,不得算作本轮引入):`tests/test_preflight_fragment_scan.py::test_preflight_fragment_scan_preserves_audit_capability_and_oracle_boundaries`,断言 `4 >= (0 + 8)`,由主检出的未跟踪残留文件导致。
|
||||
|
||||
## BUG 编号起点
|
||||
|
||||
`docs/BUG_HISTORY.md` 当前最大号 **BUG-1002**(共 832 条)。本任务书编号从 **BUG-1003** 起,开工时需重新核对最大号。
|
||||
|
||||
关联记录:**BUG-999**(普通报告导出仍带出内部技法与工作流字段)。本轮任务 1 与 BUG-999 属同一现象族——内部词外流。BUG-999 的解法是普通正文按 allowlist 投影,未覆盖 `/api/professional_report_reference` 的原始附录通道,因此该通道的 3,797 处标识符没有被拦住。任务 1 不是把 BUG-999 推翻,而是补上它没覆盖的第二条通道;决策记录里写明的两处推翻只限附录通道。
|
||||
|
||||
## 本任务书据以成立的实测记录与三处更正
|
||||
|
||||
本任务书之前的口头分析有三处数字错误,均已更正,执行方以本文件为准:
|
||||
|
||||
1. "我方导出 163,320 字符 / 530 表格行 / 0 个日期行" —— 该次是在主检出的旧分支 `codex/unified-loading-20260902`(9-02)上跑的。`origin/staging` 实测为 309,357 字符 / 1,478 表格行 / 227 日期行,Vimshottari 主大运表存在。
|
||||
2. "全仓没有任何 API 或前端调用 PL9 导出" —— 错。`/api/professional_report_reference` 存在,`frontend/src/lib/personal-report-longform-generate.ts` 第 141 行在调。
|
||||
3. "产品页报告 charts 上限 6 张" —— 错。`origin/staging` 上是 `.max(CHART_IDS.length)` = 9 张。
|
||||
Reference in New Issue
Block a user