Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
14 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/labeler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ substrate:release:
- any:
- changed-files:
- any-glob-to-any-file:
- 'tools/maven-artifact-verify/**'
- 'tools/reproducible-archive/**'

substrate:review:
Expand Down
3 changes: 2 additions & 1 deletion docs/labels-and-capabilities.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ framework substrate:
| `substrate:action-guard` | substrate | Deterministic pre-tool-use command guards. |
| `substrate:privacy` | substrate | PII redaction / approved-LLM gating. |
| `substrate:framework-dev` | substrate | Build / validate / eval the framework itself. |
| `substrate:release` | substrate | Release-artefact helpers an adopter's release process runs: reproducible-archive build, lint and comparison. |
| `substrate:release` | substrate | Release-artefact helpers an adopter's release process runs: reproducible-archive build, lint and comparison; maven-artifact-verify for staged JVM artefacts. |
| `substrate:setup` | substrate | Adopter-side setup state an agent resolves at runtime rather than at development time: lock parsing, floor comparison, reconciliation fingerprints. |
| `substrate:review` | substrate | A second model's read of a change before it is published: other models' CLIs run read-only, findings merged. |

Expand Down Expand Up @@ -362,6 +362,7 @@ or a contract-free mix of substrates (e.g. `tools/spec-inventory` is
| [`tools/vendor-neutrality-score`](../tools/vendor-neutrality-score/) | `substrate:framework-dev` + `substrate:analytics` | Deterministic vendor-neutrality score — reads each contract tool's `**Kind:**` / `**Vendor:**` metadata and scores per-contract + per-skill neutrality (`analytics`); backs the score block in [`docs/vendor-neutrality.md`](vendor-neutrality.md) |
| [`tools/spec-validator`](../tools/spec-validator/) | `substrate:framework-dev` | Spec-frontmatter and body-section validator — counterpart to `skill-and-tool-validator` for `tools/spec-loop/specs/` |
| [`tools/reproducible-archive`](../tools/reproducible-archive/) | `substrate:release` | `repro-archive` — build, lint and compare reproducible source archives from a git ref (`git archive` + `.gitattributes` `export-ignore`, every reproducible-builds.org archive rule applied); used by `release-rc-cut` Step 2/2b and `release-verify-rc` Step 9 |
| [`tools/maven-artifact-verify`](../tools/maven-artifact-verify/) | `substrate:release` | `maven-artifact-verify` — verify locally staged JVM RC artefacts: POM ALv2 licence / developers / scm (with parent-POM inheritance resolution), podling incubation disclaimer in `<description>`, companion `-sources.jar` / `-javadoc.jar` presence with their own signatures and checksums; used by `release-verify-rc` Step 6b |
| [`tools/symlink-lint`](../tools/symlink-lint/) | `substrate:framework-dev` | Self-adoption symlink hygiene — rejects cyclic symlinks, misdirected skill relays (canonical/relay target-correctness), and incomplete self-adoption symlink sets |
| [`tools/pilot-report-validator`](../tools/pilot-report-validator/) | `substrate:framework-dev` | Adopter pilot-report validator — required frontmatter keys, no unfilled placeholders, valid profile, and required body sections; counterpart to `spec-validator` for `docs/pilot-report-template.md` |
| [`tools/skill-reconciler-diff`](../tools/skill-reconciler-diff/) | `substrate:framework-dev` | Deterministic structural diff between two skill trees — parses frontmatter, section headings, step inventory, placeholders, support files, and safety-baseline clauses into a JSON diff object for the `skill-reconciler` skill |
Expand Down
7 changes: 5 additions & 2 deletions docs/release-management/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -408,8 +408,11 @@ loop before posting `+1`.

- A pass/fail report per check (signatures, checksums, license
headers via Apache RAT, NOTICE / LICENSE presence + diff vs
previous release, no prohibited binaries, source-tree integrity,
version-string consistency, and — optional per
previous release, no prohibited binaries, published-JVM-artefact
compliance via `tools/maven-artifact-verify` — POM licence set,
podling incubation disclaimer, companion `-sources.jar` /
`-javadoc.jar` with signatures and checksums — source-tree
integrity, version-string consistency, and — optional per
`release-build.md § Reproducibility checks` — reproducibility: the
source artefact rebuilt from the tag with `repro-archive build` at
the recorded `SOURCE_DATE_EPOCH` and compared (`identical` /
Expand Down
2 changes: 1 addition & 1 deletion docs/setup/marketplace.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ can say so, because it is the floor everything else is managed from.
|---|---|---|
| `magpie-security` | 15 | ~1.1k |
| `magpie-setup` | 10 | ~0.7k |
| `magpie-release-management` | 10 | ~1.3k |
| `magpie-release-management` | 10 | ~1.4k |
| `magpie-pr-management` | 8 | ~0.8k |
| `magpie-issue` | 8 | ~0.7k |
| `magpie-repo-health` | 7 | ~0.7k |
Expand Down
5 changes: 3 additions & 2 deletions docs/vendor-neutrality.md
Original file line number Diff line number Diff line change
Expand Up @@ -595,7 +595,7 @@ Organization scope (declared, orthogonal to vendor): ASF = 16, agnostic = 62.

**LLM / agent-integration neutrality**

**Agent harness: 29/29 substrate tools run under any harness unchanged (100%).** Substrate tools are Magpie's own machinery; each declares the agent harness it integrates with (`**Harness:**`), or `agnostic`. A tool is neutral when it is harness-agnostic or supports two or more harnesses; *coupled* when it targets a single harness.
**Agent harness: 30/30 substrate tools run under any harness unchanged (100%).** Substrate tools are Magpie's own machinery; each declares the agent harness it integrates with (`**Harness:**`), or `agnostic`. A tool is neutral when it is harness-agnostic or supports two or more harnesses; *coupled* when it targets a single harness.

| Substrate tool | Substrate | Harness support | Verdict |
|---|---|---|---|
Expand All @@ -607,6 +607,7 @@ Organization scope (declared, orthogonal to vendor): ASF = 16, agnostic = 62.
| `dashboard-generator` | analytics | any | ✅ agnostic |
| `dev` | framework-dev | any | ✅ agnostic |
| `egress-gateway` | sandbox | any | ✅ agnostic |
| `maven-artifact-verify` | release | any | ✅ agnostic |
| `permission-audit` | sandbox | any | ✅ agnostic |
| `pilot-report-validator` | framework-dev | any | ✅ agnostic |
| `pr-management-stats` | analytics | any | ✅ agnostic |
Expand Down Expand Up @@ -637,7 +638,7 @@ Harness → substrate tools it supports:
- **Gemini CLI** (3): `agent-guard`, `sandbox-lint`, `spec-loop`
- **Kiro** (3): `agent-guard`, `sandbox-lint`, `spec-loop`
- **OpenCode** (3): `agent-guard`, `sandbox-lint`, `spec-loop`
- **any harness** (26): `adversarial-review`, `agent-isolation`, `container-gateway`, `contributor-metrics`, `dashboard-generator`, `dev`, `egress-gateway`, `permission-audit`, `pilot-report-validator`, `pr-management-stats`, `preflight-audit`, `privacy-llm`, `probe-templates`, `reproducible-archive`, `security-tracker-stats-dashboard`, `setup-preflight`, `skill-and-tool-validator`, `skill-evals`, `skill-reconciler-diff`, `skill-token-count`, `spec-inventory`, `spec-status-index`, `spec-validator`, `symlink-lint`, `vendor-neutrality-score`, `vetted-ops`
- **any harness** (27): `adversarial-review`, `agent-isolation`, `container-gateway`, `contributor-metrics`, `dashboard-generator`, `dev`, `egress-gateway`, `maven-artifact-verify`, `permission-audit`, `pilot-report-validator`, `pr-management-stats`, `preflight-audit`, `privacy-llm`, `probe-templates`, `reproducible-archive`, `security-tracker-stats-dashboard`, `setup-preflight`, `skill-and-tool-validator`, `skill-evals`, `skill-reconciler-diff`, `skill-token-count`, `spec-inventory`, `spec-status-index`, `spec-validator`, `symlink-lint`, `vendor-neutrality-score`, `vetted-ops`

**Model endpoint: neutral by construction — 4 default-approved endpoint classes across independent trust domains, plus adopter opt-in.** From the [`privacy-llm` registry](../tools/privacy-llm/models.md): the framework keys approval on *endpoint identity*, not on who hosts the model, so no single LLM vendor is privileged.

Expand Down
124 changes: 120 additions & 4 deletions plugins/magpie-release-management/skills/verify-rc/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@ description: |
for `<upstream>`. Checks artefact integrity (GPG signatures and
checksums), Apache RAT licence headers, NOTICE/LICENSE completeness,
prohibited-binary absence (including `.pyc` / `__pycache__`),
source-tree integrity (no dangling symlinks or broken internal
references), version-string consistency, and — optionally, per
published-JVM-artefact compliance (POM licence/developers/scm,
podling incubation disclaimer, companion `-sources.jar` /
`-javadoc.jar` with their own signatures and checksums), source-tree
integrity (no dangling symlinks or broken internal references),
version-string consistency, and — optionally, per
`release-build.md § Reproducibility checks` — reproducibility: the
source archive is rebuilt from the tag with `repro-archive` and
compared byte-for-byte with the staged artefact, and convenience
Expand All @@ -32,9 +35,9 @@ when_to_use: |
run standalone with no other release-* skill in the session.
argument-hint: "<version>-rcN [--post-to <planning-issue-url>] [--skip-repro] [--trusted-hardware]"
capability: capability:triage
surface_hash: sha256:42f7f872b6dcd0e8
surface_hash: sha256:ed944a58facaae21
license: Apache-2.0
measured_tokens: 10725
measured_tokens: 12502
---

<!-- SPDX-License-Identifier: Apache-2.0
Expand Down Expand Up @@ -550,6 +553,107 @@ tarball was not exported clean from the tag.

---

## Step 6b — JVM artefact checks (when the RC stages jars)

**When it runs.** Only when the Step 1 listing contains at least one
`.jar` or `.pom`, and only when `release-build.md § JVM artefact
checks` does not declare `jvm_artefact_checks: off` (absent or `on`
means run). A non-JVM project's RC, or a project that has turned the
checks off, skips this step cleanly — state the skip explicitly, do
not silently pass.

Step 6 treats a `.jar` as contraband inside the **source** artefact.
The jars downstream consumers actually resolve are a separate surface:
the published `.pom` files, the main jars, and their companion
`-sources.jar` / `-javadoc.jar`. This step validates that surface with
the [`maven-artifact-verify`](../../../../tools/maven-artifact-verify/README.md)
tool — blocking checks 1–3 of
[issue #1173](https://github.com/apache/magpie/issues/1173), which
implement [ASF Incubator distribution policy § Maven
distribution](https://incubator.apache.org/guides/distribution.html)
and [Maven Central's publishing
requirements](https://central.sonatype.org/publish/requirements/):

1. **POM licence entry** — every `.pom` declares ALv2, `<developers>`
and `<scm>`. An element absent from the POM itself resolves against
the chain of locally staged parent POMs: the first ancestor
declaring the element is judged as-is, so a staged parent carrying
a non-ALv2 licence fails the child too. An element no staged
ancestor declares when the chain ends at a POM with no `<parent>`
— including a POM with no `<parent>` at all — is a `FAIL`, the
same judgement Maven Central applies. `INHERITED-UNVERIFIED` — a
warning naming what to verify — is reserved for a chain that
cannot be fully resolved offline; it never fails a correct POM
that inherits from the ASF parent.
2. **Incubator disclaimer in `<description>`** — podlings only, when
`--podling` is passed. Accepts the standard disclaimer text and the
`DISCLAIMER-WIP` variant, tolerating whitespace and line-wrapping.
An inherited description is judged the same way as a local one.
3. **Companion jars** — for every main jar staged locally,
`-sources.jar` and `-javadoc.jar` exist and each carries its own
`.asc` and checksums, the checksums verified against the jar's
actual bytes. Offline the tool checks `.asc` presence only:
extend the paste-ready recipe with one `gpg --verify <companion>.asc
<companion>` line per companion whose `.asc` is staged (same `KEYS`
flow as Step 2) so the companions get the same signature
verification as the main artefacts; a companion with no `.asc` is
already a finding and gets no line. A main
jar declared by a staged POM but not staged locally is an
observation (`ABSENT`), not a failure: in the common ASF workflow
the jars are staged in the Nexus staging repository, which this
step never reads (read-only, and check 4 is a later PR on
[#1173](https://github.com/apache/magpie/issues/1173)). Classify an
`ABSENT` jar against `release-build.md § JVM artefact checks` —
when that file declares `jvm_companion_location: staged`, an
absent jar is a `FAIL`.

Emit the paste-ready recipe. Resolve every placeholder to a concrete
value: `<framework>` is the framework root (`.apache-magpie` in an
adopter repository), `<staged-dir>` is the local directory holding the staged RC
artefacts, `<digest-set>` is the `jvm_digest_set` key of
`release-build.md § JVM artefact checks` when it is set, otherwise the
§ Digest set (comma-separated, default `sha512`), and pass
`--podling` **only** when the unpacked source artefact ships a
`DISCLAIMER` or `DISCLAIMER-WIP` file at its root — that is the
podling signal this step uses until the `project_stage` plumbing
lands.

```bash
uv run --project <framework>/tools/maven-artifact-verify \
maven-artifact-verify "<staged-dir>" --digests <digest-set> [--podling]
# without uv:
# python3 <framework>/tools/maven-artifact-verify/src/maven_artifact_verify/__init__.py ...
```

The step never modifies anything: the tool is offline and reads the
staged directory only, so any voter may run it.

Return ONLY valid JSON with this structure:

```json
{
"step": "jvm-artefacts",
"status": "PASS" | "WARN" | "FAIL" | "SKIP",
"tool_report": "<the maven-artifact-verify JSON report verbatim>",
"pom_findings": ["<one line per POM finding>"],
"companion_findings": ["<one line per jar finding>"],
"paste_recipe": "<multi-line shell commands>"
}
```

`pom_findings` and `companion_findings` list only the checks that did
not pass (`FAIL`, `INHERITED-UNVERIFIED`, `ABSENT`), one line each
naming the artefact and what is wrong; a passing check is not a
finding, and an empty list means there is nothing to report.

`status` is the tool report's `status`, except that an `ABSENT` jar
becomes `FAIL` when `release-build.md § JVM artefact checks` declares
`jvm_companion_location: staged` (the RC was expected to stage it).
`SKIP` when no jars or POMs are staged, or when the section declares
`jvm_artefact_checks: off`.

---

## Step 7 — Source-tree integrity (dangling symlinks + broken references)

A source archive can be signed, checksummed and licence-clean and
Expand Down Expand Up @@ -914,6 +1018,11 @@ the RM has not yet confirmed posting.
| Step 5 WARN — material diff | Licence or attribution changed vs previous release | RM reviews diff; if intentional, document in planning issue |
| Step 6 FAIL — prohibited binary | Binary sneaked into source artefact | RM removes binary, updates `.gitattributes` or build excludes, cuts new RC |
| Step 6 FAIL — `.pyc` / `__pycache__` present | Tarball zipped from a working tree that ran tests, not exported clean from the tag | RM rebuilds via `git archive <tag>` (never `zip -r`), cuts new RC |
| Step 6b FAIL — POM licence/developers/scm wrong | The POM does not satisfy ASF Incubator distribution policy § Maven distribution | RM fixes the POM, re-deploys, re-cuts RC |
| Step 6b FAIL — companion jar or its `.asc`/checksum missing | Maven Central requires `-sources.jar` / `-javadoc.jar` companions, each signed and checksummed; Nexus close-time validation fails without them | RM re-deploys with signed companions, re-cuts RC |
| Step 6b FAIL — companion checksum mismatch | The recorded digest does not match the companion jar's bytes (stale or corrupted checksum file) | RM re-deploys the companion set with regenerated checksums, re-cuts RC |
| Step 6b WARN — `INHERITED-UNVERIFIED` | POM element inherited from a parent POM that is not staged locally | Verify against the effective POM (`mvn help:effective-pom`); if correct, no action |
| Step 6b FAIL — jar absent but `jvm_companion_location: staged` | The RC was expected to stage its jars locally and did not | RM re-stages the jar set or corrects `release-build.md` |
| Step 7 FAIL — dangling symlink | A committed symlink's target was stripped by `export-ignore` (or is otherwise absent) | RM fixes `.gitattributes` to ship the target (or drops the symlink), cuts new RC |
| Step 7 FAIL — broken internal reference | A shipped file links to a path stripped from the artefact | RM stops stripping the referenced path, or repoints the reference at shipped content, cuts new RC |
| Step 8 FAIL — version mismatch | Version bump missed one manifest file | RM fixes the manifest and cuts a new RC |
Expand Down Expand Up @@ -943,6 +1052,13 @@ the RM has not yet confirmed posting.
checks, and the 🪶 ASF-specific automated-signing validation.
- [`tools/reproducible-archive`](../../../../tools/reproducible-archive/README.md) —
`repro-archive check` / `build` / `compare`.
- [`tools/maven-artifact-verify`](../../../../tools/maven-artifact-verify/README.md) —
the JVM-artefact checker behind Step 6b (blocking checks 1–3 of
[issue #1173](https://github.com/apache/magpie/issues/1173)).
- [ASF Incubator distribution guidelines § Maven distribution](https://incubator.apache.org/guides/distribution.html) —
the policy behind the Step 6b POM and disclaimer checks.
- [Maven Central publishing requirements](https://central.sonatype.org/publish/requirements/) —
the mandatory sources/javadoc companions behind Step 6b check 3.
- [reproducible-builds.org § Archive metadata](https://reproducible-builds.org/docs/archives/) —
the rules `repro-archive check` verifies.
- `release-keys-sync` (proposed) — remediation path when a signing
Expand Down
27 changes: 27 additions & 0 deletions plugins/magpie-setup/templates/release-build.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
- [Source-tree validators](#source-tree-validators)
- [Expected artefact list](#expected-artefact-list)
- [Digest set](#digest-set)
- [JVM artefact checks](#jvm-artefact-checks)
- [Reproducibility checks](#reproducibility-checks)
- [Binary-exclude list](#binary-exclude-list)
- [Apache RAT configuration](#apache-rat-configuration)
Expand Down Expand Up @@ -189,6 +190,32 @@ Example shape:
> - `sha512`, required.
> - `sha256`, published for downstream-tool compatibility.

## JVM artefact checks

Optional, and relevant only when the release publishes Maven
artefacts. `release-verify-rc` Step 6b verifies the staged `.pom`
files (ALv2 licence, `<developers>`, `<scm>`, podling incubation
disclaimer in `<description>`) and — for jars staged locally — the
companion `-sources.jar` / `-javadoc.jar` set with their signatures
and checksums, via
[`tools/maven-artifact-verify`](../../../tools/maven-artifact-verify/README.md).
When the staged artefact set contains no `.jar` and no `.pom`, the
step skips cleanly and nothing here needs to be configured.

| 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) |
Comment thread
potiuk marked this conversation as resolved.
| `jvm_companion_location` | *(unset)* | `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` |
| `jvm_digest_set` | *(unset)* | digests each companion must carry; unset means the § Digest set above applies as-is |

Model the companion set in § Expected artefact list too: for a
`kind: jar` convenience artefact, name the `.pom`,
`-sources.jar` and `-javadoc.jar` companions expected alongside it,
so a missing companion is caught by the Step 1 inventory as well.

The incubation-disclaimer check is gated on the podling signal (a
`DISCLAIMER` / `DISCLAIMER-WIP` file at the source artefact root).

## Reproducibility checks

Optional checks that `release-rc-cut` (Step 2b, RM self-check) and
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ members = [
"tools/jira",
"tools/maildir",
"tools/mail-source/imap",
"tools/maven-artifact-verify",
"tools/permission-audit",
"tools/pr-management-stats",
"tools/preflight-audit",
Expand Down
Loading
Loading