merge origin/staging into narrower delivery (只碰文档, issue #77)
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
# TASK · 生时校正交付区间收窄 · 第三份修复单(issue #77)
|
||||
|
||||
- 日期:2026-10-19
|
||||
- 被验提交:`f67d266129393197821c1373d0cfdac4c50f2e1f`(分支 `codex/rectification-narrower-delivery-20261016`)
|
||||
- 前序:`TASK-rectification-narrower-delivery-fix-20261017.md`(F1–F4);产品 10-17 选 A(等回放跑完再交)
|
||||
- 状态:同一单再次未过,按循环规则等产品负责人拍板谁来改(选项见 issue #77)
|
||||
- BUG 编号:不新开号;显示漏段那条合并时由 BUG-1375 顺延为 **BUG-1392**(1375/1376 已归 #81)
|
||||
|
||||
## 验收结论(Claude)
|
||||
|
||||
| 项 | 结论 | 证据 |
|
||||
| --- | --- | --- |
|
||||
| F1 回放 | 数字通过 | Claude 从两份 JSON 的 924 条记录独立重算:12 格(3 窗口 × 全对 / 翻 1/3/5)改前整段与改后分段包含真值均 70/70;两边可比较的是同一批 840 条;未完成的 84 条是同样 7 个案例、同一阶段停住 |
|
||||
| 显示宽度 | 通过 | ±60 全对中位 32.5 → 21.5;±60 翻 1 题 65.5 → 34 |
|
||||
| tsc / lint | 通过 | 0 错;0 error |
|
||||
| **隐私标记** | **未通过** | `tests/test_repo_privacy_markers.py`:`R003` 命中 `docs/research/rectification_narrower_delivery_baseline_2026_10_16.json` 2 处、`..._t1_2026_10_17.json` 4 处 |
|
||||
|
||||
AGENTS §8.5:写了实测数字的文档推送前必须跑这条测试。
|
||||
|
||||
## H1 · 回放文件不得含与隐私标记相撞的钟点(必做)
|
||||
|
||||
两份 JSON 的每条记录以 `HH:MM` 字符串记了 `credible_intervals`、`credible_range`、`living_display_intervals` 等区间端点。其中有端点与 `R003` 规则的值相同。不论是否巧合,提交的文件都不得命中。
|
||||
|
||||
改法(推荐):
|
||||
|
||||
- 回放脚本输出时,区间端点改记为**相对本例窗口起点的分钟数**(整数),不写钟点字符串;真值也只记相对分钟。`truth_in_envelope`、`truth_in_display`、`remaining_minutes`、`display_width_minutes` 等结论字段不变。
|
||||
- 已有两份 JSON 可以用一次性转换脚本按同一规则改写,不必重跑回放;转换前后每条记录的结论字段逐条相等(进度里贴核对输出)。
|
||||
- **不要**把这两个文件加进 `test_repo_privacy_markers.py` 的碰撞白名单(白名单只用于已审核的单点、且需要产品授权)。
|
||||
|
||||
验收:
|
||||
|
||||
- `python3 -m pytest tests/test_repo_privacy_markers.py -q` 绿。
|
||||
- 两份 JSON 中不再出现 `"HH:MM"` 形状的区间端点;Claude 重算的 12 格包含率与本单「验收结论」表相同。
|
||||
|
||||
## 不要做
|
||||
|
||||
- 不改任何前端 / Python 业务代码(上一轮已验收)。
|
||||
- 不放宽隐私规则。
|
||||
|
||||
## 回报
|
||||
|
||||
issue #77 回报新 SHA,贴隐私测试结果与转换前后结论字段的核对输出。
|
||||
@@ -0,0 +1,93 @@
|
||||
# TASK · 完整合盘报告 · 修复单(issue #82,第 1 次打回)
|
||||
|
||||
- 日期:2026-10-19
|
||||
- 被验提交:`9ea5b3b0c072c6b2491e4067fb2316003cbe74e6`(分支 `codex/synastry-full-report-20261018`)
|
||||
- 原任务书:`docs/tasks/TASK-synastry-full-report-20261018.md`(第四版为准,下称「原单」)
|
||||
- 执行方:Grok,同一分支追加提交;`origin/staging` 前进时用 `git merge origin/staging`,不 rebase
|
||||
- BUG 编号:执行中新发现的缺陷,从开工时 `docs/BUG_HISTORY.md` 最大号 +1 起(当前 staging 已用到 1391;#77 合并时会占 1392)
|
||||
|
||||
## 验收结论(Claude)
|
||||
|
||||
骨架(计费键、迁移、选人、建单、复用、扣点结算)方向对,迁移对已部署代码向后兼容;但**报告正文这条主链在真实数据下跑不通**,且原单要求的测试大部分缺失。打回。
|
||||
|
||||
已确认通过(不用再动):
|
||||
|
||||
- 上游 Skill 6 个文件与 `docs/research/upstream_full_synastry_7a773d13/skill/` 逐字一致,其余仍与 bde5d615 一致(原单 T9 授权)。
|
||||
- 迁移 `20261019010000_synastry_full_report.sql`:新列可空、约束只放宽、`chart_subject_usage` 同事务重建且保留旧列、`delete_chart_subject` 仍 `security definer` + `search_path=''`;`synastry_english_jobs` 开了 RLS。
|
||||
- 计费:`synastry.full` 进了各处枚举 / 管理端 / 标签 / 会员;未发布价格返回 `pricing_configuration_unavailable`;同一对人 + 指纹 + 规则版本命中 ready / generating 时不预留;入队前失败会释放;英文版不预留。
|
||||
- 增长合同:主 API 文件只在既有分发里加 7 行;`page.tsx` 未动;scripts 根目录未增文件。
|
||||
|
||||
## 必须修(阻断)
|
||||
|
||||
### R1 · 第 2–7 节拿不到证据
|
||||
|
||||
`frontend/src/lib/synastry-full-sections.ts` 的 `SECTION_FIELDS` 把 `emotional_safety`、`communication_conflict_and_repair`、`attraction_and_closeness`、`shared_life_gains_and_pressures`、`relationship_progression`、`can_it_stay_steady` 当成证据包**顶层键**去取(`if (field in packet)`)。它们其实是 `reader_section_brief` 列表里各项的 `section` 值(上游 `build_full_synastry_dossier.py` 的 `READER_SECTION_BRIEFS`,约第 241 行起;组装约第 748 行)。结果是情感、沟通、冲突、日常、方向几节只拿到空对象。
|
||||
|
||||
另外 `PRIVATE_KEYS = /birth|date|time|lat|lon|…|day|hour|minute/i` 按子串删键,会误删 `relationship_axis`(含 lat)、`update…`(含 date)一类正常键。
|
||||
|
||||
修法:按上游结构取证——从 `reader_section_brief` 里按 `section` 找到对应条目,再按条目里引用的 lens / topic 去 `relationship_lenses`、`pair_interaction_evidence` 等取原始条目。隐私剔除改为**精确键名白名单或黑名单**(出生年月日时分、经纬度、时区、地点),不用子串正则。
|
||||
|
||||
验收:用 **两位公开名人**的真实证据包(`tests/test_synastry_full_dossier.py` 已用的那对)生成每节输入,单测断言 9 节输入都非空,且不含任何出生资料键。
|
||||
|
||||
### R2 · 提示词与质检对不上,也没按原单写
|
||||
|
||||
- 质检 `scripts/marriage_match_service/synastry_full_reader_gate.py` 要求 `label` 必须是 6 个上游标签之一、每节不少于 120 字、全文不少于 1800 字、`evidence` 逐字引用;提示词(`synastry-full-sections.ts`、`mastra/synastry-report.ts`)一条都没告诉模型。
|
||||
- 原单要求系统提示以关系语言指南(`docs/research/synastry_relationship_language_guide_2026_10_18.md`)为主体,含五条规则与示例,加上游证据规则(每个判断两条支撑、冲突降级、应期写条件、不点名补充方法)。现在只有 5 行,没有示例。
|
||||
|
||||
修法:按原单重写提示词,把质检的每条硬规则写进去;质检与提示词共用一份规则常量(或在测试里断言两边一致)。
|
||||
|
||||
验收:**真实模型跑一次**两位公开名人,中英各一份,质检一次或两次内通过;进度里贴每节字数、轮次、未通过原因。没有模型 key 就写进 `BLOCKED.md` 并在回报里明说,不得写「通过」。
|
||||
|
||||
### R3 · 英文版把中文时间线喂给模型
|
||||
|
||||
`synastry-full-run.ts` 英文任务把 `zh.timeline`(中文阶段名、描述、依据)当 `segments` 传入,`sectionEvidence` 再把它塞进英文时间线的输入。原单 T6:英文按需生成,依据行由程序生成。修法:英文时间线的 `segments` 由程序从同一份大运数据重新生成英文依据行;模型只写英文阶段名和描述。加测试:英文时间线输入里不含中日韩字符。
|
||||
|
||||
### R4 · 英文任务会永久卡住
|
||||
|
||||
`runIdleSynastryEnglish`:先把任务改成 `running`,之后几处 `return null`(找不到报告、快照缺字段)都不回写状态,任务永远停在 `running`;表里有 `lease_token` / `lease_expires_at` 却没用。英文路由把 `failed` 改回 `queued` 时不清 `attempt_count`,超过 `max_attempts` 后认领会撞 `attempt_count <= max_attempts` 的约束,任务永远排队。
|
||||
|
||||
修法:认领时写租约,过期可被重新认领;所有提前退出路径都回写 `failed` + 错误码;重排时按原单规则重置次数(或明确上限后给出不可再试的提示)。加测试覆盖这三条。
|
||||
|
||||
### R5 · 英文生成的用量没记账
|
||||
|
||||
原单红线 5:模型用量照常记录并计入成本统计。英文生成路径没有写用量。补上,与中文路径同一个记账函数,并加测试。
|
||||
|
||||
### R6 · 单节重试没做
|
||||
|
||||
原单 T4:某一节超时或报错只重写这一节。现在 `writeOne` 抛错会冲出并发池,变成整单 `model_unavailable` 重跑 9 节。修法:单节失败按原单次数重试该节,仍失败才整单失败并退点。加测试。
|
||||
|
||||
### R7 · 原单要求的测试大量缺失(AGENTS §7.4:合同 fixture 用真实引擎输出)
|
||||
|
||||
- 现有 `synastry-full-report.test.ts`、`tests/test_synastry_full_reader_gate.py` 全是手造「甲 / 乙」数据。补公开名人的真实证据包 golden,并核对技术依据第 ⑥ 块与 `execution_receipt` 逐行一致。
|
||||
- T1/T2 `npm run test:db`:同一对人复用、指纹变化不复用、删人级联、预留 / 结算 / 释放三条路径。
|
||||
- T3 路由:同一人 400、他人 id 拒绝、复用不预留、产品开关关闭。
|
||||
- T4:两轮质检不过 → 退点;生成中删除 → 退点。
|
||||
- T6 路由与 worker;T7 阅读页渲染;英文质检用例补齐到原单列的各项。
|
||||
|
||||
### R8 · T9 上游测试没搬
|
||||
|
||||
`test_bilingual_synastry_delivery`、`test_compose_full_synastry_delivery`、`test_full_synastry_dossier`、`test_full_synastry_execution_contract`、`test_prepare_full_synastry_packets` 按原单搬进 `tests/` 并通过。`scripts/aspects.py` 不在快照里,按原单写进 PROGRESS / BLOCKED,不要自写。
|
||||
|
||||
### R9 · 前端全量测试新增 1 条失败
|
||||
|
||||
`frontend/tests/class-name-definition-contract.test.ts`「every project class a component renders has a rule in our CSS」:`synastry-report-heading`、`synastry-technical`(`src/components/synastry/synastry-report-view.tsx`)在 CSS 里没有规则。补样式或去掉类名;不要加进 `knownUnstyled` 来绕过。Claude 本机:tsc 0 错、lint 0 error、前端 5042 条中失败 26,与基线相比只多这一条(另一条是只在 Docker 下能跑的已知项)。
|
||||
|
||||
### R10 · Python 全量测试新增 1 条失败
|
||||
|
||||
`tests/test_api_server_security.py::test_capability_audit_scans_registry_and_local_sources`:页面扫描结果多了 `synastry`(新页面 `app/(app)/synastry`),与测试里固定的页面清单不一致(`At index 33 diff: 'synastry' != 'terms'`)。按 AGENTS §7.3 / §7.8 更新期望清单并写「原值 / 新值 / 原因」三栏;不要删掉这条断言。Claude 本机全量 pytest 与 staging 基线比对,只多这一条(`test_vedastro_gateway` 的差异是已知并行抖动)。
|
||||
|
||||
## 应该修(不阻断,但这一轮一起做)
|
||||
|
||||
- 质检:`evidence in json.dumps(input)` 一个字也能过,改为要求证据是输入里某个**完整字段值**;依据行按原单逐字段比对(星座、星宿也要比);`\bD\d{1,2}\b` 在中文旁失效;时间线 `phase` 也要过禁词;英文禁表补 kuja、nadi、lagna、UL、DK 等。
|
||||
- 技术依据第 ② 块补齐 7 宫主、DK、UL、A7、D9;第 ⑤ 块用上 `raman_marriage_match`(#79 已存);未知状态不要一律写「无法计算」。
|
||||
- `synastry_report_id` 始终为空:Python 侧返回 #79 存的那一行 id 并写入。
|
||||
- 先结算、再标 ready(或标 ready 与结算同事务),避免进程在两步之间崩溃后预留一直挂着。
|
||||
- 英文生成不要放在 `tick()` 里同步跑,别挡住新报告任务。
|
||||
- 选人页按原单:自定义下拉、按钮文案「开始合盘」、`synastry.full` 价格说明、「之前的合盘」列表;资料不全的人不可选。
|
||||
- 阅读页:标题带「·」、支持 `?lang=en`、`personal-report-progress.ts` 补新阶段文案。
|
||||
- 报告列表:两人都是他人时,两个人的列表里都要能看到。
|
||||
- 侧栏「婚恋合盘」入口与 `/synastry` 页按 `compatibility` 开关隐藏;英文路由也检查开关。
|
||||
|
||||
## 交回前必跑
|
||||
|
||||
`tsc`、`lint`、前端全量 `npm test`(与基线逐名比对)、`npm run test:db`(Windows 已知失败清单逐条对照)、`npm run build`(`/` 仍 Static)、全量 `pytest` 与开工时 `origin/staging` 逐名比对、快速门、屏蔽 PyJHora 后跑证据包与质检测试。
|
||||
Reference in New Issue
Block a user