Skip to content

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

Open
liwenjie200543 wants to merge 12 commits into
apache:mainfrom
liwenjie200543:jvm-artefact-verify-rc
Open

liwenjie200543 wants to merge 12 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

| Key | Value | Notes |
|---|---|---|
| `jvm_artefact_checks` | `on` | `on` (default) — run Step 6b whenever the staged set contains jars or POMs; `off` — skip (e.g. the project stages jars only through a platform checked elsewhere) |

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.

jvm_artefact_checks: off and jvm_digest_set are never read: Step 6b reads only jvm_companion_location and § Digest set, so adopters get settings that do nothing. Please wire both into Step 6b (skip when off; pass jvm_digest_set as --digests) or drop them. Also, the example value staged for jvm_companion_location turns ABSENT into FAIL, while an unset value means observation-only, so copying the template silently opts into the stricter mode. Please state the unset default explicitly.

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.

if pom["developers"]:
return True, None
return False, "<developers> declared but empty"
scm = pom["scm"]

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.

Maven merges <scm> per field — a child declaring only <scm><tag>v1.0</tag></scm> still inherits url/connection from its parent. Here any local <scm> is judged alone, so that child is a hard FAIL (<scm> declared without url or connection) — both when a staged parent supplies them and when the parent isn't staged (where it should be INHERITED-UNVERIFIED). Please resolve url/connection per field along the chain (nearest non-empty ancestor wins, INHERITED-UNVERIFIED if the chain is unstaged), with tests for a tag-only child with a staged and an unstaged parent.

entries[key + "_detail"] = "element absent and no parent POM in the staged chain declares it"
else:
detail = "element absent and the parent chain is not fully staged locally; verify against the effective POM"
if chain_reason == "cycle":

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.

A cyclic parent chain is a broken staged set (Maven refuses to build it), so it can't be "a correct POM inheriting from the ASF parent" — the case INHERITED-UNVERIFIED protects. I'd make cycle a FAIL.

algorithm this Python's ``hashlib`` does not provide (the file is
still required, but its content cannot be checked offline). The
file is parsed leniently: the first whitespace-separated token is
the recorded digest, tolerating a trailing newline or a BSD-style

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.

<digest> <filename> is the GNU coreutils format, not BSD-style. The real BSD/tagged form (SHA512 (file) = <hex>, from shasum --tag) and gpg --print-md output (still published by some ASF projects) give a false "checksum mismatch". Please fix the docstring and state the accepted format, or extract the hex digest leniently.

"has yet to be fully endorsed by the asf",
]

APACHE_LICENSE_NAME_RE = re.compile(r"apache\s+license.*2\.0", re.IGNORECASE)

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.

APACHE_LICENSE_NAME_RE misses the SPDX id Apache-2.0 and The Apache Software License, Version 2.0 — those only pass today via the URL regex, so <name>Apache-2.0</name> with no <url> FAILs.

| Key | Value | Notes |
|---|---|---|
| `jvm_artefact_checks` | `on` | `on` (default) — run Step 6b whenever the staged set contains jars or POMs; `off` — skip (e.g. the project stages jars only through a platform checked elsewhere) |
| `jvm_companion_location` | `staged` | `staged` — the companion `.pom` / `-sources.jar` / `-javadoc.jar` set is staged with the RC and must be present, each companion signed and checksummed; `nexus-staging` — the jars publish through the Nexus staging repository only, so a locally absent jar is an observation, not a failure; *(unset)* — same as `nexus-staging` |

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 for documenting the unset default — but the Value column still ships staged, so copying the template verbatim still opts an adopter into strict mode. Please make it *(unset)*, like jvm_digest_set.

@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.

# The main jar lives in the POM's own directory (in Maven
# repository layout that is the versioned subdirectory, not
# the staged root).
main = pom_path.parent / f"{data['artifact_id']}-{data['version']}.jar"

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.

artifact_id / version come from the staged POM and go straight into a path here, so a POM with <artifactId>../../x</artifactId> makes the tool stat and hash files outside the staging directory. Low impact, since nothing leaves the machine, but cheap to close: reject coordinates that don't match Maven's [A-Za-z0-9_.-]+ before building paths.

@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.

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.

4 participants