Compare commits

...
Author SHA1 Message Date
Matt PocockandClaude Opus 4.8 af6d6922c3 Drop Negative Space; keep Negation only
Negative Space read as clever but not actionable — "notice your
silences" is fuzzy legwork the agent can't reliably act on. Negation
stays: a checkable authoring failure with a positive-instruction cure.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-06 13:57:05 +01:00
Matt PocockandClaude Opus 4.8 30afefecc9 changeset for Negation and Negative Space failure modes
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-06 13:56:16 +01:00
Matt PocockandClaude Opus 4.8 0847bb31bc writing-great-skills: add Negation and Negative Space failure modes
Two adjacent Steering failure modes about how language you think of as
"off" still steers:

- Negation — a prohibition names the forbidden behaviour and makes it
  more available, not less (don't-think-of-an-elephant). Cure: prompt
  the positive.
- Negative Space — what you omit is delegated to the agent's priors,
  not left neutral. Cure: read a draft for what it's silent on and
  decide each omission deliberately.

Each carried as a full GLOSSARY entry plus a SKILL.md failure-mode
bullet, matching every other failure mode.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-06 13:54:46 +01:00
Matt PocockandGitHub 66f92b61f5 Merge pull request #456 from mattpocock/wayfinder-deferred-section
wayfinder: split the map catch-all into Not yet specified / Out of scope
2026-07-05 18:37:09 +01:00
Matt PocockandClaude Opus 4.8 97dca07b64 Duplication pass: collapse restated out-of-scope mechanics
- Out of scope section: drop embedded 'however sharply you can see it'
  duplicate; the 'Scope, not sharpness, lands it here' punchline carries
  the claim once.
- Work-through step 5: delegate close+one-line mechanics to the Out of
  scope section via the 'rule it out of scope' leading phrase instead of
  restating them.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-05 17:48:56 +01:00
Matt PocockandClaude Opus 4.8 7d34a8dc38 Split fog and out-of-scope into separate explanatory sections
QA follow-up: the Fog of war section was teaching both concepts, which
muddies the leading word — fog should point only *toward* the
destination. Now Fog of war teaches only the not-yet-specified bucket
(with the two-way fog-or-ticket sharpness test restored), and a new
Out of scope section owns the scope axis: beyond the destination,
closed not graduating, kept out of Decisions so far.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-05 17:44:13 +01:00
Matt PocockandClaude Opus 4.8 3ea01314c1 Rename the two buckets to plain map headings: Not yet specified / Out of scope
Following review: the map-body headings a cold reader sees should be
self-evident without having read the skill, so drop the metaphor from
the headings — `## Not yet specified` (in-scope, unripe) and
`## Out of scope` (beyond the destination). Keep **fog of war** as the
leading word: it still titles the explanatory section and drives the
"clears the fog" / "graduate the fog" behavior in the prose.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-05 17:35:50 +01:00
Matt PocockandClaude Opus 4.8 299eb0c017 Give wayfinder a distinct Deferred section for beyond-destination work
Fog is the undiscovered frontier *toward* the destination — in scope,
just not yet sharp — so it graduates into tickets as the frontier
advances. Work ruled out of *this* effort's scope was being parked in
Fog too, where it read as takeable frontier (an unblocked, unclaimed
ticket is indistinguishable from a live one).

Add a dedicated `## Deferred` section for beyond-the-destination work:
it never graduates (the frontier stops at the destination) and returns
only as a fresh effort if the destination is redrawn. The "Fog or
ticket?" test becomes "Fog, ticket, or deferred?", gated on scope as
well as sharpness, and both charting and working-the-map now defer a
mis-scoped ticket (close it, one line in Deferred) rather than leaving
it on the frontier or logging it in Decisions so far.

Builds on #455 (destination as the leading word / destination fixes
scope).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-05 15:08:48 +01:00
Matt PocockandGitHub 4691566bbb Merge pull request #455 from mattpocock/wayfinder-destination-purpose
Reframe wayfinder around "destination" as the leading word
2026-07-05 15:03:18 +01:00
Matt PocockandClaude Opus 4.8 913a105881 Split charting triage into two grilling steps: destination, then frontier
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-05 15:02:39 +01:00
Matt PocockandClaude Opus 4.8 c808f64f92 Make triage step 1 breadth-first: fix scope, then find the frontier
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-05 15:00:34 +01:00
Matt PocockandClaude Opus 4.8 53c6219cd2 Reframe wayfinder around "destination" as the leading word
Wayfinding finds the way to a destination rather than building it. The
destination varies per effort and is named first, since it shapes every
ticket. Adds a Destination map-body field, makes it triage step 1, and
unifies the stray "goal" mentions onto "destination".

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-05 14:57:57 +01:00
Matt PocockandGitHub 272f99b225 Merge pull request #436 from mattpocock/wayfinder-assign-to-claim
wayfinder: claim by assigning the ticket, not a label
2026-07-03 11:37:11 +01:00
Matt PocockandClaude Opus 4.8 6f9e9956fd wayfinder: claim by assigning the ticket, not a label
A session now claims a ticket by assigning it to the dev driving the
map, rather than setting a `wayfinder:claimed` label. The assignee is
the claim; an open, unassigned ticket is unclaimed. Reads more naturally
in the tracker's own UI and frees the label vocabulary to
`wayfinder:<type>` alone.

Updates the GitHub and GitLab tracker-operations docs to the assignee
mechanism (`--add-assignee @me` / `--assignee @me`). The local-markdown
tracker keeps its `Status: claimed` line — a file store has no assignee.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-03 11:34:42 +01:00
Matt PocockandGitHub efa058a349 Merge pull request #435 from mattpocock/wayfinder-native-blocking-rationale
wayfinder: prefer native blocking, and say why
2026-07-03 10:44:51 +01:00
Matt PocockandClaude Opus 4.8 8c2a4c554a wayfinder: tighten blocking rule, update GH/GL templates
Concision pass on the blocking rule (fold the "wherever the tracker has
one" clause into the fallback sentence; drop restatements). Bring the
GitHub and GitLab issue-tracker templates up to the same standard: the
GitHub template now carries the native issue-dependencies recipe and
frontier query; the GitLab template names the native /blocked_by link
(Premium/Ultimate) with the body-convention fallback.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-03 10:42:56 +01:00
Matt PocockandClaude Opus 4.8 b289481499 wayfinder: prefer native blocking, and say why
The blocking rule now leads with the tracker's native dependency
relationship and encodes the rationale: native rendering makes the
frontier visible in the tracker's own UI, so the human sees what's
takeable without opening the map. Notes the body-convention fallback
for trackers that lack native blocking (GitHub has it; GitLab only on
paid tiers).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-03 10:39:04 +01:00
Matt PocockandGitHub e9dea692fd Merge pull request #434 from mattpocock/fix/tdd-code-review-reference
docs: fix tdd skill reference to code-review skill
2026-07-03 10:02:26 +01:00
Matt PocockandClaude Opus 4.8 bd453a6742 docs: fix tdd skill reference to code-review skill
The tdd skill pointed at a `review` skill that no longer exists; the
review skill is now named `code-review`. Update the reference.

Fixes #432

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-03 09:53:34 +01:00
Matt PocockandGitHub aed86f6b35 Merge pull request #433 from mattpocock/grilling-gate-and-leading-word
grilling: add confirmation gate and grill leading word
2026-07-03 09:49:36 +01:00
11 changed files with 89 additions and 27 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"mattpocock-skills": minor
---
Add two adjacent Steering failure modes to **`writing-great-skills`**, both about how language you think of as "off" still steers the agent. **Negation** — the _elephant_ — is steering by prohibition: naming what _not_ to do drags the forbidden behaviour into context and makes it _more_ available, not less (_don't think of an elephant_), so the cure is to prompt the **positive**. **Negative Space** — the void — is blindness to the steering done by what you leave _out_: every decision a skill declines is delegated to the agent's priors rather than left neutral, so the cure is to read a draft for its silences and decide each omission deliberately (fill it, or leave it open as a real **branch**). Kept as two entries, not one — they carry different diagnostics and different cures — each a full `GLOSSARY.md` entry plus a `SKILL.md` failure-mode bullet, matching how every other failure mode is carried.
+7
View File
@@ -0,0 +1,7 @@
---
"mattpocock-skills": minor
---
Change **`wayfinder`**'s claim mechanism from a label to an assignee.
A session now **claims** a ticket by assigning it to the dev driving the map, rather than setting a `wayfinder:claimed` label. The assignee _is_ the claim — an open, unassigned ticket is unclaimed — which reads more naturally in GitHub's own UI and frees the label vocabulary to `wayfinder:<type>` alone. The *claim* leading word and its "first, before any work" rationale are unchanged; only the physical expression moved.
+11
View File
@@ -0,0 +1,11 @@
---
"mattpocock-skills": minor
---
Give **`wayfinder`** a first-class notion of **out of scope**, separate from fog.
Fog and out-of-scope were conflated under one `## Fog` map section, gated by different things: fog by *knowledge* (can't specify it yet — in scope, unripe, graduates as the frontier advances), out-of-scope by *scope* (beyond the destination — never graduates). Cramming both under "Fog" made out-of-scope work read as takeable frontier (an unblocked, unclaimed item is indistinguishable from a live ticket).
Now the map body has two plainly-named sections — **`## Not yet specified`** and **`## Out of scope`** — and the skill's prose splits to match: the **Fog of war** section teaches only the not-yet-specified bucket and keeps the two-way *fog-or-ticket* sharpness test, while a new **Out of scope** section owns the scope axis (beyond the destination, closed not graduating, returns only as a fresh effort if the destination is redrawn). Charting and working-the-map now rule a beyond-destination ticket out of scope — close it, one line in *Out of scope* — rather than leaving it on the frontier or logging it in *Decisions so far*.
The **fog of war** leading word is retained: it names the concept and drives the graduate-the-fog behavior in the prose; only the human-facing map headings go to plain language.
@@ -0,0 +1,7 @@
---
"mattpocock-skills": minor
---
Sharpen **`wayfinder`**'s top-level purpose around **destination** as the leading word: wayfinding finds the *way* to a destination, it doesn't charge at building it.
The opening now states that the destination varies per effort — a spec to hand off and iterate, a decision to lock before planning, or a change made in place like a data-structure migration — and that naming it is the first act of charting, because it shapes every ticket. The map body gains a `## Destination` field that every session orients to before choosing a ticket, and triage's first step now pins the destination before any ticket exists. The stray `goal` mentions in the description and Fog section are unified onto `destination`.
@@ -0,0 +1,7 @@
---
"mattpocock-skills": patch
---
Sharpen Wayfinder's blocking rule to prefer the tracker's native dependency relationship, and update the GitHub and GitLab issue-tracker templates to match.
Native blocking is essential rather than cosmetic: it renders the frontier visually in the tracker's own UI, so the human sees what's takeable at a glance without opening the map. `wayfinder`'s SKILL.md now states that preference and rationale; the GitHub template spells out the native issue-dependencies recipe (`gh api .../dependencies/blocked_by`, frontier query on `issue_dependencies_summary.blocked_by`), and the GitLab template names the native `/blocked_by` blocking link (Premium/Ultimate) with the body-convention fallback. Both keep the body fallback for trackers that lack native blocking.
@@ -38,8 +38,8 @@ Run `gh issue view <number> --comments`.
Used by `/wayfinder`. The **map** is a single issue with **child** issues as tickets.
- **Map**: a single issue labelled `wayfinder:map`, holding the Notes / Decisions-so-far / Fog body. `gh issue create --label wayfinder:map`.
- **Child ticket**: an issue linked to the map as a GitHub sub-issue (`gh api` on the sub-issues endpoint). Where sub-issues aren't enabled, add the child to a task list in the map body and put `Part of #<map>` at the top of the child body. Labels: `wayfinder:<type>` (`research`/`prototype`/`grilling`/`task`), plus `wayfinder:claimed` once claimed.
- **Blocking**: native issue relationships where available; otherwise a `Blocked by: #<n>, #<n>` line at the top of the child body. A ticket is unblocked when every issue it lists is closed.
- **Frontier query**: list the map's open children (`gh issue list --state open`, scoped to the map's sub-issues / task list), drop any with an open `Blocked by` issue or the `wayfinder:claimed` label; first in map order wins.
- **Claim**: `gh issue edit <n> --add-label wayfinder:claimed` — the session's first write.
- **Child ticket**: an issue linked to the map as a GitHub sub-issue (`gh api` on the sub-issues endpoint). Where sub-issues aren't enabled, add the child to a task list in the map body and put `Part of #<map>` at the top of the child body. Labels: `wayfinder:<type>` (`research`/`prototype`/`grilling`/`task`). Once claimed, the ticket is assigned to the driving dev.
- **Blocking**: GitHub's **native issue dependencies** — the canonical, UI-visible representation. Add an edge with `gh api --method POST repos/<owner>/<repo>/issues/<child>/dependencies/blocked_by -F issue_id=<blocker-db-id>`, where `<blocker-db-id>` is the blocker's numeric **database id** (`gh api repos/<owner>/<repo>/issues/<n> --jq .id`, _not_ the `#number` or `node_id`). GitHub reports `issue_dependencies_summary.blocked_by` (open blockers only — the live gate). Where dependencies aren't available, fall back to a `Blocked by: #<n>, #<n>` line at the top of the child body. A ticket is unblocked when every blocker is closed.
- **Frontier query**: list the map's open children (`gh issue list --state open`, scoped to the map's sub-issues / task list), drop any with an open blocker (`issue_dependencies_summary.blocked_by > 0`, or an open issue in the `Blocked by` line) or an assignee; first in map order wins.
- **Claim**: `gh issue edit <n> --add-assignee @me` — the session's first write.
- **Resolve**: `gh issue comment <n> --body "<answer>"`, then `gh issue close <n>`, then append a context pointer (gist + link) to the map's Decisions-so-far.
@@ -39,8 +39,8 @@ Run `glab issue view <number> --comments`.
Used by `/wayfinder`. The **map** is a single issue with **child** issues as tickets.
- **Map**: a single issue labelled `wayfinder:map`, holding the Notes / Decisions-so-far / Fog body. `glab issue create --label wayfinder:map`. (On GitLab tiers with native epics, an epic may hold the map instead; a labelled issue works everywhere.)
- **Child ticket**: an issue carrying `Part of #<map>` at the top of its description and labels `wayfinder:<type>` (`research`/`prototype`/`grilling`/`task`), plus `wayfinder:claimed` once claimed.
- **Blocking**: GitLab's native `/blocked_by #<n>` quick action (or a `Blocked by: #<n>, #<n>` line in the description as fallback). A ticket is unblocked when every issue it lists is closed.
- **Frontier query**: `glab issue list -F json` scoped to the map's children, drop any with an open blocker or the `wayfinder:claimed` label; first in map order wins.
- **Claim**: `glab issue update <n> --label wayfinder:claimed` — the session's first write.
- **Child ticket**: an issue carrying `Part of #<map>` at the top of its description and labels `wayfinder:<type>` (`research`/`prototype`/`grilling`/`task`). Once claimed, the ticket is assigned to the driving dev.
- **Blocking**: GitLab's **native blocking link** — the canonical, UI-visible representation. Add it with the `/blocked_by #<n>` quick action, posted as a note (`glab issue note <child> --message "/blocked_by #<blocker>"`). Native blocking links are a Premium/Ultimate feature; on the free tier (or where unavailable) fall back to a `Blocked by: #<n>, #<n>` line at the top of the description. A ticket is unblocked when every blocker is closed.
- **Frontier query**: `glab issue list -F json` scoped to the map's children, drop any with an open blocker — a native `blocked_by` link to an open issue (`glab api projects/:id/issues/:iid/links`), or an open issue in the `Blocked by` line — or an assignee; first in map order wins.
- **Claim**: `glab issue update <n> --assignee @me` — the session's first write.
- **Resolve**: `glab issue note <n> --message "<answer>"`, then `glab issue close <n>`, then append a context pointer (gist + link) to the map's Decisions-so-far.
+1 -1
View File
@@ -33,4 +33,4 @@ Ask: "What's the public interface, and which seams should we test?"
- **Red before green.** Write the failing test first, then only enough code to pass it. Don't anticipate future tests or add speculative features.
- **One slice at a time.** One seam, one test, one minimal implementation per cycle.
- **Refactoring is not part of the loop.** It belongs to the review stage (see the `review` skill), not the red → green implementation cycle.
- **Refactoring is not part of the loop.** It belongs to the review stage (see the `code-review` skill), not the red → green implementation cycle.
+36 -18
View File
@@ -1,9 +1,11 @@
---
name: wayfinder
description: Plan a huge chunk of work — more than one agent session can hold — as a shared map of investigation tickets on your issue tracker, and resolve them one at a time until the way to the goal is clear.
description: Plan a huge chunk of work — more than one agent session can hold — as a shared map of investigation tickets on your issue tracker, and resolve them one at a time until the way to the destination is clear.
---
A loose idea has arrived — too big for one agent session, and wrapped in fog: the route from here to a plan isn't visible yet. This skill charts it as a **shared map** on the repo's issue tracker, then works its tickets one at a time. The map is domain-agnostic — engineering work, course content, whatever fits the shape.
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 the repo's issue tracker, 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. The map is domain-agnostic — engineering work, course content, whatever fits the shape.
## Refer by name
@@ -22,6 +24,10 @@ The map is an **index**, not a store. It lists the decisions made and points at
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>
@@ -32,9 +38,13 @@ The whole map at low resolution, loaded once per session. Open tickets are **not
- [<closed ticket title>](link) — <one-line gist of the answer>
## Fog
## Not yet specified
<!-- see "Fog of war" for what belongs here -->
<!-- see "Fog of war": in-scope fog you can't ticket yet; graduates as the frontier advances -->
## Out of scope
<!-- see "Out of scope": work ruled beyond the destination; closed, never graduates -->
```
### Tickets
@@ -47,12 +57,11 @@ Each ticket is a **child issue** of the map; the tracker's issue id is its ident
<the decision or investigation this ticket resolves>
```
Two label families:
Each ticket carries a `wayfinder:<type>` label — one of `research`, `prototype`, `grilling`, `task` (see [Ticket Types](#ticket-types)).
- `wayfinder:<type>` — one of `research`, `prototype`, `grilling`, `task` (see [Ticket Types](#ticket-types)).
- `wayfinder:claimed` — a session sets this **first**, before any work, so concurrent sessions skip it.
A session **claims** a ticket by assigning it to the dev driving the map, **first**, before any work, so concurrent sessions skip it. That assignee _is_ the claim: an open, unassigned ticket is unclaimed.
Blocking uses the tracker's native semantics. A ticket is **unblocked** when every ticket blocking it is closed. The **frontier** is the open, unblocked, unclaimed children — the edge of the known.
Blocking uses the tracker's **native** dependency relationship — essential because it renders the frontier _visually_ in the tracker's own UI, so the human sees what's takeable without opening the map. Only a tracker that lacks native blocking falls back to a body convention. 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 (see [Work through the map](#work-through-the-map)). Assets created while resolving a ticket are linked from the issue, not pasted in.
@@ -65,16 +74,24 @@ The answer isn't part of the body — it's recorded on resolution (see [Work thr
## Fog of war
The map is _deliberately_ incomplete: don't chart what you can't yet see. Beyond the tickets lies fog — 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 — one at a time, until the way to the goal is clear and no tickets remain.
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 — one at a time, until the way to the destination is clear and no tickets remain.
The map's **Fog** section is where that dim view is written down: the suspected question, the area to revisit later, the risk you're deferring. Write as loosely or as fully as the view allows; it doubles as a signpost for collaborators reading where the effort is headed.
The map's **Not yet specified** section 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. Write as loosely or as fully as the view allows; it doubles as a signpost for collaborators reading where the effort is headed.
**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 it's blocked and you can't act on it yet.
- **Fog when** you can't yet phrase it that sharply. Don't pre-slice 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.
- **Not yet specified when** you can't yet phrase it that 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.
Fog excludes only what's already decided (that's Decisions so far) and what's already a ticket.
**Not yet specified** excludes what's already decided (Decisions so far), what's already a live ticket, and what's out of scope (the next section).
## Out of scope
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: work you've consciously ruled out of _this_ effort. Scope, not sharpness, lands it here.
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.
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 — mis-scoped in while charting, or exposed by a resolution — **close it** (a closed ticket is unambiguously off the frontier) and leave one line in the **Out of scope** section: the gist plus why it's out of scope, linking the closed ticket. It stays out of **Decisions so far**, which records the route actually walked — a scope boundary isn't a step on it.
## Invocation
@@ -84,19 +101,20 @@ Two modes. Either way, **never resolve more than one ticket per session.**
User invokes with a loose idea.
1. Run a `/grilling` and `/domain-modeling` session to surface the open decisions.
2. **Create the map** (label `wayfinder:map`): Notes filled in, Decisions-so-far empty, Fog sketched.
3. **Create the tickets you can specify now** as child issues of the map — then wire blocking edges in a **second pass** (issues need ids before they can reference each other). Wiring sorts them into the frontier and the blocked; everything you can't yet specify stays in the Fog.
4. Stop — charting the map is one session's work; do not also resolve tickets.
1. **Name the destination.** Run a `/grilling` and `/domain-modeling` session 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.
2. **Map the frontier.** Grill again, **breadth-first** this time: fan out across the whole space rather than deep on any one thread, surfacing the open decisions and the first steps takeable now.
3. **Create the map** (label `wayfinder:map`): Destination and Notes filled in, Decisions-so-far empty, the fog sketched into **Not yet specified**.
4. **Create the tickets you can specify now** as child issues of the map — then wire blocking edges in a **second pass** (issues need ids before they can reference each other). Wiring sorts them into the frontier and the blocked; everything you can't yet specify stays in the fog — the **Not yet specified** section.
5. Stop — charting the map 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 the next decision, not the user.
1. Load the **map** — the low-res view, not every ticket body.
2. Choose the ticket. If the user named one, use it. Otherwise take the first frontier ticket in order. **Claim it**: set `wayfinder:claimed` and save before any work.
2. Choose the ticket. If the user named one, use it. Otherwise take the first frontier ticket in order. **Claim it**: assign it to yourself before any work.
3. Resolve it — **zoom as needed**: fetch the full body of any related or closed ticket on demand; invoke the skills the `## Notes` block names. If in doubt, use `/grilling` and `/domain-modeling`.
4. Record the resolution: post the answer as a **resolution comment**, **close** the issue, and **append a context pointer** to the map's Decisions-so-far.
5. Add newly-surfaced tickets (create-then-wire); graduate any fog the answer has made specifiable, clearing each graduated patch from the Fog so it lives only as its new ticket. If the decision invalidates other parts of the map, update or delete those tickets.
5. Add newly-surfaced tickets (create-then-wire); graduate any fog the answer has made specifiable, clearing each graduated patch from **Not yet specified** so it lives only as its new ticket. If the answer reveals a ticket — this one or another — sits beyond the destination, **rule it out of scope** rather than resolving it on the route. If the decision invalidates other parts of the map, update or delete those tickets.
The user may run unblocked tickets in parallel, so expect other sessions to be editing the tracker concurrently.
@@ -158,6 +158,12 @@ _Failure mode._ Ending the current step before it is genuinely done, because the
_Avoid_: premature closure, the rush, rushing, shortcutting
### Negation
_Failure mode._ Steering by prohibition — telling the agent what _not_ to do — which drags the forbidden behaviour into context and makes it _more_ available, not less. _Don't think of an elephant_, and the elephant is all there is; _never write verbose comments_, and verbosity is the pattern the agent has just read. The negation is a weak modifier the strongly-activated concept overruns, so the ban half-reads as an instruction to do the thing. Its **leading word** is the _elephant_: whatever a prohibition names into the frame. Cure: prompt the **positive** — describe the target behaviour ("write one-line comments") so the banned one is never spoken. A prohibition earns its place only as a hard guardrail on a behaviour you cannot phrase positively; even then, pair it with the positive target so attention lands on what to do.
_Avoid_: ironic rebound, don't-prompting, the pink elephant
## Pruning
Keeping a skill lean — each remedy paired with the failure it cures.
@@ -80,3 +80,4 @@ Use these to diagnose issues the user may be having with the skill.
- **Sediment** — stale layers that settle because adding feels safe and removing feels risky. The default fate of any skill without a pruning discipline.
- **Sprawl** — a skill simply too long, even when every line is live and unique. Hurts readability and maintainability and wastes tokens. The cure is the ladder: disclose **reference** behind pointers, and split by **branch** or sequence so each path carries only what it needs.
- **No-op** — a line the model already obeys by default, so you pay load to say nothing. The test: does it change behaviour versus the default? A weak leading word (_be thorough_ when the agent is already thorough-ish) is a no-op; the fix is a stronger word (_relentless_), not a different technique.
- **Negation** — steering by prohibition backfires: _don't think of an elephant_ names the elephant and makes it more available, not less. Prompt the **positive** — state the target behaviour so the banned one is never spoken; keep a prohibition only as a hard guardrail you can't phrase positively, and even then pair it with what to do instead.