diff --git a/.doc/audit/2026-09-13-document-revision-runtime-404.md b/.doc/audit/2026-09-13-document-revision-runtime-404.md new file mode 100644 index 00000000..6a738017 --- /dev/null +++ b/.doc/audit/2026-09-13-document-revision-runtime-404.md @@ -0,0 +1,108 @@ +--- +title: "文档版本账本运行时 404 与修订链路失效现场审计" +status: in_progress +created: 2026-09-13 +updated: 2026-09-13 +severity: critical +--- + +# 文档版本账本运行时 404 与修订链路失效现场审计 + +## 现象 + +登录项目对话后: + +1. `GET /api/v1/documents/doc-upload-1789263145197-0/revision-state` → **404**,body 含 `docrevision: not found` +2. `GET /api/v1/documents/doc_proj143_srs/revision-state` → **404**(同错误) +3. UI 工具条显示「版本账本未就绪:docrevision: not found」 +4. 块双击编辑保存无效(或仅改本地 AST) +5. 纯净阅读 / 人工修改 / 全部变更切换无可视效果 +6. 未重跑智能体小队时看不到变更摘要、风险、项目/文档影响(预期);但即便重跑,当前接线也会写入**静态假 JSON** 而非真实 diff/报告 + +## 根因分析(证据) + +### R1 — 账本仅进程内 map,PostgreSQL schema 未真正读写(主因) + +`internal/docrevision/service.go` 中 `Service` 虽接收 `*pgxpool.Pool`,但全部状态存在: + +- `blobs` / `snapshots` / `versions` / `events` / `candidates` / `reports` / `roots` / `idemp` + +`GetRevisionState` 仅查内存 `s.roots[docID]`;无 hydrate、无 INSERT/SELECT。 +Goose `00028` 已建表且 CURRENT 记录 schema 28 healthy,但**运行态账本与 PG 脱节**。 + +**后果**:服务重启 / 多副本 / 冷启动后一律 404;backfill CLI 亦 `NewService(nil)`,apply 不落库。 + +### R2 — GET revision-state 无确定性 bootstrap + +账本仅在以下路径创建: + +- `OpenTemplateVersion`(PATCH 时 DocGov 命中且先前 404;或 bizdev 首次 agent 成功) +- `CommitHumanRevision` + `AllowCreateBaseline` +- freeform `syncLedgerLocked`(仅走 freeform 保存 API 时) + +首次打开文档只读 GET **不会**从 `document_records` / `freeform_documents` / `output.md` 回填 → 老文档与上传文档稳定 404。 + +### R3 — 上传文档与受控文档解析/权限边界未统一 + +- `doc-upload-*`:前端本地 `deliverables` + IndexedDB,**未**强制经 freeform API 落库;`governanceMode: freeform` +- `doc_proj143_srs`:受控 DocGov 记录存在,但无 ledger 指针/内存根 +- Handler `handleDocRevisionState` 仅 `requirePrincipal`,未走 DocumentAccess / 项目成员校验,也未按 kind 解析事实源 + +### R4 — 人工块保存未更新用户所见事实源 + +`web/src/App.tsx` `handleSaveBlockEdit`: + +```ts +if (!target || target.governanceMode === 'freeform') { + return; // 上传/自由文档直接跳过 PATCH +} +``` + +受控路径虽调 PATCH,但: + +- `ProjectOutputMarkdown(docID, ".")` 工作目录相对路径易错; +- 成功后仅 `MarkDocumentContentUpdated` 哈希,重启后内存账本仍丢; +- GET 404 时工具条已坏,overlay 无数据。 + +### R5 — Overlay 三模式未接到块渲染 + +- `DocumentRevisionToolbar` 在 state=null 时仍可切换 select,但 `onOverlay(null)` +- `ManualChangeOverlay` 仅为提示文案,不装饰块 +- `BlockRenderer` 无 `overlayHunks` / 模式 props;App 仅在工具条下显示「人工差异 N 处」统计条 + +### R6 — Agent/Squad → change report 使用静态假数据 + +`internal/bizdev/service.go` 硬编码: + +```go +reportJSON := `{"schema_version":1,"summary":["智能体交付物已生成"],...}` +``` + +违反「不可伪造」要求。确定性层(真实 hunk、rule risk、lineage impact)已有 `RuleRiskFloor` / `ImpactFromLineage` / `ValidateChangeReportJSON`,但调用方未喂真实 diff 摘要;智能体叙事层尚未接 PI 生成 → 须标 **不可伪造 blocker**(叙事)同时交付确定性报告。 + +## 严重度 + +`critical` — 版本账本对用户表现为全面不可用;保存与差异认知失效;假报告有审计污染风险。 + +## 关联整改 + +- Remediation: [../remediation/2026-09-13-document-revision-runtime-remediation.md](../remediation/2026-09-13-document-revision-runtime-remediation.md) +- Short-term: [../ops/short-term/2026-09-13-document-revision-runtime.md](../ops/short-term/2026-09-13-document-revision-runtime.md) +- 前置设计: [../system-design/document-revision-management.md](../system-design/document-revision-management.md) +- 前置 ADR: [../adr/2026-09-13-document-version-boundary.md](../adr/2026-09-13-document-version-boundary.md) + +## 证据 + +| 项 | 路径 | +|----|------| +| 内存账本 | `internal/docrevision/service.go` `NewService` / `GetRevisionState` | +| PG schema 未接线 | `deploy/postgres/goose/00028_2026-09-13-document-revisions.sql` | +| GET 无 bootstrap | `internal/server/document_revision_handlers.go` `handleDocRevisionState` | +| freeform 跳过保存 | `web/src/App.tsx` `handleSaveBlockEdit` | +| 静态 report | `internal/bizdev/service.go` CreateAgentCandidate `ReportJSON` | +| Overlay 空壳 | `web/src/components/doc/ManualChangeOverlay.tsx` | + +## 开放问题 + +1. 纯客户端上传且从未调用 freeform create 的文档:服务端无正文事实源 → bootstrap 需 PATCH/显式注册,或返回可操作的 empty/register 状态(禁止静默假账本)。 +2. PI Agent 叙事变更报告(业务含义、开放问题文案)需独立调用链;本轮以确定性 fallback 报告上线,叙事标 blocker。 diff --git a/.doc/audit/INDEX.md b/.doc/audit/INDEX.md index 174b6322..82408b1f 100644 --- a/.doc/audit/INDEX.md +++ b/.doc/audit/INDEX.md @@ -13,6 +13,14 @@ ## 核心文档(按阅读顺序推荐) +### 文档版本账本运行时失效(2026-09-13) + +**文件**: [2026-09-13-document-revision-runtime-404.md](./2026-09-13-document-revision-runtime-404.md) + +**结论**: Wave0–6 合入后现场仍 404——账本仅内存、GET 无 bootstrap、freeform 跳过 PATCH、overlay 未装饰、agent 报告为静态假 JSON。 + +**整改**: [运行时整改方案](../remediation/2026-09-13-document-revision-runtime-remediation.md) · [short-term](../ops/short-term/2026-09-13-document-revision-runtime.md) + ### 文档修改与智能体版本专项分析(2026-09-13) **文件**: [2026-09-13-document-revision-management-gap-analysis.md](./2026-09-13-document-revision-management-gap-analysis.md) diff --git a/.doc/ops/CURRENT.md b/.doc/ops/CURRENT.md index fe5ea673..96866dda 100644 --- a/.doc/ops/CURRENT.md +++ b/.doc/ops/CURRENT.md @@ -1,11 +1,11 @@ # 当前焦点 **更新**: 2026-09-13 -**production_ready**: no(只读文档总结已通过真实 PI;刷新/双标签页 busy 浏览器 E2E 待补录;DOCREV 待合 dev) +**production_ready**: no(DOCREV 运行时账本未持久化导致现场 404;CHAT/INTENT 并行中) ## 焦点 -1. **DOCREV**: feature 分支 Wave0–6 及前端鉴权修复已合入 `dev`;migrate 00028 生效,dev 重建并通过冒烟验证;真实 PI/Playwright 补录中 +1. **DOCREV-RT**: [运行时 404/保存/overlay 整改](short-term/2026-09-13-document-revision-runtime.md)(`fix/document-revision-runtime`;不占集成槽) 2. **CHAT**: [刷新恢复整改已实施](short-term/2026-09-13-chat-history-refresh-remediation.md)(待合 dev + PI E2E 补录) 3. **CI**: `TEST_DATABASE_URL` + 真实 PI E2E 实录;INTENT 发布 blocker 见 conversation-intent short-term @@ -16,6 +16,7 @@ | Cursor | chat-history-refresh-remediation | fix/chat-history-refresh | - | chat | in_progress | | Codex | conversation-intent-runtime-state | fix/conversation-intent-state | .worktrees/fix-conversation-intent-state | intent | in_progress | | Cursor | document-revision-wave1-6-implementation | feature/document-revision-management | - | docgov | done | +| Cursor-Auto | document-revision-runtime | fix/document-revision-runtime | - | docgov | in_progress | > 新任务开始前登记。`branch` 必须为 `feature/` 或 `fix/`,**禁止** `dev` / `test` / `main`。同一 `mutex` 同时仅一个 `in_progress`。 diff --git a/.doc/ops/short-term/2026-09-13-document-revision-runtime.md b/.doc/ops/short-term/2026-09-13-document-revision-runtime.md new file mode 100644 index 00000000..01a81193 --- /dev/null +++ b/.doc/ops/short-term/2026-09-13-document-revision-runtime.md @@ -0,0 +1,55 @@ +--- +title: "文档版本账本运行时整改" +status: in_progress +created: 2026-09-13 +updated: 2026-09-13 +owner: Cursor-Auto +branch: fix/document-revision-runtime +worktree: "-" +mutex: docgov +--- + +# 文档版本账本运行时整改 + +## 目标 + +消除 revision-state 404、重启丢账本、人工保存无效、overlay 无效,并接通确定性 change report;停在 fix 分支待集成。 + +## 范围 + +- `internal/docrevision` PG hydrate/persist + bootstrap +- `internal/server/document_revision_handlers.go` 授权与事实源 +- `internal/bizdev` agent candidate 确定性报告 +- `cmd/document-revision-backfill` 接真实 pool +- `web` 保存链路与 overlay 三模式 +- 工程测试 + UI 验收计划(分栏) + +## 非目标 + +- 不占 CURRENT 集成槽、不 `env-service rebuild`、不 push +- 不伪造 PI 叙事 change report +- 不把 stub 输出写入最终用户验收报告 + +## 步骤 + +1. [x] 审计 / 整改 / 本任务 + CURRENT 认领 +2. [ ] 分支 `fix/document-revision-runtime` +3. [ ] PG store + bootstrap + backfill +4. [ ] Handler / agent / 前端 +5. [ ] 测试与 UI 计划 +6. [ ] 分层 commit,输出哈希与集成建议 + +## 验收标准 + +- [ ] 工程门禁(单测/vet/前端 build)与 UI 实战计划分栏标识完成 +- [ ] 剩余 blocker(PI 叙事、orphan upload)写清且不可用假数据掩盖 + +## 相关链接 + +- Audit: [../../audit/2026-09-13-document-revision-runtime-404.md](../../audit/2026-09-13-document-revision-runtime-404.md) +- Remediation: [../../remediation/2026-09-13-document-revision-runtime-remediation.md](../../remediation/2026-09-13-document-revision-runtime-remediation.md) +- Checklist/UI: [../checklists/2026-09-13-document-revision-runtime-ui-acceptance.md](../checklists/2026-09-13-document-revision-runtime-ui-acceptance.md) + +## 证据 / 备注 + +(提交后回填 commit hashes) diff --git a/.doc/remediation/2026-09-13-document-revision-runtime-remediation.md b/.doc/remediation/2026-09-13-document-revision-runtime-remediation.md new file mode 100644 index 00000000..0a55dc9b --- /dev/null +++ b/.doc/remediation/2026-09-13-document-revision-runtime-remediation.md @@ -0,0 +1,55 @@ +--- +title: "文档版本账本运行时持久化与修订链路整改" +status: in_progress +created: 2026-09-13 +updated: 2026-09-13 +--- + +# 文档版本账本运行时持久化与修订链路整改 + +## 背景 + +现场审计:[../audit/2026-09-13-document-revision-runtime-404.md](../audit/2026-09-13-document-revision-runtime-404.md) + +Wave0–6 已合入 `dev` 并完成 schema 00028,但 ledger **未持久化**、GET **无 bootstrap**、前端 freeform **跳过 PATCH**、overlay **未装饰**、agent report **静态假数据**,导致生产可见能力全面失效。 + +## 目标 + +1. PostgreSQL 为账本事实源;进程重启后 revision-state / versions / overlay / reports 可恢复 +2. 首次访问对已有受控/自由文档确定性 bootstrap;旧数据可 backfill +3. 统一受控与上传/自由文档的解析与授权边界;PATCH 更新用户所见事实源且刷新可恢复 +4. Agent/squad 提交写入 immutable snapshot + **确定性** change report(摘要/风险/影响来自 diff+lineage);禁止静态假 JSON +5. 工程单测/门禁与「仅浏览器 UI 实战验收」计划分离标识 + +## 分波次计划 + +| 波次 | 内容 | 验收 | +|------|------|------| +| W0 | audit/remediation/short-term + CURRENT 认领 `docgov` + 分支 `fix/document-revision-runtime` | 文档与认领无冲突 | +| W1 | PG store:blob/snapshot/version/event/candidate/report + 根指针投影;hydrate on read;mutate 事务写入 | 单测:写入→新 Service 实例可读;并发冲突 | +| W2 | `EnsureBootstrap`:controlled(output.md)/freeform(content)/orphan(需正文);GET revision-state 触发;backfill CLI 接 pool | 旧 doc_id 首次 GET 200;空正文清晰 empty/404 | +| W3 | Handler:项目/文档授权;PATCH 写 workDir 或 freeform 正文;错误码与空状态 | 授权负例 403;保存后刷新可见 | +| W4 | Agent 接线:`BuildDeterministicChangeReport` + lineage impacts;去掉静态假 JSON;叙事 PI 标 blocker | 报告 AnalysisFallback/Complete 均可追溯 facts | +| W5 | 前端:freeform/upload 走 PATCH;overlay 三模式装饰 BlockRenderer;清晰未就绪/空状态 | 组件/契约测 | +| W6 | 工程门禁 + Ubuntu 无头浏览器 UI 验收计划(与单测分离) | 计划文档落盘;本轮不占 docker 槽 | + +## 不可伪造 Blocker(明确写出) + +| ID | 内容 | 为何本轮不能安全伪造完成 | 本轮替代 | +|----|------|--------------------------|----------| +| DOCREV-RT-PI-NARRATIVE | 由真实 PI/MiniMax 生成的业务叙事摘要、开放问题措辞、风险业务解释 | 需占集成槽 + 真实 runner + 提示词契约 E2E;本轮禁止 docker rebuild | 确定性报告:`summary` 来自 hunk 统计与标题路径,`risk`=`RuleRiskFloor`,`document_impacts`=lineage,`analysis_status=fallback` | +| DOCREV-RT-UPLOAD-ORPHAN | 从未调用服务端 freeform create、仅 IndexedDB 存在的上传附件二进制预览 | 服务端无 Markdown 事实源,不能凭空造 ledger | GET 返回明确 `DOCUMENT_REVISION_NEEDS_CONTENT` / 引导首次 PATCH 注册;禁止静默假 V1 | + +## 验收标准 + +- [ ] `go vet ./...` 与 `go test -short ./internal/docrevision/...`(含旧数据/重启语义/并发/授权契约)PASS +- [ ] 前端相关 vitest + `npm run build` PASS +- [ ] 代码停在 `fix/document-revision-runtime`,**不**占集成槽、不 rebuild docker、不 push +- [ ] UI 实战计划文档已写,与工程门禁分栏标识 + +## 相关链接 + +- Audit: [../audit/2026-09-13-document-revision-runtime-404.md](../audit/2026-09-13-document-revision-runtime-404.md) +- Short-term: [../ops/short-term/2026-09-13-document-revision-runtime.md](../ops/short-term/2026-09-13-document-revision-runtime.md) +- gap-matrix 行: `DOCREV-RUNTIME-404` +- UI 计划: [../ops/checklists/2026-09-13-document-revision-runtime-ui-acceptance.md](../ops/checklists/2026-09-13-document-revision-runtime-ui-acceptance.md) diff --git a/.doc/remediation/INDEX.md b/.doc/remediation/INDEX.md index 43a566f4..56cba23f 100644 --- a/.doc/remediation/INDEX.md +++ b/.doc/remediation/INDEX.md @@ -3,6 +3,7 @@ | 文档 | 说明 | |------|------| | [gap-matrix.md](./gap-matrix.md) | 发布缺口 SSOT | +| [2026-09-13-document-revision-runtime-remediation.md](./2026-09-13-document-revision-runtime-remediation.md) | 账本 PG 持久化、bootstrap、保存/overlay/确定性 change report | | [2026-09-13-document-revision-management-implementation-plan.md](./2026-09-13-document-revision-management-implementation-plan.md) | 智能体版本、人工修订、差异认知与负责人通知 | | [2026-09-13-conversation-intent-runtime-state-remediation.md](./2026-09-13-conversation-intent-runtime-state-remediation.md) | 对话写意图、刷新可恢复任务状态、文档占用可见性与诊断隔离 | | [2026-09-13-chat-history-refresh-remediation.md](./2026-09-13-chat-history-refresh-remediation.md) | 对话刷新恢复、消息作用域与授权统计一致性 | diff --git a/.doc/remediation/gap-matrix.md b/.doc/remediation/gap-matrix.md index 84bb9eb7..11157429 100644 --- a/.doc/remediation/gap-matrix.md +++ b/.doc/remediation/gap-matrix.md @@ -60,6 +60,7 @@ | CHAT-HISTORY-REFRESH | 工作流激活后刷新,对话正文被阶段过滤器清空,但分类数量与锚点仍按全量返回 | **PASS** | [test-report](../test-reports/2026-09-13-chat-history-refresh-test-report.md);代码:`message_scope.go`、`chat_history_auth.go`、goose 00026/00027 | 真实 PI 刷新 E2E 待 dev 容器补录(自动化/PG 已 PASS) | | CHAT-INTENT-STATE | 真实会话被诊断探针污染;只读查询误启动文档写任务;错误动作与编辑状态刷新后丢失 | **FAIL** | [audit](../audit/2026-09-13-conversation-intent-runtime-state.md);dev `sess-p143-u9` / task run / lease 现场 | [remediation](./2026-09-13-conversation-intent-runtime-state-remediation.md) | | ENV-RESTART-SOURCE | `docker compose restart` 只重启旧镜像,健康检查无法证明合入代码已部署 | **PASS** | `env-service.sh rebuild` + 真实摘要重测 | 集成冒烟统一使用 `dev rebuild` | +| DOCREV-RUNTIME-404 | revision-state 404;账本内存丢失;块保存/overlay 无效;agent 假报告 | **FAIL** | [audit](../audit/2026-09-13-document-revision-runtime-404.md);`internal/docrevision/service.go` 仅 map | [remediation](./2026-09-13-document-revision-runtime-remediation.md) | --- diff --git a/.doc/status/FEATURE-MATRIX.md b/.doc/status/FEATURE-MATRIX.md index 9c48c37d..48e6b550 100644 --- a/.doc/status/FEATURE-MATRIX.md +++ b/.doc/status/FEATURE-MATRIX.md @@ -21,7 +21,7 @@ | 工作流治理 | 三正式工作流 + 阶段门禁 | done | [remediation/three-workflows](../remediation/2026-09-12-three-workflows-strict-governance-remediation.md);[test 2026-09-12](../test-reports/2026-09-12-three-workflows-governance-remediation-test-report.md) | Phase2 设计器 partial | `workflow` | | IAM / 鉴权 | 项目级 API 鉴权 + RBAC | partial | [audit/authorization](../audit/authorization-matrix-v2.md);[刷新恢复专项审计](../audit/2026-09-13-chat-history-refresh-disappears.md) | 历史读取端点补统一会话 owner + 阶段授权;旧 API 410 标注(BUG-11 partial) | `authz` | | 文档治理 | 法定文档生命周期 + 租约 | done | [test docgov](../test-reports/2026-09-08-docgov-lifecycle-and-claiming-framework-test-report.md) | — | `docgov` | -| 文档版本与修改认知 | 智能体版本边界、人工修订标记、任意版本比较、变更报告与负责人通知 | partial | [test 2026-09-13](../test-reports/2026-09-13-document-revision-management-test-report.md);[ADR](../adr/2026-09-13-document-version-boundary.md);[实施方案](../remediation/2026-09-13-document-revision-management-implementation-plan.md) | feature 分支已交付 Wave0–6 代码;真实 PI / 双用户 Playwright / 00028 容器 migrate 待占集成槽位 | `docgov` | +| 文档版本与修改认知 | 智能体版本边界、人工修订标记、任意版本比较、变更报告与负责人通知 | partial | [test 2026-09-13](../test-reports/2026-09-13-document-revision-management-test-report.md);[运行时审计](../audit/2026-09-13-document-revision-runtime-404.md);[ADR](../adr/2026-09-13-document-version-boundary.md) | **运行时 blocker**:PG 未接线→404/重启丢失;overlay/freeform 保存缺口;PI 叙事报告待集成;见 [runtime remediation](../remediation/2026-09-13-document-revision-runtime-remediation.md) | `docgov` | | 前端工作台 | 三栏 + 块文档 + SSE | partial | [test workbench](../test-reports/2026-09-08-three-column-workbench-and-block-document-test-report.md);[现场专项审计](../audit/2026-09-13-conversation-intent-runtime-state.md) | 错误卡片/任务进度/文档 busy 状态刷新恢复与人工抽检待完成 | `web` | | PI Runner / 配置链 | pi-agent + MiniMax 真实链路 | done | [test piagent](../test-reports/2026-09-13-codex-audit-p0-remediation-test-report.md);[container-env](../test-reports/2026-09-13-container-env-configuration-test-report.md) | — | `pi-agent` | | 三环境运维 | dev/test/main + 共享 KB | done | [PROJECT.md](../../PROJECT.md) §4;四环境 healthy | — | `infra` |