pi-gauntlet 8.4.7 → 8.4.9

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.
@@ -1,114 +1,46 @@
1
1
  # gatekeep-pr: step 5 - report
2
2
 
3
- Read from SKILL.md step 5, after `findings.md`. Input: the integration output. Output: the rendered report, then the menu (`decision-menu.md`). SKILL.md `## Wording rules` bind every line.
3
+ Read after `findings.md` at step 5. Render report, then `menus.md`; apply SKILL.md's wording rules.
4
4
 
5
- ## Order
5
+ ## Report
6
6
 
7
- Render bottom-up for a terminal: least important first, verdict and menu last. Empty sections are omitted - never "None". A failed comment refresh, an incomplete comment source review (`post-selection-loop.md` `### Re-render`), a blocked or unknown merge state, or a binding pending check renders its one line under `PR comments` as well.
7
+ Write whole sentences in three unlabeled parts: change and scope, standing and problems, then a recommendation. Omit empty sections; number findings when two or more problems block merging.
8
8
 
9
- For an eligible BLOCKED merge, omit the blocked PR-comments line; resolve eligibility through `post-selection-loop.md` `### Merge preconditions` and render the bypass consequence through `menus.md` `## final`. For false or unreadable eligibility, render the actor-framed BLOCKED line below and `Not offered: merge (blocked by GitHub)` unchanged. Keep `bypass_eligible` and its value only in the digest `permissions` block; never name the field in rendered output, including obstacle explanations and `show evidence`.
9
+ Preserve:
10
10
 
11
- Section order is fixed:
11
+ - Render the opening as one paragraph of exactly two sentences. Describe the change first; fold the role into either sentence. In the second, explain covered and deferred behavior, its references, deliberate deviations and their reasons, behavior handled elsewhere and its repositories, and observations checked after merge; name the behavior, never a row number. Count a covered mechanism as covered even when its observation waits; say when nothing is covered. Keep row numbers and detailed mapping under `show evidence` or in the posted `AC coverage` checklist.
12
+ - In that opening, state whether the viewer is the author, a requested reviewer, neither, or unreadable, using refreshed `viewer.role` and `pr.review_requests`. Keep other requested users and teams in API order: exclude the viewer by case-insensitive User login comparison, exclude nobody when that login is unreadable, render Users by login and Teams by slug, and use `unknown` for a missing login or slug. Say, for example, "You are a requested reviewer; robin and acme/reviewers are also requested." Omit the list when empty.
13
+ - Start the second part with the standing sentence: nothing blocks merging, a count of problems to fix, or the one thing it waits on. Supply this sentence unchanged to the set parent's summary. Explain each problem in one or two sentences with one concrete example; retain the exact supplied failing test name and its file, or the file when no test name was supplied. Retain supplied path:line locators for every problem and nit. Print a compact exact old-to-new description preview under its blocker for consent; retain a declined proposal's preview on every re-render until the claim resolves.
14
+ - Explain replyable PR comments and the drafted reply's meaning, a pending reviewer run, a failed refresh or incomplete source review, and any merge prerequisite that still blocks progress. Follow with any wait, sync and prior-review results, and PR-named after-merge steps. Keep nits distinct and name their count and the offered action that can take them.
15
+ - For a non-null `prior_review`, count addressed items from distinct resolved `R#` entries and the supplied total. For an ancestor, say how many were addressed; with nonzero items and `prior_review.commit == headRefOid`, also say there are no commits since that review. With zero items, say that review posted no items and the changes since it were reviewed. For a baseline that is not an ancestor, retain the reason from `assessment.md` `## Prior-review ancestry` and that the whole diff was reviewed. Omit the prior-review sentence when null.
16
+ - Only with `--rebase`, explain the sync outcome, including resolved files on success and the actual reason on a skip, decline or failure. Translate the digest's status into prose; keep its exact value in the evidence record. Do not invent a sync result on loop re-entry.
12
17
 
13
- Read and apply [menu-layout](../../brainstorming/reference/menu-layout.md) before presenting these options and before acting on a numeric reply.
18
+ For eligible BLOCKED readiness, omit the blocked comment and explain the admin override through `menus.md` `## final`. For WRITE or MAINTAIN, name override eligibility, not admin rights. With unreadable eligibility and green CI, say required checks passed independently of GitHub's block. Otherwise say GitHub blocks this actor from merging; never invent a named rule. Keep `bypass_eligible` and its value in the digest's permissions only, including when answering `show evidence`. Resolve other unavailable actions through `menus.md` and explain their actual missing prerequisites in prose, not a separate omission line.
14
19
 
15
- ```
16
- Delivers: <one sentence: what the PR does. With source: spec, a second sentence built from these clauses in
17
- order, each present only when it applies, joined with semicolons: covered rows ("ACs 1, 2, 4";
18
- "ACs 1-5" when every row is covered; "no ACs" when none; a row whose mechanism half is covered
19
- counts in the covered list and its observation half adds the trailing clause); deferred rows grouped by ref, in row
20
- order ("3, 5 deferred per spec to <ref>"); deviating rows ("2 deviates per spec: <why>"); elsewhere rows grouped by repo ("6 elsewhere per spec: <repo>");
21
- observation halves ("4's observable half (<what>) is checked after merge, not here").>
20
+ ## Standing
22
21
 
23
- Role: <author | requested reviewer | none | unreadable>
22
+ Put part three's recommendation sentence and reason immediately above `Pick one:`; follow `menus.md`. Name a running required check or unchanged obstacle, not readiness. Translate verdict and exit state into prose.
24
23
 
25
- PR comments: (replyable review comments, a pending reviewer run, a blocked or unknown merge state, a binding pending check, a failed refresh, or an incomplete source review - see the paragraph above)
26
- - <reviewer>'s comment on <topic> <verdict clause>, so the drafted reply <what it says>. (<locator>)
27
- - The reviewer run is still in progress, so merge waits. (<run url>)
28
- - GitHub reports this actor's merge as blocked, so merge waits. (merge_state_status BLOCKED; reviewDecision <value>)
29
- - <other applicable line from decision-menu.md `## Withhold reason resolver`>
30
-
31
- Nits: (after the list, one line `<N> nits open - fix nits to take them` (`1 nit open` for one); rendered only while the `fix nits` row renders.)
32
- - <1-2 sentences>. (<file:line>)
33
-
34
- Prior review: <baseline outcome> (non-null prior_review only; forms and placement below)
35
-
36
- Blockers: (numbered; menu picks reference these numbers)
37
- 1. <1-2 sentences: what is wrong, why it matters>. (<file:line and exact supplied test name for a failing test; file only when no test name was supplied> | <check name> | <doc path>)
38
-
39
- Description: <optional concise non-blocking uncertainty: author assertion versus what the gate cannot verify>
40
-
41
- Sync: <digest's sync field value verbatim; optional explanation after it as a second clause or sentence; only when --rebase was passed>
42
-
43
- Verdict: mergeable - <evidence clause> | fixable - <N> blockers | not ready - <withhold reason>
44
-
45
- <menu>
46
- ```
47
-
48
- Print exactly one `Role:` directly under `Delivers` on every report from the refreshed `viewer.role` and `pr.review_requests`; append `(also requested: <entries>)` for requested reviewer, `(requested: <entries>)` otherwise, omitted when `<entries>` is empty. `<entries>`: the User and Team entries other than the viewer, API order (Keep API order, exclude the viewer by case-insensitive User login comparison, exclude nobody when the login is unreadable), User as login, Team as `slug`; render missing login/slug as `unknown`. Example: `Role: requested reviewer (also requested: robin, acme/reviewers)`.
49
-
50
- Render `Sync:` only when `--rebase` was passed. Open the `Sync:` line with the digest's `sync` field value verbatim (for example `Sync: declined - other author's branch`). Put any explanation after that value as a second clause or sentence. Never paraphrase the status value into prose. Exempt `Sync:`, `Role:`, and `Prior review:` from SKILL.md wording rule 5 (passing facts only under `show evidence`): name the resolved files even when the sync succeeded.
51
-
52
- For a non-null `prior_review`, print exactly one `Prior review:` line directly
53
- above `Blockers` when it renders; otherwise directly above the obstacle `Evidence:` line when that line renders; otherwise directly above `Verdict`:
54
-
55
- | Ancestry result | Line |
56
- |---|---|
57
- | `delta: ancestor` | `Prior review: <k> of <n> items addressed`; count `k` from distinct `R#` items recorded resolved through `findings.md` **Prior-item closure**, and `n` from the supplied item count. For nonzero items, append ` - no commits since <sha7>` whenever `prior_review.commit` equals `headRefOid`, regardless of `k`. For zero items use `Prior review: no items posted at <sha7>; the delta since it was reviewed`. |
58
- | `delta: not ancestor (<reason>)` | `Prior review: baseline <sha7> is not an ancestor of the head (<reason>), so the whole diff was reviewed`; carry the reason from `assessment.md` `## Prior-review ancestry` verbatim. Use `unknown` for a null review commit. |
59
-
60
- With `prior_review: null`, print no `Prior review:` line.
61
-
62
- For obstacle reports, print exactly one `Evidence:` line naming the resolved evidence source and the assessed head, immediately before the verdict (for example `Evidence: CI (run 7001, test_unit and build_image green on 9c1e4f2)`). Use the resolved local verification summary instead when local evidence owns the assessment; do not invent a passing result when evidence is unavailable. Carry the same source summary into the obstacle menu's evidence hint. Exempt this compact source summary and the final template's `Evidence:` line from the evidence-only rules below and SKILL.md wording rule 5; keep the full record under `show evidence`.
63
-
64
- ## Verdict
65
-
66
- For ordinary assessments, use `mergeable`, `fixable`, or `not ready`. Carry the mergeable evidence clause from `findings.md` `## Provenance`: `CI green on the assessed head (<check name>)` or `verification command passed locally`. Name the blocker count or concrete unmet prerequisite for fixable/not-ready assessments. Delegate obstacle/cap verdicts to `post-selection-loop.md` `### Exit check` and menu verdicts to `menus.md`.
67
-
68
- `<N> blockers` reads `1 blocker` for one.
24
+ Explain standing with true evidence: distinguish CI from local runs and never turn pending or missing evidence into a pass. Put raw check conclusions, run URLs, head, prior-review and sync SHAs, pending-check counts, repair/sync usage counters and raw field/value pairs under `show evidence`, not in report prose, a separate evidence line or a hint parenthetical. A pending reviewer's run URL may still locate its comment. Apply the same rule to obstacle and final reports.
69
25
 
70
26
  ## What stays out
71
27
 
72
- Verbatim command output stays in its `log_path` file and never prints; `show evidence` prints its `show evidence: <log_path>` line instead. CI run URLs and conclusions (the pending-reviewer locator in `PR comments` is the one URL that prints in the report), drafted file edits and full description bodies, drafted replies, matched claims, per-row AC outcomes, internal IDs, and disposition annotations print only under the `show evidence` command. A clean run with a spec renders `Delivers`, `Role`, the applicable `Prior review:` line, the verdict line, and the menu.
73
-
74
- Print the compact exact old-to-new description preview under its blocker; keep the full replacement body under `show evidence`. Keep a declined correction's proposal open and its preview line under the blocker on every re-render until the claim resolves. Uncertainty alone preserves the mergeable verdict.
75
-
76
- Print `state: <absolute-path>` under `show evidence`, followed by the run record's course, immutable target, stored scope baseline, cumulative round/sync usage and caps, deadline, wave checkpoints and failed-prerequisite history. Then print, in this order: the evidence record (CI: each satisfying check's name, conclusion, SHA, run URL; local: each run's command, `result`, `exit_code`, and one `show evidence: <log_path>` line pointing at its captured output - never the output itself); claim dispositions; AC outcomes per row and the `cross-check:` line (`assessment.md` `## Select the scope contract`); check dispositions; drafted payloads keyed by the blocker or nit number they fix; drafted replies keyed by the `PR comments` item they answer.
77
-
78
- ## Worked example
79
-
80
- Own PR, ticket gh-45:
81
-
82
- ```
83
- Delivers: the reports page exports CSV on demand. ACs 1, 2, 4; 3 deferred per spec to acme/widgets#46; 4's observable half (export completes under 5s on production data) is checked after merge, not here.
84
- Role: author
85
-
86
- PR comments:
87
- - maria's comment on the missing CSV header is already addressed, so the drafted reply points her at the fix. (3f2a1c0)
88
-
89
- Nits:
90
- - The export pages results with its own loop instead of the shared paging helper, so a paging bug fixed once would need fixing twice. (src/api/export.ts:31, lib/page.ts)
91
- 1 nit open - fix nits to take them
92
-
93
- Blockers:
94
- 1. The export endpoint ships with no test, so nothing proves it works and nothing
95
- catches it breaking. (src/api/export.ts:10-58)
96
- 2. The export guide still says exports run nightly; the PR makes them on-demand, so a
97
- reader following the docs waits for a job that no longer exists; the doc fix is drafted.
98
- (docs/exports.rst:88)
99
-
100
- Verdict: fixable - 2 blockers
101
-
102
- ```
103
-
104
- A clean own PR with ticket gh-45 and CI green:
105
-
106
- ```
107
- Delivers: the reports page exports CSV on demand. ACs 1-5.
108
- Role: author
109
-
110
- Verdict: mergeable - CI green on the assessed head (test)
111
-
112
- ```
113
-
114
- Render the initial example and every later menu from `menus.md`; keep all evidence-only details under the hint command. Preserve bottom-up report order before the selected template.
28
+ Verbatim command output stays in its `log_path` file and never prints; `show evidence` prints its `show evidence: <log_path>` line instead. Keep full drafted file edits, description bodies and replies, matched claims, per-row AC outcomes, internal IDs and check classifications behind that command. An author assertion the gate cannot verify is non-blocking uncertainty, not a fabricated finding.
29
+
30
+ Under `show evidence`, print `state: <absolute-path>`, then the run record's course, immutable target, stored scope baseline, cumulative round/sync usage and caps, deadline, wave checkpoints and failed-prerequisite history. Follow with the prior-review and sync records, retaining their SHAs, and the evidence record (CI: each satisfying check's name, conclusion, SHA and run URL; local: each run's command, `result`, `exit_code` and `show evidence: <log_path>`); claim dispositions; AC outcomes and `cross-check:` from `assessment.md` `## Select the scope contract`; check dispositions; drafted payloads keyed by blocker or nit; drafted replies keyed by comment. Keep these records inspectable without copying them into the report.
31
+
32
+ ## Example
33
+
34
+ > This PR adds an on-demand CSV export button. The spec defers scheduled exports to acme/widgets#46, and the speed target needs checking after merge; you and robin are requested reviewers.
35
+ >
36
+ > One problem blocks merging: the description says "Exports run nightly", but the button exports on demand. The correction is "Exports run when you click Download." One smaller point does not block merging: the export repeats a shared helper's paging code.
37
+ >
38
+ > I recommend deliver because the description's correction is ready.
39
+ >
40
+ > Pick one:
41
+ > 1. deliver - apply the drafted description fix, merge main into the branch if it falls behind, watch the checks, and continue until merge is offered. [recommended]
42
+ > 2. deliver with nits - the same, and also replace the repeated paging code.
43
+ > 3. assess - post the problem to the PR as a review and make no repairs.
44
+ > 4. stop - remove the worktree and leave the PR as it is.
45
+ >
46
+ > Type a number; show evidence prints the full record.
@@ -81,4 +81,4 @@ Triggers: an unresolved stop, `open` for any reason other than a failing scoped
81
81
 
82
82
  ## Sync record
83
83
 
84
- The digest's `sync` field is one of: `rebased <pre_head7>..<new_head7> onto origin/<base>, <n> stop(s) resolved in <files>, <m> commit(s) dropped as already applied`, `rebased locally <pre_head7>..<new_head7> onto origin/<base>, ..., scoped tests red in <file>: <tests>` (the plain `rebased ...` form is this record with the `scoped tests red in` clauses removed), `no-op - ...` (short form `sync: no-op`), `skipped - ...` (`sync: skipped`), `declined - ...` (`sync: declined`), `failed - ...` (for example `sync: failed - reviewer: ...` or `sync: failed - push rejected: <first server line>`), `stopped - ...`. `report.md` renders it as the `Sync:` line immediately before `Verdict:`. `<m>` is `git rev-list --count origin/<base>..<pre_head>` minus `git rev-list --count origin/<base>..HEAD`; omit the stops clause when no stop occurred.
84
+ The digest's `sync` field is one of: `rebased <pre_head7>..<new_head7> onto origin/<base>, <n> stop(s) resolved in <files>, <m> commit(s) dropped as already applied`, `rebased locally <pre_head7>..<new_head7> onto origin/<base>, ..., scoped tests red in <file>: <tests>` (the plain `rebased ...` form is this record with the `scoped tests red in` clauses removed), `no-op - ...` (short form `sync: no-op`), `skipped - ...` (`sync: skipped`), `declined - ...` (`sync: declined`), `failed - ...` (for example `sync: failed - reviewer: ...` or `sync: failed - push rejected: <first server line>`), `stopped - ...`. `report.md` translates this record into a prose sync outcome before the standing sentence, preserving resolved files and failure reasons; keep the exact status in `show evidence`. `<m>` is `git rev-list --count origin/<base>..<pre_head>` minus `git rev-list --count origin/<base>..HEAD`; omit the stops clause when no stop occurred.
@@ -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
 
@@ -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 |