Skip to content

fix(attribution): reject wrapped bylines - #90

Merged
thequantumfalcon merged 1 commit into
mainfrom
fix/attribution-wrapped-bylines
Sep 8, 2026
Merged

fix(attribution): reject wrapped bylines#90
thequantumfalcon merged 1 commit into
mainfrom
fix/attribution-wrapped-bylines

Conversation

@thequantumfalcon

Copy link
Copy Markdown
Owner

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, so
pytest emits no numeric summary line; the counts are the progress characters
and the listed node IDs.

Pre-fix tree, exit status 1:

$ python3.14 -m pytest -q --tb=no -p no:cacheprovider tests/test_attribution_controls.py::test_standalone_source_literal_credits_are_rejected tests/test_attribution_controls.py::test_ordinary_product_discussion_and_human_identities_remain_clean tests/test_attribution_controls.py::test_raw_commit_rejects_decorated_and_plain_message_bylines tests/test_attribution_controls.py::test_real_workflow_commit_path_rejects_a_base_valid_bypass tests/test_attribution_controls.py::test_real_hooks_reject_a_standalone_source_literal tests/test_attribution_controls.py::test_real_workflow_tree_rejects_a_standalone_source_literal
FFFFF.FFFFFFF....FFF.FFFF                                                [100%]
=========================== short test summary info ============================
FAILED tests/test_attribution_controls.py::test_standalone_source_literal_credits_are_rejected[module.py-"""-"""]
FAILED tests/test_attribution_controls.py::test_standalone_source_literal_credits_are_rejected[module.py-'''-''']
FAILED tests/test_attribution_controls.py::test_standalone_source_literal_credits_are_rejected[module.py-r"""-"""]
FAILED tests/test_attribution_controls.py::test_standalone_source_literal_credits_are_rejected[module.py-"-";]
FAILED tests/test_attribution_controls.py::test_standalone_source_literal_credits_are_rejected[module.py-'-';]
FAILED tests/test_attribution_controls.py::test_standalone_source_literal_credits_are_rejected[module.py-# "-"]
FAILED tests/test_attribution_controls.py::test_standalone_source_literal_credits_are_rejected[module.js-// "-"]
FAILED tests/test_attribution_controls.py::test_standalone_source_literal_credits_are_rejected[module.c-/* "-" */]
FAILED tests/test_attribution_controls.py::test_standalone_source_literal_credits_are_rejected[module.rs-/*! "-" */]
FAILED tests/test_attribution_controls.py::test_standalone_source_literal_credits_are_rejected[README.md-<!-- "-" -->]
FAILED tests/test_attribution_controls.py::test_standalone_source_literal_credits_are_rejected[README.md-"-"]
FAILED tests/test_attribution_controls.py::test_standalone_source_literal_credits_are_rejected[README.md-- "-"]
FAILED tests/test_attribution_controls.py::test_raw_commit_rejects_decorated_and_plain_message_bylines[parts2]
FAILED tests/test_attribution_controls.py::test_raw_commit_rejects_decorated_and_plain_message_bylines[parts3]
FAILED tests/test_attribution_controls.py::test_raw_commit_rejects_decorated_and_plain_message_bylines[parts4]
FAILED tests/test_attribution_controls.py::test_real_workflow_commit_path_rejects_a_base_valid_bypass[source-literal]
FAILED tests/test_attribution_controls.py::test_real_workflow_commit_path_rejects_a_base_valid_bypass[markdown-list]
FAILED tests/test_attribution_controls.py::test_real_hooks_reject_a_standalone_source_literal
FAILED tests/test_attribution_controls.py::test_real_workflow_tree_rejects_a_standalone_source_literal

Candidate tree, exit status 0:

$ python3.14 -m pytest -q --tb=no -p no:cacheprovider tests/test_attribution_controls.py::test_standalone_source_literal_credits_are_rejected tests/test_attribution_controls.py::test_ordinary_product_discussion_and_human_identities_remain_clean tests/test_attribution_controls.py::test_raw_commit_rejects_decorated_and_plain_message_bylines tests/test_attribution_controls.py::test_real_workflow_commit_path_rejects_a_base_valid_bypass tests/test_attribution_controls.py::test_real_hooks_reject_a_standalone_source_literal tests/test_attribution_controls.py::test_real_workflow_tree_rejects_a_standalone_source_literal
.........................                                                [100%]

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

  • commit d1782879c3ef386d7d8683daee3e26c8a2181eb6
  • parent 8bdbc256ec9d134807cdaf9b51b394a76c0098e9
  • tree 69ad9b5bf0cd93ffa5ce4a0dca9e2aedd5303cb9
  • patch 9,568 bytes, SHA-256
    1323c29ed892a80375183c8db4187ff5d3777b1df53294655f1c854e42bce560
  • stable patch ID da444b94d48bd60aa1f0e52d74b165afa5f58be9
  • three paths, all mode 100644, +111/-8
  • one locally verified signed commit, owner-authored and owner-committed, with
    exactly one owner Signed-off-by trailer
path added deleted
.github/scripts/check_attribution.py 22 6
AGENTS.md 4 0
tests/test_attribution_controls.py 85 2

Verification

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:

  1. clean source before release
  2. content integrity
  3. commit metadata integrity
  4. release metadata
  5. tests
  6. lint
  7. stdlib boundary
  8. benchmark
  9. conformance corpus
  10. capability generation
  11. capability drift
  12. reproducible distributions
  13. distribution structure
  14. distribution behavior
  15. clean source after release

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-change labeled event. Mere
label 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

  • Assignments and embedded fixture or object strings remain outside the narrow
    rule.
  • At most one supported literal or template layer is unwrapped.
  • No language parser, provenance inference, proof of human authorship, or
    detection of undisclosed or novel assistance is claimed.
  • Sentence-form product discussion and Markdown vendor headings and lists
    remain non-credit contexts.
  • The historical READY review covered
    3f2d47b45c08ce36729a88f204616c2ef360861c, not this candidate.
  • The historical +96/-8 delta and patch ID
    e43ca55f9f83a11813295f681f18a7bd19f6dfb3 are distinct from the reconciled
    +111/-8 delta and patch ID da444b94d48bd60aa1f0e52d74b165afa5f58be9.
  • Raw JUnit and invocation files are not installed evidence; their byte counts
    and SHA-256 values are recorded in the run records.
  • Unit 17 is not preserved and not merged, and no release readiness is claimed.

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-date and its reserved subject is
chore(release): date v0.1.5.

Its reserved paths are CHANGELOG.md, CITATION.cff, and
tests/test_release_controls.py. The Unit 17 and Unit 18 path sets do not
overlap.

The historical commit 2f9380f6a6daa805b96952d936b39ee89c2c77ad
is 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

  • Owner review of the three-path diff and patch identity
  • Hosted checks observed on the exact head
  • Exact-head owner authorization for the protected scanner path
  • Ready transition requested separately
  • Merge requested separately

Signed-off-by: Thomas Albrecht <241560317+thequantumfalcon@users.noreply.github.com>
@thequantumfalcon thequantumfalcon added the content-integrity-policy-change Owner authorization for exact-head changes to protected integrity controls. label Sep 8, 2026
@thequantumfalcon
thequantumfalcon marked this pull request as ready for review September 8, 2026 03:31
@thequantumfalcon
thequantumfalcon merged commit 3ec3f79 into main Sep 8, 2026
16 of 17 checks passed
@thequantumfalcon
thequantumfalcon deleted the fix/attribution-wrapped-bylines branch September 8, 2026 04:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

content-integrity-policy-change Owner authorization for exact-head changes to protected integrity controls.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant