Repository navigation
Description
id(world-manifest): validate() never checks the execution profile or the schedule count — manifests parse and plan clean, then fail partway through a live apply
Evidence (main 6bbb065b, verified this run)
WorldManifest::validate() (pkgs/id/src/world_manifest.rs:164-196) — the only gate parse() runs (:151-155) — checks grant names, ceiling names, schedule ids and positive fire times, module-hash shape, and hash/source exclusivity. It never looks at two fields it carries:
-
The execution profile. Every bound
WorldExecutionProfile::resolve()refuses (pkgs/id/src/world_limits.rs:71-92) sails throughparse():wasm_fuel = 0,wasm_message_bytes = 0,native_cpu_seconds = 0,native_call_deadline_ms = 0wasm_memory_bytes = 1024(below the 64 KiB one-page minimum)native_memory_bytes = 1024(below the 16 MiB minimum)
plan()then emits aSetProfilestep for each (any non-default profile that differs from current,world_manifest.rs:285-289). The live apply reachesWorldService::set_execution_profile, which resolves first and refuses (pkgs/id/src/world_session/mod.rs:266:profile.resolve(self.runtime)?).world doctor'scheck_profile(world_doctor.rs:326-366) flags exactly these values — the doctor and the manifest validator disagree about what a valid profile is. -
The schedule count. A present
schedulesmap is reconciled exactly (world_manifest.rs:293-308: add missing, cancel undeclared), so the desired end state has exactlylen(schedules)pending.validate()accepts 65 entries — one pastMAX_PENDING_SCHEDULES = 64(world_caps.rs:95), the capWorldCore::check_scheduleenforces on every live set (world/core.rs:613-617, called fromworld/actor.rs:759). No live world can ever hold the state the manifest declares.
Verified with a probe (laptop, this run)
Probe crate ~/git/fleet/probe-2026-10-31-laneA-manifestvalidate/ (laptop) built from verbatim world_manifest.rs (md5 7b3e4e0a…), the verbatim validators/constants of world_caps.rs (md5 ac9d6bd5…), and the verbatim WorldExecutionProfile + resolve() of world_limits.rs (md5 94fccbd8…) — both clones at 6bbb065b:
- All six profile values above:
parse()→ Ok,plan()→ exactly oneSetProfilestep,resolve(RuntimeLimits::default())→ Err. - A 65-entry
schedulesmap:parse()→ Ok,plan()against an empty state → 65ScheduleAtsteps.
Why it matters
id world apply is not atomic: apply_steps runs the steps in reachability order (commands/world.rs ordered_steps: cancels → profile → grants → ceiling → module → schedule additions) and stops at the first error. So a manifest that parse() blessed can:
- fail at the
SetProfilestep after schedule cancels have already landed, or - fail on the 65th
ScheduleAtstep after the profile, grants, ceiling and module install have all been applied and journaled —
leaving the world half-reconciled to a manifest that can never be fully applied, with diff still promising the remaining steps will converge. Validation is the manifest's contract ("a manifest should be validated first; this is a defensive re-check", world_manifest.rs:311-314 on apply()) — the two fields it skips are exactly the two whose live refusals arrive mid-apply.
Distinct from #2876 (unknown/misspelled keys silently ignored — serde-level) and #2166 (module_hash blake3:<hex> doc mismatch): this is about declared, known fields whose values validate() never checks. The schedule horizon (30 days, check_schedule) is deliberately not part of this issue: it is relative to the apply-time clock, so a pure validate() cannot judge it — only the count is time-free.
Acceptance criteria
-
WorldManifest::validate()(orparse()) refuses a profile thatresolve()would refuse: zerowasm_fuel/wasm_message_bytes/native_cpu_seconds/native_call_deadline_ms,wasm_memory_bytes < 64 KiB,native_memory_bytes < 16 MiB— naming the offending bound, consistent withcheck_profile's problem list. -
validate()refuses aschedulesmap with more thanMAX_PENDING_SCHEDULES(64) entries, naming the cap. - Regression tests in
world_manifest.rs's test module (extendingvalidation_rejects_unknown_names_and_bad_hashesor new tests): each bad profile bound failsparse(); a 65-entry schedule map failsparse(); a 64-entry map and a boundary-valid profile (exactly 64 KiB / 16 MiB) still parse. - Existing manifest tests keep passing (
parses_and_round_tripsuseswasm_fuel = 5_000_000and one schedule — both stay valid).
Activity
dezren39 commentedon Oct 31, 2026
🤖 Agent note · filed
dezren39 commentedon Oct 31, 2026
🤖 Agent note · filed (verification correction)
6bbb065b: 17 manifest lib tests + both probe tests pass; the schedule test printsdeclared=65 cap=64 plan_steps=65. Every claim in the issue body now stands as verified.~/git/fleet/probe-2026-10-31-laneA-manifestvalidate/38 remaining items
dezren39 commentedon Nov 2, 2026
🤖 Agent note · picked up
fix(id): repair format string in schedule-count parse test (#3015)
test(id): prefix new world_manifest tests with test_ (#3015)
fix(id): validate world manifest profile bounds and schedule count at…
dezren39 commentedon Nov 2, 2026
🤖 Agent note · done