--- title: "CHAT-HISTORY-REFRESH 口径冲突裁定(单一事实源)" task_id: chat-history-refresh-reconcile-2026-09-22 status: done created: 2026-09-22 updated: 2026-09-22 owner: Cursor task_type: research task_tier: small policy_revision: "agent-governance-2026-09-21-r1 @ 364ed7f1a3f0393ef77ec4623a9518116ed2cb87" 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"] allowed_environments: [] head_sha: "7292c01aaac6d8566deef15d57eb54952c35e3a5" mutex: docs-chat-history-refresh-reconcile review_state: not_required integration_state: pending deployment: not_required cleanup: pending cleanup_owner: "Cursor 之外的集成/维护执行者" cleanup_trigger: "合入 dev、证据归档且 owner 退出后核对清理门禁" remote_sync: not_requested --- # CHAT-HISTORY-REFRESH 口径冲突裁定 ## 用户目标与授权 - 用户目标:对 handoff(open / blocker)、gap-matrix(PASS)、remediation(planned / 10 未勾)三方口径冲突做单一事实源裁定;基于 tip `364ed7f1` 真实代码与仓库内活验证据,不得无证据 invent PASS。 - 交付终点:裁定文档落盘;三份文档对齐;本地 commit;不 push。 - 禁止项:无代码证据改 PASS;空 `stage_key` 一律放行;前端 localStorage 掩盖服务端错误作为“修复”。 ## 例外登记(本机治理工具不可用) - owner:Cursor(本任务)。 - 原因:`agentctl with` 依赖 Linux `/proc`;本机 macOS 实测 `TypeError: 'NoneType' object is not subscriptable`。 - 覆盖条款:操作规范 §3(with 租约)提交钩子。 - 范围:仅本任务 `.doc` 提交;本 macOS 宿主执行期间。 - 退出条件:agentctl macOS 支持落地,或迁到 Linux 宿主。 - 恢复动作:仅改预期 `.doc` 路径;`git -c core.hooksPath=<空目录>` 旁路 agentctl hook(**不用** `--no-verify`)。 ## 冲突摘要 | 文档 | 裁定前状态 | 问题 | |------|------------|------| | [handoff](../handoffs/2026-09-13-chat-history-refresh-diagnosis.md) | `open`,称发布 blocker | 诊断交接未收口;实施与门禁证据已存在 | | [gap-matrix](../../remediation/gap-matrix.md) `CHAT-HISTORY-REFRESH` | **PASS** | 与 open handoff 矛盾;计划动作曾写「发布门禁仍开放」但门禁 B3 已 ☑ | | [remediation](../../remediation/2026-09-13-chat-history-refresh-remediation.md) | `planned`,10 验收未勾 | 与 archive short-term/checklist `done`、代码合入及 B3 证据矛盾 | ## 裁定(单一事实源) **结论:原缺陷已修复;`CHAT-HISTORY-REFRESH` 维持 gap-matrix PASS;handoff / remediation 收口为 done。本行不是当前发布 blocker。** 发布缺口 SSOT 仍为 [gap-matrix](../../remediation/gap-matrix.md)。 ### tip `364ed7f1` 代码证据 | 关注点 | 证据 | 判定 | |--------|------|------| | 作用域写入 / 可见性 | `internal/projectinstance/message_scope.go`:`pre_activation` / `workflow_stage` / `legacy_unscoped`;受限下空 `stage_key` 仅 session owner 可见(非 blanket allow) | 红线保持 | | 读取同集 | `internal/app/chatflow/chatlog.go`:`GetWindow` / `CategoryStats` / dates / search / unread 均经 `MessageRecordVisible`;`internal/server/chat_history_auth.go` 同源谓词 | 原「窗 0 / 分类全量」分裂已消 | | 迁移回填 | goose `00026` 作用域列;`00027` 受控 backfill(零正文删除) | 已落地 | | 前端 | `useChatWindow.ts`:`authorized_empty` / `forbidden` / `error`;403 与空日桶清缓存;缓存键含 `userId` | 非「用 localStorage 冒充服务端成功空窗」 | | 本轮复测 | `go test -short ./internal/projectinstance -run 'MessageVisible\|ResolveMessageScope\|StageKeyAllowed' -count=1` → PASS;`go test -short ./internal/server -run 'ChatHistory\|MessageScope\|authorizeSession' -count=1` → PASS | 实时 | ### 归档活验(不复跑共享环境;以仓库内证据为准) - 闲聊刷新:[2026-09-13 test-report](../../test-reports/2026-09-13-chat-history-refresh-test-report.md) + [live.json 6252](../../test-reports/assets/2026-09-15-chat-history-refresh-live/live.json)(window=categories=2,guest 403) - 发布门禁 B3(激活后文档任务 + rebuild):[2026-09-16 gate report](../../test-reports/2026-09-16-chat-refresh-gate-test-report.md) + [live.json 6359](../../test-reports/assets/2026-09-16-chat-refresh-gate/live.json)(`pi_task_refresh` window=categories=4,`overall=PASS`)+ [restart.json](../../test-reports/assets/2026-09-16-chat-refresh-gate/restart.json)(before=after=4);gap-matrix 发布门禁已 ☑ ### 红线复核 1. **禁止空 `stage_key` 一律放行**:`MessageVisible` 在 `Restricted` 且 `ScopeWorkflowStage`+空 key 时仅 owner;`legacy_unscoped` 受限亦仅 owner。`StageKeyAllowed("")==true` 是 helper 语义,聊天可见性不经该捷径对非 owner 放行。 2. **禁止前端 localStorage 掩盖服务端错误**:成功空窗 → `authorized_empty` 并清缓存;403 → `forbidden` 并清缓存。网络失败时若有同用户缓存会暂显并 `phase='ready'`——属降级 UX 残留,**不是**本 gap 的修复手段,也不构成重新 FAIL。 ### 非目标 / 残留(不回退本 gap) - 网络错误态「cache → ready」可另开前端 UX 任务。 - `StageKeyAllowed("")` 在非聊天调用点的收紧另账。 - 项目 143 历史只读样本不要求本裁定复跑。 ## 对齐动作(本提交) 1. handoff → `done`,指向本裁定与 B3 证据;不再称发布 blocker。 2. remediation → `done`,验收项按闲聊 + B3 + 代码证据勾选。 3. gap-matrix 行保持 **PASS**;计划动作与门禁 B3 已签一致,并回链本文件。 ## 验证与证据 | 范围 / 被测 SHA | 命令与环境 | 预期 | 实际 / 判定 | 证据 | |---|---|---|---|---| | tip `364ed7f1` MessageVisible | `go test -short ./internal/projectinstance -run 'MessageVisible\|ResolveMessageScope\|StageKeyAllowed' -count=1` | PASS | PASS | 本会话终端 | | tip `364ed7f1` ChatHistory | `go test -short ./internal/server -run 'ChatHistory\|MessageScope\|authorizeSession' -count=1` | PASS | PASS | 本会话终端 | | 仓库 B3 活验 | 读 [live.json](../../test-reports/assets/2026-09-16-chat-refresh-gate/live.json) / [restart.json](../../test-reports/assets/2026-09-16-chat-refresh-gate/restart.json) | overall PASS;rebuild 4→4 | 已核实 | 仓库资产 | | 文档三角对齐 | 人工对照 handoff / remediation / gap-matrix | 无 open-blocker vs PASS 冲突 | 本提交后一致 | 本文件 | 未重新跑真实 PI / 全量 `go test ./...` / `npm test`;不把未运行项记为新 PASS。 ## 收口与交接 - `review_state=not_required`;`integration_state=pending`(待合入 dev);`remote_sync=not_requested`;不 push。 - cleanup:合入后由独立维护者按 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: [../../remediation/gap-matrix.md](../../remediation/gap-matrix.md) - Archive task: [../../archive/ops/2026-09-13-chat-history-refresh-remediation.md](../../archive/ops/2026-09-13-chat-history-refresh-remediation.md) - Archive checklist: [../../archive/ops/checklists/2026-09-13-chat-history-refresh-remediation.md](../../archive/ops/checklists/2026-09-13-chat-history-refresh-remediation.md)