Compare commits

...
Author SHA1 Message Date
Remote Box Agent 0505536390 Remove "It assumes one writer" section from grill-with-docs docs
The section's single-writer framing doesn't fit how the skill is actually used across a team; drop it rather than carry a stale caveat.
2026-08-17 07:23:08 +00:00
Matt Pocock 068b6e0c62 Merge pull request #880 from mattpocock/fix/user-invoked-skill-invocation
Stop skills from calling other user-invoked skills
2026-08-15 22:24:19 +01:00
Remote Box Agent 6a34259e99 Cut the 'it's user-invoked' rationale from the five preconditions
Per writing-for-agents' no-op test: "tell the user to run /X" is
already an unambiguous instruction with no branch where the agent
would otherwise try to call it, so the trailing justification changes
nothing at runtime. It also duplicates the rule .agents/invocation.md
already states as the single source of truth. Cut it from all five
call sites; the carve-out paragraph there is the one place the reason
needs to live.
2026-08-15 21:22:05 +00:00
Remote Box Agent 1dab98299c Stop skills from calling other user-invoked skills
Five skills (to-spec, wayfinder, to-tickets, triage, code-review) told
the agent to call the Skill tool on setup-matt-pocock-skills as a
missing-config precondition. It's user-invoked, so per
.agents/invocation.md no other skill — user- or model-invoked — can
ever reach it that way. PR #878 turned the old soft "/skill"-style
prose into a literal "Call the Skill tool with ..." instruction
without checking invocation type, which made this fire more reliably
in the wrong direction. Reworded all five as instructions to tell the
human to run it instead.

diagnosing-bugs had the same problem handing its post-mortem off to
improve-codebase-architecture, with no human anywhere in that loop to
catch the failed call. Removed the hand-off outright rather than
softening it, since it rarely fired in practice; Phase 6 is now
"Cleanup" only.

Added a carve-out to .agents/invocation.md's "Dependencies between
them" section — the section PR #878 introduced — so future
"call the Skill tool" instructions can't repeat this against a
user-invoked target.

Fixes #453.
2026-08-15 21:19:23 +00:00
Matt Pocock bb1c760d55 Merge pull request #878 from mattpocock/audit/skill-tool-invocation-terminology
Standardize cross-skill invocation on "call the Skill tool" phrasing
2026-08-15 22:01:36 +01:00
Matt Pocock 755611effd Merge pull request #879 from mattpocock/remove-em-dashes-grilling-skill
Remove em-dashes from grilling skill
2026-08-15 21:50:36 +01:00
remote-box d419977fe0 chore: add changeset for grilling em-dash removal 2026-08-15 20:50:05 +00:00
remote-box 86cba45f42 Remove em-dashes from grilling skill
Replaces em-dash punctuation in SKILL.md with colons and semicolons for plain-text consistency.
2026-08-15 20:45:25 +00:00
11 changed files with 27 additions and 17 deletions
+2
View File
@@ -19,6 +19,8 @@ This is about **operative** instructions — a skill's own steps telling the age
The Skill tool takes one skill per call. A step that needs two skills is two calls, not one call with two names — say so (`Call the Skill tool twice, for "grilling" and "domain-modeling"`), not "call it with X and Y," which reads as a single call taking both.
This whole convention only holds when the named skill is **model-invoked**. A user-invoked skill can never be reached this way, full stop — per the invariant above, no other skill can call it, including by naming it to the Skill tool. When a step's precondition is a user-invoked skill (e.g. `setup-matt-pocock-skills`), phrase it as an instruction for the human to act on — "tell the user to run `/setup-matt-pocock-skills`" — never as a Skill tool call.
## Passive vs active domain work
Merely _reading_ `CONTEXT.md` for vocabulary is a one-line prose pointer, not the `domain-modeling` skill. Only the active build/sharpen discipline (challenge terms, edge-case scenarios, write ADRs, update `CONTEXT.md` inline) is `domain-modeling`.
+5
View File
@@ -0,0 +1,5 @@
---
"mattpocock-skills": patch
---
grilling: remove em-dashes from `SKILL.md`, replacing them with colons and semicolons so the instructions read as plain text.
@@ -0,0 +1,11 @@
---
"mattpocock-skills": patch
---
Stop skills from trying to reach user-invoked skills through the Skill tool — fix cross-skill references that violated the "no other skill can call it" invariant in `.agents/invocation.md`, in `to-spec`, `wayfinder`, `to-tickets`, `triage`, `code-review`, and `diagnosing-bugs`.
- `to-spec`, `wayfinder`, `to-tickets`, `triage`, and `code-review` each carried a precondition ("...run `/setup-matt-pocock-skills` if not") that PR #878 rewrote into a literal `Call the Skill tool with "setup-matt-pocock-skills"` instruction. `setup-matt-pocock-skills` is user-invoked, so none of these skills — user-invoked or model-invoked — can call it. Reworded all five as instructions for the agent to tell the human to run it instead.
- `diagnosing-bugs`'s Phase 6 post-mortem hand off to `improve-codebase-architecture` (also user-invoked) the same way, from an autonomous, often-unattended bug-fixing flow with no human in the loop to catch the failed call. Removed the hand-off outright rather than softening it — it rarely fired in practice. Phase 6 is now "Cleanup" only; the mechanical checklist is untouched.
- Added a carve-out paragraph to `.agents/invocation.md`'s "Dependencies between them" section: the `Call the Skill tool with "name"` convention only applies when the named skill is model-invoked. This is the section PR #878 introduced without reconciling it against the user-invoked/model-invoked invariant stated eight lines above it — the gap is most of why this bug reached six call sites instead of one.
Fixes #453.
-6
View File
@@ -40,12 +40,6 @@ That third row is the one that catches people out. `CONTEXT.md` is a glossary an
The glossary is the point. Domain language is the thing this skill is actually building — the project's own words, agreed once, so you, the agent and your colleagues stop paying to re-derive them. It is worth saying that not everyone agrees this buys you agent performance: the sharpest public pushback is that a term and its plain-English expansion get the same result from the [model](https://www.aihero.dev/ai-coding-dictionary/model), and that the vocabulary really compresses communication between the humans who share it. That reading still leaves the glossary valuable; it just moves the value.
## It assumes one writer
The stateful outputs assume a single person curating them. A two-developer team running four months in one repo reported state drift on roughly 20% of sampled merged PRs, with ADR citations and README claims the highest-drift surfaces — deliberate, human-curated docs drifted worse than agent memory did. Pruning the stale docs did not hold; the same sweep was stale again within days. What worked was deleting shadow state outright and adding a deterministic citation and link linter to CI.
Related: running the skill repeatedly across unrelated changes in one repo tends to accumulate mixed-topic docs, because nothing separates one session's output from another's. Neither of these is fixed in the skill today.
## Common questions
**Should I use this or `/wayfinder`?**
+1 -1
View File
@@ -10,7 +10,7 @@ Two-axis review of the diff between `HEAD` and a fixed point the user supplies:
Both axes run as **parallel sub-agents** so they don't pollute each other's context, then this skill aggregates their findings.
The issue tracker should have been provided to you — call the Skill tool with "setup-matt-pocock-skills" if `docs/agents/issue-tracker.md` is missing.
The issue tracker should have been provided to you. If `docs/agents/issue-tracker.md` is missing, tell the user to run `/setup-matt-pocock-skills`.
## Process
+1 -3
View File
@@ -127,7 +127,7 @@ If a correct seam exists:
4. Watch it pass.
5. Re-run the Phase 1 feedback loop against the original (un-minimised) scenario.
## Phase 6 — Cleanup + post-mortem
## Phase 6 — Cleanup
Required before declaring done:
@@ -136,5 +136,3 @@ Required before declaring done:
- [ ] All `[DEBUG-...]` instrumentation removed (`grep` the prefix)
- [ ] Throwaway prototypes deleted (or moved to a clearly-marked debug location)
- [ ] The hypothesis that turned out correct is stated in the commit / PR message — so the next debugger learns
**Then ask: what would have prevented this bug?** If the answer involves architectural change (no good test seam, tangled callers, hidden coupling) hand off by calling the Skill tool with "improve-codebase-architecture" and the specifics. Make the recommendation **after** the fix is in, not before — you have more information now than when you started.
+1 -1
View File
@@ -6,7 +6,7 @@ disable-model-invocation: true
This skill takes the current conversation context and codebase understanding and produces a spec. Do NOT interview the user — just synthesize what you already know.
The issue tracker and triage label vocabulary should have been provided to you — call the Skill tool with "setup-matt-pocock-skills" if not.
The issue tracker and triage label vocabulary should have been provided to you. If not, tell the user to run `/setup-matt-pocock-skills`.
## Process
+1 -1
View File
@@ -8,7 +8,7 @@ disable-model-invocation: true
Break a plan, spec, or conversation into a set of **tickets** — tracer-bullet vertical slices, each declaring the tickets that **block** it.
The issue tracker and triage label vocabulary should have been provided to you — call the Skill tool with "setup-matt-pocock-skills" if not.
The issue tracker and triage label vocabulary should have been provided to you. If not, tell the user to run `/setup-matt-pocock-skills`.
## Process
+1 -1
View File
@@ -40,7 +40,7 @@ For a PR, the same states read against the attached code: `ready-for-agent` mean
Every triaged issue should carry exactly one category role and one state role. If state roles conflict, flag it and ask the maintainer before doing anything else.
These are canonical role names — the actual label strings used in the issue tracker may differ. The mapping should have been provided to you - call the Skill tool with "setup-matt-pocock-skills" if not.
These are canonical role names — the actual label strings used in the issue tracker may differ. The mapping should have been provided to you. If not, tell the user to run `/setup-matt-pocock-skills`.
State transitions: an unlabeled issue normally goes to `needs-triage` first; from there it moves to `needs-info`, `ready-for-agent`, `ready-for-human`, or `wontfix`. `needs-info` returns to `needs-triage` once the reporter replies. The maintainer can override at any time — flag transitions that look unusual and ask before proceeding.
+1 -1
View File
@@ -22,7 +22,7 @@ The map is a single issue on this repo's issue tracker, labelled `wayfinder: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.
**Where the map, its child tickets, blocking, and frontier queries physically live is tracker-specific.** The issue tracker should have been provided to you — call the Skill tool with "setup-matt-pocock-skills" if not. Consult the tracker doc's "Wayfinding operations" section for how _this_ repo expresses them. If no tracker has been provided, default to the local-markdown tracker.
**Where the map, its child tickets, blocking, and frontier queries physically live is tracker-specific.** The issue tracker should have been provided to you. If not, tell the user to run `/setup-matt-pocock-skills`. Consult the tracker doc's "Wayfinding operations" section for how _this_ repo expresses them. If no tracker has been provided, default to the local-markdown tracker.
### The map body
+3 -3
View File
@@ -5,7 +5,7 @@ description: Grill the user relentlessly about a plan, decision, or idea. Use wh
Interview the user relentlessly until you reach a shared understanding. Map this as a **design tree**: every decision branches into the decisions that hang off it.
Work the tree in **rounds**. The **frontier** is every decision whose prerequisites are already settled the questions you can ask _now_ without guessing at answers you haven't heard yet. Ask the whole frontier in one round: number each question and give your recommended answer. Then wait for the user's answers before the next round.
Work the tree in **rounds**. The **frontier** is every decision whose prerequisites are already settled: the questions you can ask _now_ without guessing at answers you haven't heard yet. Ask the whole frontier in one round: number each question and give your recommended answer. Then wait for the user's answers before the next round.
Each question should be formatted like so:
@@ -15,8 +15,8 @@ Each question should be formatted like so:
➡️ <your recommended answer>
```
Each round the user answers reshapes the tree settled decisions push the frontier outward and unblock questions that depended on them. Recompute the frontier and ask the next round. A question whose answer depends on another question still open in this round belongs to a _later_ round, not this one.
Each round the user answers reshapes the tree: settled decisions push the frontier outward and unblock questions that depended on them. Recompute the frontier and ask the next round. A question whose answer depends on another question still open in this round belongs to a _later_ round, not this one.
Finding _facts_ is your job, never the user's. When a frontier question needs a fact from the environment (filesystem, tools, etc.), dispatch a sub-agent to find it don't ask the user for anything you could look up yourself. Don't block on it: a running exploration is an unsettled prerequisite, so only the questions downstream of it wait for the sub-agent to report ask the rest of the frontier now. The _decisions_ are the user's put each to them and wait.
Finding _facts_ is your job, never the user's. When a frontier question needs a fact from the environment (filesystem, tools, etc.), dispatch a sub-agent to find it; don't ask the user for anything you could look up yourself. Don't block on it: a running exploration is an unsettled prerequisite, so only the questions downstream of it wait for the sub-agent to report; ask the rest of the frontier now. The _decisions_ are the user's: put each to them and wait.
The session is done when the frontier is empty: every branch of the design tree visited, nothing left silently assumed. Do not act on it until the user confirms you have reached a shared understanding.