think
16px
820px

Commitment payload formats — decision & shelved designs

Status: one format shipped (payload/commitment.py). This records why, and preserves the
short-codeword alternatives for a future revisit.

Shipped: bound-ordinal commitment @ 64-bit

tag = HMAC(k_epoch, ctx || email || 0x00 || day_be32 || n_be32 [|| 0x00 doc_id])[:5]   # 40-bit tag
codeword = RS(8,5)(tag)                                                                 # 64-bit
  • Traceability, DB-free. Attribution needs only the epoch key + the recipient roster. It survives
    a full database nuke, deleted issuance rows, or a deleted document row. Key and roster live outside
    the app DB by construction (vault/HSM; HR/IdP).
  • n = per-(email, day) issuance ordinal, bound into the tag, not carried. This gives
    per-issuance resolution (which of several copies to the same person that day) for free: with a live
    ledger you recompute over its rows and match instantly; with the DB gone you enumerate
    email × day × n (n is 0..255) and the 40-bit tag still pins the exact issuance. "Bind, don't
    embed," one level deeper than the identity.
  • Floor: decodes a ~one-paragraph excerpt (~9–11 lines / ~64–73 gaps). Below that a paragraph has
    fewer inter-word gaps than the 64-bit codeword needs — an information wall, not a decoder weakness.
  • False-match (DB-gone worst case): roster × days × n / 2^40. For 100 × 1000 × 256 ≈ 2.6e7,
    that is ~2e-5. The forensic search is a rare offline operation; the 256× from enumerating n is
    irrelevant to that.

Shelved: short codewords (Hybrid @48 / @32)

To attribute a sub-one-paragraph excerpt you must shrink the codeword, which shrinks the tag:

format codeword min lines (real doc) payload split DB-free fallback
commitment @64 (shipped) 64-bit ~9 40-bit tag yes (~2e-5 false)
Hybrid @48 48-bit ~6 ~12b seq + ~12b tag no — 12-bit tag → ~24 false matches over 1e5 candidates
Hybrid @32 32-bit ~4 ~16b seq+tag no

The short formats reach smaller excerpts (measured 9 → 6 → 4 lines) but only because a ledger
resolves the identity and the tiny tag merely confirms the one name it supplies (a 12-bit tag
confirming a single candidate is wrong 1-in-4096 — fine). With the DB gone there is no name to
confirm, and the tag is far too short to identify anyone against a roster. The short mark dies with
the DB — inverting the survivability premise this whole design exists for.

Why not ship them alongside as an option

  1. A format is a permanent decode obligation. Marks sit in leaked documents for years; every
    format ever shipped must be decoded forever.
  2. A weak format weakens the whole decoder. A leaked excerpt does not announce its format, so
    the decoder must try them all. Adding a 16-bit-tag format means every decode of every artifact
    also runs a weak-tag search — importing that false-match risk system-wide, onto documents that were
    marked with the strong format.

That cost is real and permanent; the gain is ~3 lines. Not worth it by default.

When to revisit / better alternative

If genuine sub-9-line attribution is ever needed, prefer a second carrier axis (more bits per
line without shrinking the tag) — e.g. combine the word-gap carrier with a sub-line baseline channel —
over a short codeword. If a short format is truly required, scope it as an explicit
per-classification setting clearly labelled as trading away DB-free recovery, composable with any
mode — never as the default and never as a fourth mode.