Files
Jyotisha/docs/tasks/TASK-report-blocked-repairs-20260902.md
T
Jesse_ChenandClaude Fable 5.1 8db71aaf81 docs: product-level README, AGENTS.md split into code/reading parts, add CLAUDE.md, move task briefs to docs/tasks
- README.md is now the product/repo front door (architecture, repo map,
  local dev, test tiers, delivery flow, doc map). Engine positioning,
  VedAstro/Codex setup and the oracle/benchmark command reference move
  verbatim to docs/engine/README.md, docs/engine/vedastro-gateway.md and
  docs/benchmark/README.md. Capability badges realigned with the registry
  (91/78/8/0); tests/test_readme_badges.py was red on staging.
- AGENTS.md: Part A (environment truth, delivery, worktrees, record
  placement, bug workflow, growth freeze, frontend red lines, privacy,
  pre-work check, test tiers) and Part B (reading-rigor constraints).
  GitHub issue-tracker/triage boilerplate removed: GitHub is a read-only
  mirror. All strings locked by tests/ are preserved.
- CLAUDE.md added: roles, three working modes, task-brief sections,
  acceptance criteria, session discipline; imports AGENTS.md.
- 50 tracked TASK-*/PROGRESS-* files and 3 never-committed briefs move to
  docs/tasks/ with an index; REPO_LAYOUT.md merged into README.

Docs-only change (no gated path touched).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0193vBv6w5MV2cifdTUu9H5P
2026-09-03 06:56:06 +00:00

13 KiB
Raw Blame History

任务书 · 个人报告全主题 blocked 修复(2026-09-02

基线:origin/staging @ 24a1cf37

事故实证

2026-09-02 15:45 staging 真实生成的 personal_full 报告(请求主题 career/marriage/timing/wealth)四个主题全部 blocked,摘要退化为"报告主题尚未生成"。blocked 理由:

  • career:缺少最低证据组 AmK、Transit
  • marriage:缺少最低证据组 DK
  • timing:缺少最低证据组 Transit
  • wealth:缺少结构化分盘 D2、D11

已在本地用 origin/staging @ 24a1cf37 的前端提取层 + 同版本 Python 引擎(scripts/jyotish_api_server.py,虚构 smoke 出生数据,按 worker 的方式每主题一次 /api/consultation_workflow完整复现:blocked 主题与理由逐字一致。这是确定性缺陷,不是线上环境问题。

根因(已逐项定位,不需要重新猜)

根因 1(wealth):分盘值形状不匹配,所有分盘图提取失败。 引擎 chart.modules.varga_full 的值形状是:

{ "ascendant": { "sign": "Gemini", "sign_index": 2, "degree": 21.027 },
  "planets": { "Sun": { "sign": "Libra", "sign_index": 6, "degree": 15.23, "house": 5 }, ... },
  "house_chart": [["Ketu"], [], ...], "division": ..., "name": ..., "meaning": ... }

frontend/src/lib/personal-report-generation.tsderiveVargaHousesFromEngine(约 :336)读的是大写 Ascendant + sign_idx + 顶层行星键 → 每张分盘都返回 null → bundle charts 只剩 D1。昨日 45f190a1 修了键名别名(D2_HoraD2)并新增"claim card 主题缺结构化分盘图则降 blocked"的兜底(demoteThemesMissingRequiredCharts),但没修值形状——于是 wealth 从"write 后文档校验失败"变成"bundle 层 blocked"。643f6f7a 的 fixture 是按旧形状手造的,所以测试全绿、线上照挂。(2026-08-30 观察到的 final_parse_rejected 大概率同源。)

根因 2timing、career 之一半):Transit 回执从不生成。 引擎响应 chart.modules.transits 存在且 status: "executed"(含 sade_sati、triggers、search_period、boundary),但 consumer_context.available_layers 与 machine packet sections 里都没有 transit 名目,前端提取层从不为它 upsert 执行回执 → 要求 Transit 的 timing/career 自这套 claim gate 上线起从未通过。存量问题。

根因 3career:AmK、marriage:DK):consultation 响应没有 Chara Karaka 数据。 整个响应中无 Amatyakaraka/Darakaraka 数值层:chart.modules.jaimini 只有 arudha_padasguided topics 里 DK 的值是空占位符 - H-。引擎的 full-reading 路径有现成 karaka 计算(scripts/jaimini.py),但 scripts/jyotish_api_server.py_attach_local_consultation_layers 没有把这层挂进 consultation 响应。前端修不了,必须引擎响应新增字段。

决策记录

产品负责人 2026-09-02 确认修复方向并授权:

  • (a) 引擎侧允许在 consultation 响应中新增 Chara Karaka 字段(这是 TASK-report-skill-parity-20260901.md 任务 0 预留的"响应新增字段"止损分支,正式启用)。仍然只许新增、不许改动既有字段的键名、形状或语义。
  • (b) 643f6f7a / 既有测试中按旧分盘形状手造的 fixture 与断言,属于"锁住本轮要修的缺陷本身",允许按红线 9 的程序修改(注明原值与原因)。
  • (c) 主题最低证据组(report-theme-evidence-plan.ts不在授权范围内:不得为了让主题通过而删除或放宽 AmK/DK/Transit/D2/D11 要求。修法只能是把证据真实供给上。

硬红线

  1. 最低证据组一条不得放宽(见决策记录 c)。demoteThemesMissingRequiredCharts 兜底保留,不得删除——修好值形状后它自然不触发。
  2. 引擎改动只许响应新增字段:不改既有字段、不改排盘算法、不改 full-reading 路径;新增层必须复用 scripts/jaimini.py 既有实现,不得重写 karaka 算法。
  3. fixture 必须来自真实引擎响应(golden),不得再手造形状。任务 0 是门控:先落 golden fixture 与形状契约测试,任务 1–3 的实现测试必须建立在它之上。
  4. 上一轮任务书(TASK-report-skill-parity-20260901.md)的红线继续有效:输入隔离不放松、writer 输出 schema 只可收紧、assertionLevel 推导与 consensus ≥2 verified 防升级校验一字不改、本轮不改数据库结构、章节串行、telemetry 只记指标名与数值。
  5. 隐私红线:fixture 与测试只用虚构 smoke 出生数据;golden fixture 入库前确认不含任何真实用户资料。
  6. 推 staging 前 ./node_modules/.bin/tsc --noEmit 必须通过(不要用 npx tsc,会装到空包 tsc@2.0.4)。不得改 .gitea/workflows/**,不得自行提升 main。
  7. Python 侧改动必须带单元测试(.venv + unittest/pytest,按仓内既有测试形式),并真实跑过。

让步顺序:数据不损坏 > 证据纪律不回退 > 功能与测试不回归 > 可验证的修复 > 成本 > 代码整洁。

开工前置

git fetch origin --prune
git worktree add -b codex/report-blocked-repairs-20260902 \
  ../.worktrees/report-blocked-repairs-20260902 origin/staging

pre_work_error_ledger.md,跑 scripts/pre_work_check.py,读 frontend/AGENTS.md,在 docs/BUG_HISTORY.md 检索(BUG-486 及相邻条目与本轮直接相关)。

先读这几处再动手

  • frontend/src/lib/personal-report-generation.ts —— deriveVargaHousesFromEngine:336 附近)、readAllVargaCharts / readVargaHousesVARGA_KEY_ALIASES 已存在)、demoteThemesMissingRequiredCharts、receipt upsert 逻辑
  • frontend/src/lib/report-theme-evidence-plan.ts —— 各主题 requiredTechniqueGroups(只读,不改)
  • scripts/jyotish_api_server.py —— _attach_local_consultation_layersexecute_consultation_workflow
  • scripts/jaimini.py —— 既有 Chara Karaka 实现
  • git show 45f190a1git show 643f6f7a —— 昨日两次治标修复的全部内容

复现方法(验收也用它)

起本地引擎:.venv/bin/python scripts/jyotish_api_server.py --port 5200。用虚构出生数据(如 1993-06-15 10:30lat 36.42 / lon 114.21 / tz 8)按 worker 的调用方式(entryMode: "direct_chart"question 请为个人报告计算 <theme> 主题证据)对 career/marriage/timing/wealth 各调一次 runConsultationWorkflow,把 4 个响应喂给 buildReportEvidenceBundleV2,检查 claimCards / blockedSections / executionLedger / charts。修复前的预期输出(用于确认复现成功):claimCards 为空、四主题全在 blockedSections、charts 只有 D1。


任务 0P0,门控)· Golden fixture 与形状契约

做法

  • 用上述复现方法捕获 4 个主题的真实响应,裁剪成 fixture(保留 chart.modules.varga_full(至少 D2/D9/D10/D11/D24 各一张完整值)、modules.transitsmodules.jaiminiconsumer_context、machine packet sections;删除与提取无关的大块字段以控制体积),入库为测试资产。
  • 新增形状契约测试:断言 varga_full 值的真实形状(小写 ascendantsign_indexplanets 字典、house_chart),并断言 modules.transits.status 字段存在。这个测试在修复前就应该通过(它锁的是引擎真实形状,不是前端行为)。
  • 643f6f7a 手造的旧形状 fixture 替换为 golden 派生数据;按红线 9 在改动处注明原值与原因。

验收

  • 形状契约测试直接对 golden fixture 通过;PROGRESS 记录 fixture 的捕获命令与裁剪规则。

任务 1(P0)· 修分盘值形状,复活结构化分盘图

做法

deriveVargaHousesFromEngine 兼容真实形状,规则:

  • 上升:varga.ascendant ?? varga.Ascendant;星座索引 sign_index ?? sign_idx ?? signIndex(sign);度数 degree ?? degree_in_sign
  • 行星:优先读 varga.planets 字典(每行星有 sign_indexhouse,宫位可直接用 house,无 house 时按整星座宫从上升推导);planets 不存在时退回旧的顶层行星键路径(保持对旧形状的兼容,两种形状都要有测试)。
  • 不吸收 house_chart 以外来源不明的字段;未知键一律不复制。

验收

  • 单元测试双形状覆盖(golden 新形状 + 既有旧形状)。
  • 复现管线跑通后:charts 至少含 D1/D2/D9/D10/D11/D24wealth 出 claim carddemoteThemesMissingRequiredCharts 不触发;D2/D11 回执 executed。
  • education / migration_home 等依赖分盘的主题在补充复现(9 主题全请求)中同样解锁,PROGRESS 记录逐主题结果。

任务 2P0)· Transit 执行回执

做法

提取层读 chart.modules.transitsstatus === "executed" 时 upsert Transit 回执(status: "partial"executed: true,与 ashtakavarga/dasha_sub_periods 的既有读取方式同风格);status 缺失或非 executed 时不产回执(fail closed,不得默认 executed)。

验收

  • 单元测试:executed / 缺失 / 其他 status 三种输入。
  • 复现管线:timing 出 claim cardcareer 的 blocked 理由只剩 AmK(在任务 3 完成前)。

任务 3P0)· 引擎挂 Chara Karaka + 前端 AmK/DK 回执

做法

  • 引擎:_attach_local_consultation_layers 调用 scripts/jaimini.py 既有实现,把 Chara Karaka 挂到 chart.modules.jaimini.chara_karakas(结构建议:{ "AmK": { "planet": ..., ... }, "DK": { ... }, ... },具体键名以 jaimini.py 现有输出为准,新增字段不改既有 arudha_padas)。带 Python 单元测试。
  • 前端:从 modules.jaimini.chara_karakas 中 AmK/DK 的存在性 upsert AmK / DK 回执(partial + executed: true);数据缺失时不产回执。
  • golden fixture 用引擎修复后的响应重新捕获(或叠加一份含 karakas 的 golden),形状契约测试同步覆盖新层。

验收

  • Python 测试:consultation 响应含 chara_karakas 且 AmK/DK 数据来自 jaimini.py 现有输出。
  • 复现管线:career/marriage/timing/wealth 四主题全部出 claim cardblockedSections 为空executionLedger 中 AmK/DK/Transit/D2/D11 均 executed。

止损

  • jaimini.py 现有实现无法在 consultation 输入上直接复用(缺参数、口径冲突),停下BLOCKED.md,不得重写算法、不得放宽最低证据组来绕过。

任务 4P1)· 端到端与既有欠账

  • 全套质量门:frontend tsc --noEmit / eslint0 error/ tsx --test(失败清单与基线逐条比对)/ next buildPython 相关测试真实跑过。
  • 部署后(委托方核对 health gitCommit)真实生成一份 personal_full 报告,验收:四主题有正文、不再全 blocked;顺带补上一轮欠的交付物——真实 writer 输出回溯抽查(≥3 处)与每章实测 inputTokens/墙钟对照(对照基线与 2 倍线裁决记录见 PROGRESS-report-skill-parity-20260901.mdBLOCKED.md 对应条目)。

不在本轮范围

  • 主题最低证据组的增删改(决策记录 c)。
  • 引擎排盘算法、full-reading 路径、varga_full 既有形状的任何改动。
  • 知识包内容、writer prompt、成本优化(沿用已裁决结论)。
  • 章节并发、模型更换、计费、数据库结构。

收尾

  • PROGRESS 文件名写 PROGRESS-report-blocked-repairs-20260902.md
  • docs/BUG_HISTORY.md 新增条目(编号先对远端确认;根因 1 与 BUG-486 关联,注明 45f190a1/643f6f7a 是治标、本轮治本)。
  • 建议两次推送:任务 0+1+2(纯前端)一次;任务 3(引擎+前端)一次。staging push 触发全量构建+部署,全链路约 20 分钟,推送后核对 https://staging.jyotisha.chat/api/health.deployment.gitCommit
  • 不自行提升 main。

交付物清单

  1. Golden fixture(真实响应派生)+ 形状契约测试;643f6f7a 旧 fixture 的替换说明
  2. deriveVargaHousesFromEngine 双形状兼容 + 测试;复现管线中 charts/D2/D11 复活证据
  3. Transit 回执提取 + 三态测试
  4. 引擎 chara_karakas 新增层 + Python 测试;前端 AmK/DK 回执 + 测试
  5. 复现管线修复前后对照:blockedSections 从 4 → 0claimCards 从 0 → 4(9 主题全请求的逐主题表)
  6. 部署后真实报告验收 + 上一轮欠账(writer 输出回溯抽查、实测 tokens/墙钟对照)
  7. docs/BUG_HISTORY.md 条目、BLOCKED.md(任何触发止损的项)、PROGRESS-report-blocked-repairs-20260902.md
  8. 全套质量门实际输出(frontend 四件 + Python 测试)