Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ location; if `wherefore/` exists, use it.
wherefore/
topics.md controlled tag vocabulary: Areas and Topics
log/YYYY-MM-DD-short-slug.md one decision per file
questions/Q-NNN.md one question per file
questions/Q-NNN-short-slug.md one question per file (ID prefix + scannable slug)
```

There is no index file. The frontmatter in each `log/` and `questions/` file is the
Expand Down Expand Up @@ -96,7 +96,11 @@ For an abandoned decision with no replacement: `status: obsolete`, a

When a decision leaves something unresolved, register it. Next Q-ID = (highest `id:`
across the existing `wherefore/questions/Q-*.md` files) + 1; IDs are sequential and
never reused. Create `wherefore/questions/Q-NNN.md` with this EXACT frontmatter:
never reused. Create `wherefore/questions/Q-NNN-short-slug.md` (the `Q-NNN` prefix is
the zero-padded ID; the slug is a short, lowercase, hyphenated summary distilled from
the question, same style as a log slug). The `id:` frontmatter field remains the
authoritative ID; the filename slug is only for human scanning. Use this EXACT
frontmatter:

```markdown
---
Expand Down
8 changes: 4 additions & 4 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ plugins/wherefore/
skills/capture/
SKILL.md # captures a discussion into wherefore/ as one or
# more tagged Markdown entries; registers any open
# questions as questions/Q-NNN.md files
# questions as questions/Q-NNN-short-slug.md files
topics.seed.md # starter vocabulary copied on first use if no
# topics.md exists yet
skills/ask/
Expand All @@ -57,7 +57,7 @@ plugins/wherefore/
# also surfaces open questions in the same area
skills/resolve/
SKILL.md # closes an open question by editing its
# questions/Q-NNN.md file (answer, rationale, back-link)
# questions/Q-NNN-short-slug.md file (answer, rationale, back-link)
skills/supersede/
SKILL.md # marks an entry superseded (with pointer to
# replacement) or obsolete via its frontmatter
Expand All @@ -71,6 +71,6 @@ The `wherefore/` directory itself is **not** in this repo -- it lives in each co
- **Command `.md`** front matter: `description`, `argument-hint`, `allowed-tools`.
- All skills use a two-facet tag system: **areas** (feature slices: WHAT) and **topics** (cross-cutting concerns: HOW), drawn from the consuming project's `wherefore/topics.md`. Keep this separation consistent if extending the skills.
- There is no hand-maintained index. INDEX.md and QUESTIONS.md are gone: entry and question frontmatter is the single source of truth, and `ask` derives its shortlist by reading only the leading frontmatter block of each file. Do not reintroduce a generated index in any skill or command; if extending the skills, derive on read instead.
- `capture` is write-heavy (creates/edits files); a single discussion may produce multiple entry files when it covers independently-queryable threads. `ask` is read-only. `resolve` edits only the `questions/Q-NNN.md` file (and optionally the source entry). `supersede` edits an existing entry file's frontmatter and adds a banner. `seed` is read-first, write-only-after-confirmation -- preserve this ask-before-write pattern for any new commands.
- `capture` is write-heavy (creates/edits files); a single discussion may produce multiple entry files when it covers independently-queryable threads. `ask` is read-only. `resolve` edits only the `questions/Q-NNN-short-slug.md` file (and optionally the source entry). `supersede` edits an existing entry file's frontmatter and adds a banner. `seed` is read-first, write-only-after-confirmation -- preserve this ask-before-write pattern for any new commands.
- Entry filenames: `YYYY-MM-DD-short-slug.md`; the entry frontmatter (`date`, `title`, `areas`, `topics`, `stories`, `status`, `supersedes`, `superseded_by`, `superseded_date`) is what readers shortlist on.
- Question files: `questions/Q-NNN.md`, one per question, with `id`, `question`, `status`, `areas`, `asked_date`, `asked_slug`, `resolution`, `resolution_slug` frontmatter. IDs are sequential and never reused; the next ID is (highest existing `id:`) + 1.
- Question files: `questions/Q-NNN-short-slug.md` (the `Q-NNN` prefix is the zero-padded ID; the slug is a short, lowercase, hyphenated summary of the question, same style as a log slug and only for human scanning). One per question, with `id`, `question`, `status`, `areas`, `asked_date`, `asked_slug`, `resolution`, `resolution_slug` frontmatter. The `id:` field is the authoritative ID (the dashboard keys off it, not the filename). IDs are sequential and never reused; the next ID is (highest existing `id:`) + 1.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ maintained.
It shortlists from entry frontmatter, then reads only the matching files. After
answering, it surfaces any still-open questions in the same area.
- **`resolve`** -- closes out an open question by updating its
`wherefore/questions/Q-NNN.md` file, recording the answer, the rationale, and a
link to the discussion that settled it.
`wherefore/questions/Q-NNN-short-slug.md` file, recording the answer, the rationale,
and a link to the discussion that settled it.
- **`supersede`** -- marks a past decision superseded (with a pointer to its
replacement) or obsolete, without requiring a new discussion to be captured.
Updates the entry file and adds a visible banner so both the `ask` skill and
Expand Down Expand Up @@ -240,7 +240,7 @@ Each consuming project's log lives in its own repo, not here:
└── wherefore/
├── topics.md # controlled tag vocabulary (areas + topics)
├── questions/
│ └── Q-NNN.md # one file per question
│ └── Q-NNN-short-slug.md # one file per question (ID prefix + scannable slug)
└── log/
└── YYYY-MM-DD-short-slug.md # one file per independently-queryable thread
```
Expand Down
2 changes: 1 addition & 1 deletion plugins/wherefore/skills/ask/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ The wherefore lives under a repo-relative `wherefore/` directory:
wherefore/
├── topics.md # controlled topic vocabulary
├── questions/
│ └── Q-NNN.md # one file per question
│ └── Q-NNN-short-slug.md # one file per question (ID prefix + scannable slug)
└── log/
└── YYYY-MM-DD-short-slug.md # one file per discussion
```
Expand Down
8 changes: 4 additions & 4 deletions plugins/wherefore/skills/capture/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ wherefore/
├── README.md # what this directory is + link to the plugin
├── topics.md # controlled tag vocabulary (areas + topics)
├── questions/
│ └── Q-NNN.md # one file per question
│ └── Q-NNN-short-slug.md # one file per question (ID prefix + scannable slug)
└── log/
└── YYYY-MM-DD-short-slug.md # one file per discussion
```
Expand Down Expand Up @@ -149,9 +149,9 @@ scalar to a one-line summary and move the detail into a body section.
8. Write `wherefore/log/YYYY-MM-DD-short-slug.md`. Slug short, lowercase, hyphenated, recognizable (`oauth-token-refresh`, not `discussion-about-the-auth-stuff`). If the name exists, add a short suffix; never overwrite.

9. Register open questions. For each genuine unresolved item:
- Next Q-ID = (highest `id:` across `wherefore/questions/Q-*.md`) + 1. Derive it from the files, e.g. `ls wherefore/questions/Q-*.md 2>/dev/null | sed -E 's|.*/Q-0*([0-9]+)\.md|\1|' | sort -n | tail -1`. If the directory is empty or absent, start at Q-001. IDs are sequential and never reused.
- Next Q-ID = (highest `id:` across `wherefore/questions/Q-*.md`) + 1. Derive it from the files, e.g. `ls wherefore/questions/Q-*.md 2>/dev/null | sed -E 's|.*/Q-0*([0-9]+).*|\1|' | sort -n | tail -1`. If the directory is empty or absent, start at Q-001. IDs are sequential and never reused. (The regex tolerates both the legacy `Q-NNN.md` and the current `Q-NNN-slug.md` naming.)
- Prefix the entry's item with the ID: `- Q-001: How should we ...`
- Create `wherefore/questions/Q-NNN.md`, leaving `resolution` and `resolution_slug` blank:
- Create `wherefore/questions/Q-NNN-short-slug.md`, leaving `resolution` and `resolution_slug` blank. Name it like a log entry: `Q-` + the zero-padded ID + a short, lowercase, hyphenated slug distilled from the question (`Q-001-eu-buyer-tax`, not `Q-001-question-about-tax-stuff`). The `Q-NNN` prefix keeps questions sorted and greppable by number; the slug is for human scanning; the authoritative ID is always the `id:` frontmatter field.
```
---
id: Q-001
Expand All @@ -178,6 +178,6 @@ scalar to a one-line summary and move the detail into a body section.

Reversal. Input: "We're dropping RLS and going schema-per-tenant after the perf testing." Before writing, dump entry frontmatter and scan for active entries sharing `multi-tenancy` or `postgres`, surface the RLS entry, and confirm the reversal. On confirmation, write the new entry with `supersedes: 2026-06-23-rls-tenant-isolation`, mutate the old entry's frontmatter (`status: superseded`, `superseded_by`, `superseded_date`) and add its banner line, and report every file touched.

No decision. Input: a long thread weighing GraphQL caching with no conclusion. The Decisions section reads "No decision, see Open questions"; the contenders go under Open questions, each becoming a `Q-NNN.md` so a later discussion can close them out explicitly.
No decision. Input: a long thread weighing GraphQL caching with no conclusion. The Decisions section reads "No decision, see Open questions"; the contenders go under Open questions, each becoming a `Q-NNN-short-slug.md` so a later discussion can close them out explicitly.

Two threads in one discussion. Input: a thread covering both an order PDF renderer swap and a separate cart price-suggestion feature, which share no causal link. Write two files (`2026-06-24-order-pdf-renderer.md`, `2026-06-24-buyer-price-suggestion.md`), each with its own tags. Report: "Split into 2 entries; the two decisions are unrelated and would be retrieved separately."
26 changes: 15 additions & 11 deletions plugins/wherefore/skills/resolve/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,11 @@ summary and move detail into a `## Resolution` body section. `status` and

## Workflow

1. **Find the question.** Open `wherefore/questions/Q-NNN.md` directly (the file is
named by its ID). If it doesn't exist, say so clearly. To list what is open,
1. **Find the question.** Files are named `Q-NNN-short-slug.md` (ID prefix plus a
scannable slug), so glob by the ID rather than assuming the exact name:
`ls wherefore/questions/Q-042-*.md wherefore/questions/Q-042.md 2>/dev/null`
(the second path catches any legacy file still named `Q-NNN.md`). Expect exactly
one match; open it. If nothing matches, say so clearly. To list what is open,
dump the question frontmatter and filter `status: open`:
```bash
for f in wherefore/questions/Q-*.md; do
Expand All @@ -49,7 +52,7 @@ summary and move detail into a `## Resolution` body section. `status` and
ran the `capture` skill and a fresh entry exists. If no wherefore entry captures
it, the resolution is standalone.

3. **Update `wherefore/questions/Q-NNN.md`.** Edit the frontmatter in place:
3. **Update the question file** (`wherefore/questions/Q-NNN-short-slug.md`). Edit the frontmatter in place:
- Set `status: resolved`
- Fill in `resolution` with a one-sentence answer (and the why, if concise
enough to fit; otherwise put it in a `## Resolution` body section below the
Expand All @@ -60,7 +63,7 @@ summary and move detail into a `## Resolution` body section. `status` and
4. **Update the source wherefore entry (if applicable).** If the resolution came from
a specific wherefore entry, open `wherefore/log/<slug>.md` and add a note in its
"Open questions / follow-ups" section next to the relevant item:
`- Q-042: <question text> (resolved, see wherefore/questions/Q-042.md)`
`- Q-042: <question text> (resolved, see wherefore/questions/Q-042-<slug>.md)`

5. **Report back.** Show:
- The question text and its ID
Expand All @@ -74,22 +77,23 @@ summary and move detail into a `## Resolution` body section. `status` and
**Example 1: resolution from a new discussion**
User: "Mark Q-001 resolved: we decided to use zero-rated VAT for EU digital goods.
We discussed it in the entry we just logged, 2026-07-01-eu-vat-strategy."
Action: edit `wherefore/questions/Q-001.md` (status -> resolved, resolution filled,
resolution_slug set), update that wherefore entry to note the question is resolved.
Report both files touched.
Action: find the file (`ls wherefore/questions/Q-001-*.md`) and edit it (status ->
resolved, resolution filled, resolution_slug set), update that wherefore entry to
note the question is resolved. Report both files touched.

**Example 2: standalone resolution**
User: "Close Q-007. We're not doing offline sync this quarter, pushed to Q3."
Action: edit `wherefore/questions/Q-007.md` (status -> resolved, resolution filled,
resolution_slug left blank). No wherefore entry to update. Report the file touched.
Action: edit the Q-007 file (`wherefore/questions/Q-007-*.md`) (status -> resolved,
resolution filled, resolution_slug left blank). No wherefore entry to update. Report
the file touched.

**Example 3: question not found**
User: "Resolve Q-099"
Action: `wherefore/questions/Q-099.md` doesn't exist. Respond: "Q-099 wasn't found
Action: no `wherefore/questions/Q-099-*.md` matches. Respond: "Q-099 wasn't found
in wherefore/questions/. Check the ID; I can list the open questions if that helps."

**Example 4: already resolved**
User: "Mark Q-002 resolved"
Action: open `wherefore/questions/Q-002.md`; status is already resolved. Show the
Action: open the Q-002 file (`wherefore/questions/Q-002-*.md`); status is already resolved. Show the
recorded resolution date and text and make no changes, e.g. "Q-002 was resolved on
2026-06-24: zero-rated VAT for EU digital goods. No changes made."
Loading