diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 68dba9d..a83d7ed 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/claude-code-marketplace.json", "name": "pulseengine-eu", - "version": "0.9.0", + "version": "0.10.0", "description": "PulseEngine engineering plugins for Claude Code — verification + traceability + attestation methodology, the tool directory, and the procedural skills that compose them.", "owner": { "name": "PulseEngine", @@ -11,7 +11,7 @@ { "name": "pulseengine-claude", "description": "PulseEngine methodology as installable Claude Code tooling — philosophy + toolchain + repo-taxonomy + model-operating-contract memory, memory-persistence hooks (situational awareness + working-context across sessions/compaction), plus thirteen procedural skills (clean-room verification, release execution with a V-model traceability gate, oracle-gating, the full feature loop, the standardized release-artifact pipeline, tool-friction reporting, session-learning capture, STPA/STPA-Sec hazard-analysis audit, backend-agnostic proof synthesis, full bidirectional traceability audit across the V, greenfield verification bootstrap, release planning with an issue-driven delivery loop, and an incremental issue-hunt loop).", - "version": "0.9.0", + "version": "0.10.0", "source": "./claude-tooling/plugins/pulseengine-claude", "category": "development" } diff --git a/claude-tooling/plugins/pulseengine-claude/.claude-plugin/plugin.json b/claude-tooling/plugins/pulseengine-claude/.claude-plugin/plugin.json index 1487df9..e2d0692 100644 --- a/claude-tooling/plugins/pulseengine-claude/.claude-plugin/plugin.json +++ b/claude-tooling/plugins/pulseengine-claude/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "pulseengine-claude", - "version": "0.9.0", + "version": "0.10.0", "description": "PulseEngine methodology as installable Claude Code tooling — philosophy + toolchain + repo-taxonomy + model-operating-contract memory, memory-persistence hooks (situational awareness at session start, working-context checkpoints across sessions/compaction), plus thirteen procedural skills (clean-room verification, release execution with a V-model traceability gate, oracle-gating, the full feature loop, the standardized release-artifact pipeline, tool-friction reporting, session-learning capture, STPA/STPA-Sec hazard-analysis audit, backend-agnostic proof synthesis, full bidirectional traceability audit across the V, greenfield verification bootstrap, release planning with an issue-driven delivery loop, and an incremental issue-hunt loop).", "author": { "name": "PulseEngine", diff --git a/claude-tooling/plugins/pulseengine-claude/README.md b/claude-tooling/plugins/pulseengine-claude/README.md index d3f9943..928e805 100644 --- a/claude-tooling/plugins/pulseengine-claude/README.md +++ b/claude-tooling/plugins/pulseengine-claude/README.md @@ -19,7 +19,7 @@ PulseEngine engineering methodology as installable Claude Code tooling. - `release-execution/` — end-to-end release machinery: PRs → reviewers → fixes → merge → CI → **V-model traceability completeness gate** → tag → GitHub Release + crates.io verify. The gate blocks the tag until every `approved`/`implemented` artifact has a closed V (req → arch → impl) and green right-side evidence (tests, witness MC/DC, attestation). Includes the per-release falsification statement. - `oracle-gate-a-change/` — per-change procedure: name the mechanical oracle (rivet check / spar pass / witness gap / sigil verify / Kani / Verus / fuzz / nm symbol check), write it first if it doesn't exist, only the diff that flips it counts. - `pulseengine-feature-loop/` — end-to-end compose loop: spar (AADL) → WIT → rivet typed artifacts → code (oracle-gated) → witness MC/DC → sigil attestation → clean-room verify. - - `release-artifact-pipeline/` — the standardized release.yml: signed `SHA256SUMS.txt`, CycloneDX SBOM, SLSA attestation, cosign keyless OIDC. Canonical implementation in `pulseengine/synth/.github/workflows/release.yml`. + - `release-artifact-pipeline/` — the standardized release across **five tracks**: (A) native binaries — signed `SHA256SUMS.txt`, CycloneDX SBOM, SLSA attestation, cosign keyless OIDC (canonical: `pulseengine/synth`); (B) distribution — crates.io for everything Rust + npm for CLIs; (C) wasm — sigil + cosign signing and **witness MC/DC + scry** verification gates, holding wasm to the same bar as the binary; (D) a Pages verification dashboard (witness-viz/scry-viz); (E) rivet verification extraction (the relay/gale test-level `verifies` pattern). Built from an org-wide release-consistency sweep. - `report-tool-friction/` — standing dogfooding practice: when a tool errors, misbehaves, or forces a workaround during real work, file it as a `tool-friction` issue in the tool's own repo — automatically, as you hit it. Referenced by the feature loop and release execution. - `capture-session-learnings/` — continuous learning: distill a session's resume-state into the working-context checkpoint, and promote durable patterns/decisions into memory or a new skill. The agent-authored counterpart to the memory-persistence hooks; where recurring `report-tool-friction` workarounds get promoted so they stop recurring. - `stpa-audit/` — conduct or **audit** an STPA / STPA-Sec hazard analysis on rivet's typed artifacts: completeness as a mechanical oracle (`rivet check` over the loss→hazard→constraint→UCA→scenario closure rules + STPA-Sec CIA/adversarial-causation/attacker-type) plus soundness as a clean-room reasoning review. The safety-case front-end of the feature loop; feeds the release V-model gate. diff --git a/claude-tooling/plugins/pulseengine-claude/skills/release-artifact-pipeline/SKILL.md b/claude-tooling/plugins/pulseengine-claude/skills/release-artifact-pipeline/SKILL.md index 92a693c..e37e61c 100644 --- a/claude-tooling/plugins/pulseengine-claude/skills/release-artifact-pipeline/SKILL.md +++ b/claude-tooling/plugins/pulseengine-claude/skills/release-artifact-pipeline/SKILL.md @@ -1,9 +1,9 @@ --- name: release-artifact-pipeline -description: This skill should be used when setting up, standardizing, auditing, or modifying a release artifact pipeline on a PulseEngine project — including "standardize release artifacts", "set up release workflow", "fix the release pipeline", "add cosign signing", "add SLSA attestation", "add SBOM", "switch to signed SHA256SUMS", "audit release artifacts", "migrate off per-file .sha256 sidecars", or any GitHub Actions release.yml setup/refactor. ALWAYS use this skill when proposing or reviewing changes to a release.yml workflow, when adopting the PulseEngine release-artifact standard for a new repo, or before claiming a release pipeline is "compliant" or "signed". +description: This skill should be used when setting up, standardizing, auditing, or modifying a release artifact pipeline on a PulseEngine project — including "standardize release artifacts", "set up release workflow", "fix the release pipeline", "add cosign signing", "add SLSA attestation", "add SBOM", "switch to signed SHA256SUMS", "sign the wasm with sigil", "add a witness/scry gate to the release", "publish to crates.io / npm", "add a Pages verification dashboard", "audit release artifacts", "migrate off per-file .sha256 sidecars", or any GitHub Actions release.yml setup/refactor. ALWAYS use this skill when proposing or reviewing changes to a release.yml workflow, when adopting the PulseEngine release-artifact standard for a new repo, or before claiming a release pipeline is "compliant" or "signed". Covers all five tracks: native binaries, distribution channels (crates.io + npm), wasm signing (sigil + cosign) and wasm verification gates (witness MC/DC + scry), the Pages verification dashboard, and rivet verification extraction. metadata: author: pulseengine.eu - version: "0.1.0" + version: "0.2.0" --- # Release artifact pipeline @@ -14,9 +14,26 @@ Anytime you touch the *release workflow itself* on a PulseEngine project — set This is distinct from `release-execution`, which fires when you're *cutting* a release on top of an already-working pipeline. Pipeline setup is the rarer, deeper task. -## The standard +## The standard — match it for *every artifact type the repo ships* -Every PulseEngine repo that ships binaries shares one release-artifact convention. The canonical implementation lives at **`pulseengine/synth/.github/workflows/release.yml`** — Phase 6 onward. **Copy that block verbatim** into the target repo's release workflow, then adapt the SBOM step's manifest path to point at the target repo's main crate. +A repo's release is compliant only when **each kind of artifact it produces** meets +its track below. The recurring org-wide defect (2026-06 sweep): the *native binary* +gets the full supply chain everywhere, while the *wasm* it ships gets weaker signing +and no verification gate. Hold wasm to the **same bar** as the binary. + +- **Track A — native binaries** → the cosign+SBOM+SLSA bundle (canonical: synth). +- **Track B — distribution channels** → crates.io for everything Rust; npm for CLIs/tools. +- **Track C — wasm artifacts** → sigil + cosign signature, **and** a witness MC/DC + gate **and** a scry abstract-interpretation gate. No wasm ships unverified. +- **Track D — Pages verification dashboard** → witness-viz / scry-viz (canonical: + witness, scry). + +A repo skips a track only if it produces none of that artifact type — and "we emit +wasm but only Track A is wired" is the exact drift this skill exists to close. + +## Track A — native binaries + +The canonical implementation lives at **`pulseengine/synth/.github/workflows/release.yml`** — Phase 6 onward. **Copy that block verbatim** into the target repo's release workflow, then adapt the SBOM step's manifest path to point at the target repo's main crate. ### Required release assets (and no others for checksums/attestation) @@ -55,6 +72,88 @@ permissions: - **All per-file `.sha256` sidecars.** The single signed `SHA256SUMS.txt` replaces them. - **Exception**: witness keeps its per-asset `.cert` / `.sig` files because they're consumed as certification evidence. For witness, the signed sums file is *added*, not replacing. +## Track B — distribution channels + +Distribution is currently incoherent (rivet npm-only, sigil/synth/scry crates.io-only, +mcp a stale unsigned manual script). The rule: + +- **crates.io for everything written in Rust** — canonical, published from CI via + OIDC trusted publishing, never a hand-run `cargo publish` from a laptop. Keep it + in a dedicated `publish-to-crates-io.yml` on the `v*` tag (canonical: sigil, + synth, scry) so the artifact-release and the registry-publish don't race. + **mcp's manual `scripts/publish.sh` is the anti-pattern — it ships unsigned, out + of CI, with stale pinned versions; move it into CI.** +- **npm for CLIs and tools** — the platform-package wrapper pattern (canonical: + rivet's `release-npm.yml`: per-target `@pulseengine/-` packages + wired to a root launcher via `optionalDependencies`), triggered `workflow_run` + after the GitHub Release so the binaries exist. This is **not** rivet-only — + every user-facing CLI (rivet, spar, …) should ship it. +- **More channels (OCI, editor marketplaces) are in scope later** — sigil's GHCR + `oras push` and rivet/spar's VS Code Marketplace are precedents; not required now. + +A Rust tool is compliant on Track B only when it is on crates.io **and** (if it's a +CLI) on npm. crates.io-but-no-npm and npm-but-no-crates.io are both drift. + +## Track C — wasm artifacts (same bar as the binary) + +Any repo that **ships or emits wasm** (component or module) must sign and verify it +to the binary's standard. The sweep found this is where every repo cuts corners. + +### Signing — sigil + cosign +- **sigil signature** (dogfood the attestation tool) **and** cosign over the sums. + Canonical signer: sigil's own `wsc sign --keyless` (see sigil `release.yml` / + `wasm-signing.yml`). +- **Prerequisite — fix sigil first.** sigil cannot yet parse its own `wasm32-wasip2` + output, so it ships unsigned-on-failure. **Do not mandate the sigil step on a repo + until that parser blocker is fixed** (tracked upstream in `pulseengine/sigil`); add + cosign now, add the sigil signature as the blocker clears. Mandating a broken step + just reintroduces `continue-on-error` theatre. +- SLSA `subject-path` must cover the **`.wasm`**, not only the `.o`/`.tar.gz` + (gale's provenance currently covers the `.o` objects but not the wasm — fix). + +### Verification gates — witness AND scry (both required) +Every wasm-emitting repo runs, as a **CI/release gate** (not a manual side-script): +- **witness** — MC/DC truth-table on the wasm; the gate asserts zero unresolved gap + rows for new decisions (canonical: witness `ci.yml` dogfood + `verdict-suite`; + scry's `mcdc-gate.sh` is the consume-as-library exemplar). Where the bundled + witness can't parse component-format exports (relay #145), that's a witness bug to + file via [`report-tool-friction`] — not a reason to leave the gate manual. +- **scry** — sound abstract interpretation over the fused Wasm core (consume scry as + a crates.io library, v1.15+; canonical: scry's self-analysis dogfood). + +"We emit wasm and run neither" is the headline gap (loom — a wasm *optimizer* — runs +no wasm verification; meld, gale, spar likewise). Manual witness runs (relay, wohl) +count as **not a gate** until they're in CI. + +## Track D — Pages verification dashboard + +Publish the verification evidence as a browsable dashboard on every repo that runs +witness/scry. Canonical: witness's and scry's `publish-pages` job (witness-viz / +scry-viz MC/DC truth-table + self-analysis, `actions/upload-pages-artifact` + +`deploy-pages`). **One-time setup gotcha to document in the PR** (it bit both repos): +Pages *Source* must be "GitHub Actions", and the `github-pages` environment needs a +`v*` **tag** deployment-branch policy or tag deploys are rejected — +`gh api -X POST repos///environments/github-pages/deployment-branch-policies -f name='v*' -f type=tag`. +(gale's `pages.yml` deploys only the gust demo, not a verification dashboard — that's +the gap, not coverage.) + +## Track E — the verification IS extracted into rivet (gate, not prose) + +A signed, dashboarded wasm is still non-compliant if the requirement→test mapping +isn't in the rivet graph. The right side of the V must be *driven*, not narrated. +The in-house exemplars already exist — **copy them, don't reinvent**: +- **relay** — test/target-level `verifies` links (e.g. a specific bazel coverage + target → `SWREQ-…`), all 174 verification artifacts linked, + a `verification-gate.yml` + that *executes* the steps (`run-falcon-verification.py`). The model for "name the + actual test, not the crate." +- **gale** (642 links, ~complete coverage) and **synth** (141) for volume. +- The rivet-driven PR gate (`tools/run_verification.py` over `type: test-case` + artifacts) is canonical in witness/loom/spar — adopt it where missing. + +Laggards as of the sweep: scry (0 links despite 111 tests + 12 Rocq proofs + a live +MC/DC gate), witness (2/55), loom, meld, mcp. The procedure for closing this lives in +[`traceability-audit`]; this track just makes it a release-pipeline requirement. + ## Verification — the oracle for this skill Per [`oracle-gate-a-change`], the release pipeline is itself a mechanical oracle. The diff that flips it red→green is one where the verification one-liner below runs cleanly against the published release. **Paste this verification block into the release notes of every release that uses this pipeline**, so consumers can re-run the check: @@ -73,12 +172,21 @@ If either of these fails on the published release, the pipeline did not actually ## How to apply to a target repo 1. **Read the canonical**: open `pulseengine/synth/.github/workflows/release.yml`. Find Phase 6 onward (the artifact-generation block). -2. **Identify the target repo's deltas**: - - Does it already have binary archives? (loom: no — missing upload step entirely. Fix that first; the sums/signing flow is moot until artifacts exist.) - - Does it have per-file `.sha256` sidecars? (sigil/wsc: yes — must be replaced.) - - Does it have a SBOM? (most repos: no — add it.) - - Does it have cosign signing? (spar: no — add it.) - - Does it have SLSA attestation? (most repos: no — add it.) +2. **Identify the target repo's deltas** — Track A is broadly done org-wide; the + live gaps from the 2026-06 sweep are Tracks B–E: + - **Track A (binaries):** mostly compliant. Exceptions: sigil lacks the CycloneDX + SBOM; kiln/mcp have no real release at all. + - **Track B (distribution):** rivet is npm-only (no crates.io); sigil/synth/scry + crates.io-only (no npm CLI wrapper); **mcp publishes via a stale unsigned manual + script — move it into CI.** + - **Track C (wasm):** the big one. loom/meld/gale/spar emit/handle wasm and run + **neither** witness nor scry; relay/wohl run witness **manually** (not a gate); + gale has an open `TODO(sigil)` and SLSA that misses the `.wasm`. (sigil-sign step + is blocked on the wasip2-parser fix — add cosign now.) + - **Track D (Pages):** only witness + scry deploy a verification dashboard — roll + it to every repo running witness/scry. + - **Track E (rivet extraction):** scry (0 links), witness (2/55), loom, meld, mcp + are the laggards; copy relay's test-level pattern. 3. **Copy the Phase 6+ block from synth verbatim**, adapt only: - The main crate manifest path for the SBOM step. - The `` name in the verification one-liner.