cc-os/docs/adr/0004-sqlite-sequel-ruby-tag...

2.2 KiB

id date status supersedes superseded-by affected-paths affected-components migration_confidence migration_source
0004 2026-06-03 Superseded 0010
medium docs/memory-system/03-architecture-decisions.md### ADR-004 — SQLite + Sequel (Ruby) tag index as the knowledge-layer cache

0004 — SQLite + Sequel (Ruby) tag index as the knowledge-layer cache

Context

The AI can't use Obsidian tags directly; tag filtering needs a machine-queryable index. A previous ~/Documents/SecondBrain/ tag database was lost track of.

Decision

A small Ruby program using the Sequel ORM over SQLite, exposed as a CLI. Schema: files(path, mtime, summary, scope), tags(name), files_tags join (many_to_many). The summary is a column on files (an attribute), not a join.

  • Rationale: Normalized tags table makes enumerating the vocabulary a first-class cheap query (the "virtual index" goal). The summary column is what turns the index from a finder into a router — the AI sees enough to pick a file without opening it (progressive disclosure, low tokens). Ruby + Sequel + CLI keeps the contract clean and the DB swappable; the AI never touches SQLite directly.
  • Failure-mode guard (the lost-SecondBrain lesson): markdown is always authoritative; the SQLite file is a disposable cache that is never synced and can be rebuilt from frontmatter anytime (index update --rebuild).

Consequences

A Ruby/Sequel/SQLite CLI tag index was built as the machine-queryable cache over the vault, with markdown treated as always-authoritative and the SQLite file as a disposable, rebuildable cache — never synced. This bespoke index and its CLI were later dropped and superseded by ADR-010's Graphify graph, though the summary + namespaced-tag frontmatter it introduced was retained as note metadata.

Alternatives rejected

Plain-markdown generated INDEX.md (must regenerate; grep-at-scale is token-heavy). Frontmatter grep on demand (scales badly). Milvus/Postgres for knowledge (overkill; QMD/memsearch prove SQLite is enough — see ADR-006/008).

  • Query output: returns path + summary + matched tags (option C) — tags are cheap and show why a result matched, useful for cross-client queries.