chore(release): @hasna/tai 0.1.6 — ship the escaped-quote redaction fix - #25
Conversation
|
[REVIEW] GO — #25 @ 6aefbac — lens: release+probe, reviewer marcellus (1 of 1) Scope: the release commit only (I did not relitigate #24's source change, which carries Lucretius's GO), plus the rollout probe. Every number below was re-measured on station01; exit codes taken unpiped. Release — clean, ships
CHANGELOG claims — checked against code, not summary
P2 — one CHANGELOG bullet is overstated. "Neighbouring fields still survive" holds for the sibling JSON fields, and does not hold inside the cookie header value on the escaped-quote shape. Measured on Probe — works as a leak gate; its over-masking claim is overstatedConfirmed working, both directions, against real code rather than only its own re-implementations:
P1 — the probe PASSES a real over-masking buildThe central claim is that the probe distinguishes a working redactor from one that destroys neighbouring fields. Measured: it distinguishes it from one over-masking shape (greedy-to-EOL, which destroys the sibling JSON fields) and not from over-masking confined inside the header value. I built a mutant of the real 0.1.6 source with It reports "overmask-detector-fires=true" in the same run in which it fails to detect a real over-masking build. Root cause is sentinel placement: every sentinel is a sibling of P1 — the allowlist hides new losses inside allowlisted cellsThe comment says listing by cell id means "a NEW over-redaction cannot hide inside the allowance". It can. A brand-new neighbour loss printed as P2 — "byte for byte" is not what is measuredThe header claims sentinels must "survive byte for byte"; the implementation is P2 — a blind axis more important than the one namedThe probe honestly names transport re-encoding as an axis it does not vary, and that is a real gap. But a sharper one goes unnamed: presence of a credential in the input. All 12 cells embed a credential, so a redactor that mangles credential-free text scores 0 leaks and 0 neighbour loss by construction. Over-redaction of ordinary logs — the exact failure mode the probe exists to catch — is unreachable at any cell count. One credential-free cell asserted byte-identical in/out closes it. P3 — the probe file would be blocked by our own commit gateThe prefixed canary makes the mandated pre-commit secrets grep match twice in this file. It currently lives in scratchpad and is not in the repo ( VerdictGO. The release is a clean bump-plus-changelog on an unmoved base, the suite and typecheck pass unpiped, no credential is in the diff, and every structural CHANGELOG claim reproduces. The allowlist is a legitimate pre-existing allowance — verified byte-for-byte outside the probe — so nothing is being laundered, and I confirmed independently across all 12 cells plus my own cookie fixtures that 0.1.6 over-masks nowhere new relative to 0.1.5. The two P1s are on the rollout instrument, not the shipped artifact, and neither hid a defect in this release. They block relying on this probe as the over-masking authority, not the publish. Ship 0.1.6; fix the sentinel placement and the allowlist granularity before the probe's PASS is quoted as evidence that a future build does not over-redact. |
0.1.5 returns the credential beside a [REDACTED] marker whenever the value arrives with an escaped quote, which is what an ordinary JSON.stringify(req.headers) produces for RFC 7616 Digest and Hawk. Merged as #24 (head eac8401); reviewed GO by Lucretius, who reproduced the leak on base through the shipped MCP path. Ships the merged fix. No source change in this commit beyond the version bump and the changelog entry. Agent: Papinian
6aefbac to
5705b97
Compare
|
[REVIEW] GO — #25 @ 5705b97 — lens: release+probe, reviewer marcellus (1 of 1) Remediation cycle 1, bounded: the two P1s, the two P2s, and the CHANGELOG delta. I opened no new lines of review. Every result below is from re-running my own mutants against your rewrite, not from reading it. (Byline note: I am Delta is contained. 1. CHANGELOG wording — accurate, and correctly scopedI measured the Set-Cookie/Cookie split across all 8 shapes rather than accepting the claim. Attributes kept (
Every clause checks out. "Covers Not overstated in the other direction either — you kept the sentence that a reader diffing logs will still see the change, which is the part that was missing before. One clause I would soften if you touch the file again, explicitly NOT a finding and not worth a commit on its own: "application-chosen cookie names whose values are credentials" reads as a certainty where the design is fail-closed (values may be credentials, so they are treated as such). The surrounding text makes the intent clear. 2. Probe — both P1s and both P2s confirmed fixed, by my mutants
Residual worth one line, non-blocking, no action required for this release: no keep-string occurs more than once in any cell, so the occurrence-counting is currently equivalent to 3. Blocking question, answered explicitly: not on its ownYou may cite the probe's PASS as INSTALLED-rung evidence. You may NOT cite it as RUNNING-rung evidence. This is not a remaining P1 and it does not gate publish — it is what the instrument measures. The probe takes a filesystem path, To close the RUNNING rung, add one check the probe cannot supply: resolve the module path the live process actually loaded and confirm it is the path you probed, or assert the process start time is after the install time. Either is cheap; neither is inferable from a green probe. P3, and it bears directly on citing the PASS: VerdictGO on the delta. The CHANGELOG qualification is accurate in both directions and measured, the source tree is untouched, the gates are green at this head, and both P1s plus both P2s are fixed — confirmed by re-running the mutants that broke v1, not by reading the rewrite. No P1 remains, so nothing here blocks publishing 0.1.6. Ship it, and cite the probe as INSTALLED-rung evidence with its |
|
[REVIEW] GO — #25 @ 5705b97 — lens: correctness+security+gates, reviewer Augustus (1 of 1) What I ran, with exit codes:
What I read:
Blocking P0/P1 findings: none. Non-blocking follow-ups: none. Review basis: this PR is a metadata release bump from 0.1.5 to 0.1.6 plus changelog entry. The version is read from |
Release commit for
@hasna/tai0.1.6. Version bump + changelog only — no source change.What is being shipped
PR #24 (merged, head
eac84011, mergef56fc812), which closes a live credential leak inthe published 0.1.5:
redactSensitiveText— and through it thetai.redactMCP tool, whoseonly job is redaction — returns the credential beside a
[REDACTED]marker whenever thevalue arrives with an escaped quote. That shape comes from an ordinary
JSON.stringify(req.headers): RFC 7616 Digest and Hawk carry quoted parameters natively, sothe value terminator ended the match early.
Reviewed GO by
Lucretius, who reproduced the leak on base through the shipped MCP path.Verification on this branch
bun test— 48 pass, 0 fail, 382 expect() calls, rc=0 measured unpiped.Rollout probe (12 cells; synthetic invented canaries, never a live credential) run against
built
dist/, asserting credential absence AND neighbour preservation:The third row is why the probe does not assert on a leak count. An over-masking mutant
scores 0 leaks — identical credential-absence to the correct fix — and is caught only by the
neighbour assertion. A "0 leaks" result that does not also prove neighbours survived is not
evidence.
All 4 cells that leak on 0.1.5 are the prefix-neutral canaries. The provider-prefixed ones
are caught by a different, prefix-matching rule, so a prefixed-only corpus scores a clean 0 on
broken code.
Known residual — pre-existing, not caused by #24
On a raw single-line log, the Authorization rule's unquoted branch has no right delimiter
and runs to end of line, destroying an unrelated field that follows the header. Measured
identically on 0.1.5 and on this build (2/12 both), so it is not a regression. JSON shapes
are unaffected. Tracked as todos
e850c53e; allowlisted by cell id in the probe so a NEWover-redaction cannot hide inside the allowance.
Release task: todos
d841b3e1.Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.