| created | "2026-04-17T00:00:00.000Z" |
| modified | "2026-06-28T00:00:00.000Z" |
| reviewed | "2026-06-28T00:00:00.000Z" |
| name | vault-mocs |
| description | Map-of-Content (MOC) curation for Obsidian vaults. Use when creating a MOC for a tag, extending with orphans, fixing legacy MOC tags, or analyzing coverage. |
| user-invocable | false |
| allowed-tools | Read, Edit, Write, Grep, Glob |
MOC Curation
When to Use This Skill
| Use this skill when... | Use the alternative instead when... |
|---|
| Creating or extending a Map of Content hub for a tag category | Reconnecting individual orphaned notes without building a hub โ use vault-orphans |
Migrating legacy ๐บ๏ธ MOC tags to canonical ๐/moc | Renaming or consolidating non-MOC tags across the vault โ use vault-tags |
| Auditing MOC coverage and linking orphans into existing hubs | Repairing broken [[...]] references inside an existing MOC โ use vault-wikilinks |
A Map of Content (MOC) is a structured hub note that organizes related content via wikilinks. It's the primary navigation surface of a mature Obsidian vault โ more useful than tags, more discoverable than search.
Canonical MOC Shape
---
tags: [๐/moc]
---
# Neovim MOC
Central hub for Neovim configuration, plugins, and workflows.
## Core
- [[Neovim]] โ base configuration
- [[Lazy.nvim]] โ plugin management
## Plugins
- [[nvim-treesitter]]
- [[Mason LSP]]
## Keybindings and Workflow
- [[Neovim Keybindings]]
- [[Neovim Session Management]]
Rules:
- Tag is exactly
๐/moc โ not ๐บ๏ธ (legacy), not MOC (flat), not ๐/MOC (wrong case).
- File lives in
Zettelkasten/ (personal) or work/MOC/ (work).
- Filename is
{Subject} MOC.md โ suffix, not prefix.
- Body has a one-paragraph description, then
## section headings, then bullet-list wikilinks.
- Never has
id: or other legacy frontmatter.
Legacy MOC Fixups
| Issue | Fix |
|---|
tags: ๐บ๏ธ | Rewrite to tags: [๐/moc] |
tags: [๐บ, ๐/moc] | Deduplicate to tags: [๐/moc] |
MOC in work/z/ instead of work/MOC/ | Move file |
Uses [[Kanban/Foo]] path-qualified links | Rewrite to [[Foo]] when basename unique |
Coverage Analysis
For each tag category (๐ ๏ธ/, ๐/, ๐ป/, etc.), the vault-agent mocs.analyze_mocs analyzer reports how many tagged notes are NOT linked from any MOC. High uncovered counts indicate:
- Missing MOC โ the category has 10+ notes but no MOC exists.
- Stale MOC โ the MOC exists but hasn't been updated with recent additions.
- Tag mismatch โ notes are tagged but don't belong in the relevant MOC.
Offline Fallback (App Closed)
The detection methodology above is unchanged โ only the data source changes when Obsidian (and its obsidian CLI / live link index) is closed. The obsidian CLI and vault-agent analyzers are the live-index path; parsing the .md corpus directly with Glob/Grep is the deterministic headless default, and for batch/scheduled audits it is often the better choice (reproducible, free of app/index state). vault-frontmatter already operates this way.
Parse the corpus directly:
- Frontmatter โ read each note's YAML block between the leading
--- fences; extract tags, aliases, context. See vault-frontmatter for YAML-block mechanics.
- Wikilinks โ match
[[Target]], [[Target|Alias]], [[Target#Heading]], [[folder/Target]], and ![[embed]]. Resolve each target to a note by basename, then relative path, then alias (from frontmatter), all case-insensitive. Resolve ![[embed]] against attachments as well as notes โ the attachment folder is per-vault configurable, so read it from .obsidian/app.json (attachmentFolderPath) and fall back to the vault root / Files/ only when that key is unset.
Coverage analysis offline: for each tag category, count notes whose parsed frontmatter tags place them in the category but which no ๐/moc-tagged note links to (via the resolution cascade). That is the same uncovered count mocs.analyze_mocs produces from the live index.
Creating a New MOC
Thresholds (heuristic):
- โฅ 10 tagged notes in the category AND
- No existing MOC covers them AND
- Notes share enough subject to belong in one hub
If all three hold, create Zettelkasten/{Category} MOC.md:
---
tags: [๐/moc]
---
# {Category} MOC
{One-paragraph framing of the category.}
## {Section}
- [[Note1]]
- [[Note2]]
Pick 2โ4 ## sections that reflect natural groupings within the notes โ don't force a deep hierarchy.
Extending an Existing MOC
When the analyzer reports orphaned notes that belong in an existing MOC:
- Read the MOC and find the most appropriate
## section (or create a new one if 3+ notes fit a new grouping).
- Add wikilinks one per bullet, alphabetical within the section.
- Keep descriptions brief โ one short phrase per link at most.
Don't add a "See also" or "Random" section as a dumping ground. If a note doesn't fit any section, reconsider whether it belongs in this MOC at all.
Never Do
- Don't create nested MOCs (MOC of MOCs) unless the vault has 20+ MOCs that justify a top-level index.
- Don't dataview-generate MOC content in place of hand-curated links. Dataview is fine for supplementary sections ("Recent notes in this category"), but the primary content should be hand-picked.
- Don't add the
๐/moc tag to a note that isn't actually a MOC โ it pollutes MOC inventories.
- Don't rename existing MOCs without updating every link (use
vault-wikilinks rewrite patterns).
Commit Messages
| Action | Commit |
|---|
| New MOC | feat(mocs): add {Category} MOC covering N notes |
| Fixup tag | fix(mocs): ๐บ๏ธ โ ๐/moc on work MOCs |
| Add orphans | feat(mocs): link 12 notes into Neovim MOC |
| Rewrite path-qualified link | fix(mocs): unqualify [[Kanban/X]] โ [[X]] across 6 MOCs |
Safety
- Never modify a MOC's section structure without the user's input โ they reflect the user's mental model.
- When adding links, preserve the user's existing sort order (alphabetical, chronological, by-importance โ look at the first section to infer).
- Don't link notes that are tagged but clearly off-topic for the MOC.
Related Skills
- vault-orphans โ identifies candidate notes to add to MOCs
- vault-tags โ tag taxonomy that drives coverage analysis
- vault-wikilinks โ link syntax and safe-rewrite rules