Storage
arka-deck stores three types of data locally: files (sessions, memory, ArkaDoc, project marker), SQLite databases (chat sessions, provider instances, ArkaDoc manifest), and encrypted secrets (provider keys, OAuth tokens).
No user data leaves the machine except explicit traffic to the public Cortex (catalogue) or the configured AI provider.
Filesystem — anti-symlink allowlist
Section titled “Filesystem — anti-symlink allowlist”The Filesystem port applies an allowlist at boot:
~/.arka-deck/(global arkaHome)<projectPath>/.arka-deck/(for each opened project)- Attachment paths explicitly imported through the UI
Any write outside the allowlist is refused. The protection includes realpath before matching, to prevent symlink bypass.
See ADR 0001 for the global decision and adapters/outbound/system/preferences-path-policy.ts for the impl.
SQLite — local databases
Section titled “SQLite — local databases”| Database | Path | Content |
|---|---|---|
chat.db | ~/.arka-deck/chat/chat.db | Chat sessions and messages (full timeline) |
providers.db | ~/.arka-deck/providers/providers.db | Provider instances (encrypted keys) |
| Per-project | <project>/.arka-deck/squad/missions.sqlite | Multi-agent missions (Squad Orchestration) |
The engine is better-sqlite3 (synchronous, performant, without complicated native deps). All critical writes are atomic (transaction).
Secrets — local AES-256-GCM
Section titled “Secrets — local AES-256-GCM”Secrets (API keys, OAuth tokens) are encrypted via the SecretCipher port:
| Element | Detail |
|---|---|
| Algorithm | AES-256-GCM |
| Format | v1:<iv-base64>:<tag-base64>:<encrypted-base64> |
| Master key | ~/.arka-deck/secrets/secrets.key, mode 600, created at first boot |
| Auth tag | 16 bytes — bit flip → visible SecretCipherFailedError |
| Migration | Port swappable to macOS Keychain / Linux libsecret |
If secrets.key is deleted, a new key is generated at next boot. Old encrypted instances become unrecoverable — that’s intentional (no external recovery path).
See ADR 0005.
Typical disk tree
Section titled “Typical disk tree”~/.arka-deck/ ← arkaHome (override via ARKA_DECK_HOME) index/ workspaces.json projects.json preferences/ user.json security.json ← user allowlist cache/ catalogue/... providers/ providers.db ← provider instances SQLite secrets/ secrets.key ← master key (mode 600) chat/ chat.db ← chat sessions SQLite
<projectPath>/ .arka-deck/ project/marker.json ← project marker (source of truth) agents/installed.json ← installed agents (Materializer track) hooks/installed.json skills/installed.json memory/ ← local memory (memory-local) addons/<addon>/... ← per-addon data cortex-actions/... ← cortex-actions logs squad/missions.sqlite ← Squad missions SQLite arkadoc/ ← project documents .claude/ ← Claude Code materializations agents/<slug>/ hooks/<name>.json skills/<name>/ settings.json ← NEVER touched by arka-deckSafe write cycle
Section titled “Safe write cycle”Critical operations (project marker, index, providers SQLite) follow a POSIX tmp + rename pattern:
- Write to a temporary file (
marker.json.tmp) - Atomic
fs.rename(tmp, final) - On failure, the final file remains intact
This guarantees that a mid-write crash never corrupts critical data.
See also
Section titled “See also”- ADR 0005 Secrets: ../../adr/0005-secrets-aes-gcm-local.md
- Projects/workspaces reference: ../reference/projets-workspaces
- Outbound ports: ./ports-outbound