Souspli

Souspli / Docs / How

Keys, library and storage

Everything the client keeps lives under one per-user directory (paths). SHELL_USER_DATA_DIR overrides it, which is how tests and the multi-account world get hermetic profiles.

<userData>/
  identity.key.enc        the encrypted identity (never the plaintext key)
  library/
    index.sqlite          one row per admitted envelope + relation tables
    blobs/<sha256-hex>    content-addressed store: programs and attachments
  seeds/blobs/<tar-sha256>  admitted bundles, byte for byte, re-servable
  downloads/<infohash>/   partial BitTorrent transfers

Keyring — src/shell/keyring/

The only code that touches private key bytes. Everything else receives a Signer and an Unsealer interface; the format library and the container never see key material, so a bug in either can at worst produce a wrong verification result, not an exfiltrated key.

Library — src/shell/library/

A SQLite index (better-sqlite3) over a content-addressed blob store.

Sealed letters never touch disk in the clear

A sealed letter's decrypted program, manifest and attachments live in an in-memory store scoped to the session, never in blobs/. Its encrypted bundle is what sits in seeds/ and what Export writes. After a restart a sealed letter is unmountable until it is re-ingested. This is pinned by a test (test/shell/library.spec.ts) and proposed as a MUST for the specification.

Export is a copy, never a rebuild

Saving a letter to a file copies the admitted bundle byte for byte from seeds/. Rebuilding it would sign with the local key and therefore re-author it: someone else's letter would leave under your signature, and your own would arrive under a new hash.

Native module note

better-sqlite3 is compiled against Electron's ABI, not Node's (pnpm rebuild:native, run by postinstall). For that reason the library is tested through Electron rather than under Vitest.