Spec · v1 draft · for red-pen

plato prime

Make Plato the reflex. Today it waits to be asked — and the demand experiment proved that’s the whole bottleneck: when an agent reaches for Plato it wins decisively (47/47 vs a grep’s 30/47); when it doesn’t, Plato may as well not exist. prime flips pull→push: the moment an agent starts work in a repo, Plato injects a short, current orientation — the map, the load-bearing spots, any lying gate, and where it’s blind — without the agent deciding to ask.

Draft for Robert’s annotation · graded-review folded · not approved · no building yet
01

What I decided — and why

The shape of the build. The five calls that are yours are in §09.

Scope
A thin shell, not new analysis
prime composes things Plato already computes — the wiring map, the centrality ranking, the broken-chain detector just shipped — into one compact headline. ~40–60 new lines of glue + a delivery hook. Low risk, fast.
Grows with Plato
A registry, not a hardcode (your addition)
prime doesn’t hardcode today’s signals. Every capability registers what it contributes and at which moments. Add a detector → register it → prime surfaces it automatically, with zero edits to prime. And the registry refuses any signal that doesn’t declare its fence — so growth can never smuggle in a silent lie. The nudge grows in lockstep with the capability.
Shape
Two layers, not one
prime is the orientation at session start; the existing pre-edit brief stays the action layer when you touch a file. Neither alone works — the context-rot research shows a session-start orientation provably decays mid-session and per-edit alone never fixes cold-start. Both are needed.
Delivery
AGENTS.md is primary, the hook is the bonus
The graded review caught this: on Claude Code today the session-start hook often doesn’t fire on a fresh session (open bug). So the always-on AGENTS.md instruction (“this repo has Plato — run prime before you start”) carries the load; the hook auto-delivers the live headline when it fires. The current map always comes from prime itself.
02

The delivery — one reflex, three layers

Re-weighted after the graded review: the reliable, always-on surface is the static one.

The one rule: prime never says “all clear.” A session-start push is read as the briefing, so its silence is an implicit “everything else is safe” — the exact lie-by-omission Plato exists to refuse. Every push carries the verbatim fence: here’s what I can see + here’s where I’m blind.
the build
AGENTS.md block — PRIMARY
A static, always-on instruction in the repo telling any agent (Claude Code / Cursor / Aider / Codex) to call prime before it starts. Survives compaction, hook-less hosts, and the Claude Code hook bugs. It carries the reach instruction; the live map comes from prime.
the build
SessionStart hook — ENHANCEMENT
Auto-delivers the live headline when it fires. Best-effort, not load-bearing — Claude Code’s startup hook is buggy today.
↘ go deeper — the machinery
Matcher startup|compact, plain stdout (≤10k cap → ~600-char headline), --hook-json opt-in for Gemini. Installed to the project’s .claude/settings.local.json ONLY. Rejected vectors: the MCP instructions field (CC stores but never reads it); Skills auto-invoke (~50% probabilistic — it reproduces the reach gap); a slash-command (manual pull = status quo). Only a hook + a static pointer are deterministic.
have it
Pre-edit brief — ACTION (shipped)
The can’t-skip moment: when you actually Edit/Write a file, the file-scoped fenced brief fires. Unchanged. This — not the hook’s compact re-fire — is the real post-compaction safety net.
03

What prime pushes — in order

One token-budgeted headline. Headline only — per-file detail is the action layer’s job.

  1. Currency line first — the load-bearing step. “PLATO map @ <pin>” with the live dirty bit — and STALE if HEAD moved since the snapshot. The graded review’s blocker lived here: a naive compose would let sub-sections read “current” on a dirty tree. prime strips every composed label and re-derives ONE currency surface. A stale “clean” is the cardinal sin.
  2. Wiring headline. N nodes / M edges / orphans + the completeness label (and the orphan/excluded count — the completeness fence made visible, never dropped).
  3. Top load-bearing hubs. The 3–5 spots a change ripples widest — labeled “the spots I can rank (lower bound)”, NOT “the spots that matter”; structural importance, not task relevance.
  4. Lying-gate signal. “N dangling suspects (confirm before acting) + K I cannot certify” — the can’t-certify count rides first-class. Dropping it turns “I can’t tell” into “I checked, it’s clean.”
  5. Where I’m blind. The repo’s blind classes (dynamic-import / .astro / registry counts) as a labeled soft note + a loud coverage line. Absence of a flag there is NOT a clean signal.
  6. Pointer to the action layer. “Run plato_change_brief on the file you actually touch — this map is the on-ramp, not the verdict.”
↘ go deeper — selectivity (the anti-banner-blindness discipline)
After session 1, prime emits the delta (what changed) + top-K, not the full map. The FIRST session is hard-capped too (top-5 hubs + counts + a one-line coverage note — no full-map dump; that’s the session that sets the agent’s “signal or noise?” prior). Recompute + evict on HEAD move — never a cached digest, never a beads-style decaying summary.
04

The never-lie contract — carried verbatim from the change-brief

The whole reason anyone could trust a push. Lifted from the file grain to the session grain.

N-1No rolled-up green
Never a top-of-push “safe/all-clear.” Each section carries its own fence. The only honest headline is see + blind.
N-2One currency surface
Strip every composed handler’s frozen label; re-derive one live currency line (dirty bit + HEAD-drift). No section lies “current” on a dirty tree.
N-3Fenced count is first-class
“K I cannot certify” rides beside “N dangling.” Same for orphans/excluded. The fence is the product.
N-4Lower-bound labels
Hubs are “what I can rank,” not “what matters.” A registry/dynamic-wired hub may outrank the list.
N-5Empty ≠ clean
A degraded snapshot (0 nodes) reads “cannot certify — empty is NOT clean,” never a clean orientation.
N-6Fail open
A failed prime never blocks a session — returns empty, work proceeds. A push that can wall an agent gets disabled at first inconvenience.
05

What could go wrong — honest

Each has a structural guard + a RED-under-break gate tooth.

Banner-blindness
The failure that kills reach — a fat blob fired every session is indistinguishable from no push. Guard: delta-only + hard first-session cap + tune-down-on-ignore instrumentation. Fire-count alone is a vanity metric.
A stale “clean”
The graded-review blocker — composed sub-labels reading current on a dirty tree, or a sibling commit moving HEAD mid-session. Guard: one re-derived currency surface + a serve-time HEAD-drift flag + two teeth.
Lie-by-omission
Silence read as safety. Guard: the verbatim never-lie fence — no rolled-up green, blind spots surfaced first.
Host fragility
Claude Code’s startup hook often doesn’t fire (open bug). Guard: the AGENTS.md block is the primary always-on surface; the hook is the bonus; the per-edit layer is the real safety net.
06

How we’ll know it works — phased

P1 · this build
Dogfood on Plato
prime answers over MCP + CLI; install writes the project hook + AGENTS.md block; the gate proves the headline is current, fenced, never an all-clear; the freshness tooth goes RED on a dirtied-tree cache-hit; a drift tooth catches a mid-session HEAD move; and the AGENTS.md-alone path delivers with the hook disabled (the path most likely live).
P2 · measure
The reflex bet
Wire it into a real DE agent loop with the content-free heeded-vs-ignored instrument; read the ignore-rate by delta-size — the honest test of whether the push is load-bearing, not just firing. That number decides rollout vs. tune-down-first.
07

Your calls — the red-pen targets

The spec waits on these. The starred two are the ones I most want you to set.

1
Two layers or one? (the central scope call)
Ship prime (orientation) and keep the per-edit brief (action)? My rec: yes, both — phased. The alternative: harden only the per-edit brief first (safer never-lie surface, but leaves the cold-start reflex — the actual bottleneck — unsolved).
4
Install posture (a boundary call).
install writes a hook into a repo’s project-scoped .claude/settings.local.json + AGENTS.md. My rec: human-gated on first run, never autonomous, never the global config, never your vetharness-sites working tree.
2
Does prime carry the lying-gate signal at session start?
Most valuable and most cry-wolf-prone (Neuron has 91 can’t-certify gates). My rec: push only the two counts as one line, full list reserved for an explicit plato broken-chains pull. Alternative: leave it out of prime v1.
3
How aggressive is selectivity?
My rec: delta-only after session 1, hard cap (top-5 hubs + top-5 changed), “more on request”; fixed for v1, tunable per-repo later.
5
Which repo proves it first?
My rec: dogfood Plato-on-Plato first (cheapest, zero boundary risk), then a DE repo. Not Neuron’s working tree.