| name | map-wayfind |
| description | Decision-frontier wayfinding: build and work a durable map of open design decisions BEFORE planning, for large or foggy efforts where /map-plan would force premature decomposition. Use when a task is too big or too vague to decompose — many unknowns, tangled decisions, or "I'm not even sure what to build yet" — and you want to resolve the key decisions one at a time (research, prototype, grilling, task tickets) behind a claim-before-work frontier, with a "fog of war" for questions you cannot yet state sharply. Produces a handoff that /map-plan consumes. Modes are explicit: chart (start a map), work (resolve one ticket), handoff (finish). Do NOT use when scope is already clear enough to specify — go straight to /map-plan; do NOT use to implement code or to decompose an already-specifiable change.
|
| disable-model-invocation | true |
| argument-hint | [chart "loose idea" | work <slug> [ticket] | handoff <slug>] |
| effort | medium |
/map-wayfind — Decision-Frontier Wayfinding
Purpose: for a large or foggy effort, resolve the key design decisions ONE AT A TIME on a durable map before any planning. If the scope is already clear enough to specify, skip this and run /map-plan directly.
Contrast with /map-plan: /map-plan decomposes an already-understood task into subtasks. /map-wayfind comes earlier — it resolves the decisions that make decomposition possible, then hands the settled decisions to /map-plan. The map is durable and repo-level (.map/wayfind/<slug>/); it outlives branches and can span many sessions.
Effort and Parallelism Policy
thinking_policy: medium/adaptive
parallel_tool_policy: research_only
- Use deeper reasoning for the sharpness test (is a question ticketable now?), for wiring dependencies, and for judging whether a decision is truly resolved.
- Do not over-chart: if a breadth-first interview surfaces no real fog, there is nothing to wayfind — say so and route to
/map-plan.
- Parallelize ONLY independent research-agent reads dispatched against research tickets. Keep charting interview, claiming, human grilling, resolving, and handoff strictly sequential.
Determinism boundary
All state lives in .map/wayfind/<slug>/state.json and is mutated ONLY through python3 .map/scripts/wayfind_runner.py <command>. You write prose only: resolution files under resolutions/, and verbatim human answers under resolutions/<ticket>.human.md. Never hand-edit state.json, map.md, or tickets/*.md — the views carry a DO-NOT-EDIT banner and are regenerated on every mutation. Every command prints a JSON result; a non-success status means stop and read the message.
See wayfind-reference.md for the full CLI reference, the fog-sharpness rubric, the ticket-type guide, and extended examples/troubleshooting. When a step points to a reference section, read it before executing the step; supporting files are not assumed to be in context automatically.
Mode selection
Parse $ARGUMENTS. The FIRST token is the explicit mode — chart, work, or handoff. There is no auto-detection. If no mode is given, run python3 .map/scripts/wayfind_runner.py wayfind_status to show existing maps, then ask the user which mode to run.
Mint ONE session id for this run and reuse it for every claim/record/resolve below:
WAYFIND_SESSION="$(date -u +%Y%m%dT%H%M%SZ)"
Mode: chart "<loose idea>"
Start a new map. Six steps, mirroring the way a good architect opens a foggy problem.
-
Name the destination. Interview the user briefly for where this is headed (1–2 sentences). If it turns out the scope is already crisp, stop and recommend /map-plan.
-
Breadth-first interview. Walk the surface of the problem to surface the open decisions. If nothing genuinely uncertain appears, there is no frontier to chart — STOP and route to /map-plan.
-
Create the map. Pick a short slug ([a-z0-9-], ≤50 chars). Pass genuinely-unsharp concerns as fog:
python3 .map/scripts/wayfind_runner.py create_wayfind_map \
<slug> "<title>" "<destination>" --fog-json '["still-vague concern", "..."]'
Then warn the user: the map is committed by default, so grilling transcripts and prose resolutions are shared with the repo. To keep one map local, add .map/wayfind/<slug>/.gitignore with a single *.
-
Add sharp tickets. For each decision you can state as ONE sharp question right now, add a ticket. Choose the type deliberately (see the reference): research (find out), prototype (build a cheap probe — human-in-the-loop), grilling (interrogate the human — human-in-the-loop), task (a self-contained decision/chore). Keep unsharp concerns as fog via add_fog; do not pre-slice fog into fake tickets.
python3 .map/scripts/wayfind_runner.py add_ticket <slug> "<title>" <type> "<one sharp question>"
In a second pass, wire dependencies with wire_blocking (rejects cycles and unknown ids).
-
Kick off research. For each research ticket, claim_ticket it FIRST — resolve_ticket requires the ticket to be claimed by your session, so an unclaimed dispatch-then-resolve returns not_owner. Serialize these claim mutations, then you MAY dispatch research-agent subagents in parallel to gather findings; each writes to resolutions/<ticket>.md, after which you resolve_ticket it (research resolves are exempt from the one-per-session limit).
-
Stop. Show wayfind_status <slug> and tell the user to run /map-wayfind work <slug> to resolve the frontier.
Mode: work <slug> [ticket]
Resolve exactly ONE non-research decision, then stop. Five steps.
-
Load low-res. Read only .map/wayfind/<slug>/map.md. Zoom into a specific ticket with show_ticket <slug> <ticket> only when needed.
-
Claim first. Pick the named ticket, or the first frontier ticket from wayfind_frontier <slug>, and claim it BEFORE any work:
python3 .map/scripts/wayfind_runner.py claim_ticket <slug> <ticket> "$WAYFIND_SESSION"
If the result has hitl_pending: true, this is a human-in-the-loop ticket — see step 3b.
-
Resolve by type.
-
task: do the work / make the call, then write the decision prose to resolutions/<ticket>.md.
-
research: gather the answer (a subagent may help), write it to resolutions/<ticket>.md.
-
3b. prototype / grilling (human-in-the-loop): ask the human the ticket's question verbatim (AskUserQuestion for grilling; describe the cheap probe for prototype), then STOP and hand control back. Do not answer on the human's behalf. When the human replies, save their words VERBATIM to resolutions/<ticket>.human.md and register them:
python3 .map/scripts/wayfind_runner.py record_human_input <slug> <ticket> "$WAYFIND_SESSION" resolutions/<ticket>.human.md
resolve_ticket refuses a human-in-the-loop ticket until this is recorded.
-
Resolve + maintain the map. Write the one-line gist and the resolution file, then:
python3 .map/scripts/wayfind_runner.py resolve_ticket <slug> <ticket> "$WAYFIND_SESSION" "<one-line gist>" resolutions/<ticket>.md
With what you learned, keep the map honest: add_ticket newly-sharp decisions, graduate_fog a fog entry that is now sharp, or rule_out_of_scope a ticket/fog that is settled as excluded (exclusions never appear under Decisions).
-
Stop. The runner blocks a second non-research resolve in the same session by design. Report the decision and stop; start a fresh session (or /map-wayfind handoff <slug>) to continue.
Mode: handoff <slug>
When wayfind_status <slug> reports handoff_eligible: true (fog empty, no active claims, every ticket resolved or out-of-scope):
python3 .map/scripts/wayfind_runner.py emit_wayfind_handoff <slug> --remaining-risks-json '["..."]'
This writes .map/wayfind/<slug>/handoff.md (+ handoff.json) and registers a wayfind_handoff artifact-manifest stage on the current branch. If you must hand off with open items, pass --early --confirmed-by-user and confirm with the user first; the open items are folded into remaining risks so nothing is lost. Then, on a feature branch, run /map-plan --wayfind <slug> to seed the spec from the settled decisions.
Guardrails
- Do not pre-slice fog: only create a ticket when you can state its question sharply NOW (rubric in the reference). Otherwise keep it as fog.
- Resolve at most ONE non-research ticket per session; the runner enforces this.
- Out-of-scope is an exclusion, not a decision — it never graduates into the plan.
- No implementation subtasks and no code changes here — that is
/map-plan + execution.
- Never write secrets into tickets, resolutions, or the map. Warn about the commit-by-default privacy note in
chart.
- Refer to tickets by name in prose, not bare ids, so the map reads for a human.
- Honesty note: the human-in-the-loop and one-per-session checks add friction and an audit trail; they are not a mechanical guarantee. Ask the human when in doubt.
Examples
- Foggy feature:
/map-wayfind chart "rebuild checkout" → name destination, interview, create map checkout with 2 fog entries + 3 sharp tickets (1 research, 1 grilling, 1 task) → dispatch the research ticket → stop.
- Resolve one decision:
/map-wayfind work checkout → claim the grilling ticket → ask the human verbatim, stop, record their answer, resolve → stop (one non-research decision done).
- Finish:
/map-wayfind handoff checkout → all tickets resolved/out-of-scope, fog empty → emit handoff → /map-plan --wayfind checkout.
More worked examples are in wayfind-reference.md.
Troubleshooting
emit_wayfind_handoff returns not_terminal: fog, claimed, or unresolved tickets remain — resolve or rule them out, or hand off --early --confirmed-by-user.
resolve_ticket returns awaiting_human: it is a prototype/grilling ticket — record the human answer with record_human_input first.
resolve_ticket returns session_limit: you already resolved a non-research ticket this session — start a new session.
wire_blocking returns cycle: the dependency you added would close a loop — re-check the blocker direction.
- Full command reference and the fog-sharpness rubric are in wayfind-reference.md.