Skip to content

fix(attribution): the shapes a footer collapses to, and the half no hook reaches - #52

Merged
protonspy merged 2 commits into
mainfrom
fix/attribution-escapes
Sep 17, 2026
Merged

protonspy merged 2 commits into
mainfrom
fix/attribution-escapes

Conversation

@protonspy

@protonspy protonspy commented Sep 17, 2026 •

Copy link
Copy Markdown
Owner

What changed

A session told not to sign its work does not stop signing it — it rephrases. Three escapes were measured walking past the attribution validator, and one surface was never read at all.

A vendor product link is a signature wherever it sits. The old gate asked whether the URL stood alone on its line; a harness that kept the link and moved it into a sentence was read as prose. A product page is nobody's citation, so its position says nothing. Documentation keeps the old gate — an argument that cannot cite the vendor's own docs is one nobody can check, so a docs host or a docs path is reported only standing alone.

Crediting a tool in one's own words is the same claim as the footer. "thanks to", "with the help of", "powered by", "pair-programmed with", and the instrumental voice — "used Claude Code to draft the tests". The last needs a stricter test, since the passive reading is ordinary prose about a harness this repo supports: the name has to be the verb's own object, and not possessive.

scc validate --pr now reads the comments and the review bodies. A commit message passes through commit-msg on the machine that wrote it; a comment is posted straight into the forge, by a tool as readily as by a person, and nothing runs when it is. The comment query degrades on its own, so a forge that answers about the pull request and not about its comments still gets the title and body checked.

What the review found

Two defects in code this change did not write, but did newly expose to live traffic.

signed accepted any Unicode symbol, and > and | are Sm. Every blockquoted line and every table row opened a signature — so the rule reported > Claude Code, Codex, and opencode, which is the exact sentence its own paragraph promises never to report. A review bot writes entirely in blockquotes, and reading comments is what made that live. The symbol now has to be non-ASCII, which is what a signature's decoration actually is; ASCII's symbol block is Markdown punctuation.

Measured over this repository's own record — 147 files, every PR body, issue comment and review comment:

hits false
before 56 2 — a bot's quoted file list on #6, and a table row in #6's body
after 54 0

A file is not a name. CLAUDE.md is a path the vocabulary matches on, so a line naming it read as somebody signing the work.

clip escapes now. It formats the offending line into a finding that finding.Set.Report prints to a real terminal on every push, and under --pr that line is written by anybody who can comment — not only by whoever opened the PR. A raw ESC surviving the trip is a control sequence the reader's emulator obeys, enough to scroll a finding off the screen and paint a clean report over it, which is the one lie this validator exists to prevent. Non-graphic runes become spaces, and the cut is by rune so hostile text cannot leave invalid UTF-8 in the report.

Review

Gate Verdict
scc-code-review blocked → fixed. One blocker (the signed/mention false positive above) and one minor (the rules line had dropped the clause saying --pr, not commit-msg, is what reads the forge). Both addressed. Its "ticked boxes are true" gate was not-run: this work has no plan, so there was no task list to check it against.
scc-security-review changes-requested → fixed. One high: terminal-escape injection from a PR comment through clip into render. Fixed at clip. It also flagged the same sink as pre-existing for every other validator — recorded as n-0013 rather than fixed here, since nothing else currently embeds untrusted text.

Both were re-run against the gates, not re-reviewed.

Verification

go build ./... · golangci-lint run · golangci-lint fmt --diff · scc validate --checks --pr — 12 validators, 0 findings; 1001 tests at 86.2%, above the 86% floor. pre-commit, commit-msg and pre-push all passed on this branch.

The false-positive claim is measured, not asserted: the corpus table above comes from scanning this repository's own pull request history with the code as it stands here.

Notes

assets.Version 33 → 35. Two template edits landed on this branch, and scc update writes the manifest only when it applies a file — so a managed file already byte-identical to the next template kept a stale hash, and at the version after that would have compared as edited and never been updated again. Recorded as n-0014.

And then it fired on this pull request

Running scc validate --pr against #52 once it was open reported two findings — one on this branch's own commit message and one on this body. Both are quotations: the commit explains the widened rule by quoting the phrasings it catches, and the paragraph above lists them.

That is the failure the package comment names at the top of its own file — "a pattern that could match mid-sentence would fire on a commit message that merely quotes one of these lines, which is exactly what a fix for this finding looks like". Every other rule is anchored against it: a trailer at the start of a line, a badge, a link or a mention alone on one. The footer family had nothing, and the instrumental voice added here had nothing either.

Second commit: an occurrence behind an odd number of straight quotes or backticks, or inside a typographic quotation still open, is skipped — per occurrence, so an unquoted credit beside a quotation is still caught. The apostrophe is not counted, being a possessive far more often than an opener.

What it gives up is a footer written inside quotation marks, which nothing writes and a reader would take as a mention anyway. Re-measured over 149 files — the corpus above plus this branch's commit and this body: 54 hits, all real, nothing else. scc validate --pr is now exit 0 against the live pull request.

…ook reaches

A session told not to sign its work does not stop signing it — it rephrases.
Three escapes were measured walking past the validator, and the pull request
comment was never read at all.

A vendor product link is now a signature wherever it sits. The old gate asked
whether the URL stood alone on its line, and a harness that kept the link and
moved it into a sentence was read as prose. A product page is nobody's citation,
so its position says nothing. Documentation keeps the old gate — code.claude.com
and docs.anthropic.com are sources, and an argument that cannot cite the vendor's
own documentation is one nobody can check.

Crediting a tool in one's own words is the same claim as the footer: "thanks to",
"with the help of", "powered by", "pair-programmed with", and the instrumental
voice, "used Claude Code to draft the tests". The last needs the stricter test —
the name has to be the verb's own object and not possessive — because the passive
reading is ordinary prose about a product this repository supports.

`scc validate --pr` now reads the comments and the review bodies. A commit
message passes through commit-msg on the machine that wrote it; a comment is
posted straight into the forge, by a tool as readily as by a person, and nothing
ran when it was. The query degrades on its own, so a forge that answers about the
pull request and not about its comments still gets the title and body checked.

Two things the review found, both in code this change did not write but did newly
expose to live traffic:

`signed` accepted any unicode symbol, and `>` and `|` are Sm — so every
blockquoted line and every table row opened a signature, and the rule reported
"> Claude Code, Codex, and opencode", the very sentence its own paragraph
promises never to report. Measured over this repository's 147 pull request
bodies and comments: 56 hits before, of which two were false — a review bot's
quoted file list and a table row from #6 — and 54 after, every one a real
signature. The symbol now has to be non-ASCII, which is what a signature's
decoration actually is.

And a file is not a name: CLAUDE.md is a path the vocabulary matches on, so a
line naming it read as somebody signing the work.

`clip` also escapes now. It formats the offending line into a finding that
finding.Set.Report prints to a real terminal on every push, and under --pr that
line is written by anybody who can comment. A raw ESC surviving the trip is a
control sequence the reader's emulator obeys — enough to scroll a finding off
the screen and paint a clean report over it, which is the one lie this validator
exists to prevent.

Verified: go build, golangci-lint run, golangci-lint fmt --diff, and
scc validate --checks --pr — 12 validators, 0 findings; 1001 tests at 86.2%.
The corpus measurement above is the evidence for the false-positive claim.
The package comment names this failure at the top of the file: a pattern that
could match mid-sentence fires on a commit message that merely quotes one of
these lines, which is exactly what a fix for this finding looks like. The other
rules are anchored against it — a trailer at the start of a line, a badge or a
link or a mention alone on one. The footer family had nothing, and the
instrumental voice added in the previous commit had nothing either.

Measured on this branch's own record. The commit explaining the widened rule
quotes the phrasings it now catches, and the pull request body quotes them
again, in a list. Both were reported by the rule they were explaining, and
`scc validate --pr` came back exit 2 on the change that had just been pushed.

So an occurrence behind an odd number of straight quotes or backticks, or inside
a typographic quotation still open, is skipped — per occurrence rather than per
line, so an unquoted credit beside a quotation is still caught. The apostrophe
is deliberately not counted: it is a possessive far more often than it opens
anything, and the instrumental rule already reads one three words along to tell
a credit from a description.

What this gives up is a footer written inside quotation marks, which is a shape
nothing writes and a person would read as a mention anyway. What it buys is the
one property this package trades everything for: one wrong finding teaches the
reader to disbelieve the other ten.

Verified against this repository's whole record — 149 files, every pull request
body, issue comment and review comment, plus this branch's own commit and the
body of #52: 54 hits, every one a real footer or session link from the pull
requests that predate the rule, and nothing else.
@protonspy
protonspy merged commit 0aef289 into main Sep 17, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant