Hive

A hive is an encrypted, mountable filesystem image that OctoMY™ uses for any piece of state that must survive a restart, follow an identity around, or be cryptographically scoped to one owner. Hives are the storage substrate that sits underneath every other concept in the app — sentient identity, node identity, contacts, key material, configuration, OPAL audit history.

TL;DR

A hive is a single file on disk that, when mounted with the right key, becomes a writable directory tree. Three classes exist today (sentient hive, node hive, general hive); only the first two are user-visible.

For the user-facing controls, see Active Mounts. For the encryption model see the Security Model.


Why an encrypted filesystem and not a database?

A hive is a Shufflecake volume — a deniable encrypted block device wrapped around a sparse store file, presented as an ExFat filesystem once unlocked. That gives the app three properties that an ordinary on-disk database can't provide:

  1. One key, one mount point. Authentication is a single Argon2id derivation against the hive's header. Everything inside is then plaintext-accessible to the running process; nothing else on the system can read it without the same key.
  2. Plausible deniability. Shufflecake allows multiple logical volumes to coexist in the same underlying store file with different keys; an attacker who compels a passphrase sees only the volume that key unlocks.
  3. Mount/unmount semantics map cleanly onto identity lifecycle. Switching sentient = unmount old hive, mount new hive. There's no "drop my contacts from a shared SQLite" surface area; the contacts are simply no longer addressable.

The encrypted-store-as-identity-boundary is what lets the app move a user between sentients without restarting the process and without leaving residue from the previous identity in shared in-memory caches.


Three classes of hive (§HT-1)

Every hive carries its type in its on-disk identifier. There is no separate manifest field; the prefix is the type.

Class On-disk id What it stores Owner Display
Sentient hive SID-<sentient-sid-hex> The owning sentient's vault (Ed25519 keys, BIP39 recovery phrase, display name), contacts and trust state, per-node hive keys, OPAL conversation/audit history scoped to that sentient One sentient Looks up the sentient and renders their friendly display name + identicon (the user never sees the raw SID hex anywhere)
Node hive NID-<node-nid-hex> The owning node's per-NID state — NodeStore folder layout, per-node OPAL history database, courier blob spool, runtime settings that aren't OS-wide One node, owned by one sentient Looks up the node and renders its friendly display name + identicon
General hive Free-form name User-named encrypted volume not tied to any identity. Future surface — the taxonomy reserves space for it but no UX ships yet. None / user Literal name; no identicon

Why types live in the identifier

Earlier versions of the app used a privileged "System" hive owned by the device's primary sentient. The string was special-cased throughout the codebase: in passphrase prompts, in the lanyard, in factory code paths. Renaming a sentient required hunting through string literals; auto-creating a hive for an imported sentient required carving an exception for the magic name.

Replacing that with a typed prefix moves the type into a single field and lets the display layer look it up freshly every time. Renaming a sentient now updates every UI surface without changing anything on disk; importing an additional sentient produces another SID-<hex> hive that's visually peer-equal to the original.


How sentient and node hives layer

Within an active session, a node hive is always mounted on top of its owning sentient hive — the node hive's mount path lives inside the sentient hive's mount tree. Two practical consequences:

The layering is one-sentient-active-at-a-time and at-most-one-node-on-top: §OQ-7's "concurrent mounts" resolution. The architecture supports the dual mount; it does not pursue N>1 sentients mounted side-by-side, because there is no user-facing model for it.


The hive lifecycle

                                         ┌───────────────┐
                                         │ HiveFactory   │
                                         └──────┬────────┘
                                                │  createSentientHive (auto / wizard)
                                                │  createNodeHive    (§9b funnel)
                                                ▼
                                         ┌───────────────┐
            mount  ───────────────────►  │   on disk     │
            (Argon2id + ExFat)           │ SID-<hex>     │
                                         │ NID-<hex>     │
                                         └──────┬────────┘
                                                │ HiveSession::mountHiveAsync
                                                │ HiveSession::mountNodeHive
                                                ▼
                                         ┌───────────────┐
                                         │  mounted      │ ─── Lanyard / Active Mounts
                                         │  (writable    │
                                         │   ExFat tree) │
                                         └──────┬────────┘
                                                │ §SP-8a Save → Teardown
                                                ▼
                                         ┌───────────────┐
                                         │  unmounted    │
                                         │  (still on    │
                                         │   disk)       │
                                         └───────────────┘

Where the user sees hives

Outside the diagnostic Active Mounts screen, the user never sees the raw SID-<hex> / NID-<hex> strings. Every UI surface — the lanyard chips, the sentient and node lobbies, the selection activities, the status widgets, log lines that surface in the UI — looks up the owning entity and renders its friendly display name + identicon.

The taxonomy is engineering visible (in spec text, in log entries, in HiveRegistry::sentientHives() / nodeHives() / generalHives() filters) but user invisible. That separation is on purpose: the type prefix is a stable contract for code, while the display name is a mutable choice the user makes.


Common questions

Can I rename a sentient? Yes, freely. The on-disk hive id is SID-<hex> and never changes; the display name is read fresh from the sentient's vault every time the lanyard updates.

What happens if my sentient hive is corrupted? Mount fails with a wrong-passphrase or volume-error reason. The session is not affected (you're still on the previous active sentient if there was one). Recovery is the BIP39 phrase you wrote down at first boot.

Can two devices share a hive file? No. The hive is per-device — moving a sentient identity to a new device is the migration protocol, which produces a fresh SID-<hex> hive on the new device with the original SID derived from the recovery phrase. Per §SP-10, imports always land in a new hive, never overwrite an existing one.

Is a "general hive" useful today? Not yet. The class is reserved in the taxonomy so future surfaces (user-named encrypted volumes, mount-time union-fs composition) don't have to renegotiate the type system. No factory or UI exists for them.


Topic Why it's relevant
Sentient Identity What lives inside a sentient hive
Identity Switching The mount / unmount choreography
Active Mounts User-facing diagnostic for what's mounted
Open Files What can block an unmount during a switch