fix(attribution): reject wrapped bylines - #90
Merged
Conversation
Signed-off-by: Thomas Albrecht <241560317+thequantumfalcon@users.noreply.github.com>
thequantumfalcon
marked this pull request as ready for review
September 8, 2026 03:31
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.
What changes and why
The attribution control rejected explicit credit lines, but some standalone
whole-line literal, paired-comment, and Markdown carriers passed through. This
change closes those observed gaps while preserving the existing
template-wrapper detections.
The rule remains lexical. It is not an authorship or provenance detector. It
recognises a narrow set of whole-line wrappers around an otherwise prohibited
credit line, and nothing more.
Concretely the change unwraps at most one supported standalone whole-line
literal or template layer, composes paired comment and Markdown wrappers, and
applies Markdown semantics to raw commit and commit-message carriers.
No issue is linked; the change was prompted by the preserved review finding
described below.
Defect reproduction
The baseline phase had two separate invocations; their outcomes are not
combined.
The first attempt used a broad keyword selector. It exited 2 because three
unrelated test modules failed collection in the ambient environment. It
executed zero approved cases and is permanently a non-verdict.
The sole decisive baseline used six exact file-bound selectors against the base
scanner with only the candidate test file overlaid. It produced 25 cases: 19
intended semantic failures, 6 passes, zero errors and zero skips.
Five of those passes represent behavior the base already rejected: the two
backtick wrapper cases, two legacy raw-commit cases, and the existing role
workflow case. The sixth pass is the ordinary product-discussion and
safe-identity control, which must stay clean.
The 19 failures are the intended pre-fix gaps for this one narrow rule. They
are not 19 independent defects, and it is not claimed that all newly introduced
cases failed against the base.
The transcript below is additive reviewer-visible evidence. The existing
baseline and focused evidence remains authoritative and unchanged. One
invocation was made per tree, with no retry, and stderr was empty for both.
The repository's own
addopts = "-q"combines with the command's-q, sopytest emits no numeric summary line; the counts are the progress characters
and the listed node IDs.
Pre-fix tree, exit status 1:
Candidate tree, exit status 0:
Candidate behavior and deciding paths
The candidate exercises the direct scanner path, the raw-commit path, the
pre-commit hook path, the commit-msg hook path, the workflow commit-range path,
and the workflow tree path.
Unit 15's Windows hook-launch and exact-diagnostic protections remain intact.
The real-hook test is not skipped on Windows; only the Ubuntu-only workflow
simulations are skipped there, and they keep their explicit skip reasons.
Candidate identity and scope
d1782879c3ef386d7d8683daee3e26c8a2181eb68bdbc256ec9d134807cdaf9b51b394a76c0098e969ad9b5bf0cd93ffa5ce4a0dca9e2aedd5303cb91323c29ed892a80375183c8db4187ff5d3777b1df53294655f1c854e42bce560da444b94d48bd60aa1f0e52d74b165afa5f58be9exactly one owner
Signed-off-bytrailer.github/scripts/check_attribution.pyAGENTS.mdtests/test_attribution_controls.pyVerification
The identical six candidate selectors passed: 25 passed, zero failures, zero
errors, zero skips. Ruff 0.16.1 passed.
The first trusted scanner invocation used a flat scratch layout, exited 2, and
is a non-verdict rather than a finding. The correctly staged replacement and
the remaining required scans all passed.
Commit hooks ran normally and gitleaks 8.30.1 executed successfully.
The canonical gate was one uninterrupted invocation with immediate status 0,
empty stderr, and all 15 stages exactly once and in order. The figure 2,340
means pytest progress characters, not a numeric test total.
The recorded stage order was:
This changes the repository attribution gate, not an Engine.complete_task
rejection path, so no tests/test_instrument_validation.py planted-defect case
applies. Its regression coverage is in tests/test_attribution_controls.py.
Canonical pytest was 9.1.1. The baseline and focused invocations used pytest
9.0.3; both ran outside the canonical bootstrap environment.
Local evidence is macOS-only and makes no hosted-CI or hosted-Windows claim.
Protected-control authorization sequencing
The exact protected intersection for this change is only
.github/scripts/check_attribution.py.The opened advisory is therefore expected to fail only at its exact-head owner
authorization step. The final head, title, and body must be frozen before a
later owner-generated
content-integrity-policy-changelabeled event. Merelabel presence, or a checked box in this body, is not authorization.
No claim is made that authorization, hosted checks, a ready transition, or a
merge has already occurred.
Limits
rule.
detection of undisclosed or novel assistance is claimed.
remain non-credit contexts.
3f2d47b45c08ce36729a88f204616c2ef360861c, not this candidate.e43ca55f9f83a11813295f681f18a7bd19f6dfb3are distinct from the reconciled+111/-8 delta and patch ID
da444b94d48bd60aa1f0e52d74b165afa5f58be9.and SHA-256 values are recorded in the run records.
Preparation and process record
The local preparation phase made no GitHub or shared-state mutation. The
publication base was fetched read-only and the candidate was built by strict
application of a frozen patch, with the regenerated full-index diff
byte-identical to it.
Two invocations are recorded as non-verdicts rather than results: the
wrong-scope baseline described above, and the flat-layout trusted scanner. Their
captures are bound by byte counts and SHA-256 values in the run records, and
neither was relabelled as a pass.
One additive correction records that the canonical gate run record copied the
ambient pytest version into a canonical field. The retained canonical log and
the hash-locked dependency lock both establish pytest 9.1.1 for that run. The
original record is unchanged and superseded only for that one field.
Canonical provisioning downloaded its hash-locked toolchain from the public
package index during the single gate invocation. Retained ignored build and
cache output is deliberate and is not source dirtiness.
Unit 18 boundary
Unit 18 remains unauthorized. Its reserved branch is
chore/v0.1.5-release-dateand its reserved subject ischore(release): date v0.1.5.Its reserved paths are
CHANGELOG.md,CITATION.cff, andtests/test_release_controls.py. The Unit 17 and Unit 18 path sets do notoverlap.
The historical commit
2f9380f6a6daa805b96952d936b39ee89c2c77adis retained as provenance only and is not the Unit 18 candidate. Its 2026-08-22
release-date value is stale and must be regenerated for the actual release
date.
Checklist