obsidian-vault-scaffolder
Scaffolds a PARA-style Obsidian vault for a software engineering project — folders, Obsidian Bases (database views), note templates, an AGENTS.md briefing, plus (when a spec/brief is provided) atomize
SKILL.md.claude/skills/obsidian-vault/SKILL.md
GitHubObsidian Vault Scaffolder
Build a PARA-style Obsidian vault for a software engineering project, with the boilerplate (folders, Bases, templates, index) auto-generated by a script and the project-specific content (atomized spec sections, risks, open questions) authored by Claude based on the user's source material.
Why this skill exists
Software project specs end up as one giant Markdown file that nobody navigates after week one. Obsidian fixes that if the vault is structured well — atomic notes, queryable frontmatter, Bases as live views. But the structure has a lot of boilerplate (templates, base files, MOCs, an AGENTS.md for AI context) that's tedious to handcraft every time. This skill captures the working layout so the user can go from "here's my spec" to "here's a navigable knowledge base I can build on" in one shot.
When to use
Trigger on any of these:
- "Set up an Obsidian vault for [project]"
- "Build a project workspace / knowledge base / memory system for [project]"
- "Scaffold a PARA vault"
- "Turn this spec into a browsable structure"
- "I want project memory management for [project]"
- "Make me a vault for the project I'm starting"
- The user references the PARA method (Projects, Areas, Resources, Archive) for project organization
Do NOT use for:
- Simple "save this file" requests
- Non-project notes (a single research note, journal entries, etc.)
- Vaults already fully built — for adding a single note to an existing vault, just write the note directly
High-level workflow
Interview → Build config → Run scaffold script → Atomize spec (if any) → Verify → Save memory
Each step below has a section. Don't skip the interview — assumptions about vault path or scope wreck the output.
Step 1: Interview the user
Use the AskUserQuestion tool. Bundle the questions that matter into one or two calls — don't drip-feed.
Required information:
Vault location. Where does this go? Two cases:
- Adding a project to an existing Obsidian vault → ask for the vault root path. The skill creates
10_Projects/<ProjectName>/and shared scaffolding (_Bases/,_Templates/,00_Index/) only if missing. - Creating a new vault from scratch → ask for the target path. The skill creates the full PARA layout.
- Adding a project to an existing Obsidian vault → ask for the vault root path. The skill creates
Project name. The folder name under
10_Projects/. Keep it concise.Source material. Three modes, sharply distinguished:
- Spec-driven (≥1 page of structured content with headings): user points at a Markdown/Word/PDF spec. Atomize per
references/atomization_playbook.md. After atomizing, populate the Project Charter from the spec's Executive Context. Skipcharter_seed— Step 4's Charter-population will rewrite the Charter anyway, so seeding it here is wasted work. - Brief-driven (≥3 paragraphs of conversational text, e.g., a Slack post): atomize what you can extract — open questions, risks, architecture notes, stakeholders — using the playbook's "informal source" rules. Populate the Charter from the brief in Step 4. Same as spec-driven, skip
charter_seed. - One-liner (a sentence or two of description, in chat or via the prompt): no atomization. Pass the description as
charter_seedin the config so the scaffolder drops it into the Project Charter's blockquote and One-Line Pitch. No Step 4 follow-up needed. - Skeleton-only (truly nothing — the user has not described the project at all): blank Charter for the user to fill in. Rare. If the user said anything substantive about the project, treat as one-liner instead.
TL;DR:
charter_seedis for one-liner mode only. Spec and brief modes overwrite the Charter in Step 4.- Spec-driven (≥1 page of structured content with headings): user points at a Markdown/Word/PDF spec. Atomize per
Optional knobs. Default to the recommended layout. Ask only if the user has signaled customization:
- Drop folders (e.g.,
20_Areasis often unnecessary for a single project) - Skip Bases (the user may be on an old Obsidian version that doesn't support
.base) - Skip Templates folder
- Drop folders (e.g.,
The AskUserQuestion call should look like:
1. Where should the vault live? (existing vault path / new path)
2. Project name?
3. Source material? (spec doc + path / brief in chat / one-liner / nothing)
4. Custom layout? (default / drop 20_Areas / skip Bases / other)
Include reasonable defaults marked "(Recommended)" so the user can blow through it in seconds.
No-follow-ups escape hatch
If the user preemptively waives the interview ("don't ask follow-ups", "just do it", "use defaults"), skip Step 1 entirely. Infer every answer from the message:
- Vault path → whatever path the user named (or, if they only named "Obsidian", the canonical Obsidian vault path you can infer from their setup; ask only if truly ambiguous)
- Project name → from the message
- Source mode → spec-driven if they gave you a file path; brief-driven if they pasted/pointed at multi-paragraph text; one-liner if they gave a sentence; skeleton if nothing
- Layout → default
Go straight to Step 2. The "no follow-ups" instruction is a signal that the user wants execution, not negotiation.
Step 2: Build the config JSON
Translate the interview answers into a JSON config the scaffolder script consumes. Schema lives in references/config_schema.md. Quick example:
{
"vault_path": "/Users/example/Obsidian/MyVault",
"project_name": "Forge",
"mode": "new_vault",
"include_top_folders": ["00_Index", "10_Projects", "30_Resources", "40_Archive", "_Attachments", "_Bases", "_Templates", "docs"],
"project_subfolders": ["Architecture", "Brief", "Contracts", "Data Sources", "Open Questions", "People", "Phases", "Plans", "Reference", "Risks", "Specs", "Sprints", "Week 1", "Work Batches"],
"bases": ["Open Questions", "Project Tracker", "Risks", "Signals"],
"templates": ["Project", "Open Question", "Risk", "Spec Section", "Person", "Sprint", "Signal", "Note"],
"create_home": true,
"create_agents_md": true,
"create_moc": true
}
Save it to a temp path (e.g., /tmp/vault_config_<project>.json).
Step 3: Run the scaffolder
python3 <skill-path>/scripts/scaffold_vault.py --config /tmp/vault_config_<project>.json
The script:
- Creates the folder layout (idempotent — skips folders that exist)
- Writes
_Bases/*.basefiles - Writes
_Templates/*.md(with{{title}},{{sprint}},{{milestone}}placeholders for cloning) - Writes
00_Index/HOME.md,00_Index/AGENTS.md,00_Index/MOCs/<ProjectName> MOC.md(only if absent — preserves existing HOME/AGENTS in existing-vault mode) - Writes
10_Projects/<ProjectName>/Project Charter.md(usescharter_seedfrom config if present) - Writes
10_Projects/<ProjectName>/Week 1/Milestone 1.mdshell - Prints a summary of files created, updated in place (HOME.md splices, AGENTS.md rewrites), and skipped (already existed)
Existing-vault mode
When the target vault already exists with at least one project, the scaffolder:
- Detects existing projects by counting populated subfolders in
10_Projects/before adding the new one. - Splices the new project into
00_Index/HOME.md— idempotently inserts[[Project Charter|<NewProject>]]under## Active Projectsand[[<NewProject> MOC]]under## Maps of Content. Does not overwrite or reformat the rest of HOME.md. - Rewrites
00_Index/AGENTS.mdas project-agnostic if there are now 2+ projects in the vault. The single-project AGENTS.md bakes the project name into the body ("for the X project") — once you have multiple projects, that becomes stale, so the scaffolder swaps in a generic version that references10_Projects/<Project>/paths instead. - Leaves the existing project's MOC, Charter, atomized notes, and Specs/ completely untouched. It only writes new files under
10_Projects/<NewProject>/.
If the script fails, read the error, fix it, and rerun. Don't silently fall back to manual file creation — the script's deterministic output is the value of bundling it.
Step 4: Atomize the spec or brief (if applicable)
This is the high-leverage part. If the user has source material (spec or brief), follow references/atomization_playbook.md to break it into discrete notes across the project subfolders. The playbook maps common spec sections to target folders and tells you what to extract vs. summarize. It includes a section on informal sources (briefs, transcripts) for the brief-driven case.
Key principles (full detail in the playbook):
- One concept per note. Each risk, each open question, each spec section gets its own file.
- Frontmatter
type:is mandatory. Bases query against it. Schema inreferences/frontmatter_schema.md. - Wikilinks for cross-references.
[[Note Name]], not relative paths. - The original source stays canonical. Move it to
10_Projects/<ProjectName>/Specs/<original-filename>.mdand add frontmatter. Atomized notes link back to it; they don't duplicate it. - Don't paraphrase into drift. If a section is genuinely small enough to live inline, leave it inline and link.
Populating the Project Charter
The scaffolder writes a Charter shell. After atomization, circle back and populate it from the source material:
- One-Line Pitch: extract from the spec's Executive Context / one-line claim, or from the first sentence of the brief.
- Why It Works: 3–5 bullet points pulled from the source.
- Phase I Scope and Phase I Non-Goals: lift directly from the source if those sections exist.
- Key Documents: link to
[[canonical-spec-filename]],[[Forge MOC]], the main Architecture / Plan notes you just authored. - Status: one sentence on current state ("Pre-implementation, spec drafted X").
If you passed charter_seed in the config (one-liner mode), the scaffolder pre-fills the blockquote and One-Line Pitch — you may still want to populate Why It Works / Scope from the source if there's material to work with.
After atomization, update 00_Index/MOCs/<ProjectName> MOC.md to list the new notes grouped by category (Anchor, Brief, Architecture, Specs, Phases & Plans, Reference, Open Questions, Risks, Sprints, etc.).
Step 5: Skeleton mode (truly nothing provided)
If the user has provided no description at all (rare — usually they'll have at least a one-liner, which is the one-liner mode, not skeleton), leave the scaffolded shells empty but well-frontmattered. Specifically:
Project Charter.mdhas frontmatter and section headers (Pitch, Why It Works, Phase I Scope, Non-Goals, Status) that the user fills inBrief/,Architecture/,Open Questions/,Risks/are empty folders_Templates/ensures any future note starts with proper frontmatter
The user can come back and re-run the skill once they have a spec. Atomization is an additive operation.
The one-liner case is not skeleton. When the user has given you a sentence — even just "a self-hosted Vercel alternative for Node services" — pass that as charter_seed in the config. The scaffolder drops it into the Charter blockquote so the vault opens to "this is what this project is" instead of "(fill in)". Throwing away the user's own description is wasteful.
Step 6: Verify
Run the bundled verify subcommand — it checks every note has a type: frontmatter value AND that the value is in the canonical set. The naive grep ^type: check from earlier versions only confirmed presence, missing typos like type: Risk (capital R) that silently break Bases.
python3 <skill-path>/scripts/scaffold_vault.py verify <vault-path>
Exit code 0 = clean. Exit code 1 = one or more notes have missing or invalid type: values, listed with paths. Fix and re-run.
If you need a quick distribution check (which type values appear and how often), use:
find <vault>/10_Projects/<ProjectName> -name "*.md" -print0 | xargs -0 grep -h "^type:" | sort | uniq -c
Filenames with spaces are common in Obsidian — always use find -print0 and xargs -0 (or read -d ''). Pipe-then-while with unquoted variables is a trap.
Step 7: Save memory (optional)
If the user has Claude memory available (the auto-memory system), save two entries:
- Project memory — what the project is, current phase, why it matters
- Vault structure memory — vault path, layout conventions, where the canonical spec lives, frontmatter conventions, "don't paraphrase the spec into drift" rule
Reference: how I save these for the Forge project is the canonical example. See pattern in references/memory_entries.md.
Skip this if the memory system isn't available or the user hasn't opted in.
Conventions to keep stable across vaults
These are deliberate — don't let the user negotiate them away unless they have a strong reason. They're what makes the vault queryable and AI-friendly:
- Top-level folders are numbered (
00_Index,10_Projects,30_Resources,40_Archive) so they sort predictably. Special folders are underscore-prefixed (_Attachments,_Bases,_Templates). - Frontmatter
type:is non-negotiable on every note. Bases break without it. - Risks and Open Questions get their own files, never lists in a single
Risks.md. The Bases views depend on this. - Filename prefixes for sortability: "Risk — X", "Open Question — X" sort and search well.
- The canonical spec (if any) is the single source of truth. Atomized notes link back; they don't duplicate.
AGENTS.mdexists so future AI agents (Claude included) have a one-stop briefing on vault conventions.
Folder roles inside a project (clarification)
These three are easy to confuse — they have distinct jobs:
Plans/— the what. Milestone definitions, implementation sequence, roadmap. One note per milestone (e.g.,Milestone 1 — Foundation.md) plus anImplementation Sequence.mdindex. Frontmattertype: plan. These are stable, definitional documents.Sprints/— execution containers. One note per sprint (could be a week, could be a 2-week cycle). Tracks tasks, daily log, risks surfaced, decisions made. Frontmattertype: sprint. These are working logs.Week 1/,Week 2/, ... — short-term sprint folders during the project's earliest velocity-tracking phase. Sametype: sprintasSprints/but the timeboxed folder name makes the cadence visible in the tree. Once the project is past Week 4 or so, fold them intoSprints/.
In short: Plans/ says what we're going to build and when. Sprints/ and Week N/ say what we did each cycle.
Reference files
references/atomization_playbook.md— how to break a spec into notes (read this when you have a spec to atomize)references/frontmatter_schema.md—typevalues and their extra fields (consult before authoring any note)references/bases_yaml.md— Obsidian Bases v1 YAML format and version-compat notes (consult if Bases need adjustment)references/folder_layout.md— full PARA layout with rationale per folderreferences/config_schema.md— JSON config schema forscaffold_vault.pyreferences/memory_entries.md— pattern for saving vault/project memory entries
Example invocation
User says: "I'm starting a new GPU resale platform project. The spec is at ~/Documents/spec.md. Set me up an Obsidian vault for it."
- AskUserQuestion → vault path (default: existing Obsidian vault), project name (Forge), source = spec at the given path, layout = default (drop 20_Areas)
- Build config JSON
- Run scaffolder script → folder structure + Bases + Templates + Index
- Read the spec, follow the atomization playbook → create notes in Specs/, Architecture/, Open Questions/, Risks/, etc.
- Verify frontmatter is consistent
- Save memory entries
- Tell the user where to open:
vault/00_Index/HOME.md