Skip to content

feat(tools): add maven-artifact-verify and wire JVM artefact checks into release-verify-rc - #1415

Merged
potiuk merged 14 commits into
apache:mainfrom
liwenjie200543:jvm-artefact-verify-rc
Oct 4, 2026
Merged

potiuk merged 14 commits into
apache:mainfrom
liwenjie200543:jvm-artefact-verify-rc

Conversation

@liwenjie200543

Copy link
Copy Markdown
Contributor

Summary

  • Add tools/maven-artifact-verify, a stdlib-only, fully offline Python adapter implementing blocking checks 1–3 agreed on in release-verify-rc: validate rc jars #1173 (POM licence/developers/scm, podling incubation disclaimer, signed companion -sources.jar/-javadoc.jar sets) against a locally staged directory — no Nexus probing in this PR.
  • Wire the tool in as release-verify-rc Step 6b (numbered to preserve every existing cross-reference to Steps 7–9), skipped cleanly for non-JVM RCs, plus the matching jvm_artefact_checks configuration surface in the release-build.md template.
  • Sync the capability map, docs/release-management/spec.md, and the spec-loop spec; add a step-6b-jvm-artefacts eval suite (4 cases) for the new skill behaviour.

Type of change

  • Skill change (.claude/skills/<name>/) — eval fixtures updated below
  • Tool / bridge contract (tools/<system>/*.md)
  • Python package (tools/*/ with pyproject.toml)
  • Groovy reference impl
  • Cross-cutting (RFC, AGENTS.md, sandbox, privacy-LLM)
  • Documentation (docs/, README.md, CONTRIBUTING.md)
  • Project template (projects/_template/)
  • CI / dev loop (prek, workflows, validators)
  • Other:

Test plan

  • prek run --all-files passes (not run locally: the author's uv is below the repo floor and prek is unavailable in this environment; the repo's skill-and-tool-validator, check-doc-sync, check-workspace-members and the surface-hash/token-count checks were run individually and pass — happy to run prek in CI or on request)
  • For Python packages touched: uv run pytest / ruff check / mypy passes (24 new tests + the package's ruff/ruff format/mypy all clean; run with an isolated Python 3.13 venv since the local uv is 0.11.7)
  • For Groovy bridges touched: command-line invocation tested end-to-end
  • For skill changes: eval suite passes for the affected skill
    (PYTHONPATH=tools/skill-evals/src python3 -m skill_evals.runner tools/skill-evals/evals/<skill>/) (fixtures added and JSON-validated; runner not executed locally)
  • For skill behaviour changes: a new or updated eval fixture is included in this PR
    (a regression test for the bug fixed / the behaviour added — see CONTRIBUTING.md) — step-6b-jvm-artefacts, 4 cases
  • Other: end-to-end smoke test of the real CLI over three staged-set scenarios (clean podling set → PASS; wrong licence → FAIL; unsigned companion → FAIL), plus the read-only-skip path (no jars/POMs → SKIP)

RFC-AI-0004 compliance

  • HITL — any new mutation is gated on explicit user confirmation (no new mutation: the step and the tool are read-only)
  • Sandbox — no new unrestricted host access; network reach declared in the adapter (the tool is fully offline and reads the staged directory only)
  • Vendor neutrality — placeholders (<PROJECT>, <tracker>, <upstream>, <security-list>) used in all skill / tool prose (the check-placeholders prek hook is the mechanical gate)
  • Conversational + correctable — agentic-override path documented if behaviour is adopter-tunable
  • Write-access discipline — no autonomous outbound messages; drafts only, sent on confirmation
  • Privacy LLM — private content does not reach a non-approved LLM; redactor invoked where needed

Linked issues

Refs #1173 (PR 1 of the approved split: blocking checks 1–3, local artefacts only; check 4 / informational checks 5–7 are follow-up PRs)

Notes for reviewers (optional)

  • Step 6b numbering. The step is inserted after Step 6 without renumbering 7–9, so existing cross-references (docs, evals, specs) stay valid. Renumbering could be done in a dedicated PR if maintainers prefer.
  • INHERITED-UNVERIFIED is a WARN, not a FAIL. Check 1 resolves absent licence/developers/scm elements against a locally staged parent POM; when that is impossible (e.g. inheritance from org.apache:apache outside the staging dir) the POM is reported as inherited-unverified rather than failing a correct POM. Effective-POM verification would need Maven or network access, both out of scope for an offline read-only check.
  • --podling is gated on a DISCLAIMER/DISCLAIMER-WIP file in the unpacked source artefact, not on a project_stage config key — that mechanism is release-* family has no ASF incubator/podling handling (IPMC vote, DISCLAIMER, incubator dist paths, -incubating suffix) #1172's territory and this PR does not pre-empt it.
  • A main jar declared by a staged POM but absent locally is an ABSENT observation, not a FAIL — staging jars in the Nexus staging repo instead of the local dir is the common ASF workflow. It escalates to FAIL only when release-build.md declares jvm_companion_location: staged.
  • Disclaimer matching accepts both the standard incubation text and the DISCLAIMER-WIP variant, verbatim from the Incubator distribution/branding guides, tolerant of whitespace and line-wrapping.
  • .last-sync drift: tools/spec-loop/.last-sync on this branch is 37 commits behind main (pre-existing upstream drift); this PR does not bump it.

🤖 Generated with WorkBuddy

Comment thread tools/maven-artifact-verify/src/maven_artifact_verify/__init__.py Fixed
Comment thread tools/maven-artifact-verify/tests/test_maven_artifact_verify.py Fixed

@potiuk potiuk left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Solid, well-scoped start on #1173 with green CI — stdlib-only, offline, no subprocess or archive extraction, and the CodeQL double-report fix checks out. But check 1 can report a false PASS: an element inherited from a staged parent passes without the parent being read, and a missing licence/scm on a POM with no <parent> is downgraded to a warning. Both need fixing before this can gate an RC; details inline.

Also before merge

  • Check 3 verifies only that companion signature/checksum files exist, not their contents (inline).
  • jvm_artefact_checks and jvm_digest_set in the template aren't read anywhere yet (inline).

Smaller observations

  • tools/maven-artifact-verify/README.md — the tool is ASF-policy-specific (ALv2 requirement, Incubator disclaimer), so per AGENTS.md → Labeling it should declare **Organization:** ASF. The SPDX header comment also appears twice.
  • tools/spec-loop/specs/release-management-lifecycle.md:80 — "Step 6b" is a step inside the skill, but the surrounding parenthetical uses lifecycle step numbers; drop it there.
  • tools/dev/tests/test_check_duplication.py — an unrelated flaky-test fix; please split it into its own PR (the same fix is riding along in two other open PRs).
  • The test plan leaves the new eval suite unrun; please run tools/skill-evals for release-verify-rc and paste the summary.
  • Labels: this needs family:release-management and capability:* — I'll add them.

This review was drafted by an AI-assisted tool and
confirmed by an Apache Magpie maintainer. After you've
addressed the points above and pushed an update, an Apache Magpie
maintainer — a real person — will take the next look
at the PR. The findings cite the project's review criteria;
if you think one of them is mis-applied, please reply on the
PR and a maintainer will weigh in.

More on how Apache Magpie handles maintainer review:
CONTRIBUTING.md.

Comment thread tools/maven-artifact-verify/src/maven_artifact_verify/__init__.py Outdated
Comment thread tools/maven-artifact-verify/src/maven_artifact_verify/__init__.py
Comment thread tools/maven-artifact-verify/src/maven_artifact_verify/__init__.py Outdated
Comment thread plugins/magpie-setup/templates/release-build.md
Comment thread plugins/magpie-setup/templates/release-build.md Outdated
Comment thread tools/maven-artifact-verify/src/maven_artifact_verify/__init__.py Outdated
@potiuk potiuk added family:release-management release-* skills capability:triage Sweep + classify + propose disposition substrate:release Tool substrate: release-artefact helpers (reproducible archive build, lint, comparison) labels Sep 27, 2026
@liwenjie200543

Copy link
Copy Markdown
Contributor Author

Thanks for the thorough review — all points addressed on the branch:

Check 1 false PASS — elements now resolve against the full staged parent chain (cycle-protected, up through grandparents): the first ancestor declaring the element is judged as-is, so a staged parent carrying MIT (or an empty <scm/>) fails the child. A parentless POM with missing elements is now a hard FAIL (test_parentless_pom_with_missing_licence_fails). Negative tests added for the staged-parent-MIT, staged-parent-without-scm, grandparent-chain and cycle cases.

Check 3 contents — checksums are now verified with hashlib against the companion jar's actual bytes (test_checksum_mismatch_fails); unknown digest algorithms degrade to presence-only with an explicit finding, never a fake PASS. Companion .asc files stay presence-only offline; Step 6b now instructs extending the paste-ready recipe with gpg --verify <companion>.asc <companion> lines (same KEYS flow as Step 2), and README/SKILL say plainly what is and isn't verified.

Template keys — Step 6b now skips when jvm_artefact_checks: off, resolves --digests from jvm_digest_set when set (else § Digest set), and the template documents the unset default for jvm_companion_location.

Template issue refs — dropped the framework-internal #1172/#1173 notes from the adopter-facing template. Keeping the DISCLAIMER-file podling signal for now rather than keying off <project-stage>, since that mechanism is #1172's territory (happy to switch if you'd rather land it here).

Smaller points — README declares **Organization:** ASF and carries the SPDX header once; the "Step 6b" mention is dropped from the lifecycle spec; the test_check_duplication.py rider is reverted (your #1428 already has it — it was also the merge conflict); the tool now scans nested Maven-repository layouts with rglob (test_maven_repository_layout_is_verified).

Eval suite — the release-verify-rc fixtures were synced with the new semantics. One blocker on my side: the runner needs a model CLI and my claude -p currently returns a 402 (no balance), so I could not paste an eval summary yet — the package's pytest/ruff/mypy all pass locally (33 tests, 9 new). I'll run the eval suite and paste the summary as soon as I have a working CLI, or happy if CI can run it.

@potiuk potiuk left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks — solid turnaround. Both blockers are properly fixed: the parent chain is walked with cycle protection, a staged MIT or <scm>-less parent now fails the child, and a parentless POM missing elements is a hard FAIL, each with a test. hashlib checksum verification, the jvm_artefact_checks / jvm_digest_set wiring, rglob, the README header and Organization line, the spec wording and dropping the rider are all resolved.

Left before merge:

  1. <scm> inheritance is per-field (inline) — a child declaring only <scm><tag> is failed even when its parent supplies url / connection. That's a false FAIL on a correct POM, the case #1173 says must never happen.
  2. Template default (inline) — jvm_companion_location still ships staged in the Value column.
  3. Eval run for release-verify-rc — understood you're blocked on model credits; I'll run it on my side.

The other inline comments are non-blocking polish.


This review was drafted by an AI-assisted tool and
confirmed by an Apache Magpie maintainer. The findings
below are observations, not blockers; an Apache Magpie
maintainer — a real person — will take the next look at the
PR. If you think a finding is mis-applied, please reply on
the PR and a maintainer will weigh in.

More on how Apache Magpie handles maintainer review:
Contributing guide.

Comment thread tools/maven-artifact-verify/src/maven_artifact_verify/__init__.py Outdated
Comment thread tools/maven-artifact-verify/src/maven_artifact_verify/__init__.py Outdated
Comment thread tools/maven-artifact-verify/src/maven_artifact_verify/__init__.py Outdated
Comment thread tools/maven-artifact-verify/src/maven_artifact_verify/__init__.py Outdated
Comment thread plugins/magpie-setup/templates/release-build.md Outdated

@potiuk potiuk left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This review was drafted by an AI-assisted tool and
confirmed by an Apache Magpie maintainer. The findings
below are observations, not blockers; an Apache Magpie
maintainer — a real person — will take the next look at the
PR. If you think a finding is mis-applied, please reply on
the PR and a maintainer will weigh in.

More on how Apache Magpie handles maintainer review:
Contributing guide.

Comment thread tools/maven-artifact-verify/src/maven_artifact_verify/__init__.py
@potiuk

potiuk commented Sep 27, 2026

Copy link
Copy Markdown
Member

Ran the release-verify-rc suite against 783c328 with claude -p: 18/22 pass.

  • step-6b (new): 1/4. Cases 2–4 reach the right verdicts (MIT licence → FAIL, missing companion .asc → FAIL, INHERITED-UNVERIFIED / ABSENT as an observation), but pom_findings[] / companion_findings[] are free-text and compared exactly, because step-6b-jvm-artefacts/fixtures/grading-schema.json lists only paste_recipe and tool_report as prose fields. Please add pom_findings and companion_findings to prose_fields so the judge grades them, or switch those fields to structural assertions (see tools/skill-evals/README.md → structural assertions). With that change, 2–4 should pass on the evidence above; I'll re-run once it's pushed.
  • step-2 case-2 fails on a KEYS URL wording difference; that suite isn't touched here, so not this PR's concern.
  • Everything else passes.

(Run by an AI-assisted tool on behalf of an Apache Magpie maintainer, who confirmed this comment.)

@liwenjie200543

Copy link
Copy Markdown
Contributor Author

Thanks for running the suite and for the review. All three "left before merge" items are on the branch (783c328..8b65339), plus the four non-blocking polish comments:

  • step-6b grading (6f134ee): pom_findings / companion_findings are declared as prose fields in the step's grading-schema.json (option 1 — other suites grade findings-style list fields the same way), so they go to the judge while status/step stay exact. Ready for the re-run.
  • <scm> inheritance is per field (299c9dd): url/connection resolve independently along the staged chain, nearest non-empty declaration wins, and an empty or tag-only declaration never fails a child on its own. A tag-only child of a staged parent passes, an unstaged parent reports INHERITED-UNVERIFIED, and a complete chain supplying neither field is a hard FAIL — with the tag-only staged/unstaged tests you asked for, plus complete-chain-FAIL and empty-child-grandparent pins.
  • Template (e2b4f07): jvm_companion_location now ships as (unset).
  • Polish (8b65339): a cyclic parent chain is now a FAIL (check 1, the <scm> resolution and check 2); checksum files parse leniently, so shasum --tag's ALGO (file) = <hex> and gpg --print-md layouts match alongside the GNU coreutils one, and the docstring no longer mislabels that GNU layout as BSD-style; APACHE_LICENSE_NAME_RE accepts the SPDX id Apache-2.0 and The Apache Software License, Version 2.0 without a <url>; and artifactId/version are validated against [A-Za-z0-9_.-] before any path is built from them, so a hostile <artifactId>../../x</artifactId> can no longer point the companion checks outside the staged directory.

pytest (43 tests), ruff check, ruff format --check and mypy are all clean on the branch.

@Kaap10 Kaap10 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM on the latest iteration. All items from the previous review round are cleanly resolved:

  • Per-field <scm> inheritance (url/connection) with cycle detection.
  • Path traversal validation on <artifactId> and <version>.
  • grading-schema.json updated with prose fields for the Step 6b eval judge.
  • All 43 package unit tests pass.

The branch currently has a merge conflict with main. Please rebase on latest main so this can be merged.

…nto release-verify-rc

The JVM blocking checks agreed on in apache#1173 (checks 1-3) had no local,
offline enforcement path: release-verify-rc Step 6 covered source
tarballs only, so a staged RC could ship POMs without an ALv2 licence,
a podling without its incubation disclaimer, or companion
-sources/-javadoc jars missing their .asc signatures and checksums.

Add tools/maven-artifact-verify, a stdlib-only Python adapter that
verifies a staged directory:

- Check 1: every .pom carries an ALv2 licence, <developers> and
  <scm>. Elements absent from the POM are resolved against a locally
  staged parent POM; when that cannot resolve they are reported as
  INHERITED-UNVERIFIED (WARN), not FAIL.
- Check 2 (--podling): the incubation disclaimer inside
  <description>, accepting both the standard text and the
  DISCLAIMER-WIP variant from the Incubator distribution guide,
  tolerant of whitespace and line-wrapping. Gated by a DISCLAIMER
  file in the source tree, leaving the project_stage mechanism of
  apache#1172 untouched.
- Check 3: each staged main jar has its -sources.jar and
  -javadoc.jar companions, each companion signed (.asc) and
  checksummed. packaging=pom is exempt, classified jars (-tests,
  -shaded, ...) are never mistaken for companions, and a main jar
  not staged locally (Nexus-only publication) is recorded as an
  ABSENT observation rather than a failure.

Wire the tool in as release-verify-rc Step 6b: skipped cleanly when
no JVM artefacts are staged, keeping the existing step numbering and
every cross-reference to Steps 7-9 intact. release-build.md gains
the matching jvm_artefact_checks configuration surface, the
capability map, docs/release-management/spec.md and the spec-loop
spec are synced, and a step-6b-jvm-artefacts eval suite (4 cases)
covers the new skill behaviour.

Refs apache#1173

Generated-by: WorkBuddy (GLM-5.3-Flash)
Adding tools/maven-artifact-verify to the workspace in the previous
commit changed the member set, so `uv run --locked` in CI (skill-token-
count and every other uv-based job) rejected the stale lockfile. Re-run
`uv lock` with uv 0.12.17: the diff is the new member entry only
(16 added lines, lock revision unchanged at 3, no version bumps).

Generated-by: WorkBuddy (GLM-5.3-Flash)
…w tool

The labeler config and the generated vendor-neutrality block are
derived from the repo tree; adding tools/maven-artifact-verify made
both stale (`test_committed_config_is_in_sync` and the three
vendor-neutrality in-sync tests fail in CI).

- .github/labeler.yml: `tools/maven-artifact-verify/**` joins the
  `substrate:release` label (one line, from
  tools/dev/generate-labeler-config.py).
- docs/vendor-neutrality.md: the agent-harness section counts 29
  substrate tools and lists maven-artifact-verify as
  harness-agnostic; skill sections are unchanged.

Generated-by: WorkBuddy (GLM-5.3-Flash)
… tool

check-doc-sync caught two hand-maintained figures the Step 6b addition
made stale:

- docs/setup/marketplace.md: magpie-release-management publishes
  ~1.4k always-on tokens (verify-rc grew by the Step 6b section).
- tools/skill-evals/README.md: release-verify-rc is 22 cases across
  8 suites with the new step-6b-jvm-artefacts suite.

Generated-by: WorkBuddy (GLM-5.3-Flash)
…ompanions

CodeQL flagged two alerts on the new package; one was a real bug.

check_companions appended a PASS record in a loop `else` whose body
has no `break`, so the else ran unconditionally: a companion missing
its .asc (or checksum) was reported twice — once FAIL, once PASS.
Nothing downstream misclassified (status aggregation takes the FAIL),
but the JSON carried contradictory records for the same companion.
Collect the missing files first and branch on the result; a new
regression assertion pins one classification per companion.

The second alert was cosmetic: the POM fixture built one XML attribute
string by implicit concatenation inside a list literal; the parts are
now joined with explicit `+`.

Generated-by: WorkBuddy (GLM-5.3-Flash)
…e staged parent chain

check_pom_entries reported PASS for an element absent from the POM
itself whenever any parent POM was staged, without ever reading the
parent: a child of a staged parent declaring MIT (or no licence at
all) passed a blocking check, and the walk never went past the direct
parent. A POM with no <parent> and a missing element got the
INHERITED-UNVERIFIED warning, but nothing can be inherited there and
Maven Central rejects such a POM.

Resolution now walks the locally staged parent chain with cycle
protection: the first ancestor declaring the element is judged as-is
(the same _evaluate_element used locally), a complete chain that
supplies nothing — including a parentless POM — is a hard FAIL, and
only a chain that cannot be fully resolved offline stays
INHERITED-UNVERIFIED. check_disclaimer shares the chain, so an
inherited description is judged as-is too, and report details name the
ancestor coordinate. Negative tests cover staged-parent-MIT,
staged-parent-without-scm, parentless-missing-element, a two-level
chain resolving through the grandparent, and a parent-chain cycle.

check_companions verifies checksum files with hashlib against the
companion jar's actual bytes (still offline); unknown digest
algorithms degrade to presence-only with an explicit finding instead
of a fake PASS. .asc signatures stay presence-only offline — the Step
6b recipe extends the Step 2 gpg --verify flow to the companions — and
the README says so. A top-level-only glob misreported a staging
directory in Maven-repository layout as a non-JVM artefact set, so the
scan is rglob-based and the main jar resolves next to its own POM.

Generated-by: WorkBuddy (AI agent)
release-build.md declared two keys nothing read: Step 6b now skips
cleanly (stating the skip) when the section declares
jvm_artefact_checks: off, and resolves the recipe's --digests from
jvm_digest_set when it is set, falling back to the Digest set. The
template documents the unset default for jvm_companion_location
(observation-only, same as nexus-staging) so copying the example value
staged is a deliberate opt-in to the stricter mode.

Step 6b text now describes the parent-chain resolution and the
companion checksum verification as the tool implements them, extends
the paste-ready recipe with gpg --verify lines for companion .asc
files, and drops the bare apache#1172/apache#1173 references from the
adopter-facing template (a bare #NNN resolves against the adopter's
tracker once the template is copied). The lifecycle spec keeps its
lifecycle step numbers only. The eval fixtures' tool-report excerpts
and the output spec are synced with the new detail strings and the
jvm_digest_set rule, and the measured_tokens stamp is re-measured.

Generated-by: WorkBuddy (AI agent)
A maintainer run of the release-verify-rc suite scored step-6b 1/4:
cases 2-4 reached the right verdicts but failed on pom_findings /
companion_findings, which the step's grading schema did not list as
prose fields, so the model's one-line paraphrases of the tool report
were compared verbatim against expected.json. The output spec defines
both as one-line model-written findings, not verbatim tool output, so
they belong to the semantic grader alongside paste_recipe and
tool_report; status and step stay exact. The suite README's
grading-methodology paragraph named only paste_recipe; state the
mechanism instead.
…chain

Maven merges <scm> per field: a child declaring only <scm><tag> still
inherits url/connection from an ancestor. The tool judged any local
<scm> in isolation, so such a child was a hard FAIL both when a staged
parent supplied the fields and when the parent was unstaged (where
INHERITED-UNVERIFIED is the honest answer) - a false FAIL on a correct
POM, the case apache#1173 says must never happen.

url/connection now resolve independently along the staged chain
(nearest non-empty declaration wins; empty and tag-only declarations
never fail a child on their own). Either field resolvable is a PASS;
neither field anywhere in a complete chain is a hard FAIL. <licenses>
and <developers> stay element-level.
…mplate

The Value column shipped staged, so an adopter copying the template
verbatim was opted into strict mode, where a locally absent jar is a
FAIL. Unset matches the documented default (same as nexus-staging: an
absent jar is an observation) and mirrors jvm_digest_set.
…ents

Four small review follow-ups:

- A cyclic parent chain is a FAIL, not INHERITED-UNVERIFIED: Maven
  refuses to build one, so it cannot be a correct POM inheriting from
  the ASF parent - the case the warning protects. Applies to check 1
  (licences/developers), the <scm> per-field resolution and check 2.
- Checksum files are parsed leniently: the hex digest is extracted by
  shape, so the BSD/tagged 'ALGO (file) = <hex>' (shasum --tag) and
  'gpg --print-md' layouts match like the GNU coreutils one already
  did. The old docstring called the GNU layout BSD-style; fixed.
- APACHE_LICENSE_NAME_RE also accepts the SPDX id 'Apache-2.0' and the
  legacy 'The Apache Software License, Version 2.0' wording, which
  previously only passed via the URL regex.
- artifactId/version are validated against Maven's [A-Za-z0-9_.-]
  before a path is built from them, so a POM with <artifactId>../../x
  can no longer point the companion checks outside the staged
  directory; that POM's jar checks are skipped with a finding instead.
Rebasing onto main pulled the upstream edits to release-verify-rc into
the merged file, so the generated stamps no longer describe it:
recompute surface_hash and measured_tokens, and bump the agent-harness
count to 30/30 now that maven-artifact-verify is part of the tree the
count measures.

Generated-by: WorkBuddy (AI agent)
@liwenjie200543

Copy link
Copy Markdown
Contributor Author

Rebased onto latest main and force-pushed (8b653391 → 05e2af4f). Notes on the rebase:

  • docs/vendor-neutrality.md: kept both contributor-metrics (landed upstream meanwhile) and maven-artifact-verify (this PR) in the any-harness list (now 27), and bumped the agent-harness count to 30/30.
  • The release-verify-rc generated stamps were recomputed against the merged content: surface_hash: sha256:ed944a58facaae21, measured_tokens: 12380 — verified with the repo's own tooling.
  • Dropped the test_check_duplication.py order-independence commit from the series: the same flake was already fixed upstream via fix(dev): make the pre-flight dedup test independent of glob order #1428 with a sorted()-based scan, so carrying it would have been redundant.

Full CI is green on the new head (52/52 checks, including the pytest matrix, prek, and the token-count measure job); the branch now merges cleanly.

Resolve workspace member conflict in pyproject.toml after apache#1466.

Co-authored-by: Arnav <imarnavpurohit@gmail.com>
@onlyarnav
onlyarnav force-pushed the jvm-artefact-verify-rc branch from 90ebbc0 to 65f489b Compare October 2, 2026 05:47

@onlyarnav onlyarnav left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

- maven-artifact-verify: when no contiguous hex run is found, rejoin
  the digest after the last ':' so real `gpg --print-md` output
  (upper-case 8-char groups, wrapped with a hanging indent) verifies
  instead of reporting a mismatch on a correct companion. Tests now use
  the real grouped, wrapped layout, plus a wrong-digest case that still
  fails.
- verify-rc Step 6b: resolve `<framework>` in the paste-ready recipe;
  emit a companion `gpg --verify` line only when its `.asc` is staged;
  `pom_findings` / `companion_findings` list only checks that did not
  pass. measured_tokens restamped.
- step-6b eval fixtures: expected recipes include the companion
  `gpg --verify` lines the step requires. Suite is 4/4.

Generated-by: Claude Opus 5

@potiuk potiuk left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving — thanks for working through both rounds. Everything I raised is fixed: the parent chain is walked with cycle protection and negative tests, a parentless POM with missing elements is a hard FAIL, checksums are verified with hashlib, the template keys are read, <scm> resolves per field, Apache-2.0 passes without a <url>, coordinates are validated before any path is built, and both CodeQL alerts are closed. I've resolved my threads.

I pushed one fixup commit (ac8ffe2) so this can land now:

  • gpg --print-md checksum files — real gpg output prints the digest in upper-case groups of 8 hex characters, wrapped with a hanging indent, so the contiguous-run search found nothing and a correct companion was reported as a mismatch. When no contiguous run is found, the tool now rejoins the digest after the last :. The tests use the real grouped, wrapped layout, plus a wrong-digest case that still fails.
  • Step 6b wording — the recipe now resolves <framework>; it emits a companion gpg --verify line only when that companion's .asc is staged (a missing .asc is already a finding); and pom_findings / companion_findings list only checks that did not pass. measured_tokens restamped.
  • Step-6b fixtures — the expected recipes include the companion gpg --verify lines the step asks for.

Eval re-run (as promised): release-verify-rc on the original head was 19/22; with the fixup, step-6b is 4/4. The remaining failure, step-2-verify-signatures/case-2-tampered-sig (a KEYS-URL variant, dist.apache.org vs downloads.apache.org), predates this PR. prek run --all-files is green.

Nits for a follow-up, not blocking:

  • A cyclic parent chain is reported only when some element is left unresolved; if every element is declared before the cycle point, the report is PASS and the cycle goes unmentioned. Maven would refuse to build such a set anyway, so a one-line finding whenever chain_reason == "cycle" would be enough.
  • Two staged POMs with the same GAV in different subdirectories silently overwrite each other in the coordinate index — worth a warning.

This review was drafted by an AI-assisted tool and
confirmed by an Apache Magpie maintainer. The maintainer
approving this PR has read the findings and signed off. If
something feels off, please reply on the PR and a maintainer
will follow up.

More on how Apache Magpie handles maintainer review:
CONTRIBUTING.md.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

capability:triage Sweep + classify + propose disposition family:release-management release-* skills substrate:release Tool substrate: release-artefact helpers (reproducible archive build, lint, comparison)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants