Attestation Envelopes
RStack already writes business-readable contracts for every governed task —builder.json, validation.json, and readiness reports. Attestations (#73) wrap those contracts in a DSSE-style envelope so the evidence is tamper-evident: the envelope records what was attested (run, task, commit, file checksums), who produced it (agent, harness, model), and the contract snapshot itself. Anyone can later verify that the evidence a report points at is still the evidence that was produced.
Artifacts
builder.attestation.json).
Envelope shape
rstack.dev/builder-contract/v1alpha1, rstack.dev/validator-contract/v1alpha1, rstack.dev/release-readiness/v1alpha1.
CLI
verify-attestations exits non-zero only when an envelope is invalid (stale subject, mismatched run, malformed predicate, bad signature). Contracts that simply have no envelope yet are listed as missing — informational, because attestation is opt-in per run. A checkout with no .rstack run exits 0: nothing to verify is not a failure, which makes the command safe as a CI step (it runs in ci.yml after the test suite).
Unsigned local mode vs signed mode
unsigned(default): no key configured. The envelope still detects drift — subject checksums catch any post-hoc edit to contracts or claimed files — but proves nothing about the author.local-dev-signature: set theRSTACK_ATTESTATION_KEYenvironment variable andattestproduces an HMAC-SHA256 signature over the canonical (key-order-independent) envelope payload. Verification requires the same key — shared-secret integrity for a team that controls the key. The key is only ever read from the environment, never a CLI flag.- Sigstore / keyless signing is a deliberate extension point:
signature.typeis open, and the verifier reports unknown types honestly instead of pretending to verify them.
