Adage

How it works

How Adage plugs into Claude Code.

Claude Code exposes hooks at fixed moments in a session. Adage uses them to match local rules and deliver a useful next step: run the repository's check, regenerate files after an edit, or avoid a known failed command. It also learns those rules from past work. Whether that saves effort depends on the task; the evidence page shows what we have measured.

  • The model: remote, on GPUs, one call per turn
  • Adage: local learning and matching, no model request
  • Runs a command only with a person's approval

Advisory mode is the default: Adage informs, and nothing runs on the agent's behalf. Execution mode is opt-in and experimental: Adage also runs checks a person approved.

Scroll through one session, start to finish. Hover, tap or tab to a dotted word to see what it means; “Technical detail” opens the precise account.

The agent loop: you send a request to Claude Code, which calls the remote model for each next step and runs tools on your machine. Adage attaches at the hooks along that loop (SessionStart, the prompt, PreToolUse, PostToolBatch, Stop, SessionEnd) and runs on your CPU; any command it runs needs a person's approval. After the session, it learns from the trace. MODEL · REMOTE GPUs YOUR MACHINE · CPU each turn of the loop: one model call Model decides the next step You Claude Code the agent loop Tools read · edit · run model call next step SessionStartthe start Promptyour request PreToolUsebefore a run PostToolBatchafter edits Stop“done” SessionEndafterwards Adage your CPU · local · no network · fails open listens at the hooks; one session in ten it stays silent, as a control opt-in: names the approved check it will run, and when matches the task · procedure card · where the files stand now points the command at the project's own environment advice for the next step · opt-in: runs the approved tests anything still owed goes back once · opt-in: reruns the check starts the learner for this repository, in the background advisory mode: fewer model calls, the same hidden tests passing person-approved trace → learner → reflexes → your review → the next session
  1. The agent loop

    Every turn of the loop is one model call.

    You ask. Claude Code sends the conversation to the model, which runs on GPUs in a data centre, and gets back the next step: read a file, make an edit, run a command. The tool runs on your machine, its result goes back to the model, and the loop turns again until the work is done.

    Claude Code lets outside tools speak at fixed moments in that loop, called hooks. Adage listens at them. It answers on your CPU, with no network, and never calls a model of its own.

    Technical detail

    The Claude Code plugin registers SessionStart, UserPromptSubmit, PreToolUse (Bash only), PostToolBatch, PostToolUseFailure, Stop and SessionEnd (plugin/claude-code/hooks/hooks.json). Each call is a short-lived adage hook claude <event> process with a budget of a few seconds (30 seconds for the two that can run a check). On any error it fails open: the agent carries on as if Adage were not installed. About one session in ten is a silent control, so its effect can be measured.

  2. SessionStart · before the first word Execution mode

    It says which check it will run for you.

    In execution mode, if a person has approved one of this repository's checks, the agent hears it up front, in one plain sentence: which tests Adage runs, after which edits, and that it runs them again at the end. No approval, no sentence. In advisory mode the agent hears nothing here.

    In this repository Adage runs .venv/bin/python -m pytest tests/test_validate.py -q (approved by a person, sandboxed) after edits to tests/*.py then CHANGELOG.rst, and again when you finish if files changed since.
    Technical detail

    adage-exec's SessionStart adds an <adage-reflex … kind="execution-contract"> block naming at most two current verification grants. Only a grant whose approval key still matches is named: a lapsed one promises nothing, and the person is told instead, in a line the agent never sees. Control sessions get no note. Source: crates/adage-exec/src/hook.rs.

  3. UserPromptSubmit · your request arrives Advisory

    It recognises the task, and says where things stand.

    Adage compares your request with the tasks this repository keeps repeating, using a small model built into the binary. On a match it hands over a procedure card, once: the files to touch, the commands that worked and the ones that failed. Then it reads those files itself, read-only, and adds where they stand right now: line counts, the last definitions, the end of the test file, the changelog's head. The agent goes straight to the right line instead of paging through files.

    Technical detail

    Matching runs locally against a bundled static embedding model (potion-base-8M, int8); a card is delivered once per session when the prompt's similarity to its family clears learn.card_threshold (0.811). The orientation (crates/adage-runtime/src/orient.rs) reads only the card's own files, skips dotfiles, ignored, secret-holding and symlinked files and anything over 1 MiB, withholds secret-looking lines, and stays under about 1,200 tokens. Instincts and learned reflexes for the prompt are matched here too.

  4. PreToolUse · before a command runs Advisory

    It fixes the command before it can fail.

    Instincts know how your repository is set up. If the agent starts the tests with the system Python, Adage points the command at the project's own verified environment before it runs, so it does not fail and cost another call. In execution mode, if Adage's passing check already covers the test run the agent is about to start, the agent gets a note saying so. A note, never a refusal: the command still runs.

    Technical detail

    The rewrite uses Claude Code's updatedInput and changes only the interpreter word of a top-level command (python3 -m pytest becomes .venv/bin/python -m pytest), never text in a heredoc, a quoted string or a -c payload. It is on by default in Claude Code, shown to you each time, and adage delegate rewrites off turns it off. The receipt note needs a passing run in this session on byte-identical inputs.

  5. PostToolBatch · after the edits, before the next model call AdvisoryExecution mode

    The next step arrives before the model asks.

    In advisory mode, this is where learned advice lands: after editing the schema, regenerate; after these edits, these checks, in this order. It arrives with the tool results, before the model decides what to do next.

    In execution mode, when the agent's edits match the learned pattern (here: the tests, then the changelog), Adage also runs the person-approved test command in a sandbox, right there on your CPU, and hands back a short receipt: whether it passed, how long it took, and the agent's own new tests by name.

    A receipt, as Adage writes it (example values)Adage ran .venv/bin/python -m pytest tests/test_validate.py -q after your edits: passed (exit 0, 1.2 s; receipt 3f9c2a7e01b4). Tests: 1202 collected; exit 0; the tests added in this session: test_finite.
    Technical detail

    PostToolBatch fires once the agent's batch of tool calls has resolved and before the next model request. A learned context (an edit to tests/*.py, then CHANGELOG.rst, within eight events) nominates the command; the person's E2 grant authorises exactly that command; adage-exec stages the inputs, runs it in an OS sandbox with no network, journals it and applies only declared outputs (pytest's cache). Test names come from pytest's own cache record, never from its output. Learned directives (for example "after editing schema/*.json, run make gen") arrive here too, and a failing command gets dead-end advice at PostToolUseFailure.

  6. Stop · the agent says it is done AdvisoryExecution mode

    It checks the finish line.

    If a step this repository always needs is still owed (say, regenerating code after a schema edit), the agent is asked once to finish it, in a message marked as coming from Adage, not from you. In execution mode, if the code changed since the last passing run, Adage also runs the approved check once more: a pass lets the agent stop, a failure goes back with the failing tests named. It asks at most twice a session, so it can never loop.

    Technical detail

    The finish-line check (the Stop gate) goes through the same request, policy, sandbox, staging and journal as any action; a failure continues the agent once with a message that begins Adage finish-line check:. A learned finish-line step due at the same moment (such as make gen after a schema edit) is asked in the same continuation. If Adage cannot confirm a run completed, it tells the agent not to retry and pauses actions in that worktree until a person looks.

  7. SessionEnd · after the session

    It learns, and you decide what may run.

    When a session stops or ends, Adage starts a background learner for this repository. It reads the trace Claude Code left on your machine and turns steps that keep paying off into reflexes. Instincts work from day one; learned reflexes take over as evidence builds. Evidence thresholds and review determine which guidance becomes active. Inspect what Adage learned and review candidates that need a decision. Automatic execution always needs separate permission for the exact command. Change the command, its scripts or its environment, and the approval stops matching.

    Technical detail

    The learner (adage condition --auto) runs detached, at most once per learn.min_interval_secs (120 s) per repository, and never touches the network. Letting Adage run a check takes three decisions at a terminal, each refused inside an agent session: adage delegate policy --max-level e2, adage review delegate … for one command, and adage delegate on.

  8. What it adds up to

    Does the guidance reduce repeated work?

    A guidance hook adds context; it does not itself skip a model call. It may help an agent avoid a failed command or a repeated search. We measure the whole task with and without Adage to see whether that actually helped.

    29.0 → 22.8model calls per session on 4 held-out tasks, in advisory mode (the default): about 22% fewer model calls and a third lower cost, with the same correctness. Hidden tests passed 19/20 with Adage and 19/20 alone.

    Execution mode, experimental · quality bar not yet met: 19.6 calls per session, with hidden tests 17/20.

How it learns

From a transcript to a reflex, stage by stage.

Your coding agent keeps rediscovering how your repository works. Adage watches what worked in past sessions, turns the habits that keep paying off into reflexes, and hands your agent the right next step at the right moment. Then it checks that it helped.

Take the quick tour below, or switch to the full tour for every step. Hover, tap or tab to a dotted word to see what it means.

      Drag the scene to turn it; pinch or ctrl-scroll to zoom. Keys: ← → step, space plays, D shows more detail. The data is a small sample set of traces, the same one the adage map tour uses.

      The math

      Every threshold, written down.

      Adage never asks a model whether a reflex is good. Each decision is arithmetic over counted traces, with the constants below. The values below are the defaults.

      01

      Reading traces: one shape for every harness

      In short. Every session becomes the same simple list of actions, whichever agent wrote it, and each action is labelled by what it does.

      For example. “Look up ticket W-1041” and “look up ticket W-1042” become the same step, look up {id}, so Adage can see the agent doing the same thing twice.

      1. observereads, lookups
      2. verifytests, checks
      3. regeneratecodegen, builds
      4. environmentinstalls
      5. authoredits
      6. publishpush, release

      From safest to riskiest. The further along a step is, the less Adage may push it: lookups and checks can be insisted on, edits and publishing are never suggested.

      More detail

      A transcript becomes a prompt followed by a flat list of steps. Tool calls that share one message id form one turn; results join their calls by id, wherever they appear. A compound shell command splits into one step per sub-action, and a failure is blamed on its last part only, unless the command used ||.

      Each step gets a template key, with specifics replaced (a ticket becomes {id}), and an effect. Effects are ranked, and the rank caps how strongly a step may ever be directed (shown above).

      Observe and verify steps may fire. A regenerate step fires only after its edit. An install primes at most and starts nascent until a person reviews it. Edits and publishing are never directed. Only the hook's own output counts as a directive: what a directive named is exposed from the moment it arrived, and is no evidence for a reflex that directs it, so a reflex never learns from its own advice. Sub-agent transcripts are read too.

      In the code: crates/adage-learn/src/{lib,import,codex,opencode,cache}.rs · crates/adage-core/src/types.rs

      ← See it in the walkthrough: Read what the agent did

      02

      Graph engine: repeated subgraphs, chosen by compression

      In short. A habit is a run of actions that keeps repeating. Adage counts how often it held, allows for small samples, and keeps only habits that let it describe the sessions more briefly.

      For example. make gen followed an edit in registry/ in 7 of 8 sessions. With only 8 to go on, Adage leans that 7/8 toward the broader habit’s rate and scores it cautiously, at 0.59.

      θ∼Beta(α,β),α=s+κm,β=(n−s)+κ(1−m),κ=2

      Where s is the sessions the habit held in, n the sessions it could have, m the rate of the broader habit it refines, and κ = 2 how many sessions’ worth of weight that guess gets. θ is the habit’s true rate; Adage scores the low end of its likely range.

      More detail

      The graph engine is Adage's only learner, and it has no list of reflex kinds to look for: a reflex is whatever reliably precedes a step, and how it is delivered follows from its shape. Events are embedded and clustered into prototype labels, so each trace becomes a string, and repeated subgraphs become repeated substrings. Mining starts from a step worth delivering and grows closed patterns around it. A pattern is read as a prediction, after this context, this follows, with s supporting traces out of n opportunities. Its confidence is shrunk toward its parent pattern's confidence m (shown above).

      Counts are discounted with a 60-day half-life, and a candidate is judged by the posterior's 5% quantile, q0.05. Calibration then compares posterior means with held-out outcomes on 3 task-grouped folds, using isotonic regression over 200 bins.

      Frequent is not the same as useful, so selection is by minimum description length: a reflex earns its place by describing the traces in fewer bits.

      L(D,CT)=L(CT)+L(D∣CT),L(X∣CT)=−log2u(X)∑Yu(Y)

      A pattern in the code table costs its items' codes, plus 4 bits per item and log2 6 bits for its length. Tables fill best gain first, re-checking each gain before accepting it. Candidates that would deliver different directives never compete: each delivery shape gets its own table, and dead ends one per failing runner. Winners compile to delivery shapes (run, avoid, read-batch, obligation, sequence, advise), and every compiled reflex is then counted again on the traces as its own trigger and step read them (Evidence, below); until then it is provisional, prime at most. An interlock drops any reflex that would direct a runner a dead end says fails. Survivors go to one track per repository, <repo>/learned, with a .why.json beside it for people. On the offline bench's core suite, a deterministic replay whose committed baseline cargo test reproduces exactly, the learner scores J 0.6307. The synthetic sessions carry that score; the recorded demo sessions score below zero. It is a regression check, not a measure of savings.

      In the code: crates/adage-graph · crates/adage-learn/src/{bridge,engine}.rs · design: docs/tracks/track-g-graph-engine.md

      ← See it in the walkthrough: Spot the patterns

      03

      Evidence: the Wilson lower bound

      In short. A rate from a few examples cannot be taken at face value. Adage scores each reflex by the lowest its true rate is likely to be, and lets it insist only once that score reaches 0.80.

      For example. 6 of 8 is a 75% rate, but with so few sessions the true rate could be as low as 41%. Even a perfect record needs 16 sessions to reach 0.80. Try it below.

      LB= p^+z22n−zp^(1−p^)n+z24n2 1+z2n ,p^=kn,z=1.959964

      Where k is the sessions that took the step, n the sessions where it applied, and z = 1.96 sets 95% confidence. LB is the cautious score.

      Try it: how many sessions before a reflex can insist?

      More detail

      Every advisory reflex the learner compiles is judged again on the traces, exactly as its own trigger and step read them. Evidence is counted in distinct traces, and a trace a directive already steered toward the step is left out. Out of n traces where a reflex had its chance, k took its path. A rate from few traces is uncertain, so strength is judged by the lower end of the 95% Wilson score interval, not by the rate (shown above).

      Predictive execution has a separate test: by default, at least five unsteered sessions across more than one task, with a compatible successful continuation supporting at least 90% of matching edit or sequence contexts. Intervening observations are allowed within a bounded window; later mutations and task changes end it. Every matching opportunity counts, including those without a supporting outcome. This evidence creates a candidate for human execution approval; it grants no permission and proves no savings by itself.

      Fire
      LB ≥ 0.80 and k ≥ 5, within the effect's ceiling
      Prime
      a new reflex primes at a rate of 0.50; an existing one keeps its place down to 0.30
      Finish line
      the command must belong to the edit: P(c∣e)−P(c∣¬e)≥0.30
      Dead end
      the runner fails in ≥ 9 of 10 traces that ran it, a different check that works follows it, and the pair appears in ≥ 5 traces; a dead end inhibits
      Distinct tasks
      the traces supporting a step after an edit or a command must span at least 2 tasks
      Outcome lift
      a step too few traces took can still prime, never fire, when the traces that took it succeeded more often than those that did not: the 95% lower bound on the difference ≥ 0.20

      In the code: crates/adage-tracks/src/model.rs (wilson_lower, ceiling) · crates/adage-learn/src/{engine,evidence}.rs · crates/adage-tracks/src/params.rs

      ← See it in the walkthrough: Check the evidence

      04

      Uplift: does telling the agent change anything?

      In short. Telling an agent what it would do anyway is noise. Adage compares how often agents take a step when told with how often they take it unprompted, and stays quiet when the difference is small.

      For example. If agents regenerate after an edit 79% of the time on their own and 97% when reminded, the reminder adds 18 points: worth saying. Under 10 points, the reflex stays quiet until a person approves it.

      u=E[pfollow]−E[pself],pself∼Beta(κsms+k,κs(1−ms)+n−k),κs=4,κf=11.8

      Where pfollow is how often agents take the step when told and pself how often they take it unprompted. Each starts from a typical rate for its kind of advice (m) and moves toward this repository’s own sessions (k of n); κ sets how much the starting guess counts.

      Try it: is it worth saying?

      More detail

      A step agents always take on their own is not worth saying. For each reflex Adage estimates two rates: pfollow, how often agents take the step when told, and pself, how often they take it unaided. Each is a Beta posterior that starts from a prior for its kind of directive and is updated by this repository's evidence: unexposed traces in the same situation and the control arm's would-have judgements for pself, treated judgements for pfollow.

      Quiet
      a reflex with u < 0.10, once at least 3 situations of the repository's own evidence say so, is kept nascent, listed in adage review as quiet, until a person approves it; a prior alone never silences one
      Priors
      pself from randomised control data: 0.29 for a dead end, 0.32 for a run after an edit, 0.88 for a finish line or a sequence, 0.93 for reading listed files, 0.95 at the prompt; pfollow 0.88–0.99 by kind
      Not gated
      procedure cards, reflexes a person wrote, and the demo thresholds, where uplift is still estimated and shown

      In the code: crates/adage-learn/src/value.rs (uplift, assess) · crates/adage-tracks/src/params.rs (UPLIFT_MIN)

      ← See it in the walkthrough: Check the evidence

      05

      Intent: prompts that mean the same thing

      In short. Requests are placed on a map of meaning, so ones that mean the same thing sit close together. Families of similar requests that usually start the same way become reflexes.

      For example. “Why is CI failing on main?” and “the main build is red, can you look?” share almost no words, yet land side by side, and both usually start with make test.

      e(x)=v‖v‖,v=1|T|∑t∈TWt,cos(a,b)=e(a)·e(b)

      Where Wt is the model’s row of numbers for word t, T the words in the request, and v their average, scaled to length 1. Two requests are as alike as their arrows point the same way: 1 for the same meaning, 0 for unrelated.

      More detail

      Prompts are cut to their first 128 words, with tickets, paths, URLs, SHAs, versions and code replaced by placeholders. A static model bundled in the adage binary (potion-base-8M, int8, 7.7 MB, SHA-256 pinned; nothing to download) embeds each one as the mean of its WordPiece token rows, scaled to unit length, so similarity is a dot product (shown above).

      Each prompt links to its 10 nearest neighbours (found exactly, ties broken by index), and links below cosine 0.60 are cut. Louvain then groups the graph by modularity, visiting nodes in a fixed order so the result never varies:

      Q=12m∑i,j[Aij−γkikj2m]δ(ci,cj),γ=2.0

      A community becomes a family when at least 60% of its traces took the same first route (the first check or lookup before editing). Routes that appear in more than 80% of all traces say nothing about intent and are ignored. Each kept family gets its own threshold, chosen on this repository's prompts:

      t*=arg⁡maxtLB(kt,nt)

      Here nt counts prompts at cosine ≥ t from the family centre and kt those whose trace ran the family's route. At the hook, a new prompt matches the most similar centre whose threshold it clears; it fires only if that family's LB reaches 0.80, and otherwise primes. With the explicit hashed fallback in place of a model there are no intent reflexes, and nothing fails.

      In the code: crates/adage-graph/src/compile/intent.rs · crates/adage-intent

      ← See it in the walkthrough: Recognise similar requests

      06

      Procedure cards: the task a repository repeats

      In short. When two sessions start with similar requests and edit similar files, they are the same kind of task. A task seen at least twice, once successfully, gets a procedure card.

      For example. Adding flag_url.go one week and flag_port.go the next count as the same task: same folder, same kind of name, same extension.

      cos(pa,pb)≥0.6and|Fa∩Fb||Fa∪Fb|≥0.25

      Where pa and pb are the two first requests, compared by meaning, and Fa and Fb the shapes of the files each session edited. The second part is the share of file shapes they have in common.

      More detail

      Most work in a repository is a variation of something done before. Two traces are one family when their first prompts are similar and the files they edited have the same shapes (directory, name tokens, extension, so flag_url.go and flag_port.go agree) (shown above).

      A family with a passing trace gets a card: the files edited in at least half its traces, in order, with the lines the latest passing trace added; the commands most traces ran, kept when they mostly worked and listed to avoid when they mostly failed; and the check the passing traces finished with.

      The delivered card leaves those added lines out. In their place it says where the card's files stand in the checkout when it is delivered: each file's line count, a Python source's last top-level definitions with their lines, a test file's last lines and a changelog's first headings. Adage reads them itself, read-only, and runs no command. This orientation has been measured only in one development study on a single task; the card benchmarks used the earlier form.

      Forms
      from at least 2 traces, one of them passing; at most 16 cards per repository, the best supported
      Delivered
      once per session, as prime, when a new prompt's best cosine to the family's prompts reaches 0.811 (learn.card_threshold); up to 0.10 below, at the first edit of one of the card's files
      Bounded
      at most 800 tokens, plus at most about 1,200 for the orientation; never quotes .env files, files git ignores, or anything that looks like a secret; never shared in a pack
      Verified
      adage train cards replays a card's commands on a clean checkout in a sandbox, and the next learn keeps only those that worked

      In the code: crates/adage-learn/src/cards.rs · crates/adage-tracks/src/card.rs

      ← See it in the walkthrough: Recognise similar requests

      07

      Skills: compiled, then verified

      In short. Reflexes learned from a written guide are accepted only if agents follow them about as well as they follow the guide itself, at no more than 10% extra cost.

      For example. If 9 of 10 sessions follow the learned reflex, 9 of 10 follow the guide, and the reflex costs no more, it is accepted, and the guide no longer has to sit in every prompt.

      freflex≥0.70,fskill−freflex≤0.10,creflexcskill≤1.10

      Where f is the share of sessions that followed the step and c the cost, in turns or dollars, with the reflex or with the guide.

      More detail

      adage train <SKILL.md> compiles a skill's procedure into one pack of reflexes by rules, with no model and no agent session: which command, after which edit, in which order. Every compiled command is replayed on a clean checkout of HEAD in adage-exec's sandbox, with the network off, your working tree untouched and the .venv lent read-only. A command that fails there is stale and dropped; one that could not be replayed is kept at prime at most; judgment stays text. Nothing is installed until adage train accept.

      Skill-steered sessions are optional evidence, and they cost money. The skill's claims get generated tasks plus controls, your own agent runs each headlessly in a sealed clone with no remote, the traces go through the same learner, and reflexes are staged at prime, never activated. Held-out tasks then run in three arms: no skill, the skill in the prompt, and the staged reflexes through the hooks. A reflex is accepted when (shown above).

      Here f is the share of sessions that followed the step and c the cost in turns or dollars. A claim the agents contradict, like a test command that fails where another works, comes back as a dead end, and the skill is told which of its claims are stale.

      In the code: crates/adage-train/src/{compile,verify,report}.rs · docs/training.md

      ← See it in the walkthrough: Learn from a written guide

      08

      The index: one sealed file

      In short. Every active reflex is merged into one file, and a fingerprint of that file names its version, so Adage always knows exactly which set of reflexes it is using.

      For example. Change one reflex and the fingerprint changes completely: a1de421c7f5760b4 becomes something else entirely.

      generation=hex(SHA-256(index))[0:16)

      SHA-256 turns the file into a fingerprint; its first 16 characters are kept as the index’s generation.

      More detail

      Every installed track compiles into one list. The same behaviour gets the same id wherever it was found, so duplicates collide, and precedence decides which copy stays: your own evidence, then a teammate's signed pack, then an instinct. The survivors are serialised in order and hashed, and the hook reads only that file (shown above).

      Tracks are versioned: evidence moving bumps the patch number, an added reflex the minor, a changed or removed one the major. Imported reflexes start forming and never fire until your own traces confirm them. Instincts, 8 in the default set, deliver as prime at most and extinguish themselves if they keep misfiring. Tracks and the index are readable by their owner only.

      In the code: crates/adage-tracks/src/{index,interlock}.rs · adage-instincts · adage-pack

      ← See it in the walkthrough: Package what was learned

      09

      The hook: a pure decision, and a control arm

      In short. About 1 in 10 sessions is left alone as a comparison group. A fingerprint of the session’s id decides, so the choice is random but always the same for the same session.

      For example. Session T2’s fingerprint comes out at 0.064, under 0.10, so Adage stays silent in it and only notes what it would have said.

      x=u32le(SHA-256("adage-arm:"∥session)[0:4))232−1,control⇔x<0.10

      The session id is fingerprinted with SHA-256, and its first 4 bytes are read as a number x between 0 and 1. Below 0.10 means the control group.

      More detail

      Each hook event runs a pure function of the event and the index. Before anything is said, the session is assigned to an arm by a hash, so the assignment is stable and reproducible (shown above).

      A control session runs the same decision, records what it would have said, and stays silent. Each record carries its propensity, the probability of the arm it got. The share is 0.10 unless runtime.control or ADAGE_CONTROL sets another.

      On Claude Code the hook also runs before each shell command (PreToolUse), for the one change Adage makes by default: a Python test run or scratch repro under the system Python, in a repository whose .venv was verified to hold pytest and the project, runs with .venv/bin/python instead. The command is read as a shell reads it, and only the command word of a top-level simple command changes: never a heredoc, a quoted string or a -c payload. A command that activates an environment, cds outside the checkout or pins another Python version is left alone; one your permission rules would not allow once rewritten gets advice instead. You see each rewrite, a control session records it without rewriting, and adage delegate rewrites off (or runtime.rewrite = false) turns it off.

      Slots
      a value from the prompt binds only if it matches the contract learned from real values and is a plain token: at most 200 characters from A–Z a–z 0–9 _ . / : @ = + , -, with no leading dash
      Followed
      a directive stays pending for 3 tool batches; it is followed if a batch runs its canonical command (options may be added), ignored otherwise, and misfired when the agent followed it and the command failed
      Wrapper
      each directive reaches the agent as <adage-reflex track="…" route="…" strength="…" kind="…">, with a last line saying where it came from
      Fails open
      if the hook errors or runs out of time, the agent carries on as if Adage were not installed

      Approved execution is a separate path. With adage-exec enabled and a local grant for the exact reflex, E1 prefetches a read-only result; E2 runs an action in a disposable stage and applies permitted outputs. The invocation is selected and run on the CPU without a model request. The next model request may still consume its result. Learning a command does not approve it, and a delivered procedure card does not demonstrate CPU execution or saved turns.

      When a person has approved one learned verification, Adage owns it in treated sessions: at the session start the agent is told which command Adage runs and when; after a run it gets a short receipt naming the tests that ran, including the ones it added; and when it finishes, Adage runs the check again if it has not passed on the current files, asking the agent to continue once if it fails. A person is told in one line when an approval stops matching. On real repositories it has so far one development result, on a single task, and no held-out result. Savings are counted in model calls, tokens and API cost; GPU use and energy are not measured.

      In the code: crates/adage-runtime/src/{lib,pretool,render}.rs (assign_arm) · crates/adage-hook

      ← See it in the walkthrough: Speak up at the right moment

      10

      Measurement: the task is the unit

      In short. Adage measures by task, not by run: it compares each task with and without Adage, averages the differences, then checks how often pure chance would do as well.

      For example. Across 8 sample tasks, runs with Adage averaged 9.9 fewer turns. Shuffling which runs had Adage 10,000 times never produced a gap that large, so luck is a poor explanation.

      dj=x¯jadage−x¯jcontrol,T=1J∑j=1Jdj

      Where x̄ is a task’s average (turns, cost or pass rate) in each arm, dj the difference for task j, and T the average difference over all J tasks.

      More detail

      Runs of one task are not independent, so the task, not the run, is the unit. For each of J tasks, compare the arms' means, then average over tasks (shown above).

      No distribution is assumed. Arm labels are shuffled within each task, never across tasks, 10,000 times, and the p-value counts how often chance does at least as well:

      p=1+#{b:|Tb*|≥|T|}1+N,N=10,000

      Whether the effect would hold for new tasks is a separate question. A sign-flip test over the task differences answers it exactly up to 16 tasks, where its smallest possible p is 2/2J:

      pflip=#{s∈{±1}J:|∑jsjdj|≥|∑jdj|}2J

      Turns, cost and pass rate are tested together, so Holm's step-down corrects for looking at several metrics. With the m p-values sorted ascending:

      p~(i)=maxk≤imin(1,(m−k+1)p(k))
      Interval
      a 95% percentile bootstrap that resamples whole tasks 2,000 times
      Per reflex
      a share is stated only with at least 10 treated and 5 control traces
      Offline bench
      before any agent runs, a learner scores J=turns saved−2.0×false directives+1.0×route F1 per session
      Your savings
      adage savings estimates, per session, control minus treated: API-list-equivalent cost, model turns and turns to the first edit, each session weighted by its recorded propensity (Hajek), winsorised at the 95th percentile, with an expanded percentile interval from 2,000 bootstrap resamples stratified by arm. Dollars appear only with at least 10 control and 30 treated sessions; before that, counts. Beside it, always: how often each arm ended asking the person for help

      In the code: crates/adage-cli/src/savings.rs · demo/report.py (cluster_perm_p, task_signflip_p, cluster_boot_ci, holm) · crates/adage-eval · evals/live

      ← See it in the walkthrough: Prove it helped

      See it on your own traces

      The same walkthrough ships inside adage map, where the chapters replay with your repository's reflexes.

      Get startedBack to the overview