# Parallel writable pre-dispatch gate (PM)

## Layer: L2 (within-plan)

This reference is **L2** worktree isolation: **same `plan_id`**, **same business repo**, **≥2 concurrent writable implement tracks**.

**L1 (cross-plan)** is separate and stacks on top when iteration Phase 2 defaults apply:

- The **control root** is the primary checkout (main worktree) — the process-SSOT holder whose residency is recorded as **`Main worktree branch`** in the main plan header. The **integration worktree** (`integration_worktree_path`, checked out to `spec_integration_branch`) is the sole merge cwd; status/SDD coordination reads/writes run via absolute control-root paths.
- Each ready row uses a distinct metadata.worktree_path/source branch, different from main/control and integration; verify actual checkout before writable dispatch. This applies to serial as well as concurrent product edits.
- Ordinary coordinator configuration/atomic writes/serial merge rules → mstar-iteration/references/phase-2-worktree-lease.md.

Within-plan multiple writable tracks also require L2; cross-plan isolation never substitutes for it.

## Why this exists

Host dispatch can satisfy **「N Assignments ⇒ N invokes in one message」** while every writer still shares **one checkout directory**. That may satisfy `mstar-dispatch-gates` tool concurrency but **violates** same-repo write isolation.

**N parallel invokes ≠ parallel-safe.** Worktree isolation is a **separate, earlier** gate.

## Mode switch (do not carry single-track habits)

Serial single-plan waves (one feature branch, one feature worktree, PM merging via the integration worktree) do **not** authorize multi-writer parallel tracks without re-running this **L2** gate.

When the round adds a second **concurrent** writable implement track on the **same business repo** within one plan, treat it as a **mode switch** — even if earlier plans in the iteration were serial or L1 already assigned each plan its own feature worktree.

## Pre-dispatch checklist (HARD)

Before the **first** concurrent writable implement dispatch in a round:

1. **Re-read repo parallel rules** — root `AGENTS.md` and `{HARNESS_DIR}/AGENTS.md` for branch / worktree / merge-order constraints not duplicated in harness skills.
2. **Confirm PM checkout** — PM thread operates the **integration worktree** (dedicated checkout on `spec_integration_branch`); the primary checkout (main worktree) keeps its recorded **`Main worktree branch`** and never switches. **Do not** `checkout` topic / feature branches in the PM **primary cwd** to "help" implementers.
3. **Create isolation** — from the realpath of the Git top-level, for each writable track: `mkdir -p ../<repo>.worktrees && git worktree add ../<repo>.worktrees/<track-slug> <branch>` (or equivalent checkout-isolation capability) **before** dispatch. `<repo>` is the repo basename; create a new branch with `-b <branch>` when needed. Each Assignment **must** include absolute **`Worktree path`**.
4. **Verify paths exist** — for each track: directory exists; `git -C <path> branch --show-current` matches Assignment **`Working branch`**.
5. **Retain track ownership** — before L2 dispatch, PM records every track's Assignment **`Working branch`** in the governing plan row **`metadata.track_branches: string[]`** (ACTIVE: store execution authority graph). Retain these branches while the lifecycle is active; the main-residency check consumes this record. Tracks hold no row-level execution leases.
6. **Assignment tags** — `Dispatch mode: parallel independent tracks` + `Worktree isolation: required` (`mstar-phase-gates`).
7. **Merge order** — when tracks may touch overlapping paths (shared packages, migrations, lockfiles), PM assigns **explicit sequential merge order** before dispatch.

## PM primary cwd invariants

| Allowed (PM thread) | Forbidden (PM thread) |
|---------------------|----------------------|
| operate the **integration worktree** (dedicated checkout on `spec_integration_branch`) for merges and tracked-result commits | `git checkout` any branch in the **primary cwd** — the main worktree never leaves its recorded **`Main worktree branch`** |
| `git worktree add` / `list` / `remove` | `commit` product code in the main or integration checkout (product source → feature worktree) |
| read-only inspection inside worktrees | switch primary cwd to an implementer feature branch |

## Leaf implementer invariants

- **Before first** repo `Write` / `commit`: `cd` to Assignment **`Worktree path`**.
- **Never** implement in PM's integration checkout when Assignment names a different **`Worktree path`**.
- Completion Report: **`Worktree path used`** (absolute) + **`Working branch used`**.

## Common anti-patterns

| Looks compliant | Actually wrong |
|----------------|----------------|
| Two Task invokes in one message | Both writers share default repo root checkout |
| Assignment lists `Working branch: feature/...` only | No `Worktree path`; subagent inherits PM cwd |
| `git checkout -b feature/...` on shared checkout | Branch exists but **no** directory isolation |
| Sibling worktree root exists | Per-track subdirs missing — empty root ≠ isolation |
| Prior serial plans succeeded | Assumes parallel needs no worktree setup |

## Emit-zero until ready

If worktrees are not created and verified, **`Subagent invokes issued: 0`** for that implement batch — same discipline as `mstar-dispatch-gates` emit-zero for incomplete parallel QC batches.

## After parallel dev (pointer)

Before plan QC tri: merge all tracks to one **`Working branch` `HEAD`** — parent skill §「单一待审 Git 快照」.
