mirror of
https://github.com/stablyai/orca.git
synced 2026-09-22 08:02:28 +00:00
* Skip no-op state writes and bound save postponement in persistence orca-data.json (1.6MB live) was fully rewritten (pretty-print + tmp + rename) on every debounced save even when the state content had not changed - measured 3 rewrites/min (~5MB/min) on an idle production instance, and a sync-flush storm of identical multi-MB writes at every warm start via persistPtyBinding re-binds. - Content-hash guard in both writers: a save whose plaintext state hash matches the last successful write skips serialize+write+rename entirely. Hashing plaintext (not the payload) because encrypt() uses a random IV per call. Safe under flushOrThrow's durability contract: a matching hash means the file already holds exactly this state. - Debounce 300ms -> 1s trailing with a 5s max-wait. The old timer reset on every mutation with no bound, so sustained sub-interval mutation bursts could postpone the write indefinitely; now staleness is capped at 5s while bursts coalesce. Co-authored-by: Orca <help@stably.ai> * Guard the state-hash against sync-flush interleaving mid-rename From adversarial review: an async writer that had already passed its generation check and dispatched the rename could have a sync flush interleave during the await, write fresher state, and record its hash - the async continuation then clobbered lastWrittenStateHash with a value describing content NOT on disk, making later saves (including the quit flush) silently skip. Re-check writeGeneration before recording. Twin edge: a hash-matching sync flush could skip its write while a stale dispatched rename lands afterwards, leaving stale content unchallenged. flushOrThrow now forces the sync write whenever an async write chain was in flight at entry, restoring the sync-write-last disk ordering. Co-authored-by: Orca <help@stably.ai> --------- Co-authored-by: Orca <help@stably.ai>