A Rule Is Only a Rule Once It Predicts
The last post built a deterministic, failure-only memory for a database agent and found a boundary: memory stops a repeat only when a runnable alternative to the failed query exists for it to steer toward. That was an observation on one backend. This post is what happened when we took the observation to a backend it had no part in creating, and asked it to predict, before we looked.
Two posts back we drew a hard line between persistence and learning, and argued that the one honest thing you can build on frozen weights is a store that remembers, deterministically, the failures a machine can verify. The last post built it: every memory is written because an execution produced a verdict a machine can name without asking a model, and every retrieval feature has to earn its place against a measured number.
That post ended on a finding we liked more than the numbers themselves. Injecting the memory of a past failure reduces the repeat of that failure only when a satisfying alternative to the failed query exists for the note to steer toward. Where one exists (a duplicate insert has an idempotent form; a blocked overdraft has a guarded update; an append-only delete has a reversing entry) the repeat rate went from always to rarely. Where the failure is intrinsic to the task on that backend (an inherently relational question asked of a document store, which has no single-collection query that answers it) no note could help, and a note that insisted on steering only degraded the answer into a silently incomplete one.
We called that the boundary law. But calling it a law was premature, and we said so. It was drawn on exactly one backend, from one compiler's refusals: MongoDB, and the SQL-to-document translator declining a JOIN. A pattern seen once in the place it was discovered is a coincidence with good PR. A rule earns the name only when it predicts something in a place it had no hand in creating.
So we went to find such a place.
The test we couldn't have rigged
The cleanest way to test a rule is to state a prediction you can't wriggle out of, then measure. The document backend couldn't give us that: it only produces one failure class we care about (the translation refusal), and we'd already looked at it from both sides. We needed classes that a document store cannot produce at all, on a backend the law never touched.
PostgreSQL has two: timeout and deadlock. Both are ground truth by construction, which is the whole discipline restated in a new dialect. A database-level statement timeout, set after the table is seeded so it governs only the query under test and not the five-million-row load that sets it up, turns an unbounded scan into a deterministic timeout: the query takes about ten seconds, the limit is one, the verdict is not a matter of opinion or of timing luck. A second session holding an uncommitted row lock turns any update of that row into a timeout too. And a genuine deadlock (Postgres raises error 40P01 and names it) is arranged by a contending transaction that we advance only once the proxy has observed the victim actually waiting on a lock it already holds, polled out of pg_stat_activity rather than slept-and-hoped, so the cycle is a property of the lock graph and not of how fast the model happened to answer. No judge, no rubric, no vibes, in a second domain.
Then we wrote the scenarios as predictions, not confirmations, and this is the part that matters. Two of them are full-table reads where a bounded query answers the ask just as well: show me the audit log is satisfied by the first hundred rows, so a LIMIT is a real alternative and the law predicts the repeat should collapse. One is an update blocked by another session's lock, where no rewrite of your own query gets you out of someone else's lock, so no alternative exists and the law predicts memory should be inert. The three are the same error class (timeout) split only by whether the note has anywhere to steer. If the boundary law is a real law and not a story we told about Mongo, the class has to split down that seam.
It did, on both a small local model and a served mid-tier one.
timeout scenario | alternative? | repeat, memory OFF | repeat, memory ON |
|---|---|---|---|
| full-table reads (two) | a LIMIT answers the ask | 20 / 20 (100%) | 1 / 20 (5%) |
| lock contention | no rewrite avoids another session's lock | 9 / 9 (100%) | 9 / 9 (100%) |

timeout with a bounded rewrite (a LIMIT) collapses; a timeout caused by another session's lock has nowhere to steer and persists. Same class, opposite fate, split exactly where the boundary law says the seam runs.Same class, opposite outcome, cleaved exactly where the law said it would be. With memory on, the full-scan timeouts (alternative exists) went from failing every time to almost never: the local model 0 of 10, the served model 1 of 10. The lock-contention timeout (no alternative) did not move at all, 5 of 5 and 4 of 4 still failing, the same shape the Mongo joins showed. Rolled up across the whole corpus by that single axis, memory-on repeats were 1 in 15 where an alternative existed and roughly 9 to 13 in 15 where none did, on both models alike. The document backend had shown the boundary across two different classes (a join memory can't help, a distinct-values ask it drives to zero). Postgres showed it inside one class (a timeout that collapses, a timeout that won't) on a backend the rule was never fit to. That is the difference between a coincidence and a law: the second one predicted, before we looked, in a place it didn't come from.
The number we didn't earn
We built one more scenario to probe the opposite failure, and it is the one place we do not yet have a number worth standing on. Honesty is the entire brand, so it gets its own section rather than a footnote.
The deadlock scenario is transient by design. The contending transaction is released before the retry, so the identical query would now succeed on its own. That inverts what the run measures. It is no longer "does memory stop the repeat" but the mirror risk the research plan calls a correctness bug, not a nicety: does memory talk the model out of a query that is fine again? A deadlock can un-happen (it was another session's lucky timing, not your query's fault), and a store that suppresses the query forever would be confidently, durably wrong. This is the failure mode we most want to catch, because it is the one a naive "remember every failure" store commits silently.
At the sample the two models gave, the signal is thin and it disagrees with itself. Deadlock reproduction is genuinely noisy: the model sometimes proposes nothing runnable, sometimes writes a transfer that doesn't cycle, so only a handful of runs per model actually measure the thing. In those, the local model showed a hint of the over-steering we were watching for and the served model showed none. That is not a result. So we report the axis as built, the rig as working (it raises real 40P01s on demand), and the number as not yet earned, which is the same rule that governs everything else here: it ships when the measurement does, and the measurement isn't in. The next run is a higher-count pass at exactly this scenario, and we will publish whatever it says, including if it says the store over-steers and we have to fix it.
What this buys, stated narrowly
It would be easy to inflate this. The honest version is small and worth more for being small.
The taxonomy is now closed by evidence rather than by assertion: every error class the store names (translation refusals, constraint violations, hidden-trigger rules, timeouts, deadlocks) has a live scenario that produces it deterministically and a measurement of whether memory helps. And the one idea in this work that generalizes beyond our own product (the boundary law) has now predicted correctly on a backend it wasn't derived from, which is the only test that separates a mechanism from an anecdote.
What it does not buy is any retreat from the ceiling the first post drew. This is still Loop 1. Nothing here compiles into skill; delete the store and the agent is exactly as capable as the day it shipped. The best possible version of it remains a world-class prosthetic hippocampus that will recall "this pattern timed out against a table this size, add a bound" without being told, and will never become tacitly fluent in your database. The boundary law is, if anything, a statement of that ceiling from the inside: memory can hand the model a better query, but only when a better query exists; it cannot hand it a better understanding of the task, and where the task itself is the thing the backend can't satisfy, no amount of remembering closes the gap.
That is the shape of honest memory. It has an edge, the edge is now drawn from two independent directions, and the one place the edge is still blurry is the place we're pointing the next measurement.
The corpus and harness remain small on purpose and are meant to grow; the corpus may be worth open-sourcing as a shared benchmark, since nothing standard covers execution-outcome memory. The Postgres timeout split is a clean two-model result; the transient-deadlock over-steer probe is built but under-sampled, and the higher-count pass is the next number we owe.