@gobing-ai/spur 0.3.41 → 0.3.43

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (185) hide show
  1. package/.claude-plugin/marketplace.json +15 -0
  2. package/README.md +15 -1
  3. package/config/templates/AGENTS.md +5 -3
  4. package/config/workflows/task-pipeline.yaml +113 -12
  5. package/package.json +15 -12
  6. package/plugins/README.md +655 -0
  7. package/plugins/sp/README.md +621 -0
  8. package/plugins/sp/agents/expert-spur.md +109 -0
  9. package/plugins/sp/agents/super-coder.md +126 -0
  10. package/plugins/sp/agents/super-planner.md +283 -0
  11. package/plugins/sp/agents/super-reviewer.md +154 -0
  12. package/plugins/sp/commands/dev-arch.md +30 -0
  13. package/plugins/sp/commands/dev-brainstorm.md +40 -0
  14. package/plugins/sp/commands/dev-changelog.md +28 -0
  15. package/plugins/sp/commands/dev-daily.md +29 -0
  16. package/plugins/sp/commands/dev-debug.md +29 -0
  17. package/plugins/sp/commands/dev-dogfood.md +33 -0
  18. package/plugins/sp/commands/dev-featurechange.md +130 -0
  19. package/plugins/sp/commands/dev-find-conflict.md +51 -0
  20. package/plugins/sp/commands/dev-find-issue.md +76 -0
  21. package/plugins/sp/commands/dev-find-next.md +60 -0
  22. package/plugins/sp/commands/dev-fixall.md +33 -0
  23. package/plugins/sp/commands/dev-gitmsg.md +28 -0
  24. package/plugins/sp/commands/dev-gtd.md +97 -0
  25. package/plugins/sp/commands/dev-handover.md +26 -0
  26. package/plugins/sp/commands/dev-idea.md +50 -0
  27. package/plugins/sp/commands/dev-next.md +31 -0
  28. package/plugins/sp/commands/dev-parallel.md +30 -0
  29. package/plugins/sp/commands/dev-plan.md +46 -0
  30. package/plugins/sp/commands/dev-refine.md +48 -0
  31. package/plugins/sp/commands/dev-refineall.md +65 -0
  32. package/plugins/sp/commands/dev-refresh.md +32 -0
  33. package/plugins/sp/commands/dev-reverse.md +32 -0
  34. package/plugins/sp/commands/dev-review.md +31 -0
  35. package/plugins/sp/commands/dev-run.md +63 -0
  36. package/plugins/sp/commands/dev-runall.md +83 -0
  37. package/plugins/sp/commands/dev-simplify.md +39 -0
  38. package/plugins/sp/commands/dev-unit.md +29 -0
  39. package/plugins/sp/commands/dev-verify.md +48 -0
  40. package/plugins/sp/commands/dev-verifyall.md +72 -0
  41. package/plugins/sp/commands/dev-wrap.md +48 -0
  42. package/plugins/sp/commands/dev-wrapall.md +51 -0
  43. package/plugins/sp/commands/rule-add.md +18 -0
  44. package/plugins/sp/commands/rule-refine.md +18 -0
  45. package/plugins/sp/commands/rule-scan.md +18 -0
  46. package/plugins/sp/commands/spur-init.md +22 -0
  47. package/plugins/sp/commands/workflow-add.md +18 -0
  48. package/plugins/sp/commands/workflow-refine.md +18 -0
  49. package/plugins/sp/hooks/agent-hint.ts +60 -0
  50. package/plugins/sp/hooks/careful-guard.ts +147 -0
  51. package/plugins/sp/hooks/context-post-tool.ts +325 -0
  52. package/plugins/sp/hooks/context-session-start.ts +182 -0
  53. package/plugins/sp/hooks/context-session-stop.ts +95 -0
  54. package/plugins/sp/hooks/hooks.json +51 -0
  55. package/plugins/sp/hooks/pi/guard-extension.ts +341 -0
  56. package/plugins/sp/hooks/task-write-guard.ts +84 -0
  57. package/plugins/sp/plugin.json +8 -0
  58. package/plugins/sp/scripts/batch-preflight.ts +204 -0
  59. package/plugins/sp/scripts/daily-summary/daily-summary.ts +606 -0
  60. package/plugins/sp/scripts/daily-summary/logger.ts +28 -0
  61. package/plugins/sp/scripts/dogfood-testing/detect-pipeline-driving.ts +363 -0
  62. package/plugins/sp/scripts/dogfood-testing/validate-report.ts +168 -0
  63. package/plugins/sp/scripts/feature-sync-bounded.ts +451 -0
  64. package/plugins/sp/scripts/stage-registry-adapter.ts +1341 -0
  65. package/plugins/sp/scripts/task-size-precheck.ts +202 -0
  66. package/plugins/sp/scripts/validate-commands.ts +651 -0
  67. package/plugins/sp/scripts/validate-flag-contracts.ts +875 -0
  68. package/plugins/sp/skills/brainstorm/SKILL.md +361 -0
  69. package/plugins/sp/skills/brainstorm/agents/openai.yaml +14 -0
  70. package/plugins/sp/skills/brainstorm/examples/ideation-example.md +209 -0
  71. package/plugins/sp/skills/brainstorm/metadata.openclaw +7 -0
  72. package/plugins/sp/skills/brainstorm/references/grilling-interview.md +68 -0
  73. package/plugins/sp/skills/brainstorm/references/workflows.md +255 -0
  74. package/plugins/sp/skills/branch-workflow/SKILL.md +109 -0
  75. package/plugins/sp/skills/branch-workflow/references/branch-lifecycle.md +69 -0
  76. package/plugins/sp/skills/branch-workflow/references/worktree-patterns.md +100 -0
  77. package/plugins/sp/skills/code-implementation/SKILL.md +203 -0
  78. package/plugins/sp/skills/code-implementation/references/debugging.md +64 -0
  79. package/plugins/sp/skills/code-implementation/references/implementation-patterns.md +113 -0
  80. package/plugins/sp/skills/code-improvement/SKILL.md +231 -0
  81. package/plugins/sp/skills/code-improvement/references/deepening-signals.md +205 -0
  82. package/plugins/sp/skills/code-review/SKILL.md +112 -0
  83. package/plugins/sp/skills/code-review/references/receiving-code-review.md +70 -0
  84. package/plugins/sp/skills/code-review/references/review-lenses.md +117 -0
  85. package/plugins/sp/skills/code-review/references/self-review-checklist.md +53 -0
  86. package/plugins/sp/skills/code-review/references/verification-before-completion.md +68 -0
  87. package/plugins/sp/skills/code-simplification/SKILL.md +225 -0
  88. package/plugins/sp/skills/code-testing/SKILL.md +108 -0
  89. package/plugins/sp/skills/code-testing/references/stacks/bun-ts.md +165 -0
  90. package/plugins/sp/skills/code-testing/references/stacks/go.md +88 -0
  91. package/plugins/sp/skills/code-testing/references/stacks/python.md +117 -0
  92. package/plugins/sp/skills/code-testing/references/test-loop-breaker.md +37 -0
  93. package/plugins/sp/skills/code-testing/references/test-output-discipline.md +52 -0
  94. package/plugins/sp/skills/code-testing/references/unit-testing.md +212 -0
  95. package/plugins/sp/skills/code-verification/SKILL.md +535 -0
  96. package/plugins/sp/skills/code-verification/references/code-improvement.md +39 -0
  97. package/plugins/sp/skills/code-verification/references/secu-review.md +94 -0
  98. package/plugins/sp/skills/code-verification/references/verdict-schema.md +141 -0
  99. package/plugins/sp/skills/conflict-finding/SKILL.md +254 -0
  100. package/plugins/sp/skills/conflict-finding/references/authority-resolution.md +258 -0
  101. package/plugins/sp/skills/conflict-finding/references/comparison-protocol.md +277 -0
  102. package/plugins/sp/skills/conflict-finding/references/finding-contract.md +346 -0
  103. package/plugins/sp/skills/conflict-finding/references/remediation-routing.md +276 -0
  104. package/plugins/sp/skills/daily-summary/SKILL.md +171 -0
  105. package/plugins/sp/skills/daily-summary/agents/openai.yaml +13 -0
  106. package/plugins/sp/skills/doc-evolve/SKILL.md +175 -0
  107. package/plugins/sp/skills/doc-evolve/references/operations.md +93 -0
  108. package/plugins/sp/skills/dogfood-testing/SKILL.md +608 -0
  109. package/plugins/sp/skills/dogfood-testing/references/monitor-ledger.md +211 -0
  110. package/plugins/sp/skills/dogfood-testing/references/report-template.md +351 -0
  111. package/plugins/sp/skills/doubt-driven-development/SKILL.md +136 -0
  112. package/plugins/sp/skills/functional-review/SKILL.md +364 -0
  113. package/plugins/sp/skills/functional-review/references/verdict-schema.md +133 -0
  114. package/plugins/sp/skills/indexed-context/SKILL.md +164 -0
  115. package/plugins/sp/skills/issue-finding/SKILL.md +442 -0
  116. package/plugins/sp/skills/issue-finding/agents/openai.yaml +15 -0
  117. package/plugins/sp/skills/issue-finding/examples/expected-findings.json +27 -0
  118. package/plugins/sp/skills/issue-finding/examples/session-test-loop.jsonl +23 -0
  119. package/plugins/sp/skills/issue-finding/references/session-formats.md +151 -0
  120. package/plugins/sp/skills/next-feature/SKILL.md +125 -0
  121. package/plugins/sp/skills/next-feature/references/handoff-routing.md +92 -0
  122. package/plugins/sp/skills/next-feature/references/proposal-contract.md +49 -0
  123. package/plugins/sp/skills/next-feature/references/ranking-rubric.md +52 -0
  124. package/plugins/sp/skills/next-feature/references/signal-derivation.md +67 -0
  125. package/plugins/sp/skills/next-router/SKILL.md +181 -0
  126. package/plugins/sp/skills/next-router/references/messages.md +90 -0
  127. package/plugins/sp/skills/next-router/references/routing-table.md +216 -0
  128. package/plugins/sp/skills/parallel-execution/SKILL.md +148 -0
  129. package/plugins/sp/skills/parallel-execution/references/dispatch-surface.md +109 -0
  130. package/plugins/sp/skills/parallel-execution/references/fan-out-patterns.md +101 -0
  131. package/plugins/sp/skills/parallel-execution/references/result-synthesis.md +94 -0
  132. package/plugins/sp/skills/reverse-engineering/SKILL.md +375 -0
  133. package/plugins/sp/skills/reverse-engineering/agents/openai.yaml +18 -0
  134. package/plugins/sp/skills/source-driven-development/SKILL.md +124 -0
  135. package/plugins/sp/skills/spec-decomposition/SKILL.md +117 -0
  136. package/plugins/sp/skills/spec-decomposition/references/decomposition.md +539 -0
  137. package/plugins/sp/skills/spur-cli/SKILL.md +133 -0
  138. package/plugins/sp/skills/spur-cli/references/agent.md +179 -0
  139. package/plugins/sp/skills/spur-cli/references/features/acceptance-criteria.md +82 -0
  140. package/plugins/sp/skills/spur-cli/references/features/hierarchy-mece.md +177 -0
  141. package/plugins/sp/skills/spur-cli/references/features/roadmap-priority.md +84 -0
  142. package/plugins/sp/skills/spur-cli/references/features/verbs.md +122 -0
  143. package/plugins/sp/skills/spur-cli/references/features.md +234 -0
  144. package/plugins/sp/skills/spur-cli/references/init.md +119 -0
  145. package/plugins/sp/skills/spur-cli/references/message.md +98 -0
  146. package/plugins/sp/skills/spur-cli/references/rules/authoring-rules.md +212 -0
  147. package/plugins/sp/skills/spur-cli/references/rules/fine-tuning.md +148 -0
  148. package/plugins/sp/skills/spur-cli/references/rules/operations.md +228 -0
  149. package/plugins/sp/skills/spur-cli/references/rules/validation-and-extension.md +129 -0
  150. package/plugins/sp/skills/spur-cli/references/rules.md +209 -0
  151. package/plugins/sp/skills/spur-cli/references/serve.md +58 -0
  152. package/plugins/sp/skills/spur-cli/references/tasks/l3-guard-cheatsheet.md +98 -0
  153. package/plugins/sp/skills/spur-cli/references/tasks/section-editing.md +95 -0
  154. package/plugins/sp/skills/spur-cli/references/tasks/verbs.md +361 -0
  155. package/plugins/sp/skills/spur-cli/references/tasks.md +280 -0
  156. package/plugins/sp/skills/spur-cli/references/team.md +133 -0
  157. package/plugins/sp/skills/spur-cli/references/workflows/authoring-workflows.md +226 -0
  158. package/plugins/sp/skills/spur-cli/references/workflows/operations.md +211 -0
  159. package/plugins/sp/skills/spur-cli/references/workflows/validation-and-extension.md +129 -0
  160. package/plugins/sp/skills/spur-cli/references/workflows.md +355 -0
  161. package/plugins/sp/skills/spur-dev/SKILL.md +224 -0
  162. package/plugins/sp/skills/spur-dev/references/ac-style-guide.md +196 -0
  163. package/plugins/sp/skills/spur-dev/references/cross-cutting.md +680 -0
  164. package/plugins/sp/skills/spur-dev/references/decision-brief.md +80 -0
  165. package/plugins/sp/skills/spur-dev/references/dev-operations.md +546 -0
  166. package/plugins/sp/skills/spur-dev/references/done-housekeeping.md +164 -0
  167. package/plugins/sp/skills/spur-dev/references/execution-batch.md +790 -0
  168. package/plugins/sp/skills/spur-dev/references/execution-workflow.md +352 -0
  169. package/plugins/sp/skills/spur-dev/references/feature-link-helper.md +191 -0
  170. package/plugins/sp/skills/spur-dev/references/flag-glossary.md +417 -0
  171. package/plugins/sp/skills/spur-dev/references/gate-checklists.md +171 -0
  172. package/plugins/sp/skills/spur-dev/references/glossary.md +95 -0
  173. package/plugins/sp/skills/spur-dev/references/idea-evaluation.md +80 -0
  174. package/plugins/sp/skills/spur-dev/references/inline-pipeline-driver.md +120 -0
  175. package/plugins/sp/skills/spur-dev/references/planning-workflow.md +302 -0
  176. package/plugins/sp/skills/spur-dev/references/product-planning.md +206 -0
  177. package/plugins/sp/skills/spur-dev/references/section-batching.md +24 -0
  178. package/plugins/sp/skills/sys-architecture/SKILL.md +155 -0
  179. package/plugins/sp/skills/sys-architecture/references/decision-method.md +137 -0
  180. package/plugins/sp/skills/sys-architecture/references/upkeep-survey.md +75 -0
  181. package/plugins/sp/skills/sys-debugging/SKILL.md +228 -0
  182. package/plugins/sp/skills/sys-debugging/references/debugging-protocol.md +62 -0
  183. package/plugins/sp/skills/test-driven-development/SKILL.md +248 -0
  184. package/plugins/sp/skills/wayfinder/SKILL.md +292 -0
  185. package/spur.js +6035 -4963
@@ -0,0 +1,292 @@
1
+ ---
2
+ name: wayfinder
3
+ description: "Chart a multi-session investigation map when the destination is too foggy to spec in one session. Creates a spur feature as the map, decomposes specifiable questions into spur tasks, and resolves them one at a time until the route becomes visible. Triggers: wayfind, chart a course, multi-session investigation, --wayfind."
4
+ license: Apache-2.0
5
+ version: 1.0.0
6
+ created_at: 2026-07-06
7
+ updated_at: 2026-07-06
8
+ type: technique
9
+ platform: sp
10
+ tags: [wayfinding, investigation, multi-session, fog-of-war, map, exploration, workflow-core]
11
+ metadata:
12
+ author: sp
13
+ platforms: "claude-code,codex,antigravity,opencode,openclaw"
14
+ category: workflow-core
15
+ interactions:
16
+ - reviewer
17
+ - pipeline
18
+ severity_levels:
19
+ - high
20
+ - medium
21
+ - low
22
+ pipeline_steps:
23
+ - chart
24
+ - resolve
25
+ see_also:
26
+ - sp:brainstorm
27
+ - sp:spur-dev
28
+ - sp:spur-cli
29
+ - sp:code-implementation
30
+ - sp:spec-decomposition
31
+ ---
32
+
33
+ # sp:wayfinder — Multi-Session Investigation Map
34
+
35
+ When a loose idea is too big and foggy to spec in one session, wayfinding charts a persistent map of investigation tickets and resolves them one at a time until the route to the destination becomes visible.
36
+
37
+ **Key distinction:**
38
+ - **`sp:brainstorm`** = Ideation: generate approaches when the destination IS clear enough to decompose
39
+ - **`sp:wayfinder`** = Wayfinding: chart a map when the destination ITSELF is foggy — the spec is the destination, not the input
40
+ - **`sp:spur-dev`** = Execution: drive tasks through the pipeline once they're specifiable
41
+ - **`sp:spec-decomposition`** = Decomposition: break a clear spec into tasks
42
+
43
+ ## Overview
44
+
45
+ sp's standard flow is brainstorm → spec → decompose → implement — it assumes the destination is clear enough to decompose. Wayfinder handles the case where **the spec itself is the destination**, requiring multiple sessions of investigation to even write. It charts the way as a **spur feature** (the map) with child **spur tasks** (investigation tickets), then resolves them one at a time until the route is clear.
46
+
47
+ The destination varies per effort — it might be a spec to hand off, a decision to lock before planning starts, or a change made in place like a data-structure migration. Naming it is the first act of charting; it shapes every ticket.
48
+
49
+ ## When to Use
50
+
51
+ Activate sp:wayfinder when:
52
+
53
+ | Trigger Phrase | Description |
54
+ |----------------|-------------|
55
+ | "wayfind" / "chart a course" | User explicitly requests wayfinding |
56
+ | "this is too big to spec" | The idea exceeds one session's capacity |
57
+ | "multi-session investigation" | User expects multiple sessions to reach clarity |
58
+ | "find the way to X" | Destination is named but the route is unknown |
59
+ | "explore the solution space" | Open-ended exploration before committing |
60
+ | `--wayfind` flag on `/sp:dev-brainstorm` | Power-user skip straight to charting |
61
+
62
+ **NOT for:**
63
+ - A clear spec that just needs decomposition (use `sp:spec-decomposition` instead)
64
+ - A well-understood problem needing solution options (use `sp:brainstorm` instead)
65
+ - A single-session fix or feature (use `sp:spur-dev` instead)
66
+ - Pure research without a destination (use `spur agent run` for research instead)
67
+
68
+ ## Core Principles
69
+
70
+ ### 1. The Map Is a Spur Feature — but decisions are not tasks
71
+
72
+ The map is a `spur feature` — its description IS the map body. sp already has the nouns (feature, task, dependency graph, WBS, status lifecycle), so no new data model is needed.
73
+
74
+ **Only executable investigations become `spur task` children.** A task file is work to be done, not a question to be answered — see [`../spur-dev/references/cross-cutting.md`](../spur-dev/references/cross-cutting.md) § What belongs in a task file. Apply its test to every candidate:
75
+
76
+ | Candidate | Where it lives |
77
+ |---|---|
78
+ | Research, prototype, inventory, measurement — an implementer can execute it and produce an artifact | **`spur task`** child of the map |
79
+ | A decision needing the operator's judgment — "decide X", "choose A or B", "what should the contract be" | **`## Open questions`** on the map body, never a task |
80
+
81
+ A decision filed as a task sits in the feature's Tasks table looking like queued work, gets handed to an implementing agent, and is either stalled on or invented. Resolve open questions in conversation with the operator; record the answer in **`## Decisions so far`**; then create tasks for whatever work the answer implies.
82
+
83
+ **Shippable destinations:** If the map destination is a **shippable implementation** (code lands, not design-doc-only), research and prototype tickets alone are not “feature done.” After investigation tickets close, graduate implement work into tasks; close the map only when `/sp:dev-verifyall --feature <id> --fix all` reports **`Shippable: PASS`** (or use `--skip-shippable` only for deliberate non-ship audits). Per-task research PASS is not enough — see `sp:code-verification` Step 13.
84
+
85
+ ### 2. The Destination Fixes the Scope
86
+
87
+ The destination is a one-line statement of what reaching the end of this map looks like — the spec, decision, or change this effort is finding its way to. Every session orients to it before choosing a ticket. Scope is fixed by the destination: work beyond it is out of scope, not fog.
88
+
89
+ ### 3. One Ticket Per Session
90
+
91
+ **Never resolve more than one ticket per session.** Multiple tickets in one session defeat the purpose — deliberate, bounded investigation steps. This pairs naturally with sp's batch execution model: the batch driver can loop over frontier tickets one per session.
92
+
93
+ ### 4. Claim Before Work
94
+
95
+ A session claims a ticket by transitioning it to `wip` (`spur task update <wbs> wip`) **before any work begins**. This prevents concurrent sessions from colliding on the same ticket.
96
+
97
+ ### 5. Refer by Name
98
+
99
+ Every map and ticket has a name — its title. In everything the operator reads, refer to it by WBS + title, never by a bare WBS number. A wall of bare numbers is illegible; names read at a glance.
100
+
101
+ ### 6. The Map Is an Index, Not a Store
102
+
103
+ The map lists 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.
104
+
105
+ ## Process
106
+
107
+ Two modes. Either way, **never resolve more than one ticket per session.**
108
+
109
+ ### Chart the Map
110
+
111
+ Invoked when the operator has a loose idea and the destination itself is foggy. Charting IS one session's work — do not also resolve tickets.
112
+
113
+ 0. **Branch first.** `git checkout -b wayfind/<destination-slug>` before touching the map. A session is what spans the fog edit and the tickets it graduates into — routinely separate commits — so the branch point is the only boundary that contains both. The `corpus.ungraduated-fog` gate measures `merge-base(origin/main, HEAD)..(working tree)`, which means it **cannot fire at all** on work done directly on the default branch. That is exactly how the 2026-08-07 incident shipped.
114
+ 1. **Name the destination.** Run a discovery interview (one question at a time, always with a recommendation) to pin down what this map is finding its way to — the spec, decision, or change. The destination fixes the scope, so it's settled first.
115
+ 2. **Map the frontier breadth-first.** Fan out across the whole space rather than deep on any one thread, surfacing open decisions and the first steps takeable now. Use the decision-brief format for each HITL choice (see `../spur-dev/references/decision-brief.md`).
116
+ 3. **Create the map as a spur feature.** `spur feature create "<destination>"`. The feature description carries:
117
+ - **## Destination** — the one-line destination statement
118
+ - **## Notes** — domain context, skills every session should consult, standing preferences. Fog and scope cuts live **under** Notes as `###` subsections, not as standalone `##` sections — the `corpus.ungraduated-fog` gate matches `### Not yet specified` and `### Out of scope` (nested under Notes), so a top-level `##` heading the gate cannot see is a defect, not a style preference.
119
+ - **## Open questions** — sharp decisions that need the operator's judgment. These are **never tasks**. Each carries the question, why only the operator can settle it, and what it blocks. Resolved in conversation, then moved to Decisions so far.
120
+ - **## Decisions so far** — empty on creation; populated as questions and tickets resolve (one line each: the decision, or WBS + title + one-line gist)
121
+ - **### Not yet specified** — the fog of war: in-scope questions you can sense but can't yet phrase sharply enough to ticket. Nest under `## Notes`.
122
+ - **### Out of scope** — work consciously ruled beyond this destination. Nest under `## Notes`.
123
+ - **Tag the feature as a wayfinder map.** `spur feature update <id> --section tags --from-file <(printf '["wayfinder-map"]')`. The `wayfinder-map` tag tells `feature check` to skip BDD AC validation — maps deliberately carry a prose no-AC disclaimer instead of Gherkin scenarios, so without the tag the checker flags a false error.
124
+ 4. **Create child tasks only for executable investigations.** `spur task create "<title>" --feature <feature-id>` for each sharp question **an implementer can answer without the operator** — research, prototype, inventory, measurement. Anything needing the operator's judgment goes to **## Open questions** instead. Ticket types (see below) determine which skill resolves the tasks.
125
+ 5. **Wire blocking edges.** After all tickets exist (they need IDs before they can reference each other), set dependencies via `spur task update`. Wiring sorts tickets into the frontier (open, unblocked, unclaimed) and the blocked.
126
+ 6. **Populate the fog.** Everything you can't yet specify stays in **### Not yet specified** — sketch it as loosely or as fully as the view allows. Don't pre-slice fog into ticket-sized pieces; one patch may graduate into several tickets, or none.
127
+ 7. **Stop.** Charting is one session's work.
128
+
129
+ ### Work Through the Map
130
+
131
+ Invoked when a map already exists (operator provides the feature ID). A ticket is **optional** — without one, pick the next frontier ticket, not the operator's preference.
132
+
133
+ 0. **Branch first.** `git checkout -b wayfind/<wbs>-<slug>`, for the same reason as charting: steps 6 and 7 below remove fog from the map, and the gate that checks the removal was paid for measures the branch, not the commit. On the default branch the check silently passes no matter what you delete.
134
+ 1. **Load the map** — the feature description (the low-res view), not every task body. Read the destination and Decisions-so-far to orient.
135
+ 2. **Pick the first frontier ticket.** Query: `spur task list --feature <id> --status todo` — the first open, unblocked, unclaimed task. If the operator named one, use it instead.
136
+ 3. **Claim it.** `spur task update <wbs> wip` — before any work.
137
+ 4. **Resolve it per its type.** Zoom as needed: read related or closed ticket bodies on demand. Consult the skills the feature's **## Notes** block names.
138
+
139
+ | Ticket Type | Resolution method | Records |
140
+ |---|---|---|
141
+ | **Research** | Fact-finding, doc reading, API exploration. Delegate to `sp:brainstorm` or deep-research via `spur agent run`. | Linked summary as a task artifact |
142
+ | **Prototype** | Cheap, rough, concrete artifact to react to — an outline, stub, or rough implementation via `sp:code-implementation`. | Linked prototype as a task artifact |
143
+ | **Task** | Literal manual work — nothing to prototype or research. Moving data, provisioning access. | Checklist in task body; resolved when done |
144
+
145
+ An open question from the map is **not** resolved this way. It is settled with the operator in
146
+ conversation (`AskUserQuestion` where available) and recorded straight into **## Decisions so far**
147
+ — no task is claimed, and it does not consume the session's one ticket.
148
+
149
+ 5. **Record the resolution.** Post the answer in the task body, then `spur task update <wbs> done`. Append one line to the map's **## Decisions so far**: `- [<WBS> <title>](path) — <one-line gist of the answer>`.
150
+ 6. **Graduate fog into new tickets.** Any fog the answer has made specifiable becomes fresh child tasks (create-then-wire). Clear each graduated patch from **### Not yet specified** so it lives only as its new ticket. Doing half of this — deleting the fog without creating the ticket — destroys the only record the work was ever identified, so `corpus-check` fails the branch (`corpus.ungraduated-fog`) unless the removal is matched by a new/re-parented ticket or a line in **### Out of scope**.
151
+ 7. **Rule out mis-scoped tickets.** If the answer reveals a ticket sits beyond the destination, close it and add one line to **### Out of scope** (the gist + why it's out of scope, linking the closed ticket). A scope boundary is not a step on the route — it stays out of **## Decisions so far**.
152
+ 8. **Stop after ONE ticket.** Never resolve more than one per session.
153
+
154
+ ### Ticket Types
155
+
156
+ Each ticket carries its type in the task body or a tag, signaling which skill resolves it. **Every type here is executable by an implementer** — that is what makes it a task at all. Decisions are not on this list; they live in the map's `## Open questions`.
157
+
158
+ | Type | Label | Resolved by | When to use |
159
+ |------|-------|-------------|-------------|
160
+ | Research | `wayfinder:research` | `sp:brainstorm` / `spur agent run` | Knowledge outside the current working directory is required |
161
+ | Prototype | `wayfinder:prototype` | `sp:code-implementation` (rough take) | "How should it look/behave?" is the key question |
162
+ | Task | `wayfinder:task` | Manual checklist | Literal work with nothing to decide, prototype, or research |
163
+
164
+ ### Fog of War
165
+
166
+ The map is **deliberately incomplete**: don't chart what you can't yet see. Beyond the live tickets lies the fog of war — the dim view of decisions and investigations 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.
167
+
168
+ The map's **### Not yet specified** section (nested under `## Notes`) is where that dim view is written down: the suspected question, the area to revisit later. It's the undiscovered frontier toward the destination — everything here is in scope, just not sharp enough to ticket.
169
+
170
+ **Ask, merge, ticket, or fog?** Sharpness alone does not earn a ticket — a ticket costs a whole session, so it must also need one *and* be worth one on its own. Apply the tests in this order:
171
+
172
+ 1. **Ask now when** the question is sharp **and the operator already holds the answer** — a preference, a scope call, a ruling only they can make. These are decision briefs, not investigations. Put them to the operator in the charting session (`AskUserQuestion` where available), record the answer directly in **## Decisions so far**, and never create a ticket. A ticket here buys nothing and costs a session.
173
+ 2. **Merge when** the question is sharp and needs real work, **but a sibling ticket's session would answer it anyway** — same files, same sources, same body of evidence, or one is unreadable without the other. Cohesion beats sharpness: two sharp questions answered by one investigation are **one ticket**. See [`../spur-dev/references/cross-cutting.md`](../spur-dev/references/cross-cutting.md) § Task sizing.
174
+ 3. **Ticket when** the question is sharp, answering it needs real work, no sibling covers it, **and an implementer can execute it without the operator** — research, a prototype, a codebase inventory, a measurement. Blocked-but-sharp still tickets.
175
+ 3b. **Open question when** it is sharp and needs deciding but the operator holds the judgment and is not available right now. It goes to the map's **## Open questions**, never to a task. This is test 1's deferred form: the answer still comes from the operator, just in a later session.
176
+ 4. **Not yet specified when** you can't yet phrase the question sharply. Don't pre-slice the fog into ticket-sized pieces: it's coarser than a ticket, and one patch may graduate into several tickets, or none, once the frontier reaches it.
177
+
178
+ Three failure modes this prevents:
179
+
180
+ - Charting a map, then watching the operator answer half the tickets in their next message. Those were briefs mis-filed as tickets (test 1) — consolidate them and record the answers.
181
+ - Charting a map the operator sends back as over-sliced. Those were cohesive investigations split across tickets (test 2). Splitting one body of evidence across several sessions is worse than merging: each session re-derives the same context, and no session sees the whole picture.
182
+ - Filing a decision as a task (test 3 vs 3b). It then sits in `spur task list` looking like queued work; an implementing agent picks it up and either stalls or invents the decision and calls it done. Task files are work to be done, not questions to be answered.
183
+
184
+ **Sanity check before creating the tickets:** count them. A first cut above ~5 is a signal, not a plan — re-run test 2 across every pair before writing anything. Prefer the coarser map; a ticket that turns out to hold two questions can be split when the frontier reaches it, but a session spent on a fragment is spent.
185
+
186
+ **Not yet specified** excludes what's already decided (Decisions so far), what's already a live ticket, and what's out of scope.
187
+
188
+ ### Out of Scope
189
+
190
+ Fog only ever gathers toward the destination. The destination fixes the scope, so work beyond it is out of scope — it isn't fog, and it doesn't belong in **### Not yet specified**. It gets its own **### Out of scope** section on the map (nested under `## Notes`): work consciously ruled out of this effort.
191
+
192
+ Out-of-scope work never graduates — the frontier stops at the destination — so it returns only if the destination is redrawn, and then as a fresh effort, not a resumption.
193
+
194
+ Ruling something out of scope is a scoping act, not a step on the route. When a ticket that already exists turns out to sit past the destination, close it and leave one line in **### Out of scope**: the gist plus why it's out of scope, linking the closed ticket.
195
+
196
+ ## Invocation
197
+
198
+ ### From `/sp:dev-brainstorm` (semi-automatic escalation)
199
+
200
+ At the end of the discovery interview (Phase 1), the brainstorm command runs a **scope check**: "Can this be spec'd in one session, or is the destination itself still foggy?" If foggy, it offers wayfinding as the escalation path:
201
+
202
+ > *"This is a multi-session investigation. Want me to chart a wayfinder map so we can work through it one decision at a time?"*
203
+
204
+ The operator confirms before wayfinding begins — never silently escalate. The `--wayfind` flag on `/sp:dev-brainstorm` skips the prompt and enters wayfinding directly.
205
+
206
+ ### Direct invocation
207
+
208
+ The operator invokes this skill directly: `Skill(skill="sp:wayfinder", args="<loose idea or feature ID>")`. If the argument is a feature ID, enter "Work through the map" mode. Otherwise, enter "Chart the map" mode.
209
+
210
+ ## Common Rationalizations
211
+
212
+ | Rationalization | Reality |
213
+ |---|---|
214
+ | "I can spec this now if I just think hard enough." | A foggy destination isn't a thinking-harder problem — it's a missing-information problem. Chart the map and resolve one ticket to get the first missing piece. |
215
+ | "Let me resolve a few tickets while I'm here — it's efficient." | Multiple tickets in one session defeat the purpose. Each resolution clears fog that changes what the next ticket should ask. Stop after one. |
216
+ | "The fog section is vague — skip it and just create tickets for what's clear." | The fog IS the value. It tells the next session (or another operator) where the effort is headed and what's suspected but not yet sharp. An empty fog section hides the known-unknowns. |
217
+ | "I'll auto-escalate to wayfinding when the topic looks big." | Scope judgment needs human confirmation. A 30-minute quick-answer need might touch a big domain without requiring a multi-session map. Always ask. |
218
+ | "The map feature description is just boilerplate — the tasks are what matter." | The map is the orienting artifact every session loads first. Without a clear destination and running Decisions-so-far log, each session re-derives context from scratch. |
219
+ | "I'll pre-slice the fog into ticket stubs so the map looks more complete." | Pre-sliced fog is noise — it creates tickets for questions you can't yet phrase, which wastes time and may point the wrong direction once earlier tickets resolve. |
220
+ | "Making it a task gives the decision a WBS, a status, and a place in the queue." | Those are exactly the reasons not to. A decision with a WBS looks like queued work to every agent and dashboard that reads the corpus, and an implementer handed it will invent the answer rather than stall. The map's **## Open questions** gives it a home without pretending it is executable. |
221
+ | "More tickets make the map look thorough." | A ticket costs a session. If the operator answers it in their next message, it was a decision brief mis-filed as a ticket — ask those during charting and record them in Decisions so far. |
222
+ | "These are two distinct questions, so they're two tickets." | Distinctness is not the test — cohesion is. If one investigation's evidence answers both, they're one ticket. A map is judged by how few sessions reach the destination, not by how many questions it enumerates. |
223
+ | "I'll ticket the secondary sources now and handle the primary ones downstream." | Backwards. The sources or files the operator cares most about belong in the *first* discovery ticket. Deciding a contract on evidence from the peripheral cases is how a map ends up re-derived later. |
224
+
225
+ ## Red Flags
226
+
227
+ - Resolving more than one ticket in a single session.
228
+ - Charting or resolving directly on the default branch — the `corpus.ungraduated-fog` gate is branch-scoped, so on `main` fog can be deleted with no ticket and nothing complains.
229
+ - Creating a map without a destination statement — the destination fixes scope; without it, every ticket is unbounded.
230
+ - Auto-escalating to wayfinding without operator confirmation (except under `--wayfind`).
231
+ - An empty or missing **### Not yet specified** section when the destination was described as foggy — fog that isn't written down is fog the next session can't see.
232
+ - Skipping the claim step (`spur task update <wbs> wip`) before work — concurrent sessions may collide.
233
+ - Pre-slicing fog into ticket stubs before the questions are sharp.
234
+ - Ticketing a question the operator could answer on the spot — a preference or scope ruling is a decision brief, not an investigation ticket.
235
+ - A ticket whose deliverable is a decision ("decide X", "choose A or B", "what should the contract be"). Task files are work to be done; that belongs in **## Open questions**.
236
+ - Two tickets that would read the same files or the same sources to answer — that is one investigation split in two.
237
+ - A discovery ticket that omits the operator's primary subjects while a downstream ticket covers them.
238
+ - A first cut above ~5 tickets that was written without re-checking every pair for cohesion.
239
+ - Referring to tickets by bare WBS number instead of WBS + title.
240
+ - Treating wayfinding as a replacement for brainstorming — wayfinding is for when the destination ITSELF is foggy, not for generating options toward a clear destination.
241
+
242
+ ## Verification
243
+
244
+ ### Charting verification
245
+
246
+ - [ ] The session ran on its own branch, not the default branch (`git branch --show-current`).
247
+ - [ ] Destination is a single, concrete sentence (not a paragraph, not a vague noun phrase).
248
+ - [ ] Map feature exists (`spur feature show <id>` returns clean).
249
+ - [ ] Feature description has all six sections: Destination, Notes, Open questions, Decisions so far (empty), Not yet specified, Out of scope.
250
+ - [ ] No task's deliverable is a decision — every ticket is executable by an implementer without the operator. Decisions sit in **## Open questions**.
251
+ - [ ] Every specifiable question has a child task with a sharp, answerable question in its body.
252
+ - [ ] Blocking edges are wired (tasks that depend on others list them in their dependency graph).
253
+ - [ ] No ticket pre-slices fog — every ticket's question is precise enough to answer in one session.
254
+ - [ ] No two tickets would be answered by the same investigation — every pair passed the cohesion test (§ Fog of War, test 2).
255
+ - [ ] The operator's primary subjects are covered by a frontier ticket, not deferred behind one.
256
+
257
+ ### Resolution verification
258
+
259
+ - [ ] The session ran on its own branch, not the default branch (`git branch --show-current`).
260
+ - [ ] Exactly one ticket was resolved this session.
261
+ - [ ] The ticket was claimed (`wip`) before work began.
262
+ - [ ] The resolution is recorded in the task body (not just a status transition — the answer is written down).
263
+ - [ ] The map's **## Decisions so far** has one new line: WBS + title + one-line gist.
264
+ - [ ] Any graduated fog was removed from **### Not yet specified** and created as new child tasks.
265
+ - [ ] Any mis-scoped tickets were closed and recorded in **### Out of scope**.
266
+
267
+ ## Reference Files
268
+
269
+ - **`../spur-dev/references/decision-brief.md`** — Decision-brief format for HITL choices during charting
270
+ - **`../spur-dev/references/cross-cutting.md`** — Verification-before-completion rule (one-ticket-per-session discipline)
271
+ - **`../spur-dev/references/execution-batch.md`** — Batch execution model (pairs with one-ticket-per-session loop)
272
+
273
+ ## Platform Notes
274
+
275
+ ### Claude Code
276
+
277
+ - Use `Skill(skill="sp:brainstorm", args="dev-brainstorm --context ...")` for research tickets
278
+ - Use `Skill(skill="sp:code-implementation", ...)` for prototype tickets
279
+ - Use `AskUserQuestion` to settle the map's open questions — they are conversations, not tickets
280
+ - Use `Bash` with `spur` CLI for all task/feature operations
281
+ - Use `AskUserQuestion` for the scope-check confirmation
282
+
283
+ ### Other Platforms
284
+
285
+ - Delegate research via `spur agent run`
286
+ - Delegate task/feature operations via `spur` CLI
287
+ - Charting and resolution protocol is platform-agnostic
288
+ - Output format is platform-agnostic markdown
289
+
290
+ ---
291
+
292
+ **Remember:** Wayfinding is about finding the way, not charging at the destination. Chart deliberately. Resolve one ticket at a time. The map is the shared artifact that survives session boundaries — keep it current.