SuperAPI AI 工具集

worktree-discipline

部署与运维

查看项目

更新于 10-17 16:20

技能介绍

Worktree Discipline 是一项围绕 git worktree 的强制性隔离规范,用于 guardrails 项目中所有改动。其基本前提是:无论写 SRS 章节还是写代码都属于改动,任何改动都不能发生在 worktree 之外。基线分支是主非 worktree 检出所检出的分支,只能通过带签名的 squash 合并(merge-change)移动。一次改动对应一个改动工作树和一个改动分支(从基线分支分出),这也是 merge-change 唯一能看到的工作树。

用途与适用场景

该技能适用于需要对 guardrails 项目做任何变更的流程:创建需求、风险、设计或问题条目,编写计划,实现任务,进行独立评审和验证。它还适用于一个改动被拆分为多个并行任务、交由子代理分头处理的场景。

主要能力与规则

  • 隔离判定:若 git rev-parse --git-dir 与 --git-common-dir 不同(且不在子模块中),即说明当前处于 worktree 中;除任务工作树这一例外情况外,不得再嵌套 worktree。
  • 任务工作树例外:从改动工作树派发的子代理,会按派发目的决定工作树安排。实现计划任务的子代理会在改动分支上创建自己的任务工作树,并使用任务分支,在其中提交后停止,不合并;由调度方在任务通过后,从改动工作树将任务分支合并进改动分支。评审改动时,子代理同样创建自己的任务工作树,但无需合并回去。运行验证门禁时,子代理不使用自己的工作树,而在改动工作树中运行,因为 verify-before-merge 的干净 git status 检查读取的是该工作树的未提交状态。子代理不能自行合并任务分支:git 会拒绝对另一工作树已检出分支的更新,也不应尝试对改动分支执行 git merge、checkout、push . 或 fetch .,而应提交、报告并停止。
  • 并行约束:仅在任务的文件触集互不相交时才并行展开,使任务分支合并不冲突;不得让并行子代理共享同一个工作树。
  • 位置规则:任务工作树放在改动工作树内部的 .worktrees/<change-branch>-t<N>;其中 <N> 为计划任务编号,无任务编号的派发用标签代替 t<N>(如独立评审用 .worktrees/<change-branch>-review)。调度方在派发提示中指明该路径,子代理在派发报告的 worktree: 行回填。
  • .worktrees/ 忽略项是调度方的前置条件:改动工作树内未跟踪目录会导致 verify-before-merge 的干净 git status 检查失败,须在派发前于改动工作树中确认该条目,缺失则添加并提交;该提交不由子代理完成。
  • 启动任务工作树:在改动工作树中运行 sh .guardrails/scripts/task-worktree.sh start t<N> 创建 .worktrees/<change-branch>-t<N>;随后优先用 harness 的 worktree 工具进入;若无,则原地通过路径驱动,使用 git -C .worktrees/<change-branch>-t<N> ... 及绝对路径编辑。编辑前须以 git -C <path> status 确认工作树可用。若 worktree 工具被给到 pin 之外的路径,会报告成功却拒绝所有 shell 调用,需重新进入改动工作树自身路径。
  • 新建任务工作树只含跟踪文件;start 会把改动工作树中被忽略的条目(如 vendored 测试运行器、已安装依赖、构建缓存)复制进来;若 verify_commands 仍找不到产物,可与改动工作树中的 git status --ignored 比对。
  • 开始前检查:创建改动工作树前运行 references/before-opening.md 中的两项检查:(a) 每个已注册 worktree 的状态行,包含分支、相对基线分支领先的提交数、脏文件数、最后提交日期;(b) 对本次改动将解决或修订的每个条目 ID,检查未合并本地分支相对基线分支的 diff 是否新增或删除含该 ID 的行;有命中即表示另一改动已认领该条目,应停止并询问用户。
  • 创建改动工作树:优先使用 harness 的 worktree 工具(如 EnterWorktree、/worktree 命令);回退方式为 git worktree add .worktrees/<branch-name> -b <branch-name> 后 cd 进入。创建前确保 .worktrees/ 已被 gitignore(否则添加并提交)。分支名使用简短 kebab-case,描述改动内容(如 add-dose-limits、rmf-overdose-hazards)。
  • 基线:立即运行项目 verify_commands(.guardrails/config.yaml);若基线失败,报告并取得明确决定后再继续。
  • 生成 ID:新需求、风险、设计或问题条目在写入时即获取真实 ID,使用 .guardrails/scripts/new-id.sh REQ 或 .guardrails/scripts/new-id.sh HAZ 3;不得手工编造,check-ids.sh 会将手写 token 报告为 MALFORMED-ID。生成的 ID 可在代码、测试(verifies:)和计划中自由引用,自首次键入即最终确定。
  • 台账文件:在 ledger-layout 项目中,新条目写入本次改动自己的文件 docs/<area>/<YYYY-MM-DD>-<slug>.md,日期为创建日;不得重命名;对既有条目的修订编辑在定义它的带日期文件中进行,不得在文件间移动定义。
  • 提交:worktree 提交可不签名(git -c commit.gpgsign=false commit),它们会被 squash 掉,只有基线分支上的合并提交必须签名;不得从 worktree 检出或提交到基线分支。
  • 清理:派发结束时调度方移除每个任务工作树。任务子代理在任务分支上提交后保留;派发报告通过后,调度方在改动工作树中运行 sh .guardrails/scripts/task-worktree.sh merge t<N> 合并任务分支,并移除工作树、删除任务分支。评审工作树无内容可合并:task-worktree.sh remove review 移除工作树及其任务分支,并拒绝带提交的分支;应把每个此类提交记为发现,再运行 task-worktree.sh discard review 移除工作树并连同分支删除。仅在任务报告通过后运行 merge。验证派发无内容可移除,因为它在改动工作树中运行。
  • 产物即记忆:对话只覆盖一次改动,状态须写入产物:计划(docs/plans/<date>-<slug>.md,含任务、每个任务触及的文件、完成情况,以及每个完成任务旁的 red -> green: 证明,随报告到达写入);台账(需求、风险、设计、问题条目及其生成 ID 与 satisfies:/implements:/verifies: 引用);验证记录(merge-change,含评审、处置、red -> green、差距;squash 的 trailer 记录运行了什么及其报告)。
  • 改动工作树留给 merge-change:在经核验的签名 squash 合并之后才移除,绝不提前,也绝不在存在未合并工作时未经用户明确同意就移除。

注意事项

资料列出多种常见误区:认为文档微调无需 worktree(文档是受管制产物,需要 worktree);手工挑选 ID(可能与其他 worktree 冲突,应用 new-id.sh);直接在基线分支上快速修复(基线分支只能通过签名 squash 合并移动);让子代理共享工作树(会在 index.lock 和 red→green 证据上冲突);子代理自行合并任务分支(git 会拒绝,且从任务工作树 git merge 方向错误并仍以 0 退出,应由调度方在改动工作树中合并);依赖记忆而非写入计划;在新工作树中运行门禁(干净只因是新工作树,证明不了什么,门禁应在改动工作树中运行);按项目习惯放置任务工作树(应嵌套在改动工作树内);以 git worktree add 成功判断位置可用(两个位置都能创建成功,证明不了能否写入、提交或测试);以文件写入成功判断位置可用(pin 之外的普通 shell 重定向不被阻止,应以 git -C <path> status 证明);以 worktree 工具报告进入判断已在其中(pin 之外会报告成功却拒绝 shell 调用,需重新进入改动工作树路径)。

完成条件

改动在改动工作树及其改动分支中,每个派发任务在其调度方指定的任务工作树路径中并经 git -C <path> status 确认;基线已运行,失败基线有明确决定;每个新条目都有来自 new-id.sh 的 ID,在 ledger-layout 项目中位于本次改动自己的文件;每个任务工作树都已合并或丢弃并随分支移除;计划、台账与验证记录包含该改动的状态。

参考资料

references/rationale.md:当某条规则在你的场景下看似不合理,或准备修改规则前阅读。references/before-opening.md:到达第 2 步、创建改动工作树前阅读。references/harness-pin-test.md:需要判断 harness 是否将派发子代理 pin 到子树时阅读。