fix(rectification): open history cases with their bound skill identity (BUG-621)
Independent Staging Quality Gate / validate (push) Successful in 9m46s
Independent Staging Quality Gate / publish (push) Successful in 32m4s

Session open was sending the live registry version into v2, so every Skill
bump rejected older cases with an unmapped 500 and no error on the clicked row.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Jesse_Chen
2026-09-09 19:35:23 +08:00
co-authored by Cursor
parent 15cede97e7
commit a31a5e2426
16 changed files with 423 additions and 33 deletions
+16
View File
@@ -9636,6 +9636,22 @@
- 复发自:无
- 修复版本:待发布
## BUG-621 | 升 Skill 版本后历史生时校正从列表点不开
- 状态:resolved
- 首次发现:2026-09-09
- 最近更新:2026-09-09
- 影响面:`openRectificationCase``open_agentic_rectification_case_v2`、历史会话列表、`KNOWN_RPC_ERROR_CODES`
- 用户现象:历史对话里的生时校正(含当天较早创建的)点了没反应,主栏也不换会话。
- 触发条件:生时校正 Skill 已从 10.0.15 升到 10.0.19;点开绑定旧版本的历史校正。
- 根因:08-14 不可变注册表让 Case 钉住自己的 `skill_name/version/sha256/source_commit`,agent 也按绑定版本跑。打开 RPC `open_agentic_rectification_case_v2` 却把**当前注册版本**与 Case 做相等比较,任一不同就 `skill_identity_mismatch`。该错误码未映射,变成 500「校正服务暂时不可用」;客户端再兜成「暂时无法打开生时校正」。错误只画在首页起始卡下,而 BUG-599 之后 `selectSession` 等 Case 打开成功才切会话,历史列表点击看起来像没反应。
- 修复:`intent === "session"` 时先走 v1 按会话取 Case,再读绑定身份,用 `resolveExactSkillPackage` 核验快照存在且 sha 一致,核验通过后把**绑定身份**交给 v2。`homepage` / `new` 仍用当前注册版本。映射 `skill_identity_mismatch` → 409。历史打开失败把错误画在被点的那一行下面,起始卡不重复同一条。不改迁移、不改采用门。
- 验证:`frontend/tests/rectification-v9-case-service.test.ts``frontend/tests/rectification-history-open-20260909.test.ts``frontend/tests/skill-registry.test.ts`。Docker DB 套件本机跑不了(环境缺口);本轮无新迁移。
- 防复发:按会话打开必须用 Case 绑定身份,不得把当前注册版本交给 v2 做相等比较。升 Skill 版本后,历史校正必须仍能从历史对话打开,且以其绑定版本运行。废弃版本快照须仍可 `resolveExactSkillPackage`
- 相关记录:BUG-599、BUG-583、BUG-593、BUG-595、BUG-597、BUG-604
- 复发自:无
- 修复版本:待发布
## BUG-622 | staging 质量门因两条过期前端合同红掉,Deploy staging 未派发
- 状态:resolved
@@ -0,0 +1,51 @@
# PROGRESS · 历史生时校正打开时用绑定 Skill 身份(BUG-6212026-09-09
工作树:`.worktrees/rectification-history-open-20260909`
分支:`codex/rectification-history-open-20260909`
任务书:`docs/tasks/TASK-rectification-history-open-20260909.md`
基线:任务书写 `origin/staging` @ `af70ae77`;本 worktree 从任务书提交 `e8d46f12` 切出,开工后快进合并 `c41afe26`(BUG-622,对齐过期合同测试)。
本单状态:**待验收**。未 push,未合入 staging/main。合入时更新落点 SHA。
预检:本机 `python3 scripts/pre_work_check.py` 失败(系统 Python 3.14 无 pytest、无 swissephERR-078)。不把预检失败写成门禁已过。前端用 worktree 里指向其他 worktree 的 `frontend/node_modules` 符号链接。
未改:数据库迁移、`adopt-skill` 路由、采用门 / 确认门、只读终态、`homepage` / `new` 仍用当前注册版本、Skill 版本号。
## 做了什么
- **决策 1** `openRectificationCase``intent === "session"` 时:`open_agentic_rectification_case`v1)按会话取 Case → `get_agentic_rectification_skill_identity` 读绑定身份 → `resolveExactSkillPackage` 核验快照与 sha → 把绑定身份作为 `p_skill_*` 调 v2。绑定版本不在注册表 → `skill_identity_missing`。legacy sha 为空仍走既有 `skill_identity_unverifiable`
- **决策 2** `KNOWN_RPC_ERROR_CODES` 增加 `agentic_rectification_skill_identity_mismatch` → 409,文案「该校正绑定的规则版本与当前不一致,请刷新后重试」。
- **决策 3** 历史打开失败把 `rectificationErrorSessionId` 绑到被点会话;侧栏行下 `.session-open-error` 一行;`StarterHome` 收到空字符串,起始卡不重复。成功或另选会话则清除。
- **记录** `docs/BUG_HISTORY.md` BUG-621`CHANGELOG.md``docs/testing/rectification-history-open-20260909.md`
## 三栏
| 用例 | 原值 | 新值 | 理由 |
| --- | --- | --- | --- |
| 历史会话绑定 10.0.17(快照仍在) | v2 收到当前 10.0.19 → mismatch → 500 | v2 收到 10.0.17,打开成功 | 决策 1:按绑定版本打开 |
| 绑定版本不在注册表 | 同上,落到 500 | `skill_identity_missing`,不调 v2 | 决策 1:核验失败走既有 missing |
| homepage / new | 当前注册版本 | 仍是当前注册版本 | 只有 session 改绑定身份 |
| `skill_identity_mismatch` | 未映射 → 500「校正服务暂时不可用」 | 409,请刷新后重试 | 决策 2 |
| 历史列表点开失败 | 错误在首页起始卡下;会话不切 | 错误在被点那一行下;起始卡不重复 | 决策 3;BUG-599 让点击不再先切会话 |
## 测试
- `frontend` `./node_modules/.bin/tsc --noEmit`exit 0
- 本单改动文件 `eslint`0 error`page.tsx` / `app-sidebar.tsx` 等既有 hooks warning 未新增)
- 全仓 `npm run lint`4 error / 108 warning。4 error 全在 `rectification-agentic-chat.tsx` 的既有 `react-hooks/refs`(约 L1461),本单未改该文件
- 针对性 `tsx --test`case-service / history-open / agentic-entry / skill-registry / sidebar-contract / surface-contract / home-bootstrap-reveal):**147 passed / 0 failed**
- 任务书切片 `ls tests/rectification-*.test.ts tests/skill-registry*.test.ts tests/home-bootstrap*.test.ts | grep -v database | xargs tsx --test`**1093 passed / 0 failed**
- Docker DB / `test:db`:本机无 Docker,记环境缺口;本轮无新迁移,不触发该硬要求
- 浏览器真人走查:无登录态,未见真实历史 Case。走查清单见 `docs/testing/rectification-history-open-20260909.md`
## 偏离
1. 任务书基线 `af70ae77`;执行分支从已推任务书的 `e8d46f12` 切出,并快进 `c41afe26`BUG-622)。
2. 侧栏错误用 `.session-open-error`overline + danger),不再引入已删除的 `composer-notice` 类名。
3. 未跑 Docker 中的打开 RPC 真库套件。
## 环境缺口
- 本机系统 Python 3.14 无 pytest / swisseph,预检失败(ERR-078)。
- 无 Docker,不能跑 `test:db`
- 无 staging 登录态,不能真人点历史校正。
+1 -1
View File
@@ -88,7 +88,7 @@
| `TASK-rectification-conversation-economy-20260909.md` | `PROGRESS-rectification-conversation-economy-20260909.md` | 对照竞品后产品拍板三条:开场三句讲做法 + 一次收多件(推翻 opening brief「不要一次说完/不举例」与 SKILL L52);采集题「没有 / 记不清」按钮(不做示例骨架条);每轮只留一句(方法句进活动记录、点选旁白去领先落后、证据轮正文一句复述 + 服务端裁剪);Skill 10.0.19 | 已验收通过(2 条 P3 备注) | `aa7ccb30` + `1453fb16`BUG-604606Skill 10.0.19 |
| `TASK-consultation-daily-empty-answer-20260909.md` | `PROGRESS-consultation-daily-empty-answer-20260909.md` | 首页「深入看今日」计算完成却 `empty_answer`:入口定的 `timing` 被模型改成 `general``canonicalDomainPlan` 以模型为准),分段写作标题与今日格式错位,分段 `maxSteps=1` 且工具仍可调 → 模型在分段里再调工具、零正文;思考流按 chunk 过滤漏出缺词英文 | 待验收 | `codex/consultation-daily-empty-answer-20260909`BUG-612613);走查 `docs/testing/consultation-daily-empty-answer-20260909.md` |
| `TASK-rectification-compare-card-polish-20260909.md` | `PROGRESS-rectification-compare-card-polish-20260909.md` | 三列卡两列经历对照 0、三列无未来窗:引擎按引擎前三算 by_time,卡片按推断前三查表,键不匹配(BUG-614);交付旁白被 BUG-606 裁成一句(BUG-615);设计减法:相同性格句只写一次、经历对照说人话、删小标题、右栏本命宫位改北印星盘、换升时刻默认折叠 | 待验收 | `codex/rectification-compare-card-polish-20260909`BUG-614615 |
| `TASK-rectification-history-open-20260909.md` | `PROGRESS-rectification-history-open-20260909.md` | 历史生时校正打不开:`open_agentic_rectification_case_v2` 把 Case 绑定 Skill 身份与当前注册版本做相等比较,两天内 10.0.15→10.0.19 五次 bump 让所有旧 Case 被拒;错误码未映射成 500;错误只画在首页卡下 → 表现为点了没反应。决策:session 打开用绑定身份(v1 取 Case → 读身份 → 注册表核验 → v2),不改迁移 | 待执行 | `codex/rectification-history-open-20260909`BUG-621 |
| `TASK-rectification-history-open-20260909.md` | `PROGRESS-rectification-history-open-20260909.md` | 历史生时校正打不开:`open_agentic_rectification_case_v2` 把 Case 绑定 Skill 身份与当前注册版本做相等比较,两天内 10.0.15→10.0.19 五次 bump 让所有旧 Case 被拒;错误码未映射成 500;错误只画在首页卡下 → 表现为点了没反应。决策:session 打开用绑定身份(v1 取 Case → 读身份 → 注册表核验 → v2),不改迁移 | 待验收 | `codex/rectification-history-open-20260909`BUG-621 |
| `TASK-rectification-window-cluster-cap-20260909.md` | `PROGRESS-rectification-window-cluster-cap-20260909.md` | **P0** 真实用户:一小时窗口分 17 个签名簇,`select_signature_representatives` 按时间取前 12 个,14:40 之后整簇丢弃(本机复现表);区间按代表分钟跨度而非簇覆盖;中途说出真实时段时助手口头答应却未改 → 改为固定回复"范围开始时按资料定、中途不改"(产品否决口头改范围);intake 自定义范围等产品答复 | 待执行 | `codex/rectification-window-cluster-cap-20260909`BUG-623625Skill 10.0.20 |
### 聊天主链路与首页
@@ -0,0 +1,31 @@
# 生时校正 · 升 Skill 版本后历史对话仍能打开(2026-09-09)
对应 BUG-621。自动化锁的是打开 RPC 身份与侧栏错误位置,**锁不住**真实历史 Case 在 staging 上按绑定版本跑完一轮。
## 0. 确认测的是新版本
浏览器打开 `https://staging.jyotisha.chat/api/health`,看 `deployment.gitCommit` 前 8 位是否等于本单合入 staging 后的提交。不一致 = 先别测。
## 1. 升版本之后,旧校正仍能从历史对话打开(P0)
前置:账号里至少有一条在当前 Skill 版本之前创建的生时校正(例如 10.0.17 / 10.0.18 那天建的)。当前注册版本更高。
1. 停在首页,不要先点「生时校正」入口。
2. 在左侧历史列表点那条旧校正。
- ✅ 预期:主栏打开该校正,沿用它绑定的那一版规则继续;不是空白、不是「暂时无法打开」。
- ❌ 失败:点了没反应;或首页起始卡下才出现错误;或打开后按当前新版本重跑。
## 2. 绑定版本若已从注册表消失(P1)
只有在故意缺少快照的环境才测。正常 staging 应仍保留 10.0.1510.0.18。
- ✅ 预期:被点的那一行下面出现一行错误(Skill 版本不可用),首页起始卡不再重复同一条。
- ❌ 失败:仍像没点到,或主栏/起始卡出现 500「校正服务暂时不可用」。
## 3. 新开一场仍用当前版本(P1)
从首页点「生时校正」新建。
- ✅ 预期:新 Case 绑定当前注册版本(现为 10.0.19)。
- ❌ 失败:新 Case 也去套某个旧版本。