Merge pull request 'Adopt the governance kit in Dev and record the v2 adoption matrix' (#602) from feature/governance-v2-closeout into main
ci / svc-realcombo (push) Successful in 2m7s
ci / test (push) Successful in 7m3s
ci / test-pg (push) Successful in 8m31s

This commit was merged in pull request #602.
This commit is contained in:
2026-10-17 11:32:24 +00:00
16 changed files with 1201 additions and 23 deletions
+2
View File
@@ -168,6 +168,8 @@ jobs:
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
File diff suppressed because one or more lines are too long
+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;放弃路径注明原因>。
+2
View File
@@ -67,6 +67,8 @@ U2 起实施与部署分别评审。
测试。实际目标以根 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` 另核对
真正被测的组件工作树。两者分别验证固定组合与实际检出,不能相互替代。
@@ -6,6 +6,10 @@
全局任务只有在全部正式仓达到 `ADOPTED_ACTIVE`、新项目入口启用、主 PR 全部合入并完成清理后才能标记 `CLOSED`。
## 全局状态
Phase 0–5、7 已合入;Phase 6:17 个正式仓中 16 个 ADOPTED_ACTIVE(合入提交与 main CI 见矩阵),Agent-System-Dev 待 [PR #602](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/602) 合入。#602 合入、任务卡闭合与 worktree/分支清理完成后,在闭合记录中回填 Dev 行并把本节改为 `CLOSED`;在此之前全局状态为 IN_PROGRESS。新项目入口(Phase 7 `governance init|check`)证据见 DM #18–#20 合入记录。`RELEASED` 不适用:Guidelines 正式版本 tag 与分支保护必需检查均为用户双钥匙事项(命令见文末),不阻塞 CLOSED。
## 交付主线
| Phase | 内容 | 仓库 / 分支 | PR | 状态 | 依赖 |
@@ -15,9 +19,9 @@
| 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);Dev `feature/dev-shared-executor-switch` | #16、[#17](https://git-home.u1680832.nyat.app:30319/weichen/Development-Manager/pulls/17) | DM 执行器 MERGED(183e764);清点缺陷修复 #17 MERGED(9c38345);Dev 已固定 DM 42e675f,P5-A 薄入口切换(501b685)与 P5-B Python 退役(63e11ea)完成,等价重放 11 SAME + 1 预期差异(legacy-config),Dev PR 待 Review/CI | 4 |
| 6 | 存量仓逐仓采纳 | 各仓独立 initiative | 各仓 `feature/governance-adoption` | IN_PROGRESS(试点 Agent-System-Core:单元成功、正负例 ALL PASS;钩子环境缺陷经 DM [#19](https://git-home.u1680832.nyat.app:30319/weichen/Development-Manager/pulls/19) 修复后改固定新版本) | 5 |
| 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) | MERGED(42e675f;K1+K2、K3 独立 Review APPROVE,CI GATE 通过);钩子环境修复 #19 进行中 | 5 |
| 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` | 见下方采纳矩阵 | IN_PROGRESS(16/17 ADOPTED_ACTIVE:已合入且 main 上 CI 通过;Agent-System-Dev 待 PR #602 合入) | 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 |
## 当前候选对象与历史证据
@@ -41,25 +45,27 @@
来源: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 | 共享执行器入口 | 正例 | 负例 | Review/CI | 状态 |
| 批次 | 仓库 | Guidelines 固定版本 | AGENT-EXECUTION.md | 共享执行器入口 | 采纳 PR | 合入提交 | main 上 CI(GATE) | 状态 |
|---|---|---|---|---|---|---|---|---|
| A | Development-Guidelines | 自身 | — | — | — | — | — | PLANNED |
| A | Agent-System-Dev | deps/development-guidelines 2688fd2 | 有(Go 执行器校验通过) | scripts/agent-exec → DM 42e675f | P5-A/P5-B 实际单元 | adopt_cases ALL PASS + 等价重放 | 待 PR | IN_PROGRESS |
| A | Development-Manager | 待更新 | 无 | 实现方 | — | — | — | PLANNED |
| B | Agent-System-Core | 2688fd2 | 有 | scripts/dm(待改固定 #19 后版本) | 单元 r1 success | ALL PASS | — | IN_PROGRESS |
| B | Agent-System-Backend | — | 无 | 无 | — | — | — | PLANNED |
| B | Agent-System-RDM | — | 无 | 无 | — | — | — | PLANNED |
| C | Agent-System-Frontend | — | 无 | 无 | — | — | — | PLANNED |
| C | Agent-System-UI | — | 无 | 无 | — | — | — | PLANNED |
| C | Agent-System-Documents | — | 无 | 无 | — | — | — | PLANNED |
| C | Agent-System-Releases | — | 无 | 无 | — | — | — | PLANNED |
| D | Agent-Command | — | 无 | 无 | — | — | — | PLANNED |
| D | Agent-Intent | — | 无 | 无 | — | — | — | PLANNED |
| D | Agent-Native | — | 无 | 无 | — | — | — | PLANNED |
| D | Agent-Squad | — | 无 | 无 | — | — | — | PLANNED |
| E | Error-Code-System | — | 无 | 无 | — | — | — | PLANNED |
| E | Logging-System | — | 无 | 无 | — | — | — | PLANNED |
| E | Agent-Document-Renderer | — | 无 | 无 | — | — | — | PLANNED |
| 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) | 待合入 | 合入前 PR 头的 CI(GATE)记录于任务卡 `.task/feature-governance-v2-closeout.md`「合入与清理」;governance check 位于必需检查 `ci / test` | PR_OPEN(合入后回填合入提交与 main CI 并置 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。每仓的收据、证据与 Review 结论在该仓归档任务卡 `.task/archive/feature-governance-adoption.md`(Guidelines 按其 CONTRIBUTING.md 记录在本目录 `2026-10-17-guidelines-governance-adoption.md`)。
## Owner 决策记录
@@ -70,6 +76,10 @@
| 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 |
## 停止条件
@@ -80,4 +90,50 @@ CLI 终态无效或副作用未知;Review、CI 或平台准入缺失;主干
## 用户双钥匙事项
- Development-Guidelines 正式版本 tag:Agent 只准备命令,由用户执行。
- 分支保护变更(如新增必需检查):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-*` 远端分支待清点。
@@ -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) |
+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
@@ -0,0 +1,13 @@
command: python3 /tmp/gov-neg/adopt_cases.py .
cwd: /home/weichen/projects/Development-Guidelines-wt-feature-governance-adoption
head: e82e76ef026de5ef35fc2395608432041bc17b6f
exit: 0
utc: 20261017T083826Z
---
[object] Development-Guidelines-wt-feature-governance-adoption HEAD=e82e76ef026de5ef35fc2395608432041bc17b6f
PASS positive-run-apply: run exit=0 terminal=success apply exit=0 head=f2fb0241b685
PASS missing-config: run exit=2 terminal=invalid-config validate exit=2
PASS bad-receipt: apply exit=4 head_unchanged=True msg=apply: no local integrity record: changed paths do not match the transport diff
PASS out-of-scope-path: run exit=5 terminal=scope-expansion transport=False
PASS unknown-side-effect: run exit=4 terminal=failed-unknown transport=False
[verdict] ALL PASS cases=5
@@ -0,0 +1,19 @@
command: scripts/dm governance check --repo . --guidelines-self
cwd: /home/weichen/projects/Development-Guidelines-wt-feature-governance-adoption
head: 7cafc7d03b4ef6bde22c591d64ee583f386d3d2c
exit: 0
utc: 20261017T092431Z
---
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: 7cafc7d03b4ef6bde22c591d64ee583f386d3d2c
exit: 0
utc: 20261017T092431Z
---
validate: ok
+31
View File
@@ -0,0 +1,31 @@
# 通用规范采纳记录
- 项目/负责人:Agent-System-Dev / weichen
- 状态:active
- 规范位置:`deps/development-guidelines`
- 规范性文档目录:`policy/`(项目规则与制度放此处;只收紧不放宽上游规范)
- 过程文档位置:任务卡 `.task/`,归档 `.task/archive/`,规划记录 `docs/superpowers/plans/`;任务主记录在对应 PR 中
- 版本权威:本仓 gitlink `deps/development-guidelines` @ `2688fd2be6a5`(完整提交 `2688fd2be6a52c0bf110e7e6366b6f291ab5e4eb`);可读标签:无
- 批准/生效依据:`feature/governance-v2-closeout PR(Agent-System-Dev)`;在该 PR 合入前,证据、Review 与 CI 须先记录于 `.task/feature-governance-v2-closeout.md`
- 替代范围和迁移说明:无。既有 [policy/adoption.md](adoption.md) 的逐条决策保持不变,本文件不替代其内容。
逐条规范的采纳、不适用理由与执行方式以 [policy/adoption.md](adoption.md) 为准,本文件不重复其表格。
本仓 `make task-*`(`scripts/task.sh`、`scripts/task_triage.py`、`scripts/task_pr_check.py`)仍是权威任务生命周期;
`scripts/task` 只是 DM 共享入口,供不含 `task.sh` 的仓库使用,本仓不以它替代 `make task-*`。
本文件由 kit 要求的采纳入口只登记以下一行,其余规范沿用 [policy/adoption.md](adoption.md):
| 规范/工作流 | 适用条件与范围 | 采纳或不适用理由 | 执行方式/证据 |
|---|---|---|---|
| [standards/agent-execution.md](../deps/development-guidelines/standards/agent-execution.md) | 工程 Agent CLI 执行路由、会话隔离与受控集成 | 凡允许 AI 协助必须采纳;配置见 `AGENT-EXECUTION.md` | advisory:`AGENT-EXECUTION.md` + `scripts/agent-exec`(validate / admit);CI 步骤「Validate AGENT-EXECUTION.md with the pinned shared executor」与「Governance check with the pinned kit」(`scripts/dm governance check --repo .`)。分支保护要求 governance check 为必需检查之前,不宣称为强制(enforced)门禁 |
## 项目差异
无。项目差异(如有)以 [policy/adoption.md](adoption.md) 的「项目差异」节为准。
## 本次升级或首次接入验证
- 入口:根目录 `AGENTS.md`、`PROJECT.md`、`AGENT-EXECUTION.md`、`scripts/dm`、`scripts/task`、`.task/templates/task-card.md`。
- 相对链接:规范文档统一经 `../deps/development-guidelines/...` 引用;本仓内文档使用仓内相对路径。
- 版本获取:`deps/development-guidelines` gitlink 固定于上表版本;`deps/development-manager` gitlink 固定于 `0552b7358d6955057d6eea090326f83317ed992a`,由 `scripts/dm` 按该提交构建共享 dm-server。
- 验证:在采纳 PR 的临时副本中运行 `scripts/dm governance check --repo .` 与 `scripts/agent-exec validate --repo .`,结果与 `make test-governance` 记录于 `.task/feature-governance-v2-closeout.md`。
Executable
+55
View File
@@ -0,0 +1,55 @@
#!/usr/bin/env bash
# 共享 dm-server 薄入口:读取 deps/development-manager 的 gitlink 钉住提交,
# 按该提交构建并缓存 dm-server,再 exec 其子命令(agent-exec、task、governance)。执行语义与退出码以该二进制为准。
set -euo pipefail
root=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)
dm="$root/deps/development-manager"
die() { echo "dm: $*" >&2; exit 2; }
# git 钩子会导出仓库本地变量(GIT_DIR、GIT_INDEX_FILE 等),它们会让 `git -C "$dm"` 解析到外层仓库。
# 所有针对 DM 检出的 git 与 go 调用都在清除这些变量后执行;读取外层 gitlink 与最终 exec 仍保留继承环境。
dm_local_env="GIT_DIR GIT_WORK_TREE GIT_INDEX_FILE GIT_PREFIX GIT_OBJECT_DIRECTORY GIT_ALTERNATE_OBJECT_DIRECTORIES GIT_COMMON_DIR GIT_GRAFT_FILE GIT_NAMESPACE GIT_CONFIG GIT_CONFIG_PARAMETERS GIT_CONFIG_COUNT GIT_SHALLOW_FILE GIT_IMPLICIT_WORK_TREE $(git rev-parse --local-env-vars 2>/dev/null || true)"
dm_clean_env() { for v in $dm_local_env; do unset "$v"; done; }
dmgit() ( dm_clean_env; git -C "$dm" "$@" )
# 1. 钉住版本只来自索引中的 gitlink(mode 160000),不读取工作区文件。
entry=$(git -C "$root" ls-files -s -- deps/development-manager 2>/dev/null || true)
[ -n "$entry" ] || die "索引中缺少 deps/development-manager 的 gitlink,无法确定钉住的 DM 版本"
read -r mode pin _stage _path <<<"$entry"
[ "$mode" = 160000 ] || die "deps/development-manager 不是 gitlink(mode=$mode)"
[[ "$pin" =~ ^[0-9a-f]{40}$ ]] || die "gitlink 提交格式无效:$pin"
# 2. 检出必须存在且确为 DM 独立仓库(避免 git -C 误解析到外层仓库),HEAD 必须等于钉住提交。
[ -e "$dm/.git" ] || die "deps/development-manager 未检出;请按钉住提交 $pin 检出该 gitlink"
top=$(dmgit rev-parse --show-toplevel 2>/dev/null || true)
[ -n "$top" ] && [ "$top" = "$(cd "$dm" && pwd -P)" ] \
|| die "deps/development-manager 不是独立检出;请按钉住提交 $pin 检出该 gitlink"
head=$(dmgit rev-parse HEAD 2>/dev/null || true)
[ "$head" = "$pin" ] \
|| die "deps/development-manager HEAD(${head:-未知})与钉住提交 $pin 不一致;请按钉住提交检出"
# 3. 检出工作树必须干净(忽略嵌套 submodule 状态)。
dirty=$(dmgit status --porcelain --ignore-submodules=all) \
|| die "无法读取 deps/development-manager 的工作树状态"
[ -z "$dirty" ] || die "deps/development-manager 存在未提交改动,拒绝运行(请先清理该检出)"
# 4. 二进制按钉住提交缓存;缺失时在缓存目录内临时构建,完成后原子改名,避免留下半成品。
cache="${DM_CACHE:-${XDG_CACHE_HOME:-$HOME/.cache}/development-manager/dm-server}"
bin="$cache/dm-server-$pin"
if [ ! -x "$bin" ]; then
command -v go >/dev/null 2>&1 || die "缺少 go,无法构建 dm-server($pin)"
mkdir -p "$cache"
cache=$(cd "$cache" && pwd -P)
bin="$cache/dm-server-$pin"
work=$(mktemp -d "$cache/build-$pin.XXXXXX")
if ! (dm_clean_env; cd "$dm" && GOWORK=off go build -trimpath -o "$work/dm-server" ./cmd/dm-server); then
rm -rf "$work"
die "构建 dm-server 失败($pin)"
fi
mv -f "$work/dm-server" "$bin"
rm -rf "$work"
fi
exec "$bin" "$@"
Executable
+4
View File
@@ -0,0 +1,4 @@
#!/usr/bin/env bash
# 通用任务入口:转调 scripts/dm 的 task 子命令(triage / start / pr-check)。
set -euo pipefail
exec "$(dirname "$0")/dm" task "$@"