Skip to content
VERASPEC
Repository
ADR-0009Recorded

Redaction reaches derived artifacts and non-metadata channels

Status: Accepted — 31 August 2026 (owner hardening directive, 30–31 August repository audit; drafted and implemented in the same session under that directive — see Consequences for the review posture). Drafted at standards/ver/1.1-draft/VER-1.1-draft.md §5.4 and §5.5; profile rule VER1011; wire duties in §14.5/§14.7 and the draft lexicons. Applies only to Records declaring ver_version: "1.1"; VER 1.0.x Records are unaffected in perpetuity.

Context

ADR-0006 decided what a redaction is: a REQUIRED state, a commitment where one is possible, a prohibition where one is not, and a §5.3 construction whose framed, salted preimage exists so that a withheld value cannot be confirmed by dictionary attack. E15 decided where a redacted value must not remain: a raw segment still containing it, with omission as the only remedy.

Both decisions are metadata-plane machinery, and the 30–31 August audit demonstrated that a removed value survives the machinery through channels neither decision reaches:

  • A contextual embedding computed from the redacted text. A caption redacted from the normalized view with a proper commitment can still travel as an embeddings[] entry whose source.class is caption_human. Vector inversion recovers an approximation of the text; the redaction is annotated, not performed. Nothing in the standard, the schema, or the profile connected metadata.redactions[] to embeddings[].
  • source.text_sha256 as a confirmation oracle. The member is a REQUIRED, unsalted, undomained SHA-256 of the source text, one JSON member away from a commitment construction whose entire design (§5.3: domain tag, 8-octet framing, ≥128-bit unique salt) exists to prevent exactly that oracle. A challenger holding a candidate caption tests it against text_sha256 for free.
  • A fused vector mixing a contextual input escapes even a source-class-keyed rule, because the leak is one recipe hop away.
  • Non-metadata channels: acquisition and chain URIs carrying usernames or tenant paths, actor strings naming people, lineage parents disclosing the existence and location of private assets, C2PA certificates carrying signer identity, source_bytes_ref resolving to the unredacted original whose digest E25 binds to content_hash.

Options

(a) Do nothing; document the limits. Rejected: a standard whose redaction chapter can be satisfied while the value ships in a sibling array is the handoff-era defect ("annotated the leak") wearing 1.1 clothing.

(b) Extend the availability machinery to embeddings — an availability state per embedding, a redaction ledger for vectors. Rejected: it doubles the schema surface to express what is, normatively, one sentence — the artifact goes — and invites the same family/field mapping ambiguity a second time.

(c) One normative MUST plus a deliberately partial profile rule. Selected. The Record MUST NOT carry an artifact derived from a value it redacts; the profile enforces the mechanically decidable slice (an exact-field map from redacted normalized keys to contextual source.class values, VER1011) and §15.4 records the rest as a Producer duty no validator can discharge, in the same voice the standard already uses for value-scoped raw carriage.

(d) Enumerate sensitive fields normatively. Rejected for the same reason 1.1 left reason an open string: a closed sensitivity vocabulary is a legal conclusion wearing a schema, and it goes stale the day it ships. Guidance lives in informative §5.5; the normative rules key on what the Producer declared redacted, which the Producer alone decides.

Decision

  1. §5.4 (normative). A Record MUST NOT carry an artifact derived from a value the Record redacts. Named consequences: the derived embedding is omitted (its source block and text_sha256 with it); a fused embedding whose recipe consumed such an input is omitted or recomputed without it; no other member — reason in the ledger and the in-view object included — restates the redacted value or a recoverable transform of it.
  2. VER1011 (error, stage 11, 1.1-draft only). Where a redacted normalized field maps by exact name to contextual source classes (dc:titletitle; dc:descriptiondescription/caption_auto/ caption_human; Iptc4xmpExt:AltTextAccessibilityalt_text), a carried embedding of that class is the mechanically decidable slice of the §5.4 MUST and draws an error. The map is exact-field and deliberately small; growing it is registry-style additive work, never inference.
  3. §5.5 (informative privacy considerations) consolidates what the standard owes its deployers in one place: pixels are not anonymized by metadata removal; the identity tier is a cross-producer correlation surface by design (E27) and content_hash a confirmation oracle for holders of the bytes; a preserved segment is a container (thumbnails, maker notes) and E15's remedy is segment-granular for that reason; URIs, actors, lineage parents, C2PA certificates and JWS headers carry identity; references resolve to the unredacted world and a redacting Record SHOULD NOT carry openly resolvable ones; no conformance claim is a legal-compliance claim.
  4. Wire duties. ext gains the producer-side prohibition the audit found missing (consumer MUST-ignore was never a licence to smuggle): a wire record MUST NOT carry in ext content its privacy mode withholds, the record-plane salt prohibition included. hashes_only extends to tags (content-derived labels are content tier): the array is present (the lexicon requires it) and MUST be empty. The trust-tier vocabulary gains signed_invalid — checked-and-failed is the most security-relevant outcome and had no name — and a retraction reason MUST NOT carry personal data or the retracted content.

Consequences

Good. The redaction chapter's guarantee becomes true: a conformant 1.1 Record that declares a redaction no longer has a sanctioned channel that undoes it. The profile catches the common case (captions/titles/alt text — the classes that exist because text was worth embedding); §15.4 stays honest about the rest. No 1.0.x Record changes meaning; no schema member is added.

Bad. The exact-field map will under-fire — that is its design. A producer using vendor field names for captions evades VER1011 while still violating the §5.4 MUST; the high-trust profile does not change this. ocr_pixels embeddings over values burned into pixels remain out of reach entirely (§5.5's first consideration is the honest statement of why). The fused withdrawal is prose-only: recipes name spaces, not values.

Review posture. This ADR was accepted under the owner's standing hardening directive rather than by a distinct review round, in a repository whose CONTRIBUTING.md warns against resolving decisions by implementation. The distinction is recorded rather than blurred: everything here is 1.1-draft material, ratification-gated like the rest of the draft, and reversing this ADR before ratification costs a supersession note and the removal of one rule, two sections, and one fixture family. An owner who wants the question reopened supersedes this ADR; nothing published moves.

Compatibility. Additive, 1.1-draft only, version-gated in the profile. COMPATIBILITY.md carries the row; the errata ledger carries the audit findings this answers (REV-31 and its neighbours).