Files
playbook/templates/AGENT_RULES.template.md
T

27 KiB
Raw Blame History

AGENT_RULES

目的:为本仓库提供稳定的 Matt Pocock 工程流程与 ticket 执行约束。

.scratch/ 是 spec、ticket、feature 队列和执行状态的唯一事实源。 memory-bank/ 保存稳定的项目定位、技术上下文和当前系统模式。 CONTEXT.md 保存稳定领域词汇,docs/adr/ 保存关键架构决策。

优先级

  1. 系统/开发者指令
  2. 项目私有规则:AGENT_RULES.local.md(如存在)
  3. 仓库规则:.agents/AGENTS.md
  4. 本文件

沟通原则

  • 统一使用简体中文
  • 发现用户理解有误时,礼貌纠正
  • 不给时间估算,专注事实、风险与下一步

项目边界

  • {{PLAYBOOK_ROOT}}/ 是 Playbook 模板/供应商目录,不是业务项目源码
  • 除非任务明确维护 Playbook,不得修改 {{PLAYBOOK_ROOT}}/ 下内容
  • 当前项目的生效规则位于项目根目录的 AGENT_RULES.mdAGENT_RULES.local.mdAGENTS.md.agents/
  • 搜索、批量修改、review 和提交时默认排除 {{PLAYBOOK_ROOT}}/
  • 不覆盖、stash、reset 或提交不属于当前 ticket 的既有改动

会话启动

处理首个实质性任务前,按相关性读取;不存在则跳过:

  1. AGENT_RULES.local.md
  2. .agents/index.md
  3. memory-bank/project-brief.md
  4. memory-bank/tech-context.md
  5. memory-bank/system-patterns.md
  6. docs/agents/issue-tracker.md
  7. docs/agents/domain.md
  8. CONTEXT.mdCONTEXT-MAP.md
  9. 相关 docs/adr/
  10. main_loop.py status --state-root .scratch 的当前状态

任务入口

四个入口按成本递增排列,从上往下取第一个满足的。每个入口都定义了强制升级条件;条件成立 时立即停止当前路径并转入指定入口,已产生的改动只作为事实输入,不视为已批准方案。

入口 1:直接执行

只读分析、定位、审查,以及不改变可观察行为的机械修改(重命名、格式化、注释、导入整理、纯 文档措辞)。不生成 spec/tickets,不建 branch。仍须遵守项目规则、验证实际结果,并只处理本次 相关改动。

升级条件:出现任何可观察行为变化 → 入口 2。

入口 2:单切片改动

会改变行为、不属于入口 3 的已知 bug,且同时满足以下全部条件的改动走这里,不入队、不建 ticket branch

  • 只涉及一个模块,或只扩展一个已存在的公开接口
  • 能在已存在的测试 seam 上验证,不需要新建 seam
  • 不新增公开接口、配置项、数据格式或第三方依赖
  • 不涉及数据迁移、回滚、兼容性窗口或并发协调
  • 预计一个 session 内交付,不需要跨 session 调度

流程:在已存在 seam 上按 tdd 完成一个可观察行为切片 → 运行局部验证 → 提交 → 对 HEAD 运行 code-review 的 Standards 单轴 → 修完硬 finding 后重新提交和验证。证据 写入 commit message 和 session 收尾,不写 .scratch/

升级条件(任一成立即停止并转入口 4):需要新 seam、跨出上述任一条边界、或发现 未确认的设计取舍。

入口 3:已明确预期行为的 bug

正确行为已知的 bug 走这里,无论当下能否建立失败反馈回路——建立反馈回路是 diagnosing-bugs 的 Phase 1,不是进入它的前提。diagnosing-bugs 完整执行 Phase 1-6,负责反馈回路、 复现最小化、假设、回归测试、修复、验证和清理;不另起 tdd 会话(Phase 5 内部已是 test-first),也不为已确定的需求重新 grilling。

两种缺口按该 skill 自身的规定处理:Phase 1 建不出可失败的命令时停下来索取环境、artifact 或 许可,不要换入口绕过;不存在正确 seam 时把"缺失 seam"本身作为发现记录,不因此中断修复, 修复落地后再建议 improve-codebase-architecture。诊断暴露新的产品取舍或架构方向时,先完成 Phase 5-6 让缺陷不再复现,再把取舍带入入口 4,不要把未修完的缺陷留在原地等设计结论。

若 bug 来自已领取 ticketPhase 6 后直接继续本地 ticket 执行协议的提交、review 和 finish 门禁。

入口 4:新 feature 或设计变更

以下任一条成立时进入完整工程主链:

  • 存在需要用户决策的产品取舍或架构方向
  • 需要新的测试 seam,或新增公开接口、配置项、数据格式
  • 跨两个以上模块边界
  • 涉及数据迁移、回滚或兼容性窗口
  • 需要跨 session 调度或多 session 并发
  • 预计无法在一个 session 内交付

边界不清时先按入口 2 起步,触到入口 2 的任一升级条件时立即转入本入口。"不确定"的正确 处置是用最小路径试探到边界,不是预付最贵的流程。

非交互模式下的入口 4

主链的 grilling 收敛和 seam confirmation 需要用户在场。无人值守而判定为入口 4 时:已有已领取 ticket 就 finish --result blocked --reason "<待确认的具体决策>";尚无 ticket 则不得代替用户 决策、也不得降级到入口 2 硬做。用 to-questionnaire 把待决问题写到项目根目录的 .scratch/questions/<slug>.md,记录阻塞阶段、已知上下文、待决问题和恢复入口;用户回答后从 grill-with-docs 恢复。不得把问题清单写入临时 worktree 或稳定知识文件。

正式工程主链

入口 4 使用以下顺序:

setup-matt-pocock-skills
  -> grill-with-docs (grilling + domain-modeling)
  -> to-spec
  -> to-tickets
  -> main_loop.py enqueue
  -> 提交 planning baseline
  -> main_loop.py claim
  -> 本地 ticket 执行协议 (tdd -> commit -> code-review -> finish)
  -> main_loop.py integrate
  -> 提交 final workflow state
  • 每个仓库首次使用时运行 setup-matt-pocock-skills,本地开发选择 local markdown tracker
  • 进入 grill-with-docs 或本地 ticket 执行协议前,重新读取 memory-bank/project-brief.mdmemory-bank/tech-context.mdmemory-bank/system-patterns.md
  • grilling 必须走完整 design treedesign frontier(尚未定下的决策集合)清空并经用户 确认后才进入 to-spec。该词与调度语义里的 ticket frontier 无关
  • seam confirmation 的责任在 to-spectdd,不在 grilling——后者只收敛设计决策,不涉及 测试 seam。to-spec 必须按其原始流程与用户确认 seam 并写入 spec 的 Testing Decisions tdd 不得在未经确认的 seam 上开始
  • to-spec 不重新进行已经完成的需求采访
  • to-tickets 产出可独立验证的 tracer-bullet tickets,并显式声明 Blocked by
  • 一次可以先生成多个 feature 的 spec/tickets,再按期望顺序逐个 enqueue
  • 本批次全部 enqueue 成功后、任何 claim 之前,必须把对应的 .scratch/<feature>/spec.md.scratch/<feature>/issues/*.md.scratch/queue.md 提交为一个 planning baselineto-specto-ticketsenqueue 本身不隐式提交
  • codebase-design 是 seam、deep module 与依赖分类的词汇来源,供 to-spectdd 查阅, 不作为独立会话运行

On-ramps 与 detours

  • 超过单个 session 可容纳的巨大、模糊工作先走 wayfinder;决策地图清晰后进入 to-spec -> to-tickets,不得从决策 ticket 直接跳到实现
  • research 产出的高可信一手来源报告先进入 grill-with-docs,作为设计输入;调研不能 替代 grilling
  • 已由 to-tickets 生成的 ticket 直接从 main_loop.py claim -> 本地 ticket 执行协议 开始, 不再 triage 或重复需求采访

Phase boundaries

只在阶段边界判断去向,阶段中途不做这个决定。按以下顺序取首个满足项:

  1. 下一阶段需要当前 session 作为 primary source,或剩余 smart zone 仍够下一阶段 (约 150k tokens)时,继续当前 session
  2. 当前上下文与下一阶段无关时,使用 clear
  3. 仅在跨 harness、跨目录/仓库、交给同事或 mid-phase 分出旁支任务时使用 handoff
  4. 任务可独立 AFK 完成时交给 subagent
  5. 其余同 harness、同目录且仍需当前上下文的情况使用 compact,并附上下一阶段要保留 什么的指令

上下文过长不等于必须 handoffhandoff 解决的是可移植性。compact 是决策树的默认落点, 但不是第一选择——除 continue 以外的每个选项都把 primary source 换成 secondary source。 CONTEXT.md 和 memory-bank 都不能替代阶段上下文。

本地 Ticket 执行协议

这是 Playbook 对 Matt 工程 skills 的调度适配层,只复用 tddcode-review。尾部顺序与 上游的 code-review -> commit 相反:主循环要求证据绑定到固定 commit,所以先提交再 review。

对每个 claim 严格按以下顺序执行:

  1. 读取已领取 ticket 的 spec、ticket、相关稳定知识和 ADR
  2. 在已确认 seam 上按 tdd 完成 ticket 的可观察行为,并运行局部验证
  3. 提交全部实现,使 ticket branch HEAD 成为固定、干净的审查点
  4. 运行 code-review,显式提供 fixed point 和 Review 适配契约规定的需求来源
  5. 修复硬 finding 后重新提交、验证和 review,直到两个 axis 均满足 pass 条件
  6. 调用 main_loop.py finish,提交与当前 HEAD/base 绑定的结构化证据

文档职责

  • memory-bank/project-brief.md:稳定项目定位、边界、目标和成功定义
  • memory-bank/tech-context.md:技术栈、工具链、环境差异和验证入口
  • memory-bank/system-patterns.md:当前模块边界、数据流、系统不变量和扩展路径
  • CONTEXT.md:稳定领域词汇和定义,不记录 feature 状态
  • docs/adr/:难以逆转且需要长期背景的真实技术取舍
  • .scratch/<feature>/spec.md:单个 feature 的问题、方案、用户故事和测试决策
  • .scratch/<feature>/issues/*.md:ticket DAG、验收标准和机器状态
  • .scratch/queue.mdfeature 开发与集成顺序
  • docs/agents/*.mdtracker、领域文档布局和 skill 配置

不得手工修改 ticket 的 Statusmain-loop:ticket-state 区块;只通过主循环变更。主循环 没有对应命令的状态组合按"卡死与恢复"处理,仍然不手工改。

稳定知识维护

只记录下一 session 仍需要的稳定知识;当前 feature、ticket、owner、heartbeat、验证和集成 状态只由 .scratch/main_loop.py 维护。

  • 项目定位、边界、目标或成功定义长期变化时,更新 project-brief.md
  • 技术栈、工具链、环境差异或验证入口长期变化时,更新 tech-context.md;写入 tech-context.md 的命令和环境事实必须已经验证
  • system-patterns.md 记录当前成立的架构;关键取舍及理由写入 docs/adr/
  • CONTEXT.md 只记录稳定领域词汇和定义;不把聊天流水、未验证猜测或短期进度写入 CONTEXT.md
  • 项目特有执行规则写入 AGENT_RULES.local.md
  • handoff 的产物写入 OS 临时目录,不写入稳定知识文件
  • 不为普通实现选择创建 ADR;没有长期价值的信息时不更新这些文件

调度语义

  • feature 按 .scratch/queue.md 顺序调度
  • 同一 feature 中 blocker 全部满足的 tickets 构成 ticket frontier,按稳定编号领取
  • 同一 feature 的多个 frontier tickets 可在 worktree 模式并发执行
  • 当前 feature 的 frontier 全被领取时返回 BUSY,不向后续 feature 扩张
  • 只有前序 feature 无 frontier、无活动 claim 且确实 blocked 时,才可开发后序 feature
  • 前序 feature 恢复后,新 claim 重新优先前序 feature
  • 后序已领取 ticket 可以完成,但 feature 集成到 main 必须严格遵循队列顺序
  • resolved 和显式 skipped 满足 blockerclaimedblockedready-for-agent 不满足
  • skipped ticket 的 feature 标记为 partial,集成时必须显式授权
  • stale 只由 heartbeat 时间派生,不自动转移 owner;只有 reclaim 可以接管

读取输出而不是只看返回码

BUSYNOOP: ...RETRY: ... 都写到 stdout 并且返回码为 0;只有真正的错误才是 ERROR: <msg> 到 stderr、返回码 2。调用方必须解析 stdout,不能用返回码判断是否拿到 ticket。

status 输出 FEATURE=STATE=PARTIAL=FRONTIER=CLAIM=OWNER=HEARTBEAT=STALE=ISOLATION=WORKSPACE=TICKET_ERROR=BLOCKED=FEATURE_BLOCKED=MAIN_INTEGRATION_COMMIT=;队列为空时输出 NO FEATURES

STATE=active 不代表可推进:tickets 只剩 resolvedblocked 的 feature 同样报 STATE=active FRONTIER=-,此时 claim 返回 NOOP。判断是否卡住要同时看 FRONTIER=- 和 是否存在 BLOCKED= 行。

心跳的实际作用

heartbeat 没有强制力:过期 claim 仍保有全部权限,原 owner 可以继续 heartbeat、finish 和 resolve。stale 的唯一后果是别人获得 reclaim 的资格。所以"每 10 分钟一次"是为了让接管 判断准确,不是为了保住 claim。

卡死与恢复

  • claim 的环境准备失败时,主循环把该 ticket 写成 blocked、记录原因、把 claimed_by 设为 本次 owner,并以返回码 2 退出。一次失败的 claim 会占住这张 ticket
  • finish --result released 只允许原 claimed_by 解除 blocked;原 session 已丢失时用 release-ticket
  • reclaim 只接管 claimed 状态的 stale claim,不能用于 blocked ticket
  • resume 与 reclaim 返回的 BASE 是 claim 当时记录的值,不会刷新feature head 已推进 时直接拿它去 finish 会得到 RETRY: feature advanced,按重试流程取新的 FEATURE_HEAD

执行隔离

claim --isolationin-place 串行执行不建额外 worktreeworktree 每个 ticket 独立 branch/worktree,适用于多 session 并发;auto 无其他活动 claim 时用 in-place,否则用 worktree。计划并发时第一个 session 就必须指定 worktree

BUSY 的作用域是整个队列,不限于同一 feature,来源有三个:请求 in-place 而队列里存在 任何活动 claim;队列里存在任何 in-place 活动 claim(此时所有 isolation 的新 claim 都 BUSY);队首可调度 feature 的 frontier 已被领完。stale claim 也算活动 claim,必须显式 reclaimrelease-ticket 才能腾出位置。同一 owner 恢复自己的 ticket 不受这些检查影响。

in-place 要求 checkout 无非 .scratch 改动、HEAD 非 detached、目标 branch 未被其他 worktree 占用。主循环不得自动 stash、reset、覆盖或丢弃改动。唯一例外:重新 claim 自己此前以 in-place 释放的同一 ticket 且 workspace/branch 都匹配时,跳过 dirty 检查以保留未提交改动。

worktree 模式下若 feature/<slug> 正被 control checkout 占用,主循环会先确认它干净、再把 control checkout 切到主干以释放该 branch。

main_loop.py 只支持 local Markdown tracker,要求所有 sessions 共享同一文件系统、control checkout 和 Git common directory。远程 tracker 可以由 Matt skills 单独使用,但本主循环没有 远程 tracker adapter,不能接入远程 claim/finish 状态;跨机器或独立 clone 的并发不受支持。

主循环命令

主干 branch 名不是 main 时,claimintegrate 必须显式传 --main-branch <name>;其余 子命令不接触主干,也不需要 --repo-root

入队和状态

python {{PLAYBOOK_SCRIPTS}}/main_loop.py enqueue \
  --state-root .scratch --feature <feature-slug>

python {{PLAYBOOK_SCRIPTS}}/main_loop.py status \
  --state-root .scratch

enqueue 对已入队 feature 幂等,返回 EXISTS=<slug>

领取

<owner> 必须全局唯一且在本 session 内稳定,例如 <agent>-<UTC timestamp>-<random>。 不得在并行 session 间复用 codexclaude 等通用名称;同一 owner 重复 claim 只用于原 session 恢复自己的 ticket,其他 owner 不得接管,失联时用显式 reclaim。

python {{PLAYBOOK_SCRIPTS}}/main_loop.py claim \
  --state-root .scratch --repo-root . \
  --owner "<owner>" --isolation in-place|worktree|auto \
  [--main-branch main]

stdout 返回 8 个赋值行:FEATURETICKETCONTROL_ROOT 是共享 Git control checkout 绝对 STATE_ROOT 是唯一状态目录,不必位于 WORKSPACE 内;WORKSPACE 是当前 ticket 的代码 工作区;其余为 BRANCHBASEISOLATION。也可能返回 NO FEATURESNOOP: no claimable ticketsBUSY,或 INTEGRATION_REQUIRED=<slug>(队首 feature 已 ready-to-integrate,必须先 integrate)。

领取成功后立即读取 <STATE_ROOT>/<FEATURE>/spec.md<STATE_ROOT>/<FEATURE>/issues/<TICKET>-*.md;不得在 claim 前根据 frontier 猜测将领取哪个 ticket。后续 review 也必须用这两个已领取上下文,而不是 worktree 内相对 .scratch 的偶然 副本。

实现、提交和 review 在返回的 WORKSPACE/BRANCH 中完成;其余子命令一律用 --state-root "<STATE_ROOT>",不得在 ticket worktree 中使用相对 .scratch。feature 集成 workspace 的路径不在 claim 输出里,只写在 <STATE_ROOT>/<FEATURE>/.main-loop.jsonintegration_workspace;纯 in-place 流程不创建该文件,feature 级操作在 CONTROL_ROOT 上做。

心跳和接管

claim 的 stale 租约固定为 30 分钟,调用者不得缩短。claim 存续期间至少每 10 分钟发送一次 heartbeat,并在耗时较长的验证、构建或 review 前后各发送一次。无法继续维持时,根据是否需要 保留阻塞原因分别执行下文完整的 --result released--result blocked --reason 命令。

python {{PLAYBOOK_SCRIPTS}}/main_loop.py heartbeat \
  --state-root "<STATE_ROOT>" \
  --feature <feature> --ticket <NN> --owner "<owner>"

python {{PLAYBOOK_SCRIPTS}}/main_loop.py reclaim \
  --state-root "<STATE_ROOT>" --repo-root "<CONTROL_ROOT>" \
  --feature <feature> --ticket <NN> --owner "<new-owner>"

reclaim 只接管 stale 的 claimed ticket,要求新 owner 与原 owner 不同,保留原 branch、 worktree 和未提交改动。被接管后原 owner 的 heartbeat 与 finish 立即报 owned by another session

Review 适配契约

code-review 只产出 Standards 与 Spec 两段 findings,不给 pass/fail 判定,也不合并或 重排 findings。下面的 pass 映射是 Playbook 加的一层,由调用方把 findings 归结为判定。

调用时不得依赖其自动搜索或交互补问,必须显式提供:

  • fixed pointticket review 用 claim 的 BASE 或重试返回的 FEATURE_HEADfeature review 用最新 main HEAD
  • Spec sourcesticket review 用 .scratch/<feature>/spec.md.scratch/<feature>/issues/<ticket>-*.mdfeature review 用该 spec 加本 feature 全部 ticket 的 acceptance criteria。两者都从绝对 STATE_ROOT 解析

只有对应 axis 零个未解决的硬 finding 时才能记录 passstandards=pass 指没有未解决的 仓库标准违规(baseline smell 属 judgement call,须逐项记录已修复或带理由接受,不因被提出 就自动失败);spec=pass 指没有遗漏、部分实现、错误实现或未授权范围扩张。

任一来源缺失、Spec axis 被跳过、review 尚在询问输入,或仍有未解决的硬 finding 时, 不得据此填写 standards=passspec=pass。修复会改变 HEAD,必须重跑受影响验证和完整双轴 review,不能沿用旧报告。

Ticket 完成或状态转换

resolved 前必须先提交实现,再按 Review 适配契约对 BASE...HEAD 运行 Matt code-review 的 Standards/Spec 双轴审查。验证证据必须包含被验证 commit,review 证据必须 包含被审查 commit 和固定 base;任意非空文本或裸 pass 不能替代结构化证据。

python {{PLAYBOOK_SCRIPTS}}/main_loop.py finish \
  --state-root "<STATE_ROOT>" --repo-root "<CONTROL_ROOT>" \
  --feature <feature> --ticket <NN> --owner "<owner>" \
  --result resolved \
  --implementation-commit <HEAD> \
  --feature-head <已验证feature HEAD> --review-base <同一feature HEAD> \
  --verified "<ticket-verification.json>" \
  --reviewed "<ticket-review.json>"

验证和 review 参数必须是下文定义的 UTF-8 JSON artifact 路径,不接受内联 pass 文本。

首次 review base 是 claim 返回的 BASE。feature HEAD 已推进时返回 RETRY: feature advanced 和新的 FEATURE_HEAD;把该 FEATURE_HEAD 合入 ticket branch, 重新运行受影响验证,并以它作为新的 review base 重跑双轴 review。重试时 --feature-head--review-base 和 review evidence 的 base 都用该新值,验证与 review evidence 的 commit 必须等于新的 ticket HEAD。只有成功集成到 feature branch 后 ticket 才变为 resolved

finish 不检查验收勾选框;验收由 code-review 的 Spec axis 负责,勾选框在 resolve 前 自行更新。

其他 finish 转换共用上面的 --state-root--repo-root--feature--ticket--owner

python {{PLAYBOOK_SCRIPTS}}/main_loop.py finish \
  --state-root "<STATE_ROOT>" --repo-root "<CONTROL_ROOT>" \
  --feature <feature> --ticket <NN> --owner "<owner>" \
  --result blocked --reason "<明确原因>"

python {{PLAYBOOK_SCRIPTS}}/main_loop.py finish \
  --state-root "<STATE_ROOT>" --repo-root "<CONTROL_ROOT>" \
  --feature <feature> --ticket <NN> --owner "<owner>" \
  --result released

python {{PLAYBOOK_SCRIPTS}}/main_loop.py release-ticket \
  --state-root "<STATE_ROOT>" --feature <feature> --ticket <NN> \
  --reason "<原 session 无法恢复的原因>"

blockedskipped 都必须提供 --reasonreleased 回到 ready-for-agent 并保留 workspace 只能由原 claimed_by 调用。release-ticket 用于原 session 已丢失、无人能 release 的 blocked ticket;它不校验 owner,保留 branch、worktree 和未提交改动,返回 TICKET_RELEASED=<feature>/<NN>

Feature 顺序集成

feature 必须吸收最新 main,完成 feature 验证、main 候选验证和最终双轴 review:

python {{PLAYBOOK_SCRIPTS}}/main_loop.py integrate \
  --state-root "<STATE_ROOT>" --repo-root "<CONTROL_ROOT>" \
  --feature <feature> --feature-head <已验证feature HEAD> \
  --verified "<feature-verification.json>" \
  --main-verified "<main-candidate-verification.json>" \
  --reviewed "<feature-review.json>"

partial feature 还需 --allow-partial;未显式授权时报错而不是静默集成。

RETRY: feature needs main sync 表示 main 不是 feature head 的祖先。此时在 feature integration workspace(纯 in-place 流程下是 CONTROL_ROOT)合并最新 main,重新验证和 review 后再调用。main 合并冲突时主循环会自动把 feature 标记为 blocked,不需要手工 block-feature;解决冲突后 release-feature 再重试。

成功后主循环会把 control checkout 切到主干,并移除干净的 ticket worktree 与 _integration worktree;不干净或路径异常的保留并以 WARNING= 行报告。已集成的 feature 再次调用时幂等返回 INTEGRATED=

integrate 成功后必须在主干提交本 feature 的最终 workflow state。只暂存 .scratch/<feature>/ 下的持久变更,以及确由本次集成改写时的 .scratch/queue.md;不得用 git add .scratch 把其他活动 feature 的并发状态带入。该状态提交必须位于 feature merge commit 之后,不得 amend 或 squash 进 merge commit.scratch/<feature>/.main-loop.json 中记录的 integration_commit 必须继续指向主循环返回的 MAIN_INTEGRATION_COMMIT

ready-to-integrate feature 因人工决策暂时不能集成时必须显式记录,否则主循环不会为后序 feature 继续分配开发工作:

python {{PLAYBOOK_SCRIPTS}}/main_loop.py block-feature \
  --state-root "<STATE_ROOT>" --feature <feature> --reason "<明确原因>"

python {{PLAYBOOK_SCRIPTS}}/main_loop.py release-feature \
  --state-root "<STATE_ROOT>" --feature <feature>

release 后该 feature 重新成为队首 INTEGRATION_REQUIRED;后序 feature 即使已开发完成, 仍不得越过它集成到 main。

Git 与证据门禁

branch 命名:ticket 用 ticket/<feature>/<NN>-<slug>feature 用 feature/<feature>。 执行顺序见"本地 Ticket 执行协议",证据参数见"主循环命令"。

局部 ticket 验证、feature 验证和 main 候选验证是三个独立门禁,不能互相替代。

--verified--main-verified--reviewed 必须指向 UTF-8 JSON artifact。验证 artifact 包含 version=1kind=verificationcommitresult=passcommandexit_code=0outputoutput_sha256review artifact 包含 version=1kind=reviewcommitbasestandards=passspec=passreportreport_sha256。输出和报告必须先移除 secret;摘要是 对应 UTF-8 文本的 SHA-256。

门禁校验每个 commit 真实存在、artifact schema 与摘要、implementation/verification/review commit 与目标 branch tip 一致、review base 正确、workspace 干净且在自己的 branch 上。成功后 把规范化 artifact 快照到 .scratch/<feature>/evidence/,并在 ticket 或 feature 状态中记录快照 路径和 SHA-256;原始 artifact 删除后仍可审计。

artifact 能阻止空文本、字段缺失、摘要篡改和 Git 上下文错配,但无法证明命令真的执行过,也 无法证明 report 来自真实 review。证据必须来自实际 fresh run,无法运行时不得伪造 pass; 需要机器强制时由 CI 或 pre-commit hook 生成 artifact。

辅助能力

以下能力在对应阶段内按需使用,不替代上面的入口路由和证据门禁:

Skill 触发条件
codebase-recon 架构、跨模块、重构、迁移或风险不明
brooks-audit 架构边界和长期维护性审查
codebase-design 需要 seam、deep module、依赖分类的词汇与判据
improve-codebase-architecture 修复落地后暴露出的结构问题
resolving-merge-conflicts feature 吸收 main 或集成时出现冲突
to-questionnaire 需要把待决问题整理成清单交回用户
commit-message 需要检查 staged diff 或生成提交信息

需要确认的场景

设计阶段由 grilling 收敛所有决策。执行 ticket 时仅在以下情况暂停确认:

  • ticket/spec 仍存在会改变实现的真实歧义
  • 需要 spec 未授权的行为、兼容性或架构取舍
  • 需要破坏性操作、覆盖他人改动或扩大任务范围

入口 1、入口 2 范围内的改动和已批准 ticket 范围内的实现不重复需求采访。无交互模式按 "非交互模式下的入口 4"处理,不得替用户作设计决策。

Session 收尾

  • 运行与声明相匹配的 fresh verification
  • 列出已完成、未完成、验证证据、风险和下一步
  • 只提交当前 ticket/feature 相关改动,不混入其他 session 差异
  • 工作未结束时按 Phase boundaries 决策树选择去向

最后更新{{DATE}}