Skip to main content

ADR-0011: Default retention and evidence profile

Status: Accepted · 2026-07-14

Decision

Default profile = minimized evidence (handoff §4.1):
  • Persisted: source IDs/versions, safe metadata, label GUID state, normalized permission summaries, activity aggregates, exact + similarity fingerprints, keyphrases/detector hits, bounded redacted excerpts (default ≤ 240 chars per evidence item, ≤ 3 excerpts per asset version), assertions/decisions/findings/ actions/audit.
  • Not persisted by default: full originals, credentials, unbounded permission expansion, raw prompts/responses.
  • Bounded extracted text IS retained (documented deviation from the handoff’s “complete extracted text: not persisted”): the extractor caps output at 20,000 characters (extract.ts DEFAULT_LIMITS.maxOutputChars) and stores that bounded representation as a sensitive_derivative artifact under the classification_inference + owner_review purpose flags. Why: the product invariant “re-score compatible features without source I/O” requires re-running phrase/dictionary detectors and keyphrase extraction offline, which need a text representation; fingerprints and keyphrases alone cannot satisfy detector re-runs. Follow-up (backlog): envelope-encrypt these artifacts at rest, add per-class TTLs, and offer a metadata-only profile that drops retained text (accepting that a detector-release re-score then requires source re-fetch). This tradeoff is called out in STATUS.md and the threat model.
  • Extraction streams through a per-work-unit scratch directory under data/scratch/ that is deleted on stage completion (success or failure) and on worker startup recovery. (Design intent, not yet exercised: the current build processes bounded content entirely in memory and never writes raw source bytes to disk, so no scratch directory exists — see threat model §4.3. It becomes mandatory when sandboxed rich-format extraction lands.)
  • Every stored artifact row carries use_flags_json (classification_inference, owner_review, search, analyst, evaluation, training, troubleshooting) — absence means not permitted; enforcement in ObjectStore.get requires a purpose.
  • Evidence excerpts are stored encrypted-at-rest by OS/disk in the slice; envelope encryption is a documented follow-up for Azure Blob.
  • Log redaction is default-deny: the logger’s serializer allowlists safe fields; names/paths/URLs/excerpts/hashes/embeddings/prompts/tokens are never logged by default (tested with a log-scan test).

Consequences

  • The “enhanced evidence” profile is schema-ready (data_handling_profile on tenant) but not implemented beyond configuration validation in the slice.
  • Retention sweeps are a scheduled job scaffold with per-artifact-class TTLs.