Baalda Vault Optimizer

SkillFiles & storage

Framework-driven audit and optimizer for a Baalda vault. Applies 10 frameworks covering CLAUDE.md quality, wiki structure, compression, context rot, memory, progressive disclosure, hygiene, cross-file synthesis, architecture and discoverability, plus F10 Claude 5 rule rewriting. Every finding ships a concrete fix; the user picks apply-now or save-to-plan per finding. F10 rewrites rules written for older Claude models into judgment plus the reason, and proposes the documented Claude Fable 5.1 vault guardrails where they are missing. Baalda-aware: takes a vault checkpoint before applying, never touches .context/, and routes every move, rename or delete of a synced note through the app or the MCP tools so notes keep their doc_id. TRIGGERS: optimizer, rewrite my rules, audit my CLAUDE.md, my rules feel too strict, optimize my vault, vault audit, second brain audit, clean up my Baalda vault, framework audit, discoverability check, architecture audit, reorg vault. Run from the vault root.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Baalda Vault Optimizer skill

What this skill tells your AI

The instructions your AI receives, as published by naveedharri/benai-skills in shared-skills/optimizer/SKILL.md and read by ahel’s review.

Apply 10 frameworks to every markdown file in the vault. For each framework, read its pass-implementation file, run every check, log findings, walk the user through fixes per item, apply (or save to a plan). Save one comprehensive HTML report grouped by framework. Do not inline the HTML in chat — only the saved path and a one-paragraph summary.

Operating philosophy — read carefully, this is what makes this skill different

  1. Every finding ships a concrete fix. No flag-only. No "warn and forget." No manual-review pile. When the user runs apply-mode, every finding becomes either an applied edit, a saved migration step in a dated reorg plan, or (only if the user explicitly declines this finding in walk) a recorded decline. Nothing lingers as an open warning across runs.

  2. Severity is informational, not gating. fail / warn / info describes how load-bearing the issue is; it does not gate whether a fix is offered. Every check produces fixes.

  3. Walk per item, user picks the target. Bulk-apply is reserved for purely mechanical fixes (em dashes, duplicate H1). Anything semantic — wikilink repointing, merges, routing rewrites, Plot.md generation, reorganizations — is walk-only with the user confirming the destination/winner/wording per item.

  4. Two modes for every fix: apply now (executes in this run) or save to plan (writes the change as a checklist step into the plan file, whose path is resolved from the role registry in Step 4.3). User picks per finding for high-blast-radius items. Smaller fixes default to apply-now.

  5. Visible progress, never silent. Step 0.5 creates one TaskCreate entry per stage and per framework; tasks update in_progresscompleted as the run unfolds. The user watches the audit walk through the vault rather than waiting for one big report at the end.

  6. Read and reason, don't just match. Every framework's triggers surface candidates; every finding requires the agent to read context, judge alignment with the user's stated world, and produce reasoning specific to the case. No paraphrased rule restatements as "reasoning."

  7. Discover structure, never assume folder names. Vaults vary. One user's curated layer is Context/; another's is About/, Me/, frontmatter on root, or scattered across topic folders. The optimizer runs Step 1.5 (role discovery) before any framework, and every framework references roles (context-equivalent, decisions-equivalent, daily-equivalent, folder-index convention…) discovered from content — never hardcoded names. If a role is missing, it surfaces as a finding with a proposed fix ("you have no decisions-equivalent folder; here's a recommendation"), not as a silent assumption. Static path references in pass files are always abstractions; the agent resolves them through the role registry at run time.

  8. Respect how Baalda stores things. Notes are plain .md files, so every content fix is a normal file edit and lands live in the app (and for teammates) within ~300ms. But three things are not negotiable — see Baalda rules below. Violating them silently destroys note identity and version history, which is the one failure mode this skill must never cause.

Baalda rules

Run these checks in Step 0, before anything else.

R1 — .context/ and attachments/ are out of scope

<vault>/.context/ is Baalda's SQLite index, CRDT update log and doc-id map. attachments/ holds binaries the app syncs on its own. Never audit, edit, move, delete or report on either. They are in the technical skip list in Step 1.1 and in the protected list in Step 5.

R2 — Is this vault synced? It changes which fixes you may apply

test -f .context/config.json && echo "SYNCED-CAPABLE" || echo "LOCAL-ONLY"

A .context/config.json carries the server vault id and the note→doc_id map, so this vault is (or has been) synced: its notes have identity and history on a server, and possibly teammates.

  • LOCAL-ONLY → every fix, including moves, renames, merges and deletes, is a plain file operation. Proceed normally.
  • SYNCED-CAPABLEcontent edits in place are still completely safe and merge live. But a move, rename or delete done with mv/rm looks like delete-then-create to the app: the note gets a brand-new doc_id and loses its version history, its backlinks from other notes' indexes and its sharing settings. So for every finding whose fix relocates or removes a note or folder (F2 merges, F8.2 merges, F9.5 folder merges, F9.6 reorgs, hygiene deletes):
    1. If this session is connected to the vault over Baalda's MCP endpoint (Vault settings → MCP mints the token), the tools move_note, move_folder, delete_note, delete_folder and create_folder are available — apply the fix through them, never with shell commands. They preserve doc_id and broadcast the change to every open app.
    2. If MCP is not wired up, route the finding to save-to-plan with the step written as a human action: "In Baalda, drag X into Y" / "rename A to B in the sidebar". Do not offer apply-now for it. Say why in one line so the user isn't confused by the missing option.
    3. Content rewrites, splits that create a new file while leaving the original in place, and frontmatter/wikilink edits are unaffected — apply them normally.

R3 — Take a checkpoint before applying

Baalda has a vault-wide safety net. Before the first fix lands in Step 5, tell the user:

Take a checkpoint first: Vault settings → Versioning → Create checkpoint, label it pre-optimizer. It captures every note's content and the folder tree, and one click reverts the whole vault. Per-note history (the clock icon in the editor) is a second net for single files.

Wait for a yes before applying. If they decline, say once that fixes are then only recoverable per-note, and continue. Never take the checkpoint for them — it's owner/admin-only and capped at 5.

R4 — Write what Baalda renders

When a fix rewrites note content, keep to Baalda's markdown: frontmatter, [[wikilinks]], #tags, - [ ] tasks, tables, fenced code, ![alt](path) images. Obsidian-only syntax (![[embeds]], > [!callout], ==highlight==, %%comment%%) renders as literal text — if the audit finds it in a vault that came from Obsidian, that is itself a hygiene finding with a rewrite as the fix.

%%comments%% are a fail, not a cosmetic finding. In Obsidian they are private asides hidden from the reader; in Baalda they are ordinary visible text, so in a shared folder the whole team reads them. Surface every one with its file and line and let the user decide per instance (delete, or promote to real text) — never rewrite them silently.

R5 — Wikilinks are load-bearing

Backlinks, the graph view and [[ autocomplete are all derived from wikilink text by the local index. A dead wikilink is a dead edge in the user's graph, which makes F2.2 / F9 link findings worth more here than in a plain markdown folder. Never leave a rename without repointing inbound links.

Frameworks

#FrameworkReference (the why)Pass file (the how)Applies to
F1Anthropic CLAUDE.mdreferences/anthropic-claude-md.mdreferences/passes-anthropic-claude-md.mdevery CLAUDE.md
F2Karpathy LLM Wikireferences/karpathy-llm-wiki.mdreferences/passes-karpathy-wiki.mdwiki content notes
F3Caveman compressionreferences/caveman-compression.mdreferences/passes-caveman.mdinstruction-layer files
F4Chroma context rotreferences/chroma-context-rot.mdreferences/passes-chroma-context-rot.mdevery .md
F5Anthropic Memoryreferences/anthropic-managed-memory.mdreferences/passes-anthropic-memory.mdevery .md
F6Progressive Disclosurereferences/progressive-disclosure.mdreferences/passes-progressive-disclosure.mdevery SKILL.md
G7General Hygiene(project rules + practitioner notes)references/passes-general-hygiene.mdevery .md
F10Claude 5 Rule Rewritingreferences/claude-5-rules.mdreferences/passes-claude-5-rules.mdevery CLAUDE.md, .claude/rules/, and every SKILL.md
F8Reflection (Anthropic Dreams)references/anthropic-dreams.mdreferences/passes-reflection.mdevery folder where layer == "curated" in the Step 1.5 registry; reads the session-layer folders as evidence
F9Architecture & Discoverabilityreferences/anthropic-architecture.mdreferences/passes-architecture.mdwhole vault — root CLAUDE.md, routing, every folder's Plot.md, the navigation chain end-to-end

When running a check, read the pass-implementation file and follow its regex / heuristic / finding format exactly. Don't paraphrase. Cite the framework reference in every finding.

Flow

  1. Verify the cwd looks like a vault — light check (Step 0)
  2. Create the visible task list — TaskCreate one task per stage + framework (Step 0.5)
  3. Discover & classify every .md file — only technical skips (Step 1)
  4. Iterate frameworks F1 → F9, applying each framework's lens with agent judgment; F8 = cross-vault synthesis, F9 = whole-vault structural reasoning + discoverability walk (Step 2)
  5. Aggregate findings + write the architectural read paragraph (Steps 3 and 3.5)
  6. Walk every finding through apply-now / save-to-plan — no skip option for fixes; every finding becomes an applied edit, a saved migration step, or an explicit per-item user decline (Step 4)
  7. Apply approved fixes (Step 5)
  8. Render HTML dashboard, save, open in browser, emit as artifact (Step 6)

Step 0 — Verify the cwd looks like a vault

Run the Baalda rules checks first (R1–R2 detection now, R3 before Step 5).

Don't require any specific folder layout. Check (any one is sufficient):

test -f CLAUDE.md || test -f claude.md
[ "$(find . -maxdepth 4 -name 'CLAUDE.md' | head -1)" ]
[ "$(find . -maxdepth 1 -name '*.md' | wc -l)" -gt 0 ]

If none are true → stop:

This doesn't look like a markdown vault — no .md files or CLAUDE.md found. cd into your vault root and re-run.

Otherwise tell the user one line:

Auditing your vault against 10 frameworks. First I'll discover your structure (Step 1.5) — I won't assume folder names. Then I walk every fix with you. You'll see each stage as a task.

Proceed into Step 0.5.


Step 0.5 — Create the visible task list (TaskCreate)

This is mandatory. People running this skill on their second brain need to see what's happening — silent is unacceptable for a long-running vault audit.

Create one task per stage + one task per framework, in order. Use TaskCreate with explicit short titles. The user watches them tick through.

[ ] Discover & classify .md files (Step 1)
[ ] Role discovery — semantic folder/file classification, no hardcoded names (Step 1.5)
[ ] F1 Anthropic CLAUDE.md — read CLAUDE.md files, judge candidates
[ ] F2 Karpathy Wiki — wikilinks, orphans, schema
[ ] F3 Caveman — compression of instruction-layer files
[ ] F4 Chroma Context Rot — length, distractors, position
[ ] F5 Anthropic Memory — file size, naming, indexes
[ ] F6 Progressive Disclosure — SKILL.md layering
[ ] G7 General Hygiene — em dashes, frontmatter, H1 rules
[ ] F10 Claude 5 Rules — retired, bare prohibitions, one-sided, aggressive
[ ] F8 Reflection — cluster + judge cross-file synthesis
[ ] F9 Architecture — routing truth, Plot.md presence, discoverability walk
[ ] Aggregate findings + architectural read (Steps 3 / 3.5)
[ ] Walk every finding through apply / save-to-plan (Step 4)
[ ] Apply approved fixes (Step 5)
[ ] Render dashboard + open (Step 6)

Mark in_progress when entering a stage; completed when leaving it. For long frameworks (F2, F8, F9) emit a sub-update mid-run via TaskUpdate or a single chat line so the user knows progress.

Skipping the task list to "save time" defeats the purpose of this skill. The visible task list is non-optional.


Step 1 — Discover & classify every .md file

1.1 — Universal glob (every file audited)

find . -name '*.md' \
  -not -path '*/.git/*' \
  -not -path '*/.context/*' \
  -not -path '*/attachments/*' \
  -not -path '*/.obsidian/*' \
  -not -path '*/.trash/*' \
  -not -path '*/.claude/worktrees/*' \
  -not -path '*/node_modules/*' \
  -not -path '*/dist/*' \
  -not -path '*/build/*'

No role-based skips. No "templates skipped", no "Daily skipped", no "Onboarding skipped". Every .md outside the technical skip list above gets audited against every framework rule that applies to its role. Classification routes the right rules to the right files; classification does NOT exclude files.

1.2 — Classify each file by role (first match wins) — hints only

The patterns below are hints that bias the role registry built in Step 1.5. They're not authoritative — Step 1.5 reads sample content to confirm role assignments. A file matching \d{4}-\d{2}-\d{2}\.md outside any daily-shaped folder will not be classified daily if Step 1.5 finds no daily role; it'll be a regular note.

For backwards compatibility with vaults that do use the conventional names, the patterns still apply; for vaults that don't, Step 1.5 takes over.

RoleDetection
root-claude./CLAUDE.md or ./claude.md (cwd root only)
folder-claudeany other CLAUDE.md / claude.md in subfolders
claude-rulesfiles inside .claude/rules/
skillSKILL.md files (anywhere)
indexindex.md (case-insensitive)
readmeREADME.md (case-insensitive)
dailymatches \d{4}-\d{2}-\d{2}\.md inside any Daily/
meetinginside *meetings*/ or filename matches \d{4}-\d{2}-\d{2} - .+\.md outside Daily/
transcriptinside *transcripts*/ or files >100KB
decisioninside *decisions*/
templateinside *templates*/ or filename ends -template.md
contextinside any Context/ (case-insensitive)
noteeverything else

Build the classification map:

{
  "root_claude": "./CLAUDE.md",
  "folder_claudes": [...],
  "claude_rules": [...],
  "skills": [...],
  "indexes": [...],
  "readmes": [...],
  "dailies": [...],
  "meetings": [...],
  "transcripts": [...],
  "decisions": [...],
  "templates": [...],
  "context_files": [...],
  "notes": [...],
  "by_folder": {...},
  "stats": {"total_files": N, "total_bytes": B, "folders": F}
}

1.3 — Build supporting indexes (used by F2/F4)

IndexBuilt fromUsed by
vault_filename_indexevery .md basename, lowercased, with and without extensionF2.2, F2.4
inbound_link_indexgrep across vault for `[[name(|]
routing_tableroot CLAUDE.md routing/knowledge-routing sectionF2.6
top_level_entriesfind . -maxdepth 1F2.6
headers_indexper-file H2/H3 list with line numbers + byte sizesF3.6, F5.2
protected_zones_mapper-file map of code/URL/path/frontmatter/wikilink spansF3.x, G7.1

1.4 — Show classification summary in chat (one block, before any framework runs)

## 📋 Discovery — {N} markdown files across {F} folders, {B-formatted} total

| Role | Count |
|---|---:|
| Root CLAUDE.md | 1 |
| Folder CLAUDE.mds | {n} |
| Skills (SKILL.md) | {n} |
| .claude/rules | {n} |
| Indexes / READMEs | {n} |
| Context files | {n} |
| Notes | {n} |
| Dailies | {n} |
| Meetings | {n} |
| Transcripts | {n} |
| Decisions | {n} |
| Templates | {n} |

**Framework targets (every file in scope is audited):**
- F1 Anthropic CLAUDE.md → {n} CLAUDE.md files
- F2 Karpathy Wiki → {n} content notes (notes + context + decision + meeting + index + readme) + 1 schema doc check
- F3 Caveman → {n} instruction-layer files (CLAUDE.md + SKILL.md + .claude/rules + skill references)
- F4 Chroma Context Rot → {N} files (every `.md`)
- F5 Anthropic Memory → {N} files (every `.md`)
- F6 Progressive Disclosure → {n} skills
- G7 General Hygiene → {N} files
- F10 Claude 5 Rules → {n} instruction files (CLAUDE.md + .claude/rules + SKILL.md)
- F8 Reflection → {n} files in discovered curated-layer roles + {n} files in discovered session-layer roles ({window} window) for cross-vault synthesis
- F9 Architecture → routing table ({n} entries), {n} folders for index presence + freshness against the discovered convention, full navigation graph for discoverability, vault-specific orientation built from the discovered identity-layer

Running role discovery (Step 1.5) now…

Step 1.5 — Role discovery (semantic, not name-based)

This step replaces every hardcoded assumption about folder/file names. The pass files reference roles (context, projects, decisions, daily, meetings, transcripts, resources, skills, archive, identity, folder_index_convention). Step 1.5 discovers what folder/file in this vault plays each role — or records that the role is absent.

1.5.1 — How discovery works

For each abstract role, the agent does the following — in order — until something resolves:

  1. Read folder names + Plot/README/index/CLAUDE files at the top level, then top-2-deep. Build a candidate list: which folders look like they could play this role based on name + their own description?
  2. Read 3–5 sample files per candidate folder. Does the content match the role's purpose?
  3. Score and pick. Highest-confidence candidate wins. If no candidate clears medium confidence → role is missing.

The agent does not privilege a specific folder name. Context/, About/, Me/, Personal/, Identity/, or a frontmatter section on root CLAUDE.md can all play the identity role. The agent decides by reading.

1.5.2 — Standard roles (patterns the agent recognizes)

These are patterns, not an exhaustive taxonomy. Every folder/file gets classified — these standard roles match the common shapes; anything that doesn't match becomes a custom role (Step 1.5.3).

Standard roleDefault layerWhat it isHow to recognize it
identitycuratedFiles describing the user/operator (who they are, what they do, voice, preferences)First-person bio content; mentions of role/title; voice or style guidelines
contextcuratedFolder(s) holding canonical knowledge about the user's world (business, strategy, brand, team, stakeholders) — broader than identityDeclarative present-tense facts about the operating environment; named entities (company, products, key people)
projectscuratedActive or recent work unitsFolder names matching projects mentioned in identity/context; per-folder index describing scope, status, deadlines
decisionscuratedPersistent decision recordsFiles with date prefixes containing decision language ("decided", "chose", "going with")
dailysessionPer-day journals or logsFilenames matching YYYY-MM-DD\.md; folder organized by date hierarchy
meetingssessionMeeting notesFilenames with date + person/topic; content with attendee lists, action items
transcriptssessionRaw call/voice transcripts>100KB files with monologue/dialogue formatting
resourcescuratedReference library (prompts, frameworks, swipe files, templates)Reusable assets, not project-specific; often nested by category
skillscuratedSkill / SOP / playbook content the user ownsSKILL.md files, or markdown describing repeatable processes/playbooks
archivearchiveIntentionally deactivated contentFolder named archive/old/deprecated/_archive, or files marked archived in frontmatter
folder_index_convention(meta)The user's chosen per-folder index file nameMost-frequent filename across folders that functions as an index (Plot.md, README.md, index.md, _index.md, CLAUDE.md, etc.)

1.5.3 — Custom roles (every other folder)

After standard-role discovery, every remaining top-level folder and every meaningful subfolder must be classified, not ignored. For each unclassified folder:

  1. Read the folder's index file (under the discovered convention) if present.
  2. Sample 3–5 files in the folder. Read first 1500 chars + headers.
  3. Read the parent folder's index (if any) to see how this folder is described upstream.
  4. Assign a custom role:
    • name — a slug derived from the folder name plus content (e.g., Building/ with prototype-build content → role name building; Garden/ with idea-incubation content → garden).
    • layer — one of curated (canonical, durable), session (ephemeral, time-stamped), archive (deactivated), meta (tooling, system files), unknown (agent could not confidently classify).
    • purpose — 1-line description of what the folder holds.
    • is_standard: false.
    • confidence: high | medium | low.

If the agent cannot confidently assign a layer (confidence low) → emit an F9.0 finding asking the user to clarify the folder's purpose during walk. The answer persists in the registry going forward.

Custom roles are first-class. F8, F9, and the per-finding fixers operate on roles by layer, not by membership in the standard-role list. A custom building role with layer: curated participates in F8's curated-layer synthesis exactly like the standard context role.

1.5.4 — Output: the role registry

Build this once, cache for the rest of the run, and persist to .claude/vault-roles.json at end of Step 1.5 so future runs start from confirmed assignments instead of re-prompting:

{
  "vault_root": "./",
  "discovered_at": "2026-05-08T14:23:00Z",
  "folder_index_convention": {
    "name": "README.md",
    "confidence": "high",
    "evidence": "23 of 31 non-trivial folders have README.md",
    "coverage": 0.74
  },
  "roles": [
    {"name": "identity",  "path": "./About/me.md", "kind": "file",   "layer": "curated", "is_standard": true,  "confidence": "high",   "purpose": "Operator bio + voice"},
    {"name": "context",   "path": "./Knowledge/",  "kind": "folder", "layer": "curated", "is_standard": true,  "confidence": "high",   "purpose": "Org/strategy/brand canonical knowledge"},
    {"name": "projects",  "path": "./Work/",       "kind": "folder", "layer": "curated", "is_standard": true,  "confidence": "high",   "purpose": "Active and recent work units"},
    {"name": "daily",     "path": "./Journal/",    "kind": "folder", "layer": "session", "is_standard": true,  "confidence": "medium", "purpose": "Per-day journal entries"},
    {"name": "resources", "path": "./Library/",    "kind": "folder", "layer": "curated", "is_standard": true,  "confidence": "high",   "purpose": "Prompts, frameworks, templates"},
    {"name": "archive",   "path": "./_archive/",   "kind": "folder", "layer": "archive", "is_standard": true,  "confidence": "high",   "purpose": "Deactivated content"},
    {"name": "building",  "path": "./Building/",   "kind": "folder", "layer": "curated", "is_standard": false, "confidence": "high",   "purpose": "Active prototype builds and experiments"},
    {"name": "garden",    "path": "./Garden/",     "kind": "folder", "layer": "curated", "is_standard": false, "confidence": "medium", "purpose": "Long-form essays in slow incubation"},
    {"name": "inbox",     "path": "./Inbox/",      "kind": "folder", "layer": "session", "is_standard": false, "confidence": "high",   "purpose": "Unprocessed capture; aged out into Garden or Resources"}
  ],
  "missing_standard_roles": ["decisions", "meetings", "transcripts"],
  "low_confidence_roles": ["garden"],
  "unconfirmed_custom_roles": []
}

1.5.5 — Show the discovery summary in chat (one block)

Shortened here. Read the whole file on GitHub.

Signals

GitHub stars
61
Forks
26
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
optimizer
Source
github.com/naveedharri/benai-skills