Merge authoritative main into the task branch

Why: include the current integration baseline before verification.

Evidence: fetched origin/main=d9ac28f89159e17781e2a8ef3094965130f29d2f.

Impact: integrate upstream changes without rewriting task history.

Refs: task-sync
This commit is contained in:
2026-10-19 01:39:07 +00:00
165 changed files with 32570 additions and 644 deletions
+21 -1
View File
@@ -1,7 +1,6 @@
name: ci
on:
pull_request:
branches: [main]
push:
branches: [main]
@@ -46,6 +45,7 @@ jobs:
"modules/ui": "Agent-System-UI",
"modules/documents": "Agent-System-Documents",
"deps/agent-system-core": "Agent-System-Core",
"deps/agent-document-renderer": "Agent-Document-Renderer",
"deps/development-guidelines": "Development-Guidelines",
"deps/agent-native": "Agent-Native",
"deps/agent-squad": "Agent-Squad",
@@ -53,6 +53,8 @@ jobs:
"deps/agent-command": "Agent-Command",
"deps/error-code-system": "Error-Code-System",
"deps/logging-system": "Logging-System",
"deps/development-manager": "Development-Manager",
"development/guidelines": "Development-Guidelines",
}
root_token = os.environ.pop("TOKEN", "")
component_token = os.environ.pop("SUBMODULE_TOKEN", "")
@@ -156,6 +158,8 @@ jobs:
print("Checkout complete; credentials were not persisted in Git configuration")
PY_CHECKOUT
unset TOKEN SUBMODULE_TOKEN
- name: PR base gate
run: python3 scripts/task_pr_check.py ci
- name: Install Go 1.27.1
run: |
set -euo pipefail
@@ -163,6 +167,10 @@ jobs:
tar -C /usr/local -xzf "$RUNNER_TEMP/go.tgz"
ln -sfn /usr/local/go/bin/go /usr/local/bin/go
ln -sfn /usr/local/go/bin/gofmt /usr/local/bin/gofmt
- name: Validate AGENT-EXECUTION.md with the pinned shared executor
run: scripts/agent-exec validate --repo .
- name: Governance check with the pinned kit
run: scripts/dm governance check --repo .
- name: Install Node 22
run: |
set -euo pipefail
@@ -179,6 +187,9 @@ jobs:
# 缺服务时失败而非跳过(make test-backend-pg 硬校验环境变量);
# 组件版本随 job 输出固定,供验收记录对齐(方案 KTD12/U2)。
test-pg:
# 分级门禁:base 非 main 的 PR(L2 child → L1 initiative)只跑轻量 CI(test 作业);
# 进入 main 的 PR 与 main 推送跑全量门禁。
if: ${{ github.event_name != 'pull_request' || github.base_ref == 'main' }}
runs-on: ubuntu-latest
env:
GOPROXY: https://goproxy.cn,direct
@@ -218,6 +229,7 @@ jobs:
"modules/ui": "Agent-System-UI",
"modules/documents": "Agent-System-Documents",
"deps/agent-system-core": "Agent-System-Core",
"deps/agent-document-renderer": "Agent-Document-Renderer",
"deps/development-guidelines": "Development-Guidelines",
"deps/agent-native": "Agent-Native",
"deps/agent-squad": "Agent-Squad",
@@ -225,6 +237,8 @@ jobs:
"deps/agent-command": "Agent-Command",
"deps/error-code-system": "Error-Code-System",
"deps/logging-system": "Logging-System",
"deps/development-manager": "Development-Manager",
"development/guidelines": "Development-Guidelines",
}
root_token = os.environ.pop("TOKEN", "")
component_token = os.environ.pop("SUBMODULE_TOKEN", "")
@@ -470,6 +484,9 @@ jobs:
# identity 领养/verify、release 切换、伴生工作台、RDM 全轨部署。缺件即失败,
# 不静默跳过(SVC_TEST_REAL=1 硬开关)。
svc-realcombo:
# 分级门禁:base 非 main 的 PR(L2 child → L1 initiative)只跑轻量 CI(test 作业);
# 进入 main 的 PR 与 main 推送跑全量门禁。
if: ${{ github.event_name != 'pull_request' || github.base_ref == 'main' }}
runs-on: ubuntu-latest
env:
GOPROXY: https://goproxy.cn,direct
@@ -509,6 +526,7 @@ jobs:
"modules/ui": "Agent-System-UI",
"modules/documents": "Agent-System-Documents",
"deps/agent-system-core": "Agent-System-Core",
"deps/agent-document-renderer": "Agent-Document-Renderer",
"deps/development-guidelines": "Development-Guidelines",
"deps/agent-native": "Agent-Native",
"deps/agent-squad": "Agent-Squad",
@@ -516,6 +534,8 @@ jobs:
"deps/agent-command": "Agent-Command",
"deps/error-code-system": "Error-Code-System",
"deps/logging-system": "Logging-System",
"deps/development-manager": "Development-Manager",
"development/guidelines": "Development-Guidelines",
}
root_token = os.environ.pop("TOKEN", "")
component_token = os.environ.pop("SUBMODULE_TOKEN", "")
+6
View File
@@ -34,3 +34,9 @@
[submodule "deps/agent-command"]
path = deps/agent-command
url = ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-Command.git
[submodule "deps/development-manager"]
path = deps/development-manager
url = ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Development-Manager.git
[submodule "deps/agent-document-renderer"]
path = deps/agent-document-renderer
url = ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-Document-Renderer.git
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+361
View File
@@ -0,0 +1,361 @@
# feature/ecs-sync-local-dev 任务卡
任务主记录:PR #612 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/612;状态:已完成(合入前闭合);owner:weichen
## 基线与授权
- 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= 26f3f050313aa4a96cabcca6bdddc29de63351e7
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-ecs-sync-local-dev(worktree);分支:feature/ecs-sync-local-dev
- 分支类型:standalone;root_target:main;immediate_target:main;accepting_requirements:false
- 需求分流:verdict=NEW;selected_initiative=无;requirement_sha256=9117e9fbaa296aa429645a2f370f4a442cadd5b1f80b04a87cf62bed311a5f64;triage_receipt=/tmp/ecs-sync-local-triage.json;receipt_sha256=0c6b0c064d573034e00194319ab9cdc1e9b10b610f79064b95c9e735297028e8
- 授权与交付终点:owner 2026-10-18 指令“将 imc-tx-ecs 上的服务更新到本机同样的版本”——ECS 唯一服务 dev 8788(systemd 用户服务 agent-system-dev.service)更新到本机 dev 当前版本 dev@a706e9a+rdm@4b2473bed112(二进制 sha256 1f45f640…),先备份、数据零丢失;终点为 ECS 运行该版本且数据对账通过,本仓仅任务卡。未授权:修改产品代码、改启动参数/插件激活/Caddy、签发登录 Key 或改账号凭据。
- 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进)
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
- 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入)
- 人工决策点:仅限目标/范围/验收变更、重大取舍、高后果操作或无法自动判定的业务验收
- 当前阶段:合入核验与收口;当前增量:I1(ECS dev 8788 版本同步)
- 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位)
## 目标与非目标
预期结果:ECS(imc-tx-ecs,imcrd-agent.imcbot.work → 127.0.0.1:8788)由 rdm@b8cdf01(组合二进制 792af245…,schema v34)更新为与本机 dev 相同的 dev@a706e9a+rdm@4b2473bed112(1f45f640…,schema v35),htdocs 同步为本机 release 内容;用户数据零丢失。受影响:ECS runtime/dev/bin/agent-system、htdocs、svc.env/svc.pid/history.jsonl 登记,以及新版启动时的自动迁移(schema v35 exec_env 表;settings 明文密钥迁入 secret_keys)。非目标:不改产品代码、systemd 单元参数、插件目录与 Caddy;不处理 agent-system-admin/cli 旧二进制。注意:a706e9a 位于 feature/auth-one-time-password,尚未合入 main(按 owner“与本机同版本”的指令执行)。
## Agent 实施收据
路由与 fail-stop 规则见根目录 AGENT-EXECUTION.md 与 policy/delivery.md;每次尝试一行,原始日志留在源码外收据路径。
| 单元 ID | 预期范围 | 配置摘要 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|---|---|---|---|---|---|---|---|---|---|---|
| 无(运维任务,无仓库代码单元;仓库写入仅 .task/** host 豁免) | — | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | — |
## 关联方向与规划
- 适用状态:待核对(无适用规划时说明原因)
- 主记录路径/版本:待核对(路径按仓库根目录定位,归档后不变;只引用唯一正文)
- 对应里程碑:待核对
## 需求分析
| ID | 描述 | 项目符合度及依据 | 优先级 | 验收条件 | 依赖 | 结论 |
|---|---|---|---|---|---|---|
| R1 | ECS dev 8788 更新到本机 dev 同版本 | 符合(owner 指令) | P0 | 运行中进程 exe sha256=1f45f640…;服务与恢复定时器 active;本地与域名 HTTP 200;schema v35 | 无 | 达成 |
| R2 | 先备份、数据零丢失 | 符合 | P0 | 停机冷备份 sha 校验 + 本机异地副本;冷备份 manifest ↔ 更新后逐行对账 problems=[];迁出的明文密钥与 secret_keys 逐把一致 | R1 | 达成 |
## 方案与计划
- 方案引用:待填写(含对象版本)
- 实施计划引用:待填写(含增量与需求 ID)
- 测试计划引用:待填写(含需求 ID 与验收条件)
## 阶段记录
| 阶段 | 对象版本 | 状态 | 决策/执行者 | 时间 | 依据 |
|---|---|---|---|---|---|
| 需求拆解 | 待定 | 待执行 | — | — | — |
| 需求评估 | 待定 | 待执行 | — | — | — |
| 需求表确认 | 待定 | 待执行 | — | — | — |
| 方案设计 | 待定 | 待执行 | — | — | — |
| 实施计划 | 待定 | 待执行 | — | — | — |
| 实施与自检 | 待定 | 待执行 | — | — | — |
| 正式测试与验收 | 待定 | 待执行 | — | — | — |
| 代码 Review | 待定 | 待执行 | — | — | — |
| 合入 | 待定 | 待执行 | — | — | — |
| 合入核验与收口 | 待定 | 待执行 | — | — | — |
## 探索试验与迭代
| 增量/试验 | 假设 | 范围 | 判断和停止条件 | 授权/决策依据 | 结果 | 变更影响 | 需重审补测 |
|---|---|---|---|---|---|---|---|
| 待定义 | — | — | — | 待核对 | NOT_RUN | 待评估 | 待评估 |
## 同步记录
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|---|---|---|---|
| 启动 | 26f3f050313aa4a96cabcca6bdddc29de63351e7 | 26f3f050313aa4a96cabcca6bdddc29de63351e7 | 2026-10-18T06:18:30Z |
## 证据(Evidence)
<!-- CMD="<命令>" make evidence 写入;手抄/转写输出视为无效证据(AGENTS.md 证据与验证门禁)。 -->
| 时间(UTC) | 命令 | 被测HEAD | exit | 来源 | sha256(16) |
|---|---|---|---|---|---|
## 交付调度
- 调度状态:未入队;调度记录:无
- entry_id:无;attempt_id:无;窗口执行者:无
- 固定候选:无(base/head、组件与相关配置引用实际尝试)
- 调度依据:policy/delivery.md#合入调度
- 固定后证据:源码外 RECEIPT;实际结果后按授权原样导入和闭合
## 结果与验证
- 结果:2026-10-18 14:20:24–14:20:27(CST)切换完成,停机约 3 秒;ECS 8788 现由 systemd 运行 dev@a706e9a+rdm@4b2473bed112(pid 4080336,exe sha256 1f45f640…,schema v35),htdocs 与本机 release 一致,svc.env/svc.pid 已登记新 PID 与来源,history.jsonl 追加 deploy 事件。冷备份:ECS runtime/dev/backups/20261018T062018Z-cold-pre-a706e9a(data、bin-old、htdocs-old、systemd 单元、Caddyfile、MANIFEST.json、SHA256SUMS),本机异地副本 ~/backups/imc-tx-ecs/20261018T062018Z-cold-pre-a706e9a。切换脚本 ~/ecs-ops/cutover-a706e9a.sh(含健康检查失败自动回滚,本次未触发)。
- 验证:运行版本/服务/HTTP(本地与域名 200)/schema v35 PASS;冷备份 sha 校验与异地副本 sha 校验 PASS;冷备份 manifest ↔ 更新后逐行对账 problems=[](零缺失,新增行为切换后用户正常使用)PASS;settings 中 5 类明文密钥(user 与 system 两个 scope 共 10 把)由新版启动迁移移入 secret_keys,逐把与备份明文一致 PASS;启动日志无 error/warn PASS;切换后新对话正常进入推理 PASS;浏览器登录与插件列表界面核对 NOT_RUN(ECS 无可用 API key、未签发登录 Key)。全部来源 SELF。
- 影响与剩余项:
- 回滚:v35 对旧读者兼容(migrate_compat 35=false),可将 bin-old/agent-system 放回并重启;但旧版 settings 读不到已迁入 secret_keys 的密钥,回滚需同时恢复冷备份 data(会丢失切换后的新数据)或重新写回明文密钥。
- 部署版本 a706e9a 位于未合入 main 的 feature/auth-one-time-password 分支,ECS 现运行未合入代码。
## 规划进展与下一步
- 本次推进/剩余:待核对(依据实际成果更新适用方案/规划)
- 首选下一任务:待核对(无适用规划、已完成或受阻时如实说明,不虚构任务)
- 推荐依据:待填写
- 前置条件/待确认:待核对
- 预期产物/验收条件:待定义
- 重复任务核对:待核对(已有/在途任务、PR 与规划记录)
- 启动授权:未授权(建议不自动启动新任务,仍须明确授权)
## 合入与清理
- Review 记录:当前主模型(Cursor host 会话)审阅;base 26f3f05 / head feature/ecs-sync-local-dev;diff 仅本任务卡;重放 ECS 运行 pid=svc.pid=4080336、exe sha256 前缀 1f45f640、服务与恢复定时器 active、域名 200,与证据一致;恢复定时器切换后无拉起记录;结论通过,无阻塞项。非独立 CLI 会话(来源 SELF)。
- 冲突记录:task-sync 于 2026-10-18T06:38:51Z 对 origin/main 26f3f05 同步,changed=0,无冲突。
- CI 记录:NOT_RUN(当前 HEAD 完整 SHA、全部必需检查、运行链接、执行身份及 GATE 结果)
- 合入记录:NOT_RUN(交付授权范围、PR、被核验 HEAD、合入 SHA、目标分支及内容核验)
- 清理记录:NOT_RUN(授权依据、写者退出确认、worktree/分支/任务卡处置)
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T06:17:45.128636+00:00",
"command": "make precheck",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev",
"before_head": "26f3f050313aa4a96cabcca6bdddc29de63351e7",
"after_head": "26f3f050313aa4a96cabcca6bdddc29de63351e7",
"branch": "main",
"target_branch": "main",
"target_head": "26f3f050313aa4a96cabcca6bdddc29de63351e7",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"[repo] branch=main head=26f3f05031",
"[remote] origin/main=26f3f05031 ahead=0 behind=0",
"[tree] clean submodules_drift=0 uninit=3",
"[warn] 3 个子模块未初始化——构建/测试前需物化(不阻断写入)",
"[worktrees] linked=13",
"[recycle] merged un-recycled branches: feature/card-close-20261015-064117Z feature/card-close-auth-password-management feature/layered-python-env feature/workbench-flow-completion fix/model-key-secret-overlay",
"[initiatives] local cards (not authoritative): none",
"[cards] 闭合分支超过 24 小时未合入:feature/card-close-agent-cli-enforcement feature/card-close-workbench-flow-20261015",
"[hooks] core.hooksPath=scripts/hooks(pre-commit/post-merge 实际接线)",
"[facts] policy/facts.md 6 条事实均在有效期内",
"[required-reading] core/baseline.md, workflows/delivery.md §1, policy/delivery.md",
"[R0] 26f3f05031(完整:26f3f050313aa4a96cabcca6bdddc29de63351e7)",
"[worktree] before-sync: recursive component checks passed",
"[verdict] READY — 保留本次 precheck receipt 后建任务工作区:PRECHECK_RECEIPT=/tmp/task-precheck.json make task-start NAME=feature/your-branch",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev'"
],
"output_sha256": "9736744e580f84ae74bbc75fd0c2a09b68bd17ff5b2890f4f6bdf31e4b6c9e7d",
"receipt_sha256": "128b1a86cd57436cd2c4179ba245bdcf71f8c498f2052582b377283ef0b0ff39",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/128b1a86cd57436cd2c4179ba245bdcf71f8c498f2052582b377283ef0b0ff39.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T06:20:42.275003+00:00",
"command": "ssh imc-tx-ecs 'P=$(systemctl --user show agent-system-dev.service -p MainPID --value); echo pid=$P; sha256sum /proc/$P/exe | cut -c1-64; systemctl --user is-active agent-system-dev.service agent-system-svc-recover.timer; grep -E \"^(pid|source|version)=\" ~/weichen/Agent-System-Dev/runtime/dev/svc.env; cat ~/weichen/Agent-System-Dev/runtime/dev/svc.pid; curl -sS -o /dev/null -w \"local=%{http_code}\\n\" http://127.0.0.1:8788/; curl -sS -o /dev/null -w \"domain=%{http_code}\\n\" https://imcrd-agent.imcbot.work/; python3 -c \"import sqlite3; print(\\\"schema_max\\\", sqlite3.connect(\\\"file:/home/ubuntu/weichen/Agent-System-Dev/runtime/dev/data/agent-system.db?mode=ro\\\",uri=True).execute(\\\"select max(version) from schema_migrations\\\").fetchone()[0])\"'",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-ecs-sync-local-dev",
"before_head": "ce3e7110f25efc31ad1d925e3867bedb86d26014",
"after_head": "ce3e7110f25efc31ad1d925e3867bedb86d26014",
"branch": "feature/ecs-sync-local-dev",
"target_branch": "main",
"target_head": "26f3f050313aa4a96cabcca6bdddc29de63351e7",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"pid=4080336",
"1f45f64077b8dffd25d80513e3aaf5f06c71c8a09248c21af22f9d33eab516b9",
"active",
"active",
"pid=4080336",
"source=dev@a706e9a+rdm@4b2473bed112",
"version=agent-system 0.1.0-dev",
"4080336",
"local=200",
"domain=200",
"schema_max 35"
],
"output_sha256": "2a2c0e09a38760fa0fb9fd78f59443251fdafebd3965ee49b92e3f16c72e22b8",
"receipt_sha256": "04e761ab05523603f8fe9e893eb84314267af2bb84ccee7b40ea742132c667a6",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/04e761ab05523603f8fe9e893eb84314267af2bb84ccee7b40ea742132c667a6.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T06:21:02.444374+00:00",
"command": "ssh imc-tx-ecs 'cd /home/ubuntu/weichen/Agent-System-Dev/runtime/dev/backups/20261018T062018Z-cold-pre-a706e9a && python3 ~/ecs-dbsnap.py manifest /home/ubuntu/weichen/Agent-System-Dev/runtime/dev/backups/20261018T062018Z-cold-pre-a706e9a/data /home/ubuntu/weichen/Agent-System-Dev/runtime/dev/backups/20261018T062018Z-cold-pre-a706e9a/MANIFEST.json && find data bin-old htdocs-old config -type f -exec sha256sum {} + > SHA256SUMS && sha256sum -c --quiet SHA256SUMS && wc -l < SHA256SUMS && python3 ~/ecs-dbsnap.py compare /home/ubuntu/weichen/Agent-System-Dev/runtime/dev/backups/20261018T062018Z-cold-pre-a706e9a/MANIFEST.json /home/ubuntu/weichen/Agent-System-Dev/runtime/dev/data'",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-ecs-sync-local-dev",
"before_head": "ce3e7110f25efc31ad1d925e3867bedb86d26014",
"after_head": "ce3e7110f25efc31ad1d925e3867bedb86d26014",
"branch": "feature/ecs-sync-local-dev",
"target_branch": "main",
"target_head": "26f3f050313aa4a96cabcca6bdddc29de63351e7",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "7a084c5790e15f97a41f5bca9dd14d4fc8da233e261f41465d64cfc9e8ba66e1",
"after_tracked_diff_sha256": "7a084c5790e15f97a41f5bca9dd14d4fc8da233e261f41465d64cfc9e8ba66e1",
"output_tail": [
" \"files\": {",
" \"base\": 456,",
" \"now\": 458,",
" \"missing\": [],",
" \"changed\": [",
" \"workspaces/yuzhongde/cnv_3a5839f75104/.agentx/transcript.jsonl\",",
" \"workspaces/yuzhongde/cnv_3a5839f75104/.agentx/transcript.jsonl.meta.json\"",
" ],",
" \"added\": [",
" \"artifacts/blob_3702c5068ac7\",",
" \"workspaces/yuzhongde/cnv_3a5839f75104/inputs/RDDHF0302-0095 冲击波治疗仪系统设计方案 V2.0.docx\"",
" ]",
" },",
" \"problems\": []",
"}"
],
"output_sha256": "325212538120481b1ce0223faf019bd200fdc5545ffb20e31b271103dbbb0e75",
"receipt_sha256": "66e6777c9f19df05df9f5d1240990973ba76bd809733ea461e18c5c2592c3f00",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/66e6777c9f19df05df9f5d1240990973ba76bd809733ea461e18c5c2592c3f00.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T06:23:40.506450+00:00",
"command": "ssh imc-tx-ecs 'python3 ~/ecs-ops/secret-check.py'",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-ecs-sync-local-dev",
"before_head": "ce3e7110f25efc31ad1d925e3867bedb86d26014",
"after_head": "ce3e7110f25efc31ad1d925e3867bedb86d26014",
"branch": "feature/ecs-sync-local-dev",
"target_branch": "main",
"target_head": "26f3f050313aa4a96cabcca6bdddc29de63351e7",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "b0976d4b673b94153603b11ffbc854169ebe3c96c5ac5c56c34030c0f147f6f1",
"after_tracked_diff_sha256": "b0976d4b673b94153603b11ffbc854169ebe3c96c5ac5c56c34030c0f147f6f1",
"output_tail": [
"owner='weichen' scope=user models.chat -> secret_keys match=True",
"owner='weichen' scope=user models.lightweight -> secret_keys match=True",
"owner='weichen' scope=user models.embedding -> secret_keys match=True",
"owner='weichen' scope=user models.rerank -> secret_keys match=True",
"owner='weichen' scope=user tools.tavily -> secret_keys match=True",
"owner='' scope=system models.chat -> secret_keys match=True",
"owner='' scope=system models.lightweight -> secret_keys match=True",
"owner='' scope=system models.embedding -> secret_keys match=True",
"owner='' scope=system models.rerank -> secret_keys match=True",
"owner='' scope=system tools.tavily -> secret_keys match=True",
"settings_snapshots=9 mismatches=0"
],
"output_sha256": "142d0810997be0a978e3a84084dce4bae4f11d17c3560d7651682facddd44f9f",
"receipt_sha256": "c4ee63cd7a13fd75c9329467ea5d162b91b190865c440934aa17aaa6d098b321",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/c4ee63cd7a13fd75c9329467ea5d162b91b190865c440934aa17aaa6d098b321.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T06:24:03.640459+00:00",
"command": "ssh imc-tx-ecs 'journalctl --user -u agent-system-dev.service --since \"2026-10-18 14:20:25\" --no-pager -o cat | grep -v \"genai span\" | grep -i -E \"plugin|error|panic|fatal|warn|listen|migrat\" | cut -c1-220 | head -30; python3 -c \"import sqlite3; d=sqlite3.connect(\\\"file:/home/ubuntu/weichen/Agent-System-Dev/runtime/dev/data/agent-system.db?mode=ro\\\",uri=True); print(d.execute(\\\"select status, count(*) from runs where started_at >= \\\\\\\"2026-10-18T06:20\\\\\\\" group by 1\\\").fetchall())\"'",
"exit_code": 1,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-ecs-sync-local-dev",
"before_head": "ce3e7110f25efc31ad1d925e3867bedb86d26014",
"after_head": "ce3e7110f25efc31ad1d925e3867bedb86d26014",
"branch": "feature/ecs-sync-local-dev",
"target_branch": "main",
"target_head": "26f3f050313aa4a96cabcca6bdddc29de63351e7",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "b0426e3da3d17d6d9a6674e4e2b834ac69c0b3602b936faf03eb682448c68378",
"after_tracked_diff_sha256": "b0426e3da3d17d6d9a6674e4e2b834ac69c0b3602b936faf03eb682448c68378",
"output_tail": [
"2026/10/18 14:20:26 agent-system serving on http://0.0.0.0:8788 (data: /home/ubuntu/weichen/Agent-System-Dev/runtime/dev/data, plugins: /home/ubuntu/weichen/Agent-System-Dev/runtime/dev/plugins)",
"Traceback (most recent call last):",
" File \"<string>\", line 1, in <module>",
"sqlite3.OperationalError: no such column: started_at"
],
"output_sha256": "3fa6fa9adb451343793233e0c5f751bbd610bc1b1423c3159fb7c0a3f172b542",
"receipt_sha256": "3819a4e5825b1ec8fa2cad03ecfd2e51067c4601466963f02bef08e1c79516a1",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/3819a4e5825b1ec8fa2cad03ecfd2e51067c4601466963f02bef08e1c79516a1.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T06:24:29.656967+00:00",
"command": "ssh imc-tx-ecs 'python3 -c \"import sqlite3; d=sqlite3.connect(\\\"file:/home/ubuntu/weichen/Agent-System-Dev/runtime/dev/data/agent-system.db?mode=ro\\\",uri=True); print(d.execute(\\\"select created_at, status, phase, length(coalesce(error,\\\\\\\"\\\\\\\")) from runs order by rowid desc limit 3\\\").fetchall())\"'",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-ecs-sync-local-dev",
"before_head": "ce3e7110f25efc31ad1d925e3867bedb86d26014",
"after_head": "ce3e7110f25efc31ad1d925e3867bedb86d26014",
"branch": "feature/ecs-sync-local-dev",
"target_branch": "main",
"target_head": "26f3f050313aa4a96cabcca6bdddc29de63351e7",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "2cffdb86d1706ca8576580b3591cfc63092115d8057561e07cd6e8582f1f4a54",
"after_tracked_diff_sha256": "2cffdb86d1706ca8576580b3591cfc63092115d8057561e07cd6e8582f1f4a54",
"output_tail": [
"[('2026-10-18T06:21:01.98880041Z', 'running', 'thinking', 4), ('2026-10-18T06:16:09.9173973Z', 'completed', 'done', 4), ('2026-10-18T06:13:16.808336756Z', 'completed', 'done', 4)]"
],
"output_sha256": "55cea8240269ea6a829368012c22af253633bad4ac56821482ad476eac818a3e",
"receipt_sha256": "ddf9a748e13d976417d1dbac0604a8c89c885af61aa091ac8b613987e43940c9",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/ddf9a748e13d976417d1dbac0604a8c89c885af61aa091ac8b613987e43940c9.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T06:37:10.261787+00:00",
"command": "sh -c 'cd /home/weichen/backups/imc-tx-ecs/20261018T062018Z-cold-pre-a706e9a && sha256sum -c --quiet SHA256SUMS && echo OFFSITE_SHA_OK files=$(wc -l < SHA256SUMS)'",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-ecs-sync-local-dev",
"before_head": "ce3e7110f25efc31ad1d925e3867bedb86d26014",
"after_head": "ce3e7110f25efc31ad1d925e3867bedb86d26014",
"branch": "feature/ecs-sync-local-dev",
"target_branch": "main",
"target_head": "26f3f050313aa4a96cabcca6bdddc29de63351e7",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "102b857bec8f2c3b3a9dafd7c5efc194570a362cd82590745a058c8d714f2f14",
"after_tracked_diff_sha256": "102b857bec8f2c3b3a9dafd7c5efc194570a362cd82590745a058c8d714f2f14",
"output_tail": [
"OFFSITE_SHA_OK files=476"
],
"output_sha256": "ad933be8979c37a6294a0bbb7acc1718f01e1c925038eb30b779ee21e0115e90",
"receipt_sha256": "881202c15a5bc49bd3e277bdc24dac143ec5ed2ca6f6f93d9d3449bf39a6a3a1",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/881202c15a5bc49bd3e277bdc24dac143ec5ed2ca6f6f93d9d3449bf39a6a3a1.json"
}
```
## 闭合记录(合入前折叠)
- 本卡在 PR #612(https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/612)合入前闭合并归档,随该 PR 一同合入。
- 该 PR 的合并提交即本任务的落地记录。
- 合入后无需回填,也无需单独的闭合 PR。
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,156 @@
# feature/governance-v2-closed 任务卡
任务主记录:[Agent-System-Dev PR #604](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/604);状态:已完成(随本 PR 合入生效;合入以平台记录为准);owner:weichen
## 基线与授权
- 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= f563ed612a9574e798ee3421c010a9e2ceb416a0
- 工作区:/tmp/dev-close-114347-wt-feature-governance-v2-closed(worktree);分支:feature/governance-v2-closed
- 分支类型:standalone;root_target:main;immediate_target:main;accepting_requirements:false
- 需求分流:verdict=NEW;selected_initiative=无;requirement_sha256=28c52ebbc76355bd2de798ed5cc0e28adcbfd15019e83f92aadfb19dc8fcbd68;triage_receipt=/tmp/triage-gov-closed.json;receipt_sha256=c58bc0921ce7be08bd491ed241d224c28bbd1b955090366fe46986fe2c35ffd0
- 授权与交付终点:owner 已授权 development-governance-v2 全部实施(/goal);owner 2026-10-17 授权(AskQuestion temp_clone)在 /tmp 干净克隆中完成收尾,不触碰共享主检出(其 modules/frontend 有他人未提交改动,precheck SHARED_WORKSPACE_BUSY)。终点:本 PR 合入 main——主记录 Dev 行 ADOPTED_ACTIVE、全局状态 CLOSED,并以 `make task-close FOLD=--fold` 闭合归档 PR #602 卡与本卡。不执行分支保护或 tag(双钥匙)。
- 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进)
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
- 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入)
- 人工决策点:仅限目标/范围/验收变更、重大取舍、高后果操作或无法自动判定的业务验收
- 当前阶段:收尾完成,合入待本 PR 平台核验;当前增量:I1(主记录 CLOSED 回填 + 卡片闭合)
- 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位)
## 目标与非目标
目标:主记录 `docs/superpowers/plans/2026-10-16-development-governance-v2-master.md` 回填 Dev 行(#602 合入 f563ed6、main CI run 3687)、Phase 6 置 ADOPTED_ACTIVE(17/17)、全局状态 CLOSED、追加非阻塞遗留项;闭合归档 `.task/archive/feature-governance-v2-closeout.md`(原 `.task/` 下,本 PR 移入归档)。
非目标:不改代码、脚本、配置或 gitlink;不执行分支保护或 tag。
## Agent 实施收据
按根目录 AGENT-EXECUTION.md 路由;外部 Agent 一单元一新进程/工作区。实施、修复与测试的正常候选仅为 Cursor、Antigravity(agy)和 PI;每个候选对安全可恢复失败最多 3 次全新尝试,然后才换下一候选。三者都安全耗尽后,才允许一次全新的 Codex CLI 紧急尝试。Codex 平时只用于规划、方案设计、实施计划或独立 Review。显式 fail-stop(failed-unknown、scope-expansion、blocked、cancelled、无效配置、未对账 Git 状态与安全失败)立即停止。不因推理时长、工具次数、规划方式或首次写文件时间判定失败;尝试只在显式终态失败、进程退出、总超时,或 stdin/stdout/stderr 均无活动的空闲超时时失败。CLI 可在目标、范围与安全边界内自主检查、计划、测试并迭代。实施集成必须是成功 transport 上的 scripts/agent-exec apply,或 pre-commit admit 的精确内容来源。host 直接管理的豁免仅为 .task/**、docs/superpowers/specs/** 与 docs/superpowers/plans/**。fallback 列只记录该行是否为 Codex 紧急尝试。安全耗尽不发出 host-fallback-authorized,终态为 unavailable 或 blocked。不授权 host 直接撰写该单元。原始日志保留在源码外收据路径。
| 单元 ID | 预期范围 | 配置摘要 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|---|---|---|---|---|---|---|---|---|---|---|
| 无实施单元 | 仅 host 豁免路径(`docs/superpowers/plans/**`、`.task/**`) | — | — | — | — | — | 不适用 | 无 | 否 | — |
## 关联方向与规划
- 适用状态:适用
- 主记录路径/版本:`docs/superpowers/plans/2026-10-16-development-governance-v2-master.md`(本 PR 版本)
- 对应里程碑:development-governance-v2 最终收口(全局状态 CLOSED)
## 需求分析
| ID | 描述 | 项目符合度及依据 | 优先级 | 验收条件 | 依赖 | 结论 |
|---|---|---|---|---|---|---|
| R1 | 主记录回填 Dev 行、Phase 6 置 ADOPTED_ACTIVE(17/17)、全局状态 CLOSED(条件生效),并闭合归档两张卡 | 符合:/goal 交付终点要求主记录收口 | 高 | 主记录与卡片事实一致;独立 Review 无阻塞;PR HEAD CI 通过 | Dev #602 合入(f563ed6) | 已实施,待合入 |
## 方案与计划
- 方案引用:主记录本身(`docs/superpowers/plans/2026-10-16-development-governance-v2-master.md`)
- 实施计划引用:不适用(单增量文档收口,仅 host 豁免路径,无实施单元)
- 测试计划引用:不适用(无代码变更;以独立 Review 与 PR HEAD CI 为准)
## 阶段记录
| 阶段 | 对象版本 | 状态 | 决策/执行者 | 时间 | 依据 |
|---|---|---|---|---|---|
| 需求拆解 | f563ed6 | 已完成 | host | 2026-10-17 | /goal 交付终点 |
| 需求评估 | f563ed6 | 已完成 | host | 2026-10-17 | 同上 |
| 需求表确认 | f563ed6 | 已完成 | owner(/goal 一次确认) | 2026-10-17 | 同上 |
| 方案设计 | — | 不适用 | — | — | 单增量文档收口 |
| 实施计划 | — | 不适用 | — | — | 同上 |
| 实施与自检 | 本 PR HEAD | 已完成 | host(豁免路径) | 2026-10-17 | 本 PR diff |
| 正式测试与验收 | 本 PR HEAD | 以 CI 为准 | Gitea CI | 2026-10-17 | 合入与清理节 |
| 代码 Review | a869453 → 修复后 HEAD | 首轮 BLOCK,已修复并复审 | 独立 Cursor CLI 只读会话 | 2026-10-17 | 合入与清理节 |
| 合入 | — | NOT_RUN(随本 PR,以平台记录为准) | agent | — | — |
| 合入核验与收口 | — | NOT_RUN(合入后 task-finish) | agent | — | — |
## 探索试验与迭代
| 增量/试验 | 假设 | 范围 | 判断和停止条件 | 授权/决策依据 | 结果 | 变更影响 | 需重审补测 |
|---|---|---|---|---|---|---|---|
| 不适用 | 无探索试验 | — | — | — | — | — | — |
## 同步记录
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|---|---|---|---|
| 启动 | f563ed612a9574e798ee3421c010a9e2ceb416a0 | f563ed612a9574e798ee3421c010a9e2ceb416a0 | 2026-10-17T11:44:55Z |
| 合入前(task-sync;卡已归档,工具未自动写入,值取自其 `[synced]` 输出,SELF) | 6455b54a6e2753f7d9f17ca65e62ba77fcaf81e8 | 1deffc484eff1b8a5b2571f58b19992ebf80db71 | 2026-10-17T13:53:27Z |
## 证据(Evidence)
<!-- CMD="<命令>" make evidence 写入;手抄/转写输出视为无效证据(AGENTS.md 证据与验证门禁)。 -->
| 时间(UTC) | 命令 | 被测HEAD | exit | 来源 | sha256(16) |
|---|---|---|---|---|---|
## 交付调度
- 调度状态:未入队;调度记录:无
- entry_id:无;attempt_id:无;窗口执行者:无
- 固定候选:无(base/head、组件与相关配置引用实际尝试)
- 调度依据:policy/merge-queue.md;新模式启用前按既有交付门禁
- 固定后证据:源码外 RECEIPT;实际结果后按授权原样导入和闭合
## 结果与验证(完成后填写)
- 结果:主记录全局状态 CLOSED;Dev 行 ADOPTED_ACTIVE(f563ed6,main CI run 3687 GATE);PR #602 卡与本卡经 `make task-close FOLD=--fold` 闭合归档。
- 验证:本卡不含本地复跑(证据表为空,本地 NOT_RUN);启动 precheck 为下方 SELF 收据(READY);governance/CI 检查以本 PR HEAD 的 Gitea CI 为准(GATE;合入前于合入与清理节回填,此前为 NOT_RUN)。
- 影响与剩余项:仅文档与任务卡;分支保护与 tag 为用户双钥匙事项;非阻塞遗留项见主记录。
## 规划进展与下一步
- 本次推进/剩余:development-governance-v2 收口;剩余仅用户双钥匙事项(分支保护、tag)与主记录非阻塞遗留项
- 首选下一任务:无(规划已完成)
- 推荐依据:主记录全局状态
- 前置条件/待确认:用户执行分支保护命令(见主记录)
- 预期产物/验收条件:不适用
- 重复任务核对:不适用
- 启动授权:未授权(建议不自动启动新任务,仍须明确授权)
## 合入与清理
- Review 记录:独立 Cursor CLI 只读全新会话(session not-observable),base f563ed6 / head a869453:BLOCK(CLOSED 先于清理断言;本卡模板残留);第二轮全新会话复审(head d2fb19a):两项原阻塞 RESOLVED,新增一项 BLOCK(各仓采纳卡归档为裸断言);已改为 API 核对后的表述,第三轮全新会话仅复审该项,结论以输出为准(源码外 /tmp/review-gov-dev-closed*.out)。
- 冲突记录:main 推进至 6455b54(#603/#605,他人任务);task-sync 无冲突合并,变更不重叠(本 PR 只改主记录与本任务卡)。
- CI 记录:NOT_RUN(当前 HEAD 完整 SHA、全部必需检查、运行链接、执行身份及 GATE 结果)
- 合入记录:NOT_RUN(交付授权范围、PR、被核验 HEAD、合入 SHA、目标分支及内容核验)
- 清理记录:NOT_RUN(授权依据、写者退出确认、worktree/分支/任务卡处置)
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"schema": 1,
"source": "SELF",
"timestamp": "2026-10-17T11:43:58.013984+00:00",
"command": "make precheck",
"command_sha256": "8fd03cdee8adbb8562846a1a114cc0623779a8654412cd20aac9b495e7eb0450",
"cwd": "/tmp/dev-close-114347",
"common_dir": "/tmp/dev-close-114347/.git",
"before": {
"head": "f563ed612a9574e798ee3421c010a9e2ceb416a0",
"branch": "main",
"target_branch": "main",
"target_head": "f563ed612a9574e798ee3421c010a9e2ceb416a0",
"status": "",
"tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"untracked": {},
"submodules": "-4f583ca3eeeb07a56a714c5086de84dcd6ad2980 deps/agent-command\n-343b1e6d9a5b58e47bf7e594826221036ae8175c deps/agent-intent\n-c348441691e8bdab784a03aa9be64d53dacff341 deps/agent-native\n-490b0b2dfa1567cb16ff7a7230fd78e52bc2938e deps/agent-squad\n 2688fd2be6a52c0bf110e7e6366b6f291ab5e4eb deps/development-guidelines (remotes/origin/feature/evidence-provenance-10-g2688fd2)\n 0552b7358d6955057d6eea090326f83317ed992a deps/development-manager (remotes/origin/feature/p4p5-close-27-g0552b73)\n-2688fd2be6a52c0bf110e7e6366b6f291ab5e4eb deps/development-manager/development/guidelines\n-a3ee67bba269e1276c14e22c026171ecf2cf6190 deps/error-code-system\n-49b5d8be604d05e4246dffa0d10fa1c2b7ad45d7 deps/logging-system\n-ab12fea4745cf22fb7648c1c25b18433ac8a3650 modules/backend\n-1a5ef6b75cc74088786487d82b6f6b70bf977280 modules/core\n-73bbb4cea686eb84826d5066bb4c44bf883c9365 modules/documents\n-8b59998d3c5b0545f3bb0b3e670b22aa7fe2179b modules/frontend\n-c9187473fb1ae9e8f3946cdf9b67055ee732054a modules/ui\n"
},
"after": {
"head": "f563ed612a9574e798ee3421c010a9e2ceb416a0",
"branch": "main",
"target_branch": "main",
"target_head": "f563ed612a9574e798ee3421c010a9e2ceb416a0",
"status": "",
"tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"untracked": {},
"submodules": "-4f583ca3eeeb07a56a714c5086de84dcd6ad2980 deps/agent-command\n-343b1e6d9a5b58e47bf7e594826221036ae8175c deps/agent-intent\n-c348441691e8bdab784a03aa9be64d53dacff341 deps/agent-native\n-490b0b2dfa1567cb16ff7a7230fd78e52bc2938e deps/agent-squad\n 2688fd2be6a52c0bf110e7e6366b6f291ab5e4eb deps/development-guidelines (remotes/origin/feature/evidence-provenance-10-g2688fd2)\n 0552b7358d6955057d6eea090326f83317ed992a deps/development-manager (remotes/origin/feature/p4p5-close-27-g0552b73)\n-2688fd2be6a52c0bf110e7e6366b6f291ab5e4eb deps/development-manager/development/guidelines\n-a3ee67bba269e1276c14e22c026171ecf2cf6190 deps/error-code-system\n-49b5d8be604d05e4246dffa0d10fa1c2b7ad45d7 deps/logging-system\n-ab12fea4745cf22fb7648c1c25b18433ac8a3650 modules/backend\n-1a5ef6b75cc74088786487d82b6f6b70bf977280 modules/core\n-73bbb4cea686eb84826d5066bb4c44bf883c9365 modules/documents\n-8b59998d3c5b0545f3bb0b3e670b22aa7fe2179b modules/frontend\n-c9187473fb1ae9e8f3946cdf9b67055ee732054a modules/ui\n"
},
"after_error": null,
"exit_code": 0,
"output": "make[1]: Entering directory '/tmp/dev-close-114347'\n[repo] branch=main head=f563ed612a\n[remote] origin/main=f563ed612a ahead=0 behind=0\n[tree] clean submodules_drift=0 uninit=12\n[warn] 12 个子模块未初始化——构建/测试前需物化(不阻断写入)\n[worktrees] linked=0\n[cards] 已合入未闭合任务卡:feature-governance-v2-closeout.md——make task-close 回填归档(主检出运行)\n[initiatives] local cards (not authoritative): none\n[cards] 闭合分支超过 24 小时未合入:feature/card-close-agent-cli-enforcement feature/card-close-workbench-flow-20261015\n[hooks] core.hooksPath=scripts/hooks(pre-commit/post-merge 实际接线)\n[facts] policy/facts.md 6 条事实均在有效期内\n[required-reading] core/baseline.md, workflows/delivery.md §1, policy/delivery.md\n[R0] f563ed612a(完整:f563ed612a9574e798ee3421c010a9e2ceb416a0)\n[worktree] before-sync: recursive component checks passed\n[verdict] READY — 保留本次 precheck receipt 后建任务工作区:PRECHECK_RECEIPT=/tmp/task-precheck.json make task-start NAME=feature/your-branch\nmake[1]: Leaving directory '/tmp/dev-close-114347'\n",
"root_target": "main",
"immediate_target": "main",
"output_sha256": "1f737aa25acdcac24904080a29335e579475f32498b40391a9d95cf460610ab7",
"receipt_sha256": "ec9169fcd6bb90330b9574def980ed9573babce348c1aa4e326005b3c33d089d"
}
```
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,302 @@
# feature/norm-remediation-u2 任务卡
任务主记录:PR #618 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/618;状态:已完成(合入前闭合);owner:weichen
- 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= b5e23daed2f0ea46261979de1d62e4de0cfa88f9
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u2(worktree);分支:feature/norm-remediation-u2
- 分支类型:child;initiative_id:feature-norm-remediation;root_target:main;immediate_target:feature/norm-remediation;accepting_requirements:false;parent_branch:feature/norm-remediation;parent_head_sha:01d9f50ee8aba1c40cb9b1769598698c91c30c4b;parent_pr:无;parent_source:origin
- 需求分流:免(父 initiative 子任务登记已列出 feature/norm-remediation-u2;parent_head_sha=01d9f50ee8aba1c40cb9b1769598698c91c30c4b)
- 授权与交付终点:用户于 2026-10-18 授权按规范整改计划实施 U2。仅允许安全既有任务的本地续作,并保留新任务启动及正式交付门禁。未授权扩展:改平台保护、host fallback、worker 权限、凭据轮换或其他 U-ID。
- 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进)
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
- 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入)
- 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位)
## 目标与非目标
目标:当远端暂时不可用或落后时,已有且仍获授权的任务只有在身份、记录基线、本地工作区和请求范围均可核验时,才能进入 `LOCAL_READY` 继续有界本地工作;本地收据不得被解释为远端新鲜或正式交付证据。
范围:`scripts/task.sh`、`scripts/evidence.py`、`policy/governance.md`、`tests/test_task.py`、`tests/test_task_recovery.py`、`tests/test_evidence.py`。测试可按现有代码模式作必要的最小补充,但不得改动 `task-pr-check`、`task-sync`、CI 或平台准入语义。
硬停止:关闭/放弃任务、授权或身份缺失/冲突、请求超范围、R0 本地对象缺失、dirty/共享工作区状态不安全、活动 Git 操作、未知外部副作用或未对账状态均拒绝续作。
验收:有效既有任务可在远端失败时继续本地工作;新任务仍需新鲜远端 triage;`LOCAL_READY` 不能成为 `READY`、`REPLAY`、`GATE` 或 merge check 的依据;远端恢复后 Review/merge 仍需同步权威当前目标。
## Agent 实施收据
路由与 fail-stop 规则见根目录 AGENT-EXECUTION.md 与 policy/delivery.md;每次尝试一行,原始日志留在源码外收据路径。
| 单元 ID | 预期范围 | 配置摘要 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|---|---|---|---|---|---|---|---|---|---|---|
| U2 original | local recovery behavior | caefcb72 | implementation | cursor, agy, pi | 1 | cursor-agent-stable / auto | blocked | none | 0 | /tmp/norm-remediation-u2-receipt.json |
| U2 test-only | offline local precheck regression | caefcb72 | test | pi, agy, cursor | 1 | pi / MiniMax-M3 | success | 30a582372b4c | 0 | /tmp/norm-remediation-u2-offline-test-receipt.json |
| U2 task precheck | local precheck fallback | caefcb72 | implementation | cursor, agy, pi | 1 | cursor-agent-stable / auto | success | d6df427e39e2 | 0 | /tmp/norm-remediation-u2-precheck-impl-receipt.json |
| U2 local receipt | resume-local receipt validation | caefcb72 | implementation | cursor, agy, pi | 1 | cursor-agent-stable / auto | success | 210bb031d4ac | 0 | /tmp/norm-remediation-u2-evidence-receipt-2.json |
| U2 missing-ref test | resume-local with missing tracking ref | caefcb72 | test | pi, agy, cursor | 1 | pi / MiniMax-M3 | success | dcbd36656bb3 | 0 | /tmp/norm-remediation-u2-no-tracking-test-receipt.json |
| U2 missing-ref fix | local receipt with missing tracking ref | caefcb72 | repair | cursor, agy, pi | 1 | cursor-agent-stable / auto | success | a43aa171ea7f | 0 | /tmp/norm-remediation-u2-no-tracking-fix-receipt.json |
| U2 offline-capture test | capture LOCAL_READY without tracking ref | caefcb72 | test | pi, agy, cursor | 1 | pi / MiniMax-M3 | success | eb6be71cfc34 | 0 | /tmp/norm-remediation-u2-no-tracking-capture-test-receipt.json |
| U2 offline-capture fix | capture and resume without tracking ref | caefcb72 | repair | cursor, agy, pi | 1 | cursor-agent-stable / auto | success | d2986f1f5fee | 0 | /tmp/norm-remediation-u2-offline-capture-fix-receipt.json |
| U2 offline-recovery docs | clarify missing-ref local recovery | caefcb72 | implementation | cursor, agy, pi | 1 | cursor-agent-stable / auto | success | 74e4b06e5e8b | 0 | /tmp/norm-remediation-u2-offline-doc-receipt.json |
| U2 review regression tests | closed task, reachable rewind, reappearing target | caefcb72 | test | pi, agy, cursor | 1 | pi / MiniMax-M3 | success | d5b8e74c4306 | 0 | /tmp/norm-remediation-u2-review-fix-tests-receipt.json |
| U2 review fixes | reject closed task and known target rewind/divergence | caefcb72 | repair | cursor, agy, pi | 1 | cursor-agent-stable / auto | success | 05a9a3bc89b6 | 0 | /tmp/norm-remediation-u2-review-fixes-receipt.json |
| U2 final edge tests | target divergence and receipt target branch mismatch | caefcb72 | test | pi, agy, cursor | 1 | pi / MiniMax-M3 | success | 2e0da0dadb73 | 0 | /tmp/norm-remediation-u2-final-edge-tests-receipt.json |
| U2 uncomparable-target test | reachable advertised SHA missing locally | caefcb72 | test | pi, agy, cursor | 1 | pi / MiniMax-M3 | success | 95d17188585c | 0 | /tmp/norm-remediation-u2-uncomparable-target-test-receipt.json |
| U2 target-history fix | block known but locally uncomparable history | caefcb72 | repair | cursor, agy, pi | 1 | cursor-agent-stable / auto | success | 9c0e76570832 | 0 | /tmp/norm-remediation-u2-uncomparable-target-fix-receipt.json |
| U2 no-cache target tests | target reachable/missing or forward with no tracking ref | caefcb72 | test | pi, agy, cursor | 1 | pi / MiniMax-M3 | success | fbb2aacb71ba | 0 | /tmp/norm-remediation-u2-no-cache-history-tests-receipt.json |
| U2 offline resume tests | standalone/child local resume during origin outage | caefcb72 | test | pi, agy, cursor | 1 | pi / MiniMax-M3 | success | 8d8585afec66 | 0 | /tmp/norm-remediation-u2-offline-resume-tests-receipt.json |
| U2 offline resume fix | local-only receipt resume with target history and parent R0 checks | caefcb72 | repair | cursor, agy, pi | 1 | cursor-agent-stable / auto | success | f81326bd0836 | 0 | /tmp/norm-remediation-u2-offline-resume-fix-receipt.json |
| U2 no-cache R0 fix | compare reachable targets to registered R0 without cached ref | caefcb72 | repair | cursor, agy, pi | 1 | cursor-agent-stable / auto | success | 1ff6444d3352 | 0 | /tmp/norm-remediation-u2-precheck-r0-fix-receipt.json |
| U2 reachable-missing-parent test | reject known-absent remote child target | caefcb72 | test | pi, agy, cursor | 1 | pi / MiniMax-M3 | success | 5b5537aa0fc4 | 0 | /tmp/norm-remediation-u2-child-missing-parent-test-receipt-2.json |
| U2 reachable-missing-parent fix | local child resume only falls back on remote outage | caefcb72 | repair | cursor, agy, pi | 1 | cursor-agent-stable / auto | success | 105901595805 | 0 | /tmp/norm-remediation-u2-child-missing-parent-fix-receipt.json |
| U2 offline resume tests | root/child receipt import during origin outage | caefcb72 | test | pi, agy, cursor | 1 | pi / MiniMax-M3 | success | 8d8585afec66 | 0 | /tmp/norm-remediation-u2-offline-resume-tests-receipt.json |
| U2 offline resume fix | local resume on R0/local registered parent | caefcb72 | repair | cursor, agy, pi | 1 | cursor-agent-stable / auto | success | f81326bd0836 | 0 | /tmp/norm-remediation-u2-offline-resume-fix-receipt.json |
| U2 review-proof tests | no-ref paths, auth failure, and parent identity | caefcb72 | test | pi, agy, cursor | 1 | pi / MiniMax-M3 | success | bc304111a47f | 0 | /tmp/norm-remediation-u2-final-review-tests-receipt.json |
| U2 final offline guards | missing cache, auth failures, and parent SHA checks | caefcb72 | repair | cursor, agy, pi | 1 | cursor-agent-stable / auto | success | 471948c59cfa | 0 | /tmp/norm-remediation-u2-final-guards-receipt.json |
| U2 precheck R0 implementation | compare remote advertisement without cached tracking ref | caefcb72 | repair | cursor, agy, pi | 1 | cursor-agent-stable / auto | success | 1ff6444d3352 | 0 | /tmp/norm-remediation-u2-precheck-r0-fix-receipt.json |
| U2 cached-target outage R0 regression/fix | reject cached target known to diverge from registered R0 during origin outage | caefcb72 | repair | cursor, agy, pi | 1 | cursor-agent-stable / auto | success | a06209ff0a2b | 0 | /tmp/norm-u2-cached-target-outage-fix-2.json |
| U2 cached-target independent review | independent review of exact implementation diff | caefcb72 | review | pi, antigravity, cursor, codex | 1 | pi / MiniMax-M3 | failed-unknown | none | 0 | /tmp/norm-u2-cached-target-outage-review.json |
## 同步记录
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|---|---|---|---|
| 启动 | b5e23daed2f0ea46261979de1d62e4de0cfa88f9 | 01d9f50ee8aba1c40cb9b1769598698c91c30c4b | 2026-10-18T09:51:35Z |
## 证据(Evidence)
<!-- CMD="<命令>" make evidence 写入;手抄/转写输出视为无效证据(AGENTS.md 证据与验证门禁)。 -->
| 时间(UTC) | 命令 | 被测HEAD | exit | 来源 | sha256(16) |
|---|---|---|---|---|---|
| 2026-10-18T11:24Z | `python3 -m unittest tests.test_evidence tests.test_task_recovery` | 210bb031d4acc5b9bde6cde66e7fa0f735bcf9f8 | 0 | SELF | d196e73da7f33421 |
| 2026-10-18T12:07Z | `python3 -m unittest tests.test_evidence tests.test_task_recovery` | d2986f1f5fee0e0ad151fd813b9306873131c805 | 0 | SELF | 85197f351f8458a8 |
| 2026-10-18T12:03Z | `python3 -m unittest tests.test_task tests.test_task_recovery tests.test_evidence` | d2986f1f5fee0e0ad151fd813b9306873131c805 | 1 | SELF | 9d19d33489e15d4d |
| 2026-10-18T12:42Z | `python3 -m unittest tests.test_evidence tests.test_task_recovery` | 05a9a3bc89b65eebd92cac6f82c3e4f28e13ab71 | 0 | SELF | 2d19085b0725fc46 |
| 2026-10-18T12:43Z | `make test-governance` | 05a9a3bc89b65eebd92cac6f82c3e4f28e13ab71 | 0 | SELF | 018194c0a804d1b9 |
| 2026-10-18T13:01Z | `make test-governance` | 2e0da0dadb73db1b6a70f8545dbfd5df3a8e4d00 | 0 | SELF | a44db826c4be80fb |
| 2026-10-18T13:40Z | `bash -n scripts/task.sh && make test-governance` | 9c0e7657083259759f5bd1bed6921471411dba2c | 0 | SELF | 872bbc3437ae83e3 |
| 2026-10-18T14:41Z | `python3 -m unittest tests.test_evidence tests.test_task_recovery` | 1ff6444d3352c7e13c2b75cefe7d65c631181454 | 0 | SELF | bf12f030894e1530 |
| 2026-10-18T14:40Z | `bash -n scripts/task.sh && make test-governance` | 1ff6444d3352c7e13c2b75cefe7d65c631181454 | 0 | SELF | 8e81c5353849fbd5 |
| 2026-10-18T15:47Z | `python3 -m unittest tests.test_evidence tests.test_task_recovery` | 471948c59cfabff36c018f219998139fea3757fe | 0 | SELF | 7620bd82fed319e7 |
| 2026-10-18T15:48Z | `bash -n scripts/task.sh && make test-governance` | 471948c59cfabff36c018f219998139fea3757fe | 0 | SELF | 5a3346fd73b80243 |
## 结果与验证
- 结果:U2 允许既有安全任务在真正远端不可用或目标跟踪 ref 缺失时继续有界本地工作;闭合任务和已证实的远端 target 回退/分叉均拒绝 `LOCAL_READY`。新任务和正式交付仍要求严格 READY/权威同步。
- 验证:host `python3 -m unittest tests.test_evidence tests.test_task_recovery` 79/79 通过(SELF,HEAD `1ff6444d3352c7e13c2b75cefe7d65c631181454`),覆盖 root/child 离线 task-resume 与严格 delivery 拒绝;host `bash -n scripts/task.sh && make test-governance` 490 项通过、18 项 skip(SELF,同 HEAD)。不含后续主脚本改动的 transport。local precheck no-cache 的 2 个红灯回归已由紧随其后的 `1ff6444d` 修复,三条 no-cache 状态单测 3/3 通过;最终候选完整测试仍待重跑。
- Review 发现与闭合:正确性 reviewer 发现闭合任务仍可在 precheck 收到 LOCAL_READY、以及可达但不可比较的 target 仍被当作离线;可靠性 reviewer 发现缓存 target 回退/分叉问题。已分别加入 test-first 回归并修复。测试 reviewer 建议的目标 ref 重现、receipt target branch 错配、远端分叉和不可比较 target 场景均已覆盖;项目规范/可维护性审阅无 finding。旧 CI run 3884 曾因变更外 Go 测试 `TestToolCallDeltaBeforeExecution` 失败,后续 `b492bea...` CI 通过;当前最终 head 的 GATE 与新候选完整 Review 待执行。
- 执行偏差:原 U2 Cursor attempt 对 `tests/test_task_recovery.py` 的两个 edit 调用重叠约 449 ms,并被 fail-stop;新的 evidence 单元明确要求串行编辑,但 worker 仍在同一批次向 `scripts/evidence.py` 发出两次编辑调用(未重叠,最终 diff 已审阅且验证通过)。不能据此声称提示已强制串行;后续规范计划须区分提示、可观测证据与工具级并发防护。
- 新增执行偏差:修复闭合任务与目标回退时,worker 在同一批次向 `scripts/evidence.py` 和 `scripts/task.sh` 发出两次互不重叠编辑,违反了任务包的串行编辑要求;最终 diff 已逐项审阅,定向与完整治理测试均通过,但该结果不能证明提示具备工具级强制力。
- Review 路由记录:第一次 PR 对抗性 cross-model job 因 orchestrator 使用了不匹配的约束文件名,在 provider egress 前跳过,未把代码发送给外部模型;job 目录已清理。该审阅不计入 Review 覆盖,最终 head 使用本地 adversarial reviewer。
- 后续 Review 补充(覆盖前述状态):关闭任务 precheck、reachable-but-uncomparable/缺失 target、无 tracking ref 时需查询 advertised target、以及离线 `cmd_resume` 的 fetch-first 缺口,均已补 test-first 回归与修复。root 离线 resume 使用登记 R0;child resume 仅使用已登记、包含 `parent_head_sha` 的本地 parent 作为局部参考,delivery 仍 fetch-first。最终候选完整 Review 与 exact-head CI 待完成。
- 最新 child 边界修复:origin 可达但已登记 parent ref 缺失时,local resume 不再回退本地 parent;origin 确实不可查询时仍可使用本地 parent,并验证 `parent_head_sha`。
- 最新代码验证:host `tests.test_evidence tests.test_task_recovery` 80/80 通过,`bash -n scripts/task.sh && make test-governance` 491 项通过、18 项 skip,测试对象为 `105901595805cc5fa5ce19f1a6d48317b950d6af`。此前 CI green head 尚早于这些离线恢复修复,须以最终 PR head 重跑 GATE。
- 最新验证覆盖 80 个 evidence/recovery 测试与 491 项治理测试(18 项 skip),以上命令都成功;测试对象为当前实现代码 `105901595805cc5fa5ce19f1a6d48317b950d6af`。若后续只改任务卡,代码测试可复用但 CI head 会变,须在最终提交 head 重新等待 GATE。
- child 父目标补充:若 origin 可达但已登记 parent branch 不存在,local resume 返回 REMOTE_UNVERIFIED,不再使用本地 parent;只有远端确实不可查询时才回退本地 parent,并仍核验 `parent_head_sha`。delivery 仍保持 fetch-first。
- 最终边界修复及验证:`target_history` 仅将已识别的 DNS/连接类传输错误视为 outage;认证/权限/未知错误不再降级。无 tracking ref 时 precheck 以 active task R0 比较 advertised target;reachable target/parent 缺失或不可比均拒绝。child local resume 要求有效且本地可用的 `parent_head_sha`。去掉了无 tracking-ref 时会触发 strict-shell 退出的 merged-branch 查询。
- 最终安全复审阻塞修复:当 origin 传输不可达但本地缓存 `origin/<target>` 已知分叉于登记 R0 时,`target_history` 现在返回 `rewound`;缓存存在但 ancestry 无法比较时返回 `uncomparable`,仅兼容缓存或无缓存才允许继续判断。新增回归覆盖 local precheck 拒绝 `LOCAL_READY`、resume 不导入 receipt,且 HEAD、卡片和 receipt 保持不变。修复经 agent-exec transport `a06209ff0a2b23fb750528a4bec4e7e64b3f2d6c` 集成。
- 修复验证(SELF,HEAD `a06209ff0a2b23fb750528a4bec4e7e64b3f2d6c`):`python3 -m unittest tests.test_task_recovery tests.test_evidence` 84/84 通过;`bash -n scripts/task.sh && make test-governance` 495 项通过、18 项 skip。对应完整脱敏收据由 `IMPORT_RECEIPT` 附于本卡。
- Review:PI 独立 Review attempt `a44c5c3e758a08f3ebe5d8a59bd241fd` 以 `failed-unknown` 结束,未形成可核验结论且未产生改动;当前 host 对 `398d12141c84453fb6db3dba2eaf9a208342e29f..a06209ff0a2b23fb750528a4bec4e7e64b3f2d6c` 的实际 diff 进行独立代码审查,未发现阻塞问题。旧 head `398d12141c84453fb6db3dba2eaf9a208342e29f` 的 CI run 3959 `ci / test` 失败;原因尚未从旧 run 日志确认,修复 head 的 exact CI 尚待执行。
- 最终已测生产代码 head `471948c59cfabff36c018f219998139fea3757fe`:host evidence+recovery 83/83 通过;`bash -n scripts/task.sh && make test-governance` 494 项通过、18 项 skip。随后 `105901595805cc5fa5ce19f1a6d48317b950d6af` 又通过 targeted unreachable-vs-reachable missing-parent 对照测试;其后未再改生产逻辑。exact final-head CI 与当前候选 Review 尚待重跑。
- 离线 resume 已端到端验证:root 与 child 任务在捕获有效 LOCAL_READY 收据后、origin 不可达时可用 `TASK_WORK_MODE=local make task-resume` 导入;child 仅使用本地已登记 parent 并核对 `parent_head_sha`。同一环境下 delivery resume 仍以 REMOTE_UNVERIFIED 拒绝。
- 验收补充:对照计划 U2 的“remote-tracking ref 不存在但 R0 对象本地可用”场景,host Review 发现首个修复只覆盖 receipt 捕获后 ref 消失,未覆盖离线 precheck 捕获时 ref 已缺失;随后新增 test-first 回归覆盖两种时序,并修复 `--local-context` 与 `resume-local` 的有界验证。`start` 与 `resume-delivery` 继续要求当前权威目标。
- 影响与剩余项:原失败 receipt `/tmp/norm-remediation-u2-receipt.json`,run_id `af20482c3e24cc32f3873d1451043481`;其 worktree 保留为诊断证据。该 run `blocked`、`transport_ref=null`、`host_fallback_authorizations=0`。Development-Manager PR #26 已合入 `b178dec`;Dev gitlink adoption 仍待 initiative 集成,不在本 U2 单元内。
## 合入与清理
- Review 记录:host Review 完成(base `398d12141c84453fb6db3dba2eaf9a208342e29f`,head `a06209ff0a2b23fb750528a4bec4e7e64b3f2d6c`;结论:无阻塞 finding;独立 PI attempt failed-unknown,不计为通过)
- 冲突记录:NOT_RUN(最新目标同步、冲突处置、组合兼容核验及复审/补测)
- CI 记录:NOT_RUN(当前 HEAD 完整 SHA、全部必需检查、运行链接、执行身份及 GATE 结果)
- 合入记录:NOT_RUN(交付授权范围、PR、被核验 HEAD、合入 SHA、目标分支及内容核验)
- 清理记录:NOT_RUN(授权依据、写者退出确认、worktree/分支/任务卡处置)
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T09:51:00.301997+00:00",
"command": "make precheck",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev",
"before_head": "b5e23daed2f0ea46261979de1d62e4de0cfa88f9",
"after_head": "b5e23daed2f0ea46261979de1d62e4de0cfa88f9",
"branch": "main",
"target_branch": "main",
"target_head": "b5e23daed2f0ea46261979de1d62e4de0cfa88f9",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev'",
"[repo] branch=main head=b5e23daed2",
"[remote] origin/main=b5e23daed2 ahead=0 behind=0",
"[tree] clean submodules_drift=0 uninit=3",
"[warn] 3 个子模块未初始化——构建/测试前需物化(不阻断写入)",
"[worktrees] linked=11",
"[recycle] merged un-recycled branches: feature/layered-python-env",
"[initiatives] local cards (not authoritative): none",
"[hooks] core.hooksPath=scripts/hooks(pre-commit/post-merge 实际接线)",
"[facts] policy/facts.md 6 条事实均在有效期内",
"[required-reading] core/baseline.md, workflows/delivery.md §1, policy/delivery.md",
"[R0] b5e23daed2(完整:b5e23daed2f0ea46261979de1d62e4de0cfa88f9)",
"[worktree] before-sync: recursive component checks passed",
"[verdict] READY — 保留本次 precheck receipt 后建任务工作区:PRECHECK_RECEIPT=/tmp/task-precheck.json make task-start NAME=feature/your-branch",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev'"
],
"output_sha256": "d33d43216a047c642360e2afa99b4d72781f81698ca933e8687cc8127afde332",
"receipt_sha256": "57db39b3f66caf60040427f50f45423bb2be546f4930be3696b8218f1c29f148",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/57db39b3f66caf60040427f50f45423bb2be546f4930be3696b8218f1c29f148.json"
}
```
| 同步(记录前对象) | 74bd05a876136ed8506332c76d535a6eb6356433 | f65d0169f61addfc0b2a21ef3813f38b55deb687 | 2026-10-18T10:58:22Z |
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T11:14:41.060001+00:00",
"command": "make precheck",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u2",
"before_head": "d6df427e39e2dd8f57d51d04318dedffff96523a",
"after_head": "d6df427e39e2dd8f57d51d04318dedffff96523a",
"branch": "feature/norm-remediation-u2",
"target_branch": "main",
"target_head": "ba81d638a6c845d0acde6896f4001bed096ba26c",
"root_target": "main",
"immediate_target": "feature/norm-remediation",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u2'",
"[repo] branch=feature/norm-remediation-u2 head=d6df427e39",
"[remote] origin/main=ba81d638a6 ahead=10 behind=12",
"[tree] clean submodules_drift=0 uninit=0",
"[worktrees] linked=11",
"[recycle] merged un-recycled branches: feature/layered-python-env",
"[initiatives] local cards (not authoritative): none",
"[hooks] core.hooksPath=scripts/hooks(pre-commit/post-merge 实际接线)",
"[facts] policy/facts.md 6 条事实均在有效期内",
"[required-reading] core/baseline.md, workflows/delivery.md §1, policy/delivery.md",
"[target] ba81d638a6c845d0acde6896f4001bed096ba26c(observed; task initial baseline is reported separately)",
"[task-state] registered=/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u2 initial_base=b5e23daed2f0ea46261979de1d62e4de0cfa88f9",
"[verdict] LOCAL_READY — existing task may continue authorized local work; final delivery still requires latest-target sync and checks",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u2'"
],
"output_sha256": "9875968d327058ec22a07453a7c748f5c7b3557fdc8d05355b907b8458d8fa6d",
"receipt_sha256": "00e543451c4435f6669c74d51a6a678db2cd40a0498a56ae377447044adce7f8",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/00e543451c4435f6669c74d51a6a678db2cd40a0498a56ae377447044adce7f8.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T11:39:55.756192+00:00",
"command": "python3 -m unittest tests.test_evidence tests.test_task_recovery",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u2",
"before_head": "1e26b1cccdcfe8ac83a004915cad591d27eed91c",
"after_head": "1e26b1cccdcfe8ac83a004915cad591d27eed91c",
"branch": "feature/norm-remediation-u2",
"target_branch": "main",
"target_head": "ba81d638a6c845d0acde6896f4001bed096ba26c",
"root_target": "main",
"immediate_target": "feature/norm-remediation",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"..................................................................",
"----------------------------------------------------------------------",
"Ran 66 tests in 18.749s",
"",
"OK"
],
"output_sha256": "ed93f5670caa3576929bab841735c1ad873975985fcf1a6575ce88bad5510aa7",
"receipt_sha256": "d08508edc20bdd35b340355c5b1a9295ddce5f866d1706f34afc8f76dcf1d939",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/d08508edc20bdd35b340355c5b1a9295ddce5f866d1706f34afc8f76dcf1d939.json"
}
```
## 闭合记录(合入前折叠)
- 本卡在 PR #618(https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/618)合入前闭合并归档,随该 PR 一同合入。
- 该 PR 的合并提交即本任务的落地记录。
- 合入后无需回填,也无需单独的闭合 PR。
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T16:13:57.369094+00:00",
"command": "python3 -m unittest tests.test_task_recovery tests.test_evidence",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u2",
"before_head": "a06209ff0a2b23fb750528a4bec4e7e64b3f2d6c",
"after_head": "a06209ff0a2b23fb750528a4bec4e7e64b3f2d6c",
"branch": "feature/norm-remediation-u2",
"target_branch": "main",
"target_head": "eef7e5e778cabcb6216f74b74213a3d7511f383b",
"root_target": "main",
"immediate_target": "feature/norm-remediation",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"....................................................................................",
"----------------------------------------------------------------------",
"Ran 84 tests in 31.295s",
"",
"OK"
],
"output_sha256": "7cf18f380130a11f0494ce26e3e331cb9c6532d790a869414b68b3cb5a8161f1",
"receipt_sha256": "4054bd2917a76495eec89a929dea0929ed7ab7af633ca99424950baf300a56b4",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/4054bd2917a76495eec89a929dea0929ed7ab7af633ca99424950baf300a56b4.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T16:14:30.451262+00:00",
"command": "bash -n scripts/task.sh && make test-governance",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u2",
"before_head": "a06209ff0a2b23fb750528a4bec4e7e64b3f2d6c",
"after_head": "a06209ff0a2b23fb750528a4bec4e7e64b3f2d6c",
"branch": "feature/norm-remediation-u2",
"target_branch": "main",
"target_head": "eef7e5e778cabcb6216f74b74213a3d7511f383b",
"root_target": "main",
"immediate_target": "feature/norm-remediation",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"test_feature_missing_parent_is_allowed (test_write_guard.WriteGuardTests.test_feature_missing_parent_is_allowed) ... ok",
"test_invalid_json_is_denied (test_write_guard.WriteGuardTests.test_invalid_json_is_denied) ... ok",
"test_missing_parent_on_main_is_denied (test_write_guard.WriteGuardTests.test_missing_parent_on_main_is_denied) ... ok",
"test_missing_unknown_and_malformed_write_input_are_denied (test_write_guard.WriteGuardTests.test_missing_unknown_and_malformed_write_input_are_denied) ... ok",
"test_non_git_destination_is_explicitly_outside_scope (test_write_guard.WriteGuardTests.test_non_git_destination_is_explicitly_outside_scope) ... ok",
"test_nonwrite_tools_are_outside_scope (test_write_guard.WriteGuardTests.test_nonwrite_tools_are_outside_scope) ... ok",
"test_relative_path_uses_hook_cwd_not_process_cwd (test_write_guard.WriteGuardTests.test_relative_path_uses_hook_cwd_not_process_cwd) ... ok",
"test_symlink_into_main_with_missing_parents_is_denied (test_write_guard.WriteGuardTests.test_symlink_into_main_with_missing_parents_is_denied) ... ok",
"test_valid_multi_file_patch_on_feature_is_allowed (test_write_guard.WriteGuardTests.test_valid_multi_file_patch_on_feature_is_allowed) ... ok",
"",
"----------------------------------------------------------------------",
"Ran 495 tests in 364.208s",
"",
"OK (skipped=18)",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u2'"
],
"output_sha256": "3edcb54df736b840127f6b466cac1f4046632e81f38fa02fe96cdb95cee0b87f",
"receipt_sha256": "ae37da5e99243a166bafa46ff6bf95cb704de194338a669d929f409cb540768f",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/ae37da5e99243a166bafa46ff6bf95cb704de194338a669d929f409cb540768f.json"
}
```
@@ -0,0 +1,256 @@
# feature/norm-remediation-u3 任务卡
任务主记录:PR #620 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/620;状态:已完成(合入前闭合);owner:weichen
- 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:feature/norm-remediation;R0(initial_base_sha)= fe0f1cd4649f11b0d855ec39b882b8ca37fffb6b
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u3(worktree);分支:feature/norm-remediation-u3
- 分支类型:child;initiative_id:feature-norm-remediation;root_target:main;immediate_target:feature/norm-remediation;accepting_requirements:false;parent_branch:feature/norm-remediation;parent_head_sha:fe0f1cd4649f11b0d855ec39b882b8ca37fffb6b;parent_pr:https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/616;parent_source:origin
- 需求分流:免(父 initiative 子任务登记已列出 feature/norm-remediation-u3;parent_head_sha=fe0f1cd4649f11b0d855ec39b882b8ca37fffb6b)
- 授权与交付终点:用户于 2026-10-18 授权按规范整改计划实施 U3,并按本仓门禁将子任务合入 `feature/norm-remediation`。仅允许调整 Dev `policy/delivery.md` 的任务通道分类与拓扑选择规则;未授权修改脚本、分支命令/流程、CI/平台设置、其他 U-ID 或 Guidelines。
- 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进)
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
- 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入)
- 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位)
## 目标与非目标
目标:让修复/完善/扩展/新增类别决定优先级,而 standalone、child、initiative 拓扑由集成、依赖与验收需要决定。独立可验收工作(含小完善/新能力)可 standalone;多依赖单元、跨单元集成或共同最终验收需要 initiative;修复若属于 L1 范围则可作为 child,同时保留 fix/hotfix 优先级。JOIN 必须与 initiative 已记录目标/验收一致;远端发现不可核验仍不得判断 NEW 或建分支。
范围:`policy/delivery.md`「层级、任务通道与分级门禁」。非目标:不改脚本、任务字段、命令、分支模型、triage 事实来源、门禁/排队规则或平台行为。
计划:[U1-U7 规范整改计划](</home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-plan/docs/superpowers/plans/2026-10-18-0849-fix-development-norm-remediation-plan.md>),U3。
## Agent 实施收据
路由与 fail-stop 规则见根目录 AGENT-EXECUTION.md 与 policy/delivery.md;每次尝试一行,原始日志留在源码外收据路径。
| 单元 ID | 预期范围 | 配置摘要 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|---|---|---|---|---|---|---|---|---|---|---|
| norm-u3-task-channel-by-integration-need | `policy/delivery.md` task channel/topology policy | caefcb72 | implementation | cursor, agy, pi | 1 | cursor-agent-stable / auto | success | 98447e269cea | 0 | /tmp/norm-u3-task-channel-policy-receipt.json |
| norm-u3-independent-policy-review | fresh-session review of policy/delivery.md scenarios | caefcb72 | review | pi, antigravity, cursor, codex | 1 | pi / MiniMax-M3 | success | cb582d170cc4 | 0 | /tmp/norm-u3-independent-review-receipt.json |
## 同步记录
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|---|---|---|---|
| 启动 | fe0f1cd4649f11b0d855ec39b882b8ca37fffb6b | fe0f1cd4649f11b0d855ec39b882b8ca37fffb6b | 2026-10-18T16:45:52Z |
## 证据(Evidence)
<!-- CMD="<命令>" make evidence 写入;手抄/转写输出视为无效证据(AGENTS.md 证据与验证门禁)。 -->
| 时间(UTC) | 命令 | 被测HEAD | exit | 来源 | sha256(16) |
|---|---|---|---|---|---|
## 结果与验证
- 结果:U3 将类别与集成拓扑分开:修复类别保留优先级及 hotfix 插队;独立可验收的修复、完善和新能力可走 standalone;多依赖单元、跨单元集成或共同最终验收才建立 initiative;符合在途 L1 目标与验收的工作可 JOIN/child,远端不可核验仍拒绝 NEW。
- 验证:`git diff --check && make test-affected` 通过;受影响目标为 `test-worktree` 与 `test-governance`,其中治理测试 495 项通过、18 项 skip(SELF,HEAD `98447e269ceaf1982405580d4ce5549d47b165c4`)。worker 对四个验收场景逐项核对;host 复核实际 diff 与原有分级表/triage 规则,无矛盾。SELF 收据已写入本卡。
- 影响与剩余项:
## 合入与清理
- Review 记录:host Review 完成(base `d3223f5ec13bb5456ccb96dd136374f6cce94253`,head `98447e269ceaf1982405580d4ce5549d47b165c4`;目标优先级与集成拓扑分离、修复可 standalone 或 child、JOIN/NEW/REMOTE_UNVERIFIED 条件和现有门禁均符合 U3;无阻塞 finding)
- 独立 Review(fresh session,单元 `norm-u3-independent-policy-review`,仅检视 `policy/delivery.md` 在 `d3223f5ec13bb5456ccb96dd136374f6cce94253..98447e269ceaf1982405580d4ce5549d47b165c4` 的 diff,未接触其它文件、未做 `git add`/`commit`/`push`/PR/合入/索引/配置改动):`policy/delivery.md` 净改动 +9/-8,集中于 standalone 定位(line 163)、任务通道两步判定(line 193–200)与分级门禁表(line 210)。
- 场景 1(小完善/新能力仍可 standalone):通过。line 163 明确 standalone 涵盖「修复、完善与新能力」;line 196 再次声明「小完善与新能力同样适用」并把「完善、扩展、新增不设额外优先级」写死。
- 场景 2(多依赖单元 + 共同最终验收 → L1,即便含修复):通过。line 197 L1 触发条件为「多个相互依赖的单元、跨单元集成或一个共同最终验收需要阶段集成与组合验证」,与「类别只决定优先级」正交;line 198 显式允许「工作(含修复)」作为在途 L1 的 child。
- 场景 3(属于在途 L1 集成契约的修复保留优先级且不被强推 main):通过。line 193 保留 `fix/`/`hotfix/` 队列优先级与 #518 插队权;line 198 允许该类修复走 child;分级表把原「L1 或修复→main」改为「L1 或 standalone→main」(line 210),移除对修复的 main 强制通路。修复合入主干的快慢继续由类别决定,而非由拓扑决定。
- 场景 4(远端不可核验时拒绝建分支):通过。line 168「不得得出 `NEW`」、line 170「不一致或远端不可核验时拒绝,不建分支」保持原样;line 198 任务通道节内再次写入「远端发现不可核验时不得得出 `NEW`、不建分支」,与既有分流契约一致且重复强化。
- 跨节一致性:合并调度 line 363「standalone/修复 PR」、line 366「`fix/`、`hotfix/` 优先」与本 diff 共同表述一致;修复 PR 仍以 standalone 形式占用 #518 窗口并享有优先级,子任务合入(child → L1)按 line 207 表「L2→L1」走轻量门禁且不排窗口,符合「类别只决定优先级,拓扑只决定目标」的原则。
- 残余非阻塞注意:line 363 措辞「standalone/修复 PR」在拓扑语境下存在轻微冗余(standalone 修复已由「standalone」覆盖),但当前未引发歧义、不阻塞 U3 验收,可作为后续治理 L1 增量整理。
- 结论:**无阻塞 finding**;U3 验收四条场景均在 `policy/delivery.md` 文本中得到明确、可独立验证的支撑。未声明 CI 通过(按约束)。
- 冲突记录:NOT_RUN(最新目标同步、冲突处置、组合兼容核验及复审/补测)
- CI 记录:NOT_RUN(当前 HEAD 完整 SHA、全部必需检查、运行链接、执行身份及 GATE 结果)
- 合入记录:NOT_RUN(交付授权范围、PR、被核验 HEAD、合入 SHA、目标分支及内容核验)
- 清理记录:NOT_RUN(授权依据、写者退出确认、worktree/分支/任务卡处置)
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T16:45:08.496457+00:00",
"command": "make precheck",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation",
"before_head": "fe0f1cd4649f11b0d855ec39b882b8ca37fffb6b",
"after_head": "fe0f1cd4649f11b0d855ec39b882b8ca37fffb6b",
"branch": "feature/norm-remediation",
"target_branch": "feature/norm-remediation",
"target_head": "fe0f1cd4649f11b0d855ec39b882b8ca37fffb6b",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation'",
"[repo] branch=feature/norm-remediation head=fe0f1cd464",
"[remote] origin/feature/norm-remediation=fe0f1cd464 ahead=0 behind=0",
"[tree] clean submodules_drift=0 uninit=0",
"[worktrees] linked=7",
"[recycle] merged un-recycled branches: feature/layered-python-env feature/norm-remediation-u2",
"[initiatives] local cards (not authoritative): none",
"[hooks] core.hooksPath=scripts/hooks(pre-commit/post-merge 实际接线)",
"[facts] policy/facts.md 6 条事实均在有效期内",
"[required-reading] core/baseline.md, workflows/delivery.md §1, policy/delivery.md",
"[R0] fe0f1cd464(完整:fe0f1cd4649f11b0d855ec39b882b8ca37fffb6b)",
"[worktree] before-sync: recursive component checks passed",
"[verdict] READY — 保留本次 precheck receipt 后建任务工作区:PRECHECK_RECEIPT=/tmp/task-precheck.json make task-start NAME=feature/your-branch",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation'"
],
"output_sha256": "ee1240abc7866d6b272cf3c307a650b907dc7b36ae662335d8573d8c3dd7240c",
"receipt_sha256": "92b34a0bd5532f33b1598e25686504a91dab621b36f372e7e0d31c18addb4c3a",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/92b34a0bd5532f33b1598e25686504a91dab621b36f372e7e0d31c18addb4c3a.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T16:47:54.838263+00:00",
"command": "git diff --check && make test-affected",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u3",
"before_head": "98447e269ceaf1982405580d4ce5549d47b165c4",
"after_head": "98447e269ceaf1982405580d4ce5549d47b165c4",
"branch": "feature/norm-remediation-u3",
"target_branch": "main",
"target_head": "eef7e5e778cabcb6216f74b74213a3d7511f383b",
"root_target": "feature/norm-remediation",
"immediate_target": "feature/norm-remediation",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"test_invalid_json_is_denied (test_write_guard.WriteGuardTests.test_invalid_json_is_denied) ... ok",
"test_missing_parent_on_main_is_denied (test_write_guard.WriteGuardTests.test_missing_parent_on_main_is_denied) ... ok",
"test_missing_unknown_and_malformed_write_input_are_denied (test_write_guard.WriteGuardTests.test_missing_unknown_and_malformed_write_input_are_denied) ... ok",
"test_non_git_destination_is_explicitly_outside_scope (test_write_guard.WriteGuardTests.test_non_git_destination_is_explicitly_outside_scope) ... ok",
"test_nonwrite_tools_are_outside_scope (test_write_guard.WriteGuardTests.test_nonwrite_tools_are_outside_scope) ... ok",
"test_relative_path_uses_hook_cwd_not_process_cwd (test_write_guard.WriteGuardTests.test_relative_path_uses_hook_cwd_not_process_cwd) ... ok",
"test_symlink_into_main_with_missing_parents_is_denied (test_write_guard.WriteGuardTests.test_symlink_into_main_with_missing_parents_is_denied) ... ok",
"test_valid_multi_file_patch_on_feature_is_allowed (test_write_guard.WriteGuardTests.test_valid_multi_file_patch_on_feature_is_allowed) ... ok",
"",
"----------------------------------------------------------------------",
"Ran 495 tests in 357.921s",
"",
"OK (skipped=18)",
"make[2]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u3'",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u3'"
],
"output_sha256": "56d1d5d11197d500505b98bd63f64e1c4a3375eee0bbf51b5cb7f948d3de1e24",
"receipt_sha256": "f214edd4293ec312c8ef1e50b1761db12563fe8c7f19c73dc82a95003b06e28a",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/f214edd4293ec312c8ef1e50b1761db12563fe8c7f19c73dc82a95003b06e28a.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T16:55:49.532309+00:00",
"command": "make task-sync",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u3",
"before_head": "f4a95e5698b6d31752f206f26094d31980a00f7e",
"after_head": "f4a95e5698b6d31752f206f26094d31980a00f7e",
"branch": "feature/norm-remediation-u3",
"target_branch": "main",
"target_head": "eef7e5e778cabcb6216f74b74213a3d7511f383b",
"root_target": "feature/norm-remediation",
"immediate_target": "feature/norm-remediation",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u3'",
"[worktree] before-sync: recursive component checks passed",
"[worktree] before-update: recursive component checks passed",
"[worktree] materialize: recursive component checks passed",
"[worktree] after-sync: recursive component checks passed",
"[evidence] WARN JSON receipt line 59: recorded HEAD predates non-card changes ——关键检查须重跑并以 make evidence 重新写入",
"[synced] sync_base=fe0f1cd4649f11b0d855ec39b882b8ca37fffb6b tested_head=f4a95e5698b6d31752f206f26094d31980a00f7e checked_at=2026-10-18T16:56:14Z changed=0 sync_target=feature/norm-remediation",
"[next] 跑正式验收(make test 等),证据写入任务卡",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u3'"
],
"output_sha256": "c2b5f39f8fc6cc8a30af9012b2eb46ced09d2ddbcab9ad490762a4bfc85a613d",
"receipt_sha256": "b42f1564d10e97928cdfd2f39fd6eda97e969f22bfbcff4668543a7c3be93dce",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/b42f1564d10e97928cdfd2f39fd6eda97e969f22bfbcff4668543a7c3be93dce.json"
}
```
## 闭合记录(合入前折叠)
- 本卡在 PR #620(https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/620)合入前闭合并归档,随该 PR 一同合入。
- 该 PR 的合并提交即本任务的落地记录。
- 合入后无需回填,也无需单独的闭合 PR。
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T17:00:44.968802+00:00",
"command": "make task-close SELF=1",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u3",
"before_head": "56d16ac458de980511da70f9dbeec4f0fbdab6e9",
"after_head": "1f34c35e446a3a93959fda4daf7bbdcab0819f81",
"branch": "feature/norm-remediation-u3",
"target_branch": "main",
"target_head": "eef7e5e778cabcb6216f74b74213a3d7511f383b",
"root_target": "feature/norm-remediation",
"immediate_target": "feature/norm-remediation",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u3'",
"admit: ok",
"remote: ",
"remote: Create a new pull request for 'feature/norm-remediation-u3': ",
"remote: https://git-panel.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/new/feature/norm-remediation-u3 ",
"remote: ",
"[closed] .task/feature-norm-remediation-u3.md 已在 PR #620 合入前闭合并归档;合入后无需 task-close",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u3'"
],
"output_sha256": "656fc7c46263e0b49916551bc77638a287adaf06f42197540607c9ae0fb564a4",
"receipt_sha256": "183eb304dfa804b340e56d129108f413f5616aa653a3225d5f5ee58e505bc013",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/183eb304dfa804b340e56d129108f413f5616aa653a3225d5f5ee58e505bc013.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T17:03:30.573232+00:00",
"command": "make task-sync",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u3",
"before_head": "532c7f3b6098d8071925afa48633b840b1148b69",
"after_head": "532c7f3b6098d8071925afa48633b840b1148b69",
"branch": "feature/norm-remediation-u3",
"target_branch": "main",
"target_head": "eef7e5e778cabcb6216f74b74213a3d7511f383b",
"root_target": "main",
"immediate_target": "feature/norm-remediation",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u3'",
"[worktree] before-sync: recursive component checks passed",
"[worktree] before-update: recursive component checks passed",
"[worktree] materialize: recursive component checks passed",
"[worktree] after-sync: recursive component checks passed",
"[evidence] WARN JSON receipt line 68: recorded HEAD predates non-card changes ——关键检查须重跑并以 make evidence 重新写入",
"[synced] sync_base=fe0f1cd4649f11b0d855ec39b882b8ca37fffb6b tested_head=532c7f3b6098d8071925afa48633b840b1148b69 checked_at=2026-10-18T17:03:56Z changed=0 sync_target=feature/norm-remediation",
"[next] 跑正式验收(make test 等),证据写入任务卡",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u3'"
],
"output_sha256": "13d0ce871c7520312e4e6b199dac9274b1fc6f65d26ab150e84d9b35a3305fd2",
"receipt_sha256": "ad5add14e897beee093e25645f0c30b280175676b0b7826ea6cb634b07b772df",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/ad5add14e897beee093e25645f0c30b280175676b0b7826ea6cb634b07b772df.json"
}
```
@@ -0,0 +1,261 @@
# feature/norm-remediation-u4 任务卡
任务主记录:PR #621 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/621;状态:已完成(合入前闭合);owner:weichen
- 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= eef7e5e778cabcb6216f74b74213a3d7511f383b
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u4(worktree);分支:feature/norm-remediation-u4
- 分支类型:child;initiative_id:feature-norm-remediation;root_target:main;immediate_target:feature/norm-remediation;accepting_requirements:false;parent_branch:feature/norm-remediation;parent_head_sha:6cee4c5728f1c5e723e599986f1f0e4372ec3032;parent_pr:无;parent_source:origin
- 需求分流:免(父 initiative 子任务登记已列出 feature/norm-remediation-u4;parent_head_sha=6cee4c5728f1c5e723e599986f1f0e4372ec3032)
- 授权与交付终点:按用户批准的 U1-U7 规范整改计划实施 U4,并完成 Review、测试、PR/CI 后合入 initiative。范围限 `policy/facts.md`、`scripts/facts-verify.sh`、`tests/test_facts_verify.py`;不接触真实凭据、不跑现场事实刷新、不修改平台或其他 U-ID。
- 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进)
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
- 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入)
- 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位)
## 目标与非目标
目标:F2 的验证路径不让展开后的 token 进入子进程 argv、输出或证据;F4 验证只刷新它能证明的事实,DNS/超时/泛化网络错误不能刷新 TLS 特定原因。复用已有 token-safe 请求模式,回归使用合成 HOME/IMC 凭据、桩客户端和临时表,验证正常/异常及 --update 日期语义。
计划:U1-U7 规范整改实施计划 U4(唯一正文位于 `Agent-System-Dev-wt-feature-norm-remediation-plan/docs/superpowers/plans/2026-10-18-0849-fix-development-norm-remediation-plan.md`)。实际 child 代码基线为 parent_head_sha `6cee4c5`;启动收据的 R0 为当时最新 root main 快照,二者不混同。
## Agent 实施收据
路由与 fail-stop 规则见根目录 AGENT-EXECUTION.md 与 policy/delivery.md;每次尝试一行,原始日志留在源码外收据路径。
| 单元 ID | 预期范围 | 配置摘要 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|---|---|---|---|---|---|---|---|---|---|---|
| norm-u4-safe-credential-truthful-facts | facts policy/probes/offline tests | caefcb72 | implementation | cursor, agy, pi | 1 | cursor-agent-stable / auto | success | 7e0b0e4ff8c5 | 0 | /tmp/norm-u4-facts-receipt.json |
| norm-u4-credential-destination-repair | exact destination and redirect negative cases | caefcb72 | repair | cursor, agy, pi | 1 | cursor-agent-stable / auto | success | 39834ead7d5c | 0 | /tmp/norm-u4-credential-boundary-repair-receipt.json |
| norm-u4-security-correctness-review | independent fixed-diff review and offline replay | caefcb72 | review | pi, agy, cursor, codex | 1 | pi / minimax-cn/MiniMax-M3 | success | 25cdc6adc848 | 0 | /tmp/norm-u4-independent-review-receipt.json |
## 同步记录
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|---|---|---|---|
| 启动 | eef7e5e778cabcb6216f74b74213a3d7511f383b | 6cee4c5728f1c5e723e599986f1f0e4372ec3032 | 2026-10-18T17:17:00Z |
## 证据(Evidence)
<!-- CMD="<命令>" make evidence 写入;手抄/转写输出视为无效证据(AGENTS.md 证据与验证门禁)。 -->
| 时间(UTC) | 命令 | 被测HEAD | exit | 来源 | sha256(16) |
|---|---|---|---|---|---|
## 结果与验证
- 结果:F2 token 仅在进程内读取/发送,不进入 child argv/输出/收据;端点在读取凭据前逐字核对,不跟随 301/302/303/307/308 重定向。F4 将退役禁令与现场 TLS 现象分开,DNS/超时/连接错误/握手成功均不刷新 TLS 特定事实;历史日期明确不证明新判据。
- 验证:host 在代码候选 `39834ead7d5cae48477621b5e68f737ae0082e65` 重放 8 项离线事实测试、shell syntax/diff 检查通过;`make test-governance` 执行 503 项(18 项 skip),无失败(SELF,完整收据经 evidence 导入)。独立 PI Review 同 head 重放 8 项并判无阻塞项。测试先红后绿证据在各 worker receipt;所有用例只使用合成 HOME/IMC 和客户端桩,不读真实凭据、不访问 Gitea。
- 影响与剩余项:没有刷新任何真实 last_verified 日期;无部署、凭据轮换、平台或其他范围修改。F4 若需重新证明当前 TLS 现象应另行现场重验,不能沿用旧宽泛失败。
## 合入与清理
- Review 记录(独立 fresh CLI session,2026-10-18):PI / minimax-cn / MiniMax-M3;host 按 run `03b4578a94b710425f11bd74df523a20`、attempt `d0bfc2e77832` 核验新进程及独立 Review,执行器本地记录为 SELF,不冒充 CI/GATE 身份;
base/head=6cee4c5728f1c5e723e599986f1f0e4372ec3032..39834ead7d5cae48477621b5e68f737ae0082e65,
tested_head=39834ead7d5cae48477621b5e68f737ae0082e65(`git rev-parse HEAD` 已对账);
离线 focused test `PYTHONDONTWRITEBYTECODE=1 python3 -m unittest tests.test_facts_verify -v`
→ 8 tests in 4.608s OK(test_f2_pass_sends_home_token_in_process_and_leaks_nowhere / test_f2_missing_or_malformed_credentials_fail_without_echo / test_f2_rejected_or_failing_request_does_not_refresh_or_leak / test_f2_rejects_unregistered_destination_before_reading_credentials / test_f2_refuses_redirect_without_forwarding_authorization / test_f4_only_tls_handshake_failure_passes_and_refreshes / test_f4_helper_reports_each_condition_distinctly / test_registry_separates_retired_endpoint_policy_from_tls_observation);
bash -n scripts/facts-verify.sh 无语法错误。
验收逐项:
· HOME token 仅进程内经 Authorization 头发送,child argv/stderr/stdout/收据/登记表中不存在 HOME/IMC 真实凭据值:test_f2_pass 断言 http 拦截仅 1 次且 url=https://git-home.u1680832.nyat.app:30319/api/v1/user,authorization=token <HOME_TOKEN>;assert_no_secrets 覆盖子进程 argv、PATH 桩 curl/wget argv、stdout/stderr、收据 JSON、登记表;
· 凭据缺失/格式错/文件缺失三条 subTest 均 FAIL,http 拦截=[] 即未发请求,stderr 含 "ACCESS_TOKEN" 但不含 token 字面值,且 `--update` 不刷新 F2 日期(保持 OLD_DATE):test_f2_missing_or_malformed_credentials_fail_without_echo;
· URL 校验 11 个变体(含 http://、不同端口、userinfo、userinfo@、fragment、查询串、路径尾缀 /../、路径变体、尾随空格)全部 exit 6 且无 http 拦截,且 ACCESS_TOKEN 不在 stderr(端点先于凭据校验):test_f2_rejects_unregistered_destination_before_reading_credentials;脚本侧 `if sys.argv[2] != ENDPOINT: ... sys.exit(6)` 是逐字字符串等价,避开任何 URL 归一化;
· 301/302/303/307/308 五种全不转发 Authorization:`NoRedirect(HTTPRedirectHandler).redirect_request` 固定返回 None,stub 拦截 `[r["url"] for r in requests]==["https://git-home.u1680832.nyat.app:30319/api/v1/user"]` 无后续请求、收不到 redirect-target 主机名,且 `--update` 模式下 F2 仍是 FAIL 且未刷新日期;
· F4 仅 TLS 握手错误判 PASS,dns/timeout/refused/reset/tls-timeout/ok 全 FAIL 且不刷新日期:test_f4_only_tls_handshake_failure_passes_and_refreshes;probe `tls-handshake-fails` 出口 0/3/4/5/6 区分明确,F4 现有 2026-10-14 last_verified 在 `policy/facts.md` 被显式标注为「历史日期…不证明当前 TLS 层握手失败判据;经该判据独立重验前不得当作已核实」,与 F4 行禁用字符串「不得使用」(政策禁令,相对独立)分离(test_registry_separates_retired_endpoint_policy_from_tls_observation);
· 测试全离线:`socket.socket.connect/_ex = _deny` 拒绝未桩接的真实连接,`socket.create_connection`、`ssl.SSLContext.wrap_socket`、`urllib.request.HTTPSHandler/https_open / http_open` 全部经 sitecustomize 桩化;HOME 指向 tmpdir 不读真实 ~/.secrets;PATH 桩化 curl/wget 仅写 argv 日志;全程未触达 Gitea 或旧端点;本评审运行无任何 `--update` 写回真实 `policy/facts.md`。
· reviewer profile/model 以独立运行事件为依据;Shell=bash,Bash 语法 `bash -n` 通过;Python=3.x,`task_triage.TOKEN_RE`、`task_triage.secrets_file_token()`、`task_triage.http_get_json()`、`task_triage.Stop` 已直接阅读验证其 token 仅入 Authorization 头、异常消息仅含 `type(exc).__name__` 不含凭据。
无阻塞项;不修正实现;不在本评审做合入/CI/PR 操作(合规范围内仅写一条 review 记录)。
- 冲突记录:最新 initiative `c6fe5ad` 已经 task-sync 合入;仅父任务元数据变化,无冲突;实现/测试/事实文件相对已审已测代码候选 `39834ead` 的 diff 为空,既有直接验证仍适用。
- CI 记录:NOT_RUN(当前 HEAD 完整 SHA、全部必需检查、运行链接、执行身份及 GATE 结果)
- 合入记录:NOT_RUN(交付授权范围、PR、被核验 HEAD、合入 SHA、目标分支及内容核验)
- 清理记录:NOT_RUN(授权依据、写者退出确认、worktree/分支/任务卡处置)
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T17:16:04.326553+00:00",
"command": "make precheck",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev",
"before_head": "eef7e5e778cabcb6216f74b74213a3d7511f383b",
"after_head": "eef7e5e778cabcb6216f74b74213a3d7511f383b",
"branch": "main",
"target_branch": "main",
"target_head": "eef7e5e778cabcb6216f74b74213a3d7511f383b",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev'",
"[repo] branch=main head=eef7e5e778",
"[remote] origin/main=eef7e5e778 ahead=0 behind=0",
"[tree] clean submodules_drift=0 uninit=12",
"[warn] 12 个子模块未初始化——构建/测试前需物化(不阻断写入)",
"[worktrees] linked=8",
"[recycle] merged un-recycled branches: feature/layered-python-env",
"[initiatives] local cards (not authoritative): none",
"[hooks] core.hooksPath=scripts/hooks(pre-commit/post-merge 实际接线)",
"[facts] policy/facts.md 6 条事实均在有效期内",
"[required-reading] core/baseline.md, workflows/delivery.md §1, policy/delivery.md",
"[R0] eef7e5e778(完整:eef7e5e778cabcb6216f74b74213a3d7511f383b)",
"[worktree] before-sync: recursive component checks passed",
"[verdict] READY — 保留本次 precheck receipt 后建任务工作区:PRECHECK_RECEIPT=/tmp/task-precheck.json make task-start NAME=feature/your-branch",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev'"
],
"output_sha256": "b1b224c850fc8ccfd988d17caaf1f716e2c2e07ab50d9c5387de9ed292aa9ad0",
"receipt_sha256": "818aca5afe7aca05cc3436a020562d87b532a92ebdee7a828b83a39b417e003c",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/818aca5afe7aca05cc3436a020562d87b532a92ebdee7a828b83a39b417e003c.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T17:22:01.884792+00:00",
"command": "python3 -m unittest tests.test_facts_verify && bash -n scripts/facts-verify.sh && git diff --check",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u4",
"before_head": "7e0b0e4ff8c54e9095d86be133965ab1828a8e3d",
"after_head": "7e0b0e4ff8c54e9095d86be133965ab1828a8e3d",
"branch": "feature/norm-remediation-u4",
"target_branch": "main",
"target_head": "eef7e5e778cabcb6216f74b74213a3d7511f383b",
"root_target": "main",
"immediate_target": "feature/norm-remediation",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"......",
"----------------------------------------------------------------------",
"Ran 6 tests in 3.532s",
"",
"OK"
],
"output_sha256": "0fff5c17193d077cf601d6c73735a79a0074e48107773120f33b8f14d8e71409",
"receipt_sha256": "7101fa8f0bf09c8e8ca06be96351cc1f81f4a13e69363b427a61b49b37ad9941",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/7101fa8f0bf09c8e8ca06be96351cc1f81f4a13e69363b427a61b49b37ad9941.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T17:29:35.268634+00:00",
"command": "python3 -m unittest tests.test_facts_verify && bash -n scripts/facts-verify.sh && git diff --check",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u4",
"before_head": "39834ead7d5cae48477621b5e68f737ae0082e65",
"after_head": "39834ead7d5cae48477621b5e68f737ae0082e65",
"branch": "feature/norm-remediation-u4",
"target_branch": "main",
"target_head": "eef7e5e778cabcb6216f74b74213a3d7511f383b",
"root_target": "main",
"immediate_target": "feature/norm-remediation",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"........",
"----------------------------------------------------------------------",
"Ran 8 tests in 4.333s",
"",
"OK"
],
"output_sha256": "c5b777791a060b3d9c4ef8c01df28662e588ac3c05ccd2de96068357ba5438d3",
"receipt_sha256": "0f6b6ec11bdbe651b8f6f73c82501755916e9f0d495af8cd6c8ddc0dc6e408e1",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/0f6b6ec11bdbe651b8f6f73c82501755916e9f0d495af8cd6c8ddc0dc6e408e1.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T17:30:04.489780+00:00",
"command": "make test-governance",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u4",
"before_head": "39834ead7d5cae48477621b5e68f737ae0082e65",
"after_head": "39834ead7d5cae48477621b5e68f737ae0082e65",
"branch": "feature/norm-remediation-u4",
"target_branch": "main",
"target_head": "eef7e5e778cabcb6216f74b74213a3d7511f383b",
"root_target": "main",
"immediate_target": "feature/norm-remediation",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"test_feature_missing_parent_is_allowed (test_write_guard.WriteGuardTests.test_feature_missing_parent_is_allowed) ... ok",
"test_invalid_json_is_denied (test_write_guard.WriteGuardTests.test_invalid_json_is_denied) ... ok",
"test_missing_parent_on_main_is_denied (test_write_guard.WriteGuardTests.test_missing_parent_on_main_is_denied) ... ok",
"test_missing_unknown_and_malformed_write_input_are_denied (test_write_guard.WriteGuardTests.test_missing_unknown_and_malformed_write_input_are_denied) ... ok",
"test_non_git_destination_is_explicitly_outside_scope (test_write_guard.WriteGuardTests.test_non_git_destination_is_explicitly_outside_scope) ... ok",
"test_nonwrite_tools_are_outside_scope (test_write_guard.WriteGuardTests.test_nonwrite_tools_are_outside_scope) ... ok",
"test_relative_path_uses_hook_cwd_not_process_cwd (test_write_guard.WriteGuardTests.test_relative_path_uses_hook_cwd_not_process_cwd) ... ok",
"test_symlink_into_main_with_missing_parents_is_denied (test_write_guard.WriteGuardTests.test_symlink_into_main_with_missing_parents_is_denied) ... ok",
"test_valid_multi_file_patch_on_feature_is_allowed (test_write_guard.WriteGuardTests.test_valid_multi_file_patch_on_feature_is_allowed) ... ok",
"",
"----------------------------------------------------------------------",
"Ran 503 tests in 368.596s",
"",
"OK (skipped=18)",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u4'"
],
"output_sha256": "54c9dc06bb99075654b296b8d494da68390cc635159c9a364bcc4cf9925c84a0",
"receipt_sha256": "3621e9d21fb28c174997b1c2fdbc100eda2ad653ea81d96f6206a36b15bf8ba3",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/3621e9d21fb28c174997b1c2fdbc100eda2ad653ea81d96f6206a36b15bf8ba3.json"
}
```
| 同步(记录前对象) | c6fe5adba34d7266e7bcfbb9a2c64a0ae61e9b8e | ddad7838535ae06070bfef973106e582c75c6380 | 2026-10-18T17:37:17Z |
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T17:36:52.906926+00:00",
"command": "make task-sync",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u4",
"before_head": "53897dc218b492c1498637cca9a736143793e3df",
"after_head": "e2da2fef9a205584ba5d82a9e70cf43ad294c9db",
"branch": "feature/norm-remediation-u4",
"target_branch": "main",
"target_head": "eef7e5e778cabcb6216f74b74213a3d7511f383b",
"root_target": "main",
"immediate_target": "feature/norm-remediation",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u4'",
"[worktree] before-sync: recursive component checks passed",
"Merge made by the 'ort' strategy.",
" .task/feature-norm-remediation.md | 16 ++++++++++++++--",
" 1 file changed, 14 insertions(+), 2 deletions(-)",
"[worktree] before-update: recursive component checks passed",
"[worktree] materialize: recursive component checks passed",
"[worktree] after-sync: recursive component checks passed",
"admit: ok",
"[evidence] WARN JSON receipt line 73: unverified: recorded component state was not at its pinned SHA ——关键检查须重跑并以 make evidence 重新写入",
"[evidence] WARN JSON receipt line 114: recorded HEAD predates non-card changes ——关键检查须重跑并以 make evidence 重新写入",
"[synced] sync_base=c6fe5adba34d7266e7bcfbb9a2c64a0ae61e9b8e tested_head=e2da2fef9a205584ba5d82a9e70cf43ad294c9db checked_at=2026-10-18T17:37:17Z changed=1 sync_target=feature/norm-remediation",
"[next] 跑正式验收(make test 等),证据写入任务卡",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u4'"
],
"output_sha256": "f0e3a1083a6d4caf71bdb0213510488f7496f8bf8e73ae3bcb8eee8bd940d977",
"receipt_sha256": "3f384a0ba3dba53089f1d7b26c15265f8bcc7f9007d001e7666e74245388d94d",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/3f384a0ba3dba53089f1d7b26c15265f8bcc7f9007d001e7666e74245388d94d.json"
}
```
## 闭合记录(合入前折叠)
- 本卡在 PR #621(https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/621)合入前闭合并归档,随该 PR 一同合入。
- 该 PR 的合并提交即本任务的落地记录。
- 合入后无需回填,也无需单独的闭合 PR。
@@ -0,0 +1,221 @@
# feature/norm-remediation-u5 任务卡
任务主记录:PR #623 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/623;状态:已完成(合入前闭合);owner:weichen
- 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= eef7e5e778cabcb6216f74b74213a3d7511f383b
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u5(worktree);分支:feature/norm-remediation-u5
- 分支类型:child;initiative_id:feature-norm-remediation;root_target:main;immediate_target:feature/norm-remediation;accepting_requirements:false;parent_branch:feature/norm-remediation;parent_head_sha:825e4fc98f30da4950a48d15d59f5338206726bf;parent_pr:无;parent_source:origin
- 需求分流:免(父 initiative 子任务登记已列出 feature/norm-remediation-u5;parent_head_sha=825e4fc98f30da4950a48d15d59f5338206726bf)
- 授权与交付终点:按批准的规范整改计划实施 U5,范围仅 `AGENTS.md` 与 `PROJECT.md`,完成必要检查、独立 Review、PR/CI 后合入 initiative。U1-U4 前置已完成(U4 #621 / `825e4fc`);不修改规范正文、命令、执行器、平台、组件或业务。
- 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进)
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
- 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入)
- 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位)
## 目标与非目标
目标:根入口只保留强制原则与触发式必读指针,详细规则分别归 delivery/governance/AGENT-EXECUTION/facts 等权威文档;删除重复且不安全的 token 提取步骤。PROJECT 保留稳定事实、验证入口和全部既有主题索引,将动态批准/进度/验收状态归还主记录,避免多份状态漂移。保持既有授权、安全、独立 Review、证据与最终准入边界。
## Agent 实施收据
路由与 fail-stop 规则见根目录 AGENT-EXECUTION.md 与 policy/delivery.md;每次尝试一行,原始日志留在源码外收据路径。
| 单元 ID | 预期范围 | 配置摘要 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|---|---|---|---|---|---|---|---|---|---|---|
| norm-u5-concise-project-entrypoints | AGENTS.md + PROJECT.md | caefcb72 | implementation | cursor, agy, pi | 1 | cursor-agent-stable / auto | success | 832bee205380 | 0 | /tmp/norm-u5-entrypoints-receipt.json |
| norm-u5-readiness-evidence-summary-consistency | conditional local readiness / layered evidence summaries | caefcb72 | repair | cursor, agy, pi | 1 | cursor-agent-stable / auto | success | 36103dc62d59 | 0 | /tmp/norm-u5-summary-consistency-repair-receipt.json |
| norm-u5-ready-routing-without-circular-gate | sync/recovery is not gated by prior READY | caefcb72 | repair | cursor, agy, pi | 1 | cursor-agent-stable / auto | success | 1b04fd4a0408 | 0 | /tmp/norm-u5-readiness-routing-final-receipt.json |
| norm-u5-independent-entrypoint-review | independent fixed-diff/rule/link review | caefcb72 | review | pi, agy, cursor, codex | 1 | pi / minimax-cn/MiniMax-M3 | success | d0ae825547b4 | 0 | /tmp/norm-u5-independent-review-receipt.json |
## 同步记录
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|---|---|---|---|
| 启动 | eef7e5e778cabcb6216f74b74213a3d7511f383b | 825e4fc98f30da4950a48d15d59f5338206726bf | 2026-10-18T17:48:21Z |
## 证据(Evidence)
<!-- CMD="<命令>" make evidence 写入;手抄/转写输出视为无效证据(AGENTS.md 证据与验证门禁)。 -->
| 时间(UTC) | 命令 | 被测HEAD | exit | 来源 | sha256(16) |
|---|---|---|---|---|---|
## 结果与验证
- 结果:AGENTS 改为触发式权威路由与必要边界,删除重复的 token/端点说明;明确本地续作与正式准入、同步恢复和分级证据,避免无条件摘要重新阻断 U2/U3。PROJECT 保留稳定组合/验证事实与全部既有主题链接,将动态批准/进度/验收归还主记录。
- 验证:host 在实现候选 `1b04fd4a0408931bb84c44c2fe692205ff25079f` 检查 diff 与物化后的核心权威目标文件,均通过(SELF receipt 已导入);独立 fresh PI Review 对规则保留、恢复无循环门禁、证据分级及链接/锚点审查无阻塞项。纯说明/路由变更不新增镜像文本测试、不重复完整套件;最终组合验证仍由 U6 执行。
- 影响与剩余项:只改两个入口文件。review 私有目录未物化子模块,报告中相关目标存在性以其末尾限制说明为准;host 已在当前物化 checkout 验证核心权威文件存在,既有 proposal 链接未改变。不读取凭据、不运行在线事实刷新。
## 合入与清理
- Review 记录(独立 fresh CLI session,2026-10-18):PI / minimax-cn / MiniMax-M3;本评审仅写一条 task 卡记录,不触碰源代码/索引/引用/config,不做合入/CI/PR/部署/同侪派遣。
base/head = `825e4fc98f30da4950a48d15d59f5338206726bf..1b04fd4a0408931bb84c44c2fe692205ff25079f`(已 `git rev-parse` 对账);
diff 范围仅 `.task/feature-norm-remediation-u5.md` + `AGENTS.md` + `PROJECT.md`(与 U5 任务卡「范围仅 AGENTS.md 与 PROJECT.md」一致,未越界)。
结论:**无阻塞项**。所有强制边界在压缩后保留,原始规则未丢失,仅路由至权威文档;`AGENTS.md` 不再展开凭据提取命令、SSH 指纹、API/SSH 主机名、`~/.secrets/gitea` / `~/.ssh/home_gitea` 路径字面值与 `awk` 切片片段,与 U4「凭据字面值不入仓、不回显、不进命令行/日志/证据/产出物」的硬边界一致;事实查询路由到 `policy/facts.md`,与其登记的探针命令一致。
逐项校验(按约束清单):
· **goal-first / 严格范围 / 最小充分 / 测试与编排成比例** 完整保留为「最高优先级:目标兑现与最小充分交付(强制)」节:优先级四层链、「先交付用户明确要求的产物」「最小充分实现」「绝对禁止私自扩大范围」「测试与编排成比例」与「编排成本不得超过任务本身」原文落地,细则链到 `policy/delivery.md` 三段标题锚点。
· **agent-per-unit / no-host-fallback / transport / admission / fresh independent Review** 保留为「Agent 实施与独立 Review(强制)」节:`agent-per-unit(配置:AGENT-EXECUTION.md)`、`fallback_to_host` 为 `never`、`scripts/agent-exec apply` 或 pre-commit `admit` 精确核对、host 豁免仅 `.task/**`、`docs/superpowers/specs/**`、`docs/superpowers/plans/**`、`不同阶段、不同单元各用全新会话`、`禁止实施者经 continue/resume/session 等机制续作评审`、`无法证明会话独立时不得标为独立 Review` 均原义落地;细则链 `policy/delivery.md#agent-实施单元与主模型职责`、`policy/delivery.md#阶段会话隔离与独立-review`、`deps/development-guidelines/core/baseline.md`(unobservable,见限制)。
· **任务生命周期 → governance** 保留为「任务生命周期(强制)」节,启动/恢复、PR 检查、任务卡闭合、回收、放弃未合入工作用 `make task-finish ABANDON=…`、首次克隆 `make setup`、治理脚本改动 `make test-governance` 全部原文落地,命令与细则链 `policy/governance.md`(启动与恢复 / 回收 / 持续回归)和 `policy/delivery.md`(两级分支与分流 / 分级门禁 / 合入调度 / Review 与合入);与 `policy/governance.md` 同名标题一一对应。
· **新建任务严格 fresh READY;既有任务 LOCAL_READY 仅本地** 原文落地:`SHARED_WORKSPACE_BUSY / SYNC_REQUIRED / REMOTE_UNVERIFIED` 均不得建任务;`LOCAL_READY 只是 SELF 局部工作记录,不能替代建任务、正式交付、CI、GATE 或 REPLAY 的准入或证据;脏现场、未对账或副作用未知时仍须停止`,与 `policy/governance.md` 启动与恢复节一致。
· **恢复 / task-sync 允许绕开 READY 前置** 原文落地:`已登记任务的恢复与局部继续按 [启动与恢复](policy/governance.md#启动与恢复),为消除落后所需的同步按 [被测对象](policy/governance.md#被测对象) 执行,READY 不是执行该同步的前提`,明确解环。
· **L2 / main 证据按分层表** 原文落地:`各层级要求的证据与 CI 以 [分级门禁表](policy/delivery.md#层级任务通道与分级门禁) 为准:L2→L1 不要求三段证据;推进 main 的交付仍须三段输出(precheck / task-sync / 测试)由 evidence 写入任务卡,PR 描述引用不另手抄。测试通过的权威源是 PR HEAD 上 .gitea/workflows/ci.yaml 的 CI`,与 `policy/governance.md` 本地记录与独立证据、`policy/delivery.md` 分级门禁一致;细则链回 governance 与 guidelines `standards/verification.md`。
· **凭据字面值 / 提取片段已清除**:`awk '/^HOME:/{h=1;next} /^IMC:/{h=0} h&&sub(/^- ACCESS_TOKEN=/,""){print;exit}' ~/.secrets/gitea` 命令、SSH 公钥指纹 `SHA256:GYXaOXIMeloQ1fKSfdJ/ndgPQzs/Ix7Hk62ekfkfQ20`、API/SSH 主机名 `git-home.u1680832.nyat.app:30319` / `git-ssh.u1680832.nyat.app:31411`、`~/.secrets/gitea` HOME/IMC 段、`~/.ssh/home_gitea` 与 `~/.ssh/config` 主机条目、`GITEA_TOKEN` 环境变量注入方式、token `Authorization: token <值>` 头拼接示例均已从 `AGENTS.md` 删除;现仅以「端点、SSH、API 与 token 可用性只以 [policy/facts.md](policy/facts.md) 为准;引用前先跑其验证命令;凭据类核验只用该表登记的探针」+「凭据值不入仓、不回显,不进命令行字面量、日志、证据或产出物(baseline 硬边界 2)」两短句承接,路由到 `policy/facts.md`(含 F1–F6 登记命令)与 `policy/governance.md#ci-凭据边界`;未发现事实表以外的任何凭据字面值残留。
· **高后果操作双钥匙 owner 执行** 保留为独立节:`改写历史、解除/变更分支保护、删除归档引用、发布版本:Agent 只准备方案与命令,由用户确认并亲手执行`,未削弱。
· **UI 强制 DESIGN / tokens / motion / Collapsible / 异步边界** 保留为「UI 设计门禁(强制)」节:`DESIGN.md` 四原则、`@ui/tokens.css` 颜色/圆角/字号、`--fs-ui-*` 字号标尺、`@ui/motion.css` 的 `mk-*` 工具类、`@ui` Collapsible 折叠原语、`<details>` 禁用、`design-guard.test.ts`(UI 与 Frontend 各一份)棘轮拦截裸色值/私有 `@keyframes`/行内字号、风格调整的 UI 令牌 PR + Dev 组合 PR 流程、跨仓不要求同一 PR、异步状态唯一所有者、事件按 seq 过期丢弃均原义落地,与 `DESIGN.md` 第 9 节组件范式一致。
· **提交与 PR** 保留:`Why: / Evidence: / Impact: / Refs:` 四段 body、英文祈使句主题行 ≤100 列、跨仓 gitlink 组合验证 + 受保护分支 PR 合入均原文落地。
· **必读路由表(强制)** 新增 `## 必读路由(强制)` 表把触发映射到权威文档,覆盖需求/设计/实施/交付 → `policy/delivery.md`;任务分流/启动/恢复/同步/PR 检查/证据/任务卡闭合/回收 → `policy/governance.md`;实施/修复/测试/Review 候选与模型与尝试上限与 fail-stop 与会话路由 → `AGENT-EXECUTION.md` + `deps/development-guidelines/standards/agent-execution.md`;外部 API/Git/SSH 端点或凭据 → `policy/facts.md`;界面 → `DESIGN.md`;项目组成/构建/验证/方向规划入口 → `PROJECT.md`,与各权威文档作用域一一对应。
· **`PROJECT.md` 动态批准/进度回收**:移除每条主记录后的「r1/r2/r3/r3.1、批准日期、未授权/部署/真实账号验收、U1-U5/U6 状态、PR #xxx #yyy 落地、dev 8788 续查形成候选草案」等动态状态段;保留主题链接与一句话主题描述;新增显式声明 `下列条目只是主题索引:批准、进展、验收与部署状态一律以所链主记录、任务卡与 PR 为准,本入口不复制;收录不构成批准`,符合「动态批准/进度/验收状态归还主记录,避免多份状态漂移」;同时核对保留的链接集合等于或收敛于基线(2026-10-10..18 共 14 条主记录 + 续审记录 + INDEX + 采纳记录 + 合入调度 + 开发门禁),未删除任何既往主题索引;`docs/svc-deploy/2026-10-12-account-durability-plan-review.md`、`policy/adoption.md`、`policy/governance.md`、`policy/delivery.md`、所有 `modules/documents/docs/proposals/*.md` 链接路径字符串相对基线未变(链接路径差异 = 仅删除 r1/r2/r3/r3.1 后缀与状态描述)。
链接 / 锚点核验:`git diff --check 825e4fc..1b04fd4` 无空白冲突;仓内非子模块相对链接(`policy/delivery.md`、`policy/governance.md`、`policy/facts.md`、`policy/adoption.md`、`AGENT-EXECUTION.md`、`DESIGN.md`、`PROJECT.md`、`docs/svc-deploy/2026-10-12-account-durability-plan-review.md`、`modules/documents/docs/proposals/INDEX.md`、`modules/documents/docs/proposals/`)目标文件在本仓库工作区全部存在;新引用的 16 个标题锚点(policy/delivery.md ×9 + policy/governance.md ×7)与 `policy/delivery.md` / `policy/governance.md` 的标题层级对应(去标点 lowercase slug,与基线 `[policy/delivery.md](policy/delivery.md#agent-实施单元与主模型职责)` 等使用的同一生成规则一致,渲染器侧由 Gitea 自行生成,未在 PR 头验证);`policy/facts.md` 锚点 `## ` 段无,故未引用,路由回整文件。
限制(按约束声明):
· 子模块链接 `deps/development-guidelines/core/baseline.md`、`deps/development-guidelines/standards/agent-execution.md` 与全部 `modules/documents/docs/proposals/*.md` 在本私有 checkout 未物化(`modules/documents` 与 `deps/development-guidelines` 子模块目录为空),未初始化它们;按约束仅做链接集合对比,未对子模块做 `git submodule init/update`、未断言渲染或文件存在性,host 须在物化后独立核验目标文件与锚点;此为 unobservable,不影响本评审「无阻塞项」结论。
· 本评审不跑 `make precheck` / `make test` / `make test-governance`(范围仅 prose + 任务卡路由,无脚本/治理改动);不刷新 `policy/facts.md` `last_verified`;不申请 CI(CI 是 PR HEAD 的 `make test` + `make build` 由 Gitea Actions 执行,本评审不冒充 GATE)。
· 不修正实现;不在本评审做合入 / CI / PR 操作(合规范围内仅写一条 review 记录到 `.task/feature-norm-remediation-u5.md`)。
· 基线 825e4fc 之前未合入的 prose 提案内容不在 U5 范围,不重复审查。
- 冲突记录:已同步包含 U7 的 initiative `2e5d981`,无冲突;两个入口相对已审实现 `1b04fd4` 未再改变。合成候选 `45bcba0` 的执行配置、diff 和核心权威链接检查通过(SELF receipt 已导入),不重复完整套件。
- CI 记录:NOT_RUN(当前 HEAD 完整 SHA、全部必需检查、运行链接、执行身份及 GATE 结果)
- 合入记录:NOT_RUN(交付授权范围、PR、被核验 HEAD、合入 SHA、目标分支及内容核验)
- 清理记录:NOT_RUN(授权依据、写者退出确认、worktree/分支/任务卡处置)
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T17:46:31.953994+00:00",
"command": "make precheck",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev",
"before_head": "eef7e5e778cabcb6216f74b74213a3d7511f383b",
"after_head": "eef7e5e778cabcb6216f74b74213a3d7511f383b",
"branch": "main",
"target_branch": "main",
"target_head": "eef7e5e778cabcb6216f74b74213a3d7511f383b",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev'",
"[repo] branch=main head=eef7e5e778",
"[remote] origin/main=eef7e5e778 ahead=0 behind=0",
"[tree] clean submodules_drift=0 uninit=12",
"[warn] 12 个子模块未初始化——构建/测试前需物化(不阻断写入)",
"[worktrees] linked=8",
"[recycle] merged un-recycled branches: feature/layered-python-env",
"[initiatives] local cards (not authoritative): none",
"[hooks] core.hooksPath=scripts/hooks(pre-commit/post-merge 实际接线)",
"[facts] policy/facts.md 6 条事实均在有效期内",
"[required-reading] core/baseline.md, workflows/delivery.md §1, policy/delivery.md",
"[R0] eef7e5e778(完整:eef7e5e778cabcb6216f74b74213a3d7511f383b)",
"[worktree] before-sync: recursive component checks passed",
"[verdict] READY — 保留本次 precheck receipt 后建任务工作区:PRECHECK_RECEIPT=/tmp/task-precheck.json make task-start NAME=feature/your-branch",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev'"
],
"output_sha256": "b1b224c850fc8ccfd988d17caaf1f716e2c2e07ab50d9c5387de9ed292aa9ad0",
"receipt_sha256": "b2bafbab20fc394a5013d8714d3ccdb15afdcfcc090992cf81cbc97ce930c283",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/b2bafbab20fc394a5013d8714d3ccdb15afdcfcc090992cf81cbc97ce930c283.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T18:01:25.152723+00:00",
"command": "git diff --check 825e4fc..HEAD && for task_target in policy/delivery.md policy/governance.md AGENT-EXECUTION.md policy/facts.md DESIGN.md PROJECT.md deps/development-guidelines/core/baseline.md deps/development-guidelines/standards/agent-execution.md; do test -f \"$task_target\" || exit 1; done && echo \"PASS: entrypoint authority targets exist\"",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u5",
"before_head": "1b04fd4a0408931bb84c44c2fe692205ff25079f",
"after_head": "1b04fd4a0408931bb84c44c2fe692205ff25079f",
"branch": "feature/norm-remediation-u5",
"target_branch": "main",
"target_head": "eef7e5e778cabcb6216f74b74213a3d7511f383b",
"root_target": "main",
"immediate_target": "feature/norm-remediation",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"PASS: entrypoint authority targets exist"
],
"output_sha256": "6143d7beacc4096c4d0313c752e882c73f41557171c148f3ce4da07fc2ca7517",
"receipt_sha256": "1708ac2a687dfc99f17ef1eea02ab183aacd7d72e83ee8fc8a12d4dc6fb8d7a8",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/1708ac2a687dfc99f17ef1eea02ab183aacd7d72e83ee8fc8a12d4dc6fb8d7a8.json"
}
```
| 同步(记录前对象) | 2e5d98118fe436794d1267c5d2ab5ce5013d25ca | 405d00ba05cdf3db643d2bc4d35a8aaf92ed0370 | 2026-10-18T18:03:01Z |
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T18:02:28.140768+00:00",
"command": "make task-sync",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u5",
"before_head": "92c74cee99bf49e7b93ed089d24b7d7529e9ecc8",
"after_head": "45bcba0829dc08fa932c3a52cb99e1e10a099547",
"branch": "feature/norm-remediation-u5",
"target_branch": "main",
"target_head": "eef7e5e778cabcb6216f74b74213a3d7511f383b",
"root_target": "main",
"immediate_target": "feature/norm-remediation",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
" .task/archive/feature-norm-remediation-u7.md | 216 +++++++++++++++++++++++++++",
" .task/feature-norm-remediation.md | 22 ++-",
" AGENT-EXECUTION.md | 41 ++++-",
" policy/delivery.md | 24 +++",
" 4 files changed, 295 insertions(+), 8 deletions(-)",
" create mode 100644 .task/archive/feature-norm-remediation-u7.md",
"[worktree] before-update: recursive component checks passed",
"[worktree] materialize: recursive component checks passed",
"[worktree] after-sync: recursive component checks passed",
"admit: ok",
"[evidence] WARN JSON receipt line 80: unverified: recorded component state was not at its pinned SHA ——关键检查须重跑并以 make evidence 重新写入",
"[evidence] WARN JSON receipt line 121: recorded HEAD predates non-card changes ——关键检查须重跑并以 make evidence 重新写入",
"[synced] sync_base=2e5d98118fe436794d1267c5d2ab5ce5013d25ca tested_head=45bcba0829dc08fa932c3a52cb99e1e10a099547 checked_at=2026-10-18T18:03:01Z changed=1 sync_target=feature/norm-remediation",
"[next] 跑正式验收(make test 等),证据写入任务卡",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u5'"
],
"output_sha256": "23685fbda4ccf9211ab3c9ffee2f8ebd0e239149d7a687aac214881a3192aa6b",
"receipt_sha256": "639cd7b09ba93fea06daec4dc1c750e05e7a83293ddd4da5e43fddaaf6b54388",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/639cd7b09ba93fea06daec4dc1c750e05e7a83293ddd4da5e43fddaaf6b54388.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T18:04:48.522344+00:00",
"command": "scripts/agent-exec validate --repo . && git diff --check 2e5d981..HEAD && for task_target in policy/delivery.md policy/governance.md AGENT-EXECUTION.md policy/facts.md DESIGN.md PROJECT.md deps/development-guidelines/core/baseline.md deps/development-guidelines/standards/agent-execution.md; do test -f \"$task_target\" || exit 1; done && echo \"PASS: entrypoint authority targets and merged execution config\"",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u5",
"before_head": "45bcba0829dc08fa932c3a52cb99e1e10a099547",
"after_head": "45bcba0829dc08fa932c3a52cb99e1e10a099547",
"branch": "feature/norm-remediation-u5",
"target_branch": "main",
"target_head": "eef7e5e778cabcb6216f74b74213a3d7511f383b",
"root_target": "main",
"immediate_target": "feature/norm-remediation",
"before_tracked_diff_sha256": "61ad55e3861841014dd9c58c94f17bc251511c7f83e7a70dbf2ab98e5cff5240",
"after_tracked_diff_sha256": "61ad55e3861841014dd9c58c94f17bc251511c7f83e7a70dbf2ab98e5cff5240",
"output_tail": [
"validate: ok",
"PASS: entrypoint authority targets and merged execution config"
],
"output_sha256": "5315267aaca5e016412b6f406903e907d4e7eead2f2f02bbef689581a2127221",
"receipt_sha256": "638362d67ec6d009a4dea4047844154f5e33bd81e724dd3815243b5cde60c595",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/638362d67ec6d009a4dea4047844154f5e33bd81e724dd3815243b5cde60c595.json"
}
```
## 闭合记录(合入前折叠)
- 本卡在 PR #623(https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/623)合入前闭合并归档,随该 PR 一同合入。
- 该 PR 的合并提交即本任务的落地记录。
- 合入后无需回填,也无需单独的闭合 PR。
@@ -0,0 +1,221 @@
# feature/norm-remediation-u6 任务卡
任务主记录:PR #624 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/624;状态:已完成(合入前闭合);owner:weichen
- 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= eef7e5e778cabcb6216f74b74213a3d7511f383b
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u6(worktree);分支:feature/norm-remediation-u6
- 分支类型:child;initiative_id:feature-norm-remediation;root_target:main;immediate_target:feature/norm-remediation;accepting_requirements:false;parent_branch:feature/norm-remediation;parent_head_sha:69174fcb6955f03d009dd83909da5a18373b1459;parent_pr:无;parent_source:origin
- 需求分流:免(父 initiative 子任务登记已列出 feature/norm-remediation-u6;parent_head_sha=69174fcb6955f03d009dd83909da5a18373b1459)
- 授权与交付终点:完成已批准 U6 的固定规范/执行器版本采纳、证据对账及最终组合验证,经 child PR 合入 initiative,随后 L1 最终交付 main。范围限两个治理 gitlink、policy/adoption.md、policy/guidelines-adoption.md,及最终同步时保留最新 main 的 PROJECT 主题/运行入口;不改平台保护、发布 tag、轮换凭据、部署或更新其他消费者。
- 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进)
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
- 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入)
- 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位)
## 目标与非目标
目标:将 Guidelines 固定到已审并合入 draft.14 `a15db5085585f199c3c399824f6cf24c3144bbd5`;DM 固定到修复原始单写者提示及 gitlink 准备缺口的已合入 `6c019595fa02aa2d0a1a9b8f98fc224e69d2a901`(#26/#27),纠正过时采纳说明,保留既有成功/四类负例来源,未执行的 Schema/平台/真实模型质量基准继续 NOT_RUN。执行器引导采用该已审/已测/已合入固定源码构建的既有 agent-exec,生成受控 transport;仍由现有 apply/admit 核验来源,不开放 host 代写或新路由。
DM #27 的 exact-head `2bf86c9` 双 CI build-test 通过;安全/正确性独立审阅及最终 `go test ./...`、controller race/vet 通过;最终 merge `6c019595`。上游规范 #11 的 Review/CI 与 merge 见 U7 卡。
## Agent 实施收据
路由与 fail-stop 规则见根目录 AGENT-EXECUTION.md 与 policy/delivery.md;每次尝试一行,原始日志留在源码外收据路径。
| 单元 ID | 预期范围 | 配置摘要 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|---|---|---|---|---|---|---|---|---|---|---|
| norm-u6-fixed-guidelines-executor-pins | two governance gitlinks | current config digest in receipt | implementation | cursor, agy, pi | 1 | cursor / auto | success | 97745ca3875f | 0 | /tmp/norm-u6-pins-receipt.json (bootstrap executor 6c019595) |
| norm-u6-reconcile-adoption-and-project-index | adoption records + main PROJECT compatibility | receipt | implementation | cursor, agy, pi | 1 | cursor / auto | success | 30f1ba7596ae | 0 | /tmp/norm-u6-adoption-docs-receipt.json |
| norm-u6-project-component-index-authority | single PROJECT component authority pointer | receipt | repair | cursor, agy, pi | 1 | cursor / auto | success | 847fb002225b | 0 | /tmp/norm-u6-project-components-authority-receipt.json |
## 同步记录
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|---|---|---|---|
| 启动 | eef7e5e778cabcb6216f74b74213a3d7511f383b | 69174fcb6955f03d009dd83909da5a18373b1459 | 2026-10-18T18:20:28Z |
## 证据(Evidence)
<!-- CMD="<命令>" make evidence 写入;手抄/转写输出视为无效证据(AGENTS.md 证据与验证门禁)。 -->
| 时间(UTC) | 命令 | 被测HEAD | exit | 来源 | sha256(16) |
|---|---|---|---|---|---|
## 结果与验证
- 结果:Guidelines pin=`a15db508`(draft.14),DM pin=`6c019595`;采纳文档区分源码/规则 active、manual/advisory 能力、历史成功/四负例及本次未执行项;过时 #602 引用改为已合入归档。PROJECT 同时保留 U5 简明索引和 main eef7e5e 的法规/SQLite 稳定入口,完整组件清单引用 .gitmodules。
- 验证:host 在 `847fb002225b2d15f3e49f26f39b537f6501ecb9` 物化固定嵌套依赖后运行配置校验、治理检查、test-pins、14 项入口/事实测试和 diff-check,全部通过(SELF receipt 已导入)。首次检查因新 Guidelines 嵌套 DM 未物化而停止的 exit=2 收据也保留,不计 PASS;非本次消费者旧规范 pin 仅产生既有警告,不升级其版本。独立 fresh Reviewer `u6_adoption_review` 批准上述精确对象,无阻塞项。
- 影响与剩余项:完整 `make test-governance`(包含在 make test)、`make test` 与 build 在 L1 同步最新 main 后的最终组合候选执行一次;本次 child 不重复旧业务组件组合的全套本地测试。新 PROJECT 的 main-only 目标需最终同步后验实;未宣称当前 child 中已存在。供应方容量/压缩和模型质量基准、额外 Schema/平台负例按采纳文档保持 NOT_RUN。
## 合入与清理
- Review 记录:独立 fresh review `u6_adoption_review`,session ID not-observable;base `69174fcb6955f03d009dd83909da5a18373b1459` / head `847fb002225b2d15f3e49f26f39b537f6501ecb9`;核对准确 pin/VERSION、上游合入对象、历史正负例 SELF 与新 NOT_RUN、能力等级和 PROJECT main 入口,无阻塞,APPROVE;独立重放 config/governance/diff 检查通过(只读本地结果,不冒充 GATE)。
- 冲突记录:NOT_RUN(最新目标同步、冲突处置、组合兼容核验及复审/补测)
- CI 记录:NOT_RUN(当前 HEAD 完整 SHA、全部必需检查、运行链接、执行身份及 GATE 结果)
- 合入记录:NOT_RUN(交付授权范围、PR、被核验 HEAD、合入 SHA、目标分支及内容核验)
- 清理记录:NOT_RUN(授权依据、写者退出确认、worktree/分支/任务卡处置)
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T18:19:20.152696+00:00",
"command": "make precheck",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev",
"before_head": "eef7e5e778cabcb6216f74b74213a3d7511f383b",
"after_head": "eef7e5e778cabcb6216f74b74213a3d7511f383b",
"branch": "main",
"target_branch": "main",
"target_head": "eef7e5e778cabcb6216f74b74213a3d7511f383b",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev'",
"[repo] branch=main head=eef7e5e778",
"[remote] origin/main=eef7e5e778 ahead=0 behind=0",
"[tree] clean submodules_drift=0 uninit=12",
"[warn] 12 个子模块未初始化——构建/测试前需物化(不阻断写入)",
"[worktrees] linked=7",
"[recycle] merged un-recycled branches: feature/layered-python-env",
"[initiatives] local cards (not authoritative): none",
"[hooks] core.hooksPath=scripts/hooks(pre-commit/post-merge 实际接线)",
"[facts] policy/facts.md 6 条事实均在有效期内",
"[required-reading] core/baseline.md, workflows/delivery.md §1, policy/delivery.md",
"[R0] eef7e5e778(完整:eef7e5e778cabcb6216f74b74213a3d7511f383b)",
"[worktree] before-sync: recursive component checks passed",
"[verdict] READY — 保留本次 precheck receipt 后建任务工作区:PRECHECK_RECEIPT=/tmp/task-precheck.json make task-start NAME=feature/your-branch",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev'"
],
"output_sha256": "8ebd14a4e8639e7dffb04336ad69df1bb8f80b36d3f9cf1c0875966b3503b3f4",
"receipt_sha256": "ff4d0e2ee43dc1cdc2dfbd9ae539ca52bf50fc650785f956d2682675838ad09a",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/ff4d0e2ee43dc1cdc2dfbd9ae539ca52bf50fc650785f956d2682675838ad09a.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T18:31:46.193016+00:00",
"command": "scripts/agent-exec validate --repo . && scripts/dm governance check --repo . && make test-pins && python3 -m unittest tests.test_agent_exec_entry tests.test_facts_verify && git diff --check 69174fc..HEAD",
"exit_code": 2,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u6",
"before_head": "847fb002225b2d15f3e49f26f39b537f6501ecb9",
"after_head": "847fb002225b2d15f3e49f26f39b537f6501ecb9",
"branch": "feature/norm-remediation-u6",
"target_branch": "main",
"target_head": "eef7e5e778cabcb6216f74b74213a3d7511f383b",
"root_target": "main",
"immediate_target": "feature/norm-remediation",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"ok file AGENTS.md",
"ok file PROJECT.md",
"ok file policy/guidelines-adoption.md",
"ok file .task/templates/task-card.md",
"ok executable scripts/agent-exec",
"ok executable scripts/hooks/pre-commit",
"ok executable scripts/dm",
"ok executable scripts/task",
"ok adoption status",
"ok fixtures",
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u6'",
"python3 scripts/check-worktree.py verify",
"ERROR: uninitialized submodule: /home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u6/deps/development-guidelines/deps/development-manager; initialize and inspect it first",
"make[1]: *** [Makefile:218: test-worktree] Error 1",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u6'"
],
"output_sha256": "86b91eefa0aaf1c11220b17fe27b7680052f09126eaae5d0189b09df55bbfb5d",
"receipt_sha256": "cfba7dee4b098b7c50441e488e99504bf19e7a1abdd595234c3cb465fc29ca27",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/cfba7dee4b098b7c50441e488e99504bf19e7a1abdd595234c3cb465fc29ca27.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T18:32:47.051092+00:00",
"command": "scripts/agent-exec validate --repo . && scripts/dm governance check --repo . && make test-pins && python3 -m unittest tests.test_agent_exec_entry tests.test_facts_verify && git diff --check 69174fc..HEAD",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u6",
"before_head": "847fb002225b2d15f3e49f26f39b537f6501ecb9",
"after_head": "847fb002225b2d15f3e49f26f39b537f6501ecb9",
"branch": "feature/norm-remediation-u6",
"target_branch": "main",
"target_head": "eef7e5e778cabcb6216f74b74213a3d7511f383b",
"root_target": "main",
"immediate_target": "feature/norm-remediation",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"ok deps/agent-squad agent-intent",
"ok deps/agent-squad agent-native",
"warn: deps/agent-squad deps/development-guidelines is 26b562d2e34f, Dev is a15db5085585",
"ok deps/agent-squad error-code-system",
"ok deps/agent-squad logging-system",
"warn: deps/agent-intent deps/development-guidelines is 26b562d2e34f, Dev is a15db5085585",
"ok deps/agent-intent error-code-system",
"ok deps/agent-intent logging-system",
"pins ok",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u6'",
"..............",
"----------------------------------------------------------------------",
"Ran 14 tests in 4.625s",
"",
"OK"
],
"output_sha256": "47156d314ddc13ab2b36beea736fdb08e4996834a5690fa64bfb0e21db838ba2",
"receipt_sha256": "079c7647661d7879b0f62d85d83af380ed49a06e1e9ff9896a81b62c2024fb03",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/079c7647661d7879b0f62d85d83af380ed49a06e1e9ff9896a81b62c2024fb03.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T18:34:28.257843+00:00",
"command": "make task-sync",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u6",
"before_head": "20c8fd00f6cfbb01c98c8d2ca298033b5fd26da3",
"after_head": "20c8fd00f6cfbb01c98c8d2ca298033b5fd26da3",
"branch": "feature/norm-remediation-u6",
"target_branch": "main",
"target_head": "eef7e5e778cabcb6216f74b74213a3d7511f383b",
"root_target": "main",
"immediate_target": "feature/norm-remediation",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u6'",
"[worktree] before-sync: recursive component checks passed",
"[worktree] before-update: recursive component checks passed",
"[worktree] materialize: recursive component checks passed",
"[worktree] after-sync: recursive component checks passed",
"[evidence] WARN JSON receipt line 59: unverified: recorded component state was not at its pinned SHA ——关键检查须重跑并以 make evidence 重新写入",
"[evidence] WARN JSON receipt line 100: unverified: recorded component state was not at its pinned SHA ——关键检查须重跑并以 make evidence 重新写入",
"[synced] sync_base=38c5b93b79a8f383dbb7d7883b26d8432355a52c tested_head=20c8fd00f6cfbb01c98c8d2ca298033b5fd26da3 checked_at=2026-10-18T18:34:54Z changed=0 sync_target=feature/norm-remediation",
"[next] 跑正式验收(make test 等),证据写入任务卡",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u6'"
],
"output_sha256": "993b6800959e6e1d6363c0e34341063609b849b4640b5be621f21fa353caeaf8",
"receipt_sha256": "197c71283d9201ea0d4870626e729a6a1fa441e25fa02272c99ac280fc6ff30d",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/197c71283d9201ea0d4870626e729a6a1fa441e25fa02272c99ac280fc6ff30d.json"
}
```
## 闭合记录(合入前折叠)
- 本卡在 PR #624(https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/624)合入前闭合并归档,随该 PR 一同合入。
- 该 PR 的合并提交即本任务的落地记录。
- 合入后无需回填,也无需单独的闭合 PR。
@@ -0,0 +1,216 @@
# feature/norm-remediation-u7 任务卡
任务主记录:PR #622 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/622;状态:已完成(合入前闭合);owner:weichen
- 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= eef7e5e778cabcb6216f74b74213a3d7511f383b
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u7(worktree);分支:feature/norm-remediation-u7
- 分支类型:child;initiative_id:feature-norm-remediation;root_target:main;immediate_target:feature/norm-remediation;accepting_requirements:false;parent_branch:feature/norm-remediation;parent_head_sha:c6fe5adba34d7266e7bcfbb9a2c64a0ae61e9b8e;parent_pr:无;parent_source:origin
- 需求分流:免(父 initiative 子任务登记已列出 feature/norm-remediation-u7;parent_head_sha=c6fe5adba34d7266e7bcfbb9a2c64a0ae61e9b8e)
- 授权与交付终点:用户追加并确认 U7:完善 subagent/CLI 的有界任务、容量规划、模型分工、阶段交接与测试要求;本子任务经 Review/CI 合入 initiative。范围限 `AGENT-EXECUTION.md`、`policy/delivery.md`;通用规则已由 Guidelines PR #11 合入,最终 pin/采纳归 U6。本任务不部署、不改平台或执行器架构。
- 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进)
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
- 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入)
- 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位)
## 目标与非目标
目标:工作包适合较小/未知容量模型,以一个可独立验证的结果、最小背景和明确验收派发;阶段完成自动持久交接,下一 CLI 会话全新,原生压缩仅在支持时可选;具体规划/执行模型偏好归项目本地配置,requested/effective/不可观测状态如实区分。未知容量使用 100K 显式规划假设,给实现/迭代/测试保留空间;不新增控制器、Schema 或失败门禁。
共享基线:Guidelines PR #11,merge `a15db5085585f199c3c399824f6cf24c3144bbd5`(draft.14);独立 Review、schema/config 校验与 CI run 3978 均通过。正文/模板和 Review 修复 transport 分别见 `/tmp/guidelines-u7-receipt.json`、`/tmp/guidelines-u7-review-repair-receipt.json`;worker 私有索引 intent-to-add 曾被撤销,为执行偏差,不证明提示具备工具强制力。
## Agent 实施收据
路由与 fail-stop 规则见根目录 AGENT-EXECUTION.md 与 policy/delivery.md;每次尝试一行,原始日志留在源码外收据路径。
| 单元 ID | 预期范围 | 配置摘要 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|---|---|---|---|---|---|---|---|---|---|---|
| norm-u7-dev-bounded-cli-routing | AGENT-EXECUTION.md + policy/delivery.md | caefcb72 (prior config) | implementation | cursor, agy, pi | 1 | cursor-agent-stable / auto | success | e16a75c5111c | 0 | /tmp/norm-u7-dev-receipt.json |
| norm-u7-dev-independent-review | independent fixed-diff/config review | run receipt | review | pi, agy, cursor, codex | 1 | pi / minimax-cn/MiniMax-M3 (actual event) | success | 892cf59c5075 | 0 | /tmp/norm-u7-dev-review-receipt.json |
## 同步记录
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|---|---|---|---|
| 启动 | eef7e5e778cabcb6216f74b74213a3d7511f383b | c6fe5adba34d7266e7bcfbb9a2c64a0ae61e9b8e | 2026-10-18T17:35:52Z |
## 证据(Evidence)
<!-- CMD="<命令>" make evidence 写入;手抄/转写输出视为无效证据(AGENTS.md 证据与验证门禁)。 -->
| 时间(UTC) | 命令 | 被测HEAD | exit | 来源 | sha256(16) |
|---|---|---|---|---|---|
## 结果与验证
- 结果:共享有界工作包与交接标准已合入 Guidelines PR #11(draft.14);本仓补齐工作包最小信息、100K 保守假设、阶段交接和 requested/effective 区分。PI 请求已明确为 `minimax-cn/MiniMax-M3`,独立 Review 实际事件也报告同 provider/model;Cursor auto,agy Flash 偏好保持 NOT_VERIFIED。普通上下文压力不触发扩围停止;无自动压缩或未知容量不阻断其他授权工作。
- 验证:host 在 `e16a75c5111c861afea11458194ac308f81ca99a` 运行配置校验、6 项 agent-exec 入口测试与 diff-check 均通过(SELF);独立 fresh PI Review 重放固定 diff/配置,无阻塞 finding。两个 CLI run 均为新进程和独立隔离工作区,未使用 resume/continue;session ID 未单独提取时记 not-observable,独立性依据 run/attempt 及新进程,不伪造 ID。
- 影响与剩余项:U6 才推进 Guidelines pin/采纳记录;当前旧 pin 不宣称已经采用 draft.14。未知/已知容量例子是规范一致性检查,不证明实际模型最大容量或质量提升;同任务真实模型前后质量基准 NOT_RUN(本次交付是规范与配置,未建设评测平台,也未宣称质量提升的实测数值)。端点/登录/压缩与并发强制能力均不作无证据断言。
## 合入与清理
- Review 记录(stage=review,fresh_session=true,model=minimax-cn/MiniMax-M3 as configured for PI,session ID=not-observable):独立 Review session;base=c16665365bbbf3b733b034628f102db90d985637;head=e16a75c5111c861afea11458194ac308f81ca99a;范围限 diff AGENT-EXECUTION.md + policy/delivery.md。
- 命令与对象:`git diff c16665365bbbf3b733b034628f102db90d985637..e16a75c5111c861afea11458194ac308f81ca99a -- AGENT-EXECUTION.md policy/delivery.md` → 98 行差异(AGENT-EXECUTION.md +41/-3,policy/delivery.md +24/-0);`scripts/agent-exec validate --repo .`(deps/development-manager 未初始化,回退到精确钉住 dm 二进制 `$HOME/.cache/agent-system-dev/agent-exec/dm-server-67784f43eb0430bf596c2cda685cbb4946d2e032` 与 index 钉住 `67784f43eb0430bf596c2cda685cbb4946d2e032` 完全一致;未写规范仓;binary version=0.1.0-dev)→ `validate: ok`,exit=0。
- 结论:无 blocker。机器块(`execution.fallback_to_host=never`、`max_attempts_per_profile=3`、`emergency_profile=codex`、`roles.implementation/repair/test/review` 候选顺序、超时/输出字节)逐项与 base 一致;PI `model` 由 `auto` 改为显式 `minimax-cn/MiniMax-M3`,Cursor 保持 `auto`,agy 保持 `auto` 并在 prose 明示 Gemini 3.8 Flash 为 `NOT_VERIFIED`(未观测模型 ID,未声称生效);新增 prose 段只描述本仓做法并显式声明「本节不新增门禁,不放宽凭据、范围、未知副作用与 CI 边界」与「Role lists, attempt limits, timeouts, output limits, the single Codex emergency attempt, stage isolation and fallback_to_host: never are unchanged」。
- 观测性:`requested` 模型是提示/配置意图,`effective` 以运行事件信封为准,CLI 不报告时记 `not-observable`;未知容量、agy 缺登录、缺自动压缩均登记事实,不作为全局 fail-close(仅真实扩围走既有 `scope-expansion` fail-stop)。现有 scope/credential/unknown-side-effect fail-stops 未删未弱。
- 单元包/容量:bounded packet JSON 的 `goal/constraints/verification` 已含一个结果与验收、允许路径、最小必读、前置 SHA、直接验证命令、未知容量按保守 100K 假设并为执行留余量;100K/200K/300K/500K 仅为规划参考,未声明任何 provider 能力;不新增 schema/字段/控制器。
- 阶段交接:里程碑持久交接写入既有任务记录,下一 CLI 阶段或单元以全新会话启动,只读交接与最小必读,不为交接等人工。
- 上下文压力:仅在 provider 支持且阶段完成后做上下文压缩;不支持不阻塞;普通压力走交接 + host 重新打包。
- 非阻塞观察(不阻塞交付):`AGENT-EXECUTION.md`/`policy/delivery.md` 中新增的相对链接指向 `deps/development-guidelines/standards/agent-execution.md` 与 `deps/development-guidelines/workflows/handoff.md`;当前 `deps/development-guidelines` gitlink 仍为 `2688fd2be6a52c0bf110e7e6366b6f291ab5e4eb`(未在 U7 范围 bump),文件存在与否须 U6 pin 时再核,prose 未声称当前 pin 已采纳 Guidelines PR #11(merge `a15db5085585f199c3c399824f6cf24c3144bbd5`),仅引导后续采纳。`policy/delivery.md` 锚 `#有界单元包上下文与阶段交接` 与新章节 `### 有界单元包、上下文与阶段交接` 在 GFM 风格锚归一化(移除中文标点)下等价。`agy` 段仅将「Gemini 3.8 Flash」记为请求,未声明能力,符合「不发明模型能力」要求。
- 不主张 CI 通过;未运行任何 live API/模型探测;未改 source/config/index/refs;未开 PR/部署/派遣同伴。审阅者身份:本独立 session(PI / minimax-cn/MiniMax-M3,session ID not-observable,stage=review)。重放依据:`git rev-parse HEAD` 与 `git ls-files -s deps/development-manager` 即可复现。
- 冲突记录:已同步包含 U4 的 initiative `825e4fc`,无冲突;U7 代码/配置相对已审实现 `e16a75c` 未再改变。host 在合成 head `3da20d4` 校验配置并重放入口+事实测试 14 项,均通过(SELF,receipt 已导入),未重跑与此无关的完整套件。
- CI 记录:NOT_RUN(当前 HEAD 完整 SHA、全部必需检查、运行链接、执行身份及 GATE 结果)
- 合入记录:NOT_RUN(交付授权范围、PR、被核验 HEAD、合入 SHA、目标分支及内容核验)
- 清理记录:NOT_RUN(授权依据、写者退出确认、worktree/分支/任务卡处置)
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T17:34:44.780514+00:00",
"command": "make precheck",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev",
"before_head": "eef7e5e778cabcb6216f74b74213a3d7511f383b",
"after_head": "eef7e5e778cabcb6216f74b74213a3d7511f383b",
"branch": "main",
"target_branch": "main",
"target_head": "eef7e5e778cabcb6216f74b74213a3d7511f383b",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev'",
"[repo] branch=main head=eef7e5e778",
"[remote] origin/main=eef7e5e778 ahead=0 behind=0",
"[tree] clean submodules_drift=0 uninit=12",
"[warn] 12 个子模块未初始化——构建/测试前需物化(不阻断写入)",
"[worktrees] linked=7",
"[recycle] merged un-recycled branches: feature/layered-python-env",
"[initiatives] local cards (not authoritative): none",
"[hooks] core.hooksPath=scripts/hooks(pre-commit/post-merge 实际接线)",
"[facts] policy/facts.md 6 条事实均在有效期内",
"[required-reading] core/baseline.md, workflows/delivery.md §1, policy/delivery.md",
"[R0] eef7e5e778(完整:eef7e5e778cabcb6216f74b74213a3d7511f383b)",
"[worktree] before-sync: recursive component checks passed",
"[verdict] READY — 保留本次 precheck receipt 后建任务工作区:PRECHECK_RECEIPT=/tmp/task-precheck.json make task-start NAME=feature/your-branch",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev'"
],
"output_sha256": "8ebd14a4e8639e7dffb04336ad69df1bb8f80b36d3f9cf1c0875966b3503b3f4",
"receipt_sha256": "595376851618682c9df8e7c637c465e9950237249d07bf36ea0726026961fe06",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/595376851618682c9df8e7c637c465e9950237249d07bf36ea0726026961fe06.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T17:39:09.639625+00:00",
"command": "scripts/agent-exec validate --repo . && python3 -m unittest tests.test_agent_exec_entry && git diff --check",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u7",
"before_head": "e16a75c5111c861afea11458194ac308f81ca99a",
"after_head": "e16a75c5111c861afea11458194ac308f81ca99a",
"branch": "feature/norm-remediation-u7",
"target_branch": "main",
"target_head": "eef7e5e778cabcb6216f74b74213a3d7511f383b",
"root_target": "main",
"immediate_target": "feature/norm-remediation",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"validate: ok",
"......",
"----------------------------------------------------------------------",
"Ran 6 tests in 0.389s",
"",
"OK"
],
"output_sha256": "8fde6c3d2592daa001b2e9856870a9725c40bcd8c52e7e56c58852005c56eab7",
"receipt_sha256": "1478aa40c6d51ff8198bf6517ba5fa4a7fd51f33a7112d52057e771f346cf248",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/1478aa40c6d51ff8198bf6517ba5fa4a7fd51f33a7112d52057e771f346cf248.json"
}
```
| 同步(记录前对象) | 825e4fc98f30da4950a48d15d59f5338206726bf | 66696bfc436a4adadf70fe7ecfc6ab4cda631d65 | 2026-10-18T17:48:16Z |
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T17:47:48.776787+00:00",
"command": "make task-sync",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u7",
"before_head": "2de3d398ccc1db9d235238016a12755b4ea989f2",
"after_head": "3da20d47b5a4a0732effad4992daf17acd2af944",
"branch": "feature/norm-remediation-u7",
"target_branch": "main",
"target_head": "eef7e5e778cabcb6216f74b74213a3d7511f383b",
"root_target": "main",
"immediate_target": "feature/norm-remediation",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
" policy/facts.md | 9 +-",
" scripts/facts-verify.sh | 79 ++++++",
" tests/test_facts_verify.py | 399 +++++++++++++++++++++++++++",
" 4 files changed, 746 insertions(+), 2 deletions(-)",
" create mode 100644 .task/archive/feature-norm-remediation-u4.md",
" create mode 100644 tests/test_facts_verify.py",
"[worktree] before-update: recursive component checks passed",
"[worktree] materialize: recursive component checks passed",
"[worktree] after-sync: recursive component checks passed",
"admit: ok",
"[evidence] WARN JSON receipt line 66: unverified: recorded component state was not at its pinned SHA ——关键检查须重跑并以 make evidence 重新写入",
"[evidence] WARN JSON receipt line 107: recorded HEAD predates non-card changes ——关键检查须重跑并以 make evidence 重新写入",
"[synced] sync_base=825e4fc98f30da4950a48d15d59f5338206726bf tested_head=3da20d47b5a4a0732effad4992daf17acd2af944 checked_at=2026-10-18T17:48:16Z changed=1 sync_target=feature/norm-remediation",
"[next] 跑正式验收(make test 等),证据写入任务卡",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u7'"
],
"output_sha256": "0397ae866aa211d57b600b60355563e5dc4ebb1d09569ef0cc607dfbe5bd1f27",
"receipt_sha256": "bcb38dab3f750867a93de90576aa0d39f7fd0501fb0557c085a6d26cf1a29779",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/bcb38dab3f750867a93de90576aa0d39f7fd0501fb0557c085a6d26cf1a29779.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T17:49:37.631093+00:00",
"command": "scripts/agent-exec validate --repo . && python3 -m unittest tests.test_agent_exec_entry tests.test_facts_verify && git diff --check",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u7",
"before_head": "3da20d47b5a4a0732effad4992daf17acd2af944",
"after_head": "3da20d47b5a4a0732effad4992daf17acd2af944",
"branch": "feature/norm-remediation-u7",
"target_branch": "main",
"target_head": "eef7e5e778cabcb6216f74b74213a3d7511f383b",
"root_target": "main",
"immediate_target": "feature/norm-remediation",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"validate: ok",
"..............",
"----------------------------------------------------------------------",
"Ran 14 tests in 4.466s",
"",
"OK"
],
"output_sha256": "0abf86ce43ea39bd4b51a9be1a3ca8bc47531f3e75e13af28f7f1f4d6452bc19",
"receipt_sha256": "3fb74abf04253157034696850c14561fdee89c6a47e3da22aaea6a5ef419ef70",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/3fb74abf04253157034696850c14561fdee89c6a47e3da22aaea6a5ef419ef70.json"
}
```
## 闭合记录(合入前折叠)
- 本卡在 PR #622(https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/622)合入前闭合并归档,随该 PR 一同合入。
- 该 PR 的合并提交即本任务的落地记录。
- 合入后无需回填,也无需单独的闭合 PR。
+507
View File
@@ -0,0 +1,507 @@
# feature/norm-remediation 任务卡
任务主记录:PR #616 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/616;状态:已完成(合入前闭合);owner:weichen
## 基线与授权
- 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= b5e23daed2f0ea46261979de1d62e4de0cfa88f9
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation(worktree);分支:feature/norm-remediation
- 分支类型:initiative;initiative_id:feature-norm-remediation;root_target:main;immediate_target:main;accepting_requirements:false
- 需求分流:verdict=NEW;selected_initiative=无;requirement_sha256=2342cdada7570c731d5c3216b74fbb55d85946b63d72974f3de29b45e5052a90;triage_receipt=/tmp/norm-remediation-implementation-triage-20261018.json;receipt_sha256=bb4542a99bda1327e47c56c451f36cade62ffada4ab84b878dcf3865ce1a2401
- 授权与交付终点:2026-10-18 用户选择开始实施已审查计划,并追加确认 U7,授权按 U1-U7 完成规范整改及必要缺陷修复、PR/CI/合入/收口。未授权:修改平台分支保护、发布不可移动版本 tag、轮换凭据、V3 指标复测 M、扩展到其他消费者仓库。
- 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进)
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
- 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入)
- 人工决策点:仅限目标/范围/验收变更、重大取舍、高后果操作或无法自动判定的业务验收
- 当前阶段:U1-U7 全部完成;已同步 main `eef7e5e778cabcb6216f74b74213a3d7511f383b`,固定代码候选 `f52df0e2e6bd52d1b60989ac079826787fef3307` 已通过独立 Review、本地分段组合检查与构建。当前只整理任务元数据、合入前闭合并冻结最终 PR HEAD,随后核验该 HEAD 的三项必需 CI、合入与安全收口。
- 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位)
## 目标与非目标
目标:完成计划 U1-U6,使 Development-Guidelines 只定义可复用的交付原则,Dev 保留自己的分支/命令/证据细节,并允许已授权、工作区安全的既有任务在远端暂不可用时有限本地续作,同时保持新任务启动和正式交付的严格远端门禁。
非目标:重做已合入 V3 P1-P3;执行两周指标复测 M;改变分支保护、自动合入或凭据管理;更新其他规范消费者。
方案/计划:仓库根目录 `docs/superpowers/plans/2026-10-18-0849-fix-development-norm-remediation-plan.md`(与源计划工作区正文逐字一致的已批准快照;原始工作区文件未改动,交付后以仓内版本为准)。U1 已在 Development-Guidelines PR #10 合入 `5b72099`;U7 共享规则由 #11 合入 `a15db508`;DM #26/#27 已合入 `6c019595`。U2-U7 均通过子 PR 集成;本 L1 已完成 main 同步及本地组合覆盖,最终 HEAD CI 与合入仍待核验。
分级验证:U1 文档改动核对链接、职责归属、版本/迁移记录与规则强度;U2-U5 运行受影响治理/事实验证的聚焦测试;U6 运行 `make test-governance` 与 `make test`,最终 PR 仍须当前 HEAD 独立 Review 和完整 CI。
验收:R1-R10 全部满足;LOCAL_READY 不得被提升为 READY/REPLAY/GATE;未知副作用、未授权、扩围、不安全共享工作区和未对账 Git 状态仍停;Guidelines 已合入,Dev pin 与采纳记录匹配其 SHA,组合验证及当前 HEAD CI 通过。
生命周期:接纳新需求关闭(`accepting_requirements=false`);只执行下列已登记子任务。所有必需子任务完成或显式延期后,再同步 main、冻结候选并执行整体 Review/CI/合入。
## 子任务登记
| 子任务分支 | 必需 | 状态 | PR |
|---|---|---|---|
| feature/norm-remediation-u2 | 是 | 已合入 | #618 |
| feature/norm-remediation-u3 | 是 | 已合入 | #620 |
| feature/norm-remediation-u4 | 是 | 已合入 | #621 |
| feature/norm-remediation-u5 | 是 | 已合入 | #623 |
| feature/norm-remediation-u6 | 是 | 已合入 | #624 |
| feature/norm-remediation-u7 | 是 | 已合入 | #622 |
## Agent 实施收据
路由与 fail-stop 规则见根目录 AGENT-EXECUTION.md 与 policy/delivery.md;每次尝试一行,原始日志留在源码外收据路径。
| 单元 ID | 预期范围 | 配置摘要 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|---|---|---|---|---|---|---|---|---|---|---|
| U1-U7 | 各 child 卡及共享仓 PR 中的有界单元 | 各归档卡逐次记录 | implementation/repair | 依运行配置 | 见子卡 | 见子卡 requested/effective | completed | 见子卡 | 见子卡 | `.task/archive/feature-norm-remediation-u2.md` 至 `u7.md`;共享仓 #10/#11、DM #26/#27 |
| final-governance-pin-check | scripts/check-pins.sh、tests/test_check_pins.py | 原始收据记录配置 digest | repair | cursor, antigravity, pi | 以原始收据为准 | 以原始事件为准 | completed | f52df0e2e6bd52d1b60989ac079826787fef3307 | false | /tmp/norm-final-governance-pin-check-receipt.json |
## 关联方向与规划
- 适用状态:已批准实施
- 主记录路径/版本:docs/superpowers/plans/2026-10-18-0849-fix-development-norm-remediation-plan.md
- 对应里程碑:U1-U6;Guidelines U1 PR #10 first, followed by Dev U2-U6 integration
## 需求分析
| ID | 描述 | 项目符合度及依据 | 优先级 | 验收条件 | 依赖 | 结论 |
|---|---|---|---|---|---|---|
| R1-R10 | 见关联计划的 Product Contract | Dev 实施 U2-U6;U1 在 Development-Guidelines | P1/P2(按计划) | 满足计划 R1-R10、U1-U6 与 Definition of Done | U1 precedes U2-U6; U5/U6 have declared dependencies | 用户已确认范围 |
## 方案与计划
- 方案引用:规范审查报告与用户确认的风险分层方案;U1 preserves remote startup and formal delivery gates.
- 实施计划引用:docs/superpowers/plans/2026-10-18-0849-fix-development-norm-remediation-plan.md (U1-U6)
- 测试计划引用:计划 Verification Contract;U1 文档检查、U2-U5 focused governance tests、U6 governance + combination tests
## 阶段记录
| 阶段 | 对象版本 | 状态 | 决策/执行者 | 时间 | 依据 |
|---|---|---|---|---|---|
| 需求拆解 | 用户批准计划 | 完成 | host | 2026-10-18 | 规范整改计划 |
| 需求评估 | Dev `b5e23da` / Guidelines `6c8e6cd` | 完成 | host | 2026-10-18 | 源码与启动状态核验 |
| 需求表确认 | R1-R10 | 完成 | 用户 | 2026-10-18 | 用户选择 Start ce-work |
| 方案设计 | KTD1-KTD8 | 完成 | host | 2026-10-18 | 见计划 |
| 实施计划 | U1-U6 | 完成 | host | 2026-10-18 | U1 Guidelines PR #10 先合入 |
| 实施与自检 | U1-U7 / f52df0e | 完成 | host + configured workers | 2026-10-18 | 全部 child 已合入;共享规范及执行器已固定采纳 |
| 正式测试与验收 | f52df0e | 本地分段覆盖完成;最终 GATE 待核验 | host / CI | 2026-10-18 | 原始失败及成功续跑收据见 Evidence;不声明单次全量成功 |
| 代码 Review | eef7e5e..6b58060;6b58060..f52df0e | 无阻塞 | final_norm_correctness_review / final_norm_security_review | 2026-10-18 | 全新独立审阅;增量正确性重放 5 项通过 |
| 合入 | 待定 | 待执行 | — | — | — |
| 合入核验与收口 | 待定 | 待执行 | — | — | — |
## 探索试验与迭代
| 增量/试验 | 假设 | 范围 | 判断和停止条件 | 授权/决策依据 | 结果 | 变更影响 | 需重审补测 |
|---|---|---|---|---|---|---|---|
| 待定义 | — | — | — | 待核对 | NOT_RUN | 待评估 | 待评估 |
## 同步记录
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|---|---|---|---|
| 启动 | b5e23daed2f0ea46261979de1d62e4de0cfa88f9 | b5e23daed2f0ea46261979de1d62e4de0cfa88f9 | 2026-10-18T09:24:52Z |
## 证据(Evidence)
<!-- CMD="<命令>" make evidence 写入;手抄/转写输出视为无效证据(AGENTS.md 证据与验证门禁)。 -->
| 时间(UTC) | 命令 | 被测HEAD | exit | 来源 | sha256(16) |
|---|---|---|---|---|---|
## 交付调度
- 调度状态:最终窗口进行中;调度记录:Issue #518 评论 7605(前窗口 7602 已由 7604 释放)
- entry_id:norm-remediation;attempt_id:mq-dev-20261018-norm-remediation-final-02;窗口执行者:当前主协调智能体 / weichen
- 固定候选:base `eef7e5e778cabcb6216f74b74213a3d7511f383b`;代码 `f52df0e2e6bd52d1b60989ac079826787fef3307`;后续只改任务元数据,最终 HEAD 以 PR/CI 为准。手动窗口不代表原子锁或工具级单写者保证。
- 调度依据:policy/delivery.md#合入调度
- 固定后证据:源码外 RECEIPT;实际结果后按授权原样导入和闭合
## 结果与验证
- 结果:U1-U7 全部集成。共享规范只保留通用原则,Dev 保留具体流程/命令/模型偏好;LOCAL_READY 支持安全的既有授权任务局部续作,不替代正式远端门禁。上下文不足、缺自动压缩或模型身份不可观测不成为全局 fail-close;未知副作用、秘密、授权、未对账 Git 等安全边界保留。
- 验证:首次组合尝试在治理 DM pin 误分类处 FAIL;最小修复及 5 个真实 Git 正负例 PASS。修复后的组合尝试完成 513 项治理检查(18 skip)、架构、pin、库及 Core 检查,在 Backend 权限负例因当前 umask 0077 不满足其 0644 前提而 FAIL。源码未变,显式 umask 022 后该用例、完整 Backend/Frontend/UI/agent-command 及 build PASS;仅复用同一代码对象上此前已通过的五个 make 目标,不虚报整条失败命令成功。权威结论仍等待最终 PR HEAD 的完整 CI。
- 影响与剩余项:没有部署、发布 tag 或修改分支保护。agy 精确模型 ID/有效模型、平台自动压缩能力与真实模型质量前后基准为 NOT_VERIFIED/NOT_RUN;不声称已自动压缩或实测质量提升。原始脏计划工作区和安全拒绝删除的跨仓子模块 worktree 保留。
## Post-Deploy Monitoring & Validation
No additional operational monitoring required:本次仅规范、治理脚本与固定工具采纳,不改变业务运行时,也不部署;后续治理启动/恢复与 CI 继续使用现有检查入口观察结果。
## 规划进展与下一步
- 本次推进/剩余:U1-U7、main 同步、独立 Review 及本地组合覆盖完成。余下仅任务卡闭合、最终精确 HEAD CI、PR #616 合入/核验及安全回收。
- 首选下一任务:完成本任务既定交付,不启动新的完善增量。
### 阶段交接(2026-10-18;U2/U3 完成,U4/U7 在途)
以下为该阶段历史快照;最新状态以本卡「当前阶段」「子任务登记」及后面的收口交接为准,不重启已完成的运行。
- 目标/授权:继续 U1-U7;保持未知副作用、权限、范围、秘密及正式交付边界;不部署、不改保护或发布 tag。
- 唯一计划正文:`/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-plan/docs/superpowers/plans/2026-10-18-0849-fix-development-norm-remediation-plan.md`(仍为该工作区中的既有未提交文件,不覆盖或丢弃)。父 PR #616 的目标为 main。
- U4 工作区:`/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u4`,分支同名后缀;首轮 transport `7e0b0e4`,6 项离线事实测试、syntax/diff 检查通过,SELF 已入卡。当前 head `9b29e0f` 是元数据提交。
- U4 在途 repair:`/tmp/norm-u4-credential-boundary-repair.json` → `/tmp/norm-u4-credential-boundary-repair-receipt.json`;仅封闭新 F2 探针的目标与重定向边界、补负例,及说明 F4 原日期未被新探针重验。首轮 receipt `/tmp/norm-u4-facts-receipt.json`;外部 worker 与 transport 独立,host 不直接实施。
- U7 共享工作区:`/home/weichen/projects/Development-Guidelines-wt-feature-bounded-agent-work`,分支 `feature/bounded-agent-work`,基线为最新 Guidelines main `5b72099`。远端 triage NEW 收据 `/tmp/guidelines-u7-triage.json`;共享 task-start 因规范源无消费者模板而未写入,使用已核验基线建立普通 worktree。过程记录归本卡,不进 Guidelines。
- U7 在途 worker:packet `/tmp/guidelines-u7-packet.json`,receipt `/tmp/guidelines-u7-receipt.json`;仅 Agent 标准、交接流程、工作包模板、VERSION/CHANGELOG,供应商无关,不新增控制器或 Schema。
- 模型观察:PI 已有运行事件报告 `minimax-cn / MiniMax-M3`;agy 模型列表因未登录不可核验。Dev U7 须分开 requested/effective/unobservable,不声称 agy Gemini 偏好已可用;保留已有候选和无 host fallback 边界。
- 下一步:收取两个外部运行终态→审阅实际 diff→受控 apply→聚焦检查;U4 安全/目标负例及必要治理测试、fresh 独立 Review、child PR exact-head CI 后合入。U7 共享标准经 Review/CI 合入后,Dev 采纳其固定 SHA 和项目偏好。不要覆盖未结束执行器运行,不在 failed-unknown 后自动重放。
- 证据/外部状态:本节为协调摘要(SELF),不替代执行器收据、evidence 或 GATE;没有部署或共享业务写入。任务/测试/Review/CI 各自状态分别记录。
### 收口交接(2026-10-18;U4/U7 已合入)
本节为当时快照;U5、DM #27 与 U6 的最新进展见下方最终候选交接,不恢复已结束 run。
- 已合入:U4 #621(head `4b718344`,merge `825e4fc`),8 项离线事实用例及 503 项治理测试(18 skip)、独立 PI Review、exact-head CI;U7 #622(head `f61c53e7`,merge `2ce6bc9`),配置校验、6 项入口检查及同步 U4 后 14 项组合聚焦检查、独立 PI Review、exact-head CI。完整命令证据在各归档卡/仓外 receipt,不以本摘要代替。
- 共享 U7:Guidelines #11 已合入 `a15db5085585f199c3c399824f6cf24c3144bbd5`(draft.14),独立 Review + CI run 3978;上下文压力与 scope-expansion 混用已修复,不新增 fail-close。Dev 最终 pin/采纳仍归 U6。
- U5:`Agent-System-Dev-wt-feature-norm-remediation-u5`,实现候选 `1b04fd4a0408931bb84c44c2fe692205ff25079f`;只改 AGENTS/PROJECT,修复 LOCAL_READY 与分级证据摘要冲突;`/tmp/norm-u5-independent-review-receipt.json` 是在途独立 Review 收据,不在运行期修改该规范检出。
- U6 直接阻塞:旧 cloneAttempt 不物化子模块,worker 又禁止 init/update/改父仓索引,无法按既有契约更新 gitlink。仅修共享执行器准备步骤,不新建架构/Schema/路由。DM 工作区 `/home/weichen/projects/Development-Manager-wt-fix-agent-exec-gitlink-preparation`,分支 `fix/agent-exec-gitlink-preparation`,基线 `b178dec`;首次 transport `b5098bc` 的真实临时仓库测试覆盖 transport/未声明模块/宿主不变/拒绝场景。
- DM 在途修复:`/tmp/dm-gitlink-worktree-compatibility-repair.json` → `/tmp/dm-gitlink-worktree-compatibility-receipt.json`,补实际 linked-worktree metadata 位置及活动 index.lock 回归。首轮 receipt `/tmp/dm-gitlink-preparation-receipt.json`;完整 agent-exec suite 需在物化固定 Guidelines 的 host 工作区、测试子进程常规 umask 下重放,worker 隔离样例缺失/umask 负例的失败不可算 PASS。
- 下一步:完成 U5 独立 Review/检查/child PR CI/合入;完成 DM 最小修复、独立安全/正确性 Review、当前 HEAD CI/合入;U6 用已审核固定执行器受控生成 pin 升级 transport(记录 requested/effective 执行器 SHA),经现有 apply/admit 核验,再固定 Guidelines/DM SHA、纠正采纳记录并进行一次最终完整组合验证。最终 initiative main 窗口前同步最新 main、Review、完整必需 CI、PR #616 合入及安全收口。
- 无部署、无保护变更、无 tag 发布;未知副作用/未对账状态仍停止,其他授权工作继续。本节为协调摘要 SELF。
### 最终候选交接(2026-10-18)
- U5 #623 已合入 `69174fcb6955f03d009dd83909da5a18373b1459`,最终 head `68233fd5` CI 通过;独立 PI Review 无阻塞,两个入口实际差异与主记录/链接检查已保存。U4/U5/U7 的已合入任务 worktree/本地远端分支均经 task-finish 安全回收,仅删除已确认 Python 字节码缓存。
- DM 修复 #27 已合入 `6c019595fa02aa2d0a1a9b8f98fc224e69d2a901`,最终候选 `2bf86c9` 的 push/PR build-test CI success;代码 `910425e` 的全 Go 测试、controller race/vet 通过,安全与正确性两位独立 reviewer 关闭所有阻塞。原始及后续小修 packet/receipt `/tmp/dm-gitlink-*` 保留,不重放已完成运行。
- U6 工作区 `/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation-u6`,parent head `69174fc`;两项 pin 经新固定执行器 `6c019595` 引导运行、旧 apply 校验后由 transport `97745ca` 成功集成(receipt `/tmp/norm-u6-pins-receipt.json`)。Guidelines=`a15db508` draft.14;DM=`6c019595`;host 物化后配置/治理检查全部 ok。
- U6 采纳文档 transport `30f1ba7`(receipt `/tmp/norm-u6-adoption-docs-receipt.json`)已集成:两份采纳文档纠正版本和 #602 历史证据,PROJECT 预先保留 main eef7e5e 的法规组合/SQLite 入口且不复制动态 pin。当前在途 `/tmp/norm-u6-project-components-authority-receipt.json` 仅将 PROJECT 开头硬编码组件清单改为指向 .gitmodules(main 新增 renderer);不要在 worker 运行期间改该规范检出。
- 最终 main 当前已核验 `eef7e5e778cabcb6216f74b74213a3d7511f383b`;只读 merge-tree 预检原来仅 PROJECT.md 文档冲突。U6 PROJECT 已由 worker 准备同时保留 main 新入口与 U5 简明索引的语义结果;L1 最终窗口再次核验冲突集,仅在仍只有该文档冲突时可用已审预制结果集成,其余路径正常合并。绝不丢弃 main 的业务/组件变化,最终物化 main 新组件后一次完整组合验证。
- 下一步:U6 剩余小修终态→受控 apply→固定 pin/采纳/PROJECT 独立 Review 与聚焦校验→child PR/CI/合入;父卡子任务全部标已合入、领取 #518 main 窗口→同步最新 main并核对语义→最终 Review/完整 make test+build、全部必需 CI→PR #616 合入/核验/回收。真实供应方容量/压缩与模型质量前后基准仍 NOT_RUN,不能宣称已自动执行或已实测提升。
- 推荐依据:待填写
- 前置条件/待确认:待核对
- 预期产物/验收条件:待定义
- 重复任务核对:待核对(已有/在途任务、PR 与规划记录)
- 启动授权:未授权(建议不自动启动新任务,仍须明确授权)
## 合入与清理
- Review 记录:全新独立 final_norm_correctness_review 与 final_norm_security_review 审阅 `eef7e5e..6b58060`,无阻塞;前者独立重放恢复/evidence 84 项,后者事实探针 8 项。二者随后对 `6b58060..f52df0e` 两文件增量 APPROVE,前者重放新增 5 项通过。源码外会话身份 not-observable;不是 CI GATE。后续仅任务元数据变化时核对 non-task diff 为空。
- 冲突记录:同步 main `eef7e5e` 唯一冲突 PROJECT.md,使用已由 U6 worker 预制并独立审阅的语义合并结果,保留 main 法规/SQLite/renderer 入口及 U5 精简索引。实际合并和只读 merge-tree 的 PROJECT 内容一致;业务 modules、Makefile、workflow、.gitmodules 与 main 一致。同步及物化已完成,后续组合覆盖见 Evidence。
- CI 记录:NOT_RUN(当前 HEAD 完整 SHA、全部必需检查、运行链接、执行身份及 GATE 结果)
- 合入记录:NOT_RUN(交付授权范围、PR、被核验 HEAD、合入 SHA、目标分支及内容核验)
- 清理记录:NOT_RUN(授权依据、写者退出确认、worktree/分支/任务卡处置)
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T09:24:17.082155+00:00",
"command": "make precheck",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev",
"before_head": "b5e23daed2f0ea46261979de1d62e4de0cfa88f9",
"after_head": "b5e23daed2f0ea46261979de1d62e4de0cfa88f9",
"branch": "main",
"target_branch": "main",
"target_head": "b5e23daed2f0ea46261979de1d62e4de0cfa88f9",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev'",
"[repo] branch=main head=b5e23daed2",
"[remote] origin/main=b5e23daed2 ahead=0 behind=0",
"[tree] clean submodules_drift=0 uninit=3",
"[warn] 3 个子模块未初始化——构建/测试前需物化(不阻断写入)",
"[worktrees] linked=10",
"[recycle] merged un-recycled branches: feature/layered-python-env",
"[initiatives] local cards (not authoritative): none",
"[hooks] core.hooksPath=scripts/hooks(pre-commit/post-merge 实际接线)",
"[facts] policy/facts.md 6 条事实均在有效期内",
"[required-reading] core/baseline.md, workflows/delivery.md §1, policy/delivery.md",
"[R0] b5e23daed2(完整:b5e23daed2f0ea46261979de1d62e4de0cfa88f9)",
"[worktree] before-sync: recursive component checks passed",
"[verdict] READY — 保留本次 precheck receipt 后建任务工作区:PRECHECK_RECEIPT=/tmp/task-precheck.json make task-start NAME=feature/your-branch",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev'"
],
"output_sha256": "6e552710cd7e401d0977d3d0b58a5e1f85dfb9ea08513c912be0778b1beb3733",
"receipt_sha256": "287ec384589843c0b2ee411ffc97383e668ac7c9121fda7eb391125cd1dd19b9",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/287ec384589843c0b2ee411ffc97383e668ac7c9121fda7eb391125cd1dd19b9.json"
}
```
| 同步(记录前对象) | eef7e5e778cabcb6216f74b74213a3d7511f383b | fd00a06096a27750c76eb202ec5515d2ac9379b6 | 2026-10-18T18:47:17Z |
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T19:08:02.437026+00:00",
"command": "make precheck",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation",
"before_head": "f52df0e2e6bd52d1b60989ac079826787fef3307",
"after_head": "f52df0e2e6bd52d1b60989ac079826787fef3307",
"branch": "feature/norm-remediation",
"target_branch": "main",
"target_head": "eef7e5e778cabcb6216f74b74213a3d7511f383b",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation'",
"[repo] branch=feature/norm-remediation head=f52df0e2e6",
"[remote] origin/main=eef7e5e778 ahead=107 behind=0",
"[tree] clean submodules_drift=0 uninit=0",
"[worktrees] linked=7",
"[recycle] merged un-recycled branches: feature/layered-python-env",
"[initiatives] local cards (not authoritative): none",
"[hooks] core.hooksPath=scripts/hooks(pre-commit/post-merge 实际接线)",
"[facts] policy/facts.md 6 条事实均在有效期内",
"[required-reading] core/baseline.md, workflows/delivery.md §1, policy/delivery.md",
"[R0] eef7e5e778(完整:eef7e5e778cabcb6216f74b74213a3d7511f383b)",
"[worktree] before-sync: recursive component checks passed",
"[verdict] READY — 保留本次 precheck receipt 后建任务工作区:PRECHECK_RECEIPT=/tmp/task-precheck.json make task-start NAME=feature/your-branch",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation'"
],
"output_sha256": "d364561ba0a811ef8826b0db35d156ff5a561b7e899550048512eb71f5e45b66",
"receipt_sha256": "f2e57a2a883a1693f1009af263a335b2df431dc7d433ad7ef0c868eb3b197a74",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/f2e57a2a883a1693f1009af263a335b2df431dc7d433ad7ef0c868eb3b197a74.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T18:47:45.105555+00:00",
"command": "make precheck",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation",
"before_head": "6b5806078f5119fd016465eba71f8fca490479fe",
"after_head": "6b5806078f5119fd016465eba71f8fca490479fe",
"branch": "feature/norm-remediation",
"target_branch": "main",
"target_head": "eef7e5e778cabcb6216f74b74213a3d7511f383b",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation'",
"[repo] branch=feature/norm-remediation head=6b5806078f",
"[remote] origin/main=eef7e5e778 ahead=106 behind=0",
"[tree] clean submodules_drift=0 uninit=0",
"[worktrees] linked=7",
"[recycle] merged un-recycled branches: feature/layered-python-env",
"[initiatives] local cards (not authoritative): none",
"[hooks] core.hooksPath=scripts/hooks(pre-commit/post-merge 实际接线)",
"[facts] policy/facts.md 6 条事实均在有效期内",
"[required-reading] core/baseline.md, workflows/delivery.md §1, policy/delivery.md",
"[R0] eef7e5e778(完整:eef7e5e778cabcb6216f74b74213a3d7511f383b)",
"[worktree] before-sync: recursive component checks passed",
"[verdict] READY — 保留本次 precheck receipt 后建任务工作区:PRECHECK_RECEIPT=/tmp/task-precheck.json make task-start NAME=feature/your-branch",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation'"
],
"output_sha256": "d6c359174171f0e7759d550c5236c6909b41ee78ad1b4fb9d7b2c0975fc312d3",
"receipt_sha256": "5bbd5a7dbd32f936a2c3c0b21b1675d0f54747a882ff72e15bbbb5a8a4209a92",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/5bbd5a7dbd32f936a2c3c0b21b1675d0f54747a882ff72e15bbbb5a8a4209a92.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T18:46:23.709451+00:00",
"command": "GIT_CONFIG_COUNT=1 GIT_CONFIG_KEY_0=branch.feature/norm-remediation.mergeOptions GIT_CONFIG_VALUE_0=-Xours make task-sync",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation",
"before_head": "3812031e6b481b77c5106dd40dbfed243e396504",
"after_head": "6b5806078f5119fd016465eba71f8fca490479fe",
"branch": "feature/norm-remediation",
"target_branch": "main",
"target_head": "eef7e5e778cabcb6216f74b74213a3d7511f383b",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"Cloning into '/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation/modules/ui/deps/development-guidelines'...",
"Submodule path 'deps/development-guidelines': checked out '2688fd2be6a52c0bf110e7e6366b6f291ab5e4eb'",
"Submodule 'deps/development-manager' (ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Development-Manager.git) registered for path 'deps/development-manager'",
"Cloning into '/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation/modules/ui/deps/development-manager'...",
"Submodule path 'deps/development-manager': checked out 'bd3a7de57a3a9e1a4495b94c5fa5c08d71e7be8c'",
"Submodule 'development/guidelines' (ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Development-Guidelines.git) registered for path 'development/guidelines'",
"Cloning into '/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation/modules/ui/deps/development-manager/development/guidelines'...",
"Submodule path 'development/guidelines': checked out '2688fd2be6a52c0bf110e7e6366b6f291ab5e4eb'",
"[worktree] materialize: recursive component checks passed",
"[worktree] after-sync: recursive component checks passed",
"admit: ok",
"[evidence] WARN JSON receipt line 172: unverified: recorded component state was not at its pinned SHA ——关键检查须重跑并以 make evidence 重新写入",
"[synced] sync_base=eef7e5e778cabcb6216f74b74213a3d7511f383b tested_head=6b5806078f5119fd016465eba71f8fca490479fe checked_at=2026-10-18T18:47:17Z changed=1 sync_target=main",
"[next] 跑正式验收(make test 等),证据写入任务卡",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation'"
],
"output_sha256": "1eb6e513009a02e1a0d606f2539454e81f799fe4a2b5c1e3b932ac528f58cd07",
"receipt_sha256": "655b4efe3346053c96ef2361246295488f388ab4e366cfcd9116ee656ee684ae",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/655b4efe3346053c96ef2361246295488f388ab4e366cfcd9116ee656ee684ae.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T18:47:52.335693+00:00",
"command": "make test && make build",
"exit_code": 2,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation",
"before_head": "6b5806078f5119fd016465eba71f8fca490479fe",
"after_head": "6b5806078f5119fd016465eba71f8fca490479fe",
"branch": "feature/norm-remediation",
"target_branch": "main",
"target_head": "eef7e5e778cabcb6216f74b74213a3d7511f383b",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"ok modules/backend logging-system",
"ok deps/agent-native agent-intent",
"warn: deps/agent-native deps/development-guidelines is 26b562d2e34f, Dev is a15db5085585",
"ok deps/agent-native error-code-system",
"ok deps/agent-native logging-system",
"ok deps/agent-squad agent-intent",
"ok deps/agent-squad agent-native",
"warn: deps/agent-squad deps/development-guidelines is 26b562d2e34f, Dev is a15db5085585",
"ok deps/agent-squad error-code-system",
"ok deps/agent-squad logging-system",
"warn: deps/agent-intent deps/development-guidelines is 26b562d2e34f, Dev is a15db5085585",
"ok deps/agent-intent error-code-system",
"ok deps/agent-intent logging-system",
"make[1]: *** [Makefile:201: test-pins] Error 1",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation'"
],
"output_sha256": "106c862765dde13ad3e284b434c5f1678f259de28f9ac3ebfd20f71e38a47608",
"receipt_sha256": "4247d20139741ec1b96f2213cf5194d3e05cd536da53939e1d68e21097c873cf",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/4247d20139741ec1b96f2213cf5194d3e05cd536da53939e1d68e21097c873cf.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T18:56:50.650054+00:00",
"command": "python3 -m unittest tests.test_check_pins && make test-pins && git diff --check",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation",
"before_head": "f52df0e2e6bd52d1b60989ac079826787fef3307",
"after_head": "f52df0e2e6bd52d1b60989ac079826787fef3307",
"branch": "feature/norm-remediation",
"target_branch": "main",
"target_head": "eef7e5e778cabcb6216f74b74213a3d7511f383b",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"ok modules/backend logging-system",
"ok deps/agent-native agent-intent",
"warn: deps/agent-native deps/development-guidelines is 26b562d2e34f, Dev is a15db5085585",
"ok deps/agent-native error-code-system",
"ok deps/agent-native logging-system",
"ok deps/agent-squad agent-intent",
"ok deps/agent-squad agent-native",
"warn: deps/agent-squad deps/development-guidelines is 26b562d2e34f, Dev is a15db5085585",
"ok deps/agent-squad error-code-system",
"ok deps/agent-squad logging-system",
"warn: deps/agent-intent deps/development-guidelines is 26b562d2e34f, Dev is a15db5085585",
"ok deps/agent-intent error-code-system",
"ok deps/agent-intent logging-system",
"pins ok",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation'"
],
"output_sha256": "abd51bb25efcdd4dcfef701a353d7e5f35641345297e1e33bdc2292f237b8c14",
"receipt_sha256": "df2b0d485c916e6477da5364acf963343e153d5a7c3def2027e8f458ae0f9acb",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/df2b0d485c916e6477da5364acf963343e153d5a7c3def2027e8f458ae0f9acb.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T18:57:33.241013+00:00",
"command": "make test && make build",
"exit_code": 2,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation",
"before_head": "f52df0e2e6bd52d1b60989ac079826787fef3307",
"after_head": "f52df0e2e6bd52d1b60989ac079826787fef3307",
"branch": "feature/norm-remediation",
"target_branch": "main",
"target_head": "eef7e5e778cabcb6216f74b74213a3d7511f383b",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"用法:identity <ensure|verify|capabilities> --instance-id ID [--dbref REF] [--data DIR] [--dsn-file FILE]",
"ensured instance_id=svc-t1-abcdef123456 dbref=sqlite",
"identity verify: system identity mismatch: 库内 instance_id=\"svc-t1-abcdef123456\" dbref=\"sqlite\" ≠ 期望 \"svc-t1-zzzzzz999999\" / \"sqlite\"",
"identity verify: system identity mismatch: 库内 instance_id=\"svc-t1-abcdef123456\" dbref=\"sqlite\" ≠ 期望 \"svc-t1-abcdef123456\" / \"pg\"",
"identity verify: identity database missing: /tmp/TestVerifyMissingDBCreatesNothing3410590918/001/absent/agent-system.db",
"--- FAIL: TestDSNFileMode (0.00s)",
" identity_test.go:149: 0644 的 dsn 文件必须拒绝",
"ensured instance_id=svc-dsnenv-abcdef123456 dbref=sqlite",
"verified instance_id=svc-dsnenv-abcdef123456 dbref=sqlite schema_version=50",
"FAIL",
"FAIL\tagent-system-backend/pkg/identity\t0.108s",
"? \tagent-system-backend/web\t[no test files]",
"FAIL",
"make[1]: *** [Makefile:150: test-backend] Error 1",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation'"
],
"output_sha256": "54498f0a9e266fc85b0d82ab4ef90b019fcad772710ec316d72be3681328b15f",
"receipt_sha256": "b0ceece861607937be75e2bb2bd105e099356e25ee58063cd0e523ed0aa621c0",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/b0ceece861607937be75e2bb2bd105e099356e25ee58063cd0e523ed0aa621c0.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T19:05:24.855184+00:00",
"command": "umask 022; (cd modules/backend && go test ./pkg/identity -run TestDSNFileMode -count=1) && make test -o test-governance -o test-boundaries -o test-pins -o test-libs -o test-core && make build",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation",
"before_head": "f52df0e2e6bd52d1b60989ac079826787fef3307",
"after_head": "f52df0e2e6bd52d1b60989ac079826787fef3307",
"branch": "feature/norm-remediation",
"target_branch": "main",
"target_head": "eef7e5e778cabcb6216f74b74213a3d7511f383b",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"dist/assets/index-CNWTiBCO.js 213.14 kB │ gzip: 70.03 kB",
"dist/assets/xlsx-CkFp8p6R.js 429.53 kB │ gzip: 143.07 kB",
"dist/assets/index-Bbgu8RGY.js 739.00 kB │ gzip: 229.89 kB",
"dist/assets/pptx-preview.es-C3efH30Z.js 1,255.23 kB │ gzip: 401.46 kB",
"",
"(!) Some chunks are larger than 500 kB after minification. Consider:",
"- Using dynamic import() to code-split the application",
"- Use build.rollupOptions.output.manualChunks to improve chunking: https://rollupjs.org/configuration-options/#output-manualchunks",
"- Adjust chunk size limit for this warning via build.chunkSizeWarningLimit.",
"✓ built in 5.23s",
"rm -rf modules/backend/web/dist && mkdir -p modules/backend/web/dist && cp -r modules/frontend/dist/* modules/backend/web/dist/ && touch modules/backend/web/dist/.gitkeep",
"cd modules/backend && CGO_ENABLED=0 go build -trimpath -ldflags \"-s -w -X main.version=v0.4.0-941-gf52df0e+core=1a5ef6b+backend=646dc57+frontend=1650b4f+ui=5c2b103+agentcmd=4f583ca+documents=1e036e9+native=c348441+squad=490b0b2+intent=343b1e6\" -o ../../bin/agent-system ./cmd/agent-system",
"cd modules/backend && CGO_ENABLED=0 go build -trimpath -ldflags \"-s -w\" -o ../../bin/storage-migrate ./cmd/storage-migrate",
"OK: bin/agent-system(版本 v0.4.0-941-gf52df0e+core=1a5ef6b+backend=646dc57+frontend=1650b4f+ui=5c2b103+agentcmd=4f583ca+documents=1e036e9+native=c348441+squad=490b0b2+intent=343b1e6;随附插件目录 plugins/)+ bin/storage-migrate(协作存储 U4 迁移工具)",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-norm-remediation'"
],
"output_sha256": "8301e75d16b6f4ecaac861c9a25ac51d93fb7431a5f3201a84d1c89e641d0296",
"receipt_sha256": "1356559c9425ba978cb3c9c720d8373ddbca2a562c3cc7bab876343e188a9108",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/1356559c9425ba978cb3c9c720d8373ddbca2a562c3cc7bab876343e188a9108.json"
}
```
## 闭合记录(合入前折叠)
- 本卡在 PR #616(https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/616)合入前闭合并归档,随该 PR 一同合入。
- 该 PR 的合并提交即本任务的落地记录。
- 合入后无需回填,也无需单独的闭合 PR。
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,280 @@
# feature/rdm-settings-phase1a 任务卡
任务主记录:PR #617 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/617;状态:已完成(合入前闭合);owner:weichen
## 基线与授权
- 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= ba81d638a6c845d0acde6896f4001bed096ba26c
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-rdm-settings-phase1a(worktree);分支:feature/rdm-settings-phase1a
- 分支类型:standalone;root_target:main;immediate_target:main;accepting_requirements:false
- 需求分流:verdict=NEW;selected_initiative=无;requirement_sha256=085614ee5a2a7fe92cf18f577c0a1c0d33acc11682870331edd6f173309e8e14;triage_receipt=/tmp/cleanup-20261018/rdm1a-triage.json;receipt_sha256=7de7c2c70184d1e54bb00df5e808dfaffa0e78451d1166557e7ce18cf2079424
- 授权与交付终点:用户 2026-10-18 确认 RDM settings 收尾按分期推进(scope=phase、profile=user_only、order=split);本卡为一期 1a,终点为 UI/RDM/Frontend/Dev 合入、组合改钉及用户阶段 7 验收。扩围授权 land_fe_pw:Frontend 密码管理提交经 Frontend #107 合入 Frontend 主干(已合入 `0459567`)。未授权:一期 1b(R4/R5,等 IAM U4)、二期(R1 与扩展 API 2.16 发版,发版由用户执行)。
- 关联仓工作区:UI/Frontend `/home/weichen/projects/Agent-System-RDM1a-Frontend-Combo/{ui,frontend}`;RDM `/home/weichen/projects/Agent-System-RDM-wt-feature-rdm-settings-phase1a`(分支均为 feature/rdm-settings-phase1a)。
- 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进)
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
- 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入)
- 人工决策点:仅限目标/范围/验收变更、重大取舍、高后果操作或无法自动判定的业务验收
- 当前阶段:合入;当前增量:I1(一期 1a)
- 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位)
## 目标与非目标
- 目标:R2 成员检索(账号/姓名精确与模糊检索、专业角色筛选、服务端先筛选后分页、同名以账号区分、已加入不可重复添加)在 RDM、UI Picker 与 Frontend 成员页端到端可用;Dev 验收脚本不再对未执行场景输出 PASS。
- 受影响:UI `Picker`;RDM `rdm.account.list`、`rdm.project.member.list`(向后兼容增量)与新读命令 `rdm.role.options`;Frontend `RdmMembersSection`;Dev `tests/integration/rdm-increment/acceptance_scenarios.sh` 与 `modules/{frontend,ui}` 指针。
- 非目标:R1 项目共享设置、R3 旧职责模型(已被职责矩阵取代,放弃)、R4 权限矩阵剩余项与 R5 成员移除影响(一期 1b)、`AccountValidFor` 语义变更、RDM `perms/*` 与 IAM U4 冲突区。
- 计划:`docs/superpowers/plans/2026-10-18-rdm-settings-phase1a-plan.md`。
## Agent 实施收据
路由与 fail-stop 规则见根目录 AGENT-EXECUTION.md 与 policy/delivery.md;每次尝试一行,原始日志留在源码外收据路径。
| 单元 ID | 预期范围 | 配置摘要 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|---|---|---|---|---|---|---|---|---|---|---|
| ui-rdm1a-picker-hardening | UI src/Picker.tsx、src/ui.css、test/picker.test.tsx | UI AGENT-EXECUTION.md | implementation | cursor→antigravity→pi | 1 | cursor/auto(fresh) | success | 5c2b103 | 无 | /tmp/cleanup-20261018/rdm1a/ui-picker-run.json |
| rdm-rdm1a-r2-member-search | RDM accountdir/member_search/plugin | RDM AGENT-EXECUTION.md | implementation | cursor→antigravity→pi | 1 | cursor/auto(fresh) | scope-expansion(fail-stop:需改 plugin_test 命令集) | — | 无 | /tmp/cleanup-20261018/rdm1a/rdm-r2-run.json |
| rdm-rdm1a-r2-member-search-r2 | 同上 + plugin_test.go 一项 | 同上 | implementation | 同上 | 1 | cursor/auto(fresh) | scope-expansion(fail-stop:host 追加的行类型规则与既有测试冲突) | — | 无 | /tmp/cleanup-20261018/rdm1a/rdm-r2-run2.json |
| rdm-rdm1a-r2-member-search-r3 | 同上(去掉行类型规则) | 同上 | implementation | 同上 | 1 | cursor/auto(fresh) | success | f1cd92c | 无 | /tmp/cleanup-20261018/rdm1a/rdm-r2-run3.json |
| frontend-rdm1a-members-search | Frontend adminRdmSections(RdmMembersSection)、rdmManagement.ts、新测试 | Frontend AGENT-EXECUTION.md | implementation | 同上 | 1 | cursor/auto(fresh) | success | 96ab2eb | 无 | /tmp/cleanup-20261018/rdm1a/fe-members-run.json |
| dev-rdm1a-acceptance-not-run | tests/integration/rdm-increment/acceptance_scenarios.sh | AGENT-EXECUTION.md | implementation | 同上 | 1 | cursor/auto(fresh) | success | 327c897 | 无 | /tmp/cleanup-20261018/rdm1a/dev-acceptance-run.json |
| rdm-rdm1a-repin-frontend-ui | RDM pins/agent-system-{frontend,ui} | RDM AGENT-EXECUTION.md | implementation | 同上 | 1 | cursor/auto(fresh) | success | 9bd62cd | 无 | /tmp/cleanup-20261018/rdm1a/rdm-pins-run.json |
| dev-rdm1a-repin-frontend-ui | modules/{frontend,ui} | AGENT-EXECUTION.md | implementation | 同上 | 1 | cursor/auto(fresh) | success | f90bc0f | 无 | /tmp/cleanup-20261018/rdm1a/dev-pins-run.json |
## 关联方向与规划
- 适用状态:待核对(无适用规划时说明原因)
- 主记录路径/版本:待核对(路径按仓库根目录定位,归档后不变;只引用唯一正文)
- 对应里程碑:待核对
## 需求分析
| ID | 描述 | 项目符合度及依据 | 优先级 | 验收条件 | 依赖 | 结论 |
|---|---|---|---|---|---|---|
| R2 | 账号/姓名检索、分页、专业角色过滤同源,稳定 ID 选择 | 部分符合:主干已有 Picker 与姓名子串检索;缺角色筛选、精确匹配、先筛后分页、成员表检索分页、姓名+账号显示 | P0 | 见计划「验收条件」前三条 | UI U1、RDM U2 | 纳入 1a |
| R5-a | 验收声明来自实际执行 | 不符合:场景 9 无条件输出 PASS | P0 | 未执行项报告 NOT_RUN 并计入汇总 | 无 | 纳入 1a |
| R1/R4/R5-b | 共享设置、权限矩阵剩余、移除影响 | 依赖 IAM U4 或发版 | — | — | IAM U4、扩展 API 2.16 | 1b/二期 |
## 方案与计划
- 方案引用:旧任务 `.task/feature-rdm-settings-completion.md`(旧分支,需求表 R1–R5)与本次差距分析;参考 diff 存于仓外 `/tmp/cleanup-20261018/rdm1a/`
- 实施计划引用:`docs/superpowers/plans/2026-10-18-rdm-settings-phase1a-plan.md`(单元 U1–U5,R2、R5-a)
- 测试计划引用:同计划「验收条件」;各单元 verification 见仓外单元 JSON
## 阶段记录
| 阶段 | 对象版本 | 状态 | 决策/执行者 | 时间 | 依据 |
|---|---|---|---|---|---|
| 需求拆解 | 858d566 | 完成 | host | 2026-10-18 | 需求分析表 |
| 需求评估 | 858d566 | 完成 | host | 2026-10-18 | 差距分析(R3 放弃、R1/R4/R5-b 后移) |
| 需求表确认 | 858d566 | 完成 | 用户 | 2026-10-18 | scope=phase、profile=user_only、order=split |
| 方案设计 | 858d566 | 完成 | host | 2026-10-18 | 计划「R2 合同」 |
| 实施计划 | 858d566 | 完成 | host | 2026-10-18 | docs/superpowers/plans/2026-10-18-rdm-settings-phase1a-plan.md |
| 实施与自检 | f90bc0f | 完成 | cursor worker(见收据) | 2026-10-18 | 各单元 verification + host 本地重跑 |
| 正式测试与验收 | 72280f4 | 用户决定先合入后在部署上自行验收 | 用户 | 2026-10-18 | AskQuestion stage7=merge_then_accept;问题另开修复任务 |
| 代码 Review | 各组件 PR head;Dev 72280f4 | 完成 | host(主模型,独立于实施 worker) | 2026-10-18 | 见合入与清理 |
| 合入 | 待定 | 待执行 | — | — | — |
| 合入核验与收口 | 待定 | 待执行 | — | — | — |
## 探索试验与迭代
| 增量/试验 | 假设 | 范围 | 判断和停止条件 | 授权/决策依据 | 结果 | 变更影响 | 需重审补测 |
|---|---|---|---|---|---|---|---|
| 待定义 | — | — | — | 待核对 | NOT_RUN | 待评估 | 待评估 |
## 同步记录
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|---|---|---|---|
| 启动 | ba81d638a6c845d0acde6896f4001bed096ba26c | ba81d638a6c845d0acde6896f4001bed096ba26c | 2026-10-18T10:36:45Z |
## 证据(Evidence)
<!-- CMD="<命令>" make evidence 写入;手抄/转写输出视为无效证据(AGENTS.md 证据与验证门禁)。 -->
| 时间(UTC) | 命令 | 被测HEAD | exit | 来源 | sha256(16) |
|---|---|---|---|---|---|
## 交付调度
- 调度状态:未入队;调度记录:无
- entry_id:无;attempt_id:无;窗口执行者:无
- 固定候选:无(base/head、组件与相关配置引用实际尝试)
- 调度依据:policy/delivery.md#合入调度
- 固定后证据:源码外 RECEIPT;实际结果后按授权原样导入和闭合
## 结果与验证
- 结果:R2 成员检索端到端落地——UI #59(5c2b103)Picker 加固;RDM #435(0b75756)服务端检索/筛选/分页与 rdm.role.options;Frontend #108(426d104)成员页接入;RDM #436(2b1fee7)产品改钉 Frontend/UI;本 PR:验收脚本场景 9 改报 NOT_RUN,Dev 改钉 modules/frontend→426d104、modules/ui→5c2b103。扩围:Frontend #107(0459567)落地 Dev 已上线的密码前端。
- 验证:GATE——Dev #617 CI(test、test-pg、svc-realcombo)@72280f4;UI #59 CI(test、governance)@5c2b103;RDM #435 CI(build-and-test、governance)@e3c813e;Frontend #107 @7df77c1、#108 @8260bf5(governance);RDM #436 @ce27e23。SELF——Frontend 426d104+UI 5c2b103 组合 tsc/vitest/vite build、test-pins、脚本语法(证据表);RDM make product(RDM 卡)。NOT_RUN——验收脚本对真实部署的执行、浏览器多身份验收(用户阶段 7)、部署。
- 影响与剩余项:Dev tests/integration/lifecycle/rdm.pin 未升级(生命周期测试制品钉扎,非本期必需)。非阻塞记录:Frontend 成员页第二个 import 位于文件中部(避开 IAM U4 冲突区);成员列沿用 ad-mono。一期 1b(R4/R5)等 IAM U4;二期 R1。
## 规划进展与下一步
- 本次推进/剩余:待核对(依据实际成果更新适用方案/规划)
- 首选下一任务:待核对(无适用规划、已完成或受阻时如实说明,不虚构任务)
- 推荐依据:待填写
- 前置条件/待确认:待核对
- 预期产物/验收条件:待定义
- 重复任务核对:待核对(已有/在途任务、PR 与规划记录)
- 启动授权:未授权(建议不自动启动新任务,仍须明确授权)
## 合入与清理
- Review 记录:host 主模型逐个审阅组件 diff(UI 5c2b103、RDM f1cd92c、Frontend 96ab2eb、Dev 327c897/f90bc0f),实施由独立 cursor worker 新进程完成,审阅未复用实施会话;结论通过,仅非阻塞记录;本地重放各单元 verification 一致。
- 冲突记录:NOT_RUN(最新目标同步、冲突处置、组合兼容核验及复审/补测)
- CI 记录:NOT_RUN(当前 HEAD 完整 SHA、全部必需检查、运行链接、执行身份及 GATE 结果)
- 合入记录:NOT_RUN(交付授权范围、PR、被核验 HEAD、合入 SHA、目标分支及内容核验)
- 清理记录:NOT_RUN(授权依据、写者退出确认、worktree/分支/任务卡处置)
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T10:35:55.125612+00:00",
"command": "make precheck",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev",
"before_head": "ba81d638a6c845d0acde6896f4001bed096ba26c",
"after_head": "ba81d638a6c845d0acde6896f4001bed096ba26c",
"branch": "main",
"target_branch": "main",
"target_head": "ba81d638a6c845d0acde6896f4001bed096ba26c",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev'",
"[repo] branch=main head=ba81d638a6",
"[remote] origin/main=ba81d638a6 ahead=0 behind=0",
"[tree] clean submodules_drift=0 uninit=5",
"[warn] 5 个子模块未初始化——构建/测试前需物化(不阻断写入)",
"[worktrees] linked=10",
"[recycle] merged un-recycled branches: feature/layered-python-env",
"[initiatives] local cards (not authoritative): none",
"[hooks] core.hooksPath=scripts/hooks(pre-commit/post-merge 实际接线)",
"[facts] policy/facts.md 6 条事实均在有效期内",
"[required-reading] core/baseline.md, workflows/delivery.md §1, policy/delivery.md",
"[R0] ba81d638a6(完整:ba81d638a6c845d0acde6896f4001bed096ba26c)",
"[worktree] before-sync: recursive component checks passed",
"[verdict] READY — 保留本次 precheck receipt 后建任务工作区:PRECHECK_RECEIPT=/tmp/task-precheck.json make task-start NAME=feature/your-branch",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev'"
],
"output_sha256": "2f0013d9d7dd472fc1308102365d2e2db04b7b2bb132a19880804609cd78e08e",
"receipt_sha256": "d3ff2433b1b5bfb4df2806794c102d06fd462a0ccf7ad3ad37929b26496faf19",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/d3ff2433b1b5bfb4df2806794c102d06fd462a0ccf7ad3ad37929b26496faf19.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T11:12:36.203204+00:00",
"command": "make test-pins",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-rdm-settings-phase1a",
"before_head": "f90bc0ffb3750d27b7f4e4ebadbb0ebdf1f1d68c",
"after_head": "f90bc0ffb3750d27b7f4e4ebadbb0ebdf1f1d68c",
"branch": "feature/rdm-settings-phase1a",
"target_branch": "main",
"target_head": "ba81d638a6c845d0acde6896f4001bed096ba26c",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"ok modules/backend logging-system",
"ok deps/agent-native agent-intent",
"warn: deps/agent-native deps/development-guidelines is 26b562d2e34f, Dev is 2688fd2be6a5",
"ok deps/agent-native error-code-system",
"ok deps/agent-native logging-system",
"ok deps/agent-squad agent-intent",
"ok deps/agent-squad agent-native",
"warn: deps/agent-squad deps/development-guidelines is 26b562d2e34f, Dev is 2688fd2be6a5",
"ok deps/agent-squad error-code-system",
"ok deps/agent-squad logging-system",
"warn: deps/agent-intent deps/development-guidelines is 26b562d2e34f, Dev is 2688fd2be6a5",
"ok deps/agent-intent error-code-system",
"ok deps/agent-intent logging-system",
"pins ok",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-rdm-settings-phase1a'"
],
"output_sha256": "322ec1f3a1eb346fe5a89b84b30502eca7141aa489689646a3a2faace7856924",
"receipt_sha256": "54c15d0bc22618c5c7c6bfe502df532f9c8f777ef85f7bbc56a52238fec9562b",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/54c15d0bc22618c5c7c6bfe502df532f9c8f777ef85f7bbc56a52238fec9562b.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T11:12:42.270681+00:00",
"command": "bash -n tests/integration/rdm-increment/acceptance_scenarios.sh",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-rdm-settings-phase1a",
"before_head": "f90bc0ffb3750d27b7f4e4ebadbb0ebdf1f1d68c",
"after_head": "f90bc0ffb3750d27b7f4e4ebadbb0ebdf1f1d68c",
"branch": "feature/rdm-settings-phase1a",
"target_branch": "main",
"target_head": "ba81d638a6c845d0acde6896f4001bed096ba26c",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "ae1ee7ba92fa38c5961408605c01d3f32cd5037ae206924c41db1803b2d0b471",
"after_tracked_diff_sha256": "ae1ee7ba92fa38c5961408605c01d3f32cd5037ae206924c41db1803b2d0b471",
"output_tail": [],
"output_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"receipt_sha256": "3f1e6796eb2637e8a8d51cee997c8f80a1aedf31e92bc989057c7ab7e12a82e8",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/3f1e6796eb2637e8a8d51cee997c8f80a1aedf31e92bc989057c7ab7e12a82e8.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T11:12:46.273806+00:00",
"command": "bash -c 'cd /home/weichen/projects/Agent-System-RDM1a-Frontend-Combo/frontend && git fetch -q origin && git checkout -q --detach 426d1044ac99507edfeae3b5bf6b1f6de358f0d6 && git -C ../ui checkout -q --detach 5c2b1036dd1aff89ec4eeae0c96493694e33ad4c && npx tsc -b && npx vitest run && npx vite build'",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-rdm-settings-phase1a",
"before_head": "f90bc0ffb3750d27b7f4e4ebadbb0ebdf1f1d68c",
"after_head": "f90bc0ffb3750d27b7f4e4ebadbb0ebdf1f1d68c",
"branch": "feature/rdm-settings-phase1a",
"target_branch": "main",
"target_head": "ba81d638a6c845d0acde6896f4001bed096ba26c",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "4c1eae8910d3c1e1c0960eb1dbb32bd26db36915627ae183a4ccae2ef39818d8",
"after_tracked_diff_sha256": "4c1eae8910d3c1e1c0960eb1dbb32bd26db36915627ae183a4ccae2ef39818d8",
"output_tail": [
"dist/index.html 0.40 kB │ gzip: 0.27 kB",
"dist/assets/index-LeIKZxBo.css 114.65 kB │ gzip: 19.25 kB",
"dist/assets/jszip.min-XgtLb15L.js 0.12 kB │ gzip: 0.12 kB",
"dist/assets/docx-preview-BX-E56Uz.js 77.41 kB │ gzip: 21.29 kB",
"dist/assets/jszip.min-DpFGSQHe.js 97.26 kB │ gzip: 30.16 kB",
"dist/assets/index-CTwq5Yiv.js 213.14 kB │ gzip: 70.03 kB",
"dist/assets/xlsx-CkFp8p6R.js 429.53 kB │ gzip: 143.07 kB",
"dist/assets/index-B4krzkTJ.js 639.68 kB │ gzip: 199.10 kB",
"dist/assets/pptx-preview.es-Dygvqd4B.js 1,255.23 kB │ gzip: 401.45 kB",
"",
"(!) Some chunks are larger than 500 kB after minification. Consider:",
"- Using dynamic import() to code-split the application",
"- Use build.rollupOptions.output.manualChunks to improve chunking: https://rollupjs.org/configuration-options/#output-manualchunks",
"- Adjust chunk size limit for this warning via build.chunkSizeWarningLimit.",
"✓ built in 7.63s"
],
"output_sha256": "2eb8a43a3b22a0fb54468e635c661d1ba57bc0733ac534d546721a5abd6eb072",
"receipt_sha256": "6003570995fbcdb45627954a5a0fe1ab7d331a37175a042c457635cb6e875c97",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/6003570995fbcdb45627954a5a0fe1ab7d331a37175a042c457635cb6e875c97.json"
}
```
## 闭合记录(合入前折叠)
- 本卡在 PR #617(https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/617)合入前闭合并归档,随该 PR 一同合入。
- 该 PR 的合并提交即本任务的落地记录。
- 合入后无需回填,也无需单独的闭合 PR。
@@ -0,0 +1,245 @@
# feature/regkb-corpus-wiring 任务卡
任务主记录:PR #625 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/625;状态:已完成(合入前闭合);owner:weichen
## 基线与授权
- 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= eef7e5e778cabcb6216f74b74213a3d7511f383b
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-regkb-corpus-wiring(worktree);分支:feature/regkb-corpus-wiring
- 分支类型:standalone;root_target:main;immediate_target:main;accepting_requirements:false
- 需求分流:verdict=NEW;selected_initiative=无;requirement_sha256=9fad07a7ccc92506912aebfddddcbef685159ffc076459610a9907d652618ccd;triage_receipt=/tmp/regkb-dev-triage.json;receipt_sha256=2a0801f651ffc10e149f5cdadc94da0be9ee280f83df9a9921229e12bb738c10
- 授权与交付终点:用户 2026-10-18 要求“把所有的法规、通告、指导原则等等都入库”,经 AskQuestion 确认范围=全部本地语料(含标准,按权利类别限制展示)、发布=所有者批量授权(审核人 weichen)、联网补齐=现在、接入=是(RDM/Dev 升级 KB 版本、配置 `KBREG_*` 指向新库)。终点:本 PR 合入 Dev main,rdm1 部署含新 KB 的 RDM main 并配置 `KBREG_*`,产品可检索已发布修订。凭据只放实例 0600 本地文件,不入仓。
- 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进)
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
- 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入)
- 人工决策点:仅限目标/范围/验收变更、重大取舍、高后果操作或无法自动判定的业务验收
- 当前阶段:需求拆解;当前增量:I1(待定义)
- 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位)
## 目标与非目标
- 目标:`tests/integration/regulations-kb/components.pin` 更新为含 KB 393555b 的 RDM main(RDM PR #442 合入点)与 KB main 393555b,组合门禁 `tests/integration/regulations-kb/run.sh` 通过;rdm1 实例 `serve.env`(0600,runtime/ 已 gitignore)追加产品需要的 `KBREG_*`(数据库 URL、embedder、搜索提供方 `zhipu-mcp` 与密钥),部署新 RDM 并核验法规检索可用;记录新语料修订的发布结果。
- 非目标:修改 `scripts/svc.sh`(现有 `serve.env` 已透传非 `AGENT_SYSTEM_*` 变量)、生产部署、凭据入仓、KB 语料只读账号(后续改进)。
## Agent 实施收据
路由与 fail-stop 规则见根目录 AGENT-EXECUTION.md 与 policy/delivery.md;每次尝试一行,原始日志留在源码外收据路径。
| 单元 ID | 预期范围 | 配置摘要 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|---|---|---|---|---|---|---|---|---|---|---|
| dev-regkb-components-pin-377d427 | tests/integration/regulations-kb/components.pin、README.md | AGENT-EXECUTION.md | implementation | cursor → agy → pi | 1(run d9cf2830…/0b33b9cc9050;fresh_session,session 41bf6457…) | cursor-agent(Auto) | failed-unknown(Cursor 服务重连后无输出,900 s 超时终止;工作区无改动;fail-stop,未自动重试) | 无 | 无 | /tmp/regkb-dev-pin-receipt.json |
| dev-regkb-components-pin-377d427-r2 | 同上 | AGENT-EXECUTION.md | implementation | cursor → agy → pi | 1(用户 2026-10-19 授权全新重派;run 52cabbe7…/2a2480ceef3d;fresh_session,session ID not-observable) | cursor-agent(Auto) | success | 81fa428(parent b7b0c49,apply 快进) | 无 | /tmp/regkb-dev-pin-receipt-r2.json |
## 关联方向与规划
- 适用状态:待核对(无适用规划时说明原因)
- 主记录路径/版本:待核对(路径按仓库根目录定位,归档后不变;只引用唯一正文)
- 对应里程碑:待核对
## 需求分析
| ID | 描述 | 项目符合度及依据 | 优先级 | 验收条件 | 依赖 | 结论 |
|---|---|---|---|---|---|---|
| R1 | 组合门禁固定组件升级到新 RDM/KB main | 符合(U8 组合门禁按 pin 升级走 PR) | P0 | `run.sh` 用新 pin 通过 | RDM PR #442 合入 | 采纳 |
| R2 | rdm1 接入新法规库 | 符合(用户确认接入) | P0 | rdm1 运行新 RDM,法规检索返回已发布修订结果,非 `corpus_not_configured` | R1、KB 修订发布 | 采纳 |
## 方案与计划
- 方案引用:待填写(含对象版本)
- 实施计划引用:待填写(含增量与需求 ID)
- 测试计划引用:待填写(含需求 ID 与验收条件)
## 阶段记录
| 阶段 | 对象版本 | 状态 | 决策/执行者 | 时间 | 依据 |
|---|---|---|---|---|---|
| 需求拆解 | 待定 | 待执行 | — | — | — |
| 需求评估 | 待定 | 待执行 | — | — | — |
| 需求表确认 | 待定 | 待执行 | — | — | — |
| 方案设计 | 待定 | 待执行 | — | — | — |
| 实施计划 | 待定 | 待执行 | — | — | — |
| 实施与自检 | 待定 | 待执行 | — | — | — |
| 正式测试与验收 | 待定 | 待执行 | — | — | — |
| 代码 Review | 待定 | 待执行 | — | — | — |
| 合入 | 待定 | 待执行 | — | — | — |
| 合入核验与收口 | 待定 | 待执行 | — | — | — |
## 探索试验与迭代
| 增量/试验 | 假设 | 范围 | 判断和停止条件 | 授权/决策依据 | 结果 | 变更影响 | 需重审补测 |
|---|---|---|---|---|---|---|---|
| 待定义 | — | — | — | 待核对 | NOT_RUN | 待评估 | 待评估 |
## 同步记录
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|---|---|---|---|
| 启动 | eef7e5e778cabcb6216f74b74213a3d7511f383b | eef7e5e778cabcb6216f74b74213a3d7511f383b | 2026-10-18T16:04:30Z |
## 证据(Evidence)
<!-- CMD="<命令>" make evidence 写入;手抄/转写输出视为无效证据(AGENTS.md 证据与验证门禁)。 -->
| 时间(UTC) | 命令 | 被测HEAD | exit | 来源 | sha256(16) |
|---|---|---|---|---|---|
## 交付调度
- 调度状态:未入队;调度记录:无
- entry_id:无;attempt_id:无;窗口执行者:无
- 固定候选:无(base/head、组件与相关配置引用实际尝试)
- 调度依据:policy/delivery.md#合入调度
- 固定后证据:源码外 RECEIPT;实际结果后按授权原样导入和闭合
## 结果与验证
- 结果:
- R1:`components.pin` → rdm_sha=377d427(RDM PR #442 合入点,KB gitlink 393555b)、kb_sha=393555b(KB PR #8、#9 合入后的 main);README 同步描述。
- R2:rdm1 部署 `rdm@377d427`(release rdm-377d427-20261018T163309Z-1928553),实例 `runtime/rdm1/serve.env`(0600,gitignored)追加 9 个 `KBREG_*`(数据库 URL、http embedder 1024 维 `dmxapi-1024`、`KBREG_SEARCH_PROVIDER=zhipu-mcp` 及密钥),进程环境核对到全部 9 个变量名(值未输出)。
- 语料修订:`rev_corpus_legacy_20261018` 已发布(actor weichen;评测 250 例:条款召回 0.96、版本选择 0.915、引文定位 0.96、失效抑制 1.0、摘要/来源分离 1.0,均达门槛;基线复核人 weichen,所有者批量授权);`kbreg revision verify` verified,版本 2,887、法律节点 1,701,178、清单 sha256 2df2ca96…c216bb;索引 fts `ix_461fd0509c82b79247f85425`、vector `ix_7cafae6fbb2b702c0351dec8`(64,076/64,076)。
- 验证(SELF):
- 组合门禁 `tests/integration/regulations-kb/run.sh`(RDM 377d427 分离检出、KB 393555b 主检出、一次性 pgvector:pg16 测试库,pg16 客户端工具;扫描目录为 rdm1 已部署的同版本前端产物):kb-test-pg PASS、rdm-kbreg PASS、client-asset-secret-scan PASS(证据见下方 evidence)。附加一次带 rdm1 真实 `KBREG_*` 的运行:扫描核对 3 个凭据变量无泄露 PASS;rdmapp 3 个组合测试因环境中的 `KBREG_SEARCH_PROVIDER=zhipu-mcp` 未被测试清理而失败(干净环境通过)。
- 产品路径探针(/tmp,未入仓):以 RDM 377d427 所钉 KB 代码的 `pkg/kbprovider` 与 rdm1 同一 `serve.env`、无代理运行:3 个法规检索均 state=ok、命中已发布修订;联网搜索 provider=zhipu-mcp state=ok。rdm1 HTTP 命令需管理员会话,未做 HTTP 级调用(NOT_RUN)。
- 权威结果以 PR 当前 HEAD 的 CI 为准。
- 影响与剩余项(非阻塞):RDM `composedSetup` 未清理 `KBREG_SEARCH_PROVIDER`(宿主机带该变量时 3 个组合测试误失败);产品使用可写库账号 `kbreg`(建议后续改只读账号);旧语料部分文号/标题(如标准封面“中华人民共和国国家标准”)元数据粗糙;向量检索无 ANN 索引;现行指导原则约 691 份 vs 库内约 157+ 份,`/home/weichen/regkb-inbox/` 手动下载件到位后需以新修订补充;10 份隔离、29 份原件缺失。
## 规划进展与下一步
- 本次推进/剩余:待核对(依据实际成果更新适用方案/规划)
- 首选下一任务:待核对(无适用规划、已完成或受阻时如实说明,不虚构任务)
- 推荐依据:待填写
- 前置条件/待确认:待核对
- 预期产物/验收条件:待定义
- 重复任务核对:待核对(已有/在途任务、PR 与规划记录)
- 启动授权:未授权(建议不自动启动新任务,仍须明确授权)
## 合入与清理
- Review 记录:NOT_RUN(审阅智能体/平台身份、base/head、结论、问题闭合及重放依据)
- 冲突记录:NOT_RUN(最新目标同步、冲突处置、组合兼容核验及复审/补测)
- CI 记录:NOT_RUN(当前 HEAD 完整 SHA、全部必需检查、运行链接、执行身份及 GATE 结果)
- 合入记录:NOT_RUN(交付授权范围、PR、被核验 HEAD、合入 SHA、目标分支及内容核验)
- 清理记录:NOT_RUN(授权依据、写者退出确认、worktree/分支/任务卡处置)
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T16:03:48.792262+00:00",
"command": "make precheck",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev",
"before_head": "eef7e5e778cabcb6216f74b74213a3d7511f383b",
"after_head": "eef7e5e778cabcb6216f74b74213a3d7511f383b",
"branch": "main",
"target_branch": "main",
"target_head": "eef7e5e778cabcb6216f74b74213a3d7511f383b",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev'",
"[repo] branch=main head=eef7e5e778",
"[remote] origin/main=eef7e5e778 ahead=0 behind=0",
"[tree] clean submodules_drift=0 uninit=12",
"[warn] 12 个子模块未初始化——构建/测试前需物化(不阻断写入)",
"[worktrees] linked=6",
"[recycle] merged un-recycled branches: feature/layered-python-env",
"[initiatives] local cards (not authoritative): none",
"[hooks] core.hooksPath=scripts/hooks(pre-commit/post-merge 实际接线)",
"[facts] policy/facts.md 6 条事实均在有效期内",
"[required-reading] core/baseline.md, workflows/delivery.md §1, policy/delivery.md",
"[R0] eef7e5e778(完整:eef7e5e778cabcb6216f74b74213a3d7511f383b)",
"[worktree] before-sync: recursive component checks passed",
"[verdict] READY — 保留本次 precheck receipt 后建任务工作区:PRECHECK_RECEIPT=/tmp/task-precheck.json make task-start NAME=feature/your-branch",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev'"
],
"output_sha256": "c99ae0d65c942a4fa4016864159dcbaa0a61e2e49297b058004000eab1e55baf",
"receipt_sha256": "e2a517e9383c017755499303c39c2a794c5d83d8d131a5ebae29536ab70c32c6",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/e2a517e9383c017755499303c39c2a794c5d83d8d131a5ebae29536ab70c32c6.json"
}
```
| 同步(记录前对象) | 2d35fb6b1ad5e5de7c3e41e9c1af8531a329e2ab | 2394df8fe0b4465c2272356d8dec9aaccf72ac4f | 2026-10-19T01:15:49Z |
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-19T01:15:18.866520+00:00",
"command": "make task-sync",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-regkb-corpus-wiring",
"before_head": "e53bb06fff4483ec523233f110dcd498b2ffe93b",
"after_head": "94c69b02b7b0458adbfba7dc1276b4fa30468b73",
"branch": "feature/regkb-corpus-wiring",
"target_branch": "main",
"target_head": "2d35fb6b1ad5e5de7c3e41e9c1af8531a329e2ab",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"Submodule path 'deps/development-manager': checked out '0552b7358d6955057d6eea090326f83317ed992a'",
"Submodule 'development/guidelines' (ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Development-Guidelines.git) registered for path 'development/guidelines'",
"Cloning into '/home/weichen/projects/Agent-System-Dev-wt-feature-regkb-corpus-wiring/deps/development-guidelines/deps/development-manager/development/guidelines'...",
"Submodule path 'development/guidelines': checked out '2688fd2be6a52c0bf110e7e6366b6f291ab5e4eb'",
"From ssh://git-ssh.u1680832.nyat.app:31411/weichen/Development-Manager",
" * [new branch] fix/agent-exec-gitlink-preparation -> origin/fix/agent-exec-gitlink-preparation",
" b178dec..6c01959 main -> origin/main",
"Submodule path 'deps/development-manager': checked out '6c019595fa02aa2d0a1a9b8f98fc224e69d2a901'",
"[worktree] materialize: recursive component checks passed",
"[worktree] after-sync: recursive component checks passed",
"admit: ok",
"[evidence] WARN JSON receipt line 125: unverified: recorded component state was not at its pinned SHA ——关键检查须重跑并以 make evidence 重新写入",
"[synced] sync_base=2d35fb6b1ad5e5de7c3e41e9c1af8531a329e2ab tested_head=94c69b02b7b0458adbfba7dc1276b4fa30468b73 checked_at=2026-10-19T01:15:49Z changed=1 sync_target=main",
"[next] 跑正式验收(make test 等),证据写入任务卡",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-regkb-corpus-wiring'"
],
"output_sha256": "b0a42367576f9e1d95bda34998ba5e877c5e1fe19764cefa4daa724ade872610",
"receipt_sha256": "21f367898e6165f9c638a68936407ced00464eef2eb3ff7d04cfeab5fdf9dc7d",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/21f367898e6165f9c638a68936407ced00464eef2eb3ff7d04cfeab5fdf9dc7d.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-19T01:15:55.262978+00:00",
"command": "bash /tmp/regkb-gate.sh /home/weichen/projects/Agent-System-Dev-wt-feature-regkb-corpus-wiring",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-regkb-corpus-wiring",
"before_head": "94c69b02b7b0458adbfba7dc1276b4fa30468b73",
"after_head": "94c69b02b7b0458adbfba7dc1276b4fa30468b73",
"branch": "feature/regkb-corpus-wiring",
"target_branch": "main",
"target_head": "2d35fb6b1ad5e5de7c3e41e9c1af8531a329e2ab",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "adc7e2a950d7a0ee0bab0c9e8b106d6b92fb8eb51dd62bf1fd05af4907370d4b",
"after_tracked_diff_sha256": "adc7e2a950d7a0ee0bab0c9e8b106d6b92fb8eb51dd62bf1fd05af4907370d4b",
"output_tail": [
"ok \tagent-system-rdm/internal/rdmapp/dhfmatrix\t0.003s [no tests to run]",
"ok \tagent-system-rdm/plugins/rdm\t0.069s",
"PASS rdm-kbreg",
"=== stage client-asset-secret-scan =<redacted>",
"scan: /home/weichen/projects/Agent-System-Dev/runtime/rdm1/current/htdocs",
"scan: 已核对 0 个凭据变量:<无>",
"PASS client-asset-secret-scan",
"regulations-kb: PASS"
],
"output_sha256": "845d41d71ec34de77b3a0acc8c014be16a60618828b887a655f6f933c46a2321",
"receipt_sha256": "8902a9ca2bb84d304471e18a2ac85134c5cf44a79833c1c812f081514f4d1681",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/8902a9ca2bb84d304471e18a2ac85134c5cf44a79833c1c812f081514f4d1681.json"
}
```
## 闭合记录(合入前折叠)
- 本卡在 PR #625(https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/625)合入前闭合并归档,随该 PR 一同合入。
- 该 PR 的合并提交即本任务的落地记录。
- 合入后无需回填,也无需单独的闭合 PR。
+481
View File
@@ -0,0 +1,481 @@
# feature/regulations-kb 任务卡
任务主记录:PR #614 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/614;状态:已完成(合入前闭合);owner:weichen
## 基线与授权
- 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= b5e23daed2f0ea46261979de1d62e4de0cfa88f9
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-regulations-kb(worktree);分支:feature/regulations-kb
- 分支类型:initiative;initiative_id:feature-regulations-kb;root_target:main;immediate_target:main;accepting_requirements:false
- 需求分流:verdict=NEW;selected_initiative=无;requirement_sha256=fa6ff4c75a01064e0aa767dc91455b8e5bcd0f5f29f59958962543c633bf2ba2;triage_receipt=/tmp/regkb-triage-20261018.json;receipt_sha256=907151e982da280292647462e8342fbbd1453a87565c887ef4cb2269f29eae03
- 授权与交付终点:用户 2026-10-18 指示“按照方案一步一步实现所有内容,并在完成后进行清理”(/goal)。授权范围 = 计划 U1–U9 的实施、验证、Review、各仓 PR 合入与安全收口,含新建 `Agent-System-KB-Regulations` 仓。未授权:生产部署、生产全量语料导入、发布受保护标准原文、法律适用性裁定、新增外部付费调用(真实搜索/MinerU 实网调用前须用户确认提供方与凭据)、高后果双钥匙操作。
- 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进)
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
- 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入)
- 人工决策点:仅限目标/范围/验收变更、重大取舍、高后果操作或无法自动判定的业务验收
- 当前阶段:合入核验与收口;当前增量:U1–U9 全部合入组件仓,Dev 承载 U1/U7 规格与 U8 组合
- 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位)
## 目标与非目标
- 用途与目标:建设可追溯的医疗器械法规知识库,RDM 以“受控语料库 + 真实网络搜索”双源核验法规结论,引用定位到版本、条款与原文片段,审计可重放且可检测篡改。
- 方案/计划:[docs/superpowers/plans/2026-10-18-regulations-knowledge-base-plan.md](../docs/superpowers/plans/2026-10-18-regulations-knowledge-base-plan.md)(单一正文,本卡不复制)。
- 接纳范围:计划 U1–U9;非目标见计划 Scope Boundaries(分布式向量库、自动法律适用裁定、持续法规监测、生产部署与全量导入)。
- 仓库分工:`Agent-System-KB-Regulations`(语料/解析/切片/检索/搜索与抓取证据);Backend(U9 公开扩展契约);RDM(U6/U7 编排、授权、引用、审计);Dev(本卡、U1 盘点规格、U8 组合)。组件仓按各自 AGENTS.md 与 AGENT-EXECUTION.md 交付。
- U1 产物位置调整:计划写 `docs/proposals/regulations-kb/corpus-inventory.md`;Dev 无该目录,U1 为只读调查,产物落在 host 豁免路径 `docs/superpowers/specs/2026-10-18-regulations-corpus-inventory.md`,U2 再带入新仓。
- 分级测试策略:组件仓单元/集成测试 + 各仓 CI(GATE);U8 组合验证在 Dev 最终窗口运行完整 CI。
- 验收条件:计划 Definition of Done;外部凭据缺失项(MinerU、搜索提供方实网)如实标 NOT_RUN 并给出补齐动作。
- 追加领域规则:语料原件、dump、索引与秘密不入 Git;法规原文按来源权利限制展示。
- 用户决策(2026-10-18,AskQuestion):① 授权 host 用 `~/.secrets/gitea` HOME 段 token 为新仓设置 Actions 机密 `SUBMODULE_TOKEN`(已设置,值未回显);② 搜索提供方先实现可插拔适配器(含智谱 web_search 实现)与模拟测试,实网联调 NOT_RUN,待用户确认后再跑;③ U3 用已有 MinerU 输出离线导入,同时实现 MinerU API 适配器(模拟测试),实网调用 NOT_RUN。
- 新仓:`weichen/Agent-System-KB-Regulations`(private,2026-10-18 经 API 创建);空根提交与 `dm governance init` 原样骨架由 host 绕过钩子提交(执行器尚不在 HEAD),其余经 agent-exec。分支保护待用户设置。
- 生命周期:U1–U9 合入或显式延期后置 `accepting_requirements=false`,`FINAL=1` 收口。
## 子任务登记
| 子任务分支 | 必需 | 状态 | PR |
|---|---|---|---|
| 无(各单元在组件仓独立分支交付,见「跨仓交付登记」) | 否 | — | — |
## Agent 实施收据
路由与 fail-stop 规则见根目录 AGENT-EXECUTION.md 与 policy/delivery.md;每次尝试一行,原始日志留在源码外收据路径。
| 单元 ID | 预期范围 | 配置摘要 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|---|---|---|---|---|---|---|---|---|---|---|
| dev-u8-regulations-composition | modules/{backend,documents,frontend,ui}、tests/integration/regulations-kb、tests/test_regulations_kb_pin.py、Makefile、PROJECT.md | caefcb72b970 | implementation | cursor→agy→pi | 1 | cursor(fresh_session,session not-observable) | success | 05a60f7 | never | /tmp/regkb-u8dev-receipt.json(收口后清理) |
| dev-u8-regulations-scan-default | run.sh、README、pin 测试(扫描默认目录去掉服务端 bin/) | caefcb72b970 | implementation | cursor→agy→pi | 1 | cursor(fresh_session) | success | 4764cb4 | never | /tmp/regkb-u8dev-fix-receipt.json(收口后清理) |
| dev-u8-merge-prep-frontend-pin | modules/frontend 还原到分支基线 92864db 以干净合并 main #617 | caefcb72b970 | implementation | cursor→agy→pi | 1 | cursor(fresh_session) | success | c1181d4 | never | /tmp/regkb-u8dev-prep-receipt.json(收口后清理) |
| dev-u8-readd-frontend-pin | modules/frontend → 50ec836(426d104 后代) | caefcb72b970 | implementation | cursor→agy→pi | 1 | cursor(fresh_session) | success | 9dd9f1a | never | /tmp/regkb-u8dev-readd-receipt.json(收口后清理) |
| 组件仓单元 | U2–U7、提供方、组合与 KB/RDM U8 | 各仓 AGENT-EXECUTION.md | implementation | cursor→agy→pi | 各 1 | cursor | success | 见各仓 PR 与任务卡 | never | 各仓任务卡 |
## 关联方向与规划
- 适用状态:适用
- 主记录路径/版本:docs/superpowers/plans/2026-10-18-regulations-knowledge-base-plan.md(本 PR 合入版本)
- 对应里程碑:法规知识库 U1–U9
## 需求分析
| ID | 描述 | 项目符合度及依据 | 优先级 | 验收条件 | 依赖 | 结论 |
|---|---|---|---|---|---|---|
| R1 | 受控法规语料:来源/许可盘点、解析切片、检索与版本发布(U1–U5) | 符合计划,KB 仓独立 | P0 | 计划 U1–U5 测试场景 | — | 已交付 |
| R2 | RDM 双源核验:缺任一通道报降级,不得显示已核验;审计批次防篡改(U6) | 符合 | P0 | U6 场景 | R1、R5 | 已交付 |
| R3 | 结构化引用:对话/文档/审计中定位到版本、条款与片段(U7) | 符合 | P0 | 引用合同 + U7 场景 | R2 | 已交付 |
| R4 | 组合、恢复、隐私与发布就绪(U8) | 符合 | P0 | 组合门禁 PASS | R1–R3 | 已交付(部署/发布另行门禁) |
| R5 | EXT-20 公开扩展契约与提供方(U9) | 符合 | P0 | Backend/Documents 合入 | — | 已交付 |
## 方案与计划
- 方案引用:`docs/superpowers/plans/2026-10-18-regulations-knowledge-base-plan.md`(本分支 f61737b)
- 实施计划引用:同上 U1–U9;U1 产出 `docs/superpowers/specs/2026-10-18-regulations-corpus-inventory.md`
- 测试计划引用:同上 Verification Contract;各组件仓 CI 为 GATE
### 跨仓交付登记
| 单元 | 仓库/分支 | PR | 状态 |
|---|---|---|---|
| U1 | Dev `feature/regulations-kb`(规格文档) | [Dev #614](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/614) | 已提交,随本 PR 合入 |
| U2 | KB-Regulations `feature/u2-foundation` | [KB #1](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-KB-Regulations/pulls/1) | 已合入 7e962de |
| U3 | KB-Regulations `feature/u3-parse-chunk` | [KB #2](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-KB-Regulations/pulls/2) | 已合入 2f92a9f |
| U5 | KB-Regulations `feature/u5-web-evidence` | [KB #3](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-KB-Regulations/pulls/3) | 已合入 d208f40 |
| U9 | Backend `feature/regulations-kb-ext20` | [Backend #212](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Backend/pulls/212) | 已合入 56a7f9f |
| U9 | Documents `feature/regulations-kb-ext20-proposal` | [Documents #113](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Documents/pulls/113) | 已合入 5bb4877 |
| U4 | KB-Regulations `feature/u4-retrieval` | [KB #4](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-KB-Regulations/pulls/4) | 已合入 6c3fbbe |
| U6 | RDM `feature/regulations-kb-dual-source` | [RDM #434](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/pulls/434) | 已合入 703e41d(Backend pin 56a7f9f) |
| EXT-20 提供方 | KB-Regulations `feature/kbreg-provider` | [KB #5](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-KB-Regulations/pulls/5) | 已合入 d6d7056 |
| U7 前端 | Frontend `feature/regulations-kb-citations` | [Frontend #109](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Frontend/pulls/109) | 已合入 2d65a81 |
| U7 契约 | Dev `docs/superpowers/specs/2026-10-18-regulations-citation-contract.md` | [Dev #614](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/614) | 已提交 06dd79c |
| U7 RDM | RDM `feature/regulations-kb-citations` | [RDM #437](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/pulls/437) | 已合入 3cc91de |
| 组合注册 + RDM U8 测试 | RDM `feature/regulations-kb-composition`(KB gitlink、kbreg 插件、组合测试) | [RDM #438](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/pulls/438) | 已合入 ece91da |
| U8 KB 运维与恢复测试 | KB-Regulations `feature/u8-operations` | [KB #6](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-KB-Regulations/pulls/6) | 已合入 5dddad2 |
| U7 前端卡状态修正 | Frontend `fix/close-regulations-kb-citations-card` | [Frontend #110](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Frontend/pulls/110) | 已合入 50ec836 |
| U8 Dev 组合 | Dev `feature/regulations-kb`(四个 gitlink + `make test-regulations-kb`) | [Dev #614](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/614) | 随本 PR 合入 |
## 阶段记录
| 阶段 | 对象版本 | 状态 | 决策/执行者 | 时间 | 依据 |
|---|---|---|---|---|---|
| 需求拆解 | 计划 f61737b | 完成 | 用户 /goal + host | 2026-10-18 | 计划 U1–U9 |
| 需求评估 | 计划 f61737b | 完成 | host | 2026-10-18 | 需求表 R1–R5 |
| 需求表确认 | 计划 f61737b | 完成 | 用户(/goal 一次确认 + AskQuestion 三项决策) | 2026-10-18 | 基线与授权 |
| 方案设计 | 计划 + 引用合同 06dd79c | 完成 | host | 2026-10-18 | docs/superpowers |
| 实施计划 | 计划 U1–U9 | 完成 | host | 2026-10-18 | 跨仓交付登记 |
| 实施与自检 | 各仓 PR head | 完成 | cursor worker(新进程/隔离工作区) | 2026-10-18 | Agent 实施收据 |
| 正式测试与验收 | Dev 4764cb4 + RDM ece91da + KB 5dddad2 | 完成(SELF 本地;GATE 见各仓 CI) | host | 2026-10-18 | 证据表 |
| 代码 Review | 各单元 diff | 完成 | host 主模型(未复用实施会话) | 2026-10-18 | 合入与清理 |
| 合入 | Dev #614 | 进行中 | host | 2026-10-18 | 当前 HEAD CI 通过后合入 |
| 合入核验与收口 | — | 待执行 | host | — | 清理记录 |
## 探索试验与迭代
| 增量/试验 | 假设 | 范围 | 判断和停止条件 | 授权/决策依据 | 结果 | 变更影响 | 需重审补测 |
|---|---|---|---|---|---|---|---|
| 无 | — | — | — | — | — | — | — |
## 同步记录
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|---|---|---|---|
| 启动 | b5e23daed2f0ea46261979de1d62e4de0cfa88f9 | b5e23daed2f0ea46261979de1d62e4de0cfa88f9 | 2026-10-18T09:17:44Z |
## 证据(Evidence)
<!-- CMD="<命令>" make evidence 写入;手抄/转写输出视为无效证据(AGENTS.md 证据与验证门禁)。 -->
| 时间(UTC) | 命令 | 被测HEAD | exit | 来源 | sha256(16) |
|---|---|---|---|---|---|
## 交付调度
- 调度状态:未入队;调度记录:无
- entry_id:无;attempt_id:无;窗口执行者:无
- 固定候选:无(base/head、组件与相关配置引用实际尝试)
- 调度依据:policy/delivery.md#合入调度
- 固定后证据:源码外 RECEIPT;实际结果后按授权原样导入和闭合
## 结果与验证
- 结果:U1 盘点规格与 U7 引用合同(本 PR);KB-Regulations #1–#6(基础契约、解析切片/MinerU 适配、网络搜索与 SSRF 安全抓取、检索/发布门禁、EXT-20 提供方、运维与恢复测试);Backend #212、Documents #113(EXT-20);RDM #434(双源核验与封印审计批次)、#437(结构化引用)、#438(kbreg 组合与组合测试);Frontend #109/#110(引用渲染);本 PR 固定 backend 56a7f9f、documents 5bb4877、frontend 50ec836、ui 5c2b103,并新增 `make test-regulations-kb`(固定 RDM ece91da、KB 5dddad2)。
- 验证:GATE——KB main 5dddad2(test、test-pg、governance)、d6d7056;RDM main 3cc91de、ece91da(build-and-test 首跑因既有不稳定测试 TestSlowLedgerPersistsLifecycle 失败,重跑 job 6149 通过;governance);Frontend 2d65a81、50ec836(governance);Dev 本 PR 当前 HEAD CI 见合入记录。SELF——Dev `make test` exit 0(umask 022;此前两次失败分别因嵌套子模块未物化与本机 umask 077 使 Backend TestDSNFileMode 误报,均已如实记录);`make test-regulations-kb` PASS(一次性 pgvector pg16,三阶段 kb-test-pg / rdm-kbreg 12 个目标测试 / 客户端制品凭据扫描)。NOT_RUN——真实智谱搜索、MinerU 实网调用与真实嵌入(待用户确认提供方与凭据)。
- 影响与剩余项:新仓 Agent-System-KB-Regulations 分支保护待用户设置;RDM 需求文档同步为非阻塞后续;部署、版本发布、生产语料导入与业务/法务验收为后续独立门禁。非阻塞记录:RDM TestSlowLedgerPersistsLifecycle 存在内存终态先于台账回写的竞态(waitDone 只等内存状态)。
## 规划进展与下一步
- 本次推进/剩余:计划 U1–U9 全部交付;剩余为实网联调与部署类后续门禁
- 首选下一任务:真实搜索/MinerU/嵌入实网联调(需用户确认提供方、凭据与费用)
- 推荐依据:计划 Verification Contract 中唯一 NOT_RUN 的能力验证
- 前置条件/待确认:用户批准外部付费调用并经环境注入凭据
- 预期产物/验收条件:KB `KBREG_*` 实网冒烟记录,不入库任何凭据
- 重复任务核对:无在途同类任务
- 启动授权:未授权(建议不自动启动新任务,仍须明确授权)
## 合入与清理
- Review 记录:host 主模型逐个审阅各单元 diff(Dev 05a60f7/4764cb4/c1181d4/9dd9f1a,组件仓见各 PR),实施均由独立 cursor worker 新进程完成,审阅未复用实施会话;Dev U8 审阅发现扫描默认目录含服务端 bin/ 必然误报,已由 dev-u8-regulations-scan-default 修复;其余无阻塞项。
- 冲突记录:main #617 将 modules/frontend 改钉 426d104,与本分支 50ec836 冲突;准备单元还原到基线后干净合并(d5d6f70),再由单元钉回 50ec836(426d104 的后代,仅加卡状态修正);modules/ui 两侧同为 5c2b103。
- CI 记录:NOT_RUN(当前 HEAD 完整 SHA、全部必需检查、运行链接、执行身份及 GATE 结果)
- 合入记录:NOT_RUN(交付授权范围、PR、被核验 HEAD、合入 SHA、目标分支及内容核验)
- 清理记录:NOT_RUN(授权依据、写者退出确认、worktree/分支/任务卡处置)
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T09:17:02.121735+00:00",
"command": "make precheck",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev",
"before_head": "b5e23daed2f0ea46261979de1d62e4de0cfa88f9",
"after_head": "b5e23daed2f0ea46261979de1d62e4de0cfa88f9",
"branch": "main",
"target_branch": "main",
"target_head": "b5e23daed2f0ea46261979de1d62e4de0cfa88f9",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev'",
"[repo] branch=main head=b5e23daed2",
"[remote] origin/main=b5e23daed2 ahead=0 behind=0",
"[tree] clean submodules_drift=0 uninit=3",
"[warn] 3 个子模块未初始化——构建/测试前需物化(不阻断写入)",
"[worktrees] linked=8",
"[recycle] merged un-recycled branches: feature/layered-python-env",
"[initiatives] local cards (not authoritative): none",
"[hooks] core.hooksPath=scripts/hooks(pre-commit/post-merge 实际接线)",
"[facts] policy/facts.md 6 条事实均在有效期内",
"[required-reading] core/baseline.md, workflows/delivery.md §1, policy/delivery.md",
"[R0] b5e23daed2(完整:b5e23daed2f0ea46261979de1d62e4de0cfa88f9)",
"[worktree] before-sync: recursive component checks passed",
"[verdict] READY — 保留本次 precheck receipt 后建任务工作区:PRECHECK_RECEIPT=/tmp/task-precheck.json make task-start NAME=feature/your-branch",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev'"
],
"output_sha256": "cd85b90ba7dbefab03e6e67bc8d02a3ad658a219dd81d4547f5126d876af5d9c",
"receipt_sha256": "ae2713785b994cb723da45b2f9ebf2a2144ea6aed2efb91f1592c7f4819e8e4e",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/ae2713785b994cb723da45b2f9ebf2a2144ea6aed2efb91f1592c7f4819e8e4e.json"
}
```
| 同步(记录前对象) | ba81d638a6c845d0acde6896f4001bed096ba26c | fd2c13f4d883b1bff29d6ab0f82d64483e31ca24 | 2026-10-18T11:40:44Z |
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T11:57:02.728215+00:00",
"command": "make test",
"exit_code": 2,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-regulations-kb",
"before_head": "4764cb48118975b0bd05395eaafd31c545c242ed",
"after_head": "4764cb48118975b0bd05395eaafd31c545c242ed",
"branch": "feature/regulations-kb",
"target_branch": "main",
"target_head": "a5f3ce5ac1d1a5f366b08d8e87a1379f84ac7cdf",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev-wt-feature-regulations-kb'",
"python3 scripts/check-worktree.py verify",
"ERROR: uninitialized submodule: /home/weichen/projects/Agent-System-Dev-wt-feature-regulations-kb/modules/frontend/deps/development-guidelines; initialize and inspect it first",
"make[1]: *** [Makefile:227: test-worktree] Error 1",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-regulations-kb'"
],
"output_sha256": "97d03ed7bcee4e2a490075e1dc6dd6c7fba3ccdbfc81a5d2feb1c25322f3f32e",
"receipt_sha256": "56b0266357675abe038512ea28113c8586de5ddadb48872fd50cd1287da139a5",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/56b0266357675abe038512ea28113c8586de5ddadb48872fd50cd1287da139a5.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T12:05:04.108178+00:00",
"command": "make test",
"exit_code": 2,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-regulations-kb",
"before_head": "4764cb48118975b0bd05395eaafd31c545c242ed",
"after_head": "4764cb48118975b0bd05395eaafd31c545c242ed",
"branch": "feature/regulations-kb",
"target_branch": "main",
"target_head": "a5f3ce5ac1d1a5f366b08d8e87a1379f84ac7cdf",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e5b70873c6221fa2a87e84096e16c18a4aa9687792c533b0751fc35d78810d3a",
"after_tracked_diff_sha256": "e5b70873c6221fa2a87e84096e16c18a4aa9687792c533b0751fc35d78810d3a",
"output_tail": [
"用法:identity <ensure|verify|capabilities> --instance-id ID [--dbref REF] [--data DIR] [--dsn-file FILE]",
"ensured instance_id=svc-t1-abcdef123456 dbref=sqlite",
"identity verify: system identity mismatch: 库内 instance_id=\"svc-t1-abcdef123456\" dbref=\"sqlite\" ≠ 期望 \"svc-t1-zzzzzz999999\" / \"sqlite\"",
"identity verify: system identity mismatch: 库内 instance_id=\"svc-t1-abcdef123456\" dbref=\"sqlite\" ≠ 期望 \"svc-t1-abcdef123456\" / \"pg\"",
"identity verify: identity database missing: /tmp/TestVerifyMissingDBCreatesNothing4144307923/001/absent/agent-system.db",
"--- FAIL: TestDSNFileMode (0.00s)",
" identity_test.go:149: 0644 的 dsn 文件必须拒绝",
"ensured instance_id=svc-dsnenv-abcdef123456 dbref=sqlite",
"verified instance_id=svc-dsnenv-abcdef123456 dbref=sqlite schema_version=36",
"FAIL",
"FAIL\tagent-system-backend/pkg/identity\t0.073s",
"? \tagent-system-backend/web\t[no test files]",
"FAIL",
"make[1]: *** [Makefile:150: test-backend] Error 1",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-regulations-kb'"
],
"output_sha256": "58e94f00eb461e5e952041ad5f8fa26609b119f1d7b84675c7bf2e64ec5c5e6b",
"receipt_sha256": "6d89985942566c6003a138a4292cd61e5d0133d95ddde21fb49701acbbe7cd84",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/6d89985942566c6003a138a4292cd61e5d0133d95ddde21fb49701acbbe7cd84.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T12:15:32.512450+00:00",
"command": "make test",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-regulations-kb",
"before_head": "4764cb48118975b0bd05395eaafd31c545c242ed",
"after_head": "4764cb48118975b0bd05395eaafd31c545c242ed",
"branch": "feature/regulations-kb",
"target_branch": "main",
"target_head": "a5f3ce5ac1d1a5f366b08d8e87a1379f84ac7cdf",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "42a6b8866c32451b0dc56320446448cc2ce4350bc918c331660f707d8dd9bf6d",
"after_tracked_diff_sha256": "42a6b8866c32451b0dc56320446448cc2ce4350bc918c331660f707d8dd9bf6d",
"output_tail": [
"added 162 packages in 630ms",
"",
" RUN v4.1.11 /home/weichen/projects/Agent-System-Dev-wt-feature-regulations-kb/modules/ui",
"",
"",
" Test Files 19 passed (19)",
" Tests 178 passed (178)",
" Start at 12:22:06",
" Duration 1.52s (transform 691ms, setup 0ms, import 2.26s, tests 3.11s, environment 6.10s)",
"",
"knip unused exports 57 <= 57",
"cd deps/agent-command && go vet ./... && go test -count=1 ./...",
"ok \tagent-command\t0.003s",
"ok \tagent-command/conformance\t0.002s",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-regulations-kb'"
],
"output_sha256": "a72815b5e648b64aba5b4ce14f222f3e756c959ecc60f383c139231bca7a503d",
"receipt_sha256": "f25d5268ba68318504588ef006d34ef83956535a71237780d51ecc52c0bce76c",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/f25d5268ba68318504588ef006d34ef83956535a71237780d51ecc52c0bce76c.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T12:25:15.292941+00:00",
"command": "/tmp/regkb-pg-run.sh make test-regulations-kb",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-regulations-kb",
"before_head": "4764cb48118975b0bd05395eaafd31c545c242ed",
"after_head": "4764cb48118975b0bd05395eaafd31c545c242ed",
"branch": "feature/regulations-kb",
"target_branch": "main",
"target_head": "a5f3ce5ac1d1a5f366b08d8e87a1379f84ac7cdf",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "2cea7a6a2f3deef1d75ddd4348dfd1fa9a712b05c43a1ceccd62ec5bb3ad016d",
"after_tracked_diff_sha256": "2cea7a6a2f3deef1d75ddd4348dfd1fa9a712b05c43a1ceccd62ec5bb3ad016d",
"output_tail": [
"ok \tagent-system-kb-regulations/tests/webcapture\t0.005s",
"ok \tagent-system-kb-regulations/tests/websearch\t0.156s",
"make[2]: Leaving directory '/tmp/regkb-kb-5dddad2'",
"PASS kb-test-pg",
"=== stage rdm-kbreg ===",
"ok \tagent-system-rdm/plugins/kbreg\t0.006s",
"ok \tagent-system-rdm/internal/rdmapp\t0.039s",
"ok \tagent-system-rdm/plugins/rdm\t0.041s",
"PASS rdm-kbreg",
"=== stage client-asset-secret-scan =<redacted>",
"scan: /tmp/regkb-rdm-ece91da/.build/product/frontend/dist",
"scan: 已核对 0 个凭据变量:<无>",
"PASS client-asset-secret-scan",
"regulations-kb: PASS",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-regulations-kb'"
],
"output_sha256": "e63740d8864124a5082254e4da011ea44539f30e86f1147086cf9e4522affc3e",
"receipt_sha256": "1b63184493f6cf51a4d98a6e9b556201a5a7961392200986e90315aaf2ae515d",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/1b63184493f6cf51a4d98a6e9b556201a5a7961392200986e90315aaf2ae515d.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T12:40:24.125853+00:00",
"command": "make task-sync",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-regulations-kb",
"before_head": "d5134671ab6b45e6791c1ebcf8fcb5a10d6253d0",
"after_head": "d5134671ab6b45e6791c1ebcf8fcb5a10d6253d0",
"branch": "feature/regulations-kb",
"target_branch": "main",
"target_head": "a5f3ce5ac1d1a5f366b08d8e87a1379f84ac7cdf",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev-wt-feature-regulations-kb'",
"[worktree] before-sync: recursive component checks passed",
"[worktree] before-update: recursive component checks passed",
"[worktree] materialize: recursive component checks passed",
"[worktree] after-sync: recursive component checks passed",
"[evidence] WARN JSON receipt line 161: unverified: recorded component state was not at its pinned SHA ——关键检查须重跑并以 make evidence 重新写入",
"[evidence] WARN JSON receipt line 203: unverified: recorded component state was not at its pinned SHA ——关键检查须重跑并以 make evidence 重新写入",
"[evidence] WARN JSON receipt line 234: recorded HEAD predates non-card changes ——关键检查须重跑并以 make evidence 重新写入",
"[evidence] WARN JSON receipt line 275: recorded HEAD predates non-card changes ——关键检查须重跑并以 make evidence 重新写入",
"[evidence] WARN JSON receipt line 316: recorded HEAD predates non-card changes ——关键检查须重跑并以 make evidence 重新写入",
"[synced] sync_base=a5f3ce5ac1d1a5f366b08d8e87a1379f84ac7cdf tested_head=d5134671ab6b45e6791c1ebcf8fcb5a10d6253d0 checked_at=2026-10-18T12:40:58Z changed=0 sync_target=main",
"[next] 跑正式验收(make test 等),证据写入任务卡",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-regulations-kb'"
],
"output_sha256": "9e703c40b238a0b62b878f7ea256da658543ff7bbbdced7550e4827f3b248c59",
"receipt_sha256": "4e28bf18dd14890939bd04bf1910e874af9b29ced4b77128429e9825cda3791b",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/4e28bf18dd14890939bd04bf1910e874af9b29ced4b77128429e9825cda3791b.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T12:41:05.196483+00:00",
"command": "make test",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-regulations-kb",
"before_head": "0f6310aad06e9d3c8e8eea07612f0760df9b19e6",
"after_head": "0f6310aad06e9d3c8e8eea07612f0760df9b19e6",
"branch": "feature/regulations-kb",
"target_branch": "main",
"target_head": "a5f3ce5ac1d1a5f366b08d8e87a1379f84ac7cdf",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"added 162 packages in 711ms",
"",
" RUN v4.1.11 /home/weichen/projects/Agent-System-Dev-wt-feature-regulations-kb/modules/ui",
"",
"",
" Test Files 19 passed (19)",
" Tests 178 passed (178)",
" Start at 12:47:18",
" Duration 1.58s (transform 1.02s, setup 0ms, import 2.77s, tests 3.48s, environment 5.76s)",
"",
"knip unused exports 57 <= 57",
"cd deps/agent-command && go vet ./... && go test -count=1 ./...",
"ok \tagent-command\t0.002s",
"ok \tagent-command/conformance\t0.002s",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-regulations-kb'"
],
"output_sha256": "8fe21499ad31119df362f6f54d111368de6f081512939afd2289ef45d74f901c",
"receipt_sha256": "e43b0140f620e8db23c2505152b9ae42189a0f1160acb916cb1d648f7d66bd90",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/e43b0140f620e8db23c2505152b9ae42189a0f1160acb916cb1d648f7d66bd90.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T12:47:22.351043+00:00",
"command": "/tmp/regkb-pg-run.sh make test-regulations-kb",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-regulations-kb",
"before_head": "0f6310aad06e9d3c8e8eea07612f0760df9b19e6",
"after_head": "0f6310aad06e9d3c8e8eea07612f0760df9b19e6",
"branch": "feature/regulations-kb",
"target_branch": "main",
"target_head": "a5f3ce5ac1d1a5f366b08d8e87a1379f84ac7cdf",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "6b88a13df7ae72fb457b9506c3627fbc3789863e5a024b64a8934ccce11a1429",
"after_tracked_diff_sha256": "6b88a13df7ae72fb457b9506c3627fbc3789863e5a024b64a8934ccce11a1429",
"output_tail": [
"ok \tagent-system-kb-regulations/tests/webcapture\t0.006s",
"ok \tagent-system-kb-regulations/tests/websearch\t0.156s",
"make[2]: Leaving directory '/tmp/regkb-kb-5dddad2'",
"PASS kb-test-pg",
"=== stage rdm-kbreg ===",
"ok \tagent-system-rdm/plugins/kbreg\t0.004s",
"ok \tagent-system-rdm/internal/rdmapp\t0.036s",
"ok \tagent-system-rdm/plugins/rdm\t0.042s",
"PASS rdm-kbreg",
"=== stage client-asset-secret-scan =<redacted>",
"scan: /tmp/regkb-rdm-ece91da/.build/product/frontend/dist",
"scan: 已核对 0 个凭据变量:<无>",
"PASS client-asset-secret-scan",
"regulations-kb: PASS",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-regulations-kb'"
],
"output_sha256": "6f8c741beb6d20a67cda276273bd492b6addc4f94f3a4ac522e25be6bed32e40",
"receipt_sha256": "b108ee5862b15614431152bc83dd59aff7991abc7de5487722ec1cbcf1b908a6",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/b108ee5862b15614431152bc83dd59aff7991abc7de5487722ec1cbcf1b908a6.json"
}
```
## 闭合记录(合入前折叠)
- 本卡在 PR #614(https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/614)合入前闭合并归档,随该 PR 一同合入。
- 该 PR 的合并提交即本任务的落地记录。
- 合入后无需回填,也无需单独的闭合 PR。
File diff suppressed because one or more lines are too long
@@ -0,0 +1,260 @@
# feature/u8-sqlite-instance-guard-r2 任务卡
任务主记录:PR #615 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/615;状态:已完成(合入前闭合);owner:weichen
## 基线与授权
- 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= b5e23daed2f0ea46261979de1d62e4de0cfa88f9
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-u8-sqlite-instance-guard-r2(worktree);分支:feature/u8-sqlite-instance-guard-r2
- 分支类型:standalone;root_target:main;immediate_target:main;accepting_requirements:false
- 需求分流:verdict=NEW;selected_initiative=无;requirement_sha256=14dd98bb26f46929106a9d4b7b76b137d9d996953e3466612d8140a2ad7bb426;triage_receipt=/tmp/cleanup-20261018/u8r2-triage.json;receipt_sha256=7c12187e848a9851e0ae47b2fb9345de393ff5dcd1625be6e3fd952e087a8074
- 授权与交付终点:U8 方案与实施计划由用户 2026-10-12 批准(见旧卡 .task/feature-u8-sqlite-instance-guard.md,PR #482);2026-10-18 worktree 收尾会话中用户授权“U8 同步主干后推进到合入”。本任务交付 Backend PR #210 合入后的 Dev gitlink 固定、U8 规格与 svc 文档;终点为 Dev PR 合入并收口,关闭 #482(被本任务取代)
- 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进)
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
- 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入)
- 人工决策点:仅限目标/范围/验收变更、重大取舍、高后果操作或无法自动判定的业务验收
- 停止条件(沿用旧卡):需改 scripts/svc.sh、对外 HTTP 契约、登录页,或需 live 实例/共享 PG 写入/部署
- 当前阶段:实施与自检;当前增量:I1(U8 移植到当前主干)
- 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位)
## 目标与非目标
同一 SQLite 数据文件只允许一个活动服务运行时;应用连接核验 SQLite WAL+FULL,PostgreSQL 拒绝 fsync/full_page_writes/synchronous_commit 为 off(R11/R12,语义与旧卡一致)。旧 Backend PR #183 与 Dev PR #482 落后主干并有冲突(迁移号、main.go、PROJECT.md、architecture-baseline.json、gitlink),按治理规则不由 host 手解冲突,改为从当前主干新开 r2 由外部 worker 移植。
Dev 侧产物:`docs/recovery/u8-sqlite-instance-guard.md`、`docs/svc.md` 的 U8 段、`PROJECT.md` 与 `policy/architecture-baseline.json` 的必要登记、`modules/backend` gitlink 固定到 #210 合入后的 main SHA。
Dev pin 最终指向 Backend `276dd73824116fb55064eefef17f069ee1545ada`(Backend 主干含 #211 + U8 + development-manager 对齐)。
非目标:不改 scripts/svc.sh;不在 live 实例故障注入;不写共享 PostgreSQL;账户 CLI 迁移互斥归 U7。
## Agent 实施收据
路由与 fail-stop 规则见根目录 AGENT-EXECUTION.md 与 policy/delivery.md;每次尝试一行,原始日志留在源码外收据路径。
| 单元 ID | 预期范围 | 配置摘要 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|---|---|---|---|---|---|---|---|---|---|---|
| backend-u8-sqlite-instance-guard-port-r2 | Backend cmd/agent-system、cmd/storage-migrate、internal/{app,instanceguard,store} | AGENT-EXECUTION.md | implementation | cursor→agy→pi | 1 | cursor | completed | 7b379d28e74fc695dcda4750ad64f223d41ec5af(parent cac60c08,apply 快进到 Backend feature/u8-sqlite-instance-guard-r2) | 无 | /tmp/cleanup-20261018/u8-backend-port-run.json |
| dev-u8-sqlite-instance-guard-port-r2 | Dev docs/recovery、docs/svc.md、PROJECT.md、policy/architecture-baseline.json、modules/backend | AGENT-EXECUTION.md | implementation | cursor→agy→pi | 1 | cursor | completed | b829de223b7a516f6b3206ed5eb0a3ced43df3d5(parent 0968a86,apply 快进) | 无 | /tmp/cleanup-20261018/u8-dev-port-run.json |
| dev-u8-backend-repin-d7be3fd | modules/backend | AGENT-EXECUTION.md | implementation | cursor→agy→pi | 0 | — | invalid-config(canonical checkout is dirty:apply 后子模块检出未同步;未启动任何尝试,无副作用) | — | 无 | /tmp/cleanup-20261018/u8-dev-repin-run.json |
| dev-u8-backend-repin-d7be3fd | modules/backend | AGENT-EXECUTION.md | implementation | cursor→agy→pi | 1 | cursor | completed(子模块检出对齐到已记录 pin 后重新运行) | 6d9bd7c4306c22f694d0939e8b682e5f57933ea6(parent b829de2,apply 快进) | 无 | /tmp/cleanup-20261018/u8-dev-repin-run2.json |
| backend-u8-dm-pin-align | Backend deps/development-manager | AGENT-EXECUTION.md | implementation | cursor→agy→pi | 1 | cursor | completed | 276dd73824116fb55064eefef17f069ee1545ada(parent d7be3fd,apply 快进,已推送 #210) | 无 | /tmp/cleanup-20261018/u8-backend-dm-bump-run.json |
| dev-u8-backend-repin-276dd73 | modules/backend | AGENT-EXECUTION.md | implementation | cursor→agy→pi | 0 | — | invalid-config(canonical checkout is dirty:evidence 写卡未提交;未启动尝试,无副作用) | — | 无 | /tmp/cleanup-20261018/u8-dev-repin2-run.json |
| dev-u8-backend-repin-276dd73 | modules/backend | AGENT-EXECUTION.md | implementation | cursor→agy→pi | 1 | cursor | completed | 0c645e4524c4709a37104ef00d3383d03cfda738(parent b1a0c29,apply 快进) | 无 | /tmp/cleanup-20261018/u8-dev-repin2-run2.json |
组合指针对齐:Backend #208 引入的 `deps/development-manager` 固定在 `bd3a7de`,Dev 顶层为 `67784f4`(其后代,+22 提交),`make test-pins` 硬失败。最小修复为 #210 追加 gitlink 对齐提交 `276dd73`(Backend `agent-exec validate` 与 `dm governance check` 在新 pin 下通过),Dev pin 改指 `276dd73`,`test-pins` 通过。
扩围记录(用户 2026-10-18 授权):Dev 主干原 pin `b00e192`(管理员密码管理 + 解释器路径修复)从未进入 Backend 主干,直接改 pin 到 U8 会回退已部署功能。经授权先以 Backend PR #211 将其合入 Backend 主干(merge `a670d2b`,PR HEAD `78ae397` CI 通过),再把 #210 与主干同步为 `d7be3fd`(CI 通过)并追加对齐提交 `276dd73`;#210 以 fast-forward 合入后 Backend 主干即为 `276dd73`,与 Dev pin 一致。
## 关联方向与规划
- 适用状态:已有主记录(恢复方案 r3 U8,用户 2026-10-12 批准)
- 主记录路径/版本:modules/documents/docs/proposals/2026-10-12-service-restart-data-recovery.md(r3);规格 docs/recovery/u8-sqlite-instance-guard.md
- 对应里程碑:恢复方案 U8(批次 A0 的隔离半边)
## 需求分析
| ID | 描述 | 项目符合度及依据 | 优先级 | 验收条件 | 依赖 | 结论 |
|---|---|---|---|---|---|---|
| R11 | 同一 SQLite 只允许一个活动服务 | 需补齐;主干无跨进程锁 | P0 | T8-1–T8-5(规格第 5 节) | recovery U1 身份 | 纳入(沿用 2026-10-12 批准) |
| R12 | 应用连接上的耐久档可核验 | 需补齐;DSN 无 synchronous=FULL 也无读回 | P0 | T8-6 | 无 | 纳入(沿用 2026-10-12 批准) |
## 方案与计划
- 方案引用:恢复方案 r3 U8;规格 docs/recovery/u8-sqlite-instance-guard.md(本分支由 worker 移植,迁移号随主干改为 v36)
- 实施计划引用:锁在 OpenSQLite 之前;instance_guard 为迁移 v36;migrate 子命令与 serve 共用 openServiceStore
- 测试计划引用:T8-1–T8-6 见规格第 5 节;PG 耐久在线拒绝只做策略函数单测,真实 PG 读回由 Dev CI test-backend-pg 覆盖
## 阶段记录
| 阶段 | 对象版本 | 状态 | 决策/执行者 | 时间 | 依据 |
|---|---|---|---|---|---|
| 需求拆解 | 恢复方案 r3 U8 | 通过 | 用户 | 2026-10-12 | 旧卡阶段评审;2026-10-18 用户授权同步主干推进到合入 |
| 需求评估 | 同上 | 通过 | 用户 | 2026-10-12 | 同上 |
| 需求表确认 | 同上 | 通过 | 用户 | 2026-10-12 | 同上 |
| 方案设计 | 同上 | 通过 | 用户 | 2026-10-12 | 同上 |
| 实施计划 | 旧卡与规格第 5 节 | 通过 | 用户 | 2026-10-12 | 同上;r2 仅移植,不改语义 |
| 实施与自检 | Backend 276dd73;Dev 3e32999 | 完成 | Cursor worker(5 次成功运行)+ host 集成 | 2026-10-18 | 实施收据表;host 本地组合树 go build/vet/test 与 test-boundaries/test-pins(SELF) |
| 正式测试与验收 | Dev 3e32999(pin Backend 276dd73) | 通过 | Gitea CI | 2026-10-18 | GATE:Dev runs/3775(test、test-pg、svc-realcombo);Backend runs/3773–3774(276dd73)、runs/3763–3764(#211 78ae397) |
| 代码 Review | Backend cac60c0..276dd73、ab12fea..b00e192;Dev b5e23da..3e32999 | 通过 | Host 主模型(非实施会话) | 2026-10-18 | 见“合入与清理 / Review 记录” |
| 合入 | 待定 | 待执行 | — | — | — |
| 合入核验与收口 | 待定 | 待执行 | — | — | — |
## 探索试验与迭代
| 增量/试验 | 假设 | 范围 | 判断和停止条件 | 授权/决策依据 | 结果 | 变更影响 | 需重审补测 |
|---|---|---|---|---|---|---|---|
| 待定义 | — | — | — | 待核对 | NOT_RUN | 待评估 | 待评估 |
## 同步记录
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|---|---|---|---|
| 启动 | b5e23daed2f0ea46261979de1d62e4de0cfa88f9 | b5e23daed2f0ea46261979de1d62e4de0cfa88f9 | 2026-10-18T09:22:34Z |
## 证据(Evidence)
<!-- CMD="<命令>" make evidence 写入;手抄/转写输出视为无效证据(AGENTS.md 证据与验证门禁)。 -->
| 时间(UTC) | 命令 | 被测HEAD | exit | 来源 | sha256(16) |
|---|---|---|---|---|---|
## 交付调度
- 调度状态:未入队;调度记录:无
- entry_id:无;attempt_id:无;窗口执行者:无
- 固定候选:无(base/head、组件与相关配置引用实际尝试)
- 调度依据:policy/delivery.md#合入调度
- 固定后证据:源码外 RECEIPT;实际结果后按授权原样导入和闭合
## 结果与验证
- 结果:U8 活动服务锁、耐久核验与 migrate 子命令移植到当前主干(Backend #210),Dev pin 与文档更新(本 PR);Backend 主干补齐 Dev 已部署的密码管理(#211);development-manager 组合指针对齐。
- 验证:Backend CI PASS(GATE:78ae397、7b379d2、d7be3fd、276dd73);Dev CI PASS(GATE:3e32999 runs/3775 test/test-pg/svc-realcombo);本地 test-boundaries/test-pins PASS(SELF,证据表);T8 故障注入、部署与运行验收 NOT_RUN(不在本任务范围)。
- 影响与剩余项:新增 Backend 表 v36;未部署。非阻塞记录:Backend `pkg/identity` TestDSNFileMode 依赖 umask 022,本机 umask 0077 下失败(CI 通过);Backend 分支 `fix/execenv-python-sandbox-path`、`feature/auth-one-time-password` 已被 #211 吸收,可在阶段 4 回收。
## 规划进展与下一步
- 本次推进/剩余:U8 实现与 pin 合入;Documents 正文确认状态回写与 U8 运行验收留待后续
- 首选下一任务:worktree 收尾计划的下一条线(RDM settings 同步主干并重做阶段 7)
- 推荐依据:用户 2026-10-18 授权的收尾顺序
- 前置条件/待确认:无
- 预期产物/验收条件:见收尾计划
- 重复任务核对:取代 Dev #482 与 Backend #183;旧任务卡 feature-u8-sqlite-instance-guard 随旧 worktree 放弃式回收
- 启动授权:未授权(建议不自动启动新任务,仍须明确授权)
## 合入与清理
- Review 记录:Host 主模型(未参与实施,worker 为独立 Cursor 进程)于 2026-10-18 审阅 Backend `cac60c0..7b379d2`(17 文件:迁移 v36、compat 36、storage-migrate 表清单、main.go migrate/adopt、DSN synchronous(FULL)+verifyDurability、openServiceStore 保留 S3/team 档拒绝就绪/系统身份核验)、`d7be3fd..276dd73`(仅 gitlink)、#211 `ab12fea..b00e192`(建号/随机重置单事务+审计+no-store)、Dev `b5e23da..3e32999`(文档与参考版仅 v28→v36 差异;PROJECT.md 仅两句;baseline 两条边)。无阻塞问题;重放依据为 Dev CI runs/3775 与 Backend CI runs/3773–3774。
- 冲突记录:旧分支(#482/#183)与主干冲突,不手解,改由 worker 在 R0 `b5e23da` 与 Backend `cac60c0` 上重新移植;#211/#210 经 Gitea 服务端无冲突同步主干(`78ae397`、`d7be3fd`,树已核实等于 merge-tree 结果);Dev task-sync changed=0。组合兼容由 Dev CI test-pg/svc-realcombo 核验。
- CI 记录:Dev 组合候选 `3e32999ca9a22eef866fbf32ba2638375896b4a6` runs/3775(test、test-pg、svc-realcombo)success;Backend `276dd73824116fb55064eefef17f069ee1545ada` runs/3773–3774(vet-and-test、governance)success;最终 HEAD 的 CI 以 PR #615 状态为准(GATE,Gitea Actions)。
- 合入记录:授权依据为用户 2026-10-18“U8 同步主干后推进到合入”及同日密码管理扩围授权。Backend #211 以 HEAD `78ae397` 合入 main(merge `a670d2b`);Backend #210 以 HEAD `276dd73` fast-forward 合入,Backend main = `276dd73824116fb55064eefef17f069ee1545ada`,与本 PR 的 `modules/backend` pin 一致。Dev PR #615 在最终 HEAD CI 通过后由智能体合入;#482 关闭并注明被取代。
- 清理记录:NOT_RUN(授权依据、写者退出确认、worktree/分支/任务卡处置)
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T09:21:46.646488+00:00",
"command": "make precheck",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev",
"before_head": "b5e23daed2f0ea46261979de1d62e4de0cfa88f9",
"after_head": "b5e23daed2f0ea46261979de1d62e4de0cfa88f9",
"branch": "main",
"target_branch": "main",
"target_head": "b5e23daed2f0ea46261979de1d62e4de0cfa88f9",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"make[1]: Entering directory '/home/weichen/projects/Agent-System-Dev'",
"[repo] branch=main head=b5e23daed2",
"[remote] origin/main=b5e23daed2 ahead=0 behind=0",
"[tree] clean submodules_drift=0 uninit=3",
"[warn] 3 个子模块未初始化——构建/测试前需物化(不阻断写入)",
"[worktrees] linked=9",
"[recycle] merged un-recycled branches: feature/layered-python-env",
"[initiatives] local cards (not authoritative): none",
"[hooks] core.hooksPath=scripts/hooks(pre-commit/post-merge 实际接线)",
"[facts] policy/facts.md 6 条事实均在有效期内",
"[required-reading] core/baseline.md, workflows/delivery.md §1, policy/delivery.md",
"[R0] b5e23daed2(完整:b5e23daed2f0ea46261979de1d62e4de0cfa88f9)",
"[worktree] before-sync: recursive component checks passed",
"[verdict] READY — 保留本次 precheck receipt 后建任务工作区:PRECHECK_RECEIPT=/tmp/task-precheck.json make task-start NAME=feature/your-branch",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev'"
],
"output_sha256": "db6d6c9f778b033c6a7ee0e6242afdcd5ae114fabf3ebec55d0cba732be99ea5",
"receipt_sha256": "5e0530e3a51eadb4c241dd4bb2332e9f7f5c828bec6d085619ab5cf8ec30551d",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/5e0530e3a51eadb4c241dd4bb2332e9f7f5c828bec6d085619ab5cf8ec30551d.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T09:40:43.429397+00:00",
"command": "make test-boundaries test-pins",
"exit_code": 2,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-u8-sqlite-instance-guard-r2",
"before_head": "a374cb83af0c0b3ffc7fb4b8fb0d2ee9e66cd793",
"after_head": "a374cb83af0c0b3ffc7fb4b8fb0d2ee9e66cd793",
"branch": "feature/u8-sqlite-instance-guard-r2",
"target_branch": "main",
"target_head": "b5e23daed2f0ea46261979de1d62e4de0cfa88f9",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"ok modules/backend logging-system",
"ok deps/agent-native agent-intent",
"warn: deps/agent-native deps/development-guidelines is 26b562d2e34f, Dev is 2688fd2be6a5",
"ok deps/agent-native error-code-system",
"ok deps/agent-native logging-system",
"ok deps/agent-squad agent-intent",
"ok deps/agent-squad agent-native",
"warn: deps/agent-squad deps/development-guidelines is 26b562d2e34f, Dev is 2688fd2be6a5",
"ok deps/agent-squad error-code-system",
"ok deps/agent-squad logging-system",
"warn: deps/agent-intent deps/development-guidelines is 26b562d2e34f, Dev is 2688fd2be6a5",
"ok deps/agent-intent error-code-system",
"ok deps/agent-intent logging-system",
"make[1]: *** [Makefile:192: test-pins] Error 1",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-u8-sqlite-instance-guard-r2'"
],
"output_sha256": "40b4bada2231b745080bd65b82a9eceb94ff042e2654f00c119518698f80ebd4",
"receipt_sha256": "90b6c0864e7dac1838ea43070d823ae13b360c24d6532085c7c09a7c3cfa5603",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/90b6c0864e7dac1838ea43070d823ae13b360c24d6532085c7c09a7c3cfa5603.json"
}
```
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-18T09:45:38.779500+00:00",
"command": "make test-boundaries test-pins",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-feature-u8-sqlite-instance-guard-r2",
"before_head": "0c645e4524c4709a37104ef00d3383d03cfda738",
"after_head": "0c645e4524c4709a37104ef00d3383d03cfda738",
"branch": "feature/u8-sqlite-instance-guard-r2",
"target_branch": "main",
"target_head": "b5e23daed2f0ea46261979de1d62e4de0cfa88f9",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"ok modules/backend logging-system",
"ok deps/agent-native agent-intent",
"warn: deps/agent-native deps/development-guidelines is 26b562d2e34f, Dev is 2688fd2be6a5",
"ok deps/agent-native error-code-system",
"ok deps/agent-native logging-system",
"ok deps/agent-squad agent-intent",
"ok deps/agent-squad agent-native",
"warn: deps/agent-squad deps/development-guidelines is 26b562d2e34f, Dev is 2688fd2be6a5",
"ok deps/agent-squad error-code-system",
"ok deps/agent-squad logging-system",
"warn: deps/agent-intent deps/development-guidelines is 26b562d2e34f, Dev is 2688fd2be6a5",
"ok deps/agent-intent error-code-system",
"ok deps/agent-intent logging-system",
"pins ok",
"make[1]: Leaving directory '/home/weichen/projects/Agent-System-Dev-wt-feature-u8-sqlite-instance-guard-r2'"
],
"output_sha256": "79539abc4b3e10f25c6a859b7b8d3e1f1c9b1da1945f117226803949b1c20397",
"receipt_sha256": "19650ed0a61f602519de399d0429fcb00029062249276b9ce43148b1f6db7968",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/19650ed0a61f602519de399d0429fcb00029062249276b9ce43148b1f6db7968.json"
}
```
## 闭合记录(合入前折叠)
- 本卡在 PR #615(https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/615)合入前闭合并归档,随该 PR 一同合入。
- 该 PR 的合并提交即本任务的落地记录。
- 合入后无需回填,也无需单独的闭合 PR。
@@ -1,6 +1,6 @@
# feature/work-companion-visibility 任务卡
任务主记录:[Dev PR #550](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/550);状态:进行中;owner:weichen
任务主记录:[Dev PR #550](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/550);状态:已完成(回填);owner:weichen
## 基线与授权
@@ -28,9 +28,9 @@
| ID | 描述 | 项目符合度及依据 | 优先级 | 验收条件 | 依赖 | 结论 |
|---|---|---|---|---|---|---|
| UI1 | 中栏消息按回合保持阅读顺序,过程输出归入对应轮次的折叠记录,最终回复直接展示 | 符合 DESIGN.md 对话优先 | P0 | 过程文本、思考、工具与最终文本顺序可辨;终态与刷新后可回看已保存过程 | 持久化契约 | 代码已合入组件;Dev/8788 待验 |
| UI2 | 工作卡只在可见的右侧工作栏完整展示;右栏关闭/文件模式时中栏提供完整替代 | 符合单对象单详细落位 | P0 | 同屏无重复完整工作卡;待确认动作始终可达 | UI 布局 | 代码已合入组件;Dev/8788 待验 |
| UI3 | 中右栏形成清晰视觉层级并减少重复导航 | 符合 DESIGN.md 四原则 | P1 | 桌面及窄屏可辨对话/工作/文件,浏览器截图可审阅 | UI1–2 | 代码已合入组件;Dev/8788 待验 |
| UI1 | 中栏消息按回合保持阅读顺序,过程输出归入对应轮次的折叠记录,最终回复直接展示 | 符合 DESIGN.md 对话优先 | P0 | 过程文本、思考、工具与最终文本顺序可辨;终态与刷新后可回看已保存过程 | 持久化契约 | 代码已合入;8788 用户验收通过(2026-10-15) |
| UI2 | 工作卡只在可见的右侧工作栏完整展示;右栏关闭/文件模式时中栏提供完整替代 | 符合单对象单详细落位 | P0 | 同屏无重复完整工作卡;待确认动作始终可达 | UI 布局 | 代码已合入;8788 用户验收通过(2026-10-15) |
| UI3 | 中右栏形成清晰视觉层级并减少重复导航 | 符合 DESIGN.md 四原则 | P1 | 桌面及窄屏可辨对话/工作/文件,浏览器截图可审阅 | UI1–2 | 代码已合入;8788 用户验收通过(2026-10-15) |
## 方案与计划
@@ -48,16 +48,24 @@
| 方案设计 | DESIGN.md §6/§9.6/§12.3 | 不适用 | weichen 连续授权 | 2026-10-14 | 用户明确要求必要时重设计快慢通道,设计按本卡 I1 收敛 |
| 实施计划 | 本卡 I1 | 不适用 | weichen 连续授权 | 2026-10-14 | 零付费实现与测试、跨仓组合及本机 8788 安全采用 |
| 实施与自检 | UI/Backend/Frontend 主干合入提交与 Dev 本分支 | 不适用 | weichen 连续授权 | 2026-10-14 | 本地 SELF 证据;阶段人工出口由连续授权覆盖,GATE/REPLAY 另核验 |
| 正式测试与验收 | 主干组件组合;8788 待部署 | 未评审 | — | — | 隔离浏览器与 Dev `make test` SELF 已记录;准确 HEAD CI 和真实 8788 未完成 |
| 正式测试与验收 | 8788 `rdm@f76839f`;Dev `99119a7` | 通过 | 用户正常账号 | 2026-10-15 | 中栏顺序、中右栏去重、最终回复后折叠回看三项由用户确认通过;合成浏览器 21 项为 SELF |
| 代码 Review | Frontend e10e447、Backend bb54191、UI fda7b0f | 通过 | /root/work_companion_review(独立只读智能体) | 2026-10-14 | 三项 Important 整改并重验,最后报告无 Critical/Important;Dev 组合 HEAD 后续复核 |
| 合入 | 待定 | 未评审 | — | — | — |
| 合入核验与收口 | 待定 | 未评审 | — | — | — |
| 合入 | Dev `99119a7` / PR #550 | 通过 | 已合入主干 | 2026-10-14 | 合并提交已在 origin/main;本次未重跑该 HEAD 的 CI |
| 合入核验与收口 | 闭合分支 feature/card-close-20261014-161949Z | 进行中 | — | — | 任务卡归档待闭合 PR 的当前 HEAD CI 通过后合入 |
## 探索试验与迭代
| 增量/试验 | 假设 | 范围 | 判断和停止条件 | 批准依据 | 结果 | 变更影响 | 需重审补测 |
|---|---|---|---|---|---|---|---|
| I1 隔离浏览器 | 中右栏同屏去重,终态后完整过程可回看 | 任务自有 Vite 预览、合成会话/事件/卡片;无用户数据或付费模型 | 15 场景、刷新和 320–1440px;只证明 UI/契约机制 | 本会话“开始实施直到完成”及后续 UI 要求 | SELF PASS,原始命令收据见下方;截图 `/tmp/work-companion-visibility-after-v2.png` | 视觉层级和回看机制可审阅 | 真 8788 待验 |
| I1 隔离浏览器 | 中右栏同屏去重,终态后完整过程可回看 | 任务自有 Vite 预览、合成会话/事件/卡片;无用户数据或付费模型 | 15 场景、刷新和 320–1440px;只证明 UI/契约机制 | 本会话“开始实施直到完成”及后续 UI 要求 | SELF PASS,原始命令收据见下方;截图 `/tmp/work-companion-visibility-after-v2.png` | 视觉层级和回看机制可审阅 | 8788 用户验收通过,见下方切换记录 |
## 8788 受控切换
- 结论:已切换,未回退。服务源 `rdm@f76839f56342bb5b1e55255feed6cb3cb67a406f`,release `rdm-f76839f-20261014T160614Z-4181552`,PID 4181823。实例 `svc-dev-328312de05f9`,数据根未改,基座 schema 31,RDM schema 6,两库 `quick_check=ok`。
- 停机快照:`runtime-backups/dev/cutover-8788-20261014T160508Z`。`MANIFEST` SHA-256 `690441fc264de870eae05e6ba989274f73a69eb20f9faee74709f4c21c30ff69`。清单校验、数据库完整性检查和表行数检查通过。表行数相同不证明每行内容相同。
- 用户验收(2026-10-15,正常账号):中栏顺序、中右栏去重、最终回复后折叠回看,三项通过。合成浏览器 21 项对 8788 实际页面通过(SELF,固定 Frontend `710ef83`)。
- 写入已放开。不得用切换前快照直接回退。
- 对齐后的启动检查为 READY,收据 `/tmp/cutover-8788-precheck-after-align-20261015.json`(SELF,`receipt_sha256=5bf461bc474de8a77ed2ba922a92e26fd27ce8cdd2ea874b78ecf9ae3fabb30a`)。切换过程收据在 `/tmp/cutover-8788-{stop,backup,deploy}-20261014.json`。
## 同步记录
@@ -79,11 +87,11 @@
- 调度依据:policy/merge-queue.md;新模式启用前按既有交付门禁
- 固定后证据:源码外 RECEIPT;实际结果后按授权原样导入和闭合
## 结果与验证(完成后填写)
## 结果与验证
- 结果:UI #55、Backend #199、Frontend #85 已合入各自主干;Dev 同步当前主干后固定 Backend `ead5ade`(包含 #199 与并行 #200)、Frontend `710ef83`、UI `7c35a78`;PR #550 的新 HEAD 待正式验收/CI。
- 验证:SELF:Frontend 272 单测、构建、15 个隔离浏览器场景;Backend `go test ./...`;Dev `make build` 与独立网络命名空间中的 `make test` 均 exit 0,完整收据见下方。此前无隔离 `make test` 因并发工作区占用固定 1880x 端口失败,失败原件保留;受影响用例隔离重放 PASS。准确 Dev PR HEAD CI、真实 8788 浏览器和 RDM 下游组合均 NOT_RUN。
- 影响与剩余项:Dev CI、RDM 精确 pin 和 8788 的身份/备份/回退/真实页面验收。
- 结果:UI #55、Backend #199、Frontend #85 与 Dev PR #550 已合入。8788 已切换到 `rdm@f76839f`,三项用户验收见「8788 受控切换」。
- 验证:隔离浏览器与本地测试的 SELF 收据仍见下方。8788 三项由用户于 2026-10-15 确认通过。本地 SELF 不代替 CI。
- 影响与剩余项:本闭合提交的 CI 通过后合入。写入已放开,不能用切换前快照直接回退。
## 规划进展与下一步
@@ -635,3 +643,9 @@
}
```
| 同步(记录前对象) | bc76b68cd075379122430acb24fa080b0a38ff5e | b1cb64c7f69d95382e42f385ab44065c290f8e16 | 2026-10-14T15:20:54Z |
## 闭合记录(card-autoclose 回填)
- 依据:merge 99119a733830bc120cd6747b8b61736ea6da6078(PR #550)已包含于 origin/main,分支成果已落盘;本段为合入后回填。
- 合并主题:Merge pull request 'Integrate work companion visibility across components' (#550) from feature/work-companion-visibility into main
- 归档:随闭合移入 .task/archive/;任务执行期的过程证据见原任务记录与 PR。
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,27 @@
{
"source": "SELF",
"authentication": "temporary API credentials; existing passwords unchanged; password login NOT_RUN",
"hostProjectId": "prj_8d20020e5b79",
"canonicalProjectId": "p-aea70b2559c6",
"accounts": {
"weichen": {
"conversationCreatedByUI": "cnv_a0bab630d4b5",
"projectVisible": true,
"otherAccountConversationAbsent": true,
"refreshPassed": true,
"ownFileVisible": true,
"otherAccountFileAbsent": true
},
"test": {
"conversationCreatedByUI": "cnv_36fecdb2d986",
"projectVisible": true,
"otherAccountConversationAbsent": true,
"refreshPassed": true,
"ownFileVisible": true,
"otherAccountFileAbsent": true
}
},
"pageerrorCount": 0,
"accountSwitchThroughLogout": true,
"driverSHA256": "d8b6b344a29c8914367e9530e74ebdf027563859efa3809110b82335d97f9f3b"
}
@@ -0,0 +1,83 @@
{
"source": "SELF",
"hostProjectId": "prj_8d20020e5b79",
"canonicalProjectId": "p-aea70b2559c6",
"account_visibility_and_private_creation": "PASS",
"private_peer_status": {
"weichen": {
"other_conversation": 404,
"other_original": 404
},
"test": {
"other_conversation": 404,
"other_original": 404
}
},
"cross_project_status": {
"conversation_list": 404,
"conversation_create": 404,
"artifacts": 404,
"domain_summary": 400
},
"global_duplicate_name_status": 409,
"preserved_business_rows": {
"agent-system.db:users": {
"old_preserved": 12,
"current": 12
},
"agent-system.db:projects": {
"old_preserved": 3,
"current": 3
},
"agent-system.db:conversations": {
"old_preserved": 7,
"current": 9
},
"agent-system.db:messages": {
"old_preserved": 35,
"current": 35
},
"agent-system.db:artifacts": {
"old_preserved": 14,
"current": 16
},
"agent-system.db:agent_system_identity": {
"old_preserved": 1,
"current": 1
},
"rdm.db:rdm_projects": {
"old_preserved": 1,
"current": 2
},
"rdm.db:rdm_host_project_map": {
"old_preserved": 1,
"current": 2
},
"rdm.db:rdm_members": {
"old_preserved": 6,
"current": 8
},
"rdm.db:rdm_admins": {
"old_preserved": 1,
"current": 1
}
},
"original_artifact_bytes_preserved": 14,
"fixtures": {
"conversations": {
"weichen": "cnv_7c6d2eb980cc",
"test": "cnv_dbae0c998eec"
},
"artifacts": {
"weichen": {
"id": "art_11ea0ec72767",
"sha256": "816a6cbb70fcc550b860de78cf494f9d3bfd8f77a32c48d53a5dfd83359c1dfb"
},
"test": {
"id": "art_922d016bf0a0",
"sha256": "0d894a02ee84e7ba8122f06bf3a3f4d2c0d4c2ba0bab2575d8db285c9d158a3a"
}
}
},
"password_login": "NOT_RUN; user selected temporary API credentials"
}
@@ -0,0 +1,56 @@
import hashlib,json,secrets,sqlite3
from pathlib import Path
from collections import Counter
import client,prepare
W=client.W;HOST=prepare.HOST
adopt=json.loads((W/'adoption-result.json').read_text());PID=adopt['canonicalProjectId']
state_path=W/'http-fixtures.json';state=json.loads(state_path.read_text()) if state_path.exists() else {'conversations':{},'artifacts':{}}
def state_save():client.save('http-fixtures.json',state)
def ok(owner,path,method='GET',data=None,raw=False,headers=None):
code,out=client.request(owner,path,method,data,raw,headers);assert code==200,f'{owner} {method} {path} status={code}';return out
def deny(owner,path,method='GET',data=None):
code,_=client.request(owner,path,method,data);assert code in (403,404),f'{owner} {path} not denied ({code})';return code
for owner in ['weichen','test']:
me=ok(owner,'/api/me');assert me['owner']==owner
projects=ok(owner,'/api/projects');p=next(x for x in projects if x['id']==HOST)
assert p['settings']['rdm.projectId']==PID and p['settings']['rdm.state']=='ready'
if owner not in state['conversations']:
conv=ok(owner,'/api/projects/'+HOST+'/conversations','POST',{'title':'成员协作复测-'+owner+'-20261013'})
assert conv['owner']==owner and conv['projectId']==HOST
state['conversations'][owner]=conv['id'];state_save()
own_id=state['conversations'][owner]
assert ok(owner,'/api/conversations/'+own_id)['conversation']['owner']==owner
if owner not in state['artifacts']:
marker=('PROJECT_MEMBER_RUNTIME_PRIVATE_'+owner+'_20261013\n').encode()
boundary='PMR'+secrets.token_hex(16)
raw=(f'--{boundary}\r\nContent-Disposition: form-data; name="file"; filename="成员协作复测-{owner}-私有.txt"\r\nContent-Type: text/plain\r\n\r\n').encode()+marker+(f'\r\n--{boundary}--\r\n').encode()
files=ok(owner,'/api/projects/'+HOST+'/uploads','POST',raw,headers={'Content-Type':'multipart/form-data; boundary='+boundary})
state['artifacts'][owner]={'id':files[0]['artifactId'],'sha256':hashlib.sha256(marker).hexdigest()};state_save()
a=state['artifacts'][owner]
assert hashlib.sha256(ok(owner,'/api/artifacts/'+a['id']+'/content',raw=True)).hexdigest()==a['sha256']
with prepare.db(prepare.DATA/'agent-system.db') as c:
row=c.execute('select owner,project_id from artifacts where id=?',(a['id'],)).fetchone();assert tuple(row)==(owner,HOST)
private_status={}
for viewer,other in [('weichen','test'),('test','weichen')]:
private_status[viewer]={'other_conversation':deny(viewer,'/api/conversations/'+state['conversations'][other]),'other_original':deny(viewer,'/api/artifacts/'+state['artifacts'][other]['id']+'/content')}
assert state['conversations'][other] not in [x['id'] for x in ok(viewer,'/api/projects/'+HOST+'/conversations')]
assert state['artifacts'][other]['id'] not in [x['id'] for x in ok(viewer,'/api/projects/'+HOST+'/artifacts')]
foreign='prj_b32c62943fa3';foreign_pid='p-39dd859c3c99'
assert foreign not in [x['id'] for x in ok('test','/api/projects')]
foreign_status={'conversation_list':deny('test','/api/projects/'+foreign+'/conversations'),'conversation_create':deny('test','/api/projects/'+foreign+'/conversations','POST',{'title':'cross-project denial probe'}),'artifacts':deny('test','/api/projects/'+foreign+'/artifacts')}
code,denied=client.request('test','/api/commands/rdm.inspect.summary','POST',{'params':{'projectId':foreign_pid},'entrance':'workspace'})
assert code in (400,403,404) and denied.get('receipt',{}).get('state')=='rejected';foreign_status['domain_summary']=code
code,_=client.request('test','/api/projects','POST',{'name':'genui-e2e'});assert code==409,'global duplicate name was not rejected';duplicate_status=code
before=json.loads((W/'baseline-private.json').read_text());current=prepare.logical(prepare.DATA)
backup=Path(json.loads((W/'backup-location.json').read_text())['path'])
with prepare.db(backup/'dev/data/rdm.db') as c:
moved=Counter(prepare.digest(x) for x in c.execute('select * from rdm_members where project_id=?',(HOST,)))
preserved={}
for table,b in before['logical'].items():
expected=Counter(b['rows'])
if table=='rdm.db:rdm_members':expected-=moved
assert not expected-Counter(current[table]['rows']), 'old business rows changed: '+table
preserved[table]={'old_preserved':sum(expected.values()),'current':len(current[table]['rows'])}
for a in before['artifacts']:assert prepare.sha(Path(a['content_path']))==a['sha256']
result={'source':'SELF','hostProjectId':HOST,'canonicalProjectId':PID,'account_visibility_and_private_creation':'PASS','private_peer_status':private_status,'cross_project_status':foreign_status,'global_duplicate_name_status':duplicate_status,'preserved_business_rows':preserved,'original_artifact_bytes_preserved':len(before['artifacts']),'fixtures':state,'password_login':'NOT_RUN; user selected temporary API credentials'}
client.save('acceptance-http.json',result);print(json.dumps(result,ensure_ascii=False))
@@ -0,0 +1,56 @@
import hashlib,json,secrets,sqlite3
from pathlib import Path
from collections import Counter
import client,prepare
W=client.W;HOST=prepare.HOST
adopt=json.loads((W/'adoption-result.json').read_text());PID=adopt['canonicalProjectId']
state_path=W/'http-fixtures.json';state=json.loads(state_path.read_text()) if state_path.exists() else {'conversations':{},'artifacts':{}}
def state_save():client.save('http-fixtures.json',state)
def ok(owner,path,method='GET',data=None,raw=False,headers=None):
code,out=client.request(owner,path,method,data,raw,headers);assert code==200,f'{owner} {method} {path} status={code}';return out
def deny(owner,path,method='GET',data=None):
code,_=client.request(owner,path,method,data);assert code in (403,404),f'{owner} {path} not denied ({code})';return code
for owner in ['weichen','test']:
me=ok(owner,'/api/me');assert me['owner']==owner
projects=ok(owner,'/api/projects');p=next(x for x in projects if x['id']==HOST)
assert p['settings']['rdm.projectId']==PID and p['settings']['rdm.state']=='ready'
if owner not in state['conversations']:
conv=ok(owner,'/api/projects/'+HOST+'/conversations','POST',{'title':'成员协作复测-'+owner+'-20261013'})
assert conv['owner']==owner and conv['projectId']==HOST
state['conversations'][owner]=conv['id'];state_save()
own_id=state['conversations'][owner]
assert ok(owner,'/api/conversations/'+own_id)['conversation']['owner']==owner
if owner not in state['artifacts']:
marker=('PROJECT_MEMBER_RUNTIME_PRIVATE_'+owner+'_20261013\n').encode()
boundary='PMR'+secrets.token_hex(16)
raw=(f'--{boundary}\r\nContent-Disposition: form-data; name="file"; filename="成员协作复测-{owner}-私有.txt"\r\nContent-Type: text/plain\r\n\r\n').encode()+marker+(f'\r\n--{boundary}--\r\n').encode()
files=ok(owner,'/api/projects/'+HOST+'/uploads','POST',raw,headers={'Content-Type':'multipart/form-data; boundary='+boundary})
state['artifacts'][owner]={'id':files['artifactId'],'sha256':hashlib.sha256(marker).hexdigest()};state_save()
a=state['artifacts'][owner]
assert hashlib.sha256(ok(owner,'/api/artifacts/'+a['id']+'/content',raw=True)).hexdigest()==a['sha256']
with prepare.db(prepare.DATA/'agent-system.db') as c:
row=c.execute('select owner,project_id from artifacts where id=?',(a['id'],)).fetchone();assert tuple(row)==(owner,HOST)
private_status={}
for viewer,other in [('weichen','test'),('test','weichen')]:
private_status[viewer]={'other_conversation':deny(viewer,'/api/conversations/'+state['conversations'][other]),'other_original':deny(viewer,'/api/artifacts/'+state['artifacts'][other]['id']+'/content')}
assert state['conversations'][other] not in [x['id'] for x in ok(viewer,'/api/projects/'+HOST+'/conversations')]
assert state['artifacts'][other]['id'] not in [x['id'] for x in ok(viewer,'/api/projects/'+HOST+'/artifacts')]
foreign='prj_b32c62943fa3';foreign_pid='p-39dd859c3c99'
assert foreign not in [x['id'] for x in ok('test','/api/projects')]
foreign_status={'conversation_list':deny('test','/api/projects/'+foreign+'/conversations'),'conversation_create':deny('test','/api/projects/'+foreign+'/conversations','POST',{'title':'cross-project denial probe'}),'artifacts':deny('test','/api/projects/'+foreign+'/artifacts')}
code,denied=client.request('test','/api/commands/rdm.inspect.summary','POST',{'params':{'projectId':foreign_pid},'entrance':'workspace'})
assert code in (400,403,404) and denied.get('receipt',{}).get('state')=='rejected';foreign_status['domain_summary']=code
code,_=client.request('test','/api/projects','POST',{'name':'genui-e2e'});assert code==409,'global duplicate name was not rejected';duplicate_status=code
before=json.loads((W/'baseline-private.json').read_text());current=prepare.logical(prepare.DATA)
backup=Path(json.loads((W/'backup-location.json').read_text())['path'])
with prepare.db(backup/'dev/data/rdm.db') as c:
moved=Counter(prepare.digest(x) for x in c.execute('select * from rdm_members where project_id=?',(HOST,)))
preserved={}
for table,b in before['logical'].items():
expected=Counter(b['rows'])
if table=='rdm.db:rdm_members':expected-=moved
assert not expected-Counter(current[table]['rows']), 'old business rows changed: '+table
preserved[table]={'old_preserved':sum(expected.values()),'current':len(current[table]['rows'])}
for a in before['artifacts']:assert prepare.sha(Path(a['content_path']))==a['sha256']
result={'source':'SELF','hostProjectId':HOST,'canonicalProjectId':PID,'account_visibility_and_private_creation':'PASS','private_peer_status':private_status,'cross_project_status':foreign_status,'global_duplicate_name_status':duplicate_status,'preserved_business_rows':preserved,'original_artifact_bytes_preserved':len(before['artifacts']),'fixtures':state,'password_login':'NOT_RUN; user selected temporary API credentials'}
client.save('acceptance-http.json',result);print(json.dumps(result,ensure_ascii=False))
@@ -0,0 +1,57 @@
import hashlib,json,secrets,sqlite3
from pathlib import Path
from collections import Counter
import client,prepare
W=client.W;HOST=prepare.HOST
adopt=json.loads((W/'adoption-result.json').read_text());PID=adopt['canonicalProjectId']
state_path=W/'http-fixtures.json';state=json.loads(state_path.read_text()) if state_path.exists() else {'conversations':{},'artifacts':{}}
def state_save():client.save('http-fixtures.json',state)
def ok(owner,path,method='GET',data=None,raw=False,headers=None):
code,out=client.request(owner,path,method,data,raw,headers);assert code==200,f'{owner} {method} {path} status={code}';return out
def deny(owner,path,method='GET',data=None):
code,_=client.request(owner,path,method,data);assert code in (403,404),f'{owner} {path} not denied ({code})';return code
for owner in ['weichen','test']:
me=ok(owner,'/api/me');assert me['owner']==owner
projects=ok(owner,'/api/projects');p=next(x for x in projects if x['id']==HOST)
assert p['settings']['rdm.projectId']==PID and p['settings']['rdm.state']=='ready'
if owner not in state['conversations']:
conv=ok(owner,'/api/projects/'+HOST+'/conversations','POST',{'title':'成员协作复测-'+owner+'-20261013'})
assert conv['owner']==owner and conv['projectId']==HOST
state['conversations'][owner]=conv['id'];state_save()
own_id=state['conversations'][owner]
assert ok(owner,'/api/conversations/'+own_id)['conversation']['owner']==owner
if owner not in state['artifacts']:
marker=('PROJECT_MEMBER_RUNTIME_PRIVATE_'+owner+'_20261013\n').encode()
boundary='PMR'+secrets.token_hex(16)
raw=(f'--{boundary}\r\nContent-Disposition: form-data; name="file"; filename="成员协作复测-{owner}-私有.txt"\r\nContent-Type: text/plain\r\n\r\n').encode()+marker+(f'\r\n--{boundary}--\r\n').encode()
files=ok(owner,'/api/projects/'+HOST+'/uploads','POST',raw,headers={'Content-Type':'multipart/form-data; boundary='+boundary})
state['artifacts'][owner]={'id':files['artifactId'],'sha256':hashlib.sha256(marker).hexdigest()};state_save()
a=state['artifacts'][owner]
assert hashlib.sha256(ok(owner,'/api/artifacts/'+a['id']+'/content',raw=True)).hexdigest()==a['sha256']
with prepare.db(prepare.DATA/'agent-system.db') as c:
row=c.execute('select owner,project_id from artifacts where id=?',(a['id'],)).fetchone();assert tuple(row)==(owner,HOST)
private_status={}
for viewer,other in [('weichen','test'),('test','weichen')]:
private_status[viewer]={'other_conversation':deny(viewer,'/api/conversations/'+state['conversations'][other]),'other_original':deny(viewer,'/api/artifacts/'+state['artifacts'][other]['id']+'/content')}
assert state['conversations'][other] not in [x['id'] for x in ok(viewer,'/api/projects/'+HOST+'/conversations')]
assert state['artifacts'][other]['id'] not in [x['id'] for x in ok(viewer,'/api/projects/'+HOST+'/artifacts')]
foreign='prj_b32c62943fa3';foreign_pid='p-39dd859c3c99'
assert foreign not in [x['id'] for x in ok('test','/api/projects')]
foreign_status={'conversation_list':deny('test','/api/projects/'+foreign+'/conversations'),'conversation_create':deny('test','/api/projects/'+foreign+'/conversations','POST',{'title':'cross-project denial probe'}),'artifacts':deny('test','/api/projects/'+foreign+'/artifacts')}
code,denied=client.request('test','/api/commands/rdm.inspect.summary','POST',{'params':{'projectId':foreign_pid},'entrance':'workspace'})
assert code in (400,403,404) and denied.get('receipt',{}).get('state')=='rejected';foreign_status['domain_summary']=code
code,_=client.request('test','/api/projects','POST',{'name':'genui-e2e'});assert code==403,'member unexpectedly gained system project-create authority'
code,_=client.request('weichen','/api/projects','POST',{'name':'U7宿主项目'});assert code==409,'another owner project name was not globally reserved';duplicate_status=code
before=json.loads((W/'baseline-private.json').read_text());current=prepare.logical(prepare.DATA)
backup=Path(json.loads((W/'backup-location.json').read_text())['path'])
with prepare.db(backup/'dev/data/rdm.db') as c:
moved=Counter(prepare.digest(x) for x in c.execute('select * from rdm_members where project_id=?',(HOST,)))
preserved={}
for table,b in before['logical'].items():
expected=Counter(b['rows'])
if table=='rdm.db:rdm_members':expected-=moved
assert not expected-Counter(current[table]['rows']), 'old business rows changed: '+table
preserved[table]={'old_preserved':sum(expected.values()),'current':len(current[table]['rows'])}
for a in before['artifacts']:assert prepare.sha(Path(a['content_path']))==a['sha256']
result={'source':'SELF','hostProjectId':HOST,'canonicalProjectId':PID,'account_visibility_and_private_creation':'PASS','private_peer_status':private_status,'cross_project_status':foreign_status,'global_duplicate_name_status':duplicate_status,'preserved_business_rows':preserved,'original_artifact_bytes_preserved':len(before['artifacts']),'fixtures':state,'password_login':'NOT_RUN; user selected temporary API credentials'}
client.save('acceptance-http.json',result);print(json.dumps(result,ensure_ascii=False))
@@ -0,0 +1,35 @@
import json,sqlite3
from pathlib import Path
import client,prepare
W=client.W;HOST=prepare.HOST
preview=json.loads((W/'pre-repair-preview.json').read_text())['preview']
assert preview=={'hostProjectId':HOST,'name':'genui-e2e','memberCount':2,'alreadyBound':False}
with prepare.db(prepare.DATA/'agent-system.db') as c:
p=dict(c.execute('select id,name,owner from projects where id=?',(HOST,)).fetchone())
assert p=={'id':HOST,'name':'genui-e2e','owner':'weichen'}
assert c.execute('select count(*) from projects where trim(name)=? and id<>?',(p['name'],HOST)).fetchone()[0]==0
with prepare.db(prepare.DATA/'rdm.db') as c:
assert c.execute('select count(*) from rdm_project_names where name=?',(p['name'],)).fetchone()[0]==0,'reserved domain name conflict'
assert c.execute('select count(*) from rdm_projects where name=?',(p['name'],)).fetchone()[0]==0
assert c.execute('select count(*) from rdm_host_project_map where host_project=?',(HOST,)).fetchone()[0]==0,'binding changed; reconcile'
rows=[dict(x) for x in c.execute('select owner,role from rdm_members where project_id=? order by owner',(HOST,))]
assert rows==[{'owner':'test','role':'member'},{'owner':'weichen','role':'member'}]
print('PASS pre-apply identity, host/domain name reservation and membership conflict checks',flush=True)
out=client.command('weichen','rdm.project.adopt',{'hostProjectId':HOST,'apply':True})
assert out['id']==HOST and out['owner']=='weichen' and out['name']=='genui-e2e' and out['settings']['rdm.state']=='ready'
canonical=out['settings']['rdm.projectId']
with prepare.db(prepare.DATA/'rdm.db') as c:
binding=dict(c.execute('select * from rdm_host_project_map where host_project=?',(HOST,)).fetchone())
assert binding['rdm_project']==canonical and binding['created_by']=='weichen' and binding['state']=='ready'
roles=[dict(x) for x in c.execute('select owner,role from rdm_members where project_id=? order by owner',(canonical,))]
assert roles==[{'owner':'test','role':'member'},{'owner':'weichen','role':'owner'}]
assert c.execute('select count(*) from rdm_members where project_id=?',(HOST,)).fetchone()[0]==0
assert c.execute('select count(*) from rdm_projects where name=?',('genui-e2e',)).fetchone()[0]==1
for owner in ['weichen','test']:
code,projects=client.request(owner,'/api/projects');assert code==200
visible=next(x for x in projects if x['id']==HOST)
assert visible['settings']['rdm.projectId']==canonical and visible['settings']['rdm.state']=='ready'
repeat=client.command('weichen','rdm.project.adopt',{'hostProjectId':HOST,'apply':True})
assert repeat['id']==HOST and repeat['settings']['rdm.projectId']==canonical
result={'source':'SELF','hostProjectId':HOST,'name':'genui-e2e','owner':'weichen','canonicalProjectId':canonical,'binding':binding,'members':roles,'both_accounts_see_same_project':True,'repeat_apply_same_identity':True}
client.save('adoption-result.json',result);print(json.dumps(result,ensure_ascii=False))
@@ -0,0 +1,26 @@
{
"source": "SELF",
"hostProjectId": "prj_8d20020e5b79",
"name": "genui-e2e",
"owner": "weichen",
"canonicalProjectId": "p-aea70b2559c6",
"binding": {
"host_project": "prj_8d20020e5b79",
"rdm_project": "p-aea70b2559c6",
"state": "ready",
"created_by": "weichen",
"created_at": "2026-10-13T16:02:00.170829288Z"
},
"members": [
{
"owner": "test",
"role": "member"
},
{
"owner": "weichen",
"role": "owner"
}
],
"both_accounts_see_same_project": true,
"repeat_apply_same_identity": true
}
@@ -0,0 +1,105 @@
{
"source": "SELF",
"all_original_business_rows_preserved": true,
"databases": {
"agent-system.db": {
"original_tables_checked": 53,
"unchanged_original_rows": 88359,
"deltas": [
{
"table": "conversations",
"old_rows": 7,
"new_rows": 12,
"removed_or_changed_old_rows": 0,
"new_or_changed_rows": 5
},
{
"table": "artifacts",
"old_rows": 14,
"new_rows": 16,
"removed_or_changed_old_rows": 0,
"new_or_changed_rows": 2
},
{
"table": "api_keys",
"old_rows": 24,
"new_rows": 26,
"removed_or_changed_old_rows": 0,
"new_or_changed_rows": 2
},
{
"table": "command_audit",
"old_rows": 76895,
"new_rows": 76935,
"removed_or_changed_old_rows": 0,
"new_or_changed_rows": 40
},
{
"table": "sessions",
"old_rows": 34,
"new_rows": 34,
"removed_or_changed_old_rows": 1,
"new_or_changed_rows": 1
},
{
"table": "audit_events",
"old_rows": 86,
"new_rows": 96,
"removed_or_changed_old_rows": 0,
"new_or_changed_rows": 10
}
],
"new_tables": []
},
"rdm.db": {
"original_tables_checked": 25,
"unchanged_original_rows": 231,
"deltas": [
{
"table": "rdm_members",
"old_rows": 8,
"new_rows": 8,
"removed_or_changed_old_rows": 2,
"new_or_changed_rows": 2
},
{
"table": "rdm_projects",
"old_rows": 1,
"new_rows": 2,
"removed_or_changed_old_rows": 0,
"new_or_changed_rows": 1
},
{
"table": "rdm_host_project_map",
"old_rows": 1,
"new_rows": 2,
"removed_or_changed_old_rows": 0,
"new_or_changed_rows": 1
},
{
"table": "rdm_role_actions",
"old_rows": 1,
"new_rows": 2,
"removed_or_changed_old_rows": 0,
"new_or_changed_rows": 1
},
{
"table": "rdm_account_roles",
"old_rows": 1,
"new_rows": 2,
"removed_or_changed_old_rows": 0,
"new_or_changed_rows": 1
}
],
"new_tables": [
"rdm_project_names"
]
}
},
"auth_session_differences": 1,
"notes": [
"Only the two previewed host memberships were migrated; existing business rows in all other original tables are retained.",
"Session replacement and extra role/action rows were observed while the shared instance was in use; they were left untouched, not attributed to this operation.",
"Temporary test keys were revoked, and their plaintext file was removed."
]
}
@@ -0,0 +1,28 @@
import json
from pathlib import Path
from collections import Counter
import prepare
W=prepare.W;backup=Path(json.loads((W/'backup-location.json').read_text())['path'])
result={'source':'SELF','all_original_business_rows_preserved':True,'databases':{},'auth_session_differences':0}
for name in ['agent-system.db','rdm.db']:
with prepare.db(backup/'dev/data'/name) as a,prepare.db(prepare.DATA/name) as b:
old_tables=[r[0] for r in a.execute("select name from sqlite_master where type='table' and name not like 'sqlite_%'")]
new_tables=[r[0] for r in b.execute("select name from sqlite_master where type='table' and name not like 'sqlite_%'")]
assert set(old_tables)<=set(new_tables),'old table missing'
deltas=[];preserved=0
for table in old_tables:
escaped=table.replace('"','""');cols=[r['name'] for r in a.execute('pragma table_info("'+escaped+'")')]
query='select '+','.join('"'+c.replace('"','""')+'"' for c in cols)+' from "'+escaped+'"'
old=Counter(prepare.digest(r) for r in a.execute(query));new=Counter(prepare.digest(r) for r in b.execute(query))
missing=old-new
if table=='sessions':result['auth_session_differences']=sum(missing.values())
elif name=='rdm.db' and table=='rdm_members':
moved=Counter(prepare.digest(r) for r in a.execute('select * from rdm_members where project_id=?',(prepare.HOST,)))
assert missing==moved and sum(moved.values())==2,'unexpected membership removal'
else:assert not missing,'old business data changed: '+name+':'+table
preserved+=sum(old.values())-sum(missing.values())
if missing or new-old:deltas.append({'table':table,'old_rows':sum(old.values()),'new_rows':sum(new.values()),'removed_or_changed_old_rows':sum(missing.values()),'new_or_changed_rows':sum((new-old).values())})
result['databases'][name]={'original_tables_checked':len(old_tables),'unchanged_original_rows':preserved,'deltas':deltas,'new_tables':[t for t in new_tables if t not in old_tables]}
result['notes']=['Only the two previewed host memberships were migrated; existing business rows in all other original tables are retained.','Session replacement and extra role/action rows were observed while the shared instance was in use; they were left untouched, not attributed to this operation.','Temporary test keys were revoked, and their plaintext file was removed.']
p=W/'all-table-preservation.json';p.write_text(json.dumps(result,ensure_ascii=False,indent=2)+'\n');p.chmod(0o600)
print(json.dumps(result,ensure_ascii=False))
@@ -0,0 +1,34 @@
import json,os,re,sqlite3,subprocess,urllib.request,urllib.error
from pathlib import Path
W=Path('/tmp/project-member-runtime-8788-20261013');DATA=Path('/home/weichen/projects/Agent-System-Dev/runtime/dev/data')
ADMIN=Path('/home/weichen/projects/Agent-System-RDM-wt-feature-project-member-access/bin/agent-system-admin')
NAME='project-member-runtime-20261013';HOST='prj_8d20020e5b79';BASE='http://127.0.0.1:8788'
assert (W/'backup-proof.json').is_file()
assert not (W/'credentials.json').exists(),'credentials already created; reconcile before retry'
with sqlite3.connect('file:'+str(DATA/'agent-system.db')+'?mode=ro',uri=True) as c:
assert c.execute('select max(version) from schema_migrations').fetchone()[0]==30
assert c.execute('select count(*) from api_keys where name=? and revoked=0',(NAME,)).fetchone()[0]==0
assert c.execute("select count(*) from users where owner in ('weichen','test')").fetchone()[0]==2
creds={};p=W/'credentials.json'
env=dict(os.environ);env.pop('AGENT_SYSTEM_DSN',None)
for owner in ['weichen','test']:
r=subprocess.run([str(ADMIN),'apikey','create','--owner',owner,'--name',NAME,'--data',str(DATA)],capture_output=True,text=True,env=env)
assert r.returncode==0, 'temporary credential creation failed'
key=r.stdout.strip();assert re.fullmatch(r'ask_[A-Za-z0-9_-]+',key),'unexpected credential format'
creds[owner]=key;p.write_text(json.dumps(creds)+'\n');p.chmod(0o600)
def req(owner,path,method='GET',body=None):
r=urllib.request.Request(BASE+path,method=method,data=None if body is None else json.dumps(body).encode(),headers={'Authorization':'Bearer '+creds[owner],'Content-Type':'application/json','Origin':BASE})
try:
with urllib.request.urlopen(r,timeout=20) as x:return x.status,json.load(x)
except urllib.error.HTTPError as e:return e.code,json.loads(e.read())
result={}
for owner in creds:
status,me=req(owner,'/api/auth/me');assert status==200 and me['owner']==owner
status,projects=req(owner,'/api/projects');assert status==200
result[owner]={'authenticated_as':me['owner'],'visible_project_ids':[x['id'] for x in projects]}
assert HOST in result['weichen']['visible_project_ids'] and HOST not in result['test']['visible_project_ids']
status,_=req('test','/api/projects/'+HOST+'/conversations','POST',{'title':'membership pre-deploy denial probe'})
assert status in (403,404),'old member create unexpectedly admitted; reconcile new test data'
result['member_create_before_status']=status
(W/'before-http.json').write_text(json.dumps(result,ensure_ascii=False,indent=2)+'\n')
print(json.dumps({'source':'SELF','temporary_credentials':'created for existing weichen/test; values protected; passwords unchanged','before':result},ensure_ascii=False))
@@ -0,0 +1,19 @@
{
"source": "SELF",
"backup": "/home/weichen/projects/Agent-System-Dev/runtime-backups/dev/project-member-20261013T154718Z",
"instance": "svc-dev-328312de05f9",
"old_release_retained": "releases/rdm-84ca64f-20261013T143811Z-2735902",
"runtime_directories": [
"dev",
"devweb"
],
"full_release_count": 6,
"restored_databases": [
"agent-system.db",
"rdm.db"
],
"integrity_check": "ok",
"logical_rows_match": true,
"artifact_bytes_match": 14,
"manifest_sha256": "5ed67a4d7bf7d59668e7a2dccb59358086f10559cd4c69079285f1bd2f6b0f63"
}
@@ -0,0 +1,66 @@
import { chromium, expect } from '/home/weichen/projects/Agent-System-Dev-wt-feature-project-member-access/modules/frontend/node_modules/@playwright/test/index.mjs'
import fs from 'node:fs'
import crypto from 'node:crypto'
const W='/tmp/project-member-runtime-8788-20261013', base='http://127.0.0.1:8788'
const creds=JSON.parse(fs.readFileSync(W+'/credentials.json','utf8'))
const adoption=JSON.parse(fs.readFileSync(W+'/adoption-result.json','utf8'))
const host=adoption.hostProjectId, domain=adoption.canonicalProjectId
fs.mkdirSync(W+'/screenshots',{recursive:true,mode:0o700})
const errors=[], result={source:'SELF',authentication:'temporary API credentials; existing passwords unchanged; password login NOT_RUN',hostProjectId:host,canonicalProjectId:domain,accounts:{}}
const browser=await chromium.launch({headless:true})
const context=await browser.newContext({viewport:{width:1440,height:1000},locale:'zh-CN'})
const page=await context.newPage()
page.on('pageerror',e=>errors.push(e.message))
async function api(path,method='GET',body){
return await page.evaluate(async ({path,method,body})=>{
const headers={Authorization:'Bearer '+localStorage.getItem('agent-system.apiKey')}
if(body!==undefined)headers['Content-Type']='application/json'
const r=await fetch(path,{method,headers,body:body===undefined?undefined:JSON.stringify(body)})
const text=await r.text();return {status:r.status,body:text?JSON.parse(text):null}
},{path,method,body})
}
try{
await page.goto(base,{waitUntil:'domcontentloaded'})
await expect(page.getByRole('button',{name:'登录',exact:true})).toBeVisible()
for(const owner of ['weichen','test']){
const other=owner==='weichen'?'test':'weichen'
await page.evaluate(key=>localStorage.setItem('agent-system.apiKey',key),creds[owner])
await page.reload({waitUntil:'domcontentloaded'})
await expect(page.locator('.tsb-projrow-name')).toHaveText('genui-e2e',{timeout:20000})
const me=await api('/api/me');expect(me.status).toBe(200);expect(me.body.owner).toBe(owner)
const projects=await api('/api/projects');expect(projects.status).toBe(200)
expect(projects.body.map(p=>p.id)).toEqual([host]);expect(projects.body[0].settings['rdm.projectId']).toBe(domain)
await expect(page.locator('.tsb-task-t').filter({hasText:'成员协作复测-'+owner+'-20261013'})).toBeVisible()
await expect(page.locator('.tsb-task-t').filter({hasText:'成员协作复测-'+other+'-20261013'})).toHaveCount(0)
await page.locator('.tsb-projrow').click()
await expect(page.locator('.tsb-mi').filter({hasText:'U7宿主项目'})).toHaveCount(0)
await page.locator('.tsb-mi').filter({hasText:'genui-e2e'}).click()
const waiting=page.waitForResponse(r=>new URL(r.url()).pathname==='/api/projects/'+host+'/conversations'&&r.request().method()==='POST')
await page.getByRole('button',{name:'新建对话',exact:true}).click()
const response=await waiting;expect(response.status()).toBe(200)
const conv=await response.json();expect(conv.owner).toBe(owner);expect(conv.projectId).toBe(host)
result.accounts[owner]={conversationCreatedByUI:conv.id,projectVisible:true,otherAccountConversationAbsent:true}
fs.writeFileSync(W+'/browser-progress.json',JSON.stringify(result,null,2),{mode:0o600})
const title='成员协作浏览器复测-'+owner+'-20261013'
expect((await api('/api/conversations/'+conv.id,'PATCH',{title})).status).toBe(200)
await page.reload({waitUntil:'domcontentloaded'})
await expect(page.locator('.tsb-projrow-name')).toHaveText('genui-e2e',{timeout:20000})
await expect(page.locator('.tsb-task-t').filter({hasText:title})).toBeVisible()
await page.getByTitle('文件搜索、预览、编辑与下载').click()
await expect(page.locator('.artifacts-panel')).toBeVisible()
await expect(page.locator('.artifacts-panel .name').filter({hasText:'成员协作复测-'+owner+'-私有.txt'})).toBeVisible()
await expect(page.locator('.artifacts-panel .name').filter({hasText:'成员协作复测-'+other+'-私有.txt'})).toHaveCount(0)
await page.screenshot({path:W+'/screenshots/'+owner+'-private-project.png'})
Object.assign(result.accounts[owner],{refreshPassed:true,ownFileVisible:true,otherAccountFileAbsent:true})
await page.locator('.tsb-user').click()
await expect(page.getByText('租户:'+owner,{exact:true})).toBeVisible()
await page.getByRole('button',{name:'退出登录',exact:true}).click()
await expect(page.getByRole('button',{name:'登录',exact:true})).toBeVisible({timeout:15000})
expect(await page.evaluate(()=>localStorage.getItem('agent-system.apiKey'))).toBeNull()
}
expect(errors).toEqual([])
result.pageerrorCount=errors.length;result.accountSwitchThroughLogout=true
result.driverSHA256=crypto.createHash('sha256').update(fs.readFileSync(W+'/browser.mjs')).digest('hex')
fs.writeFileSync(W+'/acceptance-browser.json',JSON.stringify(result,null,2),{mode:0o600})
console.log(JSON.stringify(result))
}finally{await context.close();await browser.close()}
@@ -0,0 +1,13 @@
{
"source": "SELF",
"authentication": "temporary API credentials; existing passwords unchanged; password login NOT_RUN",
"hostProjectId": "prj_8d20020e5b79",
"canonicalProjectId": "p-aea70b2559c6",
"accounts": {
"weichen": {
"conversationCreatedByUI": "cnv_53ed2ce8df0d",
"projectVisible": true,
"otherAccountConversationAbsent": true
}
}
}
@@ -0,0 +1,66 @@
import { chromium, expect } from '/home/weichen/projects/Agent-System-Dev-wt-feature-project-member-access/modules/frontend/node_modules/@playwright/test/index.mjs'
import fs from 'node:fs'
import crypto from 'node:crypto'
const W='/tmp/project-member-runtime-8788-20261013', base='http://127.0.0.1:8788'
const creds=JSON.parse(fs.readFileSync(W+'/credentials.json','utf8'))
const adoption=JSON.parse(fs.readFileSync(W+'/adoption-result.json','utf8'))
const host=adoption.hostProjectId, domain=adoption.canonicalProjectId
fs.mkdirSync(W+'/screenshots',{recursive:true,mode:0o700})
const errors=[], result={source:'SELF',authentication:'temporary API credentials; existing passwords unchanged; password login NOT_RUN',hostProjectId:host,canonicalProjectId:domain,accounts:{}}
const browser=await chromium.launch({headless:true})
const context=await browser.newContext({viewport:{width:1440,height:1000},locale:'zh-CN'})
const page=await context.newPage()
page.on('pageerror',e=>errors.push(e.message))
async function api(path,method='GET',body){
return await page.evaluate(async ({path,method,body})=>{
const headers={Authorization:'Bearer '+localStorage.getItem('agent-system.apiKey')}
if(body!==undefined)headers['Content-Type']='application/json'
const r=await fetch(path,{method,headers,body:body===undefined?undefined:JSON.stringify(body)})
const text=await r.text();return {status:r.status,body:text?JSON.parse(text):null}
},{path,method,body})
}
try{
await page.goto(base,{waitUntil:'domcontentloaded'})
await expect(page.getByRole('button',{name:'登录',exact:true})).toBeVisible()
for(const owner of ['weichen','test']){
const other=owner==='weichen'?'test':'weichen'
await page.evaluate(key=>localStorage.setItem('agent-system.apiKey',key),creds[owner])
await page.reload({waitUntil:'domcontentloaded'})
await expect(page.locator('.tsb-projrow-name')).toHaveText('genui-e2e',{timeout:20000})
const me=await api('/api/me');expect(me.status).toBe(200);expect(me.body.owner).toBe(owner)
const projects=await api('/api/projects');expect(projects.status).toBe(200)
expect(projects.body.map(p=>p.id)).toEqual([host]);expect(projects.body[0].settings['rdm.projectId']).toBe(domain)
await expect(page.locator('.tsb-task-t').filter({hasText:'成员协作复测-'+owner+'-20261013'})).toBeVisible()
await expect(page.locator('.tsb-task-t').filter({hasText:'成员协作复测-'+other+'-20261013'})).toHaveCount(0)
await page.locator('.tsb-projrow').click()
await expect(page.locator('.tsb-mi').filter({hasText:'U7宿主项目'})).toHaveCount(0)
await page.locator('.tsb-mi').filter({hasText:'genui-e2e'}).click()
const waiting=page.waitForResponse(r=>new URL(r.url()).pathname==='/api/projects/'+host+'/conversations'&&r.request().method()==='POST')
await page.getByRole('button',{name:'新建对话',exact:true}).click()
const response=await waiting;expect(response.status()).toBe(200)
const conv=await response.json();expect(conv.owner).toBe(owner);expect(conv.projectId).toBe(host)
result.accounts[owner]={conversationCreatedByUI:conv.id,projectVisible:true,otherAccountConversationAbsent:true}
fs.writeFileSync(W+'/browser-progress.json',JSON.stringify(result,null,2),{mode:0o600})
const title='成员协作浏览器复测-'+owner+'-20261013-'+conv.id.slice(-6)
expect((await api('/api/conversations/'+conv.id,'PATCH',{title})).status).toBe(200)
await page.reload({waitUntil:'domcontentloaded'})
await expect(page.locator('.tsb-projrow-name')).toHaveText('genui-e2e',{timeout:20000})
await expect(page.locator('.tsb-task-t').filter({hasText:title})).toBeVisible()
await page.locator('.tsb-tool[title="文件搜索、预览、编辑与下载"]').click()
await expect(page.locator('.artifacts-panel')).toBeVisible()
await expect(page.locator('.artifacts-panel .name').filter({hasText:'成员协作复测-'+owner+'-私有.txt'})).toBeVisible()
await expect(page.locator('.artifacts-panel .name').filter({hasText:'成员协作复测-'+other+'-私有.txt'})).toHaveCount(0)
await page.screenshot({path:W+'/screenshots/'+owner+'-private-project.png'})
Object.assign(result.accounts[owner],{refreshPassed:true,ownFileVisible:true,otherAccountFileAbsent:true})
await page.locator('.tsb-user').click()
await expect(page.getByText('租户:'+owner,{exact:true})).toBeVisible()
await page.getByRole('button',{name:'退出登录',exact:true}).click()
await expect(page.getByRole('button',{name:'登录',exact:true})).toBeVisible({timeout:15000})
expect(await page.evaluate(()=>localStorage.getItem('agent-system.apiKey'))).toBeNull()
}
expect(errors).toEqual([])
result.pageerrorCount=errors.length;result.accountSwitchThroughLogout=true
result.driverSHA256=crypto.createHash('sha256').update(fs.readFileSync(W+'/browser.mjs')).digest('hex')
fs.writeFileSync(W+'/acceptance-browser.json',JSON.stringify(result,null,2),{mode:0o600})
console.log(JSON.stringify(result))
}finally{await context.close();await browser.close()}
@@ -0,0 +1,21 @@
import json,urllib.request,urllib.error
from pathlib import Path
W=Path('/tmp/project-member-runtime-8788-20261013');BASE='http://127.0.0.1:8788'
CREDS=json.loads((W/'credentials.json').read_text())
def request(owner,path,method='GET',data=None,raw=False,headers=None):
h={'Authorization':'Bearer '+CREDS[owner],'Origin':BASE}
if headers:h.update(headers)
if data is not None and not isinstance(data,bytes):data=json.dumps(data).encode();h['Content-Type']='application/json'
r=urllib.request.Request(BASE+path,method=method,data=data,headers=h)
try:
with urllib.request.urlopen(r,timeout=30) as x:code=x.status;body=x.read()
except urllib.error.HTTPError as e:code=e.code;body=e.read()
if raw:return code,body
try:return code,json.loads(body)
except (ValueError,UnicodeDecodeError):return code,{'non_json_bytes':len(body)}
def command(owner,name,params):
code,out=request(owner,'/api/commands/'+name,'POST',{'params':params,'entrance':'workspace'})
assert code==200 and out.get('receipt',{}).get('state')=='committed',f'{name} rejected status={code}'
return out['payload']
def save(name,obj):
p=W/name;p.write_text(json.dumps(obj,ensure_ascii=False,indent=2)+'\n');p.chmod(0o600)
@@ -0,0 +1,22 @@
{
"source": "SELF",
"operation": "succeeded",
"pid": 3896104,
"release": "releases/rdm-3f647f6-20261013T155418Z-3842908",
"binary_sha256": "d5db3d0ac292d99582ec91938317af356c050ad61e61f42c097e7faf7a731765",
"instance": "svc-dev-328312de05f9",
"root_http": 200,
"temporary_keys_revoked": {
"weichen": 401,
"test": 401
},
"plaintext_credential_file_removed": true,
"existing_accounts_and_passwords_unchanged": true,
"original_artifact_bytes_preserved": 14,
"auth_route": "temporary API credentials; password login NOT_RUN",
"verification_data_retained": {
"empty_conversations": 5,
"synthetic_private_files": 2
},
"worktrees_retained": true
}
@@ -0,0 +1,21 @@
import json,os,urllib.request,urllib.error
from pathlib import Path
import prepare
r=prepare.R;w=prepare.W
pid=int((r/'svc.pid').read_text());exe=Path(f'/proc/{pid}/exe').resolve()
assert exe==(r/'current/bin/agent-system').resolve()
assert prepare.sha(exe)=='d5db3d0ac292d99582ec91938317af356c050ad61e61f42c097e7faf7a731765'
assert os.readlink(r/'current').startswith('releases/rdm-3f647f6-')
assert json.loads((r/'manifest.json').read_text())['instance_id']==prepare.INSTANCE
with prepare.db(prepare.DATA/'rdm.db') as c:
b=dict(c.execute('select * from rdm_host_project_map where host_project=?',(prepare.HOST,)).fetchone())
assert b['rdm_project']=='p-aea70b2559c6' and b['state']=='ready' and b['created_by']=='weichen'
roles=[tuple(x) for x in c.execute('select owner,role from rdm_members where project_id=? order by owner',(b['rdm_project'],))]
assert roles==[('test','member'),('weichen','owner')]
with prepare.db(prepare.DATA/'agent-system.db') as c:
assert c.execute("select count(*) from api_keys where name='project-member-runtime-20261013' and revoked=0").fetchone()[0]==0
assert not (w/'credentials.json').exists()
with urllib.request.urlopen('http://127.0.0.1:8788/',timeout=15) as response:assert response.status==200
try:urllib.request.urlopen('http://127.0.0.1:8788/api/me',timeout=15);raise AssertionError('anonymous authenticated')
except urllib.error.HTTPError as error:assert error.code==401
print(json.dumps({'source':'SELF','pid':pid,'release':os.readlink(r/'current'),'binary_sha256':prepare.sha(exe),'instance':prepare.INSTANCE,'binding':b,'roles':roles,'root_status':200,'anonymous_me_status':401,'revocation_verified':True,'protected_plaintext_removed':True,'fixed_runtime_object_unchanged_after_record_sync':True},ensure_ascii=False))
@@ -0,0 +1,31 @@
import hashlib,json,os,subprocess,urllib.request
from pathlib import Path
import client,prepare
W=client.W;R=prepare.R;DATA=prepare.DATA
assert (W/'acceptance-http.json').is_file() and (W/'acceptance-browser.json').is_file()
assert Path('/tmp/project-member-runtime-independent-review.md').is_file()
ADMIN=Path('/home/weichen/projects/Agent-System-RDM-wt-feature-project-member-access/bin/agent-system-admin')
NAME='project-member-runtime-20261013'
env=dict(os.environ);env.pop('AGENT_SYSTEM_DSN',None)
results={}
for owner in ['weichen','test']:
with prepare.db(DATA/'agent-system.db') as c:
row=c.execute('select revoked from api_keys where owner=? and name=?',(owner,NAME)).fetchone();assert row is not None
if not row['revoked']:
r=subprocess.run([str(ADMIN),'apikey','revoke','--owner',owner,'--name',NAME,'--data',str(DATA)],capture_output=True,text=True,env=env)
assert r.returncode==0,'credential revocation failed; reconcile before retry'
code,_=client.request(owner,'/api/me');assert code==401,'revoked credential still admitted'
results[owner]=code
with prepare.db(DATA/'agent-system.db') as c:
assert c.execute('select count(*) from api_keys where name=? and revoked=0',(NAME,)).fetchone()[0]==0
with urllib.request.urlopen(client.BASE+'/',timeout=15) as res:assert res.status==200
before=json.loads((W/'baseline-private.json').read_text());now=prepare.logical(DATA)
assert now['agent-system.db:users']==before['logical']['agent-system.db:users'],'existing account/password state changed'
for a in before['artifacts']:assert prepare.sha(Path(a['content_path']))==a['sha256']
assert json.loads((R/'manifest.json').read_text())['instance_id']==prepare.INSTANCE
pid=int((R/'svc.pid').read_text());exe=Path(f'/proc/{pid}/exe').resolve()
assert exe==(R/'current/bin/agent-system').resolve()
assert prepare.sha(exe)=='d5db3d0ac292d99582ec91938317af356c050ad61e61f42c097e7faf7a731765'
(W/'credentials.json').unlink()
result={'source':'SELF','operation':'succeeded','pid':pid,'release':os.readlink(R/'current'),'binary_sha256':prepare.sha(exe),'instance':prepare.INSTANCE,'root_http':200,'temporary_keys_revoked':results,'plaintext_credential_file_removed':True,'existing_accounts_and_passwords_unchanged':True,'original_artifact_bytes_preserved':len(before['artifacts']),'auth_route':'temporary API credentials; password login NOT_RUN','verification_data_retained':{'empty_conversations':5,'synthetic_private_files':2},'worktrees_retained':True}
client.save('final-state.json',result);print(json.dumps(result,ensure_ascii=False))
@@ -0,0 +1,16 @@
{
"conversations": {
"weichen": "cnv_7c6d2eb980cc",
"test": "cnv_dbae0c998eec"
},
"artifacts": {
"weichen": {
"id": "art_11ea0ec72767",
"sha256": "816a6cbb70fcc550b860de78cf494f9d3bfd8f77a32c48d53a5dfd83359c1dfb"
},
"test": {
"id": "art_922d016bf0a0",
"sha256": "0d894a02ee84e7ba8122f06bf3a3f4d2c0d4c2ba0bab2575d8db285c9d158a3a"
}
}
}
@@ -0,0 +1,137 @@
[
{
"artifact": "prepare.py",
"original": "/tmp/project-member-runtime-8788-20261013/prepare.py",
"sha256": "1aa3456744928a5826a3307bf773e48a99100b862f43e48e792ce7955107ffe6"
},
{
"artifact": "auth_before.py",
"original": "/tmp/project-member-runtime-8788-20261013/auth_before.py",
"sha256": "b339053f774465031205840dec23cea8720f176c26ad46d46261002fd333d317"
},
{
"artifact": "client.py",
"original": "/tmp/project-member-runtime-8788-20261013/client.py",
"sha256": "060146ec7a2c23dcc1873a018536422d6779e610df8eb7486b2d8719b023ca45"
},
{
"artifact": "pre_repair.py",
"original": "/tmp/project-member-runtime-8788-20261013/pre_repair.py",
"sha256": "8a04b44489d25d5a2f99cdf911b310c36d3dda7688716d312ccfac4fd0c6ee3f"
},
{
"artifact": "adopt.py",
"original": "/tmp/project-member-runtime-8788-20261013/adopt.py",
"sha256": "74a4a45db8afc4424fe78af014531bcdfe32a3d2707d1f3591096553e58b7aa4"
},
{
"artifact": "acceptance_http.py",
"original": "/tmp/project-member-runtime-8788-20261013/acceptance_http.py",
"sha256": "3d4c995002bc944f9697255cc314a275d9fe1418eecb835e0939287c36f51e64"
},
{
"artifact": "acceptance_http-first-attempt.py",
"original": "/tmp/project-member-runtime-8788-20261013/acceptance_http-first-attempt.py",
"sha256": "8fd08a270270c055350d282cf4a67876a3e65e7878d6ef6171a346a2d5b70071"
},
{
"artifact": "acceptance_http-second-attempt.py",
"original": "/tmp/project-member-runtime-8788-20261013/acceptance_http-second-attempt.py",
"sha256": "227b4e9587f684ec47fcb647254819981f3983fba2a5dd7ad7d4e7f2d5d76e2c"
},
{
"artifact": "browser.mjs",
"original": "/tmp/project-member-runtime-8788-20261013/browser.mjs",
"sha256": "d8b6b344a29c8914367e9530e74ebdf027563859efa3809110b82335d97f9f3b"
},
{
"artifact": "browser-first-attempt.mjs",
"original": "/tmp/project-member-runtime-8788-20261013/browser-first-attempt.mjs",
"sha256": "3c48c89efbed139790e5c8a62e7df1bf9a34bc5d1fdd1cb5584475f379bb0304"
},
{
"artifact": "finalize.py",
"original": "/tmp/project-member-runtime-8788-20261013/finalize.py",
"sha256": "6d2b80aaec325d4a05308fd0e7b331fe08853bf4c2c798209df1a2b146f289f0"
},
{
"artifact": "audit_all.py",
"original": "/tmp/project-member-runtime-8788-20261013/audit_all.py",
"sha256": "02d0e618d3a660e93a830d36a5ee85fcf81ad3cffb3f5b49f2fd36023cf673c9"
},
{
"artifact": "operation.json",
"original": "/tmp/project-member-runtime-8788-20261013/operation.json",
"sha256": "870057794fa1fe32b98dc5b033d4f6d4d6c34708115d774c6a653677a5dcc300"
},
{
"artifact": "backup-proof.json",
"original": "/tmp/project-member-runtime-8788-20261013/backup-proof.json",
"sha256": "98e1471900efc9cb0dc69fca794fe2360a3eca7e323db524774554957310edcd"
},
{
"artifact": "pre-repair-preview.json",
"original": "/tmp/project-member-runtime-8788-20261013/pre-repair-preview.json",
"sha256": "b36a0551a0124070d1e3345773e60fc6be99c45041d0a2dd1192f77d69d05be1"
},
{
"artifact": "adoption-result.json",
"original": "/tmp/project-member-runtime-8788-20261013/adoption-result.json",
"sha256": "c7d2e5109eab686cdf1a83a03e73eb67dd9a0e882eed78927c9df6f0ed3dae47"
},
{
"artifact": "acceptance-http.json",
"original": "/tmp/project-member-runtime-8788-20261013/acceptance-http.json",
"sha256": "ebbcc0c7c39593c081ac272a719be5965f4abc8149600081950340d757214380"
},
{
"artifact": "acceptance-browser.json",
"original": "/tmp/project-member-runtime-8788-20261013/acceptance-browser.json",
"sha256": "c117285f82cf318053156501ad477988f26d54f42bebc94bf5173f3de9a0816e"
},
{
"artifact": "http-fixtures.json",
"original": "/tmp/project-member-runtime-8788-20261013/http-fixtures.json",
"sha256": "d704c41c94106c5e6d6edd056e48033a6639d1fe5d571748c89ff4f6999f96f6"
},
{
"artifact": "browser-progress-first-attempt.json",
"original": "/tmp/project-member-runtime-8788-20261013/browser-progress-first-attempt.json",
"sha256": "4fb7f942d5392a2c2711e739e3e0c3e544051e8b78bbde94cbb807a9a1e38676"
},
{
"artifact": "final-state.json",
"original": "/tmp/project-member-runtime-8788-20261013/final-state.json",
"sha256": "7fa895a2303aa2ea27c3e3d870fc6229a8806e96a0df6b97b9eb628fb5bad57e"
},
{
"artifact": "all-table-preservation.json",
"original": "/tmp/project-member-runtime-8788-20261013/all-table-preservation.json",
"sha256": "406352842d316e6f82150c68aca3227dc5c7788aa179cbc5f3736fd29ac4473b"
},
{
"artifact": "project-member-runtime-independent-review.md",
"original": "/tmp/project-member-runtime-independent-review.md",
"sha256": "7de2253c9d4cc0cf6bf4de0967f7a101778d20e0c036f3b6df554ecc34dc70e4"
},
{
"artifact": "project-member-runtime-independent-replay.json",
"original": "/tmp/project-member-runtime-independent-replay.json",
"sha256": "f025cedf0b92cae644852593436af7a56bab80ee06e522ba0635b367c7c31f9c"
},
{
"artifact": "project-member-runtime-independent-comparison-receipt.json",
"original": "/tmp/project-member-runtime-independent-comparison-receipt.json",
"sha256": "aa4e03d806cc1a4ea0e5a0c249bb9322366b422a181c53b40062ba58c99b3d90"
},
{
"artifact": "project-member-runtime-independent-attestation.json",
"original": "/tmp/project-member-runtime-independent-attestation.json",
"sha256": "a66ed3928a9f004233f49d67338412d688a5dd2e69c4cbac7ffedb8a3648bcd4"
},
{
"artifact": "final_live_check.py",
"original": "/tmp/project-member-runtime-8788-20261013/final_live_check.py",
"sha256": "c9e9b0a2fdf1c072b1669e2575e72dfcdfdfa17b53b19d079357b08307c2d081"
}
]
@@ -0,0 +1,66 @@
# 8788 项目成员修复运行交付
状态:已部署、已修复、运行验收通过。记录时间:2026-10-14T00:45:11.760482+08:00(Asia/Shanghai)。
用户授权本次保数据部署、旧绑定预览及无冲突后的修复、weichen/test 复测;用户另选临时 API 凭据,不改现有密码。密码登录链路为 NOT_RUN。
## 实际对象
| 对象 | 结果 |
|---|---|
| 实例 | `svc-dev-328312de05f9`,`127.0.0.1:8788` |
| RDM 固定提交 | `3f647f6c547d3f0d5ab65310cc5f3eabf66e654f` |
| 组件 tag | Backend/Core/Frontend/UI `v0.4.0` |
| Backend | `5d5fc9891c0eb8994545ccb8b740535d9b99fb0e` |
| Core | `5773e74086791731059730bd3726dc8c9cd1381f` |
| Frontend | `eb2d6d32f9323094d568bc9d80b4e5ed4f0af25b` |
| UI | `2c4322ef56df64ad72f65907d25b048a74bb5ffc` |
| 实际 release | `releases/rdm-3f647f6-20261013T155418Z-3842908` |
| 实际二进制 SHA256 | `d5db3d0ac292d99582ec91938317af356c050ad61e61f42c097e7faf7a731765` |
| 最终验收 PID | `3896104`,`/proc` executable 与 release 一致 |
| 数据 | 原 `runtime/dev/data/agent-system.db` 与 `rdm.db`;未换库、未清库 |
实际二进制与已验证默认组合产物字节一致。部署从固定提交物化四个 pins 并构建完整前端嵌入产物;devweb 伴生工作台也已由现有 svc 流程更新。源码和 tag 的审阅/CI 沿用已固定对象,[RDM CI2977](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/actions/runs/2977) 已在本任务重新核验;运行结果为 SELF,独立只读重放身份单独记录。
## 备份与修复
配对冷备份:`/home/weichen/projects/Agent-System-Dev/runtime-backups/dev/project-member-20261013T154718Z`。保留 dev/devweb 配置、两库、14 个原件以及全部 6 份旧 release。在隔离恢复副本实际打开两库,integrity_check 与原始业务行对账通过,原件摘要一致;备份包含完整清单摘要。
旧宿主 `prj_8d20020e5b79`(`genui-e2e`,owner=weichen)保持 ID、名称、所有者不变。预览显示两个孤立成员、无绑定;再次查询物理所有者、宿主/领域名称及名称预留、绑定和成员后确认无冲突,才调用 apply。
形成唯一领域根 `p-aea70b2559c6`,映射 ready。原两条孤立成员迁到该领域根:weichen 为 owner,test 为 member。重复 apply 返回相同身份,没有重复项目。其他旧项目、绑定和成员保留。
## 运行验证
| 场景 | 结果 |
|---|---|
| 修复前同一新制品 | test 无目标项目,新建会话 404;预览未改业务行 |
| 两账户可见性 | 均看到同一宿主/领域 ID |
| 新建对话 | HTTP 和实际浏览器按钮均成功,owner 为当前账户 |
| 私人会话与文件 | 本人可读;对方直接读取 404,列表不暴露 |
| 跨项目隔离 | test 对 U7 会话列表、新建会话、工件均 404;领域摘要命令被拒 |
| 全局同名 | 有创建权限的 weichen 创建另一账号已有的 U7 宿主项目名称,409 |
| 权限分离 | test 可在已加入项目建会话,但没有系统级创建项目权限,403 |
| 浏览器 | weichen→退出→test→退出、刷新、私人文件列表通过;pageerror=0 |
| 原始数据 | 原12账户、3宿主项目、7会话、35消息、14工件与全部原件字节保留;原其他项目成员未变 |
| 最终凭据 | 两枚临时 key 已撤销,分别实测401,明文文件已删除;原账户与密码字段不变 |
全表对账覆盖原基座53张表及RDM25张表。除两条目标孤立成员的预期迁移外,旧业务行保留。共享实例使用期间观察到一条登录会话替换以及额外角色/权限行增加,保持现状,不归因本次操作,不以旧备份覆盖这些新增状态。
本次保留5条有“成员协作”标记的验收空会话及2个合成私有文件,未发送模型消息。历史会话和原件未删除。临时凭据生命周期结束,密码登录按用户选择未测试。
## 证据和限制
完整命令收据由任务卡中的 evidence 工具生成,来源保持 SELF。独立审阅者 `/root/runtime_acceptance_review` 先独立重放再对照作者记录,结论 PASS;其原始收据、attestation 和报告在本目录。浏览器由本次操作者执行,独立审阅核对报告范围,未再次创建数据或重跑 UI。
截图保存在受保护目录:`/tmp/project-member-runtime-8788-20261013/screenshots/test-private-project.png` 与 `weichen-private-project.png`,未放入 Git。
早期探针失败均保留:身份接口误写为 `/api/auth/me`,旧版本 HTTP 对照未完成;后改用真实 `/api/me` 在新制品上验证绑定修复前后。上传应答被误按数组解析,回读已成功上传的工件后复用,没有重复上传。全局名称测试最初使用无创建权限的 test,改用有权限的 weichen 验证。浏览器文件入口定位命中两个同名按钮,改为明确侧栏入口后完整重跑通过。均为探针问题,未据此修改产品代码或伪记 PASS。
服务 history 记录部署启动后现有 recover 流程再次拉起进程;所有最终 HTTP、浏览器及独立验收均针对最终 PID 和上述同一制品完成。未推断 recover 的原因,未扩大修改服务管理实现。
操作完成后服务保持运行,工作区和分支保留。没有新增产品源码改动、tag 或产品 PR;本任务的运行记录保存在独立工作区,尚未合入 main。后续可用原有账户进行常规密码登录验收;本次已选的账户身份功能复测无剩余阻塞。
这些脚本是本次已执行操作的历史证据,含明确的 live 写入步骤;不能未经新的操作授权直接重跑。私有业务副本与认证材料未纳入本目录,原始文件 byte/hash 对照见 manifest.json。
最后同步纳入上游治理/文档更新;这不改变已部署的固定 RDM3f647f6 制品。同步后已再次只读核验实际 executable/hash、实例、唯一 ready 绑定、两成员身份、HTTP200/匿名401以及临时凭据全部撤销,结果通过。未因记录工作区的变更重复部署或创建认证材料。
@@ -0,0 +1,6 @@
{
"instance": "svc-dev-328312de05f9",
"runtime": "/home/weichen/projects/Agent-System-Dev/runtime/dev",
"target": "3f647f6c547d3f0d5ab65310cc5f3eabf66e654f",
"hostProjectId": "prj_8d20020e5b79"
}
@@ -0,0 +1,28 @@
{
"source": "SELF",
"release": "releases/rdm-3f647f6-20261013T155418Z-3842908",
"pid": 3896104,
"executable": "/home/weichen/projects/Agent-System-Dev/runtime/dev/releases/rdm-3f647f6-20261013T155418Z-3842908/bin/agent-system",
"binary_sha256": "d5db3d0ac292d99582ec91938317af356c050ad61e61f42c097e7faf7a731765",
"matches_verified_product": true,
"instance": "svc-dev-328312de05f9",
"old_business_rows_preserved": true,
"old_artifact_bytes_preserved": 14,
"weichen": {
"authenticated_as": "weichen",
"project_ids": [
"prj_8d20020e5b79"
]
},
"test": {
"authenticated_as": "test",
"project_ids": []
},
"member_create_before_repair_status": 404,
"preview": {
"hostProjectId": "prj_8d20020e5b79",
"name": "genui-e2e",
"memberCount": 2,
"alreadyBound": false
}
}
@@ -0,0 +1,28 @@
import hashlib,json,os,sqlite3
from pathlib import Path
import client,prepare
W=client.W;R=prepare.R;HOST=prepare.HOST
before=json.loads((W/'baseline-private.json').read_text())
release=os.readlink(R/'current');assert release.startswith('releases/rdm-3f647f6-')
pid=int((R/'svc.pid').read_text());exe=Path(f'/proc/{pid}/exe').resolve();assert exe==(R/'current/bin/agent-system').resolve()
ref=Path('/home/weichen/projects/Agent-System-RDM-wt-feature-project-member-access/bin/agent-system-rdm-product')
assert prepare.sha(exe)==prepare.sha(ref),'deployed bytes differ from the verified default product'
assert json.loads((R/'manifest.json').read_text())['instance_id']==prepare.INSTANCE
assert prepare.logical(prepare.DATA)==before['logical'],'old business rows changed before adoption'
for a in before['artifacts']:assert prepare.sha(Path(a['content_path']))==a['sha256']
result={'source':'SELF','release':release,'pid':pid,'executable':str(exe),'binary_sha256':prepare.sha(exe),'matches_verified_product':True,'instance':prepare.INSTANCE,'old_business_rows_preserved':True,'old_artifact_bytes_preserved':len(before['artifacts'])}
for owner in ['weichen','test']:
code,me=client.request(owner,'/api/me');assert code==200 and me['owner']==owner, 'authenticated account mismatch'
code,projects=client.request(owner,'/api/projects');assert code==200
result[owner]={'authenticated_as':me['owner'],'project_ids':[x['id'] for x in projects]}
if owner=='weichen':
target=next(p for p in projects if p['id']==HOST);assert target['settings']['rdm.state']=='unbound'
else:assert HOST not in result[owner]['project_ids']
code,_=client.request('test','/api/projects/'+HOST+'/conversations','POST',{'title':'runtime pre-repair admission probe'})
assert code in (403,404);result['member_create_before_repair_status']=code
preview=client.command('weichen','rdm.project.adopt',{'hostProjectId':HOST})
assert preview['hostProjectId']==HOST and preview['name']=='genui-e2e' and preview['memberCount']==2 and not preview['alreadyBound']
assert prepare.logical(prepare.DATA)==before['logical'],'preview changed business rows'
result['preview']=preview
client.save('pre-repair-preview.json',result)
print(json.dumps(result,ensure_ascii=False))
@@ -0,0 +1,103 @@
import hashlib,json,os,re,shutil,sqlite3,subprocess,sys,time,urllib.request
from collections import Counter
from datetime import datetime,timezone
from pathlib import Path
W=Path('/tmp/project-member-runtime-8788-20261013')
ROOT=Path('/home/weichen/projects/Agent-System-Dev')
R=ROOT/'runtime/dev'; DATA=R/'data'; SVC=ROOT/'scripts/svc.sh'
INSTANCE='svc-dev-328312de05f9'; HOST='prj_8d20020e5b79'
def save(name,obj):
p=W/name;p.write_text(json.dumps(obj,ensure_ascii=False,indent=2)+'\n');p.chmod(0o600)
def sha(p):
h=hashlib.sha256()
with open(p,'rb') as f:
for b in iter(lambda:f.read(1024*1024),b''):h.update(b)
return h.hexdigest()
def db(path):
c=sqlite3.connect('file:'+str(path)+'?mode=ro',uri=True);c.row_factory=sqlite3.Row;return c
def digest(row):
return hashlib.sha256(json.dumps([{'bytes':v.hex()} if isinstance(v,bytes) else v for v in row],ensure_ascii=False,separators=(',',':')).encode()).hexdigest()
def logical(data):
result={}
sets={'agent-system.db':['users','projects','conversations','messages','artifacts','agent_system_identity'], 'rdm.db':['rdm_projects','rdm_host_project_map','rdm_members','rdm_admins']}
for fn,tables in sets.items():
with db(data/fn) as c:
for t in tables:
cols=[x['name'] for x in c.execute('pragma table_info('+t+')')]
if cols:result[fn+':'+t]={'columns':cols,'rows':[digest(x) for x in c.execute('select * from '+t)]}
return result
def inspect():
manifest=json.loads((R/'manifest.json').read_text());assert manifest['instance_id']==INSTANCE
pid=int((R/'svc.pid').read_text().strip()); exe=Path(f'/proc/{pid}/exe').resolve()
assert exe.is_relative_to(R/'releases') and exe.name=='agent-system'
args=Path(f'/proc/{pid}/cmdline').read_bytes().decode().split('\0')
assert args[args.index('--addr')+1]=='127.0.0.1:8788' and args[args.index('--data')+1]==str(DATA)
with db(DATA/'agent-system.db') as c:
ident=dict(c.execute('select * from agent_system_identity').fetchone());assert ident['instance_id']==INSTANCE and ident['dbref']=='sqlite'
active=c.execute("select count(*) from runs where status not in ('completed','failed','interrupted','cancelled','canceled')").fetchone()[0];assert active==0, 'active runs require drain'
hosts=[dict(x) for x in c.execute('select id,name,owner from projects')]
target=next(p for p in hosts if p['id']==HOST);assert target['owner']=='weichen' and target['name']=='genui-e2e'
artifacts=[dict(x) for x in c.execute('select id,content_path from artifacts')]
accounts=[dict(x) for x in c.execute("select owner,must_change_password,auth_version from users where owner in ('weichen','test')")];assert len(accounts)==2 and all(not a['must_change_password'] for a in accounts)
with db(DATA/'rdm.db') as c:
projects=[dict(x) for x in c.execute('select id,name,created_by from rdm_projects')]
maps=[dict(x) for x in c.execute('select * from rdm_host_project_map')]
members=[dict(x) for x in c.execute('select project_id,owner,role from rdm_members where project_id=?',(HOST,))]
assert not any(m['host_project']==HOST for m in maps)
assert not any(p['name'].strip()==target['name'].strip() for p in projects)
assert {m['owner'] for m in members}=={'weichen','test'}
assert not any(p['id']!=HOST and p['name'].strip()==target['name'].strip() for p in hosts)
for a in artifacts:
p=Path(a['content_path']);assert p.is_file();a['sha256']=sha(p)
result={'pid':pid,'executable':str(exe),'binary_sha256':sha(exe),'release':os.readlink(R/'current'),'identity':ident,'accounts':accounts,'target':target,'target_members':members,'host_projects':hosts,'domain_projects':projects,'bindings':maps,'artifacts':artifacts,'logical':logical(DATA),'captured_utc':datetime.now(timezone.utc).isoformat()}
save('baseline-private.json',result)
print(json.dumps({'source':'SELF','instance':INSTANCE,'pid':pid,'release':result['release'],'binary_sha256':result['binary_sha256'],'target':target,'target_member_count':len(members),'name_conflict':False,'active_runs':active,'artifact_files_readable':len(artifacts),'business_counts':{k:len(v['rows']) for k,v in result['logical'].items()}},ensure_ascii=False))
def backup():
before=json.loads((W/'baseline-private.json').read_text())
assert sha(Path(f"/proc/{before['pid']}/exe"))==before['binary_sha256']
assert os.readlink(R/'current')==before['release']
stamp=datetime.now(timezone.utc).strftime('%Y%m%dT%H%M%SZ')
dest=ROOT/'runtime-backups/dev'/('project-member-'+stamp);dest.mkdir(mode=0o700,parents=True,exist_ok=False)
meta=dest/'pre-stop';meta.mkdir(mode=0o700)
for label in ('dev','devweb'):
q=meta/label;q.mkdir()
for n in ('svc.env','serve.env','manifest.json','history.jsonl'):
src=ROOT/'runtime'/label/n
if src.is_file():shutil.copy2(src,q/n)
save('backup-location.json',{'path':str(dest),'before_release':before['release']})
print('Cold paired backup start',str(dest),flush=True)
stopped=False
try:
subprocess.run(['bash',str(SVC),'dev','stop'],check=True);stopped=True
assert not Path(f"/proc/{before['pid']}").exists(),'old process remains'
assert logical(DATA)==before['logical'],'business rows changed since preflight; refresh before backup'
for label in ('dev','devweb'):
shutil.copytree(ROOT/'runtime'/label,dest/label,symlinks=True)
blobs=dest/'artifact-contents';blobs.mkdir(mode=0o700)
for a in before['artifacts']:
assert re.fullmatch(r'[A-Za-z0-9_-]+',a['id']), 'unsafe artifact identifier'
shutil.copyfile(a['content_path'],blobs/a['id']);assert sha(blobs/a['id'])==a['sha256']
restored=W/'restore-proof';restored.mkdir(mode=0o700)
for fn in ('agent-system.db','rdm.db'):
shutil.copy2(dest/'dev/data'/fn,restored/fn)
# Cold snapshot is paired; preserve any retained WAL alongside its DB.
for suffix in ('-wal','-shm'):
src=dest/'dev/data'/(fn+suffix)
if src.exists():shutil.copy2(src,restored/(fn+suffix))
with db(restored/fn) as c:assert c.execute('pragma integrity_check').fetchone()[0]=='ok'
assert logical(restored)==before['logical'],'restored business rows mismatch'
inventory={}
for p in dest.rglob('*'):
if p.is_symlink():inventory[str(p.relative_to(dest))]={'link':os.readlink(p)}
elif p.is_file():inventory[str(p.relative_to(dest))]={'sha256':sha(p),'bytes':p.stat().st_size}
(dest/'MANIFEST.json').write_text(json.dumps({'instance':INSTANCE,'before_release':before['release'],'files':inventory},indent=2)+'\n');(dest/'MANIFEST.json').chmod(0o600)
result={'source':'SELF','backup':str(dest),'instance':INSTANCE,'old_release_retained':before['release'],'runtime_directories':['dev','devweb'],'full_release_count':len(list((dest/'dev/releases').iterdir())),'restored_databases':['agent-system.db','rdm.db'],'integrity_check':'ok','logical_rows_match':True,'artifact_bytes_match':len(before['artifacts']),'manifest_sha256':sha(dest/'MANIFEST.json')}
save('backup-proof.json',result);print(json.dumps(result,ensure_ascii=False),flush=True)
finally:
if stopped:
subprocess.run(['bash',str(SVC),'dev','start'],check=True)
with urllib.request.urlopen('http://127.0.0.1:8788/',timeout=15) as res:assert res.status==200
assert sha((R/'current/bin/agent-system'))==before['binary_sha256']
print('Original release resumed after backup; candidate deployment has not started',flush=True)
if __name__=='__main__':
{'inspect':inspect,'backup':backup}[sys.argv[1]]()
@@ -0,0 +1,21 @@
{
"reviewer": "/root/runtime_acceptance_review",
"parent": "/root",
"scope": "independent read-only runtime/data acceptance replay",
"independent_of_deployment_and_author_record_writing": true,
"author_records_read_after_minimum_replay": true,
"http_methods": [
"GET"
],
"sqlite_mode": "ro",
"outputs": "/tmp only",
"source": "SELF",
"source_label_not_upgraded": true,
"utc": "2026-10-13T16:24:44.420383+00:00",
"receipt": "/tmp/project-member-runtime-independent-replay.json",
"comparison_receipt": "/tmp/project-member-runtime-independent-comparison-receipt.json",
"browser_claims": "author SELF report checked for identity and scope; UI not independently rerun",
"temporary_credential_revocation": "parent responsibility after this review; not performed by reviewer",
"replay_script_sha256": "6ecd9e65a9d83f5d9e6764addfa8f6aecf46131f800e7a762aef459bc03617fe",
"comparison_script_sha256": "89a7064f9ec8e934dae022230ba3e6fd746300e4213c658ad414a7b4df9b68f0"
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,17 @@
# 独立运行验收复核:PASS
审阅者 `/root/runtime_acceptance_review` 未参与部署、修复及作者验收记录编写。先独立重放,再读取作者记录;只使用 HTTP GET、SQLite `mode=ro` 和 `/tmp` 输出。无实质 finding。
对象:8788 / `svc-dev-328312de05f9`;真实 `/proc/3896104/exe` 为 `rdm-3f647f6-20261013T155418Z-3842908`,SHA256 `d5db3d0ac292d99582ec91938317af356c050ad61e61f42c097e7faf7a731765`;运行参数及打开的文件描述符均指向原 `runtime/dev/data` 两库,manifest 与库身份一致。release 标记 `rdm@3f647f6`;完整源 SHA 的对应关系由已验证产物的二进制 SHA 固定,本复核不重做 CI/标签。
- weichen/test 的 `/api/me` 均 200,并看到同一 `prj_8d20020e5b79` → `p-aea70b2559c6` ready 绑定;binding 唯一,weichen=owner、test=member,旧 host 两条孤立成员已迁移。
- 自己的合成会话/文件 GET 200,文件 SHA256 与 fixture 一致;对方会话/文件 GET 404,列表不泄露对方内容。test 对 U7 会话及工件列表 GET 404,额外重放 3 条原 U7 会话直接 GET 均拒绝;U7 原域 `p-39dd859c3c99` 保持独立。U7 没有工件原件可供直接内容 GET;工件列表拒绝已重放。
- 原 7 会话/35 消息/14 工件行摘要完整保留,14 原件字节及冷备份副本字节一致;其他项目成员行摘要完全相同。两个冷备份库 integrity_check 均 ok,业务行与原 baseline 一致,配对 dev/devweb、保留 release 及 manifest 具备;manifest hash 与作者记录一致。
- 作者四份 HTTP/预览/收养/备份记录与重放一致。作者 HTTP 当时 9 会话,本重放 12;全部 5 条新增会话均为“成员协作”前缀且零消息,对应 HTTP 2 条、首轮 UI 1 条、最终 UI 2 条,属于已授权新增。当前消息35、工件16。
- `acceptance-browser.json` 的 host/domain、两账户、退出切换、隔离/刷新字段及 driver SHA 与当前对象一致,pageerrorCount=0;此项为作者 SELF 报告的身份/范围核对,未独立重跑 UI。
重放命令:`PYTHONDONTWRITEBYTECODE=1 python3 /tmp/project-member-runtime-independent-replay.py`;对照命令:`PYTHONDONTWRITEBYTECODE=1 python3 /tmp/project-member-runtime-independent-compare.py`。均由 `/home/weichen/projects/Agent-System-Dev-wt-feature-project-member-runtime/scripts/evidence.sh` 在该工作区、显式 RECEIPT 模式执行,退出码均0;工具 source 保持 SELF,独立执行者身份另附 attestation,未将本地收据自行升级为 GATE/REPLAY。
原始收据:`/tmp/project-member-runtime-independent-replay.json`;作者对照及追加 U7 GET 收据:`/tmp/project-member-runtime-independent-comparison-receipt.json`;身份声明:`/tmp/project-member-runtime-independent-attestation.json`。
限定:未修改业务/源码/任务卡/索引;未部署、重启、创建、删除、发送消息或调用模型。密码登录按用户决定 NOT_RUN;作者 POST 类权限拒绝和重复收养行为未独立重放。临时 API key 撤销及撤销后401由协调者在本复核结束后执行,尚不属于本报告已验证结果。
+29
View File
@@ -0,0 +1,29 @@
# feature/layered-python-env 任务卡
状态:实施已落在独立 worktree,未推送、未合入;owner:weichen
## 基线与授权
- 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main
- R0:64a50cf(origin/main,Merge PR #569)
- 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-layered-python-env
- 分支:feature/layered-python-env(父仓与 backend、frontend、documents 子仓同名)
- 启动检查:/tmp/layered-python-env-precheck.json,退出码 2,结论 SHARED_WORKSPACE_BUSY。共享主检出有未提交 gitlink,且落后 origin/main 60 个提交。因此没有在共享检出写入,也没有运行 make task-start。
- 授权:用户要求按已附方案实现全部分阶段,不改方案文件本身。不包含推送、合入或重启 8788。
## 目标
用不可变、按内容哈希命名的 Python 层,替换「每个工作区一个 venv」和「一个可变全局环境」。沙箱保持断网。安装只发生在宿主侧构建器。
## 本工作区已落地
- 提案:modules/documents/docs/proposals/2026-10-15-layered-python-env.md(documents 945db35),状态仍是待评审。
- P0:解释器不再解析到被沙箱遮蔽的 linuxbrew 路径;PATH 固定;工具文案和提示词不再要求 pip install --user;svc.sh 在产物支持时调用 env ensure,并把环境根与当前基础层经环境变量交给 serve。
- P1:execenv 环境根、托管解释器(独立 CPython,失败则一份系统 venv)、锁、层、wheelhouse、agent-system env ensure|lock|gc|doctor|rebase|python。
- P2:schema v35 的 exec_env_requests / exec_env_bindings、python_env 工具、白名单自动批准、其余走审批卡、pip 垫片、按会话挂载。
- P3:管理区「Python 环境」页,以及回收、重建基础层、上传 wheel 的管理接口。
- 测试(SELF,本机):execenv、tools、store、app、server、runmgr、config、cmd/agent-system 通过。含 sandbox 参数、离线解析、真实 bwrap、两个会话各一层,以及 housestyle.build 产出的 docx 通过结构自检。权威源仍是 CI,本次未推送。
## 非目标
不重启正在运行的 8788。不修改方案文件。不把项目角色加入审批人。
+66
View File
@@ -0,0 +1,66 @@
# <任务标题> 任务卡
任务主记录:<Issue/PR 链接,或注明"本文件随 PR 描述维护">。
状态:<进行中 / 待审核 / 已合入 / 已放弃>;owner:<填写>。
## 基线与授权
- 权威仓:<仓 URL 或逻辑 ID>;root_target:main;immediate_target:<main 或 feature/initiative>
- branch_kind:<initiative | child | standalone>;initiative_id:<稳定 ID,普通任务为空>
- R0(initial_main_sha):<完整 SHA>;工作区:<路径>(worktree / clone);分支:<feature|fix|hotfix/...>
- 父任务信息(仅子任务填写):parent_branch=<父分支>;parent_head_sha=<SHA>;parent_pr=<父 PR>
- accepting_requirements:<true | false>(仅 initiative 可为 true;冻结后为 false)
- 需求分流:verdict=<JOIN | NEW>;selected_initiative=<分支或无>;候选=<分支@HEAD 列表或无>;理由=<不适配/适配依据>;triage 收据=<源码外路径与摘要>
- 授权与交付终点:<本次允许的动作与终点;未授权事项写明>
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md;外部 Agent 一单元一新进程/会话/工作区)
## 目标与非目标
<预期结果、受影响入口/模块/契约;明确不做什么。>
## Agent 实施收据
按根目录 AGENT-EXECUTION.md 路由;外部 Agent 一单元一新进程/会话/隔离工作区。实施、修复与测试必须通过登记的候选执行;未配置或候选安全耗尽停在 unavailable/blocked,禁止 host 隐式代写。
| 单元 ID | 预期范围 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|---|---|---|---|---|---|---|---|---|---|
| 待定义 | — | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | — |
## 复用材料(task-start 自动检索结果摘录)
- 相关近期提交:<git log -- <paths> 命中;无则写无>。
- 相关经验条目:<检索命中;无则写无>。
## 同步记录
| 节点 | sync_base_sha | tested_head_sha | checked_at | 结果 |
|---|---|---|---|---|
| 启动 | <R0> | <HEAD> | <日期时间> | <一致/已同步> |
| 验收前 | <填写> | <填写> | <填写> | <填写> |
字段没有发生的写"无",不省略。本卡与 PR 描述同源:开 PR 时将"目标与非目标、结果与验证、影响与剩余项"复制进 PR 描述,不另写第二份。
## 交付调度(有多个就绪任务时)
- 调度记录 / entry_id / 当前 attempt_id:<平台或调度服务链接及标识;未入队写无>。
- 入队源 HEAD / owner / 依赖:<完整 SHA、身份、依赖或无>。
- 固定候选引用:<调度尝试中的 base/head、组件与配置;未固定写无>。
- 窗口、最终 CI、Review 与真实合入结果:<引用调度记录及原始证据,不复制全队列>。
定义见 [合入调度与 CI 分配](../standards/merge-queue.md)。本段在候选固定前整理;固定后先使用源码之外的记录保存运行结果,再按项目闭合流程回填。
## 结果与验证(完成后填写)
- 结果:<交付了什么;未发生写无>。
- 验证:<结论性摘要:PASS/FAIL/SKIP/NOT_RUN 逐项;逐条证据见下表,来源标注与写入规则见 [按影响选择验证与证据](../standards/verification.md)>。
- 影响与剩余项:<影响面、遗留风险、后续任务>。
| 时间(UTC) | 命令 | 被测 HEAD | exit | 来源 | 摘要/位置 |
|---|---|---|---|---|---|
| <时间> | <命令;由项目 evidence 工具写入,无工具时附命令+对象 SHA+输出 digest 并标 SELF> | <HEAD> | <exit> | GATE/REPLAY/SELF | <摘要/位置> |
## 回收(task-finish)
- 合入核对:<分支已包含于目标分支的核对输出>。
- 未跟踪/ignored 文件处置:<归档/可再生/存疑 逐项;无则写无>。
- 回收动作:<worktree remove、分支删除、prune;放弃路径注明原因>。
+115
View File
@@ -0,0 +1,115 @@
# Project Agent Execution
Project-local execution routing configuration. This document is the single
authority for which Agent CLI profiles may implement, repair, test, or review
bounded units. Human-readable notes may appear outside the machine block; the
parser accepts exactly one `agent-execution` fenced block.
U3's execution controller and U4's project wiring are integrated. This file is
the execution-routing authority for implementation, repair, test, and review.
Normal implementation, repair, and test routes stay Cursor, Antigravity
(`agy`), and PI. Each of those profiles may be attempted up to
`max_attempts_per_profile`, which is exactly 3 whenever `emergency_profile`
is configured. Only after those candidates safely exhaust their attempts does
the enabled emergency `codex` profile run once. Codex remains out of the three
normal role lists and may also appear in review. `fallback_to_host` is
`never`: the controller does not emit `host-fallback-authorized` and does not
increment host fallback authorizations. Safe exhaustion without an emergency
candidate ends `unavailable` or `blocked`, and that result does not authorize
the host to write the unit. The legacy value `all-unavailable` remains
parseable and likewise grants no host write authority. Cursor uses
`cursor-agent-stable`. `model: auto` lets a CLI use its configured default
model; any other value is passed to that CLI as its model selector. The
`integration` block declares the host-exempt paths and the transport, admission,
and cleanup entry points.
```agent-execution
schema: agent-execution/v1
execution:
fresh_process_per_unit: true
permission: run-everything
fallback_to_host: never
max_parallel: 3
timeout_seconds: 7200
idle_timeout_seconds: 600
summary_bytes: 16384
raw_output_bytes: 10485760
max_attempts_per_profile: 3
emergency_profile: codex
roles:
implementation: [cursor, antigravity, pi]
repair: [cursor, antigravity, pi]
test: [pi, antigravity, cursor]
review: [pi, antigravity, cursor, codex]
profiles:
cursor:
adapter: cursor
executable: cursor-agent-stable
model: auto
enabled: true
antigravity:
adapter: antigravity
executable: agy
model: auto
enabled: true
pi:
adapter: pi
executable: pi
model: minimax-cn/MiniMax-M3
enabled: true
codex:
adapter: codex
executable: codex
model: auto
enabled: true
integration:
exempt_paths: [".task/**", "docs/superpowers/specs/**", "docs/superpowers/plans/**"]
transport:
command: scripts/agent-exec apply
admission:
command: scripts/agent-exec admit
cleanup:
command: make task-finish
```
## Model preferences (project choice)
Generic rules for bounded packets, context budgeting, phase handoff and
requested-versus-effective model identity live in the shared
[standards/agent-execution.md](deps/development-guidelines/standards/agent-execution.md)
and [workflows/handoff.md](deps/development-guidelines/workflows/handoff.md);
project procedure is in
[policy/delivery.md](policy/delivery.md#有界单元包上下文与阶段交接). This
section records only this project's choices.
- Planning, design and implementation plans: Codex or Claude when available,
in the host or a fresh CLI session. This is a preference, not a routing role.
- Bounded implementation, repair and test units: the existing normal
candidates in the configured role order above. Requested models:
- PI: `minimax-cn/MiniMax-M3`, passed as `--model provider/id`. PI
actual events have reported `minimax-cn` / `MiniMax-M3` and the local
offline catalog lists that profile; each run still records the effective
model from that run's events.
- Cursor: `auto` (Cursor Auto).
- agy: Gemini 3.8 Flash is requested, but its exact selectable model ID and
effective identity are `NOT_VERIFIED` (the `agy` models query needs a
login that was not available). The profile therefore stays `model: auto`
until an observed model ID exists; do not claim Gemini 3.8 Flash is active.
- Assigning a different candidate or model to a unit needs a concrete,
task-specific reason recorded in the task record, and stays within the
existing roles and candidate lists. It is not a silent permission or routing
change. Role lists, attempt limits, timeouts, output limits, the single
Codex emergency attempt, stage isolation and `fallback_to_host: never` are
unchanged by these preferences.
- A requested model is prompt/config intent. Only the model reported in a
run's actual event envelope counts as effective; when the CLI does not report
it, record `not-observable`. Unknown context capacity, a missing agy login
or missing automatic compaction are recorded facts, not global fail-closed
conditions.
+66 -99
View File
@@ -1,114 +1,81 @@
# Agent 工作说明(Agent-System-Dev)
本仓开发遵循 Development-Guidelines(见 `deps/development-guidelines`,gitlink 固定版本):
核心规则与术语见其 `core/`,按任务触发阅读 `standards/` 专题;通用交付依据为 `workflows/delivery.md`。
本项目的需求、设计试验、实施调整及交付**必读 [policy/delivery.md](policy/delivery.md)**:
需求、方案、实施与验收默认逐阶段人工评审,阶段内迭代、按影响回退;代码 Review 与 PR
合入由智能体负责,解决冲突且当前 HEAD 的 CI 通过后执行合入,无需另请人工操作。
具体评审、版本及授权条件见 policy/delivery.md;其他阶段仅在用户明确授权范围内连续推进。
本文件是入口摘要:只列强制原则与触发式必读,细则与确切命令以所链权威文档为准。
通用规范为固定版本的 Development-Guidelines(`deps/development-guidelines`):核心规则与术语见 `core/`,
按任务触发阅读 `standards/` 专题,通用交付依据为 `workflows/delivery.md`。
## UI 设计门禁(强制)
## 必读路由(强制)
- 本仓一切界面生成/修改**先读根目录 `DESIGN.md`**(四原则:美观、现代、简洁、易用),
再动手;违反视为设计系统缺陷,不是风格偏好。
- 颜色/圆角/字号只消费 `@ui/tokens.css` 令牌(字号走 `--fs-ui-*` 标尺);动效只用
`@ui/motion.css` 的 `mk-*` 工具类;折叠一律用 `@ui` Collapsible 原语,禁止 `<details>`。
- 守护测试(UI 仓与 Frontend 仓各一份 `design-guard.test.ts`)以棘轮拦截新增裸色值、
私有 `@keyframes` 与行内字号;风格调整须在同一变更集中关联 UI 令牌 PR 与 Dev 的
`DESIGN.md`/gitlink 组合 PR,并验证精确组件 SHA(跨仓不要求两个文件出现在同一 PR)。
- 异步状态只有一个所有者。事件按 seq 处理,过期事件丢弃。
| 触发 | 权威 |
|---|---|
| 需求、设计试验、实施调整与交付;阶段、决策点、优先级、分支拓扑、Review/合入、合入调度、清理 | [policy/delivery.md](policy/delivery.md)(交付规则唯一权威) |
| 任务分流、启动/恢复、同步、PR 检查、证据写入、任务卡闭合、回收及其确切命令 | [policy/governance.md](policy/governance.md) |
| 实施/修复/测试/Review 的候选、模型、尝试上限、fail-stop 与会话路由 | [AGENT-EXECUTION.md](AGENT-EXECUTION.md) 与 [standards/agent-execution.md](deps/development-guidelines/standards/agent-execution.md) |
| 引用外部 API、Git/SSH 端点或凭据可用性 | [policy/facts.md](policy/facts.md) |
| 任何界面生成或修改 | [DESIGN.md](DESIGN.md) |
| 项目组成、构建与验证命令、方向规划入口 | [PROJECT.md](PROJECT.md) |
## 任务启动门禁(强制)
## 最高优先级:目标兑现与最小充分交付(强制)
- 任务启动或恢复后,**第一次项目写操作前**通过
`RECEIPT=/tmp/<本次唯一名称>.json CMD="make precheck" make evidence` 运行一次启动检查并保存
完整脱敏收据(不要求已有任务卡);按输出完成必读。`SHARED_WORKSPACE_BUSY / SYNC_REQUIRED /
REMOTE_UNVERIFIED` 均不得进入写入流程;失败后排除原因再启动,不把缓存远端当最新事实。
- 新任务运行 `make task-start NAME=feature/<slug> PRECHECK_RECEIPT=/tmp/<本次唯一名称>.json`,
建立独立 worktree 与任务卡并导入首次收据。恢复已有登记任务在原 worktree 用
`make task-resume PRECHECK_RECEIPT=/tmp/<本次唯一名称>.json` 验证并原样导入收据。
默认 delivery 要求严格 READY;局部恢复接口、启用条件与旧收据处理见 [开发门禁](policy/governance.md#启动与恢复)。任务中途不重复启动检查。
- **分支层级**:任务分支一律从权威 `origin/main` 切(`task-start` 已强制);同批互不依赖的
子任务用同一 R0 的兄弟分支。确有顺序依赖需从父 feature 分支切子分支时(collaboration.md
允许的堆叠例外):启动命令增加 `PARENT=feature/<父slug> PARENT_PR=<父PR链接>`,
任务卡记录主干 R0、父分支及其 SHA、父 PR;子分支命名 `<type>/<父slug>-<子题>`,
不嵌 SHA;合入顺序固定父→子;父合入后子分支须 `make task-sync` 并入最新 main 并把 PR
base 改回 main,方可声明可合入(分支保护要求 head 含 origin/main,未同步必被拦)。
- **验收、请求审核、合入前**各运行一次 `make task-sync`;完成声明的 precheck、task-sync、
测试三段输出由 `make evidence` 写入任务卡(见「证据与验证门禁」),不手抄。
- **多个分支交付 / CI 调度**:先读 [合入调度](policy/merge-queue.md),核对采纳状态、协调者、
记录及当前窗口。新模式尚未启用时保留既有同步节点;启用后最终同步至合入核验共用窗口,
同基线 `task-sync` 只核验,固定后检查用源码外 RECEIPT 保存(见 [证据流程](policy/governance.md#候选固定前后))。
- 合入后由工作区 owner 确认所有写者退出,在**已登记任务 worktree 根目录**运行
`TASK_WRITERS_STOPPED=1 make task-finish`。父子仓改动、未跟踪/ignored 唯一文件先保存或显式处置;删除被拒时
保留现场并按原因处理,禁止强删兜底。放弃未合入工作用
`make task-finish ABANDON="--abandon <原因>"` 并记录原因;放弃不豁免现场保护。
- **任务卡闭合(防欠账)**:分支合入 main 后,其任务卡须回填"已完成"+主记录 PR 链接并
归档至 `.task/archive/`。`task-finish` 回收后提示所有者运行 `make task-close`,不借回收修改
共享主检出或推送另一任务。主检出 pull/merge 的 post-merge 钩子仅提示待办,不自动写入或推送。
`make task-close` 会提交、推送并可能创建 PR,须先核对闭合范围和对应授权。闭合在主检出运行→建
`feature/card-close-*` 分支+PR,任务分支内加 `FOLD=--fold` 随当前 PR 合入。
precheck 的 `[cards]` 行报告欠账,验收前应清零;闭合 PR 同样由智能体按
policy/delivery.md 完成 Review、冲突处置及当前 HEAD 的 CI 核验后合入。
- 优先级固定为:授权与安全边界 → 本次任务目标和系统可用 → 阻塞目标的必要问题 → 非阻塞改进。
- 目标、范围和交付终点一次确认;范围内的分析、方案、实施、修复、验证、代码 Review、PR 合入及安全收口由智能体连续推进。
- 只在目标/范围/验收条件变更、影响用户结果的重大取舍、高后果操作,或业务验收必须由用户判定时请求人工决策。
- 先交付用户明确要求的产物;不得用基础设施、工具治理、通用化、加固、重构或“以后可能用到”替代当前目标,不把简单修改升级成平台、框架或自动化工程。
- 最小充分实现:目标与受影响系统可用、最小直接验证通过即停止并交付;完善作为后续独立增量。
- 绝对禁止私自扩大范围:只修复阻塞目标、可用性、明确验收或强制安全门禁的问题;必要修复超出范围时,说明阻塞、最小扩围和影响,取得授权后再做。“相关”“顺手”“更完美”不构成授权;非阻塞高价值项只简记,噪音忽略,Review 只围绕阻塞项。
- 测试与编排成比例:实施中只跑最小直接检查,完整套件只在最终候选或确有必要时运行一次;编排成本不得超过任务本身。
- 细则:[最高优先级](policy/delivery.md#最高优先级目标兑现与最小充分交付)、[授权与决策点](policy/delivery.md#授权决策点与连续执行)、[问题分流](policy/delivery.md#目标优先范围控制与问题分流)。
## Agent 实施与独立 Review(强制)
- 产生仓库变更的实施按可独立实施的单元交给外部 Agent,任务卡记 `实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)`。
- host 负责计划、拆解、范围审阅、权威验证、规范提交、PR/CI/合入、证据与任务元数据及安全清理;worker 不得提交、推送、开或合 PR、部署、改路由或派遣同伴。
- `fallback_to_host` 为 `never`:候选安全耗尽时终态为 unavailable 或 blocked,host 不撰写该单元;显式 fail-stop 立即停止;成功须有有效的 `completed` 终态记录。
- 实施变更只经成功 transport 的 `scripts/agent-exec apply` 或 pre-commit `admit` 精确核对进入分支;host 直接撰写的豁免只有 `.task/**`、`docs/superpowers/specs/**`、`docs/superpowers/plans/**`。
- 不同阶段、不同单元各用全新会话;Review 由当前主模型或全新独立 CLI session 执行,禁止实施者经 continue/resume/session 等机制续作评审;无法证明会话独立时不得标为独立 Review。
- 细则:[Agent 实施单元](policy/delivery.md#agent-实施单元与主模型职责)、[会话隔离与独立 Review](policy/delivery.md#阶段会话隔离与独立-review);通用契约见 guidelines [core/baseline.md(硬边界 8)](deps/development-guidelines/core/baseline.md)。
## 任务生命周期(强制)
- 新需求建分支前以远端为准分流;启动或恢复后、第一次项目写操作前保存一次启动检查收据。
- 新建任务须以权威远端分流并取得严格 READY(`SHARED_WORKSPACE_BUSY / SYNC_REQUIRED / REMOTE_UNVERIFIED` 均不得建任务),不把缓存远端当最新事实;已登记任务的恢复与局部继续按 [启动与恢复](policy/governance.md#启动与恢复),为消除落后所需的同步按 [被测对象](policy/governance.md#被测对象) 执行,READY 不是执行该同步的前提。正式 Review 与合入须先完成新鲜的权威目标同步并满足适用交付门禁。LOCAL_READY 只是 SELF 局部工作记录,不能替代建任务、正式交付、CI、GATE 或 REPLAY 的准入或证据;脏现场、未对账或副作用未知时仍须停止。
- 分支从权威远端目标切出(子任务从所属大任务分支),同批互不依赖的子任务用同一 R0 的兄弟分支;堆叠例外按门禁文档执行。
- 验收、请求审核、合入前各同步一次并做 PR 检查;任务卡默认合入前闭合并随同一 PR 合入;precheck `[cards]` 欠账验收前须清零。
- 智能体完成 Review、解决冲突并确认当前 HEAD 必需 CI 通过后执行合入,无需另请人工操作。
- 合入后仅在已登记任务 worktree 根目录、确认所有写者退出后回收;父子仓改动与未跟踪/ignored 唯一文件先保存或处置,删除被拒时保留现场,禁止强删兜底。
- 放弃未合入工作用 `make task-finish ABANDON="--abandon <原因>"` 并记录原因,不豁免现场保护。
- 首次克隆后运行 `make setup` 启用本地钩子;治理脚本改动须运行 `make test-governance`(见 [持续回归](policy/governance.md#持续回归))。
- 命令与细则:[启动与恢复](policy/governance.md#启动与恢复)、[回收](policy/governance.md#回收)、[两级分支与分流](policy/delivery.md#两级分支交付模型与分流检查)、[分级门禁](policy/delivery.md#层级任务通道与分级门禁)、[合入调度](policy/delivery.md#合入调度)、[Review 与合入](policy/delivery.md#智能体-review-与-pr-合入)。
## 证据与验证门禁(强制)
原则:**「声明已就位」≠「能力已就位」**。任何来源(用户输入、方案、报告、他人或自己的
叙述)的结果声明都不是证据;证据 = 命令 × 被测对象 SHA × 可复核输出,三者齐备才算事实。
规范依据:guidelines `standards/verification.md`「声明与证据来源」(draft.10)。
- 声明不是证据:证据 = 命令 × 被测对象 SHA × 可复核输出;用户、文档、旧报告或工具摘要中的“可用/已就位”都须先复核。
- 来源三分 `GATE` / `REPLAY` / `SELF`;本地 evidence 只生成 SELF,标签不提升可信等级;交付信任只来自精确 HEAD 的必需 CI 或独立 REPLAY。
- 命令输出只经 `make evidence` 写入任务卡;手抄、转写或凭记忆重构的输出无效,补写输出与伪造测试同级红线。
- 各层级要求的证据与 CI 以 [分级门禁表](policy/delivery.md#层级任务通道与分级门禁) 为准:L2→L1 不要求三段证据;推进 `main` 的交付仍须三段输出(precheck / task-sync / 测试)由 evidence 写入任务卡,PR 描述引用不另手抄。测试通过的权威源是 PR HEAD 上 `.gitea/workflows/ci.yaml` 的 CI。
- 验收即重放:审阅者先重放最小重放集再读作者证据,不一致即阻塞并登记失实。
- 诚实出口:未执行/未验证如实标注 NOT_RUN/未验证;无法复核的外部事实标 `[未经证实]`。
- 等待 CI 只用 `make ci-wait SHA=<完整 SHA>`;禁止手写 sleep + curl 轮询,禁止对同一 SHA 重复或并行轮询。
- 细则:[本地记录与独立证据](policy/governance.md#本地记录与独立证据)、guidelines `standards/verification.md`「声明与证据来源」。
- **来源三分**:产出物(任务卡、PR、报告、review 结论)中的通过类断言须标注来源——
`GATE`(可核验身份及固定对象的 CI/受信执行器)/ `REPLAY`(独立审阅者的重跑记录)/
`SELF`(作者或本地工具记录,含 precheck)。工具写入、摘要和来源标签不提升可信等级。
合入与验收须核验 GATE 的运行链接/身份及 SHA,或 REPLAY 的独立审阅者、命令和对象;
本地 evidence 只生成 SELF,不能靠 `SRC` 自行升级;与重验不一致时以重验为准。
- **证据由工具写入**:命令输出进入任务卡/PR 一律经 `CMD="<命令>" make evidence` 写入
(记录脱敏命令、执行前后对象、退出码、完整脱敏输出与摘要)。凭据只经环境或受保护文件
引用;命令、输出和摘要统一脱敏,摘要只证明记录完整性,不证明执行者身份。手抄、转写、
凭记忆重构的输出视为无效证据;补写输出与伪造测试同级红线。
- **完成声明三段输出**(precheck / task-sync / 测试)必须由 evidence 工具写入任务卡,
PR 描述引用任务卡段落,不另手抄。测试通过的权威源是 CI(`.gitea/workflows/ci.yaml`,
在 PR HEAD 上 `make test`+`make build`),本地输出降级为辅助线索。
- **验收即重放**:请求审核后,审阅者先在评审环境重放最小重放集(关键门禁命令 + 变更
直接相关检查)再读作者证据;重放与声明不一致直接阻塞,并作为失实事件登记。
- **外部事实零信任**:用户/文档/旧报告里的「可用/已就位」必须先执行 `policy/facts.md`
登记表中对应验证命令(或当场实测)才能写进产出物;无法当场复核的结论标 `[未经证实]`,
禁止裸写。登记表每条事实带 `last_verified` 与 TTL,precheck `[facts]` 报告过期项,
`make facts-verify` 逐条重验。
- **诚实出口**:未执行/未验证是合法状态,如实标注(NOT_RUN/未验证)优于补写。
## 高后果操作双钥匙(强制)
改写历史、解除/变更分支保护、删除归档引用、发布版本:Agent 只准备方案与命令,由用户确认并亲手执行。
## Gitea 与 Git 访问事实
- 端点、SSH、API 与 token 可用性只以 [policy/facts.md](policy/facts.md) 为准:引用前先跑其验证命令,凭据类核验只用该表登记的探针;历史卡片或旧脚本中的端点不作为事实。
- 凭据值不入仓、不回显,不进命令行字面量、日志、证据或产出物(baseline 硬边界 2);只经环境变量或受保护文件引用。CI 侧见 [CI 凭据边界](policy/governance.md#ci-凭据边界)。
## 提交与 PR
- 主题行:英文祈使句一行(≤100 列,不以句点结尾);body 写 `Why: / Evidence: / Impact: / Refs:`
四段;任务卡与 PR 描述为同一份文档。
- 跨仓 gitlink 变更须经组合验证(`make test`)后在 Dev 仓推进;受保护分支经 PR 合入。
- **高后果操作双钥匙**:改写历史、解除/变更分支保护、删除归档引用、发布版本——Agent 只准备
方案与命令,由用户确认并亲手执行;Agent 不得自行实施(baseline 硬边界 1 的授权范围要求)。
- 模块边界、公开契约与隔离档位见 `policy/modules/`(如有)与 PROJECT.md。
- 验证命令见 PROJECT.md「验证」节;完成声明的三段输出按「证据与验证门禁」节由
`make evidence` 写入任务卡,不手抄。
- 首次克隆本仓后运行 `make setup` 启用本地 pre-commit 钩子。
- 治理脚本改动须运行 `make test-governance`:临时真实仓库覆盖正常、拒绝及异常路径;该套件
同时纳入 `make test`。证据、工作区和 CI 凭据边界的操作细则见 `policy/governance.md`。
- 主题行为英文祈使句一行(≤100 列,不以句点结尾);body 写 `Why: / Evidence: / Impact: / Refs:` 四段;任务卡与 PR 描述为同一份文档。
- 跨仓 gitlink 变更经组合验证(`make test`)后在 Dev 仓推进;受保护分支经 PR 合入。模块边界与验证命令见 [PROJECT.md](PROJECT.md)。
## Gitea 与 Git 访问事实(2026-09-30 实测;登记表 `policy/facts.md`)
## UI 设计门禁(强制)
机器可核的登记表在 `policy/facts.md`(每条带验证命令、last_verified 与 TTL);
引用任一事实前先跑其验证命令。以下为叙述版:
历史任务卡与旧脚本里的 `git-panel.u1680832.nyat.app:30319` 已失效(TLS 握手失败),
见到一律按过期处理,不要再试。当前权威通道:
- **Web / API(HTTPS)**:`https://git-home.u1680832.nyat.app:30319`(Gitea 1.27.3,
API 前缀 `/api/v1`;偶发 broken pipe / 超时,重试即可)。
- **Git over SSH**:`ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/<Repo>.git`
(.gitmodules 与各仓 origin 均为此格式)。
- **API token**:`~/.secrets/gitea`,两行键值 `URL_PREFIX=…` 与
`ACCESS_TOKEN=<40 位 hex>`;取值 `grep ACCESS_TOKEN ~/.secrets/gitea | cut -d= -f2-`,
用作 `Authorization: token <值>` 请求头。**token 值不入仓、不回显、不写进产出物**
(baseline 硬边界 2:只记录来源、字段与可用状态)。
- **SSH key**:`~/.ssh/home_gitea`(ED25519,公钥指纹
`SHA256:GYXaOXIMeloQ1fKSfdJ/ndgPQzs/Ix7Hk62ekfkfQ20`,Gitea 侧密钥名 GMKtec);
`~/.ssh/config` 已有 `git-ssh.u1680832.nyat.app` 主机条目,克隆/推送直接可用。
- 任务卡闭合 PR(获授权后运行 `make task-close`)经 API 建 PR 时以
`GITEA_TOKEN` 环境变量传入同上的 token。
- 一切界面生成/修改先读 [DESIGN.md](DESIGN.md)(四原则:美观、现代、简洁、易用);违反视为设计系统缺陷,不是风格偏好。
- 颜色/圆角/字号只消费 `@ui/tokens.css` 令牌(字号走 `--fs-ui-*`);动效只用 `@ui/motion.css` 的 `mk-*`;折叠只用 `@ui` Collapsible,禁止 `<details>`。
- 守护测试(UI 仓与 Frontend 仓各一份 `design-guard.test.ts`)以棘轮拦截新增裸色值、私有 `@keyframes` 与行内字号。
- 风格调整按 DESIGN.md「演进规则」在同一变更集中关联 UI 令牌 PR 与 Dev 组合 PR,并验证精确组件 SHA(跨仓不要求同一 PR)。
- 异步状态只有一个所有者;事件按 seq 处理,过期事件丢弃。
+17
View File
@@ -36,6 +36,13 @@ Agent-System-Dev 是桌面优先、Web 兼容的 AI 工作台。界面应**冷
| `--bg-hover` | `rgba(255,255,255,.05)` | `rgba(13,13,13,.05)` | 通用悬停 |
| `--bg-active` | `rgba(255,255,255,.10)` | `rgba(13,13,13,.08)` | 选中态 |
三栏工作台的顶栏与左栏使用独立导航骨架令牌:`--workbench-chrome`、
`--workbench-chrome-text`、`--workbench-chrome-dim`、`--workbench-chrome-faint`、
`--workbench-chrome-hover`、`--workbench-chrome-active`。浅色主题为近黑导航骨架,深色主题取面板阶梯,
墨绿主题取海军蓝侧栏;反色创建按钮的 hover/分隔线使用
`--workbench-chrome-inverse-hover` / `--workbench-chrome-inverse-border`。宿主组件只能消费这些令牌,
不得用 `color-mix()`、rgba 或局部变量再次派生导航颜色。
### 2.2 边框(发丝三档)
`--border-soft: rgba(255,255,255,.06)` / `--border: rgba(255,255,255,.10)` /
@@ -324,3 +331,13 @@ Dev 组合 PR 更新 `DESIGN.md` 并固定对应 UI 提交;两者互链,附
沿用三栏、现有令牌与唯一文件预览。新用户默认浅色、辅助右栏收起,已有主题和布局偏好保留。中栏先给每轮结论,过程、会话设置和消息次要操作按需展开;后台工作通过同一任务卡显示。右栏「工作」打开时,工作卡详细内容与动作只在右栏;中栏保留对话顺序以及必要的定位入口。右栏收起或切到「文件」时,中栏提供完整工作卡。状态和动作只消费服务端已有内容。窄屏单面板提供上下文、对话、工作、文件与返回入口;不丢失同一预览的状态。
这是结构与信息层级调整;UI 仓新增当前工作卡的语义表面令牌,字号、圆角和动效仍使用现有标尺与原语。UI 组件与 Dev 精确 gitlink 组合验证后交付。设计与实施依据见 Documents 的 work-companion-ui-design r0.2 / plan r1,以及本次任务卡 I1。
### 12.4 后台成果与非阻塞选择
延续 §12.3 的视觉令牌和三栏职责。后台完成只更新原任务卡,不自动在中栏插入汇报或发起前台选择回合;中栏按真实发送顺序继续对话。中右栏独立滚动,只通过明确的定位动作关联。
任务卡先展示状态和结果预览,完整结果、材料依据与完整执行记录分层展开。累计进展合并为同一项的最新内容,已保存的公开过程仍可回看,不因最终回复删除。消息、任务更新和选择处理均使用真实时间,完整日期可查。
后续用途选择是可选事项,支持单选或多选、实际的自由输入和“先不选择”;暂缓后可重开。真正的高风险审批继续使用原确认机制。已提交的选择显示实际答案及时间,不残留输入提示。当前工作与工作历史互斥,历史默认折叠、最近在上;更新不打断阅读。未读按成果版本记录,仅明确用户动作确认已读。
右栏收起、显示文件或窄屏时,沿用中栏工作区回退,同一卡片和执行记录只保留一个完整展示位置。用户可主动将某份结果引用到下一条消息,后台完成本身不会更改输入框或当前话题。
+59 -7
View File
@@ -13,29 +13,40 @@ PLUGINS := plugins
COMBO := core=$(shell git -C $(CORE) rev-parse --short HEAD 2>/dev/null)+backend=$(shell git -C $(BACKEND) rev-parse --short HEAD 2>/dev/null)+frontend=$(shell git -C $(FRONTEND) rev-parse --short HEAD 2>/dev/null)+ui=$(shell git -C $(UI) rev-parse --short HEAD 2>/dev/null)+agentcmd=$(shell git -C deps/agent-command rev-parse --short HEAD 2>/dev/null)+documents=$(shell git -C modules/documents rev-parse --short HEAD 2>/dev/null)+native=$(shell git -C deps/agent-native rev-parse --short HEAD 2>/dev/null)+squad=$(shell git -C deps/agent-squad rev-parse --short HEAD 2>/dev/null)+intent=$(shell git -C deps/agent-intent rev-parse --short HEAD 2>/dev/null)
VERSION := $(shell git describe --tags --always --dirty 2>/dev/null)+$(COMBO)
.PHONY: help sync status build frontend svc svc-list svc-info svc-commits svc-history svc-update svc-recover svc-watchdog test-backend test-backend-pg test-multi-instance test-lifecycle test-frontend test-ui test-core test-agentcmd test-pins test-libs dev pin clean setup precheck task-start task-resume task-sync task-close task-finish facts-verify evidence version
.PHONY: help sync status build frontend svc svc-list svc-info svc-commits svc-history svc-update svc-recover svc-watchdog test-backend test-backend-pg test-multi-instance test-lifecycle test-regulations-kb test-frontend test-ui test-core test-agentcmd test-pins test-libs dev pin clean setup precheck task-triage task-triage-decide task-start task-resume task-sync task-close task-finish task-pr-check ci-wait facts-verify evidence version agent-exec-validate agent-exec-apply agent-exec-admit
version:
@echo "agent-system $(VERSION)"
TASK := scripts/task.sh
export PRECHECK_RECEIPT RECEIPT IMPORT_RECEIPT TASK_WRITERS_STOPPED
export PRECHECK_RECEIPT RECEIPT IMPORT_RECEIPT TASK_WRITERS_STOPPED TRIAGE_RECEIPT
TASK_WORK_MODE ?= delivery
export TASK_WORK_MODE
TASK_PARENT_BRANCH ?= $(PARENT)
TASK_PARENT_PR ?= $(PARENT_PR)
export TASK_PARENT_BRANCH TASK_PARENT_PR
TASK_BRANCH_KIND ?= $(KIND)
export TASK_BRANCH_KIND
TASK_INITIATIVE ?= $(INITIATIVE)
export TASK_INITIATIVE
setup:
git config core.hooksPath scripts/hooks
chmod +x scripts/hooks/pre-commit scripts/hooks/post-merge scripts/task.sh scripts/evidence.sh scripts/facts-verify.sh
git config submodule.fetchJobs 8
chmod +x scripts/hooks/pre-commit scripts/hooks/post-merge scripts/task.sh scripts/evidence.sh scripts/facts-verify.sh scripts/agent-exec
@echo "OK: pre-commit/post-merge 钩子已启用(core.hooksPath=scripts/hooks)"
precheck:
@bash $(TASK) precheck
task-triage:
@bash $(TASK) triage "$(REQ)"
task-triage-decide:
@VERDICT="$(VERDICT)" INITIATIVE="$(INITIATIVE)" REASON="$(REASON)" bash $(TASK) triage-decide
task-start:
@if [ -z "$(NAME)" ]; then echo "usage: make task-start NAME=feature/<slug>"; exit 2; fi
@if [ -z "$(NAME)" ]; then echo "usage: make task-start NAME=feature/<slug> TRIAGE_RECEIPT=<path> [PRECHECK_RECEIPT=<path>](KIND=child 已登记在父卡时可省略 TRIAGE_RECEIPT)"; exit 2; fi
@bash $(TASK) start "$(NAME)"
task-resume:
@@ -44,12 +55,22 @@ task-resume:
task-sync:
@bash $(TASK) sync
# 任务卡闭合:默认在任务 worktree 合入前运行 SELF=1(本卡随当前 PR 完成并归档,无需单独闭合 PR);
# 不带参数(主检出)或 FOLD=--fold 仅用于已合入未闭合的遗留卡。
task-close:
@bash $(TASK) close $(FOLD)
@bash $(TASK) close $(if $(SELF),--self,$(FOLD))
task-finish:
@bash $(TASK) finish $(ABANDON)
# PR base/head 门禁(两级分支):本地分支卡片期望目标 vs Gitea PR 与 origin;FINAL=1 用于 initiative 收口。
task-pr-check:
python3 scripts/task_pr_check.py local $(if $(PR),--pr $(PR)) $(if $(FINAL),--final)
# CI 等待(单条阻塞命令):轮询 Gitea 合并状态,失败即停;两次连续全绿才算成功。默认 SHA=HEAD、20 分钟超时。
ci-wait:
python3 scripts/ci_wait.py $(if $(SHA),--sha $(SHA)) $(if $(TIMEOUT),--timeout $(TIMEOUT)) $(if $(INTERVAL),--interval $(INTERVAL)) $(if $(CONTEXTS),--contexts $(CONTEXTS))
# 证据写入:执行命令并把结果行追加进当前任务卡(AGENTS.md「证据与验证门禁」)。
# 本地执行只记 SELF;RECEIPT 捕获启动收据,IMPORT_RECEIPT 导入原始收据而不重跑。
# 用法:CMD="<单行命令>" make evidence [TAIL=15];退出码随被执行命令。
@@ -66,6 +87,7 @@ help:
@echo "make build 构建单二进制 bin/agent-system(契约同步→前端构建→embed→静态链接)"
@echo "make test 全量测试(boundaries + pins + libs + core + backend + frontend + ui + agent-command)"
@echo "make test-governance 临时真实仓库中的任务、证据、写守卫与 CI 凭据回归"
@echo "make test-regulations-kb 法规知识库组合门禁:需 KBREG_TEST_DATABASE_URL、SVC_RDM_SRC_DIR、KB_SRC_DIR(不纳入 make test)"
@echo "make svc 服务级操作:make svc ENV=<name> [ACTION=deploy|start|stop|restart|status|logs] [ARGS='--from dev@<sha> --tag ...']"
@echo "make svc-list 服务总览:make svc-list [ARGS='--tag core'];数据库运维:scripts/svc.sh db create|dsn|backup|backups|restore|clone|copy|ls|set"
@echo "make svc-info 综合信息报告(只读):make svc-info [ARGS='pg1 --reveal']——运行服务/数据库实例与内部库/配置快照"
@@ -77,9 +99,27 @@ help:
@echo "make dev 开发模式说明(前后端分离热更新)"
@echo "make pin 推进 submodule 指针到各仓远端 main(提交前须 make test 通过)"
@echo "make status submodule 状态"
@echo "make agent-exec-validate 校验 AGENT-EXECUTION.md(scripts/agent-exec validate,经 dm-server agent-exec)"
@echo "make agent-exec-apply RECEIPT=<path> 快进当前分支到成功收据的 transport"
@echo "make agent-exec-admit 校验暂存路径具备 transport 来源或属于 host 豁免"
@echo "make task-triage REQ='<需求>' TRIAGE_RECEIPT=<path> 以远端为准发现接纳中的 initiative 并写分流收据(候选存在时 exit 5,待决策)"
@echo "make task-triage-decide TRIAGE_RECEIPT=<path> VERDICT=JOIN|NEW [INITIATIVE=<branch>] REASON='<理由>' 记录显式分流决策(不按数量自动 JOIN)"
@echo "make task-start NAME=feature/<slug> TRIAGE_RECEIPT=<path> [KIND=...] [INITIATIVE=...] [PRECHECK_RECEIPT=<path>] 建任务前核验分流收据(失败不建分支);KIND=child 已登记在父卡「子任务登记」时可省略 TRIAGE_RECEIPT;省略 PRECHECK_RECEIPT 时自动运行启动检查"
@echo "make task-pr-check [PR=N] [FINAL=1] 核验当前任务分支 PR 的 base/head 门禁(远端为准;FINAL=1 用于 initiative 收口)"
@echo "make ci-wait [SHA=<完整 SHA>] [TIMEOUT=1200] [INTERVAL=15] [CONTEXTS=a,b] 阻塞等待该 SHA 的 CI 结论(失败即停)"
agent-exec-validate:
scripts/agent-exec validate --repo .
agent-exec-apply:
@if [ -z "$(RECEIPT)" ]; then echo "usage: make agent-exec-apply RECEIPT=<path>"; exit 2; fi
scripts/agent-exec apply --repo . --receipt "$(RECEIPT)"
agent-exec-admit:
scripts/agent-exec admit --repo .
sync:
git submodule update --init --recursive
git submodule update --init --recursive --jobs 8
status:
@git submodule status
@@ -125,6 +165,14 @@ test-lifecycle:
bash scripts/fetch-rdm-pin.sh tests/integration/lifecycle/rdm.pin >/dev/null
python3 tests/integration/lifecycle/lifecycle_suite.py
# 法规知识库组合门禁(U8):固定 RDM/KB 修订上的 KB test-pg、RDM kbreg 与客户端制品凭据扫描。
# 缺环境直接失败,不静默跳过;不纳入 make test。见 tests/integration/regulations-kb/README.md。
test-regulations-kb:
@test -n "$${KBREG_TEST_DATABASE_URL}" || { echo "test-regulations-kb: KBREG_TEST_DATABASE_URL 未设置(一次性 PostgreSQL+pgvector 必需,不静默跳过)"; exit 1; }
@test -n "$${SVC_RDM_SRC_DIR}" || { echo "test-regulations-kb: SVC_RDM_SRC_DIR 未设置(RDM 检出必需,不静默跳过)"; exit 1; }
@test -n "$${KB_SRC_DIR}" || { echo "test-regulations-kb: KB_SRC_DIR 未设置(KB-Regulations 检出必需,不静默跳过)"; exit 1; }
bash tests/integration/regulations-kb/run.sh
# 双进程 HTTP 级验收(协作存储方案 U7):两个真实 serve 进程共享隔离 PG。
# 缺环境时明确失败而非静默跳过;见 tests/integration/multi-instance/README.md。
test-multi-instance:
@@ -166,7 +214,11 @@ plugin-new:
@test -n "$(NAME)" || (echo "用法:make plugin-new NAME=<id>"; exit 2)
bash scripts/plugin-new.sh "$(NAME)"
.PHONY: test test-governance test-worktree contracts
.PHONY: test test-governance test-worktree test-affected contracts
# host 最小直接检查:按 BASE(缺省为卡片 immediate_target 或 origin/main)以来的改动选 make 目标;DRY=1 只打印。
test-affected:
python3 scripts/test_affected.py $(if $(BASE),--base $(BASE)) $(if $(DRY),--dry-run)
test-governance:
PYTHONDONTWRITEBYTECODE=1 python3 -m unittest discover -s tests -p 'test_*.py' -v
+48 -56
View File
@@ -1,68 +1,17 @@
# Agent-System-Dev 项目事实
- 用途:开发集成父仓(gitlink 权威);非分发单元。
- 组合:modules/{core,backend,frontend,ui,documents} + deps/{development-guidelines,agent-native,agent-squad,agent-intent,agent-command,error-code-system,logging-system}。
- 组合:`modules/`(产品组件)+ `deps/`(共享依赖);完整组件清单以 [`.gitmodules`](.gitmodules) 为准。
- 部署:非容器;Releases 仓从本仓固定提交导出版本。
## 方向与规划入口
长期方向、目标及跨任务规划从过程仓的 [项目方向与规划索引](modules/documents/docs/proposals/INDEX.md)
查找主记录、里程碑和关联任务;原始正文沿用 [方案与规划目录](modules/documents/docs/proposals/)。
确立或调整具体方向时,在本入口维护其主记录链接;正文、确认依据和进展仍以该主记录为准。
目录中的既有文档不因被收录而自动成为已批准规划。记录、任务关联及收尾建议按
[交付规范的长期方向与任务衔接](policy/delivery.md#长期方向与任务衔接) 执行。
- [用户、职位角色与分层权限统一方案 r1](modules/documents/docs/proposals/2026-10-13-identity-role-permission-plan.md):用户已批准,首批仅 I1(U1–U2);
[权限合同](modules/documents/docs/proposals/2026-10-13-iam-i1-permission-contract.md) 冻结边界,
[I1 实施候选与评审记录](modules/documents/docs/proposals/2026-10-13-iam-i1-review.md) 维护实际结果与剩余限制;后续单元须另行授权。
- [快慢通道展示与动态工作摘要方案 r1.1](modules/documents/docs/proposals/2026-10-12-fast-slow-channel-display.md):
对话即时答复、后台动态发现与来源、四层阅读、真实状态、并发/恢复及 U1–U4;
2026-10-12 方案设计已批准(阶段 1–4),首批仅 U1;
[U1 实施计划](modules/documents/docs/proposals/2026-10-12-fast-slow-channel-display-u1-plan.md) 待阶段 5 批准后启动业务代码;
业务实施、模型实验、运行验收与部署 NOT_RUN。
新增方向:[Generative UI 调研与插件方案 r2](modules/documents/docs/proposals/2026-10-10-generative-ui-plugin.md)。
2026-10-11 用户裁定首试点(对话内分析页)、可信编译插件交付与试验参数;U1 受控试验当日完成
(结构分化 6/6、生成走工具参数通道、首期自研 renderer,详见方案「U1 结果与 r2 修订」);
U2 起实施与部署分别评审。
- [多人协作存储与分布式演进方案](modules/documents/docs/proposals/2026-10-11-collaboration-storage-and-distribution.md):
10–100 人、多项目、多会话并行;PostgreSQL 团队档、迁移恢复与多实例执行。方案 r1 已批准
(2026-10-11,用户指示「按方案开始改造」),实施自首选增量 U1+U2 启动。
- [RDM 两树一网集成、完善与追溯审计展示方案](modules/documents/docs/proposals/2026-10-11-rdm-two-trees-trace-audit-integration.md):
每项目一套笔记树、文档树与追溯网;项目绑定与读取授权闭环、原子事件历史、统一审计读服务
与四入口工作区。方案 r1 已获用户评审通过(2026-10-11,五阶段一并,KTD4 双层管理员裁定);
U1–U5 全部实施合入(RDM PR #195/#197/#201/#213;Dev PR #368,2026-10-11;超管槽待基座能力
接线,申请见 RDM 仓 docs/proposals/2026-10-11-u1-base-extension-requests.md);
U6 团队存储独立后续;运行验收属部署环境。
- [DHF 模板接入 RDM 文档生成管线 r0.1](modules/documents/docs/proposals/2026-10-14-dhf-template-generation-plan.md):2026-10-14 获用户批准开始实施;RDM 独立分支已保存 U1 资产合同与 44 份原件目录,E1 与获批追加试验共为 14 份 DOC 生成转换候选。owner 已分别接受项目建议书、F01、F02、设计输入规格书四份确切四哈希候选包,四份均未发布;设计输入规格书的动态 SR/子系统分组使用已裁定的 v2 内容块合同,原型和完整包分别获评审。F01/F02 为独立过程确认用途、默认阶段10,owner 兼任体系专员,公开字典与存量实例升级合同仍需独立评审。14 份 DOC 的 Word 保真待反馈。正式模板发布数为 0;U1 整体、U2–U6、正式浏览器验收、迁移和部署均未完成,复用在途两树合同并按阶段人工评审。
- [RDM 模板与两树一网对话文档生成方案 r1.1](modules/documents/docs/proposals/2026-10-11-rdm-template-dialog-generation.md):69 类历史资产盘点、模板版本与章节实例化、持久提案、文档级审签及 DOCX;待用户评审,业务实施与运行验收 NOT_RUN。 首批项目建议书/竞品分析、随后扩展全部文档已确认(2026-10-11),其余方案与实施仍待评审。
- [RDM 最终目标核对与完整交付方案 r1](modules/documents/docs/proposals/2026-10-11-rdm-final-target-completion.md):系统级项目、上限内权限覆盖、私域协作、全部文档三权与完整业务链;34 UR/68 SR/10 F 逐条映射;方案已随 #340 合入(2026-10-11),U1 需求基线核对经 RDM #199/#200 落地,U2 起未启动。
- [服务重启与全量数据恢复方案 r3.1](modules/documents/docs/proposals/2026-10-12-service-restart-data-recovery.md):
svc 启停、异常进程/主机退出后的依赖、配置/数据身份、任务/HITL/副作用、文件与组合备份恢复;
r2 已批准。r3.1 增补 D1 实例身份收尾、D2 可回滚切换、D3 真实组合门禁,并记录 2026-10-12 rdmcand 数据归属:会话不在 dev 库的 rdmcand 窗口内,领域事件为空,不跨实例搬迁。
D1 与 D2 已合入 Backend #184、RDM #291、Dev #485。D3 的 `make test-lifecycle` 跑真实组合用例;登录仍是 NOT_RUN,依赖账户方案 U7/U5,不在本轮公共化账户 CLI。r3 其余未批条款仍待人工评审。
- [svc 统一部署与一次性登录 Key 方案 r1](modules/documents/docs/proposals/2026-10-12-svc-unified-deploy-and-login-key.md):
二进制/源码统一部署、环境准备、无初始密码开户与账户恢复;一次性 Key 仅兑换设密受限会话;
2026-10-12 已批准;U1/U4 实施启动中;规格见 `docs/svc-deploy/`。
上述账户/恢复方案已有 U1/U4 与 recover/watchdog 基础源码。2026-10-12 的 dev 8788 续查形成账户 r2、恢复 r3 **候选草案**:帮助与能力发现、账户事务/审计/登录接线、SQLite 活动服务隔离及备份恢复增补。新增内容待人工评审;Documents 独立分支 `feature/svc-account-durability-plan` 仅本地保存,不推进本仓 gitlink;本入口原链接仍指固定版。候选交接与核查见[续审记录](docs/svc-deploy/2026-10-12-account-durability-plan-review.md)。
## 验证
规范修订:[最终验证与合入调度 r1](policy/merge-queue.md) 及[U1–U6 实施计划](modules/documents/docs/proposals/2026-10-13-merge-queue-implementation-plan.md)已批准。通用规范与计划已分别经 PR 合入,本候选组合固定实际合入 SHA,见[采纳记录](policy/adoption.md)。同步幂等化、显式局部恢复和源码外证据基础已实施;Dev 最新组合验收及平台调度模式启用仍按各自门禁办理。
`make test` 先核对子模块工作树与固定指针,再运行治理脚本、公开边界、跨仓指针、库及各模块
测试。实际目标以根 Makefile 为准。`make test-governance` 可独立检查开发门禁,使用临时
真实仓库,不访问生产数据;操作与证据要求见 [开发门禁](policy/governance.md)。
`scripts/agent-exec validate --repo .` 核验 `AGENT-EXECUTION.md`,`scripts/dm governance check --repo .` 核验治理 kit 入口与采纳状态(只读);二者均在 CI 中运行。
`make build` 在 backend 模块内编译,replace 指向该模块自己的 `deps/`;
`scripts/check-pins.sh` 核对这些 gitlink 与 Dev 顶层指针,`make test-worktree` 另核对
真正被测的组件工作树。两者分别验证固定组合与实际检出,不能相互替代。
@@ -70,6 +19,49 @@ U2 起实施与部署分别评审。
未加 go.work:工作区最小版本选择会抬高 backend 单独构建使用的部分 `golang.org/x` 版本。
发布消费方须从固定 Dev 提交递归物化后运行 `make build`,再核验制品与实际运行状态。
- [渐进工作台界面重设计 r0.2](modules/documents/docs/proposals/2026-10-12-work-companion-ui-design.md):用户已授权连续实施;[计划 r1](modules/documents/docs/proposals/2026-10-12-work-companion-ui-plan.md)覆盖任务摘要、对话/输入、窄屏和真实状态投影;进展见对应任务卡。
多个分支向 Dev main 交付时按 [合入调度](policy/delivery.md#合入调度) 执行;实际采纳范围见 [采纳记录](policy/adoption.md)。
- [系统项目、成员工作入口与私域协作闭环 r1](modules/documents/docs/proposals/2026-10-13-system-project-membership.md):2026-10-13 用户批准阶段 1–9 连续推进;统一全局项目身份与名称、成员个人会话、每项目两树一网和私域权限;当前组合验证/CI/tag 消费推进中,部署与线上修复未授权。
## 法规知识库组合
- 计划:[法规知识库计划](docs/superpowers/plans/2026-10-18-regulations-knowledge-base-plan.md)(U8 固定组合);进展与批准状态以该计划、任务卡与 PR 为准。
- 固定版本:Dev 侧模块以 gitlink 与 `.gitmodules` 为准;RDM 与 KB-Regulations 提交以
`tests/integration/regulations-kb/components.pin`(`rdm_sha`、`kb_sha`)为准。KB 经 RDM 的
`pins/agent-system-kb-regulations` gitlink 接入,门禁要求该 gitlink 是 `kb_sha` 的祖先。
- 凭据变量:`KBREG_DATABASE_URL`、`KBREG_EMBED_API_KEY`、`KBREG_SEARCH_ZHIPU_API_KEY`、`KBREG_MINERU_TOKEN`
(测试库用 `KBREG_TEST_DATABASE_URL`)。按环境注入、轮换与撤销见 KB 仓 `docs/operations/runbook.md`;值不入仓、不回显。
- 门禁:`make test-regulations-kb` 需 `KBREG_TEST_DATABASE_URL`、`SVC_RDM_SRC_DIR`、`KB_SRC_DIR`,
独立于 `make test`、不纳入其中;说明见 [tests/integration/regulations-kb/README.md](tests/integration/regulations-kb/README.md)。
该门禁通过不代表部署、版本发布或业务/法务验收完成。
## 方向与规划入口
长期方向、目标及跨任务规划从过程仓的 [项目方向与规划索引](modules/documents/docs/proposals/INDEX.md)
查找主记录、里程碑和关联任务;原始正文沿用 [方案与规划目录](modules/documents/docs/proposals/)。
确立或调整具体方向时,在本入口维护其主记录链接;记录、任务关联及收尾建议按
[交付规范的长期方向与任务衔接](policy/delivery.md#长期方向与任务衔接) 执行。
下列条目只是主题索引:批准、进展、验收与部署状态一律以所链主记录、任务卡与 PR 为准,
本入口不复制;收录不构成批准。
- [分层分支交付与规范精简](modules/documents/docs/proposals/2026-10-18-delivery-model-v3.md):两级分支、任务卡合入前闭合、分级门禁、任务分类通道与规范精简。
- [文档职责矩阵整改](modules/documents/docs/proposals/2026-10-15-rdm-duty-matrix-rework.md):项目设置的文档职责三视图分配。
- [svc 插件组合部署(--with)](modules/documents/docs/proposals/2026-10-14-svc-plugin-compose-deploy.md):部署时把登记插件与 Dev 基座编成一个二进制并校验激活。
- [用户、职位角色与分层权限统一](modules/documents/docs/proposals/2026-10-13-identity-role-permission-plan.md):
[I1 权限合同](modules/documents/docs/proposals/2026-10-13-iam-i1-permission-contract.md)、
[I1 实施候选与评审记录](modules/documents/docs/proposals/2026-10-13-iam-i1-review.md)。
- [系统项目、成员工作入口与私域协作闭环](modules/documents/docs/proposals/2026-10-13-system-project-membership.md):全局项目身份与名称、成员个人会话、每项目两树一网与私域权限。
- [快慢通道展示与动态工作摘要](modules/documents/docs/proposals/2026-10-12-fast-slow-channel-display.md):对话即时答复、后台动态发现与来源、四层阅读、真实状态、并发/恢复;
[U1 实施计划](modules/documents/docs/proposals/2026-10-12-fast-slow-channel-display-u1-plan.md)。
- [渐进工作台界面重设计](modules/documents/docs/proposals/2026-10-12-work-companion-ui-design.md):
[计划](modules/documents/docs/proposals/2026-10-12-work-companion-ui-plan.md) 覆盖任务摘要、对话/输入、窄屏和真实状态投影。
- [服务重启与全量数据恢复](modules/documents/docs/proposals/2026-10-12-service-restart-data-recovery.md):svc 启停、异常退出后的依赖、配置/数据身份、任务/HITL/副作用、文件与组合备份恢复;
U8 规格见 [SQLite 实例守护](docs/recovery/u8-sqlite-instance-guard.md)。
- [svc 统一部署与一次性登录 Key](modules/documents/docs/proposals/2026-10-12-svc-unified-deploy-and-login-key.md):
二进制/源码统一部署、环境准备、无初始密码开户与账户恢复;规格见 `docs/svc-deploy/`,
账户与恢复续审见 [续审记录](docs/svc-deploy/2026-10-12-account-durability-plan-review.md)。
- [Generative UI 调研与插件](modules/documents/docs/proposals/2026-10-10-generative-ui-plugin.md):对话内生成界面与可信编译插件交付。
- [多人协作存储与分布式演进](modules/documents/docs/proposals/2026-10-11-collaboration-storage-and-distribution.md):多项目、多会话并行;PostgreSQL 团队档、迁移恢复与多实例执行。
- [RDM 两树一网集成、完善与追溯审计展示](modules/documents/docs/proposals/2026-10-11-rdm-two-trees-trace-audit-integration.md):每项目笔记树、文档树与追溯网,项目绑定与读取授权、原子事件历史、统一审计读服务与四入口工作区。
- [DHF 模板接入 RDM 文档生成管线](modules/documents/docs/proposals/2026-10-14-dhf-template-generation-plan.md):DHF 模板资产合同与文档生成转换。
- [RDM 模板与两树一网对话文档生成](modules/documents/docs/proposals/2026-10-11-rdm-template-dialog-generation.md):历史资产盘点、模板版本与章节实例化、持久提案、文档级审签及 DOCX。
- [RDM 最终目标核对与完整交付](modules/documents/docs/proposals/2026-10-11-rdm-final-target-completion.md):系统级项目、权限覆盖、私域协作、全部文档三权与完整业务链的需求映射。
Vendored Submodule
+1
+65
View File
@@ -0,0 +1,65 @@
# U8 SQLite 活动服务锁与耐久核验
状态:2026-10-12 用户批准恢复方案 r3 的 U8 后编写,随 `feature/u8-sqlite-instance-guard` 实施。
主记录:[服务重启与全量数据恢复方案](../../modules/documents/docs/proposals/2026-10-12-service-restart-data-recovery.md) §7 U8、KTD13、KTD14。
本文件只定本增量的可判定行为。账户 CLI 不迁移、不建库的合同由账户方案 U7 实现。
## 1. 锁对象
活动服务在打开 SQLite(迁移发生在打开内部)之前取得锁,并持有到存储关闭之后。PostgreSQL 档不使用这把锁,沿用迁移咨询锁与执行所有权。
| 规则 | 行为 |
|---|---|
| 路径 | 先 `Abs`,已存在的路径再 `EvalSymlinks`。数据库文件若是符号链接,锁放在解析后的真实文件旁边 |
| 锁文件 | `<db>.lock`。`O_RDWR\|O_CREAT\|O_CLOEXEC\|O_NOFOLLOW`,模式 0600。永不 unlink。数据目录不存在时,活动服务在取锁前创建该目录 |
| 互斥 | `flock(LOCK_EX\|LOCK_NB)`。占用返回「活动服务已在运行」,调用方不得打开库 |
| 替换检测 | 取锁后比较 fd 与路径的 device/inode,不一致则关闭并重试,仍不一致则拒绝 |
| 硬链接 | 解析后的数据库 `nlink>1` 直接拒绝,不能用 adopt 绕过 |
| 平台 | `unix` 实现。其他平台的 SQLite 档拒绝启动。PostgreSQL 档不受此限制 |
| 范围 | 只挡活动服务与 `migrate`。`user`、`apikey`、`identity` 不取这把锁 |
svc 的 `runtime/<name>/.start.lock` 只串行化脚本生命周期,挡不住直接执行二进制。本锁补的是这条缺口。
## 2. 身份记录
两处记录,各管一种替换:
1. 锁文件内容(持有 fd 时读写):`v1 db_dev db_ino instance_id lock_gen`。`lock_gen` 是 16 字节随机值的十六进制。数据库 inode 与记录不一致,或记录还在而数据库文件消失,视为数据库被替换,**打开之前**拒绝。
2. 表 `instance_guard`(迁移 v36,单行):记录锁文件的 device/inode、instance_id 与 `lock_gen`。守卫建立之后,锁文件 inode 与表不一致,或表里已有 `lock_gen` 而锁文件记录缺失/不一致,视为锁根丢失或锁文件被重建(含 inode 被回收后内容丢失),打开并迁移之后拒绝,且不改写表。
尚无锁文件记录、表中也无行:视为首次建立(含旧库升级),写入两边。这是升级路径,不是 adopt。
同时换掉数据库文件和锁文件、新库里也没有本表:无法与真正的首次建立区分。此时若设置了 `AGENT_SYSTEM_INSTANCE_ID`,仍由既有身份校验拒绝错库。该剩余风险写入任务卡,不在本增量用第二套锁文件解决。
`instance_id` 取 `AGENT_SYSTEM_INSTANCE_ID`。表和锁文件都已有非空值且与本次不一致时拒绝。本次为空则不比较,保留表内原值。
显式 `--adopt-instance-guard`(仅 `serve` 与 `migrate`)在已持锁的前提下重写两边记录。它只接受「数据库文件还在但 inode 已变」和「锁记录损坏」。记录还在而数据库文件消失时,adopt 也不打开、不新建空库。锁文件若是指向数据库的符号链接,或与数据库同一 inode,直接拒绝且不写入。硬链接拒绝不受该标志影响。
身份校验在写入守卫之前完成。`AGENT_SYSTEM_INSTANCE_ID` 已设置但与库内身份不符时,不留下本次的 instance id。
## 3. 耐久
SQLite DSN 增加 `synchronous(FULL)`。打开后在**同一应用连接**读回 `journal_mode=wal` 且 `synchronous=2`,否则关闭并拒绝。
PostgreSQL 从应用连接读 `pg_settings`:`fsync`、`full_page_writes`、`synchronous_commit` 任一为 `off`,或读不到,则拒绝。`synchronous_commit=local` 不是 `off`,不拒绝。
写失败必须把错误返回给调用方。测试用 `RLIMIT_FSIZE` 制造失败,并忽略 `SIGXFSZ`,以免进程被信号杀死而看起来像成功。
## 4. migrate 子命令
`agent-system migrate --data <dir>`:SQLite 先取活动服务锁,有服务占用则拒绝,再打开(打开即迁移)并走第 2 节的建立/拒绝规则。
`agent-system migrate --dsn <dsn>` 或环境变量 `AGENT_SYSTEM_DSN`:不取文件锁,迁移仍用 PostgreSQL 咨询锁排队。
## 5. 验收
| 编号 | 判据 |
|---|---|
| T8-1 | 两个进程启动同一 SQLite,后者在打开前失败;前者的 running 与 waiting_hitl 行保持原状态 |
| T8-2 | 符号链接与相对路径进入同一把锁;硬链接拒绝;数据库替换拒绝;锁文件删除后重建拒绝 |
| T8-3 | 持锁进程被 SIGKILL 后,同数据目录可以再次取锁并打开 |
| T8-4 | 本增量:服务持锁期间另一进程的短事务可提交;缺库的 OpenExisting 不建目录;migrate 与持锁服务互斥。账户 CLI 不迁移归 U7 |
| T8-5 | 换端口、工作目录或路径拼写仍落在同一锁文件上 |
| T8-6 | pragma 读自应用连接;超限写入返回错误 |
`tests/test_svc_storage_ownership.py` 依赖 svc 启动路径。本任务不改 `scripts/svc.sh`,该文件留到账户 U5;若届时 svc 入口已稳定,再补脚本级用例。
+12
View File
@@ -0,0 +1,12 @@
project: 审计演示项目
docs:
- type: bd_research
title: 验证主体报告
sections:
- title: 概述
content: |
本报告给出验证主体、结论与证据链的总体视图。
- title: 设计说明
content: |
设计说明:两树一网领域事实经驾驶舱只读投影呈现。
- title: 验证结论
@@ -0,0 +1,474 @@
# Project Agent Execution Routing Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Build a project-local, Markdown-configured execution router that delegates repository-writing work to ordered Agent CLI profiles and authorizes host-model fallback only after every candidate is safely unavailable.
**Architecture:** A small `agent-exec` CLI is the external seam. It parses one `agent-execution` block from `AGENT-EXECUTION.md`, validates profiles against built-in or controlled custom adapters, runs each implementation attempt in a fresh detached worktree, and emits a bounded JSON receipt plus a host-owned transport commit. The host remains responsible for scope review, authoritative verification, integration, commits, PRs, CI, merge, and cleanup.
**Tech Stack:** Python 3 standard library, Git worktrees and plumbing commands, `unittest`, existing `make test-governance` discovery, Markdown with a constrained YAML subset.
**Spec:** `docs/superpowers/specs/2026-10-15-project-agent-execution-design.md`
## Global Constraints
- Preserve goal-first delivery, strict no-scope-expansion, usable-first sequencing, evidence provenance, platform admission, and high-consequence dual keys.
- Use no new third-party runtime dependency. The parser accepts only the documented YAML subset.
- Every implementation task below uses one fresh Cursor CLI run. Cursor workers do not commit, push, open PRs, merge, deploy, or clean canonical worktrees.
- The host creates canonical commits only after inspecting actual changes and running the task's authoritative tests.
- `run-everything` removes per-command prompts inside the isolated unit; it never expands user authorization or grants canonical Git authority.
- `model: auto` omits the model flag instead of passing the string `auto`.
- Shell command templates, secret values, unknown placeholders, and implicit environment inheritance are rejected.
- `failed-unknown`, `scope-expansion`, `invalid-config`, and safety failures never authorize host fallback.
- A normal worker return is bounded by `summary_bytes`; raw logs remain outside the repository.
## Review Focus
- A CLI exits nonzero after touching files: preserve evidence, prove exact cleanup, then classify `failed-clean`; otherwise return `failed-unknown`.
- A custom adapter places a placeholder inside a larger argv string: reject it instead of interpolating or invoking a shell.
- A role lists several missing or incompatible profiles: exhaust them in order and issue exactly one `host-fallback-authorized` receipt.
- A worker creates untracked or binary files: include them in the host-owned transport and changed-path inventory without modifying the canonical checkout.
- A worker changes HEAD, `.git`, a disallowed path, or an external object: fail-stop and retain the attempt for reconciliation.
---
## File Map
| Path | Responsibility |
|---|---|
| `AGENT-EXECUTION.md` | Human-readable project configuration and the single machine-readable `agent-execution` block |
| `scripts/agent_exec_config.py` | Markdown extraction, constrained YAML parsing, schema validation, and immutable configuration types |
| `scripts/agent_exec_adapters.py` | Built-in adapter registry, custom adapter validation, capability probes, and argv construction |
| `scripts/agent_exec.py` | `validate`/`run` CLI, selection state machine, detached worktrees, process supervision, transport commits, receipts, cleanup, and host fallback authorization |
| `tests/test_agent_exec_config.py` | Configuration parser and schema contract |
| `tests/test_agent_exec_adapters.py` | Adapter argv, model, permission, output, and custom-adapter contract |
| `tests/test_agent_exec.py` | Real temporary-Git execution, fallback, scope, transport, recovery, timeout, redaction, and process lifecycle |
| `AGENTS.md` | Short context pointer to `AGENT-EXECUTION.md`; no duplicated CLI mappings |
| `policy/delivery.md` | Project-level agent-per-unit execution and fallback authority |
| `policy/governance.md` | Receipts, isolation, evidence ownership, and recovery rules |
| `policy/adoption.md` | Adoption status and current capability limit |
| `policy/tool-adaptation-matrix.md` | Manual/enforced capability classification and verification entrypoints |
| `scripts/task.sh` | New task-card execution routing and receipt fields |
| `tests/test_task.py` | Generated task-card contract |
| `Makefile` | `agent-exec-validate` target and help text |
| `.task/feature-goal-first-delivery.md` | Scope, Cursor attempt receipts, stage state, and exact evidence references |
### Task 1: U1 Configuration Contract
**Files:**
- Create: `AGENT-EXECUTION.md`
- Create: `scripts/agent_exec_config.py`
- Create: `tests/test_agent_exec_config.py`
- Modify: `Makefile`
**Interfaces:**
- Produces: `ExecutionConfig`, `ExecutionPolicy`, `Profile`, `CustomAdapter`, `ConfigError`, `load_config(repo: Path) -> ExecutionConfig`, `validate_config(repo: Path) -> list[str]`
- Consumes: Python 3 standard library only
- [ ] **Step 1: Write the failing parser and schema tests**
Create `tests/test_agent_exec_config.py` with temporary repository fixtures and these cases:
```python
def test_loads_single_agent_execution_block(): ...
def test_rejects_missing_or_duplicate_blocks(): ...
def test_rejects_unknown_schema_and_unknown_keys(): ...
def test_role_order_does_not_follow_profile_order(): ...
def test_model_auto_is_preserved_as_none(): ...
def test_rejects_unknown_profile_reference(): ...
def test_rejects_shell_command_and_secret_shaped_values(): ...
def test_custom_placeholders_must_fill_whole_argv_items(): ...
def test_numeric_limits_are_positive_and_bounded(): ...
```
- [ ] **Step 2: Run the parser tests red**
Run: `python3 -m unittest tests.test_agent_exec_config -v`
Expected: FAIL because `scripts.agent_exec_config` does not exist.
- [ ] **Step 3: Implement immutable configuration types**
In `scripts/agent_exec_config.py`, define:
```python
@dataclass(frozen=True)
class ExecutionPolicy:
fresh_process_per_unit: bool
permission: str
fallback_to_host: str
max_parallel: int
timeout_seconds: int
summary_bytes: int
raw_output_bytes: int
@dataclass(frozen=True)
class Profile:
name: str
adapter: str
executable: str
model: str | None
enabled: bool
@dataclass(frozen=True)
class CustomAdapter:
name: str
base_argv: tuple[str, ...]
run_everything_argv: tuple[str, ...]
workspace_argv: tuple[str, ...]
model_argv: tuple[str, ...]
prompt_transport: str
output_format: str
@dataclass(frozen=True)
class ExecutionConfig:
schema: str
execution: ExecutionPolicy
roles: Mapping[str, tuple[str, ...]]
profiles: Mapping[str, Profile]
custom_adapters: Mapping[str, CustomAdapter]
```
`model: auto` becomes `None`. Reject unknown keys, duplicate mapping keys, tabs, anchors, aliases, tags, multiline scalars, implicit dates, shell metacharacter templates, credential-looking keys/values, and placeholders other than the four spec placeholders.
- [ ] **Step 4: Implement the constrained YAML parser**
Support two-space-indented mappings, inline scalar lists, booleans, integers, null, and quoted/unquoted safe strings. The parser does not implement general YAML. Extract exactly one fenced block whose opening marker is ```` ```agent-execution ```` and whose closing marker is ```` ``` ````.
- [ ] **Step 5: Add the initial project configuration**
Create `AGENT-EXECUTION.md` using the spec's example with role order:
```text
implementation: cursor -> antigravity -> claude -> codex -> pi -> kimi -> opencode
repair: cursor -> antigravity -> codex -> claude
test: pi -> antigravity -> codex
review: claude -> codex -> pi
```
Set `permission: run-everything`, `fallback_to_host: all-unavailable`, `model: auto` for every profile, and no custom adapters.
- [ ] **Step 6: Add validation entrypoint**
Add `make agent-exec-validate`, running:
```bash
python3 scripts/agent_exec.py validate --repo .
```
In U1 the target runs `python3 -m unittest tests.test_agent_exec_config -v`. Task 3 replaces that recipe with the final `agent_exec.py validate` command.
- [ ] **Step 7: Run U1 green**
Run: `python3 -m unittest tests.test_agent_exec_config -v`
Expected: PASS with all parser and schema cases.
- [ ] **Step 8: Host integration commit**
The Cursor worker leaves its tree uncommitted. The host inspects changed paths, runs the same test, and commits only the four U1 paths with subject `Add project execution agent configuration` and the repository-required four body sections.
### Task 2: U2 Adapter Seam
**Files:**
- Create: `scripts/agent_exec_adapters.py`
- Create: `tests/test_agent_exec_adapters.py`
- Modify: `scripts/agent_exec_config.py`
**Interfaces:**
- Consumes: `Profile`, `CustomAdapter`, `ExecutionPolicy`
- Produces: `AdapterSpec`, `AdapterProbe`, `Invocation`, `probe_adapter(profile, config) -> AdapterProbe`, `build_invocation(profile, config, workspace, unit_packet, result_path) -> Invocation`
- [ ] **Step 1: Write adapter contract tests red**
Cover Cursor, `agy`, Claude, Codex, PI, Kimi, OpenCode, and custom profiles:
```python
def test_cursor_run_everything_and_auto_model_argv(): ...
def test_antigravity_run_everything_argv(): ...
def test_claude_run_everything_argv(): ...
def test_codex_uses_noninteractive_workspace_sandbox(): ...
def test_pi_and_kimi_auto_model_omit_model_flag(): ...
def test_missing_opencode_is_unavailable(): ...
def test_fixed_model_uses_only_adapter_model_flag(): ...
def test_custom_adapter_builds_direct_argv_without_shell(): ...
def test_unverified_run_everything_capability_is_unavailable(): ...
```
- [ ] **Step 2: Run adapter tests red**
Run: `python3 -m unittest tests.test_agent_exec_adapters -v`
Expected: FAIL because the adapter registry does not exist.
- [ ] **Step 3: Implement adapter types and registry**
Define:
```python
@dataclass(frozen=True)
class AdapterSpec:
name: str
noninteractive_argv: tuple[str, ...]
run_everything_argv: tuple[str, ...]
workspace_flag: str | None
model_flag: str | None
output_argv: tuple[str, ...]
prompt_transport: str
@dataclass(frozen=True)
class AdapterProbe:
available: bool
reason: str | None
executable: str
observed_version: str | None
@dataclass(frozen=True)
class Invocation:
argv: tuple[str, ...]
cwd: Path
stdin: bytes | None
sanitized_display: tuple[str, ...]
```
Use direct argv with no shell. Probe via executable lookup plus bounded `--version`/`--help` inspection. Do not contact a provider during `validate`.
- [ ] **Step 4: Implement built-in mappings**
Map the currently observed CLI interfaces from the spec. Cursor uses sandboxed `--force`; Codex uses `exec`, workspace-write sandbox, and never-ask approval rather than disabling outer isolation; OpenCode returns unavailable until its installed help proves the required interface. A missing or incompatible required flag returns `unavailable` rather than silently choosing a weaker posture.
- [ ] **Step 5: Implement custom adapter expansion**
Substitute only whole-argument placeholders. Build stdin or positional prompts according to `prompt_transport`. Inherit only an allowlist of environment variables required for locale, PATH, HOME, temporary storage, and provider credential discovery by the CLI; never serialize values into receipts.
- [ ] **Step 6: Run U2 green**
Run: `python3 -m unittest tests.test_agent_exec_config tests.test_agent_exec_adapters -v`
Expected: PASS.
- [ ] **Step 7: Host integration commit**
Commit only U2 files with subject `Add execution CLI adapter registry` after host review and tests.
### Task 3: U3 Execution Controller
**Files:**
- Create: `scripts/agent_exec.py`
- Create: `tests/test_agent_exec.py`
- Modify: `Makefile`
**Interfaces:**
- Consumes: `ExecutionConfig`, adapter `Invocation`, a unit packet JSON document
- Produces: CLI commands `validate` and `run`; receipt schema `agent-exec-receipt/v1`; transport ref `refs/agent-exec/<run-id>/<attempt-id>`
- [ ] **Step 1: Write end-to-end controller tests red**
Build temporary real Git repositories and fake executables. Cover:
```python
def test_validate_does_not_contact_provider(): ...
def test_run_uses_fresh_process_and_worktree_per_attempt(): ...
def test_missing_profiles_fall_through_in_declared_order(): ...
def test_all_unavailable_authorizes_host_fallback_once(): ...
def test_failed_clean_can_continue_after_exact_restore(): ...
def test_failed_unknown_blocks_fallback(): ...
def test_scope_expansion_preserves_workspace_and_blocks(): ...
def test_worker_commit_or_head_move_is_rejected(): ...
def test_untracked_and_binary_files_enter_transport_inventory(): ...
def test_timeout_kills_process_group_and_records_receipt(): ...
def test_summary_and_raw_log_caps_are_enforced(): ...
def test_receipt_redacts_environment_secrets(): ...
def test_success_creates_base_parented_transport_without_touching_canonical_head(): ...
```
- [ ] **Step 2: Run controller tests red**
Run: `python3 -m unittest tests.test_agent_exec -v`
Expected: FAIL because `scripts/agent_exec.py` does not exist.
- [ ] **Step 3: Implement unit packet validation**
The JSON packet requires `unit_id`, `goal`, `allowed_paths`, `verification`, `constraints`, `network`, `external_cost`, and `timeout_seconds`. Reject absolute allowed paths, `..`, `.git`, secret files, an empty goal, or a timeout above project policy.
- [ ] **Step 4: Implement private run state**
Create `/tmp/agent-exec-<uid>/<run-id>/` with mode `0700`. Record config digest, base HEAD/tree, unit digest, attempts, worktree paths, process metadata, receipts, raw logs, transport refs, and cleanup state. Refuse symlinked or foreign-owned roots.
- [ ] **Step 5: Implement candidate selection and fresh worktrees**
For each role profile, create a new detached worktree from the fixed base, build the adapter invocation, launch a new process group, and never reuse a session. Missing/incompatible candidates become `unavailable` receipts without creating a provider request.
- [ ] **Step 6: Implement supervision and bounded output**
Capture stdout/stderr to private files, enforce idle/total timeout, terminate the process group, preserve exact exit state, and write bounded sanitized summaries. A process exit alone never proves no external side effect.
- [ ] **Step 7: Implement scope and transport checks**
Verify HEAD/base did not move, inventory tracked and untracked changes, reject paths outside `allowed_paths`, then create a host-owned synthetic transport commit with the recorded base as sole parent. Worker output never writes the canonical index or branch.
- [ ] **Step 8: Implement state classification and fallback**
Classify `success`, `unavailable`, `failed-clean`, `failed-unknown`, `scope-expansion`, `invalid-config`, and `cancelled`. Emit `host-fallback-authorized` only after every configured candidate is unavailable for the unit and every attempt has exact cleanup evidence.
- [ ] **Step 9: Finalize CLI and Make target**
Implement:
```text
python3 scripts/agent_exec.py validate --repo <path>
python3 scripts/agent_exec.py run --repo <path> --role <role> --unit <packet> --receipt <path>
```
Return stable exit codes for success, host fallback, invalid configuration, blocked/unknown state, and ordinary unavailable exhaustion. Update `make agent-exec-validate` to call the final CLI.
- [ ] **Step 10: Run U3 green**
Run: `python3 -m unittest tests.test_agent_exec_config tests.test_agent_exec_adapters tests.test_agent_exec -v`
Expected: PASS.
- [ ] **Step 11: Run governance regression**
Run: `make test-governance`
Expected: PASS with no tracked worktree changes.
- [ ] **Step 12: Host integration commit**
Commit U3 files with subject `Add recoverable execution agent controller` after inspecting transport and authoritative test output.
### Task 4: U4 Project Governance Integration
**Files:**
- Modify: `AGENTS.md`
- Modify: `policy/delivery.md`
- Modify: `policy/governance.md`
- Modify: `policy/adoption.md`
- Modify: `policy/tool-adaptation-matrix.md`
- Modify: `scripts/task.sh`
- Modify: `tests/test_task.py`
- Modify: `.task/feature-goal-first-delivery.md`
**Interfaces:**
- Consumes: `agent-exec validate/run`, receipt schema, `AGENT-EXECUTION.md`
- Produces: agent-per-unit repository rule, task-card profile/attempt/fallback fields, and adoption/verification entrypoints
- [ ] **Step 1: Change task-card tests red**
Update `test_start_imports_precheck_and_creates_four_part_commit` to require:
```text
实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
配置摘要、角色、候选顺序、attempt、CLI/模型、终态、transport、fallback 与收据路径
```
Require the generated card to reject the obsolete fixed-Cursor wording.
- [ ] **Step 2: Run the focused task test red**
Run: `python3 -m unittest tests.test_task.TaskLifecycleTests.test_start_imports_precheck_and_creates_four_part_commit -v`
Expected: FAIL because the template still says `cursor-per-unit`.
- [ ] **Step 3: Replace fixed-Cursor policy with the configuration pointer**
Keep `AGENTS.md` short: require reading `AGENT-EXECUTION.md` when routing implementation, repair, test, or review work. Move adapter and fallback detail to the config/design and policy. Replace, rather than layer on, the current `cursor-per-unit` authority.
- [ ] **Step 4: Update delivery and governance policy**
State that external agents implement per bounded unit, host owns planning and delivery, and current-host implementation is permitted only with a valid `host-fallback-authorized` receipt. Preserve goal-first, evidence, Review, CI, merge, cleanup, and dual-key rules.
- [ ] **Step 5: Update task generator and capability records**
Generate the agent-per-unit fields and keep all initial attempt states `NOT_RUN`. Mark config parsing/controller tests as local enforced behavior, real provider/model identity as SELF unless independently attested, and remote platform admission as GATE.
- [ ] **Step 6: Run U4 green**
Run:
```bash
python3 -m unittest tests.test_task.TaskLifecycleTests.test_start_imports_precheck_and_creates_four_part_commit -v
python3 scripts/agent_exec.py validate --repo .
make test-governance
```
Expected: PASS.
- [ ] **Step 7: Host integration commit**
Commit only U4 paths with subject `Route project work through configured agents`.
### Task 5: U5 Real CLI Probes and Combination Acceptance
**Files:**
- Create: `tests/fixtures/agent-exec/README.md`
- Modify: `tests/test_agent_exec.py`
- Modify: `.task/feature-goal-first-delivery.md`
**Interfaces:**
- Consumes: installed CLI profiles and `agent-exec run`
- Produces: source-external probe receipts, final requirements mapping, and an adoption recommendation
- [ ] **Step 1: Add opt-in real-probe harness tests**
Add a harness gated by `RUN_REAL_AGENT_EXEC=1`. It creates a temporary Git repository and a one-file unit packet. Each installed CLI is asked to create an exact marker file in its isolated workspace. The host verifies content, transport parent, changed paths, cleanup, model receipt status, and canonical-tree preservation. Missing OpenCode is expected `unavailable`.
- [ ] **Step 2: Run fake and full local regression**
Run:
```bash
python3 -m unittest tests.test_agent_exec_config tests.test_agent_exec_adapters tests.test_agent_exec -v
make test-governance
make test
make build
```
Expected: PASS; any pre-existing build warning remains non-blocking unless it affects the requested capability.
- [ ] **Step 3: Run installed CLI probes one profile at a time**
Use source-external receipts and a fixed temporary repository. Run Cursor first as the implementation acceptance path, then `agy`, Claude, PI, Codex, and Kimi. Do not run profiles concurrently against the same target. A provider quota or auth failure is recorded as `unavailable` for that probe and does not become a false PASS.
- [ ] **Step 4: Exercise host fallback**
Use a configuration whose candidates are deterministic missing executables. Verify `host-fallback-authorized`, then let the current host create the marker strictly inside the receipt's allowed scope. Run the authoritative verification and record the fallback attempt separately from external-agent success.
- [ ] **Step 5: Verify R1-R10 and migration**
Map every spec requirement to config/parser/adapter/controller/governance tests and exact receipts. Confirm no active fixed-Cursor authority remains, no task outside this scope was modified, and no CLI received commit/push/PR/merge/deploy authority.
- [ ] **Step 6: Commit acceptance records**
Commit only tracked fixtures and task-card management metadata with subject `Record execution agent acceptance evidence`. Raw CLI logs and source-external receipts remain outside Git.
- [ ] **Step 7: Enter normal delivery gates**
Run `make task-sync` before formal acceptance, Review request, and merge. Obtain an independent code-review receipt, push one PR, wait for exact-HEAD `test`, `test-pg`, and `svc-realcombo`, merge through Gitea with `force_merge=false`, verify the actual main tree, and safely close the task.
## Requirements Trace
| Requirement | Owning task and proof |
|---|---|
| R1 project-level single configuration | Task 1 parser/schema tests; Task 4 `AGENTS.md` pointer and task-card contract |
| R2 declarative role routing | Task 1 role-order tests; Task 3 ordered selection tests |
| R3 optional model | Task 1 `auto -> None`; Task 2 auto/fixed-model argv tests |
| R4 run-everything priority | Task 2 permission mapping tests; Task 5 installed-CLI probes |
| R5 multi-CLI adapters | Task 2 fake contracts for seven adapters; Task 5 real installed-CLI outcomes |
| R6 safe host fallback | Task 3 exhaustion, restoration, unknown-state and fallback tests; Task 5 real fallback drill |
| R7 low host-model consumption | Task 3 output-cap tests; Task 5 receipt and raw-log boundary review |
| R8 strict scope | Task 3 allowed-path, HEAD movement, transport, and retained-workspace tests |
| R9 controlled custom adapter | Task 1 placeholder/shell rejection; Task 2 direct-argv custom adapter tests |
| R10 recoverable evidence | Task 3 attempt/transport/cleanup receipts; Task 4 task-card fields; Task 5 evidence mapping |
## Definition of Done
- R1-R10 have code, tests, and exact evidence mappings.
- `AGENT-EXECUTION.md` validates and is the only project execution-routing authority.
- Cursor implements every repository-writing task in this plan unless a recorded all-unavailable receipt authorizes host fallback.
- Every successful worker result is scope-inspected, authoritatively tested, and committed by the host.
- Fake adapters cover all built-in routes; installed real CLIs have source-external probe outcomes.
- Full local test/build pass on the fixed candidate, independent Review has no blocking findings, and exact-HEAD CI passes before merge.
- No deployment, platform-protection change, secret persistence, or unrelated cleanup occurs.
@@ -0,0 +1,142 @@
# development-governance-v2 统一治理主记录
本文件是治理大任务跨仓状态的唯一汇总。每行状态只取以下值之一,不用笼统的“完成”:
`PLANNED / IMPLEMENTED / LOCALLY_VERIFIED / PR_OPEN / REVIEWED / GATE_PASS / MERGED / ADOPTED_ACTIVE / RELEASED / CLOSED`。
通过类结论须带来源(GATE / REPLAY / SELF)与对象 SHA;历史对象证据不得充当当前 HEAD 证据。
全局任务只有在全部正式仓达到 `ADOPTED_ACTIVE`、新项目入口启用、主 PR 全部合入并完成清理后才能标记 `CLOSED`。
## 全局状态
**CLOSED(2026-10-17;生效条件:本收尾 PR [#604](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/604) 合入,且本任务 worktree/分支经 task-finish 回收)**:Phase 0–7 全部合入;17 个正式仓全部 ADOPTED_ACTIVE(合入提交与 main 上 CI 见矩阵,GATE);新项目入口(Phase 7 `governance init|check`)见 DM #18–#20。采纳卡归档状态(2026-10-17 经 Gitea contents API 读各仓 main 核对,SELF):除 Guidelines 与 Dev 外的 15 个仓 `.task/archive/feature-governance-adoption.md` 存在,且 `.task/` 下无未闭合同名卡;Development-Guidelines 无采纳任务卡,采纳记录为 PR #9 新增的 `policy/guidelines-adoption.md`;Dev 收尾卡 `feature-governance-v2-closeout` 与本收尾卡随本 PR 闭合归档。其他仓采纳 worktree/分支回收状态本记录未取证 [未经证实],以各仓清理记录为准。`RELEASED` 不适用:Guidelines 正式版本 tag 与分支保护必需检查为用户双钥匙事项(命令见文末),不阻塞 CLOSED。
## 交付主线
| Phase | 内容 | 仓库 / 分支 | PR | 状态 | 依赖 |
|---|---|---|---|---|---|
| 0 | 纠正候选状态、建立本主记录 | Dev `feature/development-governance-v2` | [#585](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/585) | MERGED | — |
| 1 | Guidelines 合同加固 | Guidelines contract-hardening child → initiative → main | [#8](https://git-home.u1680832.nyat.app:30319/weichen/Development-Guidelines/pulls/8)、[#7](https://git-home.u1680832.nyat.app:30319/weichen/Development-Guidelines/pulls/7) | MERGED(Guidelines main 2688fd2) | — |
| 2 | Dev triage 与两级生命周期整改 | Dev child triage-hardening / target-integrity → initiative | [#595](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/595)、[#596](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/596) | MERGED(进入 initiative) | 1 |
| 3 | 真实两级 PR 演练 | Dev child PR → initiative → #585 → main | #595、#596 → #585 | MERGED(证据见 Dev 归档卡 feature-development-governance-v2) | 2 |
| 4 | Guidelines 合入 → Dev gitlink → Review → 三项 CI → 合入 #585 → 收口 | Guidelines / Dev | #7 / #585 / [#597](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/597) | CLOSED(Dev main aee351a;卡片归档 682a4e8) | 1–3 |
| 5 | DM 共享执行器 `agent-exec`;Dev 薄入口切换与 Python 退役 | DM [#16](https://git-home.u1680832.nyat.app:30319/weichen/Development-Manager/pulls/16)、[#17](https://git-home.u1680832.nyat.app:30319/weichen/Development-Manager/pulls/17);Dev `feature/dev-shared-executor-switch` | #16、#17、Dev [#600](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/600) | MERGED(DM 183e764、9c38345;Dev #600 合入 a5829c2:薄入口切换与 Python 退役,卡片闭合 #601;Dev 现经 `scripts/agent-exec` 运行固定 DM 版本) | 4 |
| 6 | 存量仓逐仓采纳 | 各仓 `feature/governance-adoption`;Dev `feature/governance-v2-closeout` | 见下方采纳矩阵 | ADOPTED_ACTIVE(17/17:全部已合入且 main 上 CI 通过) | 5、7 |
| 7 | 新项目治理初始化与 CI 准入 | DM `feature/governance-kit`(K1 triage、K2 start/pr-check、K3 governance init/check)及后续修复 | [#18](https://git-home.u1680832.nyat.app:30319/weichen/Development-Manager/pulls/18)、[#19](https://git-home.u1680832.nyat.app:30319/weichen/Development-Manager/pulls/19)、[#20](https://git-home.u1680832.nyat.app:30319/weichen/Development-Manager/pulls/20) | MERGED(#18 42e675f;#19 钩子环境修复;#20 `governance check --guidelines-self`,DM main 0552b73;均经独立 Review 与 CI GATE) | 5 |
## 历史候选对象与证据(Phase 4 时点;当前 main 对象见采纳矩阵)
| 仓库 | 分支 | 对象 | 证据 | 说明 |
|---|---|---|---|---|
| Development-Guidelines | main | `2688fd2` | PR #7 合入(Review REPLAY + 平台合入) | draft.12 合同与两个 Schema |
| Agent-System-Dev | main | `aee351a` | run 3509 三项 CI(GATE,head d648826)+ PI Review(REPLAY) | 两级分支、强制 triage、PR base 门禁 |
| Development-Manager | main | `183e764` | DM CI(GATE)+ PI Review(REPLAY) | `dm-server agent-exec` |
## 已确认阻塞缺陷(整改前)
1. Dev `task-triage` 按接纳中 initiative 数量直接给出 `JOIN`,不做适配判断(违反 KTD1)。
2. Dev `task-triage` 只扫描当前检出的 `.task/`,看不到只存在于远端分支的 initiative(违反 KTD2)。
3. `task-start KIND=child` 依赖本机已有父分支,未校验父 initiative 仍开放、接纳需求(违反 KTD3)。
4. `task-start` 不要求 triage 收据;无 PR base 门禁;闭合记录与证据未贯穿 `immediate_target`。
5. Guidelines 缺 terminal receipt 机器 Schema;配置 Schema 未覆盖 transport/admission/豁免/清理;`all-unavailable` 未与新项目准入隔离;triage 合同仍为数量判定。
6. 原 U4 实施方式为 host 预写补丁交 CLI 应用,后续单元须由 CLI 自主实施。
## 正式仓库清单与采纳矩阵
来源:Gitea `/user/repos`(2026-10-16 实测)。排除:`Agent-System`(冻结参考仓,不再开发)、`SMDF-Agent-System`(空仓)、
`governance-drill-2026-09` 与 `merge-queue-admission-fixture-20261014`(演练夹具)。本机 `*-wt-*`、备份与组合目录不计入。
| 批次 | 仓库 | Guidelines 固定版本 | AGENT-EXECUTION.md | 共享执行器入口 | 采纳 PR | 合入提交 | main 上 CI(GATE) | 状态 |
|---|---|---|---|---|---|---|---|---|
| A | Development-Guidelines | 自身(规范源) | 有(active) | scripts/agent-exec → DM 0552b73 | [#9](https://git-home.u1680832.nyat.app:30319/weichen/Development-Guidelines/pulls/9) | 6c8e6cd | governance success | ADOPTED_ACTIVE |
| A | Agent-System-Dev | deps/development-guidelines 2688fd2 | 有(active) | scripts/agent-exec → DM 0552b73 | [#602](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/602) | f563ed6 | ci / test、test-pg、svc-realcombo success([run 3687](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/actions/runs/3687));governance check 位于必需检查 `ci / test` | ADOPTED_ACTIVE |
| A | Development-Manager | development/guidelines 2688fd2 | 有(active) | 实现方:scripts/agent-exec 构建已提交 HEAD | [#21](https://git-home.u1680832.nyat.app:30319/weichen/Development-Manager/pulls/21)(证据日志补入 [#22](https://git-home.u1680832.nyat.app:30319/weichen/Development-Manager/pulls/22)) | c261cdd | ci / build-test success(含 agent-exec validate 与 governance check --implementer) | ADOPTED_ACTIVE |
| B | Agent-System-Core | 2688fd2 | 有(active) | scripts/agent-exec → DM bd3a7de | [#35](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Core/pulls/35) | 5cae3a6 | governance success | ADOPTED_ACTIVE |
| B | Agent-System-Backend | 2688fd2 | 有(active) | scripts/agent-exec → DM bd3a7de | [#208](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Backend/pulls/208) | cac60c0 | governance success;ci / vet-and-test 首次因既有不稳定测试 TestProjectEventsSharedProofAndPrivatePagination 失败(与 PR 头同树,PR 头通过),对象 cac60c0 重跑 success([run 3570 job 5779](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Backend/actions/runs/3570/jobs/5779)) | ADOPTED_ACTIVE |
| B | Agent-System-RDM | 2688fd2 | 有(active) | scripts/agent-exec → DM bd3a7de | [#431](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-RDM/pulls/431) | 7476a04 | governance、ci / build-and-test success | ADOPTED_ACTIVE |
| C | Agent-System-Frontend | 2688fd2 | 有(active) | scripts/agent-exec → DM bd3a7de | [#105](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Frontend/pulls/105) | 0f31f91 | governance success | ADOPTED_ACTIVE |
| C | Agent-System-UI | 2688fd2 | 有(active) | scripts/agent-exec → DM bd3a7de | [#58](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-UI/pulls/58) | a313d45 | governance、ci / test success | ADOPTED_ACTIVE |
| C | Agent-System-Documents | 2688fd2 | 有(active) | scripts/agent-exec → DM bd3a7de | [#110](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Documents/pulls/110) | 6c04eb2 | governance success | ADOPTED_ACTIVE |
| C | Agent-System-Releases | 2688fd2 | 有(active) | scripts/agent-exec → DM bd3a7de | [#2](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Releases/pulls/2) | 99c89b6 | governance success | ADOPTED_ACTIVE |
| D | Agent-Command | 2688fd2 | 有(active) | scripts/agent-exec → DM bd3a7de | [#8](https://git-home.u1680832.nyat.app:30319/weichen/Agent-Command/pulls/8) | 00e0875 | governance success | ADOPTED_ACTIVE |
| D | Agent-Intent | 2688fd2 | 有(active) | scripts/agent-exec → DM bd3a7de | [#12](https://git-home.u1680832.nyat.app:30319/weichen/Agent-Intent/pulls/12) | 651a2e1 | governance、ci 两项 success | ADOPTED_ACTIVE |
| D | Agent-Native | 2688fd2 | 有(active) | scripts/agent-exec → DM bd3a7de | [#47](https://git-home.u1680832.nyat.app:30319/weichen/Agent-Native/pulls/47) | 14d4869 | governance、ci 两项 success | ADOPTED_ACTIVE |
| D | Agent-Squad | 2688fd2 | 有(active) | scripts/agent-exec → DM bd3a7de | [#54](https://git-home.u1680832.nyat.app:30319/weichen/Agent-Squad/pulls/54) | 9ded893 | governance、ci 两项 success(deps/agent-native、deps/agent-intent 同步到两者采纳后 main,submodule-consistency 全 ok) | ADOPTED_ACTIVE |
| E | Error-Code-System | 2688fd2 | 有(active) | scripts/agent-exec → DM bd3a7de | [#4](https://git-home.u1680832.nyat.app:30319/weichen/Error-Code-System/pulls/4) | 3d4d5e6 | governance、ci 两项 success | ADOPTED_ACTIVE |
| E | Logging-System | 2688fd2 | 有(active) | scripts/agent-exec → DM bd3a7de | [#4](https://git-home.u1680832.nyat.app:30319/weichen/Logging-System/pulls/4) | 1758e2c | governance、ci 两项 success | ADOPTED_ACTIVE |
| E | Agent-Document-Renderer | 2688fd2 | 有(active) | scripts/agent-exec → DM bd3a7de | [#6](https://git-home.u1680832.nyat.app:30319/weichen/Agent-Document-Renderer/pulls/6) | 770d886 | governance success | ADOPTED_ACTIVE |
每仓采纳均按同一 10 步:固定 Guidelines、AGENT-EXECUTION.md、薄入口(`scripts/dm`/`scripts/agent-exec`/`scripts/task`)、四条路由、任务卡模板与分支元数据、CI 中 schema 校验与 governance check、一次真实正例单元(agent-per-unit,经 `agent-exec apply` 集成)、负例(bad-receipt、out-of-scope-path、unknown-side-effect、admit 拒绝;冻结脚本 `evidence/governance-adopt-cases.py`)、独立 Review(全新只读会话,闭合重审只围绕阻塞项)与 PR 头 CI、采纳状态 active。上述 15 个仓的收据、证据与 Review 结论记录在各自归档任务卡 `.task/archive/feature-governance-adoption.md` 中(归档卡存在性见“全局状态”,SELF;卡内证据未在本记录复核 [未经证实])。Guidelines 按其 CONTRIBUTING.md 记录在本目录 `2026-10-17-guidelines-governance-adoption.md` 与该仓 `policy/guidelines-adoption.md`。Dev 记录在 `.task/archive/feature-governance-v2-closeout.md`。
## Owner 决策记录
| 日期 | 决策 | 影响 |
|---|---|---|
| 2026-10-16 | cursor 服务端故障期间临时让 agy 成为首选;实际以不含 cursor 包装脚本的 PATH 启动执行器实现(停用 cursor profile 会使 Dev 参考解析器拒绝配置),cursor 冒烟恢复后回到正常 PATH | 无配置改动;收据中 cursor 如实记为 unavailable |
| 2026-10-17 | 共享执行器分发:各正式仓像 Guidelines 一样固定 Development-Manager gitlink(`deps/development-manager`),薄入口 `scripts/agent-exec` 构建/运行该固定版本的 `dm-server agent-exec`;CI 用同一固定版本运行 `agent-exec validate` | Phase 6 每仓增加 DM gitlink 与薄入口;Dev Python 实现退役后同样切到该入口 |
| 2026-10-17 | CI 读取私有 Guidelines/DM 子模块所需的 `SUBMODULE_TOKEN`:owner 授权智能体以 `~/.secrets/gitea` 的 API token 作为该 secret 值(只记录来源,不记录值) | 已为 Development-Manager 配置;Phase 6 按需为其他仓配置 |
| 2026-10-17 | Phase 6/7 共享入口:存量仓与新项目没有 Dev 的 task.sh,通用 triage/start/pr-check 与 `governance init|check` 放入 DM(治理套件),各仓经薄入口调用,不复制实现;先完成 Phase 7 套件再用其推进 Phase 6 | DM `feature/governance-kit`;Dev 现有 task.sh 生命周期不变 |
| 2026-10-17 | DM CI 自 2026-09-30 起从未成功(runner 无法拉取 github.com 上的 actions/checkout);按 Dev 已审阅的内联检出模式改为自包含 CI(DM-U6) | Phase 6 中使用 `uses:` 的仓(Error-Code-System、Logging-System)同样需要检查 |
| 2026-10-17 | 存量仓 CI 无法访问 github.com:Error-Code-System、Logging-System 的 `uses: actions/checkout` 改为与 governance.yml 相同的内联检出(凭据经 GIT_CONFIG_* 环境变量,`checkout -f` + `clean -ffdxq` 保持 clean 语义) | 两仓既有 CI 恢复可运行 |
| 2026-10-17 | Guidelines 冲突裁定(contrib_exception):CONTRIBUTING.md 增加一句窄例外,允许本库自身治理文件入库;过程记录仍不入库;规范正文与 VERSION 不变 | Guidelines #9 |
| 2026-10-17 | DM #21 保留新增回归测试 `cmd/dm-server/implementer_entry_test.go`(approve_test),豁免原“不改 Go 代码”表述;生产 Go 代码不变 | DM #21 |
| 2026-10-17 | codex/pi Review 额度受限(429)期间,独立 Review 改由全新只读 Cursor CLI 会话(`--mode ask`,session id not-observable)执行;评审只接收目标、base/head、diff 与证据 | 各仓 Review 记录标注 fresh_session 与 not-observable |
## 停止条件
无法获取权威远端 initiative;triage 收据与需求或候选 HEAD 不一致;child PR base 错误;Guidelines gitlink 未指向真实已合入版本;
CLI 终态无效或副作用未知;Review、CI 或平台准入缺失;主干在最终 CI 后继续前进;存量仓无共享执行器却启用强制规则;
需要发布规范 tag 而用户尚未执行双钥匙操作。出现任一项即停止对应交付窗口。
## 用户双钥匙事项
- Development-Guidelines 正式版本 tag:Agent 只准备命令,由用户执行。
- 分支保护:把 governance 检查设为各仓 main 的必需状态检查。以下命令由用户确认后亲手执行(token 只从 `~/.secrets/gitea` 读取,不回显)。
PATCH 会整体替换 `status_check_contexts`:执行前先 GET 核对(2026-10-17 只读核对:除 Dev 外各仓 main 规则均未启用状态检查、contexts 为空)。已有 `main` 规则的仓用 PATCH;Agent-System-Releases、Agent-Document-Renderer 尚无规则,用 POST 新建。Dev 的 governance check 位于既有必需检查 `ci / test` 中,无需改动。
```bash
API=https://git-home.u1680832.nyat.app:30319/api/v1
HDR=$(umask 077; mktemp) # token 只进 0600 临时头文件,不进命令行参数
printf 'Authorization: token %s\n' "$(sed -n 's/.*ACCESS_TOKEN=//p' ~/.secrets/gitea)" > "$HDR"
protect() { # protect <repo> <PATCH|POST> <context>...
repo=$1 method=$2; shift 2
ctx=$(printf '%s\n' "$@" | python3 -c 'import json,sys;print(json.dumps([l.strip() for l in sys.stdin if l.strip()]))')
if [ "$method" = PATCH ]; then url=$API/repos/weichen/$repo/branch_protections/main
body="{\"enable_status_check\":true,\"status_check_contexts\":$ctx}"
else url=$API/repos/weichen/$repo/branch_protections
body="{\"rule_name\":\"main\",\"enable_status_check\":true,\"status_check_contexts\":$ctx}"
fi
curl -sS -o /dev/null -w "$repo %{http_code}\n" -X "$method" -H @"$HDR" -H 'Content-Type: application/json' "$url" -d "$body"
}
GOV='governance / governance (pull_request)'
protect Development-Guidelines PATCH "$GOV"
protect Development-Manager PATCH 'ci / build-test (pull_request)'
protect Agent-System-Core PATCH "$GOV"
protect Agent-System-Backend PATCH "$GOV" 'ci / vet-and-test (pull_request)'
protect Agent-System-RDM PATCH "$GOV" 'ci / build-and-test (pull_request)'
protect Agent-System-Frontend PATCH "$GOV"
protect Agent-System-UI PATCH "$GOV" 'ci / test (pull_request)'
protect Agent-System-Documents PATCH "$GOV"
protect Agent-System-Releases POST "$GOV"
protect Agent-Command PATCH "$GOV"
for r in Agent-Intent Agent-Native Agent-Squad Error-Code-System Logging-System; do
protect "$r" PATCH "$GOV" 'ci / vet-and-test (pull_request)' 'ci / docker-checkout-hostgateway (pull_request)'
done
protect Agent-Document-Renderer POST "$GOV"
rm -f "$HDR"
```
设为必需检查并补一次被阻断的负例 PR 后,各仓采纳记录中 agent-execution 行才可由 advisory 登记为 enforced。
## 非阻塞遗留项(不阻塞本次交付,建议独立增量)
1. 各仓 `AGENT-EXECUTION.md` 说明文字仍有 kit 模板句“下例的 CLI 名称、命令与路径均为占位”(Agent-Intent 已改写);应修 DM kit 模板后统一刷新。
2. Agent-System-Backend、Agent-System-Frontend 归档卡内少量证据相对链接未随归档调整。
3. Agent-System-Backend 既有 CI 把 token 写入全局 git config(`insteadOf`);建议改为 URL 限定的 extraheader 环境变量方式。
4. DM `agent-exec` 的 host 豁免路径(`.task/**` 等)为硬编码;可改为读取 AGENT-EXECUTION.md。
5. 候选 PR 可修改自身 `governance.yml`(工作流取自 PR 头);单人仓风险可接受,多人协作前改为基线工作流或必需检查来源固定。
6. 各仓 governance.yml 从镜像下载 Go 未做 sha256 校验。
7. Agent-System-Backend 既有不稳定测试 `TestProjectEventsSharedProofAndPrivatePagination`。
8. 旧 `feature/card-close-*` 远端分支待清点。
9. Agent-System-Backend `internal/runtime` 不稳定测试 `TestToolCallDeltaBeforeExecution`(`llm_test.go:1084` 事件顺序断言;Dev PR #602 run 3685 与 PR #604 [run 3694](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/actions/runs/3694/jobs/5842) 失败、重跑通过;根因 [未经证实])。第 7 项同在 PR #604 run 3694 test-pg 出现。
10. `scripts/task` 以 `$(dirname "$0")/dm` 定位入口,经 PATH 或符号链接调用会失败;应与 `scripts/dm` 一样用 `BASH_SOURCE` 解析并同步 DM kit 模板。
11. 分支保护命令片段未设 `trap`,异常退出时临时头文件不会删除(0600、用户手动执行,低风险)。
@@ -0,0 +1,112 @@
# 文档驾驶舱可视化分阶段实施与验收计划 r1
状态:待评审;本计划描述后续执行顺序,不构成业务实施授权。真实实现、迁移、部署、模型数据和浏览器验收均为 `NOT_RUN`。
## 1. 目标
按四个可独立验证的增量,把既有 RDM 文档树/追溯读取能力提升为项目文档驾驶舱。每个增量都必须保持旧四入口可用,并且不新建写入权威或绕过授权的接口。
## 2. 依赖与边界
- 依赖既有 RDM 项目绑定、文档树、关系、事件历史和权限合同;先重新核对当前组件 pin 和接口,再实现。
- 复用 Frontend/UI 的三栏工作台、`@ui` tokens、`Collapsible` 和现有异步状态所有者。
- 不在本计划内修改模型路由、文档生成/审批、数据库主存储或部署配置。
- 任何跨仓 gitlink、领域 schema、权限语义或导出行为变化都要单独建立任务和评审记录。
## 3. 增量分解
### I1:聚合读取服务和 DTO
**产物**:`CockpitOverview`、`TreePage`、`NodeDetail`、来源/历史/影响/冲突分页接口;适配既有 RDM 读取命令;项目/资源/字段级授权;快照 revision、cursor、截断和错误契约。
**直接验证**:
- 同一节点在不同项目请求下返回 404/拒绝,不泄露存在性。
- 统计、树、详情和面板使用相同 `snapshotRevision`/`asOfSeq`。
- 空、部分、受限、过期、上游失败和关系截断都有可判定 DTO。
- 历史查询不会落在未提交批次中间序号。
**停止条件**:若现有领域数据无法提供某字段,返回明确 `unavailable`/`partial`,不得在服务中生成猜测值。
### I2:共享选择与全景投影
**产物**:项目统计带、文档结构树、全景中央概览、筛选和分页;共享 `selectedNodeRef`、`filterHash`、`snapshotRevision`;过期/刷新提示。
**直接验证**:
- 展开、分页、选择和筛选不会让旧响应覆盖新项目或新筛选。
- 树徽标和统计来自同一快照;刷新不重置用户选择。
- 无文档、无权限、部分加载和截断状态可读。
**停止条件**:如果真实数据没有段落级结构,使用实际可用层级并标注 structural gap,不伪造段落。
### I3:阅读器与右侧依据/影响面板
**产物**:连续正文阅读、版本摘要/差异折叠、来源/历史/影响/冲突标签页、全景↔阅读器定位、个人视图偏好。
**直接验证**:
- 从全景选择段落切换阅读器后,正文、面板和 URL/内存状态指向同一 `nodeRef`。
- 私有来源正文按字段级披露脱敏;受限不显示为空。
- 乱序事件、断线和后台更新不会抢占滚动位置。
- 所有折叠、颜色、字号和动效通过设计令牌守护。
**停止条件**:不增加第四栏或独立关系图;关系仅在右栏局部展开。
### I4:组合验证与浏览器验收
**产物**:跨 RDM/Frontend/UI 的组合测试、权限负例、快照一致性测试、Playwright 场景和设计守护证据。
**最小场景集**:
1. 首次进入项目:统计、树、全景可见。
2. 选中文档→章节→段落:全景与阅读器双向定位。
3. 来源、历史、影响、冲突展开并正确显示计数/截断。
4. 未核实来源和冲突状态改变后,所有投影一致。
5. 过期/断线/部分失败保留旧快照并给出刷新入口。
6. 未授权项目、节点、来源和下载均失败或脱敏。
7. 320/390/736/1024/1440 宽度、18px UI 字号、键盘和减少动效。
## 4. 测试矩阵
| 类别 | 必测内容 | 结果来源 |
|---|---|---|
| DTO/服务 | schema、分页、错误、截断、快照一致性 | 单元/集成测试;最终以 CI 为准 |
| 授权 | 项目越界、成员/职责、字段级来源披露、下载/导出 | 后端负例与独立重放 |
| 状态 | 旧响应、乱序事件、上下文切换、断线、过期快照 | Frontend store 测试 |
| 设计门禁 | 裸色、私有 keyframes、行内字号、`details` 禁止 | UI/Frontend design-guard |
| 浏览器 | 双视图、定位、面板、窄屏和键盘 | Playwright;真实后端链路另记 |
| 组合 | 固定组件 SHA、`make test`、`make build` | Dev 当前 HEAD CI/GATE |
## 5. 需求到验收映射
| 需求 | 计划增量 | 验收 |
|---|---|---|
| DV-R01 | I1/I2 | 项目统计与不可用原因测试 + 首屏浏览器场景 |
| DV-R02 | I1/I2 | 树分页/展开/状态测试 |
| DV-R03 | I2/I3 | 共享选中节点与视图切换场景 |
| DV-R04 | I1/I3 | 四面板分页、计数、截断与定位场景 |
| DV-R05 | I1/I2/I3 | 快照 revision、seq、旧响应丢弃测试 |
| DV-R06 | I1/I3/I4 | 项目/字段/下载授权负例 |
| DV-R07 | I3/I4 | 五宽度、18px、键盘、减少动效浏览器场景 |
| DV-R08 | I1/I2/I3 | 空、部分、过期、失败和截断状态场景 |
## 6. 交付门禁
每个增量在实现前需有独立任务卡、当前基线和明确文件范围;实现单元按仓库 `AGENT-EXECUTION.md` 路由,主模型负责集成和验证。请求审核、合入和完成声明前分别执行 `make task-sync`,命令输出通过 `make evidence` 写入任务卡。作者本地测试只能标 `SELF`;精确 HEAD 的 CI 标 `GATE`,独立复跑标 `REPLAY`。
## 7. 契约决策(已冻结 2026-10-16)
用户于 2026-10-16 评审四份文档并授权进入实施(`/goal 按照方案开始实施`),本节四项取舍由本轮评审冻结。依据为实施前对 RDM 后端(独立仓 `Agent-System-RDM`,main `5df66106`)的只读源审计;后续领域数据演进时按契约 §9 版本规则扩展,不在本版内回改。
1. **完成度分母只统计已存在的文档/章节节点。** 现状:文档树叶节点即章节 Section(`internal/domain/doctree.go:40-51`),`Section.Require` 标记必选章节,但“模板要求而未实例化的章节”缺少已核实的权威数据源;纳入分母会引入猜测值,触碰“不得生成猜测值”停止条件。树内结构性缺失继续由 `missingChildCount` 与 `structuralGap` 承载;模板级完成度留待后续增量,且须先核对 `Doc.Template` 的实例化语义。
2. **置信度由读模型固定为 `high/medium/low/unknown`,适配器不猜测。** 现状:领域仅有来源溯源枚举 `human|rule|model`(`internal/domain/eventlog.go:53-60`),无 confidence 数值;核验语义仅存在于法规双通道 `RegSource.Verified()`(`internal/domain/regcheck.go:13-27`)。v1 适配规则:只有可复核证据(如法规来源已核验)才产出 `high`,其余一律 `unknown`;禁止把溯源枚举直译为置信等级。
3. **首期冲突只投影领域现有检测视图,不做字段级断言。** 现状:无持久化冲突实体;冲突是 `fc.Detector` 对切片对的运行时碰撞检测(`internal/domain/fc/collide.go:27-53`),裁决落为 `supersedes` 追溯边并关闭成对 pending 项(`collide.go:125-145`)。v1 映射:pending 碰撞 → `open`;存在 supersedes 裁决 → `resolved`/`superseded`(按实际边语义);`acknowledged` 首期不产生。字段级断言冲突须等领域先有字段级断言登记,属后续领域增量。
4. **全景首屏只显示章节概览与统计,不显示段落摘要。** 现状:文档树只有 doc→section 两级,无段落层(`internal/domain/domain.go:23-35`);且首屏共享面上的正文摘要在无逐字段披露检查时会扩大敏感内容暴露。段落/正文摘要在选中节点与阅读器内按权限展示。
I1 的公开 DTO 实现自本节冻结起解锁;实施落点为 RDM 后端仓(聚合读取服务与命令),Dev 仓只承载文档、组合 pin 与后续前端集成。
## 8. 当前状态与下一步
四份文档已于 2026-10-16 评审通过,§7 四项决策冻结,实施授权已由用户给出(`/goal 按照方案开始实施`)。I1–I4、测试、CI、部署和业务验收仍为 `NOT_RUN`。下一步:合入本设计 PR 后,在 RDM 后端仓为 I1(聚合读取服务与 DTO)建立实施任务并按 AGENT-EXECUTION.md 拆分派发;I1 适配目标为 `rdm.inspect.*` 既有事实与 §7 冻结的映射规则。
@@ -0,0 +1,57 @@
# Development-Guidelines 采纳 development-governance-v2 治理套件 任务卡
任务主记录:[Development-Guidelines PR #9](https://git-home.u1680832.nyat.app:30319/weichen/Development-Guidelines/pulls/9)(本文件随 PR 描述维护)。
状态:已完成(PR #9 合入以平台记录为准);owner:weichen。
本卡放在 Agent-System-Dev 而非 Development-Guidelines:后者的 CONTRIBUTING.md 规定"项目事实与过程记录不提交本库",AGENTS.md 规定不复制完整日志;其既往 PR #7/#8 的过程记录同样位于 Dev。证据日志位于同目录 `evidence/guidelines-adoption/`。
## 基线与授权
- 权威仓:weichen/Development-Guidelines;root_target:main;immediate_target:main
- branch_kind:initiative;initiative_id:governance-adoption-Development-Guidelines
- R0(initial_main_sha):2688fd2be6a52c0bf110e7e6366b6f291ab5e4eb;工作区:/home/weichen/projects/Development-Guidelines-wt-feature-governance-adoption(worktree);分支:feature/governance-adoption
- accepting_requirements:false(单仓采纳 initiative,范围固定为下列十步)
- 需求分流:verdict=NEW;理由=development-governance-v2 Phase 6 每个正式仓库独立 initiative;triage 收据=无(本仓无 triage 入口)
- 授权与交付终点:owner 已授权 development-governance-v2 全部实施(主记录 2026-10-16-development-governance-v2-master.md);终点为采纳 PR 合入 main 且采纳状态 active。分支保护与 tag 由用户执行。
- 实施执行:agent-per-unit(配置:Development-Guidelines AGENT-EXECUTION.md;外部 Agent 一单元一新进程/会话/工作区)
## 目标与非目标
目标(Phase 6 十步,规范源变体):规范源不固定自身 gitlink,治理检查以 `--guidelines-self` 运行(DM #20,0552b73);增加 AGENT-EXECUTION.md;共享执行器薄入口(deps/development-manager @ 0552b7358d6955057d6eea090326f83317ed992a + scripts/dm、scripts/agent-exec、scripts/task);四条路由;任务卡模板(.task/templates/task-card.md);CI schema 校验(.gitea/workflows/governance.yml:agent-exec validate + governance check --guidelines-self);正例;负例(缺配置、坏收据、越界路径、未知副作用);独立 Review + CI;采纳状态 active。
非目标:不改规范正文(core/ standards/ workflows/ templates/)、README、CHANGELOG、VERSION;不改分支保护;不发布 tag。
引导说明:AGENT-EXECUTION.md 由 host 以固定版本治理套件(dm-server governance init @ 0552b73)生成并作为引导配置提交(bootstrap 提交 f7904ff;沿用 DM 采纳先例);其余文件由实施单元生成。
Owner 决策(2026-10-17,AskQuestion:contrib_exception):在 CONTRIBUTING.md 增加一句窄例外——本库自身治理文件(PROJECT.md、policy/guidelines-adoption.md、AGENT-EXECUTION.md、scripts/、governance.yml、.task/templates/、deps/development-manager)描述本库自身维护方式;过程记录仍不入库;规范正文与 VERSION 不变。由 repair-r3 实施。
## Agent 实施收据
| 单元 ID | 预期范围 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|---|---|---|---|---|---|---|---|---|---|
| governance-adoption-Development-Guidelines-r1 | 11 个允许路径(治理文件 + deps/development-manager gitlink) | implementation | cursor→antigravity→pi | run d88c47f0(dm-server 0552b73,attempts=1) | cursor / not-observable | success | e82e76ef026d(apply 快进 e82e76e) | 否 | /tmp/gov-receipt-Development-Guidelines-r1.json |
| governance-adoption-Development-Guidelines-repair-r1 | AGENT-EXECUTION.md、.task/templates/task-card.md | repair | cursor→antigravity→pi | run 4c475ff4(dm-server 0552b73,attempts=1) | cursor / not-observable | success | 523e71d5b797(apply 快进 e82e76e..523e71d) | 否 | /tmp/gov-receipt-Development-Guidelines-repair-r1.json |
| governance-adoption-Development-Guidelines-repair-r2 | CONTRIBUTING.md、AGENTS.md | repair | cursor→antigravity→pi | run dded35ab(attempts=1) | cursor / not-observable | failed-unknown(终态记录被 Markdown 代码围栏包裹,无有效 completed 记录;fail-stop 对账:canonical 仍为 523e71d 且干净,无 transport;以全新 r3 重做) | 无 | 否 | /tmp/gov-receipt-Development-Guidelines-repair-r2.json |
| governance-adoption-Development-Guidelines-repair-r3 | CONTRIBUTING.md、AGENTS.md | repair | cursor→antigravity→pi | run 3602b0e7(attempts=1) | cursor / not-observable | success | 7cafc7d03b4e(apply 快进 523e71d..7cafc7d) | 否 | /tmp/gov-receipt-Development-Guidelines-repair-r3.json |
## 同步记录
| 节点 | sync_base_sha | tested_head_sha | checked_at | 结果 |
|---|---|---|---|---|
| 启动 | 2688fd2be6a52c0bf110e7e6366b6f291ab5e4eb | 2688fd2be6a52c0bf110e7e6366b6f291ab5e4eb | 2026-10-17T08:24:00Z | 一致 |
## 结果与验证(完成后填写)
- 结果:Development-Guidelines 采纳治理套件——DM gitlink 0552b73、AGENT-EXECUTION.md 四条路由、共享执行器薄入口、pre-commit admit、governance CI(`--guidelines-self`);CONTRIBUTING.md 按 owner 决策增加本库治理文件窄例外;采纳状态 active(随合入生效)。
- 验证:见下表(命令输出由 ev.sh 写入 evidence/guidelines-adoption/,SELF 除非另注)。
- 影响与剩余项:规范正文与 VERSION 不变;本地钩子需人执行 `git config core.hooksPath scripts/hooks`;governance 检查设为分支保护必需项属用户双钥匙事项(命令见治理主记录)。非阻塞:AGENT-EXECUTION.md 模板“占位”句、governance.yml Go 下载无校验和。
| 时间(UTC) | 命令 | 被测 HEAD | exit | 来源 | 摘要/位置 |
|---|---|---|---|---|---|
| 20261017T083826Z | `scripts/dm governance check --repo . --guidelines-self` | e82e76ef026d | 0 | SELF | ok fixtures;[输出](evidence/guidelines-adoption/00-20261017T083826Z.log) sha256:4180c6acc02ae066 |
| 20261017T083826Z | `scripts/agent-exec validate --repo .` | e82e76ef026d | 0 | SELF | validate: ok;[输出](evidence/guidelines-adoption/01-20261017T083826Z.log) sha256:669adfbd9f1df9e6 |
| 20261017T083826Z | `python3 /tmp/gov-neg/adopt_cases.py .` | e82e76ef026d | 0 | SELF | [verdict] ALL PASS cases=5;[输出](evidence/guidelines-adoption/02-20261017T083826Z.log) sha256:f4e192e0f20271b8 |
| 20261017T092431Z | `scripts/dm governance check --repo . --guidelines-self` | 7cafc7d03b4e | 0 | SELF | ok fixtures;[输出](evidence/guidelines-adoption/03-20261017T092431Z.log) sha256:7d77f97d6a94be5b |
| 20261017T092431Z | `scripts/agent-exec validate --repo .` | 7cafc7d03b4e | 0 | SELF | validate: ok;[输出](evidence/guidelines-adoption/04-20261017T092431Z.log) sha256:359dfd4367a316e3 |
| 2026-10-17T09:32Z | 候选 HEAD CI `governance / governance (pull_request)` | 7cafc7d03b4e | 0 | GATE | success;[运行](https://git-home.u1680832.nyat.app:30319/weichen/Development-Guidelines/actions/runs/3644/jobs/5751) |
| 2026-10-17T09:32Z | 独立 Review | 7cafc7d03b4e | 0 | REPLAY | cursor-agent-stable --mode ask 全新只读会话(fresh_session=true,session id not-observable)闭合重审 VERDICT: APPROVE(对象 7cafc7d) |
@@ -0,0 +1,289 @@
---
title: Development Norm Remediation - Plan
type: fix
date: 2026-10-18
artifact_contract: ce-unified-plan/v1
product_contract_source: ce-plan-bootstrap
execution: code
---
# Development Norm Remediation - Plan
## Goal Capsule
- **Objective:** Dev contributors can identify the authoritative rule for each workflow, recover from safe remote interruptions, and still distinguish local progress from formally verified delivery.
- **Means:** Move portable policy to Development-Guidelines, keep Dev commands and choices in Dev, and use risk-specific outcomes instead of propagating every recoverable condition as a write ban.
- **Authority:** This artifact authorizes planning only. It does not authorize implementation, platform changes, credential operations, or release actions. Implementation requires a separate user instruction.
- **Stop conditions:** Preserve authorization, scope, secret-handling, unknown-side-effect, current-target, exact-head CI, independent review, and high-consequence boundaries. Stop for an unresolved decision that changes those boundaries.
- **Execution profile:** The work spans Development-Guidelines and Agent-System-Dev. Each repository retains its own branch, task record, review, CI, and merge lifecycle. Merge the shared rule change before updating Dev's guideline pin.
- **Finishing:** A future implementation run owns verification and PR delivery. Platform branch protection, publishing a Guidelines release tag, and credential rotation remain owner-controlled.
---
## Product Contract
### Summary
This plan corrects ownership and contradictions in the shared and Dev development rules. It also defines where authorized local work may continue without implying that the branch is ready for formal delivery.
### Problem Frame
The previous standards audit found that the shared delivery workflow hard-codes Dev's initiative/child branch model, the root entry repeats detailed policy, and the startup summary conflicts with the existing `LOCAL_READY` recovery path. It also found an outdated adoption record and unsafe or overly broad external-fact verification instructions.
The V3 delivery implementation is already merged by Dev PR #608. This plan does not repeat that work or run its future metrics review M.
### Requirements
#### Rule Ownership and Entry Points
- R1. Shared standards define reusable outcomes and boundaries without requiring Dev-specific branch names, task-card fields, or `make` commands.
- R2. Dev's `AGENTS.md` and `PROJECT.md` route readers to one detailed source for each rule or changing project status.
- R3. Dev task channels express priority and grouping without deciding branch depth when integration need does not require it.
#### Readiness and Continuation
- R4. Readiness states distinguish new-task startup, authorized local continuation of an existing task, and formal delivery.
- R5. A safe existing task may continue bounded local work when the authoritative remote is temporarily unavailable, provided its task identity, recorded baseline, authorization, and local workspace remain verifiable.
- R6. Local continuation never claims a fresh target, permits a new task to bypass remote triage, or replaces synchronization, review, current-head CI, or platform admission.
- R7. Dirty or shared workspaces, invalid authorization/configuration, scope expansion, secret exposure, unknown external side effects, and unresolved Git operations remain hard stops.
#### Adoption and External Facts
- R8. Adoption status, execution capability, and per-case conformance evidence remain separate; missing or unrun evidence stays `NOT_RUN`.
- R9. Credential checks do not print secrets or place expanded secret values in process-visible arguments, logs, or saved receipts.
- R10. An external-fact check supports the exact claim it records; an unrelated network failure cannot refresh a more specific causal claim.
### Acceptance Examples
- AE1. An existing, authorized task with a clean registered worktree and locally available R0 may continue local work during an origin outage, but cannot pass formal synchronization or merge gates.
- AE2. A new task cannot create a branch or worktree when remote triage is unavailable or the target cannot be verified.
- AE3. A dirty workspace, invalid task identity, unknown side effect, or scope expansion still stops the affected operation.
- AE4. A fake-token test proves that credential values do not appear in command arguments, output, logs, or receipts; it makes no request to Gitea.
- AE5. DNS failure or timeout does not verify the historical TLS-specific cause recorded for a retired endpoint.
### Scope Boundaries
**Included:** The pinned Development-Guidelines source and its Dev adoption; Dev's task readiness and recovery flow; Dev's delivery-routing policy; Dev's facts and credential instructions; and the affected root/project entrypoints.
**Deferred to Follow-Up Work:** Adoption by other repositories; a separate decision on a direct-authoring path for simple documentation; Dev V3 metrics review M, scheduled approximately two weeks after its merge; any broader governance automation. The newly requested CLI/subagent task-sizing and context-lifecycle work is now planned as U7 below; it does not expand U1-U6 implementation scope.
**Outside this plan:** Re-implementing V3 P1-P3; changing protected-branch rules; publishing a Guidelines release tag; rotating Gitea credentials; enabling an automatic merge queue; allowing host fallback for code or unknown worker outcomes; changing product runtime code.
---
## Planning Contract
### Key Technical Decisions
- KTD1. Keep one authority per rule: Guidelines owns reusable contracts; Dev `policy/` owns local behavior and commands; `AGENT-EXECUTION.md` owns machine-readable route selection; root files remain entrypoints and stable project facts. (session-settled: user-approved — chosen over a Dev-only correction: the approved plan covers both shared and project rule ownership.)
- KTD2. Use a three-way readiness distinction. Strict readiness applies to new task startup and formal delivery. Local readiness permits only authorized local work in an existing registered task with a safe workspace and locally verifiable recorded baseline. (session-settled: user-approved — chosen over blocking every write on remote drift: preserve core hard boundaries while allowing safe local progress.)
- KTD3. Preserve hard stops for authorization, scope, secrets, unknown side effects, dirty shared workspaces, and unresolved Git state. A remote outage may defer formal delivery without automatically discarding safe local progress.
- KTD4. Keep task category separate from integration topology. A fix can still receive priority; an initiative is required when multiple units need shared integration or acceptance, not only because work is labeled “new” or “improvement”.
- KTD5. Keep the agent-per-unit and no-host-fallback contract for code, policy semantics, routing, security, and execution configuration. This plan does not introduce a direct host-write exception; any non-normative documentation-only exception requires a separate explicit decision.
- KTD6. Change Guidelines in its own repository first. Update Dev's gitlink and adoption record only after the shared change is merged, then verify the pinned combination.
- KTD7. Preserve `active`/`manual` as separate adoption/capability dimensions, but reconcile them with the exact success and negative-case evidence required by the pinned adoption workflow. Never promote `NOT_RUN` from prose alone.
- KTD8. Keep F4 token-free and record only what the check proves. Retain the TLS cause as a dated historical observation unless a verifier can prove that specific condition.
### High-Level Technical Design
```mermaid
flowchart TD
A[Request or existing task] --> B{Existing registered task?}
B -->|No| C[Verify remote and triage]
C -->|Unavailable or unverified| D[Stop task creation; allow planning/read-only analysis]
C -->|Verified| E[Start against authoritative target]
B -->|Yes| F{Local identity and workspace safe?}
F -->|No| G[Hard stop and preserve workspace]
F -->|Yes| H{Remote fresh and target current?}
H -->|No| I[LOCAL_READY; allow bounded local work only]
H -->|Yes| J[READY / formal delivery path]
I --> K[Fresh fetch and sync required before review or merge]
J --> L[Exact-head review, required CI, platform admission]
K --> L
```
`LOCAL_READY` is a continuation state, not a weaker merge gate. `failed-unknown`, scope expansion, invalid authorization, and unowned workspace state do not enter the local-continuation branch.
### Alternatives Considered
| Approach | Assessment |
|---|---|
| Keep all current startup failures as global write blocks | Preserves simplicity but contradicts existing local recovery policy and prevents safe in-flight work during remote outages. |
| Treat every remote failure as permission to continue or start locally | Reduces blocks but can bypass initiative discovery, baseline freshness, and ownership checks. Rejected. |
| Permit local continuation only for an existing, authorized, verifiable task; retain strict new-start and final-delivery gates | Recommended. Preserves formal trust boundaries while allowing bounded local progress. |
| Let the host write implementation units whenever external agents fail | Rejected. It contradicts the adopted execution contract and `fallback_to_host: never`. |
### System-Wide Impact
The shared Guidelines change affects only consumers that adopt its new pinned commit. Dev must update its own gitlink and adoption record in a separate PR. Other repositories remain on their pinned versions until separately reviewed and adopted.
The readiness change affects task startup, recovery, evidence validation, and contributor instructions. Consumers must continue to distinguish `LOCAL_READY` from `READY`; CI and Gitea remain authoritative for formal merge admission.
### Risks & Dependencies
- The remote Guidelines `main` was observed at `6c8e6cdd08d4fb6009c83be43b75dfead9e9f7d9` on 2026-10-18; Dev currently pins `2688fd2be6a52c0bf110e7e6366b6f291ab5e4eb`. Re-fetch both repositories before implementation and merge decisions.
- Guidelines CONTRIBUTING.md treats changes to required conditions or authorization/validation semantics as a major behavior change, even while the source is in draft versioning. Review the version bump and migration note before merging.
- Allowing local continuation without a fresh fetch requires proving the existing task identity and saved baseline locally. If that cannot be verified, keep the operation blocked.
- `make facts-verify` executes shell commands from `policy/facts.md`. Tests must use synthetic credentials and stubbed requests; they must not read real secrets or access Gitea.
- An active adoption record does not establish platform enforcement. Runner isolation, workflow trust, and branch protection still require their own GATE or REPLAY evidence.
### Deferred Questions
- Whether a narrow direct-authoring path should exist for simple non-normative documentation changes remains separate from this remediation. The current plan preserves the adopted agent-per-unit rule for normative and behavior-bearing changes.
### Sources & Research
- Dev baseline: `f682afe8839828f2222eb8891c1fb5823ea26c29`.
- Dev Guidelines pin: `2688fd2be6a52c0bf110e7e6366b6f291ab5e4eb`.
- Guidelines remote `main` observed at `6c8e6cdd08d4fb6009c83be43b75dfead9e9f7d9` on 2026-10-18; implementation must revalidate it.
- V3 implementation reference: Dev PR #608 and `.task/archive/feature-delivery-model-v3.md`; P1-P3 are merged, metric M is future work.
- Current rule ownership and adoption references: `deps/development-guidelines/standards/documentation.md`, `core/baseline.md`, `workflows/delivery.md`, `workflows/adoption.md`, and Dev `policy/delivery.md`, `policy/governance.md`, `policy/adoption.md`.
- Current readiness and evidence references: `scripts/task.sh`, `scripts/evidence.py`, `scripts/task_triage.py`, `scripts/facts-verify.sh`, `policy/facts.md`, and `tests/test_task.py`, `tests/test_evidence.py`, `tests/test_task_triage.py`.
- No applicable files were found under `docs/solutions/`; no Compound Packs are declared.
---
## Implementation Units
### U1. Generalize shared delivery ownership
- **Goal:** Make shared delivery guidance portable while leaving Dev's branch hierarchy and tool commands in the Dev project policy.
- **Requirements:** R1, R3, R4, R6
- **Dependencies:** None
- **Target repository:** Development-Guidelines
- **Files:** `workflows/delivery.md`, `core/glossary.md`, `VERSION`
- **Approach:** Replace the mandatory Dev-specific initiative/child lifecycle in shared delivery guidance with reusable integration-target and recovery principles. Keep initiative/child/standalone fields and concrete project flows in Dev policy. Do not alter the shared agent-per-unit hard boundary or host-fallback contract in this unit.
- **Patterns to follow:** `CONTRIBUTING.md` version semantics; `AGENTS.md` and `standards/documentation.md` single-authority and project-independence rules.
- **Test scenarios:**
- A shared-workflow reader can apply the delivery guidance without adopting Dev's `main`, `feature/<initiative>`, or task-card schema.
- The Dev policy still has a clear place to define its two-level branch and initiative process.
- **Verification:** Relative links and cross-references resolve; no project-specific endpoint, branch, secret, or command leaks into shared text; Guidelines version change reflects the actual normative impact.
### U2. Enable safe local continuation for existing tasks
- **Goal:** Allow a registered, authorized task to continue bounded local work when origin is unavailable or ahead, without claiming formal readiness.
- **Requirements:** R2, R4, R5, R6, R7
- **Dependencies:** U1
- **Files:** `scripts/task.sh`, `scripts/evidence.py`, `policy/governance.md`, `tests/test_task.py`, `tests/test_task_recovery.py`, `tests/test_evidence.py`
- **Approach:** Separate existing-task local recovery from new-task startup and formal delivery. Prove authorization from the registered task record and the request's match to its recorded goal/scope; a missing or contradictory authorization record is not proof. Reject closed or abandoned tasks, a different task/branch identity, and requests outside the recorded scope. Then validate the local R0 object, current HEAD ancestry, and absence of active Git operations or ambiguous workspace changes before returning a local-only status. The local receipt records remote freshness as unavailable; it does not require or invent a current remote target SHA. New task creation and formal delivery continue to require a fresh authoritative target. If R0 is missing or local state is ambiguous, stop.
- **Patterns to follow:** Existing `TASK_WORK_MODE=local`, `LOCAL_READY`, `resume-local` receipt validation, task-card target metadata, and remote-verification errors.
- **Test scenarios:**
- An existing task with a valid card, clean worktree, available R0 commit, matching branch, and HEAD descended from R0 can resume local work when fetch fails, with an explicit local-only result and unchanged baseline.
- Local continuation still works when the remote-tracking ref is absent but the task's recorded R0 object is available locally; it hard-stops when the R0 object is unavailable.
- An existing task behind remote can continue locally, but a fresh remote sync is required before formal review or merge.
- New task startup remains blocked without verifiable remote triage and does not create a branch or worktree.
- A closed or abandoned task, missing authorization record, request outside the recorded scope, or conflicting task identity cannot enter local continuation.
- Dirty or mismatched task state, an active Git operation, invalid authorization, unknown side effects, or scope expansion remains blocked.
- A local receipt cannot validate as `READY`, `REPLAY`, or `GATE` and cannot satisfy the final merge check.
- **Verification:** Focused task, recovery, and evidence tests prove both the allowed continuation and retained hard stops. The change must not weaken `task-pr-check`, `task-sync`, exact-head CI, or platform admission.
### U3. Route project task lanes by integration need
- **Goal:** Keep task-type priority while choosing standalone versus initiative based on shared integration and acceptance needs.
- **Requirements:** R1, R3, R4
- **Dependencies:** U1
- **Files:** `policy/delivery.md`
- **Approach:** Define the conditions that require an initiative and those that allow independently acceptable work to remain standalone. Preserve repair/hotfix priority and explicit remote triage for new tasks. Keep branch, command, and queue details local to Dev.
- **Patterns to follow:** Current two-level model, `JOIN`/`NEW` triage, and the existing layered gate table.
- **Test scenarios:**
- A small independent enhancement can remain standalone even when labeled “improvement” or “new”.
- Work with multiple dependent units and one shared final acceptance enters an initiative even when one unit is a repair.
- A repair remains priority work without being forced onto `main` when it belongs to an active initiative's integration contract.
- Triage still refuses to create a branch when remote initiative discovery is unverified.
- **Verification:** Review the decision rules against the scenarios above and confirm that task type controls priority only where intended, not target topology.
### U4. Make credential and fact checks truthful
- **Goal:** Prevent credential disclosure in the documented verification path and ensure each fact check proves the claim it records.
- **Requirements:** R7, R9, R10
- **Dependencies:** None
- **Files:** `policy/facts.md`, `scripts/facts-verify.sh`, `tests/test_facts_verify.py`
- **Approach:** Reuse the existing token-safe Gitea request path where practical, or otherwise pass credentials without placing expanded values in arguments or output. Narrow F4's claim to what its check can prove, or make the verification assert the specific historical failure before refreshing the fact. Keep the legacy endpoint prohibition separate from claims about its failure cause.
- **Patterns to follow:** `scripts/task_triage.py` HOME-section parsing, token validation, and exception redaction; `tests/test_task_triage.py` synthetic-token fixtures.
- **Test scenarios:**
- A synthetic HOME/IMC secrets file selects only the intended token without printing either value.
- A stubbed HTTP client receives the credential without exposing the expanded value in child argv, stdout, stderr, or saved receipts.
- Missing or malformed synthetic credentials fail without revealing the supplied value.
- DNS failure, timeout, generic connection error, HTTP response, and the specifically claimed TLS condition do not collapse into the same fact-update result.
- No test reads `~/.secrets/gitea` or contacts Gitea.
- **Verification:** Focused offline tests cover the facts verifier and token handling. A live fact refresh is not part of the regression suite and may only use the protected credential path with normal evidence redaction.
### U5. Consolidate Dev entrypoints and project index
- **Goal:** Keep the root entry concise and the project index focused on stable facts and navigation.
- **Requirements:** R1, R2, R7
- **Dependencies:** U1, U2, U3, U4
- **Files:** `AGENTS.md`, `PROJECT.md`
- **Approach:** Keep mandatory principles and trigger links in `AGENTS.md`; leave detailed workflow and command behavior in the policy owners. Keep `PROJECT.md` as a stable project/index page and link changing initiative status to its task record. Remove the duplicate token extraction procedure from the root entry and point to the safe project fact/helper instead.
- **Patterns to follow:** `deps/development-guidelines/standards/documentation.md` entrypoint and single-source guidance; Dev's existing adoption matrix and archived V3 task record.
- **Test scenarios:**
- Each root rule points to exactly one detailed authority; no operational rule requires the reader to choose between paraphrases.
- Token instructions point to a safe retrieval mechanism and do not print secret values.
- Project proposal summaries link to the status authority rather than duplicating mutable progress.
- **Verification:** Check links, rule consistency, adoption references, and sensitive-data exposure. Do not change the protection, release, or credential-rotation authority.
### U6. Reconcile adoption evidence and verify the pinned combination
- **Goal:** Reconcile adoption evidence, pin the reviewed Guidelines revision in Dev, and verify the combined repository behavior.
- **Requirements:** R1, R2, R6, R7, R8
- **Dependencies:** U1, U2, U3, U4, U5
- **Files:** `deps/development-guidelines`, `policy/adoption.md`, `policy/guidelines-adoption.md`
- **Approach:** Only after U1 is merged to Guidelines main, update Dev's gitlink and adoption records to that exact SHA. Preserve and cite the adoption success and four negative cases already recorded for Dev; assess `active`/`manual` against the evidence required by the newly pinned workflow, not against unrelated future checks. Any additional schema-conformance or platform-side negative checks not run in Dev remain explicitly `NOT_RUN`: their absence alone neither invalidates the existing adoption record nor proves enforcement. Replace stale closeout references with verified merged and archived evidence. Reconcile the resulting combined tree before final verification. Do not update other consumers or alter platform branch protection in this plan.
- **Patterns to follow:** `policy/guidelines-adoption.md`, `policy/adoption.md`, `make test-worktree`, and the existing cross-repository pin checks.
- **Test scenarios:**
- The Dev checkout materializes exactly the approved Guidelines SHA and no unrelated component pin changes.
- The adopted Guidelines text and Dev project rules agree on generic versus project-specific behavior.
- Existing recorded adoption success and four negative cases remain traceable to their evidence; separately unrun schema/platform checks stay `NOT_RUN`, and neither an `active`/`manual` label nor missing extra checks is used to claim enforcement or automatically invalidate adoption.
- Adoption, execution capability, and individual conformance results remain separately represented; an unrun case cannot appear passed.
- The local continuation cases still reject formal delivery until the current authoritative base and required checks are verified.
- **Verification:** Run `make test-governance` for governance behavior and `make test` for the final pinned combination. Obtain independent review and current-head CI GATE before any authorized PR merge.
### U7. Make subagent and CLI work fit bounded model capacity
- **Goal:** Improve completion quality for subagents and CLI agents with smaller or uncertain context windows by giving them short, explicit, independently verifiable work packages and preserving only the handoff facts needed across stages.
- **Requirements:** New follow-up to this plan, explicitly requested on 2026-10-18. It supplements the original Product Contract without changing R1-R10 or the U1-U6 acceptance conditions.
- **Dependencies:** U1 and U6 define the shared-rule ownership and adopted Guidelines baseline. U7 may be implemented after U1 is merged; it must not block the independent U2-U5 work.
- **Target repositories:** Development-Guidelines for reusable subagent/CLI contracts; Agent-System-Dev for project routing preferences, model assignments, task-pack conventions, and local validation. Other repositories are later adopters, not part of this delivery.
- **Files (candidate):** Guidelines `standards/agent-execution.md`, its directly linked templates/schema only if fields are needed, and the relevant adoption/version documents; Dev `AGENT-EXECUTION.md`, `policy/delivery.md`, and focused prompt/config tests. Confirm actual ownership and existing coverage before editing.
- **Approach:**
- Require one bounded outcome per CLI task packet: one objective, explicit allowed paths/contracts, non-goals, dependencies, and a short verification command. Split work when it crosses independent ownership boundaries, needs unrelated background, or cannot be reviewed as one diff; avoid arbitrary tiny-unit counts.
- Include only the minimum task context in the packet. Link to authoritative files and quote only necessary sections; exclude unrelated logs, prior chat, speculative alternatives, and full plans. When context capacity is known, reserve a substantial share for inspection, implementation, iteration, and verification; when unknown, size conservatively for a 100K context and state that this is a planning assumption, not a discovered model limit. Avoid a universal token ceiling that ignores task risk or model differences.
- Treat phase boundaries as fresh sessions under the existing isolation rule. At meaningful long-task boundaries, emit a concise handoff containing objective/status, decisions, changed files and SHAs, commands/results, unresolved blockers, next action, and source links. Use provider-supported compaction only after a completed phase and only when it preserves those facts; never require hidden or unsupported auto-compression. Keep a durable handoff outside transient chat when work crosses sessions or agents.
- Separate generic standards from Dev's concrete routing. In Dev, record the requested preference: Codex or Claude for planning/design when available; PI with MiniMax-M3, Cursor Auto, and Antigravity (`agy`) with Gemini 3.8 Flash for bounded intermediate implementation/test work, selected in the existing configured order; other profiles may be chosen for a clear task-specific reason. Record requested and effective model/profile when observable, and mark unavailable/unobservable values honestly. Do not hardcode these providers or models into Guidelines.
- Make verification part of each packet and scale it to risk. The worker runs narrow direct checks; the host independently checks the integrated diff and runs the authoritative required suite once on the final candidate. Cross-file contracts, security, routing, and deploy-sensitive changes need explicit positive and negative cases; no worker summary or local receipt upgrades SELF to GATE/REPLAY.
- Preserve the existing agent-per-unit, single-writer, fresh-session, transport/admission, no-host-fallback, scope, authorization, independent-review, exact-head CI, and high-consequence boundaries. A prompt saying "do not edit concurrently" is guidance, not proof of enforcement; distinguish observed behavior from enforcement supplied by a tool. Do not add a controller or context-budget infrastructure unless current evidence shows the standard cannot be followed without it.
- **Test scenarios:**
- A sample packet for a modest 100K-context CLI agent can identify its goal, relevant files, allowed scope, and verification without needing the entire initiative plan or long chat history.
- A task spanning independent modules is split into reviewable packets with explicit dependency/handoff outputs; a cohesive local change is not fragmented unnecessarily.
- A known or unknown context window results in a transparent budget assumption and enough reserved capacity for implementation and tests, without claiming a provider's undocumented actual limit.
- A long task can hand off after a completed phase and resume in a fresh session from the concise artifact without the prior conversation; unsupported automatic compaction remains optional and is not a completion gate.
- Generic Guidelines remain provider-neutral, while the Dev configuration carries its requested model/profile preferences and records effective model when available.
- Positive and negative tests or conformance examples verify packet completeness, scope boundaries, fresh-session handoff requirements, and truthful model/context metadata; existing route validation remains unchanged unless a versioned schema extension is justified.
- Worker local checks, host integrated checks, independent review, and exact-head CI remain separate evidence classes and are all represented accurately.
- **Verification:** Review the standard and project config independently for ownership; validate any changed schema/config with existing validators; run focused prompt/config conformance tests and relevant governance tests. Test packet examples at both a small-context/unknown-model assumption and a larger-context model. Do not claim automatic context compression, model identity, or single-writer enforcement without observable evidence. Full combined `make test` remains part of final U6 validation, not a repeated check for every document edit.
---
## Verification Contract
| Scope | Verification outcome |
|---|---|
| Guidelines U1 | Relative links, rule ownership, rule strength, adoption lifecycle, and version change are internally consistent. No repository business tests are applicable to documentation-only source changes. |
| Dev U2-U5 | Focused task/recovery/evidence/token/facts tests prove permitted local continuation and retained stop conditions. Synthetic secrets and stubbed requests only. |
| Guidelines/Dev U7 | Existing schema/config validators and focused packet/prompt conformance tests cover bounded scope, stage handoff, model/context metadata, and provider-neutral ownership. |
| Combined pin U6 | `make test-governance` passes; `make test` validates the fixed component combination; `scripts/dm governance check --repo .` and `scripts/agent-exec validate --repo .` report accurate adoption/configuration state. |
| Delivery | Independent review and exact-head CI are evaluated on the final candidate. `SELF` is not promoted to `GATE` or `REPLAY`; no unavailable or `NOT_RUN` check is represented as passing. |
---
## Definition of Done
- Every original requirement R1-R10 maps to one or more implementation units and every unit has an observable completion condition; U7 has explicit follow-up acceptance scenarios.
- Local-only continuation is limited to a verifiable, authorized existing task; new-task startup and formal delivery retain strict remote and exact-candidate gates.
- Unknown side effects, authorization failures, scope expansion, dirty/unowned state, and secret disclosure remain stop conditions.
- Generic rules live in Guidelines; Dev command, branch, evidence, and adoption details remain project-owned.
- Credential and fact tests use synthetic values and stubbed external calls only.
- Adoption state is supported by specific evidence; unrun conformance remains `NOT_RUN` and enforcement is not inferred from text.
- CLI/subagent packets are sized for model capacity and task complexity, preserve concise cross-session handoffs, and keep concrete model preferences project-local; unsupported context or concurrency enforcement is not claimed.
- The updated Dev gitlink points to the merged Guidelines revision, and combined governance tests, independent review, and exact-head CI pass before any authorized merge.
- The plan's experimental or rejected implementation code is not part of its scope; the plan file and task card contain no implementation claims.
@@ -0,0 +1,40 @@
# RDM 设置收尾 · 一期 1a 实施计划(2026-10-18)
任务卡:`.task/feature-rdm-settings-phase1a.md`。取代旧任务 `feature/rdm-settings-completion` 中与主干不冲突、且不依赖 IAM U4 的部分。
## 已确认的决策
- 分期:一期 1a(本计划)= UI Picker 加固、R2 成员检索、验收脚本误报修复;一期 1b = R4 权限矩阵剩余项、R5 成员移除影响与原子移除,等 IAM U4 合入后在新主干上做;二期 = R1 项目共享设置(扩展 API 2.16,发版由用户本人执行)。
- R3 文档职责:主干已用职责矩阵取代,旧分支的 `rdm.duty.tree`、章节职责版本、旧职责界面不再移植。
- Profile 语义(二期):只禁止用户自建 profile 指定模型,内置 profile 的路由保留。
- 集成欠账:Frontend 密码管理提交(`92864db`,Dev 已钉住并上线)已经由 Frontend #107 合入 Frontend 主干(`0459567`),本期 Dev 改钉 Frontend 不会回退密码功能。
## 单元与边界
| 单元 | 仓库 | 允许路径 | 依赖 |
|---|---|---|---|
| U1 Picker 加固 | UI | `src/Picker.tsx`、`src/ui.css`、`test/picker.test.tsx` | 无 |
| U2 R2 成员检索 | RDM | `internal/rdmapp/accountdir.go`、新 `internal/rdmapp/member_search.go`、`plugins/rdm/plugin.go`(仅 account.list / member.list / role.options)、新 `plugins/rdm/member_search_test.go` | 无 |
| U3 成员页接入 | Frontend | `src/components/adminRdmSections.tsx` 中 `RdmMembersSection`(不动 import 区与 `RdmRolesPanel`)、`src/rdmManagement.ts`、新测试 | U1、U2 合同 |
| U4 验收脚本 | Dev | `tests/integration/rdm-increment/acceptance_scenarios.sh` | 无 |
| U5 组合改钉 | RDM、Dev | RDM `pins/agent-system-{frontend,ui}`;Dev `modules/{frontend,ui}` | U1–U4 合入 |
IAM U4 同时改动 RDM `perms/*`、`projects_api.go`、`perms_api.go` 与 Frontend `adminRdmSections.tsx` 的 import 区和 `RdmRolesPanel`,上表边界即为避免与其冲突。U2 只使用 U4 保留的 `perms.Store` 读取接口。
## R2 合同(RDM,向后兼容的增量)
- `rdm.account.list`:新增可选 `roleId`、`match`(`fuzzy` 默认 / `exact`);先全量筛选再按账号分页(`cursor` 为上一页最后账号,`limit` 默认 50、上限 200);每行新增 `joined`、`projectRole`、`profRole`。授权不变(member.manage)。
- `rdm.project.member.list`:新增可选 `query`、`match`、`roleId`、`projectRole`、`cursor`、`limit`;返回新增 `next`、`total`、`accountDirectoryAvailable`,成员行新增 `name`;不带 `limit` 时返回全部(权限矩阵页依赖)。授权不变(doc.read)。
- 新读命令 `rdm.role.options`(`purpose` = members | duties | permissions):返回启用的专业角色 `{roleId, name}`。
## 验收条件
- 同名人员以账号区分,选择提交稳定账号;精确/模糊匹配、专业角色筛选均由服务端在分页前完成,全部匹配可经游标逐页到达且不重复。
- 已加入人员在候选中可见但不可再次添加;失去管理资格时选择器禁用;迟到响应不展示。
- 成员表显示姓名与账号,支持检索、角色筛选和分页。
- 验收脚本中不再有未执行检查却输出 PASS 的场景;未执行项报告 NOT_RUN 并计入汇总。
- 组件 CI(UI/RDM/Frontend 治理检查,RDM 测试)与 Dev 组合 CI(`make test`、`make build`)在最终 HEAD 上通过;Frontend 与 UI 的类型检查、测试和构建在组合目录本地执行(Frontend CI 不跑这些)。
## 合入顺序
UI(U1)与 RDM(U2)并行 → Frontend(U3,基于含 U1 的 UI)→ RDM 改钉 Frontend/UI → Dev(U4 + 改钉 Frontend/UI;RDM 制品钉扎按需另行升级)。阶段 7 业务验收由用户判定。
@@ -0,0 +1,390 @@
---
title: "feat: Build a traceable medical-device regulations knowledge base"
date: 2026-10-18
type: feat
artifact_contract: ce-unified-plan/v1
product_contract_source: ce-plan-bootstrap
execution: code
origin: ../Agent-System-RDM/docs/requirements/01-用户需求与系统需求.md, ../Agent-System-RDM/docs/requirements/02-产品概念与形态定义.md, ../Agent-System-RDM/docs/requirements/03-产品设计方案.md
---
# Build a Traceable Medical-Device Regulations Knowledge Base
## Goal Capsule
- **Objective:** RDM users can rely on relevant medical-device regulations, standards, and review guidance with precise, reproducible citations in conversations and documents, backed by complete audit evidence.
- **Means:** Create an independently versioned regulations knowledge component and integrate it with RDM's mandatory knowledge-base plus real-web-search verification flow (KTD1, KTD2).
- **Authority:** Source documents and issuing authorities govern legal text and status; the versioned corpus governs the text indexed for knowledge-base retrieval; verified network captures provide the second source; RDM project/resource authorization governs access to project work and audit data.
- **Stop conditions:** Do not publish uncertain or unlicensed corpus material; do not report dual-source verification when either channel, version mapping, or excerpt comparison is incomplete; stop on access-control failure or an unreconciled source conflict.
- **Execution profile:** Cross-repository work in `Agent-System-KB-Regulations`, `Agent-System-RDM`, and the base repository when a public shared-regulations retrieval or real-web-search extension is required.
- **Finishing responsibility:** The implementation owner completes component tests, RDM integration, exact-composition verification, review, and authorized release steps. Runtime deployment and business acceptance remain separate from this plan.
---
## Product Contract
### Summary
Build a controlled, versioned medical-device regulations knowledge base that RDM can query alongside a real network search. Every generated regulatory claim must carry structured citations that resolve to exact source text, clause location, edition, verification status, and immutable audit evidence.
### Problem Frame
RDM already models a regulatory dual-channel check, but its current network leg is based on model-proposed URLs and excerpts followed by fetching and excerpt matching. This does not establish that an actual search occurred. Precise citations also require more than vector retrieval: source editions, clause hierarchy, paragraph anchors, parsed text, and exact evidence must survive re-indexing and later audit.
The current requirements already call for local regulations knowledge, knowledge-base plus network cross-checking, citations, and project isolation (`UR-14`, `SR-F3`, `SR-N4`; see origin documents above). The regulations directory currently exposes a manifest and a PostgreSQL dump; the manifest reports 2,907 documents, 312,919 chunks, and 279,184 nodes. These are inventory claims, not validation of the dump contents, source-file availability, legal status, permissions, or parsing accuracy. Those must be verified before corpus publication.
### Requirements
- R1. Regulations, standards, and review guidance relevant to RDM work must use both the controlled regulations knowledge base and a real network search. The system must distinguish actual search from model-generated URLs or recollection.
- R2. Every regulatory citation must resolve to a specific regulation identity and edition, clause path, exact excerpt, source locator, and verification batch. The system must separately check whether the cited excerpt supports the generated claim; authentic text and matching dual sources alone do not establish claim support or legal applicability. Unsupported/uncertain claims must be marked unverified or routed for review. Generated summaries may aid retrieval but must never be presented or audited as legal source text.
- R3. The corpus must preserve original assets or an authorized immutable source representation, extracted text, hierarchy, source provenance, effective status, and content hashes independently from rebuildable search indexes.
- R4. Ingestion must preserve meaningful legal structure: regulation, part/chapter/section, clause, subclause/item, paragraph, list, and table relationships when present. Retrieval chunks must retain heading context and map back to one or more exact source nodes.
- R5. Parsing, normalization, chunking, embedding, and ranking versions must be recorded. Re-indexing must not rewrite evidence used by prior answers, documents, or audits.
- R6. A dual-source result is verified only when both sources are fetched or retrieved from pinned corpus/network evidence, mapped to the same regulation edition and clause, and their relevant text is compared. Missing, stale, disputed, inaccessible, or conflicting evidence must be explicit and must not be labeled verified.
- R7. Conversation and document citations must use one structured citation contract, preserve the edition and excerpt used at creation time, and provide an authorized path to inspect the source evidence.
- R8. Audit records must reconstruct the question, corpus revision, search provider/query/results, retrieved clause IDs, source snapshots and hashes, comparison result, generated claims and citations, actor, authorization outcome, and any human resolution. Published evidence batches must detect unauthorized modification independently of mutable database rows.
- R9. Corpus access and audit disclosure must follow resource-level and project-level authorization. Public or shared regulations do not grant access to private project documents, conversations, or audit records.
- R10. MinerU may be used as a replaceable parsing adapter for supported assets. Its token is server-side only; parsing limits, task lifecycle, failures, and output provenance must be handled without exposing credentials or treating parser output as authoritative legal truth.
- R11. The regulations knowledge component must be independently versioned and testable. Its first deployment may remain local and use PostgreSQL/pgvector; a separate always-on network service is not required unless performance or operational evidence justifies it.
- R12. Outbound search queries must use the minimum regulatory context needed and exclude confidential project/user content by default. Source fetching must enforce SSRF protections at DNS resolution, connection, and every redirect.
- R13. Corpus and evidence retention must follow source-specific rights, retention, revocation, and takedown obligations. Withdrawal or expiry must not silently rewrite historical evidence; its current availability and legal retention basis must be auditable.
### Key Decisions
- K1. Independent knowledge component: use a dedicated regulations knowledge repository rather than placing corpus ingestion, parsing, and indexing inside RDM. This was accepted after considering the tighter RDM-only alternative; it gives the corpus pipeline and retrieval index an independent lifecycle while leaving RDM workflows in RDM. Governs R3, R4, R5, R10, R11. (session-settled: user-approved — chosen over keeping the entire corpus pipeline in RDM: ingestion, corpus versioning, and index rebuilds have a distinct lifecycle.)
- K2. Source assets are not Git source: large source documents, database dumps, runtime indexes, and secrets remain in controlled asset/storage systems or immutable releases. Git stores schemas, parsers, metadata contracts, migration/configuration, test fixtures that are distributable, and corpus manifests. Governs R3, R5, R10, R13.
- K3. PostgreSQL-first retrieval: begin with PostgreSQL relational source records, full-text search, and pgvector where current capacity tests support it. Keep vector indexes derived and rebuildable; move them to a dedicated vector service only if measured needs require it. Governs R3-R5, R11.
- K4. Structure-first chunking: retain exact paragraph/clause nodes and construct retrieval chunks from legal structure rather than fixed-width text windows. Include heading breadcrumbs in retrieval text, but keep headings distinguishable from quoted source text. Governs R2-R5.
- K5. Separate source and summary: store document/section summaries as generated retrieval aids with their model/prompt provenance. Do not require paragraph summaries by default, and never use any summary as the evidence for a legal citation. Governs R2, R4, R6.
- K6. Fail closed on evidence state: only mark dual-source verified when both legs have valid evidence and matching edition/clause/text. A single source, inaccessible channel, unresolved edition, or substantive disagreement produces an explicit degraded/disputed state. Governs R1, R6-R8.
- K7. RDM owns product integration: the knowledge repository owns corpus, retrieval, and ingestion; RDM owns relevance routing, dual-source orchestration, user/project authorization, conversation/document citation rendering, and business audit projection. Governs R1, R6-R9, R11-R13.
### Actors
- A1. RDM user asks a regulatory question or requests work that implicates regulations, standards, or review guidance.
- A2. RDM agent retrieves and uses verified evidence but cannot invent legal identity, version, clause, or quotation.
- A3. Corpus maintainer reviews source provenance, legal identity/status, parsing quality, licensing, and publication.
- A4. RDM reviewer resolves legal applicability or substantive conflicts that automation cannot safely decide.
- A5. Knowledge component and web-search provider return independently attributable evidence.
- A6. Base-platform owner publishes compatible shared-regulations retrieval and web-search capabilities when the current public extension contract cannot provide them safely.
### Key Flows
- F1. Dual-source regulatory answer: a regulatory-relevant task is detected; RDM queries a pinned corpus revision and executes a real web search; source documents are fetched/parsed and mapped to clauses; evidence is compared; the model produces claims bound to citation objects; citation validation runs before the answer is shown; the evidence batch is persisted for audit.
- F2. Corpus publication: an authorized asset batch is inventoried; exact source and rights are recorded; documents are parsed; structure and metadata pass quality gates or enter quarantine; stable nodes and retrieval chunks are generated; full-text/vector projections and evaluation results are built; a reviewed corpus revision is published without deleting prior revisions.
- F3. Document citation lifecycle: a generated document stores citation IDs and pinned evidence/version references; preview/export resolves those references; later source changes flag potentially stale citations but never silently rewrite the historical document.
- F4. Audit replay: an authorized auditor opens a regulatory claim and sees the exact evidence available at the time, retrieval/search provenance, comparison, citation mapping, and any human decision, subject to disclosure controls.
### Acceptance Examples
- AE1. Given both channels return the same current edition and exact clause text, when the RDM agent answers, then each regulatory assertion has a citation that opens the matching clause excerpt and both evidence records.
- AE2. Given the corpus has a clause but real web search is unavailable, when a regulatory task runs, then the result is explicitly single-source/degraded and cannot be labeled dual-source verified.
- AE3. Given web search finds an amended edition that conflicts with an older corpus edition, when comparison runs, then the system records both editions and the conflict, prevents a green verified state, and exposes the item for human review.
- AE4. Given a vector index is rebuilt with a new chunking or embedding version, when an auditor opens an older answer, then the original citation still resolves to the prior corpus revision, source node, excerpt, and hashes.
- AE5. Given an unauthorized user requests another project's regulatory audit detail, when authorization is evaluated, then the request is denied or redacted without exposing project content or restricted source text.
- AE6. Given MinerU rejects a file, times out, or returns structurally incomplete parsing, when ingestion runs, then the job remains failed/quarantined with a reason and no unreviewed chunks enter the published corpus.
- AE7. Given a real clause citation whose text does not support the generated claim, when citation validation runs, then citation authenticity may pass but claim support fails; the claim is marked unsupported/unverified or routed for review, and is not presented as a supported regulatory conclusion.
### Success Criteria
- Every displayed regulatory quotation resolves to a fixed source node and edition; citation verification can confirm the excerpt against the recorded source text/hash.
- No scenario with one unavailable source, unresolved edition, or unresolved conflict is shown as dual-source verified.
- Rebuilding an index does not alter previously stored audit batches, document citations, or source snapshots.
- Reviewers can reconstruct each accepted claim from corpus revision, exact web evidence, comparison state, and citation links without relying on model conversation history.
- Retrieval and parsing thresholds are established from a labeled representative sample before production publication; no unsupported precision/recall threshold is invented in advance.
### Scope Boundaries
In scope: independent regulations knowledge component; corpus inventory and ingestion; legal-document metadata and version relationships; MinerU adapter; structure-aware parsing and chunking; full-text/vector retrieval; real web search evidence; dual-channel verification contract; structured citations in RDM conversation/document paths; immutable audit projection; evaluation, security, and recovery tests.
#### Deferred for Later
- Advanced audit anchoring beyond the independently verifiable tamper-evidence baseline required for published evidence batches.
#### Deferred to Follow-Up Work
- Dedicated distributed vector database or always-on remote KB service unless measured scale, availability, or consumer requirements demand it.
- Automated legal applicability decisions or unattended legal conflict adjudication.
- Broad monitoring dashboards beyond the operational signals needed to run ingestion, search, and index publication.
- Continuous regulatory change surveillance and automatic bulk re-ingestion after publication; initial release supports controlled, explicit corpus updates.
#### Outside This Plan
- Modifying or deploying production services, importing the full corpus, publishing protected standards, or approving legal interpretations.
- Moving all RDM project knowledge, templates, or audit storage into the regulations component.
- Using MinerU as a source of legal authority, network search engine, or legal-status classifier.
### Dependencies and Open Questions
- The actual dump schema, row quality, source-file availability, and database-to-file provenance in `../Agent-System-Regulations` must be verified before choosing a production import path. The local manifest is not sufficient evidence.
- Rights and permitted excerpt/display/export limits must be established for every source class, especially standards and third-party review guidance. This is a publication blocker, not an implementation default.
- A real web-search provider and authoritative-source allowlist must be selected. Existing RDM code can fetch model-proposed URLs but has no verified real-search capability in the inspected flow. If no existing base extension supports search, raise and implement a base extension through its approved process.
- The initial local deployment and backup topology, corpus owner, update approval role, and recovery objective must be fixed before production publication.
- Sample-driven thresholds for OCR fidelity, clause extraction, retrieval recall, citation accuracy, and stale-edition suppression are set after a representative labeled corpus is available.
---
## Planning Contract
### Key Technical Decisions
- KTD1. Repository boundary: `Agent-System-KB-Regulations` owns corpus ingestion, legal identity/version metadata, parsing, structure, chunking, retrieval indexes, corpus release manifests, and retrieval APIs/contracts. RDM retains its current plugin and owns user-facing workflows, authorization, citations, and audits. A repository boundary does not mandate a network-service boundary.
- KTD2. Retrieval source of truth: store canonical source text and legal structure in a versioned relational corpus store; store original binaries in controlled file/object storage where appropriate; treat full-text/vector indexes as disposable projections. A vector payload may cache a short retrieval excerpt plus stable IDs and hashes but cannot be the only copy of source text.
- KTD3. Chunk model: preserve the smallest stable source nodes (paragraph/list/table/clause) with parent hierarchy, ordering, page/layout locator, original and normalized text, and hashes. Build retrieval chunks by combining complete adjacent legal nodes, normally targeting approximately 300-800 tokens and allowing longer complete clauses when needed. Never split inside a sentence or legal condition solely to satisfy a fixed token limit. Tune limits on the labeled sample set.
- KTD4. Heading context: persist titles as distinct structured fields and include a breadcrumb (regulation > part/chapter/section > clause number/title) in the embedding/search representation. Do not merge synthetic breadcrumbs into the text labeled as a quotation.
- KTD5. Summary policy: keep generated regulation/part/section summaries separate from source text, with model, prompt, generation time, and summary hash. Paragraph summaries are optional and excluded from citation evidence and dual-source text comparison.
- KTD6. Immutable corpus publication: every release pins source hashes, parsed representation hashes, metadata review state, parser/chunker/index versions, and evaluation result. Rebuild creates a new index/corpus revision; it does not mutate past evidence or citations.
- KTD7. MinerU is an adapter in the ingestion pipeline, not a hard dependency for every file type. The adapter records task ID/state, limits, retry outcome, parser version, output hashes, and page/block locators. Secrets are server-side. At the consulted docs snapshot, API documentation described asynchronous task submission/result retrieval; limits stated 50 submitted files/minute, 5,000 files/user/day, and up to 200 MB/200 pages per file. Reconfirm these values during implementation because provider limits can change.
- KTD8. Credential lifecycle: MinerU and search credentials are provisioned through protected runtime secret injection, separated by environment, limited to the component that needs them, and revocable/rotatable without source changes. They must not appear in source, fixtures, browser assets, command output, logs, or evidence exports.
- KTD9. Search provider contract: network search must return provider, minimized query, timestamp, ranked results, URL/title, and fetch evidence; prioritize official publishers/regulators. Search queries contain only minimum necessary regulatory terms and exclude confidential project/user context by default. Search snippets discover sources but are not authoritative excerpts. Fetch and preserve a permitted source snapshot before it can count as verified evidence.
- KTD10. Safe source fetch: validate scheme, host, port, resolved address, response type/size, and each redirect target; reject loopback, private, link-local, multicast, and reserved destinations after DNS resolution and at connection time. Revalidation must prevent DNS rebinding between validation and connection.
- KTD11. Citation contract: one immutable citation object is shared by conversation, document, and audit views. It identifies claim-to-excerpt mapping, regulation/version/clause IDs, corpus revision, web source, exact offsets/locator, hashes, and verification state.
- KTD12. Verification state: distinguish `verified`, `single_source`, `degraded`, `edition_unresolved`, `conflict`, `unverified`, and `not_applicable`; do not collapse them into a Boolean or infer compliance from clause-number equality alone.
- KTD13. Audit persistence: append evidence batches and human resolutions. Store full snapshots only when rights permit; otherwise retain legally allowed excerpts, source locator, hashes, fetch metadata, and an explicit reason the full source is unavailable. Published batch manifests must be tamper-evident through a separately verifiable digest/signature or append-only anchor, not only hashes stored beside mutable rows. Apply source-specific retention, withdrawal, and takedown rules while preserving a non-content audit event where permitted. Never let re-indexing overwrite evidence.
- KTD14. Shared integration contract: define a public, read-only regulations retrieval surface that pins corpus revision and returns stable regulation/edition/node IDs, permitted excerpts, locators, hashes, and disclosure metadata. The base contract must not route through owner-scoped project `KnowledgeSearch`. RDM may use only released public extensions; if absent, submit the required base proposal and compatibility tests before RDM integration. Real web search follows the same public extension boundary.
### High-Level Technical Design
```mermaid
flowchart LR
Asset[Controlled legal assets] --> Intake[Inventory and rights gate]
Intake --> Parse[Parser adapters including MinerU]
Parse --> Structure[Versioned legal structure and source text]
Structure --> Build[Chunk and index builder]
Build --> Corpus[(PostgreSQL corpus and full-text index)]
Build --> Vector[(Rebuildable vector projection)]
RDM[RDM regulatory workflow] -->|query pinned revision| Corpus
RDM --> Search[Real web-search provider]
Search --> Fetch[Fetch and snapshot permitted evidence]
Corpus --> Compare[Clause/version/text comparison]
Fetch --> Compare
Compare --> Citation[Immutable citation/evidence batch]
Citation --> Chat[Conversation citations]
Citation --> Docs[Document citations]
Citation --> Audit[Authorized audit projection]
```
The relations are versioned rather than overwrite-in-place:
```text
source_asset -> regulation_identity -> regulation_edition -> legal_nodes
| |
| +-> retrieval_chunks -> full-text/vector projections
+-> status/relations (amends, replaces, repeals)
verification_batch -> corpus_revision + legal_node/excerpt + web_capture + comparison + generated_claims
document_version -> citation_ids -> verification_batch/source hashes
```
### Data and Chunking Contract
The canonical legal node is the smallest accurately locatable source unit. Typical node kinds are document title, part/chapter/section, clause, subclause, paragraph, list item, table, table row/cell, footnote, and annex. The source may lack some levels; preserve actual structure and record extraction gaps rather than inventing empty hierarchy.
Each node records regulation and edition IDs, parent and sibling order, node kind, displayed clause number/title, original text, normalized search text, source asset hash, page range and parser locator, extraction confidence/review state, and original/normalized text hashes. Table content retains header-to-cell relationships. A missing or ambiguous clause number is represented as such and cannot be fabricated for citation display.
Retrieval chunks are a separate projection over one or more nodes. They carry ordered node IDs, full heading breadcrumbs, exact composed source text with component spans, chunking version, and embedding model/version. They may overlap only by referencing adjacent nodes where evaluation proves context helps; duplicated overlap text is not independently cited. At citation time, the system resolves the generated claim to exact source-node spans, not just the retrieval chunk.
Generated summaries are stored in a separate table/object and indexed as lower-trust retrieval hints. Every summary states its coverage, target regulation revision, model/prompt version, and generation provenance. Ranking must not cause a summary to outrank an exact applicable clause without displaying that it is a summary. Summaries never satisfy the source-evidence requirement.
### Assumptions
- The source corpus may be imported into a new controlled PostgreSQL database rather than modifying the source dump in place.
- First release favors a locally deployable component and a simple supported retrieval interface over a distributed multi-service topology.
- The RDM repository remains the owner of project-specific claim records and user-visible conversation/document flows; the regulations repository is the owner of canonical legal corpus and reusable evidence/search contracts.
- Some source classes may not permit full-text retention or redistribution; their ingestion may be metadata-only or blocked until rights are resolved.
### Sequencing and Dependencies
`U1 corpus/rights audit -> U2 repository contracts and schema -> U3 parsing/structure/chunking -> U4 retrieval and evaluation -> U6 RDM dual-source and audit integration -> U7 conversation/document citations -> U8 composition, security, recovery, and acceptance.` After U2 stabilizes the identifiers/evidence contract, U3, U5, and U9 may proceed in parallel; U4 depends on U3; U6 depends on U4, U5, and U9. RDM must not claim dual-source verification until the public contracts and both evidence legs are integrated.
---
## Implementation Units
### U1. Verify corpus provenance, content, and publication rights
- **Goal:** Establish a trustworthy import inventory and identify material that can legally and technically be published.
- **Requirements:** R3, R5, R10.
- **Dependencies:** None.
- **Files:** `docs/proposals/regulations-kb/corpus-inventory.md`; source repository's `manifest.json` and database dump are read-only inputs. U2 carries the reviewed inventory into the new repository after bootstrap.
- **Approach:** Inspect database schema and representative rows; map documents, editions, chunks, nodes, aliases, relations, and source paths; validate dump integrity and source-file availability; classify rights and disclosure constraints; produce a provenance manifest. Keep original data untouched and quarantine records with ambiguous identity, status, or rights.
- **Patterns to follow:** Existing RDM `TemplateAsset` provenance fields and immutable source/output hashes; controlled asset batches rather than copying runtime data into Git.
- **Test Scenarios:**
- A valid sample asset maps to exactly one source hash and an explicit source/rights record.
- Duplicate binary content is deduplicated without merging distinct legal identities or editions.
- Missing source, invalid dump row, ambiguous edition, or unknown rights is quarantined and excluded from publishable counts.
- **Verification:** Inventory totals reconcile with the imported source snapshot or discrepancies are enumerated; a reviewer can trace each accepted sample back to its original asset and provenance. No product source assets are copied into the new repository during this discovery unit.
### U2. Establish the independent repository, domain contract, and versioned schema
- **Goal:** Create the separately versioned regulations knowledge component and its stable source/retrieval contract.
- **Requirements:** R3, R5, R11.
- **Dependencies:** U1.
- **Files:** `Agent-System-KB-Regulations/README.md`; `Agent-System-KB-Regulations/AGENTS.md`; `Agent-System-KB-Regulations/PROJECT.md`; `Agent-System-KB-Regulations/go.mod`; `Agent-System-KB-Regulations/internal/domain/`; `Agent-System-KB-Regulations/internal/store/`; `Agent-System-KB-Regulations/migrations/`; `Agent-System-KB-Regulations/tests/`.
- **Approach:** Define stable regulation identity, edition/status, source asset, legal node, retrieval chunk, corpus revision, and evidence provenance entities. Separate canonical data from search projections. Provide local deployment configuration and schema migration/recovery ownership. Keep corpus bytes out of Git; use controlled object/file references and immutable corpus release manifests.
- **Patterns to follow:** RDM domain/store separation, immutable hashes, explicit revision contracts, fail-closed validation, and existing PostgreSQL deployment practices.
- **Test Scenarios:**
- A regulation with multiple editions and amends/replaces/repeals relations persists and reloads without identity collision.
- A corpus revision cannot publish when required rights, source hash, status review, or node provenance is missing.
- Schema migration and restore tests preserve edition/node identities and immutable historical revisions.
- **Verification:** Domain and persistence contracts round-trip against the supported local database, and a clean restore reproduces the same corpus revision hashes.
### U3. Build structure-aware parsing, chunking, and MinerU adapter
- **Goal:** Convert approved source assets into locatable legal nodes and retrieval chunks without losing source boundaries.
- **Requirements:** R2-R5, R10.
- **Dependencies:** U2.
- **Files:** `Agent-System-KB-Regulations/internal/ingest/`; `Agent-System-KB-Regulations/internal/parser/`; `Agent-System-KB-Regulations/internal/chunk/`; `Agent-System-KB-Regulations/internal/mineru/`; `Agent-System-KB-Regulations/tests/ingest/`; `Agent-System-KB-Regulations/tests/chunk/`; `Agent-System-KB-Regulations/tests/mineru/`.
- **Approach:** Add parser adapters that produce a common block/tree representation. Preserve titles, clause numbers, paragraphs, list structure, tables, page and layout locators, parser version, and confidence. Build chunks from complete legal nodes using the versioned structure-first policy; include heading breadcrumbs in search text while keeping synthetic context separate from quote text. Store document/section summaries separately with model/prompt provenance. Treat MinerU as an asynchronous optional adapter with server-side credentials and explicit limit/retry/error states.
- **Patterns to follow:** Existing RDM parsed-document contracts, source/content hash validation, parser adapter boundaries, and quarantine states for incomplete assets.
- **Test Scenarios:**
- A structured regulation preserves regulation > chapter > clause > paragraph hierarchy and exact source text through parse/chunk/reload.
- A long clause is split only at legal paragraph boundaries; every chunk maps back to ordered source nodes and no condition is dropped.
- A table retains headings and cell relationships; citations resolve to the correct row/cell source location.
- Missing titles, missing clause numbers, low-confidence OCR, and absent page locators are represented as gaps rather than invented metadata.
- MinerU timeout, provider rejection, rate limit, invalid result, or output hash mismatch leaves the job non-published and resumable/reviewable without leaking the token.
- Summary generation failure does not block exact-source storage and cannot mark a citation as verified.
- **Execution note:** Characterize parsing on representative structured, scanned, table-heavy, and long-clause samples before fixing token targets.
- **Verification:** Golden parse fixtures prove text/structure/locator fidelity; all published chunks have a source-node map, and parser/chunker versions are reproducible.
### U4. Implement hybrid retrieval, corpus revisions, and retrieval evaluation
- **Goal:** Retrieve exact, applicable clause candidates across exact identifiers, full-text, and vector semantics while keeping indexes rebuildable.
- **Requirements:** R1-R5, R11.
- **Dependencies:** U2, U3.
- **Files:** `Agent-System-KB-Regulations/internal/retrieval/`; `Agent-System-KB-Regulations/internal/index/`; `Agent-System-KB-Regulations/internal/publish/`; `Agent-System-KB-Regulations/eval/`; `Agent-System-KB-Regulations/tests/retrieval/`; `Agent-System-KB-Regulations/tests/publish/`.
- **Approach:** Implement exact standard/number/clause lookup, metadata/effectivity filters, PostgreSQL full-text and vector candidate retrieval, and explainable reranking. Return stable regulation/edition/node IDs, exact excerpts, heading paths, source locators, hashes, and corpus/index versions. Use document/section summaries only as lower-trust aids. Build a labeled retrieval set and compare clause recall, edition selection, quote localization, and stale-edition suppression before publication.
- **Patterns to follow:** Stable snapshot/revision APIs, evidence provenance enums, current RDM query/retrieval adapters, and immutable publish manifests.
- **Test Scenarios:**
- Exact standard number plus clause query selects the matching edition and node even when semantic similarity ranks another edition highly.
- Natural-language query returns relevant clause nodes with heading context and exact excerpts, not only summaries.
- A superseded or future edition is excluded or clearly labeled when the query requests current requirements.
- Rebuilding an embedding or full-text index creates a new revision and leaves old retrieval evidence readable.
- Empty results, malformed filters, unavailable vector index, and partial index build return explicit degraded states without fabricated hits.
- **Verification:** Evaluation report includes dataset provenance and per-slice retrieval metrics; publication is blocked if configured acceptance thresholds regress from the reviewed baseline.
### U5. Provide real web search and immutable web evidence capture
- **Goal:** Implement the knowledge component's independently attributable network search and evidence-capture provider behind the public contract.
- **Requirements:** R1, R6, R8, R12, R13.
- **Dependencies:** U2 for the stable regulation/evidence contract; may run in parallel with U3 and U4 after that contract is agreed.
- **Files:** `Agent-System-KB-Regulations/internal/websearch/`; `Agent-System-KB-Regulations/internal/webcapture/`; `Agent-System-KB-Regulations/internal/evidence/`; `Agent-System-KB-Regulations/tests/websearch/`; `Agent-System-KB-Regulations/tests/webcapture/`.
- **Approach:** Implement the provider adapter and fetch/evidence capture in the knowledge component. Record provider, minimized query, timestamp, ranked results, URL/title, and official-source classification. Exclude confidential project/user context from outbound queries by default; allow only a separately approved policy to add specific sensitive context. Fetch selected pages/files with DNS-resolution and connection-time private/reserved-address rejection, host/scheme/port/size controls, and validation of every redirect target. Retain only rights-permitted snapshots or excerpts plus hashes and fetch metadata, and parse clauses into candidates. Do not treat search snippets, model-generated URLs, or inaccessible pages as verified evidence. U9 owns only the public base contract/compatibility boundary; U6 owns the RDM consumer adapter and workflow integration.
- **Patterns to follow:** Existing URL fetch validation/snapshot code in RDM as a starting point only; preserve the distinction between candidate discovery and verified source fetch.
- **Test Scenarios:**
- A provider response records the exact query/provider/rank/time and returns stable result evidence.
- Search timeout, rate limit, invalid URL, redirect to a disallowed host, non-text body, oversized content, or fetch failure cannot count as a verified web source.
- A search snippet that is not present in fetched source text remains unverified.
- A query containing a confidential project identifier is minimized or rejected before reaching the provider unless an explicit approved policy allows it.
- An authentic citation whose excerpt does not support the generated claim passes source-integrity validation but fails claim-support validation and is marked unsupported/unverified or routed for review.
- An official source page fetch produces a content hash and a reproducible clause excerpt/locator within applicable retention rules.
- DNS answers resolving to private/reserved addresses, a DNS rebinding attempt, or a redirect to a disallowed address are rejected before connection and cannot count as evidence.
- An expired or revoked source snapshot is withheld from normal display and records a rights/retention event without silently changing prior batch identity.
- **Verification:** Integration tests demonstrate an actual provider search-to-fetch path and prove failure states remain non-verified; provider secrets never appear in logs, storage exports, or client responses.
### U6. Integrate mandatory dual-source verification and immutable audit batches in RDM
- **Goal:** Replace model-suggested network candidates as the search mechanism and bind each regulatory conclusion to immutable knowledge-base and web evidence.
- **Requirements:** R1, R6, R8, R9, R11-R13.
- **Dependencies:** U4, U5, U9.
- **Files:** `Agent-System-RDM/internal/domain/regcheck.go`; `Agent-System-RDM/internal/domain/payloads.go`; `Agent-System-RDM/internal/domain/replay.go`; `Agent-System-RDM/internal/rdmapp/regcheck.go`; `Agent-System-RDM/internal/rdmapp/regfetch.go`; `Agent-System-RDM/internal/rdmapp/`; `Agent-System-RDM/plugins/rdm/plugin.go`; `Agent-System-RDM/internal/domain/regcheck_test.go`; `Agent-System-RDM/internal/rdmapp/regcheck_test.go`; `Agent-System-RDM/internal/rdmapp/regfetch_test.go`; `Agent-System-RDM/plugins/rdm/` tests.
- **Approach:** Add a versioned evidence-batch model and persist complete source references, edition/node IDs, exact excerpts, source snapshots/hashes, query and fetch metadata, state transitions, and human resolutions. Call shared regulations retrieval through U9 and real web search through its released public contract as separate legs. Compare regulation identity, edition, clause mapping, and relevant text; replace clause-number-only agreement with evidence-level comparison. Retain existing project authorization and audit boundaries. Keep historical batches replayable after corpus re-indexing. Add a separately verifiable tamper-evidence record for published batches and rights-aware retention/withdrawal behavior.
- **Patterns to follow:** RDM event-log replay, content-addressed network snapshots, project-authorized snapshot reads, and resource-level authorization.
- **Test Scenarios:**
- Same-edition, same-clause, matching excerpts from both legs produce a verified batch with both immutable evidence references.
- A citation that resolves to authentic matching text but whose excerpt does not support the associated claim is recorded as unsupported/unverified or routed for review; source integrity cannot upgrade claim support.
- Knowledge-only, web-only, unavailable search, unknown edition, and mismatched text produce distinct non-verified states.
- Same clause number but different edition/text produces conflict, not agreement.
- Restart/replay restores all batch metadata, exact citation refs, human resolution, and snapshot hashes.
- Mutation of a stored batch or its linked source data is detected by audit verification when mutable database rows and adjacent hashes are changed together.
- Source withdrawal/takedown updates current access according to its retention rule while retaining a permitted non-content history event and preserving document/version references.
- Unauthorized actor cannot read another project's evidence batch or retrieve private source text through an audit command.
- Existing malformed/model-generated network output cannot satisfy the real-search requirement.
- **Verification:** Domain and application tests prove state invariants, persistence replay, source validation, and project isolation; the command-bus integration proves the public RDM command path enforces them.
### U7. Add structured citations to conversation, documents, and audit views
- **Goal:** Present one stable citation object consistently in generated answers, document content, preview/export, and audit inspection.
- **Requirements:** R2, R7-R9.
- **Dependencies:** U6.
- **Files:** `Agent-System-RDM/internal/domain/`; `Agent-System-RDM/internal/rdmapp/`; `Agent-System-RDM/plugins/rdm/plugin.go`; `Agent-System-RDM/web/app.js`; `Agent-System-RDM/web/index.html`; `Agent-System-RDM/web/app.css`; `Agent-System-RDM/web/workbench_test.mjs`; `Agent-System-Frontend/src/`; `Agent-System-Frontend/test/`; `Agent-System-Documents/docs/proposals/` if a shared renderer/API extension is required.
- **Approach:** Bind claim spans to citation IDs; render concise regulation/edition/clause/status marks with expandable exact excerpt and authorized source details. Persist citation IDs and evidence revisions in document versions and exports. Mark citations stale when a later corpus revision changes status or text, but preserve the original basis and require explicit review before refreshing it. Use existing RDM audit workspace/read-model patterns for source history rather than introducing a new write authority.
- **Patterns to follow:** Existing RDM command-bus UI, three-pane audit workspace and shared snapshot rules, document citation/trace contracts, and UI design tokens/components in the consuming frontend.
- **Test Scenarios:**
- An answer with two regulatory claims renders two distinct citation marks linked to their claim spans and correct clause excerpts.
- A generated document stores the citation and pinned edition; preview/export preserves it across reload.
- A later corpus update marks the citation for review without mutating the saved document or historic audit batch.
- A user without source-text disclosure permission sees the permitted metadata/redaction reason but not restricted excerpt or original content.
- Missing or invalid citation IDs are surfaced as unverified and cannot be rendered as valid legal references.
- **Verification:** Browser and document round-trip tests prove citation persistence, navigation, redaction, stale marking, and export consistency.
### U8. Validate composed deployment, recovery, privacy, and release readiness
- **Goal:** Prove the complete local RDM + regulations component works with recoverable data/index lifecycle and protected evidence.
- **Requirements:** R1-R13.
- **Dependencies:** U1-U7, U9.
- **Files:** `Agent-System-KB-Regulations/deploy/`; `Agent-System-KB-Regulations/docs/operations/`; `Agent-System-KB-Regulations/tests/integration/`; `Agent-System-RDM/tests/integration/`; `Agent-System-Dev/tests/`; `Agent-System-Dev/PROJECT.md`; `Agent-System-Dev/` component pins and composition configuration.
- **Approach:** Pin compatible component revisions; provision a disposable local corpus/database; build a new index revision; run dual-source and citation flows end-to-end; exercise backup/restore, source/index rebuild, provider/parser outages, and authorization. Keep legal source data and secrets outside test output and source-control history. Separate local test acceptance from deployment and business/legal approval.
- **Patterns to follow:** Existing Dev composition verification, RDM PostgreSQL and audit replay tests, fixed component pins, and resource/project authorization tests.
- **Test Scenarios:**
- A full regulatory question returns both channel records, exact cited clause, claim mapping, and audit-batch replay through the composed product.
- One channel is deliberately disabled and the UI/agent reports degraded verification without presenting a green dual-source result.
- Backup/restore followed by index rebuild preserves corpus revision hashes and historical citation resolution.
- Cross-project and restricted-source access cases are denied/redacted through the real command/API composition.
- MinerU/search credentials are absent from client assets, logs, command output, test fixtures, and audit exports.
- Credentials are injected per environment, scoped to the required component, and can be rotated/revoked without changing source or leaving old credentials usable.
- **Verification:** Exact composition tests and security/recovery checks pass on the pinned candidate; release, deployment, and user/legal acceptance are explicitly recorded as separate later gates.
### U9. Publish the shared regulations retrieval and search extension contract
- **Goal:** Provide an authorized public integration surface for RDM to query the shared read-only legal corpus and perform real web search without misusing owner-scoped project knowledge APIs.
- **Requirements:** R1, R6, R8, R9, R11, R12.
- **Dependencies:** U2 for stable identifiers and evidence schema; can be designed alongside U3-U5.
- **Files:** `Agent-System-Documents/docs/proposals/`; applicable base-repository extension contracts under `Agent-System-Backend/pkg/extension/`; base-repository contract tests.
- **Approach:** First verify whether an existing public Host or API contract can express shared corpus retrieval with revision pinning, stable source-node references, excerpt disclosure policy, and audit provenance, plus access to the knowledge component's real-search provider with minimized query input and evidence provenance. Do not use the existing owner-scoped project `KnowledgeSearch` as a substitute. If it cannot represent these capabilities, document the scenario, required public surface, reason existing registration points do not compose, and compatibility plan in the base proposal process; implement/release the base contract before RDM consumes it. No backend-internal import or private credential bypass is allowed. U5 owns search-provider behavior; U9 owns only the public contract and compatibility tests; U6 owns the RDM consumer adapter and orchestration.
- **Patterns to follow:** RDM's extension boundary and approved base-extension proposal process; versioned public command/Host contracts and cross-repository compatibility tests.
- **Test Scenarios:**
- A consumer queries a pinned shared corpus revision and receives stable regulation/edition/node IDs, permitted excerpt, locator, hashes, and disclosure state.
- An unauthorized or unsupported request cannot access restricted source text or use a project ID to widen shared corpus access.
- Search receives only permitted minimized query fields and returns provider/query/result provenance; provider failure remains a non-verified result.
- Compatibility tests prove the released base surface is consumable by the pinned RDM adapter without importing backend internals.
- **Verification:** A versioned public contract and compatibility tests exist before U6; if base changes are needed, RDM integration uses only the released compatible contract. This unit does not implement a second provider, fetcher, or RDM adapter.
---
## Verification Contract
| Gate | Evidence required | Applies to |
|---|---|---|
| Corpus admission | Source hashes, source/rights inventory, schema/data reconciliation, quarantined-record report | U1, U2 |
| Parser/chunk quality | Golden fixtures for clauses, paragraphs, headings, lists, tables, OCR, locators, and provenance; no lost or invented source text | U3 |
| Retrieval quality | Labeled set with exact/semantic queries; report retrieval, edition, locator, stale-source, and summary-vs-source behavior | U4 |
| Search evidence | Provider search, minimized query/result metadata, fetched source, source policy, SSRF negative cases, hash and excerpt/locator verification | U5, U9 |
| RDM invariants | Dual-source state matrix, event replay, authorization denial/redaction, tamper-evidence verification, rights-aware withdrawal, command-bus tests | U6 |
| User-visible citations | Browser/document round trip, stable source navigation, permissions, stale citation display, export | U7 |
| Composition/recovery | Fixed component pins; full-path tests; disposable DB backup/restore and rebuild; secret lifecycle and leak checks | U8, U9 |
| Delivery trust | Current target synchronization, independent review, and required exact-head CI/REPLAY evidence under each repository's delivery policy | All release candidates |
Planning does not run these tests. Implementers should use each target repository's current authoritative test commands and policies when the work starts. The three uninitialized Dev submodules reported by precheck must be safely materialized before a future composition build; no submodules were changed for this plan.
## Definition of Done
- U1-U9 are complete or explicitly deferred with owner and rationale; no unresolved launch-blocking rights, source identity, or extension-contract decision remains.
- The published corpus release is reproducible from approved source assets, versioned metadata, parser/chunker versions, and evaluation record.
- Every retrieval result contains stable source-node and revision references; exact excerpts resolve independently of vector-index contents.
- Real web search and knowledge-base evidence are independently recorded, and dual-source status cannot be inferred from model output or clause-number equality alone.
- Conversation, document, and audit citations share the same immutable evidence identities and enforce RDM project/resource permissions.
- Required component and composition checks pass on exact pinned revisions; review, CI, deployment, and business acceptance are reported as distinct states.
- No source assets, secrets, or abandoned experimental ingestion/index outputs are left in Git or the final product artifact.
- Published evidence tampering is detectable; confidential project context is not sent to external search by default; fetch redirects and DNS resolution cannot reach private/reserved network targets.
## Appendix
### Existing Evidence and Integration Anchors
- RDM requirements: `../Agent-System-RDM/docs/requirements/01-用户需求与系统需求.md` (`UR-14`, `SR-F3`, `SR-N4`); `../Agent-System-RDM/docs/requirements/02-产品概念与形态定义.md` (shared pgvector regulations library); `../Agent-System-RDM/docs/requirements/03-产品设计方案.md` (M11 dual-channel requirements and local regulations storage).
- Current RDM flow: `../Agent-System-RDM/internal/rdmapp/regcheck.go` uses host knowledge search and model-proposed URLs; `../Agent-System-RDM/internal/rdmapp/regfetch.go` fetches, compares excerpts, and stores content-addressed network snapshots; `../Agent-System-RDM/internal/domain/regcheck.go` records dual-channel claims but currently compares clause identity more narrowly than this plan requires.
- Current RDM integration boundary: `../Agent-System-RDM/AGENTS.md` requires extension Host use and prohibits importing backend internals; missing base capabilities require a base proposal and public extension.
- Prior platform direction: `modules/documents/docs/proposals/2026-09-29-system-skeleton-design-and-plan.md` envisioned a future regulations plugin and a pluggable local/vector RAG pipeline. This plan narrows ownership: the new repository owns reusable corpus/retrieval; RDM retains its product plugin and audit/UI flows.
- MinerU references: `https://mineru.net/apiManage/docs` and `https://mineru.net/apiManage/limit`. Provider quota and file limits are time-sensitive and must be rechecked before implementation.
- Current regulations input candidate: `../Agent-System-Regulations/manifest.json` and `../Agent-System-Regulations/regulations_db.dump`. Presence and manifest counts do not verify rows, licensing, raw-source completeness, or legal effectivity.
+160
View File
@@ -0,0 +1,160 @@
#!/usr/bin/env python3
"""Adoption positive/negative cases through a repository's own scripts/agent-exec.
Usage: adopt_cases.py <adopted-repo> [<dm-source>]
Clones the committed HEAD of <adopted-repo> into a temporary directory,
materializes deps/development-manager at its gitlink, points every profile at a
fake CLI and runs: positive run+apply, missing config, bad receipt, out-of-scope
path and unknown side effect. Prints one line per case and a verdict.
"""
import json
import os
import re
import shutil
import stat
import subprocess
import sys
import tempfile
from pathlib import Path
SRC = Path(sys.argv[1]).resolve()
DM_SOURCE = sys.argv[2] if len(sys.argv) > 2 else str(Path.home() / "projects/Development-Manager")
TERMINAL_OK = json.dumps({"terminal_status": "completed", "summary": "done", "changed_files": ["adoption-probe.txt"], "evidence": ["wrote probe"], "scope_expansion": None}, separators=(",", ":"))
HELP = "--print\n--output-format\nstream-json\n--force\n--trust\n--workspace\n--sandbox\n--model\n-p\n"
ENVELOPE = 'printf \'%s\\n\' "{\\"type\\":\\"result\\",\\"subtype\\":\\"success\\",\\"is_error\\":false,\\"result\\":$(python3 -c \'import json,sys;print(json.dumps(sys.stdin.read()))\' < "$R")}"'
def sh(*args, cwd=None, env=None, check=True):
return subprocess.run(list(args), cwd=cwd, env=env, capture_output=True, text=True, check=check, timeout=900)
def fake_cli(bindir: Path, body: str) -> None:
for name in ("fake-cli",):
p = bindir / name
p.write_text(
"#!/bin/sh\n"
'case "$1" in --version|-v|-V) echo 0.0.1-test; exit 0;; --help|-h) cat <<\'HELP\'\n' + HELP + "HELP\nexit 0;; esac\n"
'R=$(mktemp)\n' + body + "\nrc=$?\n" + ENVELOPE + '\nrm -f "$R"\nexit $rc\n',
encoding="utf-8",
)
p.chmod(p.stat().st_mode | stat.S_IEXEC)
def prepare(root: Path, drop_config=False) -> Path:
repo = root / "repo"
sh("git", "clone", "-q", "--no-recurse-submodules", str(SRC), str(repo))
sh("git", "-C", str(repo), "config", "user.email", "adopt@example.invalid")
sh("git", "-C", str(repo), "config", "user.name", "adopt")
pin = sh("git", "-C", str(repo), "ls-tree", "HEAD", "deps/development-manager").stdout.split()
if len(pin) >= 3 and pin[0] == "160000":
dm = repo / "deps/development-manager"
if dm.exists():
shutil.rmtree(dm)
sh("git", "clone", "-q", "--no-checkout", DM_SOURCE, str(dm))
sh("git", "-C", str(dm), "checkout", "-q", "--detach", pin[2])
elif not (repo / "cmd/dm-server").is_dir():
raise SystemExit("deps/development-manager is not a gitlink at HEAD")
cfg = repo / "AGENT-EXECUTION.md"
text = cfg.read_text(encoding="utf-8")
text = re.sub(r"(?m)^(\s+executable:\s*).*$", r"\1fake-cli", text)
text = re.sub(r"(?m)^(\s+adapter:\s*)\S+$", r"\1cursor", text)
cfg.write_text(text, encoding="utf-8")
if drop_config:
cfg.unlink()
sh("git", "-C", str(repo), "add", "-A", "--", "AGENT-EXECUTION.md")
sh("git", "-C", str(repo), "commit", "-q", "--no-verify", "-m", "adoption case fixture")
sh("git", "-C", str(repo), "checkout", "-q", "-b", "feature/adoption-case")
return repo
def unit(root: Path) -> Path:
p = root / "unit.json"
p.write_text(json.dumps({"unit_id": "adoption-case", "goal": "Create adoption-probe.txt", "allowed_paths": ["adoption-probe.txt"], "verification": ["test -f adoption-probe.txt"], "constraints": ["leave uncommitted"], "network": False, "external_cost": False, "timeout_seconds": 120}))
return p
def run(repo: Path, root: Path, body: str):
bindir = root / "bin"
bindir.mkdir(exist_ok=True)
fake_cli(bindir, body)
rec = root / "receipt.json"
env = dict(os.environ, PATH=f"{bindir}:{os.environ['PATH']}", AGENT_EXEC_CACHE=str(Path.home() / ".cache/adoption-cases"))
p = sh(str(repo / "scripts/agent-exec"), "run", "--repo", str(repo), "--role", "implementation", "--unit", str(unit(root)), "--receipt", str(rec), cwd=repo, env=env, check=False)
d = json.loads(rec.read_text()) if rec.exists() else {}
return p, d, rec, env
WRITE_OK = 'echo probe > adoption-probe.txt; printf "%s" \'' + TERMINAL_OK + '\' > "$R"'
results = []
def case(name, fn):
root = Path(tempfile.mkdtemp(prefix=f"adopt-{name}-"))
try:
ok, detail = fn(root)
except Exception as exc: # noqa: BLE001
ok, detail = False, f"error: {exc}"
finally:
shutil.rmtree(root, ignore_errors=True)
results.append(ok)
print(f"{'PASS' if ok else 'FAIL'} {name}: {detail}")
def positive(root):
repo = prepare(root)
p, d, rec, env = run(repo, root, WRITE_OK)
if d.get("terminal_status") != "success" or not d.get("transport"):
return False, f"run exit={p.returncode} terminal={d.get('terminal_status')} reason={d.get('reason')}"
before = sh("git", "-C", str(repo), "rev-parse", "HEAD").stdout.strip()
a = sh(str(repo / "scripts/agent-exec"), "apply", "--repo", str(repo), "--receipt", str(rec), cwd=repo, env=env, check=False)
after = sh("git", "-C", str(repo), "rev-parse", "HEAD").stdout.strip()
ok = a.returncode == 0 and after == d["transport"]["commit"] and before != after
return ok, f"run exit={p.returncode} terminal=success apply exit={a.returncode} head={after[:12]}"
def missing_config(root):
repo = prepare(root, drop_config=True)
p, d, _, env = run(repo, root, WRITE_OK)
v = sh(str(repo / "scripts/agent-exec"), "validate", "--repo", str(repo), cwd=repo, env=env, check=False)
ok = p.returncode != 0 and d.get("terminal_status") == "invalid-config" and not d.get("transport") and v.returncode != 0
return ok, f"run exit={p.returncode} terminal={d.get('terminal_status')} validate exit={v.returncode}"
def bad_receipt(root):
repo = prepare(root)
p, d, rec, env = run(repo, root, WRITE_OK)
if d.get("terminal_status") != "success":
return False, f"setup run terminal={d.get('terminal_status')}"
d["changed_paths"] = sorted(set((d.get("changed_paths") or []) + ["src/injected.txt"]))
rec.write_text(json.dumps(d))
before = sh("git", "-C", str(repo), "rev-parse", "HEAD").stdout.strip()
a = sh(str(repo / "scripts/agent-exec"), "apply", "--repo", str(repo), "--receipt", str(rec), cwd=repo, env=env, check=False)
after = sh("git", "-C", str(repo), "rev-parse", "HEAD").stdout.strip()
ok = a.returncode != 0 and before == after
return ok, f"apply exit={a.returncode} head_unchanged={before == after} msg={(a.stderr or a.stdout).strip()[:100]}"
def out_of_scope(root):
repo = prepare(root)
p, d, _, _ = run(repo, root, 'echo x > outside-scope.txt; ' + WRITE_OK)
ok = p.returncode != 0 and d.get("terminal_status") == "scope-expansion" and not d.get("transport")
return ok, f"run exit={p.returncode} terminal={d.get('terminal_status')} transport={bool(d.get('transport'))}"
def unknown_side_effect(root):
repo = prepare(root)
p, d, _, _ = run(repo, root, 'echo probe > adoption-probe.txt; printf "done, no record" > "$R"')
ok = p.returncode != 0 and d.get("terminal_status") == "failed-unknown" and not d.get("transport")
return ok, f"run exit={p.returncode} terminal={d.get('terminal_status')} transport={bool(d.get('transport'))}"
if __name__ == "__main__":
head = sh("git", "-C", str(SRC), "rev-parse", "HEAD").stdout.strip()
print(f"[object] {SRC.name} HEAD={head}")
case("positive-run-apply", positive)
case("missing-config", missing_config)
case("bad-receipt", bad_receipt)
case("out-of-scope-path", out_of_scope)
case("unknown-side-effect", unknown_side_effect)
print(f"[verdict] {'ALL PASS' if all(results) else 'FAILURES'} cases={len(results)}")
sys.exit(0 if all(results) else 1)
@@ -0,0 +1,19 @@
command: scripts/dm governance check --repo . --guidelines-self
cwd: /home/weichen/projects/Development-Guidelines-wt-feature-governance-adoption
head: e82e76ef026de5ef35fc2395608432041bc17b6f
exit: 0
utc: 20261017T083826Z
---
ok gitlink guidelines: self (specification source)
ok gitlink deps/development-manager
ok agent-execution
ok file AGENTS.md
ok file PROJECT.md
ok file policy/guidelines-adoption.md
ok file .task/templates/task-card.md
ok executable scripts/agent-exec
ok executable scripts/hooks/pre-commit
ok executable scripts/dm
ok executable scripts/task
ok adoption status
ok fixtures
@@ -0,0 +1,7 @@
command: scripts/agent-exec validate --repo .
cwd: /home/weichen/projects/Development-Guidelines-wt-feature-governance-adoption
head: e82e76ef026de5ef35fc2395608432041bc17b6f
exit: 0
utc: 20261017T083826Z
---
validate: ok

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