Skip to content

I4222 — A forge reply cut off on its way is asked again

When gh reports a forge reply that was cut off ('unexpected end of JSON input'), the integration forge counts it as an outage and asks again within its bounded backoff.

READY wave 0 · p0 · implementation profile · parallel safe

Part of ci-critical-path — The critical path from a change to its verdict, and from a merge to its verified deploy, runs under a minute warm.

Ready. Every dependency is done, so majordomus plan start I4222 will be accepted.

Objective

When gh reports a forge reply that was cut off ('unexpected end of JSON input'), the integration forge counts it as an outage and asks again within its bounded backoff.

Why

Master's pages runs went red twice in ui-snapshot, step 'the forge, observed', exit 12, for this one cause. Run 40086406838 (10:41Z) failed on the declarations GraphQL query at -F n=50 with 'failed: unexpected end of JSON input'. Run 40093453442 (12:38Z) failed the same way on 'gh pr list --state open --limit 500 --json ...,body,statusCheckRollup,...'. retry::transient matched timeouts, 5xx, rate limits, resets and EOFs, but not gh's wording for a cut-off reply, so the first truncation failed the whole observation and the site could not publish.

Current state

A cut-off reply is taken as the forge's answer: gh_retrying returns it at once and the observation fails with exit 12.

Desired state

'unexpected end of JSON input' is transient, retried with the forge's backoff (four attempts, 2/4/8 s) and reported with its attempt count if it does not stop. Case 742 proves a list cut off once is asked again and the observation is recorded.

Scope

  • apps/majordomus-cli/src/integration/retry.rs
  • apps/majordomus-cli/src/integration/forge.rs
  • test/cases/742_only_an_outage_is_asked_again.sh
  • .ai/repo/project/issues/I4222.yaml

Out of scope

  • Replacing gh pr list with a paged GraphQL read of its own; gh already pages it at a hundred
  • Retrying a merge: a merge that timed out may have landed, and it is still never asked again
  • A smaller declarations page: the size n=50 is pinned by twelve cases' scripted forges (861, 928-939), and the gh pr list cut-off is not a page-size matter; the retry covers both reads

Dependencies

None. This issue is a root of the graph.

Acceptance criteria

  • retry::transient holds 'unexpected end of JSON input' as an outage; a 401, a 404 and a refusal are still answers
  • Case 742: a pr list cut off once is asked exactly twice, the refresh exits 0 and records the observation; the four outage and refusal sections still hold

Validation

  • cargo test --lib integration::retry integration::forge::tests::the_forge_is_asked_exactly_this
  • bash test/run.sh 742_only_an_outage_is_asked_again

Evidence required

  • suite

Evidence

None recorded. Every token above needs a command or an artifact behind it before this issue can be completed; narrative is refused.

Risk

A forge that keeps cutting replies off now takes about 14 s of backoff before the observation fails, as for any outage.

Timeline

started
—
verified
—
completed
—

Those three fields, the evidence above and the state of the dependencies are all the status is made of. There is no status field to disagree with them.

Canonical record: .ai/repo/project/issues/I4222.yaml. Read it back with majordomus plan show I4222.

Searches the titles and descriptions of every page this site publishes.