pi-gauntlet 7.32.1 → 7.33.0
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.
- package/CHANGELOG.md +6 -0
- package/README.md +7 -5
- package/agents/pr-gatekeeper.md +2 -2
- package/extensions/lib/gauntlet-settings.test.ts +4 -4
- package/extensions/lib/gauntlet-settings.ts +1 -1
- package/extensions/phase-tracker.test.ts +5 -5
- package/package.json +1 -1
- package/skills/gatekeep-pr/SKILL.md +11 -11
- package/skills/gatekeep-pr/reference/assessment.md +2 -2
- package/skills/gatekeep-pr/reference/batch.md +11 -9
- package/skills/gatekeep-pr/reference/cleanup.md +19 -1
- package/skills/gatekeep-pr/reference/decision-menu.md +38 -160
- package/skills/gatekeep-pr/reference/findings.md +6 -4
- package/skills/gatekeep-pr/reference/fix-wave.md +24 -27
- package/skills/gatekeep-pr/reference/menus.md +80 -0
- package/skills/gatekeep-pr/reference/post-selection-loop.md +89 -46
- package/skills/gatekeep-pr/reference/report.md +13 -19
- package/skills/gatekeep-pr/reference/sync.md +15 -6
- package/skills/gatekeep-pr/verification-brief.md +13 -11
- package/skills/verification-before-completion/reference/conformance-check.md +1 -1
- package/skills/verification-before-completion/reference/settings-precedence.md +1 -1
|
@@ -1,175 +1,53 @@
|
|
|
1
1
|
# gatekeep-pr: step 6 - menu
|
|
2
2
|
|
|
3
|
-
Read from SKILL.md step 6
|
|
3
|
+
Read from SKILL.md step 6 with `menus.md`. Execute through `post-selection-loop.md` `### Next action`; recommendations confer no authority.
|
|
4
4
|
|
|
5
5
|
## Verbs
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
- `
|
|
16
|
-
- `
|
|
17
|
-
- `
|
|
18
|
-
- `
|
|
19
|
-
- `
|
|
20
|
-
- `
|
|
21
|
-
- `
|
|
22
|
-
- `
|
|
23
|
-
- `update branch` - `gh pr update-branch <N>`, then fast-forward the worktree to the new head (`fix-wave.md` `## Conflicts`); renders on a conflict with no wave commit, or when `merge_state_status` is `BEHIND` at the merge preconditions
|
|
24
|
-
- `merge base` - retain merging the recorded base and resolving conflicts through reviewed helper work and push during this run until readiness or a new decision boundary (`fix-wave.md`)
|
|
25
|
-
- `merge` - `gh pr merge --match-head-commit <assessed-sha>` with the flag of the resolved `merge policy` (`squash` -> `--squash`, `merge-commit` -> `--merge`, `rebase` -> `--rebase`; default squash); preconditions per `post-selection-loop.md` `### Merge preconditions`, including the repo allowing that method
|
|
26
|
-
- `merge anyway` - merge while the pending-reviewer overlay withholds it; prints what it overrode
|
|
27
|
-
- `reply` - post the drafted replies under `PR comments` (`reply <n>` for one)
|
|
28
|
-
- `post coverage to ticket` - post the rendered `AC coverage` block as a comment on the source ticket via the resolved tracker verb (`gh issue comment`, the overrides' tracker mapping, or `/skill:linear`); renders only under the `own merge` overlay
|
|
29
|
-
- `post coverage to PR` - post the same block with `gh pr comment <N> --body-file`; renders only under the `own merge` overlay
|
|
30
|
-
- `cleanup` - tear down the gate's checkout and local branch per `cleanup.md`, then run the repo's `## cleanup` steps in order; the consequence clause names each override step as `<label> (<resolved command>)` with placeholders already substituted, so the exact tracker comment or release invocation is visible before the pick; with no `## cleanup` section the clause reads `tear down the gate's checkout and local branch (untracked files there are deleted)`
|
|
31
|
-
- `show evidence` - print the evidence record, claim and AC outcomes, dispositions, drafted payloads and replies (`report.md` `## What stays out`)
|
|
32
|
-
- `wait` - run one bounded `gh pr checks --watch` on every **binding** pending check in the resolved set (required or not), then re-render
|
|
33
|
-
- `stop` - leave the PR as-is; under a terminal overlay leave the checkout as found and print one line naming the leftover worktree path and local branch; on an ordinary open-PR menu with a `rebased locally` head run `git reset --hard <pre_head>` before `### Teardown`, discarding the rewrite and any unpushed fix commits, and assert `HEAD == <pre_head>` with a clean tree; a mismatch is the existing hard stop with the error, and the remote stays untouched
|
|
34
|
-
|
|
35
|
-
Compose hint: `Type a number, or compose: "fix 2", "fix nits", "fix + nits", "fix 1 + reply". Not offered: push (needs push to <head_url>:<head_ref>), merge (needs WRITE on <owner>/<repo>).` The first sentence lists only compositions whose every verb is a rendered row: `fix nits` and `fix + nits` appear only when both the `fix` and `fix nits` rows render; no `reply` row, no `fix 1 + reply`; no composable row, `Type a number.` alone. The second sentence names every omitted row as `<verb> (<why it is omitted>)` and is dropped when nothing is omitted. `merge anyway` renders as its own row when `## Availability` allows it, so the rendered-row rule does not apply to it. Offer `revoke fix` and `revoke merge base` compose forms for held grants, persisting only the named revocation through the loop. A composed line never bundles a push-producing verb (`fix`, `fix nits`, `push`, `merge base`) with `merge`. When a failing check withholds `merge`, the hint line also offers `check <name> flaky | real | ci-broken`, which records the disposition on that check (`findings.md` `## Dispositions`): `flaky` lifts the blocker, `real` keeps it until green, `ci-broken` triggers the fallback local run (`ci-broken` records `ci-infrastructure-broken`).
|
|
36
|
-
|
|
37
|
-
A composed line naming an omitted row is refused by name and the menu re-renders; the `merge anyway` row is the only override.
|
|
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 review through `review`; use `gh pr review --request-changes` for someone else's/bot PR and `--comment` on the human's own PR; 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; 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.
|
|
38
23
|
|
|
39
24
|
## Availability
|
|
40
25
|
|
|
41
|
-
|
|
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.
|
|
42
27
|
|
|
43
28
|
| Row | Available when |
|
|
44
29
|
|---|---|
|
|
45
|
-
| `
|
|
46
|
-
| `
|
|
47
|
-
| `fix nits` |
|
|
48
|
-
| `
|
|
49
|
-
| `
|
|
50
|
-
| `
|
|
51
|
-
| `
|
|
52
|
-
| `
|
|
53
|
-
| `
|
|
54
|
-
| `
|
|
55
|
-
| `
|
|
56
|
-
| `approve`, `review`, `reply`, `post coverage to ticket`, `post coverage to PR`, `show evidence`, `wait`, `stop` | per the consent table and overlays below |
|
|
57
|
-
|
|
58
|
-
## Consent table
|
|
59
|
-
|
|
60
|
-
Authorship moves only `[recommended]`, never which rows are offered. The first rendered row is `[recommended]`; when every other row is `show evidence`, `stop` is `[recommended]`.
|
|
61
|
-
|
|
62
|
-
A `fixable` verdict with zero blockers (a withhold reason) uses the mergeable rows with `merge` omitted; the reason stays in the verdict line (`report.md`) and in the `Not offered:` sentence. On such a withhold, `[recommended]` goes to `approve workflow run` under the held-run overlay, else to `approve` or `wait` under the merge state overlay, else to `wait` under the verification-evidence-pending, pending-reviewer, or binding-pending-check overlay, else to `stop`.
|
|
63
|
-
|
|
64
|
-
| Author | Verdict | Rows |
|
|
65
|
-
|---|---|---|
|
|
66
|
-
| you | mergeable | `merge`; `fix nits`; `reply` (when a drafted reply exists); `show evidence`; `stop` |
|
|
67
|
-
| you | fixable | `fix`; `fix nits`; `review`; `reply` (when a drafted reply exists); `show evidence`; `stop` |
|
|
68
|
-
| someone else | mergeable | `approve`; `fix nits`; `merge`; `reply` (when a drafted reply exists); `show evidence`; `stop` |
|
|
69
|
-
| someone else | fixable | `review`; `fix`; `fix nits`; `reply` (when a drafted reply exists); `show evidence`; `stop` |
|
|
70
|
-
|
|
71
|
-
Add `fix` to mergeable rows only for an explicitly requested exact clarification; a clarification-only selection grants that payload and no ongoing blocker grant. Add available `merge base` to applicable main row sets without a fake blocker or empty fix. With no held strategy, prefer available `update branch`, otherwise recommend available `merge base`; higher safety overlays keep their recommendation. Preserve a held merge-base strategy, never replace it with update branch or rerun --rebase step 2b.
|
|
72
|
-
|
|
73
|
-
`push` joins any row set after `fix` or `fix nits` when unpushed fix commits sit in the worktree.
|
|
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 |
|
|
74
41
|
|
|
75
42
|
## Withhold reason resolver
|
|
76
43
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
1. `merge_state_status` is `BLOCKED` -> line `GitHub reports this actor's merge as blocked, so merge waits. (merge_state_status BLOCKED; reviewDecision <value>)`, `Not offered: merge (blocked by GitHub)`, reason `blocked by GitHub`. `reviewDecision` rides as a locator only - never as a claim about which rule blocks, and no rendered sentence says another developer's approval is required.
|
|
80
|
-
2. `merge_state_status` is `UNKNOWN` or `unreadable`, or the pre-menu refresh failed -> line `GitHub has not reported this actor's merge state, so merge waits. (merge_state_status <value>)` (on a failed refresh the locator is `merge state not refreshed (<reason>)`), `Not offered: merge (merge state unknown)`, reason `merge state unknown`.
|
|
81
|
-
3. a binding pending check (`../verification-brief.md` Section B, binding classification) -> line `A check that binds this actor is still pending, so merge waits. (<check name>)`, `Not offered: merge (<check name> pending)`, reason `binding check pending`.
|
|
82
|
-
|
|
83
|
-
## Overlays
|
|
84
|
-
|
|
85
|
-
For a pending contract exception, print the concrete proposed contract change before the rows, using the recorded proposal; numeric and typed picks select these actual rows and route to `post-selection-loop.md` `### Contract decision`. Render the `preserve contract` consequence as "reject the proposal, keep <named requirement>, and resume authorized implementation repair within it". Existing terminal/sync stops take precedence; otherwise the contract-exception overlay replaces ordinary rows, and lower overlays cannot discard its decision rows.
|
|
86
|
-
|
|
87
|
-
Apply overlays to the consent row; take additional rows only from a terminal overlay (`cleanup` and the post-coverage rows) or the pending `contract exception` (contract-decision rows). When two apply, the one higher in this table wins the `merge` reason and `[recommended]`.
|
|
88
|
-
|
|
89
|
-
| Overlay | Trigger | Effect |
|
|
90
|
-
|---|---|---|
|
|
91
|
-
| own merge | this run's `merge` pick ran and the post-merge read (`post-selection-loop.md` `### Merge course`) returned `state: MERGED` | the menu is `cleanup` `[recommended]`, `post coverage to ticket` (when `issue` is non-null and `scope.rows` is non-empty), `post coverage to PR`, `show evidence`, `stop`; each post row renders once and leaves the menu after its post succeeds, and a successful post re-renders this menu - posting never tears down and never ends the run; a failed post keeps its row and prints the `gh` error; no compare-and-swap runs before a post |
|
|
92
|
-
| merge queued | this run's `merge` pick ran and the post-merge read returned a state other than `MERGED` | the menu is `wait` (re-run the post-merge read, then re-render), `show evidence`, `stop`, with `wait` `[recommended]`; one `PR comments` line `The merge is queued, so coverage posts wait. (<state>)` |
|
|
93
|
-
| approved | the continuation record's `approved_head` equals the assessed head (`post-selection-loop.md` sets it only when `gh pr review --approve` exits 0, before the re-render; a non-zero exit prints the `gh` error and the ordinary menu re-renders) | the menu is `cleanup` `[recommended]`, `show evidence`, `stop` |
|
|
94
|
-
| merged or closed PR | `state` was not `OPEN` at step 1 | the report renders; the menu is `cleanup` `[recommended]`, `show evidence`, `stop` |
|
|
95
|
-
| contract exception | a recorded contract exception is pending, with no terminal/sync stop | replace the ordinary menu with `accept contract change`, `preserve contract`, `show evidence`, `stop`; recommend `preserve contract`; use `post-selection-loop.md` `### Contract decision` for every selection |
|
|
96
|
-
| draft PR | `isDraft` | `merge` and `approve` are omitted (`Not offered: merge (draft)`, plus `approve (draft)` when the consent row holds `approve`) and never carry `[recommended]`; `review` is recommended on someone else's fixable draft, `fix nits` on their mergeable draft when a nit exists, else `stop`; on your own, `fix` when a blocker exists, else `stop` |
|
|
97
|
-
| held run | an `action_required` conclusion on an Actions run of the assessed head (`../verification-brief.md` Evidence resolution, Held run) with no `local run: held run not approvable` evidence yet for that head | `approve workflow run` renders as row 1 when available (`## Availability`) and is `[recommended]` when `Blockers` is empty, else `[recommended]` stays on the consent row's first row; `merge` is omitted (`Not offered: merge (workflow run awaiting approval)`); once the held-run-not-approvable local run exists, this overlay no longer applies and `merge` follows the preconditions |
|
|
98
|
-
| merge state | `merge_state_status` is `BLOCKED`, `UNKNOWN`, or `unreadable`, or the pre-menu refresh failed (`post-selection-loop.md` `### Pre-menu refresh`) - independent of any pending check, so a green-CI state-only block fires it | one `PR comments` line from `## Withhold reason resolver` (reason 1 or 2); `wait` as row 1; `[recommended]` goes to `approve` when the consent row renders it (someone else's PR, resolver reason 1, `reviewDecision` `REVIEW_REQUIRED`) - recommending a row attributes nothing to a rule - else to `wait` when `Blockers` is empty; `merge` omitted with the resolver's `Not offered` text; no `anyway` row |
|
|
99
|
-
| verification evidence pending | the Evidence resolution table resolved Pending for the assessed head (`../verification-brief.md` Section B) | puts `wait` as row 1 and, when `Blockers` is empty, `[recommended]`; `merge` is omitted with `## Withhold reason resolver` reason 3's text; consent rows otherwise unchanged |
|
|
100
|
-
| CI check | an undispositioned failing check in the resolved set, or a binding pending check (`findings.md` `## Dispositions`); a held run is not a binding pending check here (the `held run` overlay owns it) | on a failing check, the hint line offers `check <name> flaky \| real \| ci-broken`; `merge` is omitted (`Not offered: merge (<check name> failing)`); `flaky` restores `merge` on the next render; `real` and `ci-infrastructure-broken` keep it omitted until green; a binding pending check renders one `PR comments` line and omits `merge` with the text of `## Withhold reason resolver` reason 3, and puts `wait` as row 1 and, when `Blockers` is empty, `[recommended]`; under both this and the `merge state` overlay the higher one owns the reason and the single `PR comments` line; it mints no disposition hint (not dispositionable) |
|
|
101
|
-
| pending reviewer | a `pending` ledger row, a queued or in-progress reviewer run on the assessed head, or a failed comment refetch (`post-selection-loop.md` `### Re-render`) | puts `wait` as row 1 and, when `Blockers` is empty, `[recommended]`; `merge` is omitted (`Not offered: merge (reviewer still running)` or `merge (comments not refreshed)`); `merge anyway` renders as its own row when `## Availability` allows it, overrides only this overlay, and does not bypass an unreviewed delta or a blocker; a `reviewer failed (<conclusion>)` row changes nothing |
|
|
102
|
-
| comment source review incomplete | the `### Re-render` step-4 source review of a comment delta did not finish (`post-selection-loop.md`) | one `PR comments` line `The comment source review did not finish, so merge waits. (<reason>)`; `merge` is omitted (`Not offered: merge (comment source review incomplete)`) with no `anyway` row; `reply` and `review` are dropped (the delta is unreviewed); `fix`, `fix nits`, `show evidence`, `stop` stay; `stop` is `[recommended]` |
|
|
103
|
-
| head not pushable | `head_pushable` is false or `unreadable` (a fork head, a branch this actor cannot push, or an unreadable head) | `push` is omitted (`Not offered: push (needs push to <head_url>:<head_ref>)`); `fix` and `fix nits` stay and apply to the local worktree branch (`assessment.md` provisioning), their consequence clauses reading "open a PR from that branch, or hand the patch to the author"; `merge` follows `## Availability` |
|
|
104
|
-
| bot author | `author_is_bot` | the someone-else rows |
|
|
105
|
-
|
|
106
|
-
## Fixtures
|
|
107
|
-
|
|
108
|
-
Fixture 1 - own PR, fixable, one nit, one drafted reply: the menu in `report.md` `## Worked example`.
|
|
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.
|
|
109
45
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
Nits:
|
|
120
|
-
- 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)
|
|
121
|
-
1 nit open - fix nits to take them
|
|
122
|
-
|
|
123
|
-
Verdict: fixable - reviewer run in progress
|
|
124
|
-
|
|
125
|
-
1. wait - run one bounded CI watch, then re-render [recommended]
|
|
126
|
-
2. fix nits - apply the one-shot nit payload in the worktree, review the wave, push
|
|
127
|
-
3. reply - post the drafted reply to maria
|
|
128
|
-
4. show evidence - gate output, CI run
|
|
129
|
-
5. stop - leave the PR as-is
|
|
130
|
-
Type a number. Not offered: merge (reviewer still running).
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
Fixture 3 - a different PR: your own, every spec row covered, no nits, no drafted replies; the reviewer bot's run was the only withhold and `wait` just returned.
|
|
134
|
-
|
|
135
|
-
(a) The run concluded `failure`: the `PR comments` line disappears, the reviewer check is inert, the verdict is `mergeable - CI green on the assessed head (test)`, and the menu is `merge` [recommended], `show evidence`, `stop`.
|
|
136
|
-
|
|
137
|
-
(b) The run concluded `success` and the verdict comment raises a retry bug; source review confirms it and mints a blocker:
|
|
138
|
-
|
|
139
|
-
```
|
|
140
|
-
PR comments:
|
|
141
|
-
- The reviewer bot's retry concern holds up against the source, so the drafted reply confirms it. (src/retry.ts)
|
|
142
|
-
|
|
143
|
-
Blockers:
|
|
144
|
-
1. Retries never count up, so a failing call retries forever instead of giving up
|
|
145
|
-
after the limit. (src/retry.ts:41)
|
|
146
|
-
|
|
147
|
-
Verdict: fixable - 1 blocker
|
|
148
|
-
|
|
149
|
-
1. fix - retain in-scope blocker repair during this run until readiness or a new decision boundary; review before push [recommended]
|
|
150
|
-
2. review - post the blocker as a comment on your PR
|
|
151
|
-
3. reply - post the drafted reply
|
|
152
|
-
4. show evidence - gate output, CI run, drafted edit
|
|
153
|
-
5. stop - leave the PR as-is
|
|
154
|
-
Type a number, or compose: "fix 1 + reply".
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
When source review disproves the comment, no blocker is minted; the mergeable menu renders with `reply` for the drafted reply.
|
|
158
|
-
|
|
159
|
-
Fixture 4 - the pre-merge refetch finds a new human comment after a `merge` pick: the merge aborts even when the concern is false, the comment is reviewed against source, and the menu re-renders for a fresh pick. A same-head identical-body timestamp edit mints a ledger row but triggers no source review or test run.
|
|
160
|
-
|
|
161
|
-
Fixture 5 - this run's `merge` pick succeeded (`state: MERGED`):
|
|
162
|
-
|
|
163
|
-
```
|
|
164
|
-
## AC coverage
|
|
165
|
-
Informational - the ticket's rows are unchanged. PR https://github.com/acme/widgets/pull/210, merged 9f1c2d3, spec <path>
|
|
166
|
-
- [ ] The reports page offers an Export CSV button. - covered
|
|
167
|
-
- [ ] Exports are emailed to the requesting user. - deferred per spec to acme/widgets#46
|
|
168
|
-
|
|
169
|
-
1. cleanup - remove .worktrees/pr-210 and branch csv-export, pull main, then close ticket (gh issue close 45 --comment "Delivered in https://github.com/acme/widgets/pull/210, merged 9f1c2d3e4b5a6978.") [recommended]
|
|
170
|
-
2. post coverage to ticket - comment the block above on acme/widgets#45
|
|
171
|
-
3. post coverage to PR - comment the block above on the PR
|
|
172
|
-
4. show evidence - gate output, CI run
|
|
173
|
-
5. stop - leave the PR as-is; .worktrees/pr-210 and branch csv-export stay
|
|
174
|
-
Type a number.
|
|
175
|
-
```
|
|
46
|
+
| Observation | Render |
|
|
47
|
+
|---|---|
|
|
48
|
+
| BLOCKED with 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 |
|
|
@@ -27,7 +27,9 @@ The `design` section is always part of the judged contract: a Design requirement
|
|
|
27
27
|
|
|
28
28
|
**Coverage.** With `source: spec`, `Delivers` lists the covered rows, then the `deferred per spec`, `deviates per spec`, and `elsewhere per spec` rows, then the observation halves (`report.md`); any other uncovered row is `gap`. The spec's disposition is the record: a tracker comment, a PR named in the body, or a later PR never widens or narrows it, and a bare `deferred:` is never confirmed by the ticket.
|
|
29
29
|
|
|
30
|
-
**Claims.** Treat `contradicted` as a blocker and draft a scope-neutral exact description correction; when a correction would narrow either spec-owned or PR-owned scope, pause the correction and route to the explicit contract-decision course in `post-selection-loop.md` `### Continuation record`, retaining the independent mechanism blocker. Render `unverifiable-pre-merge` as optional non-blocking Description uncertainty naming what the gate cannot verify, not as a nit or proof. Assess supplied evidence; leave `matched`, explicitly pending observations, and qualitative prose alone. Never invent unperformed work or a future commitment. Draft requested factual clarification only after an explicit human request;
|
|
30
|
+
**Claims.** Treat `contradicted` as a blocker and draft a scope-neutral exact description correction; when a correction would narrow either spec-owned or PR-owned scope, pause the correction and route to the explicit contract-decision course in `post-selection-loop.md` `### Continuation record`, retaining the independent mechanism blocker. Render `unverifiable-pre-merge` as optional non-blocking Description uncertainty naming what the gate cannot verify, not as a nit or proof. Assess supplied evidence; leave `matched`, explicitly pending observations, and qualitative prose alone. Never invent unperformed work or a future commitment. Draft requested factual clarification only after an explicit human request; preserve the assertion with the two-part replacement `Author's statement: <assertion> (not verified by this gate). Gate evidence: <evidence>`, rather than deleting it. Use pending-work wording only with an explicit record in the assessed body, approved spec, linked ticket, or request; conflicting records remain uncertain.
|
|
31
|
+
|
|
32
|
+
Treat a human body rewording dropping a mechanism sentence as a description defect; repair the description without amending untouched spec requirements. Keep spec-owned scope and independent mechanism blockers in force. Record a real proposed contract change and its paused continuation through `post-selection-loop.md` `### Contract decision`; limit it to the requested obligation, not omitted description mechanisms.
|
|
31
33
|
|
|
32
34
|
## Namespaces
|
|
33
35
|
|
|
@@ -63,14 +65,14 @@ Any blocking conclusion in the resolved check set (required or not - `../verific
|
|
|
63
65
|
|
|
64
66
|
Only `flaky` lifts the blocker; an undispositioned check, `real`, and `ci-infrastructure-broken` keep it until the check - or, for `ci-infrastructure-broken`, the fallback local run (brief Section B, Failed CI row) - is green.
|
|
65
67
|
|
|
66
|
-
|
|
68
|
+
Record dispositions only from direct human check commands. A flaky disposition followed by numeric deliver can resume; no helper can disposition a check. With BLOCKED and no dispositionable local repair, render the obstacle template from `menus.md`, even with course unset, and use verdict `GitHub reports BLOCKED, no local repair applies`. Render its PR-comments line as `GitHub reports this actor's merge as blocked, so merge waits. (merge_state_status BLOCKED; reviewDecision <value>)`; keep the locator and never attribute a named rule.
|
|
67
69
|
|
|
68
70
|
## Drafted payloads
|
|
69
71
|
|
|
70
|
-
Step 5 drafts, never applies. For every blocker with a file-level fix - code and doc drift alike - draft the concrete edit as a payload keyed to the finding's internal ID. Draft nit payloads
|
|
72
|
+
Step 5 drafts, never applies. For every blocker with a file-level fix - code and doc drift alike - draft the concrete edit as a payload keyed to the finding's internal ID. Draft nit payloads under `deliver-nits` or a terminal `fix nits` pick: print them in the `show evidence` payload shape and dispatch the wave in the same pick with no second confirmation; before that pick `show evidence` prints only the payloads that exist. For every replyable `C#`, draft the reply. The worktree stays tracked-clean (`git status --porcelain --untracked-files=no` empty) at every menu render; a payload is applied only under a delivery course or a terminal `fix nits` pick (the same path for code and docs) and dropped at teardown otherwise. A `P#` carried by a `rebased locally` sync record is drafted like any blocker, from the helper's test output and `git show <stopped commit>`; a `P#` whose smallest fix needs another repo, infrastructure, or a credential stays open. Keep the stored scope baseline authoritative; an implementer needing a contract change returns open - contract exception without changing it.
|
|
71
73
|
|
|
72
74
|
Extend each finding-keyed evidence pack with `target: file | description`. For file targets retain the concrete edit and scoped test files. For description targets store `{ finding_id, contributor_ids, assessed_head, original_body, old_text, new_text, replacement_body, source_evidence }` with exact old-to-new text and unrelated body text preserved. Keep independent contributions under all their IDs when one finding combines a claim and test/scope/check gap; close only source-backed resolved claim contributions, never the whole combined finding from a body edit. Judge source: pr gaps against original_intent, not the shortened body.
|
|
73
75
|
|
|
74
|
-
A payload is the smallest in-repo edit that turns the finding green and keeps the behavior the PR promises; it never adds infrastructure, a dependency, or a new module. A failure caused outside the repo (image pull, toolchain, credentials, external service) gets the smallest in-repo workaround with its reason in one sentence; a skip never removes a test an AC row relies on. A finding whose smallest fix needs another repo, infrastructure, or a credential stays open with the implementer's `open - needs <what>` sentence. A
|
|
76
|
+
A payload is the smallest in-repo edit that turns the finding green and keeps the behavior the PR promises; it never adds infrastructure, a dependency, or a new module. A failure caused outside the repo (image pull, toolchain, credentials, external service) gets the smallest in-repo workaround with its reason in one sentence; a skip never removes a test an AC row relies on. A finding whose smallest fix needs another repo, infrastructure, or a credential stays open with the implementer's `open - needs <what>` sentence. A delivery course applies a description payload alongside the file payloads through `post-selection-loop.md` `### Description repair`; show compact exact old-to-new text under the blocker and the full replacement body under `show evidence`. Apply a requested factual clarification only within selected course work; mint no fake blocker. Never draft an unsolicited style rewrite.
|
|
75
77
|
|
|
76
78
|
A posted review body is composed at post time from the blockers being addressed - one summary sentence, then the numbered items, ending on the fix or asked action.
|
|
@@ -1,56 +1,53 @@
|
|
|
1
1
|
# gatekeep-pr: fix wave
|
|
2
2
|
|
|
3
|
-
Read from `post-selection-loop.md`
|
|
3
|
+
Read from `post-selection-loop.md` for delivery work or a terminal nit iteration. Keep edits and commits helper-owned; the orchestrator never edits a tracked file or commits. Permit only fetch, merge --ff-only, ordinary push, and the exact rewrite/recovery operations owned below.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Sync
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Run only through `post-selection-loop.md` `### Loop sync`, never re-enter the once-per-invocation `sync.md`. Persist `repair.wave.sync.pre_head` = `git -C <worktree> rev-parse HEAD` as the fresh local recovery head after repair, and `repair.wave.sync.expected_remote_head` from the assessed/pushed remote SHA. Verify the remote expectation with a fresh remote-head read before sync and again before push. Preserve expected_remote_head through local repair and rebase; reject a mismatch without replacing it. For remote A, local repair B, then rebase C: lease A, restore B; a remote mismatch must never replace A. Keep this checkpoint through pre-push reads and local-head assessment; clear it only after successful push/rebinding or recorded recovery. A malformed checkpoint exits `stuck - run record unreadable`, never substitutes local HEAD. Record pre_wave_head separately before wave work. Fetch base and run `git -C <worktree> merge-tree --write-tree origin/<baseRefName> HEAD` before wave work and again before push. Exit 0 is conflict-free; 1 is a sync trigger; any other exit is an obstacle naming it. Sync only for mergeable CONFLICTING, merge_state_status BEHIND, or local merge-tree conflict. A current conflict-free head skips sync. Increment only repair.syncs_used once per sync and persist before it; spend no round for base-only conflict commits.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Read `sync.md` `## Permitted orchestrator git writes`, `## Conflict stop`, and `## Review before push` before a rewrite. Use these operations and helper continue checks with this sync's fresh pre_head, never entry-time state:
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
| Observed branch | Procedure |
|
|
12
|
+
|---|---|
|
|
13
|
+
| viewer.is_author true, author_is_bot false, `git rev-list --merges origin/<baseRefName>..HEAD` empty | Rebase onto origin/<baseRefName>. Permit fetch, rebase, `GIT_EDITOR=true git rebase --continue`, rebase --abort, reset --hard pre_head and lease push only; every command runs with git -C worktree. Dispatch one fresh conflict-stop implementer per stop using sync.md's exact task/scoped-test/continue checks; never continue with unmerged paths or residue. Never resolve conflicts in the orchestrator. |
|
|
14
|
+
| Someone else's or bot-authored head, or own head with merge commits | Dispatch one fresh implementer to merge freshly fetched origin/<baseRefName>, resolve conflicts in one commit, restore only its own edits on failure, and preserve earlier wave commits. Own merge-containing history says `sync: merged base - head contains merge commits`. Never rewrite a bot head; use ordinary push. |
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
Pass stored scope baseline to each helper; require `open - contract exception: <why>` without a contract-changing commit, preserve independent blockers and pause through Contract decision. Apply Wave's unsafe-residue stop.
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
Review rewritten replay with `git range-diff origin/<baseRefName> <pre_head> HEAD` plus `git diff <pre_head> HEAD -- <resolved files>`; retain wave P#/L# closure IDs. Record pushed_head_after_replay as the rewritten counterpart of the assessed pushed head during replay, distinct from later unpushed wave commits. For wave commits use `git diff <pushed_head_after_replay> HEAD` as the post-replay pushed-head boundary; before the single combined push review replay and wave deltas separately against their recorded boundaries. Review base merges with `git show --remerge-diff <merge-sha>`. Keep Critical/Moderate findings in the carried repair set before any push.
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
2. `merge base` - one fresh implementer helper merges the just-fetched `origin/<baseRefName>` into the branch and resolves the conflicts in one commit; the wave then continues with the selected payloads, and that merge commit joins the round's single `## Review before push` - its delta is given under `## Fix delta` as `git show --remerge-diff <merge-sha>` instead of the range diff - and shares the initial pass increment; only when `head_pushable` is true. Pass the stored scope baseline to the helper; require `open - contract exception: <why>` without a commit when resolution changes an agreed obligation or mechanism. Require the helper to restore only its own edits and preserve earlier wave commits; pause for the loop's contract decision. Apply the existing unsafe-residue stop. When picked at the pre-push check, dispatch one fresh reviewer over `git show --remerge-diff <merge-sha>` alone, gate the push on it as in `## Review before push`, and spend another counted pass for a newly required post-review base resolution. When that reviewer reports Critical or Moderate, the commits stay unpushed and `push` is omitted as `push (reviewer blocked the wave)`.
|
|
22
|
-
3. `reply` - post the drafted text "conflicts with <baseRefName>, please update".
|
|
23
|
-
4. `stop` - as `decision-menu.md` `stop`.
|
|
24
|
-
|
|
25
|
-
A worktree holding unpushed wave commits never shows `update branch`. The orchestrator resolving a conflict itself is a red flag (`../SKILL.md`).
|
|
20
|
+
On every rewritten-head push use the complete form `git push --no-follow-tags --force-with-lease=<head_ref>:<expected_remote_head> <head_url> HEAD:refs/heads/<head_ref>` (with git -C worktree). Restore on failure: rebase --abort while in progress, otherwise reset --hard pre_head; assert exact HEAD == pre_head and tracked-clean state. A failed assertion hard-stops. A refused lease or remote movement restores and exits `stuck - remote head moved`; other failures restore and exit `stuck - sync: <reason>`. Never retry a refused lease. On success write repair.wave.pushed_head and headRefOid, then Re-render rebinds evidence and carries dispositions. Spend only one push per iteration through Evidence after push.
|
|
26
21
|
|
|
27
22
|
## Wave
|
|
28
23
|
|
|
29
|
-
|
|
24
|
+
At course pick resolve `gauntlet_setting({ key: "closureReview" })`. Initialize repair.rounds_cap and repair.syncs_cap to `2 x closureReview.maxFixRounds`; use no-tool fallback `2 x 5`. Initialize usage to zero once per run. Cap 0 or missing helpers omits delivery rows. On obstacle deliver add exactly `2 x maxFixRounds` to each cap, persist before work and never reset usage; timeout continuation instead opens one window without extending either cap. Keep closureReview.enforce and the verify-phase phase-tracker's `1 x maxFixRounds` accounting unchanged; refused dispatch exits `stuck - phase-tracker fix-round guard: <its reason>`.
|
|
30
25
|
|
|
31
|
-
|
|
26
|
+
Record pre_wave_head before work. Initialize one per-pass checkpoint with round_start_head and counted false before payload dispatch, including each carried-set retry; preserve it on interrupted reconciliation, never recreate it for the same attempt. Count a round once only after at least one repair payload dispatch leaves a new source-changing commit, including a source-changing carried-set retry. Persist counted true and counted_head in repair.wave with stage apply/review/push before reconciliation can repeat it; a fresh carried pass keeps prior checkpoint history. Base-only conflict commits, description-only writes, watches, re-reviews, empty waves and restored failures cost no round. Keep usage cumulative across re-entry. At round cap reached or sync cap reached exit through the loop's ordered Exit check; retain commits and name any reviewer's top finding. Update stage and counted checkpoints without replay; clear wave only after reconciliation and settlement of No-progress obstacle. For `action: fix-nits`, retain repair.wave including its action and selected payloads through watch and own-push re-review; clear it only through `post-selection-loop.md` `### Next action`'s one-shot completion rule.
|
|
32
27
|
|
|
33
28
|
For each file payload in review order, dispatch one fresh implementer helper with `cwd` the PR worktree. Its task holds:
|
|
34
29
|
|
|
35
|
-
- the finding's evidence pack (`findings.md` `## Drafted payloads` shape) and the instruction to apply the
|
|
36
|
-
- `SCOPED_TEST_COMMANDS`, resolved once per wave from the merge-base copies of the overrides file, then `AGENTS.md` (`git show "$MB:<path>"`, the trust rule of `assessment.md` `## Configuration`): a scoped runner is a documented test command carrying a `<paths>` or `<files>` placeholder, or a command the doc labels scoped, in any section of either file (`## PR gate`, `## Project`, `## routing`, `## test-driven-development`, `## verification-before-completion` alike); keep its cwd and flags verbatim; with several runners take the one whose directory prefix matches the payload's test file; substitute the test files the payload touches or writes, and for a `P#` carried by a `rebased locally` sync record the failing test file named in that record; no runner or no test file -> `none`. Never the resolved `verification command`, whatever a consumer sentence says about fix waves - that command runs only where `../verification-brief.md` Section B selects a local-run row; `none` -> the helper reports `no scoped test` and the pre-push reviewer is its only gate;
|
|
30
|
+
- the finding's evidence pack (`findings.md` `## Drafted payloads` shape) and the instruction to apply the course-authorized payload - or, for a reviewer finding that has no drafted payload, the reviewer's finding text - never to re-solve the finding. A payload is the smallest in-repo edit that turns the finding green and keeps the behavior the PR promises; it never adds infrastructure, a dependency, or a new module. A failure caused outside the repo (image pull, toolchain, credentials, external service) gets the smallest in-repo workaround with its reason in one sentence; a skip never removes a test an AC row relies on.
|
|
31
|
+
- `SCOPED_TEST_COMMANDS`, resolved once per wave from the merge-base copies of the overrides file, then `AGENTS.md` (`git show "$MB:<path>"`, the trust rule of `assessment.md` `## Configuration`): a scoped runner is a documented test command carrying a `<paths>` or `<files>` placeholder, or a command the doc labels scoped, in any section of either file (`## PR gate`, `## Project`, `## routing`, `## test-driven-development`, `## verification-before-completion` alike); keep its cwd and flags verbatim; with several runners take the one whose directory prefix matches the payload's test file; substitute the test files the payload touches or writes; insert each path made only of `[A-Za-z0-9/._-]` bare; insert any other path single-quoted with embedded `'` escaped as `'\''`; keep each path relative to the runner's working directory (strip the `cd <dir> &&` prefix's directory from the path), and for a `P#` carried by a `rebased locally` sync record the failing test file named in that record; no runner or no test file -> `none`. Never the resolved `verification command`, whatever a consumer sentence says about fix waves - that command runs only where `../verification-brief.md` Section B selects a local-run row; `none` -> the helper reports `no scoped test` and the pre-push reviewer is its only gate;
|
|
37
32
|
- the commit rule: commit on the PR branch only when the scoped test passes, or when `SCOPED_TEST_COMMANDS` is `none`, one commit per payload, subject naming the fix; otherwise discard its edits (`git checkout -- <its files>`, remove files it created) and return `open - <why>`;
|
|
38
33
|
- the report shape: the scoped test's failing run before the edit and passing run after it; a doc-only payload with no test reports `no scoped test` and its diff, and the reviewer below is its only gate.
|
|
39
34
|
|
|
40
|
-
After each helper returns, read `git -C <worktree> status --porcelain` and `git -C <worktree> rev-parse HEAD`. A `done` return shows exactly one new commit and a clean tree; an `open` return shows no new commit and a clean tree. Any other state - staged, unstaged, or untracked residue, or a moved HEAD on `open` - stops the round: dispatch no further implementer, and re-render the menu naming the files and the payload. An `open` payload is never reported as fixed, whatever the reviewer reports. When its scoped test fails and the helper restores its edits, persist the result and failed prerequisite through `post-selection-loop.md` `### No-progress obstacle` before any retry, including carried-set retries. The orchestrator never commits or checks out files
|
|
35
|
+
After each helper returns, read `git -C <worktree> status --porcelain` and `git -C <worktree> rev-parse HEAD`. A `done` return shows exactly one new commit and a clean tree; an `open` return shows no new commit and a clean tree. Any other state - staged, unstaged, or untracked residue, or a moved HEAD on `open` - stops the round: dispatch no further implementer, and re-render the menu naming the files and the payload. An `open` payload is never reported as fixed, whatever the reviewer reports. When its scoped test fails and the helper restores its edits, persist the result and failed prerequisite through `post-selection-loop.md` `### No-progress obstacle` before any retry, including carried-set retries. The orchestrator never commits or checks out files; restrict resets to Sync's recorded pre_head recovery and assert its exact-head/clean postconditions.
|
|
41
36
|
|
|
42
37
|
## Review before push
|
|
43
38
|
|
|
44
|
-
When HEAD equals `pre_wave_head` after a round (every payload returned `open`), skip the review and the push; persist the completed empty-round result and failed prerequisites through `post-selection-loop.md` `### No-progress obstacle`, then re-render with the `open` reasons. Link a failed scoped-test return after restored edits to that same owner; do not automatically dispatch the unchanged payload again.
|
|
39
|
+
With no dispatched file payload and no new local commits, skip file review/push and continue to sync/watch; description-only success is not no progress. When HEAD equals `pre_wave_head` after a round with dispatched file payloads (every payload returned `open`), skip the review and the push; persist the completed empty-round result and failed prerequisites through `post-selection-loop.md` `### No-progress obstacle`, then re-render with the `open` reasons. Link a failed scoped-test return after restored edits to that same owner; do not automatically dispatch the unchanged payload again.
|
|
45
40
|
|
|
46
|
-
After the round's payloads, dispatch one fresh reviewer helper, `cwd` the PR worktree, read-only, over `<pushed_head>..HEAD`, where `pushed_head` is the digest's `headRefOid` (the assessed head), so commits a previous round left unpushed are always inside the reviewed range; `pre_wave_head` serves only the empty-round test. Its task carries the findings whose payloads this wave dispatched, under their `P#`/`L#` ids, under `## Previous review report (re-review trigger)`, and the output of `git diff <pushed_head> HEAD` under `## Fix delta`, and asks for the reviewer's native report plus one closure line per listed finding, accepted anywhere after the findings list: `<finding id>: resolved` or `<finding id>: open - <why>`. When the round holds a
|
|
41
|
+
After the round's payloads, dispatch one fresh reviewer helper, `cwd` the PR worktree, read-only, over `<pushed_head>..HEAD`, where `pushed_head` is the digest's `headRefOid` (the assessed head), or Sync's recorded pushed_head_after_replay under a rewrite, so commits a previous round left unpushed are always inside the reviewed range; `pre_wave_head` serves only the empty-round test. Its task carries the findings whose payloads this wave dispatched, under their `P#`/`L#` ids, under `## Previous review report (re-review trigger)`, and the output of `git diff <pushed_head> HEAD` under `## Fix delta`, and asks for the reviewer's native report plus one closure line per listed finding, accepted anywhere after the findings list: `<finding id>: resolved` or `<finding id>: open - <why>`. When the round holds a base-merge sync commit, `## Fix delta` is `git diff <pushed_head> <merge-sha>^1`, then `git show --remerge-diff <merge-sha>`, then `git diff <merge-sha> HEAD`. Ignore a `TRAJECTORY:` line in the report.
|
|
47
42
|
|
|
48
|
-
Mark a finding resolved only from a `resolved` closure line; the orchestrator never marks one. The carried set is every `open` closure line of this wave's ids, every new Critical or Moderate finding inside `## Fix delta`, and every new Critical finding outside it; a new finding entering the set is minted a `P#` before dispatch and listed under it in the next round's reviewer task. An in-delta Minor translates to a nit (`findings.md` `## Namespaces`); a `[Minor] (outside fix delta)` finding, or an outside-delta finding the report tags Moderate, prints under `show evidence` only. Push only when the carried set holds no Critical or Moderate. Within the active pre-push wave, retry every carried item
|
|
43
|
+
Mark a finding resolved only from a `resolved` closure line; the orchestrator never marks one. The carried set is every `open` closure line of this wave's ids, every new Critical or Moderate finding inside `## Fix delta`, and every new Critical finding outside it; a new finding entering the set is minted a `P#` before dispatch and listed under it in the next round's reviewer task. An in-delta Minor translates to a nit (`findings.md` `## Namespaces`); a `[Minor] (outside fix delta)` finding, or an outside-delta finding the report tags Moderate, prints under `show evidence` only. Push only when the carried set holds no Critical or Moderate. Within the active pre-push wave, retry every carried item through a fresh implementer, serially, with its payload or new finding text. Charge a source-changing carried-set retry once through Wave. Return to pre-push review without a menu or push. At exhaustion keep commits unpushed, exit through the cap with the reviewer's top finding and the Critical/Moderate carried titles.
|
|
49
44
|
|
|
50
45
|
## Evidence after push
|
|
51
46
|
|
|
52
|
-
Run `##
|
|
47
|
+
Run the local merge-tree check once more; trigger `## Sync` only for its defined failures. After review passes, push once to the recorded destination: `git -C <worktree> push --no-follow-tags <head_url> HEAD:refs/heads/<head_ref>`, using Sync's complete lease form for every rewritten head. On a locally rewritten head push only when every carried `P#` has a `resolved` closure line. For loop rewrites, freshly compare the remote to `repair.wave.sync.expected_remote_head` and lease that SHA; recover to `repair.wave.sync.pre_head` on refusal or movement through Sync's restore/assert obstacle. For an entry-time `rebased locally` record without a loop checkpoint, keep sync.md's own pre_head for both comparison/lease and recovery (`--force-with-lease=<head_ref>:<pre_head>`); its baseline requires local/remote equality. Other push failures exit with the actual reason and commits unpushed. Only for an entry-time `rebased locally` record, rewrite that entry sync record to plain rebased form after a successful lease push. For loop rewrites, settle only repair.wave.sync through Sync's successful push/rebinding rule; leave the entry sync record unchanged.
|
|
48
|
+
|
|
49
|
+
On a newly successful push persist repair.wave.pushed_head and digest headRefOid, and renew an existing poll deadline only for this gate's own push. The loop runs the pre-menu refresh as `post-selection-loop.md` `### Re-render` step 1, using the verifier's binding classification. No claim re-check and no whole-wave review runs after an own push except the affected-claims-only description recheck; preserve unrelated dispositions. Pending to CI-sufficient dispatches a fresh Section B helper in claim-check-only mode for pending claims, with a disposition for every material claim. Local-run rows dispatch the separate Section B helper and record `local run: no conclusive check`, `local run: held run not approvable`, or `local run: local verification: always`.
|
|
53
50
|
|
|
54
|
-
|
|
51
|
+
For failing CI gather `gh run view <id> -R <repo> --log-failed`. With neither failed log nor source lead request one run re-run inside the wave. Compare repeated-red observations against pushed repair-wave source commits, not arbitrary SHA movement; the loop's red-twice obstacle owns the result. Helpers never disposition checks. `approve workflow run` executes `gh api --method POST repos/<base-owner>/<base-repo>/actions/runs/<id>/approve` only under the loop/terminal permission check, then refreshes and watches under the course.
|
|
55
52
|
|
|
56
|
-
|
|
53
|
+
Return through the fixed delivery body: bounded watch at step 4, own-push Re-render comment reconciliation and any eligible source review, then Exit check. Never run an independent watch or render a mid-course menu.
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# gatekeep-pr: menu templates
|
|
2
|
+
|
|
3
|
+
Read with `decision-menu.md` at step 6. Select the template from this state map; terminal state takes precedence over a pending contract exception, which takes precedence over course execution.
|
|
4
|
+
|
|
5
|
+
| State | Template |
|
|
6
|
+
|---|---|
|
|
7
|
+
| this run's merge returned MERGED | own merge |
|
|
8
|
+
| this run's merge returned another state | merge queued |
|
|
9
|
+
| approved_head equals assessed head | approved |
|
|
10
|
+
| PR state no longer OPEN | closed PR |
|
|
11
|
+
| pending contract exception | contract exception |
|
|
12
|
+
| readiness exit, including first report ready with course unset | final |
|
|
13
|
+
| obstacle or cap exit, including course unset with undispositionable BLOCKED | obstacle |
|
|
14
|
+
| assess completed | assess terminal |
|
|
15
|
+
| first report not ready, course unset | initial |
|
|
16
|
+
| multi-PR parent round | batch summary |
|
|
17
|
+
|
|
18
|
+
Render every menu in full from its template: the verdict line, every available row, and the hint line. Never narrate or summarize a menu; do not substitute "the initial template applied; the human picked 2" for its rendering. Quote a numeric pick only after the rendered menu.
|
|
19
|
+
|
|
20
|
+
Render flat numbers through [menu-layout](../../brainstorming/reference/menu-layout.md); preserve its bare-numeric mapping. Put exactly one `[recommended]` on an available row and `stop` last. Put `show evidence` in every hint line, never in a row. Include every omission reason from `decision-menu.md`. A menu rendered under `deliver` before an exit condition, other than the contract-exception template, is a red flag; so is a menu not rendered from these templates, two recommendations, stop not last, or no evidence hint.
|
|
21
|
+
|
|
22
|
+
Render terminal cleanup consequences through `cleanup.md`; use `skipped - needs a landed change` for merge-SHA-dependent overrides in the row text and result block.
|
|
23
|
+
|
|
24
|
+
Use `viewer.is_author` (`viewer.login == pr.author.login`) and `author_is_bot` for defaults. Treat a bot-authored head as someone else's throughout. Keep `merge policy` (`squash | merge-commit | rebase`) solely as the `gh pr merge` flag selector, never approval or sync strategy. Treat `approve (round 1) / approve (round 2)` as spec approval history, not menu configuration.
|
|
25
|
+
|
|
26
|
+
## initial
|
|
27
|
+
|
|
28
|
+
Offer `assess`, eligible `deliver`, eligible `deliver with nits`, then `stop`. Recommend deliver for the human's own PR, assess for someone else's; when delivery is omitted on an own PR, recommend assess. Omit deliver with nits with zero nits, and both delivery rows with cap zero, missing helpers, or non-pushable/unreadable head; name each reason, including `Not offered: deliver (needs push to <head_url>:<head_ref>)`. For someone else's/bot PR change the sync consequence to "merge main into the branch". Map `deliver with nits` to stored `deliver-nits`.
|
|
29
|
+
|
|
30
|
+
```text
|
|
31
|
+
Verdict: not ready - 2 blockers, 1 nit
|
|
32
|
+
|
|
33
|
+
Pick one:
|
|
34
|
+
1. assess - post the review to the PR; then approve or stop, no repairs.
|
|
35
|
+
2. deliver - repair blockers, rebase on main, watch CI, repeat until merge is offered. [recommended]
|
|
36
|
+
3. deliver with nits - deliver, and fold the 1 nit into the repairs.
|
|
37
|
+
4. stop - remove the worktree, leave the PR as is.
|
|
38
|
+
|
|
39
|
+
Course holds until the final menu; `show evidence` prints the full record.
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## final
|
|
43
|
+
|
|
44
|
+
Offer available `merge`, `approve`, `fix nits` when nits remain and the course excluded them, `reply` when drafted replies exist, then `stop`. Recommend merge for own PR; recommend approve for someone else's when available, else merge; with neither available recommend stop. Omit merge on a draft with `Not offered: merge (draft)` or below WRITE with `Not offered: merge (needs WRITE on <owner>/<repo>)`. Omit approve on drafts and own PRs. Authorize exactly one delivery iteration for fix nits, leaving course unchanged (`post-selection-loop.md` `### Next action`). Hint: `Type a number; show evidence prints the full record.` Print one compact `Evidence:` line above the `Delivers:` line naming the source (`CI (source: ci)` or the local run), the head SHA, each run and its checks with their conclusions, the binding-pending count, and `merge_state_status`; put the same record in the `show evidence` hint's parenthetical.
|
|
45
|
+
|
|
46
|
+
## assess terminal
|
|
47
|
+
|
|
48
|
+
Offer available `deliver` (switch course), `approve` only on someone else's non-draft PR with zero blockers, `reply` for drafted thread replies, then `stop` `[recommended]`. Hint: `Type a number; show evidence prints the full record.`
|
|
49
|
+
|
|
50
|
+
## obstacle
|
|
51
|
+
|
|
52
|
+
For undispositionable BLOCKED with no local repair, use this template even with course unset: keep stop last and `[recommended]`, with no wait row, no sync promise, and no approve row. Describe eligible deliver only as retrying after the failed prerequisite changes; promise no automatic sync. Reserve the course-unset initial assess/deliver/stop template for a pending-only report when its sole withhold is a not-yet-resolved binding CI check; source blockers still use initial under the state map.
|
|
53
|
+
|
|
54
|
+
Print the concrete obstacle and retained failed prerequisites. Keep the `Delivers:` line in the obstacle report. Offer eligible `deliver`, `approve workflow run` only for the held-run permission case, `assess` (switch course), then `stop` `[recommended]`. Feed the `Evidence:` line from the verifier record's resolved source, never from the raw check or run rollup - render a `source: pending` record as `Evidence: pending (<binding check> binding; head <sha>)`, and when `course` is unset render the deliver row as `deliver - set course to deliver; <one clause naming what retries>, no round charged` instead of `resume the retained course`. Render ordinary obstacle continuation as `deliver - resume the retained course; <one clause naming what retries>, no round charged`. For every non-timeout deliver selection, add exactly `2 x maxFixRounds` to both caps and persist before work, preserving usage. Append `add <n> to each cap` (`+2 x maxFixRounds`, with cumulative usage/caps) to the row even below both caps. On timeout describe exactly one additional watch window instead, with neither cap extended. An unchanged prerequisite re-exits even after extension. Print exactly one `Evidence:` line before the verdict, naming the resolved evidence source and assessed head per `report.md` (for example `Evidence: CI (run 7001, test_unit and build_image green on 9c1e4f2)`). Include `check <name> flaky | real | ci-broken` in the hint for failing checks; flaky followed by a numeric deliver selection can resume. Hint: `Type a number; show evidence prints the full record (<source summary>)`. Replace `<source summary>` with the same source summary used in `Evidence:`, including the CI run, check outcomes, and assessed head when CI is the source.
|
|
55
|
+
|
|
56
|
+
## contract exception
|
|
57
|
+
|
|
58
|
+
Print the concrete proposed contract change before the rows. Offer `accept contract change`, `preserve contract` `[recommended]`, then `stop`. Render preserve's consequence as "reject the proposal, keep <named requirement>, and resume authorized implementation repair within it". Route through `post-selection-loop.md` `### Contract decision`; show evidence settles nothing. Hint: `Type a number; show evidence prints the full record.`
|
|
59
|
+
|
|
60
|
+
## own merge
|
|
61
|
+
|
|
62
|
+
After this run's merge returns `MERGED`, offer `cleanup` `[recommended]` until attempted, `post coverage to ticket` when issue and scope rows exist, `post coverage to PR`, then `stop`. Suppress each successful post for the rest of the run; a failed post keeps its row and prints the error. A post re-renders this template, never tears down or ends the run, and runs no compare-and-swap. After cleanup removes its row recommend the first available post, else stop. Hint: `Type a number; show evidence prints the full record.`
|
|
63
|
+
|
|
64
|
+
## merge queued
|
|
65
|
+
|
|
66
|
+
After this run's merge returns a state other than `MERGED`, offer `wait` - re-run `gh pr view <N> --json state,mergeCommit` `[recommended]`, then `stop`. Render `The merge is queued, so coverage posts wait. (<state>)`. A MERGED read records pr.state and pr.merge_commit and renders own merge; OPEN or another state keeps this template. Run no CI watch. Hint: `Type a number; show evidence prints the full record.`
|
|
67
|
+
|
|
68
|
+
## approved
|
|
69
|
+
|
|
70
|
+
When `approved_head` equals the assessed head, offer `cleanup` `[recommended]` until attempted, then `stop`; recommend stop after cleanup. Hint: `Type a number; show evidence prints the full record.`
|
|
71
|
+
|
|
72
|
+
## closed PR
|
|
73
|
+
|
|
74
|
+
When state is not OPEN at step 1 or mid-course, offer `cleanup` `[recommended]` until attempted, then `stop`; recommend stop after cleanup. Keep this distinct from this run's own merge. Hint: `Type a number; show evidence prints the full record.`
|
|
75
|
+
|
|
76
|
+
## batch summary
|
|
77
|
+
|
|
78
|
+
For a recovered `CONFLICTING` child, offer only safe `retry` and `stop`, with `show evidence` hint-only. Render `retry - re-dispatch this PR's assessment with the same record` `[recommended]` only after `batch.md`'s clean-recovery and no-rebase checks pass; otherwise omit retry with its recorded reason and recommend stop. Keep stop last; offer no update branch or merge base rows. Hint: `Type a number; show evidence prints the full record.`
|
|
79
|
+
|
|
80
|
+
Let the `batch.md` parent render its current summary rows and each child's template from this file. Keep terminal posts and queued-merge wait parent-owned, including after worktree removal; suppress successful posts and retain failed posts. Preserve the parent's row consequences and admission/queue semantics. Put stop last and exactly one recommendation. Hint: `Type a number; show evidence prints the full record.`
|