docs(test): record document reliability M1 stop-the-line

Unit, isolated PostgreSQL, and target-package race passed, but real PI, browser, and rebuild were not signed, so the report concludes 停止扩面 and keeps U5–U12 closed.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
weichen
2026-09-14 14:11:26 +00:00
co-authored by Cursor
parent f0f57a0755
commit 9d6594a31c
6 changed files with 167 additions and 32 deletions
+3 -3
View File
@@ -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/<slug>` 或 `fix/<slug>`,**禁止** `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。
## 集成槽位
@@ -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 证据。
## 关闭条件
@@ -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/<date>-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。
+1 -1
View File
@@ -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 |
---
+1 -1
View File
@@ -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` |
---
@@ -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。
停止扩面