docs(ops): redline evidence batch without capability release
Record SWBOOT L1–L4 (no real repo write), FAV ObserveShadow gates and observation-window prerequisites, D7 Track E ID-only checklist, and stronger PI narrative fallback negatives while keeping all redline flags off.
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
---
|
||||
title: "D7 Track E ID-only 合规清单(无物理删除)"
|
||||
status: active
|
||||
created: 2026-09-22
|
||||
updated: 2026-09-22
|
||||
compliance: pending-compliance-signoff
|
||||
related_task: "ops/short-term/2026-09-22-redline-evidence.md"
|
||||
related_adr: "adr/2026-09-17-d7-chat-data-retention.md"
|
||||
---
|
||||
|
||||
# D7 Track E ID-only 合规清单
|
||||
|
||||
> 用途:在 D7 ADR 仍为 `pending-compliance-signoff` 期间,只做表面盘点与 ID-only 合规核对。**禁止**按 365/180/30 天执行物理删除或备份清除。本清单不是删除作业授权。
|
||||
|
||||
## 0. 硬约束
|
||||
|
||||
- [x] ADR 状态仍为 `pending-compliance-signoff`(见 [ADR](../../adr/2026-09-17-d7-chat-data-retention.md))
|
||||
- [x] 本轮零 `DELETE FROM chat_*`、零备份清除、零 retention 作业
|
||||
- [x] FEATURE-MATRIX「对话数据治理(D7)」保持 `deferred`(本批不改矩阵)
|
||||
- [ ] 合规签字或改数后,另开整改任务再勾选删除路径
|
||||
|
||||
## 1. 数据表面盘点(只读)
|
||||
|
||||
| ID | 表面 | 检查方法 | 期望 | 本批结果 |
|
||||
|----|------|----------|------|----------|
|
||||
| S1 | `chat_sessions` / `chat_messages` | 代码检索写路径;对照 W7 计数资产 | 有 `deleted_at` 列;无物理 DELETE 写者;无 soft-delete 写路径亦可接受(缺口属签字后整改) | PASS:`rg` 无 `DELETE FROM chat_*`;无 chat `SET deleted_at` 写者 |
|
||||
| S2 | `context_memory_chunks`(`chat_history`) | 对照 W7 盘点 | 派生副本随正文;无独立 retention 删 | PASS(静态);未跑共享 SQL |
|
||||
| S3 | `freeform_documents` | 已知 soft-delete UI | 与聊天独立周期;本轮不删 | PASS(不触碰) |
|
||||
| S4 | `event_envelopes.payload` | 对照 Track E / W7 keys | 无 `content` / 消息正文 | PASS(沿用 W7:`has_content=f`);本批未重连 PG |
|
||||
| S5 | `event_dead_letters` / attempts | 结构 / 既有盘点 | 仅 ID + reason / error_code | PASS(沿用 W7) |
|
||||
| S6 | 应用日志 | 规范 + 既有抽检 | 无 chat 正文;DSN 脱敏 | PASS(沿用 W7);本批未 `docker logs` |
|
||||
| S7 | `scripts/backup-system-db.sh` | 阅读脚本 | `pg_dump -Fc` 整库含明文;本轮不执行 | PASS:未执行 dump |
|
||||
| S8 | `data/*/workspaces` | 目录约定 | 非终态;无自动 30 天清理 | PASS(无作业) |
|
||||
| S9 | FAV / `final_artifacts` | consumer mode | 与聊天解耦;fav off | PASS:Register(fav) fail-closed |
|
||||
|
||||
证据基线:[W7 报告](../../test-reports/2026-09-17-w7-d7-inventory-test-report.md)、[盘点审计](../../audit/2026-09-17-d7-data-inventory.md)、[红线短文](../short-term/2026-09-22-redline-evidence.md)。
|
||||
|
||||
## 2. Track E ID-only 字段规则
|
||||
|
||||
日志 / DLQ / reconciliation / 对外 summary **仅允许**:
|
||||
|
||||
| 允许 | 禁止 |
|
||||
|------|------|
|
||||
| event_id / delivery_id / run_id / plan_id / project_id / doc_id | 消息 `content` / prompt 全文 |
|
||||
| digest / sha256 / summary_ref | 用户 PII 明文堆栈 |
|
||||
| typed error_code / allowlist 摘要键 | 未 allowlist 的 payload 整包 |
|
||||
| 状态枚举(pending/leased/…) | 备份文件路径中的密钥 |
|
||||
|
||||
核对动作:
|
||||
|
||||
- [x] `events.SanitizeSummary` / StaticContracts 方向:生产路径不以正文入 envelope(W7 已证 keys)
|
||||
- [x] 发现「已签字基线被违反」才写 gap-matrix;本批**未发现** → 不改 gap-matrix
|
||||
- [ ] 签字后:收紧 `taskrun.completed` 等额外 ID 字段 allowlist(follow-up,非 blocker)
|
||||
|
||||
## 3. 签字后才允许的整改(本清单不执行)
|
||||
|
||||
1. 聊天 soft-delete 写路径 → 观察窗 → 物理清理
|
||||
2. 同步清理 `context_memory_chunks` 中 `chat_history`
|
||||
3. 备份二次批准 + 精确 delete manifest(对齐 R22)
|
||||
4. 字段级加密选型(ADR 明确首期不做默认加密)
|
||||
|
||||
## 4. 完成定义(本批)
|
||||
|
||||
- [x] 表面表 S1–S9 有结论
|
||||
- [x] ID-only 规则成文
|
||||
- [x] 无物理删除证据
|
||||
- [x] ADR 仍 `pending-compliance-signoff`
|
||||
@@ -0,0 +1,139 @@
|
||||
---
|
||||
title: "红线证据批次(无能力放量)"
|
||||
task_id: "2026-09-22-redline-evidence"
|
||||
status: done
|
||||
created: 2026-09-22
|
||||
updated: 2026-09-22
|
||||
owner: Cursor
|
||||
task_type: research
|
||||
task_tier: multi_stage
|
||||
policy_revision: "agent-governance-2026-09-21-r1 @ local-dev 364ed7f1a3f0393ef77ec4623a9518116ed2cb87"
|
||||
branch: feature/redline-evidence-2026-09-22
|
||||
worktree: .worktrees/redline-evidence-2026-09-22
|
||||
base_dev_sha: "364ed7f1a3f0393ef77ec4623a9518116ed2cb87"
|
||||
write_scope:
|
||||
- ".doc/ops/short-term/"
|
||||
- ".doc/ops/checklists/"
|
||||
- ".doc/test-reports/"
|
||||
- "internal/docrevision/narrative_test.go"
|
||||
allowed_environments: []
|
||||
head_sha: ""
|
||||
mutex: "redline-evidence-docs"
|
||||
review_state: not_required
|
||||
integration_state: pending
|
||||
deployment: not_required
|
||||
cleanup: pending
|
||||
cleanup_owner: "独立维护者"
|
||||
cleanup_trigger: "合入 dev 且无进程占用后复查 remove"
|
||||
remote_sync: not_requested
|
||||
---
|
||||
|
||||
# 红线证据批次(无能力放量)
|
||||
|
||||
## 用户目标与授权
|
||||
|
||||
- 用户目标:在 worktree `redline-evidence-2026-09-22` 落 SWBOOT / FAV / D7 / PI narrative 红线证据;**不**做能力放量、**不**翻转 flag。
|
||||
- 交付终点:短文 + test-report + D7 Track E 清单 + 叙事负例单测;本地 commit;不 push。
|
||||
- 明确禁止项:
|
||||
- SWBOOT-10 保持 fail-closed stub(不实现真实 patch/merge/push)
|
||||
- FAV:无整支 merge、无 live;`FAV_DEGRADED_READ` 保持 false;不启用 `Register(fav)`
|
||||
- D7:retention 不做物理删除;ADR 保持 `pending-compliance-signoff`
|
||||
- PI change-report narrative flag 保持 OFF
|
||||
- `MULTI_INTENT_PLAN_TIER` 保持 legacy;`SEMANTIC_SUMMARY_REPLACE` 保持未接线
|
||||
|
||||
## 范围与非目标
|
||||
|
||||
- 允许:只读复验、证据报告、观察窗前置登记、Track E ID-only 清单、叙事 fallback 负例测试。
|
||||
- 非目标:能力 release、compose/env flag 翻转、共享环境写操作、FAV live、SWBOOT-10 实施、D7 物理删除、features.go 与 drift worktree 冲突时的重复改码。
|
||||
|
||||
## 步骤与验收
|
||||
|
||||
1. [x] SWBOOT:跑验收清单中**无需真实仓写**的 L1–L4 项;L5/L6 标 pending auth — 证据:[报告](../../test-reports/2026-09-22-redline-evidence-swboot-test-report.md)
|
||||
2. [x] FAV:审计 `ObserveShadow`(WouldStage/WouldPublish false);登记观察窗启动前置;注明 `registry.go` / `dispatcher.go` 硬门 — 见下文
|
||||
3. [x] D7:盘点 DB/备份/日志表面 + Track E ID-only 合规清单(无删除)— [清单](../checklists/2026-09-22-d7-track-e-id-only-compliance.md)
|
||||
4. [x] PI narrative:补强 flag-on fallback 负例;flag 保持 off;`features.go` reason 跳过(drift worktree 已改)— 见下文
|
||||
|
||||
## FAV 审计与观察窗前置
|
||||
|
||||
### 代码门禁(本轮未改)
|
||||
|
||||
| 门禁 | 位置 | 行为 |
|
||||
|------|------|------|
|
||||
| `Registry.Register(fav)` | `internal/events/registry.go` | 恒返回 `ErrDisabledConsumer` |
|
||||
| `AssertLiveConsumers` / `LiveConsumers` | 同上 | 拒绝 / 剔除 `fav` |
|
||||
| `PeekPendingLeases` / `ClaimLeases` / `SetMode` | `internal/events/dispatcher.go` | consumer=`fav` 直接拒绝;claim SQL 含 `d.consumer <> 'fav'` |
|
||||
| `ObserveShadow` | `internal/app/fav/subscriber.go` | `WouldStage`/`WouldPublish`/`DegradedReadUsed` 恒 false;`FAV_DEGRADED_READ` 为真则拒绝 |
|
||||
| `HandleLease` | 同上 | 默认 disabled;即使 `Enabled=true` 仍 fail-closed 至 cutover 审批 |
|
||||
|
||||
复验命令(本 worktree,`-short`):
|
||||
|
||||
```text
|
||||
go test -count=1 -short ./internal/app/fav/ ./internal/events/ -run 'Fav|Register|ObserveShadow|Cutover|Disabled'
|
||||
→ PASS
|
||||
```
|
||||
|
||||
Compose 默认(dev/test/main):`FAV_DEGRADED_READ=false`、`FAV_PUBLISHER_ENABLED=false`(main 硬编码 `"false"`)。
|
||||
|
||||
### 观察窗启动前置(登记,本轮不开始计时)
|
||||
|
||||
在授权开启 live **之前**须同时满足;任一缺失则观察窗**不得**起算:
|
||||
|
||||
1. 用户显式授权:允许 `fav` durable consumer cutover(单独审批,非整支 merge `feature/final-artifact-vault`)。
|
||||
2. 解除 `events` 硬门:`Registry.Register(fav)` / `SetMode(fav,*)` / claim 路径可按审批切片放行(本批禁止改)。
|
||||
3. 顺序固定:`staging → artifact → publication`;每级 `shadow → drain → live`。
|
||||
4. 每级观察窗下限:≥7 天 **或** ≥N 终态样本(取更严);崩溃/重启幂等证据齐全。
|
||||
5. `FAV_DEGRADED_READ` **全程 false**(不随 live 开启)。
|
||||
6. 三环境 compose 与 sysadmin 成熟度目录一致声明;无旁路 `cmd/events` 注册。
|
||||
7. 独立 mutex `events` 持有者;CURRENT 集成槽位已认领。
|
||||
8. 回滚预案:任一级失败立即回 `shadow`/`off`,不前进下一级。
|
||||
|
||||
**本轮结论**:shadow 可观测;live 观察窗 **未开始**。
|
||||
|
||||
## D7 表面盘点(无删除)
|
||||
|
||||
静态复验(相对 [W7 盘点](../../audit/2026-09-17-d7-data-inventory.md) / [报告](../../test-reports/2026-09-17-w7-d7-inventory-test-report.md)):
|
||||
|
||||
| 表面 | 位置 / 入口 | 本轮结论 |
|
||||
|------|-------------|---------|
|
||||
| 会话正文 | `chat_sessions` / `chat_messages`(`deleted_at` 列) | Go 检索无 `DELETE FROM chat_*`;无 chat soft-delete 写路径 |
|
||||
| 派生记忆 | `context_memory_chunks`(含 `chat_history`) | 随正文留存;无 retention 作业 |
|
||||
| 私密文档 | `freeform_documents` soft-delete | 与聊天独立;本轮不触碰 |
|
||||
| 事件 envelope / DLQ | `event_envelopes` / `event_dead_letters` | Track E:只允许 ID/digest/typed error / allowlist 摘要 |
|
||||
| 应用日志 | Docker `json-file` / slog | 禁止消息正文;DSN 脱敏 |
|
||||
| 备份 | `scripts/backup-system-db.sh`(`pg_dump -Fc` 整库) | 含 chat 明文;本轮**未**执行 dump / 未清备份 |
|
||||
| Agent workspace | `data/*/workspaces` | 非终态;无 30 天清理作业(ADR 待签) |
|
||||
| FAV 终态 | `final_artifacts` | 与聊天口径解耦;consumer off |
|
||||
|
||||
ADR [`2026-09-17-d7-chat-data-retention`](../../adr/2026-09-17-d7-chat-data-retention.md) 仍为 `pending-compliance-signoff`。合规签字前禁止按 365/180/30 物理删除。
|
||||
|
||||
## PI narrative
|
||||
|
||||
- 仓库默认 / compose:`PI_CHANGE_REPORT_NARRATIVE=false`(dev/test/main)。
|
||||
- 新增/加宽负例:`internal/docrevision/narrative_test.go`(SHA mismatch、wrong schema kind、top-level error_code、empty raw、empty fetcher body、authorized-flip 路径仍默认 off)。
|
||||
- **跳过** `internal/sysadmin/features.go` reason 更新:并行 worktree `feature/status-drift-reconcile-2026-09-22` 已改 SEMANTIC_SUMMARY_SHADOW / PI_CHANGE_REPORT_NARRATIVE 文案;本批若改会产生冲突。集成时以 drift 为准。
|
||||
|
||||
红线保持:`MULTI_INTENT_PLAN_TIER=legacy`;`SEMANTIC_SUMMARY_REPLACE` 未接线。
|
||||
|
||||
## 验证与证据
|
||||
|
||||
| 范围 / 被测 SHA | 命令与环境 | 预期 | 实际 / 判定 | 证据 |
|
||||
|---|---|---|---|---|
|
||||
| SWBOOT L1–L4(基线 `364ed7f1`) | 见 SWBOOT 报告 | PASS;L5/L6 pending | PASS | [swboot-test-report](../../test-reports/2026-09-22-redline-evidence-swboot-test-report.md);[assets](../../test-reports/assets/2026-09-22-redline-evidence/) |
|
||||
| FAV shadow / registry | `go test … fav/ events/` | WouldStage/Publish false;Register fail-closed | PASS | [fav-shadow.txt](../../test-reports/assets/2026-09-22-redline-evidence/fav-shadow.txt) |
|
||||
| D7 / Track E | 静态检索 + 清单 | 无删除;ID-only 清单落盘 | PASS | [checklist](../checklists/2026-09-22-d7-track-e-id-only-compliance.md) |
|
||||
| PI narrative 负例 | `go test ./internal/docrevision/ -run 'Narrative\|…'` | flag off;flag-on fallback | PASS | [pi-narrative.txt](../../test-reports/assets/2026-09-22-redline-evidence/pi-narrative.txt) |
|
||||
| arch | `./scripts/arch-check.sh --mode block` | production gate passed | PASS | [arch-check.txt](../../test-reports/assets/2026-09-22-redline-evidence/arch-check.txt) |
|
||||
|
||||
## 收口与交接
|
||||
|
||||
- 本地提交在本分支;**未**合入 `dev`;**未** push;**无**部署。
|
||||
- `features.go` 以 status-drift 分支为准合并。
|
||||
- cleanup:合入并确认 tip 为 dev 祖先后由独立维护者 remove worktree。
|
||||
- 下一步(需另授权):SWBOOT L5/L6 / SWBOOT-10 安全评审;FAV live 观察窗;D7 合规签字;PI narrative flag 翻转。
|
||||
|
||||
## 相关链接
|
||||
|
||||
- 验收清单:[../checklists/2026-09-14-software-project-bootstrap-acceptance.md](../checklists/2026-09-14-software-project-bootstrap-acceptance.md)
|
||||
- W6 FAV shadow:[2026-09-17-w6-fav-subscriber-shadow.md](./2026-09-17-w6-fav-subscriber-shadow.md)
|
||||
- W7 D7 盘点:[2026-09-17-w7-d7-inventory.md](./2026-09-17-w7-d7-inventory.md)
|
||||
- Wave 7 编排:[2026-09-18-wave7-roadmap-orchestration.md](./2026-09-18-wave7-roadmap-orchestration.md)
|
||||
@@ -0,0 +1,111 @@
|
||||
# 红线证据 · SWBOOT L1–L4 验收报告(无真实仓写)
|
||||
|
||||
## 一、测试背景 (Background)
|
||||
|
||||
对照 [软件项目自举验收清单](../ops/checklists/2026-09-14-software-project-bootstrap-acceptance.md) 分层 L1–L6。本批**仅**执行无需真实仓库 patch/merge/push 的工程门禁子集;SWBOOT-10 保持 `ERR_SWBOOT10_STUB_ONLY` fail-closed。L5(真实 PI Runner)与 L6(无头浏览器页面)标 **pending auth**,不冒充 PASS。
|
||||
|
||||
## 二、测试目标 (Test Objectives)
|
||||
|
||||
- 复验 L1 catalog/manifest/policy、L2 领域服务(内存/短测)、L3 前端软件域守卫、L4 stub/固定输出(含 controlled_patch 拒绝)
|
||||
- 证明 SWBOOT-10 stub 仍拒绝 `ExecuteControlledPatch` / `ApproveMerge`
|
||||
- 不写真实软件仓;不升 FEATURE-MATRIX「纯软件项目自举」状态
|
||||
|
||||
## 三、测试方案与环境 (Test Plan & Environment)
|
||||
|
||||
| 项 | 值 |
|
||||
|----|----|
|
||||
| OS | Darwin 25.6.0(arm64) |
|
||||
| 分支 | `feature/redline-evidence-2026-09-22` |
|
||||
| 基线 SHA | `364ed7f1a3f0393ef77ec4623a9518116ed2cb87` |
|
||||
| 方法 | `go test -short`、`arch-check --mode block`、`npx tsx --test`(局部) |
|
||||
| 共享环境 | **未使用**(无 rebuild / 无 Playwright / 无真实 PI) |
|
||||
|
||||
### 分层映射
|
||||
|
||||
| 层 | 本批范围 | 状态 |
|
||||
|----|----------|------|
|
||||
| L1 | `internal/swboot` catalog/preview/allowlist;`internal/workflowdef` software_bootstrap/delivery policy | **RUN / PASS** |
|
||||
| L2 | `internal/projectworkflow` creation/catalog;controlled_patch API 拒绝(短测,无共享 PG 写) | **RUN / PASS**(隔离短测;空库全迁移 / 并发 PG 未跑) |
|
||||
| L3 | `web/src/lib/createProjectSubmitGuard.test.ts`(软件域不克隆医疗 7 包) | **RUN / PASS**(单文件;全量 `npm test`/`build` 因本机缺全局 `tsx` PATH 未整套跑,用 `npx tsx` 精确用例) |
|
||||
| L4 | stub:`RepoAllowlist` patch/merge stub;`PiSoftwareBootstrapAdvisor` 拒 `controlled_patch` | **RUN / PASS** |
|
||||
| L5 | 真实 PI Agent Runner UI/小队 | **pending auth** |
|
||||
| L6 | Ubuntu Playwright 真实页面 UI-SW-00–14 | **pending auth** |
|
||||
|
||||
## 四、预期结果 (Expected Results)
|
||||
|
||||
- L1–L4 适用项 PASS;SWBOOT-10 stub 负例 PASS
|
||||
- L5/L6 明确 pending,不写假 PASS
|
||||
- 清单 §4 controlled patch 负例中「只在 feature worktree 写入 / 真实 merge」等需真实写的项保持 NOT RUN
|
||||
|
||||
## 五、实际测试结果与判定 (Actual Results & Evaluation)
|
||||
|
||||
### 5.1 L1 Manifest / catalog
|
||||
|
||||
- **Input**:`go test -count=1 -short ./internal/swboot/ ./internal/workflowdef/ -run 'SWBOOT|Software|RepoAllow|Controlled|ProjectTypes|CreationPreview|SuggestDelivery|catalog'`
|
||||
- **Actual**:`ok` swboot / workflowdef;software_bootstrap 接受 `non_medical_software`、拒绝 `medical_device`;solo+controlled_patch 预览无效并含 `ERR_EXECUTION_MODE_DISABLED`
|
||||
- **Verdict**:PASS
|
||||
- **Duration**:<2s
|
||||
|
||||
### 5.2 L2 领域服务(短测)
|
||||
|
||||
- **Input**:`go test -count=1 -short ./internal/projectworkflow/ -run 'SWBOOT|Software|Controlled|software_bootstrap'`
|
||||
- **Actual**:`ok`;`controlled_patch` 创建路径拒绝(需 SWBOOT-10 executor)
|
||||
- **Verdict**:PASS(短测范围);空库 schema 升级 / 共享 PG 鉴权并发 **NOT RUN**(需授权环境)
|
||||
- **Duration**:<1s
|
||||
|
||||
### 5.3 L3 前端软件域守卫
|
||||
|
||||
- **Input**:`npx --yes tsx --test src/lib/createProjectSubmitGuard.test.ts`(cwd=`web/`)
|
||||
- **Actual**:4/4 pass,含 `shouldCloneMedicalTemplates` 对 `non_medical_software` 为 false
|
||||
- **Verdict**:PASS(精确用例);全仓 `npm test` / `npm run build` 本轮未整跑
|
||||
- **Duration**:~0.3s(tsx 启动另计)
|
||||
|
||||
### 5.4 L4 Stub / 固定输出
|
||||
|
||||
- **Input**:`TestRepoAllowlistStub`;`go test ./internal/app/ -run 'PiSoftware|Advise|controlled'`
|
||||
- **Actual**:`ExecuteControlledPatch` / `ApproveMerge` → `ERR_SWBOOT10_STUB_ONLY`;advisor 拒 `controlled_patch`
|
||||
- **Verdict**:PASS(stub-only,非真实执行器)
|
||||
- **Duration**:<1s
|
||||
|
||||
### 5.5 工程门禁冒烟
|
||||
|
||||
- **Input**:`./scripts/arch-check.sh --mode block`;`go vet ./internal/swboot/ ./internal/app/fav/ ./internal/events/ ./internal/docrevision/`
|
||||
- **Actual**:`arch-check block: production gate passed`;vet 无输出
|
||||
- **Verdict**:PASS
|
||||
- **Duration**:~1.6s
|
||||
|
||||
### 5.6 L5 / L6
|
||||
|
||||
- **Input**:未请求真实 PI / Playwright 授权;未占集成槽位
|
||||
- **Actual**:未执行
|
||||
- **Verdict**:**pending auth**(NOT RUN)
|
||||
|
||||
### 5.7 清单 §4 未来 controlled patch 负例
|
||||
|
||||
| 项 | 本批 |
|
||||
|----|------|
|
||||
| repo 未绑定 / 非 allowlist / `.env` 排除 | 单元 stub 部分覆盖 allowlist;真实绑定 **NOT RUN** |
|
||||
| 只在 feature worktree 写入 | **NOT RUN**(禁止真实写) |
|
||||
| 测试失败不自动 merge / 批准≠merge/push | stub `ApproveMerge` PASS;真实路径 **NOT RUN** |
|
||||
| 保护分支 force push 拒绝 | **NOT RUN** |
|
||||
|
||||
## 六、自动化测试套件汇总 (Test Suite Execution)
|
||||
|
||||
```text
|
||||
go test -count=1 -short ./internal/swboot/ ./internal/workflowdef/ ./internal/projectworkflow/ ./internal/app/
|
||||
go test -count=1 -short ./internal/app/fav/ ./internal/events/ -run 'Fav|Register|ObserveShadow|Cutover|Disabled'
|
||||
./scripts/arch-check.sh --mode block
|
||||
npx tsx --test web/src/lib/createProjectSubmitGuard.test.ts
|
||||
# L5/L6: NOT RUN (pending auth)
|
||||
```
|
||||
|
||||
全部适用命令退出码 0。未运行共享环境 dump、未写业务仓。
|
||||
|
||||
命令输出片段(脱敏/截断):[assets/2026-09-22-redline-evidence/](./assets/2026-09-22-redline-evidence/)(`swboot-l1.txt`、`arch-check.txt`、`env.txt`)。
|
||||
|
||||
## 七、测试结论与后续 (Conclusion & Next Steps)
|
||||
|
||||
- **SWBOOT L1–L4(无真实仓写子集)PASS**;SWBOOT-10 仍为 fail-closed stub。
|
||||
- **L5/L6 pending auth**:需占用集成槽位、真实 PI Runner、Playwright 容器后再跑 UI-SW-00–14。
|
||||
- 升 FEATURE-MATRIX done 仍须独立安全评审后的受控执行器(本批不做)。
|
||||
- 任务短文:[../ops/short-term/2026-09-22-redline-evidence.md](../ops/short-term/2026-09-22-redline-evidence.md)
|
||||
@@ -0,0 +1,7 @@
|
||||
=== arch-check ===
|
||||
arch-check mode=block
|
||||
boundaries=/private/tmp/Agent-System/.worktrees/redline-evidence-2026-09-22/.doc/system-design/module-boundaries.yaml
|
||||
ok chat-agent-system/internal/archtest 0.976s
|
||||
ok chat-agent-system/internal/archtest 0.494s
|
||||
arch-check block: production gate passed
|
||||
EXIT:0
|
||||
@@ -0,0 +1,11 @@
|
||||
=== chat physical delete / soft-delete write paths ===
|
||||
NONE
|
||||
=== chat_messages UPDATE (content edit paths, not retention) ===
|
||||
internal/ctxmgr/recategorize.go:99: UPDATE chat_messages
|
||||
internal/ctxmgr/message_update.go:30: UPDATE chat_messages
|
||||
internal/ctxmgr/message_update.go:77: UPDATE chat_messages
|
||||
internal/ctxmgr/message_update.go:118: UPDATE chat_messages
|
||||
=== ADR compliance field ===
|
||||
6:compliance: pending-compliance-signoff
|
||||
18:**提议 / 工程草案**(2026-09-17)。数字与删除口径标 `pending-compliance-signoff`:合规签字或改数前,W7 仅允许数据分类盘点与现状审计,不得按未签字数字执行物理删除或备份清除。接受后状态改为 `accepted`。
|
||||
54:- W7 可按本草案启动盘点;物理删除与备份清除在 `pending-compliance-signoff` 解除前禁止按建议数字自动执行。
|
||||
@@ -0,0 +1,18 @@
|
||||
=== D7 DELETE / soft-delete / retention ===
|
||||
internal/artifactvault/registry.go:265: source_run_id, payload_sha256, terminal_state, policy_version, publication_status, retention_class
|
||||
internal/artifactvault/registry.go:296: terminal_state, policy_version, publication_status, retention_class, requested_at
|
||||
internal/artifactvault/types.go:134: RetentionClass string `json:"retention_class,omitempty"`
|
||||
---backup---
|
||||
3:# 系统业务库备份脚本 (backup-system-db.sh)
|
||||
7:# 2. 采用 pg_dump -Fc 导出系统业务库(含 task_runs、工作流治理等);
|
||||
11:# ./scripts/backup-system-db.sh <dev|test|main> <目标备份目录>
|
||||
15:# 2. ${HOME}/.secrets/backup-env 中 SYSTEM_DB_PASSWORD_<ENV>
|
||||
17:# 当前实现经 docker exec 以库内角色执行 pg_dump,通常不需要宿主机口令;
|
||||
32: $0 dev ./backups/system_dev_20260912
|
||||
33: $0 test /tmp/agent_system_test_backup
|
||||
36: SYSTEM_DB_PASSWORD 或 \${HOME}/.secrets/backup-env 或 configs/.env.<env>
|
||||
81: local secrets_file="${HOME}/.secrets/backup-env"
|
||||
115:# 仅保留变量供未来宿主机连接扩展;当前 pg_dump 走容器内角色。
|
||||
161:echo "[导出] pg_dump -Fc ${DB_NAME} ..."
|
||||
163:docker exec "${CONTAINER_NAME}" pg_dump -U "${DB_USER}" -d "${DB_NAME}" -Fc -Z 6 -f "${TMP_CONTAINER_DUMP}"
|
||||
---log driver---
|
||||
@@ -0,0 +1,4 @@
|
||||
all_payload_fields_sorted= ['candidate_id', 'doc_id', 'environment', 'impacted_doc_id', 'plan_id', 'project_id', 'report_id', 'revision', 'risk', 'run_id', 'session_id', 'snapshot_id', 'status', 'step_id', 'summary_ref', 'task_key', 'user_id', 'version_no']
|
||||
forbidden_hits= NONE
|
||||
has_summary_ref= True
|
||||
contract_count= 11
|
||||
@@ -0,0 +1,19 @@
|
||||
=== Track E contracts / content forbidden ===
|
||||
internal/events/registry.go:50: {EventName: EventIntentPlanAwaiting, SchemaVersion: 1, Enabled: true, Producers: []string{"app/intentflow", "events"}, Consumers: []string{ConsumerProjection, ConsumerNotify}, PayloadFields: []string{"plan_id", "revision", "status", "environment", "project_id", "user_id", "session_id", "summary_ref"}},
|
||||
internal/events/registry.go:51: {EventName: EventIntentPlanStepChanged, SchemaVersion: 1, Enabled: true, Producers: []string{"app/intentflow", "events"}, Consumers: []string{ConsumerProjection, ConsumerNotify}, PayloadFields: []string{"plan_id", "revision", "step_id", "status", "environment", "project_id", "user_id", "session_id", "summary_ref"}},
|
||||
internal/events/registry.go:52: {EventName: EventIntentPlanCompleted, SchemaVersion: 1, Enabled: true, Producers: []string{"app/intentflow", "events"}, Consumers: []string{ConsumerProjection, ConsumerNotify}, PayloadFields: []string{"plan_id", "revision", "status", "environment", "project_id", "user_id", "session_id", "summary_ref"}},
|
||||
internal/events/registry.go:148: PayloadFields []string `json:"payload_fields"`
|
||||
.doc/system-design/module-boundaries.yaml:141: - doccontent
|
||||
.doc/system-design/module-boundaries.yaml:147: - doccontent
|
||||
.doc/system-design/module-boundaries.yaml:149: doccontent: []
|
||||
.doc/system-design/module-boundaries.yaml:343: artifact_payload_staging:
|
||||
=== RUN TestClassifySafeKnownContract
|
||||
--- PASS: TestClassifySafeKnownContract (0.00s)
|
||||
=== RUN TestSanitizeSummaryDropsPayload
|
||||
--- PASS: TestSanitizeSummaryDropsPayload (0.00s)
|
||||
=== RUN TestIntentPlanContractsOmitSensitivePayload
|
||||
--- PASS: TestIntentPlanContractsOmitSensitivePayload (0.00s)
|
||||
=== RUN TestRegistryParityWithYAML
|
||||
--- PASS: TestRegistryParityWithYAML (0.00s)
|
||||
PASS
|
||||
ok chat-agent-system/internal/events 0.490s
|
||||
@@ -0,0 +1,6 @@
|
||||
SHA=364ed7f1a3f0393ef77ec4623a9518116ed2cb87 DATE=2026-09-22T13:25:12Z OS=Darwin GO=go1.27.1
|
||||
darwin
|
||||
arm64
|
||||
go1.27.1
|
||||
Darwin WeiCHENdeMac-mini.local 25.6.0 Darwin Kernel Version 25.6.0: Fri Jul 31 19:17:26 PDT 2026; root:xnu-12377.161.14~5/RELEASE_ARM64_T6041 arm64
|
||||
2026-09-22T13:26:20Z
|
||||
@@ -0,0 +1,6 @@
|
||||
docker-compose.main.yml:132: FAV_DEGRADED_READ: "false"
|
||||
docker-compose.main.yml:133: FAV_PUBLISHER_ENABLED: "false"
|
||||
docker-compose.test.yml:129: FAV_DEGRADED_READ: ${FAV_DEGRADED_READ:-false}
|
||||
docker-compose.test.yml:130: FAV_PUBLISHER_ENABLED: ${FAV_PUBLISHER_ENABLED:-false}
|
||||
docker-compose.dev.yml:133: FAV_DEGRADED_READ: ${FAV_DEGRADED_READ:-false}
|
||||
docker-compose.dev.yml:134: FAV_PUBLISHER_ENABLED: ${FAV_PUBLISHER_ENABLED:-false}
|
||||
@@ -0,0 +1,10 @@
|
||||
=== RUN TestAssertLiveConsumersRejectsFAV
|
||||
--- PASS: TestAssertLiveConsumersRejectsFAV (0.00s)
|
||||
=== RUN TestAssertLiveConsumersRejectsUnknown
|
||||
--- PASS: TestAssertLiveConsumersRejectsUnknown (0.00s)
|
||||
=== RUN TestLiveConsumersOmitsFAV
|
||||
--- PASS: TestLiveConsumersOmitsFAV (0.00s)
|
||||
=== RUN TestManifestJSONIncludesDisabledFAV
|
||||
--- PASS: TestManifestJSONIncludesDisabledFAV (0.00s)
|
||||
PASS
|
||||
ok chat-agent-system/internal/events 0.321s
|
||||
@@ -0,0 +1,9 @@
|
||||
13: ConsumerFAV = "fav"
|
||||
22: EventFAVArtifactStaged = "fav.artifact_staged"
|
||||
49: {EventName: EventFAVArtifactStaged, SchemaVersion: 1, Enabled: false, Producers: []string{"app/docflow"}, Consumers: []string{ConsumerFAV}, PayloadFields: []string{"doc_id", "snapshot_id"}},
|
||||
84: if cons == ConsumerFAV || strings.EqualFold(cons, "fav") {
|
||||
85: return fmt.Errorf("%w: fav", ErrDisabledConsumer)
|
||||
102: if n == ConsumerFAV {
|
||||
119:func (r *Registry) Register(consumer string) error {
|
||||
123: if consumer == ConsumerFAV || strings.EqualFold(consumer, "fav") {
|
||||
124: return fmt.Errorf("%w: fav", ErrDisabledConsumer)
|
||||
@@ -0,0 +1,20 @@
|
||||
=== FAV shadow ===
|
||||
=== RUN TestFavSubscriberDefaultsDisabled
|
||||
--- PASS: TestFavSubscriberDefaultsDisabled (0.00s)
|
||||
=== RUN TestFavSubscriberStillDisabledWhenFlagOnWithoutRegistryApproval
|
||||
--- PASS: TestFavSubscriberStillDisabledWhenFlagOnWithoutRegistryApproval (0.00s)
|
||||
=== RUN TestFavSubscriberShadowComputesIntendedOutcomeWithoutWrites
|
||||
--- PASS: TestFavSubscriberShadowComputesIntendedOutcomeWithoutWrites (0.00s)
|
||||
PASS
|
||||
ok chat-agent-system/internal/app/fav 0.293s
|
||||
=== RUN TestValidateOpsCutoverRejectsFavAndNonDev
|
||||
--- PASS: TestValidateOpsCutoverRejectsFavAndNonDev (0.00s)
|
||||
=== RUN TestValidateOpsCutoverAllowsThreeConsumers
|
||||
--- PASS: TestValidateOpsCutoverAllowsThreeConsumers (0.00s)
|
||||
=== RUN TestClaimIDsDisabled
|
||||
--- PASS: TestClaimIDsDisabled (0.00s)
|
||||
=== RUN TestManifestJSONIncludesDisabledFAV
|
||||
--- PASS: TestManifestJSONIncludesDisabledFAV (0.00s)
|
||||
PASS
|
||||
ok chat-agent-system/internal/events 0.303s
|
||||
EXIT:0
|
||||
@@ -0,0 +1,19 @@
|
||||
=== FAV compose defaults ===
|
||||
---
|
||||
internal/events/registry.go:81: return fmt.Errorf("%w: %s", ErrDisabledConsumer, eventName)
|
||||
internal/events/registry.go:85: return fmt.Errorf("%w: fav", ErrDisabledConsumer)
|
||||
internal/events/registry.go:124: return fmt.Errorf("%w: fav", ErrDisabledConsumer)
|
||||
internal/app/fav/subscriber.go:4:// a separate approval. Registry.Register("fav") and SetMode(fav, live) already
|
||||
internal/app/fav/subscriber.go:41: return fmt.Errorf("%w: fav", events.ErrDisabledConsumer)
|
||||
internal/app/fav/subscriber.go:44: return fmt.Errorf("%w: fav publisher cutover not approved", events.ErrDisabledConsumer)
|
||||
internal/app/fav/subscriber.go:53:// as a write receipt; WouldStage/WouldPublish stay false in this slice.
|
||||
internal/app/fav/subscriber.go:59: WouldStage bool
|
||||
internal/app/fav/subscriber.go:60: WouldPublish bool
|
||||
internal/app/fav/subscriber.go:64:// ObserveShadow computes the intended FAV outcome without business side effects.
|
||||
internal/app/fav/subscriber.go:66:func (c *EventConsumer) ObserveShadow(lease events.Lease) (IntendedOutcome, error) {
|
||||
internal/app/fav/subscriber.go:74: return out, fmt.Errorf("%w: fav", events.ErrDisabledConsumer)
|
||||
internal/app/fav/subscriber.go:79: out.WouldStage = false
|
||||
internal/app/fav/subscriber.go:80: out.WouldPublish = false
|
||||
internal/events/dispatcher.go:126: return nil, fmt.Errorf("%w: fav", ErrDisabledConsumer)
|
||||
internal/events/dispatcher.go:165: return nil, fmt.Errorf("%w: fav", ErrDisabledConsumer)
|
||||
internal/events/dispatcher.go:338: return fmt.Errorf("%w: fav", ErrDisabledConsumer)
|
||||
@@ -0,0 +1,6 @@
|
||||
=== RUN TestVaultDefaultsStayDisabled
|
||||
--- PASS: TestVaultDefaultsStayDisabled (0.00s)
|
||||
=== RUN TestVaultStatusReportsOff
|
||||
--- PASS: TestVaultStatusReportsOff (0.00s)
|
||||
PASS
|
||||
ok chat-agent-system/internal/server 0.681s
|
||||
@@ -0,0 +1 @@
|
||||
364ed7f1a3f0393ef77ec4623a9518116ed2cb87
|
||||
@@ -0,0 +1,5 @@
|
||||
|
||||
> shuimu-workbench@1.0.0 build
|
||||
> tsc && vite build && node scripts/precompress-dist.mjs
|
||||
|
||||
sh: tsc: command not found
|
||||
@@ -0,0 +1,7 @@
|
||||
=== L3 frontend quick ===
|
||||
|
||||
> shuimu-workbench@1.0.0 test
|
||||
> tsx --test "src/**/!(*InteractiveCard*|*chatWindowArtifact*|*deliverableSync*).test.ts" && vitest run src/components/chat/InteractiveCard.test.ts src/components/chat/chatWindowArtifact.test.ts src/components/chat/deliverableSync.test.ts --run
|
||||
|
||||
sh: tsx: command not found
|
||||
EXIT:0
|
||||
@@ -0,0 +1,5 @@
|
||||
=== PI narrative flag defaults ===
|
||||
docker-compose.test.yml:128: PI_CHANGE_REPORT_NARRATIVE: ${PI_CHANGE_REPORT_NARRATIVE:-false}
|
||||
docker-compose.main.yml:131: PI_CHANGE_REPORT_NARRATIVE: ${PI_CHANGE_REPORT_NARRATIVE:-false}
|
||||
docker-compose.dev.yml:131: PI_CHANGE_REPORT_NARRATIVE: ${PI_CHANGE_REPORT_NARRATIVE:-false}
|
||||
.env.example:117:PI_CHANGE_REPORT_NARRATIVE=false
|
||||
@@ -0,0 +1,50 @@
|
||||
=== PI narrative ===
|
||||
=== RUN TestMaterializeAgentOutput_FlagOnFetcherNarrativeComplete
|
||||
--- PASS: TestMaterializeAgentOutput_FlagOnFetcherNarrativeComplete (0.00s)
|
||||
=== RUN TestPIChangeReportNarrativeFlagDefaultOff
|
||||
--- PASS: TestPIChangeReportNarrativeFlagDefaultOff (0.00s)
|
||||
=== RUN TestResolveChangeReport_FlagOffUsesDeterministic
|
||||
--- PASS: TestResolveChangeReport_FlagOffUsesDeterministic (0.00s)
|
||||
=== RUN TestResolveChangeReport_FlagOnValidNarrativeKeepsServerRisk
|
||||
--- PASS: TestResolveChangeReport_FlagOnValidNarrativeKeepsServerRisk (0.00s)
|
||||
=== RUN TestResolveChangeReport_FlagOnMalformedFullFallback
|
||||
=== RUN TestResolveChangeReport_FlagOnMalformedFullFallback/bad_json
|
||||
=== RUN TestResolveChangeReport_FlagOnMalformedFullFallback/bad_schema_version
|
||||
=== RUN TestResolveChangeReport_FlagOnMalformedFullFallback/wrong_schema_kind
|
||||
=== RUN TestResolveChangeReport_FlagOnMalformedFullFallback/digest_mismatch
|
||||
=== RUN TestResolveChangeReport_FlagOnMalformedFullFallback/from_sha_mismatch
|
||||
=== RUN TestResolveChangeReport_FlagOnMalformedFullFallback/to_sha_mismatch
|
||||
=== RUN TestResolveChangeReport_FlagOnMalformedFullFallback/timeout_envelope
|
||||
=== RUN TestResolveChangeReport_FlagOnMalformedFullFallback/top-level_error_code
|
||||
=== RUN TestResolveChangeReport_FlagOnMalformedFullFallback/partial_flag
|
||||
=== RUN TestResolveChangeReport_FlagOnMalformedFullFallback/empty_summary
|
||||
=== RUN TestResolveChangeReport_FlagOnMalformedFullFallback/empty_raw
|
||||
--- PASS: TestResolveChangeReport_FlagOnMalformedFullFallback (0.00s)
|
||||
--- PASS: TestResolveChangeReport_FlagOnMalformedFullFallback/bad_json (0.00s)
|
||||
--- PASS: TestResolveChangeReport_FlagOnMalformedFullFallback/bad_schema_version (0.00s)
|
||||
--- PASS: TestResolveChangeReport_FlagOnMalformedFullFallback/wrong_schema_kind (0.00s)
|
||||
--- PASS: TestResolveChangeReport_FlagOnMalformedFullFallback/digest_mismatch (0.00s)
|
||||
--- PASS: TestResolveChangeReport_FlagOnMalformedFullFallback/from_sha_mismatch (0.00s)
|
||||
--- PASS: TestResolveChangeReport_FlagOnMalformedFullFallback/to_sha_mismatch (0.00s)
|
||||
--- PASS: TestResolveChangeReport_FlagOnMalformedFullFallback/timeout_envelope (0.00s)
|
||||
--- PASS: TestResolveChangeReport_FlagOnMalformedFullFallback/top-level_error_code (0.00s)
|
||||
--- PASS: TestResolveChangeReport_FlagOnMalformedFullFallback/partial_flag (0.00s)
|
||||
--- PASS: TestResolveChangeReport_FlagOnMalformedFullFallback/empty_summary (0.00s)
|
||||
--- PASS: TestResolveChangeReport_FlagOnMalformedFullFallback/empty_raw (0.00s)
|
||||
=== RUN TestResolveChangeReport_AuthorizedFlipPathKeepsFlagOffDefault
|
||||
--- PASS: TestResolveChangeReport_AuthorizedFlipPathKeepsFlagOffDefault (0.00s)
|
||||
=== RUN TestCreateAgentCandidate_FlagOffIgnoresNarrativeEnrichment
|
||||
--- PASS: TestCreateAgentCandidate_FlagOffIgnoresNarrativeEnrichment (0.00s)
|
||||
=== RUN TestCreateAgentCandidate_FlagOnTimeoutFallsBackWithoutError
|
||||
--- PASS: TestCreateAgentCandidate_FlagOnTimeoutFallsBackWithoutError (0.00s)
|
||||
=== RUN TestCreateAgentCandidate_FlagOnFetcherApplies
|
||||
--- PASS: TestCreateAgentCandidate_FlagOnFetcherApplies (0.00s)
|
||||
=== RUN TestCreateAgentCandidate_FlagOnFetcherErrorFallsBack
|
||||
--- PASS: TestCreateAgentCandidate_FlagOnFetcherErrorFallsBack (0.00s)
|
||||
=== RUN TestCreateAgentCandidate_FlagOnEmptyFetcherBodyFallsBack
|
||||
--- PASS: TestCreateAgentCandidate_FlagOnEmptyFetcherBodyFallsBack (0.00s)
|
||||
=== RUN TestNarrativeModelInput_IncludesClippedChangeText
|
||||
--- PASS: TestNarrativeModelInput_IncludesClippedChangeText (0.00s)
|
||||
PASS
|
||||
ok chat-agent-system/internal/docrevision 0.350s
|
||||
EXIT:0
|
||||
@@ -0,0 +1,29 @@
|
||||
=== SWBOOT L1 unit ===
|
||||
=== RUN TestBuildCreationPreview_RejectsControlledPatchAndSoloPrivacy
|
||||
--- PASS: TestBuildCreationPreview_RejectsControlledPatchAndSoloPrivacy (0.00s)
|
||||
=== RUN TestRepoAllowlistStub
|
||||
--- PASS: TestRepoAllowlistStub (0.00s)
|
||||
PASS
|
||||
ok chat-agent-system/internal/swboot 0.290s
|
||||
=== RUN TestOfficialWorkflowKeys
|
||||
--- PASS: TestOfficialWorkflowKeys (0.00s)
|
||||
=== RUN TestCompatibleWithProductDomain
|
||||
--- PASS: TestCompatibleWithProductDomain (0.00s)
|
||||
=== RUN TestValidateDefinitionV2_SoftwareManifests
|
||||
--- PASS: TestValidateDefinitionV2_SoftwareManifests (0.00s)
|
||||
PASS
|
||||
ok chat-agent-system/internal/workflowdef 0.383s
|
||||
=== RUN TestCreateSoftwareProject_NoMedicalDefaults
|
||||
--- PASS: TestCreateSoftwareProject_NoMedicalDefaults (0.00s)
|
||||
PASS
|
||||
ok chat-agent-system/internal/projectworkflow 0.600s
|
||||
=== RUN TestPiSoftwareBootstrapAdvisor_NoTools
|
||||
--- PASS: TestPiSoftwareBootstrapAdvisor_NoTools (0.00s)
|
||||
=== RUN TestPiSoftwareBootstrapAdvisor_RejectsControlledPatch
|
||||
--- PASS: TestPiSoftwareBootstrapAdvisor_RejectsControlledPatch (0.00s)
|
||||
=== RUN TestPiSoftwareBootstrapAdvisor_LiveMiniMax
|
||||
pi_swboot_test.go:55: set RUN_PI_E2E=1 for live PI software bootstrap
|
||||
--- SKIP: TestPiSoftwareBootstrapAdvisor_LiveMiniMax (0.00s)
|
||||
PASS
|
||||
ok chat-agent-system/internal/app 0.722s
|
||||
EXIT:0
|
||||
@@ -0,0 +1,82 @@
|
||||
=== SWBOOT L2 short (authz/create/reject) ===
|
||||
=== RUN TestPG_GoverningAccess_CompletedAndTerminatedDeny
|
||||
access_governing_pg_test.go:157: TEST_DATABASE_URL not set; skipping PostgreSQL integration test
|
||||
--- SKIP: TestPG_GoverningAccess_CompletedAndTerminatedDeny (0.00s)
|
||||
=== RUN TestPG_GoverningAccess_QueryErrorFailClosed
|
||||
--- PASS: TestPG_GoverningAccess_QueryErrorFailClosed (0.00s)
|
||||
=== RUN TestPG_ActivateOfficialWorkflowRuntimeMetadata
|
||||
activation_official_pg_test.go:18: TEST_DATABASE_URL not set; skipping PostgreSQL integration test
|
||||
--- SKIP: TestPG_ActivateOfficialWorkflowRuntimeMetadata (0.00s)
|
||||
=== RUN TestPG_ActivationAndStageAdvance
|
||||
pg_integration_test.go:49: TEST_DATABASE_URL not set; skipping PostgreSQL integration test
|
||||
--- SKIP: TestPG_ActivationAndStageAdvance (0.00s)
|
||||
=== RUN TestPG_RDevActivateWithNAClose
|
||||
rdev_pg_test.go:15: TEST_DATABASE_URL not set; skipping PostgreSQL integration test
|
||||
--- SKIP: TestPG_RDevActivateWithNAClose (0.00s)
|
||||
=== RUN TestActiveWorkflowScope_NoLiveInstanceReturnsEmpty
|
||||
--- PASS: TestActiveWorkflowScope_NoLiveInstanceReturnsEmpty (0.00s)
|
||||
=== RUN TestTaskKeyInScope_EmptyAllowsAll
|
||||
--- PASS: TestTaskKeyInScope_EmptyAllowsAll (0.00s)
|
||||
=== RUN TestTaskKeyInScope_CanonicalAlias
|
||||
--- PASS: TestTaskKeyInScope_CanonicalAlias (0.00s)
|
||||
=== CONT TestClassifyDocDuty
|
||||
=== RUN TestClassifyDocDuty/all_zero
|
||||
=== CONT TestNormalizeAuthorOnlyDuties
|
||||
--- PASS: TestNormalizeAuthorOnlyDuties (0.00s)
|
||||
=== PAUSE TestClassifyDocDuty/all_zero
|
||||
=== RUN TestClassifyDocDuty/negative
|
||||
=== PAUSE TestClassifyDocDuty/negative
|
||||
=== RUN TestClassifyDocDuty/one_role
|
||||
=== PAUSE TestClassifyDocDuty/one_role
|
||||
=== RUN TestClassifyDocDuty/two_roles
|
||||
=== PAUSE TestClassifyDocDuty/two_roles
|
||||
=== RUN TestClassifyDocDuty/full_distinct
|
||||
=== PAUSE TestClassifyDocDuty/full_distinct
|
||||
=== RUN TestClassifyDocDuty/full_duplicate
|
||||
=== PAUSE TestClassifyDocDuty/full_duplicate
|
||||
=== CONT TestClassifyDocDuty/all_zero
|
||||
=== CONT TestResolveDocTaskDuty
|
||||
--- PASS: TestResolveDocTaskDuty (0.00s)
|
||||
=== CONT TestCountFullDutyDocs
|
||||
--- PASS: TestCountFullDutyDocs (0.00s)
|
||||
=== CONT TestValidateDocTaskDuties
|
||||
--- PASS: TestValidateDocTaskDuties (0.00s)
|
||||
=== CONT TestNormalizeDocTaskDuties
|
||||
--- PASS: TestNormalizeDocTaskDuties (0.00s)
|
||||
=== CONT TestDocTaskRequiresDuty
|
||||
--- PASS: TestDocTaskRequiresDuty (0.00s)
|
||||
=== CONT TestEvaluateStageReadiness_AuthorOnlyIsManaged
|
||||
--- PASS: TestEvaluateStageReadiness_AuthorOnlyIsManaged (0.00s)
|
||||
=== CONT TestComputePlanHash_LegacySnapshotStableWithoutDutyPolicy
|
||||
--- PASS: TestComputePlanHash_LegacySnapshotStableWithoutDutyPolicy (0.00s)
|
||||
=== CONT TestEvaluateStageReadiness_DutyModes
|
||||
--- PASS: TestEvaluateStageReadiness_DutyModes (0.00s)
|
||||
=== CONT TestValidateAuthorOnlyDocTaskDuties
|
||||
=== CONT TestClassifyDocDuty/two_roles
|
||||
--- PASS: TestValidateAuthorOnlyDocTaskDuties (0.00s)
|
||||
=== CONT TestClassifyDocDuty/one_role
|
||||
=== CONT TestClassifyDocDuty/negative
|
||||
=== CONT TestClassifyDocDuty/full_duplicate
|
||||
=== CONT TestClassifyDocDuty/full_distinct
|
||||
--- PASS: TestClassifyDocDuty (0.00s)
|
||||
--- PASS: TestClassifyDocDuty/all_zero (0.00s)
|
||||
--- PASS: TestClassifyDocDuty/two_roles (0.00s)
|
||||
--- PASS: TestClassifyDocDuty/negative (0.00s)
|
||||
--- PASS: TestClassifyDocDuty/one_role (0.00s)
|
||||
--- PASS: TestClassifyDocDuty/full_duplicate (0.00s)
|
||||
--- PASS: TestClassifyDocDuty/full_distinct (0.00s)
|
||||
PASS
|
||||
ok chat-agent-system/internal/projectinstance 0.547s
|
||||
=== RUN TestProjectTypesCatalog
|
||||
--- PASS: TestProjectTypesCatalog (0.00s)
|
||||
=== RUN TestBuildCreationPreview_SelfBootstrapSolo
|
||||
--- PASS: TestBuildCreationPreview_SelfBootstrapSolo (0.00s)
|
||||
=== RUN TestBuildCreationPreview_RejectsControlledPatchAndSoloPrivacy
|
||||
--- PASS: TestBuildCreationPreview_RejectsControlledPatchAndSoloPrivacy (0.00s)
|
||||
=== RUN TestRepoAllowlistStub
|
||||
--- PASS: TestRepoAllowlistStub (0.00s)
|
||||
=== RUN TestSuggestDeliveryAfterBootstrapNeverActivates
|
||||
--- PASS: TestSuggestDeliveryAfterBootstrapNeverActivates (0.00s)
|
||||
PASS
|
||||
ok chat-agent-system/internal/swboot 0.796s
|
||||
EXIT:0
|
||||
@@ -0,0 +1,11 @@
|
||||
=== SWBOOT L4 stub advisor ===
|
||||
=== RUN TestPiSoftwareBootstrapAdvisor_NoTools
|
||||
--- PASS: TestPiSoftwareBootstrapAdvisor_NoTools (0.00s)
|
||||
=== RUN TestPiSoftwareBootstrapAdvisor_RejectsControlledPatch
|
||||
--- PASS: TestPiSoftwareBootstrapAdvisor_RejectsControlledPatch (0.00s)
|
||||
=== RUN TestPiSoftwareBootstrapAdvisor_LiveMiniMax
|
||||
pi_swboot_test.go:55: set RUN_PI_E2E=1 for live PI software bootstrap
|
||||
--- SKIP: TestPiSoftwareBootstrapAdvisor_LiveMiniMax (0.00s)
|
||||
PASS
|
||||
ok chat-agent-system/internal/app 0.309s
|
||||
EXIT:0
|
||||
@@ -123,16 +123,22 @@ func TestResolveChangeReport_FlagOnMalformedFullFallback(t *testing.T) {
|
||||
t.Cleanup(docrevision.ResetPIChangeReportNarrativeForTest)
|
||||
|
||||
fromSHA, toSHA, ruleRisk, impacts, diff := sampleDiff(t)
|
||||
digest := docrevision.NarrativeInputDigest(fromSHA, toSHA, ruleRisk, impacts, diff.Hunks)
|
||||
cases := []struct {
|
||||
name string
|
||||
raw string
|
||||
}{
|
||||
{"bad json", `{not-json`},
|
||||
{"bad schema version", `{"schema_version":99,"schema_kind":"change_report_narrative_v1","input_digest":"x","summary":["a"]}`},
|
||||
{"wrong schema kind", `{"schema_version":1,"schema_kind":"other_v1","input_digest":"` + digest + `","from_sha":"` + fromSHA + `","to_sha":"` + toSHA + `","summary":["PI only"]}`},
|
||||
{"digest mismatch", mustNarrativeJSON(t, fromSHA, toSHA, "deadbeef", []string{"ok"})},
|
||||
{"from_sha mismatch", mustNarrativeJSONWithSHAs(t, "wrong-from", toSHA, digest, []string{"PI only"})},
|
||||
{"to_sha mismatch", mustNarrativeJSONWithSHAs(t, fromSHA, "wrong-to", digest, []string{"PI only"})},
|
||||
{"timeout envelope", `{"result_v1":{"outcome":"error","error_code":"TIMEOUT"},"narrative":{"schema_version":1,"schema_kind":"change_report_narrative_v1"}}`},
|
||||
{"top-level error_code", `{"schema_version":1,"schema_kind":"change_report_narrative_v1","input_digest":"` + digest + `","from_sha":"` + fromSHA + `","to_sha":"` + toSHA + `","error_code":"RUNNER_FAILED","summary":["PI only"]}`},
|
||||
{"partial flag", `{"schema_version":1,"schema_kind":"change_report_narrative_v1","input_digest":"x","partial":true,"summary":["a"]}`},
|
||||
{"empty summary", mustNarrativeJSON(t, fromSHA, toSHA, docrevision.NarrativeInputDigest(fromSHA, toSHA, ruleRisk, impacts, diff.Hunks), nil)},
|
||||
{"empty summary", mustNarrativeJSON(t, fromSHA, toSHA, digest, nil)},
|
||||
{"empty raw", ""},
|
||||
}
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
@@ -154,11 +160,19 @@ func TestResolveChangeReport_FlagOnMalformedFullFallback(t *testing.T) {
|
||||
t.Fatalf("mixed narrative field leaked: %q", s)
|
||||
}
|
||||
}
|
||||
if rep.DeterministicFacts["narrative_applied"] == true {
|
||||
t.Fatal("fallback must not claim narrative_applied")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func mustNarrativeJSON(t *testing.T, fromSHA, toSHA, digest string, summary []string) string {
|
||||
t.Helper()
|
||||
return mustNarrativeJSONWithSHAs(t, fromSHA, toSHA, digest, summary)
|
||||
}
|
||||
|
||||
func mustNarrativeJSONWithSHAs(t *testing.T, fromSHA, toSHA, digest string, summary []string) string {
|
||||
t.Helper()
|
||||
raw, err := json.Marshal(map[string]any{
|
||||
"schema_version": 1,
|
||||
@@ -174,6 +188,43 @@ func mustNarrativeJSON(t *testing.T, fromSHA, toSHA, digest string, summary []st
|
||||
return string(raw)
|
||||
}
|
||||
|
||||
// TestResolveChangeReport_AuthorizedFlipPathKeepsFlagOffDefault documents the
|
||||
// pre-authorization contract: default remains off; when a future owner flips the
|
||||
// flag for a controlled window, malformed PI output still full-falls-back.
|
||||
func TestResolveChangeReport_AuthorizedFlipPathKeepsFlagOffDefault(t *testing.T) {
|
||||
docrevision.ResetPIChangeReportNarrativeForTest()
|
||||
t.Cleanup(docrevision.ResetPIChangeReportNarrativeForTest)
|
||||
if docrevision.PIChangeReportNarrativeEnabled() {
|
||||
t.Fatal("PI_CHANGE_REPORT_NARRATIVE must remain off until separately authorized")
|
||||
}
|
||||
|
||||
fromSHA, toSHA, ruleRisk, impacts, diff := sampleDiff(t)
|
||||
digest := docrevision.NarrativeInputDigest(fromSHA, toSHA, ruleRisk, impacts, diff.Hunks)
|
||||
piRaw := mustNarrativeJSON(t, fromSHA, toSHA, digest, []string{"should stay ignored while off"})
|
||||
|
||||
offRep, err := docrevision.ResolveChangeReport(piRaw, fromSHA, toSHA, ruleRisk, impacts, diff)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if offRep.AnalysisStatus != docrevision.AnalysisFallback {
|
||||
t.Fatalf("default-off must ignore PI narrative, got %s", offRep.AnalysisStatus)
|
||||
}
|
||||
|
||||
docrevision.SetPIChangeReportNarrativeForTest(true)
|
||||
onBad, err := docrevision.ResolveChangeReport(`{"schema_version":1,"schema_kind":"change_report_narrative_v1"}`, fromSHA, toSHA, ruleRisk, impacts, diff)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if onBad.AnalysisStatus != docrevision.AnalysisFallback {
|
||||
t.Fatalf("authorized-on malformed must still fallback, got %s", onBad.AnalysisStatus)
|
||||
}
|
||||
|
||||
docrevision.SetPIChangeReportNarrativeForTest(false)
|
||||
if docrevision.PIChangeReportNarrativeEnabled() {
|
||||
t.Fatal("test toggle must restore off before exit")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateAgentCandidate_FlagOffIgnoresNarrativeEnrichment(t *testing.T) {
|
||||
docrevision.SetPIChangeReportNarrativeForTest(false)
|
||||
t.Cleanup(docrevision.ResetPIChangeReportNarrativeForTest)
|
||||
@@ -289,6 +340,32 @@ func TestCreateAgentCandidate_FlagOnFetcherErrorFallsBack(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateAgentCandidate_FlagOnEmptyFetcherBodyFallsBack(t *testing.T) {
|
||||
docrevision.SetPIChangeReportNarrativeForTest(true)
|
||||
t.Cleanup(docrevision.ResetPIChangeReportNarrativeForTest)
|
||||
|
||||
svc := docrevision.NewService(nil)
|
||||
svc.NarrativeFetcher = func(_ context.Context, _ docrevision.NarrativeFetchSpec) (string, error) {
|
||||
return " ", nil
|
||||
}
|
||||
ctx := context.Background()
|
||||
st, err := svc.OpenTemplateVersion(ctx, "doc_flag_on_empty", "# base\n\nbody\n", docrevision.ActorSnapshot{DisplayName: "t"}, 1, "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cand, rep, err := svc.CreateAgentCandidate(ctx, docrevision.AgentCandidateRequest{
|
||||
DocID: "doc_flag_on_empty", RunID: "r-empty", InputSnapshotID: st.HeadSnapshotID,
|
||||
OutputMarkdown: "# base\n\nbody changed\n",
|
||||
ActorKind: docrevision.ActorAgent,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("empty fetcher body must full-fallback without error, got %v", err)
|
||||
}
|
||||
if cand == nil || rep == nil || rep.AnalysisStatus != docrevision.AnalysisFallback {
|
||||
t.Fatalf("want fallback candidate, got cand=%v rep=%+v", cand, rep)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNarrativeModelInput_IncludesClippedChangeText(t *testing.T) {
|
||||
long := strings.Repeat("甲", 280)
|
||||
spec := docrevision.NarrativeFetchSpec{
|
||||
|
||||
Reference in New Issue
Block a user