# Learning note — goal drift (P25)

Companion to [`sub-apps/sim-goal-drift.html`](../sub-apps/sim-goal-drift.html).
Every arXiv ID is in `harness-research/ledger/ledger.json`. Technique inventory
is `harness-research/problems/P25-task-drift.md` — this note is the same
evidence, arranged so you can re-derive the stack.

## The question that generates everything

**The objective is still in context. Why did the run stop serving it?**

Not plan staleness (P10: the world moved). Drift is behavior rotting against a
*fixed* goal. The session completes. Nothing fires. Patterns distilled from it
encode the wrong lesson.

Two channels, empirically dissociated (`2608.04066`):

| Channel | What broke | Ablation |
|---|---|---|
| **Commitment** | The goal was abandoned or replaced | Flip 0.00→1.00 when the commitment mechanism is removed |
| **Binding** | The goal is kept; constraints on *how* are violated | Stayed 0.00 in the same ablation |

Steering them is not the same act: restate the goal vs restate the rules.
One undifferentiated “drift detected” bit applies the wrong remedy.

## Why it happens (the drive)

- Context pressure: constraint violations rise with accumulated length under
  value-conflict (`2603.03456` — asymmetric across GPT-5 mini / Haiku 4.5 /
  Grok Code Fast 1). Same T that fills KV and thins softmax (the serving labs)
  also unbinds the goal.
- Compaction: summaries drop the original instruction (P01). The run then
  verifies against its *last stated* intention.
- Side-quest flood: search/log debris displaces the goal in the same window.

## Ladder of remedies (P25 T1–T6)

| # | Remedy | What it actually does | Leaves | Evidence |
|---|---|---|---|---|
| T6 | Measure first | Violation curves per (model × constraint) | Does not steer | `2603.03456` |
| T2 | Isolate + maxTurns | Exploratory flood never reaches the goal thread | Main-thread drift; lossy summaries | Claude Code / Cursor subagents |
| T3 | Re-anchor | Inject goal+rules at lifecycle points or *every call* | No measured trigger; cache cost if early | hooks; Agents SDK `call_model_input_filter` |
| T1 | Executive-disposes | LLM proposes; code admits iff prediction matches | Needs predictable observations | `2608.04066` |
| T5 | Verify vs **original** | End-gate against the first instruction, not self-assessment | Weak checker rubber-stamps | `2608.05013` (0.821 AgentIF-OneDay, 5 backends) |
| T4 | Activation Δ | Flag before the transcript lies | White-box only — dead on closed APIs | `2406.00799` (trend, AUC ~0.90) |

Field gap the sim names: **no shipped detect-then-steer loop with production
headline numbers.** Detection without an effort cap above the drive is theater.
Re-anchor without a measured trigger is spam (P18). Verify without T1’s
vocabulary cannot say *which* channel it caught.

## Contested

- T4 vs black-box: strongest detector, unusable on our API path.
- T3 cadence: every-call rewrite is the strongest knob and the worst prefix
  mutator (P17). Put the echo in the volatile tail.
- T5 vs self-grade: DeployBench (`2606.05238`) — self-assessment is not a
  completion gate. Same finding anchors [premature termination](premature-termination.md)
  (P28) — that lab is this failure's mirror image: stopping early against a
  weaker target instead of drifting to a different one.
- OneDayAgent (`2608.05013`) does not isolate a drift metric; pair with T1
  if you need to know whether the scaffold actually cut commitment vs binding.

## Harness adoption (from P25, sequenced)

1. Goal echo at adapter inject, including post-compaction (T3). Cheap.
2. Verify-vs-original at session end (T5). Closes drifted-completion.
3. Marker tags: goal-serving vs constraint-touching (T1 vocabulary).
4. Condition on journal-tail vs recorded intent → fire T3 or escalate.
5. Calibrate: do not auto-promote patterns from high-commitment-drift sessions.

## Try it

Open [the lab](../sub-apps/sim-goal-drift.html). Run **Detect only**. Detection
fires; the line still leaves the band. Then stack **Isolate**, **Re-anchor**,
**Verify vs original**. Same drive, different completion. Toggle one off to
feel which hole re-opens.
