Repository navigation
Conversation
|
Rehearsal record at Run · immutable release. Release ID 420703797, 17 exact assets, no index/build-evidence/build-recipe/rebuild-check/inventory companions. All four builds and signers passed. Publication, initial release-ID/immutability validation, Independent verification below completed with exit status 0: one release verification, 17 asset verifications, 16 attestation verifications (four binaries × provenance/SPDX × signer-prefix/exact tag-ref identity), 16 checksum entries and four signed-SPDX predicate comparisons. It uses the guide commands with only repository/tag/commit substitutions. Workflow CLI: 2.102.0; independent CLI: 2.97.0. Full independent verification transcript — commands and output |
|
Successful rehearsal at Workflow — all jobs passed · immutable release · publisher log. Release ID 420812096: immutable=true, draft=false, 17 exact nonempty assets (four binaries, four SPDX2.3 documents, eight real action-produced bundles and SHA256SUMS). No index, inventory, build-evidence, build-recipe or rebuild-check companions. All four builds, all four isolated signing jobs, publication, cryptographic release/membership verification and the final release-ID/API read passed. The connection fix is exercised successfully; no mutation retry or tag reuse occurred. Immutable Independent verification completed with exit status 0 using checksum-verified GitHub CLI2.102.0, matching the publisher's recorded version: one release verification, 17 asset verifications, 16 attestation verifications (four binaries × provenance/SPDX × signer-prefix/exact tag-ref identity), all16 checksum entries and four signed-SPDX predicate comparisons. Commands are the guide's verification blocks with only repository/tag/commit substitutions. Full verification transcript — commands and output |
|
Rehearsal GitHub CLI 2.102.0 matches the publisher log. Its official macOS ARM archive was checksum-verified (SHA-256 Offline proofAll four binaries passed provenance and SPDX verification under OS-enforced network denial, with both signer identity forms, exact source/ref/signer digest pins, self-hosted runners denied, and published-SPDX predicate equality. No gh --version
gh attestation trusted-root > trusted_root.jsonl
shasum -a 256 trusted_root.jsonl
/usr/bin/sandbox-exec -p '(version 1)(allow default)(deny network*)' env GH_TOKEN=offline-verification-no-network bash -x offline-verify.shFull offline commands and success outputLocal verified Fastly routeThe downloaded wasm and host CLI first passed provenance and immutable release membership checks. Viceroy 0.21.0, pinned in the source tree, served a real configured page: HTTP 200, fixture origin marker, injected JS and the exact full source SHA in Complete local commands and outputset -euxo pipefail
REPO_ROOT=<source-checkout>
EVIDENCE=<evidence-directory>
WORK="$EVIDENCE/viceroy-smoke-2"
TS="$EVIDENCE/ts-aarch64-apple-darwin"
WASM="$EVIDENCE/trusted-server-fastly.wasm"
VICEROY=<pinned-runtime-tools>/viceroy
mkdir "$WORK"
for port in 18888 17676; do
if lsof -nP -iTCP:"$port" -sTCP:LISTEN; then exit 1; fi
done
cp "$REPO_ROOT/edgezero.toml" "$REPO_ROOT/fastly.toml" "$WORK/"
cp "$REPO_ROOT/trusted-server.example.toml" "$WORK/app.toml"
ln -s "$REPO_ROOT/crates" "$WORK/crates"
node - "$WORK" <<'JS'
const fs=require('node:fs');const root=process.argv[2];
const path=`${root}/app.toml`;let text=fs.readFileSync(path,'utf8');text=text.replace('domain = "example.com"','domain = "127.0.0.1"').replace('cookie_domain = ".example.com"','cookie_domain = "127.0.0.1"');text=text.replace('origin_url = "https://origin.example.com"','origin_url = "http://127.0.0.1:18888"');if(!text.includes('origin_url = "http://127.0.0.1:18888"'))throw Error('Origin fixture replacement failed');fs.writeFileSync(path,text);
const fastly=`${root}/fastly.toml`;text=fs.readFileSync(fastly,'utf8').replace('env = "FASTLY_KEY"','data = "fictional-local-api-key"');fs.writeFileSync(fastly,text);
JS
chmod u+x "$TS"
"$TS" --version
(cd "$WORK" && "$TS" config push --adapter fastly --local \
--manifest "$WORK/edgezero.toml" --app-config "$WORK/app.toml" --no-diff --yes)
"$VICEROY" --version
cat > "$WORK/origin.mjs" <<'JS'
import http from 'node:http';
http.createServer((req,res)=>{res.writeHead(200,{'content-type':'text/html'});res.end('<!doctype html><html><head><title>Local release proof</title></head><body>phase1-verified-origin-marker</body></html>');}).listen(18888,'127.0.0.1');
JS
node "$WORK/origin.mjs" > "$WORK/origin.log" 2>&1 &
origin_pid=$!
cleanup() {
if [[ -n "${viceroy_pid:-}" ]]; then kill "$viceroy_pid" 2>/dev/null || true; wait "$viceroy_pid" 2>/dev/null || true; fi
kill "$origin_pid" 2>/dev/null || true
wait "$origin_pid" 2>/dev/null || true
}
trap cleanup EXIT
"$VICEROY" serve -C "$WORK/fastly.toml" --addr 127.0.0.1:17676 "$WASM" > "$WORK/viceroy.log" 2>&1 &
viceroy_pid=$!
curl --fail --silent --show-error --retry 20 --retry-connrefused --retry-delay 1 \
--retry-max-time 45 --max-time 30 -H 'Host: 127.0.0.1' \
-D "$WORK/headers.txt" -o "$WORK/body.html" http://127.0.0.1:17676/
cat "$WORK/headers.txt"
node - "$WORK" <<'JS'
const fs=require('node:fs');const assert=require('node:assert/strict');const crypto=require('node:crypto');const work=process.argv[2];const headers=fs.readFileSync(`${work}/headers.txt`,'utf8');const body=fs.readFileSync(`${work}/body.html`);assert.match(headers,/^HTTP\/1\.1 200/m);assert.match(headers,/^x-ts-version: 922c2211c0cc7941bfc8ffa9f775ef8ac0971232\r?$/im);assert.ok(body.includes('phase1-verified-origin-marker'));assert.ok(body.includes('/static/tsjs=tsjs-unified.min.js'));console.log(`SUCCESS: configured Viceroy page returned HTTP200, origin marker, injected JS and exact release source header; ${body.length} bytes, sha256=${crypto.createHash('sha256').update(body).digest('hex')}`);
JS |
|
Rehearsal
Download recordThe ordinary release download was interrupted because transfer throughput was too low. Read-only bounded range downloads fetched the same release URLs; complete assembled files matched the published SHA-256 metadata before verification. No binary was substituted from a CI artifact or another release. Small companions were independently digest-checked as well. Commands and output follow; scripts existed only in the temporary evidence directory. Download commands and complete digest resultsgh api repos/prk-Jr/trusted-server/releases/tags/v0.0.0-rehearsal.4 > release-metadata.json
node range-download.mjs
node small-download.mjsimport fs from 'node:fs';
import {promisify} from 'node:util';
import {execFile} from 'node:child_process';
import crypto from 'node:crypto';
const run=promisify(execFile);
const release=JSON.parse(fs.readFileSync('release-metadata.json'));
const binaries=release.assets.filter(a=> !a.name.includes('.') || a.name.endsWith('.wasm'));
fs.mkdirSync('ranges',{recursive:true});
const tasks=[]; const chunk=2*1024*1024;
for(const a of binaries) for(let offset=0;offset<a.size;offset+=chunk) tasks.push({a,offset,end:Math.min(a.size-1,offset+chunk-1)});
let done=0;
async function worker(){while(tasks.length){const {a,offset,end}=tasks.shift();const out=`ranges/${a.name}.${offset}`; await run('curl',['--fail','--silent','--show-error','--location','--retry','2','--max-time','180','--range',`${offset}-${end}`,'--max-filesize',String(end-offset+1),'--output',out,a.browser_download_url]);if(fs.statSync(out).size!==end-offset+1)throw Error(`Range size mismatch: ${a.name} ${offset}`);done++;if(done%16===0)console.log(`Downloaded ${done} ranges`);}}
await Promise.all(Array.from({length:16},worker));
for(const a of binaries){const dest=fs.openSync(`${a.name}.assembled`,'w');const hash=crypto.createHash('sha256');for(let o=0;o<a.size;o+=chunk){const b=fs.readFileSync(`ranges/${a.name}.${o}`);fs.writeSync(dest,b);hash.update(b);}fs.closeSync(dest);if(`sha256:${hash.digest('hex')}`!==a.digest)throw Error(`Digest mismatch: ${a.name}`);fs.renameSync(`${a.name}.assembled`,a.name);console.log(`SUCCESS: ${a.name}: ${a.size} bytes match ${a.digest}`);}import fs from 'node:fs';import crypto from 'node:crypto';import {promisify} from 'node:util';import {execFile} from 'node:child_process';
const run=promisify(execFile);const {assets}=JSON.parse(fs.readFileSync('release-metadata.json'));await Promise.all(assets.filter(a=>a.size<2*1024*1024).map(async a=>{const valid=()=>fs.existsSync(a.name)&&`sha256:${crypto.createHash('sha256').update(fs.readFileSync(a.name)).digest('hex')}`===a.digest;if(!valid())await run('curl',['--fail','--silent','--show-error','--location','--max-time','180','--output',a.name,a.browser_download_url]);if(!valid())throw Error(`Bad asset: ${a.name}`);console.log(`SUCCESS: ${a.name} matches published digest`);}));Full online verification transcriptA small shell wrapper prints an explicit success line after each successful attestation command; JSON results remain separate for predicate comparison. |
|
Rehearsal Build/sign/publication run passed all seven builds/signing jobs and immutable publication. Published release: ID 421431085, Full online verification transcript, part 1. A wrapper prints explicit success after each successful attestation command; JSON output stays separate for SPDX equality. |
|
Rehearsal Build/sign/publication run passed all seven builds/signing jobs and immutable publication. Published release: ID 421431085, Full online verification transcript, part 2. |
|
Rehearsal Build/sign/publication run passed all seven builds/signing jobs and immutable publication. Published release: ID 421431085, All seven binaries passed provenance and SPDX verification with both signer identity forms, exact source/ref/signer pins, self-hosted runners denied and published-SPDX predicate equality under OS-enforced network denial. No gh attestation trusted-root > trusted_root.jsonl
shasum -a 256 trusted_root.jsonl
/usr/bin/sandbox-exec -p '(version 1)(allow default)(deny network*)' env GH_TOKEN=offline-verification-no-network bash -x offline-verify.sh |
|
Rehearsal Build/sign/publication run passed all seven builds/signing jobs and immutable publication. Published release: ID 421431085, Verified release wasm and host CLI were executed locally with pinned Viceroy 0.21.0, fictional loopback configuration and a local Node origin. A real page returned HTTP200, origin marker, injected JS and the exact full source SHA in set -euxo pipefail
REPO_ROOT=<source-checkout>
EVIDENCE=<evidence-directory>
WORK="$EVIDENCE/viceroy-smoke"
TS="$EVIDENCE/ts-aarch64-apple-darwin"
WASM="$EVIDENCE/trusted-server-fastly.wasm"
VICEROY=<pinned-runtime-tools>/viceroy
mkdir "$WORK"
for port in 18888 17676; do
if lsof -nP -iTCP:"$port" -sTCP:LISTEN; then exit 1; fi
done
cp "$REPO_ROOT/edgezero.toml" "$REPO_ROOT/fastly.toml" "$WORK/"
cp "$REPO_ROOT/trusted-server.example.toml" "$WORK/app.toml"
ln -s "$REPO_ROOT/crates" "$WORK/crates"
node - "$WORK" <<'JS'
const fs=require('node:fs');const root=process.argv[2];
const path=`${root}/app.toml`;let text=fs.readFileSync(path,'utf8');text=text.replace('domain = "example.com"','domain = "127.0.0.1"').replace('cookie_domain = ".example.com"','cookie_domain = "127.0.0.1"');text=text.replace('origin_url = "https://origin.example.com"','origin_url = "http://127.0.0.1:18888"');if(!text.includes('origin_url = "http://127.0.0.1:18888"'))throw Error('Origin fixture replacement failed');fs.writeFileSync(path,text);
const fastly=`${root}/fastly.toml`;text=fs.readFileSync(fastly,'utf8').replace('env = "FASTLY_KEY"','data = "fictional-local-api-key"');fs.writeFileSync(fastly,text);
JS
chmod u+x "$TS"
"$TS" --version
(cd "$WORK" && "$TS" config push --adapter fastly --local \
--manifest "$WORK/edgezero.toml" --app-config "$WORK/app.toml" --no-diff --yes)
"$VICEROY" --version
cat > "$WORK/origin.mjs" <<'JS'
import http from 'node:http';
http.createServer((req,res)=>{res.writeHead(200,{'content-type':'text/html'});res.end('<!doctype html><html><head><title>Local release proof</title></head><body>phase1-verified-origin-marker</body></html>');}).listen(18888,'127.0.0.1');
JS
node "$WORK/origin.mjs" > "$WORK/origin.log" 2>&1 &
origin_pid=$!
cleanup() {
if [[ -n "${viceroy_pid:-}" ]]; then kill "$viceroy_pid" 2>/dev/null || true; wait "$viceroy_pid" 2>/dev/null || true; fi
kill "$origin_pid" 2>/dev/null || true
wait "$origin_pid" 2>/dev/null || true
}
trap cleanup EXIT
"$VICEROY" serve -C "$WORK/fastly.toml" --addr 127.0.0.1:17676 "$WASM" > "$WORK/viceroy.log" 2>&1 &
viceroy_pid=$!
curl --fail --silent --show-error --retry 20 --retry-connrefused --retry-delay 1 \
--retry-max-time 45 --max-time 30 -H 'Host: 127.0.0.1' \
-D "$WORK/headers.txt" -o "$WORK/body.html" http://127.0.0.1:17676/
cat "$WORK/headers.txt"
node - "$WORK" <<'JS'
const fs=require('node:fs');const assert=require('node:assert/strict');const crypto=require('node:crypto');const work=process.argv[2];const headers=fs.readFileSync(`${work}/headers.txt`,'utf8');const body=fs.readFileSync(`${work}/body.html`);assert.match(headers,/^HTTP\/1\.1 200/m);assert.match(headers,/^x-ts-version: 937214a632f9387601dba94f996de78b2e6ee424\r?$/im);assert.ok(body.includes('phase1-verified-origin-marker'));assert.ok(body.includes('/static/tsjs=tsjs-unified.min.js'));console.log(`SUCCESS: configured Viceroy page returned HTTP200, origin marker, injected JS and exact release source header; ${body.length} bytes, sha256=${crypto.createHash('sha256').update(body).digest('hex')}`);
JS |
|
Rehearsal Build/sign/publication run passed all seven builds/signing jobs and immutable publication. Published release: ID 421431085, All 29 published files were downloaded from this release. Bounded range downloads were assembled and checked against the published SHA-256 metadata; small companions were independently digest-checked. No earlier release or CI artifact substituted for a binary. gh api repos/prk-Jr/trusted-server/releases/tags/v0.0.0-rehearsal.5 > release-metadata.json
node range-download.mjs
node small-download.mjs
node check-downloads.mjsimport fs from 'node:fs';
import {promisify} from 'node:util';
import {execFile} from 'node:child_process';
import crypto from 'node:crypto';
const run=promisify(execFile);
const release=JSON.parse(fs.readFileSync('release-metadata.json'));
const binaries=release.assets.filter(a=> a.size>=2*1024*1024);
fs.mkdirSync('ranges',{recursive:true});
const tasks=[]; const chunk=2*1024*1024;
for(const a of binaries) for(let offset=0;offset<a.size;offset+=chunk) tasks.push({a,offset,end:Math.min(a.size-1,offset+chunk-1)});
let done=0;
async function worker(){while(tasks.length){const {a,offset,end}=tasks.shift();const out=`ranges/${a.name}.${offset}`; await run('curl',['--fail','--silent','--show-error','--location','--retry','2','--max-time','180','--range',`${offset}-${end}`,'--max-filesize',String(end-offset+1),'--output',out,a.browser_download_url]);if(fs.statSync(out).size!==end-offset+1)throw Error(`Range size mismatch: ${a.name} ${offset}`);done++;if(done%32===0)console.log(`Downloaded ${done} ranges`);}}
await Promise.all(Array.from({length:32},worker));
for(const a of binaries){const dest=fs.openSync(`${a.name}.assembled`,'w');const hash=crypto.createHash('sha256');for(let o=0;o<a.size;o+=chunk){const b=fs.readFileSync(`ranges/${a.name}.${o}`);fs.writeSync(dest,b);hash.update(b);}fs.closeSync(dest);if(`sha256:${hash.digest('hex')}`!==a.digest)throw Error(`Digest mismatch: ${a.name}`);fs.renameSync(`${a.name}.assembled`,a.name);console.log(`SUCCESS: ${a.name}: ${a.size} bytes match ${a.digest}`);}import fs from 'node:fs';import crypto from 'node:crypto';import {promisify} from 'node:util';import {execFile} from 'node:child_process';
const run=promisify(execFile);const {assets}=JSON.parse(fs.readFileSync('release-metadata.json'));await Promise.all(assets.filter(a=>a.size<2*1024*1024).map(async a=>{const valid=()=>fs.existsSync(a.name)&&`sha256:${crypto.createHash('sha256').update(fs.readFileSync(a.name)).digest('hex')}`===a.digest;if(!valid())await run('curl',['--fail','--silent','--show-error','--location','--max-time','180','--output',a.name,a.browser_download_url]);if(!valid())throw Error(`Bad asset: ${a.name}`);console.log(`SUCCESS: ${a.name} matches published digest`);}));import fs from'node:fs';import assert from'node:assert/strict';import crypto from'node:crypto';
const release=JSON.parse(fs.readFileSync('release-metadata.json'));const expected=JSON.parse(fs.readFileSync('expected-assets.json'));
assert.equal(release.immutable,true);assert.equal(release.draft,false);assert.deepEqual(release.assets.map(a=>a.name).sort(),expected);assert.equal(expected.length,29);
for(const a of release.assets){assert(fs.lstatSync(a.name).isFile());const bytes=fs.readFileSync(a.name);assert(bytes.length>0);assert.equal(bytes.length,a.size);assert.equal('sha256:'+crypto.createHash('sha256').update(bytes).digest('hex'),a.digest);}
const sums=fs.readFileSync('SHA256SUMS','utf8').trim().split('\n');assert.equal(sums.length,28);assert.deepEqual(sums.map(line=>line.match(/^[a-f0-9]{64} (.+)$/)[1]).sort(),expected.filter(a=>a!=='SHA256SUMS'));
console.log('SUCCESS: immutable published release contains exactly29 nonempty assets with published digests; SHA256SUMS covers exactly28 companions and binaries, excluding itself.'); |
|
Rehearsal
Full commands and explicit success output:
Any following documentation-only head retains this exact rehearsed implementation SHA. The PR remains draft; no reviewers requested. Maintainer production-release/settings and allowlist review gates remain. |
|
Rehearsal v0.0.0-rehearsal.6 at 39a769c: failed workflow; immutable publication retained. Run, failed publisher. All seven build and signing jobs passed. The release contains exactly 29 nonempty assets; downloaded bytes match every API SHA-256 digest, and SHA256SUMS covers exactly 28 files, excluding itself. Readback confirms draft=false, immutable=true, prerelease=true, and this tag is not Latest. The documented gh release download command succeeded. The publisher stopped at gh release verify at 07:19:53.744 UTC with “no attestations for tag”. Subsequent independent verification succeeded; the verified release attestation has a trusted timestamp of 07:19:58 UTC. This supports an availability race; the pinned CLI hid the original underlying API error. This is a failed rehearsal, not a green run. No publication rerun or tag reuse occurred. The approved bounded availability check and the agreed fixes will be rehearsed with a fresh .7 tag. Build/startup evidence follows, including both macOS 13.0 checks, all CLI source labels and each non-loopback Axum container response. The manual Fastly 16.0.0 route packed, validated, inspected and byte-compared the published wasm with networking disabled; no deploy occurred. A separate Viceroy smoke returned HTTP 200 with the source header, origin marker and injected JS. Temporary local paths below are redacted. |
|
Rehearsal .6 offline verification transcript, exact source 39a769c. Pinned gh 2.102.0; saved trust-root SHA-256 65ca537f6ed8a47fd0e560c421baa1f6c1efb8b25fc200d8c5c02c0e92eb2b9c. Independent binary pins below come from the cryptographically verified release attestation, rather than trusting the downloaded checksum file alone. The OS sandbox denied networking (including the control request). Both predicates, both signer forms, exact source/tag/signer pins and all seven SPDX comparisons passed. This independent result does not change the failed workflow outcome. |
|
Rehearsal .6 online verification transcript, part 1/2, exact source 39a769c. Independent read-only checks passed: documented download, immutable prerelease/not Latest, release verification, all 29 verify-asset calls, 28 checksums, both predicates and signer forms for all seven binaries WITH bundles and WITHOUT bundles, SPDX equality, macOS minimum OS and CLI source labels. The original workflow remains failed; see the failure/build/runtime record and offline transcript. Pinned gh 2.102.0. |
|
Rehearsal .6 online verification transcript, part 2/2, exact source 39a769c. Independent read-only checks passed: documented download, immutable prerelease/not Latest, release verification, all 29 verify-asset calls, 28 checksums, both predicates and signer forms for all seven binaries WITH bundles and WITHOUT bundles, SPDX equality, macOS minimum OS and CLI source labels. The original workflow remains failed; see the failure/build/runtime record and offline transcript. Pinned gh 2.102.0. |
|
Rehearsal v0.0.0-rehearsal.7 at 7a05940: failed infrastructure rehearsal; workflow cancelled. Run. Upstream CI passed all seven builds and all six workflows at this exact reviewed head before the fresh lightweight tag was pushed. GitHub cancelled the Apple Silicon job after about 15 minutes waiting for a hosted runner. It acquired no runner and executed no steps. The annotations explicitly report hosted-runner acquisition failure and macOS ARM capacity constraints. Once that made successful publication impossible, the remaining Intel build was cancelled to avoid wasted runner work. Five builds passed. Signing and publication executed no steps. No draft or published release exists for this tag, so release/asset/attestation verification and Fastly packaging were not run for .7. The lightweight .7 tag is retained unchanged. This does not count as a successful rehearsal. The next attempt uses fresh .8 at the same CI-green reviewed commit under standing approval; no implementation or runner-setting change is required for this infrastructure failure.
Cancellation annotations: [
{
"level": "failure",
"message": "The job was not acquired by Runner of type hosted even after multiple attempts"
},
{
"level": "notice",
"message": "Due to capacity constraints, jobs targeting macOS arm64 runners may experience longer queue times."
},
{
"level": "notice",
"message": "Due to capacity constraints, jobs targeting macOS arm64 runners may experience longer queue times."
},
{
"level": "notice",
"message": "Due to capacity constraints, jobs targeting macOS arm64 runners may experience longer queue times."
}
]Release-state readback: |
|
Rehearsal v0.0.0-rehearsal.8 at 7a05940: passed. Fork run. Fresh lightweight tag; exact reviewed head; all seven builds/signing jobs and the publisher passed. The full independent verification also passed. The publisher found the release attestation on its first availability check; no availability wait was needed in this run. Failure-path tests cover the bounded 2s/5s waits and immediate rejection cases. The release has exactly 29 assets, draft=false, immutable=true, prerelease=true and is not Latest. The documented gh release download command succeeded. All 29 verify-asset checks and 28 SHA256SUMS entries passed. All seven binaries passed provenance and SPDX verification, both signer forms, exact tag/source/signer pins and deny-self-hosted-runners, both with bundles and via online attestation-store lookup without bundles. Networking-denied offline verification passed with an independent binary SHA-256 pin for each asset; every attested SBOM predicate equalled its shipped SPDX document. Both macOS minimum-OS checks and all CLI package/source/target/variant checks passed. All Axum container smokes reached the non-loopback bind through a host-published port. Pinned Fastly 16.0.0 packed, validated, inspected and byte-compared the verified wasm without deployment. Viceroy returned the expected page/source header and confirmed no Build facts log in default single mode. Full command/output transcripts follow in separate comments. Temporary local paths are redacted. This supersedes the failed .6 workflow (independent checks passed afterward) and the .7 runner-capacity cancellation. Their tags/releases remain unchanged. Any subsequent review-head update must be docs-only and retain this exact rehearsed implementation SHA. The PR remains draft with no reviewers. Full transcript: online 1 · online 2 · offline 1 · offline 2 · publisher 1 |
|
Rehearsal v0.0.0-rehearsal.8 at 7a05940: passed. Fork run. Fresh lightweight tag; exact reviewed head; all seven builds/signing jobs and the publisher passed. The full independent verification also passed. online transcript, part 1. Documented download, release/asset verification, checksums, all-seven bundle and online-store verification, both signer forms, both predicates and SPDX equality. |
|
Rehearsal v0.0.0-rehearsal.8 at 7a05940: passed. Fork run. Fresh lightweight tag; exact reviewed head; all seven builds/signing jobs and the publisher passed. The full independent verification also passed. online transcript, part 2. Documented download, release/asset verification, checksums, all-seven bundle and online-store verification, both signer forms, both predicates and SPDX equality. |
|
Rehearsal v0.0.0-rehearsal.8 at 7a05940: passed. Fork run. Fresh lightweight tag; exact reviewed head; all seven builds/signing jobs and the publisher passed. The full independent verification also passed. offline transcript, part 1. Pinned gh 2.102.0. Trust-root SHA-256: 65ca537f6ed8a47fd0e560c421baa1f6c1efb8b25fc200d8c5c02c0e92eb2b9c. Independent binary pins derive from the cryptographically verified release attestation, separately from the downloaded SHA256SUMS. OS sandbox denied networking including the control request. |
|
Rehearsal v0.0.0-rehearsal.8 at 7a05940: passed. Fork run. Fresh lightweight tag; exact reviewed head; all seven builds/signing jobs and the publisher passed. The full independent verification also passed. offline transcript, part 2. Pinned gh 2.102.0. Trust-root SHA-256: 65ca537f6ed8a47fd0e560c421baa1f6c1efb8b25fc200d8c5c02c0e92eb2b9c. Independent binary pins derive from the cryptographically verified release attestation, separately from the downloaded SHA256SUMS. OS sandbox denied networking including the control request. |
|
Rehearsal v0.0.0-rehearsal.8 at 7a05940: passed. Fork run. Fresh lightweight tag; exact reviewed head; all seven builds/signing jobs and the publisher passed. The full independent verification also passed. publisher transcript, part 1. Publisher output includes the bounded availability check, exact release-attestation binding and post-publication verification. |
|
Rehearsal v0.0.0-rehearsal.9 at 149754d: passed. Fork run. Fresh lightweight tag; exact reviewed head; all seven builds/signing jobs and the publisher passed. The full independent verification also passed. The publisher found the release attestation available on its first check; no live availability wait was needed. Failure-path tests cover five checks with 2s/5s/10s/20s backoff, the 60s availability deadline, late-success rejection and immediate definitive failures. The release has exactly 29 assets, draft=false, immutable=true, prerelease=true and is not Latest. The documented gh release download command succeeded. All 29 verify-asset checks and 28 SHA256SUMS entries passed. All seven binaries passed provenance and SPDX verification, both signer forms, exact tag/source/signer pins and deny-self-hosted-runners, both with bundles and via online attestation-store lookup without bundles. Networking-denied offline verification passed with an independent binary SHA-256 pin for each asset; every attested SBOM predicate equalled its shipped SPDX document. Both macOS minimum-OS checks and all CLI package/source/target/variant checks passed. All Axum container smokes proved 0.0.0.0:8080 through a host-published port and exit-1 rejection for both primary and legacy port zero. The publisher re-downloaded all 29 published assets and byte-compared them with the signed checksums and handoff. Pinned Fastly 16.0.0 packed, validated, inspected and byte-compared the verified wasm without deployment. Viceroy returned the expected page/source header and confirmed no Build facts log in default single mode. Full command/output transcripts follow in separate comments. Temporary local paths are redacted. This supersedes the failed .6 workflow (independent checks passed afterward) and the .7 runner-capacity cancellation. Their tags/releases remain unchanged. Any subsequent review-head update must be docs-only and retain this exact rehearsed implementation SHA. The PR remains draft with no reviewers. Full transcript: online 1 · online 2 · offline 1 · offline 2 · publisher 1 |
|
Rehearsal v0.0.0-rehearsal.9 at 149754d: passed. Fork run. Fresh lightweight tag; exact reviewed head; all seven builds/signing jobs and the publisher passed. The full independent verification also passed. online transcript, part 1. Documented download, release/asset verification, checksums, all-seven bundle and online-store verification, both signer forms, both predicates and SPDX equality. |
|
Rehearsal v0.0.0-rehearsal.9 at 149754d: passed. Fork run. Fresh lightweight tag; exact reviewed head; all seven builds/signing jobs and the publisher passed. The full independent verification also passed. online transcript, part 2. Documented download, release/asset verification, checksums, all-seven bundle and online-store verification, both signer forms, both predicates and SPDX equality. |
|
Rehearsal v0.0.0-rehearsal.9 at 149754d: passed. Fork run. Fresh lightweight tag; exact reviewed head; all seven builds/signing jobs and the publisher passed. The full independent verification also passed. offline transcript, part 1. Pinned gh 2.102.0. Trust-root SHA-256: 65ca537f6ed8a47fd0e560c421baa1f6c1efb8b25fc200d8c5c02c0e92eb2b9c. Independent binary pins derive from the cryptographically verified release attestation, separately from the downloaded SHA256SUMS. OS sandbox denied networking including the control request. |
|
Rehearsal v0.0.0-rehearsal.9 at 149754d: passed. Fork run. Fresh lightweight tag; exact reviewed head; all seven builds/signing jobs and the publisher passed. The full independent verification also passed. offline transcript, part 2. Pinned gh 2.102.0. Trust-root SHA-256: 65ca537f6ed8a47fd0e560c421baa1f6c1efb8b25fc200d8c5c02c0e92eb2b9c. Independent binary pins derive from the cryptographically verified release attestation, separately from the downloaded SHA256SUMS. OS sandbox denied networking including the control request. |
|
Rehearsal v0.0.0-rehearsal.9 at 149754d: passed. Fork run. Fresh lightweight tag; exact reviewed head; all seven builds/signing jobs and the publisher passed. The full independent verification also passed. publisher transcript, part 1. Publisher output includes the bounded availability check, exact release-attestation binding and post-publication verification. |
Summary
SHA256SUMS: 29 files.Changes
release*.yml,format.yml,phase1*main.rsAGENTS.md,domains.rsSize versus main: 36 new files / 10,093 lines, existing +567/−50. Code accounting: 958 Rust lines + 2508 workflow/script/test/cohort lines = 3466 (full new files plus additions to existing; includes domains/cohort). Ceiling waived; scope unchanged.
Full compatibility audit.
Closes
Part of #1235 until D7 (IAB settings) is complete.
Spec / Plan
Spec · Plan. The spec was reviewed in #1262 (two rounds) and is carried here with phase labels and Phase 1 notes; approving this PR approves the phased spec. #1235 asked for a separate spec PR; this PR combines them by agreement.
Test plan —
a501d1ba6a501d1ba6: docs-only since rehearsed149754d35. Docs/Markdown formatting, staged/committed domain lint and independent documentation/workflow review passed. Hosted CI: all six workflows and seven builds passed; signing/publication skipped.149754d35: all local project gates, 19 release tests and all upstream CI passed. Rehearsal .9 passed at this exact implementation SHA: 29 immutable prerelease assets; both predicates/identities online and offline; SPDX/checksums; published-byte re-download comparison; port 8080/zero checks; macOS/CLI checks; Fastly packaging and visible Viceroy no-Build-facts proof. Full transcript. Tests only, not live-proven: the HTTP 404 availability wait and stable-tagmake_latest: legacy. In.9, the attestation was available on the first check and the release was a prerelease. Failure-path tests cover the wait/exhaustion and deadline cases.#1235 Done when checklist and exact signer commands
.9passed at149754d35; IAB settings remain D7..9transcript at149754d35..9; no deployment performed.v*tags — maintainer setting.The issue example pins
release.yml; the reviewed signer is reusablerelease-build.yml.artifact-metadata: writeis intentionally omitted (not needed for file attestations). The topology alone does not establish SLSA Build Level 3.For each independently approved binary, run both predicates (
https://slsa.dev/provenance/v1,https://spdx.dev/Document/v2.3) and both identities separately:Allowlist changes needing maintainer review
Exact hosts:
actions.github.io(SLSA buildType),slsa.dev(provenance),spdx.dev(SPDX),cli.github.com(verification docs). Per-line suppressions:cyclonedx.org(historical intermediate-format reference; removed from allowlist),api.github.com,uploads.github.com.Phase 2 notes: Producing-job binding remains deferred: a compromised build dependency on one runner could replace another job's artifact, equivalent to a compromised build of the same source; the later transfer-binding slice addresses this. Complete composition, reproduction, full platform qualification and other Axum hardening remain deferred. PR callers retain the reusable workflow's permission maximum; actual builds are read-only and signing requires a tag plus the publication enablement variable.
Follow-up (binary change; fresh rehearsal required): Axum’s invalid-port diagnostic must name the actual supplied variable and say startup is refused. Today
PORT=0is refused but forwards EdgeZero’sEDGEZERO__ADAPTER__PORT="0" … falling backwarning.Human gates
Keep draft; no reviewers. Maintainers must confirm immutable releases and the
v*ruleset before settingRELEASE_PUBLICATION_ENABLED=true; no settings token/API precheck by review decision, with loud post-publication immutability checks retained. Decide rc-branch tag eligibility before official use. Approve spec/merge, reference hosts/suppressions and the first production release. Fork rehearsals use standing approval only after green CI on the exact reviewed head; fresh lightweight tags only. No IAB tags, releases or settings changed.