Plan v0.29.0: multi-realm distribution, and a corrected ingestion premise - #100
Merged
Conversation
…mise Research finding that changes the plan, and a correction to my own earlier claim. I reported that bytecodealliance publishes no verifiable provenance. That was WRONG, and the maintainer said so. I had listed release ASSETS and filtered for cosign/sums filenames — GitHub build attestations are not release assets, so the way I looked could not have found them. Measured properly, with negative controls: bytecodealliance/wasm-tools attestation verifies; bogus file rejected bytecodealliance/wit-bindgen no attestation (exit 1) bytecodealliance/cargo-component no release assets at all So upstream verification EXISTS and is not uniform. Both of my earlier answers — "fork everything because upstream is unverifiable" and "ingest upstream and disclaim" — were built on a premise I had not checked properly. The real finding is better than either: build provenance is STRONGER than a sums file. A sums file says these bytes hash to this. An attestation binds the artifact to a workflow, a repository and a source commit (observed `publish.yml@refs/heads/main`, commit 3ef3cefc) — which is exactly what `[tool.source]` has always wanted to record and could not, and which we spent v0.28.0 disclaiming because the sha256 there is never verified. REQ-INGEST-001 makes provenance a first-class second ingestion mode, records WHICH mechanism vouched for each tool inside the signed payload, and refuses a tool with neither by default — so "we could not verify this" is never the silent path. The forks keep their place, but as the answer for tools upstream does not cover (wit-bindgen), not as a blanket workaround. REQ-LAYERREPO-001 moves assembly out of varve, one repo per realm, with the assembler consumed FROM varve as a released artifact rather than copied — a copy per realm is a copy that drifts, the same defect as a gate testing a re-implementation. REQ-REALM2-001 is the one that matters. Composition has been exercised only by fixtures since v0.23.0, and every defect it has had was found by review or by a persona, never by use: a diamond refused as a cycle, cross-realm verification dead under test, an export following only the root, an install check that was direct-only. Two real realms will settle varve#91 by collision rather than by argument — two realms shipping `wasm-tools` is not hypothetical. Staged as two releases rather than one. v0.29.0 is distribution and has an outward-facing result; v0.30.0 is inward verification work (the wasm subset + MC/DC investigation, check-status, the three uncovered adapters, the error sweep). REQ-ADVISORY-002 and REQ-SYSTEST-002 move to v0.30.0 with it, so their open clauses sit in the release that closes them instead of trailing a shipped one. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019TNtfRjLNhEz82G2ggeeNu
The layer went stale in days, not months. Measured 2026-08-21, shortly after 2026.08.3 was published: rivet v0.33.1 -> v0.34.0, spar v0.36.0 -> v0.40.0 (four minors), synth v0.55.0 -> v0.58.0, witness v0.39.0 -> v0.43.0, ordeal v0.18.0 -> v0.19.0. A consumer on `rolling` is not getting a rolling toolchain; they are getting whatever was current the last time a human remembered. That is the requirement input. So the manual 2026.08.4 refresh is NOT being cut. Nothing is broken — the layer is behind, not wrong — 2026.08.3 already proved the VSIX and per-platform path end to end, and a hand-cut layer now is work that gets redone in the layers repo within the same release. The staleness is evidence for automating, not for one more manual dispatch. DD-024 is the part worth arguing about. Automating the whole pipeline — scan, assemble, sign, publish, hourly — is the obvious reading of "make it automatic", and it is wrong for varve specifically: `channel = "rolling"` is NOT a trust boundary. It is an annotation inside a layer signed by the SAME realm root as `qualified`. The realm is the boundary. So automating the rolling channel means the root key signs unattended, dozens of times a week — one release after we published `docs root-ceremony`, which says to use that key as rarely as possible, air-gapped, two-person rule, every use a ceremony entry. A key used by a cron job is a CI credential whatever the ceremony document calls it. And it is unrecoverable: varve has no revocation and no rotation, both stated in threat-model and root-ceremony. A layer published in error cannot be withdrawn — the only remedy is a yank, needing the same key — and an upstream compromise would reach every rolling consumer within the hour with no window for anyone to notice. So: automate the TOIL, not the JUDGEMENT. The scanner notices, diffs, assembles and runs the full assembly gate, then opens a PR. A person merges. The merge signs. Every signature stays something someone chose to make. Two clauses come from watching how automation actually fails: an unverifiable new release blocks THAT TOOL, not the whole proposal (one unattested upstream must not freeze the other seven), and the job is silent when nothing moved (a scheduled task that reports hourly is one people filter out of their inbox). Recorded as rejected-for-now, and the right shape if unattended publishing is ever wanted: a SEPARATE realm with its own root for machine-signed layers. That is what realms are for, and it lets consumers opt into lower assurance knowingly rather than by not reading. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019TNtfRjLNhEz82G2ggeeNu
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three requirements tagged
release: v0.29.0, and a correction to research I got wrong.The correction
I reported that bytecodealliance publishes no verifiable provenance. That was wrong, and the maintainer caught it. I had listed release assets and filtered for cosign/sums filenames — GitHub build attestations are not release assets, so the way I looked could not have found them.
Measured properly, with negative controls:
bytecodealliance/wasm-toolsbytecodealliance/wit-bindgenbytecodealliance/cargo-componentBoth of my earlier recommendations — "fork everything, upstream is unverifiable" and "ingest upstream and disclaim it" — rested on a premise I hadn't checked properly.
The finding is better than either option
Build provenance is stronger than a sums file. A sums file says these bytes hash to this. An attestation binds the artifact to a workflow, a repository and a source commit — observed:
publish.yml@refs/heads/main, commit3ef3cefc….That is exactly what
[tool.source]has always wanted to record and couldn't, and it's the field we spent v0.28.0 adding disclaimers to because varve never verifies it.What lands
REQ-INGEST-001— provenance as a first-class second ingestion mode; record which mechanism vouched for each tool inside the signed payload; refuse a tool with neither by default, so "could not verify" is never the silent path. The pulseengine forks keep their place as the answer for tools upstream doesn't cover (wit-bindgen), not as a blanket workaround.REQ-LAYERREPO-001— assembly moves out of varve, one repo per realm, with the assembler consumed from varve as a released artifact. A copy per realm is a copy that drifts — the same defect as a gate testing a re-implementation.REQ-REALM2-001— a realbytecodealliancerealm, composed across two roots, exercised by the system gate rather than a fixture.Why REQ-REALM2-001 is the one that matters
Composition has been fixture-only since v0.23.0, and every defect it has had was found by review or by a persona, never by use: a diamond refused as a cycle, cross-realm verification dead under test, an export following only the root, an install check that was direct-only.
Two real realms will settle #91 by collision rather than by argument — two realms shipping
wasm-toolsis not hypothetical.Staging
Two releases, not one. v0.29.0 is distribution with an outward-facing result. v0.30.0 is inward verification: the wasm-subset MC/DC investigation (#97),
check-status(DD-023 clause 6), the three uncovered adapters (#99), and the error sweep (#60).REQ-ADVISORY-002andREQ-SYSTEST-002move to v0.30.0 so their open clauses sit in the release that closes them rather than trailing a shipped one.rivet validatePASS.