Vaults, scoped to this project
Guide 04 also carries the estate's general handover discipline — most of that belongs to teams.sgit.ai, and vault mechanics themselves (keys, publication, sub-vaults) belong to sgit.ai and pki.sgit.ai. This page keeps only what is specific to a capture project: why two stores, not one, the deriver as the seam between them, and two data-modelling patterns worth stealing. The test throughout: if a practice would be identical for a project with no extension in it, it is not this site's.
1. Why an extension project needs two vaults
A recorder produces two kinds of artefact with opposite properties, and one store would force the most restrictive rule onto both.
code vault data vault
├── the extension source ├── captures/ verbatim exports, one per run
├── tests ├── derived/ one small stable file per run
├── tools/ (deriver, builders) ├── contacts/ one file per entity
├── notes/NOTES.md numbered lessons ├── app-data.json everything merged
├── guides/ these documents ├── index.html the viewer app
└── README.md changelog ├── INDEX.md one row per capture run
└── HANDOVER.md the contract, for a stranger
Ranked by how much each reason matters:
- Different sensitivity. The data vault holds verbatim payloads with real names and identifiers; the code vault holds no personal data and "can be mirrored to a public repository."
- Different lifecycles. Code changes many times a day; captures arrive every few days and "are never edited afterwards."
- Different sizes. A run is 50–120 MB, and "this matters more than it sounds when the agent's container is ephemeral and re-clones from scratch."
- Different failure modes. "Corrupting a capture is unrecoverable — it is evidence. Corrupting code is a revert."
The publication rule is written per folder in the code vault's README, rather than remembered, "because the answer is not obvious for every folder and the cost of getting it wrong is asymmetric." That single practice is the one to lead with here — it is what makes a public mirror safe.
2. The deriver is the seam
One tool spans both: it lives in the code vault and writes into the data vault. Three rules make it safe, and together they are why being wrong stayed cheap:
- Captures are read-only. "Nothing ever writes into
captures/. It is evidence." - Everything else is regenerable. Derived files, the merged dataset, contact records, the viewer's inlined data — all rebuilt by two commands. "If a parser improves, re-derive everything; it takes seconds and retroactively improves every past run."
- The derived format is versioned and refused when unknown. Builders exit non-zero on an old version rather than merging partially — because "a v1 file has no event log, and silently reading one understates the dataset without saying so."
That third rule is what converts improving a parser from a scary operation into a safe one, and it generalises to any pipeline that stores raw and derives meaning.
3. Two patterns worth stealing wholesale
Per-entity files with structural membership. One JSON file per entity, plus an index. The design decision that does the work: membership is structural, not a filter — a record exists only for something seen on a specific authoritative surface, and visiting a profile enriches an existing record but can never create one. "That is much stronger than a degree: 1 field, because a field has to be trusted and a provenance rule does not."
Fields remember being different. A changed value appends rather than overwrites, carrying value / firstSeen / lastSeen / history[] — because the target holds only the current value and capturing across runs is the only way to see change:
"headline": {
"value": "Current title",
"firstSeen": "2026-09-01T11:36:25Z",
"lastSeen": "2026-09-08T15:40:02Z",
"history": [ { "value": "Previous title", "firstSeen": "…", "lastSeen": "…" } ]
}
And nothing is deleted on absence: "a run that did not open the list is silence, not a disconnection."
4. The viewer ships as one file
The data vault carries a self-contained index.html that fetches the merged dataset and falls back to an inlined copy, so it renders standalone from anywhere. The justification is practical: the human can look at the data "without a server, a build step or a network", and the agent can screenshot it headlessly to verify. "Building a viewer that requires infrastructure is how a dataset ends up unexamined."
Two behaviours any such viewer needs: it never draws a missing value as zero (absent renders as —, excluded from charts, with a caption saying how many and why), and it has a coverage tab — "the tab that tells you the dataset is incomplete is the one that makes the rest trustworthy."
5. What this site does NOT own
Guide 04 also carries the estate's general handover discipline, and most of it belongs to a sibling:
| Material | Owner |
|---|---|
| Code/data vault split; the deriver seam; captures-as-evidence; per-entity records | this site |
HANDOVER.md for a stranger; NOTES numbered and cited from code; corrections in place; commit-at-every-unit; the session loop; surviving a container reset | teams.sgit.ai (the session and handover protocol) |
| Vault mechanics — keys, read-only publication, sub-vaults, app embedding | sgit.ai and pki.sgit.ai |
| Why files rather than a message bus | issues-fs.sgit.ai |
This is also the answer to why a vault belongs in this site's architecture, not only its workflow: U6 argues a vault is a first-class extension capability — the storage layer an extension needs and no browser platform offers — which is a design decision, not a session-handover habit.