fix(rectification): keep one delivery and adopt with the birth date
Accept and GET now decide with the same birth snapshot as the answer, so an under-age probe cannot flip can_adopt. The exit skips a second write when this reply already delivered. The card stays without an adopt button when adoption is not allowed, and a refusal shows the Chinese sentence.
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
# PROGRESS · 校正交付一次两段回答与点采用被拒(2026-10-06)
|
||||
|
||||
- 任务书:`docs/tasks/TASK-rectification-delivery-dup-adopt-20261006.md`(staging `65b61ed5`,只改文档,未部署)
|
||||
- 执行分支:`codex/rectification-delivery-dup-adopt-20261006`
|
||||
- 基线:任务书写的产品基线是 `e3f3a1fc`;实现从已含任务书的 `65b61ed5` 开始
|
||||
- BUG:1241、1242、1243。开工时 `docs/BUG_HISTORY.md` 最大号是 BUG-1240,没有撞号
|
||||
- 修复版本:待发布。本轮不推送,不声称已部署
|
||||
|
||||
## T0 修前复现(先于 T1–T3)
|
||||
|
||||
虚构出生日期 `1988-03-12`。开口窗口 `03:00–07:00`,可信范围 `04:45–05:15`,并列分钟 `04:53` 与 `05:00`。1998 年搬家探针(10 岁,低于搬家下限 18 岁)。四条带日期的证据。候选集合 `04:45-05:15:04:53,05:00`。探针的支持/冲突写的是分钟,不是候选编号。
|
||||
|
||||
下面两轮诊断不算复现:第一轮内存夹具把支持写成了候选编号,开口窗口又等于可信范围,采用被「范围没变窄」挡住,三处都不可采用。第一轮 PG 回执的展示许可与选择许可对不上,能力上限关掉,旁白没有改写,两条消息是同一段确定性原文。成功的那一轮才是下面的记录。
|
||||
|
||||
### 内存矩阵
|
||||
|
||||
当前证据指纹 `f0cbba1a89013d33aaa89a7ee39fc81caf3528e5a9e9407a3b41eddfea2f2c06`。
|
||||
|
||||
| 入参 | session_outcome | can_adopt | 探针 |
|
||||
| --- | --- | --- | --- |
|
||||
| 答题:出生日期 + snapshotCurrent | adopt_representative | true | 无(低于成年下限) |
|
||||
| 采用:只有指纹 | discriminate_candidates | false | relocation.1998.dasha_activation |
|
||||
| 只补出生日期 | adopt_representative | true | 无 |
|
||||
| 只补 snapshotCurrent | discriminate_candidates | false | 探针还在 |
|
||||
| 两个都补 | adopt_representative | true | 无 |
|
||||
|
||||
指纹已经对上时,只补出生日期就和答题一致;只补 snapshotCurrent 不行。没有未成年探针时,缺出生日期也不改变结论。
|
||||
|
||||
过期指纹(64 个 `b`)上,答题路径若强行 `snapshotCurrent: true`,结论也会变。生产里的重算只在重新读出的卷宗已经对上、或重算之后再从这份卷宗算出来时才标当前,不会对着过期指纹硬写成 true。所以共享入参必须带校验过的出生日期,snapshotCurrent 由卷宗自己算,答题路径不再私自传 true。
|
||||
|
||||
### PG17
|
||||
|
||||
真 PostgreSQL 17。种的是答完之后的并列卷宗,没有跑星历引擎。算法 `rectification-v5-matrix-scoring-8`,策略 `fictional-decision-policy-v1`,回执的展示/选择/确认三项与列一致且上限打开。Windows 上 `db/migrations` 的四个符号链接被检出成普通文件,和 `supabase/migrations` 重名,两目录迁移会停。这一轮把 supabase 全部加上 db 里不重名的本地身份文件放进一个临时目录,设 `MIGRATIONS_DIRECTORY`。这不是「两目录迁移在 Windows 上通过」。
|
||||
|
||||
同一份已对上指纹的卷宗:
|
||||
|
||||
| 路径 | session_outcome | can_adopt |
|
||||
| --- | --- | --- |
|
||||
| 采用那种只传指纹 | discriminate_candidates | false |
|
||||
| 答题:出生日期 + snapshotCurrent | adopt_representative | true |
|
||||
| 只补出生日期 | adopt_representative | true |
|
||||
|
||||
采用路由在 `can_adopt !== true` 时返回 409 `adoption_not_allowed`。GET 用的也是只传指纹,和答题不一致。
|
||||
|
||||
助手消息修前正好 2 条:
|
||||
|
||||
1. 采用旁白改写「这一轮已经把范围收窄,可以按代表时间看盘。」写入方是答题后的 `persistV9DeterministicTurn`。
|
||||
2. 确定性兜底,写入方是 `finalizeSuccessfulTurnExit`(日志 `rectification_delivery_turn`,trigger 为该函数)。正文含「分钟范围 04:45–05:15」和「现在还剩 04:45–05:15 里 2 个候选」。改写句不是这段的子串,子串防重没挡住。
|
||||
|
||||
收尾里的引擎刷新失败得很快(本机没有引擎),失败之后仍然写下第 2 条。选择题 JSON 没有带 `x-rectification-turn-id`,所以收尾看不到已经问过的轮次,补位照写。
|
||||
|
||||
T2 做法:不把采用旁白函数传进收尾,也不改旁白提示词。答题回复已经记下交付原文;收尾补位在「上一条助手原文去掉空白后等于这份已记原文」时不再写。子串比对留下。没有任何回复承载时,补位仍写 1 条。
|
||||
|
||||
## 实现
|
||||
|
||||
共享入参在 `decision-inputs.ts`。出生日期读不出来就抛 `birth_snapshot_unavailable`,不退回缺日期的判定。GET 和接续仍回到原来的中文 503。accept 在这条失败上返回 503「暂时无法采用」。快照是否当前仍由卷宗比较指纹,答题路径不再单独传 true。
|
||||
|
||||
收尾补位先看子串,再看已记下的交付句是否就是上一条助手原文,然后才写。先记下的那句在 60 秒内不被后一句盖掉。选择题 JSON 在有轮次编号时带 `x-rectification-turn-id`。真库验收没有靠这个头:收尾函数自己比对上一条。
|
||||
|
||||
盘型卡和分钟卡的按钮都要「结果属于采用集合,且 `can_adopt` 为真」。`frontend/DESIGN.md` 校正状态表的候选行补了「不能采用时卡片仍在、没有按钮」。
|
||||
|
||||
测试缝:`interview-state` 和 `projectTurnDecision` 在调用方没传出生日期时仍只传指纹,避免改掉几十条既有单测的结论。生产的 GET、accept、答题都传校验后的日期。`dossierResponse` 缺日期会直接抛错。
|
||||
|
||||
既有断言改动:
|
||||
|
||||
| 文件 | 原值 | 新值 | 原因 |
|
||||
| --- | --- | --- | --- |
|
||||
| `rectification-v9-contracts.test.ts` | `step_state: stepStateFromCaseDossier(dossier)` | `step_state: stepStateFromCaseDossier(dossier, decisionInputs.birthDate)` | GET 投影与答题共用出生日期(BUG-1242) |
|
||||
|
||||
`rectification-readopt-card-20261002.test.ts` 的两处盘型卡渲染补了 `canAdopt: true`,断言原文没改。若干 `dossierResponse` 测试补了虚构日期 `1900-06-15`,好让成年下限不滤掉夹具里的现代探针。新夹具用 `1988-03-12`,没有复用事故卡片上的日期。
|
||||
|
||||
## 修后真库
|
||||
|
||||
仍是种好的答完并列卷宗,没有跑星历。同一份已对上指纹的卷宗:
|
||||
|
||||
| 路径 | session_outcome | can_adopt |
|
||||
| --- | --- | --- |
|
||||
| 旧的只传指纹 | discriminate_candidates | false |
|
||||
| 共享出生日期 | adopt_representative | true |
|
||||
| GET | adopt_representative | true |
|
||||
|
||||
然后走答题后的改写落库,再调收尾且不带已问轮次编号。助手交付消息恰好 1 条,就是那句改写。日志里收尾补位被调用了,没有写出第 2 条。引擎刷新仍然很快失败(本机没有引擎),失败后也没有补写。
|
||||
|
||||
## 本机测试
|
||||
|
||||
`tsc --noEmit`:0 错。`npm run lint`:0 error,126 条既有 warning,没有改它们。
|
||||
|
||||
新文件 `rectification-delivery-dup-adopt-20261006.test.ts` 16 项通过。相关既有文件 122 项通过,含 BUG-1153 原测试。`# cancelled` 都是 0。
|
||||
|
||||
全量 `npm test`(`node scripts/run-tests.mjs`,退出码 1):
|
||||
|
||||
| | tests | pass | fail | cancelled |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| 基线 `65b61ed5` | 4848 | 4704 | 144 | 0 |
|
||||
| 本分支 | 4864 | 4719 | 145 | 0 |
|
||||
|
||||
失败名比基线多 1 条、少 0 条。多出来的是「发出后 300 毫秒内出现第一行阶段句」(`rectification-latency-20260926.test.tsx`)。这次全量跑了 414 秒,这条墙钟断言没过。同一条单独再跑通过。它不读出生快照,也不写交付轮。基线全量里没有这条名字。不记成新 bug。
|
||||
|
||||
其余 144 条名字与基线相同。测试总数多 16,就是新文件的 16 条,都通过。
|
||||
|
||||
假账本原来不返回出生快照。决策入口改成缺快照就拒绝之后,第一次全量多了 60 个失败名。给没桩过的计算 RPC 补了虚构日期 `1900-06-15`(成年下限不滤掉夹具里的现代探针),采用路由的工具桩补了 `loadV9CaseCompute`,范围句那条路由测试补了同一份快照。这三处的断言原文没改,除了 `persistApplied` 的源码顺序:原值查 `loadV9CaseCompute`,新值查 `loadCaseDecisionInputs`,原因是出生日期改由共享入口读取。三栏写在对应测试里。
|
||||
|
||||
## 构建
|
||||
|
||||
`next build --webpack`。Turbopack 会拒绝工作树里指到主检出的 `node_modules` 联接,所以用 webpack。基线 `65b61ed5` 编译 2.9 分钟、构建自带的 TypeScript 100 秒,都通过,收集页面数据时停在 `/api/rectification/agent`。本分支编译 2.2 分钟、TypeScript 83 秒,都通过,收集页面数据时停在 `/api/birth-time-guide`。两边都是 Windows 不允许为 Skill 运行别名建符号链接(`EPERM`)。先碰到哪条路由取决于收集页面的工人,不是这次改动。路由表没有打出来,这台机器没能确认 `/` 仍是 Static,也没有首屏 gzip 数字。没有为了构建改符号链接,也没有在工作树里重装依赖。首页 `page.tsx` 没改;校正卡片组件有改,gzip 要等能建符号链接的环境再量。
|
||||
|
||||
本轮没有打开浏览器,也没有在手机上点采用。真机步骤在 `docs/testing/rectification-delivery-dup-adopt-20261006.md`。修复版本待发布,没有推送,没有部署。
|
||||
Reference in New Issue
Block a user