Agent skills

Open in Claude.md

Builds

Every agent build leaves a structured, searchable record on its issue, with the stages, each child's window, the gates with their evidence, and the chat.

Ask an agent how a piece of work went and you get a paragraph. Ask the issue and, until now, you got the same paragraph, written by the agent, in a comment.

A build is that answer as data. One build per issue: the stages it went through, the window it spent on each child, every verification gate with the evidence behind it, and a searchable timeline of what the agent actually did, stitched across every session that touched the issue and surviving the workspace that produced it.

You read it on the issue. There is no separate page.

What a build is made of

Stages. An ordered list, one per workflow skill: plan · prototype · materialize · build · verify. Re-entering a stage appends an attempt rather than overwriting it, so a verify battery that went red and then green shows both.

Child windows. The work happens per child, so the build stage is subdivided: radial build child start RAD-383 opens a window, and every gate, event and stamp recorded until child done belongs to that child. The window closes with a determination (done, partial, not done or n/a) and a comment.

Gates. The verification rows, each with a result (pass · partial · failed · n/a), an elapsed, an attempt and a provenance:

ProvenanceWhat it meansHow a row earns it
run by the CLIThe CLI executed the command and read its exit code, duration and summary lineradial build gate --gate unit --exec -- pnpm test
importedRead from a standing fileradial build gate --import gates-abc.json
reported by the agentThe agent's own wordradial build gate --gate browse --result pass

The server decides which one a row gets, from the shape of what arrives. A row that claims it was observed but carries no execution envelope is stored as reported by the agent. A digest proves nothing; only execution earns it.

A gate the tier did not select is recorded as n/a with the tier named, never left out. A missing row and a skipped row look identical, and only one of them is honest.

Events. The normalized chat: your messages, the agent's, its tool calls, the agents it dispatched, the errors it hit. Every event carries the id of the session that produced it, so a build worked on across two days by two clients reads as one timeline.

Recording one

The rd-* skills do this for you. rd-plan opens the build, each workflow skill brackets its own stage, rd-build opens and closes a window per child and records a gate per row rd-verify reports, and the last step is an explicit radial build finish. If you never install the hook below, you still get everything except the chat.

By hand, the whole vocabulary is start, stage, child, gate, report and finish:

bash
radial build start RAD-382                    # opens, or resumes
radial build stage start build
radial build child start RAD-383
radial build gate --gate unit --exec -- pnpm test
radial build gate --gate browse --result pass --evidence "4/4 observed on screen"
radial build child done RAD-383 --determination done
radial build report --file report.json        # prints the tables it derives
radial build finish

Before the issue exists

A plan usually happens before its issue does. radial build start --draft <slug> opens a draft that lives only in your journal. Every verb works, every timestamp is real, and nothing is sent. When the parent is created, radial build bind RAD-382 turns the draft into that issue's build, replaying its stages at the times they really happened. The plan stage reads 14:21, not "created at bind time".

radial build drafts lists unbound drafts; radial build drafts rm <slug> deletes one. A plan you abandon leaves nothing in Radial.

Capturing the chat

bash
radial build hook install --client claude     # a Stop hook
radial build hook install --client codex      # a notify entry

The hook runs at the end of every agent turn, parses what is new in the transcript, redacts it, and appends it. Hooks capture and never finalize: radial build finish stays an explicit step in the skill.

What leaves your machine

AlwaysStages, child windows, gate rows and the report
On captureThe event timeline, redacted before it is journaled and again before it is stored
Only with --with-rawThe raw session file, gzipped and redacted, downloadable by its own session's user or a workspace admin

Redaction covers API keys, OAuth tokens, bearer headers, JWTs, connection strings, private-key blocks and NAME=value secrets. The CLI redacts before it writes and the server redacts again before it stores, against a class list that is byte-identical in both and pinned by a test in each.

The journal itself lives outside your repo, at ~/.config/radial/builds/<workspace>/<ISSUE>/, so archiving the workspace does not take the build with it. Everything works with no connectivity at all; radial build sync catches up later.

Configuring the pipeline

bash
radial build pipeline init      # writes .radial/pipeline.json

The shipped opinion is the five stages above and the gates validate · unit · e2e · review · browse. Rename them, reorder them, add explorer or release, and name the tiers each gate applies to. The gates list replaces the shipped one rather than merging with it, so your config reads as the whole truth.

json
{
  "version": 1,
  "stages": [
    { "id": "plan", "position": 0 },
    { "id": "build", "position": 1 },
    { "id": "verify", "position": 2 }
  ],
  "gates": [
    { "id": "lint", "tiers": ["T0", "T1", "T2", "T3"] },
    { "id": "unit", "tiers": ["T1", "T2", "T3"] },
    { "id": "e2e", "tiers": ["T2", "T3"] }
  ]
}

Events and correlation

Every producer names the events it pushes and the keys that tie them to the build and to the session that produced them. The keys are the build (the issue, from .radial/build.json), the session id (read from CLAUDE_CODE_SESSION_ID, CODEX_THREAD_ID, the hook payload, or --session), the open stage attempt, and the open child window.

ProducerVerbEvents it pushesCorrelation
rd-plan, before the parent existsbuild start --draft <slug>draft.opened (local only, nothing sent)Journal keyed on the slug
rd-issues, once it existsbuild bind <PARENT>build.opened, with the draft's stages at their journaled timesBinds the issue
any skill, on an existing parentbuild start <PARENT>build.resumed or build.reopenedAppends the session to sessions[]
rd-plan`stage startdone plan`stage.started, stage.done
rd-prototype`stage startdone prototype`stage.* with the attachment and critic score
rd-issues`stage startdone materialize`stage.* with the issues and edges
rd-buildstage, child, gate, report, finishchild.started, child.done, gate.recorded, report.put, build.finishedChild windows add the issue; gate rows inherit the open window
rd-verifynone, it returns rows to rd-buildn/an/a
Claude Code Stop hookbuild hook stopevent.appended[], session.seenSession id and transcript path from the hook payload
Codex notify hookbuild hook codex-notifySameThread id from the notify payload
any agent, by handbuild capture --transcript <path>Same--session when the environment names none

Reading it back

On the issue: a Build section with three tabs. Timeline is the stages and the time spent in them, with each child's window indented under Build. Gates is the verification rows, earlier attempts stacked under the latest, each with a note naming its evidence and who produced it. Session is the chat, every session stitched, tool calls folded, searchable.

A parent shows the whole tree. A child shows the same build scoped to its own window, and links back to the parent for the rest. An issue with no build has no Build section.

From the terminal:

bash
radial build show RAD-382                 # the rollup
radial build show RAD-382 --local         # from the journal, no network
radial build search RAD-382 "42501"       # full-text over the timeline
radial build export RAD-382 --report -o report.json
radial build export RAD-382 --events -o events.jsonl
radial build export RAD-382 --raw <session> -o session.jsonl.gz

From an agent, over MCP: get_build_rollup, get_build and search_build_events, on both the hosted server and radial mcp. They are read-only, because recording a build is the CLI's job: only the CLI can run a command and vouch for what it saw.