Repository navigation
Program engine M1.1a: declare program steps and carry their bundles through apply - #6264
schickling-assistant wants to merge 17 commits into
Conversation
…gine-design' into schickling/2026-11-10-program-engine-core
A `program` step names one ES module by sha256 (optional stalled-after).
The step definition stores it as ProgramSpec {bundle, bundle_hash,
stalled_after_ms}, so publishing the declaration promotes the blob and
replicas receive it. fractal apply (plain and owned-set) reads each
declared bundle, checks its hash and sends the bytes base64 by sha256;
the daemon verifies and stages them before it publishes, and the store
refuses a program whose blob it does not hold (missing-program-bundle).
fractal validate and apply --dry-run check the bundle locally. Registers
the program.step journal claim kind.
|
Build-host verification at 969ef90: |
…tch the route limit Without the engine a program step was an agentless step with no gates, so the first pass completed it. Bound and unverifiable request guards buffer up to the publication limit, so bundles reach the handlers. The release note says refused publications may leave staged, unpromoted bundle bytes.
…ub.com:compoundingtech/fractal into schickling/2026-11-10-program-engine-core # Conflicts: # crates/fractal-missions-base/src/mission.rs
…ublication guard buffer
…-program-engine-core # Conflicts: # docs/st3/large-value-sites.json
…ub.com:compoundingtech/fractal into schickling/2026-11-10-program-engine-core
|
Review record for head
|
…gine-authority' into schickling/2026-11-10-program-engine-core
…-program-engine-core # Conflicts: # crates/fractal-store/src/store.rs # crates/fractal/tests/convergence.rs
|
Delta review record for head
|
|
Compounding Manager ( Posted on behalf of @schickling
|
…-program-engine-core # Conflicts: # crates/fractal/src/main.rs
|
Delta review record for head
|
Depends on #6260 (mission run authority): this branch merges
schickling/2026-11-10-program-engine-authorityto add theprogramrow to its mission-field barrier table. Merge #6260 first.Problem
Program missions (docs/st3/program-engine.md) need a declaration the graph can publish and replicate: the step must name its bundle by hash, the bytes must travel with the publication (the daemon may run on another machine than the author's CLI), and a declaration naming bytes the member never received would be refused by every replica (
missing-replicated-blob).Goal
M1.1a of the program engine: the
programstep,ProgramSpec.bundle_hash, theprogram.stepjournal claim kind, andfractal applycarrying and verifying bundles.Decisions
step "program" { program "/abs/bundle.mjs" sha256="<hex>" stalled-after="10m"? }; the step definition storesprogram {bundle, bundle_hash, stalled_after_ms?}.bundle_hashis the field namecollect_hash_fieldspromotes, somission.publishedpromotes the staged blob and replicas receive it.after-run, or befinally.ApplyRequestand the owned-set request gainprogram_bundles(sha256 → base64, omitted when empty). The CLI reads every declared path, checks its hash (also for--dry-run) and sends the bytes;fractal validatechecks the hash locally.unused-program-bundle) before staging any withput_blob; publication routes accept up to 32 MiB.apply_as_implrefuses any program whose blob is in neitherblobsnorlocal_blobs(missing-program-bundle) — one choke point for every publication path.program.step:step-run, system-only, append, durable; fieldskey!,status!,attempt!,program!,value,error,ms,child. Added to a new convergence corpusclaims-v19.json(main's v18 is the newest frozen slot; v17 stays as main has it) anddocs/st3/schema.md.workingby the reconciler until the engine (M1.1b) decides them, so with only this PR merged a program step never completes on its own.guard_bound_requestandguard_unverifiable_requestbuffer up toPUBLICATION_BODY_LIMIT(32 MiB), matching the publication routes.programrow (mission_program, refusalmission-program-unavailable, also anapply --dry-runblocker) joins Mission run authority: parse, render and store the authority block #6260's barrier table instore/mission_capacity.rs; each daemon advertisesmission_program=1ondaemon.started.Verification
Focused tests on the Linux build host at head 9aa1096, each
CARGO_TARGET_DIR=<slice target> nix develop -c nice -n 19 cargo test …. Hosted CI at the exact head is the proof (pushed withST_EVIDENCE_LOCAL=off).cargo test -p fractal --lib -- program_bundles: 1 passed (a_publication_carries_exactly_the_declared_bytes). It failed at a191dbe withunsupported-kdl-version: st3 requires KDL version 2, but this document uses version 0: the test intent had noversion 2line. Fixed in the test (e1c0a60); the code was right.cargo test -p fractal-store --lib -- mission_capacity: 3 passed, including the newa_revision_that_declares_a_program_step_waits_until_every_member_reads_itand Mission run authority: parse, render and store the authority block #6260's capacity and authority tests.cargo test -p fractal-api-core --lib -- caller_guards_pass_a_publication_body_past_sixteen_mebibytes publication_stores_the_program_bundle_its_declaration_names publication_accepts_a_step_assigned: 3 passed. The new guard test sends a 20 MiB body through both guards (bound harness, and unverifiable ancestry) and gets it back whole.cargo test -p fractal-missions-base --lib -- program_step: 1 passed.cargo test -p fractal-reconcile --lib -- program_step_hold: 1 passed (a_published_program_step_stays_working_until_the_engine_decides).cargo test -p fractal-schema --lib -- checked_in_schema_document: 1 passed.cargo test -p fractal --test integration -- convergence::the_corpus_includes_every_registry_kind: 1 passed (corpus v19).python3 scripts/check-sqlite-large-values: passed at f7a4d11 (after resolving the main merge conflict indocs/st3/large-value-sites.jsonrecord by record), and at Program engine M1.1b: run program steps on a supervised Bun host #6265's head 3ba3725, which contains this head.cargo test -p fractal --test integration convergence:: -- --test-threads=4failed 12 of 43 (non-convergence on seeds 1, 3, 13, 17, 34, 277, 1597; trim mismatches on 2, 55, 610). The same host fails seeds 13 and 55 with main's v18 corpus at this code too, which is the known local/CI split Convergence seed tests fail locally on a loaded host but pass in CI (11 of 33 seeds at main) #6210, so the result says nothing about v19.NEVER_TRIMSstays[2, 34]until hosted CI reports; adjust it from that run, as main did for v18.Review findings answered
programmixed-version barrier row.program.stepmoves from the frozen corpus v17 into a newclaims-v19.json(generated withcargo run -p fractal-schema --example claims_json), selected by the simulation.Complexity
~330 lines of code and tests plus the fixture entry and docs.
Concerns
programwould re-hash a program mission without the field and quarantine it; publication now holds such a revision until every current member advertisesmission_program=1.to_bytes).workingand nothing here completes it; the engine is the stacked M1.1b PR.Friction & bottlenecks
Draft PRs skip hosted CI, and local convergence seed runs are unreliable on a loaded host (#6210), so the v19 never-trim set needs a hosted run once the PR leaves draft.
The build host was at load ~95 on 32 cores with ~6 GiB RAM free; the cold focused build took several minutes per crate.
Follow-ups
References
docs/st3/program-engine.md §3–§5; design PR #6253; spike PR #6254 (not for merge).