outcomeThe vault's generator owns one folder and synchronizes it
spec:decisions.vault-owned-folderPacks: pack:obsidian-vault-v1, pack:self-hosting-v1
Design: no design entries · no pinned declarations · no decisions
Findings: no errors, no warnings
specs/decisions/vault-owned-folder.sdp.md
No open questions and no blocking questions; implementation binding none, verifier binding none, and expected-outcome oracle none.
Intent
- Regenerate the vault from the one graph as often as a design pass needs without ever removing or rewriting a note a person wrote in it.
Decision
context- Every projection root is rewritten wholesale, and every command that enters the shared build removes all of them first, because an absent view is honest and a stale one is not. A vault is different: a person keeps it open in Obsidian, keeps Obsidian's settings in it, and writes intent notes beside the generated ones.
decision- The vault's generator owns one folder of the vault,
sdp/, and keeps there a file list naming every file it wrote with a hash of its content. A.DS_Storefile undersdp/is ignored. A listed.basefile a person changed is kept, even when it leaves the generated set, with its recorded content unchanged in the list; the run warns with its path and the wordsdelete it to regenerateand goes on. For every other file, a run refuses, writing and removing nothing, while that folder holds a file the list does not name or one whose content the list does not record. Otherwise it synchronizes the folder: it writes the files whose content changed, leaves the others untouched, and removes the files it wrote that the graph no longer holds. The vault is not one of the projection roots the shared build rewrites: no build removes it, a vault directory where the build writes or removes is refused, and only the vault's synchronization writes it, whethersdp vaultor the verb that writes every projection root runs it. rationale- A wholesale rewrite removes whatever a person put in the root, and a regeneration that removes or rewrites a note a person wrote is refused.
- Writing only the files that changed keeps every other note's bytes and modification time, so Obsidian keeps a person's place while a pass runs; a wholesale rename shows Obsidian every note removed and created again.
- A list of written contents tells the generator's files from a person's without marking any note, and it is a function of the graph like the notes it lists, so the vault keeps its determinism.
alternatives- Rewrite the folder wholesale through a temporary sibling, as the five roots are rewritten; refused, because it moves a reader off their place and removes any note a person left in the folder.
- Overwrite a generated note a person changed and report it afterwards; refused, because the overwrite loses what the person wrote.
- Mark each generated note with a hash in its own properties; refused, because a person's copy of a generated note carries a valid mark and would be removed as stale, and the mark shows on every note.
- Make the vault a sixth projection root; refused, because the shared build's invalidation would remove a person's intent notes with it.
consequences- While a run is under way the folder may hold notes of two generations, each note whole, and the file list lets the next run recognize what an interrupted run left.
- A run whose extraction fails keeps the last notes and says so on the index note, so a broken carrier never empties the vault a person is reading.
- The vault's determinism is checked by tests, since the repository's projection suite certifies the five projection roots only.
Verification
Verifier bindings
No verifier binding recorded.
Design view
Requirement drawing
- Declared verifying examples: no declared verifying example.
- Test or oracle bindings: no recorded binding.
The diagram as text
- spec:decisions.vault-owned-folder: The vault's generator owns one folder and synchronizes it · declared Spec
- spec:consumers.obsidian-vault: An Obsidian vault lets a person iterate on designs from the one graph · declared Spec
- impl:protocol.vault-command: validates after vault preflight and retains prior notes behind a failed-extraction index · anchored code ·
src/cli/vault-command.ts:191 - impl:protocol.vault-sync: guards every owned entry and records transitional hashes before atomic file replacement · anchored code ·
src/projections/vault/sync.ts:98 - spec:decisions.vault-owned-folder refines spec:consumers.obsidian-vault · declared — settles which files the vault's generator owns and how it regenerates them
- impl:protocol.vault-command references spec:decisions.vault-owned-folder · anchored
- impl:protocol.vault-sync references spec:decisions.vault-owned-folder · anchored
Mermaid source
Copyable source; the Studio draws static SVG.
Preferred syntax: requirementDiagram. Chosen syntax: flowchart TB because references require exact labels unavailable in requirement syntax.
Decisions
No decision record named.
Runtime
No implementation neighborhood recorded.
Runtime observation: not tracked.
Evidence
Runtime observation: not tracked.
Build attestations: not tracked.
Deployments: not tracked.
Bills of materials: not tracked.
Impact
The diagram as text
- spec:consumers.obsidian-vault: An Obsidian vault lets a person iterate on designs from the one graph
- spec:consumers.vault-on-ramp: The vault skill teaches agents to keep an Obsidian vault of the graph
- spec:decisions.vault-owned-folder: The vault's generator owns one folder and synchronizes it
- spec:decisions.vault-owned-folder refines spec:consumers.obsidian-vault · declared — settles which files the vault's generator owns and how it regenerates them
- spec:consumers.obsidian-vault decidedBy spec:decisions.vault-owned-folder · declared — the generator owns one folder of the vault and synchronizes it instead of rewriting a root
- spec:consumers.vault-on-ramp decidedBy spec:decisions.vault-owned-folder · declared — the skill keeps a person's notes outside the one folder the command owns
Mermaid source
Copyable source; the Studio draws static SVG.
Preferred syntax: flowchart. Chosen syntax: labelled flowchart, preserving exact relations, claims and folds.
Rests on
- refines · spec:consumers.obsidian-vault · stated ready, floor ready
Rested on by
Distance 1
- spec:consumers.obsidian-vault
Implementing units
impl:protocol.vault-command·src/cli/vault-command.ts:191impl:protocol.vault-notes·src/projections/vault/notes.ts:45impl:protocol.vault-sync·src/projections/vault/sync.ts:98
Referencing units
None.
Enabled verifiers: spec:consumers.obsidian-vault.changed-note-refused, spec:consumers.obsidian-vault.failed-extraction-keeps-notes, spec:consumers.obsidian-vault.failed-extraction-recovered, spec:consumers.obsidian-vault.fresh-vault, spec:consumers.obsidian-vault.hidden-file-refused, spec:consumers.obsidian-vault.interrupted-run-recovered, spec:consumers.obsidian-vault.person-notes-survive, spec:consumers.obsidian-vault.unknown-note-refused, spec:consumers.obsidian-vault.vault-in-build-path-refused
- spec:consumers.vault-on-ramp
Implementing units
impl:protocol.vault-on-ramp·test/skills.test.ts:1995
Referencing units
None.
Enabled verifiers: test:protocol.vault-on-ramp
Distance 2
- spec:consumers.obsidian-vault.bases
Implementing units
impl:protocol.vault-bases·src/projections/vault/bases.ts:43impl:protocol.vault-notes·src/projections/vault/notes.ts:45
Referencing units
None.
Enabled verifiers: spec:consumers.obsidian-vault.bases.views-match-sources
- spec:consumers.obsidian-vault.changed-note-refused
Implementing units
None.
Referencing units
None.
Enabled verifiers: test:protocol.consumers.obsidian-vault.changed-note-refused
- spec:consumers.obsidian-vault.failed-extraction-keeps-notes
Implementing units
None.
Referencing units
None.
Enabled verifiers: test:protocol.consumers.obsidian-vault.failed-extraction-keeps-notes
- spec:consumers.obsidian-vault.failed-extraction-recovered
Implementing units
None.
Referencing units
None.
Enabled verifiers: test:protocol.consumers.obsidian-vault.failed-extraction-recovered
- spec:consumers.obsidian-vault.fresh-vault
Implementing units
None.
Referencing units
None.
Enabled verifiers: test:protocol.consumers.obsidian-vault.fresh-vault
- spec:consumers.obsidian-vault.hidden-file-refused
Implementing units
None.
Referencing units
None.
Enabled verifiers: test:protocol.consumers.obsidian-vault.hidden-file-refused
- spec:consumers.obsidian-vault.interrupted-run-recovered
Implementing units
None.
Referencing units
None.
Enabled verifiers: test:protocol.consumers.obsidian-vault.interrupted-run-recovered
- spec:consumers.obsidian-vault.iteration
Implementing units
impl:protocol.vault-sync·src/projections/vault/sync.ts:98impl:protocol.vault-text·src/projections/vault/text.ts:30impl:protocol.vault-watch·src/cli/vault-command.ts:219
Referencing units
None.
Enabled verifiers: spec:consumers.obsidian-vault.iteration.watch-rewrites-changed-notes, spec:consumers.obsidian-vault.iteration.watch-source-anchor
- spec:consumers.obsidian-vault.notes
Implementing units
impl:protocol.vault-notes·src/projections/vault/notes.ts:45impl:protocol.vault-sections·src/projections/vault/sections.ts:10impl:protocol.vault-text·src/projections/vault/text.ts:30
Referencing units
None.
Enabled verifiers: spec:consumers.obsidian-vault.notes.case-collision-refused, spec:consumers.obsidian-vault.notes.entry-address-link, spec:consumers.obsidian-vault.notes.term-address-link, spec:consumers.obsidian-vault.notes.unresolved-mention-stays, test:protocol.vault-priority
- spec:consumers.obsidian-vault.person-notes-survive
Implementing units
None.
Referencing units
None.
Enabled verifiers: test:protocol.consumers.obsidian-vault.person-notes-survive
- spec:consumers.obsidian-vault.unknown-note-refused
Implementing units
None.
Referencing units
None.
Enabled verifiers: test:protocol.consumers.obsidian-vault.unknown-note-refused
- spec:consumers.obsidian-vault.vault-in-build-path-refused
Implementing units
None.
Referencing units
None.
Enabled verifiers: test:protocol.consumers.obsidian-vault.vault-in-build-path-refused
Distance 3
- spec:consumers.obsidian-vault.bases.views-match-sources
Implementing units
None.
Referencing units
None.
Enabled verifiers: test:protocol.consumers.obsidian-vault.bases.views-match-sources
- spec:consumers.obsidian-vault.iteration.watch-rewrites-changed-notes
Implementing units
None.
Referencing units
None.
Enabled verifiers: test:protocol.consumers.obsidian-vault.iteration.watch-rewrites-changed-notes
- spec:consumers.obsidian-vault.iteration.watch-source-anchor
Implementing units
None.
Referencing units
None.
Enabled verifiers: test:protocol.consumers.obsidian-vault.iteration.watch-source-anchor
- spec:consumers.obsidian-vault.notes.case-collision-refused
Implementing units
None.
Referencing units
None.
Enabled verifiers: test:protocol.consumers.obsidian-vault.notes.case-collision-refused
- spec:consumers.obsidian-vault.notes.entry-address-link
Implementing units
None.
Referencing units
None.
Enabled verifiers: test:protocol.consumers.obsidian-vault.notes.entry-address-link
- spec:consumers.obsidian-vault.notes.term-address-link
Implementing units
None.
Referencing units
None.
Enabled verifiers: test:protocol.consumers.obsidian-vault.notes.term-address-link
- spec:consumers.obsidian-vault.notes.unresolved-mention-stays
Implementing units
None.
Referencing units
None.
Enabled verifiers: test:protocol.consumers.obsidian-vault.notes.unresolved-mention-stays
Relations
| Relation and direction | Other end | Claim | Reason | Exercised keys |
|---|---|---|---|---|
| refines · outgoing | An Obsidian vault lets a person iterate on designs from the one graphspec:consumers.obsidian-vault · resolves | declared | settles which files the vault's generator owns and how it regenerates them | None |
| decidedBy · incoming | An Obsidian vault lets a person iterate on designs from the one graphspec:consumers.obsidian-vault · resolves | declared | the generator owns one folder of the vault and synchronizes it instead of rewriting a root | None |
| decidedBy · incoming | The vault skill teaches agents to keep an Obsidian vault of the graphspec:consumers.vault-on-ramp · resolves | declared | the skill keeps a person's notes outside the one folder the command owns | None |
Bindings
Implementation binding: none
Design reference: present
impl:protocol.vault-command· validates after vault preflight and retains prior notes behind a failed-extraction index ·src/cli/vault-command.ts:191· role publisher · component component:protocol.cli· layer edge · context protocolimpl:protocol.vault-sync· guards every owned entry and records transitional hashes before atomic file replacement ·src/projections/vault/sync.ts:98· role publisher · component component:protocol.projections· layer edge · context protocol
Verifier binding: none
Expected-outcome oracle: none
Runtime observation: not tracked.
Run results: not recorded in the graph.
Findings
None.
Composing (0)
Composing needs the script.