Repository navigation
ci: provenance-aware copyright header check - and stop the license plugin mislabeling fork files - #90
Merged
Merged
Conversation
…license plugin The mycila license-maven-plugin knows only ONE header template (Confluent + git-derived years) and defaulted to 'format' mode - so any bare mvn build rewrote fork-original files with the wrong attribution (how the chaos-suite files got Confluent headers), auto-bumped years, and broke in git worktrees. - Skip the plugin by default (<license.skip>true</license.skip> in the root pom) - -Dlicense.skip on the command line is no longer needed. - bin/check-copyright-headers.sh enforces the real policy instead: files in the pinned fork-point tree (7f29012, the merge-base with upstream) keep the Confluent header; files added since must carry the fork header ('Antony Stubbs and contributors') and must not claim Confluent copyright. Years are deliberately not policed. Upstream files RENAMED/EXTRACTED on the fork are registered in an in-script exceptions list: the 3 example ITs relocated in fface19 (verified renames) + ManagedPCInstance (extraction of upstream IT code, keeps Confluent header per PR #83 - pre-registered so the check doesn't ambush the chaos stack at merge). - bin/test-check-copyright-headers.sh self-tests the scanner against fixture repos: all 5 rules, the exceptions mechanism, the clean path, and the shallow-clone guard (10 assertions). Runs first in CI. - New 'Copyright Headers' workflow runs self-test + scanner on every push/PR (GitHub-hosted, <1 min, fetch-depth 0 for the fork-point commit). - AGENTS.md copyright rules updated to document the enforcement. Verified: self-tests 10/10, scanner green on master (213 files, 0 violations), actionlint clean, 'mvn process-sources' logs 'License Plugin is Skipped'. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013ALhTf1TRA2S6Ue5rkiQdK
Dependency ReviewThe following issues were found:
License Issues.github/workflows/copyright.yml
OpenSSF Scorecard
Scanned Files
|
✅ Duplicate Code ReportTwo engines run in parallel for cross-validation. Each has its own thresholds tuned to its baseline - the real safety net is the per-engine "max increase vs base" check. ✅ PMD CPD
No new clones introduced by this PR. ✅ jscpd (language-agnostic)
|
✅ SpotBugs ReportNo bugs found (new bugs only — baseline from base branch excluded). |
🧪🔒 Quarantine Lane Report
🔴 expected while the owner PR is open · 🟡🎲 flapper, pass proves nothing · 🚨 a deterministic quarantined test passing means its fix landed: delete its |
…opyright line - rule, sweep, tests Extends the scanner per review: an upstream-derived file that has been MODIFIED since the fork point can no longer keep a bare Confluent header - it must add 'Modifications Copyright (C) <year> Antony Stubbs and contributors' beneath it (Apache 2.0 4(b) retain-notices + 4(c) change-notice; the Corretto/MariaDB dual-notice convention). Nothing is planned to go upstream, so no header is held back for diff cleanliness. - Scanner: modification detected against the working tree vs the pinned fork point; the exceptions list is now provenance-smart - renames carry 'newpath|oldpath' so a rename with content changes requires the line (verbatim renames don't), and extractions (ManagedPCInstance) always do. - Sweep: 45 modified-derived files on master get the modifications line (incl. the 3 relocated example ITs - fface19 modified them too). Also two fork-original files' year ranges tidied (2020-2026 -> 2026). - Self-tests extended to 13 assertions covering the new rules (modified w/o line fails, dual header passes, verbatim rename passes, changed rename fails, extraction fails). - Workflow: push trigger scoped to master (matching maven.yml) so PR commits run the check once, not twice. - AGENTS.md + docs/inflight.md document the convention, the root cause, and the remaining chaos-stack follow-up (ManagedPCInstance needs the line on PR #83 once this merges). Verified: self-tests 13/13, real scan 213 files 0 violations, all-module test-compile clean, actionlint clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013ALhTf1TRA2S6Ue5rkiQdK
astubbs
added a commit
that referenced
this pull request
Jul 30, 2026
Inflight records inflight work (or context required for it) - the policy lives in AGENTS.md and the history in PR #90; only the chaos-stack remediation is still open. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013ALhTf1TRA2S6Ue5rkiQdK
…ht entry accordingly State the rule in the file's preamble: inflight.md records ONLY inflight work, or context required for something inflight - completed-work narratives, root-cause write-ups, and policy docs belong in AGENTS.md, PR descriptions/commits, or docs/solutions/. When work finishes, delete or shrink its entry. Applied to the copyright entry: trimmed to the one open follow-up (the chaos stack needs ManagedPCInstance's modifications line to pass the new header check once PR #90 merges). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013ALhTf1TRA2S6Ue5rkiQdK
astubbs
force-pushed
the
ci/copyright-header-check
branch
from
July 30, 2026 23:29
5eb32fb to
b32a882
Compare
astubbs
added a commit
that referenced
this pull request
Jul 31, 2026
…eal Modifications-line check (PR #90 review) (#91) Post-merge review follow-ups from the PR #90 ce-review (two independently reproduced P1s, plus the safe fixes from the pre-merge round): - require_modifications_line() now demands 'Modifications Copyright (C)' and the fork holder on the SAME line - previously any occurrence of 'Antony Stubbs and contributors' in the header window (e.g. an @author javadoc byline) silently satisfied the Apache 2.0 4(b)/4(c) notice check. - The RENAMED_FROM_UPSTREAM lookup is now an exact newpath-field match (awk '$1 == f') - previously an unanchored 'grep -F "${f}|"' substring match that misrouted any file whose path is a tail-substring of a registered newpath into the rename branch, comparing it against the wrong fork-point blob (false FAILs on compliant files, or silent bypass of the fork-original checks). Not live today, but a latent trap on the documented rename-registration workflow. - Both fixes are mutation-locked by new self-test fixtures (ModifiedAuthorByline near-miss header; a registered rename plus an unrelated tail-substring-colliding fork file). Reverting either bug fails the suite. - Pre-merge round fixes: HeaderSwapped fixture (the previously untested 'upstream file LOST its Confluent header' branch - deletable with all self-tests green before), fork copyright headers on both scripts, set -euo pipefail to match every other bin/*.sh, copyright.yml added to AGENTS.md's CI workflow catalog. - docs/solutions copyright-header doc updated: superseded-by-PR-#90 note (plugin now skipped by default, scanner is the enforcement, dual-notice convention), corrected stale references and the outdated header-update example. Verified: self-tests 16/16 green, real scan 213 files 0 violations. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
5 tasks done
astubbs
added a commit
that referenced
this pull request
Jul 31, 2026
…tream file) The new provenance-aware copyright check (merged from master, PR #90/#91) flagged VertxTest.java: this PR modified it (the DNS-coupling fix) but it lacked the required Modifications Copyright line for an upstream-derived file changed since the fork point. Add it (keeping the original Confluent line/year). Scanner now passes: 0 violations. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
astubbs
added a commit
that referenced
this pull request
Jul 31, 2026
…#92) The provenance-aware copyright-header check (bin/check-copyright-headers.sh, from PR #90/#91) only ran via the copyright.yml GitHub Action and manual invocation - a local `mvn` build did zero header enforcement (the mycila license plugin is skipped by default for this fork). So header mistakes were only caught in CI. Wire the scanner into the build: - exec-maven-plugin runs bin/check-copyright-headers.sh in the `validate` phase, once at the root (inherited=false; the script cd's to the git top-level itself). Skip with -Dcopyright.skip=true (new property, default false). Worktree-safe (unlike the mycila plugin), which is why the scanner can be bound at all. - Graceful shallow-clone handling: the scanner needs the fork-point commit to classify provenance. It now WARNs and skips (exit 0) when that commit is absent (e.g. a shallow clone / a build without full history) instead of hard-failing, so it never breaks such builds. COPYRIGHT_CHECK_REQUIRE_FORK_POINT=1 forces the old hard-fail; copyright.yml sets it (it fetches full history, so a missing fork point there is a real error), keeping the CI gate strict. - Self-test updated: fixture C now asserts both the default warn+skip (exit 0) and strict-mode hard-fail (exit 2). Verified: `mvn validate` runs the scanner and passes on a clean tree; fails the build on a fork-original file wrongly claiming Confluent; and is bypassed by -Dcopyright.skip=true. Scanner self-test passes. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
astubbs
added a commit
that referenced
this pull request
Jul 31, 2026
Master's merge brought in the copyright-header CI enforcement (PR #90). Eight files modified on this branch needed headers aligned with the fork policy: six upstream-derived files gain the 'Modifications Copyright' dual-notice line; two fork-original tests drop the incorrect Confluent claim. README.adoc is the build-regenerated sync of master's ambient-probe changelog entry. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QqHpNSXC39ANv9kG1ZvUzn
astubbs
added a commit
that referenced
this pull request
Aug 5, 2026
…ssing without a review (#124) The mycila license-maven-plugin has been inert since #90, which set license.skip=true because the plugin knows only ONE header template: its format goal stamped the Confluent header onto fork-original files, and its git-based year resolver auto-bumped copyright years and broke inside git worktrees. Header conformance moved to bin/check-copyright-headers.sh, which is provenance-aware and runs in the `validate` phase, so a plain `mvn` catches violations locally and not only via copyright.yml. The pom kept the plugin as an escape hatch "if you ever need its format goal on upstream files". That presupposes new upstream-derived files still arriving; upstream is unmaintained and heading for archival, and on fork-original files the format goal is actively wrong. An escape hatch for a case that can no longer occur is debris - and debris with a cost, since establishing that license.mode alongside the Confluent inlineHeader was not a live footgun took a full investigation. Removed: the plugin block, mycila.version, license.skip, license.mode and its profile overrides, and the license-format profile, which activated on macOS and did nothing once license.mode was gone. The dead flag is dropped from 9 bin/ scripts and 4 workflows, including the nested -Darguments in release.yml's release:prepare. Two artifacts invoked the plugin by GOAL rather than by property, so they contained none of license.skip/license.mode/mycila and survived every grep here and both review passes - one of which explicitly certified that no license:check invocation remained. Both are deleted. bin/checkcompile-license.sh ran `mvn license:check`, was referenced by nothing, and iterated commits against `parralel-test-fix`, a typo'd branch that does not exist. .idea/runConfigurations/license_format.xml was a checked-in IDE run configuration whose only goal was license:format - a button in every contributor's dropdown whose sole action was the thing this fork removed the plugin to prevent. Search for what a thing does, not only what it is called. Also swept: ChaosScenarioBase.replayCommand, which builds the invocation the chaos suite prints into CI logs precisely so a raw log is self-sufficient to reproduce a failure - a dead flag there does not sit still, it gets copy-pasted into every future investigation. Editing .github/workflows/claude-code-review.yml exposed a second defect, fixed here. The review action refuses to run unless that file matches the default branch, so a PR cannot rewrite its own reviewer. It logged "Exiting due to workflow validation skip" and exited 0. claude-review went green in 19 seconds and this PR sat mergeable with no review of any kind. Green meant "the job finished", not "this PR was reviewed", and nothing distinguished the two. That was the second time this workflow certified nothing: it also ran green for months while never posting a single review, before --comment was added. bin/check-review-posted.sh now gates the job. The action stamps its run URL into every comment it posts, so a comment citing this run id proves this run posted something; the gate also fails when the review step did not succeed at all, covering crash, timeout and skip. Comment bodies arrive on stdin, which keeps network I/O in the workflow and leaves the matching logic testable offline - bin/test-check-review-posted.sh covers 12 cases and runs in the job before the gate it protects. Run ids are matched with a trailing non-digit boundary, so a search for actions/runs/3096 cannot pass on run 30965089954's review. The gate proves a review was posted, not that it was a good review, and says so rather than implying more. claude-review is now a required status check on master. Because this PR edits the reviewer's own workflow file the action cannot run on it, so the gate correctly fails and this PR merges via a deliberate admin bypass - any PR introducing this gate blocks itself. The review it did receive was requested manually with @claude, which runs from the unmodified claude.yml; AGENTS.md documents that route for future PRs and says not to disable the gate to get a green check. Verified: ./mvnw -N validate (232 java files, 0 header violations), test-compile over the edited chaos classes, the gate's 12 self-tests green in CI, and the gate exercised against this PR's real comment history - the run that skipped fails, the manual review that genuinely posted passes.
4 tasks done
6 tasks done
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.
Why
The mycila license-maven-plugin knows only ONE header template (
Confluent, Inc. and contributors+ git-derived years) and its default mode isformat- so any baremvnbuild rewrote fork-original files with the wrong attribution. That is exactly how the chaos-suite files ended up claiming Confluent copyright (since corrected on their branches). The plugin's git-year resolver is also what auto-bumps years and breaks in git worktrees.What
<license.skip>true</license.skip>in the root pom).-Dlicense.skipon command lines is no longer needed (harmless where it remains). Verified:mvn process-sourceslogs "License Plugin is Skipped".bin/check-copyright-headers.shenforces the fork's real header policy (AGENTS.md), classifying every tracked java file by provenance against the pinned fork point (7f290122, the merge-base with upstream). Fully local and deterministic - no network, no upstream remote:Copyright (C) <year> Antony Stubbs and contributors, must not claim Confluent.Modifications Copyright (C) <year> Antony Stubbs and contributors- the Apache 2.0 §4(b)/§4(c) dual-notice convention (Corretto/MariaDB style). Nothing goes upstream from this fork, so no header is held back for diff cleanliness.newpath|oldpath(verbatim rename = Confluent-only OK; changed rename = modifications line required); extractions always require the line. Registered: the 3 example ITs relocated infface195, andManagedPCInstance(chaos stack, pre-registered so the check doesn't ambush feat(chaos): Chaos Pain Suite - calibrated, portable bug-detector pack (finds the drain-zombie on master blind) #83 at merge).bin/test-check-copyright-headers.sh- 13 assertions against fixture repos covering every rule, the exceptions mechanics, the clean path, and the shallow-clone guard. CI runs the self-test before the real scan.Copyright Headersworkflow: self-test + scan on every PR and master push (push scoped to master, matching maven.yml, so PR commits run once - not twice). GitHub-hosted, under a minute,fetch-depth: 0for the fork-point commit.Verification
mvn test-compileclean after the 45-file header sweepmvn validategreen with the pom changeNote: once this merges, the chaos-stack PRs (#83/#85/#87) will fail this check until their in-flight fork-header fixes land (plus
ManagedPCInstanceneeding its modifications line on #83) - a deliberate forcing function.🤖 Generated with Claude Code
https://claude.ai/code/session_013ALhTf1TRA2S6Ue5rkiQdK