How PRA works

Most machine brains study, then freeze. PRA — the Pose Resolution Architecture — never freezes: it keeps a head full of rival guessers that grow, compete, and get pruned for as long as it runs. This page walks through each core mechanism with a live simulation running the real update rules — smaller nets and faster clocks than the shipping system, but the same math. Scroll, poke, break things.

The whole loop at a glance

Everything else on this page is a close-up of one station on this ring.

A body senses the world. The sense becomes an observation. Paired with what was sensed before and what was done in between, it forms a triplet — the only record of cause and effect a body ever gets. A population of small world-models (frames) each try to place the observation in their own coordinate space; the ones that succeed contribute to the global pose, the system's reading of the moment. An external scorer judges every frame on everything it saw. A fixed drive turns the moment into a value signal, the action policy picks the move expected to raise it, the body acts — and the world answers with the next observation.

Before, action, after VALIDATED

A brain that reads every book about swimming still can't swim.

Everything PRA learns arrives in one shape: (previous_observation, action, observation) — what I sensed, what I did, what I sensed next. No labels, no dataset, no replay buffer. Drive the little rover below and watch its entire education stream past: each row is one triplet, each colored strip one observation (the rover's 12 distance-ish sensor channels).

Why triplets and not text

Prediction is the test of understanding: a model understands a world exactly as far as it can say what happens next, given what it does. That requires acting. Language describes the world secondhand; the triplet is the world answering you directly.

The reference frame VALIDATED

One small world-model betting the world has a particular number of knobs.

A frame is a learnable coordinate space with a chosen dimensionality dim. It does two jobs: place (turn an observation into a coordinate — its pose) and predict (given pose + action, say where the pose goes next). Below, four rival frames — betting 1, 2, 3, and 5 knobs — learn the same world live. The world secretly has 3 hidden knobs. Watch the reconstruction error: too few dimensions can't explain the world; enough dimensions can; extra dimensions… also can. That ambiguity is a problem we solve two sections down. (Give it a few hundred steps — real learning takes real time.)

step 0
observation (10 channels) dim-3 frame's reconstruction
The actual math (running live above)
encoder:     h  = tanh(W1·obs + b1);   pose = W2·h + b2
decoder:     hd = tanh(D1·pose + d1); recon = D2·hd + d2
transition:  th = tanh(T1[a]·pose + tb1[a]); pred_pose = T2[a]·th + tb2[a]   (one net per action)

fit_quality      = ‖recon − obs‖ / (‖obs‖ + 1e-6)
prediction_error = ‖decode(pred_pose) − next_obs‖ / (‖next_obs‖ + 1e-6)   ← observation space!
effort           = ‖pred_pose − pose‖

learning: plain gradient descent, every gradient element clipped to ±gradient_clip.

The load-bearing rule: prediction error is measured in observation space — the predicted pose is decoded back into a claimed observation and compared with reality. A collapsed frame can make its own pose trivially predictable; it cannot fake predicting the world. Never let a frame invent the ruler it is measured with.

Never grade your own homework VALIDATED

Frames choose what they learn from. They never choose what they're judged on.

Each event, a frame measures its fit. If the fit beats the fit_gate, the frame maps: it contributes its pose and gets to learn. If not, it drops the event — no learning. But here is the trick that keeps the whole ecology honest: the survival EMAs update on every event the frame is exposed to, mapped or not. Learning is sparse and self-selected; judgment is total. Flip the cheat switch below to see what happens if a frame were scored only on the events it deigned to map.

mapped event (frame learns) exposed, not mapped (no learning — still judged) survival EMA (what the scorer sees) true error over all events

The update, exactly
fit = ‖recon − obs‖ / (‖obs‖ + 1e-6)
recon_err_ema ← ema_decay·recon_err_ema + (1 − ema_decay)·fit     ← on EVERY exposed event
if fit < fit_gate:  frame maps → contributes pose, learns          ← "sparsity by pull"

This split — sparse learning, total judgment — is the entire reason dimensionality selection works. A cheating frame narrows its gate, learns a tiny comfortable niche, and reports a beautiful score while explaining almost nothing. The coverage-fair EMA makes that strategy fatal instead of dominant.

The price of a dimension VALIDATED

Parsimony is not a truth the system discovers. It's a price it pays.

Honest error keeps creeping down as you add dimensions — past the world's true size and onward, forever, via overfit. "Lowest error wins" would over-dimension without limit. So the scorer charges rent: w_complexity · dim. The winner is the frame at the start of the diminishing-returns plateau — the point where one more dimension stops paying for itself. The error bars below are real, from frames of every size trained live on a world with 4 hidden knobs. Drag the price and watch the winner move: at zero the raw-error minimum wanders into the overfit plateau; too dear collapses everything toward one knob. And notice the winner usually settles at 3, not 4 — the fourth knob doesn't pay its rent at this budget. The real system does the same at scale (it lands at median dim 9–10 on worlds of "true" size 20–50): the price doesn't discover truth, it buys value.

step 0 winner
measured error EMA (live) + dimension rent lowest total = survivor
The survival score
survival_score = w_explain·recon_err_ema + w_predict·pred_err_ema
               + w_effort·effort_ema + w_complexity·dim        (lower = better)

At scale the error curve has no knee at all — it just keeps falling to the capacity ceiling. So the penalty isn't detecting the world's true size; selection simply keeps buying dimensions while the marginal error-gain exceeds the price, and stops there. The ecology lands at the price-optimal operating point — stably, at every scale measured.

A head full of rival guessers VALIDATED

Evolution inside one head, on a timescale of minutes.

Nobody tells PRA how many dimensions its frames should have. Instead: if no frame can map an observation, a new frame is born on demand. Every consolidation cycle, new candidates spawn near the best frame's dimensionality (copy, never mutate — a bad idea just fails to earn its place). The young get a protection window; the mature face a survival bar that tightens as the population grows — crowding raises the pressure, so the head stays lean without a hand on the dial. Below, a real population of real frames learning a true-dim-3 world, from empty.

cycle 0 pop 0 best dim births 0 evictions 0
best dim population survival threshold (falls as pop grows)
The slow loop, in order
each consolidation cycle:
  1. age everyone; candidates mature at age ≥ min_age_cycles
  2. apply pending anatomy changes
  3. evict: threshold = base / (1 + coeff · max(0, pop − baseline))   ← falls with crowding
     remove unprotected frames scoring above it, worst first (never below min_frames)
     hard cap: still too many → cull worst to max_frames
  4. spawn candidates: dim = best_dim ± 1 (mostly), sometimes explore
  5. snapshot

Note the division: crowding tightens the tolerated-error bar. A bar that loosened instead would let eviction vanish and the population slam into the hard cap. And this is the system's whole memory story — it keeps running structure, not stored episodes. No scrapbook required.

Wanting things DESIGNEDOPEN EDGES

The one thing the system can never rewrite is its own wanting.

Action needs a direction, and direction needs a fixed notion of "better": the innate drive, a pure function from recent experience to a scalar value signal. The corridor below has three territories: a mastered zone (nothing left to learn), a learnable zone (structure the agent can still crack), and a noisy TV (pure static — unlearnable, forever novel). The agent picks actions by one-step lookahead on its drive. Switch drives and watch where it spends its life. Novelty alone walks straight into the TV and stays there; learning-progress ignores what it has mastered and what it can never master.

time spent (occupancy) current prediction error per cell

The drives, exactly
curiosity  = w_progress·LP + w_novelty·novelty
  LP        = max(0, mean(older errors) − mean(recent errors))   ← rewards error going DOWN
  novelty   = unfamiliarity vs a bounded memory of recent observations
competence = mastery + familiarity
  mastery   = max(0, 1 − mean(recent prediction error))
  familiarity = 1 − novelty

The anti-noise-trap property: on static, error is high but flat, so LP ≈ 0. On mastered ground, error is low and flat — LP ≈ 0 again. Only a live learning frontier scores. Honesty note from the measurements: at scale, novelty-directed curiosity performed worse than random (−0.062); the inverted preference — competence — is what beat it (+0.067). The perfect drive is still an open problem, and PRA says so out loud.

Turning down the static OPT-IN

Real sensors lie. Some channels carry the world; some carry snow.

Feed half the sensors pure static and structure-finding collapses: the noise floor drowns the score's gradient, static corrupts the shared encoder, and no frame ever clears the survival bar. The fix is a learning-free whiteness estimator: static is white — a fresh draw every step — while real channels carry the world's temporally-correlated dynamics. Per channel, track the lag-1 autocorrelation ρ̂; weight channels by it; apply the same weights to judging and learning (the judge and the learner must never disagree). Channels never go fully silent — the floor keeps every channel minimally audible, in case it starts carrying the world tomorrow.

ρ̂ (lag-1 autocorrelation) weight w channels 1–6 carry the world · channels 7–8 are static
frame judged without weighting — the noise floor holds it above the bar identical frame with weighting — clears the bar and can mature
The estimator (five arrays, zero learning)
per step:  m ← β·m + (1−β)·obs;  d = obs − m
           v ← β·v + (1−β)·d²
           cov ← β·cov + (1−β)·d·(prev_obs − m)
recompute: ρ̂ = clip(cov/(v+1e-6), 0, 1)
           w  = clip(ρ̂ / max(ρ̂), floor, 1)      (unready channels stay at 1)
apply:     judging  → ‖(recon − obs)⊙w‖ / (‖obs⊙w‖ + 1e-6)
           learning → encoder sees w⊙obs; placement backprops (recon − obs)⊙w

The transport argument: weighting unit static at 0.2 makes every computation operation-for-operation equivalent to running at static amplitude 0.2 — an operating point already measured as a clean PASS. The remedy doesn't hope; it transports the system into a regime known to work. Off means off: floor = 0 → byte-identical pinned behavior, zero extra float work. (Demo uses a faster β than the shipping 0.995 so you don't wait 200 steps.)

Pausing, not remembering VALIDATED

A brain you can switch off is only trustworthy if switching it back on changes nothing.

The entire evolving state — every frame's tensors, drive bookkeeping, counters, the random number generator itself — serializes to a versioned blob. The guarantee is byte-identical resume: a run resumed from any snapshot is bit-for-bit the same as the run that never stopped. Not "approximately the same brain." The same brain. Prove it to yourself:

idle

This runs a live ecology for 300 steps, snapshots at step 150, runs to the end, then restores the snapshot and re-runs the second half. The two traces are hashed and compared.