docs(ops): reconcile CHAT-HISTORY-REFRESH SSOT as PASS

Close stale open handoff/planned remediation against tip code and B3 live evidence; keep empty stage_key and localStorage masking red lines.
This commit is contained in:
WeiCHEN
2026-09-22 21:26:35 +08:00
parent 364ed7f1a3
commit 330de92ba7
4 changed files with 164 additions and 55 deletions
@@ -1,13 +1,20 @@
---
title: "对话刷新后正文消失整改实施交接"
created: 2026-09-13
updated: 2026-09-22
from: codex
to: next-agent
status: open
status: done
---
# 交接:对话刷新后正文消失整改实施
## 收口结论(2026-09-22)
**本交接关闭。** tip `364ed7f1` 上原发布缺口已关闭;发布 SSOT 以 [gap-matrix](../../remediation/gap-matrix.md) 行 `CHAT-HISTORY-REFRESH` = **PASS** 为准。
口径裁定见 [2026-09-22-chat-history-refresh-reconcile](../short-term/2026-09-22-chat-history-refresh-reconcile.md)。不得再凭本文件的历史 “open / publish blocker” 表述回退该 PASS。
## 目标(下一位 Agent 应完成什么)
按整改方案修复消息作用域、历史读取授权和统计同集问题,并完成历史回填与真实刷新 E2E。
@@ -15,16 +22,16 @@ status: open
## 已完成
- 源码链路与 dev PostgreSQL 只读定位完成,确认消息未删除。
- 确认 project 143/session `sess-p143-u9` 的 4 条消息均缺 `stage_key`,工作流激活后被窗口过滤器全部移除。
- 确认异步文档任务写入路径缺阶段/实例作用域;分类与日期统计未应用同一过滤。
- 确认 project 143/session `sess-p143-u9` 的 4 条消息均缺 `stage_key`,工作流激活后被窗口过滤器全部移除(诊断时)。
- 确认异步文档任务写入路径缺阶段/实例作用域;分类与日期统计未应用同一过滤(诊断时)。
- 审计、整改方案、发布 blocker 与 planned short-term 已建立。
- 现有相关 Go 测试和前端 192 项测试通过,但均未覆盖真实缺陷场景。
- **实施已合入**:`message_scope`、`chatflow` 同集过滤、goose 00026/00027;证据见 [test-report](../../test-reports/2026-09-13-chat-history-refresh-test-report.md) 与 [live.json](../../test-reports/assets/2026-09-15-chat-history-refresh-live/live.json)。
- 整改方案已同步关闭:[remediation](../../remediation/2026-09-13-chat-history-refresh-remediation.md)。
## 未完成
## 未完成(遗留债,非本 gap 回退)
- 未修改业务代码、迁移或运行态数据。
- 未建立实施 checklist/test-report。
- 未运行真实 PI 刷新回归和双用户对象级授权负例。
- 真实 PI「激活后文档任务 + 重登/重启」活验仍开放(live 闲聊 PASS,intake 未跑)。
- 前端网络错误路径仍可能用 localStorage 回退并显示 `ready`(`useChatWindow` catch);不得扩大,后续专项修复。
## 认领 / 槽位状态
@@ -32,39 +39,37 @@ status: open
|----|-----|
| mutex 已释放 | yes |
| 集成槽位 holder | idle |
| branch | dev(诊断);建议实施用 `fix/chat-history-refresh` |
| worktree | 建议 `.worktrees/fix-chat-history-refresh` |
| branch | 实施已合入主干历史;本裁定 `feature/chat-history-refresh-reconcile-2026-09-22` |
| worktree | `.worktrees/chat-history-refresh-reconcile-2026-09-22`(裁定用) |
## 关键文件
| 路径 | 说明 |
|------|------|
| `.doc/audit/2026-09-13-chat-history-refresh-disappears.md` | 根因与运行态证据 |
| `.doc/remediation/2026-09-13-chat-history-refresh-remediation.md` | 分波次整改与验收 |
| `internal/server/task_run_handlers.go` | 文档任务消息缺阶段作用域 |
| `internal/server/stage_access_helpers.go` | 空阶段消息被丢弃 |
| `internal/server/chat_window_api.go` | 正文与统计授权口径分裂 |
| `web/src/hooks/useChatWindow.ts` | 刷新后服务端空桶覆盖本地窗口 |
| `.doc/remediation/2026-09-13-chat-history-refresh-remediation.md` | 分波次整改与验收(已 done) |
| `.doc/ops/short-term/2026-09-22-chat-history-refresh-reconcile.md` | 三方口径裁定 |
| `internal/projectinstance/message_scope.go` | 作用域与 `MessageVisible` |
| `internal/app/chatflow/chatlog.go` | 窗口/统计同集授权 |
| `web/src/hooks/useChatWindow.ts` | 恢复态相位;勿掩盖服务端错误 |
## 如何验证
```bash
go test -short ./internal/server -run 'TestServer_ChatWindow' -count=1 -v
go test -short ./internal/ctxmgr -run 'TestChatWindow' -count=1 -v
go test -short ./internal/projectinstance -run 'MessageVisible|StageKeyAllowed' -count=1
go test -short ./internal/server -run 'ChatHistory' -count=1 -v
cd web && npm test
```
实施时必须另加真实 PG 场景:激活前对话 → 激活 → `intake` 文档任务 → 刷新窗口,以及非 owner/无阶段职责负例。
## 风险 / Blocker
- 当前为发布 blocker;刷新会造成对话“数据丢失”假象。
- 不能用“空 `stage_key` 全部放行”或保留旧 localStorage 缓存作修复,否则会扩大阶段/跨用户泄露。
- 历史回填存在重复 `task_key` 歧义,必须先 dry-run 并按实例与时间唯一匹配。
- **不再是发布 blocker。** SSOT = gap-matrix PASS。
- 红线仍有效:不能用“空 `stage_key` 全部放行”修复;不能把旧 localStorage 当作授权成功掩盖服务端错误。
- 历史回填歧义与真实 PI 文档任务活验见 remediation 遗留项。
## 相关链接
- CURRENT: [CURRENT.md](../CURRENT.md)
- Task: [chat-history-refresh-remediation](../short-term/2026-09-13-chat-history-refresh-remediation.md)
- Reconcile: [chat-history-refresh-reconcile](../short-term/2026-09-22-chat-history-refresh-reconcile.md)
- Audit: [chat-history-refresh-disappears](../../audit/2026-09-13-chat-history-refresh-disappears.md)
- Remediation: [chat-history-refresh-remediation](../../remediation/2026-09-13-chat-history-refresh-remediation.md)
@@ -0,0 +1,90 @@
---
title: "CHAT-HISTORY-REFRESH 口径冲突裁定"
task_id: "2026-09-22-chat-history-refresh-reconcile"
status: done
created: 2026-09-22
updated: 2026-09-22
owner: Cursor
task_type: research
task_tier: small
policy_revision: "AGENTS+gap-matrix @ tip 364ed7f1"
branch: feature/chat-history-refresh-reconcile-2026-09-22
worktree: .worktrees/chat-history-refresh-reconcile-2026-09-22
base_dev_sha: "364ed7f1a3f0393ef77ec4623a9518116ed2cb87"
write_scope: [".doc/ops/", ".doc/remediation/"]
allowed_environments: []
head_sha: "364ed7f1a3f0393ef77ec4623a9518116ed2cb87"
mutex: "ops-status-reconcile-chat-history-refresh"
review_state: not_required
integration_state: pending
deployment: not_required
cleanup: pending
cleanup_owner: "独立维护者"
cleanup_trigger: "本裁定合入 dev 且无进程占用后复查 remove"
remote_sync: not_requested
---
# CHAT-HISTORY-REFRESH 口径冲突裁定
## 用户目标与授权
- 用户目标:裁定 handoff(open / publish blocker)与 gap-matrix(PASS)与 remediation(planned / 10 项未勾)三方冲突,单一事实源。
- 交付终点:对齐三文档 + 本裁定落盘并提交;不 push。
- 禁止项:无代码证据不得发明 PASS;不 push;不空 `stage_key` 一律放行;不以 localStorage 掩盖服务端错误作为“已修好”口径。
## 冲突摘要
| 文档 | 冲突前状态 | 问题 |
|------|------------|------|
| [handoff](../handoffs/2026-09-13-chat-history-refresh-diagnosis.md) | `open`,称发布 blocker | 修复合入后未收口 |
| [gap-matrix](../../remediation/gap-matrix.md) `CHAT-HISTORY-REFRESH` | **PASS** | 与 handoff/remediation 矛盾 |
| [remediation](../../remediation/2026-09-13-chat-history-refresh-remediation.md) | `planned`,验收 10 项全未勾 | 实现与证据已存在但方案未关闭 |
## 裁定(SSOT)
**发布缺口 SSOT = gap-matrix:`CHAT-HISTORY-REFRESH` = PASS。**
原缺陷(工作流激活后刷新,阶段过滤器清空正文,分类/锚点仍按全量)在 tip `364ed7f1` 上已由代码与既有报告关闭;handoff/remediation 过期口径不得回退该 PASS。
遗留项(激活后真实 PI 文档任务 + 重登/重启活验、网络错误路径 localStorage 降级)记为**非本 gap 回退**的开放债,不得冒充本行 FAIL。
## tip 代码证据(`364ed7f1`)
| 断言 | 证据 |
|------|------|
| 写入作用域 | `internal/projectinstance/message_scope.go`;goose `00026`/`00027`;写入路径 `resolveTaskMessageScope` / `resolveChatMessageScope` |
| 读取同集过滤 | `internal/app/chatflow/chatlog.go`:`authorize` + `MessageRecordVisible` 用于 window/categories/search 等 |
| 空 `stage_key` **非**一律放行 | `MessageVisible`:`ScopeWorkflowStage` 且 restricted 时,空 `stageKey` → **仅 session owner**(非 `StageKeyAllowed("")`)。本轮 `go test -short ./internal/projectinstance -run 'MessageVisible\|StageKeyAllowed'` PASS |
| `StageKeyAllowed("")==true` | 仍存在于 `stage_access.go`,但**聊天历史可见性不走该短路**;活动流等其他调用点另账,不构成本 gap 回退 |
| 前端空桶 / 403 | `useChatWindow`:服务端空消息日桶 → `authorized_empty` 并 `clearSessionWindowCache`;403 → `forbidden` 清缓存 |
| localStorage 红线残留 | `catch` 非 403 时仍可回退缓存并 `phase='ready'`(掩盖瞬时网络错误)。**残留债**,不回退本 gap PASS;后续修前端时禁止扩大该路径 |
| 既有验收 | [test-report](../../test-reports/2026-09-13-chat-history-refresh-test-report.md);[live.json](../../test-reports/assets/2026-09-15-chat-history-refresh-live/live.json)(项目 6252,window=categories=2,guest 403;intake 未跑) |
| 实现合入 | `1abafa31` fix;`dca83f0d` 首次标 PASS(文档未同步收口 handoff/remediation) |
## 对齐动作
1. handoff → `done`,明确不再是发布 blocker。
2. remediation → `done`(缺口关闭);仅勾有证据的验收项;未证据项保留未勾并指向遗留债。
3. gap-matrix → 维持 **PASS**;证据列追加本裁定。
## 验证
| 范围 / SHA | 命令 | 实际 |
|---|---|---|
| tip `364ed7f1` | `go test -short ./internal/projectinstance -run 'MessageVisible\|StageKeyAllowed' -count=1` | PASS |
| tip `364ed7f1` | `go test -short ./internal/server -run 'ChatHistory\|MessageScope\|authorizeSession' -count=1` | PASS |
未重新跑真实 PI / 全量 `go test ./...` / `npm test`;不把未运行项记为新 PASS。
## 收口
- `integration_state`: pending(本分支待合入)
- `remote_sync`: not_requested
- 下一步:独立维护者合入后清理本 worktree
## 相关链接
- Handoff: [../handoffs/2026-09-13-chat-history-refresh-diagnosis.md](../handoffs/2026-09-13-chat-history-refresh-diagnosis.md)
- Remediation: [../../remediation/2026-09-13-chat-history-refresh-remediation.md](../../remediation/2026-09-13-chat-history-refresh-remediation.md)
- gap-matrix 行: `CHAT-HISTORY-REFRESH`
- Audit: [../../audit/2026-09-13-chat-history-refresh-disappears.md](../../audit/2026-09-13-chat-history-refresh-disappears.md)
@@ -1,12 +1,20 @@
---
title: "对话刷新恢复与阶段授权一致性整改方案"
status: planned
status: done
created: 2026-09-13
updated: 2026-09-13
updated: 2026-09-22
---
# 对话刷新恢复与阶段授权一致性整改方案
## 关闭说明(2026-09-22)
**本方案关闭(缺口级 done)。** tip `364ed7f1` 代码与既有报告证明原发布缺陷已修;SSOT 见 [gap-matrix](./gap-matrix.md) `CHAT-HISTORY-REFRESH` = **PASS**。
三方口径裁定:[ops/short-term/2026-09-22-chat-history-refresh-reconcile.md](../ops/short-term/2026-09-22-chat-history-refresh-reconcile.md)。
未勾验收项 = **遗留债**,不回退本 gap。红线:无空 `stage_key` 一律放行;无前端 localStorage 掩盖服务端错误作为成功态。
## 背景
审计确认消息正文仍在 PostgreSQL,但文档任务消息和激活前历史缺少工作流阶段作用域;刷新后的窗口接口将其全部过滤,而分类/日期统计仍返回全量结果。详见 [审计记录](../audit/2026-09-13-chat-history-refresh-disappears.md)。
@@ -20,46 +28,52 @@ updated: 2026-09-13
## 分波次计划
| 波次 | 内容 | 验收 |
| 波次 | 内容 | 状态 |
|------|------|------|
| Wave 0:锁定回归 | 增加失败测试:激活前聊天 → 激活工作流 → 运行 `intake` 文档任务 → 刷新拉窗口;同时覆盖非 owner、阶段无职责用户、空阶段消息和统计一致性 | 修复前测试稳定复现“窗口 0 条、分类 4 条”;记录真实 PG 证据 |
| Wave 1:统一服务端作用域 | 在任务创建事务中由服务端从冻结实例解析 `task_key → workflow_instance_id → stage_instance_id/stage_key`;把不可变作用域写入 `task_runs` 和该回合两条 `chat_messages`;普通 chat 同样写实例 ID;finalize 只合并结果,不覆盖作用域 | 新建普通聊天和任务消息均具备正确实例/阶段;伪造客户端 stage 无效;找不到唯一阶段时拒绝启动并给出结构化错误 |
| Wave 2:修正授权查询 | 建立统一的 `AuthorizeSessionRead + visible-message predicate`,窗口、day、dates、categories、search、digest、unread、export、锚点加载全部复用;私聊先校验 owner,再计算阶段范围;统计在 SQL 层对相同可见集合聚合 | 正文、数量、首尾 ID、搜索/导出完全同集;他人 session 返回 403/404;不可见 ID 不能作锚点探测 |
| Wave 3:历史迁移 | 新增 Goose 迁移或一次性受控 backfill:任务消息通过 `task_key + task_run/workflow_run + 时间区间` 回填实例/阶段;激活前 owner 私聊标记 `scope_kind=pre_activation`;歧义数据标记 `legacy_unscoped` 并记录数量,不猜测归属 | dry-run 报告、事务执行、前后计数与 hash 对账;project 143 的 4 条消息可按策略恢复;零正文删除 |
| Wave 4:前端恢复态 | `useChatWindow` 区分 loading / authorized-empty / forbidden / error;不把“带空消息的日桶”静默呈现为空白;缓存键绑定 user/session/authorization revision,权限变化时清除,不用旧缓存绕过服务端 | 刷新不闪现上一用户/无权缓存;错误有可操作提示;服务端正常时首屏稳定落底 |
| Wave 5:全链验收 | 在空库和升级库执行 PG 集成;完成真实 PI 文档生成、浏览器刷新、重登和服务重启恢复;执行双用户/跨阶段负例 | 所有自动化门禁通过并归档 test-report;人工抽检截图/网络响应入证据 |
| Wave 0:锁定回归 | PG/单测覆盖激活前 + 任务作用域 + guest 负例 | done(`chat_history_refresh_pg_test.go`、`message_scope_test.go`) |
| Wave 1:统一服务端作用域 | 服务端解析并写入 `scope_kind` / 实例 / `stage_key` | done(`message_scope.go`、task/chat 写入路径) |
| Wave 2:修正授权查询 | `chatflow` 统一 `MessageRecordVisible` | done(`internal/app/chatflow/chatlog.go`) |
| Wave 3:历史迁移 | goose 00026 列 + 00027 回填 | done(迁移在库;项目 143 专项 dry-run 报告未另档) |
| Wave 4:前端恢复态 | `authorized_empty` / `forbidden` / `error`;空桶清缓存 | 部分 done;网络错误仍可能 cache→`ready`(遗留) |
| Wave 5:全链验收 | 闲聊真实 PI 刷新同集 PASS;激活后文档任务活验未跑 | 部分 done |
## 推荐数据模型与边界
- `chat_messages` 增加正式列或受约束字段:`workflow_instance_id`、`stage_instance_id`、`scope_kind`;`stage_key` 可作为展示/索引冗余,不应成为唯一授权依据。
- `task_runs` 同样保存 `workflow_instance_id`、`stage_instance_id`,确保任务运行期间阶段推进也不会改变该回合归属。
- `scope_kind` 至少区分 `workflow_stage`、`pre_activation`、`legacy_unscoped`、`non_project_private`。
- 消息作用域只能由服务端从会话、项目与冻结工作流实例解析;忽略客户端提交的 user/stage/instance 身份字段。
- 不建议用“空 `stage_key` 一律允许”快速修复,这会绕过阶段隔离;也不建议仅在前端保留本地缓存,这会掩盖服务端错误并产生共享浏览器泄露风险。
- `chat_messages` 增加正式列:`workflow_instance_id`、`stage_instance_id`、`scope_kind`;`stage_key` 为冗余索引,非唯一授权依据。
- `task_runs` 同样保存实例/阶段键。
- `scope_kind`:`workflow_stage`、`pre_activation`、`legacy_unscoped`、`non_project_private`。
- 消息作用域只由服务端解析;忽略客户端伪造身份字段。
- **红线(仍 enforced)**:`MessageVisible` 在 restricted 下对空 `stage_key` 仅放行 session owner,禁止一律放行;前端不得用未授权 localStorage 把服务端错误呈现为成功窗口。
## 建议修改范围
## 建议修改范围(已落地)
- 后端写入:`internal/server/task_run_handlers.go`、`internal/server/task_finalize.go`、`internal/chat/session.go`、`internal/taskrun/*`
- 后端读取与授权:`internal/server/chat_window_api.go`、`internal/server/chat_search_api.go`、chat digest/unread/export handlers、`internal/server/stage_access_helpers.go`、`internal/ctxmgr/chat_window.go`
- 工作流解析:`internal/projectinstance/*`,增加按冻结实例解析消息作用域的单一入口
- 前端:`web/src/hooks/useChatWindow.ts`、`web/src/api/chatWindow.ts`、`web/src/components/chat/MessageStream.tsx`
- 数据库:`deploy/postgres/goose/00026_*`(实际序号以实施时仓库为准)及对应 dry-run/rollback 说明
- 后端:`message_scope.go`、`chat_history_auth.go`、`chatflow/chatlog.go`、task/chat 写入
- 前端:`web/src/hooks/useChatWindow.ts`
- 数据库:`deploy/postgres/goose/00026_*`、`00027_*`
## 验收标准
- [ ] 创建项目会话并发送普通消息,刷新后用户/助手两条正文、顺序、类别和锚点不变。
- [ ] 先聊天再激活工作流,刷新后激活前 owner 私聊仍按既定策略可见。
- [ ] 激活后通过后台任务生成文档,任务用户消息和最终助手消息刷新后完整恢复,artifact 仍可打开。
- [ ] 工作流推进后,已参与阶段历史按策略可见,未参与阶段消息不可见。
- [ ] `window/day/dates/categories/search/digest/unread/export` 对同一用户返回同一可见集合;统计总数等于可枚举正文数。
- [ ] 非会话 owner 即使猜到 `session_id/message_id`,所有读取与锚点入口均返回 403/404,且不泄露计数。
- [ ] 浏览器刷新、重新登录、切换用户、服务重启均不依赖未授权 localStorage 缓存恢复正文。
- [ ] 历史迁移 dry-run 与执行报告包含总数、可唯一归属数、歧义数、前后校验;正文删除数为 0。
- [ ] `go vet ./...`、`go test -short ./...`、PG 集成、`cd web && npm test && npm run build` 全绿。
- [ ] 真实 PI Agent 文档生成后刷新恢复 E2E 有控制台/网络/数据库证据并归档 `.doc/test-reports/`。
- [x] 创建项目会话并发送普通消息,刷新后用户/助手两条正文、顺序、类别和锚点不变。(live 项目 6252:window=categories=2)
- [x] 先聊天再激活工作流,刷新后激活前 owner 私聊仍按既定策略可见。(`TestChatHistoryRefresh_PG_PreActivationAndTaskScope`)
- [ ] 激活后通过后台任务生成文档,任务用户消息和最终助手消息刷新后完整恢复,artifact 仍可打开。(PG 有任务作用域用例;**真实 PI intake 活验未跑**)
- [ ] 工作流推进后,已参与阶段历史按策略可见,未参与阶段消息不可见。(单测覆盖阶段拒绝;缺推进后 E2E)
- [x] `window`/`categories`(及 chatflow 同谓词入口)对同一用户同集;guest 403。(live + PG;search/digest/unread/export 走同一 `MessageRecordVisible`,未单独活验)
- [x] 非会话 owner 猜 `session_id` 读窗口返回 403,不泄露正文。(live guest 403 `SESSION_FORBIDDEN`)
- [ ] 浏览器刷新、重新登录、切换用户、服务重启均不依赖未授权 localStorage 缓存恢复正文。(刷新/切换有相位;**重登/重启未活验**;catch 仍可能 cache→ready)
- [ ] 历史迁移 dry-run 与执行报告含总数/可归属/歧义/前后校验;正文删除 0。(有 goose 00027;**缺独立 dry-run 对账报告**)
- [x] 相关自动化门禁:本裁定重跑 `MessageVisible`/`ChatHistory` short 测试 PASS;历史报告称 `go test -short ./...` 与 `npm test` 曾绿。
- [ ] 真实 PI Agent 文档生成后刷新恢复 E2E 归档。(live **仅闲聊**;intake 因 workflow-plan 400 未跑)
## 遗留债(不回退 gap)
1. 激活后文档任务 + 重登/重启真实 PI 活验。
2. `useChatWindow` 非 403 错误路径禁止 `phase='ready'` 掩盖失败(保持 `error`)。
3. `StageKeyAllowed("")==true` 在非聊天调用点的收紧(活动流等另账)。
## 相关链接
- Audit: [../audit/2026-09-13-chat-history-refresh-disappears.md](../audit/2026-09-13-chat-history-refresh-disappears.md)
- Short-term: [../archive/ops/2026-09-13-chat-history-refresh-remediation.md](../archive/ops/2026-09-13-chat-history-refresh-remediation.md)
- Reconcile: [../ops/short-term/2026-09-22-chat-history-refresh-reconcile.md](../ops/short-term/2026-09-22-chat-history-refresh-reconcile.md)
- Handoff: [../ops/handoffs/2026-09-13-chat-history-refresh-diagnosis.md](../ops/handoffs/2026-09-13-chat-history-refresh-diagnosis.md)
- Test report: [../test-reports/2026-09-13-chat-history-refresh-test-report.md](../test-reports/2026-09-13-chat-history-refresh-test-report.md)
- gap-matrix 行: `CHAT-HISTORY-REFRESH`
+1 -1
View File
@@ -65,7 +65,7 @@
|---|---|---|---|---|
| WORKFLOW-PLAN-FROZEN-OPTIONAL-DUTIES | active 项目仍展示可编辑职责表单,409 提示在长表单视口外;现有规划又不支持非必需文档“三权全空”,且后端缺少职责人在任成员复核 | **PASS(设置页)** | [audit](../audit/2026-09-14-workflow-plan-409-frozen-and-optional-duties.md);[test-report](../test-reports/2026-09-14-workflow-plan-409-frozen-and-optional-duties-test-report.md)。项目 143 只读 frozen、A full+none 激活、B partial 不发 PUT、C 零治理拒绝、双标签转 frozen、成员无配置入口、刷新后 143 仍 frozen | 设置页矩阵 PASS;真实 PI full/none 长链已另签 [Wave2 报告](../test-reports/2026-09-16-wave2-real-pi-evidence-test-report.md) |
| DOC-CONTENT-CANONICAL-HASH-DRIFT | 旧受控文档 bootstrap 裁剪 Markdown 双空格硬换行并将 canonical SHA 写入账本/DocGov,但未同步文件;正文读取把完整性冲突误报 404,lease/list sync 又放大并制造刷新后加载死锁 | **PASS(真实 UI)** | [audit](../audit/2026-09-14-project143-controlled-content-404.md);[UI report](../test-reports/2026-09-14-controlled-content-ui-acceptance.md)。代码已合 dev、schema 32、项目 143 定向 `migration_repair`;项目 143 `clean-run3` 与新项目 `full-chain-final` 主链及 restart 全部纯页面 PASS,目标 404=0 | [remediation](./2026-09-14-controlled-content-canonical-hash-remediation.md)。Wave 3(2026-09-18)已在隔离 docker PG(5436)执行 `TestReconcile_LegacyRepair_PG` 一次并 PASS,工程测试债关闭,见 [test-report](../test-reports/2026-09-18-wave3-test-debt-blindspots-test-report.md) |
| CHAT-HISTORY-REFRESH | 工作流激活后刷新,对话正文被阶段过滤器清空,但分类数量与锚点仍按全量返回 | **PASS** | [test-report](../test-reports/2026-09-13-chat-history-refresh-test-report.md);活验 [live.json](../test-reports/assets/2026-09-15-chat-history-refresh-live/live.json)(项目 6252,window=categories=2,guest 403);代码:`message_scope.go`、`chat_history_auth.go`、goose 00026/00027 | 闲聊刷新已补。发布门禁「激活后文档任务 + 重登/重启」仍开放,不回退本 gap |
| CHAT-HISTORY-REFRESH | 工作流激活后刷新,对话正文被阶段过滤器清空,但分类数量与锚点仍按全量返回 | **PASS** | [test-report](../test-reports/2026-09-13-chat-history-refresh-test-report.md);闲聊 [live.json](../test-reports/assets/2026-09-15-chat-history-refresh-live/live.json)(6252,window=categories=2,guest 403);B3 [gate](../test-reports/2026-09-16-chat-refresh-gate-test-report.md)(6359,activate+task window=4,rebuild 4→4);代码 tip `364ed7f1`:`message_scope.go`、`chat_history_auth.go`、goose 00026/00027;[口径裁定](../ops/short-term/2026-09-22-chat-history-refresh-reconcile.md) | 已修且 B3 ☑。红线仍生效:禁空 stage_key 一律放行;禁 localStorage 掩盖服务端空/错。handoff/remediation 已关闭 |
| CHAT-INTENT-STATE | 真实会话被诊断探针污染;只读查询误启动文档写任务;错误动作与编辑状态刷新后丢失 | **PASS** | [audit](../audit/2026-09-13-conversation-intent-runtime-state.md);[test-report](../test-reports/2026-09-13-conversation-intent-runtime-state-test-report.md);双标签活验项目 **6275** / `sess-p6275-u10`(`live.json` + Docker 截图)。**不**删除 `sess-p143-u9` 历史探针 | [remediation](./2026-09-13-conversation-intent-runtime-state-remediation.md)。Wave 3–4 浏览器门已签;诊断污染消息仍不擅自删除 |
| ENV-RESTART-SOURCE | `docker compose restart` 只重启旧镜像,健康检查无法证明合入代码已部署 | **PASS** | `env-service.sh rebuild` + 真实摘要重测 | 集成冒烟统一使用 `dev rebuild` |
| DOCREV-RUNTIME-404 | revision-state 404;账本内存丢失;块保存/overlay 无效;agent 假报告 | **PASS** | [Round20 报告](../test-reports/2026-09-14-document-revision-runtime-ui-test-report.md);[audit](../audit/2026-09-13-document-revision-runtime-404.md) | 运行时 UI 已闭环。change report 仍为 fallback,不冒充 PI。历史失败目录不删 |