2026-08-18 — setting up Claude Code for the vault
First session. Goal: make Claude Code usable against this vault through the official Obsidian CLI, and encode the conventions so an agent writes notes that fit.
What was found
A six-way parallel survey of the vault and the Quartz repo. The findings that changed decisions:
Publishing is opt-out, not opt-in. publish ?? true — a note with no
publish key goes live. At the time, 303 of 325 public notes were public purely
by default. This became the organising fact of the whole setup. Details in
publishing.md.
The Assets emitter has no publish filter. assets.ts globs every
non-markdown file and copies it out without consulting shouldPublish. Verified
by reading the source. Reviewed and accepted as-is.
The CLI’s daily:* commands pointed at the wrong folder. The CLI reads the
core daily-notes plugin; this vault uses the periodic-notes community plugin,
and core had never been configured. obsidian daily:path returned
Inbox/2026-08-18.md instead of Journal/2026/08/2026-08-18.md. Every daily
command would have written to the wrong place.
The weekly note is the live ritual, not the daily. Weeklies are filled in every week; dailies are sporadic, with a seven-month gap in the recent record. Any workflow that assumes a daily note exists is built on sand.
A user-level monthly-report skill targets a different vault. Both vaults
use an identical Journal/YYYY/MM/YYYY-MM-DD.md layout, so they look
interchangeable. This one has no ## Doing sections at all. Running it here
would produce an empty report and write into the wrong tree.
Decisions
Daily notes: configure core to match, rather than ban the commands. The
rejected alternative was to forbid daily:* in the agent instructions and
compute paths by hand. That leaves the CLI half-broken for interactive use too.
Writing .obsidian/daily-notes.json to mirror periodic-notes fixes it for both.
Verified both plugins now resolve the same path.
Weekly notes have no core equivalent, so they go through
obsidian command id="periodic-notes:open-weekly-note" — the same code path the
Calendar plugin uses. Notes are never created by writing a file.
Setup lives at the repo root, not in the vault. CLAUDE.md and
.claude/skills/ sit outside digital-garden/, so the build cannot publish
them by accident. (Claude/ itself is a later, deliberate exception — it is
published on purpose.)
Read-only CLI commands were allowlisted; eval was not. obsidian eval runs
arbitrary JavaScript in the app and can mutate the vault, so it still prompts.
What was built
CLAUDE.mdat the repo root — the always-loaded safety rules, pointing here..claude/skills/garden-capture,garden-inbox,garden-journal,garden-publish-check..claude/skills/garden-publish-check/scripts/publish_audit.py— replicates the real pipeline (glob → ignorePatterns → RemoveDrafts → ExplicitPublish) plus the unfiltered Assets emitter. Exits 1 on a high-severity finding so it can gate a push..claude/settings.json— allowlist for read-onlyobsidiancommands.
The audit script’s highest-value check is the YAML one: under
yaml.JSON_SCHEMA, only a bare false is a boolean, so publish: "false",
publish: no and publish: False all publish. Tested against a scratch vault
built for the purpose.
The frontmatter cleanup
A single pass over the 373 publishable notes (325 public + 48 in Inbox/),
changing 354 of them:
| Action | Notes |
|---|---|
publish: true added (already-public) | 303 |
Created: … body line removed | 267 |
title: added | 204 |
| H1 removed (matched filename/title) | 68 |
publish: false added (Inbox/) | 28 |
H1 removed, text promoted to title: | 8 |
| Frontmatter block created from scratch | 7 |
| H1 demoted to a plain link line | 2 |
published: typo replaced with publish: | 1 |
The invariant: membership of the public set had to be identical before and after. It was — 325 both sides — while “public by default” went 303 → 0. Silence no longer publishes anything.
Removing 78 H1s could have orphaned [[Note#heading|Heading]] anchor links, so the audit
was also run against a clean git archive of HEAD and compared: broken links
44 before, 44 after. Frontmatter was then re-parsed with Quartz’s own
gray-matter + js-yaml at JSON_SCHEMA — 781 files, 0 errors.
Three judgment calls worth keeping:
- Ten
Books/Can't Hurt Me/notes have an H1 of the form# Challenge #5. That is content, not a title. Left intact. - Where an H1 was a reworded or shortened filename, its text was promoted to
title:rather than discarded. This is how00 12 Rules for Life.mdgottitle: 12 Rules for Life, and how one book index note recovered a colon a filename cannot hold. - Two MoC notes had an H1 wrapping the title in the project’s official URL. The heading was demoted to a plain markdown link so the URL survived.
Created: matching skipped fenced code blocks, so no code sample lost a line.
Corrections — claims that were wrong
Recorded because they were believed and acted on before being checked.
The CLI was reported as “not installed”. It was installed and working the
whole time; which obsidian resolves through the app bundle.
Obsidian Sync was reported as “not configured”. It is on, under the vault
name “Digital Garden”. The absence of a sync.json was read as absence of sync.
Four CLI commands were documented as permanently broken on the outdated
installer — search, help, commands, version. Re-testing showed all four
work. The real behaviour is intermittent empty output when the app is cold, which
makes an empty result untrustworthy rather than impossible. The instruction that
replaced it — empty output is not a result, re-run before concluding — is the
more useful rule anyway, because a false “nothing found” is what creates a
duplicate note.
A weekly-alias mismatch count was stated as 33, then 35. Recomputed: 37, and not confined to 2021–22 as claimed — one each in 2025 and 2026. So it is a live mistake to guard against, not a historical artefact.
The pattern in all four: a plausible reading of indirect evidence, stated with more confidence than the evidence carried. Cheap to check, and each check took under a minute.
Side effects
A subagent ran periodic-notes:open-daily-note while verifying commands, which
created that day’s daily note and left it staged. Unstaged and reported rather
than quietly deleted — it is the author’s file, and an empty daily note in the
right place is not damage.
Left undone
- The Assets emitter still copies non-markdown files with no publish filter.
Reviewed and accepted; the fix would be patching
assets.ts. Research/Research.canvasandpublish.csspublish verbatim. Both expected.- Broken links inside published notes render as dead text on the site. Not touched — fixing them is editorial.
- One published book index note is entirely a Dataview query, which Quartz cannot render, leaving its chapter notes unreachable from the site.