Repository navigation
One relay per release channel, deployed by CI when relay code changes - #2079
Merged
Merged
Conversation
Stable and rc builds keep syncing through https://codeaf.agentfield.ai/fabric; staging builds use the staging relay and every other build (dev tags, make build, tests) the dev relay, so a build nobody tagged never writes to production. CODEAF_SYNC_URL and a pairing's saved relay still win. The three addresses are spelled once, in internal/syncsetup/relayurl.go, and pairing links follow the channel's origin. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A relay job in the release workflow deploys caf-fabric-dev on dev pushes and caf-fabric-staging on staging pushes, only when the relay's input fingerprint differs from the live version's tag, and proves the deploy with the hosted conformance test and codeaf-release service, rolling back on failure. The production relay deploys only once the repository variable RELAY_DEPLOY_PRODUCTION is true. The relay keeps no logs and publishes no preview URLs, matching the live production Worker. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 31, 2026
AbirAbbas
added a commit
that referenced
this pull request
Oct 31, 2026
The link check recognises this build's own hosted origin however it is spelled, and leaves pair.LinkRelay exactly as #2079 wrote it. The rejoin test writes its device record itself, because syncsetup now imports pair. The front-page help is back under its line cap: codeaf relay keeps its own --help and the manual no longer says the front page lists it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
AbirAbbas
added a commit
that referenced
this pull request
Oct 31, 2026
The link check recognises this build's own hosted origin however it is spelled, and leaves pair.LinkRelay exactly as #2079 wrote it. The rejoin test writes its device record itself, because syncsetup now imports pair. The front-page help is back under its line cap: codeaf relay keeps its own --help and the manual no longer says the front page lists it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
AbirAbbas
added a commit
that referenced
this pull request
Oct 31, 2026
The link check recognises this build's own hosted origin however it is spelled, and leaves pair.LinkRelay exactly as #2079 wrote it. The rejoin test writes its device record itself, because syncsetup now imports pair. The front-page help is back under its line cap: codeaf relay keeps its own --help and the manual no longer says the front page lists it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
AbirAbbas
added a commit
that referenced
this pull request
Oct 31, 2026
The link check recognises this build's own hosted origin however it is spelled, and leaves pair.LinkRelay exactly as #2079 wrote it. The rejoin test writes its device record itself, because syncsetup now imports pair. The front-page help is back under its line cap: codeaf relay keeps its own --help and the manual no longer says the front page lists it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
AbirAbbas
added a commit
that referenced
this pull request
Oct 31, 2026
The link check recognises this build's own hosted origin however it is spelled, and leaves pair.LinkRelay exactly as #2079 wrote it. The rejoin test writes its device record itself, because syncsetup now imports pair. The front-page help is back under its line cap: codeaf relay keeps its own --help and the manual no longer says the front page lists it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
AbirAbbas
added a commit
that referenced
this pull request
Oct 31, 2026
The link check recognises this build's own hosted origin however it is spelled, and leaves pair.LinkRelay exactly as #2079 wrote it. The rejoin test writes its device record itself, because syncsetup now imports pair. The front-page help is back under its line cap: codeaf relay keeps its own --help and the manual no longer says the front page lists it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
AbirAbbas
added a commit
that referenced
this pull request
Oct 31, 2026
…ore removing (#2087) * Name the sync service in its own failures, and keep each error's class A relay that is down, slow or full now says so in one sentence family (internal/syncwords) instead of blaming the person's network or other machines. Status classes and causes stay exactly as before; only the words a person reads change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Pair through the right sync service, and let an unused computer join Every printed codeaf pair command carries --via on a self-hosted service. A computer whose only chats never had a turn sent can join without --replace; one with real chats is told how many and what --replace does. A removed computer can come back with --replace and a fresh device key. Removal by name refuses rather than guess when a roster cannot be read. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Say a quit saved here when only the upload is still pending A close that saved on this computer but could not reach the sync service prints that it is saved here and exits 0. A failed local write still says it could not save. The receipt is negotiated in the hello, so mixed old and new builds keep their former words and exit codes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Ask before removing a device, and draw device marks through the glyph door /devices asks once before removing a computer (y removes, any other key keeps it), lists this device and an Add another device row, and Home stays Home for /devices, /pair and /settings. Platform and presence marks come from tokens slots. A refused send keeps the person's words in the box. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Name cluster members by device on an opt-in status header Services that predate Codeaf-Cluster-Names send no labels, and the command then says another computer rather than claiming one was removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Bring the manual and the end-to-end words in step with pairing and sync wording Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Fit pairing's service check and the help page to per-channel relays The link check recognises this build's own hosted origin however it is spelled, and leaves pair.LinkRelay exactly as #2079 wrote it. The rejoin test writes its device record itself, because syncsetup now imports pair. The front-page help is back under its line cap: codeaf relay keeps its own --help and the manual no longer says the front page lists it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Change entry for #2087 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Keep the #2087 change title under one line Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Say "that chat stays" when the refusal counts one chat The hand walk read "those 1 chat stay on this computer but no longer sync". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Keep cluster, devices and terminal approval on the service this computer uses Cluster and device errors name the service the command used, never this build's hosted default. Verbose cluster status prints its membership labels as before. Roster names stay plain so a reused devbox name still finds the joined computer; duplicate tails are added only when the list is drawn. A terminal approving a self-hosted page's link keeps that page's service when it matches this computer's, and a link on another service is still refused before its code is sent. Existing tests change only where a deliberate L4 sentence or the solo device list (this device is listed) changed what they read. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Keep Home's whole credit warning beside its message Moving the account notice off the key-hint line left the credit warning beside the footer's project, where it was cut off. It now sits once at the right of Home's message row, as on dev. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Let the first-start fixture wait for its knowledge worker without spinning The wait read the worker's database in a tight loop, which starves the writer it waits for on a loaded machine. It now polls every 10 ms, and its ceiling is for setup, not a speed claim. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * A window opened once with a provider connected can still pair without --replace The picker's model list is cached as models-<key>.json for a non-default service, and the empty-computer rule knew only models.json, so a computer that had opened codeaf once with Ollama connected was told it had local work. internal/catalog now owns that file name, the window builds its path through it, and pairing accepts exactly those names. A keyless end-to-end test opens the real window with a non-default service, sends nothing and pairs, and a second window that sends one turn is refused. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Refuse a used, never-paired computer before the pairing code is exchanged The code road refused only after the exchange, so the approving computer had already said the new device was paired. A solo computer whose work rules out a merge now refuses before anything is sent. Chats written before any identity existed keep dev's behaviour: they come along and sync, which two tests pin. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wait for Home by the tuiwords needle, not a bracketed tab The selected tab reads [Home] only in some terminal modes, so the new window test timed out on a Home that was already drawn. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Say when a pre-pairing chat --once chat reaches the other computers Hello's check on a Mac found that such a chat is kept at pairing but is published the next time codeaf's window opens on that computer, in place rather than as a copy. The manual now says that instead of implying it syncs at once. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Import devname once in the devices card after the rebase onto #2085 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Lead serve's line with the machine name chat --at accepts serve printed the device name first (`reachable as beta (canoe-paddle-65)`), and `codeaf chat --at beta` is refused by the name check. The machine name comes first again, as on dev, and the device name follows only as a hint; every instruction keeps the bare machine name. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Ask remote-work approval with dev's question, not a name guess "has the same name as one of your devices" matched only the asker's label, and the approving computer has no verified link from that request to a paired device, so it misdescribed a computer that is paired. The question is dev's again; the weight line stays on the approving side. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
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.
Part of #2072 (item B: client and hosted service drifted apart unnoticed).
What changes
https://codeaf.agentfield.ai/fabric. Staging builds sync throughcaf-fabric-staging, and every other build (dev tags,make build, test binaries) throughcaf-fabric-dev. A build nobody tagged can no longer write to production. Channels do not sync with each other.CODEAF_SYNC_URLand a pairing's saved relay still win. The three addresses are spelled once, ininternal/syncsetup/relayurl.go, and pairing links use the channel's origin (HostedLinkHostsrecognises a link from any channel).relayjob inrelease.ymlruns afterprepare, andpublishnow needs it. On adevpush it deployscaf-fabric-dev; on astagingpush it deployscaf-fabric-staging.scripts/relay-fingerprint.shhashes the relay's inputs:relay/hosted, the raft wasm build scripts,go.mod/go.sum, and the module-local packages compiled into the wasm,third_party/raftincluded.TestAHostedRelay*) andcodeaf-release service --urlmust pass. Otherwise the Worker is rolled back to the recorded version and the job fails, which stops that channel's publish.caf-fabricdeploys only when the repository variableRELAY_DEPLOY_PRODUCTIONistrue. It is not set, so themainand stable runs print one line and publish against the relay that is live today.scripts/relay-wrangler-config.sh) fromrelay/hosted/wrangler.toml, which stays the one source of bindings and migrations.BASE_PATH, routes/workers_devand the rate-limit namespace ids change per channel. Rate-limit counters are per account, so staging adds 100 and dev adds 200.devhas added since (Reach a paired computer through the relay sync uses #2073's machine doors and fix(relay): harden the machine doors #2073 put on the hosted relay #2076's rate limits).caf-fabric,caf-fabric-stagingandcaf-fabric-dev, never the test rig Workers.Proof
scripts/relay-fingerprint_test.sh,scripts/relay-wrangler-config_test.sh(parsed with Wrangler's own config reader), andscripts/relay-deploy_test.sh(mocked Cloudflare API: skip on a matching tag, deploy on a missing Worker, bucket already exists, rollback on a failed proof, production off).wrangler deploy --dry-runof the generated dev config bundles every binding (2.6 MiB gzip).internal/releaseworkflow tests pin the relay job, the production switch and its default, andpublishneedingrelay.internal/syncsetup,internal/pair,internal/atlas,cmd/codeaf-release,internal/manual, andmake test-laws.After merge, the first
devpush createscaf-fabric-devand its bucket. I'll watch that run.🤖 Generated with Claude Code