Make machine configuration authoritative and restore native checkpoints exactly

This commit is contained in:
2026-09-18 09:09:41 +08:00
parent 6a69511276
commit 4a568f1f4c
94 changed files with 10882 additions and 301 deletions

View File

@@ -30,7 +30,7 @@ async function create(id) {
assert.equal(send("POWER", "power-on", { active: true }).payload.status, "verified");
assert.equal(send("HOME", "home-all", { all: true }).payload.homing.phase, "accepted");
assert.equal(send("SIM_STEP", "home-complete", { cycles: 1 }).payload.panel_snapshot.motion.homed, true);
return { core, session, send };
return { core, session, send, adoptSequence: (value) => { seq = value; } };
}
const continuous = await create("xyzac-recovery-continuous");
@@ -42,6 +42,7 @@ continuous.send("PROGRAM_RUN", "program-run");
const stepped = continuous.send("SIM_STEP", "motion-step", { cycles: 2 });
assert.equal(stepped.payload.status, "verified");
const checkpointResponse = continuous.send("CHECKPOINT", "checkpoint");
assert.equal(checkpointResponse.kind, "CHECKPOINT_READY", checkpointResponse.payload.message_key);
const checkpoint = checkpointResponse.payload.checkpoint;
assert.equal(checkpoint.state.kinematics.active_type, 1);
assert.equal(checkpoint.state.kinematics.coordinates, "XYZAC");
@@ -57,7 +58,10 @@ continuous.send("SIM_STEP", "after-checkpoint", { cycles: 2 });
const endpoint = continuous.session.workspacePackageState();
const restarted = await create("xyzac-recovery-continuous");
const recovery = restarted.session.restoreCheckpoint(checkpoint, continuous.session.timeline.export(), (operation) => operation);
const rejectedTail = restarted.session.restoreCheckpoint(checkpoint, continuous.session.timeline.export(), (operation) => operation);
assert.equal(rejectedTail.status, "blocked");
assert.equal(rejectedTail.blocked[0].reason, "trt_checkpoint_tail_requires_explicit_commands");
const recovery = restarted.session.restoreCheckpoint(checkpoint);
if (recovery.status !== "recovered") console.error(JSON.stringify(recovery));
assert.equal(recovery.status, "recovered");
const restored = restarted.session.workspacePackageState();
@@ -68,11 +72,16 @@ assert.equal(restored.kinematics.state_hash, before.kinematics.state_hash);
assert.equal(restored.kinematics.switch_count, switchCountBefore);
assert.equal(restored.program.source_hash, before.program.source_hash);
assert.equal(restored.motion_authority, "wasm");
if (fnv1a64(before) !== fnv1a64(restored)) console.error(JSON.stringify({ differing: Object.fromEntries(Object.keys(before).filter((key) => fnv1a64(before[key]) !== fnv1a64(restored[key])).map((key) => [key, { before: before[key], restored: restored[key] }])) }));
assert.equal(fnv1a64(restored), fnv1a64(before), "checkpoint must restore complete runtime state");
const replay = restarted.session.ledger.reconcile("switch-once");
assert.equal(replay.status, "committed");
assert.equal(restarted.session.xyzacKinematics.snapshot().switch_count, switchCountBefore);
restarted.adoptSequence(checkpoint.event_cursor);
const replayedSwitch = restarted.send("MDI_EXECUTE", "switch-once", { block: "M428" });
assert.equal(replayedSwitch.replayed, true);
assert.equal(restarted.session.xyzacKinematics.snapshot().switch_count, switchCountBefore);
assert.deepEqual(replayedSwitch.payload.panel_snapshot.visual.joints, before.motion.joints);
const corruptedState = structuredClone(checkpoint);
corruptedState.state.kinematics.pose.x += 1;
@@ -111,8 +120,10 @@ console.log(JSON.stringify({
status: "verified",
case: CASE,
checkpoint: { required_fields: ["context_id", "simulation_tick", "event_cursor", "state_hash", "task", "program", "kinematics", "motion", "wasm_motion", "ledger"], active_type: checkpoint.state.kinematics.active_type, state_hash: checkpoint.state.kinematics.state_hash },
continuous_endpoint_hash: fnv1a64(endpoint),
continuous_endpoint_hash: fnv1a64(before),
restored_endpoint_hash: fnv1a64(restored),
checkpoint_tick: checkpoint.simulation_tick,
unreplayed_tail_endpoint_hash: fnv1a64(endpoint),
endpoint_at_checkpoint_equal: fnv1a64(before) === fnv1a64(restored),
no_duplicate_m428: restarted.session.xyzacKinematics.snapshot().switch_count === switchCountBefore,
replayed_operation: replay.status === "committed",