Projects

Cubist

Building a symbolic autotelic agent: an AI that sets its own goals and learns its world as readable laws

2026·ResearchView on GitHub
Autotelic agentsSymbolic descentWorld-modelsOpen-endednessARC-AGI-3Interpretability

The mission

Watch a child in a new place. Nobody hands them a goal or a reward function. They poke at things, notice what surprises them, invent little challenges, and out of that self-directed play comes an ever-growing repertoire of skills. Developmental AI researchers call such a learner autotelic, from the Greek auto (self) and telos (goal): an agent that invents, selects, and pursues its own goals, driven by curiosity rather than external reward (Oudeyer & Kaplan, 2007; Forestier et al., 2022; Colas et al., 2022).

Cubist's mission is to build one, with a twist. The autotelic agents of Oudeyer, Colas, and colleagues are usually powered by deep reinforcement learning. Cubist is symbolic all the way down. Its model of the world is a set of laws you can read. Its skills are small closed-loop programs. And the algorithm that improves both is a discrete cousin of gradient descent we call symbolic descent.

Three properties motivate the symbolic bet. Continual learning: a theory made of discrete laws does not silently overwrite what it knew; a law that is already correct produces no error, and a learner driven by errors never touches it. Reasoning: every law is a falsifiable claim you can query, plan through, and revise; a weight vector predicts, a theory explains. Interpretability: when a symbolic model fails, the failure has an address. The honest counterpart is that gradients win where perception is raw and data is abundant. The symbolic bet targets the opposite regime: low data, a single life, and a demand for explanations. That happens to be the regime children, robots in the field, and scientific discovery all live in.

What follows is the current state of that bet, measured. It is the world-model half of the agent: a system that learns the laws of an unknown game while playing it, with no pretraining, no gradients, and one life. The headline result is a three-way comparison, held out on every prediction, across all 25 public ARC-AGI-3 games: 0.608 for a pure episodic memory, 0.647 for a pure theory of laws, and 0.681 for their fusion.

One life, scored honestly

Our benchmark is ARC-AGI-3, the interactive-reasoning benchmark from the ARC Prize Foundation. The agent is dropped into a grid-world game with no instructions and no stated goal: avatars, walls, buttons, counters, things that spawn and vanish, playable through a handful of abstract key actions and a click. Scoring emphasizes sample efficiency, which is Chollet's definition of intelligence as skill-acquisition efficiency made operational. A benchmark where the goal is never stated is exactly the right exam for an agent whose whole premise is inventing goals for itself. We evaluate on the 25 public games, 200 actions per game, a single episode each.

A small perception layer segments each frame into tracked, object-centric entities, and expresses what happened between frames as per-entity deltas: this entity moved by (-5, 0); that one's colours shifted; this one disappeared; a new one spawned two rows above its parent. A transition is the before-scene, the action taken (a click carries the clicked entity as its parameter), and those deltas. The deltas are the cells the world-model must predict.

Scoring is deliberately unforgiving. At every step the model predicts the incoming transition before learning from it, a genuine held-out test that never revisits the past, and a cell only counts if the predicted delta is exact. We report per-cell F1: recall punishes silence about real change, precision punishes claiming change that did not happen. Predicting "nothing changes" everywhere scores zero. Because learning is continual, every metric is a curve over the run; when we quote one number it is the run's mean.

Remembering everything

The baseline is embarrassingly simple, and it is the strongest baseline we have. Every entity in every transition becomes a case: a translation-invariant descriptor of the entity in its local context (its own colours, size, and velocity, then its nearest neighbours), paired with the delta it then underwent. To predict, the model retrieves the nearest stored cases under the same action and lets them vote. A click is part of the query, so "click the red button" is retrievable as such.

This memory is a world-model in the fullest sense. It assimilates almost every transition the moment it is seen, it transfers across levels, and it forgets essentially nothing. Across the 25 games it scores a held-out mean F1 of 0.608, in about three seconds of compute per game.

Its failure is just as clean. Retrieval interpolates; it cannot extrapolate. On ft09, a game where clicking one entity recolours a different one and each button appears only a handful of times, memory scores 0.051, and its final-step F1 is exactly zero. There is nothing near enough to retrieve. And memory explains nothing: its "model" is four thousand stored cases, and no part of it can be read.

Explaining everything

The alternative is a theory. A law is a typed rule over the scene:

(action, focus?, selector ⇒ transforms)

Under this action (or any action), if the clicked entity passes the optional focus gate, then every entity matching the selector (the WHO, a boolean query over the entity and its neighbourhood) undergoes the transforms (the WHAT, one small program per changed axis, computing the delta from the entity's own attributes). Everything the model believes is a sentence a person can read. Here are four laws from four different games' final theories, verbatim as the engine prints them:

# the scrolling background: every 1-cell-tall object drifts one column
# left on every action, whatever the player does. The run's most-fired
# law: 354 firings, 41 bits
any: (self.height == 1) ⇒ move := (0, -1)

# the countdown timer: the thin maroon bar shrinks by one cell
# every step
any: ((self.color == 9) and (self.height == 1)) ⇒ resize := (-1, 0)

# the avatar: on the up key the 5-wide player slides 5 cells up, unless
# it sits at the top row, at the right column, or a wall touches its
# left side (the exceptions entered as negated conditions, one repair
# at a time)
ACTION1: ((self.width == 5) and not (self.col == 31)
          and not exists(nbrs(selfd3@2)) and not (self.row == 18))
         ⇒ move := (-5, 0)

# a click-relative law: when a small 3-tall button is clicked, the big
# black panel elsewhere on screen lights up from color 0 to color 12
any: ((self.height == 15) and (self.color == 0) and (clicked.height == 3))
     ⇒ recolor := (-135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135, 0, 0, 0)

Reading the conditions: nbrs(selfd3@2) is "my neighbours at distance 3 in direction 2", clicked is the clicked entity, and the(...) picks a unique neighbour. Move deltas are (rows, columns); recolor deltas are colour-histogram shifts.

Where do candidate laws come from? Not from enumerating the grammar. The engine works backwards from observations, in the spirit of programming-by-example systems: for every observed delta, abduction enumerates the small expressions that exactly compute it in context, cheapest first, with the literal constant always present as the memorisation floor. Selectors are learned the same way, by contrast: each entity carries the most specific description true of it, and a selector is grown greedily to cover the entities the law must match and exclude the ones it must not. Nothing is ever proposed that is not true of something actually observed.

Symbolic descent

Fitting the theory is where the gradient-descent parallel becomes load-bearing rather than decorative. We are fitting a model to samples, so we fit it the way optimisers do.

The loss is two-part minimum description length: the size of the theory plus the size of what it fails to explain.

L(T) = bits(T) + bits(residual(T, window))

Every expression in the language carries a real code length, so a theory's size is a sum over its laws. The residual prices every error against a recent window of transitions: a missed change costs the bits to state it literally, a false claim costs a fixed penalty, and what is unexplained and unchanged costs nothing. A law earns its place only if it compresses the world better than remembering it would. Minimising L is the whole learning rule; there is no other acceptance logic in the model.

Each ingredient of the optimiser has an exact symbolic counterpart:

Gradient descentSymbolic descent
parameters θ ∈ ℝⁿa theory T, a finite set of laws
loss ℒ(θ)L(T) = bits(T) + bits(residual), over a recent window
the gradient ∇ℒthe typed residual: a miss points at ADD or GENERALIZE, a false claim at SPECIALIZE or DELETE, a wrong delta at RETARGET
a step θ ← θ − η∇ℒreplace at most one law with a refined one
step size, line searchnone needed: ΔL is computed exactly
minibatcha sliding window of the last 64 transitions
importance weightingrecurrence pricing: an error that keeps recurring across the whole life is priced above its literal bits
steepest descentall candidate moves priced, steepest taken first
convergenceaccept only if ΔL < 0, so every accepted step strictly decreases a bounded loss
epochs over a datasetanytime: a few accepted moves per frame, resuming next frame from the theory it left off with. Learning never blocks living

Two differences favour the symbolic side. Where the optimiser's step relies on a first-order approximation, ΔL is computed exactly. And the "gradient" is typed: an error does not merely say the loss grows here, it names the family of moves that would repair it. ADD is gradient boosting's move, fitting one new law to the residual. GENERALIZE relaxes one condition of a law that was merely too narrow. SPECIALIZE conjoins the condition that best separates a law's hits from its false positives; that is how "no wall touches my left side" entered the avatar law above. Because acceptance is only ever ΔL < 0, failures need no bookkeeping: a candidate that does not descend is simply not taken, and structure the language cannot yet express shows up plainly, as residual that never descends, not as a wrong law.

Here is what the descent looks like from inside a single life:

The fusion: laws take over, memory fills the rest

The two models fail in opposite places. Memory cannot extrapolate. The theory refuses what it cannot yet express: its MDL gate would rather leave residual than admit a wrong law, so its assimilation is deliberately incomplete. The fusion gives each its own jurisdiction, and the routing rule is one sentence: where the theory claims, the theory speaks; memory fills only the unclaimed.

We tried the cautious alternative first, trusting memory near stored cases and laws only far from them, and the blunt rule beat it wherever it differed. A law that has survived the MDL gate is a better witness than a nearby memory, because the memory's nearest case may be an accident and the law, by construction, is not.

Memory also shrinks as the theory matures: any stored case the theory fully explains is archived, so what stays active in memory is, precisely, the theory's residual. One subtlety mattered enough to measure. A refusing theory's silence can mean ignorance rather than "no change", so an unchanged case is only archived when the theory replays its whole transition exactly. Trusting silence without that check dragged the hybrid down to its weaker parent.

Results

Everything below is 25 games, 200 actions each, one life per game, per-cell exact-match F1, predicted before learning, means over the run. The full board runs in about 35 minutes on a laptop and is deterministic.

The full board, sorted by hybrid score. Bold marks the best model on each game; the last two columns describe the descent's final theory (number of laws, and bits of observation explained per bit of theory).

GameAnalogy (memory)Descent (laws)Hybrid (fusion)LawsCompression
tn360.8990.9510.948758.7x
su150.9490.7730.88776.0x
lf520.8790.7760.8361319.1x
sb260.9590.7110.828332.1x
sp800.8040.7770.7991041.3x
ls200.7990.7930.798257.4x
ar250.7780.7480.7782014.5x
cd820.6070.7160.729496.4x
sc250.6640.6840.720528.4x
m0r00.4860.7150.712459.2x
s5i50.6200.5980.6803310.2x
dc220.4930.6390.675306.8x
ka590.4730.6370.660289.3x
lp850.5540.5570.653165.4x
bp350.6570.6640.646349.9x
tr870.4770.6480.646249.2x
vc330.5580.6130.643456.7x
cn040.3790.5970.620306.1x
g50t0.4780.6050.614425.7x
ft090.0510.5890.58655.2x
tu930.7010.5210.583239.1x
wa300.3690.5170.536454.5x
re860.4040.4870.516476.5x
sk480.6120.4350.502775.4x
r11l0.5400.4120.439177.5x
mean0.6080.6470.681727 total

Three readings of the board. First, the theory earns its keep exactly where retrieval is blind: ft09 (0.051 to 0.589), cn04 (0.379 to 0.597), wa30 (0.369 to 0.517), m0r0 (0.486 to 0.715). These are games whose dynamics are conditional or relational, where the answer must be computed, not recalled. Second, memory earns its keep where the world is noisy or particular: sb26 (0.959 against the theory's 0.711), su15, lf52, games friendly to nearest-neighbour structure. The hybrid does not split the difference; cell by cell, it takes whichever witness is competent, and on eleven games it beats both parents. Third, the theory is small enough to read: 727 laws across all 25 games, a median of 28 per game, with per-game compression between 4.5 and 59 times.

Held-out F1 measures prediction, the guess made before learning. Two companion metrics watch the learning itself, from opposite sides. Assimilation is measured right after the model has learned from a transition: the share of that transition's changed cells it now predicts exactly. It asks how much of what the world just showed was absorbed on the spot, which matters because a one-life learner gets no second pass; whatever is not assimilated now must wait for the world to repeat itself. Regression is measured over a recent window of previously assimilated cells: the share that has since become wrong again. It asks whether learning the new thing broke an old one. This is the continual-learning claim under direct measurement, catastrophic forgetting made a number. We report both because held-out F1 alone cannot separate the two ways a continual learner fails: a mediocre F1 can hide a model that absorbs too slowly, or one that absorbs quickly and keeps losing what it had. The pair pins down which is happening.

GameAssimilation: analogydescenthybridRegression: analogydescenthybrid
tn360.930.980.990.0030.0000.000
su151.000.901.000.0000.0000.000
lf520.990.740.760.0000.0000.000
sb261.000.720.760.0000.0000.000
sp801.000.840.850.0000.0000.002
ls201.000.920.960.0000.0020.000
ar251.000.860.900.0000.0020.004
cd821.000.730.980.0000.0000.000
sc250.990.860.920.0000.0020.003
m0r00.990.950.980.0000.0000.000
s5i51.000.720.750.0000.0000.008
dc220.950.830.970.0120.0040.002
ka590.960.710.900.0000.0000.004
lp851.000.660.710.0030.0200.030
bp350.930.770.900.0370.0100.023
tr871.000.780.820.0000.0020.006
vc330.960.720.760.0220.0020.005
cn040.990.830.890.0020.0000.005
g50t0.900.800.900.0080.0030.002
ft090.450.830.920.1630.1270.088
tu931.000.660.680.0000.0020.003
wa300.970.690.770.0000.0120.000
re861.000.640.850.0000.0000.008
sk480.910.650.860.0100.0050.003
r11l0.980.470.820.0070.0000.010
mean0.960.770.860.0110.0080.008

The two columns tell one story each. Memory assimilates nearly everything the moment it is seen, 0.96 on average, with one telling exception: on ft09 the entity descriptor conflates distinct buttons, stored cases fight each other, assimilation falls to 0.45, and regression spikes to 0.48 within a window. That is what forgetting looks like when it does happen. The theory's 0.77 is lower by design: the MDL gate would rather refuse a transition than admit a law it cannot defend, so its ignorance shows up here as unassimilated residual rather than as wrong laws, and the hybrid recovers most of the gap at 0.86. Regression is where the continual-learning bet pays: near zero for every model on almost every game, means of 0.011, 0.008, and 0.008. Learning something new almost never breaks something old. A correct law produces no error, and a learner driven by errors never touches it.

Compression is not a metaphor here; it is the objective, measured. On tn36 the final theory is seven laws that reproduce 59 times their own size in observed change.

One caveat the reader deserves: prediction is not solving. Only two games see completed levels within 200 random-policy actions, and those completions are identical across all three models. At this horizon, level completion is a property of the exploration policy, not the world-model. The world-model's job is to make a competent policy possible; building that policy is the program's next chapter, not this article's claim.

What refused to work

A design is also defined by what it measurably rejected. Each row below was implemented, benchmarked, and reverted. We report them because several are the obvious improvements a reader would suggest, and the numbers were loud.

What we triedWhat we measured
Searching harder: much larger candidate pools and uncapped budgetsNo stage of the candidate funnel moved, twice, on different engines. The bottleneck is what one condition can express, not how hard we search.
Pricing errors by each law's own measured error rate, the information-theoretically honest codeMean F1 fell from 0.667 to 0.519 on the development games. Honest coding makes recurring errors cheap; a loss must keep them dear to force laws into existence. A loss is not a code.
Normalising recurrence weights by lifetime rateCatastrophic: 0.667 to 0.393, one game's theory collapsing to two laws. Normalising away persistence removes exactly the pressure that admits laws.
A dedicated per-law click gate, the "principled home" for click conditionsft09 fell from 0.578 to 0.459. As ordinary conditions, the selector chooses which click property matters and combines it freely; the gate froze that choice.
An explicit MERGE move for combining similar lawsZero accepted merges in 398 attempts. GENERALIZE plus DELETE already reach every merge stepwise, so the operator is emergent, not primitive.
Trusting the theory's silence when archiving memoryInvalid for a refusing theory: silence can mean ignorance, not "no change". The hybrid fell to its weaker parent's level until silence was validated by full replay.

The recurring lesson, across engines and months: symbolic search saturates almost immediately. Every real gain in this project came from changing what the representation could express, never from searching harder.

Limitations

The theory is bounded by its language. Games whose dynamics live outside it, long causal chains through hidden state or global patterns with no per-entity story, sit at the bottom of the board for every law-fitter we built, and no amount of descent fixes a sentence the language cannot form. The entity descriptor can conflate distinct objects on click-heavy games, capping what any retrieval or contrast can separate. The residual prices are hand-set constants that survived every principled challenger we could build, but a derivation from first principles remains open. And the board measures prediction under a random policy; the model's value for acting is so far demonstrated only indirectly, by the uncertainty and claim signals it exposes.

Toward the autotelic agent

A world-model of readable laws changes what a policy can be. Laws expose claims, what would happen if, cheaply enough to plan against. The memory's distance signal exposes uncertainty, where the model is guessing, cheaply enough to explore against. And the residual names, at every moment, exactly what the agent does not yet understand. An agent that sets its own goals needs precisely these three currencies: something to want, something to wonder about, and a ledger of its own ignorance.

The loop we are building closes on itself: model the world, find what you cannot explain, invent a skill to probe it, and let the sharper model expose new gaps. Skills that prove themselves are kept, named, and reused as building blocks for more ambitious ones, the way DreamCoder grows a library of reusable abstractions. Goals sampled where uncertainty is high, skills distilled from laws that survive the gate: that agent is the work this research sets up.

Lineage

The pieces have long roots, and we used them deliberately. ADD is gradient boosting's fit-to-residual, transported to a discrete lattice. GENERALIZE and SPECIALIZE are version-space moves in Mitchell's sense; learning selectors by contrast descends from inductive logic programming (Progol and the modern learning-from-failures line). Abduction as inverse semantics comes from programming by example, as in FlashMeta. Two-part MDL is Rissanen; pricing rules by description length goes back at least to RIPPER. What we believe is new is the assembly: the typed residual as a direction-giving gradient over a lattice of laws, with exactly computed steps, the strictly monotone anytime descent it drives, and the fusion rule that lets a compressed theory take over an episodic memory cell by cell. Everything is learned online, LLM-free, and deterministically.

References

© 2026 Louis Manhès