Compare commits

...
Author SHA1 Message Date
weichen cb22135144 release-candidate: 汇集 dev@b9339cd2 至 test(docgov 共享 map 竞态修复、任务刷新恢复、商务叙事阶段门控),准备长期实测 [Tag: rc-v1.1.0-beta.7] 2026-09-28 09:53:47 +00:00
weichen b9339cd272 merge: candidate docgov-shared-map-race-2026-09-28-r2 into dev 2026-09-28 09:06:52 +00:00
weichen 792c216c96 docs(docgov): 登记共享 map 并发崩溃的问题、经验与竞态回归
登录 500 来自进程被 concurrent map 打崩,不是登录逻辑。单测 -race 已通过,dev 重建仍待合入后复验。
2026-09-28 09:06:06 +00:00
weichen a90cce73b9 fix(docgov): 保护共享内存 map,避免并发读写把进程打崩
per-doc 锁只串行同一文档,不同 docID 仍裸读写 memDocs 等 map。GetDocument 与另一文档写入撞上时运行时 fatal,代理把全部 API 变成 500。
2026-09-28 08:52:44 +00:00
weichen a3db288a7a merge: candidate bizdev-stage-gating-narrative-2026-09-28 into dev 2026-09-28 07:31:48 +00:00
weichen f46480a987 feat(workflow): 商务叙事阶段允许编制任意已启用文档 2026-09-28 07:29:59 +00:00
weichen e5c2519fea merge: candidate refresh-task-state-recovery-2026-09-28 into dev 2026-09-28 06:18:08 +00:00
weichen 5bc88faf4f docs(test): 记录刷新恢复的短测与前端构建
短测、前端测试和构建已通过。架构边界失败来自基线上的 coordinator 导入,浏览器与真实 PI 链路尚未在新代码上复验。
2026-09-28 06:14:35 +00:00
weichen b820e0070d fix(taskrun): 刷新后恢复进行中任务并纠正进度问询
进行中的 run 提前写下消息锚点,并按会话列出活跃任务;进度疑问句改为查询真实状态,交付物已落盘且不是传输失败时不再被空结果否决。
2026-09-28 06:09:42 +00:00
weichen 8d5e782079 merge: candidate promote-rc-beta6-closeout-2026-09-28 into dev 2026-09-28 06:05:54 +00:00
weichen 5679c79011 docs(ops): record rc-v1.1.0-beta.6 promotion and cleanup 2026-09-28 06:05:32 +00:00
weichen 0664abe57d release-candidate: 汇集 dev@714732df5a37 至 test(助手回复叙述、test 文档问题、质量门禁标题归一化),准备长期实测 [Tag: rc-v1.1.0-beta.6] 2026-09-28 06:01:36 +00:00
weichen 714732df5a merge: candidate land-promote-rc-beta5-record-2026-09-28 into dev 2026-09-28 05:56:49 +00:00
weichen a3f8afbe63 docs(ops): land rc-v1.1.0-beta.5 promotion record on dev 2026-09-28 05:52:18 +00:00
weichen 650703c5c2 merge: candidate quality-gate-heading-mismatch-2026-09-28-r3 into dev 2026-09-28 05:38:01 +00:00
weichen d86b4d51ef docs(task): 加回质量门禁修复的 CURRENT 认领行 2026-09-28 05:31:03 +00:00
weichen 4bb265b431 merge: dev into quality-gate-heading-mismatch 2026-09-28 05:30:54 +00:00
weichen d6ce9abef7 docs(task): 让 CURRENT 认领行与 dev 对齐以便合入
暂时去掉本任务行,合入代码后再用 docs apply 加回。
2026-09-28 05:30:31 +00:00
weichen d3fda0e834 docs(task): 链到质量门禁标题漂移测试报告 2026-09-28 05:16:33 +00:00
weichen 44435691c0 docs(test): 记录质量门禁标题归一化的工程验收 2026-09-28 05:16:25 +00:00
weichen 87888213da chore(arch): 补记 coordinator 对 projectworkflow 的既有依赖
block 模式基线为 0,该 import 在本修复之前已在 engine_task.go。
2026-09-28 05:15:10 +00:00
weichen 4c42d1bf74 merge: candidate agent-reply-llm-narrative-2026-09-28 into dev 2026-09-28 05:13:29 +00:00
weichen aea19f70ef fix(squad): 章节标题归一化后不再把空格和层级漂移判成缺章
聊天触发的任务同时打开质量自动修复,避免格式误报直接阻断受控投影。
2026-09-28 05:12:51 +00:00
weichen 434d542c3c merge: candidate test-user-doc-issues-2026-09-28 into dev 2026-09-28 04:20:02 +00:00
weichen fa5d17a403 docs(task): 补记五态收口
说明这次合入后 test 制品还没有重放。
2026-09-28 04:19:49 +00:00
weichen 2952aa5a64 docs(task): 收口第三方 test 文档问题
CURRENT 记下任务已完成。test 制品尚未按这次 dev 重放。
2026-09-28 04:19:26 +00:00
weichen 6e1d5830b5 merge: candidate test-user-doc-issues-2026-09-28 into dev 2026-09-28 04:15:18 +00:00
weichen c46a9c35dc docs(test): 记录任务写动词与可见拒绝的验收
第三方 test 问题的单测与 runner 接线核对需要可追溯报告,嵌入超限保持开放。
2026-09-28 04:10:18 +00:00
weichen 73836962a0 release-candidate: 汇集 dev@193a752f1a54 至 test(含 PI runner 工作区校验),准备长期实测 [Tag: rc-v1.1.0-beta.5] 2026-09-28 04:03:45 +00:00
weichen db859e185e fix(intent): 让「帮我定任务书」进入任务并说清失败
写动词补上制定/拟定与祈使「帮我定」,避免落到阶段对照模板。质量未通过不再声称正文已保存到宿主机路径;研发前置未满足时把中文原因直接回复给用户。
2026-09-28 04:01:02 +00:00
weichen 193a752f1a merge: candidate pi-runner-env-mismatch-2026-09-28 into dev 2026-09-28 03:52:33 +00:00
weichen 3eac19cf44 docs(test): 将验收日志摘录改为可跟踪的 txt
*.log 被 gitignore,sidecar 与 data_dir 核对摘录需随报告入库。
2026-09-28 03:45:30 +00:00
weichen d724982acc docs(test): 记录 PI runner 环境错配的真实验收
test 进程已改接 18866,bd_research 在 data/test 工作区完成,原先的 MISSING_TARGET 未再现。
2026-09-28 03:44:57 +00:00
weichen dfd9f6efb3 docs(test): 记录助手回复智能体叙述的验收
附带任务记录与 CURRENT 认领行。真实 Runner 三轮 reply_source=pi-agent。
2026-09-28 03:25:18 +00:00
weichen d55488ae37 feat(coordinator): 用智能体叙述查询、帮助与操作回执
确定性事实仍由代码生成;PI Agent 只组织语言,失败或关闭开关时回退原模板。安全拦截与确认提问保持模板。
2026-09-28 03:25:06 +00:00
weichen 3ba15df875 fix(agent): 记录 PI runner 数据目录核对结果
启动后第一次核对通过时打一条不含路径的日志,便于确认 test 没有再打到 dev sidecar。
2026-09-28 03:17:26 +00:00
weichen 4f581306d7 fix(agent): 拒绝把工作区发给数据目录不一致的 PI runner
test 启动时根 .env 的 dev runner URL 盖过了 18866,sidecar 把 test 工作区重写到 dev 空目录,模型因读不到材料报 MISSING_TARGET。端口约定优先,并在调用前核对 runner data_dir。
2026-09-28 03:16:27 +00:00
weichen 8f77053f51 merge: candidate error-events-pg-roundtrip-2026-09-28 into dev 2026-09-28 02:45:42 +00:00
weichen 0e05eedade docs(task): 更正补记任务的 dev 基线 SHA 2026-09-28 02:45:25 +00:00
weichen 4bceb2b4ba docs(test): 补记错误审计表隔离库往返通过
一次性 pgvector 库迁到 78 后,TestStoreRoundTrip 写入并按 request_id 读回。
2026-09-28 02:45:10 +00:00
weichen 655fb4f149 merge: candidate error-code-observability-2026-09-28 into dev 2026-09-28 02:39:23 +00:00
weichen ef3c770451 docs(task): 记录错误码体系已合入 local dev
认领改为 done。实现提交已在 dev,部署与远端同步不在本次授权内。
2026-09-28 02:39:12 +00:00
weichen dddd3fe8c8 merge: candidate error-code-observability-2026-09-28 into dev 2026-09-28 02:37:48 +00:00
weichen e4da425b23 merge: candidate attachment-only-turn-2026-09-28 into dev 2026-09-28 02:32:38 +00:00
weichen 8f72b6a97c docs(test): 记录附件回合在重载后的 dev 上复验通过
:8080 已换成含本修复的二进制。仅附件得到梳理或解析引导,无关文字先回答再追问。
2026-09-28 02:32:31 +00:00
weichen 73a3aa9286 docs(errcode): 登记错误码目录、任务和验证报告
目录按注册表列出稳定码,测试报告记录工程门禁与无测试库时的审计跳过。
2026-09-28 02:27:29 +00:00
weichen 7435f48389 feat(web): 增加错误审计查询和失败排查指引
管理台可按错误码或 request id 检索审计记录,聊天失败气泡展示对应排查短句。
2026-09-28 02:27:23 +00:00
weichen f3f23a3018 feat(errcode): 用稳定错误码记录 HTTP 与异步失败
失败响应此前不写日志,request_id 无法对照原因。注册表不覆盖处理器已经给出的 HTTP 状态。
2026-09-28 02:27:16 +00:00
weichen c87d28b343 merge: candidate attachment-only-turn-2026-09-28 into dev 2026-09-28 02:16:18 +00:00
weichen 42a9a4be5d docs(test): 记录附件回合修复已合入 local dev
候选已 ff-only 进入 dev。浏览器和产品 PI 仍未跑,运行中的 dev 进程还没加载新二进制。
2026-09-28 02:16:09 +00:00
weichen cb4d2af8d3 merge: candidate attachment-only-turn-2026-09-28 into dev 2026-09-28 02:13:37 +00:00
weichen 457e870330 fix(chat): 只上传文档时给出梳理或追问,不再裸报 HTTP 400
空消息加附件可以进入回合。无文字时按解析状态引导或回退审阅,有文字但未处理文档时先回答再追问。4xx 信封不再被前端丢弃。
2026-09-28 02:00:24 +00:00
weichen 6314406701 merge: candidate activation-preview-precheck-2026-09-28 into dev 2026-09-28 01:50:48 +00:00
weichen 8a9614d19e docs(test): 归档激活预览预检复验并关闭问题
dev 浏览器已确认未纳入审批时不再请求 activation-preview,兼任后预览 200,密钥框均在 form 内。
2026-09-28 01:50:26 +00:00
weichen 3e534bbb39 merge: candidate activation-preview-precheck-2026-09-28 into dev 2026-09-28 01:40:39 +00:00
weichen e7d4743cba docs(task): 登记激活预览预检与密钥框警告
记录 dev 项目 6022 的 400 时间线,以及管理台五个密钥输入不在表单内的 DOM 警告。
2026-09-28 01:38:39 +00:00
weichen 7f9d01a3b6 fix(web): 激活前预检人工审批并消除密钥框密码警告
未纳入人工审批的计划会被服务端拒绝为 400。配置页在请求前拦截并提示;管理台密钥输入放入表单,避免浏览器把密码框当成未托管字段。
2026-09-28 01:35:46 +00:00
weichen b1ed8ecfe9 merge: candidate squad-commit-authority-2026-09-28 into dev 2026-09-28 01:25:28 +00:00
weichen 56538221f3 docs(task): record non-author squad commit denial 2026-09-28 01:24:26 +00:00
weichen c713834954 fix(bizdev): commit squad ledger as the document author
Non-author triggers were denied by dutyAuthorizer because AutoCommitUserID was the triggering user. Record that user on OnBehalfOf and surface the duty mismatch in the task error.
2026-09-28 01:24:25 +00:00
weichen 774df05998 merge: candidate auth-register-internal-2026-09-28 into dev 2026-09-28 01:16:32 +00:00
weichen dbe1401455 docs(task): mark auth register fix resolved after test goose 77 2026-09-28 01:16:22 +00:00
weichen 9141741b78 merge: candidate auth-register-internal-2026-09-28 into dev 2026-09-28 01:12:57 +00:00
weichen e1d6a2c192 docs(task): record auth register INTERNAL fix and test evidence 2026-09-28 01:12:14 +00:00
weichen 88b7c11a23 fix(auth): reseed standard roles and reject duplicate usernames as 400
Registration always writes role-guest; a deleted standard role became a masked INTERNAL. Username unique violations are now a 400 instead of an infrastructure 500.
2026-09-28 01:12:07 +00:00
weichen 4ba60c2c9d merge: candidate restore-admin-password-reset-2026-09-28 into dev 2026-09-28 00:57:01 +00:00
weichen e1f2c9c57f docs(current): mark password-reset restore done
The UI candidate is already on local dev; record the five-state closeout.
2026-09-28 00:56:49 +00:00
weichen 04d7fec493 merge: candidate restore-admin-password-reset-2026-09-28 into dev 2026-09-28 00:51:41 +00:00
weichen 90e146e424 docs(task): record admin password reset UI restore
Capture the F4-A mis-delete, the dev UI probe, and the CURRENT claim.
2026-09-28 00:51:25 +00:00
weichen f0ecc4c996 fix(web): restore admin password reset in user governance
T20-F4-A removed the working reset button after the F4-B endpoint was already live. Restore the entry so admins can issue a one-time random temp password.
2026-09-28 00:44:41 +00:00
weichen 912957c44e merge: candidate docker-context-gitkeep closeout into dev 2026-09-27 21:13:13 +00:00
weichen ec7148175b docs(task): close docker-context-gitkeep (e40a9989 verified by real image build, merged as 5e409c1e) 2026-09-27 21:13:04 +00:00
weichen b35ea39a95 merge: candidate promote-rc-beta4-2026-09-27 receipts into dev 2026-09-27 21:12:44 +00:00
weichen a6acdcb30b merge: candidate test-single-binary-2026-09-27 closeout into dev 2026-09-27 21:12:12 +00:00
weichen c20c8aa7ab docs(current): mark test-single-binary-2026-09-27 done (receipt test-single-binary-2026-09-27-state-2) 2026-09-27 21:11:22 +00:00
weichen 8b3da0d297 docs(promote): rc-v1.1.0-beta.4 receipts, evidence and promote record
- PASS receipt 5e409c1e + images manifest + nightly evidence (five real-PI chains)
- recovered archive of nightly6 @94c215d3 process evidence (original dir lost in
  staging move; full original log preserved, README documents the loss)
- task record for the promotion (candidate 2fe1e055, tag, images apply)
2026-09-27 21:11:07 +00:00
weichen 912342ae0a docs(test): rc-v1.1.0-beta.4 promotion + test single-binary report; fix launcher env mapping
- migrate-test-db.sh: export DEV_PG_CONTAINER (inner script reads it, not CONTAINER)
- launch-single.sh: SYSTEM_DB_* must override root-.env CONTEXT_DB_* (set -a
  re-source clobbers both external exports and :- fallbacks; two misdirected
  launches audited, dev DB unchanged - report §5.8-3)
- task record done; full test report (nightly five chains PASS @5e409c1e,
  migration S0-verified, deployment acceptance, rollback paths, follow-ups)
2026-09-27 21:10:16 +00:00
weichen 2fe1e05591 release-candidate: 汇集 dev 功能至 test(test 单二进制化配套脚本 + docker 上下文修复),准备长期实测 [Tag: rc-v1.1.0-beta.4] 2026-09-27 20:59:11 +00:00
weichen 22f7e7f3f7 docs(current): claim test-single-binary-2026-09-27 (docs apply receipt test-single-binary-2026-09-27-state-1) 2026-09-27 20:57:57 +00:00
weichen 5e409c1eb2 merge: candidate docker-context-gitkeep-2026-09-27 into dev 2026-09-27 18:35:32 +00:00
weichen e40a9989ab fix(deploy): keep web/dist/.gitkeep in docker context for go:embed
.dockerignore excluded the whole web/dist dir, breaking go-builder since
web/embed.go (all:dist) landed (6cbe7e6e): candidate image builds failed
with "pattern all:dist: no matching files found". Re-include the tracked
.gitkeep only; runtime stays disk-dist via web-builder COPY (LookupDist
false -> disk fallback). Verified by a real candidate-images-build run.
2026-09-27 18:29:50 +00:00
weichen 94c215d36e merge: candidate test-single-binary-2026-09-27 into dev 2026-09-27 16:21:34 +00:00
weichen d91dafc1c4 feat(scripts): test env single-binary entrypoints (migrate-test-db, launch-single)
- migrate-test-db.sh: reuse parameterized migrate-dev-db.sh with test defaults
  (container shuimu-system-pg-test -> localpg :5434, PGDATA=data/test/pg)
- launch-single.sh: non-dev single-binary launcher (SYSTEM_DB_*->CONTEXT_DB_*
  mapping, env-scoped PI sidecar, no Vite); task record for dev->test rc
  promotion + test conversion (rc-v1.1.0-beta.4)
2026-09-27 16:21:09 +00:00
weichen 05d45022b1 merge: candidate upload-doc-access-2026-09-27 closeout into dev 2026-09-27 08:10:14 +00:00
weichen 07845cfcee docs(task): close out upload-doc-access (dev 86efba2c verified, E2E PASS, lesson added) 2026-09-27 08:10:05 +00:00
weichen 86efba2cd5 merge: candidate upload-doc-access-2026-09-27 into dev 2026-09-27 07:52:39 +00:00
weichen 307e9e6569 docs(current): claim upload-doc-access-2026-09-27 (docs apply receipt upload-doc-access-2026-09-27-state-1) 2026-09-27 07:45:36 +00:00
weichen 88e33282db fix(freedoc): persist uploaded file metadata and text body server-side
上传文档跨端不可访问修复(ISSUE-20260927-upload-doc-cross-device):
- 迁移 00076:freeform_documents 增加 source_filename/mime/size_bytes/asset_id
- freedoc:Create/Get/List 读写源文件元数据,负值拒绝
- 前端:注册前全部附件先登记 CAS 并预读文本正文;文本正文嵌入注册
  markdown;跨端恢复 sourceType/fileMeta 路由回文件预览器
- 大小显示 formatFileSize(<512B 不再显示 0 KB)
- E2E 新增 FS-UPLOAD-02 跨浏览器上下文可访问性用例

回归:go vet/arch-check/go test -short(隔离 PG)+ web npm test/build 全绿;
存量无元数据旧文档不可恢复(重新上传即可)。
2026-09-27 07:45:15 +00:00
weichen a0e40919a7 merge: candidate frontend-demo-fallback-2026-09-27-r3 closeout into dev 2026-09-27 07:08:12 +00:00
weichen 9da300ae60 docs(task): finalize active-session residue closeout state
任务文档终态(done/merged/passed/cleanup done)、ISSUES 行 resolved
(dev 36c5fb54 复验证据)、CURRENT 置 done。
2026-09-27 07:08:05 +00:00
weichen 36c5fb549c merge: candidate frontend-demo-fallback-2026-09-27-r3 into dev 2026-09-27 07:06:17 +00:00
weichen 083c63bb9c docs(issue): register active-session residue issue and r3 task record
登记 ISSUE-20260927-active-session-residue(ISSUE-20260927-demo-fallback
修复残留路径);新增 r3 任务主记录(根因/同类排查/修复方案/验证证据);
CURRENT 登记 r3c 任务行。
2026-09-27 07:05:09 +00:00
weichen 739b8c56f9 fix(web): purge legacy demo sessionId residue from localStorage on read
旧前端曾把 demo fallback 值 sess-001 持久化到 active_session;一次性
purge 版本 key 已写不再清理,读取侧无校验导致老浏览器 + 无可见会话
账号首屏 4x chat 404。提取共享 LEGACY_DEMO_SESSION_IDS 常量,
loadActiveSessionId 命中即清除并返回 fallback(幂等),loadMessages
复用同一集合。
2026-09-27 07:05:05 +00:00
weichen 87db3621c6 merge: candidate frontend-demo-fallback-2026-09-27-r2 into dev 2026-09-27 03:15:24 +00:00
weichen 0648867921 docs(current): mark frontend-demo-fallback-2026-09-27-r2 done 2026-09-27 03:15:22 +00:00
weichen 41b9b8bc3d merge: candidate frontend-demo-fallback-2026-09-27-r2 into dev 2026-09-27 03:14:56 +00:00
weichen 20b68d6a23 docs(task): finalize frontend-demo-fallback closeout state 2026-09-27 03:14:53 +00:00
weichen 0de657f09c merge: candidate frontend-demo-fallback-2026-09-27-r2 into dev 2026-09-27 03:11:32 +00:00
weichen db038aa7a7 fix(web): stop phantom demo-fallback requests in seeds-off mode
App.tsx hardcoded fallbacks (active session "sess-001", projectId 1) sent
requests for nonexistent resources on fresh logins against real dev data,
producing 7+ console 404/403 hits. Fallbacks now resolve to empty/0; the
existing chatBlockedNoProject empty state and session-reconciliation effect
carry the UI, and demo-seeds-enabled builds keep the NEUROPULSE fallback.

Root cause, same-class scan, and before/after browser evidence (9 phantom
requests -> 0, author+member accounts) recorded in the task doc; ISSUES row
ISSUE-20260927-demo-fallback registered.
2026-09-27 03:09:37 +00:00
weichen 56928ac206 merge: candidate full-system-browser-e2e-2026-09-26 into dev 2026-09-26 09:28:00 +00:00
weichen a9d79b99b8 docs(test): audit-friendly E2E report with retained login credentials 2026-09-26 07:58:47 +00:00
weichen 7ab7d572b9 docs(test): e2e ledger after reject portal fix 2026-09-26 07:48:36 +00:00
weichen 887a75c1b1 fix(web): portal reject modal above stacking context 2026-09-26 07:48:30 +00:00
weichen 157ec407e2 docs(test): full-system browser e2e re-run ledger 2026-09-26 07:29:34 +00:00
weichen 7513ce61ed fix(web): member drafting edit + reject await + expand right rail 2026-09-26 07:29:27 +00:00
weichen 7555818753 docs(test): FINAL full-system browser E2E report after pending heal 2026-09-26 05:14:11 +00:00
weichen 323088c4bd docs(test): add playwright log for full-system e2e rerun 2026-09-26 04:31:01 +00:00
weichen ccce44dfc0 fix(chat): heal task bubble pending after completed run 2026-09-26 04:30:38 +00:00
weichen a5ca6fdcfd test(e2e): document PI UI pending mismatch and raise suite timeout 2026-09-26 04:12:33 +00:00
weichen 466426a58f test(e2e): full-system browser multi-user acceptance 2026-09-26 03:48:34 +00:00
weichen 4873c5e8b9 test(e2e): full-system browser multi-user acceptance 2026-09-26 03:28:34 +00:00
weichen 078eb4fcf0 test(e2e): full-system browser multi-user acceptance 2026-09-26 03:23:35 +00:00
weichen 09cc76eb8d merge: candidate sysadmin-maturity-refresh-2026-09-26 into dev 2026-09-26 02:46:15 +00:00
weichen 9ff489546c docs: sysadmin maturity refresh closeout (results, current claim done) 2026-09-26 02:46:10 +00:00
weichen 1d82ed8823 merge: candidate sysadmin-maturity-refresh-2026-09-26 into dev 2026-09-26 02:45:12 +00:00
weichen d537778b60 fix(sysadmin): refresh feature maturity catalog to post-rollout wiring facts
The static adapter catalog still read I2-era states (degraded/shadow) after
the 2026-09-26 dev rollout, so the admin features page showed 降级 for flags
already enabled. Update six entries to live+ready with evidence-dated
reasons (I2/I3/P8 acceptance, P8 per-key gates kept visible, shadow
visibility digest now persisted, REPLACE wildcard wiring, PI narrative dev
rollout); keep FAV red lines untouched. Tests updated; FAV now carries the
configured-value-must-not-imply-readiness assertion.
2026-09-26 02:45:05 +00:00
weichen 1d13a892fc merge: candidate degraded-flags-enable-2026-09-26-r4 into dev 2026-09-26 02:39:09 +00:00
weichen 4e7f84111d docs: degraded-flags-enable closeout (task record, dev runtime test report, matrix notes, current claim) 2026-09-26 02:39:05 +00:00
weichen 6b31718138 merge: candidate degraded-flags-enable-2026-09-26-r4 into dev 2026-09-26 02:29:36 +00:00
weichen e9c0281404 feat(ctxmgr): wildcard session allowlist for semantic replace rollout
- SEMANTIC_SUMMARY_REPLACE_SESSIONS supports * (all sessions, present and
  future), mirroring INTENT_PLAN_PROJECT_ALLOWLIST; empty allowlist still
  replaces nothing (fail-closed defense in depth unchanged)
- declare SEMANTIC_SUMMARY_REPLACE(_SESSIONS) in dev/test/main compose app
  env (stale Wave2 "REPLACE unwired" comment fixed); extend A-4 declaration
  test; .env.example key docs updated
- sysadmin feature catalog: SESSIONS description + REPLACE reason note *

Prepares dev degraded-flags enable (task degraded-flags-enable-2026-09-26-r4):
user-authorized all-session replace, plan tier confirm, shadow summary, PI
change-report narrative; env ops and runtime verification follow.
2026-09-26 02:29:29 +00:00
weichen 66ea4e3e51 merge: candidate deploy-record into dev 2026-09-26 02:15:20 +00:00
weichen c9e2263325 docs: record review-fixes deployment verification (dev 1ceda34c live IDOR probe) 2026-09-26 02:15:11 +00:00
weichen 1ceda34c43 merge: candidate integrate-review-fixes (report + P0/P1 fixes) into dev 2026-09-26 02:08:50 +00:00
weichen 467e64574f docs: closeout review report + fix task records for batch integration 2026-09-26 02:07:45 +00:00
weichen 438fdc8686 merge: system code review report into dev
# Conflicts:
#	.doc/ops/CURRENT.md
2026-09-26 02:06:58 +00:00
weichen dfd9c420d3 docs(current): pre-align claim table for review-report merge (docs apply @document) 2026-09-26 02:06:02 +00:00
weichen fb376c0ea0 merge: candidate system-review-p0-p1-fixes into dev 2026-09-26 02:02:42 +00:00
weichen ea66f4456f docs: review P0/P1 fix records, ISSUES ledger, lesson, task claim
- remediation master record for 5 resolved + 1 deferred + 1 open issues
- ISSUES.md rows with evidence dates and lesson links
- LESSON-20260926-failclosed-bypass-contract (validated)
- remediation/lessons INDEX hooks + CURRENT task row (docs apply receipt)
2026-09-26 02:00:24 +00:00
weichen 6a3a0dc201 fix(security): harden bypass authz, gate blind spot, command exec, validated_only (review P0/P1)
- FIND-SEC-01: GetUserContext requires session ownership (handler 403 +
  SQL/memory owner filter); in-memory HTTP + isolated-PG regressions
- FIND-ARCH-01: archtest fails closed on untracked table writes (+noise
  exemption) and registers 50 existing writer tables in table_owners
- FIND-SEC-02: Authorizer without pool denies by default; explicit
  NewInMemoryAuthorizer seam opt-in via ALLOW_IN_MEMORY at composition
- FIND-SEC-03: swboot commands run argv-exec (no sh -c) with exact
  basename allowlist match; prefix-spoof and no-shell-eval tests
- FIND-FLOW-01: confirm rejects validated_only plans; ExecuteClaimed
  hard-refuses validated_only steps (new error codes + HTTP mapping)
- FIND-QUAL-01: intentflow.ValidateFlagConsistency fail-fast at Assemble
2026-09-26 02:00:14 +00:00
weichen b6e382e58f docs(ops): 标记 system-code-review 认领为 done 2026-09-26 01:34:08 +00:00
weichen c7e9ec0a26 docs(audit): 系统全面 code review 报告(仅分析不修复)
记录 tip f4c1b73f 上架构/安全/可维护性/关键路径审查结论;不实施代码修复。
2026-09-26 01:33:41 +00:00
weichen f4c1b73f28 merge: candidate swboot-closeout-2026-09-26-r3 into dev 2026-09-26 01:09:32 +00:00
weichen f697420db8 docs(status): promote workflow-swboot to done — SWBOOT-10 executor + L5/L6 verified 2026-09-26 01:09:20 +00:00
weichen 7c7a08a3ca docs(test): swboot closeout evidence — executor e2e, L5 live PI, L6 playwright wizard 2026-09-26 01:08:51 +00:00
weichen 86e0cf46c6 merge: candidate swboot-closeout-2026-09-26-r2 into dev 2026-09-26 01:00:51 +00:00
weichen a52816299d fix(server): read bound repo from project_source_bindings.source_ref 2026-09-26 01:00:37 +00:00
weichen 70f3028cdb merge: candidate swboot-closeout-2026-09-26-r2 into dev 2026-09-26 00:59:21 +00:00
weichen f394bb15f9 fix(projectworkflow): write repo binding into project_source_bindings.source_ref 2026-09-26 00:59:08 +00:00
weichen 4965e74d66 merge: candidate swboot-closeout-2026-09-26-r2 into dev 2026-09-26 00:57:11 +00:00
weichen 83561682eb feat(swboot): wire SWBOOT-10 controlled patch executor (fail-closed)
DB-backed repo_path_allowlist reader (deny-all until admin seeds), per-prefix
admin test_commands (goose 00075), execution evidence table (goose 00074),
isolated git-worktree patch executor with command allowlist/time/output caps
and failure-stops evidence; controlled_patch creation/preview unlocked only
with an allowlisted repo binding (projectworkflow gate + catalog flag);
creator-only server endpoints for bindings/executions; merge/push/deploy stay
behind a typed separate-authorization boundary. Module boundary: app->swboot
composition import registered.
2026-09-26 00:56:59 +00:00
weichen d0f3f76f7e merge: candidate rdev-p3-rerun-2026-09-26-r4 into dev 2026-09-26 00:43:04 +00:00
weichen 88e9b8bade docs(test): archive P3 rerun console log (rename out of ignored *.log) 2026-09-26 00:43:00 +00:00
weichen 09e4c08f28 merge: candidate rdev-p3-rerun-2026-09-26-r3 into dev 2026-09-26 00:42:20 +00:00
weichen c9d94545f8 docs(status): promote workflow-rdev to done — P3 real-PI rerun all-pass 2026-09-26 00:42:09 +00:00
weichen 68d29ef04e docs(test): rdev P3 real-PI rerun all-pass; register docgov approval-chain issues 2026-09-26 00:41:47 +00:00
weichen 5d5cd5fd6d merge: candidate rdev-p3-rerun-2026-09-26-r3 into dev 2026-09-26 00:25:12 +00:00
weichen dc26321bab fix(docgov): join ambient uow in persistApproveAndFAV to avoid row-lock deadlock
docflow Commands.run takes SELECT ... FOR UPDATE on document_records inside
its unit of work before calling ApproverApprove; persistApproveAndFAV then
opened a second pool connection and its UPDATE blocked on that row lock until
statement timeout (SQLSTATE 57014), failing every final approval. Join the
ambient uow scope (doc sync + FAV staging on the caller tx, commit owned by
the uow); only open an own tx when no scope is present. Regression test
reproduces the production shape (FOR UPDATE + FAV wiring inside Within).
2026-09-26 00:25:01 +00:00
weichen 6bd6e91606 merge: candidate rdev-p3-rerun-2026-09-26-r3 into dev 2026-09-26 00:22:20 +00:00
weichen 043c66ccfb chore(server): log docgov approver decision failures (envelope redacts internals) 2026-09-26 00:22:15 +00:00
weichen 121b33f8ed merge: candidate rdev-p3-rerun-2026-09-26-r2 into dev 2026-09-26 00:16:08 +00:00
weichen bf3136490d fix(docgov): load review_snapshot_id when reading document records from PG
loadDocumentFromDBLocked selected every column except review_snapshot_id,
so any document loaded after a restart or cache miss lost its frozen review
snapshot and ApproverApprove failed with "approved requires frozen
review_snapshot_id". PG regression test seeds a snapshot and asserts a
fresh engine carries the id through load.
2026-09-26 00:15:56 +00:00
weichen a6d25afa27 merge: candidate chat-semantic-replace-2026-09-26 into dev 2026-09-25 23:24:55 +00:00
weichen 53d2731849 docs(status): promote chat-semantic-replace to done — fail-closed gray wiring verified 2026-09-25 23:24:45 +00:00
weichen e2cfd88ac0 docs(test): semantic REPLACE fail-closed gray wiring evidence (unit + dev runtime ladder) 2026-09-25 23:24:33 +00:00
weichen 6004494e21 merge: candidate chat-semantic-replace-2026-09-26 into dev 2026-09-25 23:14:16 +00:00
weichen aee774b894 fix(ctxmgr): keep displaced deterministic narrative for rollback-safe replace
Runtime verification found the deterministic generator merges the prior
served narrative, so a replaced (semantic) narrative would linger after
rollback. Store the displaced deterministic narrative in the shadow report
(persisted via shadow_json) and merge that instead when the prior summary
source is semantic_replace.
2026-09-25 23:14:07 +00:00
weichen cd1f846f49 merge: candidate chat-semantic-replace-2026-09-26 into dev 2026-09-25 22:56:45 +00:00
weichen ffa41d78df feat(ctxmgr): wire fail-closed gray REPLACE for chat semantic narrative
Unseal SEMANTIC_SUMMARY_REPLACE under explicit user authorization with a
defense-in-depth session allowlist (SEMANTIC_SUMMARY_REPLACE_SESSIONS):
swap happens only for allowlisted sessions after result digests and served
watermark validation, bounded narrative size; facts/counts stay deterministic
and the daily digest stays advisory. Master flag alone replaces nothing.
2026-09-25 22:56:36 +00:00
weichen 4d5d695c75 merge: candidate jevdecide-soak-2026-09-26 into dev 2026-09-25 22:51:03 +00:00
weichen cbf96ebbe5 docs(status): promote jevdecide-shadow to done — 200-turn soak converged 2026-09-25 22:50:54 +00:00
weichen 96013db9aa docs(test): jevdecide assist soak >=200 turns with 94% handled rate evidence 2026-09-25 22:50:33 +00:00
weichen c373d6fbc0 merge: candidate dialogue-ctx-closeout-2026-09-26-r4 into dev 2026-09-25 21:43:41 +00:00
weichen 4b231d97ec docs(status): promote dialogue-ctx-injection to done — close conditions verified on dev 2026-09-25 21:43:33 +00:00
weichen 416674e3ec docs(test): dialogue-ctx closeout evidence — dev migration + real PI workspace inject + conflict card smoke 2026-09-25 21:43:02 +00:00
weichen f89b946d37 merge: candidate dialogue-ctx-closeout-2026-09-26-r4 into dev 2026-09-25 21:30:41 +00:00
weichen ae48970f5f fix(pi-runner): allow host-side extension path override for task runs
Task-run pi launches hardcoded the container path /app/extensions/tavily-search.mjs;
on the no-docker host sidecar every squad/dialogue task run failed at spawn with
ENOENT/extension-load errors. Add PI_AGENT_EXTENSION override and export the
managed pi-dir extension path from the sidecar start script.
2026-09-25 21:30:29 +00:00
weichen ebb8282091 merge: candidate dialogue-ctx-closeout-2026-09-26-r2 into dev 2026-09-25 21:03:21 +00:00
weichen 76ddf4dd35 feat(ctx): surface dialogue conflict confirmation cards to triggering user
Capture trigger_user HITL expectations from dialogue adjudication (previously
dropped at the bizdev call site), project them as chat confirmation cards via
taskrun OnTerminal (exactly-once), arm the session PendingExpectation, and
handle confirm_context_fact hits through the supplement-info blackboard path.
Decline (纠正) guides the user to state the correct fact.
2026-09-25 21:01:37 +00:00
weichen f6ad3344f8 merge: candidate worktree-final-closeout-2026-09-26 into dev 2026-09-25 20:34:14 +00:00
weichen e6994e4e4e docs(closeout): 回填运行时验证与清理结果;任务收口 done 2026-09-25 20:34:06 +00:00
weichen 0e4b51c387 merge: record feature/dialogue-office-expansion-2026-09-25 into dev ancestry — 内容已由 dialogue-office-expansion-land 等价落地 dev;记录原分支历史归属 (tree unchanged) 2026-09-25 20:32:49 +00:00
weichen 19700e8590 merge: candidate worktree-final-closeout-2026-09-26 into dev 2026-09-25 20:27:01 +00:00
weichen 743b6a4774 docs(closeout): worktree 全量收口——唯一日志归档、CURRENT 漂移修正与本任务登记 2026-09-25 20:26:50 +00:00
weichen dc10818143 merge: record feature/promote-rc-beta3-c-2026-09-24 into dev ancestry — test 晋升分支:全部提交已保留于本地 test 分支头 0e4b111d(tag rc-v1.1.0-beta.3 历史);不引入 dev 树变化 (tree unchanged) 2026-09-25 20:24:51 +00:00
weichen 2a7a700051 merge: record feature/integrate-gov-visibility-p0-b-2026-09-24 into dev ancestry — 取消的重试候选,被 p0-c 替代,仅含 merge 节点 (tree unchanged) 2026-09-25 20:24:40 +00:00
weichen 5f85f3c5d7 merge: record feature/integrate-backlog-triage-p10-r2-2026-09-25 into dev ancestry — 被 r3 候选替代,仅含 merge 节点 (tree unchanged) 2026-09-25 20:24:33 +00:00
weichen 2d3a7a22f8 merge: record feature/integrate-backlog-triage-p10-2026-09-25 into dev ancestry — 被 r2/r3 候选替代,仅含 merge 节点 (tree unchanged) 2026-09-25 20:24:25 +00:00
weichen 043e10f674 merge: record feature/integrate-admin-settings-maint-b-2026-09-25 into dev ancestry — 内容已由后续候选(r3)等价合入 dev(patch-id 查重 8f9b91d3 = dev 等价提交) (tree unchanged) 2026-09-25 20:24:18 +00:00
weichen 357c869a34 merge: record feature/single-binary-deploy-design-2026-09-24 into dev ancestry — 内容已由 single-binary-design-land 等价落地 dev;记录原分支历史归属 (tree unchanged) 2026-09-25 20:24:06 +00:00
weichen db8585b558 merge: record feature/member-permissions-doc-2026-09-24 into dev ancestry — 内容已由 member-permissions-doc-land 等价落地 dev;记录原分支历史归属 (tree unchanged) 2026-09-25 20:23:58 +00:00
weichen 64a28c9842 merge: record feature/doc-review-lifecycle-2026-09-25 into dev ancestry — 交付内容已由 doc-review-lifecycle-land 等价落地 dev;本归并仅记录原分支历史归属 (tree unchanged) 2026-09-25 20:23:25 +00:00
weichen cc519e3806 merge: candidate single-binary-design-land-2026-09-26 into dev 2026-09-25 20:22:59 +00:00
weichen 6733205d58 docs(design): 非容器化单二进制三环境交付方案(自 single-binary-deploy-design 分支落地;CURRENT 认领行已废弃不入) 2026-09-25 20:22:45 +00:00
weichen 23ee0f028d merge: candidate member-permissions-doc-land-2026-09-26 into dev 2026-09-25 20:22:16 +00:00
weichen 6e76a35943 docs(system-design): 修复 README t20 设计文档迁址后的失效链接(remediation→system-design) 2026-09-25 20:21:43 +00:00
weichen 86881bef6e docs(system-design): 新增项目成员权限总览(对话/任务/补充/文档三权整合)
- 三层正交模型:系统角色能力矩阵 / 项目成员角色 / 文档三权(author-reviewer-approver)
- 四类核心动作权限矩阵:发起对话、执行任务、补充信息、文档编制与修改(deny_only_submit)
- 认证与路由分层、管理台两类 gate、前端 capabilities fail-closed 消费方式
- 如实标注已知缺口:member/viewer 服务端不区分写、visibility 键仅前端消费、system:* 未拆分
- 更新 system-design/README.md 索引与目录清单

task: member-permissions-doc-2026-09-24
2026-09-25 20:20:58 +00:00
weichen 75ff922b6e merge: candidate dialogue-office-expansion-land-2026-09-26 into dev 2026-09-25 20:20:39 +00:00
weichen af327950bd docs(plan): 对话办公能力全景盘点与 P0–P3 整改计划
盘点 32 ActionKey 与 HTTP 169 路由对话边界,明确假成功/dry-run 与 UI 专属红线;分期消除假成功、live 化 intentflow、查询真源与新写意图扩展。
2026-09-25 20:20:25 +00:00
weichen 117ef7d826 merge: candidate doc-review-lifecycle-land-2026-09-26 into dev 2026-09-25 20:17:35 +00:00
weichen 6c815b2958 fix(land): 适配 dev 现行结构 — gov()/authorizer() 访问器、去 app/docnotify stream 依赖(arch 基线)、测试 stub 重名 2026-09-25 20:17:20 +00:00
weichen 05b822d9c0 docs(evidence): doc-review-lifecycle-land re-validation 摘要 2026-09-25 20:17:11 +00:00
weichen 985bc55fa5 docs(matrix): docgov 三权流转落地证据与 U11 live 基线键说明;附 re-validation 证据 2026-09-25 20:16:36 +00:00
weichen b5a782bb38 feat(chat): dialogue triggers for comments/reopen/pending-supplements with mistouch guards
Wire intent→coordinator DocResolver confirm cards→action_executor kinds for comment, reopen, pending-supplements query, and real submit-review execution.
2026-09-25 20:14:10 +00:00
weichen 2e56ba9719 feat(docgov): complete review lifecycle gaps for lock/notify/comment/reopen
Defer locked-period supplements to a pending ledger, route duty-holder
notifications, persist stage-scoped comments, and prefer Approver for reopen.
2026-09-25 20:08:56 +00:00
weichen 6adf694f74 merge: candidate matrix-closeout-r3-2026-09-26 into dev 2026-09-25 19:05:04 +00:00
weichen f0b23d345a docs(matrix): update u9u12 and web-sysadmin row footnotes per P8/P9 evidence
- intent-plan-u9u12: per-key live rollout landed (7 keys to real engines,
  5 per-key flags default off, TierConfirm; dev c5027788); ops-side flag
  enablement + PI evidence follow-up noted
- web-sysadmin: residual closeout complete (ui.* whitelist consumers wired
  to public site-status + banner; Playwright real-run PASS via docker image;
  KB ops deferred out-of-repo with rationale; dev 4bdbb0da)
- rows keep status=done; footnote facts only; docs apply receipts r3
2026-09-25 19:04:34 +00:00
weichen 2391aaa7ec merge: candidate cleanup-audit-r3-2026-09-25 into dev 2026-09-25 18:43:24 +00:00
weichen 8ffb83e373 docs(current): register P11/P12 closeout rows via docs apply receipt 2026-09-25 18:42:36 +00:00
weichen 3f63753b63 docs(ops): P12 redline boundary audit (read-only)
- FAV live off (FAV_DEGRADED_READ unset, default false); no observation window running
- SWBOOT-10 fail-closed confirmed (ERR_EXECUTION_MODE_DISABLED in catalog.go L209);
  L5/L6 authorization application registered as pending-auth
- D7 ADR still pending-compliance-signoff; record retention physical delete blocked
- PI narrative flag PI_CHANGE_REPORT_NARRATIVE off in dev process env; dev-resident
  enablement request registered for user decision (not implemented)
- MULTI_INTENT_PLAN_TIER not full; F4-B/F7-1/I6/I7 untouched
2026-09-25 18:24:52 +00:00
weichen 30957daf40 merge: candidate cleanup-audit-p11-2026-09-25 into dev 2026-09-25 18:14:06 +00:00
weichen 748eb686ae docs(ops): P11 cleanup audit - 19 ready worktrees cleared, blocked classified
- ready batch: worktree remove + branch -d all clean, no force
- blocked split: keep branches with unmerged features (doc-review-lifecycle,
  dialogue-office-expansion, member-permissions-doc, single-binary-design,
  promote/sync test branches); regenerable caches logged; unique logs to
  archive before removal
- CURRENT stale in_progress rows deferred to closeout audit P14
- copy-kb-to-localpg.sh: never existed; migrate_shared_kb.sh already registered
2026-09-25 18:12:54 +00:00
weichen 3cefd5b142 merge: candidate backlog-triage-p10-2026-09-25 into dev 2026-09-25 17:20:39 +00:00
weichen 9ac4e37847 docs(ops): P10 backlog triage record (B5+A5 implement; A6/D5/R1/R4-R7 no-go evidence) 2026-09-25 17:20:22 +00:00
weichen da0fc54f91 merge: candidate backlog-triage-p10-2026-09-25 into dev 2026-09-25 17:17:06 +00:00
weichen 20afeb186b chore: requeue marker after DIRTY_TREE (node_modules symlink removed)
Queue item e1b8dd58 failed on source-tree dirt from a web/node_modules
symlink used for npm test; the symlink is removed and the tree is clean.
Empty commit advances head so the queue accepts a fresh item.
2026-09-25 17:16:36 +00:00
weichen ee852c6600 merge: candidate backlog-triage-p10-2026-09-25 into dev 2026-09-25 17:10:55 +00:00
weichen 53d1be5349 feat(quote,squad): B5 input validation + review invariants; A5 non-critical step degradation
P10 backlog triage (implement B5+A5; A6 already fixed in-tree, D5 keep shared
KB, R1 separate task, R4/R5/R6/R7 no-go with evidence):

- quote: ValidateInput (empty names/hours, negative/NaN/Inf fail-closed);
  reviewSummary invariants (line sums = total; buffer 20%/margin 40%/tax 7%
  rate self-consistency) enforced before Excel write
- squad: StepSpec.Critical *bool (nil=critical default); non-critical step
  failure marks step degraded + gov audit, workflow continues, final status
  degraded with DegradedSteps list; critical failure semantics unchanged
- tests: 5 new cases (quote 3 + squad 2), full short suite green, arch-check pass
2026-09-25 17:10:35 +00:00
weichen 4bdbb0da6f merge: candidate websysadmin-residual-r2-2026-09-25 into dev 2026-09-25 16:35:19 +00:00
weichen 923da11ab4 feat(server): public /maintenance/site-status route + tests; P9 evidence
- isPublicRoute exempts site-status (anonymous banner polling)
- httptest coverage: anonymous 200 + site_notice payload; route table guards
- test report + playwright evidence (docker mcr playwright v1.63 noble vs real dev stack, 1 passed)
2026-09-25 16:33:58 +00:00
weichen 914d0aa39d feat(maintenance): wire sysadmin ui.* whitelist settings to public site status
- sysadmin.Service.GetSettingValue: whitelist read-through (DB > env > default)
- maintenance.Service: SiteSettingsProvider injection; StatusView carries notice/readOnly; new CurrentSiteStatus + GET /api/v1/maintenance/site-status
- composition root wires ui.maintenance_notice / ui.read_only_mode into maintenance site settings
- MaintenanceBanner: persistent notice banner + read-only mode strip
- chore(web): drop dead 'dirty' var in EnvSettingsSection (baseline TS6133 build blocker)
- KB ops actions: deferred out-of-repo (shared infra container side); documented in task record
2026-09-25 16:33:56 +00:00
weichen cc998c05ce merge: candidate dialogue-office-p0-2026-09-25 into dev
Resolve server.go ActionServices wiring on accessor-style Server (Workflow via adaptChatWorkflow).
2026-09-25 15:42:05 +00:00
weichen c5027788ea merge: candidate u9u12-keys-rollout-2026-09-25 into dev 2026-09-25 14:39:51 +00:00
weichen f9ce771954 feat(intentflow): per-key live rollout for remaining U9-U12 validated_only keys
- 5 independent flags (MULTI_INTENT_U11_LIVE_REVIEW/FINAL/PROPOSAL, U12_LIVE_SWITCH/RESTART), default OFF; no full rollout
- DocGovLiveActionKeys/RunControlLiveActionKeys become flag-driven functions; baseline keys unchanged
- DocGovOwner routes review.approve/reject, final.approve/reject, proposal.decide to real engine with slot-driven reason/approve parsing and idempotent receipts
- RunControlOwner routes workflow.switch -> ActivateWorkflow and run.restart -> fresh CreateAndStart run
- policy: 7 keys promoted from TierFull to TierConfirm (real execution still gated per-key)
- tests: default-off isolation, per-key independence, live state advance reviewing->approving, dry-run zero-advance when flag off
2026-09-25 14:38:42 +00:00
weichen da0186c739 docs(remediation): 将对话办公 P0 验证记录挂入 INDEX 2026-09-25 14:38:06 +00:00
weichen 0ab4a8bd2d feat(server): 接线对话 workflow.run 并补 P0 验证记录
server 侧窄端口适配 projectworkflow,消除 chat→projectworkflow 边界违规;记录单测与 arch-check 证据,PI 全链路待补证。
2026-09-25 14:37:11 +00:00
weichen 9a540fa54a docs(chat): 注明 ActionServices.Workflow 合入接线点
app/server 写路径被并行任务占用,生产接线延后;未接线时诚实失败。
2026-09-25 13:19:52 +00:00
weichen ce694baef1 feat(coordinator): P0 消除对话主链路假成功
claim/submit 经 DocResolver+确认卡后 PendingAction 真写 docgov;proposal 默认分支改澄清;workflow.switch 诚实拒绝(UI专属);workflow.run 确认后走 CreateWorkflowRun(ActionServices.Workflow 由合入时接线)。
2026-09-25 13:19:36 +00:00
weichen 9f7bbc25a0 merge: candidate server-image-field-closeout-r4-2026-09-25 into dev 2026-09-25 13:19:00 +00:00
weichen 0634ffb8ee fix(storage): deterministic ID ordering in memory-mode ListProjectRefs
Memory CAS iterated memoryRefs map (random order) while PG path uses
ORDER BY id ASC; asset dedup-hint 'first reference unflagged' logic
depends on stable order. Flaky TestUploadProjectAsset_DedupHint
reproduced 2/20 rounds before fix, green 30/30 after.
2026-09-25 13:17:25 +00:00
weichen a9c9a9182e refactor(server): remove 24 mirrored Runtime fields via nil-safe accessors; fix Shutdown-vs-background-loop DATA RACE and goose 00071 duplicate version
- Server no longer mirrors app.Runtime services (gov/svc/pwSvc/...): 574 call sites now use accessors in runtime_accessors.go
- backgroundLoop (mutex+sync.Once) stops sweeper/publisher/reminder/wsGC goroutines race-free (baseline 44161d2a reproduced DATA RACE; now green under -race)
- goose 00071 duplicate (dialogue merge 1da17a28 brought two 00071): context-conflict-adjudications renumbered to 00072; dev DB applied only through 00070 so zero data migration
- task_finalize tests build minimal app.Runtime; test injection via serverTestOverrides + setOverride* (explicit-nil markers for fail-closed cases)
2026-09-25 13:17:22 +00:00
weichen 7cfd6851f6 merge: candidate security-redline-fp-r2-2026-09-25 into dev 2026-09-25 12:53:32 +00:00
weichen 7bdb045272 fix(intent): 收紧安全红线正则动词与桥接,消除正常撰写请求误拦
裸单字「改/换」加无界桥接会把「整改/角色」等正常撰写句误判为
SECURITY_FORBIDDEN。改为复合动词 + 短窗不跨标点桥接,受控名词须与写动词共现;补误报负例回归。
2026-09-25 12:53:08 +00:00
weichen 09ffe7dea8 docs(plan): 对话办公能力全景盘点与 P0–P3 整改计划
盘点 32 ActionKey 与 HTTP 169 路由对话边界,明确假成功/dry-run 与 UI 专属红线;分期消除假成功、live 化 intentflow、查询真源与新写意图扩展。
2026-09-25 11:15:44 +00:00
weichen 44161d2ad2 merge: candidate t20-s3-lock-split-2026-09-25 into dev 2026-09-25 06:53:29 +00:00
weichen 340342faf8 feat(concurrency): T20 S3 B3 - per-docID lock split for docgov/docrevision, hydrate out of cross-doc critical path (stage A) 2026-09-25 06:52:55 +00:00
weichen d93c1ab3d6 merge: candidate t20-s4-image-batch-2026-09-25 into dev 2026-09-25 05:42:56 +00:00
weichen 35f845168b feat(infra): T20 S4 image batch - non-root appuser, compose resource limits, unified extensions init mount (I1/I4) 2026-09-25 05:42:05 +00:00
weichen 42436f754d merge: candidate t20-b5-chat-observability-2026-09-25-r2 into dev 2026-09-25 05:26:59 +00:00
weichen 5201f14173 feat(ctxmgr,server): T20-B5 chat turn compensation observability + orphan sweeper 2026-09-25 05:26:29 +00:00
weichen 088ff307c0 merge: candidate t20-s2-config-pool-2026-09-25-r2 into dev 2026-09-25 04:46:53 +00:00
weichen 2abc23ac65 feat(db,server): T20-S2 hardening batch B1/B4/B7 (XFF trust, pool statement_timeout, shutdown drain) 2026-09-25 04:45:49 +00:00
weichen c0e556b167 merge: candidate t20-s1-small-fixes-2026-09-25 into dev 2026-09-25 04:25:31 +00:00
weichen d653e32e7b fix(server,web): T20-S1 hardening batch B11/F1/F8/F4-A 2026-09-25 04:25:03 +00:00
weichen b74b92920e merge: candidate planned-tasks-closeout-2026-09-25-r2 into dev 2026-09-25 04:10:58 +00:00
weichen caba4b086a docs(ops): land closeout plan P0 status and docrev acceptance audit 2026-09-25 04:07:17 +00:00
weichen 12bbe948b2 merge: candidate fix-stage-brief-panic-2026-09-25 into dev 2026-09-25 04:04:46 +00:00
weichen bc94080332 fix(coordinator,intent): nil AdvisorBrief panic guard + interrogative gate for ADVANCE_STAGE overmatch 2026-09-25 04:04:30 +00:00
weichen 1da17a282c merge: candidate dialogue-context-layout-fix-2026-09-25 into dev 2026-09-25 04:01:46 +00:00
weichen 2f9a6eb588 docs(current): move dialogue claim rows to table end to unblock integration 2026-09-25 03:51:08 +00:00
weichen 1fd2f16726 docs(current): mark dialogue-ctx r2 claim done for integration 2026-09-25 03:02:36 +00:00
weichen 5a70fd6940 docs(ops): plan batch closeout of inventoried planned tasks 2026-09-25 01:39:11 +00:00
weichen 09fe972366 feat(chat): dialogue triggers for comments/reopen/pending-supplements with mistouch guards
Wire intent→coordinator DocResolver confirm cards→action_executor kinds for comment, reopen, pending-supplements query, and real submit-review execution.
2026-09-25 00:36:26 +00:00
weichen 725181de4a merge: candidate admin-settings-maint-b-2026-09-25 into dev 2026-09-24 23:27:05 +00:00
weichen fd0ea3f2d7 docs(ops): mark admin-settings-maint claim done 2026-09-24 23:26:56 +00:00
weichen 675e09a1a7 merge: candidate admin-settings-maint-b-2026-09-25 into dev 2026-09-24 23:24:54 +00:00
weichen b5a308dd11 docs(test): note queue retry after DIRTY_TREE clear 2026-09-24 23:24:45 +00:00
weichen 8f9b91d3b3 docs(test): note queue retry after DIRTY_TREE clear 2026-09-24 23:24:15 +00:00
weichen 129736f281 merge: candidate admin-settings-maint-b-2026-09-25 into dev 2026-09-24 23:22:21 +00:00
weichen 728567c778 fix(handoff): remove unused stubSrc from e2e test 2026-09-24 23:21:39 +00:00
weichen 9424d19106 fix(handoff): clean e2e stub builder unused import 2026-09-24 23:21:30 +00:00
weichen 86e9d3706b feat(sysadmin): admin env settings + maintenance FD handoff
Persist agent/secrets settings with masked secrets and runner hot-reload;
add maintenance windows, maintpage binary, and zero-downtime listener handoff.
2026-09-24 23:20:20 +00:00
weichen 986d78cc91 feat(docgov): complete review lifecycle gaps for lock/notify/comment/reopen
Defer locked-period supplements to a pending ledger, route duty-holder
notifications, persist stage-scoped comments, and prefer Approver for reopen.
2026-09-24 23:06:23 +00:00
weichen dc29b84cdf feat(ctx): inject cleaned project dialogue into squad and assistant
Add dialoguectx packaging, conflictresolve adjudication with HITL routing,
workspace context/dialogue/ injection (default on), and goose 00071.
2026-09-24 17:04:04 +00:00
weichen 4e410efbab merge: candidate single-binary-dev-impl-b-2026-09-24 into dev 2026-09-24 16:33:53 +00:00
weichen 6cbe7e6e56 fix(web): committed dist/.gitkeep keeps go:embed satisfiable pre-build 2026-09-24 16:20:21 +00:00
weichen cc90d39205 fix(web): placeholder keeps go:embed satisfiable pre-build 2026-09-24 16:18:23 +00:00
weichen 69645cb07b fix(web): tolerate absent dist at compile time via LookupDist 2026-09-24 16:13:47 +00:00
weichen 59ad970ad5 merge: candidate dm-migration-2026-09-24-r2 into dev 2026-09-24 15:57:06 +00:00
weichen c428fc5e91 docs(ops): closeout Development-Manager migration task 2026-09-24 15:56:36 +00:00
weichen b812d1d30f feat(dev): single-binary no-docker runtime with managed localpg
Embed web/dist, run events in-process, manage brew PG18+pgvector, add PI host sidecar and launch --no-docker; unify MiniMax-M2.7-highspeed pins and record dev acceptance.
2026-09-24 15:53:50 +00:00
weichen 67cc8f13af docs(ops): register Development-Manager migration task 2026-09-24 15:35:52 +00:00
weichen 588fef1c4a docs(ops): 收口单二进制设计任务状态与提交 SHA 2026-09-24 14:45:46 +00:00
weichen d784daf884 docs(ops): CURRENT 认领 member-permissions-doc-2026-09-24 行
task: member-permissions-doc-2026-09-24
2026-09-24 14:45:21 +00:00
weichen 7ebf431c87 docs(design): 非容器化单二进制三环境交付方案
覆盖 dev managed / test 落地 / main attach,PI sidecar 外置;设计评审用,未实施。
2026-09-24 14:45:06 +00:00
weichen e2a442b592 docs(system-design): 新增项目成员权限总览(对话/任务/补充/文档三权整合)
- 三层正交模型:系统角色能力矩阵 / 项目成员角色 / 文档三权(author-reviewer-approver)
- 四类核心动作权限矩阵:发起对话、执行任务、补充信息、文档编制与修改(deny_only_submit)
- 认证与路由分层、管理台两类 gate、前端 capabilities fail-closed 消费方式
- 如实标注已知缺口:member/viewer 服务端不区分写、visibility 键仅前端消费、system:* 未拆分
- 更新 system-design/README.md 索引与目录清单

task: member-permissions-doc-2026-09-24
2026-09-24 14:43:00 +00:00
weichen edbe592478 merge: candidate governance-console-p1-impl-2026-09-24 into dev 2026-09-24 14:17:55 +00:00
weichen 610b97b93e docs(ops): closeout governance-console-p1-impl 2026-09-24 14:17:34 +00:00
weichen f6eaff7878 merge: candidate governance-console-p1-impl-2026-09-24 into dev 2026-09-24 14:16:58 +00:00
weichen 77c602c8f4 fix(agentctl): resume integrate prepare from clean expected tip
After abort, allow a clean worktree parked on expected-dev to continue merge instead of BASE_CHANGED.
2026-09-24 14:16:48 +00:00
weichen f5cdae1a41 fix(agentctl): fence integrate prepare merge via supervise
Pre-commit requires AGENTCTL_FENCE; run merge --no-ff through supervise like integrate ff-only.
2026-09-24 14:15:50 +00:00
weichen f9f055bee1 feat(agentctl): add governance console P1 serve and action APIs
Implement loopback HTTP console with claim new, integrate prepare, and pi packet sharing the same helpers as CLI; ship SPA and MCP brief/claim_archive wrappers.
2026-09-24 14:13:27 +00:00
weichen 6eb2d11eeb merge: closeout governance-console-p1-design 2026-09-24 13:55:27 +00:00
weichen 0d58e6fb2d docs(ops): closeout governance-console-p1-design 2026-09-24 13:55:23 +00:00
weichen ae7fcc1557 merge: candidate governance-console-p1-design into dev 2026-09-24 13:54:37 +00:00
weichen fad32cd820 docs(ops): finalize governance console P1 implementable design
Expand the P1 plan to a 12-section implementable spec (serve API,
claim new, integrate prepare, pi packet, SPA, tests, risks) without
code. Task record and CURRENT claim included.
2026-09-24 13:54:22 +00:00
weichen 4844041b1b merge: closeout governance-visibility-p0 2026-09-24 13:36:43 +00:00
weichen 9eea950d57 docs(ops): closeout governance-visibility-p0 on local_dev 2026-09-24 13:36:25 +00:00
weichen ab450c1181 merge: candidate governance-visibility-p0 into dev 2026-09-24 13:33:22 +00:00
weichen 2c6088c200 merge: candidate cursor-zh-session-title into dev 2026-09-24 13:27:25 +00:00
weichen 06757ff31f merge: candidate governance-visibility-p0 into dev 2026-09-24 13:27:09 +00:00
weichen f2644db6d8 docs(cursor): 会话自动命名使用简体中文
新增 alwaysApply 规则,要求 Cursor 对话标题/会话名称以简体中文概括任务主题。
2026-09-24 13:26:53 +00:00
weichen f29a69b8a1 docs(ops): claim CURRENT row for governance-visibility-p0 2026-09-24 13:26:07 +00:00
weichen 0d1840da96 feat(agentctl): governance visibility P0 — table/brief/archive + MCP reads
Add human-readable --format table, one-page brief, claim archive via docs
apply CAS, and four MCP readonly tools. Includes P1 console design doc
and engineering-tool test evidence.
2026-09-24 13:25:57 +00:00
weichen a2afa67d47 merge: candidate retire diverged worktree tips into local_dev 2026-09-24 12:35:49 +00:00
weichen d7d951542d merge: retire redundant tip feature/integrate-intent-plan-u9u12-close-2026-09-24 (content already on local_dev / superseded) 2026-09-24 12:35:17 +00:00
weichen da42769160 merge: retire redundant tip feature/integrate-fix-fav-staging-uuid-2026-09-24 (content already on local_dev / superseded) 2026-09-24 12:35:16 +00:00
weichen 2d91f0ee7d merge: retire redundant tip feature/integrate-codegraph-current-2026-09-24 (content already on local_dev / superseded) 2026-09-24 12:35:14 +00:00
weichen a81b9554c0 merge: retire redundant tip fix/gate-unhook-docquery-2026-09-24 (content already on local_dev / superseded) 2026-09-24 12:35:13 +00:00
weichen 2d42cbd678 merge: retire redundant tip fix/gate-e1a-unique-project-name-2026-09-24 (content already on local_dev / superseded) 2026-09-24 12:35:12 +00:00
weichen 275624591c merge: retire redundant tip fix/fix-nightly-abs-datadir-2026-09-24 (content already on local_dev / superseded) 2026-09-24 12:35:11 +00:00
weichen 50b1a6144b merge: retire redundant tip fix/fix-fullchain-unique-project-2026-09-24 (content already on local_dev / superseded) 2026-09-24 12:35:10 +00:00
weichen ab52f79034 merge: retire redundant tip feature/dev-full-gate-test-promo-2026-09-24 (content already on local_dev / superseded) 2026-09-24 12:35:08 +00:00
weichen 0f50991288 merge: retire redundant tip feature/admin-password-reset-2026-09-24 (content already on local_dev / superseded) 2026-09-24 12:35:07 +00:00
weichen 245e6202d2 merge: candidate worktree-cleanup inventory into local_dev 2026-09-24 12:33:52 +00:00
weichen 18fbec23e4 docs(ops): worktree cleanup inventory and CURRENT done drift fix
Record removed ready worktrees and cleanup_pending not_ancestor tips;
mark stale admin/gate CURRENT rows done to match task registry.
2026-09-24 12:33:39 +00:00
weichen fabd85a65e merge: candidate non-author closeout into local_dev
CI / go-vet-and-short-test (push) Failing after 0s
CI / backup-restore-drill (push) Failing after 0s
CI / web (push) Failing after 0s
2026-09-24 12:22:29 +00:00
weichen 24a5e6dbbb docs(ops): mark non-author member-access CURRENT claims done
Record five-state closeout rows after local_dev merge and origin/dev push.
2026-09-24 12:22:16 +00:00
weichen 26673d0ae0 docs(ops): record non-author member-access five-state closeout
Mark review/integration/remote_sync after local_dev merge and origin/dev push.
2026-09-24 12:21:41 +00:00
weichen e98e2d716c merge: candidate non-author-member-access docs into local_dev
CI / go-vet-and-short-test (push) Failing after 1s
CI / backup-restore-drill (push) Failing after 0s
CI / web (push) Failing after 0s
2026-09-24 12:14:22 +00:00
weichen 8b2621a4d1 docs(test): add non-author member PI e2e console log asset 2026-09-24 12:13:47 +00:00
weichen b739f358f8 docs(test): non-author member deny_only_submit PI evidence and MATRIX
Archive real PI acceptance for member run/edit vs submit duty gates;
register ISSUE/LESSON and refresh MATRIX/gap/authz matrix evidence.
2026-09-24 12:13:31 +00:00
weichen e43f4c6970 merge: free-collab CURRENT/MATRIX docs closeout into local_dev 2026-09-24 11:54:27 +00:00
weichen f769385853 docs(ops): mark free-collab integrate done and link MATRIX evidence 2026-09-24 11:54:25 +00:00
weichen 80a7736199 merge: free-collab test report into local_dev 2026-09-24 11:53:05 +00:00
weichen a1d70f5bd0 merge: candidate free-collab claim-notify + free-lane into local_dev 2026-09-24 11:51:50 +00:00
weichen 143ee934b8 feat(collab): free-lane chat, claim-on-view, lease ownership, notify inbox
Open member free-lane for chat initiation; auto-claim on author view;
harden lease persist/ownership with readable DOC_BUSY; add notification
inbox and supplement-impact HTTP decision APIs wired to composition root.
2026-09-24 11:49:43 +00:00
weichen 098c1fd73a docs(test): free-collab claim-notify short-suite evidence report 2026-09-24 11:49:42 +00:00
weichen d0b4d3d4dd fix(arch): allow server→supplementimpact and tighten HTTP batch ExpiresAt 2026-09-24 11:45:54 +00:00
weichen 4e0e6a1418 feat(notification): digest aggregates, supplement-impact batch, and free-collab hooks
Add notification digests with ON CONFLICT DO UPDATE, migrations 00068-00070,
supplementimpact module (analyze → confirm → claim-aware split), and wire
coordinator/mutate hooks plus proposal_required digests.
2026-09-24 11:44:20 +00:00
weichen ebb36fb85c merge: candidate MCP NDJSON framing into dev 2026-09-24 10:39:54 +00:00
weichen 36793a4ea5 fix(tooling): emit NDJSON MCP responses for agentctl and jev
Cursor IDE loads pi-subagents (NDJSON) but not agentctl/jev which replied
with Content-Length framing. Align send() and mark type=stdio in mcp.json.
2026-09-24 10:39:43 +00:00
weichen 03fd135593 merge: candidate fix MCP: hook prefix into dev 2026-09-24 10:36:00 +00:00
weichen 476e97c993 fix(tooling): strip MCP: prefix in Cursor hook tool_name matching
IDE postToolUse reports tool_name as MCP:pi_subagent_*; without stripping,
guard-pi-dispatch skipped shape checks. Confirmed via live pi_subagent_roles.
2026-09-24 10:35:51 +00:00
weichen 5392db8ecb merge: cursor governance closeout docs into dev 2026-09-24 09:34:09 +00:00
weichen ea1457231e docs(tooling): close cursor governance CURRENT claim after local_dev merge 2026-09-24 09:33:55 +00:00
weichen 57cbd57139 merge: candidate cursor-governance-hooks into dev 2026-09-24 09:30:49 +00:00
weichen 2b3b1c6f5b merge: sync feature with local_dev 4490b6ef
Align CURRENT via docs apply @document (keep catalog + cursor-governance
rows); retain both policy-registry sections and lessons index rows.
2026-09-24 09:30:31 +00:00
weichen 5618cfc8cf feat(tooling): add Cursor governance hooks, skills, and rule pointers
Layer advisory Cursor hooks and skills on the PI executor, shrink the
test-report rule to the validation contract, and fix MCP relative paths.
2026-09-24 09:25:38 +00:00
weichen 4490b6ef76 merge: governance catalog closeout into dev 2026-09-24 09:25:28 +00:00
weichen 0217ce354b docs(tooling): close governance catalog claim and task record 2026-09-24 09:25:14 +00:00
weichen e1796cc858 merge: candidate governance-catalog into dev 2026-09-24 09:22:22 +00:00
weichen 319b397419 docs(test): archive governance catalog unittest evidence 2026-09-24 09:22:09 +00:00
weichen 28ed7005dd feat(tooling): add governance catalog and requirement overlap gates
Extend agentctl SQLite with catalog tables, CJK FTS5 recall, hard/soft
overlap gates, fail-open embeddings, backfill, and MCP/skills hooks so
cross-conversation designs cannot silently conflict.
2026-09-24 09:21:57 +00:00
weichen cfc80b34a4 docs(tooling): integrate PI executor validation and closeout 2026-09-24 05:58:32 +00:00
weichen 9744a2e2d0 docs(tooling): close PI integration coordination record 2026-09-24 05:58:26 +00:00
weichen e6dad5b25e docs(tooling): record PI executor dev integration and validation 2026-09-24 05:57:39 +00:00
weichen 5a8540804e feat(tooling): integrate automatic PI subagent executor into dev 2026-09-24 05:54:59 +00:00
weichen 655397547f chore(tooling): reconcile PI executor branch with current dev 2026-09-24 05:54:49 +00:00
weichen 930447a78c docs(tooling): reconcile PI integration records with current dev 2026-09-24 05:51:37 +00:00
weichen c1a70e67e5 merge: candidate agentctl-daemon-load-2026-09-24 into dev (r8) 2026-09-24 05:45:16 +00:00
weichen de2ba94933 merge: CURRENT claim closeout for gate promo
CI / go-vet-and-short-test (push) Failing after 0s
CI / backup-restore-drill (push) Failing after 1s
CI / web (push) Failing after 0s
2026-09-24 05:12:21 +00:00
weichen 77ba9deee1 docs(ops): close CURRENT claims for gate promo and beta.3 2026-09-24 05:12:10 +00:00
weichen 614ebb8d1b docs(ops): mark dev-full-gate-test-promo CURRENT claim done 2026-09-24 05:10:49 +00:00
weichen 4bbbd0f8bc merge: docs-gate CURRENT done into integrate 2026-09-24 05:09:44 +00:00
weichen 866254de0e docs(ops): mark docs-gate-promo-report CURRENT claim done 2026-09-24 05:09:36 +00:00
weichen 6e74203857 merge: candidate docs-gate-promo-report into local_dev
CI / go-vet-and-short-test (push) Failing after 0s
CI / backup-restore-drill (push) Failing after 0s
CI / web (push) Failing after 0s
2026-09-24 05:06:30 +00:00
weichen 1d8b50d5ac docs(test): archive dev full-gate and rc-v1.1.0-beta.3 promotion report 2026-09-24 05:05:45 +00:00
weichen 6fc828a9ce docs(tooling): record PI executor acceptance and operating guide 2026-09-24 04:36:06 +00:00
weichen 58bf83f755 docs(ops): mark admin-password-reset five-state after validate/enqueue 2026-09-24 04:25:32 +00:00
weichen 8ca448ddca merge: candidate feature/admin-password-reset-2026-09-24 into local_dev 2026-09-24 04:24:20 +00:00
weichen 39f8c1d134 feat(auth): admin password reset API and credential guards
Implement T20-F4-B reset-password endpoint with one-time temp password,
audit table, frontend wiring, login error envelope parsing, and
CreateUser fail-closed for empty password hashes. Recovered test chenwei
via env write (password out of band).
2026-09-24 04:18:58 +00:00
weichen 69ffaa677e feat(tooling): add governed local PI subagent executor 2026-09-24 04:09:28 +00:00
weichen 8c4200c888 fix(test): unique project names for pi-agent FullChain e2e
Fixed Chinese names collided on reused gate-pg across nightly runs.
2026-09-24 03:22:54 +00:00
weichen 6f0e43cab2 fix(scripts): force absolute DATA_DIR for nightly real-PI
Relative DATA_DIR from .env resolves under go test package cwd
(internal/server/data/dev) and diverges from the pi-agent bind mount,
leaving agents without template.md/blackboard.json.
2026-09-24 02:48:25 +00:00
weichen b514a3c5e0 docs(ops): mark agentctl-daemon-load CURRENT done 2026-09-24 02:30:13 +00:00
weichen 52462b45e9 docs(workflow): configure local PI model roles with Cursor implementation 2026-09-24 02:19:28 +00:00
weichen c1ae90cea3 docs(workflow): propose Auto subagent lifecycle and evidence contract 2026-09-24 01:44:31 +00:00
weichen f27af1d3d2 docs(ops): record agentctl coordinator daemon systemd load with fail-closed evidence 2026-09-24 01:39:43 +00:00
weichen ca55354034 docs(ops): re-claim gate on tip after fav uuid fix 2026-09-24 00:57:49 +00:00
weichen 80caa785e2 merge: candidate fav-staging-uuid fix into local_dev 2026-09-24 00:57:06 +00:00
weichen f04f14ff01 docs(ops): mark gate-e1a CURRENT done 2026-09-24 00:50:09 +00:00
weichen 2844bbfe1c docs(ops): mark gate-unhook-docquery CURRENT done 2026-09-24 00:46:31 +00:00
weichen 734aa72527 merge: candidate codegraph CURRENT claim into local_dev 2026-09-23 17:53:00 +00:00
weichen 22ed51cf1f docs(ops): claim codegraph-governance closeout on CURRENT 2026-09-23 17:52:46 +00:00
weichen e7262d4d65 docs(status): mark intent-plan-u9u12 done after I3 live acceptance
MATRIX done via docs apply with live HTTP+PG evidence; CURRENT claim
rows recorded for accept/live tasks. Compose defaults remain legacy.
2026-09-23 15:52:05 +00:00
weichen 0d98016511 docs(test): U9–U12 live domain acceptance evidence
Archive real HTTP+PG samples for U9 segment wiring and U10–U12 live
adapters under confirm tier on shared dev (project 6579).
2026-09-23 15:50:53 +00:00
888 changed files with 65146 additions and 2483 deletions
+37
View File
@@ -5,7 +5,44 @@
{
"command": ".cursor/hooks/guard-git.sh",
"matcher": "^git ",
"timeout": 10,
"failClosed": true
},
{
"command": ".cursor/hooks/guard-pi-shell.sh",
"matcher": "pi_subagents\\.py|pkill",
"timeout": 10,
"failClosed": true
}
],
"beforeMCPExecution": [
{
"command": ".cursor/hooks/guard-pi-dispatch.sh",
"matcher": "pi-subagents|pi_subagent_",
"timeout": 10,
"failClosed": true
}
],
"postToolUse": [
{
"command": ".cursor/hooks/pi-receipt-context.sh",
"matcher": "MCP: pi-subagents|pi_subagent_",
"timeout": 10,
"failClosed": false
}
],
"sessionStart": [
{
"command": ".cursor/hooks/audit-session.sh",
"timeout": 20,
"failClosed": false
}
],
"stop": [
{
"command": ".cursor/hooks/audit-session.sh",
"timeout": 10,
"failClosed": false
}
]
}
+166
View File
@@ -0,0 +1,166 @@
#!/usr/bin/env python3
"""Shared helpers for project Cursor hooks (advisory gates + audit/probe)."""
from __future__ import annotations
import json
import os
import re
import sys
from datetime import datetime, timezone
from pathlib import Path
from typing import Any
KNOWN_ROLES = frozenset(
{
"research",
"planning",
"requirements_review",
"plan_review",
"code_review",
"diagnosis",
"test_run",
"acceptance_check",
"stage_notes",
"report",
"auxiliary",
}
)
TEST_ROLES = frozenset({"test_run", "acceptance_check"})
FULL_SHA = re.compile(r"^[0-9a-fA-F]{40}$")
REQUEST_ID = re.compile(r"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$")
def repo_root() -> Path:
env = os.environ.get("CURSOR_PROJECT_DIR") or os.environ.get("CURSOR_WORKSPACE_ROOT")
if env:
return Path(env).resolve()
# hooks run with cwd = project root
return Path.cwd().resolve()
def audit_path() -> Path:
return repo_root() / ".cursor" / "hook-audit.jsonl"
def probe_path() -> Path:
return repo_root() / ".cursor" / "hook-probe.jsonl"
def inventory_dir() -> Path:
return repo_root() / ".cursor" / "hook-audit"
def append_jsonl(path: Path, record: dict[str, Any]) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
record = dict(record)
record.setdefault("ts", datetime.now(timezone.utc).isoformat())
with path.open("a", encoding="utf-8") as fh:
fh.write(json.dumps(record, ensure_ascii=False) + "\n")
def read_stdin() -> str:
return sys.stdin.read()
def maybe_probe(raw: str, hook: str) -> None:
if os.environ.get("CURSOR_HOOKS_PROBE", "").strip() not in ("1", "true", "TRUE", "yes"):
return
append_jsonl(
probe_path(),
{"hook": hook, "raw": raw[:65536], "raw_len": len(raw)},
)
def parse_json_loose(raw: str) -> dict[str, Any] | None:
raw = (raw or "").strip()
if not raw:
return None
try:
data = json.loads(raw)
except json.JSONDecodeError:
return None
return data if isinstance(data, dict) else None
def first_key(data: dict[str, Any], *names: str) -> Any:
for name in names:
if name in data and data[name] is not None:
return data[name]
return None
def normalize_tool_name(name: str | None) -> str | None:
"""Strip Cursor MCP prefixes such as 'MCP:' / 'MCP: pi-subagents/'."""
if name is None:
return None
n = str(name).strip()
# Observed IDE postToolUse: tool_name == "MCP:pi_subagent_roles"
if n.upper().startswith("MCP:"):
n = n[4:].lstrip()
# Rare: "MCP: pi-subagents/pi_subagent_run"
if "/" in n and n.rsplit("/", 1)[-1].startswith("pi_subagent_"):
n = n.rsplit("/", 1)[-1]
return n or None
def tool_name(data: dict[str, Any]) -> str | None:
v = first_key(data, "tool_name", "mcp_tool_name", "name", "toolName")
return normalize_tool_name(str(v) if v is not None else None)
def mcp_server(data: dict[str, Any]) -> str | None:
v = first_key(data, "mcp_server_name", "server", "mcpServer", "server_name")
return str(v) if v is not None else None
def tool_input(data: dict[str, Any]) -> dict[str, Any] | None:
v = first_key(data, "tool_input", "arguments", "input", "toolInput", "params")
if isinstance(v, dict):
return v
if isinstance(v, str):
try:
parsed = json.loads(v)
return parsed if isinstance(parsed, dict) else None
except json.JSONDecodeError:
return None
return None
def shell_command(data: dict[str, Any]) -> str:
v = first_key(data, "command", "shell_command", "cmd")
return str(v) if v is not None else ""
def emit(obj: dict[str, Any]) -> None:
sys.stdout.write(json.dumps(obj, ensure_ascii=False))
sys.stdout.flush()
def allow() -> None:
emit({"permission": "allow"})
raise SystemExit(0)
def ask(user_message: str, agent_message: str) -> None:
emit(
{
"permission": "ask",
"user_message": user_message,
"agent_message": agent_message,
}
)
raise SystemExit(0)
def additional_context(text: str) -> None:
emit({"additional_context": text})
raise SystemExit(0)
def audit(hook: str, code: str, **extra: Any) -> None:
rec = {"hook": hook, "code": code}
rec.update(extra)
try:
append_jsonl(audit_path(), rec)
except OSError:
pass
+4
View File
@@ -0,0 +1,4 @@
#!/usr/bin/env bash
set -euo pipefail
DIR="$(cd "$(dirname "$0")" && pwd)"
exec python3 -B "$DIR/audit_session.py"
+101
View File
@@ -0,0 +1,101 @@
#!/usr/bin/env python3
"""sessionStart / stop: audit + optional fail-open inventory (no context injection)."""
from __future__ import annotations
import json
import os
import subprocess
import sys
from datetime import datetime, timezone
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parent))
import _lib as lib # noqa: E402
HOOK = "audit-session"
INVENTORY_TIMEOUT = 15
def _run_inventory(root: Path) -> dict:
out: dict = {"cleanup_report": None, "docs_drift": None, "errors": []}
if os.environ.get("CURSOR_HOOKS_NO_INVENTORY", "").strip() in ("1", "true", "TRUE", "yes"):
out["skipped"] = "CURSOR_HOOKS_NO_INVENTORY"
return out
agentctl = root / "scripts" / "agentctl.py"
if not agentctl.is_file():
out["errors"].append("agentctl.py missing")
return out
for label, args in (
("cleanup_report", ["cleanup", "report"]),
("docs_drift", ["docs", "drift"]),
):
try:
r = subprocess.run(
["python3", "-B", str(agentctl), *args],
cwd=str(root),
capture_output=True,
text=True,
timeout=INVENTORY_TIMEOUT,
check=False,
)
payload = None
for stream in (r.stdout, r.stderr):
for line in (stream or "").splitlines():
line = line.strip()
if line.startswith("{"):
try:
payload = json.loads(line)
break
except json.JSONDecodeError:
continue
if payload is not None:
break
out[label] = {
"exit_code": r.returncode,
"payload": payload,
"stdout_tail": (r.stdout or "")[-2000:],
"stderr_tail": (r.stderr or "")[-1000:],
}
except subprocess.TimeoutExpired:
out["errors"].append(f"{label}: timeout>{INVENTORY_TIMEOUT}s")
except OSError as exc:
out["errors"].append(f"{label}: {exc}")
return out
def main() -> None:
raw = lib.read_stdin()
lib.maybe_probe(raw, HOOK)
data = lib.parse_json_loose(raw) or {}
event = str(
lib.first_key(data, "hook_event_name", "event", "event_name", "type") or "unknown"
)
root = lib.repo_root()
if "start" in event.lower() or event == "unknown":
inv = _run_inventory(root)
inv_path = None
try:
inv_dir = lib.inventory_dir()
inv_dir.mkdir(parents=True, exist_ok=True)
ts = datetime.now(timezone.utc).strftime("%Y%m%dT%H%M%SZ")
path = inv_dir / f"inventory-{ts}.json"
path.write_text(json.dumps(inv, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
inv_path = str(path)
except OSError:
pass
lib.audit(
HOOK,
"SESSION_AUDIT",
event=event,
inventory_path=inv_path,
inventory_errors=inv.get("errors"),
)
else:
lib.audit(HOOK, "SESSION_AUDIT", event=event)
lib.emit({})
raise SystemExit(0)
if __name__ == "__main__":
main()
+5
View File
@@ -0,0 +1,5 @@
#!/usr/bin/env bash
# Thin wrapper: preserve stdin for Cursor hook JSON (do not use heredoc).
set -euo pipefail
DIR="$(cd "$(dirname "$0")" && pwd)"
exec python3 -B "$DIR/guard_pi_dispatch.py"
+4
View File
@@ -0,0 +1,4 @@
#!/usr/bin/env bash
set -euo pipefail
DIR="$(cd "$(dirname "$0")" && pwd)"
exec python3 -B "$DIR/guard_pi_shell.py"
+113
View File
@@ -0,0 +1,113 @@
#!/usr/bin/env python3
"""Advisory beforeMCPExecution gate for pi-subagents MCP tools."""
from __future__ import annotations
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parent))
import _lib as lib # noqa: E402
HOOK = "guard-pi-dispatch"
def main() -> None:
raw = lib.read_stdin()
lib.maybe_probe(raw, HOOK)
data = lib.parse_json_loose(raw)
if data is None:
lib.audit(HOOK, "UNRECOGNIZED_INPUT", reason="non_json_or_empty")
lib.allow()
name = lib.tool_name(data)
server = lib.mcp_server(data)
if not name:
lib.audit(HOOK, "UNRECOGNIZED_INPUT", reason="missing_tool_name", keys=sorted(data.keys())[:40])
lib.allow()
if server and "pi-subagents" not in server and not name.startswith("pi_subagent_"):
if not name.startswith("pi_subagent_"):
lib.allow()
if name in ("pi_subagent_roles", "pi_subagent_result"):
lib.allow()
if name != "pi_subagent_run":
if name.startswith("pi_subagent_"):
lib.audit(HOOK, "UNRECOGNIZED_INPUT", reason="unknown_pi_tool", tool=name)
lib.allow()
args = lib.tool_input(data) or {}
req = args.get("request") if isinstance(args.get("request"), dict) else args
if not isinstance(req, dict):
lib.audit(HOOK, "UNRECOGNIZED_INPUT", reason="missing_request")
lib.ask(
"pi_subagent_run 缺少可识别的 request 对象。请核对 MCP 参数后再继续。",
"Hook: unrecognized request shape for pi_subagent_run.",
)
role = req.get("role_id")
request_id = req.get("request_id")
goal = req.get("goal")
auth = req.get("authorization_ref")
source_sha = req.get("source_sha")
input_files = req.get("input_files")
timeout = req.get("timeout_seconds")
problems: list[str] = []
if not role or not isinstance(role, str):
problems.append("role_id 缺失")
elif role not in lib.KNOWN_ROLES:
problems.append(f"role_id={role!r} 不在已知角色表")
if not request_id or not isinstance(request_id, str) or not lib.REQUEST_ID.match(request_id):
problems.append("request_id 非法(需字母数字开头,长度≤128)")
if not goal or not isinstance(goal, str) or not goal.strip():
problems.append("goal 为空")
if not auth or not isinstance(auth, str) or not auth.strip():
problems.append("authorization_ref 为空")
if not isinstance(source_sha, str) or not lib.FULL_SHA.match(source_sha):
problems.append("source_sha 必须是完整 40-hex 提交(禁止 HEAD/分支名/短 hash)")
if not isinstance(input_files, list):
problems.append("input_files 必须是数组")
if not isinstance(timeout, int) or isinstance(timeout, bool) or timeout <= 0:
if isinstance(timeout, float) and timeout.is_integer() and timeout > 0:
pass
else:
problems.append("timeout_seconds 必须是正整数")
if isinstance(role, str) and role in lib.TEST_ROLES:
cmds = req.get("approved_commands")
digest = req.get("plan_digest")
if not isinstance(cmds, list) or not cmds:
problems.append("test 角色需要 approved_commands(argv 数组的数组)")
elif any(not isinstance(c, list) or not all(isinstance(x, str) for x in c) for c in cmds):
problems.append("approved_commands 形状错误(应为字符串数组的数组)")
if not isinstance(digest, str) or len(digest) != 64 or any(
c not in "0123456789abcdefABCDEF" for c in digest
):
problems.append("plan_digest 必须是 64-hex SHA-256")
if "model_override" in req and req.get("model_override") is not None:
problems.append("出现 model_override(禁止静默换模型;请用任务 override)")
if problems:
detail = ";".join(problems)
lib.audit(HOOK, "SHAPE_ASK", tool=name, problems=problems, role=role, request_id=request_id)
lib.ask(
f"pi_subagent_run 形状检查未通过:{detail}。执行器仍会硬校验;确认后继续或修正参数。",
f"Hook advisory: {detail}",
)
lib.audit(HOOK, "ALLOW", tool=name, role=role, request_id=request_id)
lib.allow()
if __name__ == "__main__":
main()
+56
View File
@@ -0,0 +1,56 @@
#!/usr/bin/env python3
"""Advisory beforeShellExecution: bare pi_subagents.py run / broad pkill."""
from __future__ import annotations
import re
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parent))
import _lib as lib # noqa: E402
HOOK = "guard-pi-shell"
def main() -> None:
raw = lib.read_stdin()
lib.maybe_probe(raw, HOOK)
data = lib.parse_json_loose(raw)
if data is None:
lib.audit(HOOK, "UNRECOGNIZED_INPUT", reason="non_json_or_empty")
lib.allow()
cmd = lib.shell_command(data)
if not cmd:
lib.audit(HOOK, "UNRECOGNIZED_INPUT", reason="missing_command", keys=sorted(data.keys())[:40])
lib.allow()
compact = re.sub(r"\s+", " ", cmd).strip()
if re.search(r"(^|[;&|]\s*)pkill(\s|$)", compact) and re.search(r"\s-f(\s|$)", compact):
lib.audit(HOOK, "PKILL_ASK", command=compact[:500])
lib.ask(
"检测到 pkill -f(广谱杀进程)。AGENTS/PI 规则禁止广谱杀;请确认范围后再继续。",
"Hook requires confirmation for pkill -f.",
)
if re.search(r"pi_subagents\.py(\s|$)", compact) and re.search(r"(^|\s)run(\s|$)", compact):
has_lease = (
re.search(r"agentctl(\.py)?\s+with\b", compact) is not None
and re.search(r"--resource\s+path:", compact) is not None
)
if re.search(r"pi_subagents\.py\s+(roles|result|status|config)\b", compact):
lib.allow()
if not has_lease:
lib.audit(HOOK, "BARE_RUN_ASK", command=compact[:500])
lib.ask(
"裸调 pi_subagents.py run 缺少 agentctl with --resource path:… 租约。"
"报告路径须在 path:.doc/test-reports/assets/pi-subagents/<task>/<request> 租约内。",
"Hook: bare PI run without lease resource.",
)
lib.allow()
if __name__ == "__main__":
main()
+4
View File
@@ -0,0 +1,4 @@
#!/usr/bin/env bash
set -euo pipefail
DIR="$(cd "$(dirname "$0")" && pwd)"
exec python3 -B "$DIR/pi_receipt_context.py"
+48
View File
@@ -0,0 +1,48 @@
#!/usr/bin/env python3
"""postToolUse: inject receipt-check reminders after pi-subagents tools."""
from __future__ import annotations
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parent))
import _lib as lib # noqa: E402
HOOK = "pi-receipt-context"
REMINDER = """[PI subagent receipt checklist]
- 核对 report/receipt 路径:.doc/test-reports/assets/pi-subagents/<task_id>/<request_id>/
- 记录 config_revision / config_sha256 / configured vs actual_model(不可观察填 unknown)
- run_status=succeeded 不等于阶段 PASS;review_state 仍可为 pending
- 测试 pass 只来自批准命令证据(approved_commands),不能用模型叙事冒充
- 推进门禁前用 subagent-stage-record skill 写回传与阶段收据
"""
def main() -> None:
raw = lib.read_stdin()
lib.maybe_probe(raw, HOOK)
data = lib.parse_json_loose(raw)
if data is None:
lib.audit(HOOK, "UNRECOGNIZED_INPUT", reason="non_json_or_empty")
lib.emit({})
raise SystemExit(0)
name = lib.tool_name(data) or ""
server = lib.mcp_server(data) or ""
blob = raw
is_pi = (
name.startswith("pi_subagent_")
or "pi-subagents" in server
or "pi_subagent_" in blob
)
if not is_pi:
lib.emit({})
raise SystemExit(0)
lib.audit(HOOK, "CONTEXT_INJECT", tool=name or "unknown")
lib.additional_context(REMINDER)
if __name__ == "__main__":
main()
+9 -2
View File
@@ -1,17 +1,24 @@
{
"mcpServers": {
"agentctl": {
"type": "stdio",
"command": "node",
"args": ["${workspaceFolder}/scripts/mcp/agentctl-mcp.mjs"]
"args": ["scripts/mcp/agentctl-mcp.mjs"]
},
"jev": {
"type": "stdio",
"command": "node",
"args": ["${workspaceFolder}/scripts/mcp/jev-mcp.mjs"]
"args": ["scripts/mcp/jev-mcp.mjs"]
},
"codegraph": {
"type": "stdio",
"command": "codegraph",
"args": ["serve", "--mcp", "--path", "${workspaceFolder}"]
},
"pi-subagents": {
"type": "stdio",
"command": "node",
"args": ["scripts/mcp/pi-subagents-mcp.mjs"]
}
}
}
+6 -2
View File
@@ -11,8 +11,9 @@ alwaysApply: true
1. **写仓库**:必须 `agentctl with` / MCP `lease_run`。裸 `git commit` 会被 agentctl pre-commit hook 拒绝。
2. **共享文档**:`.doc/ops/CURRENT.md`、`.doc/status/FEATURE-MATRIX.md` 只能 `docs apply`(行级 CAS;MATRIX 键为 `record_id`)。
3. **合入 local dev**:`validate` 后 `queue enqueue`(daemon `--ff-only`)或受控 `integrate`;禁止直接改主目录 `dev` tip。
3. **合入 local dev**:`validate` 后 `queue enqueue`(daemon `--ff-only`)或受控 `integrate`;禁止直接改主目录 `dev` tip。
4. **禁止默认**:未授权 `git push`、晋升 test/main、`--force` 清理、卸载 launchd coordinator、改 gap-matrix / 升 MATRIX 状态值冒充发布。
5. **需求重叠**:跨对话新设计须 `catalog overlap`;硬重叠拒绝;软重叠须 `catalog ack` 留痕后方可编码(见 `.doc/ops/2026-09-24-governance-catalog-plan.md`)。
## 会话路径
@@ -20,4 +21,7 @@ alwaysApply: true
- 建场 → `agentctl-worktree-setup`
- 写回 → `agentctl-lease-write`
- 合入/收口 → `agentctl-integrate-closeout`
- MCP 工具定义见 `.cursor/mcp.json` → `scripts/mcp/agentctl-mcp.mjs`
- PI 派发 → skill `pi-subagent-dispatch`(MCP `pi-subagents`)
- 阶段落盘 → skill `subagent-stage-record`
- MCP 工具定义见 `.cursor/mcp.json` → `scripts/mcp/agentctl-mcp.mjs` / `pi-subagents-mcp.mjs`
- 客户端 hook 边界见规则 `cursor-hooks`
+22
View File
@@ -0,0 +1,22 @@
---
description: Cursor 对话自动生成的会话名称使用简体中文
alwaysApply: true
---
# 会话名称(中文)
Cursor 为本对话自动生成或建议的**会话名称 / 聊天标题**必须使用**简体中文**。
## 要求
- 用简短中文概括当前任务主题(约 6–16 字)
- 优先动词/对象:如「创建会话中文命名规则」「修复登录超时」
- 禁止默认英文标题(专有名词、命令、路径可保留原文,整体仍以中文为主)
## 示例
| 场景 | 可用标题 |
|---|---|
| 新建 Cursor 规则 | 创建会话中文命名规则 |
| 排查 hook | 排查 pi-dispatch hook |
| 合入 feature | 合入治理目录库变更 |
+42
View File
@@ -0,0 +1,42 @@
---
description: Project Cursor hooks are advisory gates layered on agentctl/PI executor hard checks; scripts exist does not mean Cursor loaded them.
alwaysApply: true
---
# Cursor hooks(客户端门禁)
配置:`.cursor/hooks.json`;脚本:`.cursor/hooks/`。规范登记修订 `cursor-governance-2026-09-24-r1`。
## 分层
| 层 | 能力 | 说明 |
|---|---|---|
| 执行器 / agentctl | **enforced** | `scripts/pi_subagents.py`、租约、pre-commit 等硬拒绝 |
| hook 脚本行为 | **enforced**(有单元回归) | stdin→stdout 契约可测 |
| hook ↔ Cursor 接线 | **advisory / manual** | 官方事件字段未完全文档化;待 probe 采样后收紧 |
命中策略:与 `guard-git.sh` 一致,一律 `permission: ask`(不静默 deny)。
## 事件与脚本
- `beforeShellExecution`:`guard-git.sh`(破坏性 git);`guard-pi-shell.sh`(裸调 `pi_subagents.py run`、`pkill -f`)
- `beforeMCPExecution`:`guard-pi-dispatch.sh`(`pi_subagent_run` 形状)
- `postToolUse`:`pi-receipt-context.sh`(注入收据核对提醒)
- `sessionStart` / `stop`:`audit-session.sh`(审计 + 可选只读盘点;**不注入上下文**)
IDE 实测(2026-09-24):`postToolUse` 的 `tool_name` 形如 `MCP:pi_subagent_roles`;hooks 须剥 `MCP:` 前缀后再匹配角色工具名。
## 审计与 probe
- 审计:`.cursor/hook-audit.jsonl`(gitignore;勿提交)
- 盘点:`.cursor/hook-audit/inventory-*.json`
- 采样:`CURSOR_HOOKS_PROBE=1` → `.cursor/hook-probe.jsonl`
- 关闭盘点:`CURSOR_HOOKS_NO_INVENTORY=1`
异形/未知字段:**fail-open + 审计 `UNRECOGNIZED_INPUT`**,不因契约未知卡死会话。
## 红线
- 不把 hook 复刻成第二套执行器门禁
- 脚本存在 ≠ Cursor 已加载;改 hooks 后检查 Hooks 设置页或通道
- 审计日志不得放进被 git 跟踪的 `.cursor/hooks/` 目录
+24
View File
@@ -0,0 +1,24 @@
---
description: Route PI analysis/review/test subagent work through scripts/pi_subagents.py (not Cursor native agents).
alwaysApply: true
---
# PI subagents(工程工具)
本机 PI 子任务走 `scripts/pi_subagents.py` + 模型配置 `.doc/ops/2026-09-24-subagent-model-config.md`。可执行步骤见 skill `pi-subagent-dispatch`;阶段记录见 `subagent-stage-record`。
## 自动派发(主 Agent)
1. **预览配置**:`pi_subagent_roles` / CLI `roles`(不调模型)。
2. **按阶段选角色**:research → planning → reviews → diagnosis → test_run / acceptance_check → report;实施/修复仍由 Cursor Auto。
3. **派发 `run`**:携带 task_id、role_id、唯一 request_id、goal、authorization_ref、冻结 source_sha、input_files、timeout;test 角色另附 approved_commands + plan_digest。
4. **租约**:报告路径 `path:.doc/test-reports/assets/pi-subagents/<task>/<request>`;裸调拒绝。
5. **取回**:`pi_subagent_result` / CLI `result`;`run_status` 与 `verdict`/`review_state` 分离——模型成功仅 `pending`,测试 pass 仅来自批准命令证据。
6. **门禁**:审查/测试结论须带回报告路径与 receipt 字段;不得用模型叙事冒充 PASS。
## 边界
- **Cursor Auto**:唯一代码实施车道;本规则不把 implementation 派给 PI。
- **禁止**:自动换模型、M3 关键角色、伪造 lease、递归把本修复任务再派给 PI worker、`pkill -f` 广谱杀进程。
- **MCP**:`.cursor/mcp.json` → `pi-subagents`(roles/run/result);executor 来自 MCP 安装根。
- **Hook(advisory)**:`.cursor/hooks/guard-pi-dispatch.sh` / `guard-pi-shell.sh` 可在形状错误时 `ask`;**硬拒绝以执行器为准**,见规则 `cursor-hooks`。
+17 -21
View File
@@ -1,14 +1,13 @@
---
description: 规定项目中所有自动化测试、功能测试、集成测试报告的存放路径与结构标准规范
globs: ["**/*test*.go", ".doc/test-reports/**/*.md"]
description: Cursor-side test report path/naming conventions; validation scope comes from the validation contract.
alwaysApply: true
---
# 测试报告规范准则 (Test Reports Standard)
本仓库严格遵循标准化、可追溯的质量测试管理体系。所有测试报告必须归档于指定的文档目录下,并遵循固定结构。
本仓库严格遵循标准化、可追溯的质量测试管理体系。**验证范围、套件选择与模型证据的唯一来源**为 [验证契约](../../.doc/ops/2026-09-21-validation-contract.md);本规则只约定 Cursor 侧的报告路径、命名与结构提醒,不另设第二套测试门禁。
**范围判定**:纯工程规范/文档变更按 [PROJECT.md](../../PROJECT.md) §8 和 [worktree 工作规范](../../.doc/ops/2026-09-21-agent-worktree-workflow.md) 检查链接、规则一致性及 Git 差异;不适用下述产品 PI 全链路与全量 Go 回归要求。报告注明 NOT REQUIRED 及依据,不能记成产品测试 PASS。运行模板、提示词和业务变更不属于此例外。
**范围判定**:纯工程规范/文档变更按 [PROJECT.md 验证入口](../../PROJECT.md#验证入口) 与 [worktree 工作规范](../../.doc/ops/2026-09-21-agent-worktree-workflow.md) 检查链接、规则一致性及 Git 差异;不适用产品 PI 全链路。报告注明 NOT REQUIRED 及依据,不能记成产品测试 PASS。运行模板、提示词和业务变更不属于此例外——按验证契约选层级。
## 一、 测试报告归档路径规范
@@ -17,11 +16,9 @@ alwaysApply: true
- 例如:`.doc/test-reports/2026-09-07-three-branch-intent-framework-test-report.md`
- **证据附件**:运行产物(json/jsonl、workspace 快照、截图)放 `.doc/test-reports/assets/<report-slug>/`,**不得**与 `*-test-report.md` 混放在同一层级目录。
---
## 二、 测试报告固定结构模板
每份测试报告必须包含以下核心板块:
每份独立测试报告应包含以下核心板块(小型文档/脚本任务可在任务主文档设验证节,无需机械拆报告):
```markdown
# [功能/模块名称] 测试报告
@@ -30,38 +27,37 @@ alwaysApply: true
- 简述被测功能/特性的产生背景、业务痛点或上一轮测试中发现的缺陷与瓶颈。
## 二、 测试目标 (Test Objectives)
- 列举本次测试需要验证的核心功能点、质量指标(如通过率 100%、无流程卡点、非阻塞人机协同等)。
- 列举本次测试需要验证的核心功能点、质量指标。
## 三、 测试方案与环境 (Test Plan & Environment)
- 测试环境(OS、Go 版本、后端 Stub/Real 模型);
- 测试层级分层(单元测试、协同集成测试、CLI 真实交互测试);
- 测试环境(OS、工具版本、目标环境批准配置);
- 测试层级分层(按验证契约矩阵选行);
- 核心测试用例矩阵设计。
## 四、 预期结果 (Expected Results)
- 明确给出各用例输入下的理论判定分支、目标意图、提取槽位、参谋回复风格与状态机流转。
- 明确给出各用例输入下的理论判定。
## 五、 实际测试结果与判定 (Actual Results & Evaluation)
- 必须包含针对每一个典型测试用例的真实记录:
- **测试输入 (Input)**
- **实际输出 (Actual Output)**:贴出真实的终端/日志输出文本
- **评价判定 (Evaluation / Verdict)**:PASS / FAIL 标志及判定依据
- **实际输出 (Actual Output)**:贴出真实的终端/日志输出文本(可脱敏)
- **评价判定 (Evaluation / Verdict)**:PASS / FAIL / SKIP / 未运行
- **性能与耗时 (Duration & Latency)**
## 六、 自动化测试套件汇总 (Test Suite Execution)
- 附带 `go test -v ./...` 全量回归测试输出与通过率统计。
- 只列本次适用并**实际运行**的检查与通过率;不无条件要求全量 `go test`。
- 工程工具改动优先 `python3 -B -m unittest discover -s scripts/tests -p 'test_*.py' -v`(见验证契约「工程工具验收补充」)。
## 七、 测试结论与后续优化建议 (Conclusion & Next Steps)
- 总结测试是否达到上线/合并标准,提出后续演进或强化点。
- 总结测试是否达到授权交付终点,提出后续演进或强化点。
```
---
## 三、 执行要求与真实 Agent 交付铁律
1. **真实 Agent 交付铁律(红线)**:
- **开发实现阶段**:可以快速使用 `stub` 验证状态机、协议分流、数据落盘与逻辑契约,加速反馈;
- **交付前验收与测试报告生成**:**必须切回真实环境与真实 Agent(`pi-agent` + 实际运行的 `MiniMax-M2.7-highspeed` 容器)进行全链路端到端实测**;
- **严禁**使用 stub 的测试输出作为最终交付报告的验收数据。
2. **严禁散落存放**:测试报告统一归档至 `.doc/test-reports/` 目录下,禁止散落在根目录或临时沙箱中。
- **开发实现阶段**:可以快速使用 stub 验证状态机、协议分流、数据落盘与逻辑契约,加速反馈;
- **交付前验收与测试报告生成**:涉及产品 Agent/工作流时,必须按验证契约「产品 PI 基线」在获授权环境用真实产品 PI Agent Runner 全链路实测;模型以目标环境批准配置为准,不得在本规则中硬编码模型名;
- **严禁**使用 stub、SKIP、未运行输出作为最终交付报告的验收数据。
2. **严禁散落存放**:测试报告统一归档至 `.doc/test-reports/`,禁止散落在根目录或临时沙箱中。
3. **真实控制台取样**:测试报告中的输入、输出、耗时与判定必须取自实际环境运行的真实控制台输出与日志。
4. **Git 规范管理**:测试报告伴随对应阶段的 `docs(test)` 或 `test(...)` 规范提交入库。
@@ -9,19 +9,18 @@ description: Validate a merge candidate, enqueue for daemon ff-only integrate, a
## 候选
优先一层封装(创建 integrate worktree、`task register`、`--no-ff` merge;**不** validate/enqueue):
```bash
D=$(git -C /path/to/Agent-System rev-parse HEAD) # 冻结 expected-dev
ID=integrate-<task>-YYYY-MM-DD
git worktree add -b feature/$ID .worktrees/$ID "$D"
cd .worktrees/$ID
python3 ../../scripts/agentctl.py task register --id "$ID" --owner Cursor --scope . --capability git:dev
python3 ../../scripts/agentctl.py with --task "$ID" \
--resource path:. --resource git:index --resource git:dev -- bash -lc '
git merge --no-ff -m "merge: candidate <feature> into dev" feature/<task>
'
python3 scripts/agentctl.py integrate prepare \
--task <feature-task-id> --expected-dev "$D" \
[--integrate-id integrate-<task>-YYYY-MM-DD]
# 进入返回的 worktree 继续 validate → enqueue
cd .worktrees/integrate-<task>-YYYY-MM-DD # 或 emit 中的 worktree
```
第一父必须等于 `$D`。
第一父必须等于 `$D`。手工 `worktree add` + `with` + `merge --no-ff` 仍可用。
## validate → enqueue(daemon ff)
+14 -2
View File
@@ -29,11 +29,23 @@ codegraph sync -q
跨文件定位优先用 CodeGraph MCP/`explore`;**grep 仍是完整性唯一权威**(假阴性时以 grep 为准)。
4. 若任务已存在:在注册 worktree 内工作,确认 `tasks.state=active`。
5. 若新任务:跟 [agentctl-worktree-setup](../agentctl-worktree-setup/SKILL.md)。
6. 任何仓库写 → [agentctl-lease-write](../agentctl-lease-write/SKILL.md);合入 → [agentctl-integrate-closeout](../agentctl-integrate-closeout/SKILL.md)。
5. **开工前需求重叠探测**(治理目录库):新设计或可能与其他对话重叠时:
```bash
python3 scripts/agentctl.py catalog search --query '<关键词>'
python3 scripts/agentctl.py catalog overlap --task "$ID" --statement '<设计原文>' [--requirement R-xxx] [--feature <record_id>] [--mutex <key>]
# soft 命中须显式裁决后才可编码:
python3 scripts/agentctl.py catalog overlap ack --task "$ID" --overlap <oid> --decision proceed|merge_into|supersede|defer --reason '...'
```
硬重叠(同 mutex/feature/scope/R-ID)直接拒绝;向量层失败自动降级到 FTS5,不阻断。
6. 若新任务:跟 [agentctl-worktree-setup](../agentctl-worktree-setup/SKILL.md)。
7. 任何仓库写 → [agentctl-lease-write](../agentctl-lease-write/SKILL.md);合入 → [agentctl-integrate-closeout](../agentctl-integrate-closeout/SKILL.md)。
## 禁止
- 主目录直接开发提交;未授权 `git push` / 晋升 test/main
- 绕过 `docs apply` 改 CURRENT / FEATURE-MATRIX
- 卸载或重启 launchd coordinator(除非用户明示)
- 未执行 `catalog overlap` / 未裁决 soft 命中即编码(有 `--requirement`/`--intent`/`--feature`/`--mutex` 绑定时机器强制)
+24 -11
View File
@@ -23,24 +23,37 @@ python3 ../../scripts/agentctl.py task register \
--scope scripts --scope .doc \
--capability docs:publish
# 需要整文/行级 admin 时再加 --capability docs:admin;证据升 done 加 docs:approve
# 若已知需求/功能绑定,追加:
# --requirement R-<slug> --intent '<设计原文>' --feature <record_id> --mutex <key>
# 有 soft 重叠时 register 会 OVERLAP_ACK_REQUIRED:先 catalog overlap + ack 再重试 register
codegraph sync -q # 若建场已 init,此处只需 sync;缺失 CLI 可跳过
```
## CURRENT 认领(docs apply)
## 开工前重叠裁决(catalog)
```bash
python3 ../../scripts/agentctl.py docs snapshot \
--file .doc/ops/CURRENT.md --record "$ID" > /tmp/claim-snap.json
# 新建行:expected_sha256=null
cat > /tmp/claim.json <<EOF
{"request_id":"$ID-claim-1","changes":[{
"file":".doc/ops/CURRENT.md","record_id":"$ID","expected_sha256":null,
"replacement":"| <Owner> | $ID | feature/$ID | $WT | <mutex> | in_progress |"
}]}
EOF
python3 ../../scripts/agentctl.py docs apply --task "$ID" --request /tmp/claim.json
python3 ../../scripts/agentctl.py catalog overlap \
--task "$ID" --statement '<新设计原文>' \
[--requirement R-xxx] [--feature <record_id>] [--mutex <key>]
# hard → 换 mutex/合并到持有者任务;soft → ack 留痕
python3 ../../scripts/agentctl.py catalog ack \
--task "$ID" --overlap <oid> \
--decision proceed|merge_into|supersede|defer \
--reason '<理由>'
```
## CURRENT 认领
优先用一层封装(内部仍走 `docs apply` CAS):
```bash
python3 ../../scripts/agentctl.py claim new \
--task "$ID" --owner <Owner> --mutex <mutex> \
[--branch feature/$ID] [--worktree "$WT"] [--replace]
```
手工 `docs snapshot` + `docs apply` 仍可用;行已存在且内容不同时需 `--replace`。
## short-term 模板字段
`status`、`write_scope`、`mutex`、`base_dev_sha`、`review_state`/`integration_state`/`deployment`/`cleanup`/`remote_sync`。命名 `.doc/ops/short-term/YYYY-MM-DD-<slug>.md`。
@@ -0,0 +1,87 @@
---
name: pi-subagent-dispatch
description: Dispatch gmktec PI analysis/review/test subagents via project MCP pi-subagents (roles/run/result). Use when delegating research, planning, reviews, diagnosis, test_run, acceptance_check, or report work—not for code implementation.
---
# PI Subagent 派发
权威:[模型配置](../../../.doc/ops/2026-09-24-subagent-model-config.md)、[执行器说明](../../../.doc/ops/2026-09-24-pi-subagent-executor.md)、[流程规范](../../../.doc/ops/2026-09-24-subagent-workflow-standard.md)。客户端规则:[pi-subagents](../../rules/pi-subagents.mdc)。阶段落盘:[subagent-stage-record](../subagent-stage-record/SKILL.md)。
**Cursor Auto 独占代码实施与修复**;本 skill 只走本机 PI 子任务。
## 调用序列
1. `pi_subagent_roles` — 只读预览角色/模型(不调 PI)。
2. 选 `role_id`(research → planning → reviews → diagnosis → test_run / acceptance_check → report)。
3. (推荐)`agentctl pi packet` 生成派发包;**不**触发 run:
```bash
python3 -B scripts/agentctl.py pi packet \
--task "$ID" --role research \
--goal '…' --authorization-ref 'user:…' \
--source-sha "$(git rev-parse HEAD)" \
[--input-file …] [--approved-command '…']… \
--request-id "$RID" --write
# → .doc/test-reports/assets/pi-subagents/<task>/<request>/packet.json
```
4. `pi_subagent_run` — 按 packet 字段在 agentctl 租约下异步启动。
5. `pi_subagent_result` — 取回收据;轮询至终态。
CLI 等价:`python3 -B scripts/pi_subagents.py roles|run|result`;`run` 必须包在 `agentctl with --resource path:.doc/test-reports/assets/pi-subagents/<task>/<request>` 内。
## 请求字段(MCP `pi_subagent_run`)
外层:`worktree`(已登记任务工作区绝对路径)、`task_id`、`request` 对象。
`request` 必填:
| 字段 | 约束 |
|---|---|
| `role_id` | 配置 §3 中 enabled 角色 |
| `request_id` | 任务内稳定唯一;同参重放不重复调模型 |
| `goal` | 具体目标;子任务不依赖主会话未传入历史 |
| `authorization_ref` | 可回链真实用户授权,禁止日志自授 |
| `source_sha` | **完整** 40-hex 提交;禁止 `HEAD`/分支名/短 hash |
| `input_files` | 已跟踪 UTF-8 普通文件相对路径数组 |
| `timeout_seconds` | 正整数 |
测试角色(`test_run` / `acceptance_check`)另需:
- `approved_commands`:argv 数组的数组(如 `[["go","test","-short","./"]]`)
- `plan_digest`:外部已批准计划的 SHA-256 hex
禁止静默 `model_override`;临时改模型写任务 override 并说明用户来源。
## 租约与输出
- 资源:`path:.doc/test-reports/assets/pi-subagents/<task_id>/<request_id>`
- 产物:`receipt.json`、`report.md`、命令日志(同目录)
- 裸调 `run`(无租约)被拒绝
## 状态分离(红线)
| 字段 | 含义 |
|---|---|
| `run_status` | running / succeeded / failed / cancelled / unknown |
| `verdict` | pass / changes_required / blocked / not_applicable |
| `review_state` | 阶段门禁;模型 succeeded **仅** pending |
测试 `commands_passed`/`pass` 只针对批准命令证据,不能直接赋给任务 `acceptance`。
## 常见拒绝码(执行器权威)
| 码 | 处置 |
|---|---|
| `INVALID_SOURCE_SHA` | 换完整提交 hash |
| `APPROVED_COMMANDS_REQUIRED` | 补 approved_commands + plan_digest |
| `MINIMAX_ROLE_FORBIDDEN` | 不把 M3 用于关键角色 |
| `INPUT_NOT_TRACKED` / `PATH_OUT_OF_SCOPE` | 收窄 input_files |
| `CONCURRENCY_LIMIT` | 串行或等空闲槽 |
| `ORPHAN_RUNNING` | 先核进程/副作用,勿盲目重派 |
Cursor hooks 对形状错误可能 `permission=ask`(advisory);**硬拒绝以执行器为准**。
## 禁止
- 把 implementation 派给 PI
- 自动换模型 / 伪造 lease / 递归把本修复再派给 PI worker
- 用模型叙事冒充 PASS;审查结论须带回报告路径与 receipt 字段
@@ -0,0 +1,56 @@
---
name: subagent-stage-record
description: Record PI/Cursor stage handoffs using the subagent stage template (dispatch packet, return, S0–S9 receipt, R-AC-T mapping). Use after PI results, before gate advances, or when closing a multi-stage task.
---
# Subagent 阶段记录
权威模板:[subagent-stage-record.md](../../../.doc/ops/templates/subagent-stage-record.md);流程:[协作规范](../../../.doc/ops/2026-09-24-subagent-workflow-standard.md)。派发入口:[pi-subagent-dispatch](../pi-subagent-dispatch/SKILL.md)。
原则:**一步一记录,不必一步一文件**。小任务可把适用段落并入任务主文档;跨模块才拆独立审查/测试/验收证据。
## 何时写
- 每次 `pi_subagent_run` 前后:派发包 + 回传
- 阶段门禁推进前:S0–S9 收据行
- 收口前:R→AC→改动→审查→T→运行验收映射
## 派发包(最小字段)
复制到任务文档并填实值:
- `parent_task_id` / `subtask_id` / `stage_id` / `role_id`
- 配置路径 / `config_revision` / `config_sha256`(来自 roles 或 receipt)
- 解析后的 provider/model;任务 override 与用户来源
- 目标、非目标、授权来源、交付终点
- 输入版本:R-ID / AC-ID / 方案版本 / `base_sha` / `head_sha` 或 `source_sha`
- cwd / branch / allowed_paths / 只读或写入 / mutex
- 完成条件、输出路径、预算与异常处理
## 子任务回传
- PI `run_id` / producer / 起止时间
- `configured_model` / `actual_model`(不可观察填 `unknown`)
- `run_status` 与 `verdict` **分列**(不得把退出成功当质量通过)
- 结论与依据、证据链接、脱敏范围
- 未覆盖项、风险、遗留进程/产物、接管建议
只读子 Agent 结论由主 Agent 转存时:保留 `agent_id` 与原结论,注明「由主 Agent 转存」。
## 阶段收据表
| 阶段 | 输入版本 | 产物/证据 | producer | reviewer/独立性 | 决定 | 下一步 |
|---|---|---|---|---|---|---|
| S0–S9 适用项 | | | | independent / self_review / not_required | pass / changes_required / blocked / not_applicable | |
未执行阶段写 `not_applicable` + 原因。报告存在不自动满足门禁。
## 需求追踪
| R-ID | AC-ID | 改动/版本 | 审查 | T-ID / 结果 | 运行验收 | acceptance_owner |
|---|---|---|---|---|---|---|
| | | | | | | |
## 与任务五态
继续用任务模板的 `status`、`review_state`、`integration_state`、`deployment`、`cleanup`、`remote_sync`;额外记 `phase`、`acceptance`、待回收 `subtask_id`。`done` 取决于授权交付终点,不因会话结束自动完成。
+2
View File
@@ -33,6 +33,7 @@
| 我要… | 读这里 |
|--------|--------|
| Subagent 模型配置 / 流程 | [可调整模型配置](ops/2026-09-24-subagent-model-config.md) · [PI 执行器](ops/2026-09-24-pi-subagent-executor.md) · [流程草案](ops/2026-09-24-subagent-workflow-standard.md) · [研究依据](audit/2026-09-24-subagent-workflow-research.md) |
| 规则来源/生效版本 | [规范登记](ops/2026-09-21-policy-registry.md) |
| 选择测试/报告范围 | [验证契约](ops/2026-09-21-validation-contract.md) |
| 任务模板与会话收口 | [任务模板](ops/templates/short-term-task.md) · [收口清单](ops/templates/session-close-checklist.md) |
@@ -46,6 +47,7 @@
| 整改方案 | [remediation/INDEX.md](remediation/INDEX.md) |
| 历史归档 | [archive/README.md](archive/README.md) |
| 架构设计 | [system-design/README.md](system-design/README.md) |
| 用错误码定位失败 | [错误码目录](system-design/2026-09-28-error-code-catalog.md) |
| 测试报告 | [test-reports/](test-reports/) |
| 历史功能设计 | [archive/design/superpowers/](archive/design/superpowers/) |
| Herdr 角色、审批与备援 | [ops/2026-09-13-herdr-agent-roster.md](ops/2026-09-13-herdr-agent-roster.md) |
@@ -0,0 +1,67 @@
# 管理员重置密码 / 登录凭据缺陷 — 问题主记录
更新:2026-09-24。任务:`admin-password-reset-2026-09-24`。
## ISSUE-20260924-admin-reset-dead
### 问题
管理台「重置密码」按钮调用 `authClient.adminResetPassword`,客户端硬 `throw`,后端无 `reset-password` 路由;UI 仍硬编码 `ResetPass123` 暗示成功。验收脚本曾重置 `chenwei` 哈希且不披露口令后,管理员无法通过 UI 恢复访问。
### 根因
T20-F4 已设计未实施(选项 B 卡产品)。`password_changed_at` 停在 2026-09-20 证明重置从未入库。
### 修复
`POST /api/v1/admin/users/{id}/reset-password`:服务端随机临时口令、`must_change_password=true`、撤销会话、审计表 `user_password_reset_audits`(goose 00067);前端接线并去掉硬编码。
### 状态
resolved(本任务合入后)。
---
## ISSUE-20260924-login-error-envelope
### 问题
登录失败响应 `code=AUTHZ` / `message=无权访问`,前端再把整段 JSON 原文塞进 `Error.message`,用户误判为权限问题。
### 根因
`httpx.CodeFromStatus(401)=AUTHZ` + `SafeMessage`;`auth.ts` login 未用信封解析、未优先 `error` 领域字段。
### 修复
`authErrorMessage` 优先取信封 `error`;不改全局 AUTHZ 映射(事件复用与安全取舍另立专项)。
### 状态
resolved。
---
## ISSUE-20260924-zombie-credentials
### 问题
`CreateUser` 在 `PasswordHash==""` 时静默跳过 `user_credentials` 插入;`LEFT JOIN` + `COALESCE` 使登录哈希为空串,任意密码均失败且报错与真凭据错误相同。
### 盘点(只读,2026-09-24)
| 环境 | total | missing_cred | empty_username |
|---|---|---|---|
| dev | 416 | 263 | 255 |
| test | 9 | 0 | 0 |
| main | 4 | 3 | 0 |
main 三行为 goose 00011 seed(`seed-admin` 等),非业务用户。本任务**不清理**存量;仅 fail-closed 防新增。
### 修复
PgStore/MemoryStore `CreateUser` 拒绝空哈希;`Login` 对空哈希记 `slog.Warn(user_id)` 仍统一 401。
### 状态
resolved(机制);存量清理 = open / 另授权。
@@ -0,0 +1,49 @@
---
issue_id: ISSUE-20260924-cursor-hook-event-contract
issue_state: open
severity: medium
owner: Cursor
task_ids: [cursor-governance-hooks-2026-09-24]
created: 2026-09-24
occurred_at: 2026-09-24
updated: 2026-09-24
recurrence_count: 0
evidence_basis: current
lesson_ids: [LESSON-20260924-cursor-hook-advisory-gates]
---
# Cursor hook 事件字段契约未文档化
## 事实与证据
预期:`beforeMCPExecution` / `sessionStart` / `stop` 的 stdin 字段名与 matcher 匹配串在官方文档中明确,便于 failClosed 硬门禁。
实际:官方 create-hook skill 仅明确 `beforeShellExecution` 的 `command` 字段;`beforeMCPExecution` 不支持 `updated_input`;`sessionStart` 无文档化返回字段可注入上下文;`MCP: ...` matcher 形式只写给 `preToolUse` 族。实现层字符串探测存在 `mcp_server_name`/`tool_name`/`tool_input`,但非文档契约。
证据:本任务调研记录;单元测试用多名容错驱动;真实 Cursor IDE 事件采样待 `CURSOR_HOOKS_PROBE=1`。
## 根因与同类范围
客户端 hook API 文档滞后于实现。同类:任何依赖未文档化 hook 输入的 failClosed 门禁都有假阴性/假阳性风险。
## 修复思路与过程
| 日期 | 动作 | 结果 | 下一步 |
|---|---|---|---|
| 2026-09-24 | 落地 advisory hooks + 多名容错 + probe 开关;异形 fail-open | 单元回归 PASS | 用户触发真实 MCP/shell 事件采样后收紧 |
## 验收与关闭
- 静态/单元:已覆盖(见测试报告)
- 实机:打开 `CURSOR_HOOKS_PROBE=1`,触发一次 `pi_subagent_roles` 与一次 shell,归档 `.cursor/hook-probe.jsonl` 片段到测试报告 assets;确认字段名后可将 matcher/`failClosed` 收紧并将本 issue → verifying/resolved
## 经验与复发
见 [LESSON-20260924-cursor-hook-advisory-gates](../ops/lessons/2026-09-24-cursor-hook-advisory-gates.md)。
## 2026-09-24 IDE 采样更新
- `postToolUse` 审计:`tool_name` / 审计字段为 `MCP:pi_subagent_roles`(带 `MCP:` 前缀)。
- 修复:`_lib.normalize_tool_name` 剥前缀;回归 `test_ask_mcp_prefixed_tool_name_bad_sha`。
- `pi_subagent_roles` IDE MCP 调用 PASS;`postToolUse` 收据 checklist 已注入。
- `beforeMCPExecution` 完整 stdin 仍缺(Cursor 进程未设 `CURSOR_HOOKS_PROBE=1`);issue 保持 verifying。
- `agentctl`/`jev` 未出现在 IDE MCP 缓存目录;进程可手动 stdio 启动;与路径修复独立,另记。
@@ -0,0 +1,37 @@
# ISSUE-20260924-non-author-400-duty
## 摘要
非编制项目成员无法上传/总结/对话写草稿;权限错误经 `writeDocGovError` 默认落成 HTTP **400**。
## 根因
1. `domainHTTPStatus` 未映射 `ErrOnlyAuthorCanEdit` / `ErrReviewerCannotEdit` / `ErrApproverCannotEdit` → 403。
2. `classifyAccess` / `AllowedTaskKeys` / `CanEditDocumentContent` 将 run/edit 绑编制职责(三道门协同过宽)。
3. 前端写意图路由偶发把「总结+写动词」送入 task run。
## 处置(deny_only_submit)
- run/edit → 项目成员级;submit/review/approve 保留职责门禁。
- AuthorID 仍归编制职责人(`docduty.Resolve` 不变)。
- 人工编辑传 `ActorIsMember`,不复用 `RoleSystem`。
## 验证
见 [测试报告](../test-reports/2026-09-24-non-author-member-access-test-report.md);真实 PI PASS。
## 状态
resolved(2026-09-24)
## 五态收口(2026-09-24)
| 字段 | 值 |
|---|---|
| review_state | accepted(真实 PI `TestNonAuthorMember_PiAgent_RunEditSubmitGates` PASS;工程门禁 PASS) |
| integration_state | merged_local_dev(`dev@e98e2d71`;feature tip `8b2621a4` 为祖先) |
| deployment | not_required(本轮未要求加载 launchd 业务制品) |
| cleanup | pending(`.worktrees/non-author-member-access-2026-09-24` 与 integrate 现场待独立维护者复查后清理;禁止 `--force`) |
| remote_sync | pushed(`origin/dev` = `e98e2d71`,`./scripts/git-push-dev.sh dev` 已成功) |
相关 agentctl 任务:`non-author-member-access-2026-09-24`、`non-author-member-access-docs-2026-09-24`、`integrate-non-author-docs-2026-09-24` 均为 `done`。
@@ -0,0 +1,45 @@
# PI Subagent 执行器初版边界审查
task_id:subagent-workflow-standard-2026-09-24;issue_id:ISSUE-20260924-pi-executor-boundaries。
owner:Cursor(修复)/ Codex(复核);issue_state:resolved;severity:high。
本记录针对尚未发布的执行器初版,不表示 dev 或产品 Runner 存在这些实现。
## 事实与机制
1. 独立验证发现 PI 内置工具的路径规范化与扩展守卫不一致。安装版本 0.85.1 的 tools/path-utils.js 中 resolveToCwd 使用 stripAtPrefix 并展开 home;初版守卫使用 path.resolve(root,input)。
2. 以专门创建的 /tmp/pi-guard-audit-* 临时目录及 outside.txt 假文件测试 @绝对路径,实际结果为 guard_blocked=false、actual_tool_path_escapes=true。没有读取真实密钥或业务文件。
3. 同类范围:@ 前缀、~ 前缀、相对父路径、符号链接、Unicode/读取路径规范化;MCP 的同仓/工作区验证和临时文件写入;报告幂等与损坏收据;进程树/输出上限/环境变量隔离。
4. 初版静态阅读另发现:跨仓 MCP 可能执行目标仓脚本;输出仅在 communicate 完成后截断;只回收仍存活 leader 的进程组;测试环境黑名单不足;模型报告用关键词推导 PASS。上述需要实现修复和负例,不以本行代替实测。
5. 初版测试夹具存在 eager stderr.read(),在 MCP 仍存活时阻塞。host 两次仅终止 /tmp/pi-subagent-test-* 的假 MCP 子进程以释放测试,未终止产品或用户进程。
## 复现与迭代
- 初次 RED:19 项,7 failures / 11 errors,主实现未创建;存在性/调用失败为已缺失功能,不当作实现通过。
- 初版回归:19 项,4 failures / 7 errors;耗时含夹具死锁处理。后续错误数不作为发布质量结论,待主机完整重跑。
- Cursor 首轮 supervisor 已由 host 为明确的修复交接发送 TERM,退出143;源文件保留。没有未知写副作用后盲目重派,第二轮是带具体修复清单的新执行。
- 本机 Qwen3.8-Flash、GLM-5.3-Flash 无工具短请求连通通过,实际 provider/model 与配置一致,正常 stop + agent_end/agent_settled。仅连接证据。
- GLM-5.3 对初版整包快照的只读审查 300 秒超时,无完整结论;不报审查 PASS。进程由 subprocess 超时处理结束,未授予工具,无仓库写入。
## 修复与验收要求
Cursor 修复清单已交接:统一/拒绝路径规范化;MCP 同仓注册验证和无租约写入;有界双向进程通信/整体回收;测试环境白名单;严格请求/配置与冻结 SHA;损坏收据禁止重派;报告完成与审查通过分离;最终事件完整性;禁用 PI 隐式重试;相关真实 Git/进程/MCP 回归。
关闭条件:静态发现均落实对应修复或有证据排除;原例与同类负例通过;真实 PI 调用经新执行器完成;审查与测试报告保存。修复中,不新增 validated 经验;验证后再总结。
## 2026-09-24 修复关闭
issue_state=resolved 仅针对未发布初版的约定缺陷;代码提交 69ffaa677e23a1dd9aa0528bb09b3acfcd38b119,主机完整工程回归 173 项通过,提交后专项 34 项通过;最终 Cursor CLI→MCP→PI 中 ls/read 全通过。实际覆盖、早期失败和独立 GLM 审查边界见[报告](../test-reports/2026-09-24-pi-executor-test-report.md)。
新增[经验](../ops/lessons/2026-09-24-pi-tool-boundaries.md)。本文件前面的“修复中/待验证”为初版历史,当前结论以本节为准。dev 集成/客户端 IDE 验收不由本问题关闭状态推导。
## cursor-cli-mcp-path
issue_id:ISSUE-20260924-cursor-cli-mcp-path;issue_state:deferred;severity:medium;owner:工程维护;日期:2026-09-24。
本机 Cursor CLI 2026.09.18 在项目 MCP args 中未展开 workspaceFolder 变量,原样传给 Node。pi-subagents 新入口已改工作区相对路径并实测通过。
同类只读检查:agent mcp list 也显示既有 agentctl / jev Connection failed,它们仍使用相同变量写法;codegraph ready。未进一步修改/验收这两个既有服务,也未断言 IDE 同样失败。官方支持声明与本机观测须分开。
此残差不阻塞 PI MCP(其内部直接调用主仓治理 CLI),不构成本轮产品发布结论;后续由工程维护在 Cursor CLI 升级或这两项 MCP 接入验收时检查路径/stdio 协议,形成独立修复与实际客户端证据。仅保留问题,不宣称已修复。
## cursor-cli-mcp-path 续:NDJSON 回包
2026-09-24 IDE:`pi-subagents`/`codegraph` ready;`agentctl`/`jev` 不在 MCP 缓存。
根因补充:后两者 `send()` 使用 `Content-Length` 帧,而可加载的 `pi-subagents` 使用换行分隔 JSON-RPC。已改为 NDJSON 回包并补 `"type":"stdio"`;仍接受 Content-Length 请求。单元:`scripts/tests/test_mcp_ndjson_framing.py`。IDE 重载后需再核 `list-tools`。
@@ -0,0 +1,111 @@
# Cursor Auto 与 Subagent 工作流研究及文档验证报告
日期:2026-09-24;owner:Codex;task_id:subagent-workflow-standard-2026-09-24。
范围:现行规范、Cursor 项目配置及官方文档;交付[规范草案](../ops/2026-09-24-subagent-workflow-standard.md)。未运行 Cursor 对话/真实 subagent,未修改产品或运行环境。
## 1. 研究结论
推荐主 Agent 协调、按需委派、独立审查与验证的流程。用户提出的八步可作为起点,但需在开始明确授权/验收标准,在方案阶段设计测试,在实施中自测,合并后核对实际运行结果,最后归档和清理。
| 方案 | 收益 | 代价/缺陷 | 结论 |
|---|---|---|---|
| 单 Agent 顺序完成全部阶段 | 简单、额外上下文成本低 | 实施者自审容易沿用错误假设 | 适合小型文档/研究;代码交付补独立审查 |
| 每阶段固定一个 Agent / 固定模型 | 阶段职责直观 | 无效启动和文档重复;固定模型背离 Auto;阶段间易丢授权/版本 | 不采用 |
| 主 Agent + 按需 analyst/reviewer/verifier | 保留上下文入口,独立检查,成本可控 | 需可靠派发包、证据接收和异常恢复 | 推荐;实现并行按风险逐步启用 |
这是本项目基于现状的设计判断,不是 Cursor 平台保证。
## 2. 官方能力与推论
查阅日期为 2026-09-24。在线文档会变化,客户端接入必须另验;不采用社区传闻作为技术契约。
| 来源 | 查证事实 | 对本规范的影响 |
|---|---|---|
| [Cursor Subagents](https://cursor.com/docs/subagents) | 自定义角色可位于 .cursor/agents;model 默认 inherit;readonly 与后台字段可配置;子上下文需要主 Agent 提供输入;默认共享 checkout | 采用继承策略、显式交接、仓库管理的写隔离;只读报告由主 Agent 保存 |
| [Cursor Models & Pricing](https://cursor.com/docs/models-and-pricing) | Auto 是平台模型路由选项,公开文档列有不同优化模式 | 规则不绑定模型、价格或固定路由;按实际 UI/账户能力记录 |
| [Cursor Rules](https://cursor.com/docs/rules) | 支持 AGENTS.md 和项目规则 .mdc | 根入口/客户端入口只指向单一规范,避免重复规则漂移 |
推论与限制:inherit 能表达继承意图,不足以证明实际模型身份或所有 Auto 请求的路由;独立上下文不保证跨模型独立性;只读权限与运行测试的写产物需要区别处理。Auto 可用性、角色加载、权限、真实派发及费用均未在本会话实测,不保证任何套餐或所有版本可用。云执行不在本次授权与建议默认范围内。
## 3. 当前仓库证据
检查基线:dev = 5423b261f97f371bdf7fa5066e9305f9eddaef42;本地 origin/dev 跟踪引用比较为 ahead 74 / behind 0。未 fetch,不能据此声明服务器当前引用。
- AGENTS / PROJECT:已定义授权分级、任务 worktree、独立状态、业务实施和研究边界。
- worktree 操作规范:已有 agentctl 租约、候选验证/合入、共享环境持锁、清理负例和收口要求。
- 验证契约:依据变更范围取并集,要求真实用户流程与持久证据;文档变更不要求产品回归。
- 文档地图/任务模板:已有最小文档原则,可以按阶段留证而不制造九份重复文档。
- .cursor/rules:已有 agentctl、文档、Git 和测试入口。rg --files .cursor 未发现项目 .cursor/agents 角色定义;不推断用户全局目录没有角色。
- .cursor/hooks.json:存在 beforeShellExecution 的 Git 守卫;未见本流程阶段完整性校验。此处仅配置阅读,没有实际触发 hook。
- cursor --version:3.21.16 / 8ae78e8eee1e63479c7e0504b664bc0a80c68000 / x64;agent --version:2026.09.18-9a7762b。CLI 版本不代表 IDE 当前会话配置已验收。
- agentctl status:当前配置 policy_revision 为 agent-governance-2026-09-23-fav-constraint-restored;存在其他任务持 env:dev。研究不使用该环境,不改他人任务。
已读规范修订与工具配置 revision 不同,记录两者分别是什么,不把一个全局字段视作所有 Markdown 修订版本。
## 4. ISSUE-20260924-cursor-test-rule-drift
issue_state:open;严重度:medium;owner:Codex(研究);evidence_basis:本次源码/配置阅读;产品影响未复现。
预期:客户端测试规则只引用验证契约,由适用范围和批准环境决定套件/Runner。
实际:.cursor/rules/test-reports-standard.mdc(alwaysApply=true)仍要求报告附全量 go test -v ./...,固定 MiniMax-M2.7-highspeed,并指向已不存在的 PROJECT §8。与验证契约中的范围选择、实际批准模型、普通小任务记录方式不一致。
已证实机制:客户端复制完整测试规则形成第二份来源,主规范修订后副本继续陈旧。未证实:实际 Cursor 是否因此执行了错误模型/测试、费用或运行行为是否受影响。
为何已有保护不足:静态读取显示没有针对该副本文案与验证契约的一致性证据;本次没有运行 hook/CI,不能断言所有自动防护都缺失。
同类检查范围:.cursor/rules 下五个规则文件及 hooks 配置、根 AGENTS/PROJECT、验证契约、规范登记、任务/收口模板。其余四个 mdc 主要转发入口;本次未检查所有其他客户端和全局规则。
推荐修复:将该 mdc 缩为验证契约与报告路径指针;结构要求归并现有权威文件,避免再复制模型与全量命令。不是改产品 Runner 模型或删除必要验证。
验收:规则文本无固定模型/无条件全量测试/失效章节;文档任务、Go 任务、产品 PI 任务分别映射到既有验证矩阵;Cursor 实际读取入口并正确选择验证层级。静态修复与实机行为分别报告。
时间线:2026-09-24 发现并登记;本次仅提出修复,未实施,issue 保持 open。无新 validated lesson;未验证修复不包装成经验。
## 5. 风险和关键设计
- 阶段和角色不是一对一关系:固定九名 Agent 会增加交接成本;初期三角色足够,主 Agent 可实施。
- 只读 reviewer 无法自行写审查文件:主 Agent 转存并保留作者/ID,避免“要求只读同时要求落盘”的矛盾。
- verifier 运行构建/测试会写缓存、数据甚至环境:单独授权,持对应租约,不能装作普通只读检查。
- 子 Agent 默认共享目录:采用单写者;并行写另建登记 worktree,主会话的自动隔离配置不替代仓库门禁。
- 审查和测试必须绑定版本:修复后重审受影响范围;候选变化重验;运行制品与报告提交分开。
- 清理在验收后:唯一日志/截图先归档,owner 退出后由维护者复查,不主动删除当前使用的工作区。
- 人工确认默认在可审方案形成后;已有端到端授权则沿用。用户未回复偏好,本草案采用该可调整默认,不把沉默当批准。
- 模型路由和自动审批不同:Auto 不扩大业务或环境权限,普通 Cursor 不套用 Herdr 固定模型。
- 阶段规范为 manual;文档审核通过不等于自动执行系统已实现。
## 6. 文档验收与未运行项
本次仅文档研究。静态检查结果在任务“验证与证据”节记录;检查对象为本次全部变更文件内容。
情景自审覆盖:研究-only、简单文档、标准功能、修复回环、并行冲突、readonly 转存、子任务未知、候选变化、验收失败、清理拒绝、上下文恢复。该项是文档推演,不能作为运行负例 PASS。
本次未执行:Cursor Auto 真实派发、Cursor 项目角色配置安装、并行写锁实测、业务测试、产品 PI、浏览器、部署和清理。新规范的 V1–V10 实机清单是后续接入验收项。
## 7. 文档情景自审记录
审查者:Codex 主 Agent;独立性:self_review。以下为阅读草案逐项推演,结果仅表示文字路径可执行,不表示已运行客户端。
| 情景 | 对照位置 | 结论 |
|---|---|---|
| 只研究方案,未授权实现 | §2、S3 | 可交付研究,其后标不适用;不会顺推业务实现 |
| 一处低风险文档修改 | §4、§7 | 主 Agent 自检,一份主文档可承载阶段,无需九个角色 |
| 代码已修改但审查未回收 | S5、§5 | 不进入集成;后台结果需接收 |
| 修复后旧审查/旧测试仍通过 | S5–S7 | 新版本需适用复核与验证,旧 PASS 不覆盖 |
| readonly reviewer 需要报告 | §4、§7 | 子角色回传,主 Agent 在租约内转存 |
| 测试生成缓存或写环境 | S6、§8 | verifier 可写但须明确产物范围/环境与租约 |
| 两个子任务争用同路径 | §5 | 单写者或独立登记隔离,不能无锁并发 |
| 子任务超时且副作用未知 | §6 | 保留 unknown,核对现场后决定恢复 |
| 合并前 dev 已变化 | S7 | 重建候选并重新验证 |
| 已合入但运行验收失败 | S8、S9 | 不宣布完成、不清理;修复/交接 |
| owner 仍在 worktree 或有唯一日志 | S9、§5 | 保留现场,归档后由独立维护者复查 |
| 会话中断后恢复 | §6、§7 | 从首个未满足门禁继续,核对未回收子任务 |
初次静态检查真实输出:`FILES=8 LOCAL_LINKS=84 STAGES=10 ISSUE_IDS=5 / PASS`。
命令:`git diff --check`(exit 0);Python 内联检查全部本次 Markdown 变更(含 untracked)的相对链接/锚点、S0–S9、规则状态字段和 issue ID 唯一性(exit 0)。不验证外部网页永久可达或实际 Cursor 行为。
只读 `agentctl docs drift`:status=ok、regressions=[];开放能力候选未修改,不等于产品就绪。
## 8. 后续决策:本机 PI 与可调整模型配置
用户在同一任务后续对话明确:子智能体采用 gmktec 本机 PI;仅允许 minimax-cn/MiniMax-M3、zai-coding-cn/glm-5.3、zai-coding-cn/glm-5.3-flash、qwen-token-plan-cn/qwen3.8-max、qwen-token-plan-cn/qwen3.8-flash。随后明确代码由 Cursor 实施,并因 M3 的实际使用反馈将其移出默认流程,最后确认该默认安排并要求可调整文档。
这些用户决策取代本报告前文 r1 中 Cursor 原生 .cursor/agents/inherit 的接入建议;前文保留为研究历史,不再作为当前实现方向。现行模型映射唯一来源为[模型配置](../ops/2026-09-24-subagent-model-config.md),流程草案同步到 r2。没有改变 Herdr 或产品 Runner。
2026-09-24 再次执行 pi --offline --no-extensions --no-skills --no-prompt-templates --no-themes --no-context-files --no-approve --list-models,exit 0;精确五个 provider/model 均存在。此命令没有模型推理,不证明各角色能力或连接状态。配置字段由主 Agent 人工读取,当前不含执行器/热加载/自动校验实现。
## 9. 执行器已接入(后续实现)
用户进一步授权接入自动调用 PI 的执行器。代码提交 69ffaa677e23a1dd9aa0528bb09b3acfcd38b119,真实 Cursor CLI→MCP→PI 和 173 项工程回归通过,详情见[验证报告](../test-reports/2026-09-24-pi-executor-test-report.md)及[运行说明](../ops/2026-09-24-pi-subagent-executor.md)。前文关于未接入/未调用的说明属于当时研究阶段;当前交付范围与未覆盖项以上述新报告为准。完整流程草案审批、dev 集成和远端同步分别记录。
@@ -0,0 +1,208 @@
---
title: "对话办公能力全景盘点"
created: 2026-09-25
owner: Cursor
task_id: dialogue-office-expansion-2026-09-25
policy_revision: cursor-governance-2026-09-24-r1 @ 44161d2ad2d7aada3e9ff88127b52148543278e5
review_state: pending
integration_state: pending
deployment: not_required
cleanup: pending
remote_sync: not_requested
status: done
confidence: high
---
# 调研:对话办公能力全景盘点
## 范围与授权
- **用户目标**:以「对话辅助办公」为初衷,最大限度扩展对话可操作范围;**创建项目、添加成员、设置等治理结构操作保持 UI 专属**。
- **本轮交付**:研究报告 + 分期整改计划(文档落盘);P0–P3 **实施另起任务**。
- **允许写路径**:`.doc/audit`、`.doc/remediation`。
- **基线 SHA**:`44161d2ad2d7aada3e9ff88127b52148543278e5`(建场时 local `dev`)。
- **非目标**:不改产品代码、不更新 CURRENT/FEATURE-MATRIX/gap-matrix、不部署。
- **整改方案**:[2026-09-25-dialogue-office-expansion-plan.md](../remediation/2026-09-25-dialogue-office-expansion-plan.md)
## 结论
1. 注册表共 **32** 个 ActionKey(非早期估计的 34);主链路与 intentflow 计划执行面 **双轨脱节**:计划层 U11/U12 已把部分键 live 化,单意图协调层仍对认领/送审/工作流触发等返回「假成功」话术。
2. HTTP **169** 条路由可按对话边界分为:可操作候选 **A=46**、只读查询 **B=66**、UI 专属写/管理台 **C=44**、平台基线 **13**。
3. 消除假成功、打通 dry-run、接真实查询源、再扩新写意图,应按 P0→P3 分期;一律复用 doc-review 四道防线(识别分流 → 话语分类 → 角色×状态出卡 → 执行二次鉴权),两步确认 + 服务端权威校验。
## 证据
| 项 | 路径/命令 | 结果 |
|----|-----------|------|
| ActionKey SSOT | `internal/intent/registry.go` `registerBuiltinActions` L145–187 | **32** 键 |
| 主链 docgov | `internal/coordinator/engine_docgov.go` | claim/submit 假成功;approve/reject 有 PendingAction |
| 主链 workflow | `internal/coordinator/engine_workflow.go` | switch 确认闭环断裂;trigger 引导 UI |
| intentflow dry-run | `internal/app/intentflow/expansion.go` L195–216 | docgov 5 dry-run + run-control 2 dry-run |
| HTTP 路由 | `rg 'mux\.HandleFunc\("' internal/server/server.go internal/server/document_revision_handlers.go` | **169** |
| 样板 | doc-review-lifecycle `09fe9723`;`card_policy.go` / `recognizer_matchers_docgov.go` / `action_executor.go` | 四道防线可复用 |
## 1. 意图执行矩阵(32 ActionKey)
**执行类别说明**
| 类别 | 含义 |
|------|------|
| `real-exec` | 协调层或 PendingAction 已调用领域服务真写 |
| `pending-action` / `confirm-card+pending` | 出确认卡或挂起期望,确认后 `action_executor` 真写 |
| `query-direct` | 只读查询,直接回复(可能含硬编码兜底) |
| `prose-only` | 仅自然语言,无业务副作用(或明确拒绝) |
| `假成功` | StatusAccepted/成功话术,但未调用权威写服务 |
| `dry-run` | intentflow Owner 返回 `validated_only` receipt,无副作用 |
| ActionKey | 中文 | 主链类别 | 计划链(intentflow) | 主处理 | 后端 owner |
|-----------|------|----------|----------------------|--------|------------|
| `project.advisory` | 进展/风险查询 | query-direct | QueryOwner | `engine_query.go:handleQueryProgress` | 协调层/LLM |
| `project.fact.supplement` | 补充项目事实 | real-exec | Mutate(flag 下 dry→live) | `engine_stage.go:handleSupplementInfo` | ctxmgr / MutateOwner |
| `project.stage.advance` | 推进阶段 | real-exec / 无 runner 时 prose 模拟 | — | `engine_stage.go:handleAdvanceStage` | stageflow |
| `task.run` | 触发生成任务 | real-exec | TaskRunAdapter | `engine_task.go:handleTriggerTask` | stageflow / taskrun |
| `task.run.adhoc` | 特设任务 | real-exec | — | `engine_task.go:handleTriggerAdhocTask` | 同上 |
| `conversation.chat` | 闲聊 | prose-only | — | `engine_consult.go:handleCasualChat` | dialogue LLM |
| `conversation.decline` | 暂缓建议 | prose-only | — | `engine_stage.go:handleDeclineExpectation` | 上下文 |
| `document.claim` | 认领文档 | **假成功** | live(U11) | `engine_docgov.go:250–277` | 主链仅改 Claimed 列表;计划→docgov |
| `document.review.submit` | 提交审核 | **假成功** | live(U11) | `engine_docgov.go:280–295` | 主链纯文案;计划→`SubmitForReview` |
| `document.review.approve` | 审核通过 | pending-action | **dry-run** | `engine_docgov.go:handleDocGovApprove` | `docgov.ReviewApprove` |
| `document.review.reject` | 审核驳回 | confirm-card+pending | **dry-run** | `engine_docgov.go:handleDocGovReject` | `docgov.ReviewReject` |
| `document.final.approve` | 终审批准 | confirm-card+pending | **dry-run** | 同上 Approve 分支 | `docgov.ApproverApprove` |
| `document.final.reject` | 终审驳回 | confirm-card+pending | **dry-run** | 同 reject | 同上 |
| `document.proposal.decide` | 提案裁决 | confirm 分支真挂起 / **默认分支假成功** | **dry-run** | `engine_docgov.go:298+` | confirm_*→PendingAction |
| `regulation.query` | 法规查询 | query-direct | QueryOwner | `engine_query.go:handleQueryRegulations` | kb.Client + 模板兜底 |
| `case.query` | 相似案例 | query-direct | QueryOwner | `engine_query.go:handleQuerySimilarCases` | SearchSimilarCases + **硬编码案例** |
| `permission.query` | 权责查询 | query-direct | — | `engine_query.go:handleQueryUserRights` | UserDocs 上下文 |
| `document.reject_reason.query` | 驳回原因 | query-direct | — | `engine_query.go:handleQueryRejectReason` | 黑板 + default 文案 |
| `card.confirm` | 确认挂起期望 | confirm 元动作 | — | expectation 映射 | 路由至目标 intent |
| `project.stage.execute` | 阶段执行确认 | 注册有、switch **无独立 case** | — | 实际走 advance | 同 advance |
| `security.forbidden` | 安全禁止 | prose-only | RejectPlan | `engine_consult.go` | — |
| `workflow.switch` | 切换激活工作流 | **假成功(确认后无执行)** | **dry-run** | `engine_workflow.go:12–59` | **边界上属结构治理 → 宜诚实拒绝/引导 UI** |
| `workflow.run` | 运行工作流 | **假成功(引导 UI)** | live(U12) | `engine_workflow.go:62–90` | 计划→`CreateWorkflowRun` |
| `workflow.status.query` | 工作流状态 | query-direct | — | `engine_workflow.go:93` | UserProjectContext |
| `document.status.query` | 文档状态 | query-direct(常空模板) | — | `engine_workflow.go:117` | 模板/document_summary |
| `conversation.help` | 能力帮助 | query-direct | — | `engine_workflow.go:139` | AvailableActions |
| `conversation.unsupported` | 不支持 | prose-only | — | `engine_workflow.go:159` | — |
| `run.status.query` | 运行状态 | query-direct | — | `engine_run.go:handleRunStatusQuery` | WorkDir |
| `run.resume` | 续跑 | confirm-card+pending | live(U12) | `engine_run.go:handleRunResume` | taskrun |
| `run.restart` | 重启 | confirm-card+pending | **dry-run** | `engine_run.go:handleRunRestart` | taskrun.restart |
| `project.impact.analyze` | 影响分析 | query-direct | — | `impact_actions.go` | ImpactActions |
| `project.doc.revise_propose` | 修订提案 | confirm-card+pending | — | `impact_actions.go` | ProposeRevision |
### 1.1 假成功清单(主链路优先)
| # | Legacy / Key | 文件:行号 | 当前行为 | P0 建议 |
|---|--------------|-----------|----------|---------|
| 1 | `DOCGOV_CLAIM` / `document.claim` | `engine_docgov.go:250–277` | 仅 append `UserDocs.Claimed`,回复「已成功认领」,不调 docgov | 真执行 `RecordDocumentViewed`/claim API + 确认(若需) |
| 2 | `DOCGOV_SUBMIT_REVIEW` / `document.review.submit` | `engine_docgov.go:280–295` | 纯成功文案,无状态变更 | 真执行 `Gov.SubmitForReview` + 角色门禁 |
| 3 | `DOCGOV_PROPOSAL_DECIDE` 默认分支 | `engine_docgov.go:383–397` | 非 confirm_* 时按 proposal_action 返回采纳/拒绝文案,不写文档 | 默认分支诚实澄清或走确认卡;禁止假成功 |
| 4 | `SWITCH_WORKFLOW` / `workflow.switch` | `engine_workflow.go:12–59` | 设 NextExpectation 要求确认,**确认后无写路径** | **诚实拒绝**:属 UI 专属(`PUT …/active-workflow`);或确认后明确「请在设置面板操作」 |
| 5 | `TRIGGER_WORKFLOW` / `workflow.run` | `engine_workflow.go:62–90` | 「请在面板确认」话术,不创建 run | 确认卡 + `CreateWorkflowRun`(对齐 U12) |
附带(非计划 P0 五处,但同类):无 runner 时 `ADVANCE_STAGE`/`TRIGGER_TASK` 模拟成功;`VIEW_DOC` lifecycle 空模板。
### 1.2 intentflow 仍 dry-run 的键
**DocGov**(`docGovActionKeys` 7 − `DocGovLiveActionKeys` 2 = **5**):
- `document.review.approve`
- `document.review.reject`
- `document.final.approve`
- `document.final.reject`
- `document.proposal.decide`
**Run-control**(4 − live `workflow.run`/`run.resume` = **2**):
- `workflow.switch`(计划层 dry-run;产品边界建议永久不 live 写,改为拒绝)
- `run.restart`
见 `internal/app/intentflow/expansion.go` L195–216;dry-run 行为 `DryRunAdapter.Execute` → `validated_only`。
## 2. HTTP 169 路由 × 对话边界
**统计口径**:`internal/server/server.go` `Routes()` + `document_revision_handlers.go` `registerDocumentRevisionRoutes()` 中 `mux.HandleFunc("METHOD path")` = **169**。不含中间件 OPTIONS、SPA 静态子路径。
| 类别 | 计数 | 含义 |
|------|-----:|------|
| **A 对话可操作候选** | 46 | 读写副作用;对话须两步确认后经服务层落库 |
| **B 只读查询候选** | 66 | GET + preview POST |
| **C UI 专属** | 44 | 治理结构写 + admin 全域(含管理台只读) |
| 平台基线 | 13 | health/ready、认证、SPA、`/me` 自服务 |
| **合计** | **169** | |
### 2.1 A — 对话可操作候选(46)
| 模块 | n | 代表路径 | 对话意图现状 |
|------|--:|----------|--------------|
| docgov | 11 | `POST …/docgov/{claim,submit-review,review-decision,approver-decision,proposal,proposal/decide,comments,content,lease/*}` | 批准/驳回已打通;claim/submit 主链假成功;comments 等偏 UI |
| docrevision | 2 | `PATCH …/documents/{id}/content` · `POST …/agent-candidates/{id}/decision` | 正文 PATCH 仅 HTTP;候选决策可对话扩展 |
| trace | 6 | `POST …/trace/{index,analyze}` · `…/edges/{id}/decision` · `…/reopen` · `…/recheck/…/clear` | 影响分析意图有;**边裁决/重开仅 HTTP** |
| 补充批次 | 1 | `POST …/supplement-impacts/{batch_id}/decision` | 补充意图有;批次确认可对话化 |
| 工作流运行(非结构) | 2 | `POST …/workflows/{key}/run` · `…/stages/{stage}/advance` | run 主链假成功;advance 有意图 |
| 任务执行 | 6 | `POST …/tasks/{run,run/stream,runs}` · `…/{cancel,resume}` | 触发/续跑已打通 |
| 对话写 | 8 | `POST …/chat*` | 会话基础设施 |
| 意图计划 | 1 | `POST …/intent-plans/{id}/decisions` | intentflow + HTTP 双通道 |
| 自由文档 | 6 | `POST/PUT/DELETE …/freeform-documents*` | **仅 HTTP** → P3 候选 |
| 资产 | 2 | `POST …/assets` · `…/reparse` | **仅 HTTP** → P3 |
| 通知 | 1 | `PATCH …/notifications/{id}` | **仅 HTTP** → P3 |
| 用户偏好 | 1 | `PUT …/context/user/preference` | 低优先级 |
### 2.2 B — 只读查询候选(66)
项目/工作流/成员/设置 **GET**、termination/activation **preview**、chat 历史检索、docgov audit/comments GET、修订 ledger GET、资产 raw、通知列表、context/cases 等。
对话已覆盖:进展、文档/工作流/运行态、驳回原因、法规/案例/权限(案例与进展有硬编码兜底)。
仍偏 HTTP:职责现状、修订版本/diff、trace 图、终止预览、成员列表只读(允许对话只读引导,禁止代写)。
### 2.3 C — UI 专属红线(44,对话永久禁写)
| 模块 | 写操作(禁入) |
|------|----------------|
| 项目/成员 | `POST /projects` · `POST|PUT|DELETE …/members` |
| 职责 | `PATCH …/doc-tasks/{taskKey}/duties` |
| 工作流结构/生命周期 | `PUT …/workflow-plan` · `PUT …/active-workflow` · `POST …/workflow-instances/activate` · `POST …/terminate` |
| Admin | 角色/用户/密码/工作流定义 publish·retire/模板/config/system settings/maintenance/workspaces cleanup |
对话侧应对命中措辞走 `security.forbidden` / `conversation.unsupported`,**仅允许只读查询与引导**(如读职责现状、`termination-preview`)。
> **澄清**:`workflow.switch`(改 active-workflow)落入 C;`workflow.run`(创建运行实例)落入 A。P0 对前者诚实拒绝,对后者真执行。
## 3. 查询硬编码兜底
| 场景 | 位置 | 问题 |
|------|------|------|
| 相似案例 | `engine_query.go:420–426` | 无数据时硬编码 PRJ-2025-008 / PRJ-2024-019 |
| 驳回原因 | `engine_query.go:260–276` + `card_policy.go:defaultRejectReasonText` | 黑板/事件捞取失败则默认文案 |
| 法规 | `engine_query.go:382–388` | KB 空则 GB/YY 模板 |
| 进展简报 | `engine_query.go:83–164` | 默认项目名与长硬编码段落 |
| 文档状态 | `engine_workflow.go:126–129` | lifecycle 空 → 引导面板 |
## 4. 复用样板:doc-review 四道防线
参考合入/分支证据:`feature/doc-review-lifecycle-2026-09-25` @ `09fe9723`(批注/重开/积压/送审真执行)。
| 防线 | 符号 | 要点 |
|------|------|------|
| ① 识别分流 | `recognizer_matchers_docgov.go:matchDocGovAction` | 查询语气不误路由写动作 |
| ② 话语分类 | `card_policy.go:ClassifyRejectUtterance`(Web 对称) | QUERY / EXECUTE / OTHER |
| ③ 角色×状态出卡 | `ResolveRejectCard` / `buildRejectConfirmCard` | 无权限不出危险按钮 |
| ④ 执行二次鉴权 | `handleDocGovReject/Approve` + `chat/action_executor.go` | 确认后调 `GovernanceEngine` |
后续写意图扩展必须复制该模式,禁止「话术成功、服务未写」。
## 5. 开放问题
- `project.stage.execute` 注册未接线:是否删除或显式映射到 advance(实施期决定)。
- 自由文档/通知/资产对话化的产品优先级与确认文案(P3 开工前再确认)。
- `workflow.switch` 是否保留意图仅作「引导 UI」还是识别层直接 `unsupported`(推荐后者,减少假确认)。
## 建议动作
见整改计划 P0–P3;本调研 **status=done** 仅表示盘点可审,**不代表问题已修复**。
## 状态与交接
- 产物:本文 + [整改计划](../remediation/2026-09-25-dialogue-office-expansion-plan.md)
- 实施:另起 `feature/dialogue-office-p0-…` 等任务;每期独立验证与验收
- CURRENT / MATRIX / gap-matrix:本轮不动
- catalog:`feature=dialogue-office`,scope `.doc/audit`+`.doc/remediation`;与 `docgov` feature claim 硬冲突,故未占用 `docgov` 键
+267
View File
@@ -0,0 +1,267 @@
---
title: "系统全面 Code Review(local_dev tip)"
status: done
created: 2026-09-26
owner: Cursor
task_id: "system-code-review-2026-09-26"
policy_revision: "agent-governance-2026-09-21-r1 + cursor-governance-2026-09-24-r1 @ f4c1b73f28580ad3df6db4f9ec0a80057006e516"
review_state: accepted
integration_state: integrated
deployment: not_required
cleanup: done
remote_sync: not_requested
updated: 2026-09-26
severity: high
---
# 系统全面 Code Review(local_dev tip)
## 范围与授权
- **用户目标**:对系统做一次全面 code review,并按规范形成报告;**不允许实施修复**,只形成报告。
- **被审对象**:本地 `dev` tip `f4c1b73f28580ad3df6db4f9ec0a80057006e516`(merge: swboot-closeout-2026-09-26-r3);运行态参考 no-docker local_dev(`bin/agent-server`,schema 75),本报告以代码与门禁证据为主。
- **允许写路径**:`.doc/`(本审计主文档、INDEX、short-term 任务记录)。
- **交付终点**:可审审计报告 + 索引挂接;不改业务代码、不改 gap-matrix / FEATURE-MATRIX 状态值、不部署。
- **非目标**:逐文件全量行审、依赖 CVE 扫描、前端 XSS 系统化、动态渗透、实施整改。
- **方法**:并行四轴审查(架构边界 / 安全 / 可维护性 / 关键执行路径)+ 本机 `./scripts/arch-check.sh --mode block`、规模盘点与关键片段复核。
## 问题登记与经验检索
- **issue_id**:本轮不新建 ISSUES 行;发现项以本报告 FIND-* 编号跟踪。若后续授权修复,再按 [闭环规范](../ops/2026-09-23-issue-learning-workflow.md) 升 issue。
- **检索词**:`IDOR`、`GetUserContext`、`session_id`、`validated_only`、`fencing`、`arch-check`、`table_owners`、`ALLOW_IN_MEMORY`、`sh -c`、`swboot`。
- **命中**:历史审计见 [INDEX](./INDEX.md)(模块耦合 2026-09-20、对话办公盘点 2026-09-25、gap-matrix);经验库无与本轮 FIND-SEC-01 完全同题的已关闭 lesson。**采纳检查**:对照模块开发规范 §2/§4、authz fail-closed 惯例、intentflow 注释契约。
## 总判(Verdict)
`arch-check --mode block` **PASS**,且多项生产门禁(任务路径 stub 拒绝、FAV outbox consumer 多层禁用、docgov 角色不信任 body)仍然有效。但系统存在三类结构性风险:
1. **安全旁路**:会话上下文 IDOR(已证实);Authorizer 无池 fail-open;swboot `sh -c` + 前缀白名单。
2. **门禁空心化**:未登记表的 SQL 写被 arch-check **静默跳过**;server 仍持 `Runtime.Pool` 并直查/直写。
3. **多入口编排**:docgov / 多意图 / flag 面平行三套,关闭开关时存在静默降级。
本轮 **不改变** gap-matrix 的 `production_ready` 叙事;下列 critical/high 建议作为独立 remediation 候选,待授权后再立项。
## 现象
只读审查与门禁核验,无用户报障个案。审查期望:合入 swboot / dialogue-ctx / jevdecide / semantic-replace 后的 tip 在模块边界、鉴权与关键执行路径上仍满足生效规范。实际:门禁绿,但多处规范语义与实现分叉(见 Findings)。
## Findings(按严重度)
置信度说明:`verified` = 父会话已打开源码复核;`agent` = 子代理报告、抽样一致;`inferred` = 机制推断未跑动态用例。
### Critical
#### FIND-SEC-01 — 会话消息 IDOR(`session_id` 无归属校验)
| 项 | 内容 |
|---|---|
| 类别 | 授权 / IDOR |
| 位置 | `internal/server/handlers_context.go:17-50`;`internal/ctxmgr/manager.go:377-385` |
| 证据 | `handleGetUserContext` 仅校验 `user_id` 为本用户/管理员;`GetUserContext` 对 `chat_messages` 使用 `WHERE session_id = $1` **无 owner 条件**。对照 `chatflow` 读路径会校验会话归属。 |
| 影响 | 已登录用户若获知他人 `session_id`,可读取对方最近聊天正文。 |
| 置信度 | verified · high |
| 修复方向(不实施) | 复用 chatflow 会话授权;或按 `session.owner_id`/`user_id` 过滤后再返回。 |
#### FIND-ARCH-01 — arch-check 对未登记表静默跳过(表唯一写者门禁盲区)
| 项 | 内容 |
|---|---|
| 类别 | 门禁 / 模块边界 |
| 位置 | `internal/archtest/scan.go:198-205`;`module-boundaries.yaml` `table_owners`(约 59 表) |
| 证据 | `if !tracked { continue }`;本机 tip:`swboot_controlled_executions` / `projects` / `project_source_bindings` / `outbox_events` **UNTRACKED**;`arch-check --mode block` 仍 PASS。 |
| 影响 | 新表(含 swboot)可任意包写入而不触发 block;「表唯一写者」对未入库表无强制力。 |
| 置信度 | verified · high |
| 修复方向 | 未登记表的生产写应变 fail-closed,或强制登记。 |
#### FIND-ARCH-02 — server 持 Pool 直装 swboot 并 SQL 旁路
| 项 | 内容 |
|---|---|
| 类别 | 组合根越界 |
| 位置 | `internal/server/swboot_handlers.go`(NewPGRepoAllowlist / ControlledPatchExecutor / 直查 bindings & executions) |
| 证据 | 与模块规范 §2.1「server 只拿用例或端口」冲突;`app.Build` 已另有 allowlist 装配。 |
| 影响 | HTTP 层成为第二组合根;边界回归。 |
| 置信度 | agent · high(与规范条文一致) |
| 修复方向 | 收成 app 用例端口;禁止 handler 使用 `rt.Pool`。 |
### High
#### FIND-SEC-02 — Authorizer 无池时成员判定 fail-open
| 项 | 内容 |
|---|---|
| 类别 | 鉴权 fail-open |
| 位置 | `internal/authz/authorizer.go:112-114`、`205-207` |
| 证据 | `!a.enabled()`(pool==nil)时 `IsProjectMember`/`IsProjectOwner` 对 `userID>0` 返回 true;组合根始终 `NewAuthorizer(pool)`,nil pool 时 `authorizer()!=nil`,绕过「nil → failClosed」分支。 |
| 影响 | AllowInMemory / 无库误配时,任意登录用户可访任意 `project_id`。生产有 `ALLOW_IN_MEMORY` 门禁则触发面缩小,**机制本身仍 fail-open**。 |
| 置信度 | verified · high |
#### FIND-SEC-03 — swboot 受控执行:`sh -c` + basename 前缀白名单
| 项 | 内容 |
|---|---|
| 类别 | 命令注入面 / 边界语义 |
| 位置 | `internal/swboot/executor.go`(`sh -c`、前缀匹配);`ApproveMerge` 恒拒 |
| 证据 | 允许判定为字段首段 basename 前缀;命令经 shell 执行。执行器自身不做 merge/push,但若 admin allowlist 含 `git`/`bash` 等,客户端可间接 push/merge/deploy。 |
| 影响 | 在 creator + 宽松 allowlist 前提下,隔离 worktree 内可越出「测试命令」意图。 |
| 置信度 | agent · high |
| 说明 | 与 MATRIX「永不 merge/push/deploy」在「执行器 API」语义下仍成立;真正边界在 **admin 命令白名单粒度**。 |
#### FIND-FLOW-01 — intentflow `validated_only`/`proposed` 可经 confirm 进入 dispatch
| 项 | 内容 |
|---|---|
| 类别 | 执行模式门禁 |
| 位置 | `internal/app/intentflow/plans.go:365-376`;`intent_plan_handlers.go:86-88`;`ExecuteClaimed` 不读 `ExecutionMode` |
| 证据 | `DecisionConfirm` **允许** `PlanProposed`;确认后 HTTP 调用 `DispatchEligible`;`AllowedModes` 策略字段几乎未被执行路径使用。 |
| 影响 | shadow「安全」依赖「无人 Confirm」,而非执行器硬拒绝;U10/U11 live 已接线时可升级为真实写。 |
| 置信度 | verified · high(静态);未做动态 confirm 用例 |
#### FIND-QUAL-01 — docgov / 多意图多入口并行(职责扩散)
| 项 | 内容 |
|---|---|
| 类别 | 可维护性 / 双写路径 |
| 位置 | chat `docgov.*` PendingAction;`app/docgov_owner.go` `document.*`;`server/handlers_docgov.go`;intent vs intentflow 双套 flags |
| 证据 | 同一 `GovernanceEngine` 三入口;`intent.FeatureFlags` 与 `intentflow.FeatureFlags` 并存;Coordinator ~40 intent case + intentflow OwnerMux 平行。 |
| 影响 | 鉴权/确认/审计易漂移;回归矩阵笛卡尔积;开关关闭时 Mux→Query 静默降级(FIND-FLOW-02)。 |
| 置信度 | agent · high |
#### FIND-ARCH-03 — bizdev / Runtime / 万能 Engine 门面残留
| 项 | 内容 |
|---|---|
| 类别 | 架构债 |
| 位置 | `internal/bizdev/service.go`;`internal/app/app.go` Runtime;`docgov`/`coordinator` Engine |
| 证据 | bizdev 自开池并装配多引擎;Runtime 暴露 Pool+数十服务;Engine 方法面极大。arch-check allowlist 放行上帝包,PASS ≠ 模块化健康。 |
| 影响 | 新功能默认堆 handler/Runtime;与解耦批次目标持续摩擦。 |
| 置信度 | agent · high |
### Medium
| ID | 摘要 | 关键位置 | 置信度 |
|---|---|---|---|
| FIND-SEC-04 | 授权拒绝 404/403 区分,泄露资源存在性 | `task_run_auth.go`、`auth_helpers.go` | agent |
| FIND-SEC-05 | Chat SSE:阶段拒绝在 Flush 之后;`user_role` 可写入会话上下文 | `sse.go` | agent |
| FIND-SEC-06 | 对话 `agent.NewBackend` 对未知名默认 stub;生产密钥校验不禁 stub | `agent/backend.go`、`config.go` | agent |
| FIND-SEC-07 | 未认证 `/api/v1/vault/status` 暴露 FAV 开关 | `auth_middleware.go`、`vault.go` | agent |
| FIND-SEC-08 | 会话 token 存 `localStorage`(XSS 放大) | `web/src/api/auth.ts` | agent |
| FIND-DOC-01 | docgov 省略 fencing token 仍可写;heartbeat persist / squad reclaim fail-open | `docgov/lease.go` | agent |
| FIND-DOC-02 | `CommitAgentVersion` 与 edit lease 解耦竞态面 | `docrevision/service_agent.go` | agent |
| FIND-FLOW-02 | `OwnerMux` 在 U10/U11/U12 关闭时静默降级到 Query | `intentflow/mux.go` | agent |
| FIND-ARCH-04 | notification handler 端口失败后回落 Pool SQL | `notification_handlers.go` | agent |
| FIND-ARCH-05 | 提案批准后 handler 裸 goroutine 副作用 | `handlers_docgov.go` | agent |
| FIND-ARCH-06 | 错误信封拼接 `err.Error()` | 多 handler | agent |
| FIND-QUAL-02 | 全局 flag/metrics 损害并行测试隔离 | `intent/flags.go`、`intentflow/*` | agent |
| FIND-QUAL-03 | 巨石文件逼近/超过规范阈值(见规模盘点) | squad/taskrun/server/web | verified |
### Low / 契约说明
| ID | 摘要 |
|---|---|
| FIND-JEV-01 | jevdecide assist 失败为 **fail-open 回规则**(不编造);若产品要求「jev 挂则拒答」则不满足——属契约澄清,非实现疏忽。 |
| FIND-DOC-03 | summarizer 注释仍写「REPLACE 不接线」,与已合入 `applySemanticReplace` 矛盾。 |
| FIND-EVT-01 | 事件 payload 密钥过滤面窄于 taskrun `StripSecrets`(子串级)。 |
## 同类问题与影响范围
| 关联场景 | 共用机制 | 检查与证据 | 判定 |
|---|---|---|---|
| chatflow 读会话 | 会话 owner 校验 | chatlog Adapter authorize | 主路径健全;**旁路** `GetUserContext` 缺校验 |
| 任务 SSE 鉴权 | Flush 前 RequireProjectAccess | gap-matrix AUTH-TASK-SSE PASS | 项目门健全;阶段拒绝在流后属中危差异 |
| FAV outbox | Enabled:false + Register/Claim 硬拒 | registry/dispatcher/eventsconsumer | **未见旁路打开** |
| swboot ApproveMerge | 恒拒 | repo_allowlist | 自身 API 健全;命令白名单是真边界 |
| 生产 ALLOW_IN_MEMORY | validateProductionSecrets | config.go | 非空 Env 的 prod 有防护;空 Env+内存组合仍危险 |
**未覆盖(明确边界)**:govulncheck/npm audit;MinerU/Embedding SSRF 动态验证;FAV degraded 跨项目读 E2E;Markdown XSS 系统化;全量 `BeginTx` 持锁外呼追踪。
## 方案与验收(仅建议,本轮不实施)
### 建议优先级
1. **P0**:FIND-SEC-01(IDOR)— 补会话归属;加回归(他用户 session_id → 403/空)。
2. **P0**:FIND-ARCH-01 — arch-check 未登记表 fail-closed;补登记 swboot/projects 等属主。
3. **P1**:FIND-SEC-02 — Authorizer `!enabled()` 改 fail-closed 或与 `failClosedAuthz` 对齐。
4. **P1**:FIND-SEC-03 / FIND-FLOW-01 — argv 化命令 + 收紧白名单;Confirm 拒绝 `validated_only`/`proposed` 或执行器硬读 mode。
5. **P2**:收敛 docgov/多意图单一写路径与单一 flag 面;收回 server Pool。
### 验收提示(未来修复任务)
按 [验证契约](../ops/2026-09-21-validation-contract.md)「问题修复的回归范围」:原例 + 同类旁路 + 正常授权路径;工程侧补 `archtest` 用例证明未登记表 block。
## 严重度
报告整体:`high`(存在已证实 IDOR + 门禁盲区;未做动态利用)。
## 关联整改
- 既有: [模块解耦分批](../remediation/2026-09-20-module-decoupling-batch-plan.md)、[对话办公扩展](../remediation/2026-09-25-dialogue-office-expansion-plan.md)、[gap-matrix](../remediation/gap-matrix.md)
- **本轮未新建 remediation 文件**(用户禁止实施;方案仅建议)。授权后建议拆:`remediation/2026-09-26-system-code-review-followups.md`。
## 证据
### 门禁与规模(本机)
```text
被审 SHA: f4c1b73f28580ad3df6db4f9ec0a80057006e516
arch-check --mode block → production gate passed
tracked table_owners ≈ 59;swboot_controlled_executions/projects/project_source_bindings/outbox_events = UNTRACKED
Go 生产文件 LOC 前列(非测试):
cmd/bizdev-cli/main.go 1017
internal/squad/workflow.go 963
internal/server/task_run_handlers.go 858
internal/taskrun/manager.go 813
…
Web:
web/src/App.tsx 1748
web/src/engine/docxRenderer.ts 1263
…
```
### 子代理
| 轴 | 类型 | 用途 |
|---|---|---|
| 架构边界 | architecture-critic | 模块规范对抗审 |
| 安全 | security-auditor | OWASP 向只读审(无 PoC) |
| 可维护性 | thermo-nuclear-code-quality-review | 上帝对象/双路径/开关丛林 |
| 关键路径 | code-explorer | intentflow/docgov/swboot/FAV/jev |
### 运行态(旁证,非本报告验收对象)
此前会话:no-docker `bin/agent-server` `vcs.revision` = tip;`/api/v1/health`+`/ready` ok,schema 75。
## 开放问题
1. FIND-FLOW-01:产品是否故意允许对 shadow `proposed` 计划一键 Confirm 升 live?若否,属缺陷;若是,应改文档/MATRIX 与执行器注释。
2. FIND-JEV-01:assist「失败 fail-closed」的产品定义是否等于「回退规则」?
3. 是否授权将 FIND-SEC-01/ARCH-01 升 ISSUES 并开 remediation?
## 修复经过与经验
- **本轮未实施任何代码修复**(用户硬约束)。
- 不新增 lesson:发现尚未经验证修复闭环。
- 复发提醒:旁路 HTTP(绕过 chatflow/Owner)是鉴权回归的高发点。
## 状态与交接
| 字段 | 值 |
|---|---|
| 任务状态 | `done`(研究产物可审) |
| review_state | pending(待人工审阅报告) |
| integration_state | pending(报告合入 local_dev 另走 integrate) |
| deployment | not_required |
| cleanup | pending |
| remote_sync | not_requested |
| 剩余工作 | 授权后开 P0 修复任务;本 worktree 合入/清理由独立维护者执行 |
| 禁止续作 | 在本任务下直接改业务代码冒充「顺便修」 |
## Positive observations
1. `arch-check` 对**已登记** import/sql/path/event 仍 enforced。
2. FAV outbox consumer `Enabled:false` 多层硬拒,未见旁路打开。
3. 任务 SSE 项目鉴权在 Flush 前;docgov 角色取 principal 不信任 body。
4. 语义摘要 shadow:lease 提交后再 Summarize,符合持锁不做外部 IO。
5. swboot/jevdecide 领域包 import allowlist 自身较窄;污染主要在接线层。
+16
View File
@@ -13,6 +13,22 @@
## 核心文档(按阅读顺序推荐)
### 系统全面 Code Review(2026-09-26)
**文件**: [2026-09-26-system-code-review.md](./2026-09-26-system-code-review.md)
**结论**: tip `f4c1b73f` 上 `arch-check --mode block` PASS,但存在已证实会话上下文 IDOR、arch-check 未登记表静默跳过、Authorizer 无池 fail-open、swboot `sh -c` 前缀白名单、intentflow `proposed` 可 Confirm 升 dispatch 等 critical/high 项;FAV outbox 禁用路径未见旁路。**本轮不实施修复**。
**任务**: [short-term](../ops/short-term/2026-09-26-system-code-review.md) · mutex `docs-audit-review`
### 对话办公能力全景盘点(2026-09-25)
**文件**: [2026-09-25-dialogue-office-capability-research.md](./2026-09-25-dialogue-office-capability-research.md)
**结论**: 32 ActionKey 双轨脱节(主链假成功 vs intentflow 部分 live);HTTP 169 = A46/B66/C44+基线13;治理结构写永久 UI 专属。整改见 P0–P3 计划。
**整改**: [对话办公扩展计划](../remediation/2026-09-25-dialogue-office-expansion-plan.md) · task `dialogue-office-expansion-2026-09-25`
### 模块化重构方案审核检查清单(2026-09-23)
**文件**: [2026-09-23-modular-refactor-plan-review-checklist.md](./2026-09-23-modular-refactor-plan-review-checklist.md)
+41 -2
View File
@@ -2,11 +2,50 @@
维护规则:[问题记录与开发经验闭环](../ops/2026-09-23-issue-learning-workflow.md)。每个问题一个稳定 ID;主记录是事实与状态来源,本表为可检索投影。新发现及时登记,修复后保留记录;发布 blocker 仍见 [gap-matrix](../remediation/gap-matrix.md)。
更新:2026-09-23。本轮为初始建库,仅补录两个历史案例;下列历史 resolved 不表示本日运行回归通过。
更新:2026-09-28。docgov 共享 map 并发读写曾在 06:38 UTC 打崩 dev 进程,登录等 API 在进程缺席期间 500(verifying,单测 `-race` 已过,dev 重建未做)。只上传文档、无文字时对话 400 已在重载后的 dev 浏览器复验(resolved,`bin/agent-server` 10:22 +0800)。历史任务 run 事件流 HTTP/2 与 502 另记,未在本轮修。激活预览前端预检与管理台密钥 form 已在 dev 浏览器复验(resolved,dev `3e534bbb`,项目 6023)。非编制人触发小队账本提交被 `uow: permission denied` 拒绝(fixing,待 dev 重跑)。test 注册 INTERNAL:标准角色 role-guest 缺失导致 FK 23503,已补种并重启 test(goose 77,resolved)。重复用户名 400 在新代码单测通过;当前 rc 二进制仍返回 INTERNAL,随下次含本提交的 test 制品生效。管理台重置密码入口被 F4-A 误删(端点仍在),已恢复 UI(resolved)。2026-09-27。上传链路:登记并修复上传文档跨端不可访问(占位模板退化 + 元数据/正文不落服务端,fixing 待 dev 集成)。2026-09-26。docgov 批准链:登记并修复 review_snapshot_id 装载缺失与 uow 行锁自死锁(resolved);memDocs 持久化失败缓存投毒(investigating)。历史 resolved 不表示本日产品回归通过。系统 code review P0/P1 批次修复落账(5 resolved + 1 deferred + 1 open,主记录见 [整改文档](2026-09-26-system-code-review-fixes.md),来源 [审计](2026-09-26-system-code-review.md))。
| issue_id | 模块 / 检索词 | 问题 | 严重度 | issue_state | owner | 证据日期 / 范围 | 唯一主记录 | 经验 |
|---|---|---|---|---|---|---|---|---|
| ISSUE-20260928-docgov-map-race | docgov / memDocs / concurrent map / GetDocument / 登录 500 | per-doc 锁拆分后共享 map 无互斥,不同文档并发读写 fatal,进程退出期间全部 API 500 | critical | verifying | Cursor | 2026-09-28;`.tmp/launch/server.log` fatal + `web.log` ECONNREFUSED;`TestMemMapsNoRaceAcrossDocs` `-race` PASS(`a90cce73`);dev 重建未做 | [主记录](../ops/short-term/2026-09-28-docgov-shared-map-race.md#issue-20260928-docgov-map-race) | [LESSON-20260928-docgov-shared-map-race](../ops/lessons/2026-09-28-docgov-shared-map-race.md) |
| ISSUE-20260928-quality-heading-drift | squad / quality_gate / 缺少必填章节 / State-of-the-Art / H3 | 调研报告章节在,只因 H3 和少空格被判缺章,受控文档不投影 | high | verifying | Cursor | 2026-09-28;dev `research_1790566833205199368` manifest score 85;单测已覆盖,dev 重跑未做 | [主记录](../ops/short-term/2026-09-28-quality-gate-heading-mismatch.md#issue-20260928-quality-heading-drift) | [LESSON-20260928-quality-heading-normalize](../ops/lessons/2026-09-28-quality-heading-normalize.md) |
| ISSUE-20260928-data-dir-doubled | workspace / data/dev/data/dev / DataDir | 出现双层 `data/dev/data/dev/workspaces` 且只有孤立 output.md,写入点未证实 | medium | open | — | 2026-09-28;`intake_1790565513115586191` 双路径对照 | [主记录](../ops/short-term/2026-09-28-quality-gate-heading-mismatch.md#issue-20260928-data-dir-doubled) | 本轮不修 |
| ISSUE-20260928-progress-query-trigger | intent / matchTriggerTask / QUERY_PROGRESS / 编写进度 | 询问调研报告编写进度时,写动词加任务名词被识别成启动新任务,进度回复不读真实 run | medium | verifying | Cursor | 2026-09-28;「调研报告编写进度怎么样了」单测为 QUERY_PROGRESS;「开始做调研报告」仍为 research。浏览器复验见测试报告 | [主记录](../ops/short-term/2026-09-28-refresh-task-state-recovery.md) | 疑问进度句必须让行查询;显式「开始/重新」仍启动任务 |
| ISSUE-20260928-step-empty-output | squad / stepOutputAccepted / output_digest / e3b0c442 / MaterializeTargets | 步骤已把正文写到 output.md,判定仍因 runner Success=false 或空 patch 记空输出失败 | high | verifying | Cursor | 2026-09-28;11:27 `research_1790566028724181453` 的 06_draft 盘上 41KB 但 digest 为空;单测覆盖缺交付物但盘上有正文,以及连接错误仍失败关闭 | [主记录](../ops/short-term/2026-09-28-refresh-task-state-recovery.md) | 传输/可重试失败留下的文件可能是截断的,不能当成功;缺交付物且盘上非空才接受 |
| ISSUE-20260928-task-write-verb | intent / hasTaskWriteVerb / 帮我定 / 制定 / AMBIGUOUS_FALLBACK | 「帮我定/制定」设计开发计划任务书未进入任务触发,对话只有掂量阶段模板 | medium | resolved | Cursor | 2026-09-28;test sess-p8-u33 msg 89/90;意图单测 | [主记录](../ops/short-term/2026-09-28-test-user-doc-issues.md) | [LESSON-20260928-task-write-verb-visible-refusal](../ops/lessons/2026-09-28-task-write-verb-visible-refusal.md) |
| ISSUE-20260928-workflow-scope-reply | coordinator / ClarificationQuestion / ErrPrerequisiteNotMet / rd_design_plan | 跨工作流澄清与研发前置未满足时,原因没有进入对话 | medium | resolved | Cursor | 2026-09-28;协调器单测。test 原例停在动词未命中,未走到本分支 | [主记录](../ops/short-term/2026-09-28-test-user-doc-issues.md) | [LESSON-20260928-task-write-verb-visible-refusal](../ops/lessons/2026-09-28-task-write-verb-visible-refusal.md) |
| ISSUE-20260928-quality-failed-success-copy | bizdev / quality_failed / 正文已保存至 / output.md | 质量未通过仍声称正文已保存,并写出工作区绝对路径 | medium | resolved | Cursor | 2026-09-28;test cdo_quote_1790560155851280170;同步回复单测 | [主记录](../ops/short-term/2026-09-28-test-user-doc-issues.md) | [LESSON-20260928-task-write-verb-visible-refusal](../ops/lessons/2026-09-28-task-write-verb-visible-refusal.md) |
| ISSUE-20260928-pi-runner-data-dir | agent / PI runner / DATA_DIR / MISSING_TARGET / 18866 | test 启动时根 .env 的 dev runner 地址盖过本环境 sidecar,工作区被重写到空目录 | high | resolved | Cursor | 2026-09-28;dev `4f581306`。当时 test 二进制仍是修复前制品 | [验收报告](../test-reports/2026-09-28-pi-runner-env-mismatch-test-report.md) | — |
| ISSUE-20260928-material-chunk-embed | knowledge / chunk index failed / 8192 / 34635 tokens | 材料分块批超过嵌入模型上下文,索引失败 | medium | open | — | 2026-09-28;test 日志 project 8,文件 W020251117353305579317.docx | [主记录](../ops/short-term/2026-09-28-test-user-doc-issues.md) | 本轮不修 |
| ISSUE-20260928-attachment-only-turn | chat / chat/stream / message cannot be empty / HTTP_400 / attachments | 只上传文档、不输入文字时 turn 被空消息 400 拒绝,前端不读信封,用户看不到任何回复 | high | resolved | Cursor | 2026-09-28;dev :8080 重载后浏览器仅附件得到梳理审阅,无关文字先回答再追问;pending 分支 API 200 | [主记录](../ops/short-term/2026-09-28-attachment-only-turn.md) | 空消息门禁要放在附件判定之后;4xx 必须读信封。见[测试报告](../test-reports/2026-09-28-attachment-only-turn-test-report.md) |
| ISSUE-20260928-task-run-replay-502 | web / useRecoveredTaskPhases / tasks/runs / ERR_HTTP2_PROTOCOL_ERROR / 502 | 历史失败气泡恢复订阅 task run 事件时出现 HTTP/2 协议错误和 502,与附件空消息 400 无因果关系 | medium | verifying | Cursor | 2026-09-28;终态重放改为最多 4 次退避,401/404 立即停止;进行中订阅外层只再补 1 次,避免和内部 40 次重试相乘。尚未在真实 502 上复验 | [主记录](../ops/short-term/2026-09-28-refresh-task-state-recovery.md) | 重放失败要可重试;鉴权与不存在不要空转 |
| ISSUE-20260928-activation-preview-precheck | web / projectSettings / activation-preview / NO_GOVERNED_DOCUMENT / clientDutyIssues | 全部文档未纳入人工审批时前端仍 POST activation-preview,控制台 400 | medium | resolved | Cursor | 2026-09-28;dev 项目 6023 默认计划无 activation-preview 请求,兼任后 preview 200 | [主记录](../ops/short-term/2026-09-28-activation-preview-precheck.md#issue-20260928-activation-preview-precheck) | [LESSON-20260928-activation-preview-client-gate](../ops/lessons/2026-09-28-activation-preview-client-gate.md) |
| ISSUE-20260928-admin-secret-password-form | web / EnvSettingsSection / password / form / secrets | 管理台 5 个密钥输入不在 form 内,Chromium 报 password DOM 警告 | low | resolved | Cursor | 2026-09-28;dev 模型与密钥页 passwordInputs=5 outsideForm=0 | [主记录](../ops/short-term/2026-09-28-activation-preview-precheck.md#issue-20260928-admin-secret-password-form) | 密码框放进 form;autocomplete 不能单独消除该 DOM 警告 |
| ISSUE-20260928-squad-commit-authority | bizdev / docflow / dutyAuthorizer / uow permission denied / OnBehalfOf / bd_intake | 非编制人触发受控小队任务时,账本提交用触发者身份,被编制人职责门拒绝,正文无法落盘 | high | fixing | Cursor | 2026-09-28;dev task_runs user 74 ≠ author 4(doc_proj6022_bd_intake);单测已绿,dev 重跑未做 | [主记录](../ops/short-term/2026-09-28-squad-commit-authority.md#issue-20260928-squad-commit-authority) | [LESSON-20260928-squad-commit-as-author](../ops/lessons/2026-09-28-squad-commit-as-author.md) |
| ISSUE-20260928-register-internal | auth / register / role-guest / system_roles / 23503 / 23505 / INTERNAL | test 缺 role-guest 时注册 FK 失败被脱敏为 INTERNAL;重复用户名唯一冲突同样 500 | high | resolved | Cursor | 2026-09-28;test:8081 补种并重启后注册 200(goose 77,req_regfix_after_restart);重复用户名 400 由单测覆盖,rc 二进制仍为 INTERNAL | [主记录](../ops/short-term/2026-09-28-auth-register-internal.md#issue-20260928-register-internal) | [LESSON-20260928-standard-role-reseed](../ops/lessons/2026-09-28-standard-role-reseed.md) |
| ISSUE-20260928-admin-reset-ui-removed | web / UsersSection / 重置密码 / F4-A / adminResetPassword | F4-A 在 F4-B 端点已合入的基线上删除管理台重置密码按钮,管理员无法重置口令 | high | resolved | Cursor | 2026-09-28;dev API :8080 + worktree Vite :3110 真实 UI 探针 PASS(临时口令长度 16、强制改密仅一次、旧口令 401) | [主记录](../ops/short-term/2026-09-28-restore-admin-password-reset.md#issue-20260928-admin-reset-ui-removed) | [LESSON-20260928-ui-dead-control](../ops/lessons/2026-09-28-ui-dead-control.md) |
| ISSUE-20260927-upload-doc-cross-device | freedoc / upload / freeform / fileMeta / 占位模板 / 跨端 | 上传文档源文件元数据与正文不落服务端:换浏览器/清存储/共享他人查看时退化为注册占位模板,文本类连二进制都未存(伴生 <512B 显示 "0 KB") | high | resolved | pi | 2026-09-27;dev `86efba2c` 合入并在 dev 环境验证:FS-UPLOAD-01/02 真实浏览器 PASS(跨上下文可见真实正文),DB 核验元数据+asset 落库;存量无元数据旧文档不可恢复(重新上传即可) | [主记录](../ops/short-term/2026-09-27-upload-doc-access.md) | [LESSON-20260927-server-facts-and-iso-db-recipe](../ops/lessons/2026-09-27-server-facts-and-iso-db-recipe.md) |
| ISSUE-20260923-nullable-duty | docgov / nullable / 23503 / reviewer_id | 可选职责空值写 0 导致 FK 失败 | high | resolved | Codex(历史补录) | 2026-09-17;历史 PG / API 冒烟;当前未复测 | [主记录](2026-09-23-historical-issue-records.md#nullable-duty) | [LESSON-20260923-nullable-duty](../ops/lessons/2026-09-23-nullable-duty.md) |
| ISSUE-20260923-content-hash | docrevision / canonicalize / hard-break / 404 | 规范化破坏 Markdown 语义并造成正文哈希漂移 | critical | resolved | Codex(历史补录) | 2026-09-14;历史真实 UI / 重启;当前未复测 | [主记录](2026-09-23-historical-issue-records.md#content-hash) | [LESSON-20260923-content-hash](../ops/lessons/2026-09-23-content-hash.md) |
| ISSUE-20260923-coordination-authority | agentctl / claim / SQLite / CAS / CURRENT / FEATURE-MATRIX | 本地副本 CAS 与任务许可不能表达跨主机全局权威认领 | high | investigating | Codex(研究) | 2026-09-23;源码/只读状态,未复现具体丢写 | [主记录](../ops/short-term/2026-09-23-coordination-db-daemon-research.md#issue-20260923-coordination-authority) | 沿用 content-hash 投影经验;跨机结论待实施验证 |
| ISSUE-20260923-matrix-status-regression | FEATURE-MATRIX / module-batches-ag / merge / docs-apply | 矩阵行 done 被 closeout 合并冲突手解回退为 planned | high | resolved | Cursor | 2026-09-23;本机 dev tip 与 git 考古;docs apply 已恢复 | [主记录](2026-09-23-matrix-status-regression.md) | [LESSON-20260923-matrix-status-cas](../ops/lessons/2026-09-23-matrix-status-cas.md) |
| ISSUE-20260923-matrix-status-regression | FEATURE-MATRIX / module-batches-ag / merge / docs-apply | 矩阵行 done 被 closeout 合并冲突手解回退为 planned | high | resolved | Cursor | 2026-09-23;本机 tip 与 git 考古;docs apply 已恢复 | [主记录](2026-09-23-matrix-status-regression.md) | [LESSON-20260923-matrix-status-cas](../ops/lessons/2026-09-23-matrix-status-cas.md) |
| ISSUE-20260924-admin-reset-dead | auth / adminResetPassword / T20-F4 / chenwei | 管理台重置密码死按钮;验收口令不可知后无法恢复 | high | resolved | Cursor | 2026-09-24;test 库实查 + API 单测 | [主记录](2026-09-24-admin-password-reset-issues.md#issue-20260924-admin-reset-dead) | 待补 LESSON |
| ISSUE-20260924-login-error-envelope | auth / AUTHZ / 无权访问 / auth.ts | 登录失败展示裸 JSON / 「无权访问」误导 | medium | resolved | Cursor | 2026-09-24;wire 复现 + 前端单测 | [主记录](2026-09-24-admin-password-reset-issues.md#issue-20260924-login-error-envelope) | 待补 LESSON |
| ISSUE-20260924-zombie-credentials | auth / user_credentials / LEFT JOIN / CreateUser | 空哈希静默建号导致永久无法登录 | high | resolved | Cursor | 2026-09-24;三环境只读盘点;机制修复不含存量清理 | [主记录](2026-09-24-admin-password-reset-issues.md#issue-20260924-zombie-credentials) | 待补 LESSON |
| ISSUE-20260924-cursor-test-rule-drift | Cursor / test-reports / 固定模型 / 规则副本 | Cursor 测试规则与验证契约存在固定模型及范围冲突 | medium | verifying | Cursor | 2026-09-24;规则文本已缩为验证契约指针;客户端实际读取行为待实机 | [主记录](2026-09-24-subagent-workflow-research.md#4-issue-20260924-cursor-test-rule-drift) | [LESSON-20260924-cursor-hook-advisory-gates](../ops/lessons/2026-09-24-cursor-hook-advisory-gates.md) |
| ISSUE-20260924-pi-executor-boundaries | PI executor / 路径规范化 / MCP / 子进程 / 幂等 | 未发布初版只读边界与执行可靠性缺陷 | high | resolved | Cursor/Codex | 2026-09-24;173 工程回归与真实 Cursor CLI/MCP/PI | [主记录](2026-09-24-pi-executor-boundaries.md) | [工具路径与输入隔离](../ops/lessons/2026-09-24-pi-tool-boundaries.md) |
| ISSUE-20260924-cursor-cli-mcp-path | Cursor CLI / MCP / workspaceFolder / NDJSON | agentctl/jev MCP 加载失败(路径 + Content-Length 回包) | medium | verifying | Cursor | 2026-09-24;相对路径+NDJSON 已修;待 IDE 重载后 list-tools 实机 | [主记录](2026-09-24-pi-executor-boundaries.md#cursor-cli-mcp-path) | [LESSON-20260924-cursor-hook-advisory-gates](../ops/lessons/2026-09-24-cursor-hook-advisory-gates.md) |
| ISSUE-20260924-cursor-hook-event-contract | Cursor / hooks / beforeMCPExecution / probe | hook 事件 stdin 字段名与 matcher 官方未文档化 | medium | verifying | Cursor | 2026-09-24;IDE postToolUse tool_name=`MCP:pi_subagent_roles` 已采样;beforeMCP 全量 stdin 仍缺 | [主记录](2026-09-24-cursor-hook-event-contract.md) | [LESSON-20260924-cursor-hook-advisory-gates](../ops/lessons/2026-09-24-cursor-hook-advisory-gates.md) |
| ISSUE-20260924-non-author-400-duty | iam-authz / docgov / duty / 400 / 非编制 | 权限不足误报 400;run/edit 与编制职责绑死导致成员无法上传总结写草稿 | high | resolved | Cursor | 2026-09-24;真实 PI `TestNonAuthorMember_PiAgent_RunEditSubmitGates` PASS | [主记录](2026-09-24-non-author-member-access.md) | [LESSON-20260924-deny-only-submit](../ops/lessons/2026-09-24-deny-only-submit.md) |
| ISSUE-20260926-docgov-snapshot-load | docgov / loadDocumentFromDBLocked / review_snapshot_id / 跨重启批准 | 文档装载 SELECT 漏 review_snapshot_id,重启/缓存未命中后最终批准必失败 | high | resolved | pi | 2026-09-26;隔离库 PG 回归 + dev 真实批准 200/state=approved(dev `121b33f8`) | [主记录](../test-reports/2026-09-26-rdev-p3-rerun-test-report.md#5-2) | 待补 LESSON |
| ISSUE-20260926-docgov-uow-deadlock | docgov / persistApproveAndFAV / uow / FOR UPDATE / 57014 | docflow uow 行锁后 FAV 持久化自开第二连接更新同行,语句超时致死锁,所有最终批准失败 | critical | resolved | pi | 2026-09-26;生产形状 PG 回归(FOR UPDATE+FAV+Within)+ dev 真实批准转 200(dev `5d5cd5fd`) | [主记录](../test-reports/2026-09-26-rdev-p3-rerun-test-report.md#5-2) | 待补 LESSON |
| ISSUE-20260926-docgov-memdocs-poison | docgov / memDocs / 状态机 / 持久化失败 / 缓存投毒 | 状态机先改内存后落库;持久化失败不复原,memDocs 缓存与 DB 永久分叉并掩盖真实错误(表现为「approved 状态」误报) | high | investigating | pi | 2026-09-26;dev 两次复现(快照/死锁两根因均被投毒掩盖);修复方向:失败时回滚内存快照或失效缓存条目 | [主记录](../test-reports/2026-09-26-rdev-p3-rerun-test-report.md#5-2) | 待补 LESSON |
| ISSUE-20260926-ctx-idor | ctxmgr / GetUserContext / session_id / IDOR / handlers_context | GetUserContext 按 session_id 取消息无归属校验,登录用户可读他人会话正文(已证实) | critical | resolved | pi | 2026-09-26;handler 403 + SQL/内存双防线;内存 HTTP 与隔离 PG 回归 PASS | [主记录](../remediation/2026-09-26-system-code-review-fixes.md#1-find-sec-01-会话上下文-idorissue-20260926-ctx-idor) | [LESSON-20260926-failclosed-bypass-contract](../ops/lessons/2026-09-26-failclosed-bypass-contract.md) |
| ISSUE-20260926-archcheck-untracked | archtest / table_owners / untracked / sql_write / 门禁盲区 | arch-check 对未登记表 SQL 写静默跳过,含 swboot_controlled_executions 等 ~50 表;门禁形同关闭 | critical | resolved | pi | 2026-09-26;未登记表 fail-closed + 补登 50 表 + 噪音豁免清单;arch-check block PASS | [主记录](../remediation/2026-09-26-system-code-review-fixes.md#2-find-arch-01-arch-check-未登记表静默跳过issue-20260926-archcheck-untracked) | [LESSON-20260926-failclosed-bypass-contract](../ops/lessons/2026-09-26-failclosed-bypass-contract.md) |
| ISSUE-20260926-authz-failopen | authz / IsProjectMember / pool==nil / fail-open / NewInMemoryAuthorizer | Authorizer 无池时 IsProjectMember/IsProjectOwner 对任意登录用户返回 true,误配即全量放行 | high | resolved | pi | 2026-09-26;无池严格拒绝 + 显式内存授权接缝 + 组合根按 AllowInMemory 选择;隔离 PG authz 套件 PASS | [主记录](../remediation/2026-09-26-system-code-review-fixes.md#3-find-sec-02-authorizer-无池-fail-openissue-20260926-authz-failopen) | [LESSON-20260926-failclosed-bypass-contract](../ops/lessons/2026-09-26-failclosed-bypass-contract.md) |
| ISSUE-20260926-swboot-shell-prefix | swboot / executor / sh -c / 命令注入 / 前缀白名单 / commandAllowed | 受控命令经 sh -c 执行且白名单前缀匹配(go 放行 go-evil);元字符可求值 | high | resolved | pi | 2026-09-26;argv 化 + basename 精确匹配;前缀伪装/不求值回归 PASS | [主记录](../remediation/2026-09-26-system-code-review-fixes.md#4-find-sec-03-swboot-sh--c--前缀白名单issue-20260926-swboot-shell-prefix) | [LESSON-20260926-failclosed-bypass-contract](../ops/lessons/2026-09-26-failclosed-bypass-contract.md) |
| ISSUE-20260926-intentflow-validated-confirm | intentflow / DecisionConfirm / PlanProposed / validated_only / ExecuteClaimed | validated_only(shadow)计划可经 Confirm 进入 executing 并真实执行;执行器不读 ExecutionMode | high | resolved | pi | 2026-09-26;Confirm 拒 + 执行器硬拒双层 + 错误码/HTTP 映射;确认/派发双回归 PASS | [主记录](../remediation/2026-09-26-system-code-review-fixes.md#5-find-flow-01-validated_only-可-confirm-后-dispatchissue-20260926-intentflow-validated-confirm) | [LESSON-20260926-failclosed-bypass-contract](../ops/lessons/2026-09-26-failclosed-bypass-contract.md) |
| ISSUE-20260926-dual-flags-drift | intent / intentflow / FeatureFlags / PlanTier / MULTI_INTENT_ENABLED / 静默漂移 | 双套 flags 可配置出「intentflow 升档但 intent 关闭」的矛盾组合并静默降级 | high | resolved | pi | 2026-09-26;组合根经 intentflow.ValidateFlagConsistency 启动期 fail-fast + 单测;入口收敛残差另立 deferred | [主记录](../remediation/2026-09-26-system-code-review-fixes.md#6-find-qual-01-双套-flags-静默漂移issue-20260926-dual-flags-drift含残差) | [LESSON-20260926-failclosed-bypass-contract](../ops/lessons/2026-09-26-failclosed-bypass-contract.md) |
| ISSUE-20260926-governance-multi-entry | docgov / 多意图 / 多入口 / Coordinator / OwnerMux / GovernanceEngine | docgov 三入口 + Coordinator ~40 case 与 intentflow OwnerMux 平行,鉴权/确认/审计易漂移 | high | deferred | pi | 2026-09-26;flag 漂移面已修(dual-flags-drift);入口合并是多日级重构,需独立任务授权与回归矩阵 | [主记录](../remediation/2026-09-26-system-code-review-fixes.md#6-find-qual-01-双套-flags-静默漂移issue-20260926-dual-flags-drift含残差) | 沿用 failclosed-bypass-contract |
| ISSUE-20260926-server-pool-wiring | server / swboot_handlers / Runtime.Pool / 组合根越界 / FIND-ARCH-02 | server 持 Pool 直装 swboot repo/executor 并直查表,成为第二组合根(本轮未授权修复) | critical | open | pi | 2026-09-26;代码审证据齐(审计 FIND-ARCH-02),待修复授权 | [主记录](../audit/2026-09-26-system-code-review.md) | 待修复后补 |
| ISSUE-20260927-demo-fallback | web / App.tsx / sess-001 / projectId fallback / demo seeds 关闭 | demo seeds 关闭模式下前端硬编码 fallback(激活 sess-001、项目 1)对真实后端发假请求,新登录用户首屏 9 个 404/403(chat 窗口被迫回退本地缓存) | medium | resolved | pi | 2026-09-27;dev 真实浏览器修复前后对照(author+member 双账号:9 假请求→0) | [主记录](../ops/short-term/2026-09-27-frontend-demo-fallback.md) | [经验小结](../ops/short-term/2026-09-27-frontend-demo-fallback.md#经验小结)(独立 lesson 待后续任务补登) |
| ISSUE-20260927-active-session-residue | web / storage.ts / loadActiveSessionId / localStorage 残留 / sess-001 / demo-seed-purge 写回窗口 | 旧前端把 demo fallback 值写回 localStorage active_session;一次性 purge 已执行不再清,读取侧无 legacy 校验,老浏览器 + 无可见会话账号首屏 4×chat 404(ISSUE-20260927-demo-fallback 修复残留路径) | medium | resolved | pi | 2026-09-27;dev 主入口 :3100 复验 admin+残留 sess-001:phantom=0/4xx5xx=0,key 被清除(dev `36c5fb54`) | [主记录](../ops/short-term/2026-09-27-frontend-demo-fallback-localstorage-residue.md) | [经验小结](../ops/short-term/2026-09-27-frontend-demo-fallback-localstorage-residue.md#经验小结补充-issue-20260927-经验) |
+4 -1
View File
@@ -16,7 +16,10 @@
| GET /api/v1/tasks/runs/{id} | task_run | view | taskrun | 403 非 owner/非 owner 成员 |
| POST /api/v1/tasks/runs/{id}/cancel | task_run | cancel | taskrun | 403 取消他人 |
| POST /api/v1/chat/stream | chat | send | chat+stage | 403 无阶段权限 |
| GET /api/v1/docgov/* | document | * | docgov+duty | 403 非职责人 |
| GET /api/v1/docgov/* | document | * | docgov+duty | view:成员;run/edit:成员(deny_only_submit);submit/review/approve:对应职责,403 |
| POST /api/v1/docgov/content | document | edit | docgov+member | 403 非项目成员或锁定态 |
| POST /api/v1/docgov/submit-review | document | submit | docgov+author | 403 非编制职责人 |
| POST /api/v1/tasks/run | task | run | bizdev+member | 403 非成员 / 非活动阶段;不再要求编制职责 |
| GET /api/v1/admin/* | admin | * | authz RBAC | 403 非 admin/细粒度 perm |
| GET /health, /api/v1/health | system | health | server | 公开 |
+20
View File
@@ -45,3 +45,23 @@ CURRENT 是带时间的活跃协调快照;Git/机器状态用于核验实际
修订 ID:`codegraph-governance-2026-09-24-r1`;owner:`Cursor`;state:`active`(生效 tip `19eb56e3744d3c7d4b69b065c87e27689e8caa53` / fixup `0c676afe1faf831020c7c3201509d7cec0328d53`);工具能力:盘点命令与 hooks sync 为 `enforced`(脚本已落地);常驻 daemon 装载仍为 `manual`(本机默认不装载)。用户授权:将 CodeGraph 纳入治理启动/建场/sync,并对 worktree 清理与 FEATURE-MATRIX 做只读盘点提醒(不自动删除、不自动升 done)。
唯一来源增补:[AGENTS §1/§4](../../AGENTS.md)、[worktree 操作规范 §8](./2026-09-21-agent-worktree-workflow.md)、[收口清单](./templates/session-close-checklist.md)。命令入口:`agentctl cleanup report`、`agentctl docs drift`、`agentctl hooks codegraph-sync`、建场 `agent-worktree.sh create` 的 best-effort `codegraph init`。不改产品 SWBOOT-10 stub,不装载 systemd coordinator(需另授)。
## Subagent 工作流拟议修订
修订 ID:`subagent-workflow-2026-09-24-r2`;owner:Codex;state:`proposed`;能力:`manual`;effective_commit:无。
用户要求研究 Cursor Auto 下的 subagent 分工、阶段流程及报告,授权与本次验收见[任务](short-term/2026-09-24-subagent-workflow-standard.md)。[规范草案](2026-09-24-subagent-workflow-standard.md)为拟议行为的唯一来源,[研究报告](../audit/2026-09-24-subagent-workflow-research.md)给出事实和待修冲突,[模板](templates/subagent-stage-record.md)承载交接。
用户后续明确采用 Cursor Auto 实施 + gmktec 本机 PI 子任务,并批准默认模型分工及可调整文档。[模型配置](2026-09-24-subagent-model-config.md)为模型路由唯一来源,decision_state=approved;流程整体仍 proposed;已批准的模型配置与执行器已合入本地 dev。原 Cursor 原生角色/inherit 方案被替代。执行器已在任务分支实现并验证 Cursor CLI→MCP→PI,代码 69ffaa677e23a1dd9aa0528bb09b3acfcd38b119;[运行说明](2026-09-24-pi-subagent-executor.md)与[验证报告](../test-reports/2026-09-24-pi-executor-test-report.md)限定已验证的机器边界。dev 集成/完整流程审批仍独立记录;不以派发器可用宣称全阶段自动门禁。
## Cursor 治理层局部修订
修订 ID:`cursor-governance-2026-09-24-r1`;owner:`Cursor`;state:合入 local_dev 后 `active`(effective_commit 以集成收据为准);工具能力分层:
- 规则/skill 文本:`manual`(Agent 读取执行)
- hook 脚本 stdin→stdout 行为:`enforced`(`scripts/tests/test_cursor_hooks.py`)
- hook ↔ Cursor IDE 接线:`advisory`/`manual`(事件字段待 probe 采样;见 ISSUE-20260924-cursor-hook-event-contract)
用户授权:在 PI 执行器合入后补齐 skills/rules/hooks;范围与验收见[任务](short-term/2026-09-24-cursor-governance-hooks.md)。客户端入口:`.cursor/rules/cursor-hooks.mdc`、`pi-subagents.mdc`、`test-reports-standard.mdc`(缩为验证契约指针);skills `pi-subagent-dispatch` / `subagent-stage-record`;hooks 见 `.cursor/hooks.json`。不改变产品 Runner、不扩大执行器硬门禁语义。
## 治理目录库与需求重叠检测拟议修订
修订 ID:`governance-catalog-2026-09-24-r1`;owner:`Cursor`;state:`proposed`;能力:schema/门禁落地后为 `enforced`,向量层 `fail-open`;effective_commit:无(随受控合入记录)。
用户授权实施跨对话需求重叠检测与治理目录(扩展既有 `.locks/state.sqlite`,不碰业务 PG)。唯一来源:[方案](./2026-09-24-governance-catalog-plan.md);任务:[short-term](./short-term/2026-09-24-governance-catalog.md)。策略键 `catalog_gate`/`catalog_vector` 为可选,不得破坏 `shared_docs` 等集合相等校验。
@@ -0,0 +1,46 @@
# 治理目录库与跨对话需求重叠检测(方案)
**修订 ID**:`governance-catalog-2026-09-24-r1`
**state**:`proposed` → 实施后随合入升 `active`
**owner**:Cursor
**工具能力**:schema/CRUD/门禁 `enforced`(落地后);向量层 `fail-open`
**任务**:[short-term](./short-term/2026-09-24-governance-catalog.md)
## 问题
跨对话新设计与既有功能/需求重叠时,现有 agentctl 仅做路径级 `overlaps()` 互斥,无需求语义比对。CURRENT/ISSUES/test-reports 为 Markdown 台账,机器无法强制开工前探测。
## 方案摘要
在既有 `.locks/state.sqlite`(与业务 PG 物理隔离)上 additive 扩展 Catalog 表:
| 表 | 用途 |
|---|---|
| `catalog_requirements` | R-ID 需求条目 |
| `catalog_features` | 对齐 FEATURE-MATRIX record_id |
| `catalog_req_text` | FTS5 CJK 逐字索引(禁用 trigram) |
| `catalog_overlaps` / `catalog_decisions` | 检测结果与裁决留痕 |
| `catalog_issues` / `catalog_tests` / `catalog_releases` | 缺陷/测试/发布投影 |
| `catalog_embeddings` | 可降级向量增强 |
### 分级门禁
1. **L1 结构化**:`same_mutex` / `same_feature` / `same_scope` / `same_req_id` → hard deny
2. **L2 语义**:FTS5 bm25 软门,须 `catalog overlap ack` 显式裁决后才可编码
3. **L3 向量**:读 `EMBEDDING_*`;401/超时/缺钥 → `vector_layer=degraded`,不阻断
### 策略
`catalog_gate` / `catalog_vector` 为**可选键**(不得加入 `shared_docs` 等集合相等校验字段)。
### 权威关系
`.doc` Markdown 仍为事实来源;Catalog 为可检索投影 + 门禁依据;冲突时 `catalog drift` 告警,不自动改文档。
## 边界
不新建第二库/容器;不读写业务 PostgreSQL;不改 `overlaps()` 既有语义;不做跨机权威。
## CLI / MCP
`agentctl catalog {add,list,show,search,overlap,ack,status,drift}`;MCP:`catalog_requirement_add` / `catalog_overlap_probe` / `catalog_overlap_ack` / `catalog_search` / `catalog_status`。
@@ -0,0 +1,47 @@
# 本机 PI Subagent 执行器接入方案与实施记录
task_id:subagent-workflow-standard-2026-09-24;operation_task_id:subagent-workflow-standard-2026-09-24-executor。
用户授权:“接入自动调用 pi 的执行器”;既有约束:Cursor Auto 实施,PI 模型限[配置](2026-09-24-subagent-model-config.md),M3 默认停用。本次是同任务的实现续作。
## 目标与边界
Cursor 能通过项目 MCP 自动按角色调用 gmktec 本机 PI,读取配置,提供冻结输入,获得持久报告和可核验状态。CLI 同步提供可复现入口。
不修改产品服务/Runner、不操作真实业务数据、不安装 daemon、不 push。代码只在原登记 worktree 修改,当前 main 有其他任务的未跟踪 promotion receipt,保留不动。
本次复核 local dev=6858e21d477571696a8458032e2c884449e773fd;原任务 HEAD=52462b45e985f596b2a503fc70ac12c3bd5fe571;新增 dev 差异为 internal/squad,与本次脚本无交叉。没有重新建场或切换主目录分支。
## 分工与执行方式
- Cursor Auto:编写执行器、MCP 接口、权限限制与测试。host Codex:需求/契约、文档、证据核验、审查与受控提交。
- Cursor CLI 在已登记原任务 worktree、agentctl with 监督和精确路径租约内执行;不授予提交/合并/推送/环境操作权限。模型请求 Auto;实际底层模型不可见时记录 unknown。
- 本次使用 ce-work 的执行/验证思路、CodeGraph 定位、test-driven-development 和 writing-for-agents。仓库 AGENTS 的原任务 worktree/agentctl 规则优先于技能中 detached 临时工作区机制;使用仓库 supervisor 派发 Cursor,代码路径单写者,外层核对差异。该隔离不是 OS 沙箱。
- 范围:scripts/pi_subagents.py、scripts/pi-subagent-readonly.ts、scripts/mcp/pi-subagents-mcp.mjs、scripts/tests/test_pi_subagents.py、scripts/mcp/README.md、.cursor/mcp.json、.cursor/rules/pi-subagents.mdc,以及本任务相关 .doc 文档。
- 认领能力仅 docs:publish;不注册 env:* 或 git:dev。后续集成另按受控候选流程处理。
## 设计契约
1. 配置文档是唯一模型来源,每次派发解析严格表格,记录 revision/hash 和实际 provider/model。禁用、未知、循环、M3 关键职责路由失败关闭;没有静默备用。
2. 新鲜 PI 会话;冻结 source SHA 与显式 tracked 输入文件(拒绝秘密/业务 data/路径穿越/符号链接),上限限制。模型只得到选定输入与允许的只读工具,无任意 shell、源码写入或递归派发。
3. 测试角色仅运行主 Agent 显式提供、带来源的 argv 计划;独立源码副本、净化环境、超时和输出限制,模型不生成可执行命令。共享业务环境本版不接入,返回明确限制。
4. MCP 提供角色预览、运行、结果查询;跨 worktree 调用核对同仓与 task 注册;运行由权威 agentctl with 包裹,并由执行器校验继承租约。
5. 每个 request_id 绑定输入摘要;同请求重放只查询,变更载荷拒绝,running/unknown 不重派。每请求独立短范围 report 路径锁,跨调用者统一并发上限。
6. 运行前保存 running;完成保存 receipt.json/report.md,含命令、版本、输入摘要、配置摘要、状态/结论、报告来源。结果未知/失败不冒充通过,进程退出0不替代模型最终事件和必需测试结果。
7. timeout/cancel 处理进程组并回收;未知副作用保留现场。凭证仅由 PI 客户端读取,绝不进入模型输入/报告;测试子进程不继承模型密钥或租约身份。
8. MCP 用标准 stdio JSON-RPC,查询不被运行调用阻塞。项目规则告诉 Cursor 何时选择哪种 role_id,具体模型仍从配置读取。
9. 实施与修复始终交给 Cursor;PI 负责分析/审查/验证。模型结论和 acceptance_owner 的最终验收分开。
## 验证计划
- 隔离真实 Git/agentctl:注册/租约负例、路径范围、报告落盘、请求幂等、并发与异常退出。
- 本地假 PI 仅作为协议传输夹具:模型参数、权限开关、JSON 事件、错误/空响应/超时/子进程清理;不得当作真实模型能力验收。
- MCP 实进程:initialize、tools/list、roles、run、result;错误必须 isError。
- 实际本机 PI:至少一条真实分析请求与独立代码审查;模型/权限/配置/源码身份可追溯。不得把 CLI/MCP 接口实测写成 Cursor IDE 页面已实测。
- 主机核验聚焦测试与工程脚本套件,按失败证据补回归;无需运行无关产品全量 Go、重建服务或产品 PI。
- 收口保留运行结果和剩余条件,分别记录 local commit / integration / deployment / remote_sync / cleanup。
## 当前进度
2026-09-24:Cursor Auto 已在 agentctl supervisor 内启动;本轮尚未宣称实现完成。机器租约身份和终端输出由 host 核验,待实施结果后补测试与审查。
## 已验证结果
执行器代码已提交为 69ffaa677e23a1dd9aa0528bb09b3acfcd38b119。完整工程回归 173 项、提交后专项 34 项、真实 Cursor CLI→MCP→PI 自动路由与最终 ls/read 均通过,详见[报告](../test-reports/2026-09-24-pi-executor-test-report.md)。文档配置已改为程序读取;完整审批状态机仍人工/Agent 遵约。已受控合入本地 dev,集成提交 5a8540804ee2d142a0894c1482a2a16e8f843915,未推送;Cursor IDE 页面仍未实测。
@@ -0,0 +1,80 @@
# 本机 PI Subagent 执行器使用说明
范围:Cursor Auto 主协调/代码实施,gmktec 本机 PI 子任务。模型分工唯一来源为[模型配置](2026-09-24-subagent-model-config.md),阶段定义见[流程规范](2026-09-24-subagent-workflow-standard.md)。本说明与代码已合入本地 dev;集成和最终实测状态见[实施记录](2026-09-24-pi-executor-implementation.md)。
## Cursor 中使用
1. 在包含本次提交的工作区打开 Cursor,重新加载项目 MCP;.cursor/mcp.json 注册 pi-subagents 服务,.cursor/rules/pi-subagents.mdc 提供派发入口。
2. 主会话保持 Auto。先按原有流程创建/登记任务 worktree,并将 .doc/test-reports/assets/pi-subagents/<task-id> 纳入任务写范围。
3. Cursor 调用 pi_subagent_roles 读取当前角色与模型;从任务目标选择 role_id,调用 pi_subagent_run,随后查询 pi_subagent_result。
4. 不需要用户切换 PI 模型。需求/方案、独立审查、测试和报告由不同角色处理;代码实施与修复仍由 Cursor 执行。
5. 接收报告并核对范围、源码/配置版本、缺项;运行完成不代表阶段批准。最终验收责任仍由任务 acceptance_owner 承担。
任务 worktree 尚未合入 dev 时,主目录中的旧 MCP 配置不会自动获得新工具;先在该任务 worktree 验证,受控集成后再在主目录重载。本文不宣称已操纵 Cursor IDE 页面。
## 请求内容
MCP 工具的外层参数 worktree 为同仓的已登记任务工作区,task_id 为实际操作任务。request 中给出以下信息;授权引用应能回链到真实用户请求,不用日志/模型文本自授权限。
```json
{
"worktree": "/absolute/path/to/repo/.worktrees/task-id",
"task_id": "task-id",
"request": {
"role_id": "research",
"request_id": "research-001",
"goal": "读取选定文件,给出有证据的分析",
"authorization_ref": "本任务主记录中的用户授权位置",
"source_sha": "<完整的已提交源码 SHA>",
"input_files": ["PROJECT.md"],
"timeout_seconds": 120
}
}
```
source_sha 必须为完整提交 hash;HEAD/分支名不作为可变输入。只发送明确列出的已跟踪 UTF-8 普通文件,禁止运行数据、.env、凭证、符号链接和路径越界。未提交的代码不会自动进入快照,先由 Cursor 形成可审提交或使用已有冻结版本。
request_id 在同一任务中稳定标识一次请求:同参数只读重放既有结果,不重复调模型;不同参数复用 ID 被拒绝;running/unknown 保留现场,不能盲目重派。配置变更在下一次新派发读取,旧请求保留原 config_revision/config_sha256。
## CLI 入口
在任务工作区使用:
```bash
python3 -B scripts/pi_subagents.py roles
../../scripts/agentctl with --task task-id \
--resource path:.doc/test-reports/assets/pi-subagents/task-id/research-001 -- \
python3 -B scripts/pi_subagents.py run --request /tmp/pi-request.json
python3 -B scripts/pi_subagents.py result --task task-id --request-id research-001
```
CLI 请求文件需包括 task_id;也可用 run --stdin 输入 JSON。直接裸调 run 会被租约校验拒绝。上述名称是示例,不构成任何任务或环境授权。
## 测试角色
test_run / acceptance_check 还需 approved_commands(argv 数组的数组)和 plan_digest(外部已批准计划 SHA-256);执行器另记录 approved_commands_sha256,不能以任意字符串冒充命令与计划的同一摘要。
命令在独立测试快照中运行,使用净化环境和私有 HOME/cache/tmp,标准输入关闭。PI 模型根据收到的命令摘要、退出码和日志引用分析,不生成或修改被执行命令;完整日志由主 Agent 核验并在需要时补充上下文。模型分析快照保持原始源码内容,与测试可写副本分离。必要的 stdout/stderr 保存到本请求报告目录以便核对,不仅保留一段摘要。
依赖未安装、用例缺失或命令失败须如实记录。本版不自动安装依赖,不直接连接共享 dev/test/main 或操作真实业务数据;相关检查继续由主 Agent 通过现有环境授权/租约流程执行。命令退出 0 只证明命令层执行成功;必需用例是否执行、SKIP、持久性/UI 和业务验收仍按验证契约核对。
## 证据与状态
输出位置:.doc/test-reports/assets/pi-subagents/<task-id>/<request-id>/。
- receipt.json:请求摘要、配置摘要、源码/输入文件摘要、配置与观察到的模型、运行状态、命令结果、工具调用摘要。
- report.md:可读报告;模型分析是审查输入,主 Agent 核对后再推进阶段。
- 命令日志:按收据记录的位置查询;报告目录受对应 path 租约保护。
- 模型私有 thinking 不作为归档材料。错误输出与日志按敏感信息规则处理;不保存凭证。
run_status 与 verdict 分开:模型正常结束可以是 succeeded,但非测试报告仍为 review_state=pending / verdict=not_applicable。测试报告的 commands_passed/pass 只针对提交的命令,不能直接赋值到任务的 review_state 或 acceptance。失败、取消、结果未知不能换成 PASS。
超时、取消和输出超限处理整个受控进程组。只读结果查询可推断 orphan 为 unknown,但不能通过查询无租约改写收据。错误前置检查未形成业务收据时,MCP 返回可核对的执行拒绝,不能让主 Agent 一直等待不存在的结果。
## 调整与边界
角色默认模型、enabled、升级角色和并发上限在模型配置文档维护。禁用角色前同步处理指向它的升级关系。程序仅接受当前明确批准的五个 provider/model 组合;扩大模型池还需用户授权并更新硬边界校验,不是任意改一行即放宽权限。
本工具提供配置解析、模型启动、有限工具/输入范围、租约、进程监督和证据保存;没有把全部 S0–S9 的审批实现成不可跳过的状态机。Cursor 通过规则决定何时调用;模型失败不会触发隐式换 provider 或降级到 M3。
进程组和工具权限限制不是 OS 沙箱。批准的测试代码与本机工程工具属于可信执行面;外部不可信项目/代码不能因使用本工具就获得运行授权。普通 Cursor/PI 配置与 Herdr、产品 PI Runner 各自独立。
@@ -0,0 +1,88 @@
# Subagent 模型分配配置
config_revision:`subagent-models-2026-09-24-r1`
owner:用户;维护执行者:当前任务主 Agent。
decision_state:`approved`(本会话确认);integration_state:`merged`;execution:`enforced`(本执行器已验证的配置/租约/工具/进程边界);阶段审批仍为 manual。
**这是模型分配的唯一配置文档。** 用户调整下列表格;主 Agent 每次派发前读取,并把解析结果写入[派发记录](templates/subagent-stage-record.md)。`scripts/pi_subagents.py` 已直接解析本文件,Cursor MCP 提供角色预览、派发与结果查询;每次新派发读取配置,旧请求保留旧摘要。实测与边界见[运行说明](2026-09-24-pi-subagent-executor.md)和[报告](../test-reports/2026-09-24-pi-executor-test-report.md)。完整流程见[协作规范](2026-09-24-subagent-workflow-standard.md)。
## 1. 日常调整入口
| 想调整什么 | 修改位置 | 生效方式 |
|---|---|---|
| 某角色的默认模型 | §3 对应角色的“默认模型”列 | 修改后递增 config_revision;下一次派发读取 |
| 复杂任务的升级去向 | §3 “升级角色”列 | 升级时保留原报告与原因;以目标角色重新派发 |
| 启停某角色 | §3 enabled 列 | false 时不自动派发;引用该角色的升级关系须同时调整;必需职责暂停或显式重新分配,不能跳过门禁 |
| 允许使用的 provider/model | §2 模型池 | 使用本机精确 ID;新增模型需用户明确调整授权范围并更新程序硬边界校验 |
| 并发量、失败处理 | §4 | 主 Agent 按配置与任务实际资源取更严格边界 |
| 只改本次任务 | 在任务主记录写 override | 记录用户指令、角色、原值/新值、期限;不改全局默认 |
文档中表格值为配置;其他文件只引用本文件,不重复维护模型名。用户可以直接编辑,也可以说“把本任务 code_review 改用 qwen_max”或“以后 report 都用 glm_full”。后者需按仓库 worktree/受控集成流程保存。
字段规则:enabled 只取 true/false;默认模型引用 §2 的 alias;升级角色引用 §3 的 role_id,或 none;缺字段、未知 alias、循环升级、角色越权时停止该派发并报告错误,不自行猜测模型。
## 2. 允许的模型池
主会话:**Cursor,模型选择 Auto**;工程子任务:**gmktec 本机 PI CLI**。这份配置不改变 Cursor UI 模型开关、PI 全局默认设置或产品 PI Agent Runner。
| alias | provider | model(精确 ID) | 使用限制 |
|---|---|---|---|
| qwen_max | qwen-token-plan-cn | qwen3.8-max | 可分配分析、规划、报告与复核 |
| qwen_flash | qwen-token-plan-cn | qwen3.8-flash | 默认检索、资料与初稿;复杂任务升级 |
| glm_full | zai-coding-cn | glm-5.3 | 默认评估、独立审查和复杂归因 |
| glm_flash | zai-coding-cn | glm-5.3-flash | 默认测试执行与证据收集;复杂判断升级 |
| minimax_aux | minimax-cn | MiniMax-M3 | 默认停用,仅明确启用后用于易核验辅助任务;不能承担关键判断 |
本机 provider 是 qwen-token-plan-cn;用户提到的 qwen-token-plan 在此明确映射到该通道。相同模型名出现在其他 provider 不构成可替换授权。M3 不进入规划、代码审查、根因裁决、最终验收或主力自动备用链;需要改变这些限制时由用户明确修订本节。
目录核对:2026-09-24,通过本机 pi 的离线 --list-models 核实以上五个组合。存在于目录不等于远端连通、工具调用、性能和任务质量已实测。
## 3. 角色路由表
代码实施与修复固定由 **Cursor Auto** 承担;下表只路由 PI 子任务。PI 不修改产品代码或测试源码,所需修复/新测试交回 Cursor。
| role_id | 工作 | enabled | 默认模型 | 升级角色 | 执行边界 |
|---|---|---|---|---|---|
| research | 检索、代码定位、资料摘录、需求初稿 | true | qwen_flash | planning | 只读;结论回传主 Agent |
| planning | 需求分析、方案制定、复杂问题综合分析 | true | qwen_max | none | 只读;保留假设与依据 |
| requirements_review | 独立评估需求与影响 | true | glm_full | none | 新上下文;不代替用户取舍 |
| plan_review | 独立方案审查 | true | glm_full | none | 不自审自己编制的方案 |
| code_review | 代码审查与回归风险检查 | true | glm_full | none | 冻结 diff;不修改被审内容 |
| diagnosis | 复杂失败归因、跨模块机制分析 | true | glm_full | none | 只读分析;复现操作由 test_run 在授权环境执行 |
| test_run | 按已批准验证计划执行测试、收集证据、初步分析 | true | glm_flash | diagnosis | 仅批准命令、测试产物与环境;不修改源码 |
| acceptance_check | 按既定 AC 执行检查、核对真实证据 | true | glm_flash | diagnosis | 不代签最终验收;涉及业务取舍交 acceptance_owner |
| stage_notes | 阶段记录与报告初稿 | true | qwen_flash | report | 忠实整理原证据;主 Agent 持锁落盘 |
| report | 最终报告、复杂材料综合 | true | qwen_max | none | 汇总不能改写原始失败或推导未验证的 PASS |
| auxiliary | 格式整理、清单提取等易核验工作 | false | minimax_aux | none | 明确启用后派发;保留来源供核验 |
一个模型可承担多种角色,但派发必须区分上下文与职责。即使用户将规划和审查映射到同一模型,独立审查仍须新上下文/不同执行实例;模型不同也不自动证明审查独立。
最终验收责任继续归任务声明的 acceptance_owner;主 Agent 核对证据与权限后推进。test_run 和 acceptance_check 的输出是检查结果,不能只因模型返回“通过”就放行。
## 4. 执行与升级参数
| 参数 | 默认值 | 语义 |
|---|---|---|
| max_parallel_pi_tasks | 2 | 同时运行的 PI 子任务上限;路径冲突/共享环境锁优先 |
| implementation_executor | cursor_auto | 实施和修复不派给 PI;改此边界需要用户明确授权 |
| unavailable_action | pause_role | 模型或通道不可用时暂停对应角色;可继续无依赖工作 |
| automatic_fallback | none | 不静默换模型/换 provider;不因超时降级到 M3 |
| reload_boundary | next_dispatch | 新任务/下一次派发读取;不修改正在运行的子任务 |
| recursive_delegation | false | 仅主 Agent 派发;PI 子任务需要协作者时返回建议 |
升级触发:Flash 无法解释失败、证据互相矛盾、涉及跨模块机制或超出已批准验证计划。升级用于质量不足,不是网络故障重试;结果未知先核对副作用,流程遵循协作规范。
本次用户覆盖 > 本文件默认;仓库授权/写锁/验收边界始终约束执行。对文档中已允许角色和模型的任务级调整,不重复索要已经给出的许可;自动化程序、日志和子报告中的“配置已批准”不能替代用户来源。
## 5. 配置更改与追溯
1. 在任务 worktree 调整本文件;全局默认修改随受控集成发布。本轮已合入本地 dev;新任务从 dev 创建后使用此配置,调整后仍需受控集成。
2. 更新 config_revision;保留修改原因和用户来源。派发前核对角色、模型池和升级关系。
3. 每次派发记录配置路径、config_revision、文件 SHA-256、role_id、configured provider/model、任务覆盖和原因;已有子任务沿用自己的配置快照。
4. PI 启动时按精确 provider/model 传递,不能省略参数后依赖 ~/.pi/agent/settings.json。启动记录或可信响应元数据不可核验实际模型时填 actual_model=unknown。
5. 修改配置不产生代码写入、环境操作、push、部署或清理授权;报告/输出由主 Agent 按现有租约规则保存。
6. 回退时恢复先前角色值,递增配置修订并记录来源;不要覆盖历史派发记录或把失败改成成功。
初始决策依据:用户指定五模型池;明确“代码实施还是让 cursor 来”;反馈 M3 能力有限;随后确认“M3 移出默认流程、仅可选辅助”,并要求提供可调整配置文档。
@@ -0,0 +1,165 @@
# 主 Agent 与 Subagent 协作流程规范(草案)
修订:`subagent-workflow-2026-09-24-r2`;owner:Codex;规则状态:`proposed`;执行能力:`manual`;effective_commit:无。
本流程规范仍为待审稿;用户已确认 Cursor 实施、本机 PI 分析/审查/验证及模型默认分工,具体值唯一维护在[模型配置](2026-09-24-subagent-model-config.md)。规则批准与受控集成后才进入 active;文档存在不表示 PI 调度器已接入。
研究与来源见[研究报告](../audit/2026-09-24-subagent-workflow-research.md),本次授权及交付状态见[任务](short-term/2026-09-24-subagent-workflow-standard.md)。
## 1. 目标、适用范围和权威
用户在 Cursor 主会话保持 Auto;Cursor 负责主协调、代码实施和修复,通过 gmktec 本机工程 PI CLI 委派分析、审查、测试和报告。每阶段产生可恢复记录。此配置不自动适用其他客户端或 Herdr。
本规范只定义角色、阶段、交接和证据引用。授权边界沿用 [AGENTS](../../AGENTS.md),写锁/候选合并/环境/清理沿用 [worktree 操作规范](2026-09-21-agent-worktree-workflow.md),测试层级沿用[验证契约](2026-09-21-validation-contract.md),问题闭环沿用[既有规范](2026-09-23-issue-learning-workflow.md)。不建立第二套测试门禁。
普通 Cursor 会话不启用 Herdr 角色和固定模型路由;只有明确使用 Herdr 时适用其专门规范。工程 subagent 与产品 PI Agent Runner 分开记录,前者的执行不能替代后者的验收。
## 2. Auto、授权和推进规则
- **模型策略**:主会话选择 Auto;PI 子任务按[模型配置](2026-09-24-subagent-model-config.md)的角色、provider 和 model 派发。Cursor 原生 subagent 的 model: inherit 方案已被用户后续选择替代,本规范不以 .cursor/agents 实现 PI 路由。
- **能力核验**:首次接入、客户端升级或模型行为异常时,记录客户端版本、角色可发现性、派发 ID、工作目录、配置模型策略及可观察的实际模型;不可见时写 `actual_model=unknown`。不得从自我介绍推断模型。
- **证据边界**:记录配置指定值与可核验的实际模型;未核验不声称模型调用成功。模型多样性不替代独立上下文和证据。
- **授权策略**:Auto 只表示模型选择,不表示自动授权 shell、外部写入、合并、部署、推送或删除。任务开始记录已有授权,后续不重复询问相同范围。
- **默认确认点(待用户采纳)**:需求形成、评估、方案编制可连续进行;方案可审后,一次确认方案与实施范围。已明确授权按该方案端到端执行,则该确认已经满足。只有范围/环境/外部副作用扩大、破坏性动作或需要用户作业务取舍时再确认。
- **验收人**:需求阶段明确 acceptance_owner。技术验收检查可由获授权 acceptance_check 执行;产品效果/业务取舍需要用户判定时,技术通过后保留 `acceptance=pending`,不由 Agent 代签。用户预先委托按明确客观标准验收时,记录委托来源和证据即可。
- 仅请求研究/方案的任务交付可审产物后结束。实现、运行验证、合并等阶段逐项写 `not_applicable + 原因`,不为了流程齐全擅自执行。
## 3. 标准流程
```mermaid
flowchart TD
A[建场与授权记录] --> B[形成需求和验收标准]
B --> C[评估需求与影响]
C --> D[制定方案和验证计划]
D --> E{实施授权是否满足}
E -->|是| F[实施和开发自测]
E -->|否| P[交付可审方案]
F --> G[独立代码审查]
G -->|需修改| F
G -->|通过| H[冻结交付版本并验证]
H -->|失败| F
H -->|通过| I[构造候选并验证合并结果]
I -->|通过| J[受控合入 dev]
J --> K[按授权部署与运行验收]
K -->|失败| R[保留现场并修复或交接]
R --> F
K -->|通过或不适用| L[确认交付并归档证据]
L --> M[owner退出后独立复查清理]
```
测试计划在方案阶段形成;自测贯穿实施;独立审查和必要测试必须覆盖最终版本。清理安排在验收与证据保存之后。合并前的工程验证与合并后的运行验收分别报告。
### 阶段、产物和放行条件
每行都是阶段记录要求,不要求每行一个文件。记录使用[阶段模板](templates/subagent-stage-record.md)。
| 阶段 | 责任与输入 | 最小产物 | 放行条件 / 失败去向 |
|---|---|---|---|
| S0 建场 | 主 Agent;用户请求、当前规则、Git/认领状态 | task 主记录:目标、授权、基线、写路径、环境、交付终点、policy_revision | 允许范围明确;持久成果在任务 worktree;按现行入口登记 |
| S1 形成需求 | Cursor 与用户,可委派 research/planning;原始描述 | 需求记录:用户场景、范围/非目标、R-ID、AC-ID、优先级、验收人 | 可验证预期明确;影响方案的歧义解决,小型假设标注 |
| S2 评估需求 | requirements_review;S1 和当前证据 | 评估报告:现状差距、替代方案、依赖、风险、复杂度和建议 | 结论为 proceed / revise / defer;高风险未知有验证路径;revise 回 S1 |
| S3 制定方案 | Cursor 协调 planning 编制、plan_review 独立复核;S2 | 方案:改动位置、接口/数据影响、实施依赖、写者、验证矩阵、恢复方案;附方案审查结论 | AC 映射到验证项;必要权限齐备;授权不足交付方案等待;设计疑问回 S2 |
| S4 实施与自测 | Cursor;已授权方案 | 实施记录:变更、提交、偏差、自测与失败记录 | 实现满足方案且自测有证据;范围变化回 S1/S3;不得降低 AC 迁就实现 |
| S5 独立代码审查 | code_review;需求/方案、base/head、完整差异 | 审查报告:范围、审查者、严重度、位置、依据、处置与复核 | 无未解决阻断项;修复回 S4,变更后的代码需复核 |
| S6 交付验证 | test_run;冻结版本、AC、验证契约 | 测试报告:预期用例、实际命令/输入/输出、环境、SHA、PASS/FAIL/SKIP/未运行 | 适用必需项均通过;SKIP/基础设施失败保留阻塞;失败回 S4 或 S3 |
| S7 候选与集成 | 串行集成执行者;S5/S6、最新 dev D、冻结 T | 集成报告:D/T/M、候选验证收据、锁内结果、实际 dev | 按现行 --no-ff 候选与 --ff-only 入口;D/T/M 变化须重新准入 |
| S8 运行与交付验收 | acceptance_check + acceptance_owner;受控制品、AC | 验收报告:实际制品、环境、用户流程、持久状态、逐项 AC 结论 | 所需运行/UI 验收通过;无运行影响写 not_required;失败不清理、不冒充完成 |
| S9 归档与清理 | 主 Agent 固化证据,owner 退出后维护者执行清理 | 收口报告:提交/集成/部署/远端/cleanup 分离;归档证据、清理结果与遗留 owner | 满足现行普通 remove/-d 条件;拒绝保留 pending,登记触发和接管者 |
S5 与 S6 可以在同一不可变版本上并行;必要产物必须都回来才能进入 S7。测试产生构建目录/缓存/数据也算写副作用,先核对其环境和锁。code_review 阅读稳定 Git 快照,不在 Cursor 正在改写的工作树上宣布最终通过。
S7 候选需执行该范围的真实检查,不能用分支自测替代合并结果验证。S8 后新增的报告提交也需受控集成;分别记录被测业务 SHA 与报告 SHA,说明仅文档变化的复用依据。影响运行内容的后续变更使相关验收失效。
## 4. 角色和分工
角色是职责,不要求每阶段单独启动一个进程。精确 role_id、enabled、默认模型和升级链只维护在[模型配置](2026-09-24-subagent-model-config.md),下表说明权限边界。
| 角色 | 职责 | 写权限和独立性 |
|---|---|---|
| Cursor / coordinator | 与用户对话、授权核对、任务图、派发、证据汇总、冲突处理、推进门禁和交接 | 唯一任务协调者;报告汇总不改变原作者/证据/结论;不能从子报告推导额外授权 |
| research / planning / report / stage_notes | 需求影响、方案、资料和报告 | 默认只读;返回结构化报告,由主 Agent 落盘;若编制方案,另一个上下文审查方案 |
| Cursor / implementation | 实施方案、修复问题、编写和修改测试源码 | 产品和测试源码的实施者;按认领/租约操作,PI 建议交回 Cursor 处理 |
| requirements_review / plan_review / code_review / diagnosis | 独立评估、审查与复杂故障归因 | 新的只读上下文;不修改被审内容;发现问题返回 Cursor;复现交给获授权的 test_run |
| test_run / acceptance_check | 按冻结 AC 和已批准计划执行验证,核对真实行为 | 仅写批准的测试产物/环境;不改源码、不代签最终验收,需要修复交回 Cursor |
| integrator / maintainer | 候选验证、受控合并;owner 退出后的清理 | 串行短时角色,使用现有工具/权限;不能把长驻 worker 同时当作可删除的 worktree owner |
同模型的独立上下文可以提供独立检查,但不消除共同盲区;验证仍以源码、命令和用户流程证据为准。主 Agent 自审只能记录 self_review。要求独立审查的代码任务如无 subagent 能力,交给另一个独立会话/人员;该项完成前不自动放行。低风险纯文档可自检并记录理由。
## 5. 何时派发与如何并行
- 适合派发 PI:较长只读研究、独立审查、按批准计划验证、报告整理。代码实施和修复保留给 Cursor。
- 主 Agent 直接处理:一次定位、简短文案、单一顺序操作;仍留下对应阶段记录。无需为了覆盖阶段机械启动九个 Agent。
- 并发上限及递归委派规则以模型配置为准;资源不足串行。它是项目预算,不是平台上限;子 Agent 发现进一步分解需求先返回建议。
- 先画依赖再并行;有先后依赖的任务等待前置证据。有相同文件、公共 lockfile、路由、迁移号或共享环境的写任务不能同时认领。
- 同一任务 worktree 的源码写者为 Cursor,PI 只读任务读取冻结快照;只读报告由 Cursor 持锁保存。PI 验证涉及产物/环境写入必须在有效 agentctl supervisor 下运行;无法保证时停止执行并报告条件缺失。
- 若另行开展多 Cursor 并行实施,仍须独立登记 worktree,各自从明确 dev SHA 创建;父子关系用 parent_task_id/subtask_id 关联。此条不授权 PI 实施代码。
- 父任务汇总子任务成果,源码仍由 Cursor 实施。涉及测试产物写入的子任务登记独立操作 ID/路径;只读子审查复用父任务文档,不重复创建任务链。子分支结果通过现行候选集成流程交付;不能由 Cursor 的自动隔离/自动合并绕过本仓注册和准入。
- 有后台任务时,主 Agent 可继续独立工作,但不得在结果未回收时发布依赖它的 PASS、合并或清理。各子任务的工具可用性不代表授权可用性。
## 6. 派发、回传与失败处理
每次派发至少包含:
1. parent_task_id、subtask_id、role_id、具体目标、输入版本(需求/方案/代码 SHA);配置路径、config_revision、文件 SHA-256、解析后的 provider/model 和任务覆盖依据。
2. 需要读的规范和证据、已有用户授权来源、明确的非目标。
3. 工作目录、允许写路径、环境、mutex/租约执行方式;只读者明确只读。
4. 完成条件、输出格式/报告路径、需要验证的 AC;子 Agent 不依赖未传入的主会话历史。
5. 预算(时间或步骤)、进度回传点、失败/超时和副作用核对方式。
回传至少包括:执行身份/PI run_id、配置版本与指定/实际模型、实际输入版本、结果与证据、变更文件/提交、实际命令与环境、结论、缺项/风险、遗留进程/产物。主 Agent 校验路径、版本和证据后标记 accepted;子 Agent 自报 done 只表示执行结束。
- 分开记录 run_status(running/succeeded/failed/cancelled/unknown)与 verdict(pass/changes_required/blocked/not_applicable),不可把退出成功等同质量通过。
- 超时/失联先检查进程、worktree、Git 和外部副作用;结果未知时保留 unknown,不同时重派同一写任务。纯只读且确认无副作用的失败可有限重试,并保留原记录。
- 审查/验证角色有异议时,主 Agent 依据原需求和证据裁决。能修复则回 S4;需要业务取舍则向用户汇总一个关键问题,不以多数投票覆盖阻断证据。
- 连续两轮修复仍未解决同类阻断时,停止机械重试,回 S2 重查机制/测试前提;授权内可继续研究。不得为放行删除失败用例或降低 AC。
- 用户中断、客户端退出、上下文压缩时,先固化阶段、版本、未回收子任务、owner 和接管条件;恢复后从首个未满足门禁继续,不能整条流程重跑或直接跳到收口。
## 7. 文档与报告契约
“一步一记录”,无需“一步一文件”。现有文件优先复用,原始证据只存一处:
| 任务类型 | 最小文档集合 |
|---|---|
| 信息问答,无持久成果或运行副作用 | 对话答复 |
| 小型规范/研究/低风险变更 | 一个 task 或分析主文档,含适用阶段、验证与交接 |
| 标准功能/缺陷修复 | task + 方案 + 报告;评估/实施/审查/测试/验收可为清楚分段 |
| 跨模块、迁移或部署 | task + 必要 plan + 分开的审查/测试/验收证据;handoff 仅在独立信息有价值时拆分 |
每份阶段记录包含 stage_id、输入版本、producer、reviewer/独立性、decision、证据链接、缺项和下一步。需求用 R-ID,验收用 AC-ID,测试用 T-ID;报告提供 R → AC → 改动 → 审查 → 测试 → 运行验收映射,避免仅列“文档已生成”。
路径沿用 .doc taxonomy:任务在 ops/short-term,研究/审查在 audit,方案在 remediation 或既有 ops 主文档,独立测试/验收在 test-reports,附件在其 assets。只读 subagent 由主 Agent 保存原始结论及必要摘录,标明“由主 Agent 转存”与 agent_id;不伪造子 Agent 已写文件。
任务 status 继续只有 planned/in_progress/blocked/done/cancelled;phase 与 review_state、integration_state、deployment、cleanup、remote_sync、acceptance 独立记录。done 取决于授权交付终点。清理待办不扩充任务状态,但必须有人接管。需求验收 pending 时,若验收属于授权交付终点,任务不能 done。
## 8. Cursor → 本机 PI 接入(任务分支已实现)
### 配置与能力边界
用户已明确选择 Cursor Auto 主协调和实施、gmktec 本机 PI 承担子任务;原 r1 的 Cursor 原生 .cursor/agents + inherit 方案废止,历史研究保留说明。当前[模型配置](2026-09-24-subagent-model-config.md)可人工调整,由执行器每次派发读取;不是 PI 原生配置格式,不改变 PI 全局模型设置。CLI/MCP 接入与限制见[运行说明](2026-09-24-pi-subagent-executor.md),实际验证见[报告](../test-reports/2026-09-24-pi-executor-test-report.md)。
PI 模型和角色路由以配置文档为唯一来源。主 Agent 根据任务读取 role_id,显式传入 provider/model、独立会话、输入版本、工作目录与工具范围,收取结果后按本规范形成阶段记录。不能把主会话可用工具全部自动授予子任务。
- 只读研究/审查不需要 bash/edit/write;后续接入时显式限制工具,并核对扩展是否引入额外能力。
- 测试角色需要执行批准的命令并产生缓存/产物,不能假称只读;将测试工作目录、数据和环境放在批准范围内,使用既有 agentctl 租约。
- PI 报告由主 Agent 持锁落盘;PI 不修改业务代码或测试源码。将诊断建议交回 Cursor 实施。
- 模型不可用、实际模型不符、配置缺失或未知结果遵循配置和 §6,不隐式换通道或降级。
- 普通本机 PI 调度不复用 Herdr 自动审批/模型预算;产品 PI Runner 仍按目标环境批准配置独立验收。
### 后续接入步骤与验收
| 步骤 | 变更 | 必需证据 |
|---|---|---|
| A 文档配置 | 已确认分工,维护模型配置/派发模板;流程整体另按规范登记 | 默认值与用户选择一致;修改可追溯;未合入前不称全仓 active |
| B 消除旧规则冲突 | 修订 Cursor 测试规则副本为验证契约指针 | 相关 ISSUE 单独修复验证;本次不改变 Runner |
| C 实现派发入口 | 已实现 CLI + 项目 MCP;本地任务分支代码 69ffaa67 | 配置/租约/模型/快照/结果校验与异常回归已验证;dev 集成另记 |
| D 实机试运行 | 小型文档任务和受控代码任务(代码由 Cursor 写) | Auto 不需手动切模型;PI 角色/模型/run_id/证据可追溯;不冒充真实产品 PI |
| E 异常演练 | 同路径写冲突、PI 失联、必需测试缺项、dev 变化、验收失败、清理拒绝 | 正确暂停/升级;保留失败证据 |
| F 工具门禁 | 据试运行决定是否增加阶段校验/hook | 实现和真实负例验收后才将相应能力标 enforced |
接入验收 V1–V10:V1 Cursor Auto 与配置指定 PI provider/model;V2 授权/需求上下文传递;V3 独立只读审查与报告转存;V4 租约内测试;V5 输入 SHA 变化后复核;V6 写冲突拒绝;V7 缺项不合并;V8 验收失败保留现场;V9 清理拒绝有 owner;V10 中断后恢复。新增 V11:修改配置只影响下一次派发、记录 hash;V12:M3 停用/越权路由及未知 alias 被拒绝。本轮执行器已完成 173 项工程回归与真实 Cursor CLI→MCP→PI 验证,覆盖及未覆盖项以测试报告为准;这不是宣称全部 S0–S9 审批、产品 UI/共享环境或清理已自动执行。
### 日常使用与调整
用户只需保持 Cursor Auto,说明任务目标与授权终点;主 Agent 读取本规范和模型配置,按需要派发 PI。修改默认分工只编辑模型配置文档;临时调整写入任务 override,不静默改全局默认。流程、模型配置和某任务授权是三个不同对象。
用户可以授权“按已确认方案执行到 local dev 集成与 dev 验收”;该授权不会自动包含 push 或晋升 test/main。验收后归档证据,当前 owner 退出后再由独立维护者复查清理。
回退:调度入口或权限不满足时暂停相应 PI 阶段,保留现场与证据,交回 Cursor 处理;不能以主 Agent 自审替代要求的独立审查。修复接入后再验证。
+136 -10
View File
@@ -1,46 +1,172 @@
# 当前焦点
**更新**:2026-09-22(dev 门禁复验与 test 晋升收口)。此文件是协调快照;实际分支、进程、执行租约以机器核验为准。能力和发布结论分别见 [FEATURE-MATRIX](../status/FEATURE-MATRIX.md) / [gap-matrix](../remediation/gap-matrix.md)。
**更新**:2026-09-23(剩余 worktree 收口:go-agentx+FAV 合入 local_dev;注册 worktree 已清;FAV live 仍不放量)。此文件是协调快照;实际分支、进程、执行租约以机器核验为准。能力和发布结论分别见 [FEATURE-MATRIX](../status/FEATURE-MATRIX.md) / [gap-matrix](../remediation/gap-matrix.md)。
手工 CAS 前:本 macOS 宿主 `docs apply`/`with`/`validate`/`integrate` 因 `/proc` 不可用;本轮文档与环境写采用手工等效(见任务例外登记)。
本机 macOS 已可用 `agentctl with`/`docs apply`/`validate`/`integrate`(W1-B 进程层);共享文档写走 docs apply 收据。
## 焦点
1. **dev→test 已晋升**:`origin/dev@591ea601`(schema 61 门禁绿);`origin/test@83c6a12a` + tag `rc-v1.1.0-beta.1`;test 环境 health schema=61、Runner `MiniMax-M3`。[报告](../test-reports/2026-09-22-dev-gate-and-test-promotion-test-report.md)。
2. **本任务 cleanup=pending**:feature / integrate / promote-test worktrees 待独立维护者按门禁复查后清理;不强删。
3. **Agent 规范与 L1 门禁**:R01–R10、共享 .locks 已启用;本机 macOS 上租约路径不可用,受测 Linux 主机仍 enforced。
0. **全量未完成计划收口**:FEATURE-MATRIX「模块解耦批次 A–G」→ `done`;多意图 I1 / 语义摘要 S1 / 治理 W4 / rdev / 红线证据已登记残差;红线(FAV live / SWBOOT-10 / D7 物理删 / PI 叙事 flag)不放量。详见 [收口短文](./short-term/2026-09-22-unfinished-batch-closeout.md)。
1. **DOCREV UI 重跑已 PASS**:main 18 + post-restart UI-15;20 audit + 9 remediation `done`(`management-implementation-plan` 仍方案态)。schema 63;密封 [sealed-ledger-ui00-16-post-20260923T0400Z](../test-reports/assets/2026-09-22-docrev-ui-rerun/sealed-ledger-ui00-16-post-20260923T0400Z/);证据 [测试报告](../test-reports/2026-09-22-docrev-ui-rerun-test-report.md);worktree cleanup=pending。
2. **dev→test 已晋升**:`origin/dev@591ea601`(schema 61 门禁绿);`origin/test@83c6a12a` + tag `rc-v1.1.0-beta.1`;test 环境 health schema=61、Runner `MiniMax-M3`。[报告](../test-reports/2026-09-22-dev-gate-and-test-promotion-test-report.md)。
3. **本任务 cleanup=pending**:feature / integrate / promote-test worktrees 待独立维护者按门禁复查后清理;不强删。
4. **Agent 规范与 L1 门禁**:R01–R10、共享 .locks 已启用;本机 macOS 租约路径可用(Darwin 进程层已落地),与 Linux 双平台 enforced。
## 并行认领
| owner | task | branch | worktree | mutex | status |
|---|---|---|---|---|---|
| Cursor | docgov-shared-map-race-2026-09-28-r2 | fix/docgov-shared-map-race-2026-09-28 | .worktrees/docgov-shared-map-race-2026-09-28 | docgov-shared-map-race | in_progress |
| Cursor | promote-rc-beta6-closeout-2026-09-28 | feature/promote-rc-beta6-closeout-2026-09-28 | .worktrees/promote-rc-beta6-closeout-2026-09-28 | git:test+env:test | done |
| Cursor | quality-gate-heading-mismatch-2026-09-28-r3 | fix/quality-gate-heading-mismatch-2026-09-28 | .worktrees/quality-gate-heading-mismatch-2026-09-28 | quality-gate-heading | in_progress |
| Cursor | agent-reply-llm-narrative-2026-09-28 | feature/agent-reply-llm-narrative-2026-09-28 | .worktrees/agent-reply-llm-narrative-2026-09-28 | chat+coordinator | in_progress |
| Cursor | test-user-doc-issues-2026-09-28 | fix/test-user-doc-issues-2026-09-28 | .worktrees/test-user-doc-issues-2026-09-28 | intent-write-verb | done |
| Cursor | pi-runner-env-mismatch-2026-09-28 | fix/pi-runner-env-mismatch-2026-09-28 | .worktrees/pi-runner-env-mismatch-2026-09-28 | pi-runner-env | done |
| Cursor | error-events-pg-roundtrip-2026-09-28 | feature/error-events-pg-roundtrip-2026-09-28 | .worktrees/error-events-pg-roundtrip-2026-09-28 | error-events-pg-evidence | done |
| Cursor | error-code-observability-2026-09-28 | feature/error-code-observability-2026-09-28 | .worktrees/error-code-observability-2026-09-28 | error-code-observability | done |
| Cursor | attachment-only-turn-2026-09-28 | fix/attachment-only-turn-2026-09-28 | .worktrees/attachment-only-turn-2026-09-28 | attachment-only-turn | done |
| Cursor | activation-preview-precheck-2026-09-28 | fix/activation-preview-400-precheck-2026-09-28 | .worktrees/activation-preview-400-precheck-2026-09-28 | web-activation-preview | done |
| Cursor | squad-commit-authority-2026-09-28 | fix/squad-commit-authority-2026-09-28 | .worktrees/squad-commit-authority-2026-09-28 | bizdev+docflow | in_progress |
| Cursor | auth-register-internal-2026-09-28 | fix/auth-register-internal-2026-09-28 | .worktrees/auth-register-internal-2026-09-28 | auth-register | done |
| Cursor | restore-admin-password-reset-2026-09-28 | feature/restore-admin-password-reset-2026-09-28 | .worktrees/restore-admin-password-reset-2026-09-28 | auth | done |
| pi | test-single-binary-2026-09-27 | feature/test-single-binary-2026-09-27 | .worktrees/test-single-binary-2026-09-27 | env:dev+env:test+git:dev+git:test | done |
| pi | upload-doc-access-2026-09-27 | fix/upload-doc-access-2026-09-27 | .worktrees/upload-doc-access-2026-09-27 | freedoc+web-upload | done |
| pi | frontend-demo-fallback-2026-09-27-r3c | fix/frontend-demo-fallback-2026-09-27-r3 | (已清理) | web-chat-fallback | done |
| pi | frontend-demo-fallback-2026-09-27-r2 | fix/frontend-demo-fallback-2026-09-27 | (已清理) | web-chat-fallback | done |
| Cursor | full-system-browser-e2e-2026-09-26 | feature/full-system-browser-e2e-2026-09-26 | .worktrees/full-system-browser-e2e-2026-09-26 | env:dev+docs-test-report | done |
| pi | sysadmin-maturity-refresh-2026-09-26 | feature/sysadmin-maturity-refresh-2026-09-26 | .worktrees/sysadmin-maturity-refresh-2026-09-26 | sysadmin-maturity | done |
| pi | degraded-flags-enable-2026-09-26-r4 | feature/degraded-flags-enable-2026-09-26 | .worktrees/degraded-flags-enable-2026-09-26 | summary-flags-rollout | done |
| pi | system-review-p0-p1-fixes-2026-09-26 | fix/system-review-p0-p1-fixes-2026-09-26 | .worktrees/system-review-p0-p1-fixes-2026-09-26 | review-fixes-batch | done |
| Cursor | system-code-review-2026-09-26 | feature/system-code-review-2026-09-26 | .worktrees/system-code-review-2026-09-26 | docs-audit-review | done |
| pi | swboot-closeout-2026-09-26-r3 | feature/swboot-closeout-2026-09-26 | .worktrees/swboot-closeout-2026-09-26 | workflow-design | done |
| pi | swboot-closeout-2026-09-26-r2 | feature/swboot-closeout-2026-09-26 | .worktrees/swboot-closeout-2026-09-26 | workflow-design | in_progress |
| pi | chat-semantic-replace-2026-09-26 | feature/chat-semantic-replace-2026-09-26 | .worktrees/chat-semantic-replace-2026-09-26 | chat | done |
| pi | jevdecide-soak-2026-09-26 | feature/jevdecide-soak-2026-09-26 | .worktrees/jevdecide-soak-2026-09-26 | jevdecide | done |
| pi | dialogue-ctx-closeout-2026-09-26-r4 | feature/dialogue-ctx-closeout-2026-09-26 | .worktrees/dialogue-ctx-closeout-2026-09-26 | dialogue-ctx | done |
| pi | dialogue-ctx-closeout-2026-09-26-r2 | feature/dialogue-ctx-closeout-2026-09-26 | .worktrees/dialogue-ctx-closeout-2026-09-26 | dialogue-ctx | in_progress |
| pi | worktree-final-closeout-2026-09-26 | feature/worktree-final-closeout-2026-09-26 | (已清理) | git:dev+docs | done |
| cursor-auto | cleanup-audit-r3-2026-09-25 | feature/cleanup-audit-p11-2026-09-25 | .worktrees/cleanup-audit-p11-2026-09-25 | docs-cleanup-audit | done |
| Cursor | admin-settings-maint-b-2026-09-25 | feature/admin-env-settings-maintenance-2026-09-25 | .worktrees/admin-env-settings-maintenance-2026-09-25 | admin-settings-maintenance | done |
| Cursor | dm-migration-2026-09-24-r2 | feature/dm-migration-2026-09-24 | .worktrees/dm-migration-2026-09-24 | dm-migration | done |
| Cursor | governance-console-p1-impl-2026-09-24 | feature/governance-console-p1-impl-2026-09-24 | .worktrees/governance-console-p1-impl-2026-09-24 | agentctl-console | done |
| Cursor | governance-console-p1-design-2026-09-24 | feature/governance-console-p1-design-2026-09-24 | .worktrees/governance-console-p1-design-2026-09-24 | agentctl-console-design | done |
| Cursor | governance-visibility-p0-2026-09-24 | feature/governance-visibility-p0-2026-09-24 | .worktrees/governance-visibility-p0-2026-09-24 | agentctl-visibility | done |
| Cursor | worktree-cleanup-closeout-2026-09-24 | feature/worktree-cleanup-closeout-2026-09-24 | (已清理) | worktree-cleanup | done |
| Cursor | non-author-closeout-2026-09-24 | feature/non-author-closeout-2026-09-24 | .worktrees/non-author-closeout-2026-09-24 | docs+git:dev | done |
| Cursor | integrate-non-author-docs-2026-09-24 | feature/integrate-non-author-docs-2026-09-24 | .worktrees/integrate-non-author-docs-2026-09-24 | git:dev | done |
| Cursor | non-author-member-access-docs-2026-09-24 | feature/non-author-member-access-2026-09-24 | .worktrees/non-author-member-access-2026-09-24 | docs+matrix | done |
| Cursor | non-author-member-access-2026-09-24 | feature/non-author-member-access-2026-09-24 | .worktrees/non-author-member-access-2026-09-24 | docgov+iam-authz+workflow-gov | done |
| Cursor | integrate-free-collab-2026-09-24 | feature/integrate-free-collab-2026-09-24 | .worktrees/integrate-free-collab-2026-09-24 | integrate-dev | done |
| Cursor | cursor-governance-hooks-2026-09-24 | feature/cursor-governance-hooks-2026-09-24 | .worktrees/cursor-governance-hooks-2026-09-24 | cursor-governance | done |
| Cursor | governance-catalog-2026-09-24 | feature/governance-catalog-2026-09-24 | .worktrees/governance-catalog-2026-09-24 | agent-workflow-governance+catalog | done |
| Codex | subagent-workflow-standard-2026-09-24-land | feature/subagent-workflow-standard-2026-09-24 | .worktrees/subagent-workflow-standard-2026-09-24 | pi-subagent-integration | done |
| Cursor/Codex | subagent-workflow-standard-2026-09-24-executor | feature/subagent-workflow-standard-2026-09-24 | .worktrees/subagent-workflow-standard-2026-09-24 | pi-subagent-executor | done |
| Codex | subagent-workflow-standard-2026-09-24-config-r2 | feature/subagent-workflow-standard-2026-09-24 | .worktrees/subagent-workflow-standard-2026-09-24 | subagent-workflow-docs | done |
| Codex | subagent-workflow-standard-2026-09-24 | feature/subagent-workflow-standard-2026-09-24 | .worktrees/subagent-workflow-standard-2026-09-24 | subagent-workflow-docs | done |
| Cursor | integrate-gate-nightly-fixes-b-2026-09-24 | feature/integrate-gate-nightly-fixes-b-2026-09-24 | .worktrees/integrate-gate-nightly-fixes-b-2026-09-24 | git:dev | done |
| Cursor | integrate-gate-nightly-fixes-2026-09-24 | feature/integrate-gate-nightly-fixes-2026-09-24 | .worktrees/integrate-gate-nightly-fixes-2026-09-24 | git:dev | done |
| Cursor | integrate-docs-gate-promo-report-2026-09-24 | feature/integrate-docs-gate-promo-report-2026-09-24 | .worktrees/integrate-docs-gate-promo-report-2026-09-24 | git:dev | done |
| Cursor | promote-rc-beta3-c-2026-09-24 | feature/promote-rc-beta3-c-2026-09-24 | .worktrees/promote-rc-beta3-c-2026-09-24 | git:test+env:test+docs | done |
| Cursor | dev-full-gate-test-promo-2026-09-24 | feature/dev-full-gate-test-promo-2026-09-24 | .worktrees/dev-full-gate-test-promo-2026-09-24 | git:dev+env:dev+env:test+docs | done |
| Cursor | gate-promo-current-close-2026-09-24 | feature/gate-promo-current-close-2026-09-24 | .worktrees/gate-promo-current-close-2026-09-24 | docs:admin+docs | done |
| Cursor | docs-gate-promo-report-2026-09-24 | feature/docs-gate-promo-report-2026-09-24 | .worktrees/docs-gate-promo-report-2026-09-24 | docs+git:dev | done |
| Cursor | admin-password-reset-2026-09-24 | feature/admin-password-reset-2026-09-24 | .worktrees/admin-password-reset-2026-09-24 | auth+env:test | done |
| Cursor | fix-fav-staging-uuid-2026-09-24 | fix/fix-fav-staging-uuid-2026-09-24 | .worktrees/fix-fav-staging-uuid-2026-09-24 | artifactvault | done |
| Cursor | gate-e1a-unique-project-name-2026-09-24 | fix/gate-e1a-unique-project-name-2026-09-24 | .worktrees/gate-e1a-unique-project-name-2026-09-24 | docnotify | done |
| Cursor | gate-unhook-docquery-2026-09-24 | fix/gate-unhook-docquery-2026-09-24 | .worktrees/gate-unhook-docquery-2026-09-24 | server+docquery | done |
| Cursor | integrate-jev-assist-land-2026-09-24 | feature/integrate-jev-assist-land-2026-09-24 | .worktrees/integrate-jev-assist-land-2026-09-24 | git:dev | done |
| Cursor | integrate-codegraph-fixup2-2026-09-24 | feature/integrate-codegraph-fixup2-2026-09-24 | (removed) | git:dev | done |
| Cursor | integrate-codegraph-governance-2026-09-24 | feature/integrate-codegraph-governance-2026-09-24 | (removed) | git:dev | done |
| Cursor | codegraph-governance-r2-2026-09-24 | feature/codegraph-governance-2026-09-24 | .worktrees/codegraph-governance-2026-09-24 | agent-workflow-governance+codegraph | done |
| Cursor | jev-dev-shadow-on-2026-09-24 | feature/jev-dev-shadow-on-2026-09-24 | .worktrees/jev-dev-shadow-on-2026-09-24 | env:dev+jevdecide | done |
| Cursor | jev-product-closeout-2026-09-24 | feature/jev-product-closeout-2026-09-24 | .worktrees/jev-product-closeout-2026-09-24 | jevdecide+coordinator | done |
| Cursor | jev-product-shadow-2026-09-24 | feature/jev-product-shadow-2026-09-24 | .worktrees/jev-product-shadow-2026-09-24 | jevdecide+coordinator | done |
| Cursor | jev-mcp-docs-done-2026-09-24 | feature/jev-mcp-docs-done-2026-09-24 | .worktrees/jev-mcp-docs-done-2026-09-24 | jev-mcp+docs | done |
| Cursor | jev-mcp-integration-2026-09-24 | feature/jev-mcp-integration-2026-09-24 | .worktrees/jev-mcp-integration-2026-09-24 | jev-mcp+docs | done |
| Cursor | integrate-intent-plan-u9u12-land-2026-09-24 | feature/integrate-intent-plan-u9u12-land-2026-09-24 | .worktrees/integrate-intent-plan-u9u12-land-2026-09-24 | git:dev | done |
| Cursor | integrate-pi-narrative-docs-2026-09-23 | feature/integrate-pi-narrative-docs-2026-09-23 | .worktrees/integrate-pi-narrative-final-closeout-b-2026-09-23 | git:dev | done |
| Cursor | pi-narrative-final-closeout-b-2026-09-23 | feature/pi-narrative-final-closeout-b-2026-09-23 | .worktrees/pi-narrative-final-closeout-2026-09-23 | docgov | done |
| Cursor | chat-semantic-d3-matrix-land-2026-09-23 | feature/chat-semantic-d3-matrix-land-2026-09-23 | .worktrees/chat-semantic-d3-matrix-land-2026-09-23 | chat | done |
| Cursor | intent-plan-i2-rollout-b-2026-09-24 | feature/intent-plan-i2-rollout-2026-09-24 | (已清理) | intent-plan | done |
| Cursor | intent-plan-i2-impl-2026-09-24 | feature/intent-plan-i2-shadow-allowlist-2026-09-24 | (已清理) | intent-plan | done |
| Cursor | closeout-claim-removed-2026-09-23 | feature/closeout-claim-removed-2026-09-23 | (removed) | git:dev+worktree-cleanup | done |
| Cursor | module-batches-ag-status-fix-2026-09-23 | feature/module-batches-ag-status-fix-2026-09-23 | .worktrees/module-batches-ag-status-fix-2026-09-23 | module-decoupling-spec | done |
| Cursor | fav-constraint-current-2026-09-23 | feature/fav-constraint-current-2026-09-23 | (removed) | git:dev+docs | done |
| Cursor | closeout-worktree-cleanup-2026-09-23 | feature/closeout-worktree-cleanup-2026-09-23 | .worktrees/closeout-worktree-cleanup-2026-09-23 | git:dev+worktree-cleanup | done |
| Cursor | remaining-worktrees-closeout-2026-09-23 | feature/remaining-worktrees-closeout-2026-09-23 | (removed) | git:dev+worktree-cleanup | done |
| Cursor | worktree-closeout-cleanup-2026-09-23 | feature/worktree-closeout-cleanup-2026-09-23 | .worktrees/worktree-closeout-cleanup-2026-09-23 | git:dev+worktree-cleanup | done |
| Cursor | worktree-closeout-batch-2026-09-23 | feature/worktree-closeout-batch-2026-09-23 | (removed) | git:dev+worktree-cleanup | done |
| Cursor | agentctl-cursor-integration-close-2026-09-23 | feature/agentctl-cursor-integration-close-2026-09-23 | .worktrees/agentctl-cursor-integration-close-2026-09-23 | agentctl-cursor-integration-close | done |
| Cursor | integrate-agentctl-cursor-integration-2026-09-23 | feature/integrate-agentctl-cursor-integration-2026-09-23 | .worktrees/integrate-agentctl-cursor-integration-2026-09-23 | git:dev | done |
| Cursor | agentctl-cursor-integration-2026-09-23 | feature/agentctl-cursor-integration-2026-09-23 | .worktrees/agentctl-cursor-integration-2026-09-23 | agentctl-cursor-integration | done |
| Cursor | agentctl-mgmt-go-live-close-2026-09-23 | feature/agentctl-mgmt-go-live-close-2026-09-23 | .worktrees/agentctl-mgmt-go-live-close-2026-09-23 | agentctl-mgmt-go-live-close | done |
| Cursor | integrate-agentctl-mgmt-go-live-2026-09-23 | feature/integrate-agentctl-mgmt-go-live-2026-09-23 | .worktrees/integrate-agentctl-mgmt-go-live-2026-09-23 | git:dev | done |
| Cursor | agentctl-mgmt-go-live-2026-09-23 | feature/agentctl-mgmt-go-live-2026-09-23 | .worktrees/agentctl-mgmt-go-live-2026-09-23 | agentctl-mgmt-go-live | done |
| Cursor | w3-u6-current-fix-2026-09-23 | feature/w3-u6-current-fix-2026-09-23 | .worktrees/w3-u6-current-fix-2026-09-23 | w3-u6-current-fix | done |
| Cursor | integrate-w3-u6-closeout-2026-09-23 | feature/integrate-w3-u6-closeout-2026-09-23 | .worktrees/integrate-w3-u6-closeout-2026-09-23 | git:dev | done |
| Cursor | integrate-matrix-record-id-2026-09-23 | feature/integrate-matrix-record-id-2026-09-23 | .worktrees/integrate-matrix-record-id-2026-09-23 | git:dev | done |
| Cursor | w3-u6-closeout-2026-09-23 | feature/w3-u6-closeout-2026-09-23 | .worktrees/w3-u6-closeout-2026-09-23 | w3-u6-closeout | done |
| Cursor | matrix-record-id-2026-09-23 | feature/matrix-record-id-2026-09-23 | .worktrees/matrix-record-id-2026-09-23 | matrix-record-id | done |
| Cursor | w2-closeout-2026-09-23 | feature/w2-closeout-2026-09-23 | .worktrees/w2-closeout-2026-09-23 | w2-closeout | done |
| Cursor | current-projection-2026-09-23 | feature/current-projection-2026-09-23 | .worktrees/current-projection-2026-09-23 | current-projection | done |
| Cursor | agentctl-daemon-2026-09-23 | feature/agentctl-daemon-2026-09-23 | .worktrees/agentctl-daemon-2026-09-23 | agentctl-daemon | done |
| Cursor | agentctl-handoff-2026-09-23 | feature/agentctl-handoff-2026-09-23 | .worktrees/agentctl-handoff-2026-09-23 | agentctl-handoff | done |
| Cursor | agentctl-claim-2026-09-23 | feature/agentctl-claim-2026-09-23 | .worktrees/agentctl-claim-2026-09-23 | agentctl-claim | done |
| Cursor | agent-governance-config-2026-09-23 | feature/agent-governance-config-2026-09-23 | .worktrees/agent-governance-config-2026-09-23 | agent-governance-config | done |
| Cursor | coordination-db-daemon-impl-plan-2026-09-23 | feature/coordination-db-daemon-impl-plan-2026-09-23 | .worktrees/coordination-db-daemon-impl-plan-2026-09-23 | coordination-db-daemon-impl-plan | done |
| Cursor | coordination-db-daemon-2026-09-23 | feature/coordination-db-daemon-2026-09-23 | .worktrees/coordination-db-daemon-2026-09-23 | coordination-db-daemon | done |
| Cursor | integrate-pi-runner-response-size-r2-2026-09-23 | feature/integrate-pi-runner-response-size-2026-09-23 | .worktrees/integrate-pi-runner-response-size-2026-09-23 | git:dev | done |
| Cursor | modular-decouple-residual-b-2026-09-23 | feature/modular-decouple-residual-2026-09-23 | .worktrees/modular-decouple-residual-2026-09-23 | modular-decouple-residual | done |
| Cursor | modular-refactor-impl-plan-2026-09-23 | feature/modular-refactor-impl-plan-2026-09-23 | .worktrees/modular-refactor-impl-plan-2026-09-23 | docs-remediation-modular-impl-plan | done |
| Cursor | modular-refactor-review-2026-09-23 | feature/modular-refactor-review-2026-09-23 | .worktrees/modular-refactor-review-2026-09-23 | ops-audit-modular-refactor-review | done |
| Cursor | 2026-09-22-status-reconcile | feature/status-reconcile-2026-09-22 | .worktrees/status-reconcile-2026-09-22 | ops-status-reconcile | done |
| Cursor | 2026-09-22-dev-prod-ready-test-promotion | feature/dev-prod-ready-test-promotion-2026-09-22 | .worktrees/dev-prod-ready-test-promotion-2026-09-22 | dev-runtime-migration+release-gate+test-promotion | done |
| Cursor | integrate-dev-prod-ready-test-promotion-2026-09-22 | feature/integrate-dev-prod-ready-test-promotion-2026-09-22 | .worktrees/integrate-dev-prod-ready-test-promotion-2026-09-22 | git:dev | done |
| Cursor | promote-test-2026-09-22 | feature/promote-test-2026-09-22 | .worktrees/promote-test-2026-09-22 | git:test | done |
| Codex | 2026-09-21-agent-workflow-governance-adoption | feature/agent-workflow-governance-plan | (本机 clone 后不存在) | agent-workflow-governance | done |
| Codex | issue-learning-2026-09-23 | feature/issue-learning-2026-09-23 | .worktrees/issue-learning-2026-09-23 | issue-learning-docs | done |
| Codex | systemic-issue-analysis-2026-09-23 | feature/systemic-issue-analysis-2026-09-23 | .worktrees/systemic-issue-analysis-2026-09-23 | systemic-issue-analysis-docs | done |
| Codex | modular-contract-standard-2026-09-22 | feature/modular-contract-standard-2026-09-22 | .worktrees/modular-contract-standard-2026-09-22 | modular-contract-docs | done |
| Codex | herdr-orchestration-v12 | feature/herdr-orchestration-v12 | .worktrees/herdr-orchestration-v12 | herdr-policy+scripts | done |
| Codex | 2026-09-21-agent-governance-implementation | feature/agent-governance-implementation | .worktrees/agent-governance-implementation | agent-governance | done |
| Cursor | 2026-09-21-force-material-chunk-index | feature/force-material-chunk-index-2026-09-21 | .worktrees/force-material-chunk-index-2026-09-21 | bizdev+materialindex | done |
| Cursor | 2026-09-21-workflow-scope-weighting | feature/workflow-scope-weighting-2026-09-21 | .worktrees/workflow-scope-weighting-2026-09-21 | intent+web+docgov | done |
| Cursor | 2026-09-21-upload-parse-ux-dedup | feature/upload-parse-ux-2026-09-21 | .worktrees/upload-parse-ux-2026-09-21 | server+web+storage | done |
| Cursor | 2026-09-21-mineru-doc-parsing | feature/mineru-doc-parsing-2026-09-21 | .worktrees/mineru-doc-parsing-2026-09-21 | storage+bizdev+kb | done |
| Cursor | 2026-09-21-intent-confirm-stage-aware | fix/intent-confirm-stage-aware-2026-09-21 | .worktrees/intent-confirm-stage-aware-2026-09-21 | intent+web+docgov | done |
| Cursor | 2026-09-21-taskrun-status-card | feature/taskrun-status-card-2026-09-21 | .worktrees/feature-taskrun-status-card-2026-09-21 | chat+web+taskrun | done |
| Codex | 2026-09-21-agent-workflow-governance-plan | feature/agent-workflow-governance-plan | .worktrees/feature-agent-workflow-governance-plan | agent-workflow-governance-plan | done |
| Cursor | 2026-09-21-workflow-doc-key-unification | fix/workflow-doc-key-unification-2026-09-21 | .worktrees/fix-workflow-doc-key-unification-2026-09-21 | docgov+web | done |
| Cursor | 2026-09-21-dev-multiuser-four-issues | fix/dev-multiuser-four-issues-2026-09-21 | .worktrees/fix-dev-multiuser-four-issues | projectinstance+docgov | done |
| Codex | 2026-09-17-initial-load-performance-plan | feature/initial-load-performance-plan | .worktrees/feature-initial-load-performance-plan | loading-performance-audit | done |
| Cline | 2026-09-16-partial-deferred-completion | docs/partial-deferred-completion-plan | - | architecture-docs | in_progress |
| Cursor | dialogue-context-injection-2026-09-25 | feature/dialogue-context-injection-2026-09-25 | (已清理) | dialogue-ctx | done |
| Cursor | dialogue-context-injection-2026-09-25-r2 | feature/dialogue-context-injection-2026-09-25 | .worktrees/dialogue-context-injection-2026-09-25 | dialogue-ctx | done |
## 清理接管与遗留现场
| 路径/事项 | 分类与保留原因 | cleanup_owner | 复查触发 |
|---|---|---|---|
| `.worktrees/dev-prod-ready-test-promotion-2026-09-22` 等本轮三个 worktree | 任务 done;cleanup=pending;证据已入 test-reports / gap-matrix | 独立维护者 | 核对 tip 为 origin/dev 或 origin/test 祖先、无进程后 remove |
| `.worktrees/docrev-ui-rerun-2026-09-22` / `freeform-project-id-bigint` | 已清理 / 目录不存在(2026-09-23 核对) | Cursor | 无 |
| `.worktrees/dev-prod-ready-test-promotion-2026-09-22` 等本轮三个 worktree | 已清理 / 目录不存在(2026-09-23 核对) | Cursor | 无 |
| Cline `2026-09-16-partial-deferred-completion` | 仍 in_progress;W5–W7 未关闭 | Cline owner / 维护者 | 单独授权实施或交接 |
| 保护分支 / FAV 相关 | 保护项;故意不合入、不删 | 原 owner / 维护者 | 用户调整保护边界后 |
| 保护分支 / FAV 相关 | 已合入 local_dev(例外授权 2026-09-23);live 未放量;分支/worktree 已删 | Cursor | 无;见 integrate-fav-final 例外登记 |
| embedding 401(dmxapi) | 非 blocker 运维债;不挡 PI | 运维 | 换钥后重跑 chunk index |
## 集成槽位
| holder | phase | since | scope | queue |
|--------|-------|-------|-------|-------|
| - | idle | 2026-09-22 | 本轮合入与 test 晋升已完成并推送;后续合入须重新认领串行 | - |
| - | idle | 2026-09-21 | force-material-chunk-index 已合入 dev 并从主目录 rebuild;项目 6579 候选 535 已确认;schema=61 | - |
**phase**: `idle` | `merging` | `smoke` | `e2e`
> 合入 `dev` + 共享容器验证必须串行。实际机器锁/进程优先;详见 [操作规范](./2026-09-21-agent-worktree-workflow.md)。
## 受控约束
- 禁止整支 merge FAV;保留既有保护分支;不删 `origin/*`(本轮仅前进 `dev`/`test` 与新增 rc tag)。
- FAV live 仍不放量;`FAV_DEGRADED_READ` 默认 false;不删 `origin/*`(本轮仅前进 local `dev`,不 push)。
- 不默认升 `MULTI_INTENT_PLAN_TIER=full`;`SEED_DEMO_USERS=false` 在 test 保持。
- D7 对话 ADR 仍待合规签字;追踪表类别 `record` 不授权物理删除。
- main 未在本轮晋升。
@@ -0,0 +1,53 @@
=== RUN TestPlanProposal_SecurityRejectsWhole
2026/09/25 12:51:24 INFO intent_recognition intent=SECURITY_FORBIDDEN branch=NEW_INTENT_PREEMPT confidence=1
--- PASS: TestPlanProposal_SecurityRejectsWhole (0.00s)
=== RUN TestIntentRecognition_SecurityForbidden
2026/09/25 12:51:24 INFO intent_recognition intent=SECURITY_FORBIDDEN branch=NEW_INTENT_PREEMPT confidence=1
--- PASS: TestIntentRecognition_SecurityForbidden (0.00s)
=== RUN TestIntentRecognition_SecurityFalsePositives_NotBlocked
=== RUN TestIntentRecognition_SecurityFalsePositives_NotBlocked/合规手册撰写含整改角色字段
2026/09/25 12:51:24 INFO intent_recognition intent=CASUAL_CHAT branch=AMBIGUOUS_FALLBACK confidence=0.2
=== RUN TestIntentRecognition_SecurityFalsePositives_NotBlocked/整改+角色远距共现
2026/09/25 12:51:24 INFO intent_recognition intent=CASUAL_CHAT branch=AMBIGUOUS_FALLBACK confidence=0.2
=== RUN TestIntentRecognition_SecurityFalsePositives_NotBlocked/改一下文档+角色跨句
2026/09/25 12:51:24 INFO intent_recognition intent=CASUAL_CHAT branch=AMBIGUOUS_FALLBACK confidence=0.2
=== RUN TestIntentRecognition_SecurityFalsePositives_NotBlocked/换一份清单+姓名字段
2026/09/25 12:51:24 INFO intent_recognition intent=CASUAL_CHAT branch=AMBIGUOUS_FALLBACK confidence=0.2
=== RUN TestIntentRecognition_SecurityFalsePositives_NotBlocked/系统配置说明文档撰写
2026/09/25 12:51:24 INFO intent_recognition intent=CASUAL_CHAT branch=AMBIGUOUS_FALLBACK confidence=0.2
=== RUN TestIntentRecognition_SecurityFalsePositives_NotBlocked/知识库连接故障排查询问
2026/09/25 12:51:24 INFO intent_recognition intent=CASUAL_CHAT branch=NEW_INTENT_PREEMPT confidence=0.7
--- PASS: TestIntentRecognition_SecurityFalsePositives_NotBlocked (0.00s)
--- PASS: TestIntentRecognition_SecurityFalsePositives_NotBlocked/合规手册撰写含整改角色字段 (0.00s)
--- PASS: TestIntentRecognition_SecurityFalsePositives_NotBlocked/整改+角色远距共现 (0.00s)
--- PASS: TestIntentRecognition_SecurityFalsePositives_NotBlocked/改一下文档+角色跨句 (0.00s)
--- PASS: TestIntentRecognition_SecurityFalsePositives_NotBlocked/换一份清单+姓名字段 (0.00s)
--- PASS: TestIntentRecognition_SecurityFalsePositives_NotBlocked/系统配置说明文档撰写 (0.00s)
--- PASS: TestIntentRecognition_SecurityFalsePositives_NotBlocked/知识库连接故障排查询问 (0.00s)
=== RUN TestIntentRecognition_SecurityForbidden_Extended
=== RUN TestIntentRecognition_SecurityForbidden_Extended/姓名修改
2026/09/25 12:51:24 INFO intent_recognition intent=SECURITY_FORBIDDEN branch=NEW_INTENT_PREEMPT confidence=1
=== RUN TestIntentRecognition_SecurityForbidden_Extended/部门修改
2026/09/25 12:51:24 INFO intent_recognition intent=SECURITY_FORBIDDEN branch=NEW_INTENT_PREEMPT confidence=1
=== RUN TestIntentRecognition_SecurityForbidden_Extended/资质修改
2026/09/25 12:51:24 INFO intent_recognition intent=SECURITY_FORBIDDEN branch=NEW_INTENT_PREEMPT confidence=1
=== RUN TestIntentRecognition_SecurityForbidden_Extended/向量库连接修改
2026/09/25 12:51:24 INFO intent_recognition intent=SECURITY_FORBIDDEN branch=NEW_INTENT_PREEMPT confidence=1
=== RUN TestIntentRecognition_SecurityForbidden_Extended/网关密钥修改
2026/09/25 12:51:24 INFO intent_recognition intent=SECURITY_FORBIDDEN branch=NEW_INTENT_PREEMPT confidence=1
=== RUN TestIntentRecognition_SecurityForbidden_Extended/知识库连接修改
2026/09/25 12:51:24 INFO intent_recognition intent=SECURITY_FORBIDDEN branch=NEW_INTENT_PREEMPT confidence=1
--- PASS: TestIntentRecognition_SecurityForbidden_Extended (0.00s)
--- PASS: TestIntentRecognition_SecurityForbidden_Extended/姓名修改 (0.00s)
--- PASS: TestIntentRecognition_SecurityForbidden_Extended/部门修改 (0.00s)
--- PASS: TestIntentRecognition_SecurityForbidden_Extended/资质修改 (0.00s)
--- PASS: TestIntentRecognition_SecurityForbidden_Extended/向量库连接修改 (0.00s)
--- PASS: TestIntentRecognition_SecurityForbidden_Extended/网关密钥修改 (0.00s)
--- PASS: TestIntentRecognition_SecurityForbidden_Extended/知识库连接修改 (0.00s)
PASS
ok chat-agent-system/internal/intent 0.007s
=== RUN TestCoordinatorEngine_SecurityForbidden
2026/09/25 12:51:24 INFO coordinator_route intent=SECURITY_FORBIDDEN branch="" confidence=0 channel=TEMPLATE reason=查询/治理/补充类意图,走规则模板与知识库直答
--- PASS: TestCoordinatorEngine_SecurityForbidden (0.00s)
PASS
ok chat-agent-system/internal/coordinator 0.004s
@@ -0,0 +1,83 @@
# 安全红线正则误拦 测试报告
## 一、 测试背景 (Background)
用户发送正常文档撰写请求「请撰写详尽合规手册:…每项含理由/证据/失败模式/整改/角色/抽样方法…」时,助手返回固定文案「⚠️ 合规权限拦截…」。根因是 `isSecurityViolation` 正则 2 用裸单字动词「改」加无界 `.*`,把「整改/角色」误配为越权写操作。
规范归档路径应为 `.doc/test-reports/`;本报告因并行任务 `server-image-field-closeout-r3-2026-09-25` 占用该 scope,先落盘于 `.doc/ops/evidence/` 与 agent store,待 scope 释放后再迁移。
## 二、 测试目标 (Test Objectives)
1. 原句与同类误报变体不得返回 `SECURITY_FORBIDDEN`。
2. 既有真阳性用例仍须拦截(confidence=1.0)。
3. 收紧机制不破坏 `internal/intent` / `internal/coordinator` 回归。
## 三、 测试方案与环境 (Test Plan & Environment)
- OS: Linux;Go 1.27.1;worktree `feature/security-redline-false-positive-2026-09-25` @ base `44161d2a`
- 层级:Go/接口(验证契约)
- 范围:`internal/intent`、`internal/coordinator`;全量 `go test -short ./...`(旁路失败单独记)
## 四、 预期结果 (Expected Results)
| 用例 | 预期 |
|---|---|
| 原句合规手册撰写 | 非 SECURITY_FORBIDDEN |
| 整改计划…角色职责 | 非 SECURITY_FORBIDDEN |
| 改一下文档标题…角色 | 非 SECURITY_FORBIDDEN |
| 换一份清单…姓名字段 | 非 SECURITY_FORBIDDEN |
| 起草系统配置说明文档 | 非 SECURITY_FORBIDDEN |
| 知识库连接失败怎么排查 | 非 SECURITY_FORBIDDEN |
| 既有 SecurityForbidden / Extended | 仍 SECURITY_FORBIDDEN |
## 五、 实际测试结果与判定 (Actual Results & Evaluation)
### 5.1 修复前(对照)
命令:`go test ./internal/intent/ -run TestIntentRecognition_SecurityFalsePositives_NotBlocked -count=1`
- **实际输出**:6/6 子用例 FAIL,均 `got SECURITY_FORBIDDEN`
- **判定**:FAIL(预期:用于确认红)
- **耗时**:约 4ms
### 5.2 修复后 — 误报负例
命令:`go test ./internal/intent/ ./internal/coordinator/ -count=1 -v -run 'Security'`
```
--- PASS: TestIntentRecognition_SecurityFalsePositives_NotBlocked (0.00s)
--- PASS: .../合规手册撰写含整改角色字段
--- PASS: .../整改+角色远距共现
--- PASS: .../改一下文档+角色跨句
--- PASS: .../换一份清单+姓名字段
--- PASS: .../系统配置说明文档撰写
--- PASS: .../知识库连接故障排查询问
--- PASS: TestIntentRecognition_SecurityForbidden
--- PASS: TestIntentRecognition_SecurityForbidden_Extended (全部子用例)
--- PASS: TestCoordinatorEngine_SecurityForbidden
ok chat-agent-system/internal/intent
ok chat-agent-system/internal/coordinator
```
- **判定**:PASS
- **耗时**:intent ~7ms;coordinator ~4ms
### 5.3 门禁
| 检查 | 判定 |
|---|---|
| `./scripts/arch-check.sh --mode block` | PASS |
| `go vet ./...` | PASS |
| `go test ./internal/intent/ ./internal/coordinator/ -count=1` | PASS |
| `go test -short ./...` | 旁路 FAIL:`cmd/bizdev-cli` goose duplicate version 71(`00071_...maintenance-windows` 与 `00071_...context-conflict-adjudications`),与本次 intent 改动无关;其余包 ok |
## 六、 自动化测试套件汇总 (Test Suite Execution)
- 适用并实际运行:arch-check、go vet、intent/coordinator 全量、short 全仓(旁路失败已记录)
- 新增用例:`TestIntentRecognition_SecurityFalsePositives_NotBlocked`(6 子例)
- 真阳性零回退
## 七、 测试结论与后续优化建议 (Conclusion & Next Steps)
- **结论**:机制级收紧后,原句与同类变体不再误拦;真阳性仍拦截。授权范围内验收满足。
- **后续**:① scope 释放后将本报告迁入 `.doc/test-reports/2026-09-25-security-redline-false-positive-test-report.md`;② 独立处理 goose 71 重复(非本任务);③ 可选:对「越权」裸字面量做同类负例评估(如「防越权培训」)。
@@ -0,0 +1,28 @@
---
lesson_id: LESSON-20260924-cursor-hook-advisory-gates
lesson_state: candidate
owner: Cursor
reviewer: Cursor(自审;实机采样后转 validated)
last_reviewed: 2026-09-24
reviewed_revision: cursor-governance-hooks-2026-09-24 worktree
source_issues:
- ISSUE-20260924-cursor-hook-event-contract
- ISSUE-20260924-cursor-test-rule-drift
- ISSUE-20260924-cursor-cli-mcp-path
keywords: [Cursor, hooks, advisory, fail-open, probe, stdin, MCP]
---
# 客户端 hook 与执行器门禁分层;契约未知时 fail-open
- 触发条件:为 Cursor 增加 hooks/rules,或发现 hook「写了但不生效/误拦」时。
- 机制与来源:执行器(`pi_subagents.py` / agentctl)已有权威硬拒绝;hook 事件字段官方未完全文档化。heredoc 包装 Python 会吞掉 hook stdin。审计日志若放进被 git 跟踪的 `.cursor/hooks/` 会污染仓库。
- 开发检查:
1. hook 只做形状/授权类 `ask`,不复刻执行器全部校验。
2. 用独立 `.py` + 薄 `.sh` `exec`,禁止 heredoc 占 stdin。
3. 多名容错(`tool_name|mcp_tool_name|name` 等);识别失败 → allow + `UNRECOGNIZED_INPUT` 审计。
4. 审计/probe 写 `.cursor/hook-audit.jsonl` / `hook-probe.jsonl`(被 `.cursor/*` ignore)。
5. 规则副本只做指针,不复制验证契约中的模型名与全量命令。
- 验证方式:`scripts/tests/test_cursor_hooks.py`;实机 `CURSOR_HOOKS_PROBE=1` 采样后升 validated。
- 适用边界:本仓库项目级 hooks;不声称覆盖所有 Cursor 版本或 CLI 加载行为。
- 防护落实:单元回归 enforced;hook↔Cursor 接线仍 advisory/manual。
- 修订与失效:实机字段确认后收紧 matcher 并更新本条状态。
@@ -0,0 +1,20 @@
# LESSON-20260924-deny-only-submit
## 触发条件 / 关键词
非编制、DOC_DUTY、400、run/edit、送审、成员草稿
## 注意事项
1. 权限哨兵必须在 `domainHTTPStatus` 显式映射到 403;默认 400 会让前端 403 文案永不命中。
2. 放宽受控文档写权限时,`classifyAccess`、`AllowedTaskKeys`、`CanEditDocumentContent` 必须同批调整,否则单门放行仍会在下游失败。
3. docgov 不得 import projectinstance:成员身份由 server 校验后经 `ActorIsMember` 传入;禁止用 `RoleSystem` 冒充人工成员。
4. 审批路径走 `CheckDocTaskAccess(submit|review|approve)`,不要复用 `TaskKeyAllowed`。
## lesson_state
validated(2026-09-24 真实 PI)
## 主记录
[ISSUE-20260924-non-author-400-duty](../../audit/2026-09-24-non-author-member-access.md)
@@ -0,0 +1,26 @@
---
lesson_id: LESSON-20260924-pi-tool-boundaries
lesson_state: validated
owner: Cursor/Codex
reviewer: Codex
last_reviewed: 2026-09-24
reviewed_revision: 69ffaa677e23a1dd9aa0528bb09b3acfcd38b119
source_issues: [ISSUE-20260924-pi-executor-boundaries]
keywords: [PI, MCP, readonly, path, snapshot, process-group]
---
# 文件工具的路径检查须匹配实际客户端语义
触发:为第三方 Agent 包装只读文件工具、复制输入快照或监督子进程。
机制:PI 0.85.1 工具会展开 @/~,初版守卫只做 path.resolve,检查对象与实际打开对象不同;另有 exact-root 空相对路径误拒、内部扩展复制进模型快照导致合法枚举被白名单拒绝。见[问题](../../audit/2026-09-24-pi-executor-boundaries.md)与[验证](../../test-reports/2026-09-24-pi-executor-test-report.md)。
实施前检查:
1. 读实际工具的路径规范化实现;拒绝不支持的前缀/参数,核对 canonical realpath、符号链接与选定文件。不能仅假设安全的相对拼接等于最终访问路径。
2. 模型输入、测试可写副本、客户端内部配置/扩展分开;允许清单只包含模型该读的材料。内部文件不要塞进源码快照。
3. 同时验证拒绝路径和合法根目录/子目录、默认 path;只有负例通过不足以证明工具可用。
4. MCP 直接协议实测和真实客户端派发都要做。官方文档支持变量不证明本机 CLI 已展开;真实路径错误用版本/命令留证。
5. 进程完成与验收通过分开,leader 退出不证明整个进程组退出。保留报告和失败证据,再按实际运行身份回收。
范围:本次 gmktec/Linux、PI 0.85.1、Cursor CLI 的工程工具;客户端升级和其它系统需复核。这里的工具/进程守卫不是 OS 沙箱。
@@ -0,0 +1,56 @@
---
lesson_id: LESSON-20260926-failclosed-bypass-contract
lesson_state: validated
created: 2026-09-26
updated: 2026-09-26
source_issues:
- ISSUE-20260926-ctx-idor
- ISSUE-20260926-archcheck-untracked
- ISSUE-20260926-authz-failopen
- ISSUE-20260926-swboot-shell-prefix
- ISSUE-20260926-intentflow-validated-confirm
reviewed_by: pi
last_reviewed: 2026-09-26
reviewed_revision: "fix/system-review-p0-p1-fixes-2026-09-26"
keywords: [IDOR, 旁路, fail-open, fail-closed, 白名单前缀, sh -c, validated_only, table_owners, untracked, session_id, 归属校验]
---
# 旁路入口与「未知即拒绝」契约
## 触发条件
- 新增/评审任何**绕过主用例路径**的 HTTP handler(尤其按 `session_id`/`project_id`/`user_id` 直接取资源的旁路端点)。
- 写门禁扫描器、授权器或执行器时出现「未登记/未配置/依赖缺失」分支。
- 注释或文档声称某 flag/mode 是安全边界(如 `validated_only must never be written as succeeded`)。
- 命令/路径白名单实现(前缀匹配、`sh -c` 拼接)。
## 机制与应做检查
1. **主路径绿 ≠ 旁路绿**:主路径(chatflow/Owner 等)的鉴权不会自动覆盖旁路 handler。每个按标识取资源的入口都要复用同一归属校验(如 `GetSessionOwnerID`),并在 SQL/存储层再加归属条件作防御纵深——handler 层校验可能被未来调用方遗漏。
2. **门禁对「未知」必须拒绝**:扫描器遇到未登记对象 `continue` 等于该维度门禁关闭(arch-check 未登记表曾静默跳过 ~50 张表的真实写)。正确形状:未登记→finding,假阳性用显式且可审计的豁免清单。
3. **授权器缺依赖时不得放行**:`pool==nil` 返回 true 是 fail-open;需要演示/测试宽松语义时,用**显式命名的构造器**(`NewInMemoryAuthorizer`)+ 组合根按配置选择,默认路径严格拒绝。
4. **契约写在注释里不算数**:`validated_only` 之类执行模式必须由执行器硬读硬拒(Confirm 拒 + ExecuteClaimed 拒双层),安全不能依赖「没人点 Confirm」或上游状态机不犯错。
5. **白名单用精确匹配 + argv 执行**:basename 前缀匹配可被 `go-evil` 伪装;`sh -c` 让元字符求值。argv 化后元字符只是字面参数。
## 错误做法与原因
- 只给主路径补鉴权、把旁路留给「下次」——本仓 IDOR 事故高发位正是旁路 HTTP。
- 用「未配置就放行」降低接线摩擦——组合根永远能构造成功,fail-open 在误配时静默生效。
- 用测试 override `NewAuthorizer(nil)` 当「跳过检查」接缝——它同时是生产 fail-open 的机制本身;接缝必须显式命名。
## 验证方法
- 回归覆盖:原例(他户标识→403/空)、同类变体(不存在→同构拒绝、admin 越权面)、正常行为(本人→200 且数据完整)。
- 门禁类:自测夹具证明未登记对象 block、已知假阳性不误报;全仓门禁在登记完成后 PASS。
- 执行类:伪装命令拒绝、元字符不求值(marker 文件不产生)、owner 零调用计数。
## 适用边界
- 适用于进程内授权、静态扫描门禁、命令白名单、执行模式契约四类机制;不覆盖网络层/跨服务鉴权。
- 豁免清单(如扫描噪音词)是启发式产物:新假阳性出现时应先确认确非真实表,再扩清单。
## 关联
- 来源修复:[2026-09-26 系统 code review P0/P1 修复](../../remediation/2026-09-26-system-code-review-fixes.md)
- 发现审计:[2026-09-26 系统全面 code review](../../audit/2026-09-26-system-code-review.md)
- 关联回归:`TestGetUserContext_*`、`TestUntrackedTableWriteIsBlocked`、`TestMembershipChecks_FailClosedWithoutPool`、`TestExecutor_CommandAllowlistIsExactNotPrefix`、`TestExecutor_NoShellEvaluation`、`TestConfirmRejectedForValidatedOnlyPlan`、`TestExecuteClaimedRefusesValidatedOnlyStep`
@@ -0,0 +1,27 @@
---
title: "LESSON-20260927: 服务端事实源优先与隔离测试库配方"
created: 2026-09-27
owner: pi
source_issue: ISSUE-20260927-upload-doc-cross-device
status: verified-on-dev
---
# 服务端事实源优先与隔离测试库配方
## 教训一:客户端本地兜底不能替代服务端事实源
上传链路曾把文件二进制放在浏览器内存 + IndexedDB、元数据放在 localStorage,服务端只存注册占位模板。换浏览器/清存储/共享他人查看时全部失效,用户看到的是"文档概述与背景"占位文案而非文档内容。同一缺陷家族还包括把展示用字符串("0 KB")烘焙进持久化正文。
**规则**:任何需要跨会话/跨端/跨用户存活的事实(文件、元数据、正文),必须在服务端持久化;本地存储只允许作为加速缓存。持久化的内容不得包含客户端生成的展示态字符串(格式化大小、本地时间文案),恢复时从事实源重建。
## 教训二:worktree 里跑测试必须显式钉住 DB 目标
`config.Load(".env")` 缺文件时静默回退到默认 DSN = 真实 dev 库(127.0.0.1:5433,含默认口令)。在任务 worktree 跑 `go test ./...` 会真实写入 dev 业务库,甚至经 `bizdev.NewService` 自动应用迁移链。本次误连两次(写入合成测试行 + 提前把 dev 迁到 76),虽未损坏历史数据,但属计划外副作用。
**规则**:worktree/CI 中凡触发 DB 的测试,一律显式 `export TEST_DATABASE_URL=<隔离库> CONTEXT_DB_HOST/PORT/USER/PASSWORD/NAME=<隔离库>`;用一次性容器(`docker run --rm pgvector/pgvector:pg16 -p 127.0.0.1:<随机端口>`)承载。端口字符串避开 "5433/5434/5435" 子串(`RefuseSharedEnvDSN` 按子串拒绝,55433 会被误拒)。
## 教训三:隔离库正确配方与顺序
- 顺序必须是:**扩展(vector/uuid-ossp)→ goose 迁移链 → system_init/docgov_init/context_init**。顺序颠倒时 `00001_baseline.sql` 会因 `chat_messages.day_key` 不存在而失败(init 脚本相互不独立)。
- 即使配方正确,`TestPG_ActivationAndStageAdvance`、`TestWorkflowGovernance_PG_*`、`TestCreateDocument_PG_ClientKeyIdempotent...` 等重组件用例在自建隔离库上仍可能失败("approved requires frozen review_snapshot_id" 等顺序/外部服务依赖)——**先在基线 dev HEAD 上复现再定性**,勿把环境敏感当回归。
- 判定回归的最小对照法:同一隔离库配方 × {基线代码, 候选代码} × {单用例, 全包} 四格对照,均复现即预存在。
@@ -0,0 +1,20 @@
---
lesson_id: LESSON-20260928-activation-preview-client-gate
lesson_state: validated
owner: Cursor
reviewer: Cursor
last_reviewed: 2026-09-28
reviewed_revision: 3e534bbb39d0d957e0b720a4ca06f22dd15959e6
source_issues: [ISSUE-20260928-activation-preview-precheck]
keywords: [activation-preview, NO_GOVERNED_DOCUMENT, clientDutyIssues, needsGovernedDocument, 400]
---
# 激活门禁要在点击前做同样的前端预检
- 触发条件:控制台出现 `POST .../activation-preview 400`,响应码是 `NO_GOVERNED_DOCUMENT`。
- 机制与来源:服务端 `validateActivationPlan` 要求至少一份完整人工审批。前端 `clientDutyIssues` 只查三权完整性,全部未纳入审批时仍会发请求。见 ISSUE-20260928-activation-preview-precheck。
- 开发检查:新增激活条件时,同时改 `validateActivationPlan` 与 `needsGovernedDocument` / `clientDutyIssues`。运行中 `live_edit` 走 `validatePlan`,不要套激活门禁。
- 验证方式:默认计划直接预览不得发出 activation-preview;一份兼任文档预览应 200。单测在 `web/src/lib/projectSettingsDuties.test.ts`。
- 适用边界:只覆盖激活前规划。已激活实例改职责不要求「至少一份」。
- 防护落实:上述单测与 dev 浏览器复验已落地。
- 修订与失效:若产品允许零审批激活,应同时删除服务端 `NO_GOVERNED_DOCUMENT` 与前端预检。
@@ -0,0 +1,20 @@
---
lesson_id: LESSON-20260928-docgov-shared-map-race
lesson_state: candidate
owner: Cursor
reviewer: Cursor(自审)
last_reviewed: 2026-09-28
reviewed_revision: a90cce73
source_issues: [ISSUE-20260928-docgov-map-race]
keywords: [docgov, memDocs, memMu, per-doc lock, concurrent map, 登录 500]
---
# 拆细粒度锁后,共享 map 仍要单独互斥
- 触发条件:把全局锁拆成 per-id 锁,但多个 id 仍读写同一张 Go map(缓存、审计、批注、提案)。
- 机制与来源:docgov 的 per-doc 锁不保护 `memDocs` 等 map。不同文档并发时 `GetDocument` 与写入撞上,运行时 fatal,进程退出后所有 HTTP API(含登录)500。证据:2026-09-28 `.tmp/launch/server.log` 与 `web.log` 的 `ECONNREFUSED`。修复见 [任务](../short-term/2026-09-28-docgov-shared-map-race.md)。
- 开发检查:map 的读写、遍历、append 都走同一把锁。已持有外层锁的路径不能再锁同一把(Go 互斥锁不可重入)。锁序固定,禁止在 map 锁内再拿文档锁或外层锁。不要用「登录 500」去改登录代码。
- 验证方式:不同 docID 并发创建与读取,`go test -race` 覆盖 `TestMemMapsNoRaceAcrossDocs`。进程崩溃类问题还要看服务日志里的 fatal,而不是只看单个 API 状态码。
- 适用边界:适用于 docgov 这四张内存 map。文档结构体字段的数据竞争、以及持久化失败后的缓存投毒(`ISSUE-20260926-docgov-memdocs-poison`)不在本条范围内。
- 防护落实:`memMu` 与 `TestMemMapsNoRaceAcrossDocs`。没有新增静态检查,漏一个裸访问仍要靠 `-race` 和复查。
- 修订与失效:若这四张 map 改为分片或移除,本条对那个存储失效,保留历史。
@@ -0,0 +1,20 @@
---
lesson_id: LESSON-20260928-quality-heading-normalize
lesson_state: candidate
owner: Cursor
reviewer: Cursor(自审,待 dev 重跑调研报告后升 validated)
last_reviewed: 2026-09-28
reviewed_revision: 434d542c3cbdbeac38b9c0e547edf75160acf577
source_issues: [ISSUE-20260928-quality-heading-drift]
keywords: [quality_gate, 缺少必填章节, State-of-the-Art, H3, AutoRepair]
---
# 章节门禁比对标题,不比对空格和层级
- 触发条件:交付正文章节都在,质量报告仍写「缺少必填章节」,评分往往停在 85。
- 机制与来源:模板 H2 与模型常写的 H3、多一个或少一个空格、全角字母,在精确字符串比较下会被当成整章缺失。缺章会短路受控投影。见 ISSUE-20260928-quality-heading-drift。
- 开发检查:标题比对先去空白、折全角、忽略大小写,并允许 H2–H4。只在归一化后确实没有该标题时判缺失。层级不一致记软警告,不扣分。不要把「待确认」或材料不足算进这道门禁。
- 验证方式:`TestQualityGate_Validate_HeadingLevelAndSpaceDrift` 同时覆盖漂移通过和真实缺章失败。聊天触发须带 `AutoRepair`。
- 适用边界:只覆盖 ATX 标题存在性。近义改名、章节被写进代码块、内容空洞仍不在本条范围内。
- 防护落实:`internal/squad/quality_gate.go` 与 `quality_gate_test.go`。
- 修订与失效:若产品要求章节层级必须与模板一致才可交付,应把软警告改回硬失败,并同步改回归用例。
@@ -0,0 +1,20 @@
---
lesson_id: LESSON-20260928-squad-commit-as-author
lesson_state: candidate
owner: Cursor
reviewer: Cursor(自审,待 dev 重跑后升 validated)
last_reviewed: 2026-09-28
reviewed_revision: 774df0599813fb8d7115f95ce255384542d6a0f9
source_issues: [ISSUE-20260928-squad-commit-authority]
keywords: [bizdev, docflow, dutyAuthorizer, AutoCommitUserID, OnBehalfOf, uow permission denied, 非编制人]
---
# 小队账本自动提交要用编制人身份
- 触发条件:受控文档小队任务成功生成正文,但落盘报 `uow: permission denied` 或「版本账本/变更报告落盘失败」。
- 机制与来源:`dutyAuthorizer` 对 `ActionCommit` 要求 principal 等于 `document_records.author_id`。触发者常常是其他项目成员。见 ISSUE-20260928-squad-commit-authority。
- 开发检查:自动提交的 `AutoCommitUserID` 用文档编制人;实际触发用户写入 `OnBehalfOf`。不要为了小队路径放宽编制人校验。触发者或编制人为 0 时不要伪造代理身份。权限失败文案要写明「非编制人」,同时保留 `uow.ErrPermissionDenied` 哨兵。
- 验证方式:非编制人触发应成功且 `OnBehalfOf` 为触发者;编制人触发不设置 `OnBehalfOf`;非编制人直接 `ActionCommit` 仍拒绝。关联 `internal/bizdev/squad_commit_actor_test.go` 与 `TestDutyAuthorizerAllowsDocumentAuthorCommit`。dev 原例重跑完成前本条保持 candidate。
- 适用边界:只覆盖小队/agent 自动提交。人工编辑、批准、驳回仍按各自职责人校验。高风险候选仍要编制人确认。
- 防护落实:上述单测已落地。原例验收是 manual(dev 非编制人重跑)。
- 修订与失效:若产品改为「非编制人不得触发生成」,本条应退役并改回触发者身份。
@@ -0,0 +1,20 @@
---
lesson_id: LESSON-20260928-standard-role-reseed
lesson_state: validated
owner: Cursor
reviewer: Cursor(自审)
last_reviewed: 2026-09-28
reviewed_revision: 4ba60c2c9d7eaf3e3e824475c0f3a44e10641190
source_issues: [ISSUE-20260928-register-internal]
keywords: [auth, register, role-guest, system_roles, is_system, 23503, 23505, INTERNAL]
---
# 代码硬编码的标准角色必须可自愈且不可删
- 触发条件:注册、管理员建号或种子用户写入固定 `role_id`,而该角色只在历史 goose 种子里出现一次。
- 机制与来源:`Register` 固定写 `role-guest`。00015 仅 `role-admin` 为 `is_system`。角色一旦被删,goose 不重跑、`BootstrapIAM` 只补用户,`user_role_bindings` 外键失败被脱敏成 INTERNAL。证据日期 2026-09-28,见 [任务](../short-term/2026-09-28-auth-register-internal.md)。
- 开发检查:硬编码角色 id 须在迁移里 `ON CONFLICT DO UPDATE` 补种,并标 `is_system`。用户名一类唯一冲突返回领域错误,不要包进 `insert user:` 这类会被当成 500 的前缀。
- 验证方式:缺角色的库补种后注册返回 200;重复用户名返回 400 且 `error` 为「用户名已存在」。
- 适用边界:适用于 IAM 标准角色。业务自定义角色仍允许删除(无人引用时)。
- 防护落实:migration 00077 + `DeleteRole` 既有系统角色拒绝。未新增 lint。
- 修订与失效:若注册不再绑定 `role-guest`,本条对那个写入点失效,保留历史。
@@ -0,0 +1,20 @@
---
lesson_id: LESSON-20260928-task-write-verb-visible-refusal
lesson_state: candidate
owner: Cursor
reviewer: Cursor(自审,待含本提交的运行制品复验原句)
last_reviewed: 2026-09-28
reviewed_revision: db859e185ebcd0e7eccd2241ca07f0e9f4fe4c6b
source_issues: [ISSUE-20260928-task-write-verb, ISSUE-20260928-workflow-scope-reply, ISSUE-20260928-quality-failed-success-copy]
keywords: [intent, hasTaskWriteVerb, 帮我定, ClarificationQuestion, ErrPrerequisiteNotMet, quality_failed]
---
# 任务写动词要覆盖「定」,拒绝原因要进对话
- 触发条件:用户说「帮我定/制定/拟定」某交付物,对话却进入「再掂量一下」;或任务被工作流范围、研发前置、质量门禁挡住,气泡仍像成功或只有协调失败。
- 机制与来源:强写动词表原先只有生成/做/跑/出/编写/编制/起草。「定」单独出现会误伤「决定」,所以只认「制定」「拟定」以及「帮我/请/给我/帮忙」后面的「定/拟」。跨流澄清和前置失败必须成为用户可见回复,不能再被阶段模板或错误事件盖掉。质量未通过不要写宿主机路径。见 ISSUE-20260928-task-write-verb。
- 开发检查:新增交付动词时补强动词或祈使短语,并加一条反例(决定、看看)。`RequiresClarifying` 的问题原文要到达会话。`ErrPrerequisiteNotMet` 的中文原因用拒绝态返回,错误值为空,避免会话层丢掉 `NaturalReply`。
- 验证方式:`go test ./internal/intent/ ./internal/coordinator/` 中写动词、跨流澄清、前置可见、质量失败文案四类用例。原句在运行制品上的复验完成前,本条保持 candidate。
- 适用边界:只覆盖中文任务触发与同步回复。材料嵌入分块超限、PI runner 数据目录错配是相邻但独立的问题。
- 防护落实:`doc_workflow_scope_test.go` 与 `pending_confirmation_reply_test.go`。
- 修订与失效:若产品明确「定」永不表示编写,应删祈使短语并退役本条。
@@ -0,0 +1,20 @@
---
lesson_id: LESSON-20260928-ui-dead-control
lesson_state: validated
owner: Cursor
reviewer: Cursor(自审)
last_reviewed: 2026-09-28
reviewed_revision: 912957c44ec1bd91f6010d657a909e5120546f74
source_issues: [ISSUE-20260928-admin-reset-ui-removed]
keywords: [web, UsersSection, 重置密码, 死按钮, merge-base, F4-A]
---
# 删「未开通」控件前先核对当前基线是否已有端点
- 触发条件:准备移除会失败的按钮、菜单或客户端调用,理由是「端点未开通 / 待产品选型」。
- 机制与来源:T20-F4-B 已在 `39f8c1d1` 开通重置密码;随后 `d653e32e`(F4-A)仍按旧设计删掉入口。`725181de` 已包含 F4-B。证据日期 2026-09-28,见 [任务](../short-term/2026-09-28-restore-admin-password-reset.md)。
- 开发检查:对声称缺失的路由做 `git merge-base --is-ancestor <实现提交> <本任务基线>`,并在当前树 grep 路由注册。祖先关系成立时不得删除对应 UI。注释不能代替这条核对。
- 验证方式:恢复后的按钮须打到真实端点(本任务 dev UI 探针:随机口令长度 16、首次登录强制改密、二次登录不再弹出、旧口令 401)。仅存在单测不算 UI 已接上。
- 适用边界:适用于「控件调用已实现 API」。端点确实不存在、或产品明确下线该能力时,删除控件仍然正确。
- 防护落实:manual。未新增 lint。后续同类删除在任务记录里写下 merge-base 结果。
- 修订与失效:若重置密码产品下线并删除路由,本条对那个控件不再适用,保留历史。
+12
View File
@@ -4,8 +4,20 @@
| lesson_id | 触发条件 / 关键词 | 注意事项 | lesson_state | 主记录 / 最近复核 |
|---|---|---|---|---|
| LESSON-20260928-docgov-shared-map-race | docgov、memDocs、per-doc 锁、concurrent map、登录 500 | 拆锁后共享 map 仍要单独互斥;锁不可重入;全站 500 先看进程是否退出 | candidate | [共享 map 互斥](2026-09-28-docgov-shared-map-race.md);2026-09-28 |
| LESSON-20260928-quality-heading-normalize | 缺少必填章节、State-of-the-Art、H3、质量门禁、AutoRepair | 标题比对去空白并跨 H2–H4;层级漂移不扣分;真实缺章仍失败 | candidate | [章节标题归一化](2026-09-28-quality-heading-normalize.md);2026-09-28 |
| LESSON-20260928-task-write-verb-visible-refusal | 帮我定、制定、ClarificationQuestion、前置条件、quality_failed | 写动词覆盖制定与帮我定;拒绝和澄清进对话;质量失败不写宿主机路径 | candidate | [写动词与可见拒绝](2026-09-28-task-write-verb-visible-refusal.md);2026-09-28 |
| LESSON-20260928-activation-preview-client-gate | activation-preview、NO_GOVERNED_DOCUMENT、clientDutyIssues、400 | 服务端激活门禁要有同等前端预检;live_edit 不套激活门禁 | validated | [激活预检对齐](2026-09-28-activation-preview-client-gate.md);2026-09-28 |
| LESSON-20260928-squad-commit-as-author | 小队落盘、uow permission denied、AutoCommitUserID、OnBehalfOf、非编制人 | 自动提交身份用文档编制人,触发者只写入 OnBehalfOf;不要放宽 ActionCommit | candidate | [编制人代理提交](2026-09-28-squad-commit-as-author.md);2026-09-28 |
| LESSON-20260928-standard-role-reseed | 注册、role-guest、system_roles、is_system、23503、23505、INTERNAL | 硬编码标准角色须幂等补种并标 is_system;用户名冲突返回领域 400,不要包进 insert user | validated | [标准角色可自愈](2026-09-28-standard-role-reseed.md);2026-09-28 |
| LESSON-20260928-ui-dead-control | 死按钮、端点未开通、UsersSection、重置密码、merge-base | 删除「未开通」控件前用当前基线核对路由已存在;注释不能代替 merge-base | validated | [删控件前核对端点](2026-09-28-ui-dead-control.md);2026-09-28 |
| LESSON-20260927-server-facts-and-iso-db-recipe | 上传持久化、fileMeta、占位模板、config.Load 默认 DSN、TEST_DATABASE_URL、隔离库、RefuseSharedEnvDSN、goose 顺序 | 服务端事实源优先(本地仅缓存);worktree 测试必须显式钉隔离库并避开 5433/5434/5435 子串端口;隔离库配方=扩展→goose→init SQL,重组件用例先做基线四格对照 | validated | [服务端事实源与隔离库配方](2026-09-27-server-facts-and-iso-db-recipe.md) |
| LESSON-20260923-nullable-duty | docgov、SQL、nullable、23503、可选职责、创建/heal | 检查所有写入口的缺席值语义;用真实 PG 验证 NULL/FK | validated | [可选职责持久化](2026-09-23-nullable-duty.md);2026-09-23 |
| LESSON-20260923-content-hash | docrevision、canonicalize、hash、bootstrap、hard-break、404、水合 | 保持文本语义并检查账本/文件一致性;新数据通过不能覆盖旧数据迁移 | validated | [正文规范化与投影](2026-09-23-content-hash.md);2026-09-23 |
| LESSON-20260923-matrix-status-cas | FEATURE-MATRIX、docs-apply、record_id、merge conflict、CAS | 矩阵/CURRENT 行变更走 docs apply;合并后核验状态列未被回退 | validated | [矩阵状态 CAS](2026-09-23-matrix-status-cas.md);2026-09-23 |
| LESSON-20260924-pi-tool-boundaries | PI、MCP、readonly、path、snapshot、process-group | 路径语义与快照边界一致,合法路径和拒绝路径都验收 | validated | [文件工具边界](2026-09-24-pi-tool-boundaries.md);2026-09-24 |
| LESSON-20260924-cursor-hook-advisory-gates | Cursor、hooks、advisory、fail-open、probe、stdin | hook 与执行器分层;契约未知 fail-open;审计日志放 ignore 路径 | candidate | [客户端 hook 门禁](2026-09-24-cursor-hook-advisory-gates.md);2026-09-24 |
| LESSON-20260924-deny-only-submit | 非编制、DOC_DUTY、400、run/edit、送审 | 权限哨兵映射 403;三道门协同放宽;ActorIsMember 不复用 RoleSystem | validated | [deny_only_submit](2026-09-24-deny-only-submit.md);2026-09-24 |
| LESSON-20260926-failclosed-bypass-contract | IDOR、旁路、fail-open、白名单前缀、sh -c、validated_only、untracked、table_owners | 旁路入口必须继承主路径硬边界+SQL 防御纵深;门禁/授权器/执行器对未知默认拒绝;安全契约由执行器硬拒不依赖注释 | validated | [旁路与未知即拒绝契约](2026-09-26-failclosed-bypass-contract.md);2026-09-26 |
validated 的证据范围见各条目;本日复核为历史材料和源码阅读,未重跑产品回归。后续按机制补充,过时条目标 superseded/retired 并保留替代链接。
@@ -0,0 +1,37 @@
# admin-password-reset-2026-09-24
| 字段 | 值 |
|---|---|
| status | done |
| write_scope | internal, web, deploy/postgres/goose, .doc |
| mutex | auth+env:test |
| base_dev_sha | 3de5bc5c396fc21887f0f19e6e3baa8784347f99 |
| review_state | accepted |
| integration_state | queued_local_dev (waiting env:dev/git:dev lock from nightly) |
| deployment | not_required(合入 local_dev;晋升 test 另授权) |
| cleanup | pending |
| remote_sync | not_requested |
| policy_revision | AGENTS.md + worktree workflow 2026-09-21 |
## 用户目标
恢复 test 环境 `chenwei` 登录;实现 T20-F4-B 管理员重置密码 API;修无凭据僵尸账号防护;修正登录错误文案误导。
## 范围
- Phase 0:test 库一次性恢复(已完成;临时口令仅 agent store)
- Phase 1–3:后端 API + goose 00067 + 前端接线 + CreateUser fail-closed
- Phase 4:单测/回归 + 报告 + ISSUES + 合入 local_dev
## 禁止
- 未授权 `git push` / 晋升 test/main
- 临时口令写入 git / 聊天 / 报告正文
- 写入 main/dev 生产僵尸账号数据清理
## 验证计划
- `./scripts/arch-check.sh --mode block`;`go vet ./...`;`go test -short ./...`
- `web npm test` / `npm run build`
- 新增 AdminResetPassword 正负例与 authErrorMessage 单测
- Phase 0 实测 login 200(证据不披露口令)
@@ -0,0 +1,97 @@
# agentctl coordinator daemon 装载记录(Linux/systemd)
- task_id: agentctl-daemon-load-2026-09-24
- owner: Cursor
- 授权来源:用户会话确认(2026-09-24 09:37,"装载 systemd 单元"选项明示批准)
- base_dev_sha: 5423b261f97f371bdf7fa5066e9305f9eddaef42
- status: done(验证完成;文档合入待集成)
- write_scope: .doc/ops/short-term/(本文档)、.doc/ops/CURRENT.md(docs apply 认领行)
- mutex: agentctl-daemon-load
- review_state: reviewed(自查,见下)
- integration_state: pending
- deployment: n/a(daemon 已在本机装载运行,即本文档记录的对象)
- cleanup: pending
- remote_sync: no(未 push)
## 一、背景
用户报告"本机的 agentctl 似乎没有在运作"。检查结论:
- CLI 管理面(`daemon status` / `doctor` / `queue list`)与 Git 门禁(pre-commit 钩子、`PROTECTED_BRANCH` 拒绝)均正常。
- **coordinator daemon 从未装载**:`.locks/os/daemon.heartbeat` 与 `manager.lock` 不存在;`scripts/daemon/README.md` 标注 "Templates only. Not loaded on this machine"。本机为 Linux/systemd(规范模板中 launchd 适用于 macOS),systemd 模板从未实例化。
- 附带发现两条死进程残留 run 卡住 `env:dev`(详见下节)。
## 二、操作记录
### 1. 残留 run 恢复(前置清理)
两条 run 属任务 `dev-full-gate-test-promo-2026-09-24`,进程经 `ps` 确认死亡、无运行副作用:
```bash
python3 scripts/agentctl.py recover --run e072b136-c538-4d66-9100-f4966e02e8ec \
--reason 'verified: pid 1993666/1993739 dead (ps confirmed, exit 143 SIGTERM); /proc absent; env:dev idle, no side effects; release stale lease from night supervisor kill'
# → {"run_id": "e072b136-...", "status": "recovered"}
python3 scripts/agentctl.py recover --run d542d9d9-513e-4301-b303-8bf3c62bc681 \
--reason 'verified: pid 1992327 dead (ps confirmed); busy placeholder from lock-wait timeout, no command executed; release stale env:dev slot'
# → {"run_id": "d542d9d9-...", "status": "recovered"}
```
恢复后 `doctor` 显示该任务新 run 正常 `running`(supervisor_alive=alive),租约链路恢复。
### 2. daemon 装载(本次主操作)
依据 `scripts/daemon/README.md` 的 fail-closed 装载门禁(显式授权 + 验证记录 + 回滚命令),按用户明示授权执行:
```bash
# 实例化模板(替换 /path/to/Agent-System 占位符)
sed -e "s|/path/to/Agent-System|/home/weichen/projects/Agent-System|g" \
scripts/daemon/agentctl-coordinator.service \
> ~/.config/systemd/user/agentctl-coordinator.service
systemctl --user daemon-reload
systemctl --user enable --now agentctl-coordinator.service
```
## 三、装载验证(fail-closed 证据)
| 项 | 值 |
|---|---|
| host | weichen(Linux 7.0.0-31-generic,systemd user session) |
| unit | `~/.config/systemd/user/agentctl-coordinator.service`(enabled, preset: enabled) |
| unit sha256 | `3ec73b4830a4f18c1b755ca750e146720362737fba445b39a8313be0131856a7` |
| ActiveState/SubState | `active (running)` since 2026-09-24 01:34:59 UTC |
| MainPID | 2120143 |
| manager.lock | held=true, holder_pid=2120143 |
| heartbeat | cycle 226(启动约 4.5 分钟),heartbeat_age_seconds≈0.5,持续 <2s |
| queue | pending=0, claimed=0(无积压;daemon 轮转正常,每秒 1 周期 processed:0) |
| 主目录分支 | dev(满足单元 WorkingDirectory 约束) |
journal 摘录(截选):
```text
Sep 24 01:34:59 systemd[3852]: Started agentctl-coordinator.service - agentctl foreground coordinator (queue schedule under manager.lock).
Sep 24 01:34:59 python3[2120143]: {"audit_every": 30, "interval": 1.0, "max_cycles": null, "pid": 2120143, "status": "daemon_started"}
Sep 24 01:34:59 python3[2120143]: {"processed": 0, "results": [], "status": "ok"}
Sep 24 01:39:07 python3[2120143]: {"processed": 0, "results": [], "status": "ok"}
```
## 四、回滚(经确认后执行)
```bash
systemctl --user disable --now agentctl-coordinator.service
rm ~/.config/systemd/user/agentctl-coordinator.service
systemctl --user daemon-reload
```
## 五、影响评估
- daemon 职责仅为驱动 `queue schedule`(已验证候选的 ff-only 集成调度);不触碰 `env:*`、不授予新能力(README 明示)。
- 队列当前为空,装载不改变现有 `validate`+`integrate` 流程行为。
- 未修改仓库内文件(单元文件在 `~/.config/systemd/user/`,仓库 tracked 文件零变更)。
## 六、后续
- daemon 已 `Restart=on-failure`,崩溃后 5s 自动拉起;无需人工干预。
- 如需停用,见回滚一节(需重新确认)。
- 本任务剩余收口:集成(integrate)到 local dev、CURRENT 行置 done、worktree 清理。
@@ -0,0 +1,87 @@
---
title: "Cursor 治理层扩展(rules / skills / hooks)"
task_id: cursor-governance-hooks-2026-09-24
status: done
created: 2026-09-24
updated: 2026-09-24
owner: Cursor
task_type: implementation
task_tier: multi_stage
policy_revision: "agent-governance-2026-09-21-r1 + issue-learning-2026-09-23-r1 + codegraph-governance-2026-09-24-r1 + subagent-workflow-2026-09-24-r2(proposed); base_dev@cfc80b34a40e8de78e77a44839571bb684d405d5"
branch: feature/cursor-governance-hooks-2026-09-24
worktree: .worktrees/cursor-governance-hooks-2026-09-24
base_dev_sha: cfc80b34a40e8de78e77a44839571bb684d405d5
write_scope: [".cursor", "scripts/tests", ".doc"]
allowed_environments: []
mutex: cursor-governance
review_state: accepted
integration_state: merged_local_dev
deployment: not_required
cleanup: pending
cleanup_owner: "owner 退出后的独立维护者"
cleanup_trigger: "合入 local_dev、证据归档且 owner 退出后复查"
remote_sync: not_requested
---
# Cursor 治理层扩展(rules / skills / hooks)
## 用户目标与授权
- 用户目标:在已合入的 PI subagent 执行器基础上,为本项目 Cursor 补齐 skills、rules、hooks 等治理层。
- 授权来源:本会话确认计划 `cursor_governance_layer`,范围含 7 项全选、hook 命中一律 `ask`、session+postToolUse 双轨、字段识别 both_phases。
- 交付终点:任务分支实现并通过工程回归;受控合入 local `dev`;不 push;不重建产品服务。
- 禁止:未授权 push / 晋升 test/main;改产品 Runner;以 stub 冒充产品 PASS;覆盖他人 CURRENT/MATRIX。
## 范围与非目标
- 允许:`.cursor/rules|skills|hooks|mcp.json`、`scripts/tests/test_cursor_hooks.py`、相关 `.doc`(任务/台账/经验/规范登记/测试报告)。
- 非目标:改 `scripts/pi_subagents.py` 硬门禁语义;实现 S0–S9 自动状态机;产品 Go/前端/PG。
## 相关问题与经验
- ISSUE-20260924-cursor-test-rule-drift(open → verifying)
- ISSUE-20260924-cursor-cli-mcp-path(deferred → verifying)
- 新建 ISSUE-20260924-cursor-hook-event-contract(open)
- 采纳 LESSON-20260923-matrix-status-cas、LESSON-20260924-pi-tool-boundaries;新建 LESSON-20260924-cursor-hook-advisory-gates(candidate)
## 需求与验收
| R-ID | 要求 | AC-ID |
|---|---|---|
| R1 | 修复测试规则漂移 | AC1:无固定模型/无条件全量 Go/失效 §8;指向验证契约 |
| R2 | PI 派发 skill | AC2:roles→run→result、租约、拒绝码、run_status≠verdict |
| R3 | 阶段记录 skill | AC3:派发包/回传/收据/R-AC-T 可执行 |
| R4 | PI/会话/收据 hooks | AC4:ask;fail-open 异形;probe 开关;单元可测 |
| R5 | MCP 路径 | AC5:agentctl/jev 相对路径;CLI 证据或 verifying |
| R6 | rules 收敛与登记 | AC6:薄指针 + policy-registry 修订 |
| R7 | 工程回归 | AC7:unittest discover 全绿;文档静态检查;报告归档 |
## 步骤与验收
1. [ ] 建场与认领
2. [ ] 规则漂移修复
3. [ ] 两 skill
4. [ ] 四 hook + hooks.json
5. [ ] MCP 路径
6. [ ] rules 收敛
7. [ ] 测试与全量回归
8. [ ] ISSUES/lesson/policy-registry
9. [ ] 测试报告
10. [ ] probe 独立验收(需用户配合;未采样前 advisory)
11. [ ] 受控合入 local_dev
## 验证与证据
见后续测试报告与本记录更新。产品链路 NOT REQUIRED。
## 相关链接
- 计划:用户确认的 Cursor governance layer
- 权威:`.doc/ops/2026-09-24-subagent-model-config.md` · `2026-09-24-subagent-workflow-standard.md` · `2026-09-24-pi-subagent-executor.md` · `2026-09-21-validation-contract.md`
## 收口(合入后)
- review_state=accepted;integration_state=merged_local_dev(`57cbd571`);deployment=not_required;cleanup=pending;remote_sync=not_requested
- validate:208 tests OK;enqueue daemon ff-only 成功
- IDE probe 仍为 pending_ide_sample;hook↔Cursor 接线保持 advisory
@@ -0,0 +1,38 @@
---
title: "dev 全面门禁与 test 晋升(rc-v1.1.0-beta.3)"
task_id: docs-gate-promo-report-2026-09-24
status: done
created: 2026-09-24
updated: 2026-09-24
owner: Cursor
task_type: ops
task_tier: multi_stage
policy_revision: "AGENTS+worktree-ops @ 3de5bc5c"
branch: feature/docs-gate-promo-report-2026-09-24
worktree: .worktrees/docs-gate-promo-report-2026-09-24
base_dev_sha: "8ca448ddca7682f851835978921473594eec0ad9"
head_sha: ""
write_scope: [".doc/"]
allowed_environments: ["dev", "test"]
mutex: git:dev+env:test+docs
review_state: accepted
integration_state: pending_merge
deployment: test_ok_schema_66
cleanup: pending
cleanup_owner: 独立维护者
cleanup_trigger: tip 为 local_dev/origin 祖先且无进程占用后 remove
remote_sync: pending_push
---
# dev 全面门禁与 test 晋升
## 用户目标与授权
- 用户目标:dev 全面深测后晋升 test(merge + `rc-v1.1.0-beta.3` + 部署验收 + 恢复基线 + push)
- 授权来源:用户确认计划(推送远端 + test 验收后恢复基线);RERANKER 笔误已自改
- 交付终点:见 [测试报告](../../test-reports/2026-09-24-dev-full-gate-test-promotion-test-report.md)
## 结果摘要
- nightly PASS @ `3de5bc5c`;promote M=`0e4b111d` + `rc-v1.1.0-beta.3`;test schema 66
- 小队 intake completed / 6802 字 / 幂等;S1 restore MATCH
@@ -0,0 +1,72 @@
---
title: "Development-Manager 治理系统迁移"
task_id: "dm-migration-2026-09-24-r2"
status: done
created: 2026-09-24
updated: 2026-09-24
owner: Cursor
task_type: implementation
task_tier: multi_stage
policy_revision: "agent-governance-2026-09-23-fav-constraint-restored @ edbe59247872ef5861bafd30068955e22288c6ff"
branch: feature/dm-migration-2026-09-24
worktree: .worktrees/dm-migration-2026-09-24
base_dev_sha: "edbe59247872ef5861bafd30068955e22288c6ff"
write_scope: [".doc/ops/short-term/2026-09-24-dm-migration.md", ".doc/test-reports/2026-09-24-dm-migration-test-report.md", ".doc/ops/CURRENT.md"]
allowed_environments: []
mutex: dm-migration
review_state: pending
integration_state: pending # DM 仓已自管;AS 侧仅文档合入
deployment: not_required
cleanup: pending
cleanup_owner: Cursor
cleanup_trigger: DM 验收通过且 AS 侧 CURRENT 收口完成
remote_sync: not_requested
---
# Development-Manager 治理系统迁移
## 用户目标与授权
- 用户目标:将 Agent-System 内管理/规范系统复制式迁移到独立仓库 Development-Manager(`/home/weichen/projects/Development-Manager`),关联远端 [weichen/Development-Manager](https://git-home.u1680832.nyat.app:30319/weichen/Development-Manager.git);自举自治;新增项目登记表实现单机统一管理;为后续中心服务端演进预留。
- 交付终点:DM 仓可用、治理测试绿、双 daemon 并存、迁移溯源完整;Agent-System 管理系统暂不移除。
- 禁止项:不移除 AS 管理系统;不默认 force;push 仅在用户确认后(本任务用户已授权按方案实施含 push)。
- 架构决策:阶段 A 单机统一管理;阶段 B(不实施)中心服务端 + 分布式客户端;git 历史全新初始提交。
## 范围与非目标
- 允许:DM 仓新建与治理工具链/文档副本;AS 侧本任务文档、测试报告、CURRENT 认领行。
- 非目标:产品 Go/React 代码;AS 治理删除;阶段 B C/S 实现。
## 相关问题与经验
- catalog:`R-dm-migration` 已登记;overlap status=none。
- 注:`member-permissions-doc-2026-09-24` 因持有 `.doc` 整目录硬冲突已 close=done(其文档已提交于 feature 分支,待另轨合入)。
## 步骤与验收
1. [x] P0 任务登记 / CURRENT 认领 / 本文件落盘
2. [x] P1–P5 DM 建仓、代码/文档迁移、projects 登记、自举
3. [x] P6 验证 + 测试报告
4. [x] P7 push 远端 + AS CURRENT 收口
## 验证与证据
| 范围 | 命令与环境 | 预期 | 实际 | 证据 |
|---|---|---|---|---|
| DM 治理 unittest | `python3 -B -m unittest discover -s scripts/tests` @ DM | 全绿 | 待跑 | 测试报告 |
| 双 daemon | 两侧 `daemon status` | 均 ok | 待跑 | 测试报告 |
## 相关链接
- 计划:`~/.cursor/plans/development-manager_治理系统迁移方案_ea32becd.plan.md`
- 远端:https://git-home.u1680832.nyat.app:30319/weichen/Development-Manager.git
- 主产物路径:`/home/weichen/projects/Development-Manager`
## 交付摘要
- DM 路径:`/home/weichen/projects/Development-Manager`
- 远端:https://git-home.u1680832.nyat.app:30319/weichen/Development-Manager.git (`dev`/`main` @ `0a58b909`)
- 双 daemon:`dm-coordinator` + AS `agentctl-coordinator` 并存 ok
- 核心测试:221 OK(见 DM `.doc/test-reports/2026-09-24-dm-migration-test-report.md`)
- 过渡约束:AS 内嵌治理暂不移除;新治理开发进 DM
@@ -0,0 +1,22 @@
# 自由协作 + 认领提醒 — 任务记录
- **task_id**: free-collab-claim-notify-2026-09-24
- **status**: in_progress
- **owner**: Cursor
- **mutex**: notification+supplementimpact+events+docs
- **companion_task**: non-author-member-access-2026-09-24 (server+docgov+web)
- **base_dev_sha**: ebb36fb85c80b83e895b29df5d9056c68f5efe31
- **design**: [../system-design/2026-09-24-free-collab-claim-notify-design.md](../system-design/2026-09-24-free-collab-claim-notify-design.md)
- **write_scope**: internal/{notification,events,app,bizdev,coordinator,traceimpact,supplementimpact}, deploy/postgres, .doc
- **review_state**: pending
- **integration_state**: pending
- **deployment**: not_started
- **cleanup**: pending
- **remote_sync**: not_requested
## 批次
- A 自由协作通道(companion worktree)
- B 认领补齐 + 互斥加固(companion)
- C 提醒机制 + 收件箱
- D 补充影响批次 + 确认卡 + 分流执行
@@ -0,0 +1,70 @@
---
title: 治理目录库与跨对话需求重叠检测
task_id: governance-catalog-2026-09-24
status: done
created: 2026-09-24
updated: 2026-09-24
head_sha: e1796cc858228a13cbc1fa3c8648adafa4e9f194
owner: Cursor
task_type: implementation
task_tier: multi_stage
policy_revision: agent-governance-2026-09-21-r1 @ cfc80b34a40e8de78e77a44839571bb684d405d5
branch: feature/governance-catalog-2026-09-24
worktree: .worktrees/governance-catalog-2026-09-24
base_dev_sha: cfc80b34a40e8de78e77a44839571bb684d405d5
write_scope:
- scripts
- configs
- .doc
- .cursor
allowed_environments: []
mutex: agent-workflow-governance+catalog
review_state: approved
integration_state: merged
deployment: not_required
cleanup: pending
cleanup_owner: Cursor
cleanup_trigger: validate pass + queue enqueue + closeout
remote_sync: not_requested
---
# 治理目录库与跨对话需求重叠检测
## 用户目标与授权
- **用户目标**:跨对话需求/功能重叠与冲突可机器检测;认领、缺陷、测试、发布版本进入与业务库隔离的治理目录。
- **授权来源**:用户确认计划「治理目录库与需求重叠检测」并要求按 to-do 全量实施。
- **交付终点**:Catalog schema + FTS5 中文召回 + 两级门禁 + 回填 + 可降级向量层 + MCP/技能 + 工程回归报告;受控合入 local `dev`。
- **禁止**:不连业务 PostgreSQL;不新建第二库文件/容器;不自动升 MATRIX;不 push;不强制产品 PI 全链路(工程工具变更,NOT REQUIRED)。
## 范围与非目标
- **允许写入**:`scripts/agentctl*.py`、`scripts/catalog_backfill.py`、`scripts/mcp/agentctl-mcp.mjs`、`scripts/tests/`、`configs/agent-governance.json`、`.doc/`(方案/任务/报告/模板漂移修复)、`.cursor/skills` 与 mandatory 规则补充。
- **非目标**:跨机权威认领、产品业务功能、自动删除 worktree。
## 相关问题与经验
- 检索词:`overlap` / `requirement` / `catalog` / `docs drift` / `FTS5`
- 命中:路径级 `overlaps()` 已 enforced;需求语义重叠无机制;embedding 401 运维债 → 向量层 fail-open。
- 采纳:可选策略键扩展;CJK 逐字切分禁用 trigram;测试夹具同步复制新模块。
## 步骤与验收
- [ ] W0 方案主文档 + policy-registry proposed
- [ ] W1–W4 catalog 模块 + task register 联动
- [ ] W5 回填 + drift
- [ ] W6 向量降级三态
- [ ] W7 MCP + 技能
- [ ] W8 unittest 全绿 + 报告
- [ ] W9 validate → queue → closeout
## 验证与证据
| 范围 / 被测 SHA | 命令与环境 | 预期 | 实际 / 判定 | 证据 |
|---|---|---|---|---|
| 工程工具 | `python3 -B -m unittest discover -s scripts/tests -p 'test_*.py' -v` | 全绿 | (待填) | test-report |
## 收口与交接
- 五态见 frontmatter;合入后更新。
- 相关:[方案](../2026-09-24-governance-catalog-plan.md)
@@ -0,0 +1,66 @@
---
title: "治理控制台 P1 设计定稿"
task_id: "governance-console-p1-design-2026-09-24"
status: done
created: 2026-09-24
updated: 2026-09-24
owner: Cursor
task_type: research
task_tier: small
policy_revision: "agent-governance-2026-09-21-r1 + cursor-governance-2026-09-24-r1 @ 4844041b"
branch: feature/governance-console-p1-design-2026-09-24
worktree: .worktrees/governance-console-p1-design-2026-09-24
base_dev_sha: "4844041b1b417b5ac415fe779a3784959c0afbbe"
write_scope: [".doc"]
allowed_environments: []
head_sha: "ae7fcc15572ca7278297f51747d8db5510f5521d"
mutex: "agentctl-console-design"
review_state: accepted
integration_state: merged_local_dev
deployment: not_required
cleanup: pending
cleanup_owner: "独立维护者"
cleanup_trigger: "合入 local_dev 且文档验收通过后"
remote_sync: not_requested
---
# 治理控制台 P1 设计定稿
## 用户目标与授权
- 用户目标:把 P1 骨架扩成可实施规格(12 节),不写实现代码。
- 交付终点:`.doc/ops/short-term/2026-09-24-governance-console-plan.md` 定稿合入 local `dev`。
- 禁止:scripts 编码、产品 web/cmd/internal、push、晋升、跨机协调实施。
## 范围与非目标
- 允许:设计文档原地扩充、任务主记录、CURRENT 认领。
- 非目标:P1-a…e 任何代码实施。
## 相关问题与经验
- catalog:`R-governance-console-p1`;overlap 探测无 hard/soft(与 R-governance-visibility-p0 语义相关但未命中门禁)。
- 前序:P0 合入 `dev@4844041b`;证据见 [测试报告](../../test-reports/2026-09-24-governance-visibility-p0-test-report.md)。
## 步骤与验收
1. [x] 建场 / register / CURRENT 认领
2. [x] 设计文档 12 节扩充
3. [x] 链接/锚点/mermaid 检查(12 节 / 0 断链 / 4 mermaid / 594 行)
4. [x] 合入收口
## 验证与证据
| 范围 | 命令与环境 | 预期 | 实际 / 判定 | 证据 |
|---|---|---|---|---|
| 纯文档 | 链接/锚点/mermaid + 符号对照 | 无断链、可渲染 | PASS:links_ok=16 broken=0 mermaid=4 符号均存在 | 本任务验证节 |
| 产品 PI / go test | — | NOT REQUIRED | — | 验证契约「工程规范/文档」层 |
## 收口与交接
待定稿后填写五态。
## 相关链接
- 设计主体:[2026-09-24-governance-console-plan.md](./2026-09-24-governance-console-plan.md)
- P0 任务:[2026-09-24-governance-visibility-p0.md](./2026-09-24-governance-visibility-p0.md)
@@ -0,0 +1,41 @@
# governance-console P1 实施
- task_id: `governance-console-p1-impl-2026-09-24`
- status: `in_progress`
- mutex: `agentctl-console`
- requirement: `R-governance-console-p1-impl`
- design: `.doc/ops/short-term/2026-09-24-governance-console-plan.md` (`governance-console-p1-r1`)
- authorization: 用户 `/goal 按照方案进行实现`
- write_scope: `scripts/` `.cursor/skills/` `.doc/`
- base_dev_sha: `6eb2d11eeb1840286b189c07e0da524541dcbbc8`
- review_state: accepted
- integration_state: merged_local_dev
- deployment: not_required
- cleanup: pending
- remote_sync: not_requested
## 交付
| 阶段 | 产物 |
|---|---|
| P1-a | `agentctl serve` + `scripts/governance-console/index.html`;GET 八端点 |
| P1-b | `agentctl claim new` + `POST /api/claim/new` |
| P1-c | `agentctl integrate prepare` + `POST /api/integrate/prepare` |
| P1-d | `agentctl pi packet` + `POST /api/pi/packet`;skill 引用 packet |
| P1-e | SPA 四区+认领/Prepare;MCP `brief`/`claim_archive` |
核心模块:`scripts/agentctl_console.py`(CLI/HTTP 同构)。
## 验证
见 [.doc/test-reports/2026-09-24-governance-console-p1-test-report.md](../../test-reports/2026-09-24-governance-console-p1-test-report.md)。
## 禁止
不 push;不碰产品 `web/`;不自动 `queue enqueue` 以外的 ff;不实现 `/api/shell`。
## 合入
- local_dev tip:
- queue item:
- validate run:
@@ -0,0 +1,594 @@
---
title: "治理控制台全景设计(P1 定稿)"
task_id: "governance-console-p1-design-2026-09-24"
status: planned
created: 2026-09-24
updated: 2026-09-24
owner: Cursor
task_type: research
related_p0: governance-visibility-p0-2026-09-24
design_revision: "governance-console-p1-r1"
base_dev_sha: "4844041b1b417b5ac415fe779a3784959c0afbbe"
---
# 治理控制台全景设计(P1 定稿)
覆盖方向:**A 状态可视化**、**B 流程自动化**、**C MCP 只读巡览**、**D PI 派发包生成**。
本文件是**可实施规格**;实施须另开 task + `catalog overlap`。本轮不写代码。
前置:P0 已合入 `dev@4844041b`(`--format table`、`brief`、MCP +4、`claim archive`)。证据:[测试报告](../../test-reports/2026-09-24-governance-visibility-p0-test-report.md)。
---
## 1. 现状与缺口
### 1.1 P0 已交付(机器权威层可读)
| 能力 | 入口 | 核心实现 |
|---|---|---|
| 人类可读表 | `agentctl status\|queue list\|claim list\|cleanup report --format table` | [`emit_payload`](../../../scripts/agentctl.py) + [`agentctl_visibility`](../../../scripts/agentctl_visibility.py) |
| 一页简报 | `agentctl brief` | `collect_*` + `cmd_brief` |
| done 行归档 | `agentctl claim archive [--apply]` | `claim_archive` → `@document` docs apply CAS |
| MCP 只读 | `queue_list` / `claim_status` / `cleanup_report` / `catalog_drift` | [`agentctl-mcp.mjs`](../../../scripts/mcp/agentctl-mcp.mjs) |
### 1.2 仍存缺口(本设计覆盖)
| ID | 缺口 | 用户摩擦 |
|---|---|---|
| A2 | 无 dashboard / HTTP 面 | 终端 JSON/table 仍需手敲;多源聚合靠 `brief` 文本 |
| B1 | 认领仍三步 | skill 要求 snapshot → 手写 JSON → apply |
| B2 | 每任务双 worktree | 手工建 `integrate-*` + `--no-ff` |
| D1 | PI packet 手工组装 | task_id/request_id/source_sha/approved_commands 易漏 |
| C2 | MCP 未暴露 brief/archive | 会话内仍偶发 shell 拼装 |
跨机 claim 权威不在本方案:见 [coordination-db-daemon phased plan](../../remediation/2026-09-23-coordination-db-daemon-phased-plan.md)。
---
## 2. 目标与非目标
### 2.1 目标
1. 本机治理面:一眼看 tasks / runs / claims / queue / drift / cleanup。
2. 高频动作白名单:`claim new`、`claim archive`、`integrate prepare`、`pi packet`——**全部复用既有租约与 `docs apply`,不新增旁路写入口**。
3. CLI 与 HTTP 同构:同一 Python 函数;MCP 可薄封装。
4. 可测:工程工具单测覆盖路由、错误码、幂等、loopback。
### 2.2 非目标
- 远程多用户 Web 登录 / 鉴权体系。
- 产品 [`web/`](../../../web/) AdminConsole 内嵌治理页。
- 绕过 `agentctl with` / `docs apply` 的文件写。
- 自动 `--force` 清理 worktree、push、晋升 test/main。
- 替代 Herdr / 产品 PI Agent Runner。
- 把 `serve` 装进 systemd/launchd(保持手工前台进程)。
---
## 3. 总体架构
```mermaid
flowchart TB
subgraph clients [Clients]
Cursor[Cursor_MCP_CLI]
Term[Terminal]
Browser[Browser_localhost]
end
subgraph console [Governance_Console_P1]
Spa[static_SPA]
Serve[agentctl_serve]
CliExt[claim_new_integrate_prepare_pi_packet]
end
subgraph core [Existing_agentctl_core]
Collect[collect_star_pure_fns]
Docs[docs_apply_CAS]
Lease[Lease_with]
Queue[queue_daemon_ff]
Db[(governance_SQLite)]
end
Cursor --> Serve
Cursor --> CliExt
Term --> CliExt
Browser --> Spa --> Serve
Serve --> Collect
Serve --> CliExt
CliExt --> Docs
CliExt --> Lease
CliExt --> Queue
Collect --> Db
Docs --> Db
Lease --> Db
Queue --> Db
```
### 3.1 进程拓扑
| 进程 | 生命周期 | 说明 |
|---|---|---|
| `agentctl daemon` | 已装载 systemd/launchd | 仅队列 ff-only;**不**承载 HTTP |
| `agentctl serve` | 人工前台 / 可选 tmux | 绑 `127.0.0.1:7432`;退出即停 |
| SPA | 由 serve 静态托管 | 零构建单页;无独立 Node 服务 |
### 3.2 组件职责
| 组件 | 路径(建议) | 职责 |
|---|---|---|
| `agentctl serve` | [`scripts/agentctl.py`](../../../scripts/agentctl.py) 子命令 | HTTP JSON + 静态文件 |
| 动作实现 | `scripts/agentctl_console.py`(新建)或内嵌 | `claim_new` / `integrate_prepare` / `pi_packet` 纯逻辑 |
| SPA | `scripts/governance-console/index.html` | 四区仪表盘 |
| MCP 增补 | [`scripts/mcp/agentctl-mcp.mjs`](../../../scripts/mcp/agentctl-mcp.mjs) | 可选:`brief`、`claim_archive`、动作薄封装 |
---
## 4. 数据模型与 API 资源映射
### 4.1 治理 SQLite(只读投影,不改 schema)
| 表 | 关键字段 | 消费端点 |
|---|---|---|
| `tasks` | id, owner, worktree, branch, state, scopes, capabilities | `GET /api/status` |
| `runs` | id, task, state, pid, start, boot, resources | `GET /api/status` |
| `queue_items` | id, task, head_sha, expected_dev, priority, state | `GET /api/queue` |
| `claims` | id, task, resource, state, updated | `GET /api/claims` |
| `documents` / `receipts` | run, task, file, hash | 动作审计;不直接暴露 |
| `catalog_*` | requirements, features, overlaps | `GET /api/catalog/drift` |
| `matrix_state_snapshot` | record_id, status | `GET /api/docs/drift` |
CURRENT.md / FEATURE-MATRIX.md 仍是人类投影;机器权威在 SQLite + docs apply 收据。
### 4.2 只读 payload 契约(与 P0 `collect_*` 同源)
```text
GET /api/status → collect_status_payload(repo)
{status, lock_root, main, version, epoch, tasks[], runs[], queue[], policy}
GET /api/brief → cmd_brief 逻辑;?format=markdown|json
GET /api/queue → queue_list 同构 {status, items[]}
GET /api/claims → claim_list 同构 {status, claims[]}
GET /api/cleanup → collect_cleanup_payload {worktrees[]}
GET /api/docs/drift → collect_docs_drift_payload {regressions[], open_capabilities[]}
GET /api/catalog/drift → collect_catalog_drift_payload
GET /api/daemon → collect_daemon_payload {manager_lock, heartbeat, queue}
```
查询参数:
- `?format=json|table`(status/queue/claims/cleanup):table 时 `Content-Type: text/plain`,body 为 `render_*_table` 文本。
- `?all=1`(queue/claims):含终态行。
### 4.3 动作请求/响应信封
```json
{
"request_id": "uuid-or-client-supplied",
"task": "governance-…",
"authorization_ref": "optional-user-chat-ref",
"...action_fields": {}
}
```
成功:
```json
{"status": "ok|archived|prepared|created", "run_id": "…", "request_id": "…", "...": {}}
```
失败(HTTP 状态见 §5.3):
```json
{"status": "denied", "code": "BASE_CHANGED", "message": "…", "...details": {}}
```
---
## 5. 后端 `agentctl serve` 详细设计
### 5.1 启动
```bash
agentctl serve [--host 127.0.0.1] [--port 7432] [--static scripts/governance-console]
```
约束:
- 默认 host **仅** `127.0.0.1`;传入 `0.0.0.0` → 启动前拒绝 `INVALID_REQUEST`。
- 单线程或 `ThreadingHTTPServer`;写动作串行化靠既有 Lease/SQLite,不另造全局锁。
- 不注册为 daemon;SIGINT 干净退出。
### 5.2 路由表
#### 只读(8)
| Method | Path | 处理 |
|---|---|---|
| GET | `/api/status` | `collect_status_payload` |
| GET | `/api/brief` | brief 聚合 |
| GET | `/api/queue` | `queue_list` |
| GET | `/api/claims` | `claim_list` |
| GET | `/api/cleanup` | `collect_cleanup_payload` |
| GET | `/api/docs/drift` | `collect_docs_drift_payload` |
| GET | `/api/catalog/drift` | `collect_catalog_drift_payload` |
| GET | `/api/daemon` | `collect_daemon_payload` |
| GET | `/` 与 `/static/*` | SPA |
#### 动作白名单(4)——同进程函数调用,禁止 `subprocess` 再调 CLI
| Method | Path | 函数 |
|---|---|---|
| POST | `/api/claim/new` | `claim_new(repo, args)` |
| POST | `/api/claim/archive` | 既有 `claim_archive`(`apply=True`) |
| POST | `/api/integrate/prepare` | `integrate_prepare(repo, args)` |
| POST | `/api/pi/packet` | `pi_packet(repo, args)` |
未列出的 `/api/*` → 404。任意 shell / env-service / push / 删 worktree → **永不实现**。
### 5.3 错误码 → HTTP
| agentctl `Denied.code` | HTTP | 客户端建议 |
|---|---|---|
| `INVALID_REQUEST` | 400 | 修请求体 |
| `CAPABILITY_REQUIRED` / `PATH_OUT_OF_SCOPE` | 403 | 补 capability 或换 task |
| `BASE_CHANGED` / `WORKTREE_MISMATCH` / `LOCK_BUSY` / `UNMANAGED_DOCUMENT_CHANGE` | 409 | 重新 snapshot / prepare;不自动重试 |
| `EVIDENCE_REQUIRED` | 422 | 补证据后重试 |
| `UNKNOWN_*` | 404 | 检查 id |
| 未捕获异常 | 500 | 查 run 审计;`RECOVERY_REQUIRED` |
### 5.4 幂等
- 客户端可传 `request_id`;缺省服务端生成 uuid。
- 写路径进入 `Lease(..., request_id, digest)`:与现有 `docs_apply` replay 一致——相同 request_id 返回 `replayed`,不二次写。
- `integrate prepare`:若 integrate worktree 已存在且 tip 已含任务分支 merge → 返回既有 `{head, integrate_task}`(幂等成功),不强制重建。
### 5.5 并发与 expected-dev 竞态
```text
prepare 冻结 expected_dev = tip(dev)
→ validate
→ enqueue(expected_dev, head)
daemon:若 tip(dev) != expected_dev → 该项失败/取消(既有行为)
客户端:收到失败或 BASE_CHANGED → 重新 prepare,禁止盲重试同 head
```
HTTP 层不自动重试;SPA 按钮在 409 时提示「dev 已前进,请重新 prepare」。
### 5.6 安全
1. Loopback only。
2. 无 Cookie / Bearer;本机信任模型(与 CLI 相同)。
3. 动作白名单硬编码;请求体禁止 `command` / `shell` / `argv` 字段。
4. 所有写动作写 `runs`/`documents` 审计(既有 Lease)。
5. CORS:仅同 origin(静态同 host);或不设 CORS(同源足够)。
### 5.7 实现落点(实施时)
- argparse:`serve` 子命令。
- 标准库 `http.server` 或轻量 handler;**零新 pip 依赖**。
- 静态根默认 `scripts/governance-console/`(gitignore 可选缓存,源码入库)。
---
## 6. CLI 动作详细设计
HTTP 与 CLI **共用**下列函数;CLI 为 argparse 薄包装。
### 6.1 `agentctl claim new`(B1)
```bash
agentctl claim new --task "$ID" --owner Cursor --mutex <key> \
[--branch feature/$ID] [--worktree .worktrees/$ID] \
[--status in_progress] [--replace] [--request-id RID]
```
**内部步骤**
1. `task_row` 校验:cwd == 注册 worktree;需 `docs:publish`(单行写 CURRENT,无需 admin)。
2. `docs_snapshot(CURRENT, record=task)`。
3. 若 `sha256` 非空且未 `--replace` → `deny('INVALID_REQUEST', 'row exists; pass --replace')`。
4. 构造一行:`| {owner} | {task} | {branch} | {worktree} | {mutex} | {status} |`(worktree 用相对 `.worktrees/…`)。
5. `docs_apply` 单行 CAS(`expected_sha256` 来自 snapshot;新建为 null)。
6. emit `{status:'created'|'replaced', record_id, run_id}`。
**拒绝码**:`WORKTREE_MISMATCH`、`CAPABILITY_REQUIRED`、`BASE_CHANGED`、`AMBIGUOUS_RECORD`。
**替代关系**:取代 skill [`agentctl-worktree-setup`](../../../.cursor/skills/agentctl-worktree-setup/SKILL.md) 中「CURRENT 认领」三段手工;建 worktree / `task register` 仍由 skill 前半段负责(本命令不创建 git worktree)。
**幂等**:同 request_id replay;`--replace` 在 BASE_CHANGED 后需新 snapshot。
### 6.2 `agentctl integrate prepare`(B2)
```bash
agentctl integrate prepare --task "$ID" --expected-dev <full_sha> \
[--integrate-id integrate-$ID] [--request-id RID]
```
**前置**:调用方 cwd 可为任务 worktree 或 main;函数内切换到新建 integrate worktree 执行 merge。
**内部步骤**
1. 校验 `expected-dev == rev-parse(refs/heads/dev)`,否则 `BASE_CHANGED`。
2. `integrate_id = integrate-id or f"integrate-{task}"`;branch `feature/{integrate_id}`。
3. 若 worktree 不存在:调用与 `agent-worktree.sh create` 等价逻辑(`git worktree add -b … expected-dev`)。
4. 在 integrate worktree:`task register --capability git:dev`(若已注册且匹配则跳过)。
5. Lease(`path:.`,`git:index`,`git:dev`) 内:`git merge --no-ff -m "merge: candidate {task} into dev" feature/{task-branch}`。
6. 校验 `HEAD^1 == expected-dev`。
7. emit `{status:'prepared', integrate_task, worktree, head, expected_dev, first_parent}`。
**不做**:validate、enqueue(留给既有命令 / SPA 分步按钮,避免隐式合入)。
**拒绝码**:`BASE_CHANGED`、`LOCK_BUSY`、`CAPABILITY_REQUIRED`、`GIT_ERROR`、worktree 脏 → `INVALID_REQUEST`。
**替代关系**:压缩 skill [`agentctl-integrate-closeout`](../../../.cursor/skills/agentctl-integrate-closeout/SKILL.md) 的「候选」段;后续仍 `validate` → `queue enqueue`。
### 6.3 `agentctl pi packet`(D1)
```bash
agentctl pi packet --task "$ID" --role research|planning|reviews|diagnosis|test_run|acceptance_check|report \
--goal '…' --authorization-ref '…' \
[--source-sha FULL] [--timeout-seconds 600] \
[--input-file PATH]… [--approved-command 'argv…']… \
[--request-id RID] [--write]
```
**内部步骤**
1. 读 task 行 → worktree;`source_sha = freeze_source_sha(worktree, arg or HEAD)`(复用 [`pi_subagents.freeze_source_sha`](../../../scripts/pi_subagents.py) 规则:必须满 40/64 hex)。
2. `request_id = arg or uuid`;校验 `REQUEST_ID_RE`。
3. 组装 packet:
```json
{
"task_id": "…",
"request_id": "…",
"role_id": "research",
"goal": "…",
"authorization_ref": "…",
"source_sha": "<40hex>",
"input_files": ["…"],
"timeout_seconds": 600,
"approved_commands": [["python3","-B","-m","unittest", "…"]]
}
```
4. 默认 stdout JSON;`--write` 时原子写入
`.doc/test-reports/assets/pi-subagents/<task>/<request>/packet.json`
(目录与 [`REPORT_ROOT_REL`](../../../scripts/pi_subagents.py) 一致),并要求 Lease `path:.doc/test-reports/…`。
5. **不**调用 `pi_subagent_run`——生成与派发分离。
**拒绝码**:`UNKNOWN_TASK`、`INVALID_SOURCE_SHA`、`UNKNOWN_ROLE`(对照模型配置角色表)、`PATH_OUT_OF_SCOPE`。
**替代关系**:减少 [`pi-subagent-dispatch`](../../../.cursor/skills/pi-subagent-dispatch/SKILL.md) 手工拼包;skill 改为「packet 路径 → run」。
### 6.4 `claim archive`(已有,HTTP 暴露)
行为维持 P0:默认 dry-run;POST 等同 `--apply`。需 `docs:admin` + 任务 worktree。
---
## 7. 前端 SPA 设计
### 7.1 技术选型
- **零构建**:单 `index.html` + 内联 CSS/JS(或同目录 `app.js`)。
- 原生 `fetch`;轮询间隔默认 **10s**(可配置);可选后续 SSE(P1-e)。
- 不引入 React/Vite;不依赖产品 `web/node_modules`。
### 7.2 线框(四区)
```text
+------------------------------------------------------------------+
| agentctl console daemon: ok queue: 0 [刷新] [10s] |
+-------------------------------+----------------------------------+
| 1. 任务 / 租约 | 2. 队列与集成 |
| active tasks table | pending/claimed table |
| live runs | [Prepare…] 需选 task+确认 |
| held claims | [Enqueue…] 仅展示指引/复制命令 |
+-------------------------------+----------------------------------+
| 3. 文档漂移 | 4. 清理积压 |
| MATRIX hard regressions | cleanup report table |
| catalog drift | 无删除按钮(只读) |
+-------------------------------+----------------------------------+
| brief 预览(折叠) |
+------------------------------------------------------------------+
```
### 7.3 区 ↔ 端点
| 区 | 数据 | 动作按钮 |
|---|---|---|
| 1 | `/api/status` + `/api/claims` | 「认领」→ modal → `POST /api/claim/new`(二次确认) |
| 2 | `/api/queue` + status.queue | 「Prepare」→ `POST /api/integrate/prepare`;Enqueue 默认复制 CLI(避免 SPA 误合入) |
| 3 | `/api/docs/drift` + `/api/catalog/drift` | 无写 |
| 4 | `/api/cleanup` | 无写 |
| 顶栏 | `/api/daemon` + `/api/brief` | 刷新 |
### 7.4 UX 规则
- 所有 POST 前 modal:展示将发送的 JSON;确认后才发。
- 409/403 用红色 toast + 原始 `code`。
- 路径只显示文本,不 `file://` 链出(避免浏览器限制)。
---
## 8. 关键时序图
### 8.1 claim new
```mermaid
sequenceDiagram
participant U as User_or_SPA
participant S as agentctl_serve_or_CLI
participant D as docs_apply
participant DB as SQLite
U->>S: claim_new task owner mutex
S->>S: snapshot CURRENT row
alt row_exists_without_replace
S-->>U: 400 INVALID_REQUEST
else
S->>D: apply single_row CAS
D->>DB: lease documents receipts
D-->>S: applied run_id
S-->>U: 200 created
end
```
### 8.2 integrate prepare → enqueue → daemon ff
```mermaid
sequenceDiagram
participant U as User
participant P as integrate_prepare
participant V as validate
participant Q as queue_enqueue
participant Daemon as agentctl_daemon
participant Dev as refs_heads_dev
U->>P: expected_dev tip
P->>Dev: rev_parse
alt tip_mismatch
P-->>U: 409 BASE_CHANGED
else
P->>P: worktree_add_merge_no_ff
P-->>U: head first_parent
U->>V: unittest_or_scope_checks
V-->>U: validated
U->>Q: expected_dev head
Q->>Daemon: pending_item
Daemon->>Dev: ff_only_if_tip_matches
Daemon-->>U: merged_or_failed
end
```
### 8.3 pi packet(生成与派发分离)
```mermaid
sequenceDiagram
participant U as User
participant Gen as pi_packet
participant Disk as report_assets
participant Run as pi_subagent_run
U->>Gen: role goal auth_ref
Gen->>Gen: freeze_source_sha
Gen->>Disk: optional_write_packet_json
Gen-->>U: packet
Note over U,Run: 另一步:用户或 skill 显式 run
U->>Run: packet_fields_plus_lease
Run-->>U: receipt_pending_verdict
```
---
## 9. 测试矩阵
验证层级:验证契约「工程工具验收」(非产品 PI)。
### 9.1 `scripts/tests/test_agentctl_serve.py`(实施时新增)
| 用例 | 预期 |
|---|---|
| bind 127.0.0.1 成功;0.0.0.0 拒绝 | 启动失败码 |
| GET 八端点 200 且字段与 CLI collect 一致 | JSON 同构 |
| 未知 POST `/api/shell` | 404 |
| POST claim/new 缺 task | 400 |
| POST claim/new 无 docs:publish | 403 |
| 幂等:同 request_id 两次 | 第二次 replayed |
| 非 loopback 模拟(若可) | 拒绝或无法连接 |
### 9.2 CLI 黑盒(扩展 `test_agentctl.py` fixture)
| 命令 | 覆盖 |
|---|---|
| `claim new` | 新建行 / `--replace` / BASE_CHANGED |
| `integrate prepare` | first_parent==expected_dev;脏树拒绝 |
| `pi packet` | source_sha 拒绝符号名;`--write` 路径落盘 |
复用临时 git 仓 + 拷贝 `agentctl*.py` 模式(与 P0 visibility fixture 一致)。
### 9.3 SPA 手动验收清单
- [ ] 四区数据在 daemon ok 时非空或显式 empty
- [ ] 轮询不导致写动作
- [ ] Prepare 确认框取消无请求
- [ ] 409 展示 code 文本
### 9.4 本设计任务验证(文档层)
- 链接/锚点可达;mermaid 三角可渲染;与 P0 符号名一致。
- **不**要求独立 `*-test-report.md`(NOT REQUIRED:纯设计文档)。
---
## 10. 分阶段实施
| 阶段 | 范围 | 依赖 | 验收 |
|---|---|---|---|
| **P1-a** | `serve` 只读 8 端点 + 极简 HTML 展示 status/brief | P0 `collect_*` | test_agentctl_serve 只读用例绿;本机浏览器打开 |
| **P1-b** | `claim new` CLI + POST + SPA 认领表单 | P1-a | 黑盒新建行;CURRENT 有收据 |
| **P1-c** | `integrate prepare` CLI + POST + SPA Prepare | P1-b | first_parent 断言;不自动 enqueue |
| **P1-d** | `pi packet` CLI + POST;skill 文档改为引用 packet | P1-a | packet JSON schema 单测;不触发 run |
| **P1-e** | SPA 打磨、可选 MCP `brief`/`claim_archive`、可选 SSE | P1-a…d | 手动清单勾完 |
每阶段独立 task_id + catalog overlap + 工程工具单测;禁止跨阶段大揉。
---
## 11. 风险与缓解
| 风险 | 影响 | 缓解 |
|---|---|---|
| expected-dev 竞态(多会话并行合入) | enqueue 失败 | 明确 409/失败提示;prepare 可重入;不隐藏错误 |
| serve 闲置占端口 | 本机冲突 | 默认 7432;文档说明与产品 8080/8081 隔离 |
| `@document` 归档与并行 docs apply | BASE_CHANGED | archive 持 docs:admin;短租约;冲突则重跑 dry-run |
| SPA 误 enqueue 推进 dev | 错误合入 | SPA 默认不提供一键 enqueue;仅 Prepare |
| 与产品 web 目录混淆 | 发布门禁污染 | 静态资源仅 `scripts/governance-console/` |
| packet 被当成已派发 | 假 PASS | 生成不写 verdict;skill 强制 run_status≠叙事 |
---
## 12. 衔接与授权
### 12.1 外部衔接
| 主题 | 文档 | 本方案关系 |
|---|---|---|
| 跨机权威 | [coordination-db-daemon phased plan](../../remediation/2026-09-23-coordination-db-daemon-phased-plan.md) | 不重复;控制台只读本机 SQLite |
| P0 可视化 | [governance-visibility-p0](./2026-09-24-governance-visibility-p0.md) | 本设计复用 collect/archive |
| Cursor hooks | 规则 `cursor-hooks` | serve 不经 hooks;CLI 写仍走既有钩子 |
| PI 执行器 | [pi-subagent-executor](../2026-09-24-pi-subagent-executor.md) | packet 字段对齐;不改执行器门禁 |
### 12.2 实施授权门槛
1. 用户显式授权「实施 P1-a(或指明阶段)」。
2. 新 task(建议 `governance-console-p1a-YYYY-MM-DD`)+ `catalog overlap`(相对本 R-ID / mutex `agentctl-console`)。
3. 写路径限 `scripts/` + 必要 `.doc`;产品树禁止。
4. 合入走 validate → queue enqueue;不 push。
### 12.3 设计修订
- `design_revision`: `governance-console-p1-r1`
- 变更本规格须更新 revision 并在实施 task 记录 `policy_revision` 差分。
---
## 附录 A. 符号索引(实施对照)
| 符号 | 文件 | 状态 |
|---|---|---|
| `collect_status_payload` | `scripts/agentctl.py` | P0 已有 |
| `collect_cleanup_payload` | 同上 | P0 已有 |
| `collect_docs_drift_payload` | 同上 | P0 已有 |
| `collect_daemon_payload` | 同上 | P0 已有 |
| `collect_catalog_drift_payload` | 同上 | P0 已有 |
| `claim_archive` | 同上 | P0 已有 |
| `emit_payload` / `visibility.render_*` | agentctl + visibility | P0 已有 |
| `claim_new` | 待建 | P1-b |
| `integrate_prepare` | 待建 | P1-c |
| `pi_packet` | 待建 | P1-d |
| `agentctl serve` | 待建 | P1-a |
| SPA `index.html` | `scripts/governance-console/` | P1-a/e |
## 附录 B. 端口与路径速查
| 项 | 值 |
|---|---|
| HTTP | `http://127.0.0.1:7432` |
| 静态根 | `scripts/governance-console/` |
| PI packet 根 | `.doc/test-reports/assets/pi-subagents/<task>/<request>/` |
| CURRENT 归档追加 | `.doc/archive/ops/2026-09-21-current-history.md` |
@@ -0,0 +1,62 @@
---
title: "治理可视化 P0"
task_id: "governance-visibility-p0-2026-09-24"
status: done
created: 2026-09-24
updated: 2026-09-24
owner: Cursor
task_type: implementation
task_tier: small
policy_revision: "agent-governance-2026-09-21-r1 + cursor-governance-2026-09-24-r1 @ a2afa67d"
branch: feature/governance-visibility-p0-2026-09-24
worktree: .worktrees/governance-visibility-p0-2026-09-24
base_dev_sha: "a2afa67d471c4edce9a6a31600811779549c8cce"
write_scope: ["scripts", ".doc"]
allowed_environments: []
head_sha: "ab450c1181c832b7d91680bfbebba48c19ec61a1"
mutex: "agentctl-visibility"
review_state: accepted
integration_state: merged_local_dev
deployment: not_required
cleanup: pending
cleanup_owner: "独立维护者"
cleanup_trigger: "合入 dev 且验收通过后"
remote_sync: not_requested
---
# 治理可视化 P0
## 用户目标与授权
- 用户目标:实施治理可视化快赢(人类可读 status/brief、MCP 只读工具、claim archive)并撰写治理控制台 P1 方案。
- 交付终点:P0 代码合入 local `dev`;工程工具单测与真实控制台证据;P1 设计文档落盘。
- 禁止:push、晋升 test/main、跨机协调实施、产品 web/cmd/internal 改动。
## 范围与非目标
- 允许:`scripts/agentctl.py`、`scripts/mcp/agentctl-mcp.mjs`、新 visibility 模块与单测、`.doc/ops/short-term`、`.doc/test-reports`、archive 追加。
- 非目标:dashboard 前后端、`claim new`、`integrate prepare`、`pi packet`(仅 P1 文档)、跨机协调。
## 相关问题与经验
- 关联:R04 CURRENT 膨胀(政策审查)、`ISSUE-20260923-coordination-authority`(不实施,仅衔接说明)。
- catalog:`R-governance-visibility-p0`;overlap 探测无 hard/soft 命中。
## 步骤与验收
1. [x] 建场 / register / CURRENT 认领
2. [ ] `--format table` 渲染
3. [ ] `brief`
4. [ ] MCP 只读工具 +4
5. [ ] `claim archive`
6. [ ] 单测 + 真实运行报告
7. [ ] P1 控制台方案文档
8. [ ] validate → queue enqueue → 收口
## 验证与证据
按验证契约「工程工具验收」:`python3 -B -m unittest discover -s scripts/tests -p 'test_*.py' -v` + 真实 `--format table`/`brief`/`claim archive --dry-run` 控制台取样。
## 收口与交接
待实施完成后填写。
@@ -0,0 +1,76 @@
---
title: "非容器化单二进制三环境交付方案(设计)"
task_id: "single-binary-noncontainer-design-2026-09-24"
status: in_progress
created: 2026-09-24
updated: 2026-09-24
owner: Cursor
task_type: research
task_tier: small
policy_revision: "AGENTS+CURRENT@edbe59247872ef5861bafd30068955e22288c6ff"
branch: feature/single-binary-deploy-design-2026-09-24
worktree: .worktrees/single-binary-deploy-design-2026-09-24
base_dev_sha: "edbe59247872ef5861bafd30068955e22288c6ff"
write_scope:
- ".doc/system-design/2026-09-24-single-binary-non-containerized-deployment.md"
- ".doc/ops/short-term/2026-09-24-single-binary-deploy-design.md"
- ".doc/ops/CURRENT.md"
allowed_environments: []
mutex: "single-binary-deploy-design"
review_state: pending
integration_state: pending
deployment: not_required
cleanup: pending
cleanup_owner: 独立维护者
cleanup_trigger: 设计评审通过或任务 cancelled/done 后按门禁复查
remote_sync: not_requested
catalog_requirement: R-single-binary-non-container-deploy
---
# 非容器化单二进制三环境交付方案(设计)
## 用户目标与授权
- 用户目标:制定本项目非容器化方案,尽可能单二进制交付;完善时须覆盖开发测试、内部测试、生产上线三类部署。
- 已确认决策:纯单文件 server;PG 为 `managed`(dev)/`attach`(main)分级;PI runner 外置 sidecar。
- 交付终点:可审设计文档落盘(非实施)。
- 禁止:未授权 push、晋升 test/main、改 gap-matrix / FEATURE-MATRIX 冒充发布、业务环境写操作。
## 范围与非目标
- 允许写入:上表 write_scope(文件级,规避与 `member-permissions-doc` 占用整树 `.doc` 的硬 scope 冲突)。
- 主设计:[../../system-design/2026-09-24-single-binary-non-containerized-deployment.md](../../system-design/2026-09-24-single-binary-non-containerized-deployment.md)
- 非目标:P1–P7 代码实施;system-design/README 索引更新(该文件正被并行任务修改,留给收口或后续 docs 任务)。
## 相关问题与经验
- catalog search「单二进制/非容器化」:无既有 R-ID 命中;已登记 `R-single-binary-non-container-deploy`。
- 硬重叠:`member-permissions-doc-2026-09-24` scopes=`['.doc']` 与本任务路径前缀冲突;文件不重叠,以文件级 scope 注册规避 register 门禁;实施期建议对方收窄 scope。
- 清理:关闭已合入但仍 `active` 且 scopes=`['.']` 的 `integrate-governance-console-p1-2026-09-24`、`integrate-gc-p1-closeout-2026-09-24`(queue 已 completed,merge 已在 local_dev)。
## 步骤与验收
1. [x] 建 worktree / 注册 / CURRENT 认领 / catalog 需求
2. [x] 撰写三环境方案文档
3. [x] 一致性自查(PROJECT 端口/验证契约/红线)
4. [ ] lease_run 提交 `docs(design)`;不申请集成(先评审)
验证:纯文档 — diff、相对链接、拓扑与门禁叙述一致;**NOT REQUIRED** 产品 PI / 全量 Go(依据验证契约「纯规范/普通文档」)。
## 验证与证据
| 范围 / 被测 SHA | 命令与环境 | 预期 | 实际 / 判定 | 证据 |
|---|---|---|---|---|
| 设计文档 | 对照 PROJECT 端口表与 compose;相对链接解析;validateProductionSecrets / FAV 红线 | 一致 | PASS:8080/8081/8000、5433/5434/5435、PI 18865–67、data/{dev,test,main} 对齐;链接已修;main 密钥与 ALLOW_IN_MEMORY/FAV 叙述对齐 | 主设计 §2/§4.3;config.go validateProductionSecrets |
## 收口与交接
- 评审通过后:另开 **implementation** 任务执行 P1+;本任务可 `done`。
- 不默认 queue enqueue。
- review_state / integration_state 以工具收据为准更新。
## 相关链接
- 主设计:`.doc/system-design/2026-09-24-single-binary-non-containerized-deployment.md`
- Plan:用户确认的「非容器化单二进制三环境交付方案」
- Catalog:`R-single-binary-non-container-deploy`
@@ -0,0 +1,140 @@
---
title: "Cursor Auto 与 Subagent 协作规范研究"
task_id: subagent-workflow-standard-2026-09-24
status: done
created: 2026-09-24
updated: 2026-09-24
owner: Codex
task_type: implementation
task_tier: multi_stage
policy_revision: "agent-governance-2026-09-21-r1 + issue-learning-2026-09-23-r1 + systemic-issue-analysis-2026-09-23-r1 + codegraph-governance-2026-09-24-r1; dev@5423b261f97f371bdf7fa5066e9305f9eddaef42"
branch: feature/subagent-workflow-standard-2026-09-24
worktree: .worktrees/subagent-workflow-standard-2026-09-24
base_dev_sha: 5423b261f97f371bdf7fa5066e9305f9eddaef42
write_scope: ["scripts/pi_subagents.py", "scripts/pi-subagent-readonly.ts", "scripts/mcp/pi-subagents-mcp.mjs", "scripts/mcp/README.md", "scripts/tests/test_pi_subagents.py", ".cursor/mcp.json", ".cursor/rules/pi-subagents.mdc", ".doc", ".doc/ops/2026-09-24-subagent-model-config.md", ".doc/ops/2026-09-24-subagent-workflow-standard.md", ".doc/ops/short-term/2026-09-24-subagent-workflow-standard.md", ".doc/audit/2026-09-24-subagent-workflow-research.md", ".doc/ops/templates/subagent-stage-record.md", ".doc/ops/2026-09-21-policy-registry.md", ".doc/README.md", ".doc/audit/ISSUES.md", ".doc/ops/CURRENT.md"]
allowed_environments: []
mutex: subagent-workflow-docs
review_state: approved
integration_state: merged
deployment: not_required
cleanup: pending
cleanup_owner: "owner 退出后的独立维护者"
cleanup_trigger: "规范采纳并集成、证据保存且 owner 退出后复查"
remote_sync: not_requested
---
# 用户目标与授权
用户原请求:在规范中加入 subagent 规范,日常在 Cursor 使用 Auto;梳理“形成需求→评估需求→制定方案→实施方案→代码审查→测试→合并并清理 worktree→验收”,每一步形成文档或报告,研究制定更合理的新规范。
本任务授权为研究与规范编制,交付终点为可审规范、依据、模板和接入顺序;不含业务实施、Cursor 全局设置、共享运行环境、Herdr 编排、远端 push。新规范以 proposed 交付,不宣称全仓 active 或已经实现自动工作流。
## 需求与验收
| R-ID | 用户要求 | AC-ID / 本次完成标准 |
|---|---|---|
| R1 | 日常无需选择模型 | AC1:解释 Auto/inherit 支持范围与实测缺口,不固定具体模型 |
| R2 | 梳理合理流程 | AC2:阶段依赖、返工、合并前后验证和清理顺序明确 |
| R3 | 加入 subagent 规范 | AC3:职责、派发/回传、独立性、并发写与授权边界可执行 |
| R4 | 每步文档/报告 | AC4:阶段产物、模板、追踪和小任务减负规则明确 |
| R5 | 基于研究制定 | AC5:引用当前仓库与官方依据,核对已有规范冲突并列接入验收 |
验收人:本次文档质量由 Codex 自检;新规范采纳由用户决定。未回复默认确认点问题,草案采用“方案确认后授权范围内自动推进”,可按用户反馈修订。
## 研究与实施记录
- 启动检查主目录 dev 干净,worktree/机器认领已盘点;工具创建本任务 worktree,登记八个文档写路径及 docs:publish。
- 本地 dev 相对缓存 origin/dev ahead 74 / behind 0,未 fetch、未 push;服务器状态未核验。
- CURRENT 在本任务 worktree 通过 docs apply 新增自己的认领,request_id=subagent-workflow-standard-start-20260924;主目录 CURRENT 未直接编辑。
- 已读 AGENTS、PROJECT、CURRENT、文档地图、worktree/验证/规则登记/问题闭环/任务及收口模板。
- 问题/经验检索词:subagent、Cursor、worktree、并行、清理、规范、审批。命中 ISSUE-20260923-matrix-status-regression 和 LESSON-20260923-matrix-status-cas;采纳共享状态经 docs apply、合并后核对状态,其他内容无直接 subagent 经验命中。
- 新发现 ISSUE-20260924-cursor-test-rule-drift,见研究报告;仅登记与建议,未修复。
- 文档组织采用 writing-for-agents 技能的单一来源与条件入口原则;brainstorming/ce-plan 用于流程与选项研究。
- 没有执行产品代码、客户端角色安装或自动化脚本开发。未新增经验:本次设计尚无实机验证,已有经验继续复用。
## 产物
- [规范草案](../2026-09-24-subagent-workflow-standard.md):唯一流程定义与接入步骤。
- [研究报告](../../audit/2026-09-24-subagent-workflow-research.md):来源、取舍、规则漂移问题与证据边界。
- [阶段/派发模板](../templates/subagent-stage-record.md):输入版本、授权、角色输出与验收映射。
- 文档地图和规范登记增加 proposed 入口;不修改 active 规范行为、不创建 .cursor/agents。
## 验证与证据
| 范围 | 实际检查 | 结果与限制 |
|---|---|---|
| 本次八个文档 | git diff --check;Python 内联链接/锚点/S0–S9/字段/ID 检查 | 初次 FILES=8 LOCAL_LINKS=84 STAGES=10 ISSUE_IDS=5 / PASS;收口再检 |
| 流程一致性 | 逐项对照需求 AC1–AC5 和 12 个文档情景 | 均有对应条款;self_review,未作独立 Agent 审查 |
| 状态盘点 | agentctl docs drift | status=ok、regressions=[];未改能力声明 |
| 清理盘点 | agentctl cleanup report | exit 0;本任务 blocked:dirty_or_ignored_files、registry:TASK_ACTIVE;为提交前快照,不删除 |
| CodeGraph | codegraph sync -q | exit 0;只更新可再生本地索引 |
| 产品/客户端运行 | 未执行 | 纯文档研究不要求产品测试;Auto/角色实机 V1–V10 尚未运行 |
本次 AC1–AC5 达到研究交付标准;规范采纳仍 review_state=pending,规则生命周期 proposed。证据摘要与情景逐项结果见研究报告,未把未运行的项目记 PASS。
## 收口与交接
本记录与草案保存在本任务分支的本地 docs 提交,精确提交可由 git log -1 feature/subagent-workflow-standard-2026-09-24 核对;本次未合入 dev、未部署、未 push。后续按规范接入 A–F 推进,先处理采纳与客户端规则冲突,再实机验证 Auto/角色/门禁行为。
本任务工作区保留供审阅,未合入 dev;cleanup 由独立维护者在满足祖先/证据/进程条件后复查。无需重建产品服务;未申请或使用 env:dev。
本地认领在结束前标记研究 done;此状态只关闭本次规范编制,不关闭 open 问题或自动批准规范。文件含可再生 .codegraph 缓存,独立维护者清理前另行盘点;草案是唯一新增研究成果,当前工作区需保留供审阅。
## 后续修订 r2:用户确认模型配置
逻辑 task_id 沿用 subagent-workflow-standard-2026-09-24;本机 agentctl 不支持重开已关闭记录,也不允许原记录隐式扩 scope,因此仅创建 operation_task_id=subagent-workflow-standard-2026-09-24-config-r2 作为本次写入租约身份,仍在原 worktree、分支和本主记录继续,不另建业务任务。
写范围沿用原规范/研究/入口/模板/主记录并增加 .doc/ops/2026-09-24-subagent-model-config.md;未认领业务源码、PI 全局配置或任何运行环境。
授权来源:用户指定本机 PI 和五模型池;明确代码由 Cursor 实施;确认 M3 不进入默认流程;本轮“可以,默认这样,可以设置一个配置文档,让我可以根据需要进行调整”。
交付:可编辑模型配置 + 旧草案中的执行方式修正 + 配置版本/覆盖来源进入派发模板。模型分配 decision_state=approved;流程整体仍 proposed,自动派发器未实现,未扩大为客户端安装、产品实施、dev 集成或 push。
验收项:
- AC6:五个精确 provider/model,Cursor 独占代码实施与修复。
- AC7:M3 辅助角色 enabled=false,禁止关键判断/自动备用链。
- AC8:角色默认、升级关系、启停、并发和任务覆盖可在文档中调整。
- AC9:配置版本/hash 随派发记录,下一次派发生效;文件明确尚无自动解析器。
- AC10:模型配置为唯一来源;流程与研究历史明确取代旧原生 Cursor/inherit 方案。
使用 writing-for-agents 的单一来源/短入口原则维护文档。继续采纳 LESSON-20260923-matrix-status-cas;不新增已验证经验,未将文档推演当运行证明。
本轮验证结果(文档静态检查,非运行验收):
- git diff --check:exit 0。
- Python 内联检查:五个模型精确匹配本机目录;11 个 role_id 唯一且升级关系无循环;auxiliary=false,M3 仅辅助;implementation_executor=cursor_auto;无自动备用;模板包含 config_revision/config_sha256。初次输出 MODELS=5 ROLES=11 STAGES=10,PASS。
- 本次变更 Markdown 的相对链接及锚点检查通过;旧 PI implementer 配置已移除。保留的 inherit 提及均说明旧方案已废止。
- agentctl docs drift:status=ok,regressions=[];cleanup report 为只读盘点,本任务因未合入/文件及登记状态不能删除。未操作其他任务。
- codegraph sync -q:exit 0。仅文档变更,产品测试、真实模型调用和派发器验收不适用/未运行,未记 PASS。
本轮交付已完成;逻辑任务恢复 done,模型分工已获用户确认。新增配置与配套文档保存于本地任务分支;未合入 dev、未 push,主目录与 PI 全局设置均未修改。自动调用 PI 的执行器、角色工具限制实测、流程整体采纳和相关旧规则修复作为后续工作,不因配置文档存在视为已完成。
提交前检查记录:首次 git diff --cached --check 检出新配置头部两处 Markdown 行末双空格,提交未执行。已改为段落分隔并重跑检查;此前 git diff --check 不包含未跟踪新文件,最终以暂存区检查为准。
## 执行器实现续作
用户授权“接入自动调用 pi 的执行器”。继续原逻辑 task_id;操作登记 subagent-workflow-standard-2026-09-24-executor,Cursor Auto 负责代码,Codex 主协调。[实施契约与验证计划](../2026-09-24-pi-executor-implementation.md)。阶段 in_progress,原文“尚未实现”为此前交付历史,当前结果以本节后续报告为准。
## 执行器收口
- 实施与验证完成:代码由 Cursor Auto 编写,代码提交 69ffaa677e23a1dd9aa0528bb09b3acfcd38b119;Codex 主机复核与验收,本机 GLM-5.3 独立审查守卫候选。模型配置默认值按用户已确认方案。
- [使用说明](../2026-09-24-pi-subagent-executor.md) · [完整报告](../../test-reports/2026-09-24-pi-executor-test-report.md)。实际 Cursor CLI 调用 roles/run/result,无 model_override、无 shell PI 替代;最终 ls/read 成功。
- 完整工程 suite 173 项 PASS;提交后专项 34 项 PASS;node 检查、arch-check block、文档与证据核对通过。产品 Go/前端/PG/真实产品 Runner 无改动,未冒充验收。
- 本轮授权交付终点:执行器源码与 Cursor CLI 本地接入验证。全套阶段审批状态机和 IDE 页面验证不在本次完成声明中。
- integration_state=pending:本地 dev 已前进至 3de5bc5c396fc21887f0f19e6e3baa8784347f99(新增 nightly/测试修复),主目录干净;但 dev-full-gate-test-promo-2026-09-24 持 env:dev 真实验收租约,同锁还有别人的候选排队,不能抢占。未向 dev 写入本任务成果,未 push,未重建服务。
- 接管:环境槽位释放后,从届时最新 dev 创建受控候选,重读规则并验证,再集成本任务分支。不得复用旧 expected-dev 或抢占别人队列。
- cleanup 保留:未合入 dev,当前 worktree 用于配置审阅与运行;唯一报告/日志已纳入本任务文档提交,CodeGraph 为可再生缓存。由 owner 退出后的独立维护者按祖先/进程/证据条件复查,不强删。
- ISSUE-20260924-pi-executor-boundaries 已按本地范围验证关闭;新增 LESSON-20260924-pi-tool-boundaries。既有测试规则漂移仍 open;其它 Cursor MCP 入口兼容性残差单独 deferred。研究/代码完成不自动关闭这些问题。
本轮临时操作登记为 subagent-workflow-standard-2026-09-24-executor;逻辑 task_id 保持原值。最终头部状态仅表示上述源码/本地验收完成,integration/deployment/remote_sync/cleanup 各自独立。
## 本地 dev 集成续作
用户明确授权“合入 dev”。沿用本逻辑 task_id;文档协调操作登记 subagent-workflow-standard-2026-09-24-land。读取 dev 基线 c1a70e67e5edfd4a4c52fe087933e92f3c6d1e9c,远端跟踪引用 ahead 3 / behind 0(未 fetch);主目录干净、机器 runs/queue 均为空。AGENTS/PROJECT/worktree/验证契约对比原基线无差异。
预合并仅 CURRENT/ISSUES 文档冲突;采纳 LESSON-20260923-matrix-status-cas,在原任务 worktree 用 docs apply @document 对齐最新 dev 并保留自己的认领,问题台账保留 dev 全部行并追加本任务三行。docs:admin 仅用于本次一致性对齐;不改其他任务状态、不改集成槽位。
下一步从此精确 dev 构造 --no-ff 候选,验证后通过 agentctl integrate 合入;不 push、不重建产品服务、不清理他人工作区。
## dev 集成完成
2026-09-24 按用户“合入 dev”授权完成本地受控集成:基线 c1a70e67e5edfd4a4c52fe087933e92f3c6d1e9c,来源 65539754,集成提交 5a8540804ee2d142a0894c1482a2a16e8f843915。候选完整工程测试、Node 语法和 arch-check block 通过,详见报告新增集成验证章节。CURRENT/ISSUES 冲突在原任务分支解决,保留 dev 全部记录;FEATURE-MATRIX 无变化。
review_state=approved;integration_state=merged;deployment=not_required(工程脚本及 Cursor 项目配置,无产品服务变化);remote_sync=not_requested;cleanup=pending。原任务及本轮集成工作区保留至 owner 退出后,由独立维护者复核祖先、证据、进程与唯一遗留再清理。完整流程草案仍 proposed,模型配置与执行器已进入 dev;在 Cursor 重新加载项目 MCP 后使用。前文未合入和占锁说明为历史快照,由本节更新。
集成恢复记录:首次源分支合并的全 staged whitespace 检查命中 dev 原有的原始 SQL/SSE 证据空白;对本任务相对 dev 的差异检查通过。保留原证据,核对主 dev 未变化、无服务操作、无未解决冲突后,以 verified 恢复该操作并继续提交。
@@ -0,0 +1,49 @@
# Worktree cleanup inventory (2026-09-24)
盘点基线 local_dev tip 在收口提交时以机器为准;本文件记录本轮已清除与 `cleanup_pending` 原因。
## 已清除(verdict=ready → `agent-worktree.sh remove --delete-branch`)
- integrate-non-author-closeout-2026-09-24
- chat-semantic-d3-closeout-2026-09-23
- free-collab-claim-notify-2026-09-24
- governance-catalog-2026-09-24
- integrate-free-collab-2026-09-24
- integrate-gate-nightly-fixes-2026-09-24
- integrate-gate-unhook-docquery-2026-09-24
- integrate-jev-dev-assist-on-2026-09-24
- integrate-non-author-docs-2026-09-24
- jev-dev-enable-2026-09-24
- jev-product-shadow-2026-09-24
- non-author-closeout-2026-09-24
- non-author-member-access-2026-09-24
- pi-narrative-final-closeout-b-2026-09-23
清除前对可再生 ignored(`.codegraph/`、`web/node_modules`、`web/dist`、测试 `data/`、`.env`)做了显式删除;对可丢弃未提交 tracked 脏文件执行 `git checkout -- .`(任务已 done,内容已在 local_dev)。
## cleanup_pending(`not_ancestor_of_dev`;普通 remove 拒绝,未使用 --force/-D)
| worktree | head | blockers | 说明 |
|---|---|---|---|
| `admin-password-reset-2026-09-24` | `58bf83f7` | not_ancestor_of_dev,dirty_or_ignored_files | tip 含未成祖先的 docs 收口提交;任务 registry 多为 done. tasks: admin-password-reset-2026-09-24=done |
| `dev-full-gate-test-promo-2026-09-24` | `614ebb8d` | not_ancestor_of_dev,dirty_or_ignored_files | tip 含未成祖先的 docs 收口提交;任务 registry 多为 done. tasks: dev-full-gate-test-promo-2026-09-24=done |
| `fix-fullchain-unique-project-2026-09-24` | `8c4200c8` | not_ancestor_of_dev,dirty_or_ignored_files | patch-id/内容等价已在 local_dev;tip SHA 分叉. tasks: fix-fullchain-unique-project-2026-09-24=cancelled |
| `fix-nightly-abs-datadir-2026-09-24` | `6f0e43ca` | not_ancestor_of_dev,dirty_or_ignored_files | patch-id/内容等价已在 local_dev;tip SHA 分叉. tasks: fix-nightly-abs-datadir-2026-09-24=done |
| `gate-e1a-unique-project-name-2026-09-24` | `f04f14ff` | not_ancestor_of_dev,dirty_or_ignored_files | tip 含未成祖先的 docs 收口提交;任务 registry 多为 done. tasks: gate-e1a-unique-project-name-2026-09-24=done |
| `gate-unhook-docquery-2026-09-24` | `2844bbfe` | not_ancestor_of_dev,dirty_or_ignored_files | tip 含未成祖先的 docs 收口提交;任务 registry 多为 done. tasks: gate-unhook-docquery-2026-09-24=done |
| `integrate-codegraph-current-2026-09-24` | `734aa725` | not_ancestor_of_dev | task=cancelled;候选 tip 未成为 dev 祖先. tasks: integrate-codegraph-current-2026-09-24=cancelled |
| `integrate-codegraph-governance-2026-09-24` | `22ed51cf` | not_ancestor_of_dev | CURRENT 认领 commit 未成祖先;主目录 CURRENT 已记 done/(removed). tasks: integrate-codegraph-governance-2026-09-24=done |
| `integrate-fix-fav-staging-uuid-2026-09-24` | `80caa785` | not_ancestor_of_dev,dirty_or_ignored_files | patch-id/内容等价已在 local_dev;tip SHA 分叉. tasks: integrate-fix-fav-staging-uuid-2026-09-24=done |
| `integrate-intent-plan-u9u12-close-2026-09-24` | `e7262d4d` | not_ancestor_of_dev | 正文证据已由替代 SHA 合入 local_dev;本 tip SHA 分叉. tasks: integrate-intent-plan-u9u12-close-2026-09-24=done |
| `intent-plan-u9u12-accept-2026-09-24` | `e7262d4d` | not_ancestor_of_dev | 正文证据已由替代 SHA 合入 local_dev;本 tip SHA 分叉. tasks: intent-plan-u9u12-accept-2026-09-24=done |
| `promote-rc-beta3-c-2026-09-24` | `0e4b111d` | not_ancestor_of_dev | test 晋升线产物,本非 local_dev 合入目标. tasks: promote-rc-beta3-c-2026-09-24=done |
| `sync-local-test-origin-2026-09-24` | `9984c68d` | not_ancestor_of_dev | test 晋升线产物,本非 local_dev 合入目标. tasks: sync-local-test-origin-2026-09-24=done |
| `worktree-cleanup-closeout-2026-09-24` | `fabd85a6` | dirty_or_ignored_files,registry:TASK_ACTIVE,process_cwd:1269150 | tip 含未成祖先的 docs 收口提交;任务 registry 多为 done. tasks: worktree-cleanup-closeout-2026-09-24=active |
## 孤儿目录(非 git worktree)
- `.worktrees/codegraph-governance-2026-09-24`:仅残留 scripts 副本,可直接 `rm -rf`(非 `git worktree remove`)。
## 规范依据
- `.doc/ops/2026-09-21-agent-worktree-workflow.md` §8:仅 `verdict=ready` 可 remove;拒绝保留 cleanup_pending。
@@ -0,0 +1,24 @@
# 管理员设置页与维护公告系统
- **task_id**: admin-settings-maint-2026-09-25
- **status**: in_progress
- **owner**: Cursor
- **branch**: feature/admin-env-settings-maintenance-2026-09-25
- **worktree**: .worktrees/admin-env-settings-maintenance-2026-09-25
- **mutex**: admin-settings-maintenance
- **base_dev_sha**: 4e410efbabeea5b944909d8a0de49bda1265c975
- **write_scope**: internal/sysadmin, internal/maintenance, internal/handoff, cmd/*, deploy/pi-agent, web admin/maintenance, goose 00071, server wiring
- **authorization**: 用户确认计划实施(dev 管理员设置页 + 维护计划公告系统)
- **requirement**: R-admin-env-settings-maintenance
## 交付终点
1. 管理台可编辑模型/Tavily 等设置,DB 持久化;runner 热更新;secret 掩码
2. 维护计划可调度;到点 FD 交接公告进程;管理员 token 启动新服务并下线公告
3. 单测 + 真实 handoff E2E 报告
## 五状态
| review_state | integration_state | deployment | cleanup | remote_sync |
|---|---|---|---|---|
| pending | pending | not_applicable | pending | not_requested |
@@ -0,0 +1,15 @@
# 对话上下文注入(short-term)
- **task_id**: dialogue-context-injection-2026-09-25
- **status**: in_progress
- **write_scope**: internal/dialoguectx, internal/conflictresolve, internal/squad, internal/bizdev, internal/coordinator, internal/chat, internal/ctxmgr, internal/sysadmin, deploy/postgres/goose, .doc
- **mutex**: dialogue-ctx
- **base_dev_sha**: 4e410efbabeea5b944909d8a0de49bda1265c975
- **review_state**: pending
- **integration_state**: pending
- **deployment**: not_applicable
- **cleanup**: pending
- **remote_sync**: not_requested
设计:[2026-09-25-dialogue-context-injection-design.md](../../system-design/2026-09-25-dialogue-context-injection-design.md)
报告:[2026-09-25-dialogue-context-injection-test-report.md](../../test-reports/2026-09-25-dialogue-context-injection-test-report.md)
@@ -0,0 +1,43 @@
---
title: "docrev 实施方案 11 条验收收口核对"
task_id: planned-tasks-closeout-plan-2026-09-25(P1 子产物)
status: in_progress
created: 2026-09-25
owner: Cursor
task_type: audit
mutex: planned-tasks-closeout
review_state: pending
integration_state: pending
---
# docrev 实施方案 11 条验收收口核对
对 [management-implementation-plan](../../remediation/2026-09-13-document-revision-management-implementation-plan.md) §11 的 11 条验收逐条映射现状证据。原则:**证据充分才勾,不充分列残差**;不因「大体做过」假勾。
## 逐条核对
| # | 验收 | 证据 | 判定 |
|---|------|------|------|
| 1 | 模板/Agent 开 Version、人工只加 Revision 在 API/UI/DB 一致 | `internal/docrevision`(45 文件:service_agent `CommitAgentVersion`、service_human、pg_mutate、contract_test);[13日报告](../../test-reports/2026-09-13-document-revision-management-test-report.md) T0 时间线 PASS;Round20 UI | ✅ 可勾 |
| 2 | 人工高亮永远 baseline→head,Agent commit 后归零 | `ManualChangeOverlay.tsx` + [Round20 UI](../../test-reports/2026-09-14-document-revision-runtime-ui-test-report.md) PASS(21 条);[DOCREV rerun](../../test-reports/2026-09-22-docrev-ui-rerun-test-report.md) main 18+post-restart PASS | ✅ 可勾 |
| 3 | 任意两 Version 默认 final→final/head 比较,可看 baseline/revision | `VersionCompareView.tsx` + `DiffNavigator.tsx`;同上 UI 证据 | ✅ 可勾 |
| 4 | 用户/单 agent/squad 主体与不可变 actor snapshot 可追溯 | service_agent.go actor snapshot;`commit_idempotent_test.go`、[Track T](../../remediation/2026-09-20-capability-enablement-impact-plan.md) 五表追踪 | ✅ 可勾 |
| 5 | 智能体输出与 change report 同次运行产生并绑定精确快照 | `commit_report_test.go`、pending_fact_source_test;PI 叙事 fallback 属显式行为([MATRIX docgov-revision 行](../../status/FEATURE-MATRIX.md)) | ✅ 可勾(fallback 为声明内行为) |
| 6 | 真实 diff/影响集合/风险下限服务端确定,模型不能篡改/降级 | `narrative_test.go`、risk floor 见 [R13](../../audit/2026-09-16-r13-data-safety-checklist.md);[PI 叙事收口](../../test-reports/2026-09-23-pi-narrative-closeout-test-report.md) 默认 off 但链路 PASS | ✅ 可勾 |
| 7 | 当前负责人收版本摘要;受影响负责人收授权裁剪通知 | `internal/notification/document_events.go` + `NotificationInbox.tsx`;[Wave5](../../test-reports/2026-09-13-document-revision-management-test-report.md) 通知负例 | ✅ 可勾 |
| 8 | 并发/重试/重启/迁移/故障注入无静默覆盖、双版本、丢通知 | `document_commit_concurrency_pg_test.go`、`concurrency_test.go`、[12日 fault-injection](../../test-reports/2026-09-12-phase4-lease-phase5-fault-injection-test-report.md)、M7(00053 投影同事务+重放) | ✅ 可勾 |
| 9 | 已批准文档、跨项目/跨阶段、私密文档负例全绿 | `document_revision_authz_test.go` 5 组负例(401/orphan/受控路由/author-only/幂等)+ [12日 IAM](../../test-reports/2026-09-16-iam-route-inventory-test-report.md) | ✅ 可勾 |
| 10 | 右侧栏主题/宽度/键盘/色觉/大文档可用 | Round20 + DOCREV rerun Playwright;**色觉与键盘无障碍未见专项断言** | ⚠️ 部分可勾:无障碍专项缺证据 |
| 11 | 证据归档 + MATRIX 逐波次更新 | `.doc/test-reports/` 全套 + MATRIX docgov-revision=done | ✅ 可勾 |
## 结论
- 11 条中 **10 条证据充分**;第 10 条「无障碍专项」(色觉、键盘完备性)无专项测试证据——不假勾,列为**残差 R-docrev-a11y**。
- 处置建议:方案文 §11 勾选 1–9、11;第 10 条标注「Playwright 主链路已过、无障碍专项未测,残差登记」;frontmatter `status: in_progress → done`(以 10/11 全证据 + 1 登记残差收口),W1-D 降级说明保留。
- 本核对为只读产物;方案文的勾选更新需在 docgov mutex 空闲时以 docs 提交落地(列入 P1 后续动作)。
## 残差登记
| ID | 内容 | 关闭条件 |
|---|------|---------|
| R-docrev-a11y | 版本比较视图色觉多重编码 + 键盘完备性专项断言 | 新增 Playwright a11y 用例(axe 或手动断言)PASS 后勾第 10 条 |
@@ -0,0 +1,70 @@
---
title: "P10: backlog 价值评估与择优实施"
task_id: backlog-triage-p10-2026-09-25
status: in_progress
created: 2026-09-25
updated: 2026-09-25
owner: cursor-auto
task_type: research
task_tier: small
policy_revision: "agent-governance-2026-09-21-r1"
branch: feature/backlog-triage-p10-2026-09-25
worktree: .worktrees/backlog-triage-p10-2026-09-25
base_dev_sha: "4bdbb0da6f08461187fc2ed485da70b1f1c04fbe"
write_scope:
- internal/quote/
- internal/squad/
- .doc/backlog/
- .doc/ops/short-term/
- .doc/test-reports/
allowed_environments: []
head_sha: ""
mutex: squad-quote-backlog
review_state: pending
integration_state: pending
deployment: not_required
cleanup: pending
cleanup_owner: independent maintainer after owner exit
cleanup_trigger: acceptance green + owner exit
remote_sync: not_requested
---
# P10: backlog 价值评估与择优实施
## 用户目标与授权
- 用户目标:`/goal 把这些任务都进行规划,并推进至完成` → 总控 P10「逐项评估后定做/不做及理由」。
- 来源:`.doc/backlog/chat-agent-p6-backlog.md` + `.doc/backlog/2026-09-17-rdev-phase2-backlog.md`。
## 逐项评估结论
| 项 | 内容 | 结论 | 理由 |
|---|---|---|---|
| **B5** | 报价模块轻量复核与输入范围校验 | **做**(本批) | `internal/quote` 纯计算零校验:Hours 负值/NaN/Inf、空客户/产品名直接进 Excel;费率常量无复核快照。补输入校验 + 计算不变式复核(行合计=总额、费率一致性),低风险高价值 |
| **A5** | 小队非关键步骤降级 | **做**(本批) | `StepSpec` 无 critical 概念,任一步失败即 `wf.Status=failed` 整体终止(`workflow.go:339`)。补 `Critical *bool`(默认 critical)+ 非关键步骤失败转 `degraded` 记录继续推进,对齐 rdev `SkipHint` 的 skippable 语义 |
| **A6** | 并行 trace 序号读-算-写竞态 | **不做(已修复)** | `workflow.go:582-596`:`traceSeq := len(LoadTrace)+1` 与 `AppendTrace` 均在 `mu.Lock()` 临界区内(`&mu` 传入 `runOneStep`);并行组共享同一把锁。backlog 描述的竞态在现行代码不存在 |
| **D5** | KB 按环境隔离评估 | **不做(维持共享)** | 三环境共享 `shuimu-kb-shared` 为 intentional 架构(`docker-compose.shared.yml` 专有数据卷);KB 为纯只读法规库(`internal/kb` 无写路径),隔离收益低、运维成本高(数据卷×3)。评估结论:维持现状 |
| **R1** | N/A 不适用页生成模式 | **不做(另立任务)** | 需 manifest 不适用标记 + bizdev N/A 生成路径 + squad 编排 + 前端规划 UI 四处联动(跨 3 模块大改)。现 `SkipHint` 元数据已就位(`rdev_stage_meta.go`),属完整 feature 应独立认领 |
| **R4** | depends_on 精确血缘 | **不做** | 依赖 manifest 落地后的 upstream 声明表(backlog 自注前置条件未满足) |
| **R5** | DMR 双记录归档 | **不做** | 本仓库无云盘;需 docgov 元数据扩展设计,低优先级 |
| **R6** | `sw_` 前缀盘点 | **不做** | backlog 自注「并入 P4 或其后」;P4(锁批)已收口,此尾巴无实际运行问题 |
| **R7** | 高复杂度 regulatory 注入 | **不做** | S2 批已实现 `TestRDevRegulatoryFollowsComplexityTier`(`complexity_tier` 动态注入已落地);backlog 描述与现状不符,可关账 |
## 本批实施(B5 + A5)
### B5 报价复核与校验
- `quote.Input` 校验:客户/产品名非空;Hours 非空、每个值 ≥0 且非 NaN/Inf;模板存在。
- 计算不变式复核:行合计(PersonYear/Cost/Buffer/Margin/Tax/Price)= 总计;费率组合自洽(buffer 20%、margin 40%、tax 7% 以代码常量复核重算对比)。
- 违规 fail-closed 返回 error,不产出畸形 Excel。
### A5 非关键步骤降级
- `StepSpec.Critical *bool`(nil=critical 默认,显式 false=非关键)。
- 非关键步骤失败:trace 记录 `Success=false`、步骤 `status=degraded`(非 `failed`)、工作流继续;全部完成后 `wf.Status=degraded`(非 `failed`),`WorkflowExecutionResult.Success=true` + `DegradedSteps` 列表。
- 关键步骤失败行为不变(立即终止)。
## 验证
- `go test ./internal/quote/ ./internal/squad/` 新增用例全绿 + 全量回归。
- 详见测试报告:[2026-09-25-p10-backlog-triage-test-report.md](../../test-reports/2026-09-25-p10-backlog-triage-test-report.md)
@@ -0,0 +1,45 @@
---
title: "P11: 未收口任务与 cleanup=pending 复查"
task_id: cleanup-audit-p11-2026-09-25
status: in_progress
created: 2026-09-25
owner: cursor-auto
task_type: research
task_tier: small
policy_revision: "agent-governance-2026-09-21-r1"
parent_task: backlog-triage-p10-2026-09-25
---
# P11: 未收口任务与 cleanup=pending 复查
## 执行记录(2026-09-25)
### P11a:ready 候选实清(已完成)
`agentctl cleanup report`:19 个 verdict=ready(全部 tasks done/cancelled = owner 退出、head 为 dev 祖先、registry 清、lifecycle idle)。逐个执行标准 `git worktree remove` + `git branch -d`,全部成功,无 --force / -D:
integrate-admin-settings-maint-c/d、integrate-backlog-triage-p10-r3、integrate-dialogue-context-layout-fix、integrate-dm-migration、integrate-fix-stage-brief-panic、integrate-gc-p1-closeout、integrate-governance-console-p1、integrate-planned-tasks-closeout-r2、integrate-security-redline-fp、integrate-single-binary-dev-impl-b、integrate-t20-b5-r2、integrate-t20-s2-r2、integrate-t20-s3、integrate-t20-s4、integrate-u9u12、integrate-websysadmin-r2、t20-b5-chat-observability(源)、t20-s4-image-batch(源)。
### P11b:blocked 项分类处置
| 类别 | 项 | 处置 |
|---|---|---|
| **含未合入功能**(head 非 dev 祖先且 patch-id 查重确认内容未以其他形式进 dev) | `doc-review-lifecycle-2026-09-25`(docgov 生命周期 lock/notify/comment/reopen + 对话触发,37+30 文件;任务表 done 但代码未集成,落后 dev 45 commits,需 rebase 评估冲突后另立集成任务);`dialogue-office-expansion-2026-09-25`(对话办公 P0–P3 全景计划文档);`member-permissions-doc-2026-09-24`(成员权限总览设计文档);`single-binary-deploy-design-2026-09-24`(非容器化设计收口);`promote-rc-beta3-c` / `sync-local-test-origin`(test 晋升/同步分支,含 rc tag 历史) | **保留**(worktree + 分支),登记为待评估集成/归档清单,不按年龄批量删 |
| **废弃集成候选**(integrate-* 非 dev 祖先:重试后被 r3 等替代) | integrate-admin-settings-maint-b、integrate-backlog-triage-p10(-r2)、integrate-gov-visibility-p0-b | 内容已由后续候选合入(如 P10 r3=3cefd5b1 已进 dev),分支删除前需逐个 `git log dev..HEAD` 确认无独有提交——已确认仅含 merge 提交或已被 dev 包含的等价内容 |
| **可再生缓存**(dirty = `!!` 前缀 ignored 文件:`.codegraph/`、`scripts/__pycache__/`、`internal/server/data/`、`web/dist/`) | 大量源 worktree | 登记后处理:`.codegraph` 可 `codegraph sync` 重建;`internal/server/data/` 为运行产物;唯一日志(`handoff-e2e.log`、`focused-security-tests.log`)**先归档** `.doc/test-reports/assets/` 对应目录后才能删 worktree |
| **进程占用** | admin-env-settings-maintenance(pid 3484192 = `/tmp/TestRealFDHandoffE2E.../stubserver` 遗留测试进程);u9u12-keys-rollout(pid 3386059 = bash rcfile 孤儿 shell) | 遗留测试 stub 进程待确认无父服务后终止;孤儿 shell 属用户会话,不动 |
### P11c:CURRENT 残留行
- `intent-plan-i2-rollout-b-2026-09-24` / `intent-plan-i2-impl-2026-09-24` 两行 CURRENT 标 `in_progress`,但任务表已 `done`、worktree 已删(早前批次清理)。属共享文档行状态漂移;因 `own_row_only` 规则需以该任务身份修改而 worktree 已不存在,归入收口审计(P14)统一处置(CURRENT 历史「只迁移、不删除」原则下移入历史区或以 admin 能力任务修正)。
- `worktree-cleanup-closeout-2026-09-24` 行 `in_progress`,任务表 `done`、worktree 在 blocked 清单(仅缓存脏)。同上处置。
### P11d:copy-kb-to-localpg.sh 补登记
**结论:无需登记**。全仓与全部 git 历史均无 `scripts/copy-kb-to-localpg.sh`(`git log --all -- 'scripts/copy-kb*'` 为空)。上轮会话摘要的引用为误记;实际 KB 迁移脚本是 `scripts/migrate_shared_kb.sh`,已有登记(`.doc/test-reports/2026-09-07-regulatory-knowledge-base-integration-test-report.md` TC-KB-01)。
## 红线遵守
- 未用 `--force` / `-D` / 批量按年龄删除;每个删除前核对 owner-exit + ancestor。
- 唯一日志类未删(所在 worktree 保留待归档)。
- `cleanup=pending` 语义为操作状态,不是任务第六状态;本记录即复查证据。
@@ -0,0 +1,36 @@
---
title: "P12: 红线项登记与授权边界核查(只读)"
task_id: redline-audit-p12-2026-09-25
status: in_progress
created: 2026-09-25
owner: cursor-auto
task_type: research
task_tier: small
policy_revision: "agent-governance-2026-09-21-r1"
parent_task: cleanup-audit-p11-2026-09-25
---
# P12: 红线项登记与授权边界核查(只读)
依据总控 P12:「只登记与证据核查,不越权实施」。核查时点:2026-09-25,dev 服务 pid 2398019(`bin/agent-server`,schema 72,health ok)。
## 逐项核查结果
| 红线项 | 运行态证据 | 结论 |
|---|---|---|
| **FAV live 不放量** | 服务进程环境无 `FAV_DEGRADED_READ`(默认 false,`config.go` FAVDegradedRead default false);无 `Register(fav)` 启用 | ✅ 维持红线;观察窗计时未启动(staging 未放量),无到期待核项 |
| **SWBOOT-10 fail-closed stub** | `internal/swboot/catalog.go`:`controlled_patch` 仍返回 `ERR_EXECUTION_MODE_DISABLED: controlled_patch requires SWBOOT-10 executor`(L209);无 SWBOOT 环境变量 | ✅ 维持 fail-closed;L5/L6 真实 patch/merge/push 授权申请**未提出**——继续 pending auth(与 [2026-09-22 红线证据](./2026-09-22-redline-evidence.md) 登记一致) |
| **D7 不物理删** | ADR `2026-09-17-d7-chat-data-retention.md` 仍 `pending-compliance-signoff`;追踪表类别 `record` 无删除路径调用 | ✅ 红线维持;合规签字**仍未完成**,365/180/30 物理删除继续禁止;无新签字事件可追踪 |
| **PI 叙事 flag off** | `PI_CHANGE_REPORT_NARRATIVE` 未设(`flags.go` 默认 false);服务进程环境无此变量 | ✅ dev 维持 off。**授权申请登记**:dev 常驻开启需用户明确授权(涉及 PI 叙事生成路径常驻化),本批仅登记申请占位,不实施 |
| **`MULTI_INTENT_PLAN_TIER` 不升 full** | 服务进程无 `MULTI_INTENT_PLAN_TIER`(进程仅有 `MULTI_INTENT_ENABLED=true` 与 `INTENT_V2_DECISION_TIER=none`) | ✅ 未升 |
| **F4-B/F7-1/I6/I7 未授权不实施** | 无对应实现提交(本 goal 各批次未触碰) | ✅ 维持 |
## 授权申请登记(待用户裁决,非本批实施)
1. **SWBOOT L5/L6**:真实 patch/merge/push 执行器实施授权——前置条件:安全评审(W5b)+ 用户明确授权;当前仅 stub。
2. **PI 叙事 dev 常驻开启**:`PI_CHANGE_REPORT_NARRATIVE=1` 于 dev 环境——前置条件:PI 叙事 E2E 证据复核 + 用户授权;建议独立任务执行。
## 边界遵守
- 本任务零代码变更、零 flag 翻转、零环境写入;全部结论来自只读核查(源码 + `/proc/<pid>/environ` + health 端点)。
- 与 CURRENT「受控约束」四条(FAV/tier/D7/main)逐条对账一致。
@@ -0,0 +1,94 @@
---
title: "已规划任务总控:批次计划与推进"
task_id: planned-tasks-closeout-plan-2026-09-25
status: in_progress
created: 2026-09-25
updated: 2026-09-25
owner: Cursor
task_type: planning
policy_revision: "AGENTS.md + agent-worktree-workflow @ 725181de"
branch: feature/planned-tasks-closeout-plan-2026-09-25
worktree: .worktrees/planned-tasks-closeout-plan-2026-09-25
base_dev_sha: "725181de4aa4480f77c52e40eeaef040c6563c3f"
write_scope:
- .doc/ops/short-term/2026-09-25-planned-tasks-closeout-plan.md
mutex: planned-tasks-closeout
review_state: pending
integration_state: pending
deployment: not_required
cleanup: pending
remote_sync: not_requested
---
# 已规划任务总控:批次计划与推进
## 用户目标与授权
- 用户 `/goal`(2026-09-25):把 [盘点](#盘点来源) 出的「已规划未开工 / 未收口」任务全部规划并推进至完成。
- 红线边界不变:SWBOOT-10 stub、FAV 不 live、D7 不物理删、PI 叙事 flag off、`MULTI_INTENT_PLAN_TIER` 不升 full、F4-B/F7-1/I6/I7 未授权不实施。
- 授权内自主推进;每个实施批次独立 task_id + worktree + 验证证据;本总控只写本文件(scope 已收窄避免与活跃任务 `.doc` 宽 scope 假冲突)。
## 盘点来源
FEATURE-MATRIX(SSOT)非 done 行、CURRENT 并行认领表、`2026-09-19-audit-remainder` T20 区、两份 backlog、各任务文五状态。盘点结论见对话记录;本文件将其转为可执行批次。
## 批次总表
| 批 | 内容 | 来源 | 依赖/互斥 | 状态 |
|----|------|------|-----------|------|
| **P0** | 存量 panic 修复:`engine_stage.go:306` 裸解引用 `stageRes.AdvisorBrief`(空产物时 nil deref,dev 基线复现)+ `matchAdvanceStage` 疑问句误判(`做.*报价` 命中问句) | 本总控新发现(属 audit-remainder M3/M5 家族) | ~~blocked:scope 被 dialogue-r2 硬占~~ **已解锁**:持有者收口后经 `dialogue-context-layout-fix` 布局修正合入 dev(`1da17a28`),P0 随后 validate+integrate 落地(dev `12bbe948`) | **done** |
| **P1** | docrev `management-implementation-plan` 收口核对:11 条验收逐条映射既有证据(Wave1–5 + Round20 UI + DOCREV rerun),产出勾选或残差清单;无法证明的条目列为显式残差,不假勾 | CURRENT 焦点1「仍方案态」 | 只读核对 + 文档更新;mutex `docgov` | pending |
| **P2** | T20 S1 小改批:B11(GET 禁 message)、F1(loadOlder generation)、F8(poll 去重+blob revoke)、F4-A(隐藏死按钮) | [T20 设计](../../system-design/2026-09-22-t20-hardening-design.md) 实施拆批 S1 | mutex `web`;无环境写 | pending |
| **P3** | T20 S2 配置/池批:B1(XFF 可信代理)、B4(statement_timeout 分级)、B7(SHUTDOWN_DRAIN 对齐) | 同上 S2 | mutex `server`/`infra`;需回归 | pending |
| **P4** | T20 S3 锁批:B3(docgov/docrevision 分锁 + 锁外 hydrate) | 同上 S3 | mutex `docgov`;独立大改,`go test -race` | pending |
| **P5** | T20 S4 镜像批:I1(非 root + limits)、I4(init mount 统一)——代码/compose 可合;共享环境部署另授权 | 同上 S4 | mutex `infra`;部署不自动 | pending |
| **P6** | T20 观测:B5(FailChatTurn 可观测 + 孤儿扫描) | 同上 | mutex `chat` | pending |
| **P7** | Server 镜像字段增量收口(module-batches-ag 剩余「另立任务」) | MATRIX `module-batches-ag` 行尾注 | mutex `module-decoupling-spec` | pending |
| **P8** | U9–U12 剩余键逐键放量:`document.review.approve/reject`、`document.final.*`、`document.proposal.decide`、`workflow.switch`、`run.restart`(validated_only,逐键独立 flag + 真实 PI 证据,禁 full 一次放量) | MATRIX `intent-plan-u9u12` 行尾注 | mutex `intent-plan`;每键独立任务 | pending |
| **P9** | web-sysadmin 残差:Playwright 实跑、KB 运维动作、白名单项接消费方 | MATRIX `web-sysadmin` 行尾注 | mutex `web+sysadmin` | pending |
| **P10** | backlog 价值评估 + 择优实施:B5 报价复核、A5/A6 小队降级、D5 KB 隔离评估、R1/R4–R7 rdev 增强 | 两份 backlog | 逐项评估后定做/不做及理由 | pending |
| **P11** | 未收口任务推进:`intent-plan-i2` 两行、`worktree-cleanup-closeout`、cleanup=pending 批量复查(`cleanup report` 门禁) | CURRENT 表 | `cleanup report` 只读盘点先行 | pending |
| **P12** | 红线项推进至授权边界:FAV 观察窗计时核查、D7 合规签字追踪、SWBOOT L5/L6 授权申请登记、PI 叙事 dev 常驻开启申请登记——只登记与证据核查,不越权实施 | CURRENT 受控约束 | 只读 | pending |
## 执行顺序与理由
1. **P0 先行**:dev 基线 panic 是所有后续 `go test` 的噪音源,必须先修。
2. **P1 只读核对**并行做(不占代码 mutex)。
3. **P2(S1 小改)** → **P3(S2)** → **P6(B5)**:按设计文档优先级 P1 软件项排完。
4. **P4(B3 锁)**独立大改单独排。
5. **P5(I1/I4)**代码层完成后停在「待部署授权」。
6. **P7–P9** 各自独立,按 mutex 空闲插入。
7. **P10 评估先行**,产出做/不做决策再实施。
8. **P11 cleanup** 用 `agentctl cleanup report` 机器门禁复查,不手工删。
9. **P12** 全程只读登记。
## 每批验收口径
- 代码批:`go test`(含 `-race` where applicable)+ 工程/产品分层按 [验证契约];报告落 `.doc/test-reports/`。
- 文档批:链接可达、状态真实、无假勾选。
- 红线批:只登记 blocker 与授权申请,不实施。
- 合入:`validate` → `queue enqueue`(daemon ff-only),串行。
## 状态机
| 字段 | 值 |
|---|---|
| review_state | done(P0 已合入 dev `12bbe948`) |
| integration_state | partial(P0 done;P1–P12 待续) |
| deployment | not_required |
| cleanup | pending |
| remote_sync | not_requested |
## 进展日志
- 2026-09-25:建场、盘点转批次、P0 根因定位(`engine_stage.go:306` nil deref,空 `executedArtifacts` 时 `stageBrief=nil`;dev@725181de 复现 `TestBizDev_CaseRecommendation_FullLink_E2E` panic)。
- 2026-09-25:P0 双层修复完成并全绿(nil 保护 + `isInterrogative` 疑问句排除;新增回归 `TestCoordinatorEngine_AdvanceStageNilBriefNoPanic`;intent/coordinator/bizdev/squad/dialoguectx/conflictresolve/ctxmgr 全 PASS,chat 存量失败 `TestChatSession_SemanticMemoryRecallAndAsyncTurnRecord` 为基线同款)。**落地受阻**:catalog hard same_scope(持有者任务未收口,hard 不可 ack)→ 补丁与测试报告存 `~/fix-stage-brief-panic-patches/`,登记 blocked 待持有者收口后落地。
- 2026-09-25:存量遗留新登记:chat 语义记忆异步轮记录用例失败(dev 基线同款),候选批次。
- 2026-09-25:**P0 落地**:`dialogue-context-injection-2026-09-25-r2` 经布局修正(r1/r2 行移表尾,`docs apply @document` + 新任务 `dialogue-context-layout-fix-2026-09-25` 持 docs:admin)解除 integrate 相邻插入冲突,merge 一枪成功合入 dev(`1da17a28`)。P0 补丁随即 apply 到 `fix-stage-brief-nil-panic-2026-09-25` worktree,`go test ./internal/coordinator/... ./internal/intent/...` 全 PASS(含新增回归 `TestCoordinatorEngine_AdvanceStageNilBriefNoPanic`),validate+integrate 合入 dev `12bbe948`(5 文件 +231 行:nil 保护、疑问句门控、回归测试、任务文与测试报告)。
## 相关链接
- 盘点对话:本轮 /goal 前置盘点
- T20 设计:[../../system-design/2026-09-22-t20-hardening-design.md](../../system-design/2026-09-22-t20-hardening-design.md)
- docrev 方案:[../../remediation/2026-09-13-document-revision-management-implementation-plan.md](../../remediation/2026-09-13-document-revision-management-implementation-plan.md)
- 验证契约:[../2026-09-21-validation-contract.md](../2026-09-21-validation-contract.md)
@@ -0,0 +1,83 @@
---
title: "P7: Server 镜像字段增量收口"
task_id: server-image-field-closeout-r3-2026-09-25
status: in_progress
created: 2026-09-25
updated: 2026-09-25
owner: cursor-auto
task_type: implementation
task_tier: small
policy_revision: "agent-governance-2026-09-21-r1"
branch: feature/server-image-field-closeout-2026-09-25
worktree: .worktrees/server-image-field-closeout-2026-09-25
base_dev_sha: "44161d2ad2d7aada3e9ff88127b52148543278e5"
write_scope:
- internal/server/
- internal/app/
- internal/storage/
- deploy/postgres/goose/
- .doc/ops/short-term/
- .doc/test-reports/
allowed_environments: []
head_sha: ""
mutex: module-decoupling-spec
review_state: pending
integration_state: pending
deployment: not_required
cleanup: pending
cleanup_owner: independent maintainer after owner exit
cleanup_trigger: acceptance green + optional owner exit
remote_sync: not_requested
---
# P7: Server 镜像字段增量收口
## 用户目标与授权
- 用户目标:`/goal 把这些任务都进行规划,并推进至完成` → 总控 [P7 批次](./2026-09-25-planned-tasks-closeout-plan.md)。
- 来源:MATRIX `module-batches-ag` 行尾注「Server 镜像字段增量收口另立任务」;[batch A 残留债务表](./2026-09-22-server-assembly-cleanup.md)「`gov` 等镜像字段:迁完用例前保留镜像」。
- 交付终点:删除 `Server` 全部 Runtime 镜像字段、短测+race 绿、arch-check PASS、可合入 dev。
- 禁止项:不 push;不改 HTTP 状态码语义;不动 FAV live / production_ready。
## 开工检索
- `matrix|镜像字段|module-batches-ag` → [ISSUES](../../audit/ISSUES.md) 无命中;[lessons INDEX](../lessons/INDEX.md) 无命中。
- 采纳检查:全仓 grep(镜像字段访问 `s.X` 穷举 485 处)+ 基线 race 复测(临时 worktree 对照)。
## 实施内容
1. **删除 `Server` 24 个 Runtime 镜像字段**(`svc/pwSvc/rec/engine/authSvc/taskRuns/authorizer/authzSvc/wfDefSvc/instSvc/notifySvc/resolver/wsCap/cmds/stageflow/gov/rev/ctxMgr/cas/freeDoc/kb/sysadmin/maintenance` 及 stop 通道),`NewFromRuntime` 装配行同步删除。
2. **新增 `internal/server/runtime_accessors.go`**:同名 nil 安全访问器(`s.gov()` → `s.rt.Gov`),集中承接领域服务访问;测试注入走 `serverTestOverrides` + `setOverride*` setter(显式 nil 经 `authorizerNil`/`instSvcNil` 位标记支持 fail-closed 用例)。
3. **574 处调用点机械替换** `s.X`/`srv.X` → `s.X()`/`srv.X()`(脚本 + 编译核对)。
4. **附带修复(既有债务撞车)**:
- `Shutdown` 与 4 个后台循环(sweeper/publisher/reminder/wsGC)对 stop 通道的 DATA RACE——dev 基线 `44161d2a` 复测同样失败(`chat_turn_sweeper.go:21` vs `server.go:471`)。新增 `backgroundLoop`(mutex + `sync.Once` 通道),通道只在 loop goroutine 内创建持有,`Shutdown` 经 `stop()` 通知。
- **goose 00071 版本号冲突**:`1da17a28` dialogue 合并同时带入两个 `00071_*`(maintenance-windows、context-conflict-adjudications),goose sort panic 阻塞全仓 `go test`。dev 库(`agent_system_dev@5433`)已应用至 00070、两个 00071 均未应用 → `context-conflict-adjudications.sql` 重编号 `00072`,零数据迁移。
- **`ListProjectRefs` 内存模式排序缺失**:map 迭代顺序随机令「同 SHA 首条引用不标 dedup」判定不稳定(`TestUploadProjectAsset_DedupHint` 20 轮 2 失败复现)。内存路径补 `sort.Slice(by ID)` 与 PG `ORDER BY id ASC` 对齐,修复后 30 连跑全绿。
5. `task_finalize_test.go` 改用 `newMinimalRuntime`(仅测试所需字段的 `app.Runtime`)。
## 非目标
- 迁移 handler 到 `internal/app` 用例层(batch-plan 原愿景):本批完成镜像字段删除后,`app.Runtime` 已是唯一服务持有者,后续用例迁移不再受镜像字段干扰。
- `supplementImpact` 字段保留:本包接口类型非 Runtime 镜像。
- `intentPlans` 测试 override 经 `intentPlansOverride` 字段(setter 语义无法用访问器表达)。
## 验证与证据
| 范围 / 被测 SHA | 命令与环境 | 预期 | 实际 / 判定 | 证据 |
|---|---|---|---|---|
| server 包短测 | `go test -short -count=1 ./internal/server/` | PASS | PASS(19.9s) | 本机 Linux |
| server 包 race | `go test -race -short -count=1 ./internal/server/` | PASS | PASS(232s,含既有 race 修复后) | 基线 `44161d2a` 同用例 FAIL(DATA RACE)已复测留证 |
| 相邻包 | `go test -short ./internal/app/... ./internal/chat/... ./internal/intent/...` | PASS | PASS 全 12 包 | |
| 全仓 short | `go test -short -count=1 ./...` | PASS | PASS(含 goose 00072 修复后 bizdev-cli) | 基线因 00071 重复 panic |
| 架构门禁 | `./scripts/arch-check.sh --mode block` | PASS | PASS | |
| 工程工具 | `python3 -B -m unittest discover -s scripts/tests` | PASS | PASS 234 tests | |
## 收口与交接
- 本地提交 / 待 validate + integrate 合入 dev / 不部署 / 不 push。
- 详见测试报告:[2026-09-25-p7-server-image-field-closeout-test-report.md](../../test-reports/2026-09-25-p7-server-image-field-closeout-test-report.md)
## 相关链接
- 总控计划:[2026-09-25-planned-tasks-closeout-plan.md](./2026-09-25-planned-tasks-closeout-plan.md)
- 债务来源:[2026-09-22-server-assembly-cleanup.md](./2026-09-22-server-assembly-cleanup.md)
@@ -0,0 +1,44 @@
---
title: "阶段推进 AdvisorBrief 空指针 panic 修复"
task_id: fix-stage-brief-nil-panic-2026-09-25-r2
status: in_progress
created: 2026-09-25
owner: Cursor
task_type: fix
policy_revision: "AGENTS.md @ 725181de"
branch: fix/fix-stage-brief-nil-panic-2026-09-25(实施并入 dialogue-context-injection-2026-09-25 scope 持有者 worktree)
worktree: .worktrees/fix-stage-brief-nil-panic-2026-09-25(注册用)/ 实际代码在 .worktrees/dialogue-context-injection-2026-09-25
base_dev_sha: "725181de4aa4480f77c52e40eeaef040c6563c3f"
write_scope:
- internal/coordinator/engine_stage.go
- internal/coordinator/engine_test.go
- internal/intent/recognizer_matchers_task.go
- .doc/test-reports/2026-09-25-stage-brief-nil-panic-fix-test-report.md
mutex: coordinator-nil-panic-fix
review_state: accepted_with_evidence
integration_state: pending
deployment: not_required
cleanup: pending
remote_sync: not_requested
---
# 阶段推进 AdvisorBrief 空指针 panic 修复
## 用户目标与授权
- 总控 `/goal`(2026-09-25)批次 P0:消除 dev 基线存量 panic。
- scope 冲突处置:`internal/coordinator` 被 `dialogue-context-injection-2026-09-25-r2` 声明(hard same_scope),按 catalog 规则「合并到持有者任务」——修复作为独立提交挂入持有者 worktree 分支。
## 修复内容
1. **panic**:`engine_stage.go` `stageRes.AdvisorBrief` nil 保护 + 降级文案。
2. **意图误判**:`matchAdvanceStage` 前置 `isInterrogative` 疑问句排除(问句不构成推进指令)。
3. **回归测试**:`TestCoordinatorEngine_AdvanceStageNilBriefNoPanic`。
## 验证
见 [测试报告](../../test-reports/2026-09-25-stage-brief-nil-panic-fix-test-report.md):PASS。
## 残差
- `internal/chat` 的 `TestChatSession_SemanticMemoryRecallAndAsyncTurnRecord` 存量失败(dev 基线同款,非本批引入),登记后续批次。
@@ -0,0 +1,47 @@
---
title: "T20 B5:chat 回合补偿可观测与孤儿扫描"
task_id: t20-b5-chat-observability-2026-09-25
status: in_progress
created: 2026-09-25
updated: 2026-09-25
owner: Cursor
task_type: hardening
policy_revision: "AGENTS.md @ 088ff307"
branch: feature/t20-b5-chat-observability-2026-09-25
worktree: .worktrees/t20-b5-chat-observability-2026-09-25
base_dev_sha: "088ff307c0c4c27cd1d1635c79227408c437346e"
write_scope:
- internal/ctxmgr
- internal/chat
mutex: chat+ctxmgr
review_state: done
integration_state: pending
deployment: not_required
cleanup: pending
remote_sync: not_requested
---
# T20 B5:chat 回合补偿可观测与孤儿扫描
## 用户目标与授权
- 来源:`planned-tasks-closeout-plan-2026-09-25` P6 批次;设计 [T20 B5](../../system-design/2026-09-22-t20-hardening-design.md#b5--chat-消息与-turn-原子性)。
- 按「本阶段不强制同事务」决策:加固既有补偿 + 补可观测 + 孤儿批量清理。
## 变更清单
| 项 | 变更 | 文件 |
|----|------|------|
| 补偿可观测 | `FailChatTurn`/`CompleteChatTurn` 失败时 `slog.ErrorContext` 结构化日志(`chat_turn_fail_compensation_failed` / `chat_turn_complete_failed`),不再静默 `_ =` | `internal/ctxmgr/chat_turns.go` |
| 孤儿扫描 | 新增 `SweepExpiredProcessingTurns(ctx, limit)`:PG 路径批量 `UPDATE ... WHERE status=processing AND lease_expires_at<now()`(批上限 + ASC 排序);内存路径同语义;扫到记 `chat_turn_sweep_expired_processing` WARN | 同上 |
| 周期调度 | Server 启动 `startChatTurnSweeper`:2 分钟间隔、批 200、单次 30s 超时;Shutdown 关闭 | `internal/server/chat_turn_sweeper.go`、`internal/server/server.go` |
## 回归测试
- `TestSweepExpiredProcessingTurns_Memory`:过期 processing→failed;fresh/completed 不动;幂等(二次扫描 0)。
- 既有 `TestAcquireChatTurn_*` 家族不回归。
## 边界确认
- 不改 `AcquireChatTurn` 幂等/租约语义(`client_turn_id` 重放仍拒绝双写助手)。
- 「用户消息已写、turn 未绑定」孤儿告警为后续可选项(设计文档 2.3 条),本批未做——依赖真实失败注入数据。
@@ -0,0 +1,59 @@
---
title: "T20 S1 小改批:B11/F1/F8/F4-A"
task_id: t20-s1-small-fixes-2026-09-25
status: in_progress
created: 2026-09-25
updated: 2026-09-25
owner: Cursor
task_type: fix
policy_revision: "AGENTS.md + agent-worktree-workflow @ 725181de"
branch: feature/t20-s1-small-fixes-2026-09-25
worktree: .worktrees/t20-s1-small-fixes-2026-09-25
base_dev_sha: "725181de4aa4480f77c52e40eeaef040c6563c3f"
write_scope:
- internal/server
- web/src
mutex: web+server
review_state: done
integration_state: pending
deployment: not_required
cleanup: pending
remote_sync: not_requested
---
# T20 S1 小改批:B11/F1/F8/F4-A
## 用户目标与授权
- 来源:`planned-tasks-closeout-plan-2026-09-25` P2 批次;用户 `/goal` 授权批量推进。
- 设计依据:[T20 加固设计](../../system-design/2026-09-22-t20-hardening-design.md) S1 行(B11/F1/F8/F4-A,均「无环境写」)。
## 变更清单
| ID | 变更 | 文件 |
|----|------|------|
| B11 | GET `/api/v1/chat/stream` 带 `message` query → 400 指向 POST;GET 分支不再读 `message`(保留订阅型参数) | `internal/server/sse.go` |
| F1 | `loadOlder` / `loadFullDay` / `jumpToDate` 入口捕获 `generationRef.current`,resolve 后比对丢弃晚到响应;失败日志与 `setPhase` 同样受 gen 门控 | `web/src/hooks/useChatWindow.ts` |
| F8-a | run 轮询 in-flight 合并(`Map<runId, Promise>`)防慢请求重叠;卸载清理 | `web/src/App.tsx` |
| F8-b | `fetchChatCategories`/`fetchChatDates` 绑定 `statsGenRef`;切会话旧 stats 不落地 | `web/src/App.tsx` |
| F8-c | 导出 Markdown blob URL 统一 `try/finally revoke` | `web/src/App.tsx` |
| F4-A | 移除 UsersSection「重置密码」死按钮(服务端端点未开通);注释引导 F4-B 产品选型后重建 | `web/src/components/admin/console/sections/UsersSection.tsx` |
## 回归测试
- `TestChatStream_GetMessageQueryRejected`:GET+message → 400 且文案指向 POST。
- `TestChatStream_GetWithoutMessageNotLeak`:无 message GET → 400(empty message 统一拒绝),不产生 SSE 头。
- `useChatWindow.loadOlder.race.test.ts`:切会话后 loadOlder 晚到 resolve 不写 dayStack/cache。
## 验证记录
- `go build ./internal/server/...` PASS。
- `go test ./internal/server/ -skip 'TestPiAgent_FullLifecycle'` PASS(20.5s;被 skip 项为 KB 离线环境依赖,dev 基线同款失败,与本批无关)。
- `tsc --noEmit`:仅剩 `EnvSettingsSection.tsx(151)` TS6133 —— dev 基线同款(主目录同报),非本批引入。
- node `--test` loadOlder race:1 pass。
- 既有 `useChatWindow.race.test.ts`(主窗口竞态)不回归。
## 边界确认
- F4-B(服务端重置端点)未实施——需产品选型,见设计文档 F4 表。
- 未动 `EventSource` 前端调用(`web/src/api/chatStream.ts` 已是 POST)。
@@ -0,0 +1,51 @@
---
title: "T20 S2 配置/池批:B1/B4/B7"
task_id: t20-s2-config-pool-2026-09-25
status: in_progress
created: 2026-09-25
updated: 2026-09-25
owner: Cursor
task_type: hardening
policy_revision: "AGENTS.md + agent-worktree-workflow @ c0e556b1"
branch: feature/t20-s2-config-pool-2026-09-25
worktree: .worktrees/t20-s2-config-pool-2026-09-25
base_dev_sha: "c0e556b1679ebf8032459c53219af361a27e8a50"
write_scope:
- internal/server
- internal/db
- cmd/server
- deploy
mutex: server+infra-config
review_state: done
integration_state: pending
deployment: not_required
cleanup: pending
remote_sync: not_requested
---
# T20 S2 配置/池批:B1/B4/B7
## 用户目标与授权
- 来源:`planned-tasks-closeout-plan-2026-09-25` P3 批次;设计依据 [T20 加固设计](../../system-design/2026-09-22-t20-hardening-design.md) S2 行。
- 均为「无环境写」的代码/配置层改动;compose 变更只入 Git,不部署(部署另授权)。
## 变更清单
| ID | 变更 | 文件 |
|----|------|------|
| B1 | `clientIP` 仅当 `RemoteAddr` 落入 `TRUSTED_PROXY_CIDRS` 时解析 XFF(最右非可信跳);空配置忽略一切 XFF;裸 IP 自动 /32 | `internal/server/login_rate_limit.go` |
| B4 | 新增 `internal/db/pool.go`:`PoolProfile`(default 30s / migrate 0)+ `OpenAppPool` 统一入口(`RuntimeParams.statement_timeout` + `MaxConns` 可配);`bizdev.NewService` 改走 `OpenAppPool(DefaultProfile())` | `internal/db/pool.go`、`internal/bizdev/service.go` |
| B7 | `cmd/server/main.go` drain 窗口 = `SHUTDOWN_DRAIN_TIMEOUT` 显式覆盖或 `min(AGENT_TIMEOUT,35m)+30s`;三环境 compose `stop_grace_period: 35m30s`(可 `SHUTDOWN_DRAIN_GRACE` 覆盖) | `cmd/server/main.go`、`docker-compose.{dev,test,main}.yml` |
## 回归测试
- `TestClientIP_*` ×4 + `TestParseTrustedProxyCIDRs_Formats`:伪造 XFF 直连不得改变限流 key;可信代理链解析正确。
- `TestDefaultProfile/TestMigrateProfile/TestOpenAppPool_SetsRuntimeParams/TestLongStatementTimeout/TestOpenAppPool_InvalidDSN`。
- `TestShutdownDrainTimeout_*` ×5:封顶/跟随/覆盖/非法回落/nil 配置。
- 三环境 `docker compose config --quiet` 全过(修正 main.yml 双依赖服务插入点)。
## 边界确认
- 旧 5s→10s Shutdown 硬编码移除;不部署(P5 镜像批一并授权后生效)。
- 业务 SQL 无散落 timeout 改动(按设计「池默认 + SET LOCAL」原则,long 路径后续按需 `SET LOCAL`)。
@@ -0,0 +1,69 @@
---
title: "T20 S3 锁批:B3 docgov/docrevision 分锁"
task_id: t20-s3-lock-split-2026-09-25
status: in_progress
created: 2026-09-25
updated: 2026-09-25
owner: Cursor
task_type: hardening
policy_revision: "AGENTS.md @ d93c1ab3"
branch: feature/t20-s3-lock-split-2026-09-25
worktree: .worktrees/t20-s3-lock-split-2026-09-25
base_dev_sha: "d93c1ab3d685e988f4bfc3f09a84bfc1e25f3302"
write_scope:
- internal/docrevision
- internal/docgov
- .doc/ops/short-term/2026-09-25-t20-s3-lock-split.md
- .doc/test-reports/2026-09-25-t20-s3-lock-split-test-report.md
mutex: docgov/docrevision
catalog: R-t20-s3-lock-split(overlap 探测无硬/软重叠)
review_state: done
integration_state: pending
deployment: not_required(纯进程内并发改造,无部署面变化)
cleanup: pending
remote_sync: not_requested
---
# T20 S3 锁批:B3 docgov/docrevision 分锁
## 用户目标与授权
- 来源:`planned-tasks-closeout-plan-2026-09-25` P4 批次;设计 [T20 B3](../../system-design/2026-09-22-t20-hardening-design.md)(阶段 A)。
- 目标:单文档慢 DB 查询不再阻塞**全部**文档的修订/租约路径。
## 实现方式(阶段 A,行为不变)
### docgov(`internal/docgov`)
- 新增 `lock_split.go`:`docLockIndex`(`map[docID]*sync.Mutex` + meta 锁只保护分锁表)与幂等 `docLockGuard`。
- 迁移写路径为 `acquireDocLock(docID)`:`AcquireLease`/`ReleaseLease`/`HeartbeatLease`/`SaveDocumentContent`/`AssertLeaseFencing`/`CheckHumanCanEdit`/`AssertWritableForComment`/`AddComment`/`CreateOrGetDocument`/`LockDocumentDuty`/`MarkDocumentContentUpdated`/`SetDocumentWorkDir`/`RecordDocumentViewed`/`RecordDocumentEdited`/`CheckModificationPermission`/`SubmitForReview`/`ReviewApprove`/`ReviewReject`/`ApproverApprove`/`ApproverReject`/`ReopenForRevision`/`GetDocument`/`ListAuditLogs`/`ListComments`/`ProposeModification`。
- 提案决策类(`DecideModificationProposal`/`MarkProposalApplied`)以 `*proposal:<id>` 命名空间分锁。
- `ApproverApprove` 的 hook-out-of-lock 段改用 guard 释放/重取(替代原 `e.mu.Unlock()/Lock()`)。
- 全局 `e.mu` 保留:`loadDocumentFromDBLocked` 内部短临界区写 `memDocs`、hooks 注册、`materialize` 模板段与 `hasCanonicalSibling` 内存兜底——均为纯内存操作,无 DB RTT。
### docrevision(`internal/docrevision`)
- 新增 `lock_split.go`:同构 `docLockIndex` + `Service.lockDoc`。
- 全部公开入口改为 **doc 锁 → 全局 `s.mu`** 两段式(`GetRevisionState`/`ListVersions`/`GetVersionContent`/`ManualOverlay`/`GetCandidate`/`GetChangeReport`/`CommitHumanRevision`/`OpenTemplateVersion`/`EnsureBootstrap`/`CreateAgentCandidate`/`CommitAgentVersion`/`ImportFreeformLegacy`/`SetDocWorkDir`/`SetLifecycle`/`EnsureRoot`/`ReconcileDocument`/`CommitMigrationRepair`/`InspectProjection`/`HeadContent`/`projectOutputMarkdown`/`ContentProjectionPending`/`MarkContentProjected`)。
- hydrate 的 PG 查询仍在 doc 锁内(保证同文档 TOCTOU 语义),但**不再进入跨文档临界路径**——这正是 B3「单文档慢查询阻塞全部文档」的修复点。
- 锁序统一:`docLocks[docID] → s.mu`(与 docgov `docLocks[docID] → e.mu` 对称);`docLocks.meta` 仅在查表瞬间持有。
## 关键设计决策
1. **hydrate 保持在 doc 锁内**(而非完全锁外):`lockOpenVersionTX` 的 `FOR UPDATE` 行锁 + 乐观 head/etag 校验依赖「检查-写入」原子性;锁外 hydrate + 短临界区合并需要引入版本 CAS,超出阶段 A「行为不变」边界(设计文档亦将完整缓存化列为阶段 B)。
2. **`sync.Once` 幂等 guard**:防止 `ApproverApprove` 这类显式释放/重取模式下的双重 Unlock panic(首轮 race 测试捕获后修复)。
3. **提案命名空间锁**:提案不属于单一文档的互斥域(决策跨 doc + proposal 表),独立命名空间避免与 doc 锁混序。
## 验证
- `go test -race ./internal/...`:67 包全绿(含 docgov/docrevision/app 下游)。
- 新增 `lock_split_test.go` 三用例:
- `TestParallelHydrateDoesNotSerializeAcrossDocs`:docA 持锁期间 docB 可完成锁定(验收断言);
- `TestParallelSameDocStillSerialized`:同文档串行不放松(回归保护);
- `TestConcurrentDistinctDocsCommits`:4 文档×10 版并行提交链无交叉污染。
- 既有并发负例(`TestConcurrentHumanRevisions`、`document_commit_concurrency_pg_test` 所在包)随 67 包回归通过。
## 未做(明确边界)
- 阶段 B(PG 为 SSOT、内存缓存化、锁外 hydrate + 版本 CAS):设计文档标注「需单独容量评估」,不与本批绑定。
- `SaveDocumentContent` 的 `e.mu.Lock()` 中段保留为全局锁(原代码即两段式:AcquireLease(已分锁)→ 内容写段);该段无 DB hydrate,仅 persist 一条 UPDATE,非 B3 痛点。
@@ -0,0 +1,50 @@
---
title: "T20 S4 镜像批(代码层):I1/I4"
task_id: t20-s4-image-batch-2026-09-25
status: in_progress
created: 2026-09-25
updated: 2026-09-25
owner: Cursor
task_type: hardening
policy_revision: "AGENTS.md @ 42436f75"
branch: feature/t20-s4-image-batch-2026-09-25
worktree: .worktrees/t20-s4-image-batch-2026-09-25
base_dev_sha: "42436f754d904d7e54c2b0b0fd559a91b7889f17"
write_scope:
- deploy/app/Dockerfile
- docker-compose.dev.yml
- docker-compose.test.yml
- docker-compose.main.yml
mutex: infra-config
review_state: done
integration_state: pending
deployment: blocked_awaiting_authorization
cleanup: pending
remote_sync: not_requested
---
# T20 S4 镜像批(代码层):I1/I4
## 用户目标与授权
- 来源:`planned-tasks-closeout-plan-2026-09-25` P5 批次;设计 [T20 I1/I4](../../system-design/2026-09-22-t20-hardening-design.md)。
- **仅代码/compose 层合入**;共享环境部署需另授权(I1 卷权限冒烟须在部署窗口做)。
## 变更清单
| ID | 变更 | 文件 |
|----|------|------|
| I1 | Dockerfile 建 `appuser`(uid/gid 10001)、`chown /app`、`USER appuser`;compose app/events 服务 `mem_limit`/`mem_reservation`/`cpus`(dev 1.5g/2g、test 2g/1g、main 3g/1g app) | `deploy/app/Dockerfile`、`docker-compose.*.yml` |
| I4 | dev(context_init)与 main(goose baseline)统一改挂 `extensions_init.sql` → `01-extensions.sql`;表结构一律走 app goose 迁移 | `docker-compose.dev.yml`、`docker-compose.main.yml` |
## 验证
- `docker build --check`:无警告。
- 三环境 `docker compose config --quiet`:PASS;渲染含 `mem_limit/cpus/01-extensions.sql`。
- `USER appuser` 在 healthcheck/entrypoint 前生效。
## 部署边界(redline)
- **新卷首次启动顺序**:Postgres 扩展 init → app goose 迁移。已建数据卷不受挂载变更影响(init 脚本仅在空卷执行)。
- **宿主卷权限**:`data/*` 须对 uid 10001 可写;部署窗口先冒烟 `/health` + 一次写 data。
- I6(systemd 备份)不在本批;cap_drop ALL 列为后续可选。
@@ -0,0 +1,73 @@
---
title: "P8: U9–U12 剩余键逐键放量"
task_id: u9u12-keys-rollout-2026-09-25
status: in_progress
created: 2026-09-25
updated: 2026-09-25
owner: cursor-auto
task_type: implementation
task_tier: small
policy_revision: "agent-governance-2026-09-21-r1"
branch: feature/u9u12-keys-rollout-2026-09-25
worktree: .worktrees/u9u12-keys-rollout-2026-09-25
base_dev_sha: "9f7bbc25a05853aceecad4c60233fa8d38a8990a"
write_scope:
- internal/app/
- internal/app/intentflow/
- internal/config/
- .doc/ops/short-term/
- .doc/test-reports/
allowed_environments: []
head_sha: ""
mutex: intent-plan
review_state: pending
integration_state: pending
deployment: not_required
cleanup: pending
cleanup_owner: independent maintainer after owner exit
cleanup_trigger: acceptance green + optional owner exit
remote_sync: not_requested
---
# P8: U9–U12 剩余键逐键放量
## 用户目标与授权
- 用户目标:`/goal 把这些任务都进行规划,并推进至完成` → 总控 [P8 批次](./2026-09-25-planned-tasks-closeout-plan.md)。
- 来源:MATRIX `intent-plan-u9u12` 行尾注「未开放:`document.review.approve/reject`、`document.final.*`、`document.proposal.decide`、`workflow.switch`、`run.restart`(validated_only)」。
- 交付终点:逐键独立 flag + 真实引擎路由 + 单测验收 + 真实 dev PI 证据;**禁 full 一次放量**。
## 实施内容
1. **逐键 flag**(`intentflow/flags.go`):`U11LiveReview`、`U11LiveFinal`、`U11LiveProposal`、`U12LiveSwitch`、`U12LiveRestart`(env `MULTI_INTENT_U11_LIVE_REVIEW` 等,默认全 OFF)。域名总 flag 开启后细粒度键仍须单独打开。
2. **live 集合函数化**(`intentflow/expansion.go`):`DocGovLiveActionKeys()`/`RunControlLiveActionKeys()` 按当前 flag 动态返回;基线键(claim/review.submit、workflow.run/run.resume)不受影响。新增 `IsDocGovLiveKey`/`IsRunControlLiveKey` 判定。
3. **DocGovOwner 路由扩展**(`app/docgov_owner.go`):
- `document.review.approve` → `ReviewApprove`(RoleReviewer)
- `document.review.reject` → `ReviewReject`(RoleReviewer,reason 走 slots)
- `document.final.approve` → `ApproverApprove`(RoleApprover)
- `document.final.reject` → `ApproverReject`(RoleApprover,rollback→drafting)
- `document.proposal.decide` → `DecideModificationProposal`(proposal_id/approve slots;收据走 `commitReceipt`)
4. **RunControlOwner 路由扩展**(`app/run_control_owner.go`):
- `workflow.switch` → `ActivateWorkflow`(workflow_key slot 必填校验)
- `run.restart` → `CreateAndStart`(全新 run,不续 workspace,幂等键防重)
5. **policy 表**(`intentflow/policy.go`):7 个新键从 `TierFull` 提到 `TierConfirm`(confirm 档进计划;真实执行仍受 per-key flag 限制)。
6. **验收单测**(`app/live_keys_rollout_test.go`):默认 OFF 不入 live、逐键 flag 独立、review.approve 真实状态推进(reviewing→approving)+ 幂等重放、flag OFF 时 dry-run 零状态推进。
## 非目标
- 不改 tier 默认(仍 legacy);compose 不动。
- `run.resume` 已 live 无需动。
- 真实 dev 逐键 PI 证据:flag 打开后另行采集(见测试报告)。
## 验证与证据
| 范围 | 命令 | 结果 |
|---|---|---|
| P8 新用例 | `go test -short -run 'TestP8' ./internal/app/` | PASS |
| app/intent/coordinator 全量 | `go test -short ./internal/app/... ./internal/intent/... ./internal/coordinator/...` | PASS(13 包) |
| 架构门禁 | `./scripts/arch-check.sh --mode block` | PASS |
## 收口与交接
- 详见测试报告:[2026-09-25-p8-u9u12-keys-rollout-test-report.md](../../test-reports/2026-09-25-p8-u9u12-keys-rollout-test-report.md)
- 后续:dev 运维按键打开 flag(`configs/.env.dev`),采集真实 PI 证据后更新 MATRIX 行尾注。
@@ -0,0 +1,68 @@
---
title: "P9: web-sysadmin 残差收口"
task_id: websysadmin-residual-r2-2026-09-25 (r1 cancelled: scope missed internal/app)
status: in_progress
created: 2026-09-25
updated: 2026-09-25
owner: cursor-auto
task_type: implementation
task_tier: small
policy_revision: "agent-governance-2026-09-21-r1"
branch: feature/websysadmin-residual-2026-09-25
worktree: .worktrees/websysadmin-residual-2026-09-25
base_dev_sha: "c5027788ea72bc9488247c2c22dc67c511241fd6"
write_scope:
- internal/maintenance/
- internal/sysadmin/
- internal/server/
- internal/app/
- web/
- .doc/ops/short-term/
- .doc/test-reports/
allowed_environments: []
head_sha: ""
mutex: web+sysadmin
review_state: pending
integration_state: pending
deployment: not_required
cleanup: pending
cleanup_owner: independent maintainer after owner exit
cleanup_trigger: acceptance green + owner exit
remote_sync: not_requested
---
# P9: web-sysadmin 残差收口
## 用户目标与授权
- 用户目标:`/goal 把这些任务都进行规划,并推进至完成` → 总控 P9 批次。
- 来源:MATRIX `web-sysadmin` 行尾注「剩余 deferred:Playwright 实跑、KB 运维动作、白名单项接消费方」。
- 交付终点:三项残差处理完毕(做/不做+理由),验收绿。
## 残差处置
| 残差 | 处置 | 说明 |
|---|---|---|
| 白名单项接消费方 | **本批实施** | `ui.maintenance_notice` + `ui.read_only_mode` 接入维护状态公开端点与前端横幅 |
| Playwright 实跑 | **本批实施(docker 镜像通道)** | 宿主缺 libatk 系统库且无 sudo,改用 `mcr.microsoft.com/playwright` 官方镜像跑 `admin-console.spec.ts`(自带全部依赖) |
| KB 运维动作 | **登记不做** | KB 为纯只读检索客户端(`internal/kb` 无写路径),rebuild/index 属共享基础设施容器(`shuimu-kb-shared`)侧能力,超出本仓边界;一期只读口径维持,管理台 KB 分组补探活刷新即可 |
## 实施内容(白名单消费方接线)
1. `sysadmin.Service.GetSettingValue(key)`:白名单 key 只读解析(DB > env > default),供跨模块消费。
2. `maintenance.Service`:新增 `SiteSettingsProvider` 注入位(装配根从 sysadmin 解析,避免业务包反向依赖);`StatusView` 增加 `notice`/`readOnly` 字段;`CurrentStatus` 每次读取携带站点开关;新增 `CurrentSiteStatus`(无窗口时也可轮询)。
3. 装配根(`app.go`):`rt.Maintenance.SetSiteSettings(...)` 从 sysadmin 读 `ui.maintenance_notice`/`ui.read_only_mode`。
4. 新公开端点:`GET /api/v1/maintenance/site-status`(无需登录,同 status 口径)。
5. 前端 `MaintenanceBanner`:readOnly → 蓝色只读提示条;notice 非空且无窗口 → 黄色常驻公告横幅;类型 `MaintenanceStatus` 补两字段。
6. 顺手修:`EnvSettingsSection.tsx` 死变量 `dirty`(dev 基线既有 TS6133 构建阻断,单行删除不改行为)。
## 验证
- Go:`go build ./...` + `go vet` + `go test -short ./internal/maintenance/ ./internal/sysadmin/ ./internal/server/` 全绿(新增 3 个 site settings 用例)。
- Web:`npm test`(34/34)+ `npm run build` PASS。
- Playwright:docker 镜像通道跑 `admin-console.spec.ts`(证据见测试报告)。
## 非目标
- 不做 KB 写路径/重建编排(超边界,见上表)。
- 不改 `chat.default_session_role` 等其余白名单键(消费方属各自业务模块后续任务)。
@@ -0,0 +1,69 @@
# chat-semantic-replace fail-closed 灰度接线(short-term)
- **task_id**: chat-semantic-replace-2026-09-26
- **owner**: pi
- **status**: in_progress
- **授权来源**: 用户会话指令「把 FEATURE-MATRIX 中的 …chat-semantic-replace 完成;严格按规范」——构成该行关闭条件中要求的「用户独立授权」(Wave5 X-2 密封条件:启用 REPLACE 需独立显式授权 + fail-closed 灰度设计)
- **write_scope**: internal/ctxmgr, internal/sysadmin, .doc
- **mutex**: chat
- **base_dev_sha**: 4d5d695c75d8a59452fcb2946b0b1217553e0c4e
- **capabilities**: docs:publish, docs:approve, env:dev
- **policy_revision**: AGENTS 2026-09 / agent-worktree-workflow r1 / validation-contract 2026-09-21
- **review_state**: pending
- **integration_state**: pending
- **deployment**: pending
- **cleanup**: pending
- **remote_sync**: not_requested
## 一、当前进度分析
现状(dev):`SEMANTIC_SUMMARY_REPLACE` 可读但密封不接线——`shadow_task.go:274` 与 `semantic_summary.go:367` 显式 `_ = SemanticSummaryReplaceEnabled()` 不换叙事;sysadmin 目录登记为 placeholder。shadow 链路(durable jobs/租约/watermark/可见集 digest/provenance)已生产化且 2026-09-23 收口重验 PASS。
关闭条件:用户独立授权(本任务授权来源满足)+ **fail-closed 灰度设计**。本行声明范围仅「chat 会话 served Narrative」;daily digest headline 不在替换范围(保持 advisory)。
## 二、方案(fail-closed 灰度)
### 2.1 双开关(默认全关)
- `SEMANTIC_SUMMARY_REPLACE`(master,默认 false,语义不变)
- 新增 `SEMANTIC_SUMMARY_REPLACE_SESSIONS`:会话 ID 逗号分隔 allowlist。**allowlist 为空时不替换任何会话**(即使 master 开——纵深防御,误开 master 无全局影响)
### 2.2 替换点与条件(全部满足才换,任一失败保留 deterministic)
接线点:`shadow_task.go persistShadowProvenance`(后台 durable job 完成处,serve 前持久化):
1. master on 且 `session ∈ allowlist`
2. shadow report `Status == ok`(模型成功、结果 digest/watermark 校验通过)
3. `ValidateShadowWatermark` 通过(revision/visibility/watermark 与当前 served 摘要一致——不换旧摘要)
4. 叙事非空且 ≤ `semanticReplaceMaxRunes`(4096)——超限视为模型异常,fail-closed
替换动作:`current.Narrative = report.Narrative`;`current.Source = "semantic_replace"`;FreshnessNote 记录替换时间戳;Facts/计数保持 deterministic(声明范围仅 Narrative)。回滚:关 master(或摘除会话)+ 下一轮摘要自然回 deterministic(确定性摘要为消息纯函数)。
### 2.3 不变式
- 摘要请求仍 no-tool、R13 最小化授权可见集;替换不改变可见集 digest 校验
- daily digest(`applyDigestSemanticShadow`)继续 advisory-only
- 单测覆盖:off 保留 / 非空 allowlist 未命中保留 / 命中+OK 替换 / 命中+fallback 保留 / 命中+stale 保留 / 超长保留
- sysadmin 目录 REPLACE 行从 placeholder 改 live+allowlist 说明;features envs 列表补 allowlist 键
### 2.4 验证
- Go 单测(上述矩阵)+ `arch-check --mode block` + `go vet` + `go test -short ./...`
- dev 运行时验收:dev 会话开启 shadow+replace(allowlist) → 真实对话后 served Narrative 换为语义叙事(chat digest API 可见 Source=semantic_replace);同会话关 master → 下一轮回 deterministic;非 allowlist 会话不受影响
## 三、计划
1. [x] 分析(§一)
2. [x] 实现 §2(flags/allowlist/替换点/单测/sysadmin 目录;dev `cd1f846f`)
3. [x] 工程门禁 + 候选集成 dev(含回滚残留修复 `6004494e`)
4. [x] dev 运行时验收(替换/隔离/回滚无残留全 PASS;另修复 goose62 schema 漂移)
5. [ ] 测试报告 + 矩阵行更新 + 收口清理
## 四、结果登记
- **review_state**: done(单测 8/8 + 工程门禁 + 既有密封负例保持)
- **integration_state**: done(dev `cd1f846f` + `6004494e` --no-ff 候选集成)
- **deployment**: dev_runtime_verified(阶梯验收后已恢复默认关闭;compose/env 默认不变)
- **验证结论**: 见 [测试报告](../../test-reports/2026-09-26-chat-semantic-replace-test-report.md)
- **过程修复**: ①回滚残留(displaced_narrative);②dev localpg goose62 对象缺失按幂等 DDL 修复
- **cleanup**: 本任务 worktree 按门禁清理
- **remote_sync**: not_requested(本地 dev 前进,未 push)
@@ -0,0 +1,60 @@
# 降级功能开关放量 dev(short-term)
- **task_id**: degraded-flags-enable-2026-09-26-r4
- **owner**: pi
- **status**: in_progress
- **授权来源**: 用户会话指令「请将已经实现但是降级了的功能都启动」+ 追加确认(① dev 单二进制启动、不用容器;② SEMANTIC_SUMMARY_REPLACE 面向系统全部会话含后续新建;③ MULTI_INTENT_PLAN_TIER 保持 confirm)。该指令同时构成 docgov-pi-narrative 行「dev 常驻开启另授权」与 chat-semantic-replace 行「放量逐环境另授权(dev)」的显式授权。
- **write_scope**: internal/ctxmgr, internal/sysadmin, internal/config, docker-compose.{dev,test,main}.yml, .env.example, .doc/ops/CURRENT.md, .doc/ops/short-term, .doc/status/FEATURE-MATRIX.md, .doc/test-reports
- **mutex**: summary-flags-rollout
- **base_dev_sha**: 66ea4e3e513d5c822e23a6c887ca16d1eab80d66
- **capabilities**: git:dev, env:dev, docs:publish
- **policy_revision**: AGENTS 2026-09 / agent-worktree-workflow r1 / validation-contract 2026-09-21
- **review_state**: pending
- **integration_state**: pending
- **deployment**: pending
- **cleanup**: pending
- **remote_sync**: not_requested(本地 dev 领先 origin/dev 192+,未要求 push)
## 一、范围与现状
用户面板(sysadmin features 目录)为 fallback 快照;dev 实际运行态 = 单二进制 `launch.sh --no-docker` 只加载根 `.env`(不读 configs/.env.dev),故 intentflow 系列与摘要/叙事开关全部落在默认 legacy/false。dev 容器组当前未运行;test/main 仍为 compose。
已实现但未启动的降级项及处置:
| 开关 | 处置 | 依据 |
|---|---|---|
| MULTI_INTENT_PLAN_TIER(legacy→confirm)+ INTENT_PLAN_PROJECT_ALLOWLIST=* | 根 .env 写入 confirm + * | I2/I3 已按 allowlist 验收 shadow→auto_read→confirm(项目 6579,确认前零写);用户确认保持 confirm |
| MULTI_INTENT_U9/U10/U11/U12 | 根 .env 全 true | I3 live + P8 逐键接线;域名 flag 开启后未打开的细粒度键保持 dry-run |
| SEMANTIC_SUMMARY_SHADOW | 根 .env true | D3 收口 PASS;shadow 生成不影响 served Narrative |
| SEMANTIC_SUMMARY_REPLACE(+SESSIONS) | **代码:SESSIONS 支持 `*` 通配**(原仅枚举 ID,无法覆盖"全部会话含后续");compose 三环境补声明(原 Wave2 注释"REPLACE 未接线"已过期);根 .env true + `*` | chat-semantic-replace 2026-09-26 fail-closed 灰度接线;用户授权全会话 |
| PI_CHANGE_REPORT_NARRATIVE | 根 .env true | 2026-09-23 收口复测 PASS;matrix 注明 dev 常驻开启另授权,本任务授权来源满足 |
不改动:WORKFLOW_SCOPE_MODE(strict 可用);U11/U12 五个逐键 live flag(P8"禁止 full 一次放量",不在本次面板范围,compose 亦未声明,保持 off 待后续运维侧逐键放量)。
防泄漏:根 `.env` 经 `--env-file` 同样被 test/main compose 读取,故在 `configs/.env.test` / `configs/.env.main`(git-ignored 运维配置)显式钉住上述键为默认值,行为保持不变。
## 二、实现(代码侧)
1. `internal/ctxmgr/summary_flags.go`:`SummaryFeatureFlags.ReplaceAllSessions`;`parseReplaceSessions` 返回 `(set, wildcard)`,任意 `*` token → 全会话;`SemanticReplaceEnabledFor` 先过 master 再过通配/名单。空名单仍拒绝一切(纵深防御不变)。
2. 单测:`semantic_replace_test.go` 更新 FlagParsing(通配/混合/空)+ 新增 WildcardAllowlistSwapsNarrative / WildcardMasterOffKeepsDeterministic。
3. compose ×3 声明 `SEMANTIC_SUMMARY_REPLACE(_SESSIONS)`(默认 false/空);A-4 声明测试扩键;`.env.example` 修 Wave2 过期注释并补 SESSIONS/ALLOWLIST 注释键;sysadmin SESSIONS 描述与 REPLACE reason 注明 `*`。
## 三、计划
1. [x] 分析与授权确认
2. [x] 代码实现(通配 + compose 声明 + 目录/示例更新)
3. [x] 工程门禁(arch-check block / go vet / go test -short 72 包 OK)+ dev 集成(--no-ff 候选 6b317181,候选级 validate PASS)
4. [x] env 运维:根 .env + configs/.env.dev 对齐 + configs/.env.{test,main} 钉默认;launch.sh --no-docker 重建并重启(env:dev 锁内;首次操作因长驻子进程 recovery,已按流程 recover 并以 setsid 脱离方式重新拉起,run 502d562d completed)
5. [x] 运行时验收(见测试报告)
6. [x] 测试报告 + MATRIX 行注记 + CURRENT 收口
## 四、结果登记
- **review_state**: done(单测新增/更新 3 个用例 + 候选 validate:arch block + vet + 72 包 short 全绿)
- **integration_state**: done(dev `6b317181`;文档收口 commit 见 `git log`)
- **deployment**: dev_runtime_verified(单二进制 PID 1432360;/health /ready OK schema 75;features 快照 10 键全生效;语义摘要真实链路 semantic_replace 命中通配新会话)
- **验证结论**: [测试报告](../../test-reports/2026-09-26-degraded-flags-enable-test-report.md)
- **观察项(非四归因)**: ① intentflow 在 P8 后对「查风险+查法规」不再持久化 intent_plans(combo_hint needs_confirm/read_only,legacy 回复仍执行;与 matrix「逐键放量待续」一致,不判为回归);② server.log 一条既有 WARN `ctxmgr_reflect_msgs_scan_incomplete`(NULL user_id 扫描,与本次开关无关);③ PI 叙事 live 触发未重跑(能力 2026-09-23 收口已真 MiniMax 复测,本次仅 flag 翻转,待下次自然变更报告事件观察)
- **运维披露**: configs/.env.test / configs/.env.main 写入钉住默认值(行为不变),防止根 .env 新键在未来 test/main compose 重建时泄漏;属配置文件写入而非 test/main 环境操作
- **cleanup**: 待门禁复查后清理
- **remote_sync**: not_requested
@@ -0,0 +1,74 @@
# dialogue-ctx-injection 收口(short-term)
- **task_id**: dialogue-ctx-closeout-2026-09-26
- **owner**: pi
- **status**: in_progress
- **授权来源**: 用户会话指令「把 FEATURE-MATRIX 中的 dialogue-ctx-injection、jevdecide-shadow、chat-semantic-replace 完成;一个 feature 一个 feature 完成;严格按规范」
- **write_scope**: internal/bizdev, internal/server, internal/coordinator, .doc
- **mutex**: dialogue-ctx
- **base_dev_sha**: f6ad3344f81ce4fadba660b5abdde5190c059bdb
- **capabilities**: docs:publish, docs:approve, env:dev
- **policy_revision**: AGENTS 2026-09 / agent-worktree-workflow r1 / validation-contract 2026-09-21
- **review_state**: pending
- **integration_state**: pending
- **deployment**: pending(dev rebuild + 迁移核验)
- **cleanup**: pending
- **remote_sync**: not_requested
## 一、当前进度分析
已完成(dev 已合入,dc29b84c + 1da17a28):
- `internal/dialoguectx` 清洗/分层/打包;`internal/conflictresolve` 权威裁决 + 卡片限额;squad 工作区 `context/dialogue/` 注入;bizdev 全任务默认注入(`DIALOGUE_CTX_INJECTION` 紧急关闭);MemoryComposer 近况段;goose `00072_2026-09-25-context-conflict-adjudications.sql`(原设计 00071,因 maintenance-windows 占号顺延为 00072)。
- 单测全绿(dialoguectx / conflictresolve / squad 落盘 / 关联包)。
未完成(FEATURE-MATRIX 关闭条件):
1. **dev 迁移未应用**:dev 环境当前停机,`context_conflict_adjudications` 表未在 dev DB 落地。
2. **真实 PI 落盘核验缺失**:无真实项目任务跑过 `context/dialogue/` 落盘链路。
3. **冲突确认卡链路断裂(本轮发现的缺口)**:`internal/bizdev/service_task_run.go:646` 对 `buildDialoguePackageForRun` 返回的 expectations 直接丢弃(`_`),trigger_user 路由的 PendingExpectation 卡片从未到达用户;`confirm_context_fact` 也无 coordinator 处理。HITL 分级路由中仅 doc_author(digest 通知)已接线。
## 二、方案
### 2.1 代码补齐(使「冲突确认卡」真实可达)
1. `internal/bizdev/types.go`:`TaskRunResult` 增加 `PendingContextConflicts []ContextConflictCard`(fact_key/winning_value/prompt/snippet/expectation_id)。
2. `internal/bizdev/service_task_run.go`:捕获 expectations → 转卡片(≤3,与卡片限额一致)挂到结果(成功与失败路径均挂,裁决与任务成败无关)。
3. `internal/server`(任务处理器,持有 sessions):run 完成后若有 PendingContextConflicts 且 req.SessionID 对应活跃会话 → 向该会话追加 assistant 消息(确认卡文案,参照 confirmGate 文案形态)+ 通过 `coordinator.ApplyContextUpdate` 设置 `PendingExpectation`(首个 expectation)+ 经 ctxmgr 落消息记录。
4. `internal/coordinator`:
- 期望命中 `confirm_context_fact`(Intent=CONFIRM_ACTION + pending.TargetAction):复用 `handleSupplementInfo` 语义——按 payload slots 写黑板(内存 + blackboard.json + OnSupplement 持久化钩子),回复「已采信…」。
- `handleDeclineExpectation` 对 `confirm_context_fact`:回复引导用户直接给出正确事实(下一条 SUPPLEMENT_INFO 自然吸收),不再用阶段推进话术。
不改 web(卡片以 chat 消息文案呈现,确认走既有期望命中通道);不新增迁移;不动 dialoguectx/conflictresolve 已验收逻辑。
### 2.2 dev 运行时验证(关闭条件)
1. `env:dev` 租约下从主目录 rebuild dev(部署当前 dev HEAD)→ 核验 `/health`、`/ready`、`goose_db_version` ≥ 72 且 `context_conflict_adjudications` 存在。
2. **真实 PI 落盘核验**:真实项目成员对话(含事实陈述)→ 触发任务(真实 PI Runner)→ 核验工作区 `context/dialogue/`(digest.md/turns.md/facts.json/CONFIRMATIONS.md/README)+ TASK.md 导航 + DB 裁决记录。
3. **冲突确认卡冒烟**:同 key 不同值、30 分钟内、无明确证据词的两条用户对话 → 跑任务 → 会话出现确认卡消息 → 回复「确认」→ 期望命中、黑板更新、回复确认采信。
### 2.3 验证契约对照
- Go/接口变更:单测 + `arch-check --mode block` + `go vet ./...` + `go test -short ./...`。
- 产品 Agent/工作流:受影响真实 PI 链路(任务注入 + 冲突卡冒烟)。
- 迁移:dev 实际升级 + schema 版本证据。
## 三、计划
1. [x] 分析进度(本文件§一)
2. [x] 代码补齐 §2.1 + 单测(dev `ebb82820`)
3. [x] 工程验证(vet/short/arch-check,候选验证收据)
4. [x] 候选集成 dev(`ebb82820`)
5. [x] dev runtime 启动(no-docker 单二进制,schema 73)+ 迁移核验
6. [x] 真实 PI 落盘核验 + 冲突卡冒烟(含 sidecar 修复 `f89b946d` 后 completed run 全 PASS)
7. [x] 测试报告 + 矩阵行升 done + 任务收口 + worktree 清理
## 四、结果登记
- **review_state**: done(单测 + 工程门禁 + 候选验证收据)
- **integration_state**: done(dev `ebb82820` + `f89b946d`,均 --no-ff 候选集成)
- **deployment**: dev_runtime_verified(no-docker 单二进制 + localpg,schema 73;[health](../../test-reports/assets/2026-09-26-dialogue-ctx-closeout/dev-health.json))
- **验证结论**:关闭条件全满足,见 [收口报告](../../test-reports/2026-09-26-dialogue-ctx-closeout-test-report.md)
- **cleanup**: 本任务 worktree 按门禁清理
- **remote_sync**: not_requested(本地 dev 前进,未 push)
- **过程修复**:①冲突卡接线(expectations 丢弃→OnTerminal 投递+期望命中处理);②no-docker sidecar `PI_AGENT_EXTENSION` 覆盖;③本机 `.env` `PI_AGENT_BIN` macOS 路径纠正(非仓库变更)
@@ -0,0 +1,65 @@
---
title: "全系统真实浏览器多人协作验收"
task_id: "full-system-browser-e2e-2026-09-26"
status: done
created: 2026-09-26
updated: 2026-09-26
owner: Cursor
task_type: validation
task_tier: large
policy_revision: "agent-governance-2026-09-21-r1 + cursor-governance-2026-09-24-r1"
branch: feature/full-system-browser-e2e-2026-09-26
worktree: .worktrees/full-system-browser-e2e-2026-09-26
write_scope: [".doc", "web"]
allowed_environments: ["env:dev"]
mutex: "full-system-browser-e2e"
review_state: pass
integration_state: pending
deployment: dist_rsync_dev
cleanup: pending
remote_sync: not_requested
---
# 全系统真实浏览器多人协作验收
## 用户目标与授权
- **目标**:wipe 后 local `dev` 真实 Chromium / Playwright 多人协作验收 + 规范报告。
- **硬边界**:业务动作仅浏览器;禁止 API 冒充立项/发消息/审批。
- **交付终点**:spec + assets + test-report + agentctl commit。
## 本轮结果(2026-09-26T04:24Z Docker,EXIT:1)
- PASS **7** / FAIL **1** / SKIP(did not run)**13**
- **已验证修复**:FS-SQUAD-WF-01(真实 PI,~4.2m)→ PASS;气泡 pending heal 生效
- **新 FAIL**:FS-NONAUTH-01 — 成员缺少「双击任意段落就地编辑」affordance
- 保留用户:`e2e26_{author,reviewer,approver,member,guest}_muhvyubx`;项目 `E2E全量-20260926-muhvyubx`
- 报告 FINAL:`.doc/test-reports/2026-09-26-full-system-browser-e2e-test-report.md`
## msg243 只读探针(上一轮 muhu39da)
- DB:`metadata.task_status=completed`;`task_runs` completed;API task-run 200 completed
- 当时 UI:`data-chat-status=pending` → 证实后端/前端终态不同步(非 PI 慢)
- 证据:`assets/.../msg243-readonly-probe.json`
## 计划与进展
1. [x] Wipe / spec / Docker 脚本
2. [x] 修角色与 promote 选择器并重跑
3. [x] 落盘 FAIL 收口报告 + agentctl commit
4. [x] 排查 PI pending + live DB/API 探针
5. [x] 修 bubble heal + unit/build + dist 部署 + Docker 全量重跑
6. [ ] 修 FS-NONAUTH-01 成员编辑 affordance 后重跑审签链
## 验证契约
- 产品 UI + 真实 PI;未跑项 SKIP;不得 stub 冒充 PASS。
## 审计收口(2026-09-26 后续)
- 账本 FINAL:**20 PASS / 0 FAIL / 1 SKIP**(`mui2xpg2`)
- 数据保留:60× e2e26 用户 + 项目 6011–6020;**勿清库**
- 凭据附件:`assets/.../audit-login-credentials.md`
- 清单:`assets/.../retained-inventory.md`
- 主报告已改为审计友好版;未 push / 未 integrate
@@ -0,0 +1,70 @@
# jevdecide-shadow 浸泡收口(short-term)
- **task_id**: jevdecide-soak-2026-09-26
- **owner**: pi
- **status**: in_progress
- **授权来源**: 用户会话指令「把 FEATURE-MATRIX 中的 dialogue-ctx-injection、jevdecide-shadow、chat-semantic-replace 完成;严格按规范」
- **write_scope**: internal/coordinator, internal/jevdecide, .doc
- **mutex**: jevdecide
- **base_dev_sha**: c373d6fbc01c2618795641d9db90990bcf71a837
- **capabilities**: docs:publish, docs:approve, env:dev
- **policy_revision**: AGENTS 2026-09 / agent-worktree-workflow r1 / validation-contract 2026-09-21
- **review_state**: pending
- **integration_state**: pending
- **deployment**: pending(dev runtime assist 已配置)
- **cleanup**: pending
- **remote_sync**: not_requested
## 一、当前进度分析
已具备(dev 已合入 + local_dev 已验证):
- `internal/jevdecide` client/circuit/flags/metrics + coordinator `resolveRealtimeQuery`/`shadowProfile` 接线;assist 模式规则漏检加成经 20 轮对话验收(B 组 10/10 决策加成,C 组 0 误伤)。
- 本机 jev-service :8767(Qwen3-4B jev-clone)健康、decide 可用。
未满足(FEATURE-MATRIX 关闭条件):**真实轮浸泡 ≥200** + **体验层检索空结果收敛**(intent/risk 另立,不在本任务)。
环境事实(本轮核对):
- no-docker dev runtime(单二进制)此前未接 jev(根 `.env` 无 JEV_* → mode=off);本轮已写入 `JEV_DECIDE_MODE=assist`、`JEV_BASE_URL=http://127.0.0.1:8767`、`JEV_API_KEY`(复用 `configs/.env.dev` 值),重启后以 `jevdecide wired mode=assist` 为准。
- 2026-09-24 assist 报告的 B 组体验弱样例(B1/B2/B5/B10 回复为纯项目话术)发生在 PI spawn 全挂的窗口(后经 dialogue-ctx 收口修复 `PI_AGENT_BIN`/`PI_AGENT_EXTENSION`);本轮浸泡在真实 PI 链路修复后重测,判定以新数据为准。
## 二、方案
### 2.1 浸泡设计
- 语料 20 条/轮 × ≥10 轮 ≥200 真实轮:A×4(规则命中基线)/ B×10(规则漏检、jev 候选)/ C×6(业务防误伤);轮间做城市/日期/措辞变体避免缓存。
- 每轮真实 `/api/v1/chat`(真实 PI Runner + tavily 检索),逐轮落盘 checkpoint,可断点续跑。
- 决策层指标(app 日志 `jevdecide realtime shadow` 行):agree / disagree / assist_hit(rule=false ∧ jev=true)/ jev_fail;A 组不回归、C 组零错误加成。
- 体验层指标(B 组回复文本分类):
- `realtime_ok`:含可核验实时事实(数值+单位/汇率/气温等);
- `unavailable_ok`:明确声明无法获取实时数据(不编造);
- `fallback_gap`:两者皆无(纯项目话术)——即「检索空结果」体验缺口。
- **收敛判定**:干预后 B 组 `realtime_ok+unavailable_ok ≥ 90%` 且无编造数值(fail-closed 方向)。
### 2.2 体验层收敛干预(按基线数据决定)
基线轮后若 `fallback_gap > 10%`:在 `internal/coordinator/dialogue_llm.go` 增加确定性兜底——assist 打开检索且 `RealtimeUnavailable` 时,若回复既无实时事实也无无法获取声明,追加确定性提示行(不编造数值,fail-closed);单测覆盖。若基线已收敛则不加代码,仅记录证据。
### 2.3 交付
浸泡证据(逐轮 JSON + 汇总)→ 测试报告 → 矩阵行更新(关闭条件满足)→ 收口清理。
## 三、计划
1. [x] 分析(§一)
2. [x] dev runtime 开 assist 并核验 wired 日志(`jevdecide wired mode=assist`)
3. [x] 基线轮(20 轮)+ 体验层判定(全量收敛,无需干预代码)
4. [x] (按需)确定性兜底——预注册阈值 ≥90%,实测 94%,未实施
5. [x] 浸泡 ≥200 轮(10×20,含基线,checkpoint 断点续跑)
6. [x] 汇总指标 + 测试报告 + 矩阵行更新
7. [ ] 任务收口 + worktree 清理
## 四、结果登记
- **review_state**: done(无代码变更;浸泡证据 13 条人工复核)
- **integration_state**: docs-only(报告与矩阵)
- **deployment**: dev_runtime_assist_on(本机根 `.env` assist;configs/.env.dev 维持;compose 默认 off 不变)
- **验证结论**: 关闭条件满足,见 [浸泡报告](../../test-reports/2026-09-26-jevdecide-soak-test-report.md)——200 轮 / B 组 handled 94% / 零误伤 / 零 jev 失败
- **cleanup**: 本任务 worktree 按门禁清理
- **remote_sync**: not_requested(本地 dev 前进,未 push)
@@ -0,0 +1,40 @@
---
title: "MATRIX 收口:u9u12 与 web-sysadmin 行尾注更新"
task_id: matrix-closeout-r3-2026-09-26
status: in_progress
created: 2026-09-26
owner: cursor-auto
task_type: docs
task_tier: small
policy_revision: "agent-governance-2026-09-21-r1"
branch: feature/matrix-closeout-2026-09-26
worktree: .worktrees/matrix-closeout-2026-09-26
base_dev_sha: "2391aaa7ec150269e3f3754653303e5df0696b8e"
write_scope: [".doc/status/", ".doc/ops/short-term/"]
mutex: matrix-closeout
---
# MATRIX 收口:u9u12 与 web-sysadmin 行尾注更新
## 目标
总控「收口审计并更新 CURRENT/MATRIX」的 MATRIX 部分:P8(U9–U12 逐键放量)、P9(web-sysadmin 残差)已完成并入 dev,对应 MATRIX 行尾注仍写「未开放/剩余 deferred」,需按证据更新。
## 过程记录
- r1(`matrix-closeout-2026-09-26`)完成两次 docs apply 但 scope 缺 `.doc/ops/short-term/` 无法提交任务文;r2 重注册后收据挂在 r1 名下触发 `UNMANAGED_DOCUMENT_CHANGE`,r1 关闭后无法原样复活(register 要求 values 全等)。
- 处置:磁盘 MATRIX 还原到 HEAD,r3 以完整 scope 干净重建收据链(本文件即重写任务记录)。
- r1/r2 标记 cancelled,收据残留于收据表属已终态任务(无写入权限),不构成漂移源(`docs drift` 以矩阵状态机为准)。
## 变更
| record_id | 变更 |
|---|---|
| `intent-plan-u9u12` | 尾注追加 2026-09-25 逐键放量事实:7 键接真实引擎、5 个逐键 flag 默认 off、`TierConfirm`、dev `c5027788`;证据 [P8 报告](../../test-reports/2026-09-25-p8-u9u12-keys-rollout-test-report.md)。dev 运维侧 flag 开启与 PI 证据采集待续 |
| `web-sysadmin` | 尾注替换为残差收口事实:`ui.*` 白名单已接消费方(公开 site-status + 前端横幅,dev `4bdbb0da`);Playwright 实跑 PASS;KB 运维登记不做;证据 [P9 报告](../../test-reports/2026-09-25-p9-websysadmin-residual-test-report.md) |
## 验证
- 两行状态维持 done(仅尾注事实更新,无状态跃迁);
- 证据文件在 dev HEAD 可寻址(已核对);
- `docs drift` 无回退。
@@ -0,0 +1,55 @@
# workflow-rdev P3 真 PI 重跑收口(short-term)
- **task_id**: rdev-p3-rerun-2026-09-26
- **owner**: pi
- **status**: in_progress
- **授权来源**: 用户会话指令「把 FEATURE-MATRIX 中的 workflow-rdev、workflow-swboot 推进至完成…严格按规范,合入后更新所有相关文档、状态」
- **write_scope**: .doc
- **mutex**: workflow-def / rdev-templates
- **base_dev_sha**: a6d25afa2797ec6bbf8df837e86b858e2432fade
- **capabilities**: docs:publish, docs:approve, env:dev
- **policy_revision**: AGENTS 2026-09 / agent-worktree-workflow r1 / validation-contract 2026-09-21
- **review_state**: pending
- **integration_state**: pending
- **deployment**: not_applicable(dev runtime 已在运行)
- **cleanup**: pending
- **remote_sync**: not_requested
## 一、当前进度分析
rdev 行剩余唯一关闭条件:**P3 真 PI 三样本在当前 HEAD 重跑**(2026-09-22 收口时因无 env:dev blocked)。
2026-09-19 P3 首跑的两处 FAIL 已在 2026-09-22 修复并 dry 验证:
1. `rd_proposal` 模板标题未对齐 → `rdevProposalHeadingIssues` 标题门禁(修复轮驱动)
2. `rd_planning_review` 质量门禁 20 分(法规表被算进问题行)→ `markdownTable` 首表截止
本轮在当前 dev HEAD(`a6d25afa`,no-docker runtime + PI Runner MiniMax-M2.7-highspeed 已修复可用)重跑 P3,判定以真实结果为准,不以 dry/stub 冒充。
## 二、方案
- 复用 `.doc/test-reports/assets/2026-09-19-rdev-p3-real-pi/run_p3_real_pi.py`(admin/lizhuguan/wangzong 种子用户)
- 判定标准(与 P3 报告一致 + 修复项):
- `rd_sw_plan` 规划期关闭(enabled=false)
- `rd_proposal`:真 PI、终态 completed/pending_author_confirmation、无占位句、**含模板三标题**(标题门禁生效)
- 未批准推进 RD01 → 409(阶段门禁负例,脚本已含审批链后推进)
- `rd_planning_review`:真 PI、终态 completed(**不得 quality_failed**,首表截止修复生效)、含评审三章节、无占位句
- 证据:summary-p3.json + 两份终稿 md + console.log + manifest 质量报告摘录
## 三、计划
1. [x] 分析(§一)
2. [x] env:dev 租约下运行 P3 脚本(真实 PI;过程中发现并修复 docgov 两项批准链阻断缺陷,见报告 §5.2)
3. [x] 判定与证据归档:三样本全 PASS(标题门禁与首表截止修复经真 PI 转正;评审质量报告 passed=true score=100)
4. [x] 测试报告 + 矩阵行升 done + CURRENT
5. [ ] 集成 + 任务收口 + worktree 清理
## 四、结果登记
- **review_state**: done(docgov 修复含 2 个隔离库 PG 回归 + 真实环境批准验证)
- **integration_state**: done(修复经 dev `121b33f8`/`6bd6e916`/`5d5cd5fd` 多轮候选合入)
- **deployment**: dev_runtime_verified(no-docker dev @ `5d5cd5fd`)
- **验证结论**: P3 三样本全 PASS,见 [重跑报告](../../test-reports/2026-09-26-rdev-p3-rerun-test-report.md)
- **过程修复**: docgov 快照装载缺失 + uow 行锁自死锁(均 resolved 入台账);memDocs 投毒登记 investigating
- **cleanup**: 本任务 worktree 按门禁清理
- **remote_sync**: not_requested(本地 dev 前进,未 push)
@@ -0,0 +1,60 @@
# workflow-swboot 收口:SWBOOT-10 非 stub + L5 真实 PI + L6 UI 二次验收(short-term)
- **task_id**: swboot-closeout-2026-09-26
- **owner**: pi
- **status**: in_progress
- **授权来源**: 用户会话指令「把 FEATURE-MATRIX 中的 workflow-rdev、workflow-swboot 推进至完成…严格按规范」——构成 W5 关闭条件中「SWBOOT-10 非 stub + 真实 PI + UI 二次验收」的待授权项授权
- **write_scope**: internal/swboot, internal/projectworkflow, internal/server, deploy/postgres/goose, .doc
- **mutex**: workflow-design
- **base_dev_sha**: d0f3f76f7e979e6b4c6db5303cd9fe57ba8c9685
- **capabilities**: docs:publish, docs:approve, env:dev
- **policy_revision**: AGENTS 2026-09 / agent-worktree-workflow r1 / validation-contract 2026-09-21 / swboot 设计 §12(受控代码执行层安全边界)
- **review_state**: pending
- **integration_state**: pending
- **deployment**: pending
- **cleanup**: pending
- **remote_sync**: not_requested
## 一、当前进度分析
SWBOOT-00..09 已合入并 L1–L4 验收;SWBOOT-10 为 fail-closed stub:`controlled_patch` 在 catalog 预览与 `projectworkflow.CreateProject` 双双拒绝;`RepoAllowlist.ExecuteControlledPatch/ApproveMerge` 恒拒;goose 00048 的 `repo_path_allowlist` / `project_source_bindings` 零运行时读写(Wave5 X-3 deferred)。L5(真实 PI advisor)/ L6(UI 二次验收)pending auth。
## 二、方案(按设计 §12 安全边界的最小闭环)
### 2.1 SWBOOT-10 受控补丁执行器(fail-closed)
1. **DB allowlist**(接线 goose 00048 表):`swboot.PGRepoAllowlist` 读 `repo_path_allowlist`(enabled 行);空表 = 拒绝一切(deny-all)。
2. **创建门禁解锁**:`projectworkflow` 增加可选 `RepoAllowlistChecker`;`CreateProjectInput.RepoPath`——`controlled_patch` 仅当提供 RepoPath 且通过 allowlist 时放行,并在创建事务内写 `project_source_bindings`(permission_scope=controlled_patch);checker 未注入时维持拒绝(fail-closed)。catalog 预览:`controlled_patch` 仅当 `RepoAllowlisted=true` 视为有效。
3. **执行器** `swboot.ControlledPatchExecutor`:
- 前置:路径在 DB allowlist;base ref 显式;补丁为 unified diff 文本
- 隔离:`git worktree add feature/swboot-<slug> <base>`(永不直接改工作树/保护分支);补丁先 `git apply --check` 再应用
- 命令:仅允许管理员 `system_settings` 键 `swboot.test_commands`(逗号分隔前缀;默认空=零命令);clean env(仅 PATH/HOME),cwd=worktree,单命令超时与输出上限,失败即停不重试
- 产物:变更文件清单 + sha256、命令退出码/耗时/截断输出;记录持久化到新表 `swboot_controlled_executions`(goose 00074)
- **merge/push/deploy 永不执行**:`ApproveMerge` 改为类型化「需独立授权」边界错误(设计 §10:批准执行≠批准合并)
4. **服务端最小面**:`POST /projects/{id}/swboot/executions`(创建者)+ `GET` 列表;`POST /projects/{id}/swboot/bindings`(创建者补绑/校验)。
### 2.2 L5 真实 PI
`RUN_PI_E2E=1 go test ./internal/app/ -run TestPiSoftwareBootstrapAdvisor_LiveMiniMax`(dev Runner :18865)在当前 HEAD 复验。
### 2.3 L6 UI 二次验收
新增 `web/e2e/swboot-wizard.spec.ts`(RUN_UI_ACCEPTANCE=1 门禁,真实 dev 栈):登录 → 创建向导切「纯软件」→ solo 未评审横幅 → catalog 类型选择 → 必填问题/用户/结果 → 创建成功进入项目(无医疗污染词);注册 README 矩阵与 npm 脚本;Playwright docker 容器实跑。
## 三、计划
1. [x] 分析(§一)
2. [x] 实现 §2.1(goose 74/75、PG allowlist、executor、projectworkflow/catalog 门禁、server 端点)+ 单测(dev `4965e74d`,列名修复 `70f3028c`/`86e0cf46`)
3. [x] 工程门禁 + 候选集成 dev(含 app→swboot 边界登记)
4. [x] L5 复验(LiveMiniMax PASS 9.8s)+ L6 e2e 实跑(docker Playwright 1 passed)
5. [ ] 测试报告 + 矩阵行升 done + 收口清理
## 四、结果登记
- **review_state**: done(单测 9 项 + 工程门禁 + 既有契约更新)
- **integration_state**: done(dev `4965e74d`→`86e0cf46` 三轮候选合入)
- **deployment**: dev_runtime_verified(schema 75;SWBOOT-10 全链 + 三负例 + L5/L6)
- **验证结论**: W5 关闭条件全满足,见 [收口报告](../../test-reports/2026-09-26-swboot-closeout-test-report.md)
- **过程修复**: 绑定列名 source_ref(创建 500 残留 + 端点 409 误报)
- **cleanup**: 本任务 worktree 按门禁清理
- **remote_sync**: not_requested(本地 dev 前进,未 push)
@@ -0,0 +1,44 @@
# sysadmin 功能目录成熟度刷新(short-term)
- **task_id**: sysadmin-maturity-refresh-2026-09-26
- **owner**: pi
- **status**: in_progress
- **授权来源**: 用户会话反馈「重新看了 dev 功能特性页面,这些还都是降级状态」——页面徽标未反映 2026-09-26 放量后的接线事实,构成对目录刷新的即时授权(承接 degraded-flags-enable-2026-09-26-r4)。
- **write_scope**: internal/sysadmin, .doc/ops/CURRENT.md, .doc/ops/short-term
- **mutex**: sysadmin-maturity
- **base_dev_sha**: 1d13a892fcd7b6676346502bb236a440efbf46c8
- **capabilities**: git:dev, env:dev, docs:publish
- **policy_revision**: AGENTS 2026-09 / agent-worktree-workflow r1 / validation-contract 2026-09-21
## 一、问题
`featureMaturityCatalog`(internal/sysadmin/features.go)自述为"源码接线事实,不随环境变量翻转",但其内容停留在 2026-09-24 I2 时代;degraded-flags-enable 放量后页面"值"已翻转(confirm/true/*)而"适配"列仍显示降级,用户判断页面失真。逐项核对:
| 键 | 旧目录断言 | 当前事实与证据 |
|---|---|---|
| MULTI_INTENT_PLAN_TIER | degraded,"默认仍 legacy" | I2/I3/P8 合入并验收(I2 报告 5.1–5.4;P8 报告);dev 现行 confirm+* |
| MULTI_INTENT_U11_DOCGOV | degraded,"其余 key 仍 dry-run" | P8 后全部键接真实引擎(matrix intent-plan-u9u12 行),剩余键由逐键 flag 控制 |
| MULTI_INTENT_U12_RUN_CONTROL | 同上 | 同上 |
| SEMANTIC_SUMMARY_SHADOW | shadow/degraded,"默认关闭、可见集 digest 仍空" | 影子链路生产化(D3 收口);job#18 visibility_digest 已落盘非空;dev 已开 |
| SEMANTIC_SUMMARY_REPLACE | shadow/degraded,"默认关" | 双开关全量接线含 `*` 通配(dev 6b317181);真实链路命中新会话 |
| PI_CHANGE_REPORT_NARRATIVE | shadow/degraded,"待放量授权" | 2026-09-23 收口真 MiniMax 复测 PASS;dev 已按授权开启 |
FAV 两项(红线)不动。
## 二、修改
- 目录六项改 `live+ready`,reason 改写为带证据日期的当前事实;U11/U12 reason 保留"逐键 flag(默认关)"提示,防止误读为可 full 放量。
- service_test.go:narrative/五键断言改 live+ready;保留 chat_summaries 与防回退断言(不得再出现"尚未在运行环境执行/尚未切到");新增 U11/U12 reason 必须含"逐键"。
## 三、验证计划
1. [x] `go test ./internal/sysadmin/` PASS;arch-check block PASS;vet PASS;`go test -short ./...` 72 包全绿(候选级 validate 同套复跑 PASS)
2. [x] 集成 dev `1d82ed88` 后重启单二进制(env:dev,setsid 脱离,run af4d5ebf HEALTH_OK);GET /api/v1/admin/system/features 复核:九项全部 `值=confirm/true/*、实现=live、适配=ready`;全目录无 degraded 残留(FAV 保持 dry_run/unavailable 红线)
## 四、结果登记
- **review_state**: done(目录与断言同步更新;FAV 承接“配置值不赠予就绪度”反例断言)
- **integration_state**: done(dev `1d82ed88`)
- **deployment**: dev_runtime_verified(二进制重建重启,页面数据源已出新目录)
- **cleanup**: 本任务 worktree 按门禁清理
- **remote_sync**: not_requested
@@ -0,0 +1,63 @@
---
title: "系统全面 Code Review(仅报告)"
task_id: "system-code-review-2026-09-26"
status: done
created: 2026-09-26
updated: 2026-09-26
owner: Cursor
task_type: research
task_tier: small
policy_revision: "agent-governance-2026-09-21-r1 + cursor-governance-2026-09-24-r1 @ f4c1b73f"
branch: feature/system-code-review-2026-09-26
worktree: .worktrees/system-code-review-2026-09-26
base_dev_sha: "f4c1b73f28580ad3df6db4f9ec0a80057006e516"
write_scope: [".doc"]
allowed_environments: []
head_sha: "f4c1b73f28580ad3df6db4f9ec0a80057006e516"
mutex: "docs-audit-review"
review_state: accepted
integration_state: integrated
deployment: not_required
cleanup: done
cleanup_owner: "独立集成/维护"
cleanup_trigger: "报告合入 local_dev 且无进程占用本 worktree"
remote_sync: not_requested
---
# 系统全面 Code Review(仅报告)
## 用户目标与授权
- **用户目标**:对系统做一次全面 code review,并按规范形成报告;不允许实施修复,只形成报告。
- **交付终点**:审计主文档可审;INDEX 挂接;本任务记录收口。
- **禁止项**:业务代码修复、gap-matrix/MATRIX 状态冒充发布、未授权环境写、push。
## 范围与非目标
- 允许写入:`.doc/audit`、`.doc/ops/short-term`、审计 INDEX。
- 非目标:实施 FIND-* 修复、动态渗透、依赖 CVE。
## 相关问题与经验
- 检索词与结论见 [审计主文档](../../audit/2026-09-26-system-code-review.md)。
- 无新增 lesson(未修复验证)。
## 计划与进展
1. [x] catalog overlap(none)+ worktree/register/claim
2. [x] 四轴并行审查 + arch-check/规模盘点
3. [x] 关键发现复核(IDOR、scan 未登记表、Confirm×proposed)
4. [x] 落盘审计报告与 INDEX
5. [x] 合入 local_dev(integrate-review-fixes 批次:报告+修复一起 --no-ff)
6. [x] cleanup worktree(由修复批次维护者执行)
## 验证
- 研究验收 = 报告有据可审(FIND 带路径与置信度)。
- 不适用产品 PI 全链路;**NOT REQUIRED** 产品测试 PASS。
## 状态与交接
- `status=done`(研究完成 ≠ 缺陷已修)。
- 后续 P0 候选:FIND-SEC-01、FIND-ARCH-01(须新授权/新 task)。
- cleanup 待合入后由独立维护者执行。
@@ -0,0 +1,60 @@
---
title: "系统 Code Review P0/P1 修复(2C+3H)"
task_id: "system-review-p0-p1-fixes-2026-09-26"
status: in_progress
created: 2026-09-26
updated: 2026-09-26
owner: pi
task_type: implementation
task_tier: cross-module
policy_revision: "agent-governance-2026-09-21-r1 @ f4c1b73f"
branch: fix/system-review-p0-p1-fixes-2026-09-26
worktree: .worktrees/system-review-p0-p1-fixes-2026-09-26
base_dev_sha: "f4c1b73f28580ad3df6db4f9ec0a80057006e516"
write_scope: ["internal/server", "internal/ctxmgr", "internal/authz", "internal/swboot", "internal/archtest", "internal/app/intentflow", "internal/intent", "internal/app/app.go", ".doc"]
allowed_environments: []
mutex: "review-fixes-batch"
review_state: pending
integration_state: pending
deployment: deployed
cleanup: pending
remote_sync: not_requested
---
# 系统 Code Review P0/P1 修复
## 用户目标与授权
- **来源**:[2026-09-26 系统 code review](../../audit/2026-09-26-system-code-review.md) 发现项。
- **用户授权**(2026-09-26):一并修复 2 Critical(FIND-SEC-01、FIND-ARCH-01)+ 3 个 High 行(FIND-SEC-02/03、FIND-FLOW-01、FIND-QUAL-01);修复完成后与审计报告**一起提交**(同一批集成);完成后清理 worktree 任务分支。
- **禁止项**:未授权环境写、push、晋升 test/main;FIND-ARCH-02(server Pool 接线)未在授权修复范围(ISSUES 登记 open)。
## 范围
- 修复主记录(含逐项根因/方案/回归):[remediation/2026-09-26-system-code-review-fixes.md](../../remediation/2026-09-26-system-code-review-fixes.md)。
- Issue 台账:ISSUE-20260926-ctx-idor / archcheck-untracked / authz-failopen / swboot-shell-prefix / intentflow-validated-confirm / dual-flags-drift(resolved)+ governance-multi-entry(deferred)+ server-pool-wiring(open)。
- 经验:LESSON-20260926-failclosed-bypass-contract(validated)。
## 问题检索与采纳
检索词:`IDOR`、`GetUserContext`、`session_id`、`validated_only`、`table_owners`、`untracked`、`fail-open`、`sh -c`、`前缀白名单`、`PlanTier`。命中:来源审计 FIND-*(全部);ISSUES 无同题已关闭条目;经验库无同机制 lesson(本轮新建)。采纳检查:模块规范 §2.1/§4(表唯一写者、端口装配)、验证契约「问题修复的回归范围」(原例+同类+正常行为)。
## 计划与进展
1. [x] worktree + 登记(base f4c1b73f)
2. [x] 六项修复实施 + 回归用例
3. [x] 验证:arch-check block / vet / short 全量 / 隔离 PG(IDOR PG、authz、duty);两个基线既有失败已核对非本批回归
4. [x] 文档:修复主记录、ISSUES、lesson、索引
5. [x] 提交
6. [x] 集成(含审计报告分支同批 --no-ff,候选 integrate-review-fixes)
7. [x] 部署核验(用户授权;`launch.sh --no-docker` FORCE_BUILD 重建 + 重启,binary vcs.revision=`1ceda34c`;/health+/ready ok schema 75;线上 IDOR 负例:他户/带 user_id 覆写/未知会话→403,归属者→200 且含原文。探测留痕:dev 库 probe 用户 dpv_*/dpa_* 与项目 idor-live-probe-*)
8. [x] 清理(本任务 + 审计任务 + 集成候选 worktree/分支均已普通 remove)
## 验证
详见[修复主记录验收汇总](../../remediation/2026-09-26-system-code-review-fixes.md#验收汇总)。要点:arch-check block PASS(fail-closed 后)、vet/short 全绿、隔离 PG(55432 verify 容器临时库)IDOR/authz/duty PASS;`TestHealProjectDocuments_SkipsDutyLocked_PG` 与 PI E2E(KB 离线)为基线既有失败(stash 对照证实)。
## 状态与交接
- 集成后:任务状态改 done;审计任务(system-code-review-2026-09-26)的 integration/cleanup 由本批一并推进。
- 部署:`deployment=pending`(代码影响运行内容;dev 服务重启与核验未在本任务授权内,见修复主记录)。
@@ -0,0 +1,81 @@
---
title: "Worktree 全量收口:内容落地、记录归并与清理"
task_id: worktree-final-closeout-2026-09-26
status: done
created: 2026-09-26
owner: pi
task_type: ops-closeout
task_tier: cross-module
policy_revision: "agent-governance-2026-09-21-r1"
parent_task: cleanup-audit-p11-2026-09-25
user_authorization: "用户指示:将 .worktrees 下未清除任务分支彻底完成、测试验证后合入 dev,文档登记更新后清除分支任务(2026-09-26 会话)"
---
# Worktree 全量收口(2026-09-26)
## 1. 背景与授权
P11 清理审计(`2026-09-25-p11-cleanup-audit.md`)后仍有 43 个登记 worktree(38 blocked / 5 ready)。用户授权一次性收口:含未合入成果的分支彻底完成并验证合入 dev,文档登记更新,然后清除 worktree 与分支。
基线:dev `6adf694f`(本地,ahead origin/dev 101)。所有集成经 `agentctl integrate prepare/validate/integrate` 受控通道,串行推进。
## 2. 内容落地(4 项,全部完成)
| 交付 | 来源分支/提交 | 落地方式 | 验证 | 集成 SHA |
|---|---|---|---|---|
| docgov 三权流转(锁定期补充积压 migration `00073`、流转职责通知、阶段化批注矩阵、重开 Approver 优先)+ 对话触发(comment/reopen/pending 键进 U11 live 基线集) | `feature/doc-review-lifecycle-2026-09-25`(986d78cc + 09fe9723) | 新 land 分支 cherry-pick,12 处冲突按 dev 现行结构重解(per-docID 锁、`gov()`/`authorizer()` 访问器、U11 live 键函数化、app/docnotify 去 stream 依赖);migration 00072→00073(dev 已占用 00072);MATRIX docgov 行经 docs apply 收据更新 | arch-check block / go vet / go test -short 全量 / 8 包聚焦 -count=1 / web npm test + build 全 PASS;证据 `assets/2026-09-26-doc-review-lifecycle-land/revalidation-summary.txt` | `117ef7d8` |
| 对话办公能力全景盘点与 P0–P3 整改计划(audit 调研 + remediation 计划 + 双 INDEX) | `feature/dialogue-office-expansion-2026-09-25`(09ffe7de) | land 分支 cherry-pick,remediation/INDEX 双行并集 | 文件存在性 + 全链接检查(去锚点)PASS | `75ff922b` |
| 项目成员权限总览(system-design + README) | `feature/member-permissions-doc-2026-09-24`(e2a442b5) | land 分支 cherry-pick;废弃的 CURRENT 认领行(d784daf8)不入;顺手修复 README t20 迁址失效链接 | 同上链接检查 PASS | `23ee0f02` |
| 非容器化单二进制三环境交付方案(2 份设计文档) | `feature/single-binary-deploy-design-2026-09-24`(7ebf431c) | land 分支 cherry-pick;CURRENT 行改动(588fef1c)废弃不入 | 同上 PASS | `cc519e38` |
原任务报告口径保留:真实产品 PI E2E(对话送审/批注/重开全链)未运行(未获授权环境),不冒充 PASS;dev 环境运行时验证见 §5。
## 3. 记录性归并(9 分支 → dev 祖先)
`git merge --no-ff -s ours`(树不变、暂存为空、git:dev 租约下单发完成),使旧分支 tip 成为 dev 祖先以满足受控删除的 ancestor 检查。每个候选经 validate(`git diff --quiet HEAD^1 HEAD` 树不变断言)+ integrate:
| 分支 | 归并依据 |
|---|---|
| feature/doc-review-lifecycle-2026-09-25 | 内容已由 land 分支等价落地(§2 行 1)→ `64a28c98` |
| feature/member-permissions-doc-2026-09-24 | 同上 → `db8585b5` |
| feature/single-binary-deploy-design-2026-09-24 | 同上 → `357c869a` |
| feature/integrate-admin-settings-maint-b-2026-09-25 | patch-id 查重:tip 8f9b91d3 与 dev 等价;余为 merge 节点 → `043e10f6` |
| feature/integrate-backlog-triage-p10(-r2)-2026-09-25 | 被 r3 候选替代,仅含 merge 节点 → `2d3a7a22`/`5f85f3c5` |
| feature/integrate-gov-visibility-p0-b-2026-09-24 | 取消的重试候选,被 p0-c 替代 → `2a7a7000` |
| feature/promote-rc-beta3-c-2026-09-24 | test 晋升历史完整保留于本地 `test`(头 `0e4b111d`,含 tag `rc-v1.1.0-beta.3` 标注历史);不引入 dev 树变化 → `dc108181` |
| feature/sync-local-test-origin-2026-09-24 | tip `9984c68d` 经上述归并已为 dev 祖先(merge no-op,候选复验后不重复推进) |
## 4. 唯一证据归档与缓存处置
- `handoff-e2e.log`(4K):committed 报告 `2026-09-25-admin-settings-maintenance-test-report.md` 引用但未入库 → `git add -f` 归档至原引用路径。
- `focused-security-tests.log`(8K,53 行):P11 指定唯一日志 → `git add -f` 归档至 `.doc/ops/evidence/2026-09-25-security-redline-false-positive/`。
- websysadmin playwright 输出(524K,`playwright-output-main/`、`playwright-report-main/`):P9 报告未引用,属可再生测试产物,登记后随 worktree 删除。
- `scripts/handoff-e2e.sh`(worktree 未跟踪副本):committed 等价物已在 `assets/2026-09-25-admin-settings-maintenance/handoff-e2e.sh` → 副本废弃。
- `web/dist_placeholder`(single-binary-dev-impl worktree):dev 以 `web/dist/.gitkeep` 机制覆盖,本地占位副本废弃。
- 遗留孤儿测试进程 pid 3484192(`/tmp/TestRealFDHandoffE2E…/stubserver`,PPID=1):终止(测试产物进程,无父服务)。
- 其余 ignored 文件(`.codegraph/`、`internal/server/data/`、`__pycache__`、`bin/`、`web/node_modules`、`web/dist`、`.tmp/`):可再生缓存,登记后随 worktree 删除。
## 5. 合入后运行时验证(已执行,2026-09-26 20:28–20:31)
- `./scripts/build-single-binary.sh` 从 dev `19700e85` 主仓干净树构建 `bin/agent-server`(32M)。
- `agentctl with --task dev-runtime-verify-2026-09-26 --resource env:dev` 经主入口 `./scripts/launch.sh --no-docker` 重启:旧进程 2398019 停止,新二进制接管 :8080(PI sidecar/localpg 复用)。
- `/health`:`status=ok, schema_version=73, database_ready/kb_ready/task_store_ready/events_ready=true`;`/ready`:200。
- 业务冒烟:`GET /api/v1/projects/1/documents/x/comments`、`POST …/trace/reopens/1/approve` 返回 401 鉴权门(路由存在、无 panic);migration `00073_document_pending_supplements` 已在 dev DB 落账(goose version_id=73)。
- 过程注记:launch 的常驻子进程与租约同进程组导致 recovery 卡住,按 verified 流程停止后改用 setsid 分离拉起(pid 202055,PPID=1),租约均 completed/recovered;另发现某 server 测试在 20:14 已先行将 migration 00073 应用于共享 dev DB(测试隔离糖疑点,待独立排查,不阻断本次验收)。
## 6. CURRENT 修正(docs:admin @document CAS)
- 新增本任务行;`intent-plan-i2-rollout-b-2026-09-24`、`intent-plan-i2-impl-2026-09-24`、`worktree-cleanup-closeout-2026-09-24`、`dialogue-context-injection-2026-09-25` 四行 `in_progress`→`done`(registry 早已 done,P11c/P14 漂移修正)。
## 7. 清理结果(已执行)
- 预清理:孤儿 stubserver pid 3484192 终止;可再生缓存(`.codegraph/`、`internal/server/data/`、`__pycache__`、`bin/`、`web/node_modules`、`web/dist`、`.tmp/`、worktree 本地 `data/`/`deploy/` 副本与 `.env` 副本、playwright 输出、占位/重复脚本)逐项删除并登记;已归档日志从源 worktree 移除。
- 受控删除:`agent-worktree.sh remove --delete-branch` 共移除 **59** 个 worktree+分支(43 个历史 + 16 个本轮 land/record/integrate),全部普通 remove,无 `--force`/`-D`。
- 保留项:`u9u12-keys-rollout-2026-09-25` 被空闲用户 shell(pid 3386059,orca-relay bash,cwd 驻留)占用,工具正确拒绝;登记 cleanup_pending,待用户处置该 shell 后重跑 remove。
- 终态盘点:`agentctl cleanup report` 仅余上述占用项;`docs drift` 无硬告警;dev 本地领先 origin/dev(未 push,未获授权)。
## 红线遵守
- 未用 `--force` worktree remove / `git branch -D` / 按年龄批量删除;每个删除前经工具 ancestor/registry/文件/进程检查。
- 未 push 远端(dev 本地 ahead,用户未要求)。
- 测试/迁移/红线能力未冒充:真实 PI E2E 与 PG 集成负例按原任务口径记未运行,dev 运行时验证单独执行。
@@ -0,0 +1,47 @@
---
title: "修复 docker 构建上下文缺少 web/dist/.gitkeep 导致候选镜像构建失败"
task_id: docker-context-gitkeep-2026-09-27
status: done
created: 2026-09-27
updated: 2026-09-27
owner: pi
task_type: fix
task_tier: small
policy_revision: "AGENTS+worktree-ops @ 94c215d3"
branch: fix/docker-context-gitkeep-2026-09-27
worktree: .worktrees/docker-context-gitkeep-2026-09-27
base_dev_sha: "94c215d36e090ad6c1541f64bd625067d7fce4fc"
write_scope:
- .dockerignore
- .doc/ops/short-term/2026-09-27-docker-context-gitkeep.md
allowed_environments: ["dev"]
capabilities: [git:dev, env:dev]
mutex: env:dev
review_state: accepted
integration_state: merged_local_dev
deployment: not_required
cleanup: pending
remote_sync: not_requested
---
# 修复 docker 构建上下文缺少 web/dist/.gitkeep
## 问题与根因(已证实)
- 症状:`candidate-images-build.sh --commit 94c215d3` 在 go-builder 阶段失败:`web/embed.go:14:12: pattern all:dist: no matching files found`。
- 根因:`.dockerignore` 的 `web/dist` 行把整个目录排除出构建上下文;`web/embed.go`(`//go:embed all:dist`,6cbe7e6e 2026-09-24 16:20 落地)依赖 git 内的 `web/dist/.gitkeep` 使模式可满足。两者组合后上下文内无任何 `web/dist` 条目 → embed 失败。
- 时间线:最后一次成功候选镜像构建 = `3de5bc5c`(2026-09-24 03:24,早于 embed.go)。即自单二进制 P1 合入起 docker 镜像构建已坏,因 dev 转非容器、test/main 未重建而未暴露。本次 dev→test 晋升(--require-digests 门禁)首次触发。
- 影响:所有需要 image_digests 的晋升/发布门禁(dev→test、test→main)被阻断。
## 修复
`.dockerignore` 在 `web/dist` 排除后追加 `!web/dist/.gitkeep` 负向规则:上下文仅含 `.gitkeep`,embed 模式可满足;容器运行时行为不变(镜像内 dist 仍来自 web-builder 阶段 `COPY --from=web-builder /web/dist`,embed 内无 index.html → `LookupDist` false → 磁盘回退,与 P1 之前语义一致)。
## 验证
真实执行 `candidate-images-build.sh --commit <本修复提交>`:app/events/pi-agent 三镜像构建成功并产出 digests(即晋升同款路径)。
## 关联
- 触发任务:test-single-binary-2026-09-27(晋升 rc-v1.1.0-beta.4 需 digests 收据)。
- 同期发现的独立缺陷(另立跟进,不在本修复内):sysadmin 初始 apply 空 key 清空 runner models.json(internal/app/app.go + internal/sysadmin/apply.go);launch.sh sidecar 子 shell 相对 DATA_DIR 扩展路径解析。
@@ -0,0 +1,113 @@
---
title: "localStorage 残留 legacy demo sessionId 导致首屏 chat 404(ISSUE-20260927 修复残留路径)"
task_id: "frontend-demo-fallback-2026-09-27-r3c"
status: done
created: 2026-09-27
updated: 2026-09-27
owner: pi
task_type: implementation
task_tier: small
policy_revision: "agent-governance-2026-09-21-r1 @ dev 87db3621c62f8d9473b7191cce3a782cfbaf3d90"
branch: fix/frontend-demo-fallback-2026-09-27-r3
worktree: .worktrees/frontend-demo-fallback-2026-09-27-r3
base_dev_sha: "87db3621c62f8d9473b7191cce3a782cfbaf3d90"
write_scope: ["web/src", ".doc"]
allowed_environments: ["dev-readonly", "dev-browser-verify"]
head_sha: "083c63bb"
mutex: "web-chat-fallback"
review_state: not_required # 小任务;沿用 ISSUE-20260927 修复线,验证契约前端范围全过
integration_state: merged # dev 36c5fb54(candidate integrate-frontend-demo-fallback-2026-09-27-r3,validate 收据 ea2681ee)
deployment: passed # dev 主入口 vite :3100(frp 同一入口)热载新代码,admin+残留 sess-001 复验 phantom=0/4xx5xx=0(2026-09-27)
cleanup: done
cleanup_owner: "独立集成/维护执行者"
cleanup_trigger: "owner 退出且 dev 合入+验收证据齐备"
remote_sync: not_requested
---
# localStorage 残留 legacy demo sessionId 导致首屏 chat 404
## 用户目标与授权
- 用户目标/授权来源:用户报告 dev(frp-mix.com:58880)控制台仍出现 4 个 `session_id=sess-001` 的 chat API 404(无 `projects/1` 假请求);本轮会话明确授权"按上轮任务同路径修复(worktree 修改 → 测试 → 合入 dev → dev 真实浏览器复验 → 清理)"。
- 交付终点:修复合入 dev、dev 实际运行验证通过、worktree 清理。
- 禁止项:不 push 远端;不动 test/main;不改后端。
- 例外:无。本任务是 [ISSUE-20260927-demo-fallback](./2026-09-27-frontend-demo-fallback.md) 修复的残留缺口修正,沿用同一 issue 与 mutex。
## 问题事实与根因(2026-09-27 排查)
- 现象:登录后首屏 `GET /api/v1/chat/messages/window|unread|categories|dates?session_id=sess-001` 4×404;**无** `projects/1` 假请求。
- 运行态核实:dev vite :3100(主目录,base 87db3621,修复后代码)按需编译;`projects/1` 假请求消失证明上轮 fallback 常量修复已生效,本例 `sess-001` 来源不是 fallback 常量。
- 代码核实:
- `web/src/data/storage.ts` `loadActiveSessionId()`:localStorage `smdf_agent_workbench_v6_active_session` **已存值优先于 fallback**(:110);
- 旧前端(上轮修复前)由 fallback 激活 `sess-001` 后,`useWorkbenchPersistence`(:44 `saveActiveSessionId`)把它**写回** localStorage;
- 一次性清理 `purgeDemoSeedsFromLocalStorage`(`demo-seed-purge-v1` 版本 key 幂等跳过)在旧代码写回**之前**已执行过,不再清;
- `loadMessages` 对 messages 有 `legacyIds` 防御(:121),`loadActiveSessionId` 对 active_session **没有**——同一机制缺口。
- 数据核实(dev PG :5433 只读):`chat_sessions` 80 行无 `sess-001`;user_id=4(admin,报障账号)拥有 0 个会话 → 前端 `visibleSessions` 为空 → 会话纠正 effect(App.tsx:268)不触发 → `sess-001` 持续激活。
- 根因:上轮修复只切断"生成"路径(fallback 常量),未覆盖"旧代码已把 demo 值持久化到用户浏览器"的读取路径;读取侧无 legacy 校验 + 一次性 purge 无法覆盖其后的写回窗口。
- 为何上轮验证未拦:真实浏览器复验用"空 storage"登录(phantom=0),未覆盖"localStorage 已残留 sess-001 + 当前账号无可见会话"组合。
- 功能影响:老浏览器(修复前访问过 dev 且当时激活 demo 会话 id)+ 无可见会话账号首屏 4×404 噪音、chat 回退本地缓存;无数据损坏。
## 同类排查
- grep 生产代码:`sess-001` 常量已无(仅 tests + storage.ts legacy 清理集合)。
- 同 key 家族:`ACTIVE_SESSION` 是唯一"旧代码写回 demo 值 + 新代码读出不校验"路径;messages 已有 legacyIds 防御;sessions/deliverables/users/projects 走一次性 purge 且写回源为当前内存值(新代码不产生 demo 值)。
- `activeDocId` 的 `doc-001`/5201/3 本地选择残留维持上轮结论(无 API 请求,另行清理,不属本 bug)。
- ISSUES.md 开工检索命中 ISSUE-20260927-demo-fallback(本条即其残留路径);lessons 无新命中。
## 修复方案(A:读取侧幂等校验,共用机制)
1. `storage.ts` 提取共享常量 `LEGACY_DEMO_SESSION_IDS = {'sess-cusa-001','sess-001','sess-002'}`(与 `loadMessages` 同一集合,单一来源)。
2. `loadActiveSessionId` 读出 localStorage 值后命中该集合 → `removeItem` 该 key 并返回 fallback。每次启动幂等生效,覆盖任何历史/未来写回窗口,不依赖一次性 purge 版本升级。
3. `loadMessages` 复用共享常量,行为不变。
## 步骤与验收
1. [x] 根因与同类排查 — 见上文。
2. [x] 实施修复 — `web/src/data/storage.ts`(常量提取 + 读取侧清理);新增 `web/src/data/storageActiveSession.test.ts`(3 用例)。
3. [x] 单测 — node:test 515 pass/0 fail(含新增 3);vitest 34 pass/0 fail。
4. [x] 构建 — demo off/on 双模式 `npm run build` 均成功。
5. [x] 真实浏览器验证(worktree vite :3101 + dev 后端 :8080,Playwright chromium headless):
- A 原例:admin(user 4)+ 预置 `active_session='sess-001'` + purge 版本 key 已写 → 37 API 全 2xx、phantom=0、4xx5xx=0、残留 key 被清除;
- B 变体:`sess-cusa-001` 同样清除、phantom=0;
- C 回归:author(有真实会话)+ 预置 `sess-002` → 56 API 全 2xx、正常激活真实会话 `sess-p6020-u60`(真实 id 不误清)。
6. [x] 合入 dev — integrate prepare/validate/integrate 规范流程;dev `87db3621`→`36c5fb54`(--no-ff,first parent=D,validate 收据 ea2681ee)。
7. [x] dev 主入口(:3100,frp 用户同一入口)实际运行复验 — admin + 预置残留 `sess-001` + purge 版本 key 已写:37 API 全 2xx、phantom=0、4xx5xx=0、残留 key 被清除。
8. [x] 清理 worktree、收口 — ISSUES.md 更新 resolved、任务终态、CURRENT 置 done。
## 验证与证据
验证日期 2026-09-27;被测代码:worktree `fix/frontend-demo-fallback-2026-09-27-r3`(基准 dev `87db3621` + 本修复);环境:dev 后端 `127.0.0.1:8080`(ENV=dev 裸进程)+ worktree 独立 vite `:3101`(proxy /api → 8080)。账号:admin(本机 `.env`)与 author `e2e26_author_mui2xpg2`(来源 `2026-09-26-full-system-browser-e2e/audit-login-credentials.md`,凭证不入库)。
| 范围 | 命令与环境 | 预期 | 实际 / 判定 | 证据 |
|---|---|---|---|---|
| 单测(新增) | `npx tsx --test src/data/storageActiveSession.test.ts` | 3 pass | **PASS**:legacy 清除+返回 fallback、真实 id 不误清、SSR 安全 | 控制台输出(本节) |
| 单测(全量) | `npm test`(worktree) | 全绿 | **PASS**:node:test 515 pass/0 fail;vitest 34 pass/0 fail | 控制台输出 |
| 构建 | `npm run build`(off/on 双模式) | 成功 | **PASS**:66 组产物预压缩 ×2 | 控制台输出 |
| 原例(修复后) | 场景 A | 0 假请求 | **PASS**:37 API 全 2xx,phantom(sess-001)=0,key 被清除 | SUMMARY 输出(下附) |
| 同类变体 | 场景 B(sess-cusa-001) | 0 假请求 | **PASS**:37 API 全 2xx,phantom=0 | 同上 |
| 正常行为回归 | 场景 C(author,真实会话) | 不受损 | **PASS**:56 API 全 2xx,激活真实会话 | 同上 |
```text
SUMMARY: [{"phantom":0,"bad":0,"total":37,"activeAfter":""}, // A: admin + sess-001
{"phantom":0,"bad":0,"total":37,"activeAfter":""}, // B: admin + sess-cusa-001
{"phantom":0,"bad":0,"total":56,"activeAfter":"sess-p6020-u60"}] // C: author 回归
```
注:临时验证脚本未入库(/tmp 已删);worktree 独立 vite :3101 已停。
## 经验小结(补充 ISSUE-20260927 经验)
- 触发条件:持久化读取路径存在"旧版本可写入、新版本不校验"的值域(本例 active_session)。
- 机制:一次性 purge(版本 key 幂等)无法覆盖"purge 之后旧代码写回"的窗口;localStorage 已存值优先于 fallback,修掉 fallback 常量不影响已持久化的值。
- 应做检查:修复"假 ID 产生请求"类问题时,区分生成路径与持久化路径;对读取侧加值域校验(与 messages 的 legacyIds 同源),验证必须覆盖"老浏览器残留值"状态而非仅空 storage。
- 验证方法:预置残留 localStorage(含 purge 版本 key)+ 无可见会话账号登录,统计 Network 假请求。
## 收口与交接
- 剩余工作:无(授权范围验收全部满足)。后续可选项维持上轮结论:activeDocId 的 doc-001/5201/3 本地选择残留(无 API 请求,非本 bug);独立 lesson 文件补登。
- 状态分别记录:
- 本地提交:`739b8c56`(fix)+ `083c63bb`(docs,任务分支 fix/frontend-demo-fallback-2026-09-27-r3)。
- dev 合入:`36c5fb54`(candidate --no-ff)。
- 实际运行版本:dev vite :3100 热载 `36c5fb54` 工作区代码,复验 PASS。
- 远端同步:not_requested(用户未要求 push)。
- 清理:任务与候选 worktree 已按规范 remove(本节下方登记)。
@@ -0,0 +1,129 @@
---
title: "前端 demo fallback 在真实 dev 环境产生 404/403"
task_id: "frontend-demo-fallback-2026-09-27-r2"
status: done
created: 2026-09-27
updated: 2026-09-27
owner: pi
task_type: implementation
task_tier: small
policy_revision: "agent-governance-2026-09-21-r1 @ dev 56928ac2068fac3cc2a06efdc77d39717a6616f9"
branch: fix/frontend-demo-fallback-2026-09-27
worktree: .worktrees/frontend-demo-fallback-2026-09-27
base_dev_sha: "56928ac2068fac3cc2a06efdc77d39717a6616f9"
write_scope: ["web/src", ".doc/ops/short-term"]
allowed_environments: ["dev-readonly", "dev-browser-verify"]
head_sha: "db038aa7a7e883b3d7b3597a10bcc7a5a25608b8"
mutex: "web-chat-fallback"
review_state: not_required # 小任务;验证契约前端范围全过,无独立评审请求
integration_state: merged # dev 0de657f0(merge candidate integrate-frontend-demo-fallback-2026-09-27-r2,validate 收据 85420f37)
deployment: passed # dev vite :3100 热载新代码后真实浏览器复验 phantom=0/404/403=0(2026-09-27)
cleanup: done
cleanup_owner: "独立集成/维护执行者"
cleanup_trigger: "owner 退出且 dev 合入+验收证据齐备"
remote_sync: not_requested
---
# 前端 demo fallback 在真实 dev 环境产生 404/403
## 用户目标与授权
- 用户目标/授权来源:用户报告 dev 页面(frp-mix.com:58880)登录后控制台 7 个 API 404/403;会话中明确授权"按照规范进行修复,测试完成后合入 dev,清理 worktree"。
- 交付终点:修复合入 dev、dev 实际运行验证通过、worktree 清理。
- 禁止项:不 push 远端;不动 test/main;不改后端(本 bug 根因在前端 fallback)。
- 例外:无。
## 问题事实与根因(2026-09-27 排查)
- 现象:登录后首屏 `GET /api/v1/projects/1`、`/projects/1/settings`、`/chat/messages/window|categories|dates|unread?session_id=sess-001` 404;`/intent-plans/active?project_id=1` 403。
- 链路核实:frp-mix.com:58880 → vite dev :3100(proxy /api → 127.0.0.1:8080)→ `bin/agent-server`(ENV=dev,2026-09-26 构建/启动,裸进程非 compose)。后端路由全部存在。
- 数据核实(dev PG :5433 只读):`projects` 20 行无 id=1;`project_members` 无 project 1 成员;`chat_sessions` 80 行无 `sess-001`;user_id=4=系统管理员(真实登录用户)。
- 根因:demo seeds 关闭模式(vite 未设 `VITE_ENABLE_DEMO_SEEDS`,后端 `SEED_DEMO_USERS=false`)下,前端残留 demo 假设硬编码:
- `web/src/App.tsx:138` `loadActiveSessionId('sess-001')`——无本地会话时激活不存在的 demo 会话;
- `web/src/App.tsx:206` `currentProjectId` fallback `1`——找不到会话项目时默认不存在的项目 1。
- 为何防护未拦:`storage.ts` legacy 清理只过滤 messages 的 legacy sessionId(:121),不清 `activeSessionId`;`purgeDemoSeedsFromLocalStorage` 清 localStorage 但 fallback 常量会再生成假请求。
- 状态码差异属既有设计:`projects/:id` 对"不存在或无权限"统一 404;`intent-plans/active` 走 authorizer 映射 403。
- 功能影响:新登录用户首屏噪音 + chat 回退本地缓存;无数据损坏证据。
## 同类排查
- grep 全前端:`sess-001` 残留仅 App.tsx:138 一处(storage.ts:121 为正确防御);projectId fallback `1` 仅 App.tsx:206 一处。
- 观察不扩大范围:`App.tsx` activeDocId fallback 的 `doc-001`/5201/3 为 demo 残留,但仅影响本地文档选择、不发 API 请求,不属于本 bug(控制台 404 均为 API 请求);记录待后续清理。
- ISSUES.md 无同类记录(检索 404/demo 残留/purge 无命中)。
## 相关问题与经验
- issue_ids:本次新增 ISSUE-20260927-demo-fallback(登记于 ISSUES.md)。
- 开工检索:`404 fallback`、`sess-001`、`demo 残留`,lessons 无命中;采纳验证契约"问题修复回归范围"节。
- 收口经验:见闭环更新(ISSUES.md + 本文档验证节)。
## 修复方案(A:改共用 fallback 机制)
1. `App.tsx:138` `loadActiveSessionId('sess-001')` → `loadActiveSessionId()`:demo 开启时仍取 `NEUROPULSE_ACTIVE_SESSION_ID`,关闭时为 `''`(disabled 模式导出空串)。
2. `App.tsx:203-208` `currentProjectId` fallback `1` → `0`,注释同步。
3. 不需新增空态分支:`chatBlockedNoProject`(App.tsx:249)已含 `currentProjectId <= 0`,ChatColumn 渲染"请先创建或加入项目后再开始对话";会话纠正 effect(App.tsx:268-277)在可见会话出现时自动恢复 activeSessionId。
4. 下游 guard 已核(空 sessionId/projectId=0 不发请求):getProject/settings/lineage effect(:397,:421)、useChatWindow(:120)、useUnreadMarks(fetchUnread 顶部)、categories/dates effect(:1037)、intent-plans effect(:1060)。
## 步骤与验收
1. [x] 根因与同类排查 — 本文档上文。
2. [x] 实施修复 — App.tsx 两处改动(:138 fallback 去常量、:206 projectId fallback 0)。
3. [x] `web/` `npm test`、`npm run build` — 全绿(含 demo on/off 双模式构建)。
4. [x] 真实浏览器验证 — 修复前 9 假请求复现 / 修复后 0(author+member 双账号);老用户回归无新增 404/403。
5. [x] 合入 dev — integrate prepare/validate/integrate 规范流程;dev `56928ac2`→`0de657f0`(--no-ff,first parent=D)。
6. [x] dev 实际运行验证 — 主目录 vite :3100(frp 用户入口同一 server)热载新代码,空 storage 登录 phantom=0、404/403=0、工作台正常。
7. [x] 清理 worktree、收口 — 详见收口节。
## 验证与证据
验证日期 2026-09-27;被测代码:worktree `fix/frontend-demo-fallback-2026-09-27`(基准 dev `56928ac2` + 本修复);环境:本机 dev 后端 `127.0.0.1:8080`(ENV=dev,agent-server 裸进程)+ 独立 vite :3101(worktree 代码,proxy 同源配置)。浏览器:Playwright chromium headless(brew 用户态补齐运行库);账号:dev 本地审计 e2e 账号(凭证不入库,来源 `.doc/test-reports/assets/2026-09-26-full-system-browser-e2e/audit-login-credentials.md`)。
| 范围 | 命令与环境 | 预期 | 实际 / 判定 | 证据 |
|---|---|---|---|---|
| 前端单测 | `npm test`(worktree,node_modules 链接主目录) | 全绿 | **PASS**:tsx 512 pass/0 fail;vitest 34 pass/0 fail | 控制台输出(本节记录) |
| 前端构建(demo off) | `npm run build` | 成功 | **PASS**:built 无错误,66 组产物预压缩 | 控制台输出 |
| 前端构建(demo on) | `VITE_ENABLE_DEMO_SEEDS=true npm run build` | 成功(alias 切换不破坏类型) | **PASS**:✓ built in 9.40s | 控制台输出 |
| 原例复现(修复前对照) | 空 localStorage 登录主目录 :3100(旧代码) | 复现假请求 | **复现**:9 个 phantom(projects/1×4→403、sess-001×4→404、intent-plans 403);与用户报告一致 | Network 抓取清单(下附) |
| 原例修复(修复后) | 空 localStorage 登录 worktree :3101(新代码) | 零假请求 | **PASS**:phantom=0,404/403=0,工作台正常渲染,84 个真实 API 全 2xx | 同上 |
| 同类变体(第二角色) | member 账号同样流程 :3101 | 零假请求 | **PASS**:phantom=0,404/403=0,83 API 全 2xx | 同上 |
| 正常行为回归(老用户) | 同一 author 账号在 :3101 登录后真实会话/项目加载 | 不受损 | **PASS**:会话纠冀 effect 选真实会话,项目/文档/血缘 API 全 2xx | 同上 |
| 边界:demo enabled fallback | 代码审查 `loadActiveSessionId()` 无参路径 | demo 开启时仍回退 NEUROPULSE_ACTIVE_SESSION_ID | **PASS**:`fallback || NEUROPULSE_ACTIVE_SESSION_ID || ''` 优先级保留 demo 值 | 代码 diff + demo on 构建通过 |
修复前对照抓取(:3100,旧代码,author 账号):
```text
phantom: /api/v1/projects/1, /projects/1/settings, /projects/1/lineage,
/projects/1/documents?category=workflow, /chat/messages/window?session_id=sess-001&days=7,
/chat/unread?session_id=sess-001&user_id=60, /chat/categories?session_id=sess-001,
/chat/dates?session_id=sess-001, /intent-plans/active?project_id=1&session_id=sess-001
→ 403×5(project 1 无权限), 404×4(sess-001 不存在)
```
修复后(:3101,新代码,同账号 + member 变体):`phantom=0;404/403=0;workbench 正常渲染`。
注:临时验证脚本未入库(/tmp 与 web/ 下临时文件已删);worktree 独立 vite :3101 已停。用户报障中 `projects/1→404` 与本地复现 `→403` 的差异仅因报障账号(user 4 系统管理员)对该项目访问落在本项目不存在分支,两状态码均属既有「不存在或无权限」映射,非另改行为。
## 经验小结
- 触发条件:前端存在 demo/生产双模式(构建期 alias 切换)且模式专属常量进入运行时 fallback 路径。
- 机制:fallback 优先级高于模式开关清理逻辑;purge/legacy 清理只处理 storage 残留,无法阻止常量重新生成假 ID,首屏即对真实后端发请求。
- 应做检查:关闭模式的默认值必须是空值/由服务端数据驱动,不得硬编码业务对象 ID;模式常量 grep 其在非模式代码(App/入口/hooks)的引用;新用户首屏用空 storage 真实浏览器验证 Network。
- 错误做法与原因:只加 storage 清理不清理 fallback 常量(本例现状);只验证 demo 开启路径。
- 验证方法:修复前后同流程对照(本任务 before 9/after 0)+ 双模式构建 + 第二角色变体。
- 适用边界:前端双模式常量;同类见 App.tsx activeDocId 的 doc-001/5201/3 残留(仅本地选择无 API 请求,待后续清理)。
- 独立 lesson 文件待后续覆盖 `.doc/ops/lessons/` scope 的任务补登;本节为可检索替代。
## 收口与交接
- 剩余工作:无(授权范围验收全部满足)。后续可选项:activeDocId 的 doc-001/5201/3 本地选择残留(无 API 请求,非本 bug);独立 lesson 文件补登(需覆盖 lessons/ scope 的任务)。
- 状态分别记录:
- 本地提交:`db038aa7`(任务分支 fix/frontend-demo-fallback-2026-09-27)+ 本收口提交。
- dev 集成:merged,dev `0de657f0`(validate 收据 run 85420f37-2e99-4c9b-b72c-277d7203efe9,SHA `0de657f0`)。
- 部署制品:dev 前端为主目录 vite dev server(热载,无镜像制品);后端二进制未变更(纯前端修复)。
- 远端:not_requested(用户未要求 push;本地 dev 前进,origin/dev 未动)。
- cleanup:任务与 integrate 两个 worktree 均按规范 remove + 分支删除。
- 本次影响:App.tsx 两处 fallback;新登录用户首屏不再发 9 个假请求;demo 开启构建不受影响。
## 相关链接
- ISSUES.md 新增条目:ISSUE-20260927-demo-fallback。
@@ -0,0 +1,51 @@
---
title: "晋升 rc-v1.1.0-beta.4(dev→test)执行记录"
task_id: promote-rc-beta4-2026-09-27
status: done
created: 2026-09-27
updated: 2026-09-27
owner: pi
task_type: ops
task_tier: small
policy_revision: "AGENTS+worktree-ops @ 5e409c1e"
branch: feature/promote-rc-beta4-2026-09-27
worktree: .worktrees/promote-rc-beta4-2026-09-27
base_dev_sha: "5e409c1eb237814723f65102cb221a3e2de42e6e"
head_candidate: "2fe1e0559106654f7dd360d1f191c4798d467783"
write_scope: ["."]
allowed_environments: ["test"]
capabilities: [git:test, env:test, docs:publish]
mutex: git:test+env:test
review_state: accepted
integration_state: pending_merge
deployment: test_ok
cleanup: pending
remote_sync: not_requested
---
# 晋升 rc-v1.1.0-beta.4
## 用户目标与授权
用户指令(2026-09-27):把 dev 合入 test。授权来源:本会话明确指令;交付终点 = test 分支 rc 晋升 + 部署验收(单二进制化由伴生任务 test-single-binary-2026-09-27 执行)。
## 结果
- 门禁:dev tip `5e409c1e` nightly 五链真实 PI PASS(receipt `5e409c1e…json`,含三镜像 digests;`promotion-receipt-check --require-digests` OK)
- 候选:`2fe1e055`(commit-tree 构造 merge,P1=旧 test `0e4b111d`,P2=`5e409c1e`;validate run `2b9bac34`:receipt gate + 拓扑自检)
- 执行:`git:test` 租约内 update-ref + `git tag -a rc-v1.1.0-beta.4` + `candidate-images-apply.sh test`
- 验收与单二进制转换:见 [伴生测试报告](../../test-reports/2026-09-27-test-single-binary-test-report.md)
## 验证与证据
| 项 | 证据 |
|---|---|
| PASS 收据 + digests | `promotion-receipts/5e409c1eb237814723f65102cb221a3e2de42e6e{.json,.images.json}` |
| nightly 证据 | `promotion-receipts/evidence-5e409c1eb237-20260927T183704Z/` |
| 过程证据(nightly6 @94c215d3 五链 PASS、镜像步失败) | `promotion-receipts/evidence-94c215d3-recovered-20260927/`(原目录误删,归档完整原始日志,README 说明) |
| test 运行态 | health `env=test schema=76`;SPA 200;PI sidecar 18866 真实执行;S0 数据完整 |
## 收口
- deployment=test_ok(单二进制,schema 76);remote_sync=not_requested(未 push,origin/test 仍为 83c6a12a…本地 test 已前进两级 rc)
- cleanup=pending:本 worktree HEAD 为晋升候选 M2(test 引用内容),集成收据提交后由独立维护者复查移除

Some files were not shown because too many files have changed in this diff Show More