The enemy of agent-driven work is drift. The cure is an anchor — a fixed reference the work must keep satisfying so it can’t wander — installed as strong as your current grounding allows, and upgraded toward a hard gate as grounding crystallizes. The process is the skill; the transpiler, the gate, NNUE, the jira board are tools inside it.
Links: Transpilation as a Grounding Strategy, The LLM Grounding Problem, Principled LLM Code, Praxis: Agent Teams, AI History — A Personal Arc · case studies: na1-decompiler (proof-driven), pygone (exploratory)
Process is not an exact science. This is a living playbook of warning signs and moves the director uses judgment on — not a checklist. It accretes: every project adds signs. Born from the NA1 decompiler (where it was discovered, not designed) and stress-tested against the projects that drifted (camelot→DJ, monopoly, MOO1).
The defining move is the self-validating gate — every change is automatically proven against a reference before it’s kept, and falls back to a safe form if it can’t be. NA1’s gate: lower(structured C) == bytecode CFG on all 495 subs, or the fold reverts to an honest goto.
The gate is usually framed as “proves correctness.” That undersells it. The gate proves grounding — it is how you know the work is faithful and not plausible-but-wrong — and because it pins every change to a fixed reference, it makes drift structurally impossible. NA1 never wandered because the gate wouldn’t let it. The projects that hurt had no anchor.
→ Without a gate you are not “moving faster,” you are drifting and won’t find out until later.
Projects often start “ohh this is neat” — not because they’re unserious, but because you aren’t grounded in what the thing is yet. Exploration grounds the operator (the grounding gradient applies to you reading an unfamiliar project, exactly as it applies to an LLM reading bytecode). NA1 ran the arc: understand the mechanics → it’s bytecode → it’s a VM → build the decompiler → install the CFG gate. The gate couldn’t exist at the start; there was nothing identified to gate against yet.
The transition trigger — install the gate the instant you can name a ground truth + a cheap deterministic check against it. Before that, keep exploring (you’re still grounding yourself) but install the strongest anchor available now: a north-star statement + a decision log + the built-tools registry.
Director / workers / QA / logs / “jira boards.” This isn’t bureaucracy — it’s context management: small focused worker contexts, the director holding the thread, QA bound to the gate. It exists to kill sprawl — the agent wandering off and coming back empty. (Decision-class hierarchy: Praxis: Agent Teams — director handles the harder class, workers the line.)
A correctness gate proves each increment is sound. It says nothing about whether the increment-grind is still the right move. You can grind correct atoms forever while a wrong founding assumption silently caps the whole thing. So the director runs a standing meta-check:
Warning signs of spinning (heuristic — expect to find more):
The recalibration move — NOT tweaks (they get overrun). Escalate from worker-grind (“invert the next case”) to director-rethink (“what assumption builds this wall — the gate? the IR? a missing tool?”), then run a tournament of genuinely divergent approaches — 1 approach vs another, e.g. address-based gate vs. a different IR — not variations on one theme (the _COMBOS grid was variations; it can’t escape a wall baked into the theme). The gate judges the winner. When reactive discovery won’t close the set, enumerate the table forward instead (the lowering-atlas move). Output is one of: a new tool, a dropped assumption, or an explicit “this wall is acceptable — log it, move on.”
Check the set is real — name the dual. For each candidate, name the one component it changes (discovery loop / reducer / emitter / gate’s equivalence relation / IR). If they all name the same one, you have variations — go find the dual: the component every attempt has avoided. NA1’s blind spot was loud once asked this way — every fix changed the emit to satisfy an address-based gate; nobody changed the gate to stop caring about address order (a reorder-invariant equivalence relation — and it’s cheaper than the emitter rearchitecture).
Tool or approach? Don’t let the incumbent eat the rival. The dominant approach has gravity — it doesn’t reject a new idea, it assimilates it, reducing a different way of knowing into “another input for the way you already work.” The tell is in how the idea gets described: “now we have N new tests to run” = swallowed into a tool (more answers to the current question), vs “now I can derive the class without testing” = a real approach (it changes the question / what’s derivable). It happens because the incumbent owns the scoreboard — a deductive rival (“read the compiler, know the lowering, invert the mechanism”) pays off slowly, so judged by the incumbent’s short metric (goto-delta-this-session) it always loses to the next quick empirical clue → “nahh,” or demoted to a clue-generator. A tournament isn’t fair if the incumbent sets the win condition and the horizon. So: classify on arrival (tool vs approach); give an approach its own track, metric, and horizon; fund the understanding (deductive approaches need runway the toy-loop won’t pay); and treat clue-collecting as a symptom — to invert something, learn how it works and invert that; gathering empirical output-clues is a confession you haven’t learned the mechanism yet (NA1: “compile C and observe the CFG” was the empirical crutch; “read GCC’s CFG-construction passes and know the forward map” is the rival that kept getting eaten).
The director isn’t a hero. The point of the standing check is that good direction doesn’t depend on a person staying vigilant — the agent can run this meta-check for you (this playbook was validated by running it on NA1, which surfaced the gate blind spot no amount of willpower had). The human’s job is to notice the flag and choose the move, not to out-discipline drift unaided.
Run the playbook on NA1 right now: does it fire the recalibration NA1 has been missing — “you’ve hit the address-based gate N times; stop adding atoms, run address-gate vs. new-IR as a divergent tournament”? A method that can’t diagnose its own birthplace is just prose. (Secondary: the next “ohh this is neat” project kicks off anchored and doesn’t sprawl.)