Problem
When the host permission classifier denies the readiness gate, nothing mechanical stops an orchestrator from reporting a PR as merge-ready anyway. The guard is prose in skills/babysit-prs/reference/loop.md:484-488 (a NEVER-do bullet) and :536-541 (§5.5 "Gate verdict, quoted verbatim") — instructions to an agent, not a predicate that refuses.
The plugin's own philosophy, stated in scripts/babysit-readiness-gate.sh, is the standard this fails:
Prose "MANDATORY" is a word; this gate counts rows, not intentions.
Why the existing READINESS_UNPROVEN verdict does not close it
PR #1264 added an unproven() helper (scripts/babysit-readiness-gate.sh:109-112) that prints READINESS_UNPROVEN reason=<...> pr=<n>. That is a real improvement to the gate's own output hygiene and should land on its merits. It is not enforcement:
- Exit codes are unchanged (3 and 4), which that PR's CHANGELOG states outright: "Exit codes are unchanged, so existing callers keyed on them are unaffected." No caller's behavior changes.
- No executable consumer parses the token.
git grep -n "READINESS_" across plugins/source-control, excluding the gate and its own tests, returns only CHANGELOG, reference/review-discipline.md, reference/loop.md, reference/safety.md, skills/babysit-prs/evals/evals.json, two Python source comments (babysit_classify.py, babysit_findings.py), and test files. The only consumer is an LLM told to quote it.
- The branch concedes the gap in writing (
reference/safety.md:383-385): "a gate the harness never let run cannot report its own non-invocation, which is why the quoted-verdict requirement lives on the report rather than inside the script."
Scope note — #787's gate is a different script
#787's denied invocation was the merge-readiness gate:
python .../babysit_merge.py <pr> --allowed-owners ... --self-logins @me
babysit_merge.py still emits a JSON object with exit codes 0/10/2/3 and has no state distinguishing "readiness could not be proven" from "the command never ran". Any mechanical fix has to reach it, not only scripts/babysit-readiness-gate.sh.
The setup canary does not detect the condition either
skills/setup/SKILL.md probes reachability with --help invocations only. A classifier decision is per-call, so a host that permits --help and denies the production argument shapes (owner/repo#N --allowed-owners ...) yields a PASS from a lane that cannot prove readiness. Raised independently by the Codex reviewer on #1264 (skills/setup/SKILL.md:146, :147).
What would actually close it
Not prescribing a design, but the shape has to satisfy: an orchestrator that never obtained a passing gate verdict cannot emit a merge-ready verdict, and the refusal is made by code rather than by an instruction. Candidates worth weighing:
- A readiness assertion the orchestrator must present, produced only by a real gate run and checked mechanically before a merge-ready line is accepted — moving the trust anchor from the report to an artifact.
- Extending the readiness-gate predicate so that consuming machinery (rather than an LLM) reads the verdict and refuses on
READINESS_UNPROVEN or on absence.
- Giving
babysit_merge.py the same unproven state and a non-zero exit distinct from "not ready", so a caller keyed on exit codes can tell the two apart.
Whichever shape wins, a canary that exercises the production argument shapes rather than --help is part of it, or the lane still cannot tell a permitted probe from a permitted job.
Related
Problem
When the host permission classifier denies the readiness gate, nothing mechanical stops an orchestrator from reporting a PR as merge-ready anyway. The guard is prose in
skills/babysit-prs/reference/loop.md:484-488(a NEVER-do bullet) and:536-541(§5.5 "Gate verdict, quoted verbatim") — instructions to an agent, not a predicate that refuses.The plugin's own philosophy, stated in
scripts/babysit-readiness-gate.sh, is the standard this fails:Why the existing
READINESS_UNPROVENverdict does not close itPR #1264 added an
unproven()helper (scripts/babysit-readiness-gate.sh:109-112) that printsREADINESS_UNPROVEN reason=<...> pr=<n>. That is a real improvement to the gate's own output hygiene and should land on its merits. It is not enforcement:git grep -n "READINESS_"acrossplugins/source-control, excluding the gate and its own tests, returns only CHANGELOG,reference/review-discipline.md,reference/loop.md,reference/safety.md,skills/babysit-prs/evals/evals.json, two Python source comments (babysit_classify.py,babysit_findings.py), and test files. The only consumer is an LLM told to quote it.reference/safety.md:383-385): "a gate the harness never let run cannot report its own non-invocation, which is why the quoted-verdict requirement lives on the report rather than inside the script."Scope note — #787's gate is a different script
#787's denied invocation was the merge-readiness gate:
babysit_merge.pystill emits a JSON object with exit codes 0/10/2/3 and has no state distinguishing "readiness could not be proven" from "the command never ran". Any mechanical fix has to reach it, not onlyscripts/babysit-readiness-gate.sh.The setup canary does not detect the condition either
skills/setup/SKILL.mdprobes reachability with--helpinvocations only. A classifier decision is per-call, so a host that permits--helpand denies the production argument shapes (owner/repo#N --allowed-owners ...) yields a PASS from a lane that cannot prove readiness. Raised independently by the Codex reviewer on #1264 (skills/setup/SKILL.md:146,:147).What would actually close it
Not prescribing a design, but the shape has to satisfy: an orchestrator that never obtained a passing gate verdict cannot emit a merge-ready verdict, and the refusal is made by code rather than by an instruction. Candidates worth weighing:
READINESS_UNPROVENor on absence.babysit_merge.pythe same unproven state and a non-zero exit distinct from "not ready", so a caller keyed on exit codes can tell the two apart.Whichever shape wins, a canary that exercises the production argument shapes rather than
--helpis part of it, or the lane still cannot tell a permitted probe from a permitted job.Related