Skip to main content

Tutorial: run a risk-review before a big change

You are about to do something you can't easily undo: a large refactor, a database schema migration, a major dependency bump. One agent has already written the plan or the diff. Before you commit, you want a second pair of eyes that does not share the first agent's blind spots.

This is the single highest-value way to use ContextRelay. The point of running two agents in one session is not to double your output - it is to put an independent reviewer in the loop before you ship. This tutorial walks the full flow: stage the context, ask for a focused review, run a bounded deliberation when there is a real decision to make, synthesize the outcome into the ledger, and act on the verdict.

Why a second agent, not just a second prompt

The reviewer (Codex, in the default configuration) runs as a separate process with its own model and its own reading of the diff. It does not see the first agent's hidden reasoning - only what is written into the shared ledger. That separation is the whole value: an independent read catches the assumptions the author already baked in. See Why two agents in one session.

Before you start

This tutorial assumes you already have a paired session running. If you don't, work through your first paired session first. In short:

ctxrelay pair

That launches Claude Code and Codex in separate terminals and opens the control TUI. The examples below are written from Claude's side asking Codex to review; the flow is symmetric - Codex asks Claude with deliberate_with_claude, and the slash commands are the same.

Reviews are read-only by design

A review never edits your files. The reviewer is asked explicitly not to modify files or run git operations - it returns findings, not commits. ContextRelay is read-only by default: autonomous edits are off behind explicit layered gates, so a review can't quietly change your tree.

Step 1 - Stage the context so the reviewer has grounds

A reviewer can only be as good as what it can see. Before you ask anything, write the proposed change, the diff or plan, and the specific risk question into the shared ledger, and name the files in scope. This gives the review a durable starting point instead of a vague "is this okay?".

Record the proposed change as an artifact so it survives the session and shows up in the task board and viewer:

record_artifact(
kind: "patch_summary",
...summary of the diff or plan, files touched, and the risk question...
)

Or, if you just want a durable note, use append_note. Either way, be concrete about scope. A good staging note names:

  • What is changing (the refactor / migration / bump, in one line).
  • Which files are in scope.
  • The specific risk you want checked - e.g. "does this migration drop a column that's still read anywhere?", not "review my change".
Name the real diff, not the intention

The reviewer should react to the actual change, not a paraphrase of it. Point at the files and the diff. A review of what you meant to do misses exactly the bug you didn't mean to write.

Step 2 - Ask for a focused, read-only review

With the context staged, ask the peer for a focused review. The fastest path is the slash command:

/contextrelay:review does this schema migration drop a column still read by the reporting code? files: db/migrations/0042_drop_legacy.sql, app/reporting/*.ts

/contextrelay:review <focus> wraps a structured handoff under the hood: it sends Codex a read-only review request that includes your focus, asks for concrete findings with file references, and explicitly tells it not to modify files or run git operations. The handoff waits briefly for a live reply, then falls back to background polling if Codex is mid-turn.

If you'd rather drive the tools directly, a scoped handoff (or a reply to an existing thread) does the same job - just make the ask read-only and pin it to the risk question.

What you want back is severity-ordered findings of the real diff: the highest-risk problems first, each tied to a file and line, with a clear "blocker / concern / nit" framing.

Ask for findings, not a verdict

A bare "looks fine" is the failure mode of agent review. If the reviewer leads with a state-acknowledgement instead of findings, the coordinator reads it as "nothing to see here" and routes the critical path away from the review - defeating the point. Insist the reviewer lead with severity-ordered findings of the actual diff. See Working effectively with two agents.

Step 3 - For a genuine decision, deliberate

A review surfaces problems. Sometimes that's enough. But when the question is a real tradeoff - "rip the column out now vs. ship a dual-read shim first", "bump the major now vs. pin and wait" - you want the two agents to argue it out and converge, not just list findings.

That's a deliberation:

/contextrelay:deliberate drop the legacy column in this migration now, or ship a dual-read shim for one release first?

/contextrelay:deliberate <question> runs one bounded Claude-to-Codex pass via the deliberate_with_codex tool (Codex uses deliberate_with_claude toward Claude). The flow is fixed and deliberately short:

  1. The asking agent writes its opening position first - My independent view is:, Strongest reason:, Assumptions / uncertainty:.
  2. The peer responds with its own independent judgment - expect I agree on: and I disagree on:, not reflexive agreement.
  3. The asking agent synthesizes the result.

You are looking for genuine independent judgment here. If the peer just says "sounds good", press it: the value of the second agent is the place where it disagrees.

One pass, not a loop - and long reviews don't belong in a live call

Deliberation is a single bounded convergence pass on a specific tradeoff, not an open-ended back-and-forth. Live deliberation/wait calls fall back to background polling once the short live window expires (the wrapper waits ~10s live, then stays reconcilable up to its stale window). So for a long review, prefer a plain reply plus ledger pickup over one long live deliberation - kick off the request, then reconcile later with read_context or wait_for_messages scoped to the handoff id. Do not loop indefinitely.

Step 4 - Synthesize the outcome into the ledger

The durable output of a risk-review is not the chat - it's the synthesis you write down. After the review or deliberation, record four things, in the project's standard shape:

  • Current consensus - what both agents now agree on.
  • Remaining disagreement - where they still differ, and why.
  • Decision / next action - what you're actually going to do.
  • Next action - the concrete next step (commit, fix first, escalate).

Persist it with append_note (the /contextrelay:deliberate flow does this for you on its final step). This is what makes the review auditable: anyone reading the ledger later - or recovering after a crash - sees what was decided and why, not just that two agents talked. See The shared durable ledger.

Step 5 - Act on the verdict

Now turn the synthesis into action. There are three outcomes:

Low risk - proceed. No blockers, consensus to ship. Hand the actual git write to the coordinator - the one agent that owns branch, commit, merge, push, and PR. In the default project policy that's Codex; check your project's coordinator and git-write policy. Non-coordinator agents stay read-only on git and hand the work off.

Blockers found - fix first. Address the highest-severity findings before committing, then re-stage and re-review the corrected diff. Don't commit over an open blocker because the review "mostly" passed.

Needs human authority - escalate. Some decisions are not the agents' to make. Escalate to the human - do not resolve them agent-to-agent - when the change involves any of:

  • spending money or exceeding a configured budget,
  • a destructive or irreversible action,
  • credentials or secrets,
  • external business judgment, or
  • changing the coordinator or the git-write policy.
The agents converge; the human signs off

Two agents agreeing is evidence, not authorization. For anything with real-world consequences, the agents produce a recommendation and the human makes the call. When the work is genuinely complete, an agent records a finality proposal with propose_final; by default that waits for explicit human acceptance rather than self-closing. See Finality and human sign-off.

What you just did

  • Staged the proposed change, scope, and risk question into the ledger so the reviewer had grounds.
  • Asked for a focused, read-only review and demanded severity-ordered findings of the real diff.
  • Ran one bounded deliberation for the genuine tradeoff and got independent judgment.
  • Synthesized consensus, disagreement, decision, and next action into the durable ledger.
  • Acted on the verdict - proceed, fix, or escalate to the human - with git writes left to the coordinator.

That loop, run before every risky change, is the core of using ContextRelay well: an independent review you can trust, on the record, before anything ships.

Next steps