fix: make the identity pin round-trip through the self-contained commit guard (iss-63)#120
Merged
Merged
Conversation
…it guard (iss-63) The pin was stored with Go's default JSON encoder, which escapes &, <, > (and always ", \, control characters). The self-contained pre-commit identity guard reads the raw bytes between the JSON quotes with a naive sed and compares them literally to `git config`, so any escaped value never matched and fail-closed a correctly configured identity — not only a double-quote but a `user.name` of "Marks & Spencer", "AT&T", a backslash, etc. Fix the whole class at the source: marshal the pin WITHOUT HTML escaping so &, <, > are stored literally, and refuse the characters a naive parse can never read back (double-quote, backslash, control) at pin time with a clear remedy. The pre-commit hook is deliberately untouched, staying zero-dependency (it holds even when abcd is absent or stale) rather than delegating the gate to the binary. Detector: TestWritePin_RejectsUnpinnableChars + TestWritePin_LegalIdentitiesRoundTrip, watched fail->pass (the round-trip test reproduces the exact 'Marks \u0026 Spencer' escaping bug an adversarial review surfaced beyond the original quote-only fix). Ledger: resolves iss-63 (folded into this branch). Assisted-by: Claude:claude-opus-4-8
…in-quote-guard # Conflicts: # CHANGELOG.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The pin was stored with Go's default JSON encoder, which escapes &, <, > (and always ", , control). The self-contained pre-commit identity guard reads the raw bytes between the quotes with a naive sed and compares literally to git config, so an escaped value never matched and fail-closed a correct identity (e.g. a user.name of "Marks & Spencer").
Fix the whole class: marshal WITHOUT HTML escaping so &/</> store literally, and refuse the chars a naive parse can never read back (", , control) at pin time. The hook is untouched, staying zero-dependency (not delegated to a possibly-stale binary).
The original quote-only fix was widened after adversarial review caught the &/\ siblings. Detector: reject-unpinnable + legal-identities-round-trip (reproduces the exact "Marks \u0026 Spencer" bug), fail->pass. ruthless: SHIP, security: APPROVE (gate can only fail closed, never spoof).
Ledger: resolves iss-63.
Assisted-by: Claude:claude-opus-4-8