feat: route consume knowledge to two channels (#9-#14)
Reworks the consume skill around two acceptance axes and two destinations, implementing the six issues filed from the first real consume run as one design. - Add trigger-ability as a second acceptance axis alongside generalizes, with its two premises; a pull-channel note now requires both (#9). - Give consume a push channel — the target's own CLAUDE.md — for knowledge that fails an axis but is still useful: specific residue or proactive rules (#10). - Name the general-lesson/specific-residue split and route each half (#12). - Make the step-5 plan report a complete ledger with a per-note trigger line, push write-set, ref-fixes, flagged-not-authored, and drops (#13). - Extend project cleanup to reconcile CLAUDE.md (capture-gated removal/trim) and fix references to deleted files wherever they land (#11). - Encode a branch-owned output location: project notes flat under 01 sources/claude/projects/, honoring any pre-existing grouping (#14). Records the resolved vocabulary in .claude/CONTEXT.md and the two-channel write decision in .claude/adr/0001. Closes #9 Closes #10 Closes #11 Closes #12 Closes #13 Closes #14
This commit was merged in pull request #15.
This commit is contained in:
54
.claude/CONTEXT.md
Normal file
54
.claude/CONTEXT.md
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
# Skills
|
||||||
|
|
||||||
|
A personal collection of Claude Code skills.
|
||||||
|
The language below covers the knowledge-mining pipeline — the `consume` (write) and `wiki` (read) pair that move knowledge into and out of the user's Obsidian vault.
|
||||||
|
|
||||||
|
## Language
|
||||||
|
|
||||||
|
### Places
|
||||||
|
|
||||||
|
**Vault**:
|
||||||
|
The user's personal Obsidian knowledge base, read through `wiki` and written only within one area by `consume`.
|
||||||
|
_Avoid_: notes folder, Obsidian
|
||||||
|
|
||||||
|
**Pull channel**:
|
||||||
|
The vault area holding reusable knowledge, retrieved on demand by a future agent that goes looking for it.
|
||||||
|
_Avoid_: wiki proper, retrieval store
|
||||||
|
|
||||||
|
**Push channel**:
|
||||||
|
The target's own always-loaded documentation (its `CLAUDE.md`), whose value is being in front of an agent unprompted.
|
||||||
|
_Avoid_: proactive store, always-on docs
|
||||||
|
|
||||||
|
**Target**:
|
||||||
|
The single source `consume` ingests in one run — currently a project directory.
|
||||||
|
_Avoid_: source (reserve for the raw material within the target), input
|
||||||
|
|
||||||
|
### Acceptance axes
|
||||||
|
|
||||||
|
**Generalizes**:
|
||||||
|
A mined fact's property of teaching something true on a *different* target, not only the one it came from.
|
||||||
|
_Avoid_: reusable, transferable (use only informally)
|
||||||
|
|
||||||
|
**Trigger-able**:
|
||||||
|
A mined fact's property of having a recognizable symptom, error, or task that would send a future agent to retrieve it.
|
||||||
|
_Avoid_: searchable, useful
|
||||||
|
|
||||||
|
### What a source line yields
|
||||||
|
|
||||||
|
**General lesson**:
|
||||||
|
The transferable principle split out of a source line.
|
||||||
|
_Avoid_: concept, insight
|
||||||
|
|
||||||
|
**Specific residue**:
|
||||||
|
The concrete, target-only answer left after the general lesson is split off.
|
||||||
|
_Avoid_: leftover, detail
|
||||||
|
|
||||||
|
**Proactive rule**:
|
||||||
|
A mined fact that generalizes but is not trigger-able — a verification-discipline or design-stance rule whose value is firing unprompted.
|
||||||
|
_Avoid_: habit, guideline
|
||||||
|
|
||||||
|
### Planning
|
||||||
|
|
||||||
|
**Contribution map**:
|
||||||
|
The many-to-many record of which consumed file fed which planned note, with the exact contributing sections, including files that fed nothing.
|
||||||
|
_Avoid_: provenance table, coverage map
|
||||||
17
.claude/adr/0001-consume-writes-target-push-channel.md
Normal file
17
.claude/adr/0001-consume-writes-target-push-channel.md
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# Consume writes the target's push channel, not only the vault
|
||||||
|
|
||||||
|
`consume` was scoped to write only inside the vault's `01 sources/claude/` area.
|
||||||
|
A real run showed that most mined knowledge is not wiki-shaped — specific residue and proactive rules belong in the target's own always-loaded `CLAUDE.md` — and dropping it lost real signal, while redoing the target-doc edits by hand after each run was toil.
|
||||||
|
We decided `consume` writes a second channel outside the vault, the target's `CLAUDE.md`, rather than only planning those edits for the user to apply.
|
||||||
|
|
||||||
|
## Considered Options
|
||||||
|
|
||||||
|
- **Plan-only** — spell the target-doc edits out in the report and have the user apply them by hand.
|
||||||
|
Rejected: the whole value is not redoing what the run already worked out.
|
||||||
|
- **Auto-write both channels (chosen)** — apply the target edits too, but present them as a distinct, independently-approvable write-set under the one plan-approval gate, so a write outside the vault is never a surprise.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
`consume`'s blast radius now includes files outside the vault and outside the spec/task scaffolding it deletes.
|
||||||
|
The plan-approval gate is what keeps that safe: the target write-set is approved separately from the vault write-set, and a declined target write-set degrades to flagged suggestions.
|
||||||
|
Destructive edits to `CLAUDE.md` are gated on capture — an entry is removed or trimmed only when its general part is present in the wiki.
|
||||||
@@ -6,23 +6,28 @@ disable-model-invocation: true
|
|||||||
|
|
||||||
# consume
|
# 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.
|
Mine a source for its knowledge, routing each fact to the agent's own wiki or the target's always-loaded docs, 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.
|
`/consume [target]` ingests one target — a filesystem path, defaulting to the current directory — and distils what it mines into two channels.
|
||||||
It is the write side of a pair with the read-only `/wiki`, which it invokes to read the rest of the vault.
|
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.
|
The **pull channel** is the wiki — reusable knowledge a future agent retrieves on demand — and a fact earns a note there only if it both **generalizes** past the target it came from and is **trigger-able**, meaning some symptom, error, or task would send that agent looking for it.
|
||||||
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.
|
The **push channel** is the target's own always-loaded documentation, its `CLAUDE.md`, which carries what is useful but not wiki-shaped: a concrete repo-specific answer, or a proactive rule whose value is firing unprompted.
|
||||||
|
A single fact mined from the source usually splits across both — the transferable general lesson to the pull channel, the specific residue it leaves behind to the push channel.
|
||||||
|
|
||||||
Nothing is written and nothing is deleted until the user approves the plan.
|
Nothing is written and nothing is deleted until the user approves the plan.
|
||||||
|
|
||||||
## The write boundary
|
## The write surfaces
|
||||||
|
|
||||||
|
Consume writes to two places and nowhere else.
|
||||||
|
|
||||||
The vault lives at `$(xdg-user-dir DOCUMENTS)/notes`.
|
The vault lives at `$(xdg-user-dir DOCUMENTS)/notes`.
|
||||||
Resolve it; if it does not exist, report that the vault is unreachable and stop.
|
Resolve it, and if it does not exist report that the vault is unreachable and stop.
|
||||||
|
Inside the vault, write only under `01 sources/claude/`, treating every other vault path as off-limits to writes.
|
||||||
|
Outside the vault, the only sanctioned write is the target's own always-loaded documentation, its `CLAUDE.md` — the push channel of step 6.
|
||||||
|
Everything else in the target is read-only, save for the scaffolding step 7 deletes.
|
||||||
|
|
||||||
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 the vault boundary is the skill's job.
|
||||||
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.
|
All reading of the wider vault goes through `/wiki` (step 3), which enforces the vault's read boundary itself.
|
||||||
|
|
||||||
## 1. Select the branch
|
## 1. Select the branch
|
||||||
@@ -52,44 +57,74 @@ Done when you know which existing notes bear on what you are about to write.
|
|||||||
|
|
||||||
## 4. Plan the notes
|
## 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.
|
Route every fact you mined through two acceptance axes.
|
||||||
Keep each note atomic — one transferable idea per note; when a note carries two independent lessons, split it.
|
|
||||||
|
- **Generalizes** — it teaches something that holds on a *different* target, not a fact true only of this one.
|
||||||
|
- **Trigger-able** — a recognizable symptom, error, or task would send a future agent to retrieve it.
|
||||||
|
|
||||||
|
Two premises stand behind trigger-ability.
|
||||||
|
The wiki is retrieval-on-demand, so knowledge whose only value is firing *unprompted* does not belong there however well it generalizes.
|
||||||
|
And the reader is an amnesiac agent, so "the reader will internalize it" is never a reason to keep a note — trigger-ability, not memorability, is the axis.
|
||||||
|
|
||||||
|
A fact earns a **pull-channel note** only when it passes *both* axes.
|
||||||
|
A fact that fails either axis but is still useful to the target goes to the **push channel**, the target's `CLAUDE.md`: a **specific residue** that fails *generalizes* (the concrete repo-specific answer), or a **proactive rule** that generalizes but is not trigger-able (a verification-discipline or design-stance rule whose value is firing unprompted).
|
||||||
|
A fact that fails both axes and is useful to no one is dropped.
|
||||||
|
|
||||||
|
Most source lines split rather than route whole: the transferable **general lesson** goes to the pull channel, the **specific residue** it leaves behind goes to the push channel — recorded in the target's `CLAUDE.md` when that file does not already hold it.
|
||||||
|
So plan both destinations together, deciding for each pull-channel note whether it is new or an update to an existing note whose knowledge is now stale or thinner than what you have learned.
|
||||||
|
|
||||||
|
Keep each pull-channel 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.
|
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.
|
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.
|
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.
|
Done when every mined fact has a decided destination — pull note, push item, or explicit drop — every pull-channel note passes both axes 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
|
## 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.
|
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.
|
The report is a complete ledger of every mined fact's disposition, not only of what gets written, so the selection bar itself can be reviewed:
|
||||||
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.
|
|
||||||
|
1. **Vault write-set (pull)** — each note to write or update, with its **trigger line**: one sentence naming the symptom, error, or task that would send a reader to retrieve it, and the `[[hub]]` wikilinks it belongs under.
|
||||||
|
2. **Contribution map** — for every consumed file, the notes it feeds and the exact contributing sections, including any file that fed nothing.
|
||||||
|
3. **Push write-set (target `CLAUDE.md`)** — each proactive rule and each specific residue to add, each existing entry to trim to its residue, and each pure-general entry to remove, with the exact text and where it lands.
|
||||||
|
4. **Ref-fixes** — each file holding a reference to a spec or task file about to be deleted, and how the reference is fixed or removed. These accompany the scaffolding deletion of step 7, not the target write-set.
|
||||||
|
5. **Flagged, not authored** — any `[[hub]]` a note links that does not yet exist under `02 tags/` or `03 index/`, and any push knowledge whose home is a hook or checklist rather than `CLAUDE.md` — surfaced for the user to act on by hand.
|
||||||
|
6. **Drops** — every mined fact considered and cut, one line of why each.
|
||||||
|
|
||||||
|
The vault write-set and the target-`CLAUDE.md` write-set are approved independently: the user may accept one and decline the other.
|
||||||
|
A declined target write-set degrades to flagged suggestions — reported for the user to apply by hand, written nowhere.
|
||||||
|
The ref-fixes and the scaffolding deletion are not a write-set to accept or decline — they follow from proceeding with the run and execute in step 7, gated only behind the vault writes.
|
||||||
|
|
||||||
Stop and wait for the user's explicit approval.
|
Stop and wait for the user's explicit approval.
|
||||||
Write nothing and delete nothing until they approve.
|
Write nothing and delete nothing until they approve.
|
||||||
|
|
||||||
Done when the user has approved the plan.
|
Done when the user has ruled on each write-set.
|
||||||
|
|
||||||
## 6. Write the notes
|
## 6. Write the notes and reconcile the push channel
|
||||||
|
|
||||||
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.
|
Write the approved vault write-set first.
|
||||||
|
Write each new note and update each changed one under the output area the branch declares, 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.
|
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.
|
Then, if the target write-set was approved, reconcile the target's `CLAUDE.md`: add the proactive rules and any specific residue the file does not already hold, trim mixed entries to their specific residue, and remove the pure-general entries.
|
||||||
|
Removal is gated on capture — trim or remove an entry only when its general part is present in the wiki, written just now in this run or confirmed already there via `/wiki`, never on the intention to write a note.
|
||||||
|
If the target write-set was declined, write nothing to the target and leave its items as the flagged suggestions of step 5.
|
||||||
|
|
||||||
|
Done when the approved vault notes are written and, if approved, the target's `CLAUDE.md` is reconciled.
|
||||||
|
|
||||||
## 7. Clear the consumed scaffolding
|
## 7. Clear the consumed scaffolding
|
||||||
|
|
||||||
With the notes written, perform the branch's cleanup — the branch file names exactly what to remove.
|
With the notes written, perform the branch's cleanup — the branch file names exactly what to remove and what references to repair.
|
||||||
Deletion never precedes the writes of step 6.
|
Deletion never precedes the writes of step 6.
|
||||||
|
|
||||||
Done when the branch's cleanup has run.
|
Done when the branch's cleanup has run.
|
||||||
|
|
||||||
## 8. Report
|
## 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.
|
Tell the user what you created, updated, and left untouched across both channels — vault notes written or updated, and the target's `CLAUDE.md` reconciliation applied or, if declined, left as flagged suggestions.
|
||||||
|
Repeat the suggested new hubs and any hook-or-checklist items from the report, so the vault's `02 tags/` and `03 index/` and the target's other channels can be filled in by hand.
|
||||||
|
|
||||||
Done when the summary names every note written or updated and every suggested hub.
|
Done when the summary names every note written or updated, every target edit applied or flagged, and every suggested hub.
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ Reached from step 1 of [`SKILL.md`](SKILL.md) when the target is a directory con
|
|||||||
|
|
||||||
The source code is the truth for *what* the project is and does now.
|
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.
|
Read it thoroughly enough to understand its current state and to surface the reusable ideas it embodies — techniques, patterns, decisions, gotchas.
|
||||||
|
A gotcha usually carries two separable things — a transferable principle and a concrete repo-specific answer — so surface both.
|
||||||
|
Step 4 of SKILL.md routes the principle to the pull channel and the residue to the target's push channel.
|
||||||
|
|
||||||
`.claude/spec/` and `.claude/tasks/` are the record of *why* — the reasoning, trade-offs, and intent behind what the code became.
|
`.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.
|
They are the richest source of the generalizable lessons, and cleanup destroys them, so mine their reasoning now or lose it.
|
||||||
@@ -16,8 +18,18 @@ Together these are the raw material the writing logic generalizes; extracting th
|
|||||||
|
|
||||||
Done when you understand the project's current state from its source and have mined its specs and tasks for the reasoning behind it.
|
Done when you understand the project's current state from its source and have mined its specs and tasks for the reasoning behind it.
|
||||||
|
|
||||||
|
## Output location
|
||||||
|
|
||||||
|
Project notes land flat under `01 sources/claude/projects/`, this branch's own area within the vault write boundary.
|
||||||
|
This is the source-type carve — other consume source types get their own sibling areas later, so project output never mixes with them.
|
||||||
|
Keep the area flat by default and never reorganize it.
|
||||||
|
If the user has already grouped some notes into subfolders under `projects/`, write a new note into the matching group rather than at the top level.
|
||||||
|
|
||||||
## Cleanup
|
## 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.
|
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.
|
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/`.
|
Leave the now-empty `.claude/spec/` and `.claude/tasks/` directories in place, along with everything else under `.claude/`.
|
||||||
|
|
||||||
|
Deleting those files can strand references to them.
|
||||||
|
Scan the target for pointers to each file about to be deleted — in `CLAUDE.md`, `CONTEXT.md`, ADRs, and sibling specs — and fix or remove each one, following the pointer wherever it lands rather than checking `CLAUDE.md` alone.
|
||||||
|
|||||||
Reference in New Issue
Block a user