Skip to content

spec(queen): vendor dispatch_exit -- a provider refusal never charges the issue (t27#10008) - #2042

Open
gHashTag wants to merge 1 commit into
queenfrom
spec/dispatch-exit-provider-10008
Open

gHashTag wants to merge 1 commit into
queenfrom
spec/dispatch-exit-provider-10008

Conversation

@gHashTag

Copy link
Copy Markdown
Owner

Refs gHashTag/t27#10008 (card PR gHashTag/t27#10011). Part of gHashTag/t27#9976.

Why

The bee actors (queen-bee-actors.ts, TRIOS_QUEEN_DISPATCH=actors) ask dispatch_exit counts_against_issue whether an end spends a counted run.

  • A provider quota refusal (provider quota exhausted (zai code N)) did. Three in a row (RUN_LIMIT) gave the issue up, and BK_GAVE_UP is sticky until a send-back.
  • The refusal belongs to the key, not the issue. The next dispatch takes another key from the pools.
  • key_failover.t27 charges_issue (t27#9993) already said so. The card now agrees.

This lands before TRIOS_QUEEN_DISPATCH=actors is switched on in production.

What changes

  • specs/queen/dispatch_exit.t27: re-vendored, byte-identical to t27 blob 4f9fa86b.
  • specs/queen/dispatch_exit.wasm: rebuilt with the recipe in specs/PIN.
    • The same recipe rebuilds the old card to the pinned 31c0e524..., so it is the recipe that is in use now.
    • The new card gives b990a601... on two builds.
  • specs/PIN: lines 41-43 carry the new blob and hashes.
  • No TypeScript changes. The constants (queen-dispatch-exit-card.gen.ts) are unchanged.

Behaviour

  • A provider refusal is no longer a counted run. A bad request (HC_4XX) still gives up at once, and a refusal that keeps repeating still ends at STREAK_LIMIT (6).
  • tests/api/queen-bee-actors-round.test.ts only checks that a quota row reads as EF_PROVIDER, which is unchanged.

Card evidence (Railway lab):

  • t27c test-report: 11/11, 0 vacuous.
  • tri mutate spec: 81 of 84 killed. The 3 survivors are equivalent clamp mutants in the untouched restart_wait_seconds.

πŸ€– Generated with Claude Code

… the issue (t27#10008)

Re-vendors gHashTag/t27 specs/queen/dispatch_exit.t27 from t27 PR #10011
(blob 4f9fa86), byte-identical, with dispatch_exit.wasm rebuilt by the PIN
recipe (zig 0.16.0, wasm32-wasi, reactor, every fn exported). The recipe
rebuilds the old card to the pinned 31c0e524 and the new card to b990a601 on
two builds.

counts_against_issue(DX_PROVIDER_ERROR) is now false, so the bee actors stop
giving an issue up after three quota refusals; the next dispatch takes another
key. A bad request still gives up at once, and a repeating refusal still ends at
STREAK_LIMIT. No TypeScript changes: the hosts read the card from the wasm.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@tri-claw

tri-claw Bot commented Oct 17, 2026

Copy link
Copy Markdown

Summary by t27-bees

Checked by the t27 compiler

t27c parse, parse-complete and typecheck on each changed .t27 file at 4d8c713. Nothing was generated, built or run. A pass means the file is well formed, not that it is right.

  • trios/agent-server/specs/queen/dispatch_exit.t27: parses and typechecks.

Read by the model

This PR updates the dispatch_exit spec card so that provider errors (quota exhaustion, overload, 5xx) no longer count as "counted runs" against an issue. Previously three provider refusals would trigger RUN_LIMIT and give up the issue; now they're treated as key-level failuresβ€”the next dispatch picks another keyβ€”and only a repeating refusal hits STREAK_LIMIT (6). The WASM is rebuilt from the updated spec; no TypeScript code changes.

Worth a look

  • specs/queen/dispatch_exit.t27:154 β€” counts_against_issue now returns false for DX_PROVIDER_ERROR. If the key pool is exhausted and no healthy key remains, the issue could retry indefinitely (up to STREAK_LIMIT) instead of failing fast at RUN_LIMIT (3). The key_failover.t27 logic must reliably rotate keys; otherwise the issue stalls.
  • specs/queen/dispatch_exit.t27:275 β€” Test expectation flipped: DX_PROVIDER_ERROR is no longer a counted run. Any downstream consumer that relied on three provider errors giving up the issue will now see up to six retries (streak limit) before RD_GIVE_UP.
  • specs/queen/dispatch_exit.t27:287–299 β€” New test a_provider_refusal_never_charges_the_issue codifies the new contract: DX_PROVIDER_ERROR with HC_NONE/HC_429/HC_5XX returns RD_LATER even at RUN_LIMIT, but HC_4XX still gives up immediately. If the HTTP-class mapping in the host (queen-dispatch.ts) misclassifies a 4xx as 5xx (or vice versa), the give-up behavior diverges from intent.
  • specs/PIN:41–43 β€” Pinned hashes updated for the new card and WASM. The build recipe is unchanged (zig 0.16.0, -Oz -DNDEBUG -mexec-model=reactor), so reproducibility depends on that toolchain staying available.
  • No TypeScript changes β€” The generated constants in queen-dispatch-exit-card.gen.ts are said to be unchanged. If the host code branches on counts_against_issue return values, verify it doesn't assume provider errors still count toward RUN_LIMIT.

Read: 3 files, +27 -5, the whole diff. Head 4d8c713. Model: openai-compatible/nvidia/nemotron-3-ultra-550b-a55b. Commands: @t27-bees review | summary | help | pause | resume. Free for every repository.

@github-actions

Copy link
Copy Markdown

❌ Tests failed β€” 27/3971 failed

Suite Passed Failed Skipped
βœ… agent 429/429 0 0
βœ… build 9/9 0 0
βœ… cdp-protocol 5/5 0 0
βœ… eval 93/93 0 0
βœ… server-agent 280/280 0 0
❌ server-api 2229/2328 27 72
βœ… server-browser 6/6 0 0
βœ… server-integration 10/11 0 1
βœ… server-lib 279/279 0 0
βœ… server-pglive 166/166 0 0
βœ… server-root 68/68 0 0
βœ… server-sim 8/8 0 0
βœ… server-skills 31/31 0 0
βœ… server-tools 244/244 0 0
βœ… shared 14/14 0 0
Failed tests
  • server-api β€” the review, without a compiler > escalates a branch that changed specs and says the compiler is missing
  • server-api β€” a salvaged attempt is judged, not released > is empty before the salvage and reaches the reviewer after it
  • server-api β€” the sweep weighs what the Queen measured > measures the dispatch criteria at the branch head, once per head
  • server-api β€” the sweep weighs what the Queen measured > runs nothing for criteria that state no command
  • server-api β€” the sweep weighs what the Queen measured > shows the reviewer every measurement inside the fence, citable by number
  • server-api β€” the sweep weighs what the Queen measured > never accepts on measurements alone
  • server-api β€” one sweep may not measure for ever > spends a measurement budget, and never ahead of the review it feeds
  • server-api β€” one sweep may not measure for ever > does not cache a measurement that established nothing
  • server-api β€” the adversary is not the worker (#1127) > is the prompt the sweep actually sends
  • server-api β€” the adversary is not the worker (#1127) > never shows the reviewer the bee transcript
  • server-api β€” which model reviews > logs which model delivered the verdict
  • server-api β€” the reviewer cache > makes no second model call over an unchanged head
  • server-api β€” the reviewer cache > buys a new review when the branch moves
  • server-api β€” the verdict, with an adversary > never accepts on the bee word when no reviewer lane is free
  • server-api β€” the verdict, with an adversary > spends nothing when the reviewer call is refused
  • server-api β€” the verdict, with an adversary > tries another lane when a provider says "not now"
  • server-api β€” the verdict, with an adversary > does not charge a miss when a busy lane is followed by a broken one
  • server-api β€” an empty attempt the provider ended > selects what it needs to tell them apart, oldest review first
  • server-api β€” a retry that added nothing > does not mistake a wait re-read for a new attempt
  • server-api β€” the combination rule, pinned > never passes a criterion the reviewer left unanswered
  • server-api β€” the combination rule, pinned > holds a could-not-check send-back for the reviewer when no lane is free
  • server-api β€” a met must cite what was shown > asks no reviewer about a patch that could not be read
  • server-api β€” a reviewer that cannot answer > falls back from a lane refused for good, and remembers it
  • server-api β€” a reviewer that cannot answer > escalates a commit after REVIEWER_MISS_CEILING undelivered reviews
  • server-api β€” the budget and the keys > buys no more reviews than the round allows, and counts running keys
  • server-api β€” the cache key and the brief > buys a new review when only the criteria changed
  • server-api β€” the cache key and the brief > does not hand the reviewer the evidence a bee appended to a stated criterion

View workflow run

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant