# FOG Composer Status: Draft 0.1 Date: 2026-08-08 ## 1. Purpose This document defines `FOG-COMPOSER`, the networkless endpoint, local-state, transfer, recovery, and update-verification contract for FOG native services. It fixes the common Composer security boundary, MicroVM and Portable deployment profiles, process separation, authenticated encrypted vault, transaction and rollback rules, hostile import handling, committed export bundles, identity-safe recovery, update verification, local rendering, resource limits, and conformance gates. It also records four non-active implementation candidates: - `FOG-COMPOSER-CANDIDATE-LINUX-VAULT-1` for a Linux read-only system image, LUKS2 defense-in-depth volume encryption, a transactional embedded database, and object-level authenticated encryption; - `FOG-COMPOSER-CANDIDATE-MICROVM-QUBES-1` for a Qubes-style networkless VM with narrowly allowlisted qrexec transfer services; - `FOG-COMPOSER-CANDIDATE-PORTABLE-LINUX-1` for a signed read-only Linux image on dedicated physically offline hardware; - `FOG-COMPOSER-CANDIDATE-UPDATE-TUF-1` for offline update metadata derived from The Update Framework. These candidates have no active numeric profile IDs, do not select final libraries or cryptographic parameters, are not authorized for public release, and do not establish deployed endpoint-security claims. The key words MUST, MUST NOT, REQUIRED, SHOULD, SHOULD NOT, and MAY describe normative requirements in the sense of BCP 14 when they appear in uppercase. ## 2. Scope `FOG-COMPOSER` owns: - the networkless Composer runtime and its local privilege boundaries; - common, MicroVM, Portable, and lower-assurance transfer profiles; - booted-image verification requirements visible to the Composer; - encrypted mutable state, key wrapping, object protection, and state migration; - local atomic transactions spanning messaging, storage, PKI, imports, exports, recovery, and application state; - local state commitments and optional external monotonic anchors; - fixed Composer bundle framing and direction-specific record allowlists; - import quarantine, complete validation, deduplication, and state release; - transactional export creation and duplicate-export behavior; - identity recovery packages and non-resumable restored sessions; - offline release and update verification on Composer systems; - safe local rendering and native application module boundaries; - local retention, deletion, diagnostic, and resource-limit behavior; - Composer-specific conformance and fault-injection evidence. This document does not own: - message handshake, ratchet, envelope, acknowledgment, or fragmentation cryptography; - storage capabilities, replica envelopes, receipts, retention, or polling; - KEMSphinx packet or SURB construction; - adjacent online Noise links or blind-relay queue behavior; - FOG-PKI consensus production, authority recovery, or transparency proofs; - FOG-SX framing, FEC, physical signaling, or optical hardware; - entry capsule and return-rendezvous constructions; - release-repository production, signing ceremonies, or build provenance; - a native multi-device protocol or automatic account recovery service. Those contracts belong to `FOG-MESSAGING`, `FOG-STORAGE`, `FOG-SPHINX-PROFILES`, `FOG-WIRE`, `FOG-PKI`, `FOG-SX`, the entry and return specifications, a future `FOG-UPDATE` release contract, and future multi-device work. ## 3. Security Boundary and Threats ### 3.1 Assets The Composer holds the highest-value user assets in FOG: - message plaintext, drafts, permitted attachments, and rendered history; - pairwise identity roots, handshake identities, prekeys, ratchets, and skipped-message keys; - storage read and write capabilities, recovery tombstones, and outboxes; - contacts, private labels, verification decisions, and conversation state; - PKI trust anchors, accepted epochs, checkpoints, manifests, and equivocation evidence; - KEMSphinx routes, ephemeral secrets, SURBs, reply tokens, and pending network work; - vault, object, transfer-pairing, backup, recovery, and local anchor keys; - installed release state, trusted release roots, and rollback floors. Compromise of an unlocked Composer can expose or alter all local assets. No storage, boot, VM, or transfer mechanism can preserve confidentiality against an attacker that controls the code currently using the plaintext and keys. ### 3.2 Adversaries The contract considers: - theft or forensic copying of powered-off storage; - malicious, malformed, replayed, truncated, reordered, or oversized import; - a compromised blind relay, transfer receiver, removable medium, QR reader, FOG-SX decoder, or update distributor; - partial database corruption, torn writes, power failure, disk-full faults, and stale filesystem snapshots; - rollback or cloning of a complete internally consistent Composer vault; - a hostile MicroVM host, hypervisor, firmware, peripheral, DMA device, boot chain, or system update; - malicious contacts and authenticated but adversarial message content; - physical observation, evil-maid access, side channels, and secret remnants; - dependency, compiler, build, release-key, or update-metadata compromise. ### 3.3 Trust distinctions Object-level authenticated encryption protects stored object confidentiality and integrity under its exact key assumptions. It does not prove freshness. A hash-chained local journal detects missing, reordered, partially restored, or corrupted state relative to the latest state still available locally. It cannot detect replacement of the complete vault, journal, and keys by an older coherent copy. Complete rollback detection requires a monotonic anchor outside the rollback domain. A virtual TPM controlled by the same hostile VM host is not independent of that host. A counter alone also does not automatically bind the intended state commitment unless the selected anchor protocol proves that binding. Networklessness prevents direct network access by the guest or portable runtime. It does not prevent a hostile host, firmware, peripheral, or human from observing or modifying the endpoint. ## 4. Protocol Invariants ### COMPOSER-INV-01: No network interface A conforming Composer has no network adapter, route, network namespace access, socket activation, proxy, update proxy, loopback service, HTTP server, RPC server, or plugin listener. A convenience mode with networking is not a FOG Composer profile. ### COMPOSER-INV-02: One active mutable instance One Composer identity vault has exactly one active mutable instance. Copying a vault, VM private volume, database, USB state partition, or live backup does not create a second device. Any suspected clone freezes affected ratchets, capabilities, prekeys, outboxes, and monotonic state. ### COMPOSER-INV-03: Random data keys, human unlock Bulk state is encrypted under random vault and object keys. A passphrase or recovery phrase is processed only by the profile's reviewed memory-hard KDF to unlock or rewrap random key material. It is never used directly as an AEAD key, identity key, ratchet seed, storage capability, or backup key. ### COMPOSER-INV-04: Every sensitive object is authenticated Identity, contact, draft, message, ratchet, capability, outbox, inbox, deduplication, PKI monotonic, recovery, and update state has object-level authenticated encryption or an equally reviewed authenticated container. Whole-volume encryption is defense in depth and is not accepted as the sole object-integrity control. ### COMPOSER-INV-05: Persist and anchor before effect A security-critical transition is not externally exportable and its plaintext is not renderable until the complete local transaction is durable. Where the profile claims full rollback detection, the corresponding external monotonic anchor transition must also be durable before export or rendering. ### COMPOSER-INV-06: Local chain is not full anti-rollback Documentation and UI MUST distinguish local consistency verification from independent monotonic anchoring. A self-contained vault without an external anchor MUST NOT claim detection of a complete coherent rollback. ### COMPOSER-INV-07: Every import is hostile Filename, label, QR presentation, media filesystem, MIME type, transport checksum, FEC result, relay origin, and operator statement confer no authenticity. Complete bounded parsing and the owning inner cryptographic verification occur before state transition or rendering. ### COMPOSER-INV-08: Export contains committed opaque work only An export bundle contains only already committed public objects or opaque protocol work. It never contains message plaintext, drafts, identity private keys, contact labels, ratchet state, capability roots, database keys, backup keys, crash diagnostics, or a long-term Composer signature visible to the relay. ### COMPOSER-INV-09: Transfer signatures do not create a public identity FOG does not sign relay-facing bundles with a long-term user or Composer key. Each inner object supplies its owning authentication. A local transfer-pairing authenticator MAY reject random injection but does not replace inner verification and does not become a remote network identity. ### COMPOSER-INV-10: Recovery never silently resumes live state An identity recovery package can preserve explicitly allowed long-term identity and contact verification material. Restored live ratchets, capability streams, prekeys, reply tokens, outboxes, and deduplication windows remain frozen. They are replaced through authenticated recovery transitions, not resumed from a stale snapshot. ### COMPOSER-INV-11: Update verification is offline and monotonic An update installs only after threshold signature, metadata chain, target hash, target length, platform, compatibility, expiry, version, and rollback floor validation. No online fetch, local administrator override, unsigned emergency image, or boot failure authorizes a downgrade. ### COMPOSER-INV-12: Immutable runtime image The booted operating-system and Composer image are read-only and verified by a root authenticated outside that mutable image. Writable application state, temporary data, logs, and update staging cannot replace executable content. ### COMPOSER-INV-13: No active imported content Initial native applications render bounded plain text and fixed local UI objects only. HTML, scripts, macros, fonts, office files, PDFs, media codecs, shell commands, desktop launchers, and automatic external resource loading are not valid message content. ### COMPOSER-INV-14: High-assurance paths are physically directional The high-assurance export and import paths use separate transmit-only and receive-only mechanisms. A removable device alternated between online and offline systems is a named lower-assurance profile, never an invisible fallback. ### COMPOSER-INV-15: No secret-bearing diagnostics Logs, metrics, crash dumps, support bundles, command arguments, environment variables, shell history, swap, hibernation, thumbnails, previews, clipboard, and generic desktop indexes contain no Composer secrets or plaintext. ### COMPOSER-INV-16: No runtime extension mechanism The Composer loads no third-party plugin, interpreted script, external renderer, generic parser, dynamic protocol module, or operator-selected crypto provider. New functionality requires a reviewed release and an authenticated profile transition. ## 5. Deployment Profiles ### 5.1 Common profile Every Composer profile MUST: - boot an authenticated read-only software image; - omit or disable all network and radio devices and drivers; - use one dedicated authenticated encrypted mutable vault; - separate import quarantine and export spool from active vault state; - disable swap, hibernation, core dumps, automatic crash reporting, previews, indexing, and host clipboard integration; - mount no internal disk or general removable filesystem automatically; - expose only the minimum display, human input, import, export, state, and optional monotonic-anchor devices; - enforce the exact bundle profiles, limits, and direction allowlists; - require explicit human unlock and explicit update or recovery ceremonies; - show the current assurance profile and lost assumptions locally. ### 5.2 MicroVM profile The MicroVM definition contains no virtual NIC. Network absence is enforced at the hypervisor configuration, guest kernel configuration, process sandbox, and conformance-test levels. Host integration is limited to: - a minimal display path; - explicit keyboard and pointing input; - one bounded import data channel; - one separately authorized bounded export data channel; - one dedicated mutable state block device; - an optional external monotonic-anchor interface. Shared directories, host filesystem mounts, arbitrary qrexec, drag-and-drop, clipboard, audio, camera, USB passthrough, generic guest agents, shell services, and bidirectional device forwarding are forbidden. The host and hypervisor remain inside the endpoint trust assumption. A MicroVM profile can reduce accidental network exposure and contain some application failures, but cannot protect unlocked memory or execution from a host that can inspect or replace the guest. The Qubes candidate uses a dedicated no-NetVM qube and two exact qrexec services with fixed direction and byte bounds. General qrexec command execution, file-copy services, URL opening, clipboard, and update proxy access remain denied. Qubes is an integration candidate, not a runtime dependency or an automatic security claim. ### 5.3 Portable profile The Portable profile boots signed immutable media on a physically offline computer. Its kernel and initramfs omit network, Bluetooth, cellular, NFC, Thunderbolt networking, and unnecessary radio drivers. Firmware setup and physical switches disable available radios where supported. It MUST: - verify the bootloader, kernel, initramfs, command line, root-image digest, and Composer release identity before vault unlock; - use a read-only verified root image and a separate encrypted mutable state partition; - refuse automatic internal-disk, network-share, and foreign-filesystem mounting; - use dedicated receive-only and transmit-only transfer devices in its high-assurance form; - keep Composer state media away from online machines; - warn locally when Secure Boot, measured boot, immutable-root verification, external anchoring, or physical directionality is absent. Portable means the signed system and encrypted state can be carried. It does not mean the same active state may be cloned or used concurrently. A profile that binds rollback protection to one machine TPM is machine-bound even if its boot media is removable. ### 5.4 Portable shuttle profile `PORTABLE_SHUTTLE` permits one explicitly labeled removable transfer medium to move opaque bundles between online and offline systems. It is lower assurance because the online system can attack the medium controller, filesystem, and subsequent offline parser and because the medium provides a physical return channel. This profile still requires the fixed Composer bundle parser, separate import quarantine, no automatic execution, no general file browsing, and complete inner authentication. It MUST NOT inherit the high-assurance simplex or peripheral-compromise claim. ### 5.5 Claim matrix | Property | MicroVM | Portable high assurance | Portable shuttle | | --- | --- | --- | --- | | Composer process has no network | required | required | required | | Host compromise protection | not claimed | not applicable while dedicated offline hardware is honest | not claimed for online transfer host | | Read-only verified system image | required | required | required | | Separate directional transfer hardware | profile-dependent | required | absent by definition | | Complete rollback detection | only with an anchor outside the hostile host | only with independent anchor | only with independent anchor | | Physical peripheral isolation | host-dependent | required and measured | weakened | | Endpoint compromise protection while unlocked | not claimed | not claimed | not claimed | ## 6. Process and Module Architecture ### 6.1 Security domains The Composer image contains these local domains: 1. `fog-compose`: the only process that unlocks vault keys, performs protocol state transitions, and renders authenticated plaintext; 2. import decoder: an unprivileged sandbox that reads one raw transfer stream, validates only outer framing and limits, and writes one quarantine object; 3. export encoder: an unprivileged sandbox that reads one already sealed opaque export and drives one transmit-only backend; 4. update verifier: a maintenance environment that has release roots and inactive image access but no unlocked Composer vault; 5. optional anchor adapter: a minimal process or device interface that exposes only the profile's monotonic prepare, advance, and read operations. The import decoder does not receive vault keys, identity state, contact state, message plaintext, network configuration, a shell, or writable executable paths. Its output remains untrusted when `fog-compose` opens it. The export encoder cannot query the vault or create new protocol work. It can read only one immutable export spool item selected by `fog-compose` and cannot write to import quarantine. ### 6.2 Internal modules Inside the `fog-compose` trust domain, responsibilities remain explicit: ```text ui -> native applications -> messaging and storage coordinators -> transaction service -> encrypted vault import coordinator -> protocol verifiers -> transaction service export coordinator -> committed protocol outbox -> export spool PKI verifier -------^ | anchor coordinator ---------------------------^ ``` The initial implementation SHOULD use modules named by responsibility: - `composer/vault`: key hierarchy, encrypted objects, schema, transactions; - `composer/anchor`: state commitments and monotonic-anchor protocol; - `composer/import`: bundle validation, quarantine, deduplication, dispatch; - `composer/export`: committed selection, sealing, spool lifecycle; - `composer/update`: trusted metadata and installed-version state; - `composer/recovery`: recovery package creation and restore freeze; - `composer/ui`: safe presentation and explicit user decisions; - `apps/drop`, `apps/mailbox`, and `apps/im`: native state machines only. Protocol modules do not import UI, filesystem, database, qrexec, removable media, or platform code. Platform adapters do not implement messaging, storage, PKI, or cryptographic state transitions. ### 6.3 What not to split The initial implementation does not create: - separate network services for native applications; - one database per application; - a generic plugin host or IPC bus; - a background indexing or search service with plaintext access; - a universal crypto, filesystem, archive, or document adapter; - concurrent writable Composer processes. One transaction owner and one encrypted database simplify the required cross-layer atomic commits. Process separation is used only where it removes raw transfer or update parsing from the vault-bearing process. ## 7. Boot and Runtime Hardening ### 7.1 Verified immutable image The profile authenticates the complete boot path and one immutable root-image digest. The Linux candidate uses a signed boot artifact and `dm-verity` for read-only block verification. The authenticated root digest must be inside the signed boot chain, not supplied by mutable kernel arguments or the state volume. Verification failure stops before vault unlock. An integrity error after boot locks the vault, produces no export, and enters recovery. Ignore-corruption and continue-on-verification-failure modes are forbidden. ### 7.2 Writable mounts The runtime permits only: - the dedicated encrypted state volume; - a bounded encrypted or memory-backed import quarantine; - a bounded export spool containing opaque committed bundles; - bounded memory-backed temporary directories; - explicit update staging only in maintenance mode. Executable, setuid, device, and interpreter behavior is disabled on mutable mounts where the platform supports it. Imported filenames never become local paths. The Composer does not traverse a foreign filesystem supplied by a transfer medium. ### 7.3 Runtime controls The active Composer profile requires: - no swap or hibernation; - disabled core dumps and process-memory crash capture; - locked-down debugging, tracing, performance counters, and ptrace; - no shell or package manager in the user session; - no automatic login or vault unlock; - strict process, file-descriptor, memory, CPU, and disk quotas; - default-deny device and syscall policy, including network socket creation; - memory-backed plaintext staging with bounded lifetime; - explicit lock on suspend, display loss, anchor loss, or integrity fault. Memory locking and explicit zeroization are best-effort implementation controls. They do not prove that compilers, kernels, caches, firmware, DMA, hibernation remnants, or physical memory retained no copy. ## 8. Vault and Key Hierarchy ### 8.1 Vault layers The Composer uses both: 1. full-volume encryption to hide filesystem metadata, database pages, journals, temporary files, and free space while powered off; 2. object-level authenticated encryption for every sensitive logical record. The Linux candidate evaluates LUKS2 for layer 1. It does not rely on ordinary sector encryption to authenticate logical records. Any LUKS2 integrity mode requires separate maturity, performance, recovery, and power-failure review. ### 8.2 Key hierarchy The minimum hierarchy is: ```text human unlock secret -> profile-fixed memory-hard KDF -> unlock KEK -> unwrap random vault key -> profile-fixed KDF/exporter -> identity-object key epoch -> contact-object key epoch -> messaging-state key epoch -> storage-state key epoch -> PKI-state key epoch -> draft/content key epoch -> outbox/import/export key epoch -> local-state-authentication key epoch ``` The backup or recovery key hierarchy is generated independently. It never derives from the live vault key, a contact root, message ratchet, storage capability, transfer-pairing key, release key, or monotonic-anchor key. The unlock KDF stores its algorithm identifier, salt, memory cost, time cost, parallelism, and output length in authenticated keyslot metadata. Parameters are benchmarked per supported hardware class and may be raised through a versioned rewrap without reencrypting all logical objects. The deployment profile states whether volume unlock and object-vault unlock use one human secret or separate factors. If one human secret is used, each layer has independent salts, context, KDF output, and wrapping key. Raw keys are never reused between the LUKS2 and object-vault layers. ### 8.3 Keyslot rules A keyslot wraps only random vault or recovery key material. Adding, removing, or changing a passphrase is an authenticated transaction. The previous slot remains in the live header only until the new slot and replacement header backup are durably verified. A memory-hard KDF raises guessing cost but does not turn a weak passphrase into a high-entropy secret. The UI requires a profile-appropriate secret and states the offline-guessing risk. Removing a LUKS2 keyslot does not revoke an old passphrase against an attacker who retained an earlier header backup containing that slot and the same volume key. True revocation against copied old headers requires a reviewed full volume-key and vault-key rotation, reencrypted data, retirement of old object keys, and controlled destruction of obsolete headers and media. Unlock secrets are accepted only through the trusted local UI or a narrowly specified hardware-token protocol. They never appear in command arguments, environment variables, files in the export bundle, logs, clipboard, or shell input history. Failed unlock attempts have bounded memory and CPU cost. The local UI may apply a coarse delay, but denial-of-service resistance cannot depend on an attacker-writable on-disk failure counter. ### 8.4 Object envelope Every encrypted logical object has a canonical profile-fixed header containing at least: ```text [ vault_format_version, vault_profile_id, network_id, composer_instance_id, object_type, object_id, object_generation, transaction_generation, key_epoch, plaintext_length, padded_length, nonce, ciphertext ] ``` All fields preceding `ciphertext` are authenticated associated data. The profile fixes lengths, encoding, nonce construction, padding classes, AEAD, KDF, maximum plaintext, and key epoch. Unknown fields, alternate encodings, nonce reuse, invalid padding, counter wrap, or authentication failure reject the object. `composer_instance_id` is a random local domain separator. It is never placed in relay-facing bundles, contact cards, messages, PKI, storage records, public logs, or release metadata. ### 8.5 Object classes The vault separates at least these object classes and key purposes: | Class | Examples | Restore rule | | --- | --- | --- | | Identity | contact roots, handshake identities | only through identity recovery policy | | Contact | public roots, fingerprints, local labels, verification decisions | public and local metadata may be recovered | | Messaging live state | ratchets, prekeys, skipped keys, ACK and dedup windows | stale copy never resumes | | Storage live state | capabilities, indexes, tombstones, receipts, retry generations | stale copy never resumes | | Content | drafts, inbox, sent plaintext, reassembly | optional local retention, not required for identity recovery | | Protocol outbox | immutable envelopes, boxes, packets, reply material | exact live instance only | | PKI state | genesis root, highest consensus, log checkpoint, manifests | monotonic verification required | | Release state | trusted roots, metadata versions, installed target, rollback floor | monotonic verification required | | Local control | transaction journal, state commitment, anchor receipt | never exported or identity-recovered as live state | ### 8.6 Candidate primitives `FOG-COMPOSER-CANDIDATE-LINUX-VAULT-1` evaluates Argon2id for unlock key derivation and XChaCha20-Poly1305 for object protection through maintained reviewed libraries. The candidate uses random nonces from the OS CSPRNG and purpose-separated KDF outputs. No primitive, parameter, library, ABI, database, or vault profile becomes active merely because it appears here. Activation requires exact versions, byte-level vectors, nonce analysis, crash tests, benchmarks, dependency review, and independent security review. ## 9. Transactional State Model ### 9.1 One transaction owner Exactly one `fog-compose` process opens the mutable vault for writing. It uses one transaction engine capable of atomic durable commit across every logical object participating in a protocol transition. Messaging ratchet state, storage capability state, outbox objects, PKI monotonic state, application queue state, import deduplication, and export eligibility MUST NOT be committed through independent databases or eventually consistent workers. ### 9.2 State commitment Every security-critical transaction produces a canonical `StateCommitment`: ```text [ commitment_format_version, vault_profile_id, network_id, composer_instance_id, transaction_generation, previous_commitment, encrypted_catalog_root, highest_consensus_epoch, consensus_hash, transparency_tree_size, transparency_root_hash, release_root_version, installed_release_version, import_generation, export_generation, transaction_class ] ``` The commitment uses a profile-fixed authenticated hash or MAC construction. It contains no plaintext, contact identifier, message identifier, capability, box ID, or application type. It remains local except for a private external anchor that is explicitly part of the same Composer trust domain. ### 9.3 Unanchored commit An unanchored profile: 1. stages all new encrypted objects and the next catalog separately; 2. validates cross-object invariants and resource bounds; 3. writes and syncs the transaction journal; 4. atomically selects the new catalog and state commitment; 5. syncs the database and containing filesystem metadata; 6. only then releases export eligibility or authenticated plaintext. This detects ordinary partial writes and local history discontinuity. A complete older vault copy containing its matching keys and journal can still pass. ### 9.4 Externally anchored commit An anchored profile uses a prepared generation so the external effect never precedes the anchor: 1. retain generation `N` as the active catalog; 2. stage generation `N+1`, its encrypted objects, undo information, and exact commitment in a durable `PREPARED` namespace; 3. sync the complete prepared namespace without exposing its work; 4. ask the independent anchor to advance from the exact accepted generation and commitment to `N+1` and the new commitment; 5. receive and verify one anchor receipt bound to the instance, generations, old commitment, and new commitment; 6. atomically select `N+1` as active and persist the receipt; 7. sync the active selector and journal; 8. only then export work or render newly accepted plaintext. The anchor operation is compare-and-advance, not an unchecked write. It must reject a wrong old generation, wrong old commitment, repeated alternate next commitment, counter wrap, unauthorized reset, or another instance. An exact retry of an already completed compare-and-advance is idempotent and returns the same authenticated successor state without another increment. ### 9.5 Crash reconciliation At startup: - anchor equals latest finalized local commitment: open normally; - anchor equals the one exact durable prepared successor: finalize it before any other operation; - anchor remains at the finalized predecessor and no external effect was released: discard the prepared successor using its durable staging state; - anchor is ahead without the exact prepared successor: enter `RECOVERY_REQUIRED`; - anchor has the same generation but another commitment: enter `CLONE_OR_TAMPER_DETECTED`; - local state is ahead of, behind, or unrelated to the anchor outside the permitted one-step reconciliation: enter `RECOVERY_REQUIRED`. No user confirmation, clock change, file rename, or import bundle overrides a mismatch. ### 9.6 Anchor assurance levels The registry defines: - `LOCAL_CHAIN`: no external anchor and no complete-rollback claim; - `HOST_BOUND_ANCHOR`: useful against accidental snapshot restore but not a hostile MicroVM host controlling the anchor; - `INDEPENDENT_ANCHOR`: a separate hardware or physically controlled state that is outside the vault and host rollback domain. A TPM 2.0 NV counter is only a candidate building block. The active anchor profile must prove reset authorization, endurance, atomic crash behavior, binding between generation and commitment, device replacement, backup, recovery, and denial-of-service behavior. A bare increment command is not by itself the FOG anchor protocol. The anchor has no network interface and receives only its private local instance handle, generation numbers, and opaque fixed-length commitments. It does not receive the commitment body, object catalog, contact, message, capability, application type, plaintext, or vault key. It necessarily observes local anchor-operation count and timing, which remains an endpoint metadata risk. ### 9.7 Database candidate The Linux candidate evaluates one SQLite database with one writer and an exact durability profile. The selected journal mode, synchronization level, filesystem, block device, locking behavior, power-loss assumptions, and backup API become immutable profile inputs. Copying an SQLite main file while a transaction or hot journal exists is not a backup. The implementation uses the reviewed backup API or a fully quiescent profile-specific snapshot and preserves every required journal and metadata file. Database integrity checks do not replace object authentication or an external monotonic anchor. ## 10. Composer Transfer Bundle ### 10.1 Fixed outer header Every Composer bundle starts with this exact 128-byte header: ```text offset length field 0 8 magic 8 2 bundle_format_version 10 1 bundle_kind 11 1 flags 12 4 bundle_profile_id 16 32 network_id 48 32 bundle_nonce 80 8 payload_length 88 4 record_count 92 4 record_table_length 96 32 payload_digest ``` `magic`, version, kind, flags, profile, counts, and lengths have one canonical encoding. `bundle_nonce` contains 256 CSPRNG bits and is unique to the bundle; it is not an identity or protocol replay token. `payload_digest` provides bounded corruption detection and canonical deduplication only. It does not authenticate the producer. ### 10.2 Fixed record header Each record starts with this exact 48-byte header: ```text offset length field 0 2 record_type 2 2 record_version 4 4 flags 8 8 actual_length 16 8 padded_length 24 16 record_id 40 8 reserved ``` The body contains `actual_length` bytes followed by zero padding to `padded_length`. The record table lists exact ordered offsets and types before any body is dispatched. `record_id` is random and bundle-local. Reserved bits, duplicate IDs, overlap, gaps outside canonical padding, non-zero padding, integer overflow, inconsistent lengths, and trailing data reject the complete bundle. Bundles contain no nested bundle, archive, directory, symlink, device node, filesystem image, filename, URI, MIME type, compression stream, or executable metadata. ### 10.3 Bundle kinds The registry defines separate allowlists for: - `RELAY_EXPORT`: committed KEMSphinx submissions and bounded public relay scheduling hints already authorized by the Composer; - `RELAY_IMPORT`: complete signed PKI objects, opaque KEMSphinx replies, conflict evidence, and bounded public relay state; - `CONTACT_EXPORT` and `CONTACT_IMPORT`: one bounded contact card, voucher, or authenticated contact transition; - `RECOVERY_EXPORT` and `RECOVERY_IMPORT`: one encrypted recovery package and its public format metadata; - `UPDATE_IMPORT`: signed release metadata and exact target artifacts handled only by the maintenance environment. Wrong-direction records reject the bundle. `UPDATE_IMPORT` is never parsed by the unlocked ordinary Composer process, and ordinary relay or contact bundles cannot contain an executable target. ### 10.4 Absolute version-1 limits These are parser ceilings, not recommended operational batch sizes: | Item | Absolute limit | | --- | --- | | Outer header | exactly 128 bytes | | Record header | exactly 48 bytes | | Nesting | forbidden | | Relay bundle | 64 MiB | | Relay records | 2048 | | One relay record | 256 KiB | | Contact bundle | 1 MiB | | Contact records | 64 | | Recovery bundle | 64 MiB | | Recovery records | 256 | | Update metadata | 64 MiB | | Complete update bundle | 16 GiB, streamed only | | Update records | 4096 | | Unknown record type or flag | reject complete bundle | FOG-SX and deployment profiles set lower transport and memory limits. An update target is streamed to an inactive verified image and never allocated as one memory buffer. ### 10.5 Authentication ownership The outer bundle is a transport container. Authentication remains owned by each embedded protocol: - PKI objects use authority signatures and monotonic consensus rules; - KEMSphinx replies use their packet, SURB, token, storage, and message authentication; - contact objects use the exact contact-root or voucher signature rules; - recovery objects use the recovery envelope and separately held key; - updates use the release metadata threshold and target hashes. A Composer-relay pairing key MAY authenticate a local bundle envelope to reduce random injection and accidental cross-user delivery. The relay is still untrusted, a pairing MAC is never accepted as message or PKI authenticity, and the pairing handle is not exported into the FOG network. ## 11. Import Processing ### 11.1 Quarantine Raw input first enters a new size-limited quarantine object created with an unpredictable local name and exclusive creation. The decoder streams the input, enforces the outer limit, calculates the digest, syncs the completed object, and closes the input before `fog-compose` can open it. The decoder never extracts files or follows a path supplied by input. Partial, oversized, timed-out, or multiply opened inputs are deleted without entering the vault. ### 11.2 Validation order The Composer: 1. opens the quarantine object read-only without following links; 2. validates exact total size and the 128-byte header; 3. validates bundle direction, network, profile, kind, count, and limits; 4. validates the complete record table and non-overlap before allocation; 5. streams every record through its owning strict parser into staged state; 6. verifies every inner signature, AEAD, hash, token, generation, expiry, and monotonic rule required by that record type; 7. compares conflicting complete PKI views and preserves evidence rather than merging them; 8. computes all cross-record and cross-protocol state transitions; 9. commits import digest, deduplication, new protocol state, inbox, and any resulting outbox through Section 9; 10. only after final commit and required anchor advance, releases plaintext or marks resulting work exportable; 11. destroys staged plaintext and expires the quarantine object. One invalid critical record rejects the complete bundle. The parser does not continue in order to collect attacker-selected diagnostic detail. ### 11.3 Duplicate and replay handling The Composer stores a keyed local import identifier derived from the complete bundle digest and profile. An exact duplicate is idempotent and does not repeat rendering, ratchet advancement, capability advancement, voucher consumption, update installation, or recovery. The bundle identifier is only an outer deduplication aid. Each embedded protocol still performs its own replay and generation checks. Repacking the same records into another bundle cannot bypass those checks. ### 11.4 Failure privacy Detailed failure remains local and bounded. The Composer does not automatically export a parse error, invalid-contact error, decryption error, missing-message error, stale-state error, or update-verification oracle. The UI maps failures to coarse classes such as `INVALID_IMPORT`, `AUTHENTICATION_FAILED`, `STALE_OR_ROLLED_BACK`, `RESOURCE_LIMIT`, `RECOVERY_REQUIRED`, and `UNSUPPORTED_PROFILE`. Secret values and attacker bytes are not copied into diagnostics. ## 12. Export Processing ### 12.1 Export transaction For every export generation, the Composer: 1. selects only committed eligible outbox objects under the active schedule; 2. validates their protocol profile, lifetime, retry, geometry, and state; 3. generates any fresh KEMSphinx, SURB, route, entry, rendezvous, and reply material required for this network transmission; 4. stages the exact immutable bundle, random bundle nonce, record table, digest, export generation, and outbox transitions; 5. commits all state and advances the required external anchor; 6. creates a new export spool object with exclusive creation; 7. writes, syncs, seals read-only, and reopens the spool object to verify its exact bytes and digest; 8. only then authorizes the export encoder to transmit that one object. A crash before step 5 creates no exportable bytes. A crash after step 5 recovers the exact committed bundle. A crash during spool creation rebuilds only those same committed bytes and does not advance a ratchet, capability, or packet generation again. ### 12.2 Duplicate physical export Copying or replaying one already sealed bundle can cause duplicate relay submission. Bundle, packet, courier, storage, and message deduplication remain required. The Composer never assumes physical transfer occurred merely because it authorized the encoder. If the outcome is unknown, later retry creates the fresh outer packet material required by the owning packet and storage profiles from already committed inner state. It does not reconstruct an end-to-end message envelope or reuse a single-use reply secret contrary to those profiles. ### 12.3 Export contents Relay-facing export MUST NOT contain: - plaintext, local UI strings, application names, contact labels, drafts, or message history; - long-term user signatures over the bundle, stable Composer instance IDs, or vault generations; - message, session, capability, box, or receipt identifiers outside their required opaque cryptographic layer; - private PKI, release, recovery, backup, state, or transfer keys; - filesystem paths, usernames, hostnames, locale, timezone, device model, or software diagnostics. Export size class and timing remain observable to the physical transfer path and blind relay. Cover and scheduling profiles, not the bundle container alone, govern those metadata claims. ### 12.4 Spool retention An opaque export spool item remains until one of: - an explicitly lower-assurance local transfer profile returns an authenticated acceptance permitted by that profile; - a bounded re-export window ends; - the owning protocol produces authenticated terminal evidence; - the operation is explicitly cancelled before a forbidden state transition; - recovery freezes the entire instance. The high-assurance simplex profile has no automatic receiver acceptance path. Its Composer therefore relies on bounded spool retention and later owning- protocol evidence, not an FOG-SX acknowledgment. Deletion of a spool item never rewinds its protocol state. Sensitive reply material and ephemeral packet keys follow their shorter owning lifetimes. ## 13. Backup and Recovery ### 13.1 Recovery goals Composer recovery is designed to preserve the minimum long-term authority needed to reestablish an identity and verify known contacts. It is not a transparent snapshot restore and does not promise recovery of undelivered messages, forward-secret message keys, live storage positions, consumed prekeys, pending acknowledgments, or current network work. The default `IdentityRecoveryPackage` MAY contain: - the FOG network ID and genesis trust-anchor material; - the long-term pairwise or accountless identity roots explicitly selected for recovery; - contact public roots, verified fingerprints, and verification status; - encrypted local contact labels when the user includes them; - release trust roots and minimum accepted release version; - the latest public PKI checkpoint and consistency metadata as a recovery starting point, never as permission to roll backward; - identity-generation and recovery-package sequence metadata; - a declaration that every messaging session and storage stream must be replaced before use. The default package MUST NOT contain live ratchets, chain keys, message keys, skipped keys, one-time prekeys, active storage read or write capabilities, outbox ciphertexts, SURBs, reply tokens, pending packets, deduplication windows, transfer-pairing keys, local anchor credentials, or an active Composer instance ID. ### 13.2 Recovery envelope The recovery plaintext is one canonical bounded object with an explicit format version, network, identity set, package sequence, creation release, key profile, content allowlist, and restore policy. It is padded and authenticated under a random recovery data key. That random key is wrapped by a distinct recovery key hierarchy. Recovery key material is stored separately from the recovery ciphertext. A recovery passphrase, if supported, uses its own profile-fixed memory-hard KDF, salt, and parameters and does not reuse the live-vault keyslot or passphrase verifier. Recovery filenames, QR labels, media labels, and transport checksums are not authenticated metadata. Every field that affects identity, version, content, or restore behavior is inside the authenticated envelope. ### 13.3 Recovery export Recovery creation requires explicit local user confirmation and a dedicated ceremony outside normal message export. The Composer: 1. validates that the selected identities and contact metadata are eligible; 2. generates a fresh recovery package ID and random data key; 3. constructs and encrypts the exact canonical package; 4. atomically records the package sequence and digest in live state; 5. advances the external anchor when required by the active profile; 6. exports ciphertext and recovery key material through distinct controlled paths; 7. verifies one complete test decryption before reporting success; 8. erases transient recovery plaintext and wrapping material. Normal relay export, contact exchange, and FOG-SX network work MUST NOT carry a recovery package or recovery key. ### 13.4 Restore Restore occurs into a fresh verified Composer image and a newly initialized vault with a new random `composer_instance_id`, vault key, object key epochs, transfer-pairing keys, and local anchor state. After verifying and decrypting the package, the new Composer: - imports the allowed identity roots and contact verification history; - refuses any recovered PKI, release, or rollback state lower than the trusted state embedded in the verified recovery image or independent anchor; - marks every historical messaging session and storage stream `RECOVERY_REQUIRED` or `CLOSED`; - creates no message, packet, prekey, voucher, read, write, or ACK from restored mutable protocol bytes; - obtains a current PKI view through the full long-offline consistency path; - verifies the current release chain and rollback floor; - uses the recovered identity authority to authenticate fresh contact-session and storage-stream transitions; - warns that contacts may need independent fingerprint confirmation when compromise, identity change, or ambiguous recovery is suspected. The old instance is not automatically revoked merely because a new vault was created. If the old device may still operate, identity compromise and clone procedures apply and contacts require an authenticated identity transition. ### 13.5 Full-state archives A routine full copy of a live Composer vault is forbidden as a resumable backup. A profile MAY create a separately encrypted forensic archive for disaster analysis, but it is marked `NON_RESUMABLE`, contains no unlock or anchor key beside its ciphertext, and cannot be opened as an active vault. Copying a VM private volume, SQLite file, LUKS device, portable state partition, or suspended memory image is not recovery. Such a copy is clone evidence and freezes all live state if discovered. ### 13.6 Deletion limits Deleting an object key or recovery key can make surviving ciphertext inaccessible under the stated assumptions. It does not prove removal from RAM, flash translation layers, snapshots, filesystem journals, controller caches, old media, recipient devices, or adversarial copies. The UI describes deletion as local best effort with explicit retained-copy limits. It never reports cryptographic erasure as physical proof. ## 14. Offline Update Verification ### 14.1 Separation of authority Release authority is separate from user identity, FOG-PKI authority, node, relay, storage, backup, recovery, and Composer state authority. Runtime images contain only public release roots and current trusted metadata, never a release signing key. An update distributor, relay, mirror, removable medium, QR label, or package manager is an untrusted transport. It cannot authorize code. ### 14.2 Update candidate `FOG-COMPOSER-CANDIDATE-UPDATE-TUF-1` evaluates an exact future TUF revision and maintained client implementation. The candidate uses distinct threshold roles for root, targets, snapshot, and timestamp metadata, consistent target hashes and lengths, version monotonicity, expiry, and sequential root rotation. The selected release profile MUST pin: - exact TUF specification and implementation revisions; - root, targets, snapshot, timestamp, and delegated-role thresholds; - key algorithms, key IDs, role separation, and offline-key requirements; - canonical metadata encoding and absolute size limits; - trusted-time and maximum-clock-uncertainty behavior; - target naming, architecture, deployment profile, and compatibility fields; - installed-version, minimum-version, revocation, and rollback-floor rules; - root rotation, repository recovery, and emergency response ceremonies. TUF metadata transport security is not release authenticity. A valid older but unexpired view is still subject to the Composer's highest accepted versions, rollback floor, and freeze policy. ### 14.3 Update bundle validation The maintenance environment: 1. verifies the fixed Composer `UPDATE_IMPORT` framing and streaming limits; 2. starts from the currently trusted release root stored in monotonic state; 3. applies every intermediate root version sequentially with the required old and new thresholds; 4. verifies timestamp, snapshot, targets, delegations, versions, expiry, hashes, lengths, and consistent-snapshot rules; 5. rejects metadata below any locally trusted version or rollback floor; 6. verifies target architecture, deployment profile, state-schema range, boot profile, and hardware requirements; 7. streams each target to inactive storage while hashing and enforcing its exact declared length; 8. verifies the complete inactive image and its signed boot and root digest; 9. records a signed-metadata-bound prepared boot transition without opening the Composer vault; 10. activates the new boot slot for one bounded trial; 11. lets only the verified target image, after explicit user unlock, validate the prepared transition, migrate state if required, commit the installed release and rollback floor through Section 9, and mark boot success. No target is executed, mounted writable, or parsed by its own code before its owning metadata, hash, and length have been verified. ### 14.4 Trusted time and freeze Update expiry requires a trusted update-start time with a stated uncertainty. File modification times, removable-media clocks, relay timestamps, target timestamps, HTTP headers, and unauthenticated user input are not trusted time. If time uncertainty prevents expiry validation, the Composer stops update installation and invokes a separately authenticated time-recovery ceremony. It does not disable expiry. Highest accepted metadata versions reduce rollback risk but do not independently prove that a distributor has supplied the latest release. ### 14.5 A/B image and boot failure The Portable candidate uses inactive-image installation and a bounded boot trial. Automatic fallback is permitted only to an image still above the authenticated rollback floor and not explicitly revoked. If the new image and the prior image are both unauthorized or incompatible, the system enters signed recovery media rather than booting an older vulnerable release. A boot-success marker is not trusted if it can be rolled back without the profile's monotonic control. ### 14.6 State migration A release declares the exact source and target vault schema range. Migration: - runs in a dedicated mode of the verified target image after explicit user unlock; the maintenance update verifier never receives vault keys; - runs offline with network and ordinary import/export disabled; - opens the old state through the old reviewed reader and writes a separately staged new catalog; - authenticates and validates every source object before transformation; - rejects unknown-critical object types and counter or size overflow; - preserves no old live-state copy as a resumable second Composer; - commits the new schema and release version through Section 9; - cannot be reversed after external effect or anchored finalization. If migration fails before finalization, the old still-authorized image and state remain active. If the anchor or state has advanced but reconciliation cannot prove the exact prepared migration, recovery is required. ### 14.7 Emergency response Emergency metadata may revoke a target or raise the minimum release version, but uses the normal authenticated root and delegated authority rules. There is no unsigned rescue build, universal operator password, hidden update URL, network bypass, or local force-install flag. ## 15. PKI, Time, and Monotonic Consumer State ### 15.1 PKI import The Composer persists the complete trusted PKI consumer state required by `FOG-PKI` in the same security-critical transaction as any route, profile, message, or storage work that first depends on it. It accepts a newer view only after validating: - network and trust-anchor identity; - canonical full consensus and independent authority quorum; - sequential authority-set transitions; - epoch, validity, freshness, and clock uncertainty; - archive inclusion and append-only consistency from the stored checkpoint; - active packet, wire, messaging, storage, entry, cover, and Composer profiles; - complete current storage manifests and key windows; - split-view, equivocation, and conflict evidence. A bundle containing multiple valid conflicting views freezes affected work and preserves evidence. It does not select the numerically highest view or merge descriptors. ### 15.2 Offline time The Composer maintains separate notions of: - monotonic process time for one boot session; - authenticated protocol epoch and version progression; - profile-approved civil time with explicit uncertainty; - release-metadata update-start time. An RTC can be a candidate input but is not trusted merely because it is battery-backed. Clock rollback, implausible jump, uncertainty overflow, or disagreement with authenticated epoch bounds stops new time-sensitive work. The UI permits a user to report the clock problem, not to declare an arbitrary time valid. Exact offline time recovery remains a profile activation gate. ## 16. Native Applications and Safe Rendering ### 16.1 Common application boundary `fog-drop`, `fog-mailbox`, and `fog-im` are modules inside the Composer trust domain. They receive authenticated bounded application frames only after messaging, storage, import, and state commit. They do not parse raw transfer, KEMSphinx, storage, or ratchet bytes. Applications cannot select packet geometry, route length, storage replica count, retry timing, cover class, cryptographic primitive, update channel, or external renderer. ### 16.2 Initial content profile The initial content profile supports bounded UTF-8 plain text with canonical normalization rules and a small fixed set of non-active local presentation attributes. It rejects invalid UTF-8, control-character abuse, bidirectional text policy violations, oversized grapheme sequences, unknown critical fields, and active content. No content triggers: - network or filesystem access; - contact creation or verification change; - command execution, URL opening, media decoding, font installation, or external process launch; - automatic reply, read receipt, typing indicator, preview, or notification containing plaintext outside the unlocked Composer; - import, update, recovery, profile, or key transition. ### 16.3 Local UI status The UI distinguishes at least: - locally queued but not exported; - exported with unknown relay outcome; - courier accepted, replica quorum committed, and degraded storage; - authenticated recipient Composer commit acknowledgment; - expired or uncertain delivery; - contact fingerprint verified, unverified, changed, or recovery pending; - PKI fresh, stale but valid, expired, split, or recovery required; - vault locally consistent, externally anchored, unanchored, or mismatched; - installed release verified, update available, revoked, or time-blocked. It never labels courier acceptance as delivery, replica commit as human read, encryption as anonymity, networklessness as host integrity, or local hash-chain verification as complete anti-rollback. ### 16.4 Plaintext lifetime Plaintext is decrypted only for the active operation or visible bounded view. Search indexes, caches, undo history, previews, clipboard, recent-file lists, accessibility bridges, screenshots, and notifications are disabled unless a later profile explicitly bounds and protects them. Lock, suspend, inactivity timeout, display detachment, update mode, integrity failure, anchor failure, or fatal parser fault closes views and erases active keys and staging memory on a best-effort basis. ## 17. State and Key Lifecycle | Material | Owner | Persistence | Transition or destruction | | --- | --- | --- | --- | | Human unlock secret | user | never stored as plaintext | replace through authenticated keyslot rewrap | | Unlock KDF output or KEK | Composer unlock transaction | memory only | erase after vault key unwrap or lock | | Random vault key | one Composer instance | wrapped keyslot plus unlocked memory | rotate by profile; never export or identity-recover | | Object key epoch | Composer vault | wrapped or derived encrypted state | rotate by object class; retain only for live objects | | Local state-authentication key | Composer vault | one instance | erase on instance retirement; never use for backup | | Composer instance ID | Composer vault | lifetime of one active instance | replace on restore or reinitialization; never export | | State commitment chain | Composer vault | permanent for one instance | preserve until explicit retirement | | External anchor key or handle | independent anchor domain | profile-specific monotonic lifetime | controlled replacement requires recovery ceremony | | Import quarantine bytes | sandbox and Composer | one bounded import | delete after commit or rejection | | Import dedup identifier | Composer vault | maximum bundle replay window | expire by authenticated profile, not input time | | Export spool ciphertext | export encoder and Composer | bounded transfer or retry window | delete without rewinding protocol state | | Transfer-pairing key | Composer and local blind relay boundary | local pairing generation | rotate on pairing compromise; never authenticate messages | | Recovery data key | recovery transaction | package creation or restore only | erase after verified wrap or unwrap | | Recovery wrapping key | user recovery domain | separate from package ciphertext | rotate by creating and testing a new package | | Identity root in recovery | encrypted recovery package | explicit identity lifetime | revoke or replace through identity protocol after compromise | | Live ratchet and capability state | current Composer instance only | encrypted mutable state | freeze on restore, clone, rollback, or compromise | | Release trust roots | Composer maintenance state | sequential root lifetime | rotate only through authenticated old and new thresholds | | Installed-release floor | Composer and external anchor where claimed | monotonic installation lifetime | only increase through authenticated metadata | | Temporary plaintext and message keys | Composer process | one transaction or view | best-effort erase immediately after owning commit or close | Purpose-separated keys MUST NOT be converted, copied, or relabeled to satisfy a different row. ## 18. Failure and Recovery States ### 18.1 Minimum vault states The Composer state machine includes: - `UNINITIALIZED`: no identity or mutable vault exists; - `LOCKED`: image verified, vault keys absent from active memory; - `UNLOCKING`: bounded keyslot and state verification in progress; - `READY_UNANCHORED`: locally consistent, no complete-rollback claim; - `READY_ANCHORED`: local and independent anchor state match; - `IMPORT_STAGED`: one bounded import is parsed but has no effect; - `EXPORT_PREPARED`: exact export state is durable but not yet released; - `UPDATE_STAGED`: inactive release verified but not activated; - `RECOVERY_REQUIRED`: ordinary protocol actions forbidden; - `CLONE_OR_TAMPER_DETECTED`: local and anchor history conflict; - `LOCKDOWN`: integrity, runtime, or secret-lifetime policy failed; - `RETIRED`: no further use of instance keys or live protocol state. ### 18.2 Failure table | Condition | Required response | | --- | --- | | Boot signature or root-image verification failure | stop before vault unlock | | Vault keyslot authentication failure | generic local failure, no object parsing | | Object AEAD or canonical encoding failure | quarantine object or vault, no partial use | | Database integrity or durability uncertainty | lock and enter authenticated recovery | | Local commitment-chain break | freeze all mutable protocol state | | External anchor mismatch | `RECOVERY_REQUIRED` or `CLONE_OR_TAMPER_DETECTED` | | Missing anchor in an anchor-required profile | no export, render, or state advancement | | Malformed or oversized import | reject complete bundle and delete quarantine | | One invalid critical bundle record | reject complete bundle | | Duplicate valid import | idempotent success without repeated effect | | Export spool partial write | rebuild exact committed bytes or discard partial file | | PKI split or consistency failure | freeze new network work and preserve evidence | | Clock uncertainty outside profile | stop time-sensitive PKI and update acceptance | | Update signature, expiry, hash, length, or version failure | retain verified non-revoked version or stop | | Migration failure before finalization | keep old still-authorized state and image | | Migration or anchor ambiguity after advance | recovery required, no downgrade | | Recovery package failure | no identity import and no detailed oracle | | Lock, suspend, display loss, or runtime policy failure | erase active keys best effort and stop | User-visible diagnostics remain local, coarse, and free of attacker-controlled secret bytes. A failure never opens networking, mounts an internal disk, enables a general shell, skips verification, accepts an older profile, or exports an automatic error. ## 19. Resource Limits and Abuse Resistance Every active Composer profile defines lower limits within the absolute bundle ceilings for: - vault objects, object bytes, transaction objects, and staged generations; - identities, contacts, sessions, prekeys, skipped keys, capabilities, and storage streams; - drafts, messages, fragments, reassembly groups, history, and attachments; - protocol outbox, inbox, deduplication, ACK, receipt, retry, and tombstone state; - quarantine items, bundle bytes, record count, parser depth, and parse time; - export spool items, bytes, re-export attempts, and retention; - PKI objects, consensus views, proof nodes, manifests, conflicts, and history; - update metadata, targets, stream bytes, staging space, and migration work; - recovery identities, contacts, labels, package bytes, and attempts; - Argon2 memory, CPU, lanes, attempts, and concurrent KDF calls; - UI text bytes, graphemes, lines, rendering time, and notification queue; - anchor operations, prepared generations, reconciliation attempts, and device timeouts; - memory, file descriptors, processes, threads, temporary files, and disk reserve. Limits are enforced before allocation or expensive cryptography where the owning format permits. Authenticated contacts remain untrusted for resource purposes. A valid signature or ciphertext does not authorize unbounded local storage, rendering, KDF work, or notifications. Disk-full handling preserves the latest finalized catalog and anchor state. The Composer does not evict security-critical replay, ratchet, capability, commitment, or rollback state according to least-recently-used behavior. It stops new work or applies an authenticated retention policy. ## 20. Logging and Local Observability The default release logs only coarse boot, lock, integrity, capacity, and failure-class counters needed to operate the local device. Logs are bounded, stored inside the encrypted vault or volatile memory, and deleted by a fixed policy. The Composer MUST NOT log or export: - plaintext, drafts, rendered content, contact labels, or fingerprints; - private keys, unlock material, recovery keys, capabilities, or ratchets; - message, session, box, receipt, packet, SURB, reply, voucher, or bundle identifiers; - routes, replica selection, entry sets, import timing histories, or per- contact activity; - object ciphertext samples, failed attacker input, decrypted fragments, or detailed cryptographic errors; - filesystem paths containing user identity, hostnames, locale, timezone, or device serial numbers; - state commitments or anchor receipts in a generic support bundle. There is no automatic telemetry, update check, crash upload, or remote diagnostic channel. A manually exported diagnostic report uses an explicit reviewed schema, contains only coarse redacted status selected by the user, and never includes a raw log or vault object. ## 21. Candidate Implementation Profiles ### 21.1 Linux vault candidate `FOG-COMPOSER-CANDIDATE-LINUX-VAULT-1` combines: - an authenticated boot artifact and read-only `dm-verity` root image; - a dedicated LUKS2 mutable volume with Argon2id keyslots; - object-level XChaCha20-Poly1305 authenticated encryption; - one transactional SQLite database with one writer; - immutable import quarantine and export spool files; - disabled network stack, swap, hibernation, core dumps, and active-content desktop services. This combination is a review target, not a composed security proof. LUKS2, dm-verity, AEAD, SQLite, boot firmware, filesystem, storage hardware, and the Composer transaction protocol have different failure and trust assumptions. ### 21.2 Qubes MicroVM candidate `FOG-COMPOSER-CANDIDATE-MICROVM-QUBES-1` evaluates: - a dedicated persistent Composer qube with no NetVM; - an immutable reviewed template or standalone image measurement; - one private encrypted state volume unlocked inside the guest; - exact qrexec policies for bounded import and export services only; - separate untrusted transfer qubes where physical device support requires them; - explicit denial of file copy, clipboard, URL opening, general command, update proxy, audio, camera, block, USB, and arbitrary qrexec services. qrexec is a host-mediated data channel and the Qubes host remains trusted for guest confidentiality and integrity. A host-controlled vTPM is not an independent anchor against that host. ### 21.3 Portable Linux candidate `FOG-COMPOSER-CANDIDATE-PORTABLE-LINUX-1` reuses the Linux vault profile but boots a signed read-only image on dedicated offline hardware. It requires driver removal, internal-disk automount denial, separate RX/TX devices, physical inspection, and a profile-selected independent monotonic anchor for any complete-rollback claim. Secure Boot without a narrowly controlled FOG release root, root-image verification without an authenticated root digest, or a TPM without a reviewed state-binding protocol does not satisfy the complete candidate. ### 21.4 Activation gates Before any candidate receives an active numeric profile, FOG MUST freeze and verify: 1. exact operating system, kernel, bootloader, firmware assumptions, image format, and immutable-root construction; 2. exact LUKS2, Argon2id, AEAD, KDF, hash, database, filesystem, and library revisions and parameters; 3. byte-exact vault object, commitment, bundle, record, recovery, and update serialization; 4. nonce uniqueness, key-purpose separation, wrapping, rotation, and deletion; 5. database atomicity, sync, power-loss, disk-full, corruption, and backup behavior on supported hardware; 6. external-anchor state binding, crash protocol, endurance, reset, clone, replacement, and recovery; 7. exact MicroVM device model and qrexec or equivalent policy; 8. exact Portable driver set, mounts, Secure Boot ownership, dm-verity chain, and physical transfer direction; 9. exact TUF revision, client, metadata encoding, thresholds, trusted time, root rotation, rollback floor, revocation, and offline repository workflow; 10. parser fuzzing, UI rendering, import/export duplication, hostile media, migration, recovery, and update fault injection; 11. reproducible or independently verifiable builds, dependency provenance, release ceremony, and rollback rehearsal; 12. independent endpoint, cryptographic integration, and implementation review before public claims. ## 22. Conformance and Adversarial Tests Before the local PoC, FOG-COMPOSER requires deterministic positive and negative tests for: - image signature, boot argument, root digest, read-only root, and failure before vault unlock; - absence of NICs, network drivers, network syscalls, listeners, proxies, and undeclared devices; - MicroVM clipboard, shared directory, qrexec, device, and guest-agent denial; - Portable radio, internal-disk mount, foreign-filesystem, and directional device denial; - keyslot creation, unlock, wrong secret, rewrap, rotation, and partial header update; - object AEAD, associated data, nonce, padding, generation, key epoch, wrong instance, corruption, truncation, and unknown-critical fields; - atomic messaging, storage, PKI, import, export, and application commits; - every crash point before and after prepared state, anchor advance, finalization, export release, and plaintext rendering; - local-chain rollback, complete coherent rollback, clone, split generation, anchor reset, missing anchor, same-generation conflict, and reconciliation; - exact 128-byte bundle and 48-byte record headers; - every bundle kind, record allowlist, direction, size, count, padding, overlap, gap, duplicate ID, integer overflow, and trailing byte; - malformed QR, FOG-SX, removable-medium, contact, PKI, reply, recovery, and update inputs as data only; - exact duplicate import and export, repacking, reordered records, replay, interrupted transfer, and stale result; - recovery creation, separate-key handling, test decrypt, restore into a new instance, and refusal to resume live state; - rejection of a copied VM volume, database, portable partition, or full-state archive as an active restore; - TUF thresholds, sequential root rotation, expiry, freeze, rollback, fast-forward, mix-and-match, wrong target, hash, length, platform, compatibility, and revocation; - update stream interruption, inactive-image verification, A/B trial, unauthorized fallback, migration failure, and recovery media; - safe text rendering, Unicode edge cases, active content, external resource, notification, clipboard, and parser resource abuse; - disk full, fake-capacity media, I/O error, fsync failure, hot journal, corrupted database, low memory, KDF exhaustion, and anchor timeout; - lock, inactivity, suspend, display loss, update mode, and best-effort key erasure; - absence of prohibited data from logs, crash artifacts, swap, hibernation, temporary files, export, and diagnostics. Testing MUST include parser fuzzing, property tests, transaction fault injection, simulated power loss, race detection, hostile peripheral fixtures, resource exhaustion, cross-version migrations, restore exercises, dependency audits, and byte-identical vectors across independent implementations. Platform evidence MUST distinguish simulator, VM, dedicated offline hardware, and production-profile results. ## 23. Threat and Architecture Traceability | Requirement | Primary controls | | --- | --- | | `ARC-002` | no NIC, no socket service, bounded transfer only, conformance network tests | | `ARC-004` | local vault, messaging, KEMSphinx, storage, and Noise keys remain separate | | `ARC-005` | full PKI verification and monotonic consensus state before route construction | | `ARC-006` | common opaque bundle and packet classes across native applications | | `ARC-007` | explicit vault, object, transfer, backup, anchor, release, and protocol key ownership | | `ARC-008` | exact headers, absolute parser ceilings, object and transaction bounds | | `ARC-009` | fail closed on image, state, anchor, import, PKI, update, and recovery uncertainty | | `IF-01` | committed opaque export only, sealed spool, no stable Composer signature | | `IF-02` | hostile quarantine, complete parsing, owning inner authentication, atomic import | | `IF-12` | threshold release metadata, target verification, inactive image, rollback floor | | `TM-PKI-02` | persisted consensus and checkpoint monotonic state, split freeze, external anchor where claimed | | `TM-ENDPOINT-01` | MicroVM and Portable profiles, immutable image, encrypted vault, no network or active content | | `TM-ENDPOINT-02` | separate bounded binary directions, sandboxed decoder, no archive or filesystem import | | `TM-ENDPOINT-03` | separate recovery hierarchy, identity-only default, no stale live-state resume or file-copy multi-device | | `TM-APP-01` | authenticated commit before bounded plain-text rendering, no automatic actions | | `TM-OPS-01` | no telemetry or secret-bearing log, crash, support, or export artifacts | | `TM-SUPPLY-01` | separate release authority, TUF candidate, immutable verified images, provenance gates | | `TM-CRYPTO-01` | random data keys, memory-hard unlock, purpose-separated object keys, lifecycle table | | `TM-CRYPTO-02` | immutable profile registry, no runtime crypto selection or downgrade | | `TM-AVAIL-01` | absolute limits, staged streaming, bounded KDF and parser work, disk reserve and safe stop | ## 24. Claims Deliberately Withheld FOG-COMPOSER does not yet establish: - protection of plaintext or keys from a compromised unlocked Composer; - protection of a MicroVM from its malicious host or hypervisor; - detection of a complete coherent rollback without an independent anchor; - safe binding or endurance of a concrete TPM, secure element, or token; - secure deletion from every RAM, flash, snapshot, backup, or physical copy; - a final operating system, database, AEAD, KDF, filesystem, or library; - correctness of firmware, Secure Boot implementation, peripheral, DMA, or hardware randomness; - that network driver removal eliminates every physical or side channel; - that TUF alone proves the distributor supplied the latest update while the Composer is isolated; - transparent recovery of forward-secret sessions, pending delivery, or live capability streams; - safe multi-device state, cloud recovery, or server-held recovery secrets; - production security from a Qubes fixture, portable USB prototype, or local fault test. ## 25. Open Dependencies The structural Composer contract is fixed, but these dependencies remain open before an active profile or implementation: - exact supported Linux distribution, kernel, boot, immutable-image, filesystem, and hardware profiles; - exact LUKS2, Argon2id, AEAD, KDF, database, and secure-memory selections; - byte-exact vault, state commitment, bundle records, recovery envelope, and update metadata integration; - an independent monotonic-anchor construction with proven state binding, crash reconciliation, endurance, replacement, and recovery; - a trusted offline-time and clock-uncertainty recovery ceremony; - exact Qubes version, qube type, template lifecycle, qrexec services, and host policy for the MicroVM candidate; - exact Secure Boot root ownership, firmware requirements, driver manifest, RX/TX devices, and media policy for Portable; - the full `FOG-UPDATE` repository, signing, provenance, reproducible-build, revocation, and recovery contract; - activation of one byte-exact numeric `FOG-SX` joint profile after its fixed structural frame, object, padding, parser, no-ACK, and physical-direction contract passes FEC, implementation, license and IPR, resource, vector, hardware, and independent review; - entry capsule and return-rendezvous bundles needed for complete relay import/export; - identity compromise, revocation, contact recovery UX, and fresh-session transition vectors; - future native attachment, full-text search, group, and multi-device protocols. No implementation convenience may silently resolve these dependencies. ## 26. Primary References - FOG threat model: `FOG-THREAT-MODEL.md` - FOG architecture: `FOG-ARCHITECTURE.md` - FOG public key infrastructure: `FOG-PKI.md` - FOG wire protocol: `FOG-WIRE.md` - FOG Sphinx profile framework: `FOG-SPHINX-PROFILES.md` - FOG messaging protocol: `FOG-MESSAGING.md` - FOG storage protocol: `FOG-STORAGE.md` - FOG simplex transfer protocol: `FOG-SX.md` - Qubes OS qrexec architecture: - Qubes OS device handling: - Linux kernel `dm-verity` documentation: - cryptsetup and LUKS2 specification resources: - RFC 9106, Argon2 Memory-Hard Function: - libsodium XChaCha20-Poly1305 documentation: - SQLite atomic commit documentation: - SQLite database-corruption and backup guidance: - Trusted Computing Group TPM 2.0 Library specification: - The Update Framework specification and security model: These references supply maintained formats, mechanisms, and failure lessons. They do not make the combined FOG endpoint secure by inheritance. FOG still requires exact profiles, integration analysis, hardware measurement, vectors, fault testing, build provenance, update and recovery rehearsal, and independent review.