docs(tasks): synastry full report second fix brief (issue #82)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LutgzyJqNhPpZy1nFsJtN3
This commit is contained in:
Jesse_Chen
2026-10-19 13:55:44 +08:00
co-authored by Claude Opus 5.5
parent b827901c1d
commit f148e0dade
@@ -0,0 +1,75 @@
# TASK · 完整合盘报告 · 第二份修复单(issue #82,第 2 次打回)
- 日期:2026-10-19
- 被验提交:`e8793bb0d274e3df3e26851299b79590b9c14ff4`(分支 `codex/synastry-full-report-20261018`)
- 前一份修复单:`docs/tasks/TASK-synastry-full-report-fix-20261019.md`(R1–R10)
- 状态:**第 2 次打回,按循环规则等产品负责人拍板**(选项见 issue #82)
- BUG 编号:执行中新发现的缺陷从开工时最大号 +1 起
## 验收结论(Claude)
| 项 | 结论 | 说明 |
| --- | --- | --- |
| R1 第 2–7 节取证 | 已修,测试偏弱 | 按 `reader_section_brief[].section` 取证、隐私改精确键名,对;但见 S3 |
| R2 提示词 | 部分 | 质检硬规则已写进提示;指南只用了 §四 示例第一段,§一 天气句、§二 维度对照、§六 未进提示;字数下限两边各写一份,无一致性断言 |
| R3 英文时间线 | 已修 | 程序生成英文依据;有「无中日韩字符」测试 |
| R4 英文任务卡死 | 已修 | 租约、过期可再领、失败回写、重排清零次数;见 S5 |
| R5 英文记账 | 已修 | |
| R6 单节重试 | 已修 | |
| **R7 测试** | **未修** | 没有新增任何 `test:db`、路由、退点、英文路由 / worker 测试;第 ⑥ 块测试仍用手造证据包 |
| R8 上游测试 | 已修,有保留 | 见 S4 |
| R9 / R10 | 已修 | |
## 必须修
### S1 · 补齐 R7(原样照上一份修复单 R7 执行)
- `npm run test:db`:同一对人复用、指纹变化不复用、删人级联、预留 / 结算 / 释放三条路径。
- 路由:同一人 400、他人 id 拒绝、复用不预留、产品开关关闭。
- 退点:两轮质检不过 → 退点;生成中删除 → 退点。
- 英文路由与 worker 各至少一条。
- 技术依据第 ⑥ 块用**真实** `execution_receipt`(公开名人证据包)逐行比对,不用手造包。
### S2 · 测试里写死了执行方本机路径(含用户名)
`frontend/tests/synastry-full-report.test.ts` 约第 243 行候选 Python 路径含 `C:\Users\<本机用户名>\anaconda3\python.exe`;`frontend/tests/chart-view-zero-year.test.ts` 第 17 行注释里也有同一路径(之前的单子带进来的,一并清掉)。AGENTS §8:本机账号信息不进仓库。改为只用 `process.env.PYTHON`,没有就依次试 `python3`、`python`;都没有时测试 **skip 并打印原因**,不要静默通过。
### S3 · R1 的真实证据包测试太弱、在 Linux 上可能找不到 Python
「每节非空」只断言 `JSON.stringify(evidence).length > 2`。改为:每节至少含一条来自 `relationship_lenses` 或 `pair_interaction_evidence` 的原始条目(按条目 id / lane 断言),且不含 `PRIVATE_KEY_NAMES` 里的任何键。Python 查找按 S2。
### S4 · 不要用改测试来迁就旧版 `aspects.py`
`tests/test_full_synastry_dossier.py` 约第 123 行把上游用例的 270° 改成 240°。原单 T9 要求同步上游;`aspects.py` 不在快照里就写 BLOCKED,**保持上游原断言并把该用例标 `xfail(reason=…, strict=True)`**,而不是改期望值。`test_prepare_full_synastry_packets.py` 约第 40 行把 endswith 放宽成只比文件名:改为把两边路径都规范成正斜杠后再比 endswith。
### S5 · 英文后台任务异常没人接
`personal-report-worker-core.ts` 的 tick 里 `void deps.runIdleSynastryEnglish?.()`;`claimEnglishJob` 里的 `markEnglish` 在 try 之外可能抛错,变成未处理的 Promise 拒绝。加 `.catch` 记日志;认领之后的所有步骤都在 try 里。租约 10 分钟不续期:生成可能超过 10 分钟时,要么续租,要么把租约设为单份英文生成上限的 2 倍,在进度里写明。
### S6 · 技术依据第 ② 块在真实数据上会全是「未标明」
上游 `chart_snapshot()`(`build_full_synastry_dossier.py` 约第 385 行)只输出上升与行星经度;`structureLine` 读的 `sign`、`seventh_lord`、`darakaraka`、`upapada`、`A7`、`d9` 在真实快照里都不存在。改为从证据包里真实存在的字段取(或在 Python 胶水层从两人 full-reading 里补算这些结构字段并放进证据包的本地扩展键),并用真实名人证据包测试第 ② 块非空。
### S7 · 前端全量测试新增 7 条失败(Claude 本机,Linux / Node 22)
tsc 0 错、lint 0 error、构建通过(`/` 仍 Static,首屏 gzip 约 +0.3%)、全量 pytest 与 staging 基线一致(只差已知并行抖动的 `test_vedastro_gateway`)。但前端 5064 条中失败 32,比基线多 7 条:
| 测试 | 原因 |
| --- | --- |
| `sidebar-contract.test.ts`「keeps app sidebar props as product data and callbacks」「…renders read-only when `/` is not the one mounting it」 | 侧栏 `app-sidebar.tsx` 自己 `fetch('/api/product-access')`;合同要求侧栏只吃 props、不得请求接口 |
| `home-warm-return-lifecycle.test.tsx` 两条(/chart、/reports 新建对话预热) | 侧栏挂载时多出 `GET /api/product-access`,打乱了只读预取清单 |
| `chart-page-view.test.tsx`「sidebar adds 星盘 and 星历 after 新建对话…」 | 侧栏结构 / 顺序变了,断言不成立 |
| `subject-route-birth.test.ts`「a missing report subject fails closed before billing」 | 报告建单路由改动后,缺人物时的失败路径与断言不一致,需确认仍在扣点前拒绝 |
| `synastry-full-report.test.ts`「a public pair dossier fills every section…」 | `python_missing`(见 S2) |
修法:「婚恋合盘」入口的开关状态由上层(已经在取账户 / 产品信息的地方)作为 prop 传给侧栏,侧栏不发请求;导航顺序保持原合同(新入口按原单位置加入,同步更新合同测试并写三栏);路由那条按原断言修代码,不改断言。
## 应该修
- 指南 §一、§二、§六 的要点进提示词;提示词与质检共用字数常量,或加一致性测试。
- 侧栏开关默认值改为「关」,取到开关后再显示,避免闪现;`/api/product-access` 若查价格,确认未登录可访问是有意的,并加限流。
- 质检「完整字段」排除纯状态值(如 `ready_for_comparison`、`executed`),只认叙述性字段。
## 交回前必跑(上一轮没跑的全部要跑)
`tsc`、`lint`、前端全量 `npm test`(与基线逐名比对)、`npm run test:db`(Windows 已知失败清单逐条对照)、`npm run build`、全量 `pytest` 与开工时 `origin/staging` 逐名比对、快速门。