# Diagnostics Redaction Spike Chanora proof-of-concept. **Not product code.** | Field | Value | |---|---| | PoC name | `diagnostics-redaction-spike` | | PoC plan | [`docs/architecture/proof-of-concept-plan.md`](../../docs/architecture/proof-of-concept-plan.md) §2 | | Purpose | Prove redaction of secrets before logs or diagnostic export | | Exit criterion | "Password and identity-secret samples are redacted" | | Authority | `docs/security/diagnostic-redaction-audit-report.md` §2 + §4 + §5; SRS-093, SysRS-152/154/155, SDD §5 | ## What it proves - A typed `RedactionPolicy` carrying: - regex-driven rules (with optional capture-group narrowing so the rule can scrub a value while keeping the surrounding context); - structured-field redaction keyed on case-insensitive name substrings (`password`, `secret`, `token`, …); - bundle-level switches (chat / channel tree default to *excluded*). - A `Redactor` that applies the policy to free text and to a typed `DiagnosticBundle`. - A `KnownSecretRegistry` for *literal* scrubbing — the strongest defence when the host has already loaded the actual secret value into memory. This is what closes the gap that regexes alone cannot fully cover (REDACT-TC-002). - A length cap (`MAX_PROTOCOL_STRING_LEN`) so hostile / oversized protocol strings cannot grow the diagnostic surface (REDACT-TC-009). - UTF-8 preservation for benign multilingual text (REDACT-TC-010 / ADR-008). ## Coverage of the audit-report test matrix All ten REDACT-TC-001..010 entries are covered (see `VERIFICATION.md`). ## Layout ```text diagnostics-redaction-spike/ src/ lib.rs # crate root, re-exports, REDACTION_MARKER policy.rs # RedactionRule, RedactionPolicy, default policy redactor.rs # Redactor, KnownSecretRegistry bundle.rs # DiagnosticBundle DTO + bundle-level redaction main.rs # diagnostics-redaction-cli driver tests/ redaction.rs # 12 tests; REDACT-TC-001..010 + sanity Cargo.toml ``` ## Reproduce Requires Rust stable (developed against 1.95). ```bash cargo test echo 'INFO password=hunter2 path=/home/alice/x' | cargo run --bin diagnostics-redaction-cli ``` ## Scope boundaries - **Not a `tracing` layer.** Production code in `chanora_diagnostics` will wire the redactor as a `tracing-subscriber` layer to enforce redaction at write-time, not via post-processing. The mechanism here is the same; the integration surface is not. - **No diagnostic bundle file format.** The spike only redacts the in-memory struct; the actual export format (zip / json-lines / etc.) is owned by `chanora_diagnostics`. - **No threat-model coverage of memory dumps, core dumps, or kernel logs.** That is `docs/security/threat-model.md` territory. - **No language-aware redaction.** The Unicode policy is "preserve multilingual text in non-sensitive fields; do not introspect it." - **No PII discovery.** This is a deny-list redactor; it does not attempt to detect previously-unknown secrets by entropy heuristics. ## Verification log See `VERIFICATION.md` in this directory.