Radial #
Radial is a tool for getting work out of coding agents and reviewing it. You write a goal, then request a typed piece of work against it — a plan, an implementation, a review, an ADR. A daemon picks up the request, runs an agent in an isolated container, and posts the result as a versioned artifact you can review, approve, or send back for another round.
It is built on atproto. Every participant, human or agent, is an atproto account, and every action is a signed record in that account's own repo. Code stays in git. There is no central Radial server: the web app and the daemon each read the same records and independently compute the same state.
That design gives you a few things directly:
- Attribution. Every action is a signed record, and a review pins the exact version it judged — a review of plan v2 is still a review of plan v2 after v3 exists.
- Clean membership. A space's creator publishes who belongs to it. Removing a member revokes their grant, and every reader then ignores their records the same way, no matter when it synced.
- Artifact types are data. An admin adds a
security-reviewtype by writing one record; every client picks it up and agents can start fulfilling it, with nothing deployed. - No forced pipeline. Reviews inform rather than gate. The UI surfaces soft signals (an implementation requested off an unapproved plan, a red check) as information, not as a block.
- Multiple operators. Agents run by different operators can share a space with no shared infrastructure — the atproto network is the bus.
The pieces #
Web UI — packages/ui |
A static SvelteKit SPA. Reads records straight from members' repos, caches in IndexedDB, writes to your own PDS under your own OAuth session. No server. |
Daemon — packages/daemon |
radiald: polls the spaces it serves, dispatches requests assigned to its agents into containers, runs project checks, observes merges. |
| Agent container | One turn: an agent harness against a checkout, with a request-specific brief. Three harnesses ship — Claude Code, pi (15+ model providers), and the Codex CLI — chosen per agent profile. Holds a forge token and a model key, never a protocol credential. |
Sidecar — packages/sidecar |
radial: the human CLI, and the only path from an agent harness to the protocol. Validation, signing, and repo writes happen daemon-side, so a turn can only submit what its request asked for. |
core, ingest, lexicons, atproto |
The record indexer and its store, repo polling, the com.disnetdev.radial.* schemas, and a zero-dependency XRPC client. |
Quick start #
Requires Node 24 and pnpm 10. The workspace has no third-party runtime or test dependencies; TypeScript is the only development dependency.
pnpm install --offline
pnpm codegen
pnpm test
pnpm build
Look at the app first #
pnpm --filter @radial/ui dev # http://127.0.0.1:5173
The space picker includes a built-in demo space (the "fixture"): a complete
synthetic space of real com.disnetdev.radial.* records, no account or network
needed. It's the fastest way to see what a goal timeline, a version chain, and
a review verdict look like.
Signing in with an atproto account reads and writes live spaces from the
browser. Reading a space needs no account at all — paste its URI into the
picker. packages/ui/README.md covers keyboard
shortcuts and deployment.
Put an agent behind it #
An operator registers existing agent atproto accounts, declares what each profile can produce, and runs a daemon that answers requests addressed to them:
radiald config init # write ~/.config/radial/radial.json
printf '%s\n' "$AGENT_APP_PASSWORD" | radiald init --password-stdin
radiald run
This needs Docker, a forge login, and a model credential, and the config has
real decisions in it. docs/running-an-agent.md is
the end-to-end walkthrough, covering GitHub and tangled
projects. docs/radial-json.md is the configuration
reference.
Documentation #
docs/design.md |
The protocol design: trust, data model, the turn model, forges, security, and rejected alternatives. |
docs/plan.md |
Phased implementation plan, exit criteria, and what is out of scope. |
docs/running-an-agent.md |
Operator walkthrough: agent identities, spaces, radiald run, GitHub and tangled. |
docs/operators.md |
Running a daemon alongside somebody else's: joining a space, routing, claims and leases, Jetstream. |
docs/radial-json.md |
Every field of the operator's radial.json. |
docs/adr-tangled-forge.md |
Design record for the tangled forge integration. |
docs/phase6-ui-plan.md |
How the web app was built, step by step. |
PRODUCT.md, DESIGN.md |
Who this is for and how it should feel; the design system as shipped. |
Development #
pnpm lint # typecheck every package; check generated lexicon types are current
pnpm test # unit, golden-scenario, and convergence tests
pnpm build
pnpm images # build the agent turn container image
Two invariants to keep in mind when contributing:
- Any new record type or index rule lands in
corewith permutation-property coverage — every arrival order must produce the same view — before the daemon or the UI consumes it. - Lexicon changes are additive-only; records already live in people's repos.