Skip to content

Give Workshop its own Gateway discovery and progress type - #186

Merged
vinniefalco merged 2 commits into
cppalliance:masterfrom
vinniefalco:master
Oct 30, 2026
Merged

vinniefalco merged 2 commits into
cppalliance:masterfrom
vinniefalco:master

Conversation

@vinniefalco

Copy link
Copy Markdown
Member

Workshop and the Harness must depend on the Gateway only through a written API contract, never through shared Rust crates. A shared crate welds the two sides together in a way that only a single Cargo workspace can express, so the Gateway can never leave this repository while one exists. This change removes the last one on the Workshop side. Workshop now reads gateway.json and the two HTTP endpoints through a reader crate of its own, and it declares the progress payload as its own wire type.

The branch also contains a separate commit that removes the retired realtime ranges extension.

Dependency edges cut

Seven dependency edges ran from Workshop crates into Gateway crates before this change. The count is zero after it.

  • crates/workshop/desktop/Cargo.toml declared gateway-api-discovery as a dependency and again as a dev-dependency.
  • crates/workshop/gateway/Cargo.toml declared gateway-api-types, gateway-api-discovery, and a second gateway-api-discovery dev-dependency.
  • crates/workshop/server/Cargo.toml declared gateway-api-discovery as a dependency and again as a dev-dependency.

A reviewer can confirm the current count with cargo metadata --format-version 1 --no-deps.

The new crates/workshop/gateway-discovery crate

workshop-gateway-discovery is a fork of the reader half of crates/gateway-api-discovery. It reads the discovery file, validates the fields, applies the stale rule, settles a launch race, waits for health, and asks the Gateway to exit. It needs no async runtime, so Workshop holds the contract without adopting one.

crates/workshop/gateway-discovery/CONTRACT.md documents the protocol: the six file fields, the two lock files, the stale rule, the shutdown route, the three HTTP calls, and the golden fixtures. Both halves are written against that text.

crates/gateway-api-discovery and crates/gateway-api-types are untouched. The Gateway's writer remains the authority for its side of the protocol.

Enforcement

crates/build-xtask/src/product.rs no longer defines PUBLIC_GATEWAY, and the Workshop exception that let the gateway public pair through is gone. The Workshop rule now reads the same as every other family rule: no Workshop crate may depend on any Gateway crate. A new edge of that kind fails cargo test -p build-xtask, and the failure names the package and the dependency. The tests in crates/build-xtask/src/product/tests.rs cover both former exceptions, gateway-api-types and gateway-api-discovery, plus gateway-routing.

The progress type

Progress is now defined in crates/workshop/gateway/src/progress-wire.rs instead of being imported from gateway-api-types. Its two fields, busy and text, are deliberately required. A payload that omits one is a decode error rather than a default, so a version skew reports itself instead of showing a status bar that silently under-reports. crates/workshop/gateway/src/progress-wire-tests.rs pins the field names and their JSON types against golden documents.

How this was verified

  • cargo check --workspace --all-targets reports no errors.
  • cargo test -p workshop-gateway passed 85 tests.
  • cargo test -p workshop-gateway-discovery passed 75 tests.
  • cargo test -p workshop-server passed 145 tests and 76 tests.
  • cargo test -p workshop --bin runvil-workshop passed 89 tests.
  • cargo test -p build-xtask passed 264 tests, and discovery_conformance passed 7 tests.
  • cargo clippy --workspace --all-targets reports zero warnings.
  • cargo fmt --all --check reports no differences.
  • cargo xtask tidy reports no violations.

The rule was proven to fire rather than assumed to. Injecting a real gateway-api-types edge into workshop-gateway made cargo test -p build-xtask fail with a message that named the edge.

Reviewer notes

  • The fork duplicates about 2,250 non-test lines of read, validate, and per-OS process-lookup logic. A platform fix is now made in two places until the Gateway owns one copy again.
  • crates/build-xtask/tests/discovery_conformance.rs is the one crate that names both families. It runs the Gateway's real writer against Workshop's reader, and it exists only while both live in this workspace, so it disappears when the Gateway moves.
  • resolve_for_test is kept, gated to #[cfg(any(test, feature = "test-fixtures"))] and marked #[doc(hidden)]. The in-process resolution tests write a file that names the test binary's own pid, and that image can never pass the runvil-gateway name check.

This removes the \item.input_audio_transcription.hypothesis.ranges\ include token and the two hypothesis fields \inalized_through_ms\ and \inalized_seq\. A session that names the retired token now reaches the \unsupported_include\ error arm of the include parser. The base hypothesis include and its events do not change.

- \HypothesisInclude\ keeps only \Off\ and \Snapshots\, and \FinalizedRange\ keeps only \seq\. \deserialize_present\ and \FinalizedRange.through_samples\ are deleted.

- \last_hypothesis\ now holds an \InterimSnapshot\, so a change in ranges alone cannot advance the revision. \�n_unchanged_hypothesis_keeps_its_revision_for_a_new_window\ keeps the revision rule for a base session.

- The ranges fixtures and tests are deleted in \crates/gateway/stt/api\. \capture.rs\ negotiates only the base token.

- \
ealtime-wire-fixtures.mjs\ gains a decoder test for an unnegotiated include. \stt-stream.mjs\ now sends an unnegotiated include and a \
evision\ of the wrong type.

- The commit changes no Workshop source file and no documentation.
Workshop reads the Gateway discovery file and the progress snapshot without naming a Gateway crate. `crates/workshop/gateway-discovery` holds the reader half, with `CONTRACT.md` and golden `fixtures/`, and `crates/workshop/gateway` defines `Progress` locally in `progress-wire.rs`. The `crates/workshop/gateway`, `crates/workshop/server`, and `crates/workshop/desktop` manifests drop `gateway-api-discovery` and `gateway-api-types`, and `build-xtask` removes `PUBLIC_GATEWAY`.

- `build-xtask` carries `tests/discovery_conformance.rs`, the one crate that names both halves, so it runs the Gateway writer against the forked reader while both sit in this workspace.
- The Realtime socket's origin rule runs from the private `realtime-origin.rs` module and refuses a non-`http` scheme, a userinfo-bearing authority, and any host or port mismatch.
- The writer half stays out of production builds: `workshop-gateway-discovery` compiles its write, remove, and process-lease functions only under `test-fixtures`.
@vinniefalco
vinniefalco merged commit 4206be9 into cppalliance:master Oct 30, 2026
45 of 49 checks passed

This branch was successfully deployed

1 active deployment
github-pages — 4206be90 Deployed Oct 30, 2026 by vinniefalco via deploy #149
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