Privacy & security
Encryption by default and content-can't-leak invariants, enforced by CI, not by convention.
The rule underneath everything: your content never leaves the system unencrypted, and never leaks into places built for metadata. What makes it more than a policy is that each piece is enforced by an automated check that fails the build.
- Encryption by default. Every content column is encrypted at rest with AES-256-GCM via TypeORM column transformers. CI fails if a new content column ships without one. You cannot forget.
- Telemetry can’t contain content. The event log has a forbidden-key set (
text,body,content,summary_md, and friends) that its properties can never contain, enforced by an exhaustive fixture sweep in CI. The error-tracking scrubber reuses this exact list, so there’s one definition of “content” to keep honest. - Recognition logs are plaintext-free. What gets logged about a capture is its SHA-256, its length, and the first ten characters, validated against a hundred fuzzed inputs.
- Production fails closed. A boot guardrail refuses to start the gateway if the dev auth-bypass flag is set on a host tagged as production, which closed a real header-impersonation hole, rather than a hypothetical one. The servers themselves are keys-only SSH with fail2ban.
There’s also the least glamorous piece: reconciling the LLM providers’ conflicting data-retention claims into one dated, audited posture, because publishing an unverified privacy claim is a legal risk, not a marketing detail. That work lives in launch readiness.