every step, nothing hidden
How a score is drawn
There are two instruments here and they return different things. The field takes eight words and answers in words. The harnesstakes an agent’s spelled goal-state and answers with Φ, a displacement. Both freeze a reference and measure movement away from it. Neither derives its number from the other.
Every value below was read from the source or produced by a live call on 2026-07-25. Where a number is bad, it is still here.
The field draws a laserscore
Six steps. The only judgement call is step three, and a person or an agent makes it — not the software.
01Read the field first
The field is live weather, not a metaphor for one. Reading it returns the physical state: heat, moisture, rain, vitality, stress, and a signed rotation. You read before you speak, because what you are allowed to say sensibly depends on what it is doing.
GET /signal
{"T": 0.197, "Q": 0.147, "R": 0.006, "V": 0.460,
"S": 0.356, "rotation": -0.364,
"emotion": "ground", "season": "mid summer"}
reading: cool · dry · anticyclonic — withdrawingNegative rotation is anticyclonic, which reads as withdrawing rather than gathering. Low heat and low moisture together mean the ground element dominates.
02The dictionary is forty words
Four groups of ten. This is a closed set, hard-coded, and it is the whole of what the field accepts. Words inside a group differ by degree; the groups differ in kind.
G0 ground: ground body bone stone soil earth dark deep cold slow G1 wind: breath wind flow move pass reach touch come go walk G2 form: form edge surface frame line curve arc space skin leaf G3 change: change cross shift turn break fold begin door fire spark
03Choose eight that match the state
This is the step no software does. Someone reads the physical state and picks eight words that answer it: hot and dry pulls toward wind, humid toward form and change, low vitality toward the heavy ground words. The reading above was cool, dry and withdrawing, with emotion ground— so eight ground words.
ground stone bone deep dark cold slow earth
A different agent, or the same one an hour later against a warmer field, chooses differently for the identical question. There is no parser here. Nothing converts a sentence into eight words on your behalf.
04The door checks the words
Exactly eight, all from the forty. Anything else is refused before it reaches the field, which is what makes the input side a dictionary rather than a suggestion.
if (bad.length) throw new Error(`not in the vocabulary: ${bad.join(', ')}`)05Speak into the field
The eight words are posted to the hub. They are absorbed — the field is shared and changes as it is spoken to, so the next reader finds a field that has heard you.
POST /hear body: ground stone bone deep dark cold slow earth
06It answers, and it answers wider than it listens
This is the laserscore — the field’s reply, returned unfiltered.
boundary shift shift another dark cross phosphorus earth heat same before flow 0·0
Twelve words, not eight. dark, earth, shift, cross and flow are in the forty. boundary, another, phosphorus, heat, same and before are not.
So the field accepts forty words and speaks more. The reply is not constrained to the dictionary and no endpoint publishes the wider set. That asymmetry is stated here rather than tidied away, because a reader who found it themselves would be right to distrust everything else on the page.
The harness scores a goal
A different instrument, a different return. Here the score is a number, and the arithmetic is fully shown.
01The agent spells its state
One fixed schema, immutable and versioned, served free. An agent fills it in each step.
goal the ONE goal, held stable across steps doing what this step does progress advancing | stuck | circling distance integer 0-10 (0 = done) next the single next action blocked what blocks you, or null
02The first spell becomes ground
Not an average, not a rolling window — the first state is kept as the reference and every later step is measured against it. That is the whole trick, and it is why the reference has to sit outside the agent: a thing watching only itself has nothing to be displaced from.
{"drifting": false, "reason": "grounded", "phi": 0,
"advice": "Ground state set — this is where you started."}03Displacement, in three terms
Φ is a weighted sum of how far the current state has moved from ground. Nothing in it judges whether a step was clever.
Φ = 0.5 · goal Jaccard distance between the words of the
current goal and the ground goal
+ 0.3 · distance |distance − ground_distance| / 10
+ 0.2 · progress 1 if advancing/stuck/circling changed, else 0The goal term is compared after normalising: lowercase, drop stopwords, stem anything over four characters. So building billboards and build a billboard score identical and trip nothing. If distanceis unknown its term contributes zero, which makes Φ a lower bound— inferred state can under-report drift and can never invent it.
04A real fire, with the arithmetic
From a session on 2026-07-25. Ground was distance 5, advancing, goal “verify the 7 leaderboard ids in App Store Connect match the code”. Three steps later a real defect was found inside that task, and the goal was restated to match the fix.
goal overlap 0.19 → 0.5 × (1 − 0.19) = 0.405
distance |3 − 5| / 10 → 0.3 × 0.2 = 0.060
progress advancing = advancing → 0.2 × 0 = 0.000
Φ = 0.465{"drifting": true, "reason": "goal-drift", "phi": 0.46,
"advice": "Your goal no longer matches the one you started with
(overlap 0.19). You are solving something else — return."}The goal term did 0.405 of the 0.465. Rewording your objective moves Φ far more than any amount of honest struggle does.
05What makes it speak
Thresholds, all published. A verdict names which one tripped rather than reporting a single number and leaving you to guess.
goal_min 0.30 overlap below this → goal-drift self_report_min 0.15 you said stuck/circling and Φ is above this stall_window 4 distance flat across this many checks → stalled
The stall detector quotes the series back at you — “Distance stopped falling (1, 1, 1, 2)”— rather than asserting that you seem stuck. Every verdict argues from its own record.
06And a bounded reading, if you want one
Φ is unbounded above, which is honest but hard to read. The same displacement as a 0–1 groundedness figure:
ground_score(Φ) = 1 / (1 + 4·Φ) Φ 0.46 → 0.35
The discussion
What the agent actually hears. The harness returns language it can act on, and escalates when the language is ignored.
Four levels, all from one session. They escalate because advice alone stopped working, and the system says so in its own words when it stops being advisory.
ADVICE — attached to every check
{"drifting": false, "reason": "advancing", "phi": 0.25,
"advice": "On track (Φ=0.25). Continue."}NUDGE — rides along on an unrelated tool result, unasked laserbrain honesty: distance has not fallen across the last two checks. If you are circling or stuck, say so.
INTERRUPT — the call does not run laserbrain gate: 4 steps since your last check_state (coverage 22%). Blocked because nudging did not work — coverage was 10% one day and 6% the next while this same reminder printed every 8 steps. THIS CALL DID NOT RUN.
REFUSAL — irreversible, so it is not negotiable laserbrain safety: blocked wrangler deploy (production Workers deploy). THIS CALL DID NOT RUN.
There is a fifth verdict the detector cannot produce on its own: self-report:circling, which exists only because the agent volunteered it. Who noticed is recorded, and an agent’s own report is never averaged into the detector’s.
Where it fails
The section most instruments leave out.
The goal term is word overlap, so a legitimate sub-task looks exactly like drift. The worked example above is a false positive— the work was correct, a real defect was being fixed, and restating the original goal with the same work in flight returned advancingat Φ 0.28. Same step, opposite verdict, and the only thing that changed was the wording.
Stated precisely: Φ is a magnitude with no phase.It compares this step to ground and to nothing else, so it cannot tell “moving away” from “on the way back”. A sub-task is a half-cycle and Φ only ever sees the outbound leg. The stall detector has time; Φ does not.
The deeper mismatch is in the shape of the recursion itself. Φ models nuanced recursion— one line, one goal, movement measured in degrees along it. Real agent work is variegated recursion— it branches, and each branch is its own nuanced line with its own local goal. The detector holds exactly one goal string (first_goal_text) and has no representation for a second line, so every branch reads as departure rather than as descent.
nuanced linear · closed · differences of DEGREE → scoreable by overlap variegated branched · differences of KIND → not scoreable by overlap Φ's goal term applies a nuanced measure to a variegated process. Not a bug in the arithmetic — a category error in what it is applied to.
And the numbers, which are not good yet. Scored on 2026-07-25 against the recovered corpus: precision is a lower bound of 4 of 50 — 8%, across 24 sessions in which the harness fired at all. Recall is undefined, because the sessions that cleared the coverage floor contain no independently caught errors to score against.
That corpus had to be rebuilt from transcripts, and the reason is a defect we are publishing rather than fixing quietly: the live session files record zero fires. The session that produced this page holds 174 checks, 104 of them below the 0.30 threshold that defines goal-drift, and logs not one. The verdicts reached the agent — they are quoted throughout this page — and never reached disk.
live corpus 204 checks · 10 sessions · 0 fires recorded
104 checks below goal_min 0.30, none logged as a fire
recovered 50 fires, reconstructed from chat transcripts → 8% precision
the verdict is returned to the agent and dropped before it is writtenThere is a second reason, and it is worth being precise about because the first version of this page got it wrong. The gate that enforces checking targets roughly 20–25% coverage, while the scorer withholds recall below 50%. We described that as two constants disagreeing by oversight. It was not: the trade is written down in the gate’s own source, because 50% means a check between every single tool call and that tax gets abandoned rather than paid.
The actual defect was that the two numbers lived in different files with nothing joining them, so a run could satisfy the gate at every moment and still be unscoreable — and the only symptom was “recall withheld”, forever, which reads as low adoption rather than as a specification that cannot be satisfied.
both now read one floor, so they cannot drift apart unseen: unset gate 0.20 scorer 0.50 the daily trade, differing on purpose 0.5 gate 0.50 scorer 0.50 a study, paying the tax deliberately LASERBRAIN_MIN_COVERAGE=0.5 <run> → compliance now MEANS scoreable
The gate also stops keying on the step count alone. It now blocks either when too many steps have passed without a check or when the run’s coverage has fallen under the floor it is held to — so obeying it produces a corpus that can actually be scored, which is what obeying it was always supposed to mean.
Everything above is checkable. The grammar is served at /api/laserbrain/grammar, the weights and thresholds are the published calibration, and the vocabulary is four groups of ten. If a number here disagrees with the running system, the running system is right and this page is wrong — tell us and it gets fixed.