Load order(必读顺序)
首次 Read 本 skill 前:必须先 Read mstar-harness-core(SKILL.md)。 冲突时 以 mstar-harness-core 为准。
Spec 多 plan 命名(iteration_base_branch、spec_integration_branch、target_branch PR 门禁)→ mstar-conventions。L1/L2 worktree 分层(迭代 integration worktree vs feature、plan 内并行轨)→ 下文 「Worktree isolation layers」;L2 同仓并行可写派发前清单 → references/parallel-writable-pre-dispatch.md;迭代 lease claim/merge 细则 → mstar-iteration references/phase-2-worktree-lease.md(勿在本 skill 重复完整协议表)。merge 后 worktree/分支回收(cleanup)守卫契约 → 下文 「Worktree / branch cleanup」。下文为分支、三写域、QC/QA 检出对齐与 merge 后 cleanup 主文。
Scope(摘要)
- 仅 PM 决定分支;其他可写角色不得自行新开分支或切回
main。 - Assignment 须含其一:
Working branch: <existing>|create <new> from <base>|Branch policy: direct on <branch> — <reason>。 - L1(跨 plan / 迭代 Phase 2):control root(= 主 checkout / main worktree,进程 SSOT,Git 派生)+ integration worktree(snapshot
integration_worktree_path,检出spec_integration_branch,唯一 merge cwd)+ 每 plan 独立 feature worktree(execution_lease.worktree_path)+ lease;见 「Worktree isolation layers」。 - L2(同 plan 内 ≥2 可写并发):派发 前 完成
references/parallel-writable-pre-dispatch.md(含git worktree、绝对Worktree path;N 次并行 invoke ≠ 已隔离)。单 plan 多轨时 L1 不替代 L2。 - QC/QA 前:待审提交归并到 单一
Working branchHEAD;三审 + QA 共用一套Review cwd+plan_id+Review range/Diff basis(逐字相同)。
Git 功能分支、同仓并发与 Worktree 对齐
Git 功能分支门禁(业务仓库)
适用于 cwd 为 Git 托管的业务/应用仓库 且本轮会产生仓库内可合并 diff 的任务(代码、业务向测试与 fixture、影响构建或运行时的配置等)。不用于约束 ~/.config/opencode/ 全局配置目录(该目录对 agent 只读;落盘仅由用户执行)。
默认规则
- 不得在默认保护分支(常见名:
main、master;以项目约定为准)上直接实现功能改动,除非 Assignment 含显式例外。 - 例外须在 Assignment 中写明一行:
Branch policy: direct on <branch> — <reason>(典型:团队约定的热修直接打默认分支)。
<base> 与叠分支(stacked branches)
- 门禁的目标是不在未授权的默认分支上直接提交,不是「只能从
main开新分支」。 - 当需要从已有功能分支继续拆新分支时,Assignment 应写清祖先分支
<base>,例如:create feature/foo-part2 from feature/foo。 <base>可取:main/master(或项目默认分支名)、任意已存在的feature/*/fix/*、远程跟踪分支名、或current(表示以执行者检出时的HEAD为祖先,用于「就在当前分支上再拉一枝」)。- 若只写
Working branch:feature/foo且无「create … from …」:表示沿用 / 切到该已存在分支上开发,不要求新建。 - 若写新建但未写
<base>:实现侧应停下问project-manager(或按项目AGENTS.md的默认 base);禁止擅自假设「一定是main」。
角色职责
project-manager(唯一分支决策入口):向product-manager(向项目仓库提交产品文档时)、architect(向项目仓库提交技术/架构/契约类文档时)、fullstack-dev/frontend-dev/fullstack-dev-2、以及会向仓库提交工件的qa-engineer、会改仓库内文件的ops-engineer、对项目仓库落盘的prompt-engineer分派前,核对分支策略;在 Assignment 中写明Working branch(沿用已有分支名,或create <new-branch> from <base>,其中<base>遵守上一节)。若用户已指定分支/祖先,照抄进 Assignment。只有project-manager可以决定是否新开分支、从哪个<base>开分支。- 实现 / QA / 运维 / prompt / product-manager / architect(项目侧):在首次编辑仓库内文件或执行
git commit前,核对当前分支与 Assignment,并在回报中明确"正在哪个分支上工作"。**禁止自行决定新开分支、禁止自行切回main/master重开分支。**若未授权Branch policy且当前在默认分支,则仅可按 PM 已写明的Working branch执行切换/开枝;若 Assignment 未写清或与现场分支不一致,先回报project-manager,不得擅自处理。
分支协作契约(Branch Collaboration Contract)
适用范围
- 当任务会在项目 Git 仓库产生可合并 diff 时适用。
- 适用于
project-manager、product-manager、architect、fullstack-dev、frontend-dev、fullstack-dev-2、qa-engineer、ops-engineer、prompt-engineer(项目侧写入)。
唯一分支决策者
- 只有
project-manager可以决定分支策略:- 继续在现有分支开发,或
- 使用
create <new-branch> from <base>新开分支,或 - 使用
Branch policy: direct on <branch> — <reason>。
- 其他可写角色不得自行决定开分支。
PM 必须先与用户确认
在派发实现任务前,PM 必须先检查当前分支;若已在非默认开发分支(如 feature/*、fix/*),必须先与用户确认。
未获得用户明确确认前,PM 不得切回 main/master 并新开分支。
PM 确认话术模板
面向用户沟通时,使用以下结构:
当前检测到在分支:`<current-branch>`。
请确认本次任务是:
1) 继续在 `<<current-branch>>` 上开发
2) 新开分支:`<new-branch>`,基于 `<base-branch>`
未确认前,我不会切回 `main`/`master` 或新开分支。
Assignment 要求(PM)
每个可写 Assignment 必须且只能包含以下之一:
Working branch: <existing-branch>Working branch: create <new-branch> from <base>Branch policy: direct on <branch> — <reason>
若是新开分支但缺少 <base>,必须暂停并向用户澄清,不能猜测。
可写角色执行规则
在首次写仓库或 commit 之前:
- 校验当前分支与 Assignment 是否一致。
- 只能执行 PM 在 Assignment 中定义的分支策略。
- 禁止自行切回
main/master再重开分支流程。 - 若 Assignment 含糊或与本地分支状态冲突,先停下并回报 PM。
回报要求
可写角色在 Completion Report 中必须明确当前工作分支,例如:
Working branch used: <branch-name>
Worktree isolation layers (L1 vs L2)
Two complementary worktree isolation layers coexist. Do not conflate them with SDD review layers (L1–L4 in mstar-review-qc/references/review-responsibility-boundaries.md).
| Layer | Scope | When | Mechanism |
|---|---|---|---|
| L1 | Cross-plan (iteration Phase 2) | Multiple plans may implement concurrently in one iteration | Main-worktree control root (process SSOT) + integration worktree (integration_worktree_path) + per-plan feature worktrees + plans[].execution_lease (workflow snapshot workflows/<id>/snapshot.json) |
| L2 | Within-plan | Same plan_id, same business repo, ≥2 concurrent writable implement tracks |
references/parallel-writable-pre-dispatch.md — distinct absolute Worktree path per track |
Stacking rules
- Default L1 capacity is one writable track per plan. If one plan runs ≥2 concurrent writable tracks, each track also satisfies L2; L1 does not replace L2.
- L1 applies under iteration commands with Phase 2 worktree/lease defaults (unless explicit
Worktree mode: waivedthis turn). Single-plan waves without iteration leases still require L2 when ≥2 parallel writable tracks share one repo. - Cross-plan integration merge into
spec_integration_branchremains serial (snapshot top-levelintegration_merge_lease) even when L1 feature implementation runs in parallel.
Main-worktree control root, integration worktree, feature worktree (iteration / L1)
The integration worktree is established at iteration Phase 2 entry (Phase 1 Review & Edit may edit uncommitted docs on the primary checkout under the Prepare policy — the bounded exception; the main worktree never switches branch). Normative field names and claim/release/merge protocol → mstar-iteration references/phase-2-worktree-lease.md and maintenance ADR 2026-07-22-iteration-worktree-plan-lease.md. Do not invent alternate lease field names in this skill.
| Checkout | Checked-out branch | Path recorded | Writable role |
|---|---|---|---|
| Control root = the primary checkout (main worktree) | the recorded Main worktree branch from the main plan header (never a lifecycle-owned branch; never switched) |
not in the snapshot — derived from Git (readMainWorktree); the branch is recorded once as Main worktree branch: <branch> in the main plan |
Forbidden for product edits — process-SSOT holder + Git-control cwd only |
| Integration worktree | Resolved spec_integration_branch (same across active plans) |
integration_worktree_path (snapshot top-level) — canonical repository root (not {HARNESS_DIR}) |
Sole merge cwd for serial integration merges (integration_merge_lease) + tracked-result close commits (Phase 3 compound); no product-source edits — Phase-5 fixes use a feature worktree |
| Feature worktree (per plan) | Plan Working branch / feature branch from integration |
plans[].execution_lease.worktree_path (snapshot plan row) |
Required cwd for that plan's product/source edits |
Harness path SSOT under default gitignore (L1) — the three-domain table
Default process artifacts are gitignored (mstar-conventions「Git 跟踪策略」); git worktree add does not copy them into a new checkout. A worktree's .mstar/ is not categorically non-writable — writability is decided per domain. This is the sole three-domain table in the skill corpus; other skills point here instead of restating it.
| Domain | Contents | Home | Writable from a worktree? |
|---|---|---|---|
| Process SSOT (gitignored) | status.json, workflows/, projects/, plans/, sdd/, iterations/, archived/ |
control root = the primary checkout (main worktree) | No. Always addressed via absolute control-root paths; a second process-SSOT copy must never be bootstrapped under any worktree. |
| Tracked results (Git-following) | {KNOWLEDGE_DIR}, {SPECS_DIR}, {HARNESS_DIR}/AGENTS.md, CONCEPTS.md |
whichever checkout holds the target branch | Yes. Readable from any worktree; written where the target branch is checked out (iteration Phase 3 compound → the integration worktree), then committed on that branch. |
| Product source | repository code | feature worktree on Working branch |
feature worktree only. |
Control harness root = <main-repo-root>/{HARNESS_DIR}/ — resolved from Git (the main worktree), never from a snapshot field.
Hard rules
- Snapshot
integration_worktree_pathMUST differ from the main worktree (control root) and fromexecution_lease.worktree_path— never merge from the main checkout, never product-edit the integration checkout. - Main-worktree residency: the main worktree's attached branch must equal the recorded
Main worktree branchfrom the plan header (recorded before the lifecycle writes; never invented from the current branch at check time) and must not be owned by any non-terminal workflow (integration, plan or track). Never create a branch or switch main to make a residency check pass;branch.baseis a creation/merge anchor, never a residency fact. - A feature worktree's same-looking
{HARNESS_DIR}path is not the SSOT — never treat it as the source of plans/status/SDD, and never bootstrap a second process-SSOT copy there. - Absolute
Worktree path(feature) MUST appear in the writable Assignment and inexecution_lease.worktree_pathbefore first writable implement dispatch for that plan. - When L1 lease gate is active (not
Worktree mode: waived), AssignmentPlan PathandSDD dirMUST be absolute paths under the control harness root (not relative.mstar/...resolved from the feature cwd). Prefer also writingControl harness root: <main-repo-root>/{HARNESS_DIR}. - Writable dispatch for a plan requires a verified
execution_lease(same read-check-replace-verify discipline as the iteration reference). Full claim tables are not duplicated here. Scoped route: the plan session is established bymstar plan bind(claim executed inside its own lock) and scope is read from the returned row — hand-written snapshot updates are not a path (mstar-iterationreferences/plan-scoped-pm.md§2/§8).
Anti-pattern (forbidden)
- Inferring
Worktree mode: waivedbecause “feature worktree has no plans” under default gitignore. Correct response: keep feature worktrees; route harness I/O through control absolute paths. Missing same-host write lock →Plan parallelism: serialonly — that is a separate gate and does not waive worktree/lease.
Naming conventions (PM / ops; examples only — paths MUST be canonical absolute)
- Control root — always the primary checkout (main worktree), derived from Git (
readMainWorktree); never a PM-designated alternative checkout, never recorded in the snapshot. Its attached branch is recorded once asMain worktree branch: <branch>in the main plan header before the lifecycle writes, and PM passes it unchanged in writable Assignments.branch.baseis the creation/merge anchor — not a residency fact. - Integration worktree — one dedicated linked checkout on
spec_integration_branch, distinct from the main worktree, recorded once in snapshotintegration_worktree_path; sole merge cwd for the iteration. - Feature worktree (per plan) — one distinct subdirectory under the workspace root
.worktrees/per activeplan_id(e.g..worktrees/<plan-id>-<slug>; AGENTS.md「Local scratch layout」), gitignored by the repo convention; AssignmentWorktree pathmust match leaseworktree_path. - L2 track worktrees (within-plan) — additional distinct directories per parallel implement track under the same plan (see
references/parallel-writable-pre-dispatch.md), each with its own PM-approvedWorking branch.
Engine check (when available): run
mstar worktree check <plan-id> --workflow <id>(L1) /mstar worktree check --l2 --tracks <json>(L2) (orimport { l1PreDispatchCheck, l2PreDispatchCheck, readMainWorktree, assertMainWorktreeResidency, assertControlVsFeaturePath, assertBranchAlignment } from "@mstar-harness/engine"in a host hook) to verify the L1/L2 isolation rules above (main residency vs recordedMain worktree branch; main/integration/feature pairwise checkout distinctness — lease worktree ≠ main control root ≠ integration; checked-out branch matchesWorking branch). Onfail-> do not proceed; fix and re-run. Skill text below remains authoritative when the runtime is absent.
同仓并发写入与 Git worktree(强制)
首要场景是开发阶段(L2;迭代多 plan 时另见上文 L1):多条可写流 并发 改 同一仓库 时,用 worktree 做 写入侧目录隔离。派发前清单 → references/parallel-writable-pre-dispatch.md。下列规则针对该类开发并发;QC / QA 阶段的检出约定见下一小节。
当 project-manager 在同一调度轮次内并发启动多个 subagent(含宿主侧「并行 Task / 并行 subagent」),且 ≥2 个承接方可能对 **同一 Git 仓库的同一工作区(同一 cwd 检出目录)**产生写文件或 git commit 级改动时:
- 必须为每条并发写流使用 独立检出目录:优先使用宿主原生 worktree/checkout 隔离能力;没有原生能力时使用
git worktree,并按本 skill 的目录、分支和 QC/QA 对齐规则执行。 - 必须与既有分支门禁一致:每个可写承接方的 Assignment 仍须含 PM 已批准的
Working branch/Branch policy;在某一 worktree 内 不得擅自checkout到未授权分支或私自新建分支。 - PM 须在 Assignment 中写清各并发写流的 检出约定(例如预期
Worktree path/ 命名规则,或「由承接方创建/使用隔离 worktree 并在 Completion Report 回报路径」),避免多代理默认共享同一目录导致互相覆盖、冲突或半写入状态。 - 同仓、同一 plan、≥2 可写并行轨:派发各轨实现 Assignment 之前 确认
Branch policy与 plan 集成分支 / topic 分支关系(见下节 「默认编排」),并完成 reference 清单中的 worktree 步骤。
串行不豁免:并发流全部为只读、或各写入者针对不同 Git 仓库根时不存在共享写入面;但写入串行(同一时刻仅一个代理持有该仓工作区)不豁免隔离——只要本轮存在对同一仓库工作区的可写改动,每条写流都使用独立检出目录(主 checkout 可能被链接的技能/命令消费者读取,任何生命周期分支都不得落到主 worktree)。worktree 默认的唯一豁免通道:本轮显式 Worktree mode: waived 与 Phase 1 Review & Edit 链的未提交文档例外(mstar-iteration §1.6 / §6)。
并发 subagent 与同仓工作树(对齐)
当多个可写 subagent 并发修改 同一仓库 时,不得共用同一检出目录作为写入 cwd。PM 在分派前应规划 worktree/checkout 隔离,并在各承接方 Assignment 中写明 Working branch / Branch policy 及 检出路径约定(或要求回报实际 worktree 路径)。单分支决策权仍仅属 PM;worktree 只解决「目录与工作区隔离」,不替代分支授权。
同仓、同一 plan、多可写并行轨:挂齐各轨 worktree 之前 先确认 plan 集成分支与各轨 topic 分支及 merge 靶;QC 前归并到单一 Working branch HEAD。分步见下节 「默认编排」。
QC / QA 与 feature:开发常在 feature 分支的 worktree 中完成;进入 QC 三审与随后的 QA 验证时,PM 须在 Assignment 中写明 Review cwd / Worktree path、Working branch、plan_id(无 plan 流程时 N/A + 不可歧义 Feature / scope label)与 Review range / Diff basis;三份 QC Assignment 与 QA Assignment 中 plan_id 与 Review range / Diff basis 须逐字相同,保证三票审 同一 plan/feature 与同一 diff 范围。
QC / QA 检出对齐与多 worktree 门禁衔接(强制;避免误派)
对齐字段契约(canonical · Evidence)
分派 QC 三审 与对齐的 QA 验证 时,PM 必须在 Assignment 写明与待审实现一致的 Review cwd / Worktree path、Working branch、plan_id、Review range / Diff basis。开发在 feature 分支(往往在独立 worktree 中)完成后,QC/QA 针对的都是这份 feature,不是 main 或任意未对齐默认 cwd。
Review cwd/Worktree path:优先沿用开发 Completion Report 回报的业务仓实现检出路径(该 feature 的 worktree)当且仅当该路径检出分支HEAD已含本轮待审全部提交(含曾发生在其他并行 worktree、现已归并到该分支的变更)。否则必须改用集成完成后的Working branch与对应检出路径(或在该分支上另开只读审查 worktree)。开发未用 worktree → 写明单一业务仓根路径。Working branch:含全部待审提交的那条分支(常见 plan 集成分支)。plan_id:与{SDD_DIR}<plan-id>段、主 Plan Path、workflow snapshotplans[].id一致;无{PLAN_DIR}流程时写plan_id: N/A+ 一行Feature / scope label(不可歧义,足以与并行其它 feature 区分)。Review range/Diff basis:审查的 diff/提交范围(例如merge-base: <target_branch-or-base-ref>+tip: HEAD;或rev-range: <full-40>..<full-40>;或一句equivalent to: git diff <merge-base>...HEAD,以团队可复现为准)。- 逐字对齐(强制):三份 QC Assignment 与 QA Assignment 间
plan_id与Review range/Diff basis(连同Review cwd/Working branch)必须完全相同;qa-engineer验证同一 feature 时复用同一组字段。热修 / QC 单审路径也须含同一组字段,仅承接方份数为 1。 - 三审并行时三名 reviewer 共用同一组字段(对业务仓只读 diff 审查);一般不必为每位 reviewer 各开 worktree,除非宿主/环境要求进程级隔离。
Engine check (when available): run
mstar worktree qc-alignment <assignment-file>...(或 importassertQcAlignment/singleReviewSnapshotfrom@mstar-harness/enginein a host hook)以断言上述 QC/QA 对齐字段(tri + QA 间plan_id与Review range/Diff basis逐字相同;派发前 single review snapshot)。Onfail-> do not proceed; fix and re-run. Skill text below remains authoritative when the runtime is absent.
多 worktree 并行 → 单一待审快照(派 QC 前置)
语义区分(必须理解):开发阶段可存在 多个 Worktree path(每条流一条检出目录);一轮正式 QC 三审 + 对齐 QA 只对应 一套对齐字段(上文)。不要把「多个开发 worktree」误解成「QC 应轮流进多个目录各审一半」。
单一待审 Git 快照(派 QC 前置条件):若本 plan 下多条可写并行轨落在同一业务仓且成果分布在不同分支、或未合并进同一条分支 HEAD,则派发 QC 三审(及同范围 QA)之前,必须先在 Git 完成归并(merge / rebase / 按团队集成方式),使全部待审提交出现在同一条 PM 指定的 Working branch HEAD 上;然后填 一个 Review cwd(可为该分支上新开的只读审查 worktree)+ 一个可复现的 Review range / Diff basis。禁止仅填并行轨 A 的开发用 Worktree path 作 Review cwd,却期望审查覆盖仍只存在于并行轨 B 分支或提交上的变更(该变更未进入轨 A 所检出分支 HEAD 时,Git 上不可复现,属 Assignment 错误)。
推荐默认编排(plan 集成分支先行)——同仓、同一 plan、≥2 条可写并行轨时降低 QC/QA 误用单一开发目录风险。不是唯一合法 Git 拓扑;其它拓扑仍须满足上文对齐字段 + 本节强制条款(派发前 worktree 隔离 + 派 QC 前单一待审 HEAD + 一套对齐字段):
- 先起集成分支(再挂 worktree):派发各轨实现 Assignment 前,PM 与用户确认
Branch policy,建立 plan 集成分支(Assignment 用Working branch: create <plan-integration-branch> from <base>或等价明确写法;<base>必须 PM 明确记录,例如 snapshotbranch.base(iteration_base_branch)、现有 feature 分支、远程跟踪分支或团队既定主线,不得未授权假设)。分支名由 PM 指定(feature/<plan-id>-integrate、integrate/<plan-id>仅为命名示例,非强制)。多plan_id同源一条primary_spec(Spec 文档)时:该集成分支语义即 Spec 集成分支;各 Plan feature 线 merge 回此线,全部 Plans 完成后向显式target_branch走 PR(见mstar-conventionsSKILL.md「Spec 驱动的分支模型」)。 - 再挂各轨 worktree:每条并行轨分配独立
git worktree+Worktree path;各轨Working branch一般为从集成分支出的 topic 分支(create <topic-i> from <plan-integration-branch>)或 PM 书面约定等价结构(例如从同一<base>出 topic、但书面指定合并时以集成分支为靶)。禁止承接方擅自把未授权功能提交直接堆在main/master。 - 进 QC 之前:将全部须同一轮三审覆盖的提交归并(merge / rebase / cherry-pick,以 PM 指定团队方式)到同一条将作 QC
Working branch的分支HEAD(通常即 plan 集成分支;PM 已重命名/快进为最终feature/*则以 Assignment 为准)。在此解决冲突;勿在 QC Assignment 仍指向「只含部分轨」旧HEAD时派三审。 - QC/QA 的
Working branch与合并主线:Working branch即上一步已含全部待审提交的那条分支(常见 plan 集成分支)。Review range/Diff basis通常相对尚未合并 feature 的显式目标/base 参照(例如merge-base: <target_branch-or-base-ref>+tip: HEAD),审的是 「feature 线 vs 目标线」 差异;默认不要求 QC 通过前已把该分支 merge 进目标分支(除非Branch policy或用户明确 trunk 式例外)。 - 本推荐不适用时:单轨、多仓库、或 plan 已拆 scope / 多轮增量三审(见
mstar-conventions)— 仍须逐轮满足强制条款:每轮 QC 对应一条快照、一套逐字相同的plan_id+Review range/Diff basis。
不应合并为一次审时:若两轨有意保持独立可合并单元(例如两条独立 PR),不得共用同一套 plan_id + Review range / Diff basis 假装「一轮三审覆盖全部」。应拆分 scope:分轮次审查、不同 Feature / scope label、不同 plan_id、或按 mstar-conventions 写明的显式增量三审例外,使每轮 QC 各对应一条分支快照与一套对齐字段。
同分支多目录例外:若所有并行轨始终在同一条已授权 Working branch 上协作(每流仅目录不同、提交已互相 pull/推送收敛),则任一该分支检出目录在更新到含全部提交 HEAD 后均可作 Review cwd;不得使用仍停留在旧提交的 worktree 路径。
QC / QA 执行约束
- 并行 QC 禁止在共享检出跑 test / build / install / lint / typecheck 等争用缓存或锁的命令(否则 peer QC 易
Blocked)。L3 默认手段:git diff/git log/git show/ Read / Grep。运行时验证留给 L1 证据与qa-engineer(L4) — 见mstar-review-qc/references/review-responsibility-boundaries.md。 - QC 报告落盘默认仅限 Assignment 指定的
{SDD_DIR}/review/;上述约定保证git diff、git log与所读文件与待合并 feature 一致。PM 另行提交主 plan gate summary / project-register residual changes as durable artifacts。 qa-engineer(仅QA gate: mandatory)Assignment 用 QC 逐字相同的对齐字段(QC 已写清则 QA 照抄);执行业务仓命令前须核对检出与分支;Report-only 且无路径依赖时回报须说明验证环境,否则Blocked。- 若 QA 与同仓其他可写角色并发提交测试代码,仍须遵守上文「同仓并发写入」worktree 规则(可为 QA 单开一条写入 worktree,同一
Working branch,由 PM 在 Assignment 写明)。
派发前清单与常见反模式 → references/parallel-writable-pre-dispatch.md。
History rewrite 与推送安全
- 已推送分支的任何 history rewrite:先
git fetch记录远端精确 OID,发布用--force-with-lease=<branch>:<observed-oid>;禁止裸--force。 - Rewrite 推送后:重新 fetch heads;rewrite 前的 review threads / approvals / check 结果不再是当前证据 — merge 结论前须重审(commit hash 与 inline-comment anchor 已失效)。
- 证据最窄原则(audit / QA Assignment 场景):选择会在目标回归上失败的最窄检查;不因「push 在即」重跑已通过的检查。
- 本节只管 rewrite / lease / 证据失效面;CI / review 波次 push 门禁(时序)SSOT →
mstar-iteration§5.1a。
Worktree / branch cleanup(merge 后回收;唯一契约本体)
生命周期末端的物理回收(feature/integration worktree、本地/远端分支删除)的 ownership 与守卫规则只在本节;两条时序车道的 call site(Phase-2 同轮 / Phase-6 收尾)只引用本节,不复制规则。命令(dry-run 默认;无 fetch / prune / 任何写入):
mstar worktree cleanup --workflow <id> [--harness <path>] [--apply] [--remote] [--worktree <path>] [--all-workflows] [--verbose] [--ignore-unreadable-snapshots]
- dry-run 逐候选打印
verdict | kind | ref | reason后结束;--apply只执行当前remove行。Exit:0 = 合法 dry-run / eligible 移除全部成功;1 = 探测/变更失败;2 = usage。失败行永不扩大范围;受保护/拒绝行保持可见。 - 候选范围(默认 scoped):默认候选只来自选中 workflow 的记录归属(snapshot 行元数据或已验证的
--worktree断言);--all-workflows恢复全量扫(含未记录 ref 与所有 workflow 的候选)。--worktree <path>可重复:既收窄 worktree 候选集,也是操作者所有权断言——必须匹配记录的生命周期分支与同仓 checkout 身份,不能认领其他 lifecycle 的 worktree;带--worktree时本地分支候选进一步收窄到与保留断言 owner 精确同属的分支(无命中的断言 owner ⇒ 无分支候选,没有全量回退;missing / 越界的断言路径只产出一条 note,不构造目标)。 --remote只决定是否纳入origin/*删除候选;本地合并证据(git branch --merged <base>成员资格)无论是否--remote都会无条件收集,远端 integration 证据仅在使用--remote时收集。证据探测有界:base 解析一次、每个去重 base OID 至多一组 membership sweep + pass 内不可变备忘录,--verbose追加逐对 ancestry 诊断(不改变候选与判定)。- 信任模型:
--harness <path>为操作者提供且受信——dry-run 与--apply的全部状态事实(snapshot、lease、行归属元数据、protected 锚点)均读自该目录。 - 坏 sibling 不再阻塞,且不丢保护:扫描
workflows/*/snapshot.json时,非选中的坏 snapshot 不会让命令失败(exit 1)。JSON 可解析但校验失败者以降级保守形态入安全集:只携带具保护性的声明(branch.base/branch.integration/branch.target、lifecycle worktree path、merge / execution lease、行 ownership 元数据),且 lifecycle 与行状态一律强制为非终态——故只会增加 keep/refuse 判定,绝不减少(它保护的分支/worktree 会被cleanup.keep.protected-ref或cleanup.refuse.*拦住)。完全不可解析者声明不可知:默认 withhold 全部 remove(改判cleanup.refuse.unreadable-snapshot,plan 仍完整打印),仅当操作者给出--ignore-unreadable-snapshots断言时才按可读 snapshot 判定。选中 workflow 自身 snapshot 不可读仍是探测失败(exit 1);任何坏 snapshot 的字节永不被修复、改写或删除。
Ownership(禁止命名推断):候选归属只来自 snapshot 行元数据(plans[].execution_lease;lease 释放后为保留的行 metadata.working_branch / metadata.worktree_path 与 retained track Assignments)或已验证的显式 --worktree 断言。归属缺失 / 歧义 / 他属 → cleanup.refuse.foreign-worktree / cleanup.refuse.foreign-branch。归属生产者义务(owner=PM):设 Done 并删除 execution_lease 的同一 locked update 内,owner 必须把 metadata.working_branch + metadata.worktree_path 持久化到该 plan 行(值以本轮 Assignment 为准)——这是 lease 释放后 ownership 检查读取的持久归属;缺失时已 merge 的 Done 行也会被 cleanup.refuse.foreign-* 拒绝。scoped 路线上这条义务由 coordinator 的 mstar plan complete 一次原子写入承担(Done + 保留 metadata.working_branch / metadata.worktree_path / track_branches + 删除 execution_lease 与 integration_merge_lease);whole-iteration 路线仍是 owner 的同一 locked update。禁止手工补写快照来修归属——scoped 路线回到 mstar plan complete / reconcile(mstar-iteration references/plan-scoped-pm.md §6)。
合并证据硬前置:本地资格 = git branch --merged <base> 成员资格,base 取候选自己的锚(plan/track → branch.integration;standalone plan / integration 分支 → branch.target)。远端证据绑定 {branch, tip, base} 同一分支化身;当前 harness 无 PR-merged 记录源(prMerged 恒为 null)→ 远端仅走 tip-ancestor 历史残留路线。squash-only(tip 非 base 祖先)保留并报告,绝不 git branch -D;旧 merged PR 不能授权已复用分支的新化身。
Refusals(refuse 行可见、可审计,不是 apply 失败):active execution_lease / integration_merge_lease(按 path 与 branch 匹配,跨全部已知 snapshot)→ cleanup.refuse.active-lease;分支在任何 checkout 检出 → cleanup.refuse.checked-out;foreign worktree;dirty / locked worktree;protected refs(默认分支、每个 branch.base、非终结 integration 分支、非 Done plan/track 行)→ cleanup.keep.protected-ref / cleanup.refuse.non-terminal。
Done child ≠ active parent:已 merge 的 Done plan/track 行即使父迭代仍在运行也 eligible(时序车道 1)——不存在「父必须终结」的一刀切;反之,非终结 integration 与非 Done 行跨所有 lifecycle 受保护。standalone plan 即整个 lifecycle:以 branch.target 为证据 base,且先 terminal close 才清理。
顺序(--apply;worktree 移除 ≠ 分支删除):普通 git worktree remove(永不 force)移除 eligible attached worktree → 重新探测 + 重新规划 → 删除现已未检出的分支(git branch -d,永不 -D)→ 远端 expected-OID compare-and-delete(git push --force-with-lease=refs/heads/<branch>:<observed-oid> origin :refs/heads/<branch>;ref 已移动 → cleanup.refuse.facts-changed,不自动用新 OID 重试)。dry-run 打印 worktree remove + 其分支 refuse(checked-out) 是合法状态。禁止全局 git worktree prune(会动 foreign 注册);Git 调用默认在 main worktree root,git branch -d 在该分支证据 base 的检出处执行(-d merged-into-HEAD 语义所需)——任何 Git 调用永不位于移除候选内。
Lease 的释放/转移在 cleanup 范围外,且没有独立 release 动词:cleanup(与 close)从不释放 lease。scoped 路线由 mstar plan accept(转移)→ integration-start / integration-accept → complete(一次原子删除两 lease)或 return(交回 plan session)完成;whole-iteration 路线由 owner 释放。释放后归属靠保留的行元数据 / Assignments 维持。
两条时序车道(唯一合法时机):
- Phase-2 同轮(per-plan):integration merge 成功的同一轮回收该 Done plan/track 的 feature worktree + 已合并分支(call site →
mstar-iterationreferences/phase-2-worktree-lease.md「Same-round plan cleanup」)。 - Phase-6 收尾(integration 面):只在 valid terminal close(§6.1–§6.3 完成)+ PR verified merged 之后回收 integration worktree / 分支 / 远端残留(call site →
mstar-iterationreferences/phase-6-post-merge-close.md§6.4)。Phase-6 gate 只查本地 state,不验证 merged、不检查物理清理是否完成。
Engine check (when available): dry-run 即机器检查 ——
mstar worktree cleanup --workflow <id>(或 importplanWorktreeCleanupfrom@mstar-harness/engine)对当前 facts 输出 remove/keep/refuse 计划,每行带稳定cleanup.*码。若已知受保护目标(active lease / 非 Done / 非终结 owner)出现remove→ STOP:守卫有错,任何--apply前先修。Skill text below remains authoritative when the runtime is absent.
Workflow
主链:PM 唯一分支决策(Working branch / Branch policy,写进 Assignment)→ 实现者在 feature worktree 写产品编辑(L1:control root(主 checkout)管进程 SSOT、integration worktree 管 merge、feature 管源码)→ QC 前全部待审提交归并到单一 Working branch HEAD → 派 QC 三审 / QA 时共用同一套对齐字段(Review cwd / Working branch / plan_id / Review range / Diff basis,逐字相同)→ 集成分支 merge 串行(integration_merge_lease,在 integration worktree 执行;scoped 路线:mstar plan integration-start → 显式 git -C <integration-path> merge --no-ff --no-edit <pinned-source-sha> → integration-accept → complete,reconcile 是唯一恢复动词)。并发写流在派发前完成 worktree 隔离(L1 跨 plan / L2 同 plan);主 worktree 驻留分支 = 计划头记录的 Main worktree branch,全程不切换。
References
- 派发与反递归红线 →
mstar-dispatch-gates - SDD implement 波次(file handoff / reviewer)→
mstar-sdd - 迭代 Phase 2 integration worktree + lease 细则 →
mstar-iteration§2(references/phase-2-worktree-lease.md) - scoped plan 路线(bind / scope 边界 / handoff / coordinator merge 序列 / reconcile)→
mstar-iterationreferences/plan-scoped-pm.md
L1 refusal diagnostics across hosts
CLI, dsh, and omp share worktree.l1.lifecycle-register-unreadable when the active register cannot be enumerated and worktree.l1.lifecycle-snapshot-unreadable when a registered sibling cannot be read/validated. They fail closed; an absent register contributes no siblings. Engine SDD governing-row discovery remains lenient for unreadable siblings (only readable active snapshots contribute), but a governing active snapshot carrying both integration/control path keys refuses instead of becoming standalone. This is an intentional engine-versus-host seam distinction, not equivalent evidence coverage.
worktree.l1.integration-missing covers required integration inputs not supplied and a supplied integration path absent on disk; an existing unusable checkout is reported by branch/checkout probe failures. A standalone plan with both integration fields omitted has no integration requirement and does not emit this code.