Skip to content

[finding] The shared transport verdicts speak check-half-states' vocabulary ("the sweep", "the board read"), and #9966 just routed them to a second caller that does neither #10156

Description

@os-zhuang

Filed unassigned by the #9966 dev seat (session session_01DdCnBGcHeufjrq7drTD3wt), out of that card's scope: #9966's declared file surface is scripts/pm/ci-failure.mjs, and this wording lives in scripts/pm/check-half-states.mjs. Duplicate search first: swept all 231 open issues for the transport / verdict / wording shapes plus a semantic search — no hit. Adjacent but distinct: #10155 (the walk's missing transport net), #9898 (this file's --self-test runs nowhere in CI).

Observed, 2026-08-20, as real output

With #9966's repo-scoped stage adopted, ci-failure.mjs now prints the shared repo-scope-refused verdict verbatim:

$ PM_SWEEP_REPO=objectstack-ai/objectui node scripts/pm/ci-failure.mjs --sha 2d3860df9aad...
ci-failure: PREREQUISITE NOT MET — the transport authenticates but repo-scoped reads are
  refused — the sweep cannot list one page
  ...
  fix: run the sweep from a container whose egress allows repo-scoped reads (CI, or
  fix: the Routine seat class); in a proxy-mediated seat the board read stays on the
  fix: `mcp__github__*` tools, which take a different path and do work here.
EXIT=3

ci-failure.mjs runs no sweep and reads no board — it walks check-runs, jobs and annotations for one sha. A seat that pointed it at a CI failure is told the remedy for a half-state board read.

Why it is a finding and not a defect in #9966

The classification is exactly right, the exit code is right, and ci-failure.mjs deliberately imports the classifier rather than copying it — its header states the trade in as many words:

Classified by check-half-states.mjs's probe, which is imported rather than re-implemented: same numbers, same wording, one instrument.

So "same wording" was chosen with eyes open when there was one caller whose vocabulary it matched. What changed is only that a second caller now reaches these two strings, and its nouns are different. Nothing is wrong; one sentence is now addressed to the wrong reader.

The shape of a fix, if it is judged worth one

Only the caller knows what it is about to do, so the noun has to come from the caller — e.g. classifyTransportProbe({ ..., subject: 'the walk' }) defaulting to today's 'the sweep', touching the two verdicts that name it (repo-scope-refused, and rate-limited's how clause already parameterises this way, which is the precedent). That is a change to check-half-states.mjs and its self-test, which is why it is filed rather than ridden along.

Cheaper alternative worth weighing first: decide the verdicts should be caller-neutral prose ("this container cannot make one repo-scoped request") and drop the subject noun entirely — one edit, no parameter, no per-caller state.

Generated by Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions