feat(substrate): a queued execution past maxQueueAgeMs times out; ADRs 0004, 0010, 0012 match the code - #159
Merged
Merged
Conversation
…loses its row
ensureSandbox in {mode:'queue'} refuses an execution that has waited
maxQueueAgeMs or longer with `timedOut: true` and releases its queue row;
under the ceiling the row stays and the refusal carries retryAfterMs as
before. `timedOut` is an optional field on an output type, so
CONTRACT_VERSION holds.
ADR text matches the code: ADR-0004 names the ticket's signed fields
(consumer, key, pool, expiry) and the queue timeout, ADR-0010 is `partial`
with consumer-only pool selection, and ADR-0012 and the contract comment
name the detached status `gone`.
debuggingfuture
marked this pull request as ready for review
September 24, 2026 08:31
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A consumer that queues for a substrate sandbox now gets the queue-age ceiling it asks for, and four ADR statements match what the substrate does.
Problem & Insight
AdmissionModecarries{mode:'queue', maxQueueAgeMs}and ADR-0004 promises a typed queue timeout, but nothing inapps/substrateread the value. A queued execution could not time out in the substrate, and a consumer that abandoned its wait left a queue row that only lapsed through the waiter TTL. No consumer queues today: the dispatcher's runtime adapter and fractalbot both callensureSandboxinrefusemode, and the dispatcher enforces its own ceiling inpackages/core/src/run-admission.ts. The change takes effect for the first consumer that opts into queue mode.verifyTicketchecks consumer and key, so one consumer cannot boot with another's ticket.shippedfrom the recipe.classForreads the consumer only, which leaves thebrowserandagentclasses deployed and unselectable.unknown. The type andsandbox-do.tsusegone.Take
ensureSandboxin queue mode refuses an execution that has waitedmaxQueueAgeMsor longer withtimedOut: trueand releases its row. Under the ceiling the row stays and the refusal keepsretryAfterMs.timedOutis an optional field on an output type, soCONTRACT_VERSIONholds (perapps/docs/substrate/contract-versioning.md).describeRefusalinruntime-cfrenders a timeout distinctly from a busy pool.Proposed, so the text is corrected in place. ADR-0010 is markedpartialrather than implemented: recipe-based selection waits for the dispatcher's run catalog to move onto the facade, and removing the two unused classes would need a Durable Object migration.gonestays; renaming it would be a breaking change to fix a comment.Key actions
facade.workers.test.tscovers both sides of the ceiling. The timeout test fails without the facade change.vendor/substrate-contract) is byte-checked against this file in its CI; refresh the copy and its pin after merge. The change is an additive optional field, so no call site in fractalbot changes.