Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions MANIFEST.sha256
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,12 @@ d4d912fbec5d674a16c2c12242332335924405ebc6bdf080c904d32e08d15396 tests/test_sov
583706bc944261a63b317d75ad666604155d3a286ae99ad21b13d2321d7d7341 tests/test_sovereign_renderer_contract.mjs
6238a56aa042a20b86e3b555786d34849094c894d8473fd80d6a5255d38a5108 tests/test_sovereign_renderer_motion_upgrade.mjs
3f63626f40bebc0746521643f1fff6bc522e402218965ee327b8725b6e50dc94 tests/test_sovereign_reproduction.mjs
2fd7bc90cad5a8d5d51925ac2579267cc42505b4fee5dbbe8a8acd3ed6eb2e06 tests/test_sovereign_runtime_contract.mjs
f6c7f2623eeeeea2faebe84c30e135c6357403b3c44aee379dc5f8058064ecac tests/test_sovereign_runtime_contract.mjs
6c69813ab0bc4cb1534b82e8a7d06dc323c8a6c0458298e0a0584b7bde4d47e8 tests/test_sovereign_shell.mjs
3addb20df209d6f6ad84ff37adaa7dd67bf2c10adfc4c372559bc32543311415 tests/test_sovereign_shelter_environment.mjs
218e8e718765fa3e19aead2359ab5cec36778c6fda596176d8b016a38843da00 tests/test_sovereign_society.mjs
5357326e16f8493d08ecc0a56bae1a48773c1f2e979f830f99181054e144ce7a tests/test_sovereign_transient_physics_upgrade.mjs
f083f228454b586273016fe7265d7badd2e7910f6484be49f0c88640670d5214 worker/src/index.js
f19d6c322cd8b17bd8f65560e4602d523899f8546d70dd40a783cc8a285ab0a7 worker/src/index.js
2eac2b46fb9337eb62b4b716be26eb11f92359c58e6c6685039f3506346a09fb world/actions.js
79cdf84d53e19cb1500f2a782aad657d49281005c7809e06bfcf190f7411f294 world/artifacts.js
251ef01a7616cef68bba68b1bc81ac62d30b0bd1685a8beb9784c4ba55fa469b world/beliefs.js
Expand Down
15 changes: 15 additions & 0 deletions tests/test_sovereign_runtime_contract.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,21 @@ test('constructor never postpones a due alarm and alarm handler keeps the schedu
assert.match(alarm,/finally/);
assert.match(alarm,/setAlarm\(Date\.now\(\)\+ALARM_MS\)/);
});
test('runtime recovery is persisted immediately before hibernation can discard the rebase',()=>{
const tickStart=worker.indexOf('async tick(){');
const tickEnd=worker.indexOf('async alarm(){',tickStart);
const tick=worker.slice(tickStart,tickEnd);

assert.match(tick,/progress\.recovered/);
assert.match(tick,/persist\(\{forceSeal:true\}\)/);

const recoveryIndex=tick.indexOf('progress.recovered');
const checkpointIndex=tick.indexOf('checkpointDue',recoveryIndex);

assert.ok(recoveryIndex>=0);
assert.ok(checkpointIndex>recoveryIndex);
});

test('canonical world persists in Durable Object SQLite with SHA-256 checkpoint seals',()=>{
assert.match(worker,/storage\.sql/);
assert.match(worker,/CREATE TABLE IF NOT EXISTS world_state/);
Expand Down
7 changes: 6 additions & 1 deletion worker/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,12 @@ export class SovereignWorld {
this.world.clock.worldMinute-lastPersisted >=
PERSIST_INTERVAL_WORLD_MINUTES;

if(checkpointDue){
if(progress.recovered){
// Recovery rebases realEpochMs so downtime is not counted as lived
// world time. Persist that boundary immediately; otherwise Durable
// Object hibernation can discard it and reload the pre-recovery state.
await this.persist({forceSeal:true});
}else if(checkpointDue){
await this.persist();
}

Expand Down
Loading