pi-gauntlet 7.10.1 → 7.11.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 +1 -1
- package/package.json +1 -1
- package/skills/gatekeep-pr/SKILL.md +2 -2
- package/skills/gatekeep-pr/reference/decision-menu.md +5 -5
- package/skills/gatekeep-pr/reference/findings.md +3 -3
- package/skills/gatekeep-pr/reference/fix-wave.md +3 -5
- package/skills/gatekeep-pr/reference/post-selection-loop.md +13 -13
- package/skills/gatekeep-pr/reference/report.md +1 -1
- package/skills/gatekeep-pr/reference/sync.md +2 -2
- package/skills/gatekeep-pr/verification-brief.md +10 -12
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v7.11.0 - 2026-10-13
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
|
|
7
|
+
- `gatekeep-pr` waits on CI once: one `gh pr checks --watch` call bounded by `timeout minutes`, run only when Blockers are empty after the first report; the 30 s poll loop and the post-push poll are gone, and a wave push re-enters the menu on scoped-test evidence. A failing check is a `fix` target. Description corrections apply on `fix` or a retained fix grant like any payload, with readback and a re-propose when the body changed. Every payload is the smallest in-repo edit that turns the finding green - never infrastructure, a dependency, or a new module.
|
|
8
|
+
|
|
3
9
|
## v7.10.1 - 2026-10-13
|
|
4
10
|
|
|
5
11
|
### Changed
|
package/README.md
CHANGED
|
@@ -459,7 +459,7 @@ customization lives in two places, never in the wrapper itself:
|
|
|
459
459
|
```markdown
|
|
460
460
|
## PR gate
|
|
461
461
|
- verification command: <command> # required unless documented elsewhere
|
|
462
|
-
- timeout minutes: 15 # optional; default 15
|
|
462
|
+
- timeout minutes: 15 # optional; default 15; bounds each gh pr checks --watch window
|
|
463
463
|
- requires credentials: false # optional; true => skill reports "not run" as missing evidence
|
|
464
464
|
- local verification: always # optional; default (absent) = CI-first; "always" forces the local run even when exact-head CI is green
|
|
465
465
|
- ci checks: <comma-separated check names> # optional; narrows which checks count as evidence; absent = all checks on the assessed head
|
package/package.json
CHANGED
|
@@ -34,7 +34,7 @@ Re-entry: a fix wave's own push re-enters step 4 through the own-push sequence (
|
|
|
34
34
|
|
|
35
35
|
## Progress tracking
|
|
36
36
|
|
|
37
|
-
Mint and initialize the continuation record before progress initialization (`reference/post-selection-loop.md` `### Continuation record`). Use `plan_tracker`, never `phase_tracker`. `init` with the first three stages of the table, four when `--rebase` is present (`gather, provision, sync, verify, ...`); `reference/sync.md` closes `sync` before step 3 starts - `complete` after a push, a `no-op`, or a rebased, unpushed head (`rebased locally`), `skipped` when step 3 runs unsynced, `failed` on a terminal stop. In step 3 `add` one task per
|
|
37
|
+
Mint and initialize the continuation record before progress initialization (`reference/post-selection-loop.md` `### Continuation record`). Use `plan_tracker`, never `phase_tracker`. `init` with the first three stages of the table, four when `--rebase` is present (`gather, provision, sync, verify, ...`); `reference/sync.md` closes `sync` before step 3 starts - `complete` after a push, a `no-op`, or a rebased, unpushed head (`rebased locally`), `skipped` when step 3 runs unsynced, `failed` on a terminal stop. In step 3 `add` one task per claim whose evidence is the head's source and record its verdict: `complete` matched, `failed` contradicted, `skipped` unverifiable-pre-merge. Leave claims `pending` on CI outside the tracker for now; close `verify`. From then on, `add` each later stage (`review`, `report`, `menu`, ...) only when it starts, never ahead of time. When the claim-check-only helper runs after a green watch, `add` one task per pending claim then and record its verdict in the same step. A failed stage or claim stays `failed` while the skill stops at the menu. Without a `plan_tracker` tool, keep a plain checklist; behavior is unchanged.
|
|
38
38
|
|
|
39
39
|
## Harness notes
|
|
40
40
|
|
|
@@ -64,7 +64,7 @@ These bind every rendered report, menu, and external payload (review bodies, rep
|
|
|
64
64
|
- Reading the rubric, the verification command, or any ladder source from the PR's head instead of the base branch's merge-base - owner: `reference/assessment.md` `## Configuration`.
|
|
65
65
|
- Raw command output, drafted payloads except the exact description consent preview, or internal IDs in the rendered report - owner: `reference/report.md`.
|
|
66
66
|
- An open-PR menu, other than the conflict menu, an own-merge or merge-queued menu, a pending contract-exception menu, or a `--rebase` terminal stop (`stop` and `show evidence` only, `reference/sync.md`), without `fix` while an open blocker exists, or without `fix nits` while a nit exists, when a helper facility exists and the fix-round cap is neither `0` nor reached (a PR already merged or closed at step 1 offers `show evidence` and `stop` only); any menu without `show evidence`, with two `[recommended]`, or with `stop` not last - owner: `reference/decision-menu.md`.
|
|
67
|
-
- A
|
|
67
|
+
- A CI wait while a blocker is open or before the first report, or a second push inside one round - owner: `reference/post-selection-loop.md` `### Pre-menu refresh`.
|
|
68
68
|
- The orchestrator resolving a merge conflict itself, or editing or committing a tracked file during a fix wave - owner: `reference/fix-wave.md` `## Conflicts` and `## Wave`.
|
|
69
69
|
- A helper's duty run in the orchestrator's own context - owner: `## Harness notes`.
|
|
70
70
|
- Approving your own PR - owner: `reference/decision-menu.md` `## Consent table`.
|
|
@@ -12,12 +12,12 @@ Rows are `<n>. <verb> - <consequence>`; every row, `stop` included, carries its
|
|
|
12
12
|
|
|
13
13
|
- `accept contract change` - invoke the concrete proposal's owning amendment process through `post-selection-loop.md` `### Contract decision`; settle the baseline only after completion
|
|
14
14
|
- `preserve contract` - reject the concrete proposal and resume only permitted scope-preserving repair through `post-selection-loop.md` `### Contract decision`; keep independent blockers open
|
|
15
|
-
- `fix` - retain covered blocker repair during this run until readiness or a new decision boundary (`post-selection-loop.md`);
|
|
15
|
+
- `fix` - retain covered blocker repair during this run until readiness or a new decision boundary (`post-selection-loop.md`); apply description targets through the loop's Description repair and file payloads for the named blockers (open blockers by default) through fresh implementer helpers in the provisioned worktree, review the wave before any push, push when `push` is available (`fix-wave.md`); on a `rebased locally` head, lease-push once every carried blocker is resolved (`fix-wave.md` `## Evidence after push`); `fix + nits` composes this verb with `fix nits`
|
|
16
16
|
- `fix nits` - apply one-shot nit payloads drafted at this pick (`findings.md` `## Drafted payloads`) through fresh implementer helpers in the provisioned worktree, review the wave before any push, push when `push` is available (`fix-wave.md`); `fix + nits` typed with zero open blockers runs as this verb
|
|
17
17
|
- `push` - push local fix commits (renders only when unpushed commits exist)
|
|
18
18
|
- `review` - post the blockers as a GitHub review: request-changes on someone else's PR, a comment on your own
|
|
19
19
|
- `approve` - approve the PR (never your own)
|
|
20
|
-
- `approve workflow run` - `gh api --method POST repos/<base-owner>/<base-repo>/actions/runs/<id>/approve` for a held run on the assessed head, then re-
|
|
20
|
+
- `approve workflow run` - `gh api --method POST repos/<base-owner>/<base-repo>/actions/runs/<id>/approve` for a held run on the assessed head, then re-enter the refresh (`post-selection-loop.md` `### Pre-menu refresh`)
|
|
21
21
|
- `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
|
|
22
22
|
- `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`)
|
|
23
23
|
- `merge` - `gh pr merge --match-head-commit <assessed-sha>` with the resolved `merge policy` (default squash); preconditions per `post-selection-loop.md` `### Merge preconditions`
|
|
@@ -26,7 +26,7 @@ Rows are `<n>. <verb> - <consequence>`; every row, `stop` included, carries its
|
|
|
26
26
|
- `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
|
|
27
27
|
- `post coverage to PR` - post the same block with `gh pr comment <N> --body-file`; renders only under the `own merge` overlay
|
|
28
28
|
- `show evidence` - print the evidence record, claim and AC outcomes, dispositions, drafted payloads and replies (`report.md` `## What stays out`)
|
|
29
|
-
- `wait` -
|
|
29
|
+
- `wait` - run one bounded `gh pr checks --watch` on every **binding** pending check in the resolved set (required or not), then re-render
|
|
30
30
|
- `stop` - leave the PR as-is; on 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
|
|
31
31
|
|
|
32
32
|
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`).
|
|
@@ -40,7 +40,7 @@ Rows derive from the digest's `permissions` block (`../verification-brief.md` Se
|
|
|
40
40
|
| Row | Available when |
|
|
41
41
|
|---|---|
|
|
42
42
|
| `accept contract change`, `preserve contract` | a recorded contract exception is pending and no terminal/sync stop applies; route numeric and typed selections through `post-selection-loop.md` `### Contract decision` |
|
|
43
|
-
| `fix` | an open blocker or explicitly requested exact clarification payload exists (a failing-check `P#` included
|
|
43
|
+
| `fix` | an open blocker or explicitly requested exact clarification payload exists (a failing-check `P#` included), a helper facility exists (`../SKILL.md` `## Harness notes`), and the fix-round cap is neither `0` nor reached (`fix-wave.md` `## Wave`) |
|
|
44
44
|
| `fix nits` | a nit exists, a helper facility exists (`../SKILL.md` `## Harness notes`), and the fix-round cap is neither `0` nor reached (`fix-wave.md` `## Wave`); a `fix` with neither blocker nor requested clarification, or a `fix nits` with no nit, is dropped from the row set and never named in `Not offered:` |
|
|
45
45
|
| `merge base` | open PR with `mergeable: CONFLICTING` or `mergeStateStatus: BEHIND`, even with zero code blockers; head_pushable true, helpers, remaining budget, and no terminal/sync stop; preserve rebased-locally lease-only restrictions |
|
|
46
46
|
| `push` | `head_pushable` is true and unpushed wave commits exist and the last pre-push review's carried set (`fix-wave.md` `## Review before push`) held no Critical or Moderate |
|
|
@@ -117,7 +117,7 @@ Nits:
|
|
|
117
117
|
|
|
118
118
|
Verdict: fixable - reviewer run in progress
|
|
119
119
|
|
|
120
|
-
1. wait -
|
|
120
|
+
1. wait - run one bounded CI watch, then re-render [recommended]
|
|
121
121
|
2. fix nits - apply the one-shot nit payload in the worktree, review the wave, push
|
|
122
122
|
3. reply - post the drafted reply to maria
|
|
123
123
|
4. show evidence - gate output, CI run
|
|
@@ -52,7 +52,7 @@ Behavior the spec keeps in scope is a blocker until its mechanism ships; a row t
|
|
|
52
52
|
|
|
53
53
|
## Dispositions
|
|
54
54
|
|
|
55
|
-
Any blocking conclusion in the resolved check set (required or not - `../verification-brief.md` Section B, Evidence resolution table) withholds `merge` until the user dispositions it, and mints a `P#` - except the reviewer check, whose exception the brief's Section B defines (one `show evidence` line `reviewer check <name> failed - inert`).
|
|
55
|
+
Any blocking conclusion in the resolved check set (required or not - `../verification-brief.md` Section B, Evidence resolution table) withholds `merge` until the user dispositions it, and mints a `P#` - except the reviewer check, whose exception the brief's Section B defines (one `show evidence` line `reviewer check <name> failed - inert`). A **binding** pending check (`../verification-brief.md` Section B, binding classification) mints nothing and is not dispositionable: merge waits until it turns green, or `merge_state_status` leaves `BLOCKED`, or it converts to a failing check with its own `P#`. A not-binding pending check withholds nothing, never renders under `PR comments`, and prints under `show evidence` only, as `<name> pending - not binding this viewer (merge_state_status <value>)`; the `required` field stays gathered and no longer withholds on its own.
|
|
56
56
|
|
|
57
57
|
| Disposition | Annotation on the `P#` |
|
|
58
58
|
|---|---|
|
|
@@ -67,10 +67,10 @@ How each disposition changes the menu: `decision-menu.md` `## Overlays`, CI chec
|
|
|
67
67
|
|
|
68
68
|
## Drafted payloads
|
|
69
69
|
|
|
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 on a `fix nits` or `fix + nits` pick, which is the consent: 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 on a `fix`, `fix nits`, or `fix + nits` pick or a validated retained grant (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#`
|
|
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 on a `fix nits` or `fix + nits` pick, which is the consent: 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 on a `fix`, `fix nits`, or `fix + nits` pick or a validated retained grant (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. The human sees the draft at the `fix` consent and decides whether code or test expectations change; the implementer never decides it.
|
|
71
71
|
|
|
72
72
|
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
73
|
|
|
74
|
-
|
|
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 `fix` pick or a validated retained fix grant applies a description payload in the same round as 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`. A requested factual clarification enables a clarification-only `fix` without minting a blocker or ongoing grant. Never draft an unsolicited style rewrite.
|
|
75
75
|
|
|
76
76
|
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.
|
|
@@ -28,11 +28,11 @@ A worktree holding unpushed wave commits never shows `update branch`. The orches
|
|
|
28
28
|
|
|
29
29
|
`pre_wave_head` was recorded before the first `## Conflicts` check. A round is one pass over the open payloads plus one `## Review before push`. The round cap is `closureReview.maxFixRounds`, read with `gauntlet_setting({ key: "closureReview" })` when that tool exists, else 3; a cap of `0` omits `fix` and `fix nits` from the menu, named as `fix, fix nits (maxFixRounds is 0)` in the `Not offered:` sentence. The round count is per run; at the cap `fix` and `fix nits` are omitted, named `fix, fix nits (round cap reached)` in `Not offered:`.
|
|
30
30
|
|
|
31
|
-
Increment `repair.rounds_used` before the first body write or helper dispatch and persist `repair.wave` with its current stage. Count file, description-only, and conflict-only attempts under the same cap; cap 0 disables every repair target. Initial combined base/file/body work shares one increment and one push. Post-review resolution or completed unsuccessful retry spends another pass; paused-action resumption, context restoration, refresh, and
|
|
31
|
+
Increment `repair.rounds_used` before the first body write or helper dispatch and persist `repair.wave` with its current stage. Count file, description-only, and conflict-only attempts under the same cap; cap 0 disables every repair target. Initial combined base/file/body work shares one increment and one push. Post-review resolution or completed unsuccessful retry spends another pass; paused-action resumption, context restoration, refresh, and a watch or the `P#` it mints do not increment or reset usage. Stop automatic work at exhaustion; a grant never raises the cap. Update apply/review/push checkpoints and clear the wave only after reconciliation and settlement of any `post-selection-loop.md` `### No-progress obstacle`.
|
|
32
32
|
|
|
33
33
|
For each file payload in review order, dispatch one fresh implementer helper with `cwd` the PR worktree. Its task holds:
|
|
34
34
|
|
|
35
|
-
- the finding's evidence pack (`findings.md` `## Drafted payloads` shape) and the instruction to apply the consented payload - or, for a reviewer finding that has no drafted payload, the reviewer's finding text - never to re-solve the finding;
|
|
35
|
+
- the finding's evidence pack (`findings.md` `## Drafted payloads` shape) and the instruction to apply the consented 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.
|
|
36
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;
|
|
37
37
|
- 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
38
|
- 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.
|
|
@@ -51,8 +51,6 @@ Mark a finding resolved only from a `resolved` closure line; the orchestrator ne
|
|
|
51
51
|
|
|
52
52
|
Run `## Conflicts` once more, then push to the recorded destination: `git -C <worktree> push --no-follow-tags <head_url> HEAD:refs/heads/<head_ref>`. On a `rebased locally` head push only when every carried `P#` has a `resolved` closure line, with `--force-with-lease=<head_ref>:<pre_head>`; otherwise the commits stay unpushed and the menu re-renders with the open `P#`. A refusal naming the lease (`stale info`): `git reset --hard <pre_head>`, assert `HEAD == <pre_head>` and a clean tree; a mismatch is a hard stop with the error, record `sync: failed - push rejected: <first server line>`, and render `stop` and `show evidence` only - the fix commits are discarded with the rewrite, and the reason says so. After a successful lease push rewrite the sync record to the plain `rebased ...` form. Report any other rejected push verbatim and re-render the menu with the commits unpushed.
|
|
53
53
|
|
|
54
|
-
On a newly successful push,
|
|
55
|
-
|
|
56
|
-
Resolve the normalized set through `../verification-brief.md` `## Section B - Verifier` (Evidence resolution) - the same table the first pass uses. When the re-resolve moves the evidence from `source: pending` to CI-sufficient (an approved held run went green, or a `wait` ended), dispatch a fresh Section B helper in claim-check-only mode (`../verification-brief.md` Section B) before rendering the menu. `approve workflow run` executes `gh api --method POST repos/<base-owner>/<base-repo>/actions/runs/<id>/approve`, then re-polls. The evidence block records the outcome and, when a local-run row fires, dispatch a fresh Section B helper; the evidence block records which trigger fired: `local run: no conclusive check`, `local run: held run not approvable`, or `local run: local verification: always`.
|
|
54
|
+
On a newly successful push, persist `repair.wave.pushed_head`, run no poll (the one `gh pr view` and `gh run list` read belongs to the refresh), and re-enter step 5 through `post-selection-loop.md` `### Re-render` step 1 (the pre-menu refresh runs once; its watch guard decides, by the brief's binding classification, whether a watch follows). No claim re-check and no whole-wave review runs after an own push; the description recheck of `### Description repair` is the one exception. When the refresh moves the evidence from `source: pending` to CI-sufficient, dispatch a fresh Section B helper in claim-check-only mode (`../verification-brief.md` Section B) before rendering the menu. `approve workflow run` executes `gh api --method POST repos/<base-owner>/<base-repo>/actions/runs/<id>/approve`, then re-enters the refresh; an `action_required` run renders `approve workflow run` before any watch, and `### Re-render` reconciliation is unchanged. When a local-run row fires, dispatch a fresh Section B helper; the evidence block records which trigger fired: `local run: no conclusive check`, `local run: held run not approvable`, or `local run: local verification: always`.
|
|
57
55
|
|
|
58
56
|
Then run the own-push sequence of `post-selection-loop.md` `### Re-render`: the comment refetch and reconciliation, a fresh reviewer helper for any eligible comment delta, and the menu rendered from the closure lines for the exact pushed SHA. No claim re-check and no whole-wave review runs after an own push except the affected-claims-only description recheck in `post-selection-loop.md` `### Description repair`; preserve unrelated dispositions. The sequence runs the pre-menu refresh as `post-selection-loop.md` `### Re-render` step 1 (`### Pre-menu refresh`) - an approval dismissed by the push flips a bound viewer to `BLOCKED`, and the menu says so.
|
|
@@ -35,12 +35,12 @@ After fresh evidence/permission assessment and eligible comment source review, v
|
|
|
35
35
|
| Completed no-progress result with unchanged failed prerequisite | Render the obstacle through `### No-progress obstacle` before any retained repair routing. |
|
|
36
36
|
| Reconciled active pre-push wave has carried items and no unresolved obstacle, authorized by an explicit current or recorded still-valid pick or a matching held grant that has not been revoked, under the existing continuation validation | Retry the carried set through `fix-wave.md` `## Review before push`, including under a named grant; preserve its cap, scoped tests, fresh helpers, and single push. `revoke fix` invalidates the old fix pick as authority; require a restored one-shot nit wave's recorded still-valid pick, not an invented broad grant. Route missing or invalid authority to the existing decision obstacle. |
|
|
37
37
|
| Covered conflict or behind-base repair with merge-base grant | Run the helper-owned base course in `fix-wave.md`, preserving the selected strategy. |
|
|
38
|
-
| Covered source-backed file
|
|
39
|
-
| Held repair grant and only readiness evidence for the authorized repair course is pending, including after its payloads were pushed, within current deadline |
|
|
38
|
+
| Covered source-backed blockers (file or description payload) with fix grant | Run the existing wave; a description-only round goes through `### Description repair`; a finding the implementer returned `open - needs <what>` is not covered; it stays open through `### No-progress obstacle` until a new explicit pick names it. |
|
|
39
|
+
| Held repair grant and only readiness evidence for the authorized repair course is pending, including after its payloads were pushed, within current deadline | Nothing extra: the watch guard in `### Pre-menu refresh` decides whether a watch runs. |
|
|
40
40
|
| Every merge prerequisite holds | Render fresh final menu; never automatically merge or approve. |
|
|
41
41
|
| Missing decision, budget, permission, input, failed refresh or expired deadline | Render the concrete obstacle; preserve valid grants without silently renewing the deadline. |
|
|
42
42
|
|
|
43
|
-
At this boundary and before every external write, fetch actual body and live `baseRefName` with head/state. Compare live `baseRefName` against `consent.target.baseRefName` before consuming authority; pause on an unreadable or changed base without overwriting `consent.target`, choosing a new base, or continuing against the old base. A same-head body edit invalidates old readiness and selected merge; narrowly recheck changed material claims while preserving original intent. Refresh changed proposals
|
|
43
|
+
At this boundary and before every external write, fetch actual body and live `baseRefName` with head/state. Compare live `baseRefName` against `consent.target.baseRefName` before consuming authority; pause on an unreadable or changed base without overwriting `consent.target`, choosing a new base, or continuing against the old base. A same-head body edit invalidates old readiness and selected merge; narrowly recheck changed material claims while preserving original intent. Refresh changed proposals; the next `fix` round applies them. Keep the record through ready-menu rendering; readiness lost later can resume covered work but final merge consent is fresh.
|
|
44
44
|
|
|
45
45
|
### No-progress obstacle
|
|
46
46
|
|
|
@@ -50,11 +50,11 @@ Check this checkpoint before retained repair routing. Keep grants and `repair.ro
|
|
|
50
50
|
|
|
51
51
|
### Description repair
|
|
52
52
|
|
|
53
|
-
For
|
|
53
|
+
For a description payload applied on a `fix` pick or a validated retained fix grant, perform external-write checks, fetch actual head/body, and compare both with the proposal. A body or head that changed since the proposal: the old proposal is invalid; re-propose from the current body at the current head and write nothing this round; the next `fix` round applies it. Count the pass per `fix-wave.md` before this first mutation. Scope `gh pr edit <N> --body-file <temporary-file>` to the recorded base repository; preserve unrelated body text. Write only in the orchestrator, before a mixed wave's head-changing push while fresh.
|
|
54
54
|
|
|
55
55
|
Read back actual head/body and require expected text, unchanged head, and a fresh Section B `description recheck` helper before resolving only the claim contribution. Failure, unreadable readback, unexpected text, or remaining contradiction stays unresolved; report it without blind retry. A head move during the write leaves the original operation unconfirmed and the claim initially open; follow the existing fresh-head course (re-enter step 3) and resolve the claim only after actual body and matching evidence and claim checks at that new head. Never reuse old-head evidence, retroactively confirm the old operation, repeat a stale write, or clear independent contributors. API success alone is not closure. No file implementer, empty commit, or full suite runs for body-only work. Keep successful file commits independent of body failures.
|
|
56
56
|
|
|
57
|
-
Record mixed-pass potentially affected claim IDs in `repair.wave.affected_claims`; before readiness narrowly recheck them against actual pushed head/body and that head's evidence. Preserve unrelated dispositions and independent test/scope/check contributions. A new contradiction gets a new
|
|
57
|
+
Record mixed-pass potentially affected claim IDs in `repair.wave.affected_claims`; before readiness narrowly recheck them against actual pushed head/body and that head's evidence. Preserve unrelated dispositions and independent test/scope/check contributions. A new contradiction gets a new proposal, applied on the next `fix` round. This is the sole relevant exception to own-push claim carry, not whole-wave review. Preserve evidence as specified by the brief's recheck mode. A resolved unchanged claim gets no repeated correction.
|
|
58
58
|
|
|
59
59
|
Treat pre-write comparison and readback as stale-write checks, not atomic compare-and-swap: a concurrent edit inside the read/write interval remains a race; never overwrite an already observed change.
|
|
60
60
|
|
|
@@ -80,9 +80,9 @@ Before every external write, re-fetch `headRefOid`, `state`, `mergeable`, and `m
|
|
|
80
80
|
|
|
81
81
|
### Fix wave
|
|
82
82
|
|
|
83
|
-
For a `fix` pick, take the drafted payloads (`findings.md` `## Drafted payloads`) for the named blockers - all open blockers by default; `fix nits` takes nit payloads only, drafted at this pick; `fix + nits` both. A finding closed by disposition is skipped. Route
|
|
83
|
+
A retained grant never re-dispatches a finding the implementer returned `open - needs <what>`, and never starts a round whose only open blockers are such findings: render the report and menu instead. For a `fix` pick, take the drafted payloads (`findings.md` `## Drafted payloads`) for the named blockers - all open blockers by default; `fix nits` takes nit payloads only, drafted at this pick; `fix + nits` both. A finding closed by disposition is skipped. Route description targets through `### Description repair`.
|
|
84
84
|
|
|
85
|
-
Apply per `fix-wave.md`: the local conflict check, one fresh implementer helper per payload with scoped tests only, the pre-push reviewer with its closure lines,
|
|
85
|
+
Apply per `fix-wave.md`: the local conflict check, one fresh implementer helper per payload with scoped tests only, the pre-push reviewer with its closure lines, and the push. The orchestrator never edits a tracked file and never commits. When `head_pushable` is false, the wave's commits stay in the local `pr-<N>` worktree: report the branch name and re-enter step 5.
|
|
86
86
|
|
|
87
87
|
`approve workflow run` and `update branch` execute per `fix-wave.md` (`## Evidence after push`, `## Conflicts`). Execute `review`, `reply`, `approve`, `post coverage to ticket`, and `post coverage to PR` via `gh pr review`, `gh api`, `gh issue comment`, `gh pr comment`, or the resolved tracker tool, non-interactively, with the drafted payload - after the output done-check below.
|
|
88
88
|
|
|
@@ -108,7 +108,7 @@ A post is one write of that block, verbatim; a post that succeeded cannot be pic
|
|
|
108
108
|
|
|
109
109
|
After every push or any mutation that can change readiness (fix wave pushed, PR head moved), re-sync the worktree. On an own push, after `fix-wave.md` `## Evidence after push`, run steps 1-5 below and render the menu from the pre-push reviewer's closure lines for the exact pushed SHA, where a blocker whose closure line reads `resolved` leaves the rendered list while its internal ID stays in the ledger and new findings continue each sequence; no claim re-check and no whole-wave review runs after an own push except the narrow affected-claim recheck in `### Description repair`. On every other head move, re-enter step 3, then run steps 1-5 below - the last read before the menu renders:
|
|
110
110
|
|
|
111
|
-
1. Run the pre-menu refresh (`### Pre-menu refresh`)
|
|
111
|
+
1. Run the pre-menu refresh (`### Pre-menu refresh`) once. Then re-run the Section A comment fetches (`../verification-brief.md`: both `--paginate` calls, plus the GraphQL `reviewThreads` query when the initial gather used it), one `gh run view` per placeholder row, and the reviewer-run `gh run list` when a reviewer workflow is known (after an own push, use the refresh's `actions_runs[]` instead of a second run-list call). Read-only.
|
|
112
112
|
2. Diff the fresh set against the `C#` ledger (`findings.md` `## Namespaces`) by `id` and `updated_at`:
|
|
113
113
|
- same `id`, same `updated_at` -> unchanged: keep the existing `C#`.
|
|
114
114
|
- same `id`, different `updated_at` -> edited: mint a new `C#`; the old one is `superseded by C<new>`. An `updated_at` change with an identical body (reaction, revert) still counts as edited.
|
|
@@ -123,15 +123,15 @@ After every push or any mutation that can change readiness (fix wave pushed, PR
|
|
|
123
123
|
|
|
124
124
|
### Pre-menu refresh
|
|
125
125
|
|
|
126
|
-
The first read of step 5, before the report and the menu render from one state - the first pass included (a long local run or review can stale the gather), every `### Re-render` entry, the post-`wait` re-fetch, `update branch`, a `merge base` round, and a fix-wave push (`fix-wave.md` `## Evidence after push`). Run `gh pr view <N> --json headRefOid,state,mergeable,mergeStateStatus,reviewDecision,statusCheckRollup` and `gh run list -R <owner>/<repo> -c <headRefOid> --json databaseId,status,conclusion,workflowName,url
|
|
126
|
+
The first read of step 5, before the report and the menu render from one state - the first pass included (a long local run or review can stale the gather), every `### Re-render` entry, the post-`wait` re-fetch, `update branch`, a `merge base` round, and a fix-wave push (`fix-wave.md` `## Evidence after push`). Run exactly one `gh pr view <N> --json headRefOid,state,mergeable,mergeStateStatus,reviewDecision,statusCheckRollup,body,baseRefName,number,title,author,isDraft,headRefName,isCrossRepository,files,additions,deletions,commits,reviews,closingIssuesReferences,headRepository,maintainerCanModify` and one `gh run list -R <owner>/<repo> -c <headRefOid> --json databaseId,status,conclusion,workflowName,url` (Section A's fixed fields, folding the `gh pr view <N> --json headRefOid,body,baseRefName` fields into the single call). While the sync record is `rebased locally`, compare the fetched `headRefOid` against the record's `<pre_head>` and render from that alone: a move takes the lease-refusal path of `fix-wave.md` `## Evidence after push` (`git reset --hard <pre_head>`, assert `HEAD == <pre_head>` and a clean tree, record `sync: failed - remote head moved`, render `stop` and `show evidence` only); an unmoved head keeps `status_checks[]` and `actions_runs[]` as they are, skips the evidence re-resolve, and ignores `mergeable` and `mergeStateStatus` changes - `source: pending` holds until the lease push rewrites the record; a `state` change to closed or merged renders `stop` and `show evidence` only. On a pushed head: head moved -> the head-move rule (re-enter step 3). `state` or `mergeable` changed (head unchanged) -> route through `### Compare-and-swap` re-assessment. Head unchanged with `state` and `mergeable` unchanged -> replace `permissions.merge_state_status`, `pr.reviewDecision`, `status_checks[]`, and `actions_runs[]` in the digest together, re-normalize and re-classify every pending check (`../verification-brief.md` Section B, binding classification), and re-resolve the Evidence resolution table on the fresh set, so a check whose run completed since the last menu is never paired with its cached run status; when that re-resolve moves `source: pending` to CI-sufficient, dispatch the Section B helper in claim-check-only mode (`../verification-brief.md` Section B) before rendering. A `gh` failure keeps the prior values, classifies every pending check as binding (`../verification-brief.md` Section B, binding classification), and renders the `merge state` overlay (`decision-menu.md` `## Overlays`) through `## Withhold reason resolver` reason 2 (locator `merge state not refreshed (<reason>)`). Apply `### Next action` target and body freshness from that same read before readiness. The refresh is read-only and never mints `C#` rows - comment reconciliation stays in `### Re-render`.
|
|
127
127
|
|
|
128
|
-
|
|
128
|
+
Watch guard: when this is not the first report, Blockers are empty, and a binding check is pending (open nits do not count), run `### Wait course` once before rendering; a `wait` pick runs it too. After the watch returns, for any reason, re-run the two reads above once and re-resolve the Evidence resolution table (`../verification-brief.md` Section B). CI-sufficient -> the claim-check-only helper for `pending` claims (named in `fix-wave.md` `## Evidence after push`), then the menu. A failing check in the resolved set -> one `P#` per check with its failing line from `gh run view <id> -R <repo> --log-failed`, a drafted payload (`findings.md` `## Drafted payloads`), and the menu; the `P#` closes on the reviewer's `resolved` line like any blocker and the next watch re-mints it when the check still fails; the watch mints no round (`closureReview.maxFixRounds` is untouched). Still pending -> the menu with `wait` as row 1. A `gh` read that fails is a failed refresh under the existing `### Re-render` rule; a head that moved during the watch re-enters step 3. An `action_required` run renders `approve workflow run` instead of a watch.
|
|
129
129
|
|
|
130
|
-
|
|
130
|
+
### Wait course
|
|
131
131
|
|
|
132
|
-
|
|
132
|
+
Persist `repair.poll_deadline` only on the first watch with a null deadline or a new explicit `wait` selection as current time plus the resolved `timeout minutes` (default 15); preserve it through re-entry and context restoration. Before the call, if the deadline has already passed, run no call and render the timeout obstacle with `wait` as row 1. A retained grant, repeated menu/Wait entry, or expiry alone never renews it. A `wait` pick on an expired window first applies the expiry step below: a completed-`success`/prefix-persists placeholder becomes `reviewer failed (stale placeholder)` and opens no new window; only a check still running gets one. A held grant alone never starts a watch; the watch guard in `### Pre-menu refresh` or an explicit `wait` pick does.
|
|
133
133
|
|
|
134
|
-
|
|
134
|
+
The watch is one call bounded by the remaining window through the Safety contract ladder of `../verification-brief.md` Section B (harness bash timeout, else `timeout`/`gtimeout`, else background-and-kill), never unbounded: `gh pr checks <N> -R <base-owner>/<base-repo> --watch`. Its exit code is not read; the `### Pre-menu refresh` watch guard reads the refreshed digest. On expiry every `pending` row stays `pending`, merge stays withheld, and `wait` renders as row 1 for a new explicit selection; rows in the completed-`success`/prefix-persists state become `reviewer failed (stale placeholder)` (brief Section C placeholder table). On completion or timeout, run steps 2-5 of `### Re-render` plus step 1's comment and reviewer-run reads after the watch guard's refresh, then re-render.
|
|
135
135
|
|
|
136
136
|
### Output done-check
|
|
137
137
|
|
|
@@ -48,7 +48,7 @@ Two states: `mergeable` or `fixable`. `mergeable` carries the evidence clause fr
|
|
|
48
48
|
|
|
49
49
|
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` pick. A clean run with a spec renders `Delivers`, the verdict line, and the menu - about four lines.
|
|
50
50
|
|
|
51
|
-
Print the compact exact old-to-new description preview
|
|
51
|
+
Print the compact exact old-to-new description preview under its blocker; keep the full replacement body under `show evidence`. Uncertainty alone preserves the mergeable verdict.
|
|
52
52
|
|
|
53
53
|
`show evidence` prints `state: <absolute-path>` for the authoritative continuation record, then, 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.
|
|
54
54
|
|
|
@@ -52,9 +52,9 @@ A refusal whose message names the lease (`stale info`, the remote head moved sin
|
|
|
52
52
|
|
|
53
53
|
## Re-gather
|
|
54
54
|
|
|
55
|
-
Re-run every step-1 forge read for the PR (`../verification-brief.md` Section A fixed command set): `headRefOid`, `mergeable`, `mergeStateStatus`, `reviewDecision`, status checks and `actions_runs`, commits, changed files and diff, comments and reviews; the step-1 ticket reads are not repeated; re-run `assessment.md` `## Select the scope contract` on the pushed head. Unreadable fields fail closed as in step 1. Re-resolve the configuration ladder (`assessment.md` `## Configuration`) at `git merge-base origin/<baseRefName> HEAD` - `baseRefName` stays the trust source even when `<base>` names another branch. Run no CI
|
|
55
|
+
Re-run every step-1 forge read for the PR (`../verification-brief.md` Section A fixed command set): `headRefOid`, `mergeable`, `mergeStateStatus`, `reviewDecision`, status checks and `actions_runs`, commits, changed files and diff, comments and reviews; the step-1 ticket reads are not repeated; re-run `assessment.md` `## Select the scope contract` on the pushed head. Unreadable fields fail closed as in step 1. Re-resolve the configuration ladder (`assessment.md` `## Configuration`) at `git merge-base origin/<baseRefName> HEAD` - `baseRefName` stays the trust source even when `<base>` names another branch. Run no CI watch here: a binding check still pending renders the `verification evidence pending` overlay (`../verification-brief.md` Section B, binding classification), never green, and a head with no check, or only not-binding pending checks, takes the `Fallback` row and step 3 resolves the pushed head as any assessed head - the sync push is not an own push for `### Re-render` and the `Fix wave` row of Section B does not apply; a head that moves before step 3 takes the existing head-move rule (`post-selection-loop.md` `### Re-render`), with step 2's divergence stop as the backstop. Red CI on the pushed head triggers no automatic fix: step 3 records the failing checks and the menu offers `fix` - `fix [recommended]` only when `decision-menu.md` and `../verification-brief.md` Section B make it `[recommended]`. Set the digest's `sync` field (`../verification-brief.md` Section A), close the `sync` stage `complete`, and enter step 3 with the refreshed digest.
|
|
56
56
|
|
|
57
|
-
On a `rebased locally` head the forge re-read returns `<pre_head>` as `headRefOid`; keep it in the record and leave the digest's `headRefOid` at the local HEAD, which the scope-contract read and step 3 use, and take the digest's changed files and diff from `git diff origin/<base>...HEAD`. Mint one blocker `P#` per `scoped tests red in` clause before step 3 - evidence the helper's scoped-test output, the blocker contract of `findings.md` (IDs append-only, surviving re-renders); skip the
|
|
57
|
+
On a `rebased locally` head the forge re-read returns `<pre_head>` as `headRefOid`; keep it in the record and leave the digest's `headRefOid` at the local HEAD, which the scope-contract read and step 3 use, and take the digest's changed files and diff from `git diff origin/<base>...HEAD`. Mint one blocker `P#` per `scoped tests red in` clause before step 3 - evidence the helper's scoped-test output, the blocker contract of `findings.md` (IDs append-only, surviving re-renders); skip the local verification run - step 3 records `source: pending` for the local head (no claims) - the carried blockers are the verification evidence and the verdict is `fixable`; `plan_tracker` closes the `sync` stage `complete`.
|
|
58
58
|
|
|
59
59
|
## Failure path
|
|
60
60
|
|
|
@@ -55,7 +55,7 @@ never a partial digest.
|
|
|
55
55
|
Missing PR number: `gh pr view --json number,url` on the current branch; no PR found -> STOP and report. Issue reference: the explicit argument, else `closingIssuesReferences`, then the branch name, PR title, PR body, and commit subjects; none found -> `issue_ref: null`. The Gatherer only resolves the reference - fetching the ticket is step 2 (`reference/assessment.md` `## Fetch the ticket`), after the issue-fetch command resolves from the merge-base.
|
|
56
56
|
|
|
57
57
|
`mergeable` is reported as-is, including `UNKNOWN` - the Gatherer runs before
|
|
58
|
-
provisioning, so it never re-
|
|
58
|
+
provisioning, so it never re-reads; step 2 re-reads once after provisioning (`reference/assessment.md`). Bot author noted
|
|
59
59
|
(`author_is_bot`). Capture each status check's `isRequired` where exposed (digest field: `required`).
|
|
60
60
|
|
|
61
61
|
**Gather digest output schema (normative):**
|
|
@@ -69,10 +69,10 @@ provisioning, so it never re-polls; step 2 re-polls once after provisioning (`re
|
|
|
69
69
|
- consent.fix: null | { scope: "all" or an array of stable finding IDs, granted_by: string }
|
|
70
70
|
- consent.merge_base: null | { granted_by: string } # base is consent.target.baseRefName
|
|
71
71
|
- repair.rounds_used: <nonnegative integer, initially 0>
|
|
72
|
-
- repair.poll_deadline: null | <absolute timestamp for the
|
|
73
|
-
- repair.wave: null | { pre_wave_head, pushed_head, selected_ids, affected_claims, stage: apply | review | push
|
|
72
|
+
- repair.poll_deadline: null | <absolute timestamp for the watch window; reference/post-selection-loop.md ### Wait course>
|
|
73
|
+
- repair.wave: null | { pre_wave_head, pushed_head, selected_ids, affected_claims, stage: apply | review | push, no_progress: { failed_prerequisite, observed_value, result_path }? }
|
|
74
74
|
- viewer: { login, is_author }
|
|
75
|
-
- permissions: { viewer_permission, is_cross_repository, maintainer_can_modify, merge_state_status, can_update_branch, 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-
|
|
75
|
+
- permissions: { viewer_permission, is_cross_repository, maintainer_can_modify, merge_state_status, can_update_branch, 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)
|
|
76
76
|
- 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)
|
|
77
77
|
- actions_runs: [ { databaseId, status, conclusion, workflowName, url } ] # from the fixed gh run list call on the assessed head
|
|
78
78
|
- 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
|
|
@@ -120,7 +120,7 @@ edit, fix, or commit anything; you are running a gate and claim-checking,
|
|
|
120
120
|
not implementing.
|
|
121
121
|
|
|
122
122
|
**Evidence resolution (normative).** The single rule for whether the local
|
|
123
|
-
command runs. Inputs come from Section A's fixed `gh pr view` and `gh run list` calls - no ad hoc fetch; after a push by this gate,
|
|
123
|
+
command runs. Inputs come from Section A's fixed `gh pr view` and `gh run list` calls - no ad hoc fetch; after a push by this gate, the pre-menu refresh re-runs those two calls.
|
|
124
124
|
|
|
125
125
|
- **Resolved check set** = checks named by `ci checks:` if configured, else all
|
|
126
126
|
checks on the assessed `headRefOid`.
|
|
@@ -147,17 +147,15 @@ command runs. Inputs come from Section A's fixed `gh pr view` and `gh run list`
|
|
|
147
147
|
|
|
148
148
|
Row precedence is top-down: the first matching row wins. The Fix wave row is an entry point, not a state row: it names when the table is re-resolved (after a push by this gate), and the state rows above it then decide.
|
|
149
149
|
|
|
150
|
-
On the first pass the orchestrator uses the persisted poll deadline owned by `reference/post-selection-loop.md` `### Wait course` and re-runs Section A's fixed `gh pr view` and `gh run list` calls every 30 seconds while no row other than Pending or Fallback matches (cadence as in `reference/fix-wave.md` `## Evidence after push`), then resolves the table.
|
|
151
|
-
|
|
152
150
|
| Path | Trigger | Action | Evidence recorded |
|
|
153
151
|
|---|---|---|---|
|
|
154
152
|
| 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` |
|
|
155
153
|
| 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; the menu re-renders with `fix` recommended only when a drafted payload exists for that failure, else per the overlays. 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 |
|
|
156
154
|
| 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) |
|
|
157
|
-
| Pending | >=1 **binding** pending check, no blocking conclusion
|
|
155
|
+
| Pending | >=1 **binding** pending check, no blocking conclusion | the `verification evidence pending` overlay renders (`reference/decision-menu.md` `## Overlays`); a `wait` pick runs one bounded watch per `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) |
|
|
158
156
|
| CI-sufficient | >=1 `success`, zero blocking, zero binding pending | Skip local run | CI claim: check name(s), conclusion, assessed SHA, run URL |
|
|
159
|
-
| Fallback | No conclusive check: no checks on the assessed head, or only inert / fail-safe conclusions or only not-binding pending checks
|
|
160
|
-
| Fix wave | A fix-wave push by this gate (not the step-2b sync push) |
|
|
157
|
+
| 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` |
|
|
158
|
+
| Fix wave | A fix-wave push by this gate (not the step-2b sync push) | Re-enter the pre-menu refresh per `reference/fix-wave.md` `## Evidence after push`; its watch guard and this table decide | The resolved row's evidence for the pushed SHA; the evidence block lists every failing and every pending binding check on the pushed head |
|
|
161
159
|
| Stale head | Head advances since evidence was resolved (another actor's push); fires across runs - a single gather is same-head by construction | All prior evidence (CI or local) is stale; re-resolve this table for the new head before merge is offered | Fresh evidence for the new head |
|
|
162
160
|
|
|
163
161
|
CI-sufficient predicate, stated once (the rows implement exactly this): **>=1
|
|
@@ -202,14 +200,14 @@ run fires on exactly three triggers, each recorded in the evidence block:
|
|
|
202
200
|
head_sha: <git rev-parse HEAD at run time>
|
|
203
201
|
runs: [ { run_cwd, command (verbatim), exit_code, result: pass|fail|not run,
|
|
204
202
|
log_path: <file under ${TMPDIR:-/tmp} holding the full captured output> } ]
|
|
205
|
-
- claims: [ { claim, disposition: matched|contradicted|unverifiable-pre-merge, evidence } ] #
|
|
203
|
+
- claims: [ { claim, disposition: matched|contradicted|unverifiable-pre-merge|pending, evidence } ] # source: pending -> disposition source-checkable claims now; keep check-dependent claims pending for the claim-check-only helper after a green watch
|
|
206
204
|
```
|
|
207
205
|
|
|
208
206
|
Claim-check-only mode: the orchestrator's task says `claim check only`; emit the resolved row's `source: ci` block (`head_sha`, `checks`), no run, and the per-claim dispositions.
|
|
209
207
|
|
|
210
208
|
`description recheck` mode: take the actual body, assessed head, affected claims/finding IDs, and existing evidence block. Emit only affected `{ claim, disposition, evidence }` entries and supplied claim findings' `<finding id>: resolved` or `<finding id>: open - <why>` closure lines. No replacement evidence block is emitted. Run no tests or evidence resolver; preserve `source: ci`, `source: local` (including `log_path`), or `source: pending` unchanged. Preserve unrelated dispositions; pending evidence remains insufficient. Judge supplied proof against source, not author assertion alone. This mode is separate from `claim check only`.
|
|
211
209
|
|
|
212
|
-
`source: pending` records a Pending or Held run outcome - no local run, no CI sufficiency,
|
|
210
|
+
`source: pending` records a Pending or Held run outcome - no local run, no CI sufficiency; disposition every claim whose evidence is the head's source (code, tests, docs) now and list claims that need a check result as `pending`; the claim-check-only helper dispositions those after a green watch.
|
|
213
211
|
|
|
214
212
|
Local provenance rules bind only to `source: local`. `log_path` holds captured
|
|
215
213
|
output, not authored prose; anything written in your own words is labeled
|