Split Hosted into account, relay, and voice origins - #867
Conversation
hosted.dormouse.sh keeps the account and its login cookie; relay.dormouse.sh serves the one-time rendezvous and /connect/; voice.dormouse.sh serves speak and the ElevenLabs sweep. Each Worker has its own 421 gate, bindings mapper, header policy, previews, and production deploy. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…mouse.sh Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nfigs Simplify pass on the split: one Worker registry and deploy loop for preview and production, one smoke sequence, the bindings mapper applied to cron handlers, per-Worker hashed-asset prefixes, dist/<worker>/ output, tests derived from the configs, and specs that state each rule once. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ts own Code-review fixes: the account preview carries no Durable Object migrations, production deploys relay → voice → account so the rendezvous never lapses, retries only the relay and voice smokes, runs the one-time smoke on relay health alone, and the local account dev server serves no speak route. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Deploying mouseterm with
|
| Latest commit: |
2b71f55
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://7957ea89.mouseterm.pages.dev |
| Branch Preview URL: | https://remote-network-hosted.mouseterm.pages.dev |
dormouse-bot
left a comment
There was a problem hiding this comment.
Feedback on the draft, not a merge verdict. Mark the PR ready when you want the full review.
Build & Test fails at the first step of the root pnpm test. spec-lint rejects the two backticked build-output paths that docs/specs/one-time.md → "Phone page" now names:
docs/specs/one-time.md:338: path does not exist -> hosted/dist/relay/
docs/specs/one-time.md:338: path does not exist -> hosted/dist/relay/connect/
The spec on main never named hosted/dist, so the lint has no exemption for it. The fix that matches the existing ones is to add 'hosted/dist' to SKIP_PATH_PREFIXES in scripts/spec-lint.mjs, next to lib/dist and standalone/dist. The other option is to drop the backticks on those two paths.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Manual test plan for the Hosted persistent stack (#867 → #868 → #869 → #870 → #872)Automated coverage: root 0. Unblock the previews
1. Enroll a Hosted desktop build (Local networks)
2. Pair a phone, then connect directly
3. Anywhere
4. Push
5. Removal and liveness
6. Regressions
Before production
|
dormouse-bot
left a comment
There was a problem hiding this comment.
Step 17 of the stack's manual test plan won't behave as written. It expects a dev build's spoken alert to go to the voice preview and get a 503. But hostedVoiceOrigin returns the fixed HOSTED_VOICE_ORIGIN (https://voice.dormouse.sh) whatever the baked relay origin is, and #872 doesn't change that. So a dev build carrying a token minted at the account preview sends it to production voice. Production has no record of a preview-minted token, so expect a 401 "A valid voice token is required.", or no answer at all until that custom domain is attached. The preview's 503 never comes. That's correct under this PR's design ("never baked and never overridden"). Either step 17's expectation changes, or a dev Hosted build needs a way to target the voice preview before step 17 can test the preview at all.
The account's v2 deletes the old OneTimeRoom, so it must never run until the relay serving the replacement passes its revision check and oneTimeSmoke. deployWorkers gains an afterDeploy hook; deployProduction runs relaySmoke (with the relay's six bounded attempts) after the relay deploy, and a failure stops before voice or account deploy. The full smoke still runs at the end. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts: # dormouse.yml # scripts/spec-word-budgets.json
|
@dormouse-bot The maintainer has explicitly instructed us to IGNORE ARGOS for this stack; they will handle the visual decisions separately. All other CI must pass, and we need your approval before merging. Please review the current head 2b71f55 and approve if there are no remaining findings; please do not merge, since I am handling the stack bottom to top. I corrected step 17 of the manual test plan in place: desktop speech always targets production voice, so a preview-minted token gets 401/system fallback there; the voice-preview 503 needs a direct call. The current |
dormouse-bot
left a comment
There was a problem hiding this comment.
Approved at 2b71f55. The Argos checks are left out of this verdict, as requested; every other check is green.
First of the Hosted persistent stack (
docs/specs/remote-network.md→ "Hosted persistent", with saas-multitenant indocs/specs/relay.md). It resolves the one-origin pin before any Relay code lands.Origins (decided 2026-09-30):
hosted.dormouse.shdormouse-hostedrelay.dormouse.shdormouse-relay(new)/connect/; the Relay and Pocket land here in the next PRsvoice.dormouse.shdormouse-voice(new)/api/voice/speakand the ElevenLabs history sweepWhy separate: Pocket and
/connect/render untrusted terminal output, so they must never share an origin with the login cookie. Sibling origins are same-site, so every cookie route keeps its exact-Origin+ CSRF check; that is now an audited FAIL IF.Desktop:
DEFAULT_RELAY_ORIGINis nowhttps://relay.dormouse.sh. A Hosted build speaks at the fixedhttps://voice.dormouse.sh; a self-host build reaches neither. No released build bakeshosted.dormouse.sh(v1.1.0 predates one-time and voice), so no compatibility shim.Hosted:
hosted/scripts/workers.mjs) derives preview and production configs from eachwrangler*.jsonc.OneTimeRoommoves todormouse-relayas its first migration (v1). The account Worker appendsv2 deleted_classes. Production deploys relay → voice → account, so the rendezvous never lapses.Operator steps before the first production release (
hosted/README.md):relay.dormouse.shandvoice.dormouse.shcustom domains (created on deploy).ELEVENLABS_API_KEYondormouse-voice, then remove it fromdormouse-hosted.hosted.dormouse.sh.Not verified against Cloudflare:
v1andv2 deleted_classesis accepted for the existingdormouse-hostedscript;crons: []removes the account's old schedule.This PR's own preview is cleaned up by main's old script, which deletes only
dormouse-hosted-pr-N. If it closes unmerged, deletedormouse-relay-pr-Nanddormouse-voice-pr-Nby hand.Test plan
pnpm testgreen.test:deploy,test:miniflare, and the Dockerworkers.test.tssuite.Origin: <relay preview>; the one-time link from an innerdogfood build baked with the relay preview origin connects a phone.🤖 Generated with Claude Code