Skip to content

Build1 publisher3 min readPublished

WorldScript Studio's autosave fails closed on five classes of unexpected on-disk state

WorldScript Studio's autosave checks the file on disk before writing and refuses to save over five kinds of unexpected state. Destructive recovery is limited to three actions, each tied to one failure kind and one storage backend.

The Engineer · Build desk

Illustration accompanying WorldScript Studio's autosave fails closed on five classes of unexpected on-disk state

What happened

  • The autosave writer's header comment says it fails closed with a typed refusal and has, deliberately, no fallback to storageService.saveProject.
  • When startup cannot load a stored project, one pure function switches off quarantine, reset and safe open, leaving reload as the only option.
  • Every destructive operation takes the same project lock that fenced writes hold, so a delete cannot race a save past a check.
  • Each project creation writes a random token beside project.json, so an old window never matches a recreated project, even a byte-identical one.

Compiled by The EngineerSomething wrong?How this is made

Why it matters

  • cost Rolling back to an older build halts autosave on any project a newer build has written, and the user sees a refusal where a save used to be.
  • constraint Because files in a supported older format are refused too, format upgrades need their own explicit step and cannot happen during an ordinary save.
  • decision Copying the design means listing failure kinds up front and granting destructive authority per kind in one audited function that every recovery dialog reads.
  • exposure Any multi-window local-first editor that identifies a project by its file contents can let a stale window resurrect data another window deliberately deleted.

The post's case starts with a recovery dialog. A project fails to load and the tool offers to start fresh. One click later, the file that failed to parse at 23:40 is gone at 23:41 [15]. "The tool was trying to help," the post's author wrote [20]. In a local-first app, that click has no server copy or account trash bin behind it [16]. The author's rule is that "preservation is the default, destruction requires narrow, earned authority" [17].

WorldScript Studio keeps projects in browser IndexedDB or on the desktop filesystem [1]. Before autosave writes, it classifies what is on disk. Any state that is not clean and current gets one of five typed refusals: MALFORMED, FUTURE, SUPPORTED_OLDER, UNSUPPORTED_OLDER or GENERATION_CONTRADICTION [3][18]. An older build does not "fix" a record a newer build wrote, and a generation contradiction is not smoothed over [5].

The part I would copy first is what happens after a refusal. A silent no-op would let the save indicator claim durability that never happened [6]. Instead, a refusal rejects the coordinator operation. Indexing, analytics and the UI success state all register the failure [6]. The user keeps the open editor state and is told why nothing was written [6].

The post calls the startup recovery matrix deliberately narrow [8]. Quarantine applies only to a corrupt project on the filesystem backend. Reset needs a storage-level failure on IndexedDB. Safe open covers a desktop project refused for an unsupported version or a migration gap [8]. A project I/O error, an unavailable desktop storage authority or a corrupt in-browser record cannot escalate to quarantine or reset. In the code's own framing, non-destructive failures never gain quarantine authority [9].

Quarantine moves the project directory into a quarantined-projects area, where it stays inspectable and can be moved back [10]. The lock file lives beside the project directory, as a sibling. Placed inside, it would be carried off by the same quarantine rename it exists to fence [12].

The per-creation token is the best engineering in the post. It exists for two windows open on one project. If window B deletes the project while window A holds a loaded baseline, a save from A must not recreate it from that stale snapshot [14]. Comparing contents cannot catch this, because the recreated project.json can match the old one byte for byte [13]. Delete and quarantine take the token with the directory, and every create writes a new one [13].

The evidence is one project describing its own code at commit 2d9157c0, release v1.28.8 [2]. The claim that recovery code is the larger data-loss risk is the author's argument, built on the dialog example [15]. The post does not report how often refusals fire in use or what losses the design has prevented. I think the pattern transfers to any tool where the app holds the only copy of the work [16].

What to watch

  • Whether later WorldScript Studio releases keep the canonical autosave writer's no-fallback rule or add a best-effort save path.
  • Field reports on how often FUTURE and GENERATION_CONTRADICTION refusals fire when users move between builds.
  • How the IndexedDB reset path is gated in practice, and whether it keeps a copy of the store before wiping it.
Loading claim ledger
Loading source directory links
Loading share composer
Loading topic controls
Loading related stories