Load order(必读顺序)
首次 Read 本 skill 前:必须先 Read mstar-harness-core(SKILL.md)。 冲突时 以 mstar-harness-core 为准。
Spec branch naming → mstar-conventions. L1/L2 checkout isolation → Worktree isolation layers below; L2 pre-dispatch → references/parallel-writable-pre-dispatch.md. Ordinary source metadata, coordinator operations and actual serial integration → mstar-iteration/references/phase-2-worktree-lease.md. Cleanup ownership/merge/refusal rules remain solely in Worktree / branch cleanup below; no per-row claim protocol.
Scope(摘要)
- 仅 PM 决定分支;其他可写角色不得自行新开分支或切回
main。 - Assignment 须含其一:
Working branch: <existing>|create <new> from <base>|Branch policy: direct on <branch> — <reason>。 - L1: Git-derived main/control root + separate recorded integration checkout + distinct row metadata.worktree_path/source branch. Atomic coordination and serial integration remain; no per-row execution lease.
- 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 确认话术模板
面向用户沟通时,使用以下结构:
markdown当前检测到在分支:`<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 含
Worktree path,先cd到该目录,并通过git rev-parse --show-toplevel校验当前检出根目录与该路径一致;不一致则停下并回报 PM,不得写入。分支校验必须在该目录内进行,避免在 primary checkout 上校验分支而误报冲突。 - 在上一步校验过的检出目录内校验当前分支与 Assignment 是否一致。
- 只能执行 PM 在 Assignment 中定义的分支策略。
- 禁止自行切回
main/master再重开分支流程。 - 若 Assignment 含糊或与本地分支状态冲突,先停下并回报 PM。
- 提交仅用已配置身份;身份缺失或失败则 Blocked,不得编造或用
-c覆盖身份 →mstar-roles/references/_shared/leaf-executor-core.md「Git NEVER (repo writes)」。
回报要求
可写角色在 Completion Report 中必须明确当前工作分支,例如:
Working branch used: <branch-name>- 若 Assignment 含
Worktree path,还须明确实际使用的绝对检出路径:Worktree path used: <absolute>。
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) | Ready rows implement concurrently | Main-worktree control root (process SSOT) + integration worktree (integration_worktree_path) + distinct feature worktrees from ordinary row source metadata; atomic coordination |
| 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 to iteration Phase 2 source/integration isolation unless an explicit applicable
Worktree mode: waivedexception exists. Any single-plan wave with multiple writable tracks still satisfies L2; source metadata, not a per-row lease, supplies row checkout facts. - Cross-plan integration merge into
spec_integration_branchremains serial (store.dbexecution_integration_leases) even when L1 feature implementation runs in parallel.
Main-worktree control root, integration worktree, feature worktree (iteration / L1)
The integration checkout is established at Phase 2 entry; the bounded Phase 1 uncommitted-document exception does not switch main. Source metadata and direct completion procedure → mstar-iteration/references/phase-2-worktree-lease.md; field semantics → mstar-artifacts. No per-plan claim/bind protocol.
| 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 a recorded state field — 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 (ACTIVE store-backed workflow view) — 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's Working branch | Row metadata.worktree_path (ACTIVE plan view) | Required cwd for 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) | store.db, retained workflows/ bodies, projects/, authored plans/, sdd/, iterations/, archived/ (status.json / workflow snapshots / legacy session JSON: read-only import/history only) | 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 recorded state field. Discover it instead of guessing: mstar path resolve reports controlRoot / controlHarnessDir / linkedWorktree (resolution order → mstar-conventions「{HARNESS_DIR} 解析顺序」). A linked checkout without .mstar/ is not an uninitialized harness.
Hard rules
- Registered
integration_worktree_path(ACTIVE store-backed workflow view) MUST differ from the main worktree (control root) and from rowmetadata.worktree_path— never merge from the main checkout, never product-edit the integration checkout. - Main-worktree residency (engine check below): 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. - Before writable dispatch, absolute Worktree path/Working branch appear in leaf Assignments and ordinary row source metadata. Missing/corrected facts use revisable prepare.
- Plan Path and SDD dir are absolute control-root paths; do not resolve a feature checkout's ignored harness as process SSOT.
- Validate the actual source checkout/branch and atomic coordination authority, not a per-plan session/holder or ceremonial prepare record.
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 shared safe coordination authority →Plan parallelism: serialonly — that is a separate gate and does not waive worktree isolation.
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 a recorded state field; PM passes the recordedMain worktree branchunchanged in writable Assignments. - Integration worktree — one dedicated linked checkout on
spec_integration_branch, distinct from the main worktree, recorded once as registeredintegration_worktree_path(ACTIVE store-backed workflow view); sole merge cwd for the iteration. - Feature worktree (per plan) — one distinct subdirectory under the sibling root
../<repo>.worktrees/, outside the checkout, per activeplan_id(e.g.../<repo>.worktrees/<plan-id>-<slug>). The root is<parent-of-repo-root>/{repo-basename}.worktrees/, where repo root is the realpath of the Git top-level. From that repo root, create withmkdir -p ../<repo>.worktrees && git worktree add ../<repo>.worktrees/<plan-id>-<slug> -b <branch>. This keeps linked checkouts out of the repository scan/edit surface. In-repo.worktrees/remains a legal explicit override; registered absolute source and cleanup paths are location-agnostic. AssignmentWorktree path/Working branchmust match rowmetadata.worktree_path/metadata.working_branchand actual checkout facts; missing/corrected source scope uses ordinary prepare, never a holder or claim. - 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:
mstar worktree checkowns the engine-enforced checkout facts — workflow entry (--workflow <id> --entry: branch metadata, main residency, recorded integration checkout exists on its branch and clean, merge-lease state), per-plan L1 (--workflow <id> --plan <plan-id>: main residency; main/control, source-metadata and integration checkouts pairwise distinct; actual branch alignment; plus the workflow's merge-lease fact) and L2 (--l2 --tracks <json>: parallel writable tracks). These are factual isolation checks scoped to that engine-enforced subset, not per-row session/lease/seal admission, and not clearance of the full pre-dispatch checklist. Workflow-wide integration exclusion and serial real merge proof remain distinct requirements.
同仓并发写入与 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、当前执行权威的 plan id 一致(ACTIVE:store 执行行);无{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 明确记录,例如当前执行权威的branch.base(iteration_base_branch;ACTIVE:store workflow 执行行)、现有 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 / 经mstar plan issue-add捕获确认 findings 到 store.db;project register 仅迁移历史。 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 / 任何写入):
textmstar worktree cleanup --workflow <id> [--harness <path>] [--apply] [--remote] [--worktree <path>] [--all-workflows] [--verbose]
- dry-run 逐候选打印
verdict | kind | ref | reason后结束;--apply只执行当前remove行。Exit:0 = 合法 dry-run / eligible 移除全部成功;1 = 探测/变更失败;2 = usage。失败行永不扩大范围;受保护/拒绝行保持可见。 - 候选范围(默认 scoped):默认候选只来自选中 workflow 的记录归属(ACTIVE:store 执行行元数据;或已验证的
--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的全部状态事实(lease、行归属元数据、protected 锚点)均读自该目录的store.db。 - 来源选择(ACTIVE 权威):状态事实来自一次权威读(
readExecutionCleanupState(context, workflowId))——它独立于 registry 成员资格寻址被选 workflow(terminal / 已 unregister 后仍可寻址),并返回完整保护清单(全部 retained sibling 的 lease / 行归属 / protected 锚点)。retired/缺失的 JSON 不参与、也不被修复;权威损坏(保护行不可解析)fail-closed 拒绝整次读,绝不静默丢弃 sibling 保护。
Ownership (never infer from names): use retained row metadata.working_branch/metadata.worktree_path, track Assignments, valid Done completion source branch/path or a verified explicit --worktree assertion. Paths compare canonically; missing/ambiguous/foreign claims refuse. Direct complete persists source metadata with Done in the same transaction; cleanup never repairs state, advances rows or requires a deleted transfer state. Historical evidence may protect resources without authorizing deletion.
合并证据硬前置:本地资格 = 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: active workflow integration exclusion remains protected across known workflows; any checked-out branch, foreign/ambiguous ownership, dirty/locked checkout, protected anchors or nonterminal rows refuse removal. No names/age/labels bypass these guards.
Cleanliness(owner 可见的删除后果):普通 git status --porcelain 将 tracked 修改与非 ignored 的 untracked 文件视作 dirty,仍拒绝移除;仅有 ignored 内容不再阻塞 eligible worktree 移除。--apply 移除该 worktree 时其中 ignored 内容也会被删除,Git 不为其提供恢复保障;owner 在执行前须确认该后果。status 探测失败仍使命令中止(exit 1),不得当作 clean;dirty / locked refusal 与永不 force 保持不变。
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 调用永不位于移除候选内。
Cleanup/close never releases write exclusion: ordinary direct complete releases applicable exclusion with verified Done; retained row source metadata/track Assignments preserve ownership afterward. A protected resource is not made eligible through state edits or takeover.
两条时序车道(唯一合法时机):
- 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 selects branches → isolated source tasks → all reviewed commits converge on one Working branch HEAD → aligned QC tri/QA → explicit serial Git merge in the integration checkout → direct complete verifies its actual base/result and QC/QA. Standalone development instead verifies its registered source checkout; report-only uses declared fulfilment without fabricated Git. Main remains on its recorded branch. L1/L2 isolation precedes dispatch; transaction/CAS protects state.
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)
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.


