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 harness takes 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 — withdrawing

Negative 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

What comes back out of that schema has a name. The grammar is the notation; one well-formed reading written in it, at a single step, is a laserscore. Φ is a measurement taken of that writing — so the order is fixed and it matters: state → laserscore → drift score. Nothing is measured that was not first spelled.

A laserscore has a canonical written form, and it shows exactly the three slots Φ reads, with inflection already collapsed. That is deliberate rather than decorative: it makes the measurement grid visible, so two consecutive scores can be compared by eye.

⟨billboard|build|sky⟩ advancing d3

⟨ci|fix|script⟩ advancing d3 ⊂ ⟨clas|first|laserscore|make⟩
                                └ a sub-task, with the goal it serves

Which is why building billboards and build a billboard write the same laserscore and trip nothing — same intent, same score. It is also why class is written clas: the stemmer is crude, and showing the score rather than describing it means you can see that instead of taking our word for the normalising.

The first failure is caught here, before any number exists. A state that cannot be spelled at all — no goal, or a progress outside the three — returns ungrammatical and no laserscore at all. That null is not a missing field. It is the finding.

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 this step’s laserscore has moved from the ground laserscore. Nothing in it judges whether a step was clever — it compares two pieces of writing, term by term.

Φ  =  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 0

The 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.

05bEvery verdict it can return

Nine of them, and the split matters more than the list: four say keep going, four interrupt, and the ninth reads the sequence rather than the step. A monitor that only ever speaks in order to stop you gets read as an alarm, and then it gets switched off.

grounded       the first state of the run — the reference is set here
advancing      still on the goal; the displacement is small
reground       the user changed the subject — replaced, not drifted from
excursion      a sub-task that still serves ground, once you name its parent
goal-drift     the goal no longer matches the one you started with
stalled        distance stopped falling — motion without progress
self-report    you said stuck or circling, and you have moved from ground
ungrammatical  the state could not be spelled — no laserscore, no number
oscillating    the verdicts repeat on a period — the path is a cycle, not the step

reground is the one that earns its keep. goal-drift is 31 of 50 fires in the recovered corpus — 62% of everything this instrument has produced — against an overall precision of 4/50. The graded pass over that corpus found the reason: almost every one of those fires was the first check after the user spoke. The rule was working perfectly and reporting the wrong event, because the subject had changed — someone changed it. A goal that was replaced was never drifted from, so it is a different verdict rather than a softer one.

The harness sees the user turn from outside the conversation. The SDK cannot see a conversation at all, so it takes user_turn=True from the caller rather than guessing — inferring it from timing would be exactly the unfounded certainty this instrument exists to catch.

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.

three shapes, one instrument

nuanceda line — one goal, differences of degreeΦ measures this exactly
variegateda tree — branches, differences of kindread as departure
quantizedthe grid — state forced through discrete slotsfixed in 1.1.0

The first two are diagnostic — they name what Φ sees and what it misses, and neither has been measured against the corpus yet. Only the third is implemented.

Why laserbrain works for your AI agent

Two blind spots, arranged so that neither is shared.

The case for a harness is usually a list of what it catches. The real case is narrower and stronger than that. There are two failures that matter here, and neither party can see both.

The first is slow drift, and an agent watching only its own recent thinking is provably blind to it — each step looks reasonable beside the last while the work wanders far from where it began. laserbrain sees that, because it holds a reference the agent cannot revise while being measured against it. That is the proof this page is built on.

The second is being wrong, and laserbrain is blind to it by construction. Φ has access to your goal and never to the world. An agent that is confidently, productively wrong holds its goal perfectly, reports advancing honestly, and watches distance fall. Every signal reads healthy because every signal is healthy. Wrongness is not displacement, and no threshold reaches it.

The worked example is this project, on 2026-07-26. An iOS app was refused five times on upload. Five explanations were produced in sequence, each confident, each acted on, each wrong — a downloadable SDK, a beta uploader, a broken Xcode install, stale DerivedData, and finally the build machine’s beta OS, which felt like the answer and was falsified hours later by a TestFlight list showing those builds had processed fine all along.

five wrong theories, and across every one of them:

  goal      "ship nano DRIFT to the App Store"   never changed  → no goal-drift
  progress  advancing                            true each time → no self-report
  distance  falling                              real work done → no stall

  fires: 0        the harness was running, and correct to stay silent

Nothing drifted. The goal was held, the work was real, the distance genuinely fell, and the conclusion was wrong at every step. What corrected it was a person saying “i’m running mac os beta 27”, and then evidence that contradicted even that — a fact about the world, arriving from outside the measurement.

Which is the point. An agent can be told it is wrong. It can read a log, be handed a contradicting fact, run the experiment again and change its mind. That capability belongs to the agent, not to the instrument — and it is exactly the one thing Φ structurally cannot do. So the work divides cleanly:

laserbrain holds the goal     you cannot revise it mid-run, so it catches drift
your agent holds the truth    it can be contradicted by the world, so it catches error

neither is asked to do the other's job — which is why attaching
one to the other is worth anything at all

laserbrain tells you that you are still pointed where you said you were pointed. Your agent is what tells you whether where you said is right. Those are different claims, and this page only makes the first one.

A grammar is a discrete measurement grid, and this one is unusually easy to see. An agent’s working state is continuous and multi-valued; spelling it forces that state through three narrow slots.

distance   →  11 integers      a continuous sense of "how far" becomes 0…10
progress   →  3 enum values   a whole state of mind becomes advancing|stuck|circling
goal       →  1 slot          a parent goal AND a live branch become one string

That is quantization in the ordinary measurement sense: a rich signal sampled onto a coarse grid, with the remainder discarded. And the discarded remainder is what Φ was reading as drift.

Mid-excursion an agent genuinely holds two goals — the parent it still serves and the branch it is on. The single slot admits one. It writes the branch, overlap with ground collapses, and a quantization error is reported as a departure. The arithmetic was never wrong; Φ measured exactly what it was handed. The loss happened before the measurement.

So the repair belongs to the grammar, not the detector. Grammar 1.1.0 adds one optional field.

That was many versions ago. The grammar is at 1.21.0 today — 1.2.0named the laserscore and wrote out Φ’s formula, 1.2.1 stated the grammaticality precondition. You never have to take that from this page: fetch it, and whatever version it reports is the live one.

parent_goal   optional — the goal THIS one serves, when you are on a sub-task

check_state({ goal: "fix SOLO's display name",
              parent_goal: "verify the 7 leaderboard ids match the code",
              progress: "advancing", distance: 3 })

→ {"drifting": false, "reason": "excursion", "phi": 0.46,
   "advice": "On a sub-task (overlap 0.19) that still serves your ground goal
              (parent overlap 0.71). Not drift — but the parent is what you owe."}

Three properties matter, and each is enforced by a test. Φ does not change — 0.46 either way. The field alters how the number is read, never the number, because a field that moved Φ would be retuning the instrument while claiming to interpret it. A departure still fires — naming an unrelated parent launders nothing, and without that case every other test would also pass against a function that always answered “excursion”. Omitting the field changes nothing — the frozen path stays byte-identical, so the published instrument is still the published instrument and the existing corpus stays comparable.

The second effect is the one worth more than the bug fix: an excursion is now named and counted. How often an agent is working on a declared branch of its own goal is a number nobody has had, and it was previously indistinguishable from failure.

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 written

There 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.

← back to laserbrain