CRUMB a card from devarno-cloud

Drift Check Cadence and Verdict

petrova intermediate 5 min read

ELI5

A drift check is the architectural smoke alarm. When the room smells weird but you can’t see the fire, you point the alarm at the room — it sniffs the rank graph and the anti-shape list and tells you whether the smell is benign, suspicious, or confirmed smoke.

Technical Deep Dive

Cadence — when to invoke

sequenceDiagram
autonumber
participant H as Human
participant DW as drift-watcher (04-drift-check)
participant NS as docs/north-star/intent.md
participant M as MILESTONES.md
participant P as Planner
participant B as docs/backlog/frozen/
Note over H: trigger: PR / new milestone / new doc / a feeling
H->>DW: paste 04-drift-check.md, name the surface
alt human gave a feeling, not a surface
DW->>H: "what's the most recent thing that made it feel off?"
H-->>DW: walks back to a concrete artefact
end
DW->>NS: read intent.md, outranks: front-matter, drift_watches:
DW->>DW: build implied rank DAG
DW->>DW: identify which docs the change touches, rank inversion?
DW->>NS: walk drift_watches: per anti-shape — pull observed? counter-anchor?
DW->>M: cross-ref active phase / subphase
DW->>DW: verdict: aligned | drift-suspected | drift-confirmed
DW->>H: write docs/roles/auditor/outputs/drift-<DATE>-<slug>.md
alt aligned
DW-->>H: proceed
else drift-suspected
DW-->>H: human is the tiebreaker
else drift-confirmed
DW->>P: route for re-scope
DW->>B: or file in backlog/frozen/
end

Three triggers commonly fire 04-drift-check.md:

  • A specific PR or proposed diff that doesn’t quite serve intent.
  • A new milestone being scoped that pulls toward a named anti-shape.
  • A doc that just landed and contradicts another.

The fourth — “a feeling I have I can’t articulate” — is legitimate. Step 1 of the prompt makes it concrete by walking back from “what’s the most recent thing that made it feel off?” until a file/commit/milestone-ID is named.

The five-step probe

  1. Get specific about the change (file path, milestone ID, commit, conversation excerpt).
  2. Read the rank graph — every doc’s outranks: front-matter; build the implied DAG; identify which tiers the change touches and whether it inverts rank.
  3. Walk the drift watches — per anti-shape in docs/north-star/intent.md, ask: pull observed? counter-anchor? was it exercised?
  4. Cross-reference active milestones — does the change belong to active subphase, future phase (defer), or no milestone (backlog or scope creep)?
  5. Produce the verdict at docs/roles/auditor/outputs/drift-<TODAY_ISO>-<slug>.md.

Three verdicts

VerdictMeaningRouting
alignedserves intent + active phase, no counter-anchor needed beyond what’s exercisedproceed
drift-suspectedpull observed but unclear if counter-anchoredsurface to human — the human is the tiebreaker; both aligned and drift-confirmed are easy, suspected is exactly when the human earns their seat
drift-confirmedinverts a rank, pulls toward an unanchored anti-shape, or doesn’t belong to any milestoneroute to planner for re-scope, or file in docs/backlog/frozen/

Indeterminacy is not a verdict. If the agent tries to refuse a verdict (because the change is genuinely architecturally novel), force drift-suspected and route to the human.

Active-milestone alignment

Step 4 produces three sub-verdicts:

  • belongs to active milestone → aligned (assuming Step 3 cleared).
  • belongs-future-phase → not drift, but should be deferred until that phase opens; surface this.
  • scope-creep → doesn’t belong to any milestone; either backlog (frozen) or you’ve found drift.

The distinction between belongs-future-phase and scope-creep is load-bearing: future-phase items have a home; scope-creep items don’t, and trying to land them under the active phase is the most common drift pattern.

Refusal condition

The drift-watcher (AGENTS.xml.tmpl) has one refusal: the change touches surfaces in >3 phases at once. Stop and ask the planner to decompose. Cross-phase changes are how anti-shapes win silently.

When the same anti-shape keeps drifting

A repeated drift-confirmed against the same anti-shape means the anti-shape is winning. That’s a north-star revisit (potentially an MR-1 realignment), not a drift-watcher problem. Schedule the revisit; don’t keep refusing changes — eventually the team works around the watcher and the anti-shape wins anyway.

Key Terms

  • Rank graph inversion — when a lower-tier doc (e.g. backlog) implicitly modifies a higher-tier doc (e.g. north-star). Always drift-confirmed.
  • Counter-anchor — the code/process/doc that catches a named drift pull; without one, the pull is unanchored and drift-confirmed.
  • drift-suspected — the verdict where the human, not the agent, is the right tiebreaker.

Q&A

Q: What three verdicts can a drift check return, and which is the human’s tiebreaker? A: aligned, drift-suspected, drift-confirmed. drift-suspected is the human’s tiebreaker — aligned says proceed, drift-confirmed says stop, but suspected means the agent saw a pull and could not decide; the human resolves.

Q: Where does the drift-watcher write its verdict? A: docs/roles/auditor/outputs/drift-<TODAY_ISO>-<slug>.md. Note: under the auditor’s outputs path, not the planner’s — the drift-watcher reports findings; the planner re-scopes.

Q: How is ‘belongs-future-phase’ different from ‘scope-creep’? A: A future-phase item has a milestone home (it just hasn’t opened yet) — defer it; it isn’t drift. A scope-creep item belongs to no milestone — it either gets a backlog entry under docs/backlog/frozen/ or it gets refused. Trying to absorb scope-creep into the active phase is how anti-shapes silently win.

Examples

A PR adds a “user analytics dashboard” to KAHN. Drift-watcher Step 1 makes it concrete (PR #143). Step 2 finds the change touches frontend/, MILESTONES.md (no entry exists), and tries to import a metrics service from outside the active phase. Step 3 walks drift_watches: — finds a clear pull toward “treating KAHN as a CRUD product instead of an event log” with no counter-anchor exercised. Step 4 → scope-creep. Verdict: drift-confirmed. Recommended action: file in docs/backlog/frozen/user-analytics-dashboard.md with a link back to north-star intent.

neighbors on the map