# 开发门禁的执行与证据 本文件细化根 AGENTS.md 的启动、验证和回收规则。通用语义以固定的 `deps/development-guidelines` 为准;门禁实现及回归用例随本仓版本管理。 需求表、设计试验、迭代调整、阶段产物、人工决策及智能体 Review/合入按 [迭代交付](delivery.md) 执行。任务卡分别记录授权边界、必要人工决策点、 `agent-per-unit(配置:AGENT-EXECUTION.md)` 实施执行模式、逐单元 Agent 实施收据、 智能体审阅者及对象版本;权威验证与合入仍由 host/主模型执行,worker 局部自检不替代。 本地 evidence 仅记录 SELF 命令,不能证明授权/人工决策或提升为 CI/独立审阅证据。 ### Agent 实施收据与来源 每次外部实施尝试须在任务卡「Agent 实施收据」记录:配置摘要(`AGENT-EXECUTION.md` digest)、 角色、声明候选顺序、attempt、CLI/模型、终态、transport、fallback(是否为应急尝试;现行配置无 应急档,恒为否),以及源码外原始收据路径。初始生成状态为 `NOT_RUN`。原始事件流与超限输出保留在 源码外;未知终态(`failed-unknown`)与 `scope-expansion` 的隔离工作区须保留待对账,不得静默丢弃。 清理须有精确恢复或保留现场的可复核证据。 候选、尝试上限、fallback、fail-stop、尝试结束条件,以及 transport/admit 与 host 豁免路径,以[迭代交付](delivery.md#agent-实施单元与主模型职责)为唯一权威。 ## 启动与恢复 从当前检出运行一次启动检查,使用每次唯一、仓外的绝对收据路径: ```bash 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 ``` 分流以远端为准(见 [迭代交付](delivery.md) 的两级分支模型)。有候选时先运行 `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/合入或交付,本地参考不视为最新或可交付。 局部恢复接口已具备,正式交付仍按[合入调度](delivery.md#合入调度)的单一最终窗口执行。 启用后,既有任务可以显式选择 local,保持原 R0,标记落后,继续已授权局部工作: ```bash 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 通过及平台准入后合入;具体步骤与失败出口见 [迭代交付](delivery.md#智能体-review-与-pr-合入)。 闭合 PR 使用同一流程,不以任务卡已回填或本地测试通过代替 CI。 收据中的摘要检测损坏,不是签名或身份凭据。保存的是完整脱敏输出及其 SHA-256; 命令含敏感值时展示脱敏形式,并记录原命令摘要。执行前后对象分别记录;命令改变 HEAD 时不把执行前 SHA 冒充执行后对象。不能读取执行后状态时明确记录缺项。 写入任务卡(`CMD` 直写或 `IMPORT_RECEIPT` 导入)时,卡内只放摘要块(命令、退出码、前后 HEAD、 输出尾部及各摘要);完整收据以 0600 一次性写到仓外的记录路径(默认 `~/.cache/agent-system-dev/evidence/.json`,可用 `AGENT_EVIDENCE_DIR` 覆盖), 不覆盖不同内容。`check-evidence` 在本机可读时用完整收据核对摘要,缺失则警告未验证;两者仍是 SELF。 ### 候选固定前后 固定前,完成同步、必要检查、任务卡及本地收据提交,核对干净的组件组合,再读取和推送最终 HEAD。 将这个 head、base、完整组件及相关配置引用到调度尝试;任务卡表内“记录前对象”不当作最终候选。 固定后,本地命令使用源码外唯一 RECEIPT 保存完整输出,平台 CI/Review/合入结果写调度记录: ```bash 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`,新机制必须有正常、拒绝和故障分支。历史临时测试记录仅作定位线索。 普通文档核对真实入口和相对链接;规范升级检查条文、命令、模板与能力矩阵是否一致。 机制未变可按固定版本复用证据,变更的机制重新运行对应负例。