Appearance
wayfinder
wayfinder
standalone
Wayfinder
A loose idea has arrived — too big for one agent session, and wrapped in fog: the way from here to the destination isn't visible yet. Wayfinding is about finding that way, not charging at the destination. This skill charts the way as a shared map on GitHub Issues, then works its tickets one at a time until the route is clear.
The destination varies per effort, and naming it is the first act of charting — it shapes every ticket. It might be a spec to hand off and iterate on, a decision to lock before planning starts, or a change made in place like a data-structure migration.
Plan, don't do
Wayfinder is planning by default: each ticket resolves a decision, and the map is done when the way is clear — nothing left to decide before someone goes and does the thing. The pull to just do the work is usually the signal you've reached the edge of the map and it's time to hand off (to to-tickets / a build-* skill). An effort can override this in its Notes — carrying execution into the map itself — but absent that, produce decisions, not deliverables.
Refer by name
Every map and ticket is an issue, so it has a name — its title. In everything the human reads, refer to it by that name, never by a bare id: a wall of #42, #43, #44 is illegible. The id and URL ride inside the name as a link, never stand in for it.
The Map
The map is a single issue labelled wayfinder:map — the canonical artifact. Its tickets are child issues of the map.
The map is an index, not a store. It lists the decisions made and points at the tickets that hold their detail; a decision lives in exactly one place — its ticket — so the map never restates it, only gists it and links.
The tracker mechanics (map, child tickets, blocking, frontier query, claim, resolve) live in docs/agents/issue-tracker.md → Wayfinding operations.
The map body
The whole map at low resolution, loaded once per session. Open tickets are not listed — they are open child issues, found by query.
markdown
## Destination
<what reaching the end of this map looks like — the spec, decision, or change
this effort is finding its way to. One or two lines; every session orients to
it before choosing a ticket.>
## Notes
<domain; skills every session should consult; standing preferences for this effort>
## Decisions so far
<!-- the index — one line per closed ticket: gist + link -->
- [<closed ticket title>](link) — <one-line gist of the answer>
## Not yet specified
<!-- see "Fog of war": in-scope fog you can't ticket yet; graduates as the frontier advances -->
## Out of scope
<!-- work ruled beyond the destination; closed, never graduates -->Tickets
Each ticket is a child issue of the map; the issue id is its identity. Its body is the question, sized to one agent session:
markdown
## Question
<the decision or investigation this ticket resolves>Each ticket carries a wayfinder:<type> label — one of research, prototype, grilling, task (below).
A session claims a ticket by assigning it to the driving dev, first, before any work, so concurrent sessions skip it. That assignee is the claim: an open, unassigned ticket is unclaimed.
Blocking uses GitHub's native dependency relationship — it renders the frontier visually in the tracker UI, so the human sees what's takeable without opening the map. A ticket is unblocked when every ticket blocking it is closed; the frontier is the open, unblocked, unclaimed children — the edge of the known.
The answer isn't part of the body — it's recorded on resolution. Assets created while resolving a ticket are linked from the issue, not pasted in.
Ticket types
Every ticket is either HITL — worked with a human who speaks for themselves — or AFK, driven by the agent alone. A HITL ticket only resolves through that live exchange; the agent never stands in for the human's side (a grilling agent that answers its own questions has broken this).
- Research (AFK): reading docs, third-party APIs, knowledge bases. Creates a markdown summary as a linked asset. Use when knowledge outside the repo is required.
- Prototype (HITL): raise the fidelity of the discussion with a cheap, rough, concrete artifact to react to — an outline, a stub, or (for UI) a throwaway wireframe per
.claude/rules/frontend.md"Wireframe first". Links the artifact. Use when "how should it look/behave" is the key question. - Grilling (HITL): conversation via the grilling protocol (
docs/agents/grilling.md) withgrill-with-docs' domain layer, one question at a time. The default case. - Task (HITL or AFK): manual work that must happen before a decision can be made — signing up for a service, provisioning access, moving data so its shape can be seen. The one type that does rather than decides; it earns its place by unblocking a decision. Resolved when done; the answer records what was done and any resulting facts later tickets depend on.
Fog of war
The map is deliberately incomplete: don't chart what you can't yet see. Beyond the live tickets lies the fog of war — decisions you can tell are coming but can't yet pin down, because they hang on questions still open. Resolving a ticket clears the fog ahead of it, graduating whatever's now specifiable into fresh tickets — until the way to the destination is clear and no tickets remain.
Not yet specified is where that dim view is written down. Fog or ticket? The test is whether you can state the question precisely now — not whether you can answer it now: ticket when the question is already sharp (even if blocked); fog when you can't phrase it that sharply. Don't pre-slice the fog into ticket-sized pieces — one patch may graduate into several tickets, or none.
Out of scope
Fog only gathers toward the destination; work beyond it is out of scope — its own map section, not fog. It never graduates (returns only if the destination is redrawn, as a fresh effort). When an existing ticket turns out to sit past the destination, close it and leave one line in Out of scope (gist + why + link). It stays out of Decisions-so-far, which records the route actually walked.
Invocation
Two modes. Either way, never resolve more than one ticket per session.
Chart the map
User invokes with a loose idea.
- Name the destination. Run the grilling protocol (with
grill-with-docs' domain layer) to pin down what this map is finding its way to. The destination fixes the scope, so it's settled first. - Map the frontier. Grill again, breadth-first: fan out across the whole space, surfacing the open decisions and the first steps takeable now. If this surfaces no fog — the journey fits one session — you don't need a map. Stop and ask the user how to proceed.
- Create the map (label
wayfinder:map): Destination and Notes filled, Decisions-so-far empty, the fog sketched into Not yet specified. - Create the tickets you can specify now as child issues — then wire blocking edges in a second pass (issues need ids before they can reference each other). Everything you can't yet specify stays in the fog.
- Stop — charting is one session's work; do not also resolve tickets.
Work through the map
User invokes with a map (URL or number); a ticket is optional — without one, you pick.
- Load the map — the low-res view, not every ticket body.
- Choose the ticket: the user's named one, else the first frontier ticket. Claim it before any work.
- Resolve it — zoom as needed: fetch full bodies of related/closed tickets on demand; invoke the skills the map's Notes name. In doubt, grill.
- Record the resolution: post the answer as a resolution comment, close the issue, append a context pointer (gist + link) to Decisions-so-far.
- Add newly-surfaced tickets (create-then-wire); graduate fog the answer has made specifiable; rule mis-scoped tickets out of scope; update or delete tickets the decision invalidates.
Expect other sessions to be editing the tracker concurrently — the user may run unblocked tickets in parallel.