RiskRails 3.1.0
Claude Code · Codex plugin

Every change runs on a set route.

RiskRails lets an AI agent work on legacy production code. Each change is weighed on six axes before the agent edits a file, then runs light, guarded or full. A hook refuses an edit outside the task, a read of a production secret, a force push or a deploy.

npx riskrails@3.1.0 Watch two tasks
A request passes the weight junction and takes the light, guarded or full route. Light closes on its own; guarded stops for your plan; full stops for your plan and your signature. W = Σ 6 state.py weight REQUEST LIGHT · W ≤ 2 GUARDED · W 3–7 FULL · W ≥ 8 build verify close plan · you build review BAL close plan · you build review STRONG you sign

request add a 3% surcharge to card paymentsroute full

The line

One line from setup to your commit.

The same commands in Claude Code and Codex. Most days you type only /rr-build. It plans first when no task is in flight, and hands over to review and ship by the task's mode.

  1. /rr-setup

    Survey

    Scaffolds .ai/, surveys the code, asks you for the test commands, the weight table and the constitution. Never touches application code.

  2. /rr-spec

    Intent

    For a feature: one question at a time, then requirements and design, checked against your principles.

  3. /rr-plan

    Weigh

    Names the files, recalls what the record knows about them, scores six axes and picks the mode.

  4. /rr-build

    Build

    Edits inside the task's files only. Runs each step's tests, then the suite once, to the end.

  5. /rr-review

    Review

    One adversarial reviewer at the mode's tier. Blockers are fixed as one batch.

  6. /rr-ship

    Close

    Measures the two facts, asks for your approval when the mode needs it, writes the commit body.

At any point:/rr-statuswhere the task stands, in twenty lines ·/rr-status --costwhat it cost, at zero model cost ·/rr-build-alla whole plan as one task

The weight

The ceremony scales with the blast radius.

A typo fix stays a one-line edit. A payment change gets a written plan, an adversarial review and your approval. Scope, reversibility and coverage are measured from the tree. Behaviour, domain and novelty are declared with evidence, and a declaration below a measurement is replaced by the measurement.

RR301 · weight.jsonsix axes, 0–2 each
4.1The axes
Axis2 meansMeasured by
scopemore than 5 referencing files, or a hot pathreference count, git grep
behaviourchanges a process: state, async, orderingdeclared; keyword floor
reversibilitydata, schema, infra, an external writeneeds_step, irreversible globs
domainmoney, tax, identity, personal datamodule globs
noveltya new mechanism or dependencydeclared; manifest floor
coverageno test: characterize firsta test named after each file
/rr-build fix the typo in the checkout button label

scope          0  1 reference
behaviour      0  a label (declared)
reversibility  0  git revert returns everything
domain         1  templates/** is customer-visible
novelty        0  nothing new (declared)
coverage       1  no test names the file
W 2 → light
RR301 · modesthe mode only rises during a task; lowering it is yours
4.2Three modes
ModeWhenPlanReviewYou stop it at
lightW ≤ 2inline: files, test, rollbackonly when a fact at close is rednothing
guardedW 3–7plan mode, which you acceptone pass on BALANCEDthe plan
fullW ≥ 8written; architect on STRONG when the design is openone pass on STRONG, security focus when domain = 2the plan, and the tree at close

Reversibility or domain at 2 is full whatever W is. Both at 2, or DROP, TRUNCATE, DELETE FROM in the diff, is full_irreversible: you approve with approve --confirm <operation> in your own terminal. verify and close re-score the two hard axes from the real diff.

The interlocking

Guards, not guidelines.

In a signal box, the interlocking makes a conflicting route impossible to set. Here one Python hook sees every tool call in both runtimes and refuses the conflicting action, with the reason and the way out.

Lever 1 · every repository

Git

ai-guard.py

Force push, remote branch delete, history rewrite, push or merge to a protected branch, gh pr merge, --no-verify, a staged secret, a deploy, npm publish.

Lever 2 · where .ai/ exists

Paths

ai-guard.py

.env, secrets/, keys, dumps, production logs; writes to the task state, the journal, the policies' JSON and the installed guards.

Lever 3 · during a step

Scope

ai-guard.py

An edit to a file the step does not name: SCOPE_CHANGE_REQUIRED. Widen in place with start --amend --why, journaled.

Lever 4 · while a decision is open

Decision

ai-guard.py · dialog-gate.py

Holds every tool until you answer in the runtime's own dialog. Your pick runs once, verbatim; anything else is CONSENT_REQUIRED.

Lever 5 · Claude Code

Large read

cap-large-read.py

An unbounded Read over 4 000 lines or 250 KB is refused; a limit within budget passes.

Lever 6 · both

Context

context-guard.py

Warns from 80% of the compaction point, snapshots before compaction, injects the handoff when a session starts.

Lever 7 · both

Runtime

runtime-gate.py

Sends the top model's launches one tier down during an outage or at 90% of the weekly limit.

Lever 8 · your push

Record

memory-pre-push.py

Reads the pushed commits before they leave: a malformed package, a lost record, a second seal or a SQLite file under .ai/ stops the push.

The guards are regex over a command line or a path: a tripwire for the honest mistake, not a security boundary. Branch protection, secrets off the developer machine and human review stay the real backstops. Read the known risks before relying on them.

Close

Done is measured, not claimed.

state.py close asks no model whether the work is finished. It measures two facts on the tree as it is now. Green and green in light mode closes the task; guarded and full add the review and your stop.

a

The suite is green on this tree

The verification command runs once, to the end, with the log under .ai/state/logs/. Every failure is fixed as one batch. Two whole-suite runs are the budget; the third is your decision.

facts: (a) suite green on 3f9c2e1a7 (run 1)
b

Every changed file is in the task

The diff since the base tree is compared with the files the task named. One file outside, and close says which and stops.

      (b) 2 changed files, all in the task's files
Model tiers

Pay for thinking, not for re-reading.

Prompts name tiers, not models. The installed profile maps each tier to a model for your plan and runtime. Readers run on the cheapest model; the expensive tiers run one at a time, on a named trigger.

FASThaiku, low · Terra, low

Reading and running: Explore, log-reader.

BALANCEDsonnet · Terra, medium

Discovery with judgement, the guarded review, batch implementers.

STRONGopus, high · Sol, high

The full review, the security review, architect in /rr-spec.

EXPERTFable 5.1 on architect · Astra

Only what STRONG could not settle. One agent at a time.

The session itself implements. /rr-status --cost reads the local transcripts of both runtimes and shows tokens and cost per task, session, model and tier, without calling any model.

Files carry decisions

One tree. Two runtimes. One record.

Start a task in Claude Code and finish it in Codex. The knowledge base, the policies, the task state and the compact record of every closed task live in .ai/, in the repository, next to the code they describe.

The task state

.ai/state/state.json and a journal a human can read. A guard keeps agents from writing either directly.

The record

On close, who, what, how and why become JSON lines in .ai/memory/, sealed and checked by a pre-push hook. recall hands an agent what the record says about the files it is about to touch.

The local index

Optional SQLite with full-text search. It is rebuilt from the files whenever they change and is never the only copy of anything.

How storage works →
What's new in 3.1

Project schema 11. A quieter update.

risk-tiers retired

Migration 0011 takes the project from schema 10 to 11 and retires .ai/policies/risk-tiers.*; weight.json and weight.md replace them.

A cleaner --update

/rr-setup --update renders weight.md from weight.json instead of merging it, and proposes the cleanup of files the plugin no longer ships.

Templates from the plugin

The plugin supplies the SDLC templates, so a project no longer carries its own copies.

CI in two tiers

A fast smoke suite on every pull request; the full suite nightly, on demand and on release tags.

Guard and state fixes

Fixes in the path guard and in state.py. Upgrade the plugin on every machine before a project is committed at schema 11.

Full list in the CHANGELOG.

Install

Pin the version. Restart.

Node 18+ and python3. The installer detects Claude Code, Codex or both and proposes the plan it found. The hooks it installs see every command an agent runs, so pin the version. In Codex, open /hooks and trust the entries; until you do, nothing is enforced.

npx riskrails@3.1.0
# then, in any project
/rr-setup                      # once
/rr-build <what you want>      # every change

# options
npx riskrails@3.1.0 --target codex      # auto | claude | codex | both
npx riskrails@3.1.0 --plan max          # pro | team-pro | team-max | max | max20
npx riskrails@3.1.0 --dry-run           # print, write nothing

# coming from claude-agentic 2.x
/rr-setup --update             # dry run first; then --apply

Upgrading from 2.x renames the plugin, replaces the risk tiers with the weight and moves the task state. Follow the six steps in the README, in order.