RACT is a model-agnostic, local-first agentic coding tool built around three ideas: signed provenance capabilities (rootknots) on every artifact (see docs/PROVENANCE.md), explicit assumptions for every plan step, and milestone-halting recursion instead of fixed iteration counts.
v0.6.0 is the Interactive Session release: hand real coding work to a model, local or hosted, inside a policy you control, and show afterwards what changed, why, under which permission, and how to undo it. Highlights:
racton a terminal: intents, slash commands, plans before anything runs, per-hunk review,/diff,/undo, checkpoints and rewind, and a turn summary that labels unchecked claims.- The command on-ramp: setup offers a signed grant for the test command,
/testruns it through the tier-3 checks,!<command>runs what you type, as you. - Honest surfaces: what the sandbox does not enforce, what a dead endpoint means, what the model claimed versus what RACT verified.
- Run identity:
RACT_RUN_IDpasses the run id to child processes.
Full change list: CHANGELOG.md. Release notes with the success-condition evidence: docs/release/RELEASE_NOTES_0.6.0.md. Migration: docs/UPGRADING.md.
The previous release, v0.5.2 Deep-Audit Hardening, is described in CHANGELOG.md.
v0.5.1 is the External Review Response patch release. It closes the
trust-chain gap external review (DeepSeek + REVIEW_4_UNKNOWN) surfaced
against v0.5.0 without touching the sacred spine (Rootknot three-
signature schema, AL-1, author-name-free tree). The pipeline
(_BUILD/ract_v0.5.1_external_review_response/) delivered nine
closure modules plus release close:
- RootknotWAL crash-consistency (G1): WAL-durable assumption
replay (
src/ract/core/assumptions_wal.py). - Rootknot canonical-bytes extension (G2 + G3): opt-in
workspace_digest+prompt_digest+run_id; schema_version 3 → 4; v3 sidecars still verify. - RFC 8785 JCS:
src/ract/canonical.pydumps_jcs+ 15-file migration; grep-gate attests/architecture/test_no_sort_keys_in_canonical_paths.py. - T8 PROMPT_DRIFT + T9 PROMPT_DIGEST_MISSING +
intent recompile, per-iteration drift hook; HMAC-signed recompile via.ract/operator.keyORRACT_OPERATOR_KEY. - SubstrateLoop shim closure: four-gate
ToolInvocationGate, process-group tree-kill, environ allowlist, git-commit compensator. - Ambient run_id ContextVar:
src/ract/runtime.py;LoopController.run()binds at entry. - Historical Manifest Ledger: append-only Merkle-chained JSONL
- content-addressable snapshot store.
- Polyglot G5/G6 via tree-sitter: dead-code + test-copy-paste detectors for Python + JS + TS + Rust + Go.
- Sycophancy classifier v2: AST-delta + WhispererContract event; F1 = 1.000.
See CHANGELOG.md [0.5.1] and docs/ROADMAP.md for v0.6 hardening.
v0.5.0 is the Memory Discipline minor release. It installs a new
memory substrate on top of v0.4.1 without touching the sacred spine
(Rootknot three-signature schema, AL-1, author-name-free tree). The
pipeline (_BUILD/ract_v0.5.0_memory_discipline/) delivered nine
substrate modules plus a release-close module:
- Token budget accountant with hard-ceiling refusal per function
and composition override (
src/ract/memory/budget.py). - Three query indexes: the symbol index (tree-sitter + SQLite +
FTS5), the graph index (LSP-populated call/type edges), and the
semantic index (LanceDB +
bge-small-en-v1.5). An incremental file watcher keeps them current. - Retrieve primitive with a four-level cascade (symbol → graph →
semantic → best-effort), a query cache keyed on
(query_hash, repo_commit_hash), and four chunk formats. - Four function contracts:
intake,research,plan,editeach with a typed contract, a v1 prompt, and a paired test file. - Four playbooks:
refactor_rename,refactor_extract,bug_fix,unit_test, composed of those four functions. - Three self-adjustment probes:
needle,coherence,adherence, writing a per-repo capability fingerprint to.ract/probes/capability.json. - Integration wiring.
SubstrateLoopreads a retrieval bundle offSubstrateStepSpec.metadata;Rootknotpayload carries an optionalretrieval_attestation; seven new EventKind members; three new CLI subverbs (ract memory init,ract memory apply-narrowings,ract retrieval query).
Verify: pytest -q tests/test_release_surface.py runs the 56-signal
sweep (11 REBUILD + 16 SUBSTRATE + 16 ALM + 13 MEMORY) plus the
memory-module surface check plus the closed-IP wordlist gate. See
CHANGELOG.md [0.5.0] for the exhaustive change list and
docs/ROADMAP.md for v0.6 hardening backlog (deferred polish).
Earlier releases: see CHANGELOG.md.
v0.4.0 was the first release where the environment decides, not the
model. Substrate: every plan step runs in its own git worktree under an
sandbox described by a CapabilityManifest (designed; in this build only
tier-3 commands on Linux run inside bubblewrap, after a self-test, and
ract doctor --sandbox shows what is enforced on your machine); every model
action is a member of a closed Pydantic union; every run emits a
hash-chained event log at evals/runs/<run_id>/events.jsonl (designed
in v0.4.0; the writer is not wired in this build, so a run records its
audit trail in the egress ledger, the signed sidecars, the rootknot
store and, on request, the session events from --output-format stream-json) and optionally OpenTelemetry spans; termination T1 reads: every required
predicate in the AcceptanceSuite evaluates true against the final
snapshot (the model does not say "done"). Rootknot gained
environment_signature (Invariant RK-3). ALM: eight pre-commit
gates (G1-G8), a sycophancy circuit, an Investigator, and a third
Rootknot signature (antilazy_signature) held by a separate key
(Invariant AL-1). See CHANGELOG.md [0.4.0] for the exhaustive
change list; see docs/ROADMAP.md for the v0.5 hardening backlog.
pip install ractOr from source:
git clone https://github.com/LucRoot/RACT.git RACT
cd RACT
./scripts/install.sh --local --venv
source .venv/bin/activate # Linux and macOS; on Windows: .venv\Scripts�ctivateSee docs/QUICKSTART.md for a step-by-step tutorial.
In the directory you want to work in, run:
ract setupSetup finds a model server already running, or suggests a local model that
fits your machine (it never downloads) or a cloud provider (it never asks
for the key). It writes ract.yaml and checks it with one request. Bare
ract offers it too; see docs/QUICKSTART.md.
In a repository you cloned, RACT first lists any commands the repository
asks it to run (hooks, MCP servers, test gates) and runs them only if you
say so; ract trust records the decision until those files change.
Run ract with no arguments to work inside an interactive session (/plan, /loop,
/doctor, /set, and every verb as a slash command). The commands below work one at a
time from the shell.
ract init --template python-package --provider local
ract memory init # build the three memory-discipline indexes for this repo
ract doctor # verify workspace and dependencies
ract fence inspect --file src/<package>/__init__.py # check safety guardrails; use any file in your project
ract run "add a test for the hello-world script" --config ract.yaml --dry-run
ract run "add a test for the hello-world script" --config ract.yaml
ract run "refactor the greeting module" --config ract.yaml --loop --yolo --max-iterations 5Indexes need RACT_EMBED_MODEL_ROOT or RACT_EMBED_ONLINE=1.
Novelty budget and memory index notes: docs/NOVELTY_AND_MEMORY.md.
ract -p "prompt" runs one turn without a terminal. The prompt can also come
on stdin; when both are given, stdin is added to the prompt as labeled context.
stdout carries only the result and progress goes to stderr, so
ract -p "..." > out.txt gives a clean file.
A headless run starts in default mode, like a session: it would ask
before changing a file, and with no terminal to ask it refuses the change
(exit 3). Pass --accept-edits when the run may change files. Answers
need no flag.
ract -p --accept-edits "fix the failing test" # the verdict; files may change
ract -p --accept-edits "fix the failing test" --output-format json # one ract.result/1 object
ract -p "summarize this log" < build.log # stdin as the prompt's context
ract -p --ask "where is the config loaded?" # answer only; no plan, no file written
ract -p --accept-edits "fix the failing test" --output-format stream-json # every eventExit codes: 0 done, 1 the task failed, 2 usage or configuration error, 3
refused, 4 a budget was used up, 5 interrupted, 6 the provider was
unavailable, 143 terminated. The
JSON schema is in docs/EVENTS_SESSION.md.
A headless run does not run the repository's own commands (hooks, MCP
servers, test gates) unless the repository is trusted: run ract trust as an
earlier step, or pass --trust-project for one run. Nothing in the
repository can grant this itself. --bare loads none of them even when
trusted. A GitHub Actions step:
- name: Ask RACT to fix the failing test
run: |
ract -p --accept-edits "fix the failing test" --output-format json > ract-result.json
jq -e '.outcome == "done"' ract-result.jsonRun ract --help to see every verb enumerated at the top level; ract help <verb> prints per-verb usage. The list below is generated from
src/ract/cli_help.py::VERB_DESCRIPTIONS and cross-checked in CI by
tests/unit/test_readme_verb_index_matches_parser.py (v0.5.1 wiring
module_10, Lens A M8 closure).
ract run: Execute an intent as a planned-and-verified RACT run.ract plan: Load, save, replay, diff, or analyse a serialized plan.ract session: List, export, import, backup, or restore saved sessions.ract doctor: Diagnose RACT installation, config, and workspace state;--sandboxsays what confines a command here.ract status: Print a one-line summary of the current workspace state.ract self-audit: Audit RACT's own code against the audit lens findings.ract audit: Audit a workspace or run for anti-rot and provenance issues.ract leaderboard: Print the provider leaderboard by success rate.ract source-digest: Print the SHA-256 digest of a source file or workspace.ract init: Initialize a new RACT project from a template.ract docs: Generate or regenerate documentation for the workspace.ract openapi: Generate an OpenAPI client or server scaffold.ract provider: List, add, or configure provider adapters and presets.ract router: Inspect or reconfigure the provider router policy.ract config: Inspect or edit ract.yaml keys.ract cost: Report accumulated provider cost from receipts.ract memory: Init, apply-narrowings, and inspect memory-discipline indexes.ract retrieval: Search the retrieval adapter; query the three memory indexes.ract intent: Operator-signed intent recompile appending a new suite version.ract repl: Open an interactive session: type intents, use /commands, keep context.ract handshakes: List, approve, reject, defer, or review pending handshakes.ract operator-queue: List or drain the operator-approval queue.ract whisper: Brief the conventions and recent history that bear on a task (writes nothing).ract auction: List or resolve entries in the dead-code auction.ract fence: List or resolve Chesterton's fence entries.ract trust: Trust this repository's own commands and endpoints (hooks, MCP servers, gates), or list and remove trust.ract policy: The operator key and the signed tier-3 grant: keygen, init --guided, add-rule, sign, status, revoke.ract setup: Check this machine, choose a local or cloud model, and write a working ract.yaml.ract undo: Reverse the last RACT turn: restore the files it replaced, remove the files it created.ract redo: Reverse the last undo.ract skills: List and inspect builtin and installed skills.ract marketplace: (alias) Same as skills marketplace; browse skill packages.ract mcp: Manage and invoke MCP tools registered with RACT.ract refactor: Run a scoped refactor over a named target.ract rename: Rename a symbol project-wide through the symbol renamer.ract diff: Show and apply RACT-authored diffs against the workspace.ract explain: Explain a plan, step, or artifact with its provenance chain.ract consolidate: Scan for consolidation candidates and propose merges.ract report: Render run reports in markdown or HTML.ract trace: Inspect an events.jsonl trace file, if one exists. No shipped command writes one in this build.ract quality: Compute the plan quality scorecard.ract load-bearing: Inspect or manage load-bearing annotations across the workspace.ract novelty: Report novelty budget usage and scan for overruns.ract coverage: Report coverage deltas and status.ract mutation: Run mutation-testing checks over the workspace.ract conformance: Run the provider conformance suite.ract rot-report: Print the anti-rot report.ract rot: Detect and quarantine rot in the workspace.ract merge-gate: Evaluate the mutation-testing merge gate.ract provenance: Verify Rootknot signatures for artifacts and workspaces.ract verify: Check a commit range and/or a run: every changed line attributed to a signed step, each Rootknot verified, the trace chain when the run has one.ract receipt: List, show, or verify receipts.ract receipt-export: Print the signed receipts in a directory as JSON.ract manifest: Repro-manifest alias + ledger verify/inspect/show/proof.ract repro-manifest: Produce a reproducibility manifest for a run.ract policy-gate: Evaluate a run against the configured policy.ract run-fingerprint: Print or diff a run's fingerprint.ract ai-sbom: Emit an AI Software Bill of Materials.ract release: List, create, or update GitHub releases.ract calibrate: Run provider calibration (experimental).ract infer: Run a single inference call (experimental).
New to tier 3: docs/TIER3.md.
The auto-generated index above lists every top-level verb. These are the
sub-verbs first-run users reach for most often; each is asserted by
tests/test_readme_cli_index.py + tests/test_readme_version.py so
first-run docs stay honest:
ract run: start a run from an intentract doctor: one-shot workspace health checkract config validate: checkract.yamlbefore runningract provider health: verify every provider adapter can reach its backendract session list: enumerate persisted session directoriesract plan diff: compare two serialized plansract fence inspect --file <path>: inspect Chesterton's-fence entries in a file
Anti-lazy gates (G1-G8) are pre-commit helpers rather than top-level CLI verbs.
A run records its audit trail in the egress ledger in the user state
directory, in the signed Rootknot sidecars beside the files it wrote and the
.ract/rootknots.db index, and, when a caller asks for it, in the session
events from --output-format stream-json. A normal run writes no report
files; the gate report shapes the README listed here in earlier drafts
(mutation_kill.json, patch_diff.json, coverage_delta.json and friends)
exist as library functions the test suite exercises.
- Provenance-anchored artifacts: every file the loop writes carries a signed
Rootknotbinding it to its plan step, assumption, generator, and parent artifacts; a run that could not sign its files says so in the turn summary. Seedocs/PROVENANCE.md. - Assumption-driven programming: assumptions live in a registry with a four-state lifecycle (
proposed,active,discharged,violated); violations propagate through the dependency graph. - Milestone-halting recursion: the loop halts on completion, regression, provenance violation, assumption cascade, budget exhaustion, handshake block, or provider fault, each with a distinct termination cause. On a refactoring task this spends measurably fewer tokens than a naive fixed-iteration loop, see
evals/benchmarks/refactor-token-usage/report.md. - Operator Handshake: high-risk actions queue for async review instead of blocking the loop.
Core modules live in src/ract/core/: rootknot.py (signed provenance), assumption.py (Assumed[T] registry), plan.py (schema + validator), loop.py (T1–T7 recursion). See docs/ARCHITECTURE.md for the system diagram, boundary contracts, and failure modes; docs/ADRs/ for decision records.
Three reproducible tasks under evals/tasks/ (reports in evals/runs/). See evals/README.md for the eval-tree tour. evals/benchmarks/refactor-token-usage/ compares the milestone-driven loop against a naive baseline on tokens-to-pass; reproduce with python evals/benchmarks/refactor-token-usage/report.py.
ract doctor # workspace health + dependencies
ract provenance verify <file> # check a file's Rootknot (RK-1 + RK-2 + RK-3 + AL-1)
ract conformance run --provider fake # run the per-provider conformance corpus
ract trace replay <run_id> # replays a saved event log; no shipped command writes one in this build
pytest -q # full suite (includes tests/test_release_surface.py)The full release-surface sweep is pytest -q tests/test_release_surface.py
(56 signals: 11 REBUILD + 16 SUBSTRATE + 16 ALM + 13 MEMORY, plus the
memory-module surface check + the closed-IP wordlist gate).
RACT v0.5.0 enforces four invariants at verify time (unchanged from v0.4.1):
- RK-1 (Author Attestation, v0.2).
Rootknot.generator_signatureverifies under the resolved generator pubkey. - RK-2 (Sidecar Integrity, v0.2). The sidecar's Merkle root binds every attested field.
- RK-3 (Environmental Attestation, v0.4 substrate). The sandbox-key
environment_signatureverifies;acceptance_suite_digest,predicate_results, andmanifest_digestare all registered. - AL-1 (Anti-Lazy Attestation, v0.4 ALM). The ALM-verifier
antilazy_signatureverifies; everyGateResultis PASS (or its handshake was approved);reversal_taintisclean(or the run is on the operator'saccepted_partial_taint_runsset).strict=Truerefuses any sidecar older than v3.
See evals/LEADERBOARD.md (which now carries a per-provider
attested_pass_rate column) and evals/conformance/COMPANION_MATRIX.md
(eligible primary-companion provider pairs).
PolyForm Noncommercial License 1.0.0, free for personal use, research, education, and noncommercial organizations; commercial use requires an agreement. See COMMERCIAL.md and AUTHOR.md.
- Windows file-watcher tests can be flaky under heavy I/O.
- MCP tools run serially within a plan step.
- Benchmark numbers are machine-specific; re-run on your hardware.
License: PolyForm Noncommercial 1.0.0. Measurements: take them as one data point from one machine on one day, and re-run on yours.
Author: Dr. Lucas Root, Ph.D., info@lucasroot.com