Skip to content

feat: ship the SARIF taxonomy as a verified catalog release asset - #443

Merged
chaksaray merged 1 commit into
developfrom
feat/taxonomy-release-asset
Nov 4, 2026
Merged

chaksaray merged 1 commit into
developfrom
feat/taxonomy-release-asset

Conversation

@chaksaray

Copy link
Copy Markdown
Contributor

Closes #442.

Ships the SARIF taxonomy as a verified catalog-release asset, ave-taxonomy.json, built by the catalog-release workflow from the release's own records, listed in SHA256SUMS, attested with the other data files, and verified by scripts/check_release_assets.py by regenerating it and demanding a byte match. The first release that carries it is v1.3.0, and v1.3.0 must not be cut before this merges: from v1.3.0 the verifier requires the file, so a workflow that does not build it fails its own verification.

What changed

  • Workflow (catalog-release.yml): after the records and manifest, python3 scripts/build_taxonomy.py --records release/ave-records.json --release "v$VERSION" --release-date <the manifest's generated_at date> --download-uri <the asset's own URL> --out release/ave-taxonomy.json; SHA256SUMS covers three files; the verifier gets --repo "$GITHUB_REPOSITORY"; the attestation and the release upload include the taxonomy. It never runs the workflow, creates a tag or a release.
  • Verifier (check_release_assets.py): check_taxonomy regenerates the taxonomy from ave-records.json and compares bytes; when it differs it names the header field, then the taxon, that differs, before the generic "same content, different bytes" message. TAXONOMY_FROM = (1, 3, 0): from that tag a missing file is an error and SHA256SUMS must list it; v1.0.0 to v1.2.0 verify without it (and are checked like any other if they have one). New --repo owner/name (default aveproject/ave): the taxonomy's downloadUri must point at the repository it is published under. Standard library only.
  • Two old tests use the tag v1.2.9 instead of v9.9.9: they test "a tag missing from the repository" and used a tag at or above v1.3.0, where the taxonomy is now (correctly) required.
  • Docs: scaling-and-governance section 6 (the asset, the verification, why it is required from v1.3.0, both stable URLs), the README's "Releases and pinning", the AVE-in-SARIF taxonomy section (the release asset is the pinned copy to embed; dist/ave-taxonomy-latest.json is the moving one), the implementer guide, CHANGELOG.

Checked

  • python -m pytest tests -q: 1041 passed, 1 skipped. 70 in the three release files (33 existing verifier tests, 30 new in tests/test_release_taxonomy.py, 7 in tests/test_catalog_release_workflow.py).
  • The workflow's own run: blocks, extracted and executed for VERSION=1.3.0 (npm ci, then the node build, jq -r '.generated_at[:10]', the taxonomy generation, sha256sum, and the verifier): exit 0, AVE v1.3.0: 89 records on schema 1.3.0, checksums match, source_commit 0753b2d... (checked against the given commit). ave-taxonomy.json regenerated from the records and matches (89 taxa). The taxonomy came out stamped 1.3.0, dated 2026-11-04, with https://github.com/aveproject/ave/releases/download/v1.3.0/ave-taxonomy.json, and sha256sum -c SHA256SUMS was OK for all three files.
  • Four tampering scenarios, each with SHA256SUMS refreshed so only the content was wrong, each exit 1:
    1. a renamed taxon: ave-taxonomy.json taxon AVE-2026-00004 is not what ave-records.json produces
    2. ave-taxonomy.json deleted: SHA256SUMS does not list ave-taxonomy.json and ave-taxonomy.json is missing (releases from v1.3.0 carry it)
    3. downloadUri set to https://example.org/x.json: ave-taxonomy.json downloadUri is 'https://example.org/x.json', expected 'https://github.com/aveproject/ave/releases/download/v1.3.0/ave-taxonomy.json'
    4. a record title edited and the manifest sha256 updated without regenerating the taxonomy: ave-taxonomy.json taxon AVE-2026-00046 is not what ave-records.json produces
  • Mutations: 28 killed, 0 survived (the verifier's boundary, sums wiring, date, URL, tag, byte comparison, each of missing, extra and changed taxa, repository option, crash handling and success message; the workflow's build, ordering, checksums, URL, date source, --repo, attestation, upload, and an input interpolated into a command), run with PYTHONDONTWRITEBYTECODE=1; both edited files were restored byte for byte.
  • validate_records.py, build_taxonomy.py --check and check_terms_sync.py pass. records/, schema/ and dist/ are untouched. No em dashes added.

Not run

  • The workflow on GitHub, and gh attestation verify on the taxonomy asset. Run that once on the v1.3.0 draft before anyone is told the taxonomy is attested.
  • A release was not cut, and no tag was created.
  • The verifier on Python 3.8: both scripts parse under the 3.8 grammar and the verifier keeps its from __future__ import annotations, but I ran 3.12 only.
  • Small differences from the task's environment: jq 1.7 was already on the machine (not 1.7.1); the runner's python command is not on this machine, so the dry run put an alias to python3 on the PATH and left the workflow's text as it is.

After merge (maintainer)

When v1.3.0 is cut: run Actions > catalog-release with draft=true; check the draft has the four files (records, manifest, taxonomy, SHA256SUMS); then from a clean directory run sha256sum -c SHA256SUMS, python scripts/check_release_assets.py . --tag v1.3.0 --repo aveproject/ave, and gh attestation verify ave-taxonomy.json --repo aveproject/ave.

@chaksaray chaksaray linked an issue Nov 4, 2026 that may be closed by this pull request
@chaksaray
chaksaray merged commit 1c58e8c into develop Nov 4, 2026
6 checks passed
@chaksaray
chaksaray deleted the feat/taxonomy-release-asset branch November 4, 2026 15:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Ship the SARIF taxonomy as a verified catalog release asset

1 participant