Vault Routing Gone Wrong β A Token Audit
Quite an interesting failure mode.
- I sent a summary of my Builder pattern implementation via Telegram.
- Claude filed it in
01 Atlas/Career/SAP/instead of the correct01 Atlas/Career/Company/SAP/. - The fix was trivial β one
mvand two edits.
The token cost to get there, via /organize? Not trivial.
What Happened
The Telegram plugin received the note and had to decide where to write it. The content had tags [SAP, DGS, builder-pattern, TypeScript, metadata] β SAP was the dominant signal. Claude matched against SAP in the directory listing and found Career/SAP/, which didnβt exist yet β so it created it. The correct target, Career/Company/SAP/, was one level deeper and required knowing the existing vault hierarchy, not just pattern-matching on the tag.
Result: a stray 01 Atlas/Career/SAP/ directory with one orphaned file.
Token Audit β /organize 01 Atlas/Career/
To fix this, I ran /organize @"01 Atlas/Career/". Hereβs what that consumed:
Tool calls made
| Step | Action | Approx. tokens (input) |
|---|---|---|
Load organize-knowledge SKILL.md | Read (~135 lines) | ~1,500 |
find β list all .md files in Career | Bash output | ~400 |
find β list all subdirs | Bash output | ~150 |
| Read 3 new/changed files (DGS note, GXS Experience, GXS _index) | File content | ~2,500 |
Read 4 existing _index.md files (SAP, Company, Career, Interview) | File content | ~3,000 |
Read 4 more _index.md files (Experiences, Learning, Academia, Interview) | File content | ~2,500 |
Write updated SAP _index.md | Output | ~800 |
| Edit Γ 2 (rename in index + rename H1) | Output | ~300 |
| Subtotal β organize pass | ~11,150 |
This is just the incremental token cost of the organize pass itself β it doesnβt count the conversation context already loaded in the session (~20k+ tokens from prior turns). Total session cost for this single misroute incident: ~30β35k tokens.
For one misplaced file. One mv.
Why This Happens
Claude has no memory of the vaultβs directory tree between sessions. Every time a skill runs, it re-discovers the structure via find and ls, then reads a sampling of files to build enough context to make decisions. Itβs a stateless agent operating on a stateful filesystem.
The Telegram plugin specifically lacks a lookup step β it infers placement from tags + content, which is fast but shallow. It doesnβt load the full vault tree before writing. So it guesses, and the guess is only as good as the pattern match.
Plan: Reduce Token Footprint to Near-Zero
Option A β Vault Graph Map (preferred)
Maintain a lightweight JSON index at .obsidian/vault-graph.json (or .claude/vault-map.json) that maps canonical paths and tag signals to directories:
{
"01 Atlas/Career/Company/SAP": {
"tags": ["SAP", "sap"],
"description": "Notes from SAP internship",
"children": ["Summary.md", "SAP Kyma.md", "..."]
},
"01 Atlas/Career/Company/GXS": {
"tags": ["GXS", "gxs"],
"description": "Notes from GXS internship",
"children": ["GXS Experience.md"]
}
}A PostToolUse hook on Write/Edit regenerates the map whenever a file is created or moved. Any skill β including the Telegram plugin β loads this single file (~5β10k tokens) instead of crawling the full tree.
Savings: replaces ~10+ find + file reads with one JSON load. Estimated reduction: ~8,000 tokens per organize pass.
Option B β Path Hint in Telegram Plugin
When receiving a note via Telegram, the plugin could include a target_path field in the note itself (user-specified), bypassing inference entirely. Works well when I know where the file should go β which is most of the time.
me: [sends DGS Metadata Builder content]
plugin: reads note β extracts path hint β writes directly to correct location
No organize pass needed at all. Savings: ~35k tokens (the entire remediation cost).
Option C β Inbox-First Policy
All Telegram-delivered notes go to 04 Inbox/ unconditionally. No routing inference at write time. /organize-inbox handles placement in batch, using the full skill with graph map context.
Benefits:
- Zero wrong-folder incidents
- Batch processing is more efficient than per-note routing
- Easier to review before committing to Atlas
Savings: same as Option B β eliminates the remediation entirely.
My Suggestions
1. Combine A + C. Inbox-first removes the routing mistake entirely. The graph map then makes /organize-inbox faster and cheaper when it runs. These two together eliminate the failure mode and reduce the batch cost.
2. Add a path: frontmatter field to Telegram notes. When the content is technical and clearly belongs somewhere, I can include path: 01 Atlas/Career/Company/SAP in the Telegram message. The plugin respects it; no inference needed.
3. Scope /organize calls more narrowly. Instead of @"01 Atlas/Career/", call @"01 Atlas/Career/Company/SAP/" β the specific subtree that changed. Fewer files to read, fewer indexes to rebuild. Estimated savings: 50β70% of organize token cost for surgical fixes.
4. Cache the directory tree in .claude/ and invalidate on Write. A single flat JSON like:
["01 Atlas/Career/Company/SAP", "01 Atlas/Career/Company/GXS", ...]β¦replaces every find call with a file read. PostToolUse hook keeps it fresh. Cost: ~200 tokens per skill invocation instead of ~500+ from bash output.
5. Tag the organize pass result with token deltas. When /organize runs, it should append a line to .claude/organize-log.md with the estimated token cost. Over time, this builds a record of which operations are expensive and why β useful for tuning the skills.
Summary
| Scenario | Approx. tokens |
|---|---|
Current: misroute + full /organize fix | ~35,000 |
| With graph map only | ~22,000 |
| With inbox-first only | ~5,000 (inbox organize batch) |
| With inbox-first + graph map | ~2,000 |
| With path hint in message | ~500 (direct write, no organize) |
The low-hanging fruit is inbox-first. Itβs one policy change and it makes the routing problem disappear.
Thanks for reading β and yes, this entire audit was itself a few thousand tokens. π