diff --git a/.doc/ops/CURRENT.md b/.doc/ops/CURRENT.md index 836387b5..2f603379 100644 --- a/.doc/ops/CURRENT.md +++ b/.doc/ops/CURRENT.md @@ -5,7 +5,7 @@ ## 焦点 -1. **DOC-RELIABILITY**: [文档可靠性纵向试点 M0–M1](../ops/short-term/2026-09-14-document-reliability-pilot.md)(`refactor/document-reliability-pilot`;`mutex=docgov`;不占集成槽、不 rebuild) +1. **DOC-RELIABILITY**: [文档可靠性纵向试点 M0–M1](../ops/short-term/2026-09-14-document-reliability-pilot.md)(`refactor/document-reliability-pilot`;`mutex=docgov`;M1 报告 **停止扩面**;不占槽、不 rebuild、不开 U5–U12) 2. **CHAT-INTENT**: [对话意图运行时状态](../audit/2026-09-13-conversation-intent-runtime-state.md)(`fix/conversation-intent-state`;与文档账本运行时无关) 3. **CHAT**: [对话历史刷新](../audit/2026-09-13-chat-history-refresh-disappears.md)(认领仍 `in_progress`;gap 行已 PASS,以代码/handoff 为准收敛) @@ -13,7 +13,7 @@ | owner | task | branch | worktree | mutex | status | |-------|------|--------|----------|-------|--------| -| Cursor | document-reliability-pilot | refactor/document-reliability-pilot | .worktrees/refactor-document-reliability-pilot | docgov | in_progress | +| Cursor | document-reliability-pilot | refactor/document-reliability-pilot | .worktrees/refactor-document-reliability-pilot | docgov | blocked | | Codex | module-decoupling-remediation-plan | feature/module-decoupling-remediation | .worktrees/feature/module-decoupling-remediation | architecture-docs | done | | verifier_antigravity | controlled-content-ui-acceptance | fix/controlled-content-ui-acceptance | .worktrees/fix-controlled-content-ui-acceptance | document-content-ui-acceptance | done | | implementer_cursor | controlled-content-canonical-hash | fix/controlled-content-canonical-hash | .worktrees/fix-controlled-content-canonical-hash | docgov | done | @@ -54,7 +54,7 @@ > 新任务开始前登记。`branch` 必须为 `feature/` 或 `fix/`,**禁止** `dev` / `test` / `main`。同一 `mutex` 同时仅一个 `in_progress`。 > workflow-plan 409 与治理鉴权 G1–G5 已收口(见 [test-report](../test-reports/2026-09-14-governance-action-level-authz-test-report.md))。禁止终止或改写项目 143。 -> `document-reliability-pilot` 仅占 `docgov` 编码;合 `dev` + `env-service rebuild` 必须另占集成槽位。M1 报告未签字前不得 rebuild。 +> `document-reliability-pilot` 仅占 `docgov` 编码;合 `dev` + `env-service rebuild` 必须另占集成槽位。M1 结论为 **停止扩面**(见 [test-report](../test-reports/2026-09-14-document-reliability-pilot-test-report.md)),不得 rebuild,不得开工 U5–U12。 ## 集成槽位 diff --git a/.doc/ops/checklists/2026-09-14-module-decoupling-refactor-acceptance.md b/.doc/ops/checklists/2026-09-14-module-decoupling-refactor-acceptance.md index 38f408e0..a9b9b044 100644 --- a/.doc/ops/checklists/2026-09-14-module-decoupling-refactor-acceptance.md +++ b/.doc/ops/checklists/2026-09-14-module-decoupling-refactor-acceptance.md @@ -1,28 +1,28 @@ --- title: "模块解耦重构验收清单" -status: planned +status: in_progress created: 2026-09-14 updated: 2026-09-14 -owner: TBD +owner: Cursor --- # 模块解耦重构验收清单 ## M0 架构与基线 -- [ ] contracts 分类、事务 owner、表属主、锁顺序、事件信封、Principal 和 FAV 边界均有唯一规范来源。 -- [ ] arch-check 分离 production import、SQL write、path 和 event registration;例外有 owner 与到期日。 -- [ ] 当前违规基线可重复生成,新违规立即阻断。 +- [x] contracts 分类、事务 owner、表属主、锁顺序、事件信封、Principal 和 FAV 边界均有唯一规范来源。 +- [x] arch-check 分离 production import、SQL write、path 和 event registration;例外有 owner 与到期日。 +- [x] 当前违规基线可重复生成,新违规立即阻断。 ## M1 文档可靠性 -- [ ] 人工编辑、agent commit、approve/reject 的跨表写入同事务。 -- [ ] fault injection 任一点失败均无部分提交。 -- [ ] 同 ETag 并发写只有一个赢家;不同文档不被全局锁串行。 +- [x] 人工编辑、agent commit、approve/reject 的跨表写入同事务(U3;隔离库双会话编辑已测)。 +- [x] fault injection 任一点失败均无部分提交(U2 隔离库)。 +- [x] 同 ETag 并发写只有一个赢家(内存 + 双会话)。 - [ ] 1、2、4 app replicas 结果一致。 -- [ ] GET/refresh/reload 零写入,projection 缺失不伪装成 404。 +- [x] GET 服务端零写入 + typed consistency(U4 单测)。refresh/reload 真页面未测。 - [ ] 项目 143 等价 hazard 与新项目真实页面刷新、重登、restart、rebuild PASS。 -- [ ] 匿名、非成员、跨用户、跨项目、错误 stage/duty、授权失败负例 PASS。 +- [x] 服务端负例 fail closed;浏览器跨用户未测。 ## M2 事件与 FAV @@ -57,14 +57,14 @@ owner: TBD ## 证据分层 -- [ ] Unit/stub 证据。 -- [ ] PostgreSQL integration 证据。 -- [ ] race/concurrency/load 证据。 -- [ ] fault injection/crash 证据。 +- [x] Unit/stub 证据。 +- [x] PostgreSQL integration 证据(隔离库,非共享 env 库)。 +- [x] race/concurrency 目标包证据(非全仓 race)。 +- [x] fault injection 证据(U2)。 - [ ] 真实 PI 证据。 - [ ] 真实浏览器证据。 - [ ] restart/rebuild 证据。 -- [ ] cross-user/project authorization negative 证据。 +- [x] cross-user/project authorization negative 服务端证据。 - [ ] scratch recovery 与完整 DB restore 证据。 ## 关闭条件 diff --git a/.doc/ops/short-term/2026-09-14-document-reliability-pilot.md b/.doc/ops/short-term/2026-09-14-document-reliability-pilot.md index 0e4b66e8..669eff20 100644 --- a/.doc/ops/short-term/2026-09-14-document-reliability-pilot.md +++ b/.doc/ops/short-term/2026-09-14-document-reliability-pilot.md @@ -1,6 +1,6 @@ --- title: "文档可靠性纵向试点 M0–M1" -status: in_progress +status: blocked created: 2026-09-14 updated: 2026-09-14 owner: Cursor @@ -37,25 +37,28 @@ mutex: docgov 3. [x] 实现 U2,验证任意属主写入/commit 故障整体回滚。 4. [x] 实现 U3,删除提交后 outbox 正确性回调。 5. [x] 实现 U4,保证 GET 零写入和 projection 缺失不再伪装成 404。 -6. [ ] 执行多实例并发、PG、真实 PI、真实浏览器和 restart/rebuild 验收。 -7. [ ] 写 test report,更新验收清单、FEATURE-MATRIX、CURRENT 和 gap-matrix。 +6. [x] 隔离库 PG + 目标包 race 已跑;真实 PI / 浏览器 / rebuild **未**签字(未占槽)。 +7. [x] 写 test report:结论 **停止扩面**。更新验收清单、FEATURE-MATRIX、CURRENT 和 gap-matrix。 ## 验收标准 -- [ ] 同一 ETag 并发编辑只有一个合法赢家,账本/head/outbox 无孤儿。 -- [ ] 任一事务故障点不会留下部分提交。 -- [ ] 项目 143 等价 hazard 和新项目刷新/重启目标 404/409/projection missing 为 0。 -- [ ] 匿名、非成员、跨用户、跨项目、错误 stage/duty 和授权依赖失败均 fail closed。 -- [ ] 1、2、4 个 app 实例的最终状态一致。 -- [ ] M1 test report 给出继续 M2 或停止扩面的明确结论。 +- [x] 同一 ETag 并发编辑只有一个合法赢家(内存 8 协程 + 隔离库双会话)。 +- [x] 任一事务故障点不会留下部分提交(U2 隔离库)。 +- [ ] 项目 143 等价 hazard 和新项目刷新/重启目标 404/409/projection missing 为 0(真实页面未测)。 +- [x] 服务端匿名/未知文档/跨项目/错误责任人 fail closed;浏览器跨登录未测。 +- [ ] 1、2、4 个 app 实例的最终状态一致(仅到双会话)。 +- [x] M1 test report 结论:**停止扩面**。 ## 相关链接 - Checklist: [../checklists/2026-09-14-module-decoupling-refactor-acceptance.md](../checklists/2026-09-14-module-decoupling-refactor-acceptance.md) -- Handoff: 实施时创建 -- Test report: 实施后创建 `.doc/test-reports/-document-reliability-pilot.md` +- Test report: [../../test-reports/2026-09-14-document-reliability-pilot-test-report.md](../../test-reports/2026-09-14-document-reliability-pilot-test-report.md) - Plan: [../../remediation/2026-09-14-module-decoupling-refactor-plan.md](../../remediation/2026-09-14-module-decoupling-refactor-plan.md) +## M2+ 门(不开工) + +U5 WorkspaceRef、U6 outbox、U7 按文件摘 FAV 需要独立审批,且仅当 M1 报告最后一句为「继续 M2」。当前是「停止扩面」,禁止实现 U5–U12。 + ## 证据 / 备注 -只有本任务真实验收通过后,才允许启动 durable event/FAV 与横向模块扩展。 +隔离库与目标包 race 见 test-report assets。未占槽、未 rebuild。只有真实 PI/浏览器/rebuild 补测并把报告改为「继续 M2」后,才允许启动 durable event/FAV。 diff --git a/.doc/remediation/gap-matrix.md b/.doc/remediation/gap-matrix.md index f9f37351..e4d19fd7 100644 --- a/.doc/remediation/gap-matrix.md +++ b/.doc/remediation/gap-matrix.md @@ -70,7 +70,7 @@ | DOCREV-ACTIVE-DOC-ROUTING | UI-05「当前受控文档」被法规关键词改路由到 `feasibility_reg`,intake 无 pending | **PASS** | [audit](../audit/2026-09-13-document-revision-active-doc-routing.md);Round20 UI-05 pending 停在 intake V2 | **不改弱 E2E**;不删证据 | | DOCREV-QUALITY-STATUS-FP | 行动计划表状态列「待续」被门禁当敷衍,两轮 repair 后 quality_failed 80 | **PASS** | [audit](../audit/2026-09-13-document-revision-quality-status-false-positive.md);Round20 UI-03 | **不删禁词、不放宽正文**;不删证据 | | GOVERNANCE-ACTION-AUTHZ | 文档动作按职责鉴权;未激活 202-blocked;关闭创建直通 | **PASS** | [test-report](../test-reports/2026-09-14-governance-action-level-authz-test-report.md);[audit 异态](../audit/2026-09-14-planning-with-workflow-key-anomaly.md) | 不改 83 条 planning+key 夹具;none 长 PI 审批链另开 | -| DOC-RELIABILITY-PILOT | 受控文档写路径跨表非同事务、读路径被 projection 绑架、授权 TOCTOU;刷新/重启后可能 404/409/projection-missing | OPEN | [复核](../audit/2026-09-14-module-decoupling-plan-review.md);[重构计划](./2026-09-14-module-decoupling-refactor-plan.md);[试点任务](../ops/short-term/2026-09-14-document-reliability-pilot.md) | M0–M1=U1–U4;未占槽不得 rebuild;M2+ 需独立 go/no-go | +| DOC-RELIABILITY-PILOT | 受控文档写路径跨表非同事务、读路径被 projection 绑架、授权 TOCTOU;刷新/重启后可能 404/409/projection-missing | OPEN | [复核](../audit/2026-09-14-module-decoupling-plan-review.md);[重构计划](./2026-09-14-module-decoupling-refactor-plan.md);[试点任务](../ops/short-term/2026-09-14-document-reliability-pilot.md);[M1 报告](../test-reports/2026-09-14-document-reliability-pilot-test-report.md) | U1–U4 已编码。M1 **停止扩面**(无真实 PI/浏览器/rebuild)。未占槽不得 rebuild;禁止 U5–U12 | --- diff --git a/.doc/status/FEATURE-MATRIX.md b/.doc/status/FEATURE-MATRIX.md index abec2c5f..7b018a68 100644 --- a/.doc/status/FEATURE-MATRIX.md +++ b/.doc/status/FEATURE-MATRIX.md @@ -27,7 +27,7 @@ | 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` | | CI / E2E | PG 集成 + 真实 PI E2E | partial | [gap-matrix BUG-08](../remediation/gap-matrix.md);[test pg-ci](../test-reports/2026-09-12-pg-ci-soak-e2e-test-report.md);[运行时 UI Round20](../test-reports/2026-09-14-document-revision-runtime-ui-test-report.md) | CI `TEST_DATABASE_URL` 隔离库仍缺;文档运行时真实 UI 已按 UI_PHASE 分文件且 post-restart 断言最终 A1 正文。`-race` 全包并行 TempDir flake 为基建残留 | `ci` | -| 模块解耦与可靠事件 | 文档可靠性纵向试点、跨属主事务、多副本互斥、FAV 与选择性模块化 | planned | [架构](../system-design/2026-09-14-module-decoupling-architecture.md);[ADR](../adr/2026-09-14-modular-monolith-decoupling.md);[重构计划](../remediation/2026-09-14-module-decoupling-refactor-plan.md);[试点任务](../ops/short-term/2026-09-14-document-reliability-pilot.md) | 方案已入库。M0–M1=U1–U4 为首个批准范围;M2+ 需 M1 go/no-go | `docgov` | +| 模块解耦与可靠事件 | 文档可靠性纵向试点、跨属主事务、多副本互斥、FAV 与选择性模块化 | partial | [架构](../system-design/2026-09-14-module-decoupling-architecture.md);[ADR](../adr/2026-09-14-modular-monolith-decoupling.md);[重构计划](../remediation/2026-09-14-module-decoupling-refactor-plan.md);[试点任务](../ops/short-term/2026-09-14-document-reliability-pilot.md);[M1 报告](../test-reports/2026-09-14-document-reliability-pilot-test-report.md) | U1–U4 已在 `refactor/document-reliability-pilot` 落地(Unit/隔离库 PASS)。M1 **停止扩面**:真实 PI/浏览器/rebuild 未签。禁止 U5–U12 | `docgov` | --- diff --git a/.doc/test-reports/2026-09-14-document-reliability-pilot-test-report.md b/.doc/test-reports/2026-09-14-document-reliability-pilot-test-report.md new file mode 100644 index 00000000..c415715a --- /dev/null +++ b/.doc/test-reports/2026-09-14-document-reliability-pilot-test-report.md @@ -0,0 +1,132 @@ +# 文档可靠性纵向试点(M0–M1 / U1–U4)测试报告 + +## 一、 测试背景 (Background) + +受控文档写路径曾把账本、root pointer 与通知拆到提交后回调;读路径在 ledger 已存在时仍被 `InspectProjection` 绑架成 409。刷新、重登或 projection 缺失会被前端当成 404 再 hydrate。本轮只批准 M0–M1(U1–U4):门禁纠偏、UnitOfWork、文档命令同事务、授权后账本读。明确不授权 FAV 降级读、拆 chat/squad、占槽 rebuild。 + +## 二、 测试目标 (Test Objectives) + +- U1:四类生产规则可重放;新违规 block;Goose/`*_test.go` 不记生产写者债。 +- U2:跨属主同事务;第二属主/staging/commit 失败零残留;仅 `40001`/`40P01` 整事务重试。 +- U3:人工编辑 / agent commit / approve / reject 锁后重鉴权;同 ETag 一赢一输。 +- U4:projection missing/drift/empty 仍返回账本正文 + typed `consistency`;GET 零写入。 +- 分栏必须各自签字。未占集成槽不得把 `:8080` 旧镜像或 `docker compose restart` 写成 rebuild 证据。 + +## 三、 测试方案与环境 (Test Plan & Environment) + +| 项 | 值 | +|----|-----| +| OS | Linux 7.0.0-31-generic | +| Go | 1.27.1 | +| 分支 / worktree | `refactor/document-reliability-pilot` / `.worktrees/refactor-document-reliability-pilot` | +| 实现基线 | `dev@a8f9451` → `c754f77`(另含本报告前的 `fix(docflow)` 竞态修复) | +| Unit / stub | `go test -short ./...`(**未**设置 `TEST_DATABASE_URL`) | +| PostgreSQL | 隔离库 `agent_rel_itest`(`shuimu-system-pg-test:5434`),测完 `DROP DATABASE`;禁止 `agent_system_dev/test/main` | +| 目标包 race | `./internal/app/uow ./internal/app/docflow ./internal/docquery ./internal/archtest` | +| 前端 | `npx tsx --test src/lib/controlledDocHydrate.test.ts`(17 passed) | +| 真实 PI / 浏览器 / rebuild | **未执行**。集成槽 idle;CURRENT 禁止 M1 未签字 rebuild;`:8080` 仍是治理鉴权旧镜像,不能当本分支证据 | +| 证据 | `.doc/test-reports/assets/2026-09-14-document-reliability-pilot/` | + +## 四、 预期结果 (Expected Results) + +| 栏 | 期望 | +|----|------| +| Unit / stub | 全绿;arch-check `--mode warn` 过门;characterization 同 ETag 一赢、approve/reject 唯一终态 | +| PG 事务与并发 | U2 故障注入绿;同 ETag 双会话 HumanEdit 仅一赢;head revision=1 | +| 故障注入 | 第二属主失败 / staging 失败 / commit 失败零行;`40001` 整事务重跑一条结果 | +| 真实 PI | 本分支容器内真实 `pi-agent` 全链路。**本轮不做** | +| 真实浏览器 | 项目 143 等价 hazard + 新建项目打开/刷新/重登正文 100%,404/409/projection-missing=0。**本轮不做** | +| restart/rebuild | 占槽后 `env-service.sh dev rebuild`。**本轮不做** | +| 跨用户负例 | 匿名/未知文档/授权拒绝 → `docquery.ErrClosed`,不泄露存在性 | + +## 五、 实际测试结果与判定 (Actual Results & Evaluation) + +### 5.1 Unit / stub + +- **测试输入**: `go test -short ./...` +- **实际输出**: 38 个有测试包 `ok`,无 `FAIL`。摘录: + +``` +ok chat-agent-system/internal/app/docflow +ok chat-agent-system/internal/app/uow +ok chat-agent-system/internal/archtest +ok chat-agent-system/internal/docquery +ok chat-agent-system/internal/docrevision +ok chat-agent-system/internal/server 9.796s +``` + +- **评价判定**: **PASS** +- **性能与耗时**: `internal/server` 约 9.8s,其余亚秒到数秒。日志:`assets/2026-09-14-document-reliability-pilot/go-test-short.log` + +`./scripts/arch-check.sh --mode warn` → `arch-check warn: production gate passed`。`--mode block` 仍会因既有例外基线失败(U1 设计如此)。 + +### 5.2 PostgreSQL 事务与并发 + +- **测试输入**: 隔离库 `TEST_DATABASE_URL` → `./internal/app/uow`、`./internal/app/docflow`、`./internal/docquery`;`./internal/docrevision -run TestDocumentCommitConcurrencyPG` +- **实际输出**: + +``` +ok chat-agent-system/internal/app/uow 0.065s +ok chat-agent-system/internal/app/docflow 0.003s +ok chat-agent-system/internal/docquery 0.003s +ok chat-agent-system/internal/docrevision 0.024s +``` + +- **评价判定**: **PASS**(1–2 会话级)。**未**跑 4 个独立 app 进程。 +- **性能与耗时**: UoW 包 65ms;并发编辑 24ms。日志:`go-test-pg-race.log` + +### 5.3 故障注入 + +- **测试输入**: `internal/app/uow` PG 用例(第二属主失败、staging/outbox 失败、commit 失败、`40001` 重试、version/permission/digest 不重试) +- **实际输出**: `ok chat-agent-system/internal/app/uow 0.065s` +- **评价判定**: **PASS** +- **性能与耗时**: 与 5.2 同一次隔离库运行 + +### 5.4 真实 PI + +- **测试输入**: 未切本分支容器,未跑真实 `MiniMax-M2.7-highspeed` 编制链路 +- **实际输出**: 无 +- **评价判定**: **FAIL(未测)** — 禁止用 stub 冒充终态 +- **性能与耗时**: n/a + +### 5.5 真实浏览器 + +- **测试输入**: 未对项目 143 / 新建项目做本分支页面打开、刷新、重登 +- **实际输出**: 仅前端单测 17/17(`hydrate treats projection missing as ledger content, not 404`) +- **评价判定**: 单测 **PASS**;真实页面 **FAIL(未测)** +- **性能与耗时**: hydrate 套件 149ms + +### 5.6 restart / rebuild + +- **测试输入**: 未占集成槽,未执行 `./scripts/env-service.sh dev rebuild` +- **实际输出**: 无。`:8080` 仍为既有 dev 镜像(治理鉴权 G5),不得当作本分支部署证据 +- **评价判定**: **FAIL(未测)** +- **性能与耗时**: n/a + +### 5.7 跨用户负例 + +- **测试输入**: `TestGetFailClosed`(匿名、Authorize 拒绝、未知 doc_id);`TestReauthDeniesWrongAuthor`;`TestBatchGetLimitsAndCrossProject`(101 条 / 跨项目) +- **实际输出**: 均失败关闭;未知文档与拒绝同一 `ErrClosed` +- **评价判定**: 服务端单测 **PASS**。HTTP 跨登录浏览器负例 **未测** +- **性能与耗时**: 亚秒 + +## 六、 自动化测试套件汇总 (Test Suite Execution) + +| 命令 | 结果 | +|------|------| +| `go vet ./...` | PASS(U4 提交前) | +| `go test -short ./...` | PASS,38 ok | +| 隔离库 `go test ./internal/app/uow ./internal/app/docflow ./internal/docquery` | PASS | +| `go test ./internal/docrevision -run TestDocumentCommitConcurrencyPG` | PASS | +| `go test -race` 目标包 | PASS(修复 `Commands.Auth` 并发写入后) | +| `arch-check --mode warn` | PASS | +| `tsx --test controlledDocHydrate.test.ts` | 17 passed | +| 全仓 `go test`(带 `TEST_DATABASE_URL` 且无 `-short`) | 未作为本报告门禁;会把无关 workflow PG 和「5434=共享 test 口」拒绝用例搅在一起 | + +`-race` 初跑曾在 `run()` 里给共享 `Commands.Auth` 赋值,判定为数据竞争;已改为只读 `authorizer()`。 + +## 七、 测试结论与后续优化建议 (Conclusion & Next Steps) + +U1–U4 代码已在实现分支落地,Unit/stub、隔离库事务/故障注入、目标包 race 与前端 hydrate 单测通过。用户可感知的主修复(ledger-first GET)**没有**真实 PI、真实浏览器、restart/rebuild 签字;1/2/4 进程一致性只验证到双会话。按计划停走门,不得用「部分通过」打开 U5–U12。 + +停止扩面