QERYX COMING SOON
OBSERVATORY

10.0 MixcoatlDB

A database that encrypts before it stores.

MIXCOATLDB Coming soon

A sovereign database engine that encrypts before it stores. The carrier ledger holds ciphertext; plaintext never reaches it.

Hand it a plaintext row. The append path refuses.

The encryption boundary

Your messages are sealed on your device, under Q-Ratchet, before they travel. The Mixcōātl carrier ledger sits behind that boundary: it receives ciphertext envelopes and opaque routing identifiers, and its write path has no plaintext column to fill. Applications never touch the storage substrate directly — every write crosses the carrier API, and the substrate can be swapped without the invariants moving.

Envelope shape
every INSERT requires (ciphertext, aad) — Q-Storage-Carrier
Routing
opaque UUIDs; cleartext participant identifiers quenched (migration 102)
At-rest layer
FSOR envelope wrap, HKDF-SHA512 per conversation epoch (spec §8)

The five ledger invariants

The ledger is defined by what it enforces, and each invariant is a named contract you can check against the source.

Q-Storage-Carrier
the append path refuses plaintext; INSERTs carry the (ciphertext, aad) shape
Q-MetaSilence
aggregate-only access counters; no per-row access logs
Q-FS-AtRest
at-rest keys rotate on a 24-hour cadence with re-encryption of prior WAL
Q-PQ-Audit-Log
operations signed under ML-DSA-87 and anchored to the transparency log
Q-Sovereignty-Lock
replication to foreign-cloud IP ranges is refused

Delivery, then deletion

When your recipient acknowledges a delivery, the relay marks the row deleted and hard-deletes it after a short grace window; a group message, sealed to each member by default, and a message read with Stealth Mode on or read receipts off wait for the offline horizon. Destroying a conversation deletes the rows the relay can tie to it. A one-to-one message, sealed by default, names neither its sender nor its conversation, so the destroy does not reach it: it leaves on the same clock as any message. The photos and files a conversation carried stay stored apart until their own expiry, unless their sender deleted them sooner. Nothing on the volume is overwritten. A row that arrived on the REST send lane also sat in an at-rest envelope, so once its conversation is destroyed, its write-ahead and backup residue stays under a retired epoch, whose key re-derives only from the operator master; rows from the other lanes rest on end-to-end encryption alone. FSOR wraps no file, and any server-side encryption a file’s store adds is under a key the operator holds, so against the operator a file rests on its end-to-end seal alone.

Undelivered messages queue with routing metadata under the published retention ladder — the server cannot read them, and it does not keep them longer than the ladder allows.

The append path has no plaintext column to fill.

Q-Storage-Carrier invariant

Read the metadata engine in the source

backend/src/privacy.rs
/// Daily-rotated 32-byte salt for IP hashing. Rotation key is the UTC
/// calendar day at the time of `hash()`, so a query crossing midnight
/// will see two different hashes for the same IP. That is the property
/// that breaks long-window IP correlation in a forensic dump.
fn derive(base: &[u8; 32], day: NaiveDate, ip: IpAddr) -> String {
    let mut h = Sha256::new();
    h.update(b"QERYX-Q-MetaSilence-IP-v1");
    h.update(base);
    h.update(day.year().to_le_bytes());
    h.update((day.month() as u32).to_le_bytes());
    h.update((day.day() as u32).to_le_bytes());
    match ip {
        IpAddr::V4(v4) => {
            h.update(b"v4");
            h.update(v4.octets());
        }
        IpAddr::V6(v6) => {
            h.update(b"v6");
            h.update(v6.octets());
        }
    }
    let digest = h.finalize();
    hex::encode(&digest[..16])
}

Check every parameter against the file it came from

Ledger parameters — values from source
ParameterValueSource
Envelope shape (ciphertext, aad) required at INSERT Q-Storage-Carrier
Access counters aggregate-only, no per-user labels backend/src/privacy.rs
IP handling hashed under a daily 32-byte salt, 128-bit output backend/src/privacy.rs
Timestamp precision quantized to 5-minute windows privacy.rs::quantize_to_window
Delivered-row purge 10-minute grace, then hard DELETE backend/src/handlers.rs
Audit signatures ML-DSA-87 (FIPS 204), log-anchored Q-PQ-Audit-Log
At-rest rotation 24-hour cadence, prior WAL re-encrypted Q-FS-AtRest
Replication policy foreign-cloud IP ranges refused Q-Sovereignty-Lock

01

plaintext columns on the ledger's write path

10 min2

hard-purge grace for delivered rows (default)

5 min3

the finest timestamp the ledger will persist

Seize the ledger. Read what it yields.

Category classes only — never named products
QERYX Mixcōātl Classical app database Managed cloud DB
Real workloads
Full database seizure Ciphertext + routing metadata Plaintext rows are common Plaintext + provider access
Insider read No plaintext path exists DBA sees all Provider and DBA see all
Access-pattern logging Aggregate-only counters Per-row logs Provider telemetry
Replication policy Sovereignty lock — refused ranges Anywhere Provider-controlled
Erasure Hard DELETE; REST-lane residue under a retired epoch DELETE plus residue Provider snapshots persist

Ask what a warrant on this ledger reaches.

What does the ledger hold?

Ciphertext envelopes, opaque routing identifiers, and epoch commitments. There is no plaintext column anywhere in the schema's write path.

Sealed envelopes plus routing metadata under the published retention ladder. Content requires breaking both X25519 and ML-KEM-1024.

It is a sovereign ledger abstraction with its own invariants and API. Applications never touch the storage substrate directly, and the substrate can be swapped without the invariants moving.

Application code, through the carrier API only — and the audit log of operations is signed under ML-DSA-87 and externally anchored.

A backup holds what the live tables held when it was taken: end-to-end ciphertext beside the routing columns. A REST-lane row in it also sits in its at-rest envelope, and once its conversation is destroyed that epoch opens only for someone holding the operator master.

Security overview Read the docs