Repository navigation
Description
Problem
plan() / diff() in pkgs/id/src/world_manifest.rs misreport drift in both directions:
- False negative — seed-only changes vanish.
WorldStatecarries the live seed (world_manifest.rs:63-64, "The seed the active program was installed with"), and the manifest'sseedis a declared field — butplan()only ever uses the seed as a ride-along onInstallModule(:207-218). If the module is unchanged and only the seed differs, the plan is empty anddiff()prints "no drift". The new seed is never applied and the admin is told nothing is wrong. - False positive — ceiling reorder is "drift", grants reorder is not. Grants are compared as
BTreeSets (:231-240), so reordering the same grants produces no step. The ceiling is compared as an ordered slice (:242-249:current.ceiling.as_deref() != Some(ceiling.as_slice())), so writing the same ceiling in a different order produces aSetCeilingstep and a drift line — a semantically empty change thatid world applywill "apply" and count.
Evidence (verified this run, main 279c973)
Probe (crate on the laptop compiling the verbatim world_manifest.rs sha256 234f1dfc… + world_caps.rs sha256 679a2c25…, identical sandbox↔laptop; log hidden_files/probe-2026-10-27-laneB-manifest/out.log):
- Manifest
module_hash = "abc123",seed = 99vs live state{ module_hash: "abc123", seed: 7 }→steps=[],diff="no drift" - Manifest
ceiling = ["time.now", "chat.say"]vs live ceiling["chat.say", "time.now"](same set) →steps=[SetCeiling { ceiling: Some(["time.now", "chat.say"]) }] - Control, grants mirror of the same reorder →
steps=[] - Control, genuinely new schedule →
ScheduleAtstep as expected
Why it matters
id world diff is the admin's drift oracle and apply reconciles from the same plan(). A false "no drift" silently strands a seed change (the seed drives the program's deterministic initializer, so the world keeps running with the wrong one while the manifest claims otherwise), and order-noise drift trains admins to ignore diff output — the exact failure mode a declarative manifest exists to prevent.
Distinct from #818 (the CLI wiring fabricates the current state the plan runs against — this defect is in pure plan() itself, reproduced against a correct, hand-built state) and from closed #817 (omitted-field semantics).
Acceptance criteria
- A seed-only difference produces an explicit reconciliation outcome — either a step that reinstalls with the new seed, or
diff/plansurface the seed as unreconcilable-without-reinstall drift — pinned by a test; "no drift" for a differing seed is not an accepted outcome - Ceiling comparison is set-based like grants: reordering the same ceiling names yields an empty plan, and a genuinely different ceiling still yields
SetCeiling - Tests cover: seed-only diff, ceiling reorder (no step), ceiling set change (step), grants behaviour unchanged
-
cargo testfor theworld_manifestmodule passes;apply_is_idempotentand the id(world-manifest): PR #801 — plan() treats omitted grants/ceiling/schedules as authoritative, contradicting 'empty fields are left alone' (omitted ceiling widens to whole catalog) #817 regression tests still pass
Activity
developing-today commentedon Oct 27, 2026
CODE-580
dezren39 commentedon Oct 27, 2026
🤖 Agent note · filed
85 remaining items
dezren39 commentedon Oct 28, 2026
🤖 Agent note · parked
nix flake checkstill pending after 5-min poll, all other checks pass, 0 failuresid(world-manifest): seed-only change plans a reinstall; ceiling compa…
dezren39 commentedon Oct 28, 2026
🤖 Agent note · done