Quantum Studio: a run on the job service whose answer is lost is sent again, safely #600

Merged
dcharlot merged 1 commit from wai/quantum-studio-service-retry into main 2026-11-03 15:10:55 -05:00
Owner

The Studio's runs on the job service sent each job once, and gave up at the first lost answer, whether of the submission or of any poll. This is the browser's side of #596: the service's Idempotency-Key.

What changes

wai/quantum-studio/src/engine.js (ServiceEngine)

  • The key: the Studio asks the service once whether it keeps keys (GET /v1's idempotency). To one that does, a run goes under an Idempotency-Key of its own, a random UUID.
  • Sent again: where no answer comes back, the run is sent again under that key, twice at most, so a job the service took is answered rather than taken twice.
  • To a service that keeps no keys, such as the one live today, the Studio sends no key and never sends a job twice. That service's CORS preflight does not allow the header, so sending a key would block the run in the browser. The Studio therefore works against today's service and starts sending keys once #596 is deployed.
  • Polls: a poll whose answer is lost no longer ends the wait. Five lost in a row do.

The READMEs (in English and Chinese) and the CHANGELOG say so.

Tests

test/service.test.mjs, against a scripted fetch:

  • a run whose submission's answer is lost is sent again under the same UUID and ends done;
  • a service that keeps no keys is sent the job once, with no key header;
  • a lost poll does not end the wait;
  • the service is asked once whether it keeps keys;
  • five lost polls in a row end the wait.

The studio workflow runs it on its three legs, beside the hardware test.

Checked

  • node test/service.test.mjs: every check passes, here and in CI's image (catthehacker/ubuntu:act-22.04, Node 24).
  • The views page rebuilt there with Rust 1.98.0 (wai-quantum-views/build.sh) is the committed bytes. engine.js is not one of its 49 sources, so build-views.mjs --check holds.
  • The workflow parses. The public-name check is clean.

🤖 Generated with Claude Code

The Studio's runs on the job service sent each job once, and gave up at the first lost answer, whether of the submission or of any poll. This is the browser's side of #596: the service's `Idempotency-Key`. ## What changes `wai/quantum-studio/src/engine.js` (`ServiceEngine`) - **The key:** the Studio asks the service once whether it keeps keys (`GET /v1`'s `idempotency`). To one that does, a run goes under an `Idempotency-Key` of its own, a random UUID. - **Sent again:** where no answer comes back, the run is sent again under that key, twice at most, so a job the service took is answered rather than taken twice. - **To a service that keeps no keys,** such as the one live today, the Studio sends no key and never sends a job twice. That service's CORS preflight does not allow the header, so sending a key would block the run in the browser. The Studio therefore works against today's service and starts sending keys once #596 is deployed. - **Polls:** a poll whose answer is lost no longer ends the wait. Five lost in a row do. The READMEs (in English and Chinese) and the CHANGELOG say so. ## Tests `test/service.test.mjs`, against a scripted `fetch`: - a run whose submission's answer is lost is sent again under the same UUID and ends done; - a service that keeps no keys is sent the job once, with no key header; - a lost poll does not end the wait; - the service is asked once whether it keeps keys; - five lost polls in a row end the wait. The studio workflow runs it on its three legs, beside the hardware test. ## Checked - `node test/service.test.mjs`: every check passes, here and in CI's image (`catthehacker/ubuntu:act-22.04`, Node 24). - The views page rebuilt there with Rust 1.98.0 (`wai-quantum-views/build.sh`) is the committed bytes. `engine.js` is not one of its 49 sources, so `build-views.mjs --check` holds. - The workflow parses. The public-name check is clean. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Quantum Studio: a run on the job service whose answer is lost is sent again, safely
All checks were successful
WAI breaking changes and the conformance runner / WAI breaking · does this change touch WAI (pull_request) Successful in 8s
WAI energy receipts / does this change touch it (pull_request) Successful in 11s
wai-quantum contract / does this change touch it (pull_request) Successful in 9s
wai-quantum contract / the policy is linked, and the deprecations page reads (pull_request) Successful in 6s
wai-quantum docs, course and locales / does this change touch it (pull_request) Successful in 8s
WAI breaking changes and the conformance runner / WAI breaking · wire, record and API against main · linux (pull_request) Successful in 33s
wai-quantum studio and desktop / does this change touch it (pull_request) Successful in 9s
wai-quantum docs, course and locales / the Studio's words in every locale · linux (pull_request) Successful in 10s
wai-quantum views in agent hosts / does this change touch it (pull_request) Successful in 8s
WAI Studio / does this change touch it (pull_request) Successful in 8s
WAI Studio / the catalogue's actions, the unit tests and the core · linux (pull_request) Successful in 1m23s
WAI breaking changes and the conformance runner / WAI breaking and conform · their tests, and the independent verifiers through wai conform · linux (pull_request) Successful in 2m27s
wai-quantum docs, course and locales / the course and the command line's languages · linux (pull_request) Successful in 2m32s
wai-quantum studio and desktop / studio · browser (pull_request) Successful in 3m41s
wai-quantum views in agent hosts / views · a scripted host (pull_request) Successful in 4m47s
wai-quantum views in agent hosts / views · the page and its engine (pull_request) Successful in 5m9s
wai-quantum contract / schemas and the committed tool lists · linux (pull_request) Successful in 6m38s
standards workspaces build + test / macOS energy backends (pull_request) Successful in 7m18s
WAI energy receipts / energy receipts · macos (pull_request) Successful in 7m35s
wai-quantum studio and desktop / desktop app · linux (pull_request) Successful in 8m32s
wai-quantum studio and desktop / desktop app · windows (pull_request) Successful in 10m8s
wai-quantum contract / API compatibility · linux (pull_request) Successful in 12m3s
repository checks / lockfiles, advisories, tests in CI, workflow hygiene, spec and section references, public text (pull_request) Successful in 13m43s
WAI Studio / Studio in WebKit · linux (pull_request) Successful in 16m15s
wai-quantum studio and desktop / desktop app · macos (pull_request) Successful in 18m29s
WAI energy receipts / energy receipts · linux (pull_request) Successful in 28m58s
standards workspaces build + test / joule-code-rs (joule-code/joule-code-rs, joule-code-rs, linux-arm64, true) (pull_request) Successful in 8m15s
WAI Studio / Studio in Chromium and Firefox · macos (pull_request) Successful in 41m16s
wai-quantum docs, course and locales / every command and snippet in the docs · linux (pull_request) Successful in 43m34s
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Successful in 30m0s
2e7a49cd7a
The Studio's runs on the job service sent each job once and gave up on
the first lost answer, of the submission or of any poll. A run now goes
under an Idempotency-Key of its own (a random UUID) to a service whose
description says it keeps keys, and is sent again under it, twice at
most, where no answer came back, so a job the service took is answered
rather than taken twice. A service that keeps no keys is sent no key,
which its CORS would refuse, and no job twice. A poll whose answer is
lost no longer ends the wait; five in a row do.

test/service.test.mjs holds each of these against a scripted fetch, and
the studio workflow runs it. The views page is unchanged: engine.js is
not among its sources, and rebuilt in CI's image it is the same bytes.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Transaction-Science/open-standards!600
No description provided.