From a0ec3b4edc21d30c14752e24137858daaa21a193 Mon Sep 17 00:00:00 2001 From: Brent Date: Thu, 20 Aug 2026 15:49:17 -0400 Subject: [PATCH] README: say WHY redaction is TS+Rust, so it stops reading as a parity gap "redaction: TypeScript and Rust" with no explanation looks like the security fix reached 2 of 5 ports. It didn't: it reached 2 of the 2 ports that log anything about a request. Python and Go have no logging call at all, and .NET holds an ILogger for DI and never calls it. A reviewer already came within a step of filing that bug against the matrix, so the reasoning belongs next to the claim rather than in a PR description nobody reads twice. The corpus itself already carries the forward-looking half of the rule -- add a sink, wire it to the corpus in the same PR -- and the README now points at it. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_0152bbE1veqfG1SVJdyLCBxC --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index 7983933..6e6399f 100644 --- a/README.md +++ b/README.md @@ -294,6 +294,18 @@ Every port carries the shared core: **retries with backoff + jitter, `Retry-Afte Where a port leans on a battle-tested ecosystem library (mollitia, Polly), it says so above; the others implement retry/breaker/rate-limit logic natively, with each port's own test suite covering the shared behaviors. +### Credential redaction is scoped to what each port actually logs + +| Language | What it logs about a request | Redaction | +| ---------- | ------------------------------------------------------------------------------------------- | ------------------------------------------- | +| TypeScript | method, host, path, query string, **headers**, **request body**, and the URL in the message | full — headers, query, URL and body | +| Rust | method and URL, on one `tracing::debug!` event | URL only (userinfo password + query params) | +| Python | nothing | n/a — no logging sink | +| Go | nothing | n/a — no logging sink | +| .NET | nothing (an `ILogger` is held for DI but never called) | n/a — no logging sink | + +**This is not a parity gap.** Redaction exists in exactly the two ports that have something to redact. Adding a scrubber to Python, Go or .NET would be code no call site reaches — which reads as a guarantee while guaranteeing nothing. The shared cases in [`spec/redaction-corpus.json`](spec/redaction-corpus.json) are loaded by the TypeScript and Rust suites, and that file states the rule for anyone extending it: **if a logging sink is ever added to another port, wire it to this corpus in the same PR.** + --- ## 📖 Smart defaults