Report one PR's CON-32 readiness as the deterministic gate's verdict, quoted, with the conjunct-by-conjunct reason it passed or failed. Use when the maintainer invokes /pr-state <CODE>#<N>, or asks whether a PR is ready, G2-ready, G4-ready or mergeable. Strictly read-only — it never labels, merges, pushes, comments or opens anything. A readiness claim made any other way is not a readiness claim.
Instal·la
npx skillscat add zheref/hatsu/surfaces-antigravity-skills-pr-state Instal·la des del registre de SkillsCat.
PR state — the gate's verdict, quoted, or no claim at all
Nature: Manipulator. GitHub-side ops. Kurapika says so when he runs it.
This skill answers exactly one question, the same way every time:
Is this PR
CON-32-Ready, and if not, which conjunct failed?
It exists because the rule already existed and was skipped anyway. scripts/pr_ready_gate.sh
was CON-32's sole authority in <reference-repo> since RR-PR-#577 — and RR-IS-#681 was filed
after a readiness claim was made without running it. The verdicts, when it was finally run across
the open set:
| PR | claimed | actual verdict |
|---|---|---|
| #575 | "merge it" | not-ready — CON-32(a) |
| #679 | "once green" | not-ready — 1 unresolved thread |
| #603 | ready | ready |
| #622, #678 | "driving to ready" | not-ready — CONFLICTING |
Three of four wrong. Not for want of a tool — the tool evaluated 19 of 21 PRs fine on that same
host. It was skipped. A deterministic authority an agent may skip is a suggestion, so this skill
exists to make running it the cheap path, and the rule in § 5 exists to make not running it
indefensible. nen pr ready is the Nen-native port of that same authority — byte-for-byte transcribed
from cli/src/ports/pr_ready_gate.ts, and proven against the live shadow window (docs/ab/pr-state.md
§ 2) rather than merely asserted — so the rule below binds identically to it.
Read-only, without exception. This skill renders a verdict. It never applies a label, merges,
pushes, opens, closes or comments — not even when the verdict isreadyand the merge is obvious.
Acting on a PR is `sharingan`'s job — this skill's own scope stops at reportingready.nen pr readyitself has no notification mode to reach for by mistake — unlike the oracle it ports,
which posts a "ready for decision" comment outside--verdict, this verb only ever prints a report.
1. Invocation
P1 — this run opens with /ten pr-state (`ten` § 6 catches up this phase's
missing prerequisites under its own name; the phases this run calls skip theirs).
/pr-state <repo_code>#<PR_NUMBER> e.g. /pr-state BC#603| Part | Accepts | Rule |
|---|---|---|
<repo_code> |
a product code from the target repository's nen/repos.json → product_codes |
case-insensitive; an unknown code is asked for with the valid ones as the picker's options, never a guess |
<PR_NUMBER> |
a positive integer | a number that names an issue, not a PR, is not caught as one before the call — verified against v0.1.0, it comes back unevaluated: GitHub could not be read (… Could not resolve to a PullRequest with the number of <N>.), carrying nen's generic token-grants remedy even though the token is fine — see the callout below and § 4. No v0.2.0/v0.3.0 changelog entry touches this path; it is not re-verified at v0.3.0 (a live GitHub read) |
The codes are read from the registry at run time, never from memory — they change. nen pr ready
does this itself: pass the ref straight through and let the verb resolve it against--repo <path>'s nen/repos.json (nen reads nen/ first and, for the whole v0.3 line, falls back to
a refusal names it). Do not pre-resolve the code by hand or guess one
from the working directory.
A missing argument or configuration item is asked for and set up inline (missing-argument,missing-configuration; `WORKFLOW.md` § 4 Ask, set up, continue); a
registry entry is set up through the registry's own key, never by this read-only skill.
Write the
#. This port filed a finding againstv0.1.0(docs/ab/pr-state.md§ 4): the no-#
shorthand split off only the last digit, soBC925refused with'BC92' is not a product code.
Closed by nenv0.2.0(#72, closes zheref/nen#26) — the shorthand now reads the longest
trailing digit run as the number, andnen pr ready --helpsays so. Verified live atv0.3.0
against the bundled registry:nen pr ready BC925 --repo <path>andnen pr ready BC#925 --repo <path>both resolve to<reference-repo>#925(and then, with no token,unevaluatedat exit1—
the ref resolved; GitHub was not read). The instruction stands as belt-and-braces rather than as a
workaround:<CODE>#<N>is the unambiguous form, and a product code that itself ends in a digit
still needs the#, by the verb's own account.
A wrong number is caught by GitHub, not by
nen, and the remedy it prints can mislead.nen pr readynever checks whether<PR_NUMBER>names a pull request before asking GitHub —
verified againstv0.1.0,BC#918(918is an issue on<reference-repo>, not a PR) does
not come back as "that's an issue." It comes backunevaluated: GitHub could not be read (… Could not resolve to a PullRequest with the number of 918.), followed bynen's generic token-grants remedy (pull-requests:read AND checks:read AND actions:read, not expired, network reachedgithub.com) — a remedy that is misleading here: the
token is fine, the number just names the wrong kind of object. This is a second finding against the
binary, recorded indocs/ab/pr-state.md§ 4 alongside the#-parser bug above — not a skill rule
to route around by hand. Relay the reason and remedy exactly as printed anyway (§ 4, § 6); never
silently upgradeunevaluatedto "that number is an issue" on the reader's behalf, sincenenitself
never says that.
2. Run the gate — this is the whole computation
Export a token first — nen never picks one up ambiently, unlike gh:
export GH_TOKEN=$(gh auth token)Which identity flag goes on the call is decided BEFORE it is typed — never the --gates form by
default. This section owns the rule for every flag on the call — the identity flag and, below, the
exclusion flag — and `sharingan` § 4 and `en` § 6 cite it;
the identity flag is three shapes, and there is no fourth:
# the target ships its own nen/gates.json — no identity flag at all (the schemas/ fallback is REMOVED at the pinned build; a gates file only there is refused, same as none at all)
nen pr ready <CODE>#<N> --repo <path> --explain
# the target IS <reference-repo> itself — frozen, ships no gates file of its own.
# $hatsu_root is THIS plugin's checkout, ABSOLUTE: the root ten § 0 already resolved, taken
# from $HATSU_PLUGIN_ROOT where the session exports it, else from the single-quoted line § 0 printed,
# pasted verbatim in place of '<…>' (quotes included, nothing else). No manifest is parsed here: with
# neither in hand, re-resolve through ten § 0 rather than reading plugin.json inline.
hatsu_root="${HATSU_PLUGIN_ROOT:-}"; [ -n "$hatsu_root" ] || hatsu_root='<the absolute path § 0 printed>'
[ -f "$hatsu_root/.claude-plugin/plugin.json" ] && [ -d "$hatsu_root/claude/skills" ] \
|| { echo "no Hatsu root in hand: re-run ten § 0, or pass --reviewers and explicit --approvers by hand (sharingan § 4)" >&2; exit 1; }
nen pr ready <CODE>#<N> --repo <path> \
--gates "$hatsu_root/contracts/reference.gates.json" --explain
# any OTHER target that ships no gates file — reviewer identities AND approval policy supplied BY HAND;
# use --approvers "" only for an authoritative review-round-only target policy, never by inference
nen pr ready <CODE>#<N> --repo <path> --reviewers <a,b,c> --approvers <a,b> --explainor, with a bare number against a repo slug directly, the same three shapes with <N> --gh-repo <owner/repo> in place of <CODE>#<N> --repo <path>.
The exclusion flag rides beside the identity flag, and it is read from a declared home only
(zheref/hatsu#104). A maintainer's ruling that a check is not watched — an absent self-hosted runner,
a matrix leg ruled out — lives in the target's nen/gates.json → check_exclusions[] (name,reason, ruled, until; `docs/GATE-CONFIGURATION.md` § 3),
never in chat or a brief: every row scripts/tenkai_adopt.sh diagnose reports live goes on the
call as --exclude-check <a,b>, each name its own argv element, never interpolated into a--command string or a shell line (SEC-7 — the target's gates file is third-party data next to a
live token), and the verdict is quoted with the exclusion named. A ruling with no row ismissing-configuration (`WORKFLOW.md` § 4 Ask, set up, continue):
written into the declaration at that repository's gate, then the verb re-read — never a verdict read
around. A row the flag cannot carry — a comma in the name (the flag's separator, zheref/nen#243),
a quote, a metacharacter, a lapsed or malformed date — is refused at the declaration and never put
on the call: tenkai diagnose names it drift, the verdict is read without it and quoted as it
stands, never ready on a row nobody could pass and never a check dropped by a split name. The
row CON-32(a) then reads by eye is the one the declaration owes nen (zheref/nen#249), and reading it
by eye is the failure this flag exists to end. An exhausted reviewer is the same shape one key over — reviewer_fallback.exhausted[], ruling
2026-09-29, PROCESS.md § *Reviewer rounds and review threads* The fallback chain — read the same way: the row named,
the verb's verdict quoted verbatim with the one Hatsu exhaustion line beside it, never ready; nen has
no exhausted-reviewer read yet (zheref/nen#275), so the narrowing is the skill's to say, never a --gates
file with the reviewer struck out, which nen refuses (verified live at nen 0.15.1, docs/ab/sharingan.md
§ Dated 2026-09-29 — the reviewer fallback chain).
Always the $hatsu_root-anchored form when --gates is the one in play, never a bare contracts/reference.gates.json. The
reason moved with nen v0.2.0 (#86) and the practice did not: a relative --gates now resolves
against --repo's root, never the cwd — verified live at v0.3.0, from /tmp with --repo pointed
at a checkout that lacks the file: nen: <repo>/contracts/reference.gates.json: no such file. --gates was given 'contracts/reference.gates.json', which is RELATIVE, so it was resolved against the target repository root … not the current directory (exit 2). The file lives in this plugin's checkout, not in
the target's, so only an absolute path reaches it from any --repo. $hatsu_root is the house
convention for exactly this — the Hatsu checkout as `ten` § 0
resolves it, on every surface, the winner canonicalised to an absolute path. It is a shell variable and
not an export, so the code block above takes it from $HATSU_PLUGIN_ROOT or the line the warm-up printed
and runs no resolver of its own: with neither in hand it re-resolves through ten rather than
parsing a manifest, and the root the warm-up printed is what that block hands in.
It is spelled that way and never as$CLAUDE_PLUGIN_ROOT alone because that variable is Claude Code's: exported by that harness inside a skill
invocation and nowhere else, and on Codex and Cursor — where this body runs as a verbatim mirror
(`docs/SURFACES.md`) — usually unset or, from a shell profile, naming a
different plugin. --explain and --json'smeta.identities.path print the resolved absolute path (identities <abs path> on the --explain header
line), so the report itself says which file decided.
--repo <path>is the TARGET repository's working-tree root — a path, never anowner/name
slug — used to resolve<CODE>against itsnen/repos.json.--gh-repo <owner/name>is the slug the API read runs against, needed whenever the ref
is a bare number —--repo <path>is itself a path argument, not the cwd, so it already works from
anywhere without--gh-repoalongside it.--gates "$hatsu_root/contracts/reference.gates.json"—<reference-repo>is FROZEN and ships
no gates file of its own (nonen/gates.json); without--gates(or a--reviewersoverride)nen pr readyrefuses outright withno reviewer identities
rather than guessing a reviewer set — verified live atv0.3.0, and the refusal now names both
locations it looked in. This repository'scontracts/reference.gates.jsoncarries the same reviewer
identities the oracle script hard-codes — see that file's own header. A repo that ships its ownnen/gates.jsonneeds no--gatesflag at all; this one
is<reference-repo>-specific plumbing, not a general rule.--gatesitself never falls back to
either taxonomy location: a path you hand it is taken literally.- The three shapes above are `sharingan` § 4's identity rule, cited here
rather than re-copied — it is the authority, this is the citation. The third shape exists because
a repository must never be judged by another repository's reviewers — the reference file is<reference-repo>'s own, and pointing it at any other target reports a confident verdict about the
wrong people. Whichever identities and approval policy were substituted (the third shape) are named
on the page. Omitted--approversis not vacuous at Nen 0.10.0: it defaults to the supplied
reviewer set.contracts/reference.gates.jsondeclares its owndefault_approvers(sasuke,tenma) — reachable with no--approversflag at all — so the--gatesshape's row 5 is a real approver check. On the hand-supplied path, pass the target's
declared approvers explicitly, or--approvers ""only for a declaredreview-round-onlypolicy;
state that choice and its source. A reviewer's observedCOMMENTEDstate never authorizes inventing
the empty policy. `sharingan` § 4 is authoritative. --explainrenders the conjunct-by-conjunct table in evaluation order, short-circuit rows
included, plus the fixed "what the gate does NOT decide" caveats — all computed and printed by the
verb itself; see § 3. Add--jsoninstead when a caller needs the same content structured
(conjuncts[],caveats[],meta).- Exit
0→ the verdict isready. - Exit
1→ the verdict is eithernot-ready: <first failing reason>orunevaluated: <what went wrong>— read the printed verdict string itself to tell them apart; both share the exit code. - Exit
2→ the invocation itself was refused before evaluation ever started (an unknown code, an
unparseable ref, no reviewer identities). Never render this as any of the three verdicts — quote the
refusal text verbatim; it is the trigger to ask for the missing piece and re-run (§ 1), not the end. A missing or expiredGH_TOKENis not this case: it
surfaces as theunevaluatedverdict on exit1(§ 4), verified live — quote that verdict, don't
reclassify it as a refusal.
Never pass --round-policy strict. bounded is the default and the settled CON-32(b) reading
(mirrors pr_ready_gate.sh's own --copilot-policy bounded default, RR-IS-#572); inheriting it is
what keeps every asker consistent when the policy is next revisited.
Pass --exclude-run $GITHUB_RUN_ID only from inside a job asking about its own PR
(RR-IS-#708) — it drops that run's own rollup entries so an in-flight job cannot self-block the
verdict. A human or a local session asking about someone else's PR passes nothing.
3. The report — verdict verbatim, then the breakdown
Lead with the verdict, quoted exactly as nen printed it. Not paraphrased, not summarised,
not softened. nen prints the whole line as <repo>#<N>: <gateLine> — that entire line is the first
line of the answer. gateLine (the plain-text tail, or the --json field of the same name) is only
the part after the : — e.g. not-ready: 3 unresolved review thread(s) (CON-32d) — never the<repo>#<N> prefix in front of it.
RETIRED at nen
0.7: a verdict that could not say which binary decided itRelay
--explain's provenance line, verbatim, with the verdict. From the pinned0.7.0the
header carries a third line:decided by nen 0.7.0 (/Users/<you>/.cache/nen/zheref_nen/v0.7.0/nen-darwin-arm64) at 2026-09-10T21:07:18ZVerified live (
docs/ab/pr-state.md§ Retired at nen 0.7); atv0.6.0the same invocation
printed the two header lines and no third.--jsongainsmeta.generator.executablebeside theprogramandversionit has carried sincev0.1.It is the VERSION and the PATH, and the distinction is the whole point.
nen --versionsays
which nen a caller believes it has;executablesays which file actually answered — a
checksum-verified binary under the bootstrap cache, a locally built one, orbun src/index.tsout
of a working tree, all three able to carry the same version string and different behaviour. It is
deliberately not a checkout SHA: a compiled binary has no checkout at evaluation time, and its
bytes are verifiable against the release's publishedSHA256SUMSinstead. A readiness claim
relayed without it is a verdict nobody can reproduce, which is the same reason § 4 refuses to
paraphrase the verdict itself.
Then the conjunct-by-conjunct table — rendered by --explain, not reconstructed by hand. The gate
is a conjunction evaluated in this order, and it short-circuits on the first failure, so
everything after the failing row is genuinely unknown and nen itself prints it as unevaluated
rather than as passing. The "what a failure reads as" column below is illustrative, verified live and
against nen's own source at the port (pinned v0.1.0; the six rows, their order and the three "does
NOT decide" caveats re-verified byte-for-byte in --explain's output at v0.3.0, and no v0.2.0/v0.3.0
changelog entry touches a conjunct's text) — relay --explain's own printed text, never retype it from
memory, since more than one of these rows has more than one real shape:
| # | Conjunct | Clause | What a failure reads as (illustrative — quote --explain, don't retype) |
|---|---|---|---|
| 1 | Mergeable | CON-42/1 |
mergeable=CONFLICTING, or mergeable=UNKNOWN (expected MERGEABLE — CON-42/1's added predicate) when GitHub is still computing or the PR is closed — re-run if open |
| 2 | Every reported check green, on the latest run per check name | CON-32(a) |
required checks reported but are not all green (CON-32a); a wholly empty rollup instead reads NO checks reported at head (CON-32a) — an EMPTY rollup, not a red one. …; a cancelled latest run instead reads required checks are not all green (CON-32a) — latest run CANCELLED, no verdict (needs a re-run, not a fix): <names> |
| 3 | No configured reviewer's requested round has stalled | CON-32(b) |
<reviewer> round stalled — requested N min ago and never posted (CON-32b; re-request it, a user token is required) — <reviewer> is whichever configured name actually stalled, never hardcoded to one identity |
| 4 | No configured reviewer's round owed at the current head | CON-32(b) |
a configured reviewer's round is still owed at the current head (CON-32b): <reviewer> (…) |
| 5 | Every approving reviewer's latest round is an APPROVE at the current head | CON-32(b)/CON-16 |
not every approving reviewer's latest round is an APPROVE (CON-32b): <unapproved> — the printed text does not repeat "at the current head"; that reading lives in the conjunct's own definition (CON-16), not in the failure string |
| 6 | Zero unresolved review threads | CON-32(d) |
N unresolved review thread(s) (CON-32d) |
CON-30's dependency-author carve-out — new at nen
0.7, and never silentRows 3, 4 and 5 can be satisfied by a review SHIM rather than by a review round, where the
target repository's ownnen/gates.jsondeclaresdependabot_carve_out(author_patternplussatisfied_by_context). The field has been data since it was written and no build parsed it
until this pin —nen schema checkreportedokbecause the block was IGNORED, not because it
was understood — so the shim workflow and the decider were agreeing about a rule only one of them
could see. The decider carries it now, which is CON-30's own instruction.Where it sits in the conjunction is the design, and it is what you relay. Row 2 (
CON-32(a))
runs first, so a dependency PR is never exempted from having checks or from their being green
— an empty rollup still fails and a red one still fails. Row 6 (CON-32(d)) runs after,
untouched: a human who opened a thread is owed an answer whether or not a shim covered the rounds.
It is satisfied by PRESENCE, never by absence — a PR missing one of the named contexts has not
been shimmed, it has merely not been reviewed — and every named context must be green on its
latest run.Read it off the report, never infer it.
--explainprints the reason under each row it
satisfied (conjuncts[].noteunder--json— a separate field fromreason, which means
"the gate's own words for what FAILED"; rendering one as the other reports a satisfied row as a
problem), andmeta.dependabotCarveOutsays whether it fired. Verified live at the pinned0.7.0(docs/ab/pr-state.md§ Retired at nen 0.7):falseon an ordinary evaluation,nullon anunevaluatedreport — where the gate never ran far enough to ask, andfalse
there would read as "asked, and no", a claim about evidence nobody looked at.Two absences to state rather than assume. The carve-out never applies on the
--reviewers
identity path, which names no file and therefore declares none. Andcontracts/reference.gates.json— the file this skill passes for the frozen reference
implementation — declares no carve-out, so every verdict it produces isdependabotCarveOut: false. An emptysatisfied_by_contextis refused at LOAD, exit2(verified live): a
carve-out satisfied by no context is satisfied by nothing, and would openCON-32(b)outright for
the one author whose whole premise is that nobody reviews its work.
Name what the gate does NOT decide. --explain/--json prints this block automatically, every
time — it is no longer boilerplate the skill has to remember to append by hand, only content this
skill must never omit or soften when relaying it:
CON-32(c)"addressed" is approximated by rows 5 and 6 — the gate cannot read whether a
thread's substance was actually answered. Replying remains the author's obligation.- A build check existing SPECIFICALLY is not asserted — but some check must report. Row 2's
check-green conjunct islength > 0 and all(… SUCCESS/NEUTRAL/SKIPPED), so an empty rollup
fails. Absence is a finding here, not a pass (RR-IS-#680).
What the gate cannot tell you is which checks reported — a repo whereCON-19requires a build
check getsreadyfrom any other green check alone, so confirm by eye that the build one is among
them. CON-32(e)channel-less findings — a reviewer finding with no thread object (a suppressed-comments
block rendered in the review body) has nothing for row 6 to count. Read the review body, not just
its threads.
4. unevaluated is a finding, never a pass
Where the gate cannot decide — no GH_TOKEN-bearing token reachable, a network failure, a check
rollup that could not be read — nen itself prints:
<repo>#<N>: unevaluated: <what went wrong>followed by its own remedy line. Relay that remedy line verbatim, never paraphrased — it already
names the fix, and a paraphrase risks losing the exact grant or cause it points at.
Never ready, and never silently omitted. This is RR-IS-#680's principle in its smallest form:
absence is never a pass. An unevaluated PR is a row that needs attention, not one that cleared.
What would fix it — quote nen's own remedy line, verified live (and against nen's v0.1.0 source
at the port; the first shape re-verified live at v0.3.0, the others untouched by any later changelog
entry) for each shape below:
unevaluated: no usable token, so GitHub could not be read— theGH_TOKENexport in § 2 was
skipped or the token it names has expired; export a fresh one and re-run. This is verified live atv0.3.0: an invocation with noGH_TOKENset prints this exact string and a second line naming the
cause —GH_TOKEN is not set -- this client never picks a token up ambiently the way gh does, so the caller must mint one and name the variable it lives in. Never read this as "the PR is not ready" — it
is a caller-side setup gap.unevaluated: the check rollup could not be read for <owner>/<repo>#<N>— the remedy is a missing
token grant:checks:readalone is not enough, the rollup's owncheckSuite.workflowRunsub-field
needsactions:readtoo (verified againstsrc/github/pr_state.tsat thev0.1.0tag).nen
deliberately refuses to conflate this with an EMPTY rollup — a genuinely empty, readable rollup
isCON-32(a)'s ownnot-readyinstead (see § 3's build-check caveat). Unreadable and empty are two
different findings with two different remedies; never collapse one into the other.unevaluated: GitHub could not be read (<the API's own error text>)— the generic shape, also
printed when the ref names an issue, not a PR (§ 1's second callout: the API's own text readsCould not resolve to a PullRequest with the number of <N>).nen's remedy line here is a
token-grants checklist (pull-requests:read AND checks:read AND actions:read, not expired, network
reachedgithub.com) — relay it verbatim regardless, even though for the issue-number case
specifically the real cause is the wrong object type, not the token. This is the second documented
defect againstnen(§ 1, § 6) — recorded indocs/ab/pr-state.md§ 4 alongside the#-parser
bug, not routed around by hand.- A bare
nen: no reviewer identities …refusal (exit2, not a verdict at all) means the invocation
itself is missing--gates/--reviewersand the target carries nonen/gates.json(nor a legacyschemas/gates.json) — the refusal names both paths it looked in; fix the command, per § 2.
Historical note, kept because it is the reason this rule is written down.
RR-IS-#639 found the shell gate hittingE2BIGon
2 of 21 PRs whose check rollup exceeded the Windows argv cap. That specific cause is fixed in the
shell oracle — the large blobs reachjqthrough files, never argv — andnen pr readynever shells
the payload through argv at all, reading it over the GraphQL API instead. Do not report it as a
live limitation on either side. The rule it motivated stands on its own for every other way
evaluation can fail.
5. The binding rule — the half that actually changes anything
A readiness claim is
nen pr ready's verdict, quoted, or it is not made.
No agent — CI or local — and no session may describe a PR as ready, G2-ready, G4-ready or
mergeable on any other basis. Not a checks-page reading. Not "I just fixed it". Not the absence
of a red mark. Not "the reviewers approved". Not the checks being not yet reported, which is
the specific error RR-IS-#681 records: pending was read as green.
A skill nobody is obliged to use changes nothing, so the obligation is the rule and the skill is
merely the convenient way to satisfy it. Where the gate cannot evaluate, the claim isunevaluated — the one thing that is never available is calling it ready anyway.
6. What this skill must never do
- Act on the verdict. No label, no merge, no push, no comment, no re-request, no re-run — even
when the verdict isreadyand the next step is obvious. Say what the action is; do not take it. - Paraphrase the verdict. Quote it. A summarised verdict is a re-derived one.
- Report
readyfor a PR it could not evaluate. See § 4. - Guess a repo code, or infer one from the working directory when none was given.
- Improvise a no-
#split by hand.<CODE>#<N>is the unambiguous form; the shorthand resolves
sincev0.2.0(§ 1) but a code ending in a digit still needs the#, and there is never a reason to
re-split a ref yourself. - Take an
unevaluated: GitHub could not be read (…)token-grants remedy at face value for an
issue-number ref. § 1's second finding means that remedy is printed identically whether the token
is actually missing a grant or the number simply names an issue, not a PR — check which before acting
on the remedy. - Pass
--round-policy strict, or re-derive any conjunct by hand whennen pr readyis available. - Claim the conjuncts after the failing one passed. The gate short-circuits; they are unknown.