obsidian-plugin/skills/vault-stubs/SKILL.md
Work-namespace redirect-stub classification in an Obsidian vault. Use when cleaning stubs, converting duplicates to redirects, or merging content into Zettelkasten.
npx skillsauth add laurigates/claude-plugins vault-stubsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
| Use this skill when... | Use the alternative instead when... |
|---|---|
| Classifying and consolidating work-namespace redirect stubs in the vault | Triaging generic orphan notes outside the work namespace — use vault-orphans |
| Promoting a work-namespace note into the canonical Zettelkasten location | Repairing the wikilinks that point at the moved note afterwards — use vault-wikilinks |
| Merging unique work-namespace content back into a Zettelkasten note | Adding the merged note into a Map of Content hub — use vault-mocs |
A work-namespace subtree (a directory such as work/z/) is a knowledge base that mirrors select Zettelkasten notes as tiny redirect stubs. Content lives in Zettelkasten/; the work-namespace subtree points to it so work-context queries still find the topic.
---
tags: [redirect]
context: work
---
See [[Zettelkasten/Docker|Docker]] in the main knowledge base.
Properties:
[redirect]context: work| Class | Meaning | Action |
|-------|---------|--------|
| clean_redirect | ≤ 200 B, redirect tag, Zettelkasten match | ✓ keep as-is |
| broken_redirect | redirect tag but >200 B or missing target | Rewrite body to the canonical one-liner |
| stale_duplicate | Full article, basename exists in Zettelkasten | Merge content into Zettelkasten, convert stub to clean_redirect |
| ns_original | Full article, no Zettelkasten match | Legitimate — leave alone |
When a work/z/Foo.md has substantive content AND Zettelkasten/Foo.md exists, you must decide:
Zettelkasten/Foo.md first, then replace stub.Compare by section. If a heading in work/z/Foo.md has text that doesn't appear in Zettelkasten/Foo.md, that text needs migration. Use word-level comparison, not exact match — minor wording differences don't count as "unique content."
When in doubt, flag for user review rather than auto-merging. A bad merge is worse than leaving a duplicate.
Replace the whole work-namespace file body:
---
tags: [redirect]
context: work
---
See [[Zettelkasten/Foo|Foo]] in the main knowledge base.
Commit message:
refactor(stubs): convert work/z/Foo.md to redirect (content merged into Zettelkasten)
Occasionally a file classified ns_original is actually general-interest content that belongs in Zettelkasten/. Signs:
If promoting:
Zettelkasten/Foo.mdwork/z/Foo.md redirect stub in its placecontext: work from the promoted note's frontmatterrefactor(stubs): promote Foo from work/z to ZettelkastenDon't promote aggressively — the work namespace exists for a reason.
# All work-namespace files ordered by size
fd -e md . work/z -x wc -c {} | sort -n
# Ones with `redirect` tag
rg -l '^tags:.*\bredirect\b' work/z/ --glob '*.md'
# Large ones without `redirect` tag (candidates for conversion)
rg -L -l '^tags:.*\bredirect\b' work/z/ --glob '*.md'
Vault-agent's analyze_stubs gives the full classification.
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 the fd/rg Detection snippet above 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:
--- fences; extract tags, aliases, context. See vault-frontmatter for YAML-block mechanics.[[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.Classify each stub from parsed inputs only: file size (wc -c), the redirect frontmatter tag, and a basename match against Zettelkasten/ — the same inputs analyze_stubs uses. The redirect body's [[Zettelkasten/Foo|Foo]] target is verified with the resolution cascade above.
context: work on stubs (required for work-namespace queries).redirect tagredirect tag is an exception to the emoji-prefix ruledevelopment
Debug HTTP APIs: trace requests, inspect headers. Use when a request fails: check status first.
documentation
Render architecture diagrams from text sources. Use when documenting system topology.
tools
Inspect JSON payloads and extract nested fields. Use when parsing API responses.
tools
--- name: no-description allowed-tools: Read --- # No Description This skill has no description and must be dropped with a warning.