Skip to content

docs: Refresh README with agent lifecycle guide - #351

Closed
khaliqgant wants to merge 2 commits into
mainfrom
feature/readme-refresh
Closed

docs: Refresh README with agent lifecycle guide#351
khaliqgant wants to merge 2 commits into
mainfrom
feature/readme-refresh

Conversation

@khaliqgant

@khaliqgantkhaliqgant commented Jan 30, 2026

Copy link
Copy Markdown
Member

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

  • Removed: Storage implementation details, Architecture diagram, relay-pty internals, OpenCode-specific integration, Testing section
  • Streamlined: CLI Reference, Dashboard, and Cloud sections for clarity
  • Added: Collapsed "For Agents" section covering:
    • Starting relay
    • Spawning agents (with code examples)
    • Sending messages to agents
    • Releasing agents
    • Full lifecycle example (spawn → coordinate → release)
    • Protocol conventions (ACK/progress/DONE)
    • Environment variables reference

Test Plan

  • Verified removed storage/internal details
  • Confirmed "For Agents" section is collapsed by default
  • Checked code examples are accurate
  • Ensured README is concise and user-focused
  • No changelog changes included (separate PR docs: Add daily changelog entries for Jan 27-30 #350)

🤖 Generated with Claude Code


Open with Devin

Agent Relayand others added 2 commits January 30, 2026 15:41
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>

@devin-ai-integrationdevin-ai-integrationBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 3 additional flags.

Open in Devin Review

@khaliqgantAgent Relay (Rachel?)

Copy link
Copy Markdown
MemberAuthor

Closing - created clean README-only branch without changelog changes

@willwashburn
willwashburn deleted the feature/readme-refresh branch May 15, 2026 13:09
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>
Sign up for freeto 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

@khaliqgant