pi-gauntlet 8.4.8 → 8.4.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -97,11 +97,11 @@ provisioning, so it never re-reads; step 2 re-reads once after provisioning (`re
97
97
  - repair.poll_deadline: null | <absolute timestamp for the watch window; reference/post-selection-loop.md ### Wait course>
98
98
  - repair.wave: null | { pre_wave_head, pushed_head, selected_ids, selected_payloads, sync: null | { pre_head, expected_remote_head }, action: fix-nits?, affected_claims, round_start_head, counted: false | true, counted_head, checkpoint_history: [], stage: apply | review | push, no_progress: { failed_prerequisite, observed_value, result_path }? }
99
99
  - approved_head: null | <sha> # set by reference/post-selection-loop.md when gh pr review --approve exits 0; selects the approved template
100
- - cleanup_done: false | true # set by reference/cleanup.md after the cleanup pick runs
100
+ - post_steps: [ { label, source, command: null | <exact command>, payload_file: null | <absolute path>, picked: false | true, result: null | <result> } ] # reference/post-selection-loop.md ### Post steps; preserve mapping and results through nested gates
101
101
  - pr.review_requests: [ { __typename: User, login } | { __typename: Team, name, slug } ] # raw reviewRequests entries
102
102
  - viewer: { login, is_author, role }
103
103
  - prior_review: null | { id, state, commit, submitted_at, body, inline[ { id, path, original_line, body } ], delta: ancestor | not ancestor (<reason>) | unset }
104
- - permissions: { viewer_permission, is_cross_repository, maintainer_can_modify, merge_state_status, can_update_branch, bypass_eligible, head_url, head_ref, head_pushable } # head_pushable is set in step 2 after provisioning (reference/assessment.md); merge_state_status is `BLOCKED`, `BEHIND`, `UNKNOWN`, `unreadable` (null), or any other GitHub value (`CLEAN`, `UNSTABLE`, `HAS_HOOKS`, `DIRTY`) and is written only from a `gh pr view` invocation that names `mergeStateStatus` (this call, the step-2 re-read, the step-2b re-gather (`reference/sync.md`), the pre-menu refresh before and after the single watch, compare-and-swap), never from an ad hoc GraphQL query or `gh pr list`, and never from a reply carrying `errors`; any field that cannot be read is the literal `unreadable`; menu availability derives from this block (reference/decision-menu.md ## Availability)
104
+ - permissions: { viewer_permission, is_cross_repository, maintainer_can_modify, merge_state_status, can_update_branch, bypass_eligible, head_url, head_ref, head_pushable } # head_pushable is set in step 2 after provisioning (reference/assessment.md); merge_state_status is `BLOCKED`, `BEHIND`, `UNKNOWN`, `unreadable` (null), or any other GitHub value (`CLEAN`, `UNSTABLE`, `HAS_HOOKS`, `DIRTY`) and is written only from a `gh pr view` invocation that names `mergeStateStatus` (this call, the step-2 re-read, the step-2b re-gather (`reference/sync.md`), the pre-menu refresh before and after the single watch, compare-and-swap), never from an ad hoc GraphQL query or `gh pr list`, and never from a reply carrying `errors`; any field that cannot be read is the literal `unreadable`; menu availability derives from this block (reference/menus.md row tables)
105
105
  - status_checks: [ { name, kind, status, conclusion, required, url, workflowName } ] # kind: check_run | status_context | unreadable, from the rollup entry's __typename; evidence semantics: Section B Evidence resolution; workflowName from the CheckRun rollup entry (absent on StatusContext)
106
106
  - actions_runs: [ { databaseId, status, conclusion, workflowName, url } ] # from the fixed gh run list call on the assessed head
107
107
  - comments: { inline[ { id, updated_at, user_type, body, ... } ], top_level[ { id, updated_at, user_type, body, ... } ], review_threads[]? } # retain REST body for source-review deltas; C# identity diffs on id/updated_at, Section C gates placeholder detection on user_type
@@ -195,7 +195,7 @@ Row precedence is top-down: the first matching row wins. The Fix wave row is an
195
195
  |---|---|---|---|
196
196
  | Opt-out | `local verification: always` in `## PR gate` | Run local command unconditionally; a Failed-CI block below still applies independently | Local; `local run: local verification: always` |
197
197
  | Failed CI | Any blocking conclusion in the resolved set | Blocks: mints a `P#` (any resolved-set failure, required or not) and names the check in the evidence block; route the P# to the delivery wave under a set course, otherwise render initial; obstacle exits use `reference/menus.md`. A green local run never overrides it. Only the human `ci-infrastructure-broken` disposition - a pick, never a trigger - runs the fallback local run; merge stays withheld until that run is green | The disposition; plus the fallback run's result when the disposition triggered one |
198
- | Held run | an `action_required` rollup CheckRun whose run matches an `actions_runs` entry, or an `actions_runs` entry with `action_required` and no rollup entry (a rollup CheckRun matches the `actions_runs` entry whose `databaseId` equals the run id parsed from the CheckRun's `detailsUrl`) | Pending: render `approve workflow run` when available - `viewer_permission` in `WRITE`/`MAINTAIN`/`ADMIN`, the rule `reference/decision-menu.md` `## Availability` owns; when the row is not available, or it was picked and the API returned 403 or 404, run the local command at once; the fresh Section B helper receives the resolved row `held run not approvable` in its task; an approved run that completes is re-resolved per `reference/fix-wave.md` `## Evidence after push`, which dispatches the claim-check-only helper | `local run: held run not approvable` when it fired, else n/a (waiting) |
198
+ | Held run | an `action_required` rollup CheckRun whose run matches an `actions_runs` entry, or an `actions_runs` entry with `action_required` and no rollup entry (a rollup CheckRun matches the `actions_runs` entry whose `databaseId` equals the run id parsed from the CheckRun's `detailsUrl`) | Pending: render `approve workflow run` when available - `viewer_permission` in `WRITE`/`MAINTAIN`/`ADMIN`, the rule `reference/menus.md` `## action` owns; when the row is not available, or it was picked and the API returned 403 or 404, run the local command at once; the fresh Section B helper receives the resolved row `held run not approvable` in its task; an approved run that completes is re-resolved per `reference/fix-wave.md` `## Evidence after push`, which dispatches the claim-check-only helper | `local run: held run not approvable` when it fired, else n/a (waiting) |
199
199
  | Pending | >=1 **binding** pending check, no blocking conclusion | record pending evidence; run a bounded watch only at delivery step 4 through `reference/post-selection-loop.md` `### Wait course`; never a local run, never an evidence-less merge; when a later re-resolve moves this head to CI-sufficient, the orchestrator dispatches a fresh Section B helper in claim-check-only mode (no local run) so every material claim gets a disposition | n/a (waiting) |
200
200
  | CI-sufficient | >=1 `success`, zero blocking, zero binding pending | Skip local run | CI claim: check name(s), conclusion, assessed SHA, run URL |
201
201
  | Fallback | No conclusive check: no checks on the assessed head, or only inert / fail-safe conclusions or only not-binding pending checks | Run local command (protocol below) | Local command + `log_path`; `local run: no conclusive check` |
@@ -316,7 +316,7 @@ its `[View job run](<url>)` link; the result decides the row's state:
316
316
  | Bot-authored body whose first line starts with `**Claude encountered an error` (the producer's failure header) | `reviewer failed (error)` | no |
317
317
  | run completed `success` while the prefix persists | `pending` until the body changes or one bounded delivery watch deadline expires, then `reviewer failed (stale placeholder)` | yes, then no |
318
318
 
319
- A `pending` row renders as one `PR comments` line in `reference/report.md`'s form (`The reviewer run is still in progress, so merge waits. (<run url>)`); `reviewer failed` rows carry no reply and no label and print under `show evidence` only. A failed reviewer is information,
319
+ Render a `pending` row through `reference/report.md`'s waits rule; keep `reviewer failed` rows replyless and unlabeled under `show evidence` only. A failed reviewer is information,
320
320
  never a withhold.
321
321
 
322
322
  **Reviewer run on the new head.** The placeholder is written from inside the
@@ -330,8 +330,8 @@ finished or error body), record that run's `workflowName` (from
330
330
  `gh run view`) as the reviewer workflow for this run of the gate;
331
331
  after every head move,
332
332
  `gh run list -w <workflowName> -c <headRefOid>` names the reviewer run on the
333
- new head. A run with `status != completed` renders the same `PR comments` line and
334
- withholds pre-composed merge exactly like a `pending` row (delivery step 4 watches it).
333
+ new head. Render a run with `status != completed` through `reference/report.md`'s waits rule;
334
+ withhold pre-composed merge exactly like a `pending` row (delivery step 4 watches it).
335
335
  No such comment -> no reviewer workflow known -> no window check;
336
336
  `show evidence` says `reviewer workflow: unknown`.
337
337
 
@@ -106,7 +106,7 @@ Keep fields in this order. Use the portable repo identifier from `../../brainsto
106
106
 
107
107
  Run resume entry check 3 against the run home unchanged. Resolve the home spec through Candidates, retaining human approval/confirmation requirements; artifact presence supplies no approval. Before any tracker write, compare ordered brief membership with the home spec's `### Leg:` blocks exactly; name the missing, extra or reordered leg and both lists on mismatch. Use `../../brainstorming/reference/legs.md` for membership, companion-file and scope grammar; keep no duplicate grammar here.
108
108
 
109
- For each companion, parse the home overrides' selected sibling clone URL with shape-ticket's shared parser and use `<home PRIMARY parent>/<NAME>` as its declared primary. Canonicalize that primary's git common directory. Resolve an absent location from the leg's recorded `home:` contract and shared NAME (shared branch with `/` replaced by `-`), not a newly inferred wrapper. Render that derivation in the stop: name the recorded `home:` pattern and the shared NAME it was resolved from, and state that the pattern locates the tree without authorizing its recreation, a synthesized receipt or inferred approval. Require the companion worktree's canonical git common directory to equal the declared primary's, its live branch to equal the shared branch, and its leg file's full `**Home:**` tuple to equal the run home's repo, shared branch and repo-relative spec path. Stop naming the offending leg and expected/observed path, branch or full tuple. A live tree's branch or tuple mismatch is not informational drift.
109
+ For each companion, parse the home overrides' selected sibling clone URL with shape-ticket's shared parser and use `<home PRIMARY parent>/<NAME>` as its declared primary. Canonicalize that primary's git common directory. For a brief's `worktree: missing`, apply [Locate a leg tree](../../brainstorming/reference/legs.md#locate-a-leg-tree) using the declared primary and recorded branch. Use a found tree as the companion worktree for the remaining admission checks. On lookup failure, report that rule's repo, branch and reason; state that an empty lookup authorizes no recreation, receipt or approval, retaining live receipt admission below for a missing delivered tree. Keep an explicit brief `worktree:` path as recorded and validate it without replacing it from the lookup. Require the companion worktree's canonical git common directory to equal the declared primary's, its live branch to equal the shared branch, and its leg file's full `**Home:**` tuple to equal the run home's repo, shared branch and repo-relative spec path. Stop naming the offending leg and expected/observed path, branch or full tuple. A live tree's branch or tuple mismatch is not informational drift.
110
110
 
111
111
  Admit a missing companion tree only after live receipt validation under `../../finishing-a-development-branch/reference/legs.md`. A copied receipt alone proves nothing. Announce per-leg HEAD and dirty drift against live trees without stopping; identify each leg. Keep approval, standing-grant validation, arming order and task snapshots unchanged. Dispatch task `Leg:` work in that leg's checkout, not the home by default.
112
112
 
@@ -6,18 +6,44 @@ For `$ROOT`, `$BRANCH`, `REMOTE_BRANCH=existing`, follow companion mode below be
6
6
 
7
7
  ### Companion identity and provisioning
8
8
 
9
- Use caller `$ROOT` unchanged, not the session's git common directory; apply Step 0's submodule guard against that root. Use `$BRANCH` as the branch and the companion's repo identity in every stop, never a PR number. Run `git -C "$ROOT" fetch origin`, then repeat the live check `git -C "$ROOT" ls-remote --exit-code --heads origin refs/heads/<branch>` before any companion writes. On any fetch failure or lookup exit other than 0 or 2 stop naming repo and command output, never diagnose absence. On exit 0 require `origin/<branch>`. On exit 2 stop even when a stale tracking ref still resolves: `origin/<branch> is missing in <repo>; on the machine that ran option 6, push <branch> from that companion's checkout, then rerun brainstorming #N`. On that machine, verify `git log -1 --format=%H refs/heads/<branch> -- <spec-dir>/<home spec filename>` shows the leg-file commit without checking out or modifying the primary, then run `git push -u origin <branch>`. Stop continuation when that commit exists on no machine; do not regenerate it.
9
+ Use caller `$ROOT` unchanged, not the session's git common directory; apply Step 0's submodule guard against that root. Use `$BRANCH` as the branch and the companion's repo identity in every stop, never a PR number. Run `git -C "$ROOT" fetch origin`, then repeat the live check `git -C "$ROOT" ls-remote --exit-code --heads origin refs/heads/<branch>` before any companion writes. On any fetch failure or lookup exit other than 0 or 2 stop naming repo and command output, never diagnose absence. On exit 0 require `origin/<branch>`. On exit 2 stop even when a stale tracking ref still resolves; use [Missing remote recovery](#missing-remote-recovery) before selecting the stop's recovery ending.
10
10
 
11
- Set `ORIGINAL_HEAD=$(git -C "$ROOT" rev-parse origin/<branch>)`. Obtain nonempty `baseRefName` with `gh repo view <owner/name> --json defaultBranchRef -q .defaultBranchRef.name` (positional repo, never `-R`), then `BASE_SHA=$(git -C "$ROOT" rev-parse origin/<baseRefName>)`; retain full SHAs. Resolve home and create through Step 1a's rules from this repo's own overrides and `.pi/settings.json` read by file with existing preset rules, already compared with recorded contract in caller preflight. Derive NAME from BRANCH with `/` replaced by `-`.
11
+ Set `ORIGINAL_HEAD=$(git -C "$ROOT" rev-parse origin/<branch>)`. Obtain nonempty `baseRefName` with `gh repo view <owner/name> --json defaultBranchRef -q .defaultBranchRef.name` (positional repo, never `-R`), then `BASE_SHA=$(git -C "$ROOT" rev-parse origin/<baseRefName>)`; retain full SHAs. Use this repo's own overrides and `.pi/settings.json` read by file with existing preset rules, already compared with the recorded contract in caller preflight. For a recorded `home:`, resolve home/create through Step 1a; without `home:`, select and provision through [Recorded no-home provisioning](#recorded-no-home-provisioning). Derive NAME from BRANCH with `/` replaced by `-`.
12
12
 
13
- Read no `headRefOid`, `MEMBER_HEADS` or `PRE_REWORK_HEAD` on this path. Skip cross-repository/PR-head-unreachable checks, PR reports, pre-rework refs and thread fetching. Keep the checked-out-elsewhere stop from the home table, substituting BRANCH and naming repo. Before the local-branch ancestry stop, apply coordinated base-sync recovery below. Without recovery require `git -C "$ROOT" merge-base --is-ancestor refs/heads/<branch> origin/<branch>` for an existing branch; on exit 1 use the local-branch ancestry stop naming repo and replacing "rework needs the PR head" with "companion needs the published branch head". Surface command errors, not negative proofs.
13
+ Read no `headRefOid`, `MEMBER_HEADS` or `PRE_REWORK_HEAD` on this path. Skip cross-repository/PR-head-unreachable checks, PR reports, pre-rework refs and thread fetching. Keep the checked-out-elsewhere stop from the home table only for a recorded `home:`, substituting BRANCH and naming repo. Before the local-branch ancestry stop, apply coordinated base-sync recovery below. Without recovery require `git -C "$ROOT" merge-base --is-ancestor refs/heads/<branch> origin/<branch>` for an existing branch; on exit 1 use the local-branch ancestry stop naming repo and replacing "rework needs the PR head" with "companion needs the published branch head". Surface command errors, not negative proofs.
14
14
 
15
- Apply the "Provision the exact head" rows and wrapper/token/home safety rules with BRANCH for headRefName and ORIGINAL_HEAD for headRefOid. Keep their order: validated recovery, selected-home dirty-tree ask then ff-only and exact head, absent tree/local ancestor proof then update-ref and add, absent tree/absent branch existing-branch DWIM add. Never supply `-b`/`-B`. Run a compatible existing-branch wrapper only; retain `create: override skipped (contains -b)` otherwise. After creation require HEAD equal ORIGINAL_HEAD or validated recovery tip; on mismatch preserve the tree and print its path and both full SHAs.
15
+ Apply the "Provision the exact head" rows and wrapper/token/home safety rules with BRANCH for headRefName and ORIGINAL_HEAD for headRefOid; for a block without `home:`, replace their tree selection and add commands through the no-home table below, including on validated recovery. Keep their order: validated recovery, selected-home dirty-tree ask then ff-only and exact head, absent tree/local ancestor proof then update-ref and add, absent tree/absent branch existing-branch DWIM add. Never supply `-b`/`-B`. Run a compatible existing-branch wrapper only; retain `create: override skipped (contains -b)` otherwise. After creation require HEAD equal ORIGINAL_HEAD or validated recovery tip; on mismatch preserve the tree and print its path and both literal full SHAs (define any report aliases with all 40 characters).
16
16
 
17
- Run only "Merge the fetched base", with companion WORKTREE and its own BASE_SHA overrides for SCOPED_TEST_COMMANDS. Keep helper scope, staging, contained-delta and orchestrator completion checks. On failure abort and record `merge: unresolved - <files>`; return the unresolved result to the coordinated caller for its by-hand stop, not the home Task 1 continuation. Require `git -C "$WORKTREE" merge-base --is-ancestor <ORIGINAL_HEAD> HEAD` after merge. Report Base SHA and merge outcome, not `PR:` or `Pre-rework head:`. Require Step 4's coordinated read-back (`worktree list --porcelain` path and `branch --show-current` exactly BRANCH) before `Worktree ready at <path>`.
17
+ Run only "Merge the fetched base", with companion WORKTREE and its own BASE_SHA overrides for SCOPED_TEST_COMMANDS. Keep helper scope, staging, contained-delta and orchestrator completion checks. On failure abort and record `merge: unresolved - <files>`; end with the preserved-leg inventory and the caller's by-hand stop, even after a clean abort. Emit no `Worktree ready` or home Task 1 continuation on this path. Require `git -C "$WORKTREE" merge-base --is-ancestor <ORIGINAL_HEAD> HEAD` after merge. Report Base SHA and merge outcome, not `PR:` or `Pre-rework head:`. Require Step 4's coordinated read-back (`worktree list --porcelain` path and `branch --show-current` exactly BRANCH) before `Worktree ready at <path>`.
18
18
 
19
19
  On every companion provisioning failure name repo and branch and print `Preserved created legs:` using Step 4's inventory, including the stopped member's tree after a successful creator. Remove nothing.
20
20
 
21
+ ### Missing remote recovery
22
+
23
+ Print `origin/<branch> is missing in <repo>`. Run `git -C <primary> log -1 --format=%H refs/heads/<branch> -- <spec-dir>/<home spec filename>` on this machine without checking out or modifying the primary. Select the recovery ending from that file-scoped result, not the branch tip or a stale tracking ref:
24
+
25
+ | Observation | Recovery ending |
26
+ |---|---|
27
+ | The file-scoped log prints a commit | Offer `git push -u origin <branch>` from that primary, then rerun `brainstorming #N`. |
28
+ | No local branch, or a local branch without the leg-file commit; the log prints nothing | State `no local branch on this machine holds the leg file; restore origin/<branch> from a clone that still has it and rerun brainstorming #N; nothing is regenerated`. Offer no push from this machine. |
29
+
30
+ Preserve all provisioned trees. Run no creation, local ref update or merge on this stop.
31
+
32
+ ### Recorded no-home provisioning
33
+
34
+ Apply to a companion block without `home:` and to a marked home's block without `home:`. Keep blocks with `home:` and unmarked PR subjects on their existing rows, including the another-path stop and the `create: override skipped (contains -b)` native fallback.
35
+
36
+ Locate by [Locate a leg tree](../../brainstorming/reference/legs.md#locate-a-leg-tree) in ROOT using the recorded branch, including for marked home selection before its worktree exists. Use its linked-block and checkout identity checks; never derive a folder from NAME or default a missing recorded `home:`. Keep NAME as the branch with `/` replaced by `-` for creation tokens, not the located folder basename.
37
+
38
+ | Observed state | Action |
39
+ |---|---|
40
+ | One valid linked tree on the branch | Set WORKTREE to that path; bypass the another-path stop. Run the existing dirty-tree ask, ff-only and exact published-head checks there, or reuse the validated recovery tip unchanged. |
41
+ | Lookup fails other than `no worktree holds <branch>` | Stop naming repo and branch with the lookup reason; create nothing. |
42
+ | No tree, recorded script supports an existing-branch form | Read its source before any write. After the existing source-clean ask and local-branch ancestry proof, update-ref only for an unrecovered local ancestor; preserve a recovered tip. Run the script's existing-branch form from ROOT with shared NAME for `<name>` and the recorded branch for `<branch>`, quoted as single shell words. Never pass `-b`/`-B`; surface nonzero output without a built-in fallback. Locate the created tree by branch and require HEAD equal to the published head or validated recovery tip, then complete normal base sync and Step 4 read-back. |
43
+ | No tree, recorded script cannot check out an existing branch | Stop before any write, including update-ref: `cannot provision <repo>: <script> cannot check out existing branch <branch>`. Create no built-in tree. |
44
+
45
+ Resolve other tokens through the existing wrapper-token rule before execution. Keep built-in existing-branch creation only for a recorded built-in creator, never as a fallback for a script-owned tree.
46
+
21
47
  ### Recover coordinated base sync
22
48
 
23
49
  Apply only for a companion or a caller-observed marked home with N>1 Legs, before ancestry and exact-head stops. Use ORIGINAL_HEAD for companions and home headRefOid for marked home as the published head. Inspect the actual `refs/heads/<branch>` tip, not session HEAD. Keep the active-rebase guard below. For a differing local tip require published-head ancestry, then walk `git -C "$ROOT" log --first-parent --format='%H %P' origin/<branch>..refs/heads/<branch>`. Require a nonempty walk, exactly two parents on every entry, and `git -C "$ROOT" merge-base --is-ancestor <second parent> origin/<baseRefName>` exit 0 for each. Require a clean existing selected worktree. A failed proof takes the existing ancestry/carries-commits-beyond stop naming repo; preserve local commits and all created legs.
@@ -26,14 +52,14 @@ Reuse the validated tip without reset, update-ref or `-b`: keep its selected tre
26
52
 
27
53
  ## Select home and stop before writes
28
54
 
29
- Consume SYNC beside the ordered array of admitted PR values, home first; use home's `headRefName` for checkout and `PRE_REWORK_HEAD=<home headRefOid>`. Carry the remaining entries as MEMBER_HEADS `{ number, url, title, headRefName, headRefOid }`. For a caller passing PR values, follow this reference instead of `using-git-worktrees/SKILL.md` Steps 0 and 1. Derive ROOT from the absolute git common directory as in Step 0, applying its submodule guard. Resolve the worktree home through the existing overrides/native-tool/wrapper contract; default to `$ROOT/.worktrees/<name>`. Set `<name>` to `headRefName` with every `/` replaced by `-`. Never adopt the session's linked tree unless it is the selected home on `headRefName`.
55
+ Consume SYNC beside the ordered array of admitted PR values, home first; use home's `headRefName` for checkout and `PRE_REWORK_HEAD=<home headRefOid>`. Carry the remaining entries as MEMBER_HEADS `{ number, url, title, headRefName, headRefOid }`. For a caller passing PR values, follow this reference instead of `using-git-worktrees/SKILL.md` Steps 0 and 1. Derive ROOT from the absolute git common directory as in Step 0, applying its submodule guard. For a marked home with a recorded block without `home:`, use [Recorded no-home provisioning](#recorded-no-home-provisioning) for selection and every add below. Otherwise resolve the worktree home through the existing overrides/native-tool/wrapper contract; default to `$ROOT/.worktrees/<name>`. Set `<name>` to `headRefName` with every `/` replaced by `-`. Never adopt the session's linked tree unless it is the selected home on `headRefName`.
30
56
 
31
57
  Run `git -C "$ROOT" fetch origin`, then check reachability and remote equality for every admitted PR (home and members) before any worktree write: require each original `headRefOid` object and `origin/<headRefName>` equal to it; use the branch-moved stop below naming that PR. Resolve `BASE_SHA=$(git -C "$ROOT" rev-parse origin/<baseRefName>)` as a full SHA before any conflict helper needs fetched-base overrides. Then check these stops in order before creating or modifying any file in the primary or a worktree, or running `git worktree add`.
32
58
 
33
59
  | Observable case | Exact stop |
34
60
  |---|---|
35
61
  | `isCrossRepository` true | `PR #N's head lives on fork <headRepository.nameWithOwner>; rework needs an in-repo branch.` |
36
- | `headRefName` listed by `git -C "$ROOT" worktree list --porcelain` at another path, including `.worktrees/pr-<N>` | `branch <headRefName> is checked out at <path>; finish or remove that worktree first.` |
62
+ | Recorded `home:` or unmarked subject, and `headRefName` listed by `git -C "$ROOT" worktree list --porcelain` at another path, including `.worktrees/pr-<N>` | `branch <headRefName> is checked out at <path>; finish or remove that worktree first.` |
37
63
  | `git -C "$ROOT" rev-parse --verify -q <headRefOid>^{commit}` fails after fetch, or `origin/<headRefName>` differs from `headRefOid` | `PR #N head <headRefOid7> is not reachable (origin/<headRefName> is at <sha7>); the branch moved.` |
38
64
  | Local branch exists without validated recovery (after recovery below; N=1 without a rework-base ref, with or without a worktree, always takes this check) and `git -C "$ROOT" merge-base --is-ancestor <headRefName> origin/<headRefName>` exits 1 | `local branch <headRefName> is at <sha7>, not an ancestor of origin/<headRefName> (<sha7>); rework needs the PR head.` |
39
65
 
@@ -114,7 +114,7 @@ If you can't list the files, the spec isn't ready: amend or redraw per brainstor
114
114
 
115
115
  ## Leg routing
116
116
 
117
- Read the home spec's `## Legs` and [the leg contract](../brainstorming/reference/legs.md) before recon. Keep the plan and `**Spec:**` header home-owned. Resolve each member's checkout from its declared primary and recorded `home:` with shared `NAME`; admit task ownership through `plan_check`, never from `design:` prose. Follow [plan-contract.md](reference/plan-contract.md#legs-leg-unknown) for `Leg:`, per-leg baselines and path keys. Repair unknown task legs in the plan, not spec membership.
117
+ Read the home spec's `## Legs` and [the leg contract](../brainstorming/reference/legs.md) before recon. Keep the plan and `**Spec:**` header home-owned. Keep home's checkout at the session's home worktree and resolve companions through [Locate a leg tree](../brainstorming/reference/legs.md#locate-a-leg-tree); admit task ownership through `plan_check`, never from `design:` prose. Stop plan writing on a failed lookup and report its reason; create no plan against a guessed checkout. Follow [plan-contract.md](reference/plan-contract.md#legs-leg-unknown) for `Leg:`, per-leg baselines and path keys. Repair unknown task legs in the plan, not spec membership.
118
118
 
119
119
  Re-walk every task's `Files:` using Gather rules in the leg contract. Append extra task `Rules:` and resolve `Rules: root only - paths unresolved`; retain missing-link evidence. Split mixed waves into consecutive single-leg waves without violating dependencies.
120
120
 
@@ -13,7 +13,7 @@ A wave is a maximal set of tasks that have no ordering dependency on each other,
13
13
 
14
14
  Read the home spec's `## Legs` using [the leg contract](../../brainstorming/reference/legs.md). Write `Leg: <repo>` immediately after each task heading, before `**Files:**`; absence means home. Keep the plan and its `**Spec:**` header at home, citing the home spec. Repair a `leg-unknown` task in the plan, never by adding spec membership.
15
15
 
16
- Write one `Baseline <repo>: <sha>` header per member. Match each task's baseline bullets to its own leg's SHA; require equality within a leg, not across legs. Resolve `Modify:`/`Create:`/`Test:`/`Delete:` paths and globs against the admitted leg checkout, using its recorded `home:` with shared `NAME` against its declared primary. Key file overlap and cross-task created anchors on `(leg, path)`.
16
+ Write one `Baseline <repo>: <sha>` header per member. Match each task's baseline bullets to its own leg's SHA; require equality within a leg, not across legs. Resolve `Modify:`/`Create:`/`Test:`/`Delete:` paths and globs against the admitted leg checkout from [Locate a leg tree](../../brainstorming/reference/legs.md#locate-a-leg-tree), keeping home at the session's home worktree. Stop plan writing on a failed lookup and report its reason; create no plan against a guessed checkout. Key file overlap and cross-task created anchors on `(leg, path)`.
17
17
 
18
18
  Split mixed waves into consecutive leg-homogeneous waves, preserving dependencies. Re-walk each task's `Files:` under its leg using the leg contract's Gather rules procedure. Append task `Rules:` for files missing from the spec list; resolve `Rules: root only - paths unresolved`. Read the combined lists before execution and review.
19
19
 
@@ -1,53 +0,0 @@
1
- # gatekeep-pr: step 6 - menu
2
-
3
- Read from SKILL.md step 6 with `menus.md`. Execute through `post-selection-loop.md` `### Next action`; recommendations confer no authority.
4
-
5
- ## Verbs
6
-
7
- Read and apply [menu-layout](../../brainstorming/reference/menu-layout.md) before presenting rows and before numeric lookup. Render `<n>. <verb> - <consequence>` using the selected `menus.md` template. Keep `show evidence` hint-only and queued wait solely in the merge queued template.
8
-
9
- - `assess` - post the current open Blockers with locators as one head-pinned review through `post-selection-loop.md` `### Fix wave`; with zero blockers post nothing, then render assess terminal. Perform no repair or sync. Keep C# thread replies behind reply.
10
- - `deliver` - run the persistent delivery course through readiness, obstacle, or cap; at an obstacle continue under the cumulative accounting rules in `fix-wave.md` `## Wave`.
11
- - `deliver with nits` - store deliver-nits and include every current and subsequently minted nit in delivery.
12
- - `fix nits` - authorize exactly one delivery iteration without changing course; initialize missing accounting from `fix-wave.md` `## Wave` before work.
13
- - `accept contract change` - invoke the proposal's owning amendment through `### Contract decision`; update the baseline only after completion.
14
- - `preserve contract` - keep the baseline and independent blockers; resume scope-preserving course work without the rejected payload on that re-run.
15
- - `approve` - approve someone else's non-draft PR with zero blockers; persist approved_head only after success.
16
- - `approve workflow run` - execute `gh api --method POST repos/<base-owner>/<base-repo>/actions/runs/<id>/approve`, then refresh and watch under the course.
17
- - `merge` - execute `gh pr merge --match-head-commit <assessed-sha>` with the resolved policy flag and all merge preconditions; append `--admin` only on the bypass path defined in `post-selection-loop.md` `### Merge course`; never infer approval from a setting.
18
- - `reply` - post drafted replyable C# replies; exact `reply <n>` selects one.
19
- - `post coverage to ticket` - post the rendered AC coverage block through the resolved tracker verb; renders only under the `own merge` template with issue and rows.
20
- - `post coverage to PR` - post the same block with `gh pr comment <N> --body-file`; renders only under the `own merge` template.
21
- - `cleanup` - run `cleanup.md` behind a terminal pick; name each resolved cleanup override command in the consequence, or say "tear down the gate's checkout and local branch (untracked files there are deleted)" with no override.
22
- - `stop` - run `### Teardown`; delegate non-final stop to `cleanup.md` `## Non-final stop`, keeping terminal behavior distinct.
23
-
24
- ## Availability
25
-
26
- Derive availability from the digest's permissions; `unreadable` fails closed. Omit unavailable rows and name concrete reasons in `Not offered:`; never render an unavailable row with a suffix.
27
-
28
- | Row | Available when |
29
- |---|---|
30
- | `assess` | initial or obstacle course selection |
31
- | `deliver`, `deliver with nits` | helpers exist, maxFixRounds is positive, head_pushable is true; deliver with nits additionally needs nits; use the template's continuation rules at an obstacle |
32
- | `fix nits` | final template, nits remain outside the course, helpers and head_pushable true, accounting permits one iteration |
33
- | `accept contract change`, `preserve contract` | pending recorded contract exception |
34
- | `merge` | non-draft, viewer_permission `WRITE`, `MAINTAIN`, or `ADMIN`, all `### Merge preconditions` hold |
35
- | `approve` | viewer.is_author false, zero blockers, non-draft |
36
- | `approve workflow run` | held run on assessed head and viewer_permission `WRITE`, `MAINTAIN`, or `ADMIN` |
37
- | `reply` | drafted reply exists and source review complete |
38
- | `cleanup` | terminal template and cleanup_done false |
39
- | `post coverage to ticket`, `post coverage to PR` | own merge template, not previously successful; ticket also needs issue and rows |
40
- | `stop` | every template |
41
-
42
- ## Withhold reason resolver
43
-
44
- Resolve every actual unmet `### Merge preconditions` reason through `post-selection-loop.md` `### Exit check`. Keep repairable gaps in the course, not a false readiness caused by missing WRITE permission. Render one concrete reason and locator rather than spinning.
45
-
46
- | Observation | Render |
47
- |---|---|
48
- | BLOCKED with no eligible bypass and no local repair | Use findings.md `## Dispositions` for the actor-framed PR-comments line and obstacle verdict; render obstacle even with course unset, plus `Not offered: merge (blocked by GitHub)`; never attribute a named rule |
49
- | UNKNOWN/unreadable after one re-poll | `stuck - merge state unknown`; `Not offered: merge (merge state unknown)` |
50
- | binding pending check | name the check under PR comments, `Not offered: merge (<check name> pending)`; watch only at delivery step 4 |
51
- | draft | `Not offered: merge (draft)` |
52
- | below WRITE | `Not offered: merge (needs WRITE on <owner>/<repo>)` |
53
- | other failed prerequisite | name its actual missing evidence/input or unsafe-state obstacle from Exit check |