the PulseEngine toolchain layer manager
Pinned, signed, dated toolchain bundles. One layer per release — read the one your project pins.
Status: design complete, planned. Nothing is implemented yet. The architecture is settled (pulseengine.eu#157) and the two formerly-open decisions are now taken (see Decisions). The release plan lives in rivet (
rivet release status v0.1.0). Do not depend on anything here yet.
Three consumers, two toolchains, one afternoon:
| consumer | needs |
|---|---|
| relay | the August toolchain |
| jess | the August toolchain |
| wohl | the July toolchain |
They are frozen on different toolchains on purpose. Once a project takes a qualified toolchain it stays there, because re-qualification costs money. A tool that quietly moves them forward destroys evidence they paid for.
At the same time, being stale silently is expensive in the other direction: a capability gap was once filed against this toolchain thirteen days after the fix shipped, because the reporter's binary was one release behind and nothing said so.
varve exists to make both failures impossible: the pin is honoured exactly, and
divergence from it is loud.
A varve is an annual layer of sediment laid down in still water. Varve chronology dates by counting layers back, like tree rings — absolute dates you can correlate between sites.
| varve | here |
|---|---|
| one annual layer, dated | one bundle release — 2026.07, 2026.08 |
| immutable once deposited | digest-pinned, signed, never rewritten |
| the whole column is preserved | every qualified line stays reconstructible |
| you read the layer you need | wohl reads July while relay reads August |
| counting back gives absolute dates | "which layer produced this artifact?" |
| a core is extracted and archived | the offline bundle — the artifact of record |
varve install # resolve this project's pin, fetch, verify, lay down
varve verify # re-check an installed layer against its signature
varve which synth # which binary runs here — and which layer it came from
varve list # layers present locally, and which projects pin them
varve archive 2026.07 core.tar # extract the core: the offline artifact of record
varve run --varve 2026.09 -- synth # one-off, without editing the pin
varve deposit # (CI) assemble, sign and publish a layerA project declares its layer in a checked-in manifest; shims on PATH resolve it
by walking up from the working directory, then exec the real binary. Switching
projects is cd.
In scope — varve selects, verifies, and hands over tools.
- resolve a project's pinned layer and install it, verifying every signature and digest against the PulseEngine trust root
- keep many layers side by side in a content-addressed core, so switching costs nothing
- dispatch per project via shims, and answer which binary am I actually running
- archive a layer for offline reconstruction, independent of any registry
- stamp the layer identity into build outputs, so an artifact records the toolchain that produced it
Out of scope — deliberately.
- It never transforms your code.
varveselects and verifies; every compilation, fusion, optimisation and proof belongs to the tools it hands you. This boundary is what keeps its qualification scope small and separate. - No auto-update, ever. Moving a project between layers is an edit to a checked-in file, reviewed like any other change. A background updater would be a defect, not a feature.
- No silent fallback. If a pinned layer is missing,
varvefails and tells you how to install it. It never runs "whatever else is onPATH". - No server of our own. An OCI registry is the transport. Access control, when it is ever needed, is registry authentication — see below.
A CLI and a library. No service.
| crate | role |
|---|---|
varve |
the CLI, the shims, and deposit for CI |
varve-core |
manifest format, resolution, the core store, verification wiring |
Distribution is an OCI image index on a registry (public GHCR by default), signed
by digest, with attestations and qualification evidence attached as OCI referrers.
Verification is sigil, used as a library.
Where the bytes come from is pluggable — a public registry, a private one, an archived core. Whether they are accepted is not. Signature and digest checks run against our trust root on every path, and swapping the source must never change a verdict.
Both shaped the manifest format, so both were settled before it freezes (2026-08-07, after a research pass over criticalup/Ferrocene, TUF, Uptane, SUIT/RFC 9019, DO-330 and qualified-vendor patch practice — the evidence lives in the rivet artifacts, DD-004/DD-005 and CA-/AR-):
- Anti-rollback → monotonic per-line counters. Every layer manifest carries a release counter and issued-at timestamp inside the signed payload; the client keeps a high-water mark per line and rejects anything below it, warning past a staleness threshold. The SUIT/Uptane pattern: works on static hosting and in air gaps, survives registry compromise, no re-signing treadmill. tuf-on-ci is the recorded upgrade path if a connected freshness channel is ever needed.
- Patching a frozen line → three-part identifiers. A layer is always
YYYY.MM.P—2026.07.0deposits the July line,2026.07.1patches it in place, carrying a signed qualification-delta attestation scoped to what changed, plus known-problems referrers as the no-patch mitigation path. The frozen-line model every qualified-tool vendor converges on, made mechanical.
- pulseengine.eu#157 — the design thread
- sigil — signing, attestation, air-gapped trust bundles
- rivet — traceability; a layer manifest is a typed artifact
Apache-2.0