A Lesson Is a Failure Plus the Change That Fixed It
Agent memory writes what the model decides to save, or it writes everything. Animals and people learn on surprise instead. For a coding agent the surprise has a mechanical shape: a command failed, something changed, and the same command passed. Without the change, it was a retry.
Every agent memory system has to settle what gets written before it can settle anything else. The usual answers are "whatever the model decides to save" and "everything, summarized later". Models rarely volunteer a save, so the first under-fires. Most of a session is routine, so the second buries the few moments that mattered under a pile of ones that did not.
Animals and people are selective in another way. How much they learn from an event tracks surprise, the gap between what they expected and what happened. An outcome that was fully expected teaches close to nothing, even on the hundredth repetition.
For a coding agent, the surprise worth keeping has a mechanical shape: a command failed, something changed, and the same command then passed. The lesson is the middle element. Take it away and what is left is a retry that happened to pass, and on real build systems those are common enough that a memory unable to tell the difference fills up with luck.
Learning Runs on Prediction Error, Not on Repetition
The idea that learning tracks surprise came out of a conditioning result that repetition could not explain.
In a set of experiments published in the late 1960s, Leon Kamin first trained rats that one cue, call it A, reliably came before a mild shock. Then he presented A together with a second cue, B, followed by the same shock, many times over. Tested alone afterwards, B produced almost no conditioned response, even though it had been paired with the shock as often as it was in a control group that got only the A-plus-B stage and learned B well. The effect is called blocking. Kamin read it in terms of surprise: by the second stage the shock was already predicted by A, so B's arrival added nothing, and nothing was learned about it. The chapter that set out the argument is titled "Predictability, surprise, attention, and conditioning".
A colleague on your team always messages you when the nightly build breaks, usually before anything else could tell you. Later someone adds a dashboard tile that turns red on the same failures. The tile is right every time, and you see it every morning, and you never learn what it means. You never needed to. Every time it went red, you already knew. The tile is B. Your colleague is A.
Robert Rescorla and Allan Wagner turned that reading into a learning rule in 1972. The amount an association strengthens on a trial is proportional to the difference between the outcome that occurred and the outcome predicted, and the prediction comes from all the cues present on the trial, not from each cue separately. In Rescorla's own later summary: "associative learning occurs not because two events co-occur but because that co-occurrence is unanticipated on the basis of current associative strength."
V_X is the associative strength of cue X. ΣV is the sum of the strengths of every cue present on the trial: the prediction. λ is the most the outcome can support, 1 if it occurs and 0 if it does not. α_X and β are learning rates set by how salient the cue and the outcome are. The bracket is the prediction error.
Once A has been trained, V_A is close to λ, so on an A-plus-B trial the error λ − V_A − V_B is close to zero and B gains almost nothing. A fully predicted outcome teaches nothing, however many times it occurs. Rescorla points out that the rule is essentially the Widrow-Hoff learning algorithm, the delta rule from 1960s adaptive signal processing.
The model is not the last word. Its own author lists shortcomings: it predicts that a cue signalling the outcome's absence should lose that meaning when shown on its own, which does not happen, and it says nothing about timing within a trial. Mackintosh (1975) and Pearce and Hall (1980) built rival theories in which surprise and predictiveness change how much attention a cue receives, and the three accounts still disagree about why blocking happens. None of them went back to counting co-occurrences.
Train cue A alone first, then A and B together, and watch B's strength and the prediction error on every trial. B is paired with the outcome on every compound trial (A and B together) and barely moves, because by then the outcome is not a surprise. Set the first stage to zero trials to see what B learns when it arrives while the outcome is still unpredicted.
The same error signal in dopamine neurons
The quantity turned up in the brain. Wolfram Schultz's laboratory recorded dopamine neurons in monkeys while the animals learned that a cue predicted a drop of juice. Before learning, the neurons fired when the juice arrived. After learning, they fired to the cue and not to the juice. When the predicted juice failed to arrive, their firing dipped below baseline at the moment it had been due. Schultz, Dayan and Montague (1997) put it this way: the neurons emit "a positive signal (increased spike production) if an appetitive event is better than predicted, no signal (no change in spike production) if an appetitive event occurs as predicted, and a negative signal (decreased spike production) if an appetitive event is worse than predicted." An appetitive event is a rewarding one, like the juice.
The paper's claim is that this pattern is the error term of temporal-difference learning, δ(t) = r(t) + γV(t+1) − V(t): the reward just received, plus the prediction from the next moment discounted by γ (a number a little below 1, so later reward counts for less), minus the prediction from this one. The authors present it as a generalization of Rescorla-Wagner that predicts the sum of future rewards rather than a single outcome. What the recordings show is the sign pattern: better than predicted, as predicted, worse than predicted. They do not show that the brain runs this exact algorithm, and the paper does not claim they do.
Hypercorrection: confident errors are the ones that get fixed
In human memory, the hypercorrection effect shows the principle from the other side. Butterfield and Metcalfe (2001) had people answer general-knowledge questions and rate their confidence in each answer, showed them the correct answer after every error, and retested them later. The errors made with the highest confidence were the ones most likely to be corrected on the retest. That is the opposite of what a strength-based account predicts, since a confident answer should be the hardest to overwrite.
Metcalfe's 2017 review names two factors, and says they are not mutually exclusive. One is surprise: feedback that contradicts a confident answer captures attention. In a follow-up, people doing the task while listening for very soft tones missed more of the tones played at the moment they got feedback on a high-confidence error, and EEG recordings show a larger surprise-related response to that feedback. The other is knowledge: people tend to make confident errors in domains they know well, where the right answer is often already familiar once they see it. Both probably contribute. Surprise does not have to be the whole story to be a reliable marker of where learning happens.
Incidental learning: retention as a side effect
People also do not have to decide to remember for learning to happen. Hyde and Jenkins (1973) had groups of students listen to 24 words while doing one of five orienting tasks: rating each word's pleasantness, estimating how often it is used in English, checking whether it contains an E or a G, naming its part of speech, or judging whether it fits a sentence frame. Half the groups were told to expect a recall test and half were not, and two control groups did no task and simply tried to learn the list. Hyde and Jenkins counted the first two as semantic, since they require thinking about what a word means, and those two produced far more recall than the other three. The control groups, which only tried to memorize, did no better than the semantic-task groups that had been told about the test, and across this line of experiments a meaning-based task has produced about as much recall as a deliberate attempt to learn. Knowing that a test was coming made some difference. Which task people did made much more. Retention followed from what people did with each word.
Model architectures reach for the same signal
At least one recent architecture uses the principle directly. Titans (Behrouz, Zhong and Mirrokni, 2025) adds a neural long-term memory that keeps learning while the model runs, and scales each write by how surprising the input is, measured as the gradient of the memory's loss on that input. In its simplest form the update is M_t = M_(t−1) − θ_t ∇ℓ(M_(t−1); x_t), where x_t is the new input, ℓ is how badly the memory M predicts it, and θ_t is a learning rate. The full version adds a forgetting gate and a momentum term, and the momentum carries recent surprise forward, so the inputs just after a surprising one are also written strongly. The paper motivates the design with the same observation from psychology, that an event which violates expectations is more memorable.
The error term in Rescorla-Wagner says how much to learn on a trial. The set of cues present says what gets the credit. Blocking is a statement about credit: the outcome had already been credited to A, so B got none. A memory that writes on surprise needs both parts. The surprise says when to write. Something else has to say what the write is about.
For agent memory, this points at a specific design. The write signal should be a measurable surprise that the harness detects, rather than a save the model decides to make. The case against waiting for the model is empirical, and it is laid out in The Agent Never Chooses to Remember: Memory as a Harness Property: an agent given memory tools in a seeded run never chose to use them. The harness sees every tool call anyway, so it is the natural place to look for surprise.
What Surprise Looks Like in a Coding Agent's Tool Stream
A coding agent's session is a stream of tool calls: shell commands with exit statuses and output, file reads, file edits. Most of it is unsurprising. A search returns results, a file is read, a test that was expected to pass passes.
The surprising moment has a shape a harness can detect without asking a model anything:
- A command runs and fails: a non-zero exit status, or output containing an unambiguous failure marker.
- Something changes: the command's own arguments or flags, a file the agent edits, or the environment the command runs in.
- The same command, or a close variant, runs again in the same directory and passes.
That sequence is a discovery. At step 1 the agent did not know something; by step 3 it did, and the evidence is the transition from red to green. What it learned is the change in step 2, and it only makes sense bound to the context of step 1. In Rescorla-Wagner terms, the failure is the error that says a write should happen, and the change is the cue that gets the credit.
A harness cannot see what the model expected, so a failure is a proxy for surprise rather than surprise itself. Usually it is a good one, because an agent runs a command in the expectation that it will work. The exception is a reproduction run, where the agent expects a test to fail. There a red is the expected result and a green would be the surprise, and a detector that keys on failures cannot see that kind at all.
Where this sits next to "the first search is the write"
Search Is Memory's Write Path argued that for knowledge about a codebase, the first search is the write and every repeat is the read, and that capture is the hard half, because the conclusion a search produces lives in the model's reasoning rather than in the tool stream. Which moments deserve a write is a separate question. For one class of knowledge the answer is entirely in the tool stream. The failing invocation, the change and the passing invocation are all tool calls, so capturing a fail, change, pass sequence needs no model judgment at all.
A lesson is a (context, change) pair
The framing has precedent one level up. Research on mining reusable bug-fix patterns from version history treats a pattern as a pair: what was wrong, and what edit fixed it. FixMiner (Koyuncu et al., 2020) mines fix patterns from what it calls Rich Edit Scripts, edit scripts that carry "the AST-level context of the code changes", and feeds them to an automated program repair tool. The fixed code on its own would not do, because the fixed artifact without the broken one does not say what the fix was.
Commands work the same way. Storing "npm install --legacy-peer-deps works" loses the lesson. The lesson is "npm install fails here with a peer-dependency conflict, and adding --legacy-peer-deps gets past it". The context also bounds the lesson. That flag tells npm to stop enforcing peer-dependency requirements, which is a reasonable workaround in one repository and a way to ship a broken install in another. A rule stripped of the failure that motivated it cannot tell which repository it is in.
Why the Change Separates a Lesson From a Retry
The simplest detector would be: a command failed, later it passed, so record it. That detector is wrong often enough to be dangerous.
Durieux, Le Goues, Hilton and Abreu (2020) studied restarted builds on Travis CI, across 3,286,773 builds collected over about ten weeks in late 2019. Developers "restart at least 1.72% of builds, amounting to 56,522 restarted builds". A restart re-runs "the same test suite on the same code". Of the restarted builds that had originally failed or errored, 46.77% passed after the restart. The causes the authors identify are mostly failing tests, network problems and Travis CI limits such as execution timeouts: flaky behaviour, not code.
The 46.77% is not the chance that an arbitrary failing build passes on a rerun. Developers chose which builds to restart, and they restart the ones they suspect; the authors note that developers seem "reasonably adept at identifying such flaky builds." That selection is the relevant one here, though. An agent that reruns a command without changing anything is making the same bet, that the failure was not its fault. When the bet pays off, the only thing learned is that the command is unreliable. A memory that records the flip as a lesson teaches the next session something false: that some action was the fix, when nothing was.
Take q from the Travis figure, 0.4677, and assume one unchanged rerun for every genuine fix (R = F). Then 0.4677 / 1.4677 ≈ 0.32: about a third of what the naive detector stores is noise, and no single record says which third. Neither input has been measured for agents; they show the shape. The noise share grows with how often the agent reruns without changing anything and with how flaky its commands are, and it cannot be seen one record at a time.
Requiring a change removes most of the q·R term. What survives is an unchanged failure that happens to clear right after an unrelated change. The cost runs the other way: a fix whose change the harness cannot see is missed.
A doctor who writes "gave ginger tea, fever broke" in a casebook has recorded a sequence, not a cure. Many fevers break on their own. Writing only "fever broke" is worse still, because it cannot even name what to try next time. Medicine separates treatment from natural course with a control group. A command stream carries a partial control of its own: when the identical command passes on a rerun with nothing changed, the environment has just shown that this failure can clear by itself.
The analogy also marks the limit of the rule. A change followed by a pass is better evidence than a pass alone, but it is not proof: the fever might have broken on the day the tea was given. A detector that requires a change inherits that weakness, and has to be designed around it.
The change is what separates learning from luck, so the detector has to require one. It can appear in the command, in the files, or in the environment, and the detector also needs a rule for when it appears nowhere.
1. The command itself changed
The failing and passing commands must be similar enough to be the same attempt, and different enough to contain a change. For concrete numbers, take vectr, an open-source code-search and agent-memory tool I maintain. It ships a detector for these sequences, which it calls arcs, and the source is public; the figures that follow are its defaults. It only compares two commands if they fall in the same bucket: the same invoked program, run in the same directory. A changed command is, in its terms, a mutation. Each command is first normalized: the invoked program and subcommand become the verb, dash-prefixed options become flags, the rest become arguments, a leading cd is stripped, and a trailing pipe into tail, head or cat is dropped because it changes only what a person sees.
verb is 1 if the verbs match, 0.7 if they are near-identical strings (a typo fix), otherwise 0. J(flags) is the Jaccard similarity of the two flag sets. args is the average per-position string similarity when both commands have the same number of arguments; when the counts differ, it is the overlap of argument types (paths, numbers and so on), scaled down by the gap in count. A score of exactly 1 means the normalized commands are identical, and an identical command is never a mutation: it goes to the edit-and-environment check instead.
npm install followed by npm install --legacy-peer-deps scores 0.5 × 1 + 0.3 × 0 + 0.2 × 1 = 0.70, inside the band. pytest followed by python -m pytest, which can be a real fix because it puts the current directory on Python's import path, lands in a different bucket (a different program) and would score 0.05 anyway. cargo build followed by cargo build --features tls scores 0.50 and falls below the band, so that fix would be missed.
The score measures resemblance, not cause. A failing pytest tests/test_api.py::test_login followed by a passing pytest tests/test_api.py::test_logout scores 0.98 and is recorded, although running a different test fixed nothing. These weights are design defaults, not fitted values. The detector's own replay notes say none of them were tuned against real transcripts, because the only corpus available had no failures to tune against.
2. A file was edited, or the environment changed
Most coding repair loops never touch a flag. They go: fail, edit a source or config file, rerun the identical command, pass. A mutation rule alone cannot tell that rerun from a flaky retry, since the command is identical. With edit events from the same window it becomes the strongest kind of lesson: the change is a file diff, and the edited paths are the payload.
The environment is the third place a change can live, and the hardest to observe. vectr sees it only as a variable set in front of the command, as in PYTHONPATH=src pytest ..., and it compares variable names, not values. An export run as a separate command is invisible to it, and so is a switch from CC=gcc to CC=clang: both reruns look unchanged and are treated as retries.
The edit rule has a weakness of its own. It checks that some file was edited in the window, not that the edit had anything to do with the failure, and it does not consult the command's flip history. A flaky test that fails, then passes after the agent fixes a typo in a README, is recorded as a lesson with the README in its payload. That is the ginger tea, and nothing at capture time catches it. It is one of the reasons to keep the raw record rather than a summary of it.
3. Nothing changed: suppress it, and count it
An identical rerun that passes with no edit and no environment change is a retry, and it is never recorded as a discovery. It is counted, per command, as an unchanged flip. The count carries information of its own: this command's outcome does not depend only on its input.
Build tools already draw the same line. Maven's test runner, Surefire, can rerun failing tests (rerunFailingTestsCount). A test that fails and then passes on a rerun is counted as a flake, the build succeeds, and the summary reads Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Flakes: 1. The tool files the rerun under instability.
vectr adds one rule on top, aimed at the Travis base rate. After two unchanged flips of the same command in one session, near-identical variants of it (similarity 0.95 or more) stop producing lessons as well, since a command that flips on its own is weak evidence that a one-character tweak fixed it. The rule applies only to changed commands; the edit rule never consults it.
The traps, and a narrow rule for each
Five more traps show up in real tool streams. Each gets one narrow rule. A single clever rule covering all of them would be harder to test and easier to fool.
- A tool exits 0 while reporting failure. The common case is a test run piped into
tail: a pipeline reports the exit status of its last command, andtailsucceeds. Rule: read failure and success markers in the output first, and trust the exit status only when no marker matches. A marker match with exit 0 is a "soft failure", and it counts. - A transient condition clears at the same moment as an unrelated change. A network error on the first run, an edit to a README, then a pass. Rule: if the failure's output matches a known transient signature (a timeout, a connection reset, a rate limit), keep the arc but mark it low confidence. In vectr this rule is wired into the detector, but the shipped marker table does not yet define the transient signatures it refers to, so as of this writing it cannot fire.
- An interrupted run looks like a failure. A Ctrl-C in the middle of a test run can print a partial summary with failures in it. Rule: an interrupted or signal-killed run never starts an arc and never resolves one.
- The same command, in a different place.
make testfailing in one service and passing in another is two facts, not a fix. Rule: the directory the command actually ran in, including any leadingcd, is part of the bucket key, not a kind of change. A pass in one directory never resolves a failure in another. Some real fixes are a change of directory, and this rule loses them; binding unrelated services together would cost more. - Old failures. A pass an hour later is not an answer to a failure from an hour ago. Rule: a pending failure ages out after 20 commands or 10 minutes, whichever comes first.
Choose how the first run failed, what happened between the runs, and how the second run went. The panel shows what a surprise-driven detector does with the pair, and why. Worth trying in turn: every option under "Between the runs" with a passing second run, which shows both the lessons it keeps and the two it gets wrong; the same with an interrupted first run; and "nothing" or "a neighbouring test" after two earlier unchanged flips.
Keep the Raw Arc, Distill the Lesson Later
A detected arc is raw material. The obvious next move is to summarize it into a rule, "in this repo, use --legacy-peer-deps", and throw the raw sequence away. The better-known systems that learn from the trajectories of LLM agents mostly keep the evidence, and the one that compresses hardest documents what compression costs.
ExpeL keeps failed and successful attempts side by side
ExpeL (Zhao et al., AAAI 2024) gathers experience by trial and error, retrying failed training tasks after a written self-reflection, and puts every trajectory, failed or successful, into an experience pool. Extracting insights is a separate, later step: the model compares "a failed trajectory with a successful trajectory for the same task", or looks for patterns across several successes, and edits a running list of insights that can be upvoted, downvoted or removed. At evaluation the agent gets both the insights and the most similar successful trajectories as worked examples. A failed attempt, a reflection, then a successful retry of the same task is a fail, change, pass arc one level up, and ExpeL keeps the pair.
Voyager commits only what a success verified
Voyager (Wang et al., 2023) writes code to act in Minecraft. It runs each program, feeds execution errors and environment feedback into the next round of code generation, and commits a program to its skill library only after a separate verification step confirms the task succeeded. After four rounds without success it moves on. The failing attempts stay in the prompt until then; they never enter the library.
Voyager does store the fixed program without its failures, and for Voyager that is right. A skill is retrieved by an embedding of its description, when the agent has a goal the skill serves. A command lesson is needed at a different moment, when the same failure recurs, so the failure is its retrieval key and cannot be thrown away.
Agent Workflow Memory, and what compression dropped
Agent Workflow Memory (Wang, Mao, Fried and Neubig, 2024) compresses hardest. It prompts a model to induce workflows from past trajectories: reusable sub-routines with example-specific values replaced by placeholders such as {product-name}. In its online setting it induces them only from trajectories that a model-based evaluator judged successful, and it stores the workflows rather than the trajectories. The method improves success on two web-navigation benchmarks.
The paper also tests a variant that wraps each workflow as a single callable action, and it reports that variant's failure case plainly. When booking a flight, the site pops up a list of nearby airports after a city name is typed. A book-flight workflow that enters all the required data as a pre-determined action sequence fails, because "the action to choose pop-up airports is executed without seeing the intermediate states with available pop-up options". The compressed form kept the steps and dropped the observation between them.
A summary written at capture time keeps the fix and drops the branching that explains why it worked: what the failure looked like, what state the agent saw between steps, which directory it ran in. Without that, a later session facing a variant of the same failure cannot recognize it as the same failure. Capture raw arcs deterministically and immediately. Distill them later, at a boundary such as the end of a session, with the raw arc still attached as evidence.
Keeping the two steps apart also makes each one's failures easier to find. Detection is deterministic: it can be tested on constructed sequences and audited line by line on real transcripts. Distillation is a judgment, made by a model, and it can be wrong. Keeping the raw arc means a wrong distillation can be checked against its evidence instead of replacing it. It also works in the other direction. The arc that credits a README typo fix for a flaky pass is a bad lesson, and a distillation step that reads the raw record can see that the only edited file was documentation and reject it. A rule written at capture time would have kept the pass and lost that detail.
When and how the later pass should run is the subject of Consolidation Is the Missing Phase in Agent Memory, which argues that the write path is the wrong vantage point for integrating, abstracting or selecting, because at write time the agent has one episode and a task to finish. Arcs add one requirement to that phase: every lesson it writes has to keep a pointer to the arcs it came from.
Zero Arcs in Twenty Agent Sessions, and What the Environment Hid
vectr's arc detector was replayed over 20 recorded agent sessions against Apache Camel, a large multi-module Java codebase, from two earlier benchmark runs: 246 shell commands and 9 file edits in all. It emitted zero arcs.
The two runs were different kinds of work. Twelve sessions were read-only exploration: they answered questions about the code and made no edits, so an edit-mediated arc (one where the change is a file edit) was structurally impossible there, and a mutation arc would have needed a failing command. The other eight were bugfix sessions. They made all nine edits and ran the tests.
Zero is either a detector bug or a true fact about the corpus, so every one of the 246 commands was checked by hand against the raw transcripts, outside the detector, for any sign of failure: an error flag from the tool layer, a BUILD FAILURE line, a JUnit summary with failures, a Python traceback, "command not found". The tool layer flagged no command as an error. There were 35 matches on failure-shaped text, and every one sat in the output of a Maven test run that ended in BUILD SUCCESS. In every bugfix session, the Maven command that followed an edit passed on its first run. No session contained a fail, edit, rerun, pass loop anywhere. Zero was the correct answer.
Why no test ever failed
That is a stranger result than it looks. Eight sessions edited source code and ran tests, and not one test run went red.
The cause was the build setup. All 25 Maven invocations in the bugfix sessions were scoped to a single module. In Maven, a single-module run compiles against the previously installed copies of the other modules, not against their source in the working tree. On the tasks where the fix lived in one module and its test in another, the agent's edit was invisible to the test it ran. The runs were also routinely quieted (Maven's -q flag suppresses most output) or piped through tail, which replaces Maven's exit status with tail's. One bugfix session did what a careful engineer does and ran the bug's own test before touching the code, expecting red. It got green, on code that still contained the bug.
The piping is not why the detector saw nothing. It reads failure markers in the output before it trusts an exit code, precisely because pipes misreport exit status. There was no failure text to read.
The detector saw nothing because the environment never produced a failure for it to see. A memory written on prediction error cannot learn in an environment that never reports an error. Capture of this kind depends on the agent knowing how to get honest feedback from its environment: which modules to build together, which flags hide the result. That is a different kind of knowledge, procedural rather than factual, and it is the subject of Agents Forget How, Not What.
The only moment in those eight sessions that contradicted an agent's expectation was the reproduction run that went green on buggy code. The model noticed. Its reasoning at that point reads: "Wait, the test is already passing? But the bug description says it should fail." It spent 19 of its 40 turns after that green trying to account for it and ran out of turns without writing a fix.
A detector keyed on failures sees none of this. A green is a success, and successes only resolve pending failures; they never start anything. The surprise existed, but it lived in the model's reasoning, not in the tool stream. False passes are invisible to failure-driven capture by construction. Catching them needs a different trigger, such as the bug's own test passing before anything has been edited, which a harness can also detect without asking a model.
What the zero does and does not show
It shows the detector produced no false lessons on real transcripts, including in sessions full of test runs and edits. It cannot show that the detector finds real lessons, because the corpus contains none. That half rests on synthetic tests in vectr's suite, constructed sequences that pit fail, edit, identical rerun against fail, identical rerun with no edit. How many of the real lessons in real transcripts the detector would catch is, so far, unmeasured.
What Surprise-Driven Capture Changes in an Agent Memory Design
Write on arcs, not on intent
Voluntary saves stay available; a model that has something worth saying should be able to say it. But the default capture channel is a detector in the harness, watching the tool stream and requiring a failure, a change and a pass.
Store the pair, not the fix
The record is the failing invocation, the observed failure, the change (an argument diff or the list of edited paths), the passing invocation, and its scope: the directory the command ran in and a coarse environment delta. A fix learned in one repository is not automatically a fix in another, and a fix learned in one service directory is not automatically a fix in its neighbour. vectr's arc record has this shape: the chain of failing runs, the passing run, a diff over five axes (verb, flags, arguments, environment, edited files) and a confidence label.
Suppress retries loudly
Unchanged fail-then-pass sequences are counted as instability, never stored as lessons, and the count belongs somewhere a person or a later session can see it. "This test flipped three times today with no change" is useful to the next session: it describes the test and prescribes nothing. vectr currently keeps the count inside the detector, where it drives suppression, and does not show it to anyone yet.
Distill at a boundary, with the evidence attached
A distilled lesson carries a reference to the arcs it came from, so a later reader can check it. In vectr, captured arcs wait in a review step, and a note written from them records which arcs it distilled. Whether notes written this way improve later sessions has not been measured.
Treat zero arcs as a signal about the environment
A long session with edits and no failures should worry whoever reads it. It may mean the agent's tests cannot fail. In the Camel sessions, a count of arcs per session would have read zero for eight bugfix sessions in a row, and that zero would have been a cheap early sign that the tests could not fail.
| Write policy | What triggers a write | What gets stored | How it fails |
|---|---|---|---|
| Voluntary save | The model decides to save | The model's own summary | Under-fires: the save rarely happens |
| Save everything | Every event, or a summary at session end | The transcript, or a compression of it | Over-fires: routine buries the few lessons, and a summary drops the branch that explained them |
| Arc capture | Harness sees a failure, a change, then a pass | Failing run, failure, change, passing run, scope | Blind where nothing fails, and misses changes it cannot see, such as a switch to a different program |
What Surprise-Driven Agent Memory Predicts
Prediction 1. On real transcripts where honest failures occur, a detector that only looks for changed commands will miss most real lessons, and adding edit-mediated arcs will recover them. The measurement is the fraction of hand-labelled lessons each detector finds. The Camel replay cannot run it, because it contains no failures.
Prediction 2. A store populated from arcs will have far fewer entries than one populated by saving everything and far more than one populated by voluntary saves, and its entries will be retrieved and used at a higher rate per entry than either. If per-entry usage is not higher, surprise is not a better write signal than intent.
Prediction 3. Recording unchanged fail-then-pass sequences as lessons will measurably degrade later sessions, by prescribing actions that had nothing to do with the pass. This tests the consequence of the Travis base rate directly: the same memory, with and without retry suppression, on tasks that include a known flaky command.
A memory should write when the environment contradicts the agent, and what it should store is the change that resolved the contradiction, kept next to the failure. That rule is only as good as the environment's honesty. Where tests cannot fail it writes nothing, and the thing to fix is the tests.
People do not decide what to remember; surprise does much of the deciding. For an agent the surprise is a command that failed and then passed, and the lesson is the change in between. Without the change it was a retry, and a memory that cannot tell the two apart teaches luck as if it were knowledge.
Sources
- Kamin, L. J. "Predictability, surprise, attention, and conditioning." In B. A. Campbell and R. M. Church (eds.), Punishment and Aversive Behavior, pp. 279-296. Appleton-Century-Crofts, 1969.
- Moore, J. W., Schmajuk, N. A. "Kamin blocking." Scholarpedia 3(5):3542, 2008.
- Rescorla, R. A., Wagner, A. R. "A theory of Pavlovian conditioning: Variations in the effectiveness of reinforcement and nonreinforcement." In A. H. Black and W. F. Prokasy (eds.), Classical Conditioning II: Current Research and Theory, pp. 64-99. Appleton-Century-Crofts, 1972.
- Rescorla, R. A. "Rescorla-Wagner model." Scholarpedia 3(3):2237, 2008. doi:10.4249/scholarpedia.2237.
- Mackintosh, N. J. "A theory of attention: Variations in the associability of stimuli with reinforcement." Psychological Review 82(4), 1975, pp. 276-298. doi:10.1037/h0076778. Pearce, J. M., Hall, G. "A model for Pavlovian learning: Variations in the effectiveness of conditioned but not of unconditioned stimuli." Psychological Review 87(6), 1980, pp. 532-552. doi:10.1037/0033-295X.87.6.532.
- Schultz, W., Dayan, P., Montague, P. R. "A Neural Substrate of Prediction and Reward." Science 275(5306), 1997, pp. 1593-1599. doi:10.1126/science.275.5306.1593.
- Butterfield, B., Metcalfe, J. "Errors committed with high confidence are hypercorrected." Journal of Experimental Psychology: Learning, Memory, and Cognition 27(6), 2001, pp. 1491-1494. doi:10.1037/0278-7393.27.6.1491.
- Butterfield, B., Metcalfe, J. "The correction of errors committed with high confidence." Metacognition and Learning 1(1), 2006, pp. 69-84. doi:10.1007/s11409-006-6894-z.
- Metcalfe, J. "Learning from Errors." Annual Review of Psychology 68, 2017, pp. 465-489. doi:10.1146/annurev-psych-010416-044022.
- Hyde, T. S., Jenkins, J. J. "Recall for words as a function of semantic, graphic, and syntactic orienting tasks." Journal of Verbal Learning and Verbal Behavior 12(5), 1973, pp. 471-480. doi:10.1016/S0022-5371(73)80027-1.
- Tekin, E., Roediger, H. L. "Solving a Mystery in Levels-of-Processing Research: The Word-First Paradigm." The American Journal of Psychology 134(2), 2021, pp. 129-141. doi:10.5406/amerjpsyc.134.2.0129.
- Behrouz, A., Zhong, P., Mirrokni, V. Titans: Learning to Memorize at Test Time. arXiv:2501.00663, 2025.
- Koyuncu, A., Liu, K., Bissyandé, T. F., Kim, D., Klein, J., Monperrus, M., Le Traon, Y. "FixMiner: Mining relevant fix patterns for automated program repair." Empirical Software Engineering 25(3), 2020, pp. 1980-2024. doi:10.1007/s10664-019-09780-z; arXiv:1810.01791.
- Durieux, T., Le Goues, C., Hilton, M., Abreu, R. "Empirical Study of Restarted and Flaky Builds on Travis CI." MSR 2020, pp. 254-264. doi:10.1145/3379597.3387460; arXiv:2003.11772.
- Apache Maven Surefire. "Rerun Failing Tests."
- Zhao, A., Huang, D., Xu, Q., Lin, M., Liu, Y.-J., Huang, G. ExpeL: LLM Agents Are Experiential Learners. AAAI 2024. arXiv:2308.10144.
- Wang, G., Xie, Y., Jiang, Y., Mandlekar, A., Xiao, C., Zhu, Y., Fan, L., Anandkumar, A. Voyager: An Open-Ended Embodied Agent with Large Language Models. arXiv:2305.16291, 2023.
- Wang, Z. Z., Mao, J., Fried, D., Neubig, G. Agent Workflow Memory. arXiv:2409.07429, 2024.
- vectr,
benchmarks/arc_replay_results.md. - vectr,
benchmarks/vs_bash/tier1/README.md. - vectr,
results/vectr-vs-bash/camel/6b422df/t2/. - vectr,
app/arcs.py,agent/outcome.py,agent/config.yamlandagent/markers.yaml.