Uh oh!
There was an error while loading. Please reload this page.
docs: Refresh README with agent lifecycle guide - #351
Closed
khaliqgant wants to merge 2 commits into
Closed
Conversation
Adds detailed changelog entries for each day this week covering: - Jan 30: Task injection retries, cursor-agent reconciliation (v2.1.4-v2.1.5) - Jan 29: JSONL storage migration, relay-pty npx fix, agent-to-agent watch (v2.1.0-v2.1.3) - Jan 28: OpenCode integration, continuity persistence, MCP parity, CJS exports (v2.0.21-v2.0.37) - Jan 27: Dashboard migration to relay-cloud, 10K agent capacity, socket fixes (v2.0.21-v2.0.25) Each entry follows the Product/Technical Perspective format. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove storage implementation details, streamline sections, and add a collapsible "For Agents" section covering spawn, release, messaging, and full lifecycle orchestration with code examples. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
khaliqgant
commented
Jan 30, 2026
MemberAuthor
Closing - created clean README-only branch without changelog changes |
khaliqgant added a commit
that referenced
this pull request
Aug 22, 2026
…ed takeover (#1596) * fix(broker): bump relaycast to 7.0.0 and reclaim agent names by audited takeover relaycast 8.2.0 made registration create-only and moved identity replacement to explicit, proof-authorized routes. `POST /agents/{name}/rotate-token` became `requireAgentToken` — self-rollover only — so the broker's register-or-rotate paths, which sent the workspace key, could only return `401 Agent token required (at_live_...)`. That is not theoretical: it is why every cloud agent step whose name had been used before failed. The tests covering these paths were green only because they mocked a server that stopped existing. Verified against production: POST /v1/agents -> 201 POST /v1/agents (same name) -> 409 agent_already_exists POST /v1/agents/x/rotate-token rk_live_ -> 401 Agent token required POST /v1/agents/x/rotate-token at_live_ -> 200 Pin moved to `=7.0.0` (relaycast/#351), which surfaced four call sites: two for `rotate_agent_token`'s new agent-token argument and two for `create_workspace` requiring explicit provenance. Reclaiming a name the broker owns is now an audited takeover: - `rotate_token_no_fallback` performs genuine self-rollover with the cached agent token, and says so plainly when there is no token to roll over. - The crash-reclaim path uses `recover_agent` — it holds a work-unit identity proof, not the agent's token, which is precisely what recover exists for. - `register_agent_token` falls back to `take_over_agent` on a collision, so supervisor restart, offline-agent attach and the broker's own reconnect keep working and now leave an audit record. Takeover is deliberately confined to names this broker owns. The impersonation presence probe still runs first and still refuses a live agent, so takeover only ever applies where there is no live credential to strand. Where the probe has already resolved the incumbent, its id is threaded through so the takeover does not repeat the lookup. 1016 tests pass; clippy clean on stable. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * style: auto-format Rust code with cargo fmt * fix(broker): cache takeover tokens and keep the identity proof out of audit Addressing review; two of the three were real defects in the previous commit. P1 — the takeover token was never cached. `take_over_agent_identity` bypasses `AgentRegistrationClient`, so it returned a token the SDK cache never saw. The next call would re-register, collide, take over again and invalidate the token just handed out; worse, it would eventually meet the agent this broker had itself brought online and refuse to impersonate it as a live agent. Seed the cache via the existing `seed_agent_token` helper. New test `takeover_seeds_the_registration_cache` asserts the second call is served from cache with the same token and fires no second takeover. Verified it fails without the fix — two registrations instead of one. P1 — the raw identity key reached an audit field. Crash recovery copied `RELAY_AGENT_IDENTITY_KEY` verbatim into `session_ref`, but the surrounding code treats that value as a replayable credential and hashes it before anything workspace-readable. An audit record is workspace-readable, so it now gets the same treatment: `hash_identity_key`, still correlatable, no longer replayable. P1 — no changelog entry. Added under `[Unreleased - Minor] / Fixed`, describing the user-visible effect: previously used agent names can be reclaimed again. 1017 tests pass; clippy clean on stable. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * fix(broker): serialize collision recovery per agent name Addressing review. Another real race in my own change: `seed_agent_token` only runs after takeover completes, so two concurrent cache-miss registrations for the same name both issued a takeover, and the second response invalidated the token already handed to the first caller. `expected_agent_id` cannot catch this — takeover preserves the agent id, so both requests are individually valid. Added a per-agent-name singleflight around collision recovery: acquire a keyed async lock, then re-check the credential cache before taking over, so a caller that waited on the lock reuses the token the winner just seeded rather than invalidating it. New `concurrent_collisions_take_over_once` drives two registrations through `tokio::join!` against a deliberately slow takeover response and asserts a single takeover request and one shared token. Verified it fails without the lock — two takeovers. 1018 tests pass; clippy and fmt clean on stable. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * fix(broker): keep working against engines older than 8.2.0 The fleet e2e caught a real compatibility break, not a flake: "waitFor timed out (node-a back online after restart)". A restarting node re-registers its name, which now collides and goes to takeover — and the e2e pins the relaycast engine to v7.0.0, where `/takeover` and `/recover` do not exist. The node never came back. That break is not limited to CI. `/takeover`, `/recover` and the `requireAgentToken` guard on rotate all arrived together in engine 8.2.0, so as written this made the broker require 8.2.0 and would have stranded every self-hosted deployment still on an older image. Fall back instead of raising the floor: if takeover returns 404 the route is absent, which means an older engine, and those engines still let the workspace key rotate an agent's token — exactly what this path did before. On 8.2.0+ the route exists, so the fallback is unreachable and a takeover failure is a real failure that propagates. `takeover_falls_back_to_legacy_rotate_on_older_engines` pins it: 404 on takeover, then a workspace-key rotate that the older engine accepts. The fleet e2e now covers the same path end to end on a real v7.0.0 engine. 1019 tests pass; clippy and fmt clean on stable. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * fix(broker): distinguish a missing route from a missing agent Self-review of the previous commit. The legacy fallback keyed off a bare 404, but 8.2.0's takeover looks the target up first and answers 404 with `agent_not_found` when the agent is gone. So an agent that vanished between the lookup and the takeover — a real, reachable race — would have been read as "this engine is old", sending a workspace key at a `requireAgentToken` route and reporting the resulting 401 as an engine capability problem. That is the same shape of misdirecting error this whole change set exists to remove, so it should not be introduced by the fix for it. The code now decides, not just the status: fall back only when the 404 is not `agent_not_found`. A vanished agent surfaces as itself. `agent_not_found_does_not_trigger_the_legacy_fallback` asserts the error names the real cause, is not reported as an engine problem, and that the legacy rotate is never called. 1020 tests pass; clippy and fmt clean on stable. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * fix(broker): fall back on the identity-recovery path too, not just takeover The fleet e2e still failed after the last commit, and the uploaded node logs gave the real cause rather than my guess at it: Failed to start broker: ... Error: failed to initialize relaycast session Caused by: 0: failed registering agent with AGENT_RELAY_WORKSPACE_KEY workspace key 1: Route not found "Route not found" is `/v1/agents/{name}/recover` on engine v7.0.0. The previous commit added the legacy fallback to the takeover path in `ws.rs` and stopped there; `admit_agent_registration` in `auth.rs` calls `recover_agent`, and that route arrived in the same 8.2.0 release. A node restarting against an older engine therefore never came back. Same treatment as takeover: on a 404 that is not `agent_not_found`, the route is absent, so reclaim the identity through the legacy workspace-key rotate those engines still accept. `workspace_key` is threaded into `admit_agent_registration` solely for that fallback. `identity_reclaim_falls_back_to_legacy_rotate_on_older_engines` covers it — a 404 on recover followed by a workspace-key rotate — which is precisely the path the two-node fleet e2e drives against its pinned v7.0.0 engine. 1021 tests pass; clippy and fmt clean on stable. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.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 freeto 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.
Summary
Refreshed README.md to be more user-focused and concise, removing internal implementation details and adding a comprehensive guide for agents to control the relay lifecycle.
Changes Made
Test Plan
🤖 Generated with Claude Code