14 KiB
开发门禁的执行与证据
本文件细化根 AGENTS.md 的启动、验证和回收规则。通用语义以固定的
deps/development-guidelines 为准;门禁实现及回归用例随本仓版本管理。
需求表、设计试验、迭代调整、阶段产物、人工决策及智能体 Review/合入按
迭代交付 执行。任务卡分别记录授权边界、必要人工决策点、
agent-per-unit(配置:AGENT-EXECUTION.md) 实施执行模式、逐单元 Agent 实施收据、
智能体审阅者及对象版本;权威验证与合入仍由 host/主模型执行,worker 局部自检不替代。
本地 evidence 仅记录 SELF 命令,不能证明授权/人工决策或提升为 CI/独立审阅证据。
Agent 实施收据与来源
每次外部实施尝试须在任务卡「Agent 实施收据」记录:配置摘要(AGENT-EXECUTION.md digest)、
角色、声明候选顺序、attempt、CLI/模型、终态、transport、fallback(只表示该行是否为 Codex
紧急尝试),以及源码外原始收据路径。初始生成状态为 NOT_RUN。原始事件流与超限输出保留在
源码外;未知终态(failed-unknown)与 scope-expansion 的隔离工作区须保留待对账,不得静默丢弃。
清理须有精确恢复或保留现场的可复核证据。
候选、尝试上限、Codex 紧急尝试、fallback、fail-stop、尝试结束条件,以及 transport/admit 与 host 豁免路径,以迭代交付为唯一权威。
启动与恢复
从当前检出运行一次启动检查,使用每次唯一、仓外的绝对收据路径:
make task-triage REQ='<需求>' TRIAGE_RECEIPT=/tmp/my-task-triage.json
RECEIPT=/tmp/my-task-precheck.json CMD="make precheck" make evidence
make task-start NAME=feature/my-task TRIAGE_RECEIPT=/tmp/my-task-triage.json PRECHECK_RECEIPT=/tmp/my-task-precheck.json
分流以远端为准(见 迭代交付 的两级分支模型)。有候选时先运行
make task-triage-decide TRIAGE_RECEIPT=… VERDICT=JOIN|NEW … 写入显式决策与理由。子任务使用
KIND=child INITIATIVE=feature/<大任务> NAME=feature/<大任务>-<子题>,收据须为选中该大任务的 JOIN。
task-start 对 DECISION_REQUIRED、过期、远端不可核验(REMOTE_UNVERIFIED,退出码 6)或与所选 initiative 不一致的收据直接拒绝,且不建分支。
第一步先捕获原始执行,再创建任务卡;收据保存完整脱敏输出、退出码、执行位置和对象。 第二步核验收据与当前仓库/基线,再创建工作区并导入;不靠事后重跑冒充首次检查。 同一收据不可覆盖。首次检查失败时处理原因,使用新路径重新启动。主干在两步间前进时, 重新确认新的启动基线,不能把旧收据移花接木到新对象。
恢复已有登记任务先捕获本次启动检查,再在原任务 worktree 用
make task-resume PRECHECK_RECEIPT=/tmp/my-task-resume.json 验证并原样导入;不重新建分支。
默认 TASK_WORK_MODE=delivery,继续要求严格 READY 和当前目标一致。
工作区忙或落后时先由 owner 保存现场并同步。远端不可达时,delivery 恢复仍以 REMOTE_UNVERIFIED 拒绝;
显式 TASK_WORK_MODE=local 可在先核验收据、活动任务、原 R0/HEAD/工作区范围后导入 LOCAL_READY 收据,
继续已授权局部工作(子任务仅在远端不可查询时以已登记的本地父分支为参考,且须包含记录的 parent_head_sha)。
远端可达但目标或已登记父分支缺失(即使本地同名分支存在)、回退/分叉或无法比较时仍以 REMOTE_UNVERIFIED 拒绝,不导入收据。离线不得建任务、同步、PR 检查、Review/合入或交付,本地参考不视为最新或可交付。
局部恢复接口已具备,正式交付仍按合入调度的单一最终窗口执行。 启用后,既有任务可以显式选择 local,保持原 R0,标记落后,继续已授权局部工作:
TASK_WORK_MODE=local RECEIPT=/tmp/my-local-resume.json CMD="make precheck" make evidence
TASK_WORK_MODE=local make task-resume PRECHECK_RECEIPT=/tmp/my-local-resume.json
LOCAL_READY 只用于局部恢复;新任务入口始终校验严格 READY,正式验收与合入另行同步。
恢复核验实际 worktree/卡片/分支、R0 祖先关系及源码外原始收据;脏现场、Git 操作和组件漂移仍拒绝。
resume-local 只接受 LOCAL_READY 收据,且须同时满足:卡片位于本 worktree 的 .task/ 且状态未以“已”开头
(已完成/已放弃等闭合任务拒绝);收据内 [task-state] 的登记路径与 R0 等于当前登记任务;收据前后与当前 HEAD
一致、工作区干净且组件状态未变;收据 root_target/immediate_target 等于卡片范围;目标只允许快进落后,回退或分叉拒绝。
远端跟踪目标 ref 缺失时,local 模式的 precheck 与 resume-local 只在当前登记任务身份、本地 R0 对象、R0 为本地 HEAD 祖先、
工作区干净、分支/worktree、组件与范围全部核验通过时继续。缺失或过期的远端 ref 从不证明新鲜度;只要有任一目标历史可用,
其祖先关系须一致。local precheck 刷新失败时,远端不可查询按上述本地核验继续;远端可查询时,以缓存目标(无缓存时为活动任务卡
登记的 R0)为基线,通告提交须本地存在且为基线后代才继续,目标 ref 缺失、回退/分叉或通告提交本地缺失无法比较均判 REMOTE_UNVERIFIED。
正式 Review 与合入仍须先完成新鲜的权威同步。
resume-delivery 仍要求 READY 且收据目标等于当前权威目标。LOCAL_READY 始终是 SELF 本地工作记录,
不能用于建任务、正式交付、Review、合入、CI、GATE 或 REPLAY。
旧收据允许作为历史证据原样导入,不自动成为当前恢复或交付准入;格式继续为 schema 1。
堆叠(standalone)任务使用 PARENT=feature/parent PARENT_PR=<父PR链接>;子任务改用 KIND=child。父分支须包含本批主干 R0;
卡片同时记录父分支、父 SHA 和父 PR。父先合入,子同步最新 main 并改回 main 为 PR base。
当前 make task-pr-check 与 CI PR base gate 对 standalone PR 只接受 base 为 main,因此堆叠 PR 在 base 改回 main 前不能通过这两道门禁。
PR 门禁:make task-pr-check [PR=N] [FINAL=1] 核验当前分支 PR 的状态、base 与 head(远端为准)。子任务期望 base 为卡片 immediate_target(所属大任务分支,且其父仍有开放 PR 指向 main);普通任务与大任务为 main。FINAL=1 仅用于大任务收口,要求 accepting_requirements=false 且必需子任务已合入或已延期。
被测对象
make task-sync 在父仓合并后按固定 gitlink 物化未修改组件,并核对实际组件工作树。
同步目标取卡片 immediate_target:子任务为远端所属大任务分支头,其余为 origin/main。
组件 feature 分支若与新指针不同,先保留其分支,交给 owner 显式同步并更新组合;
不能用自动 checkout 丢弃组件分支现场。任何失败都保留现场并阻止同步成功声明。
make test-worktree 核对递归子模块:未初始化、冲突、指针漂移及子仓未保存改动均拒绝。
它是组合测试和构建的前置检查。父仓未提交改动可以局部测试,但证据必须记录实际对象状态;
正式验收使用已提交的固定对象,不能仅写一个与工作树不同的 HEAD。
task-sync 对同一基线重复调用只核验,保留 HEAD、索引和卡片;实际合并新目标才追加一次记录。
输出完整 sync_base、记录完成后的 tested_head、checked_at 及 changed;changed 表示是否实际纳入新目标,组件仍须核对。
本地记录与独立证据
本地 make evidence 一律生成 SELF。SRC=GATE/REPLAY 不可把本地执行升级为权威来源。
GATE 引用受信平台的运行链接、执行身份、完整 SHA 和结果;REPLAY 引用独立审阅者的
环境、命令、对象和结果。审核者核验这些来源,不能只读作者填入的标签。
PR 合入由智能体执行:先完成有效 Review,再同步并解决冲突,核验当前 HEAD 的全部 必需 CI 通过及平台准入后合入;具体步骤与失败出口见 迭代交付。 闭合 PR 使用同一流程,不以任务卡已回填或本地测试通过代替 CI。
收据中的摘要检测损坏,不是签名或身份凭据。保存的是完整脱敏输出及其 SHA-256; 命令含敏感值时展示脱敏形式,并记录原命令摘要。执行前后对象分别记录;命令改变 HEAD 时不把执行前 SHA 冒充执行后对象。不能读取执行后状态时明确记录缺项。
写入任务卡(CMD 直写或 IMPORT_RECEIPT 导入)时,卡内只放摘要块(命令、退出码、前后 HEAD、
输出尾部及各摘要);完整收据以 0600 一次性写到仓外的记录路径(默认
~/.cache/agent-system-dev/evidence/<receipt_sha256>.json,可用 AGENT_EVIDENCE_DIR 覆盖),
不覆盖不同内容。check-evidence 在本机可读时用完整收据核对摘要,缺失则警告未验证;两者仍是 SELF。
候选固定前后
固定前,完成同步、必要检查、任务卡及本地收据提交,核对干净的组件组合,再读取和推送最终 HEAD。 将这个 head、base、完整组件及相关配置引用到调度尝试;任务卡表内“记录前对象”不当作最终候选。
固定后,本地命令使用源码外唯一 RECEIPT 保存完整输出,平台 CI/Review/合入结果写调度记录:
RECEIPT=/tmp/my-attempt-worktree-check.json CMD="make test-worktree" make evidence
执行者选择位于当前 checkout 和 Git 元数据之外的未用绝对路径,工具保留 before/after、原命令退出码和 SELF 来源。 这是 manual 流程,工具不提供工作树冻结或路径范围的 OS 强制隔离。命令改变源码、组件或相关配置时, 保留实际记录,重新建立尝试及受影响验证;新增提交必须核验新 HEAD 的必需 CI。 后续实际合入/清理后按授权闭合任务,再原样导入已保存收据;不向仍冻结的候选追加记录提交或补写未来结果。
凭据从环境或受保护文件引用,避免出现在命令字面量。脱敏是补充防护,不是允许输出秘密。 执行脚本不通过 shell tracing 暴露环境;管道任何一段失败应传回非零退出码。 工具写入失败本身也必须报错,不能只保留一个看似成功的退出状态。
回收
仅在登记的任务 worktree 根目录回收。owner 先确认全部写者已退出、任务成果与证据已保存,
以 TASK_WRITERS_STOPPED=1 make task-finish 明确确认;
脚本检查主检出/子目录误用、Git 操作和锁、父子仓修改及未跟踪/ignored 文件;
子模块另有登记 worktree 时拒绝回收,避免删除其他检出依赖的 Git 管理目录。
可再生缓存由 owner 按已识别路径单独处置;无法确认用途的文件保留。
任务合入需以本次成功获取的权威目标验证:子任务为其所属大任务分支的远端头,其余为 origin/main(即 immediate_target)。合入提交不能证明未提交文件已经落盘。
Git 对含子模块的工作区需要显式删除选项时,只有全部现场检查通过才允许该路径;
它不豁免任何脏状态、忽略文件、独有提交/引用或锁检查。普通删除失败不转入强删兜底。
保留无法确认安全的目录和分支,输出下一步处理依据。
子仓 pin 之外的 refs/stash/reflog 历史采取保守拒绝,即使其中部分可能已在远端:
owner 须先独立确认其保存与归属,工具不把缓存的远端引用当作唯一数据已经备份的证据。
远端分支删除与本地回收分别报告,失败不能声明两者全部完成。
任务卡默认在合入前闭合:最终同步/合入前在任务 worktree 运行 make task-close SELF=1,本卡改为"已完成(合入前闭合)"并归档,随同一 PR 合入,无需单独闭合 PR;回收命令不顺带改写共享主检出。
主检出的 make task-close(闭合 PR base 为 main)或 FOLD=--fold(随任务分支合入,base 为卡片 immediate_target)只用于已合入未闭合的遗留卡。
post-merge 仅提示,不自动调用闭合。make task-close 会提交、推送并可能创建 PR,
执行者先按迭代交付规则核对该动作的授权及所选任务,保留未授权的其他任务现场。
回收命令使用待删目录之外的 RECEIPT 保存输出,清理结果由后续闭合记录引用。
CI 凭据边界
候选代码执行前结束有凭据的源码获取阶段。获取只访问受信主机及登记的组件仓, 不根据候选提供的任意 URL 携带 token;认证配置限单次进程,不写全局 Git 配置或 remote URL。 测试/构建阶段检查配置中不存在凭据,并使用不含 checkout token 的环境。
仓内测试只能证明脚本边界。runner 隔离、token 权限、工作流来源和平台分支保护 由平台维护者验证;没有对应 GATE/REPLAY 时标未验证,不由本地测试推断。
持续回归
make test-governance 在临时真实 Git 仓库中覆盖回收、组件同步、离线启动、收据捕获/导入、
管道失败、假凭据脱敏、写路径及 CI 凭据隔离;临时 remote 均为本地路径,禁止使用真实秘密。
它纳入 make test,新机制必须有正常、拒绝和故障分支。历史临时测试记录仅作定位线索。
普通文档核对真实入口和相对链接;规范升级检查条文、命令、模板与能力矩阵是否一致。 机制未变可按固定版本复用证据,变更的机制重新运行对应负例。