Repository navigation
ci: export the bootstrap project once per run (SPEC.md §9.4) - #476
Conversation
Every bdd part that runs a bootstrap case exported the bootstrap project
itself, a whole verification of 1,173-2,205 s per part (19 jobs, about
569 runner-minutes per gate in run 43046966603). The new `bootstrap export`
job runs it once after honesty at the examples leg's profile (`cargo xtask
export-bootstrap`), requires the committed packages, and uploads the bundle
with a custody record binding repository, run, attempt, commit, tree, pins,
toolchains and the bundle digest. Each leg starts a fetcher that takes the
artifact when a case first needs it; `exported("bootstrap")` checks the
record against its own run and checkout and replays the bundle, and exports
as before when LEXLEAN_BOOTSTRAP_EXPORT is unset. RP-14 checks the job, the
fetcher and the record against planted changes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
afflom
left a comment
There was a problem hiding this comment.
[P2] Preserve the shared environment guard in the new bootstrap consumer. At this exact head, production_export::exported() takes the bootstrap shortcut directly into export_custody::take(), bypassing export()'s support::env_shared(). take() then runs git status/rev-parse, tool-version resolution and verify_artifact without that guard. The parallel production harness also runs PX-08/PX-10/CL-23 through offline(), which holds with_env's exclusive lock while putting a failing git sentinel first on PATH. The new unguarded consumer can enter that legitimate window, falsely reject custody and trip the offline sentinel assertion. This is a source-backed reachable race, not a claimed observed CI failure.
The small fix is to use the existing shared guard for the consumer's identity/tool-resolution/replay interval, after the asynchronous wait and environment-independent bundle digest. Do not hold it across the potentially long artifact wait or wrap the whole exported() initializer: the fallback already takes this guard, and lock ordering must remain intact. No competing patch or new full-gate run is requested.
The remainder of this bounded review found no demonstrated acceptance bypass in the inspected custody/hash/path/replay and same-run attempt checks. Full manual43127877709 is still incomplete; its bootstrap export job is active. Keep that evidence distinct from the draft-event skips. The reported historical export cost is not yet measured savings from this implementation. Existing owner retains repair, transfer qualification and landing; this is not full acceptance or completion of the broader #468 factory work.
…rap-export # Conflicts: # CHANGELOG.md
afflom
left a comment
There was a problem hiding this comment.
Bounded current-release delta review: 8ab6fe6 has ordered parents [3da2bd3, actual5dcc]. The bootstrap custody/consumer code is unchanged, so the narrow env_shared finding in review5867372298 remains unresolved. The minimum next source step is still the existing shared guard around identity/tool resolution and replay after the asynchronous wait and environment-independent digest; do not hold it across the long wait or recursively wrap the fallback exporter.
The original3da manual CI43127877709 now completed SUCCESS:55/55 jobs and611/611 reported steps, including same-run honesty; exact3da repro43127931880 passed. This is useful positive transfer execution evidence for that head, not proof that the scheduling-dependent race is absent or qualification of8ab. Current8ab draft CI skips bootstrap export and other required groups; its repro passed. No completed producer, test or log was repeated by this review. Existing owner retains repair and resulting-head qualification.
What
Every bdd part that runs a bootstrap case exported the bootstrap project itself, which verifies it whole. In run 43046966603 that verification shows in 19 jobs (18
bdd-bootstrap-*parts andbdd-compiler) at 1,173-2,205 s each, about 569 runner-minutes per gate, and it grows by one per slice (27 parts after the BS-25..34 batch).This PR exports it once per run:
bootstrap export(afterhonesty, whole-gate runs only, width 2, committed hints, 12 GiB budget). It runs the newcargo xtask export-bootstrap --output DIR, which exports, requires every package to equal the committed package (the comparison PX-01 and BS-01/BS-03 make), and writes the bundle pluscustody.json(lexlean/ci-bootstrap-export/1). The record binds repository, run id, attempt, commit, tree, SHA-256 ofrust-toolchain.toml/lean-toolchain/Cargo.lock,rustc -vVandlean --version, the bundle path, and the bundle digest..github/scripts/take-bootstrap-export.sh, which makes no API call until a case first wants the export, then downloads this run'sbootstrap-exportartifact (or records that the export job ended without it). So each part's differential runs in parallel with the one export.production_export::exported("bootstrap")reads it whenLEXLEAN_BOOTSTRAP_EXPORTnames a directory. Before any case reads it, the record must match the job's own repository, run, commit, tree, pins and toolchains, and the bundle's digest, with an attempt at most the job's and a path below the project. The bundle is also replayed. When the variable is unset (just vv, draft runs), the case exports itself as before.actions: read, an unconditional fetch, and each custody field changed.Measurement
Full-gate dispatch 43127877709 on 3da2bd3 (release 7eb8162 + this change): all jobs passed. The branch has since merged release/v0.4 5dccf9e (#469); the only conflict was CHANGELOG.md, and the RP cases, validate-model and validate-spec-links pass on the merge.
Done criterion: in all 18
bdd-bootstrap-*parts and inbdd-compiler(BS-01/BS-03), the telemetry shows no bootstrap verification. In 43046966603 each showed one, of 1,173-2,205 s. Thebootstrap exportjob verified it once: 1,966 s, 36.2 min for the whole job. Its line:the bootstrap project exported once for run 43127877709 attempt 1 ...; its packages equal the committed packages (§24.7); bundle sha256 36b0f6e0... (337 files).This branch does not contain #470 (parallel evaluator), so 42946701043 is the like-for-like baseline for the differential-heavy parts; 43046966603 is the brief's baseline.
Whole run:
What this shows:
crates/lexlean/src/verify/mod.rs(for file in &stage.certificates) each certificate is compiled and replayed one after another, soLEXLEAN_VERIFY_WIDTH=2does not apply; the job never went below 10.8 GB free. Running those certificates through the verifier's pool would lower the floor for every short part and turn their wait into saved minutes. That is a verifier change and is not part of this PR.Queueing: the export job and the legs are created together when honesty passes, and the export job comes first in the file. A leg waits only once a case asks for the export, so it holds a runner while waiting only if the export job is still queued; under FIFO assignment the export job is queued no later than the legs that wait on it.
Not verified
failedmarker and the harness's refusal, not exercised by a run.Not verified locally
The export job and the cross-job transfer only run in CI; the dispatch above is their first run. Locally: fmt, clippy (
repo-conformance,xtask), validate-model, validate-spec-links, all 17 RP cases.🤖 Generated with Claude Code