Files
Jyotisha/docs/tasks/TASK-rectification-walkthrough-polish-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

78 lines
7.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 任务书 · 首次真实走查抛光:题干必达、时序、去重、采用后续流、门一致性(2026-09-02)
基线:`origin/staging` 当前 tip(含 PR #47/#48/#49 全部合并)。
## 0. 背景
2026-09-02 产品负责人在真实 staging 环境完整走查生时校正(case `a17efc37-1494-4d13-91a9-d719838ef66c`,快照向发起人索取)。**三轮修复全部生效**:收窄有进度播报、offer 出牌、采用 04:53 成功、ledger 含 `dasha-transition-proximity`、品质题生成、`matrix-scoring-7 / policy-v3` 在线。本轮修走查暴露的 5 个抛光问题,全部已静态定位。**不改任何决策门语义与真实性边界**(问题 E 除外,它是把两个已存在的权威对齐,需产品选边)。
## 问题 A(P0)· 选择卡出现过"无题干"——静默降级必须 fail-closed
**现象**:第一道区分题(D9 相处方式)卡片只有 A-D 选项,无题干;同一 focus 的题干也没写进 turn 历史(后续各题的题干均由 answer_choice 路径正常写入并显示)。
**定位**:卡片组件渲染 `card.prompt``rectification-choice-card.tsx:51``<legend>`),无题干 = focus 创建时 schema.prompt 为空。`serverOwnedChoiceCopy``choice-card.ts:433`)在 `frame.prompt`/`period` 缺失或超出 4-80 字符窗时**静默 return null**`server-focus.ts:80-84` 拿到 null 后 focus 仍带空 prompt 建立 → 卡出、题干丢;turn-exit 的题干持久化因 `question?.prompt` 空同步被跳过——一个根因两个症状。message/agent 路径创建的第一个 choice focus 命中此路径(answer_choice 路径正常,说明缺口在 agent 后 `persistNextInterviewIfIdle``persistServerOwnedFocus`/`persistFocusAfterChoice` 这条创建链上;按符号追)。
**修法**
1. choice focus 创建 fail-closed`serverOwnedChoiceCopy` 返回 null 时**不得**建立可渲染的 choice focus——回退为 spoken collect`spokenCollectFallbackFollowup` 已存在)或跳过该 probe 记入 droppedreason 如 `unrenderable_choice_copy`),二选一并写明理由。
2. 排查 null 的实际成因(该 D9 probe 的 `question` 为"亲密关系里,你更接近哪一种相处方式?",14 字在窗内——大概率是 choice_frame 组装时 prompt 字段没接上,而不是超长),修实际断点。
3. 不变量测试:任何 `choice_card` 非空 ⇒ `choice_card.prompt` 非空;任何 active choice focus ⇒ `projectCurrentQuestion(...)?.prompt` 非空。用走查 case 的 probe 形状做回归。
## 问题 B(P1)· "界面上有下一问"先于问题出现——时序与措辞双修
**现象**:模型正文说"界面上继续有下一问",但题干 turn 在流结束后的 turn-exit 才持久化,用户当下看不到。
**修法**
1. 措辞:`agentic-rectification.ts` 指令补一条——正文不得断言界面当前状态("界面上有/出现了…"),过渡用中性表述("接下来我们继续"类);VOICE.md 同步。
2. 时序:turn-exit 持久化题干/focus 后,在关闭流之前向前端 emit 一个已允许的公开事件(如 question.ready,走 `safePublicEvent` 白名单)或由前端在 `done` 事件后立即刷新 case 快照。选实现小的,说明理由。前端已有刷新机制的话只需确认时机覆盖。
## 问题 C(P2)· 同域采集问句逐字复读
**现象**:"感情这边,还记得哪年认真在一起、分开,或结婚吗?"在历史里逐字出现两次(用户第一次用工作事件回答,感情域仍未覆盖,重问正确,但复读机器感强)。
**修法**:同一域的 collect 问句在**已问过且未被拒答**时重问,需换第二措辞(copy 模块每域加一条 retry 变体,如"回到感情这边——刚才说的工作我记下了,哪年认真在一起或分开还记得吗?")。判定用结构化状态(该域 collect focus 曾建立过),不做正文匹配。
## 问题 D(P1)· 采用后没有切入前事核对,旧采集问题挂在卡下
**现象**:采用 04:53 成功后,`current_question` 仍是采用前的"钱的方面…"采集 focus,显示在候选卡下方、脱离对话流;预期是 `verify_adopted_time`:按采用分钟反推最多两件前事核对(reverse_verify 链路已实现但没被接上)。
**修法**
1. 采用(accept RPC 成功)后的下一次 turn-exit / GET 投影:关闭或替换采用前的 collect focus,按 `next_user_action.id=verify_adopted_time` 建立 reverse_verify 焦点(`remainingReverseVerifyProbes` 已存在,`MAX_REVERSE_VERIFY=2`);无可用前事探针时给出 `start_consultation` 引导,不留旧问题。
2. UI:当前问题槽在候选卡区域之后渲染时必须仍在对话流内(作为最新一条内容),不得视觉上悬挂在卡片外;具体实现交给前端组件(`rectification-agentic-chat.tsx` 的 currentQuestion 渲染位置)。
3. 不变量:`accepted_time` 非空 ⇒ `current_question` 为 reverse_verify 类或空且 `next_user_action ∈ {verify_adopted_time, start_consultation}`;不得为采用前的 collect focus。
## 问题 EP1,需产品选边)· coverage 门与 offer 工具不一致
**现象**:走查中 occupation(职业)从未被问,TS overlay 判 `can_adopt: false`(coverage 未完成),但模型 offer 工具 + 引擎 `accept_allowed=true` 照常出牌且采用成功——coverage 门被 offer 链路绕过。结果可用但两个权威打架,且 skill 文本写"职业挡出牌"。
**二选一(在 PR 里写明选择与理由,默认选 1)**
1. **对齐引擎(推荐)**coverage(含 occupation)从 `deliveryCapability` 的采用门移除,只保留为**问询路由**优先级(没问过职业时优先问,但不挡出牌);skill 10.0.14 文本中"职业挡出牌"一句需在下次 skill 版本 bump 时同步修订(本轮先在 PR 记录偏差,不 bump skill)。
2. 对齐 TSoffer 工具服务端校验 coverage,未完成时拒绝 offer。风险:重新引入"差一问才能出牌"的摩擦,与 Round A 的用户体验目标相悖。
无论选哪个:overlay 与实际可执行动作必须一致——不允许再出现 `can_adopt:false` 与"卡已出、采用成功"并存。
## 硬红线
1. 不改采用/确认门的真实性语义(问题 E 按上面二选一后对齐,不新增放宽);确认门恒 fail-closed。
2. 问题槽服务端唯一所有不变;所有判定结构化,不做正文字符串匹配。
3. 引擎(Python)不动。
4. `./node_modules/.bin/tsc --noEmit` 通过(不要用 `npx tsc`);`rectification-*` / `consultation-*` / `consult-*` / `chat-*` 测试 fail=0;改动的既有断言逐条三栏说明(旧→新→保留语义)。
5. 无凭据不得声称已真实环境验证;修完把走查 case 形状的前后对照贴 PR。
## 开工前置
```bash
git fetch origin --prune
git worktree add -b codex/rectification-walkthrough-polish-20260902 \
../.worktrees/rectification-walkthrough-polish-20260902 origin/staging
```
`frontend/AGENTS.md``docs/BUG_HISTORY.md`BUG-456/460/463/468/469 链)、`frontend/docs/VOICE.md`。**行号是线索,按符号名定位。**
## 验收标准
1. 问题 A 的两条不变量全绿;D9 probe 形状回归:卡必有题干,历史必有题干 turn。
2. 问题 D 的采用后不变量全绿;走查 case 形状:采用后 `current_question` 切换为前事核对。
3. 问题 E 所选方案落地后:overlay 的 `can_adopt` 与 offer/accept 实际可执行性一致(合成两个方向的测试)。
4. tsc + 四组测试 fail=0BUG_HISTORY 追加条目(编号接现有最大号之后,先 grep 确认,避免再撞号)。
5. 建议真实环境复测清单(人工):完整走一遍并确认——首道选择卡有题干;无"界面上有下一问"式断言;同域重问换措辞;采用后立即出现前事核对问题且在对话流内。