Compare commits

..

2 Commits

Author SHA1 Message Date
8c17f3aeb8 feat: add consume skill for mining knowledge into the vault
/consume is the write-side counterpart to the read-only /wiki: it mines a
target for generalized, transferable knowledge and files atomic concept
notes into 01 sources/claude/, the agent-owned area of the Obsidian vault.

It is user-invoked/deliberate. SKILL.md holds the branch-detection ladder
plus the common writing logic — read existing knowledge (via /wiki and a
direct scan), plan atomic generalized notes with a file-to-section-to-note
contribution map, present an HTML plan and wait for explicit approval, then
write on the vault's note template and clear the consumed scaffolding.

v1 ships one branch, project.md: source code is truth for current state,
while .claude/spec and .claude/tasks are the record of why (mined, then
deleted). The ladder is extensible for future source types.
2026-07-24 20:03:44 -04:00
0a8b5c2096 feat: add wiki skill for read-only vault lookup
A model-invoked skill that answers questions from the user's Obsidian
vault, read-only, over the filesystem. Enforces the vault's own
settings.json deny-Read globs itself, since the harness does not apply
them when running from another directory. Uses the 02 tags/ hubs as a
recall backstop and reads to saturation, then answers with per-note
provenance.
2026-07-24 20:03:44 -04:00
3 changed files with 172 additions and 0 deletions

95
skills/consume/SKILL.md Normal file
View File

@@ -0,0 +1,95 @@
---
name: consume
description: Consume a project (or, later, another source) into the agent's personal wiki — distil generalized, transferable knowledge from it into the Obsidian vault's agent-owned area, then clear the consumed scaffolding. Deliberate: run as /consume [target], never automatically.
disable-model-invocation: true
---
# consume
Distil generalized, transferable knowledge from a source into the agent's own wiki, then clear the consumed scaffolding once the knowledge is safely captured.
`/consume [target]` ingests one target — a filesystem path, defaulting to the current directory — and writes what it mines into `01 sources/claude/`, the one area of the user's Obsidian vault the agent may write.
It is the write side of a pair with the read-only `/wiki`, which it invokes to read the rest of the vault.
The wiki holds reusable knowledge, never project documentation.
A fact earns a note only if it **generalizes** past the target it came from — strip the target's name and specifics, and if nothing teachable is left, it does not belong in the wiki.
Nothing is written and nothing is deleted until the user approves the plan.
## The write boundary
The vault lives at `$(xdg-user-dir DOCUMENTS)/notes`.
Resolve it; if it does not exist, report that the vault is unreachable and stop.
Write only under `01 sources/claude/`, and treat every other vault path as off-limits to writes.
The harness does not apply the vault's own permission rules when you run from outside it, so enforcing this boundary is the skill's job.
All reading of the wider vault goes through `/wiki` (step 3), which enforces the vault's read boundary itself.
## 1. Select the branch
Route the target through this ladder, first match wins:
- A directory containing `.claude/spec/` and/or `.claude/tasks/` → a project: follow [`project.md`](project.md).
- No rung matches → report that the target is not something consume knows how to read, write nothing, and stop.
Done when a branch file is selected, or consume has stopped on an unsupported target.
## 2. Read the target and establish ground truth
Follow the selected branch file to understand the target's *current* state.
The branch file names its source of truth and what within the target is merely stale intent; ground your understanding in the former, never the latter.
Done when you understand what the target actually is now, from its branch's source of truth.
## 3. Read what the wiki already knows
Two reads with different jobs:
- Invoke `/wiki` on the concepts the target raised, to learn what the whole vault already holds — so new notes link to existing notes and hubs, and you do not re-capture knowledge the vault already has.
- Scan `01 sources/claude/` directly for the concept notes you may need to enrich.
Done when you know which existing notes bear on what you are about to write.
## 4. Plan the notes
Distil the target's knowledge into generalized concept notes, each passing the **generalizes** test: it must teach something that holds on a *different* target, not a fact true only of this one.
Keep each note atomic — one transferable idea per note; when a note carries two independent lessons, split it.
Write as many notes as the knowledge warrants; the count follows from atomicity, not from a target number.
For each note, decide whether it is new or an update to an existing note whose knowledge is now stale or thinner than what you have learned, keeping the wiki accurate to your current understanding.
Then build the contribution map: for every file you consumed, the notes it feeds and the exact sections that contributed — including any file that fed no note, recorded as feeding nothing.
The mapping is many-to-many — one file may feed several notes, and one note may draw on several files.
Done when every planned note passes the generalizes test and is atomic, and every consumed file — including those feeding no note — is mapped, with its contributing sections named.
## 5. Present the plan and wait for approval
Write the plan as a self-contained HTML file to the session's scratchpad directory and give the user its path.
The report lists every file consumed, the notes each one contributes to, and the exact contributing sections.
It also flags any `[[hub]]` a note will link that does not yet exist under `02 tags/` or `03 index/`, as a suggested new hub for the user to create by hand.
Stop and wait for the user's explicit approval.
Write nothing and delete nothing until they approve.
Done when the user has approved the plan.
## 6. Write the notes
Write each new note and update each changed one under `01 sources/claude/`, using the vault's note template (`99 meta/templates/note.md`): fill its `Tags:` line with the `[[hub]]` wikilinks the note belongs under, and its body with the distilled knowledge.
Link a hub whether or not its note exists yet — a dangling `[[hub]]` is a valid link and still feeds `/wiki` recall.
Organize files by your own judgment: flat until a category has accumulated enough notes to warrant its own subfolder under `claude/`.
Done when every note in the plan has been written or updated.
## 7. Clear the consumed scaffolding
With the notes written, perform the branch's cleanup — the branch file names exactly what to remove.
Deletion never precedes the writes of step 6.
Done when the branch's cleanup has run.
## 8. Report
Tell the user what you created, updated, and left untouched, and repeat the suggested new hubs from the report so the vault's `02 tags/` and `03 index/` can be filled in by hand.
Done when the summary names every note written or updated and every suggested hub.

23
skills/consume/project.md Normal file
View File

@@ -0,0 +1,23 @@
# project branch
How consume reads a project target, and what it clears afterward.
Reached from step 1 of [`SKILL.md`](SKILL.md) when the target is a directory containing `.claude/spec/` and/or `.claude/tasks/`.
## Read the source, mine the specs
The source code is the truth for *what* the project is and does now.
Read it thoroughly enough to understand its current state and to surface the reusable ideas it embodies — techniques, patterns, decisions, gotchas.
`.claude/spec/` and `.claude/tasks/` are the record of *why* — the reasoning, trade-offs, and intent behind what the code became.
They are the richest source of the generalizable lessons, and cleanup destroys them, so mine their reasoning now or lose it.
But they are not current fact: where a spec or task disagrees with the source, the source wins, and where one describes work later abandoned or changed, the source is what actually happened.
Together these are the raw material the writing logic generalizes; extracting the generalized notes themselves is step 4 of SKILL.md, not this branch's job.
Done when you understand the project's current state from its source and have mined its specs and tasks for the reasoning behind it.
## Cleanup
After the notes are written (step 6 of SKILL.md), delete the spec and task files that were present under `.claude/spec/` and `.claude/tasks/` when you read the project in step 2 — the scaffolding this run consumed.
A file added after that read is not swept up.
Leave the now-empty `.claude/spec/` and `.claude/tasks/` directories in place, along with everything else under `.claude/`.

54
skills/wiki/SKILL.md Normal file
View File

@@ -0,0 +1,54 @@
---
name: wiki
description: Answer from the user's personal Obsidian notes — their "vault", "wiki", or "notes" — read-only. Fires when a question plausibly concerns the user's own recorded knowledge (projects, setup, config, decisions, preferences, or how-to notes they wrote) rather than general world facts, or on "check my notes/vault/wiki", "what do my notes say about…", "do I have anything on…". Returns a synthesized answer with the source note paths, or states plainly that the vault has nothing relevant.
---
# wiki
Answer a question from the user's personal Obsidian vault, read-only.
The vault is a knowledge base the user maintains, and this skill only ever reads it.
It searches the vault and nothing else — not the web, not general knowledge — and the caller decides whether to combine the result with other sources.
The caller may be the user directly, a subagent, or another skill such as `/consume`, and the process below is the same for all three.
## 1. Resolve the vault and its read boundary
The vault lives at `$(xdg-user-dir DOCUMENTS)/notes`.
If that path does not resolve or does not exist, report that the vault is unreachable and stop.
Read `<vault>/.claude/settings.json` and collect every `permissions.deny` entry of the form `Read(<glob>)`.
The glob inside each is a path relative to the vault root, so normalize it — drop the leading `./` and trailing `/**` — to get the off-limits path, turning `Read(./05 journal/**)` into `05 journal/`.
Those paths are off-limits: never read or search under one, and never let its contents reach an answer.
The harness does not apply these rules when you run from outside the vault, so enforcing them is this skill's job.
Done when you have the vault path and the set of off-limits paths (currently `05 journal/`).
## 2. Gather candidate notes
Expand the question into several search terms — synonyms, related concepts, and named entities — so a note worded differently than the question is still found.
Search with ripgrep over the Markdown files directly, not obsidian-cli, so retrieval works whether or not Obsidian is running: `rg -l -i` each term over `*.md` under the vault, excluding each off-limits path with ripgrep's own `-g '!<path>'` syntax.
Then widen for recall through the vault's topic hubs.
Each note in `02 tags/` names a topic, and every note on that topic links to it with a `[[topic]]` wikilink, so for any hub matching the question, add its members — the notes containing `[[<hub-name>]]` — to the candidates.
Done when you have a candidate set of note paths.
## 3. Read to saturation, following links
Read every candidate note.
Within each, follow every `[[wikilink]]` that bears on the question to its note and read that one too, then repeat on those notes' links.
Continue until a full pass surfaces no note you have not already read — saturation.
There is no cap on how many notes you read, and a broad question legitimately pulls in many.
Never follow a link into a denied glob, and read only Markdown — attachments and other binaries are not sources.
Done when every note bearing on the question has been read and a further pass finds nothing new.
## 4. Answer with provenance, or report nothing
If the notes answer the question, synthesize the answer, then list the notes whose content you drew on by path, each with its key excerpt, and cite that path for every claim taken from the vault.
A note that only led you to others, such as an empty topic hub, is a discovery aid rather than a source, so leave it out of the list.
Mark anything sourced from `00 INBOX/` as unvetted, since that folder is raw capture the user has not yet curated.
If nothing relevant was found, say plainly that the vault has nothing on the question.
Do not pad the answer with vault-flavored prose that no note supports, and do not create a note to fill the gap.
Done when the answer cites its source notes, or explicitly reports that the vault has nothing relevant.