aboutsummaryrefslogtreecommitdiff
path: root/modules/core/module-world-model.js
diff options
context:
space:
mode:
Diffstat (limited to 'modules/core/module-world-model.js')
-rw-r--r--modules/core/module-world-model.js28
1 files changed, 21 insertions, 7 deletions
diff --git a/modules/core/module-world-model.js b/modules/core/module-world-model.js
index cbfd1fb..4e88f59 100644
--- a/modules/core/module-world-model.js
+++ b/modules/core/module-world-model.js
@@ -580,14 +580,28 @@ class WorldModelModule {
if (prevModel) { try { fs.fsWriteJSON('/system/world-model.prev.json', prevModel); } catch (_) {} }
// v4.5.89b fix: Clean stale temp from previous crash (P1 from review)
try { fs.deleteFile('/system/world-model.tmp.json'); } catch (_) {}
- fs.fsWriteJSON('/system/world-model.tmp.json', this._model);
- const tmp = fs.fsReadJSON('/system/world-model.tmp.json');
- if (tmp) {
- fs.fsWriteJSON('/system/world-model.json', tmp);
- fs.deleteFile('/system/world-model.tmp.json');
- } else {
- console.error('[WorldModel] Save failed: temp file corrupt after write');
+ // Atomic + verified: never promote a write we did not read back byte-for-byte.
+ // Measured 2026-10-23: the old block promoted /system/world-model.json even when every
+ // write returned false, and logged nothing — that is how a graph got replaced by a
+ // partial model. fs.fsWriteJSON() returns a boolean; ignoring it hides quota failures.
+ const payload = JSON.stringify(this._model);
+ const wrote = fs.writeFile('/system/world-model.tmp.json', payload);
+ if (!wrote) {
+ console.error('[WorldModel] Save failed: write returned false (storage quota?)');
+ return;
}
+ const back = fs.readFile('/system/world-model.tmp.json');
+ if (back !== payload) {
+ console.error('[WorldModel] Save failed: read-back mismatch ('
+ + (back ? back.length : 0) + '/' + payload.length + ' bytes) — keeping previous model');
+ return;
+ }
+ const promoted = fs.writeFile('/system/world-model.json', back);
+ if (!promoted) {
+ console.error('[WorldModel] Save failed: promote returned false');
+ return;
+ }
+ fs.deleteFile('/system/world-model.tmp.json');
} catch (e) {
console.error('[WorldModel] Save error:', e.message);
}