Vault ingestion: single vault + ignore rules

Updated · View the entry on sijie.xyz ↗

Decision: one live vault (not multi-vault live sync)

StandMeet's account syncs a single Obsidian vault as its live source — Option A. The two alternatives are deferred:

  • B. multiple live sources — namespacing + per-source snapshot diff + multi-transport; this is the "clumsy" path and fragments the link graph at the source. Rejected for now.
  • C. one canonical StandMeet vault + occasional import from other vaults — considered and REJECTED; multi-vault is not a direction.

Why A:

  1. Simplest mechanism — one source, no namespacing, no multi-source diff. The "don't be clumsy" goal is best met by not building the multi-source machinery.
  2. A connected graph represents the person better — the corpus's asset is its link graph (backlinks → graph retrieval). One connected vault beats several fragmented ones; multi-vault gives more content but worse structure.
  3. Reversible — ship single-vault, add import (C) on real demand; don't pre-pay complexity for a habit that can be accommodated later.

What to ingest from the vault (the hidden-folder problem)

A vault holds many hidden config folders (.obsidian/, .trash/, .git/, .vscode/, …). The settled recipe — converged from how Obsidian, Digital Garden, the File Ignore plugin, and git workflows all do it:

  1. Primary — opt-in publish: true. As designed. What shipped for wiki/subjectivity/raw is the opposite (84080bac5, 2026-07-15, F-L-8): every routed .md persists, and publish only decides whether anonymous visitors see it (published) — the owner wanted the agent grounded in notes that are not public, and one flag could not carry both. Only the writing/ branch still ingests on publish: true (import.go:146). Selection therefore comes from the walk rules below, not from the flag.
  2. Walk defense (for link/attachment resolution):
    • ignore every dot-prefixed file/folder — one rule covers .obsidian/, .trash/, .git/, future tool dirs (Obsidian itself doesn't index dot-prefixed names; don't enumerate a denylist). Shipped as isHiddenPath (sync_classify.go:136), which also skips _templates/; the one exception is .obsidian/snippets/*.css + appearance.json, harvested as owner CSS;
    • allow-list by extension: only .md (+ a designated attachments dir). Shipped: routeFile accepts .md only under a known top folder (wiki/ subjectivity/ raw/), bare root files and unknown folders are skipped; the writing/ bucket carries its attachments;
    • a .standmeetignore (gitignore syntax) for user custom excludes (Templates/, archives) — not built (no reference anywhere in backend/); _templates is hardcoded instead.
  3. Do NOT reuse the vault's .gitignore for content selection. .gitignore targets dev artifacts (node_modules, .obsidian/), not content; conflating them silently drops real content (cf. Quartz issue #2240).

.trash/ gotcha: Obsidian's local trash holds deleted notes — ingesting it would resurrect them. The dot-prefix rule covers it.

Prior art

  • Obsidian — dot-prefixed files/folders are not indexed (the universal convention).
  • Digital Garden (dg-publish) — opt-in publish flag, mirrors StandMeet's publish.
  • File Ignore plugin — hides by adding a dot prefix; auto-skips .obsidian//.git//.trash/.
  • Quartz #2240 — cautionary tale: don't apply .gitignore to content selection.

Related notes