Skip to content

Commit 9e85b62

Browse files
authored
feat(skills): add vault-skill-factory — generate Agent Skills from mature wiki pages (#98)
Implements the proposal from issue #96. Turns a cluster of mature, curated Obsidian wiki pages into a portable Agent Skill (SKILL.md + references/), the inverse of wiki-capture. - .skills/vault-skill-factory/SKILL.md: new skill with hard guardrails (never writes to .skills/, never auto-installs), QMD-based cluster discovery, maturity filtering, and provenance manifest. - .env.example: SKILL_FACTORY_OUTPUT_DIR and SKILL_FACTORY_MATURITY keys. - AGENTS.md: routing row for /vault-skill-factory and related phrasings. Closes #96
1 parent 8235e6f commit 9e85b62

3 files changed

Lines changed: 146 additions & 0 deletions

File tree

.env.example

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,16 @@ QMD_CLI_SEARCH_MODE=quality
7777
# Optional qmd binary override if qmd is not on PATH.
7878
QMD_CLI=qmd
7979

80+
# --- Vault Skill Factory (optional) ---
81+
#
82+
# vault-skill-factory turns mature curated pages into portable Agent Skills.
83+
# Generated skills land in a REVIEW directory — never auto-installed, never written to .skills/.
84+
#
85+
# Where generated skills are written (default: <OBSIDIAN_VAULT_PATH>/_generated-skills — a
86+
# vault-level excluded dir like _raw/_staging, NOT the skills/ knowledge category).
87+
SKILL_FACTORY_OUTPUT_DIR=
88+
# Which lifecycle states count as "mature" enough to harvest (pages with tier: core also qualify).
89+
SKILL_FACTORY_MATURITY=reviewed,verified
8090
# --- PageIndex: structure-aware long-PDF preprocessing (optional) ---
8191
#
8292
# For long PDFs (books, reports), build a table-of-contents tree (section titles +
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
---
2+
name: vault-skill-factory
3+
description: >
4+
Generate a portable, self-contained Agent Skill from mature, curated Obsidian wiki pages —
5+
turning a cluster of verified knowledge into a reusable "digital expert" (SKILL.md + references/).
6+
Use this skill when the user says "/vault-skill-factory", "make a skill from my wiki", "turn these
7+
pages into a skill", "generate an agent skill from my vault", "package my notes on X as a skill",
8+
"build a domain-expert skill from my wiki", or wants to distill recurring, mature wiki knowledge
9+
into a shareable skill. Inspired by OpenKB's "drop in a book → out comes a digital expert" pattern.
10+
The factory ONLY reads the vault and WRITES TO A REVIEW DIRECTORY — it never installs skills,
11+
never writes into .skills/, and never touches global skill directories.
12+
---
13+
14+
# Vault Skill Factory
15+
16+
You turn a cluster of **mature, curated** wiki pages into a **portable Agent Skill**: a
17+
`SKILL.md` plus a `references/` folder, written to a review directory for the human to inspect
18+
and (only if they choose) install. This is the inverse of `wiki-capture`: capture turns a
19+
conversation into a page; the factory turns a body of pages into a reusable skill.
20+
21+
## Hard guardrails (read first)
22+
23+
- **Never write into `.skills/`** and **never run `setup.sh`** or create symlinks into any global
24+
skill directory (`~/.claude/skills`, `~/.codex/skills`, …). Generated skills go to the review
25+
dir only. Installation is a separate, explicit human decision.
26+
- **Never auto-install.** End by telling the user where the skill is and how to install it
27+
*project-locally* if they want — do not do it for them.
28+
- Source pages are trusted vault content, but do not invent capabilities: the generated skill must
29+
reflect what the pages actually say.
30+
31+
## Before You Start
32+
33+
1. **Resolve config** (Config Resolution Protocol in `llm-wiki/SKILL.md`): get `OBSIDIAN_VAULT_PATH`,
34+
`OBSIDIAN_WIKI_REPO`, `OBSIDIAN_LINK_FORMAT`, the QMD vars, and:
35+
- `SKILL_FACTORY_OUTPUT_DIR` — where generated skills land. Default:
36+
`$OBSIDIAN_VAULT_PATH/_generated-skills` (a vault-level, underscore-prefixed *excluded* dir —
37+
like `_raw`/`_staging`/`_sources`, NOT the `skills/` knowledge category). This co-locates
38+
generated skills with the vault they were distilled from. Create it if missing.
39+
Note: `_generated-skills/` holds runtime Agent-Skill bundles (`name` + `description` frontmatter),
40+
**not** wiki pages — never write them into `skills/` (that category is for knowledge pages and
41+
is graph-/lint-/index-tracked).
42+
- `SKILL_FACTORY_MATURITY` — comma list of `lifecycle:` values that count as "mature".
43+
Default: `reviewed,verified`. Pages with `tier: core` also qualify.
44+
2. Read `index.md` to understand what the vault holds.
45+
46+
## Step 1: Choose the cluster
47+
48+
Decide which pages become the skill. The user may name a topic, tag, or project; otherwise propose
49+
candidates.
50+
51+
1. **Seed** from the user's intent (a topic, tag, project, or a named page).
52+
2. **Expand** the cluster:
53+
- If QMD is configured (`QMD_WIKI_COLLECTION`), run `qmd query "<topic>" -c "$QMD_WIKI_COLLECTION" --files`
54+
(or `vsearch`) to gather semantically related pages — this is the intended way to find the
55+
full cluster, not just exact-tag matches.
56+
- Otherwise `Grep`/`Glob` by tag and wikilink-neighbourhood (pages linked from the seed pages).
57+
3. **Filter by maturity:** keep pages whose `lifecycle:` is in `SKILL_FACTORY_MATURITY` **or**
58+
whose `tier:` is `core`. Drop `draft` pages unless the user explicitly includes them.
59+
4. **Confirm the cluster with the user** (list page names + count) before generating. If fewer than
60+
~3 mature pages match, say so — a skill from one thin page isn't worth it; offer to proceed anyway
61+
or widen the net.
62+
63+
## Step 2: Design the skill
64+
65+
From the cluster, decide:
66+
67+
- **`name`** — kebab-case, derived from the cluster's subject (e.g. `french-theory-expert`,
68+
`peptide-protocols`). Must not collide with an existing skill in `.skills/`.
69+
- **`description`** — the trigger. Write it "pushy" (per `skill-creator`): state **when** to use it
70+
(all the phrasings a user might say) **and** what it does. This field is what makes the skill fire.
71+
- **Reasoning approach** — how an agent should *use* this knowledge: the questions it answers, the
72+
method it applies, the caveats it respects. Distil this from the pages' synthesis, not a copy-paste.
73+
- **Depth material** — which page bodies become `references/` files.
74+
75+
## Step 3: Write the skill to the review dir
76+
77+
Create `$SKILL_FACTORY_OUTPUT_DIR/<name>/` with:
78+
79+
```
80+
<name>/
81+
├── SKILL.md # frontmatter (name + pushy description) + reasoning approach + key knowledge
82+
├── references/ # depth material distilled from the cluster
83+
│ ├── <topic>.md # one per sub-theme; declarative knowledge, not chat
84+
│ └── sources.md # provenance: which vault pages this was built from (+ their sources)
85+
└── SKILL_FACTORY.md # provenance manifest (see below) — NOT part of the installed skill
86+
```
87+
88+
**SKILL.md body** should be lean (the trigger logic + a compact reasoning guide), pushing depth into
89+
`references/`. Follow the structure of existing skills in this repo. Preserve `^[inferred]` /
90+
`^[ambiguous]` markers when carrying over uncertain claims — a generated skill must not launder
91+
synthesis into fact.
92+
93+
**`references/sources.md`** lists every vault page used (by `[[wikilink]]`) and their upstream
94+
`sources:` — so the skill stays auditable back to the vault and original sources.
95+
96+
**`SKILL_FACTORY.md`** (factory metadata, kept out of the installable skill) records: generation
97+
date, the cluster pages + their lifecycle/tier, the maturity filter used, and the vault commit/hash
98+
if available. This lets a regenerate-on-update workflow diff later.
99+
100+
Optional, if the user asks: append/update a `marketplace.json` entry in the output dir (the OpenKB
101+
one-line-install convention) — still **not** an install, just a manifest.
102+
103+
## Step 4: Optionally lean on skill-creator
104+
105+
`skill-creator` ships reusable scripts (`$OBSIDIAN_WIKI_REPO/.skills/skill-creator/scripts/`):
106+
- `improve_description.py` — tighten the generated `description` for better triggering.
107+
- `package_skill.py` — bundle the skill dir into a distributable archive.
108+
- `quick_validate.py` — sanity-check the skill's structure.
109+
110+
Use them when the user wants a polished/validated artifact; don't reinvent them.
111+
112+
## Step 5: Report — and stop
113+
114+
Tell the user:
115+
- the path: `$SKILL_FACTORY_OUTPUT_DIR/<name>/`
116+
- the cluster it was built from (page count + names)
117+
- the trigger `description`
118+
- **How to install if they want it (their decision, project-local only):**
119+
```
120+
ln -s ../../.skills/<name> <repo>/.claude/skills/<name> # after copying <name>/ into .skills/, sans SKILL_FACTORY.md
121+
```
122+
Note explicitly: review first; do not run `setup.sh` (it fans skills into global dirs); never global-install without explicit agreement.
123+
124+
Do **not** install it yourself. Do not write to `.skills/`. Done.
125+
126+
## Quality checklist
127+
128+
- [ ] Output went to `$SKILL_FACTORY_OUTPUT_DIR`, never `.skills/` or a global dir
129+
- [ ] Cluster confirmed with the user; only mature pages (per `SKILL_FACTORY_MATURITY` / `tier: core`)
130+
- [ ] `description` is pushy and accurate (when + what)
131+
- [ ] SKILL.md body is lean; depth lives in `references/`
132+
- [ ] `^[inferred]`/`^[ambiguous]` markers preserved; no synthesis laundered into fact
133+
- [ ] `references/sources.md` traces back to vault pages + their sources
134+
- [ ] `SKILL_FACTORY.md` provenance manifest present (excluded from the installable skill)
135+
- [ ] Report names the path and the manual, project-local-only install step; nothing auto-installed

AGENTS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ Skills live in `.skills/<name>/SKILL.md`. Match the user's intent to the right s
7171
| "create a dashboard" / "vault dashboard" / "show all X as a table" / "dynamic view" | `wiki-dashboard` |
7272
| "synthesize my wiki" / "find connections" / "what concepts keep coming up together" / "/wiki-synthesize" | `wiki-synthesize` |
7373
| "create a new skill" | `skill-creator` |
74+
| "/vault-skill-factory" / "make a skill from my wiki" / "turn these pages into a skill" / "package my notes on X as a skill" / "build a domain-expert skill from my vault" | `vault-skill-factory` |
7475
| "/wiki-claude [topic]" / "/wiki-codex [topic]" / "/wiki-hermes [topic]" / "/wiki-openclaw [topic]" / "/wiki-copilot [topic]" / "/wiki-pi [topic]" | `wiki-agent` |
7576
| "/memory-bridge" / "browse codex memory" / "what did codex know about X" / "compare tool memories" / "cross-tool memory" | `memory-bridge` |
7677
| "/daily-update" / "morning sync" / "refresh the wiki index" / "set up the daily cron" / "install terminal notification" | `daily-update` |

0 commit comments

Comments
 (0)