Primary issue: release binaries stopped shipping after v0.5.0
Every loom release from v0.6.0 through v1.1.1 has zero release assets — only the v0.3.0 era tags carry the loom-{platform}.tar.gz archives. Downstream (rules_wasm_component is pinned at v0.3.0) cannot move forward until the release workflow's asset-upload step is restored.
v1.1.1 2026-05-23 → assets=0
v1.1.0 2026-05-22 → assets=0
v1.0.5 → v0.6.0 → assets=0 (every one)
v0.5.0 → v0.3.0 → assets present
Looks like the asset-upload step in the release workflow was lost or made conditional. Please restore it.
Secondary: adopt the unified artifact standard while you're in there
Background
Across the six PulseEngine release pipelines (loom, meld, sigil, spar, synth, witness) we currently have three different SHA conventions (per-file .sha256 sidecars, single SHA256SUMS.txt, or none) and three different signing tiers (none, per-asset Sigstore, or single Cosign on the sums file). This inconsistency burns downstream — rules_wasm_component has to special-case each tool's checksum schema.
Reference implementation: pulseengine/synth/.github/workflows/release.yml (Phase 6 onward). Copy verbatim and adapt the cargo-cyclonedx manifest path.
Target asset set (per release)
<tool>-vX.Y.Z-<triple>.{tar.gz|zip} # binary archives, one per platform
<tool>-X.Y.Z.cdx.json # CycloneDX SBOM (no leading "v")
SHA256SUMS.txt # sha256 of every other asset above
SHA256SUMS.txt.sig # detached Cosign signature
SHA256SUMS.txt.pem # Fulcio cert (keyless OIDC identity)
SHA256SUMS.txt.cosign.bundle # verifier-friendly bundle
build-env.txt # rustc/cargo/cosign/runner versions
Plus SLSA build-provenance attestation via actions/attest-build-provenance@v2 (lives in GitHub's attestation store, not as a release asset; fetched via gh attestation verify).
Required workflow steps (this order matters)
- Build binary archives →
release-assets/.
cargo cyclonedx --manifest-path <main-crate>/Cargo.toml --format json --spec-version 1.5, copy to release-assets/<tool>-${BARE}.cdx.json. Must run before step 3 so its digest enters the sums file.
cd release-assets && sha256sum ./* > SHA256SUMS.txt.
actions/attest-build-provenance@v2 with subject-path: "release-assets/*.tar.gz".
sigstore/cosign-installer@v3 (cosign v2.4.1).
cosign sign-blob --yes --bundle SHA256SUMS.txt.cosign.bundle --output-signature SHA256SUMS.txt.sig --output-certificate SHA256SUMS.txt.pem SHA256SUMS.txt.
- Write
build-env.txt (rustc/cargo/cosign/runner versions).
gh release upload everything in release-assets/.
Required workflow permissions
permissions:
contents: write
id-token: write
attestations: write
Why sign the sums file rather than each asset
SHA256SUMS.txt lists the hash of every artifact; one signature on the sums file authenticates the entire release (Merkle-style). Per-asset .sig is appropriate only where certification evidence requires per-artifact provenance (currently only witness, for MC/DC evidence).
Generating the SBOM before the sums file means the sums file covers the SBOM too, so the single Cosign signature transitively attests to the SBOM. Reorder those two and the SBOM falls outside the trust boundary.
Verification one-liner (paste in release notes)
cosign verify-blob \
--certificate-identity-regexp 'https://github.com/pulseengine/<tool>/.github/workflows/release.yml@.*' \
--certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \
--bundle SHA256SUMS.txt.cosign.bundle SHA256SUMS.txt
gh attestation verify <tool>-vX.Y.Z-<triple>.tar.gz --repo pulseengine/<tool>
Downstream impact
Once all six repos converge, rules_wasm_component will fetch and verify SHA256SUMS.txt.cosign.bundle during repository-rule resolution, closing the gap where an attacker who can replace a release asset could also replace the checksums-PR entry. Until then we rely on SHA256-only verification.
Primary issue: release binaries stopped shipping after v0.5.0
Every loom release from v0.6.0 through v1.1.1 has zero release assets — only the v0.3.0 era tags carry the
loom-{platform}.tar.gzarchives. Downstream (rules_wasm_componentis pinned at v0.3.0) cannot move forward until the release workflow's asset-upload step is restored.Looks like the asset-upload step in the release workflow was lost or made conditional. Please restore it.
Secondary: adopt the unified artifact standard while you're in there
Background
Across the six PulseEngine release pipelines (loom, meld, sigil, spar, synth, witness) we currently have three different SHA conventions (per-file
.sha256sidecars, singleSHA256SUMS.txt, or none) and three different signing tiers (none, per-asset Sigstore, or single Cosign on the sums file). This inconsistency burns downstream —rules_wasm_componenthas to special-case each tool's checksum schema.Reference implementation:
pulseengine/synth/.github/workflows/release.yml(Phase 6 onward). Copy verbatim and adapt the cargo-cyclonedx manifest path.Target asset set (per release)
Plus SLSA build-provenance attestation via
actions/attest-build-provenance@v2(lives in GitHub's attestation store, not as a release asset; fetched viagh attestation verify).Required workflow steps (this order matters)
release-assets/.cargo cyclonedx --manifest-path <main-crate>/Cargo.toml --format json --spec-version 1.5, copy torelease-assets/<tool>-${BARE}.cdx.json. Must run before step 3 so its digest enters the sums file.cd release-assets && sha256sum ./* > SHA256SUMS.txt.actions/attest-build-provenance@v2withsubject-path: "release-assets/*.tar.gz".sigstore/cosign-installer@v3(cosign v2.4.1).cosign sign-blob --yes --bundle SHA256SUMS.txt.cosign.bundle --output-signature SHA256SUMS.txt.sig --output-certificate SHA256SUMS.txt.pem SHA256SUMS.txt.build-env.txt(rustc/cargo/cosign/runner versions).gh release uploadeverything inrelease-assets/.Required workflow permissions
Why sign the sums file rather than each asset
SHA256SUMS.txtlists the hash of every artifact; one signature on the sums file authenticates the entire release (Merkle-style). Per-asset.sigis appropriate only where certification evidence requires per-artifact provenance (currently only witness, for MC/DC evidence).Generating the SBOM before the sums file means the sums file covers the SBOM too, so the single Cosign signature transitively attests to the SBOM. Reorder those two and the SBOM falls outside the trust boundary.
Verification one-liner (paste in release notes)
Downstream impact
Once all six repos converge,
rules_wasm_componentwill fetch and verifySHA256SUMS.txt.cosign.bundleduring repository-rule resolution, closing the gap where an attacker who can replace a release asset could also replace the checksums-PR entry. Until then we rely on SHA256-only verification.