Repository navigation
feat: squabble verify-satisfied — the definition of done for a PR (exit 5 if not) - #119
Conversation
`squabble verify-satisfied <owner/repo> <pr>` answers "has the agent finished its part?" — distinct from "can this merge?". Agent items (conflict, draft, failing/missing required check, unresolved thread, bot CHANGES_REQUESTED, pending review bot, automerge unarmed or not squash, merge queue) make it exit 5; human-held items (required approval, deployment, a CLEAN PR GitHub will not automerge) are listed but do not. - squabble-core::done: the pure evaluator, 16 tests. - CheckRun::from_github: one mapping of GitHub status/conclusion, shared by fetch and the new reader. - squabble-forge::pr_done: one GraphQL query, two independently paginated connections (contexts, threads), fail-closed on errors or more than 20 pages; schema-validated against the snapshot. - fetch::base_gate: required contexts (rulesets ∪ classic) plus every ruleset rule type; empty is a real answer here, not NoGate. Check 4 (new code-scanning alerts) is not evaluated yet and says so in every verdict's notes rather than passing silently. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0136eszqrQ53Kj7aBH1D4rXK
… same-named run decides Control 1 (cicd-squabbler#114) read DONE while `rust-ci / Cargo check + clippy + fmt` was red: the check is not required, so the evaluator never looked at it. "All the checkers have run" means their output was dealt with, not that the ruleset is satisfied. New `Item::CheckFailed`; skipped and neutral are not items. Re-run live: #114 now exits 5 naming the check, #116 (its cure) exits 0. `squabble fetch` and `verify-satisfied` both took the FIRST same-named run, so a passing twin could mask a failing one depending on rollup order. One shared rule, `CheckRun::for_context`: the worst run decides. Mutants killed: first-match ordering (2 tests red), the new loop disabled (1 test red). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0136eszqrQ53Kj7aBH1D4rXK
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0136eszqrQ53Kj7aBH1D4rXK
…ue link in the PR body The previous commit made a red non-required check agent work with no way out but green, which inverts the owner's 2026-09-15 ruling: a new scanner finding becomes an issue with acceptance criteria, not a merge blocker. The ask was "checked and dismissed/acted on", not "green". A check run has no dismiss action, so the acknowledgement lives in the PR body: a line naming the context AND carrying an issue/PR reference (#N, /issues/N, /pull/N). It then moves to `notes` (still visible), not dropped. Naming the check without a link does not count. `body` added to pr_done.graphql and PrFacts (String; absent = no acks, fail-closed). Mutants killed: link requirement dropped, context match dropped, digit-after-# check dropped (1 test red each). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0136eszqrQ53Kj7aBH1D4rXK
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
The base gate feeds only the evidence-free listing once a PR is merged or closed, never an agent item; pinned by a new core test (killed by a mutant that routes every state through the open-PR path). Skipping the call keeps the commonest done-claim off the REST secondary limit this PAT shares with every other session -- live, 'landed hyperpolymath/hypatia#880' failed closed on exactly that 403. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0136eszqrQ53Kj7aBH1D4rXK
|
Pushed This binary now backs two hooks in the owner's |
…base is Owner ruling 2026-09-30: merge commits stay allowed (proof PRs keep their commit series; GitHub signs the merge commit). Rebase is the form that replays commits unsigned and breaks required_signatures, so REBASE is now the only wrong automerge method. The test pins both halves; a mutant dropping "MERGE" from the accepted set turns it red. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0136eszqrQ53Kj7aBH1D4rXK
|
58d1af6: a MERGE automerge is no longer agent work; only REBASE is. The owner ruled on 2026-09-30: allow merge commits, never rebase. A merge commit is GitHub-signed and is kept for proof PRs. Rebase replays commits unsigned (119 of 286 unsigned default-branch commits).
The matching changes are the merge-gate hook (local, 54/54 mutant harness) and hypatia#884 (strategist never picks 🤖 Generated with Claude Code |
|
Autopilot could not be updated. Open Coding to check access and billing. |
faa0752
into
fix/rollup-neutral-skipped-pass
Resolve crates/squabble-cli/src/main.rs as a union: main added `board`/`inbox-sweep` (exit 6, #123/#124) where this branch added `verify-satisfied` (exit 5, #119). Both modules, dispatch arms, usage lines and exit-code docs are kept; codes listed in numeric order. cargo fmt --check, clippy -D warnings and cargo test --workspace (279) pass. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W5CoaksP2Bg21HpDCgFgwS
Adds
squabble verify-satisfied <owner>/<repo> <pr>, one implementation of "is this PR actually done?" for the D2 Stop hook and for humans. JSON goes to stdout and a readable list to stderr. Exit 5 means agent work remains; 0/2/3/4 keep their existing meanings.What counts as done
CONFLICTING; mergeability computed; not draft; notBEHINDFailedorMissing.Pendingis fine; skipped/neutral satisfy but are listed as evidence-freeCHANGES_REQUESTED; no review bot still pendingnotes→ #117[.rules[].type]on the base, not just required checks.merge_queuerefuses rather than passing vacuously; unknown types go to notesHeld by a human (listed, not agent work): human approval, a required deployment, and a CLEAN PR, which GitHub refuses to arm automerge on, so it waits for a human merge. Change requests made only by review bots are agent work, not human-held.
Shared rules, so
fetchandverify-satisfiedcan't disagreeCheckRun::from_githubmaps rollup vocabulary. An unknown completed conclusion isFailed.CheckRun::for_contextdecides a required context from all same-named runs, and the worst run wins. Both readers used first-match before, so a passing twin could mask a failing one depending on rollup order.Evidence
#dropped (1),ctx_done = truein pagination (2).rust-ci / Cargo check + clippy + fmt. After a body line citing style: make rust-ci green on main (fmt, needless lifetime, dead fn) #116 it exits 0, and the acknowledged red is still shown in notes.SonarCloud Code Analysisrequired but never emitted → standards#1081).Not in this PR
done.rsis a policy table over forge facts with no state machine or invariant; the proof obligations live ingate_machine, which fix(gate): SKIPPED/NEUTRAL required checks satisfy, as Skipped #114 mirrors. (ci: prove spark/gate_machine in CI (no workflow runs gnatprove) #115 tracks getting gnatprove into CI at all.)hardcoded_tmpalert.~/.claude/hooks/apps-ack-gate.shis a second implementation of this question → apps-ack-gate.sh is a second implementation of verify-satisfied — make it a caller #118.Inherited red
rust-ci / Cargo check + clippy + fmtis red onmain(b12657f): unformattedsquabble-fight, aneedless_lifetimesinworkflows.rs:628, and a deadrun_with_greens. Cured by style: make rust-ci green on main (fmt, needless lifetime, dead fn) #116; merge order style: make rust-ci green on main (fmt, needless lifetime, dead fn) #116 → fix(gate): SKIPPED/NEUTRAL required checks satisfy, as Skipped #114 → this. Checked locally with style: make rust-ci green on main (fmt, needless lifetime, dead fn) #116's fix applied temporarily: this branch's own code passesclippy -D warningsandrustfmt --check.🤖 Generated with Claude Code
https://claude.ai/code/session_0136eszqrQ53Kj7aBH1D4rXK