chore(devstack): activate field encryption + full verification

Summary

Flip craig-cases to ENCRYPTION_MODE=required + provision the key (C4) + reseed, and verify the whole system with encryption genuinely on. This is the LAST child — it depends on C2, C3, C4, C5, C6.

Acceptance criteria

  • craig-cases boots required with the key (fail-closed proves it loads); cargo xtask dev reseed re-seeds keyed.
  • The full pre-push battery green including E2E + performance (the person-suggestions perf scenario exercises the C2 fix).
  • #969 (closed) + #413 (closed) proven on encrypted data (raw-DB envelope assertions).
  • DB spot-check by seeded ID: base64-CGEF envelopes + non-NULL HMACs across all covered columns; post-seed invariant passes.

Notes

Part of the field-encryption epic. Depends on C2, C3, C4, C5, C6.


Re-scoped by ADR-048 (#1004 (closed), 2026-07-10)

ADR-048 (D4) governs this child; see its §Consequences table + the epic plan. Deltas:

  • Coordinated recreation: mount the shared key into cases + seed and up both together, then a full-volume down -v reseed. Recreating a single container out-of-band is unsupported (caught by boot-verify + the seed.sh identity-mismatch fail).
  • Add the craig-cases boot verify-only (D3): recompute the KCV + decrypt the canary; refuse boot on mismatch, or on ciphertext-present-but-lineage-absent (fail closed). This is the shared-binary security control (correct for prod too; only rotation is deferred).
  • Activation correctness is the D6 round-trip, not a post-seed re-probe. Cases boots empty-first (compose: craig-seed depends_on craig-cases service_healthy), then reads the seeded data under the shared key; the round-trip is the activation proof. Boot-verify is the guard for a later restart against persisted data. (No phantom re-probe primitive.)
  • Full pre-push battery incl. E2E + performance; prove #969 (closed)/#413 (closed) on encrypted data as before.

Inherited from #986 (closed) C6 AC-refine (2026-07-13)

  • Negative restart-cases-under-wrong-key ⇒ refuse-boot test — exercises this child's D3 boot verifier (recompute KCV + decrypt canary; refuse boot on KCV mismatch / ciphertext-present-but-lineage-absent). Moved here from #986 (closed) because it requires the C7 boot verifier to exist.
  • Flip both verify-seed call sites (validate devstack phase + pentest CI backstop) from --expect-keyless to --expect-keyed once activation lands; then a plaintext seed fails the keyed assertions.
Edited by CRAIG-Bot-CA