Count Before You Move
The first thing Soul Vault built was not storage. It was a census: a scanner that finds every place on a Mac that assumes the soul vault is a folder at a path. The reason is simple. You cannot move something safely while you do not know who holds its address, and "I think it is about six places" is exactly the guess that turns a migration into an outage.
On the workbench Mac, early in the work, the census receipt listed 2,514 open rows. One focused session brought it to 2,237. The single largest family was a rule file that the repository birth template had stamped into 56 repositories. Nobody had chosen to hardcode the vault 56 times; one template did it once and every birth copied it.
Seven Surfaces
The census looks in seven places per Mac, named S1 to S7. Each exists because paths hide in a different kind of file:
- S1 tracked files of every git checkout under the family's project root.
- S2 harness globals: the home-level configuration of Claude, Codex, Kimi, ZCode, Cursor, Grok, Gemini and Trae.
- S3 runtime: the family's LaunchAgents, the crontab, and small JSON configs under
~/.config/cwk/. - S4 prompt data that code feeds to brains: cwkPippa's prompt stores and cron jobs. A path inside a prompt is invisible to a code search.
- S5 readers that have no census of their own (the Windows boxes at the time): recorded as an excluded-by-rule row, named, never a silent gap.
- S6 history-holding copies such as backups: an inventory only. Dad's rule D2 says backups are not history to be rewritten; they are listed and left alone.
- S7 absolute vault paths stored inside the family's SQLite databases: table, column and row key are recorded, never the stored value.
Rows Without Contents
Harness configuration files on a working Mac hold credentials in plain text. A scanner that copied matching lines into its receipt would turn a path inventory into a secret inventory. So a census row stores only the file path, the line number, the pattern that matched and a fingerprint of the line. It can prove a line changed without ever holding the line.
Zero Means Zero
A census is only useful if its zero is honest. Soul Vault's has three guards:
soul-vault census --checkexits 1 while any row is open, so a script can gate on it.- A file or store the census could not read is a
scan_error. An unreadable crontab is an error, never a zero-row success. A Mac without a fresh receipt is not at zero. - The census owns its own patterns. The scanner's search strings would match themselves, so the package's discipline test (T-NO-LITERALS) and the census rules are kept in one place rather than copied around.
An independent review on 2026-11-10 found inputs the census had missed: Firebrand's standing instructions in its data home, cron and macro JSON stores at the root of a data folder, and launchd property lists saved in binary form, which a text scan reads as garbage and skips. Each was added with a regression case that failed first. At 17:00 KST that day a rescan of surfaces S2 to S4 on the canonical Mac came back with zero open rows; the workbench's remaining 13 raw rows were each inspected by hand: seven were prose or test fixtures, six were legacy values in Firebrand's config that sit beside a soul_vault selector it now uses instead.
Why an Inventory Beats a Grep
You could do all this with one grep -r. The difference is what you can say afterwards. A grep tells you what it found today in the places you remembered to search. A census tells you which surfaces it searched, which it could not read, which rows are exempt and why, and it writes a dated receipt per Mac that the next run can be compared against. When the cutover came, the question "is anything still opening the old folder?" had a receipt for an answer instead of a feeling.