Git filestore (vault)

Doso always keeps a **local Git vault** for versioned library documents and thought events. SQLite/Postgres remains the Ask runtime index — same split as “file on disk” vs “query engine.”

The Git vault is independent of the API database (The instance):

ModeMeaning
This device (default)Git repo next to the instance only
Git serverSame repo + smart-HTTP so agents/peers can clone/push
RemotePoint origin at a forge / git URL you host
1{data_dir}/vault/                 local git working tree (always)2{data_dir}/vault.keywrap.json     optional passphrase wrap (remote/backup)3{data_dir}/vault-backups/         encrypted git bundles

Layout#

1vault/2  library/{id}.md3  library/raw/{id}.*      # LFS when available4  thoughts/events.jsonl5  workflows/6  chats/{id}.md7  meta/device.lock

Crypto#

SecretWho holds itSyncs?
SQLCipher / Keychain rootDeviceNo
Vault DEK (passphrase + recovery)UserYes — for remote/backup
  • Local mode may stay cleartext on a trusted machine.
  • Remote push/pull and encrypted bundles require an unlocked vault DEK.
  • Non-loopback git HTTP requires vault.access_token.

This key hierarchy is separate from the macOS desktop SQLCipher and Keychain protection. The device-only Keychain root protects the desktop SQLite Cache and encrypted settings secrets; it is neither exported nor used as the vault DEK. Postgres encryption remains the database operator's responsibility.

Local git server#

When mode is local_server, Doso binds vault.listen_addr (default 127.0.0.1:9419) and runs git http-backend for the vault project.

Clone URL example: http://127.0.0.1:9419/vault

Auth: Authorization: Bearer <token> or x-doso-git-token when a token is set.

This is the pipe for future multiplayer — not CRDT merge yet. v1 is single-active / agent access, not concurrent graph writers.

Settings UX#

Settings → Git filestore (beside Data storage):

  • On this device / Git server / Remote
  • Listen address + access token
  • Remote URL → sets origin

API: PUT /v1/settings/vault, GET /v1/vault/status, plus backup/rebuild/unlock routes under /v1/vault/*.

Changing the vault mode does not switch or migrate the SQLite/Postgres Cache. Likewise, changing Cache backends does not push the vault. See Data modes: Git filestore for the complete two-plane model.

Config (storage.json)#

1{2  "vault": {3    "enabled": true,4    "mode": "local",5    "path": "vault",6    "listen_addr": "127.0.0.1:9419",7    "remote_url": "",8    "access_token": "",9    "device_id": "<uuid>"10  }11}