# 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.
