| name | explore-latent |
| description | Chart a validated path through the latent option-space of a bounded project, from here to the target, one cheap-poke at a time. Consumes a matured intent-shape doc. Scout subagents fan out and each propose a whole candidate path; the main loop narrows them against the inviolates and risk-order (validate the core before building the shell); the next step is poked with the cheapest possible artifact, then committed via a handoff file the next session reads cold. Use after intent-shape, when the shape is bounded and the question is 'how do we get there, and what are the forks.' Works greenfield (from a seed) and brownfield (from an existing codebase, consuming intent-shape's gap audit as the frontier). Trigger on 'explore-latent', 'chart the path', 'how do we get there', 'what are the forks', 'sequence this', 'plan the build from the shape', 'find the fun first', 'plan for this existing codebase', 'brownfield plan'. Do not trigger for shaping (use intent-shape), for execution of a single known step, or for debugging. |
explore-latent
A practice for charting the path through a project's latent option-space โ the unbuilt routes living in the gaps of a bounded shape โ and walking it one validated step at a time. Sibling to intent-shape: that skill bounds what the thing is; this one charts how you get there, and where it forks.
Not a project plan. Not a Gantt chart. A pathfinding loop: scouts widen the option-space, the main loop narrows it, each step is proven with the cheapest possible poke before the next is committed, and every committed step is handed off via a dated handoff file the next session reads cold and acts on.
Input
A matured intent-shape document (parti, inviolates, anti-shapes, first seed). If no intent-shape doc exists, run the intent-shape skill first; if it isn't available, make a best-guess shape from what you have and mark it [hazy] โ a rough shape beats no shape, and walking the path will sharpen it. The shape should be bounded enough that decisions flow without escalation (intent-shape's readiness signal).
The intent-shape doc is the authority for every cut. Scouts read it. The main loop narrows against it.
Target vs goal โ two destinations, don't conflate:
- Target โ the bounded shape realized; the far destination scouts aim whole paths at. If the intent-shape doc names no explicit target, derive it from the parti (one named step) before fanning scouts.
- Goal โ the nearest human-validatable step on the path; what each handoff file commits to. A goal is never far โ it's the next checkpoint a human can look at and say "yes, that holds." The path is a chain of goals walked toward the target.
The goal artifact (the handoff each step writes) describes: context (what the poke proved, where we are), constraints (which inviolates bind this step), and target (the nearest human-validatable acceptance).
Three laws
-
Scouts widen until paths argue; the main loop surfaces the argument. Generation of options is delegated and divergent. Aggregation is centralized. Never let the main loop generate the options โ it will anchor on the first one. Never let a scout resolve the tension โ it will defend its own path. The main loop's job is to hold all the contradictions in one place, not to pick a winner. The argument is the output; resolution is flight-trajectory's job.
-
Validate the core before you build the shell. A path that builds systems before proving the load-bearing assumption is a worse path, regardless of how tidy it looks. If it's a game, find the fun first. If it's a tool, prove the core interaction first. The riskiest, hardest-to-fake assumption goes first, in the cheapest form that can prove it โ where "can prove it" is bounded by the hypothesis's context floor (see Context floors below): the cheapest form that can HOST the phenomenon, not the cheapest form full stop.
-
Build is the last resort โ explore to exhaustion, build only to open the next frontier. The cycle's natural output is a sharper frontier, not a shipped step. Writing a handoff (committing to a real build) is justified by one thing only: exploration on this frontier is exhausted and building is now the only way to discover the next frontier โ the built artifact is itself the probe that reveals what's next. If you can learn the next frontier without building, don't build. Building to show progress, or because a cycle "should" end in a commit, is the corruption this skill exists to resist. And when you must act into risk or uncertainty, prototype first (throwaway) โ commit real code only when the work is boring and certain.
Context floors โ size the test to the phenomenon, not the effort
Some properties are component-testable: they live in a rule and survive isolation (determinism, an output format's compliance, whether a written page gets a laugh). Others are gestalt properties: they exist only in accumulated context โ a feeling that needs forty turns of history, an exit that only reads as dignified if what's renounced felt worth having, an ecology that only appears at population scale. Every feel-hypothesis has a context floor: the minimum accumulated context below which the phenomenon cannot occur at all.
Below the floor, a poke's result is uninterpretable. A flat result doesn't mean the mechanic is dead; it means the chamber was too small to host the feeling. This is the false-negative trap: cheap pokes on gestalt properties produce confident kill-verdicts on designs that were never actually tested. The MVT is the minimum viable context, not the minimum viable effort.
Discipline:
- Tag every milestone's hypothesis with its floor โ component (testable in isolation), bounded-context (testable inside one natural unit of play/use: a session, a day-cycle, one full pass), or whole-run (exists only across a complete arc). Scouts state the floor per milestone; the main loop rejects any MVT sized below its hypothesis's floor as not a test.
- Hunt the licensing assumption. When a shape claims its core compresses ("the experience is fractal โ the small holding is the big throne in miniature"; "the core reduces to a tabletop"), that claim is what LICENSES cheap pokes at all. It is therefore a first-order test target, before the pokes that depend on it: if it fails, the methodology changes โ not just the path. A poke program built on an untested compression claim is circular: the pokes assume the very compression they exist to test.
- Floor-raising tricks are legitimate but bounded. A human facilitator can fake an ecology a solo kit can't; authored context (vignettes, scripted histories) can stand in for accumulated play. But authored context proves the form, never the phenomenon โ the feeling only counts when the context was earned by the subject's own choices. Mark any floor-raised result as provisional against a real-context replication.
- When the floor exceeds every cheap artifact, building IS the probe โ this is Law 3's exit taken deliberately, not a failure of exploration. Say so in the ledger: "floor above poke range; the build is the test," and design the build to measure the gestalt property, not merely to ship.
Seeds โ uncover before you discover
A seed is a primitive โ a verb, unit, or capability the artifact composes from. Seeds come in three states; explore-latent handles the last two:
- Planted โ the first seed, chosen deliberately in intent-shape (a hypothesis to test). It sets the starting frontier.
- Existing โ primitives already in the ground: built, working, composable. In brownfield they are everywhere and they are the cheapest material you have. You uncover them by walking the project, not by fanning scouts.
- Discovered โ new load-bearing primitives the fan + poke surface from the latent space. This is how intent-shape's "earn each next seed by the last one's growth" actually happens โ you don't plant the next seed, you discover it by walking. (Claudy Appleseed finds what's seeded in the ground; he doesn't import a packet.)
Walk first โ the seed inventory (mandatory in brownfield, wise in greenfield). Before the first fan on any project, the main loop walks the ground and inventories the existing seeds โ every primitive already present and composable. This is NOT the gap audit (which lists gaps against the shape); it is an asset inventory of what you can build from. Produce a short list: each primitive, where it lives, what it composes with. Feed it into every scout brief so scouts compose from existing seeds first and discover new ones only where the existing reach runs out.
Skip this and you pay for it: fan scouts cold and they forage the same ground independently and shallowly, re-deriving what a five-minute inventory would have handed everyone at once. (Learned the hard way โ a writing-synthesis run fanned four scouts before anyone noticed the corpus was already ordered markdown and the compose-primitive was lying in the existing traversal code.)
The seed inventory format. Project-level and living โ walk the project once into .ai/latent/seeds.md; every exploration reads it, every discovery appends to it. Existing seeds don't change because you picked a different frontier, so don't re-walk per exploration. Minimal columns โ only what a scout needs to compose:
# Seed inventory โ <project>
> walked <date> ยท living โ re-walk appends, never resets
## Existing seeds (already in the ground)
seed where (file:line) signature (in โ out) composes-with state
<name> <path:line> <what it takes โ returns> <other seeds> working | partial | stub
## Discovered seeds (surfaced by exploration)
<same columns> + found-on (which frontier) + verdict (proven | candidate)
## Compose-ready clusters
- <name>: <existing seeds that already chain into a capability โ the cheapest paths live here>
Field rationale: where makes it real and readable (Chesterton's fence); signature is the compose field (how you chain it); composes-with is the primitive graph; state tells scouts what's solid vs scaffolding. Absences belong to the gap audit / frontier queue, not here โ the inventory is assets only. The per-exploration PATH.md seeds field just names which inventory seeds that path composes from.
The cycle
One turn of the wheel. Repeat until the path reaches the goal. (On a project's first run, walk first โ build the seed inventory above โ before step 1.)
1. Frame the frontier
The main loop states the current open question in one line: what do we need to figure out next? On a cold start that is the whole journey from the first seed to the bounded goal. Later it is the next unresolved stretch the last step exposed. A frontier is a question, not a task โ "what's the core fun?" not "build the movement system."
2. Fan out scouts
Dispatch 3โ4 scout subagents in parallel (Agent tool, one message). Each scout receives the intent-shape doc, the current frontier, and the scout brief below. Each returns one whole candidate path from here to the target:
- Ordered milestones (here โ โฆ โ target), each a candidate goal (human-validatable checkpoint)
- For each milestone: which assumption it validates, and how it would poke that assumption cheaply
- Its own fork points โ where the path could branch and why
- One line on which inviolate the path leans hardest on, and which it most risks
Scout archetypes โ the main loop assigns archetypes to guarantee divergence (don't trust scouts to diverge on their own). Each archetype opens a different axis; the goal is to span axes, not multiply flavors. Palette:
- Conventional (expected) โ the straight, sensible route; how the work is "meant" to be done.
- Risk-first (uncertainty) โ front-load the scariest assumption; isolate and prove the load-bearing primitive before anything else.
- Contrarian (goal-validity) โ attack the premise; invert the obvious sequence; question whether the target or the unit is even right.
- Greedy (speed) โ beeline to the target as fast as possible. Strip everything not strictly required: maintenance, usability, robustness, edge cases โ all sacrificed for speed. Sets the speed floor (the shortest route reveals what the target actually requires vs what is quality-tax); where the narrowing blades kill it tells you which quality constraints are truly inviolate vs merely scaffolding.
- Steward (durability) โ greedy's opposite pole. The path optimized for longevity and maintainability; accept a slower now for a cheaper later. Run greedy โ steward in one fan to span the whole speed/durability spread โ they often share the first steps, then split hard exactly where the real tradeoff lives.
- Saboteur (failure) โ does not chart a path to the target; charts how each route dies, then hands you the inverse. A premortem worn as a scout. Orthogonal to contrarian: contrarian doubts the goal, saboteur assumes it and hunts the assassins hiding in every route. Doubles as a reality-test of the inviolates.
- Bricoleur (leverage) โ "don't build, reuse." Charts the path assembled from what already exists โ libraries, prior art, adjacent domains, nature. The cheapest poke of all is proof that already exists; this scout hunts it instead of generating fresh. Especially strong in brownfield.
- Chaotic (surprise) โ accepts the goal, ignores all assumptions about sequencing. Takes the weirdest valid route: inverts the dependency order, starts from the end and works back, or combines milestones that "shouldn't" go together. Orthogonal to contrarian: contrarian doubts whether to go; chaotic doubts how anyone thinks the path must be walked. Its value is revealing which dependencies were real vs. assumed โ the shared milestones it finds with other paths are where the conventional wisdom was actually right; its unique legs are where it wasn't.
Spanning rule: pick a subset that spans axes for the frontier, never parallel flavors of one axis. Always include contrarian (goal-validity) plus at least one pole of the speedโdurability axis (greedy or steward). For wide-open or high-stakes frontiers, add saboteur (failure), bricoleur (leverage), and chaotic (surprise). Identical paths back is a failed fan-out โ re-brief with sharper archetype contrast and re-fan.
Shared trails. Scouts may propose paths that share early milestones before diverging โ this is intentional, not a failure to diverge. A shared prefix reveals the territory both paths agree on (cheap, settled, fly once); the fork point reveals the live tension. In the emitted DAG, a milestone node that appears in multiple paths' milestone lists is flown once โ state.json marks it DONE and all paths advance through it. Scouts should explicitly name their fork-from point so the menu entry shows where each path departs from common ground.
3. Aggregate โ build the possibility menu
The main loop takes all scout paths and builds a possibility menu โ a flat list of avenues the architect can choose to walk in flight-trajectory. This is NOT a narrowing step. Do not kill paths. Do not pick a winner.
For each scout path, extract the key dimensions into one menu entry:
- What this explores โ one line: the hypothesis at its core, the assumption it would test
- Inviolate it leans on โ which constraint it honors most tightly, and which it most stresses
- Risk shape โ what goes wrong if the core assumption fails; how recoverable
- What it trades away โ what the greedy/steward/contrarian lens sacrificed to get here
Prune only genuine violations: if a path provably crosses a hard inviolate (not an interpretation, a clear violation), mark it [violates: <inviolate>] and leave it in the menu with that label. The architect may still choose it if the inviolate was wrong. A kill is appealable; remove nothing silently.
Do not merge paths into a working path. Do not pick the "best" order. Do not declare what to build next.
The menu is ready when paths are genuinely arguing. Paths argue when they make incompatible assumptions about what to prove first, what to reuse, or whether the target is even right. That tension is the value โ it is what the architect's judgement in flight-trajectory is designed to resolve. Do not resolve it here.
Re-fan only if paths are echoing. If scouts return paths that share the same fundamental assumption (different implementation, same axis), the fan didn't diverge โ re-brief with sharper archetype contrast and re-fan. The test: could you describe the disagreement between any two paths in one sentence? If not, they're echoes.
One dry re-fan confirms. After the menu is drafted, fire one more scout round briefed on the existing paths. If it returns recombinations (entries already represented on the menu), the space is mapped. If it opens a new axis, extend the menu. K=1 dry round is sufficient.
The output of this step is PATH.md with a ## Possibility menu section replacing the prior ## Working path section. Each entry includes: archetype, thesis (the core hypothesis), which inviolate it leans hardest on, what it explicitly trades away, and its fork-from point (the first milestone where it diverges from other paths on the menu).
4. Handoff to flight-trajectory
Once the menu is built, the work of explore-latent is done for this cycle. Write the menu to PATH.md and surface it to the architect. The architect reads the menu and takes it to flight-trajectory, where paths get walked and roads get written.
No prototypes unless the architect requests one. If the architect says "show me what this would look like" or "can we poke that assumption," then and only then run a poke (a QA dialogue, a one-screen sketch, or a proto-buddy prototype if the surface warrants it). The default is: map the territory and hand it over. Do not build to show progress.
proto-buddy recipe (if a poke is requested; scripts resolve only within a /proto-buddy skill invocation):
start: start.sh --dir <DIR> --port 3333
feedback: events append to <DIR>/.events (JSONL: {type, tab, selector, coords, comment, action})
watch-one.sh <DIR> blocks; react by rewriting the HTML; Cmd+. toggles interact mode
stop: stop.sh --dir <DIR>
Anti-pattern: the gestalt collapses. The most common failure of this skill is latching onto the most interesting or concrete element of one scout path and diving into it, losing the full possibility space. Every cycle must surface the full menu before any single entry gets attention. If you find yourself elaborating on one path, stop โ write the menu first.
Inviolates and anti-shapes are test targets, not just filters
The cycle above uses the inviolates and anti-shapes as blades โ passive criteria for cutting scout paths. That is necessary but not sufficient. A rule that sits in judgment but is never itself judged is an assertion in a costume. An untested inviolate is an aspiration; an untested anti-shape is a superstition. Both belong in the poke loop as first-class targets โ an untested rule is a valid frontier (step 1).
Each inviolate gets two distinct tests:
- Reality test โ is this inviolate real? Try to violate it, in the cheapest form that can show the effect (build the forbidden version small; proto-buddy works here). Does the felt experience actually collapse? This is intent-shape's subtraction check run for real, not hypothetically. If the project survives the violation, it was never an inviolate โ demote it to the scaffolding register and warm-update the intent-shape doc. A fake inviolate is worse than none: it constrains every scout path for nothing.
- Compliance test โ does what we're building actually uphold it? The rule is real; are we honoring it, or only claiming to? In brownfield this overlaps the gap audit's Violating bucket.
- Intent test โ does the wording match what the inviolate is actually for? A real inviolate can be mis-worded, and scouts narrow on the letter. If a path dies on an inviolate's literal text, check the architect's intent before trusting the kill โ the wording may forbid more (or less) than the purpose. Reword to the intent; the "violating" path may be legal after all. A scout's confident, well-argued critique can be wrong at the root if it trusts the letter over the purpose. (Earned: a scout flagged a legal human output surface as a violation because an inviolate said "no linear scroll" when it meant "no chat interface.")
Anti-shapes get the parallel pair: specificity test (is this a real, named temptation this project actually feels, or a generic warning?) and drift test (have we already slid toward it?).
Discipline โ don't test every rule every cycle. That is the methodology trap intent-shape warns against. Test the rule a given step leans hardest on, before you build much atop it. Riskiest rule first (Law 2 again โ the inviolate the whole path depends on is the one whose collapse is most expensive to discover late). Go big, ship small: the vision honors all the rules; this cycle proves the one load-bearing rule is real and upheld.
Outcomes feed back: a rule that passes is earned โ it has paid for the constraint it imposes. A rule that fails its reality test leaves the document. Either way the intent-shape doc gets truer, which makes every future scout cut sharper.
Brownfield mode (existing codebase)
When the project already has code on disk, "here" is not a blank seed โ it is a house someone lives in. Load-bearing walls, working rooms, a sofa that's fine. You chart a path through and around what exists, not from zero. Four things change:
Precondition: run intent-shape's Gap audit first. Determine the intent-shape (cold-start moves, independent of the code), then walk the codebase and produce the four-bucket gap report โ Missing / Violating / Anti-shape drift / Scaffolding-masquerading-as-shape. That audit is the brownfield frontier source. You do not invent frontiers from "what's the fun"; you draw them from the gaps. No audit โ no path.
Frontiers come from the buckets, risk-ordered. Default order of attack: Violating (code that breaks an inviolate โ bleeding now) โ Missing that the core needs (the shape demands it and it's absent) โ Anti-shape drift โ Scaffolding cleanup (last; cosmetic). But re-rank by Law 2 โ the riskiest assumption first. In brownfield the riskiest question is often "did we already ship something that doesn't actually serve the shape?" Poke the suspect existing behavior before adding anything new.
Walk first, then scouts deepen. The main loop's seed inventory (see "Seeds โ uncover before you discover") runs before the fan and is handed to every scout โ so scouts don't each forage the same ground cold. Each scout then uses Explore to deepen the inventory in its own direction and proposes a path that names โ per milestone โ what to keep, what to change, what to delete, and which existing seeds it composes from. A scout that ignores what works and proposes a rewrite has failed the brief. Route around load-bearing code; understand why a thing is there before you move it (Chesterton's fence).
The cheapest poke is usually the existing behavior. Run it, watch it, ask: does this actually serve the shape? Do not prototype fresh what already ships โ that's wasted motion and it discards real evidence. Prototype (proto-buddy) only the genuinely-new. Validating an assumption that's already embodied in shipped code means exercising that code, not rebuilding it.
Reversibility flips the judge pass on by default. Greenfield pokes are throwaway; brownfield changes touch live code and are expensive-to-reverse. So the optional adversarial judge pass (step 3) is the default for any step that modifies load-bearing code โ dispatch a judge to argue against the change and surface what it might break. The anti-pattern this guards: rewriting working code to "do it right" when it already serves the shape. That's anti-shape drift in the plan itself.
Everything else โ fan out, narrow, walk one step, commit via handoff โ is identical.
Scout brief
What each scout subagent is told (adapt to the project, keep the spine):
You are a scout charting one possible path for a bounded project. Your assigned archetype is <archetype> โ embody it fully (e.g. a greedy scout genuinely sacrifices maintenance, usability, and robustness to reach the target fastest; a contrarian genuinely attacks the premise). Read the attached intent-shape document โ it is the authority; never cross an inviolate. The current frontier is: <frontier>. Already charted on this frontier (do NOT re-propose these โ diverge from them): <seen-paths, or "none โ first fan">. Propose ONE whole candidate path from here to the target (the bounded shape realized): ordered milestones โ each a human-validatable goal โ the assumption each milestone validates and how to poke it cheaply, your fork points, and which inviolate you lean on vs risk. Stay true to your archetype โ surprise the main loop. Return the path as structured markdown. Do not build anything; propose the route only. For each milestone, state the done_condition (how you will know it is complete), whether it mutates repo files, the context_floor of its hypothesis (component | bounded-context | whole-run โ the minimum accumulated context that can host the phenomenon; an MVT sized below its floor is not a test), and 1โ2 context pointers (file paths or seed-inventory refs a cold executor would need). In depends_on, list only milestones whose artifact or proven fact this one cannot start without โ narrative ordering is not a dependency. If two milestones touch the same file, order them via depends_on.
Dispatch all scouts in a single message so they run concurrently. Brownfield: scouts MUST use Explore to survey the real codebase before proposing, and must name what to keep / change / delete per milestone (see Brownfield mode).
Output โ arming a step
The deliverable of a passing step is a handoff, armed for the next session:
-
Write a handoff to {MAIN_REPO_ROOT}/.ai/handoff/<step-slug>-MMDD.md using the existing handoff format (/handoff conventions). The acceptance gate lives in next_actions:
task โ the concrete next milestone to build
acceptance โ the human-checkable condition that closes this step; the receiving session treats it as the completion gate
context โ what the poke proved, why this milestone is next, which inviolates constrain it
-
Surface the handoff path to the architect:
.ai/handoff/<step-slug>-MMDD.md
The acceptance field is the loop-until target: the step is done when that condition holds. The architect (human, or the receiving session via txlit) reads the handoff cold and acts on it. The handoff is the prework and the trigger.
One handoff per committed step. It is also the cross-session continuity record if the build happens elsewhere (new session, peer agent via txlit).
Workspace
Persist paths and findings under:
.ai/latent/explore/<path>/
a/ scout A's candidate path + its findings
b/ scout B's candidate path + its findings
c/ scout C's candidate path + its findings
<nested optional> forks nest as subdirs under the branch they came from
<path> is a slug for the frontier/journey being charted. Each scout's whole proposal lands in its own letter dir (a, b, c); poke results, reality-test verdicts, and the chosen working path are saved as findings alongside. Forks nest one level deeper under the branch they branch from. The armed-step handoffs in .ai/handoff/ remain the cross-session continuity record; the .ai/latent/ tree is the full exploration history โ every route considered, not only the one walked.
Emitting the DAG (prose+dag mode)
Two emit modes. skills/flight-trajectory/dag-contract.md is the schema authority โ do not duplicate it here.
- prose โ default for terminal use. The PATH.md ledger and scout proposals as written.
- prose+dag โ default-on when an intent-shape doc is present AND unbounded forks remain on the frontier. Same prose output plus the structured
dag.json. Use prose-only when the session is explicitly terminal (no downstream flight-trajectory handoff).
Refresh after every narrow. Each narrow that changes the working path updates .ai/latent/explore/<slug>/dag.json. The main loop drafts the JSON itself โ it holds all the path context; serialization is not synthesis. Never delegate DAG authoring to a scout.
Mandatory before flight-trajectory handoff: run the deps-auditor agent on the emitted dag.json. One agent call. Warnings block the handoff until acknowledged.
The deps-auditor validates:
- All
depends_on edges resolve to real node ids; the graph is acyclic.
- Every non-gate node has required fields present:
done_condition, mvt, hypothesis, mutates, context.
- Every gate has typed
options objects ({label, leads_to, summary}) and a required artifact field ({kind, brief}). Missing or absent artifact is a handoff-blocking warning โ kind 'none' is valid for decision-only gates; the field itself must be present.
- Width report โ width == 1 across more than 5 consecutive nodes โ chain-smell: auditor surfaces the question "is B truly blocked by A's artifact, or just narrated after it?" for each edge in the chain. Handoff blocked until the architect confirms or dissolves each flagged edge.
- Cheap gates with
inviolate_touched โ '' are flagged suspect. Default is expensive โ a cheap gate that touches an inviolate is almost certainly under-classified; promote to expensive or justify.
Per-field sourcing (where the main loop finds each required field; skills/flight-trajectory/dag-contract.md field-provenance table is the authority for the full set):
hypothesis โ scout brief states "the assumption this milestone validates"; copy verbatim from the scout's proposal
mvt โ scout brief states "how to poke it cheaply"; copy verbatim; this is the HARD fidelity ceiling the engine enforces
done_condition โ how the scout states "how you'll know this is done" (milestone acceptance test)
mutates โ build-vs-probe split: pokes are read-only; build steps that write repo files are true
context โ seed inventory refs (.ai/latent/seeds.md) plus armed-step context from PATH.md
artifact โ the main loop picks kind from gate reversibility + hypothesis (skills/flight-trajectory/dag-contract.md field-provenance table is the authority): expensive gates default to proto-buddy when the hypothesis is web-testable, file for deliverables, none for decision-only gates. The engine writes gate-artifact .html tabs into .ai/flight/<pathId>/artifacts/ before parking; the conductor never starts the server โ it starts and stops it at harvest.
Path memory & convergence
Failure this prevents: run the loop twice and it re-proposes the same path. Two causes, two fixes โ and one of them isn't a bug.
-
Scouts have no memory โ they re-tread. The Workspace writes paths but nothing reads them back, so every fan starts cold from the same shape and the obvious routes resurface. Fix โ memory is mandatory before every fan after the first: read the ledger and inject the already-charted paths into every scout brief ("Already explored: <one-line summaries>. Propose a route genuinely distinct from these โ re-proposing a charted path is a failed scout."). The main loop also dedups new proposals against the ledger before narrowing.
-
The frontier didn't move โ same question, same answer. Re-running an unchanged frontier is supposed to reproduce the path; that is not malfunction. The loop only advances when a step is armed/walked and the frontier updates. If a fan is requested on an unchanged frontier, don't silently re-fan โ surface it: "This frontier is already charted; here's the prior cut. Advance it (walk a step) or reframe it."
Convergence (loop-until-dry). When a fresh fan returns only paths already in the ledger, the option-space on this frontier is exhausted โ that's the signal to make the cut (commit the best charted path) or advance/reframe the frontier, never to spin another identical fan. Re-tread is convergence, not failure โ name it as such.
The ledger โ one PATH.md per exploration at .ai/latent/explore/<path>/PATH.md, the single state every cycle reads before and writes after:
target โ the bounded destination
seeds โ existing (uncovered by walking) + discovered (surfaced by fan/poke); each: primitive, where it lives, what it composes with
working path โ the current chosen route, firm only at the next step
seen-paths โ one-line summary of every route already charted (THE MEMORY)
frontier queueโ open forks; each becomes a future fan (frontiers get fanned, not answered)
cold questionsโ long-tail questions batched at session boundaries; format:
`- [ ] [question] *(from: fan|explore|flight)* โ folds into: [target]`
log โ armed steps, pruned branches, convergence calls
QA discipline
AskUserQuestion takes up to 4 questions per call โ batch, don't drip. A list of 10 questions is 3 invocations (4 + 4 + 2), not 10. The architect's judgment is the scarcest resource: spend it on the cuts that matter (which path, which fork, accept/reject a poke), not on detail the scouts or the intent-shape doc already answer. Ask one at a time only when a later question genuinely depends on the answer to an earlier one.
Two-lane routing: load-bearing questions โ a fork that cannot proceed without an answer now โ go to AskUserQuestion. Long-tail questions (tangential, safely deferred, or cross-session) go to the cold lane in PATH.md. Batch cold questions at session boundaries, not mid-cycle. Unanswered cold questions travel forward in every handoff; the receiving session inherits them.
When NOT to use
- Shape isn't bounded โ intent-shape first. No path through undrawn territory.
- Single known step, no indeterminacy โ just build it. The fan-out is for genuine forks, not for validating a decision already made.
- Debugging / execution of a committed step โ that's the receiving session acting on the handoff, not this skill.
Readiness signal
No done state โ the path matures as you walk it. You're done when the last poke lands on the target the intent-shape bounded. If the target keeps receding, the shape's bound was soft โ back to intent-shape.
Anti-skill check (two failure modes, build-eager is the common one).
- Build-eager โ writing a handoff every cycle, treating a shipped step as the cadence. You've turned an explorer into a task-runner. Most cycles should end in a sharper frontier, not a build (Law 3). The exit is more exploration, not another commit.
- Explore-stuck โ the frontier has converged, building is the only way forward, and you keep fanning anyway, admiring a finished map. The exit is the one build that opens the next frontier.
Default to suspecting the first. The skill's pull, and its author's, is toward premature building.