Skip to content

fix: undo coverage, safe loads, and persistence honesty#34

Merged
zntznt merged 1 commit into
mainfrom
fix/undo-persistence
Jul 3, 2026
Merged

fix: undo coverage, safe loads, and persistence honesty#34
zntznt merged 1 commit into
mainfrom
fix/undo-persistence

Conversation

@zntznt

@zntznt zntznt commented Jul 3, 2026

Copy link
Copy Markdown
Owner

Batch 2 of the codebase review fixes: everything around undo/redo integrity, destructive loads, and persistence.

  • Undo coverage: connection path-style buttons, state-connection role chips, and the custom-variable distribution chip now commit; the +/- resource steppers commit at rest (where the count is the serialized baseline) and stay transient mid-run
  • Safe loads: new _canLoadDiagram() trial-loads untrusted payloads into a throwaway Diagram first. Open file, library Load, the share-URL path and autosave restore all validate before touching the real diagram, so corrupt input can no longer wipe your work (Open file previously destroyed the diagram and let autosave persist the wreckage). The library's raw alert() is now a toast
  • Boot hardening: the one unguarded localStorage.getItem in _initDiagram is wrapped, so blocked-storage contexts (embed iframes, strict privacy modes) boot instead of dying in the constructor
  • Scrub state: undo/redo and File/New while replaying a finished run now exit scrub mode, so the renderer stops painting the dead run's values and the slider stays live
  • Library honesty: quota/blocked-storage failures now surface as error toasts instead of a false "Saved"
  • Seed hygiene: File/New and templates no longer inherit the previous diagram's run seed
  • Scenario state: checkpoints and ghost branches are dropped on any whole-diagram replacement, so forking an old checkpoint can't resurrect a replaced diagram
  • Tool shortcuts no longer fire while a properties-panel dropdown is focused; changing the speed slider mid-run no longer resamples "on play" variables; the AI-player panel no longer mutates the model during render

Verification: 185 unit tests green, smoke test green, plus a targeted 16-check Playwright script exercising each fix end to end (commit-stack growth per control, corrupt-load leaving the diagram intact, scrub exit on undo/New, seed and checkpoint clearing, quota toast, select-focus suppression, on-play preservation across speed changes, blocked-storage boot).

Undo/autosave coverage:
- Connection path-style buttons, state-connection role chips and the
  custom-variable distribution chip now end in _commit(), so those edits
  reach undo and autosave (they previously vanished on reload/undo).
- The +/- resource steppers commit at rest (step 0), where the count is
  the serialized starting baseline; mid-run nudges stay transient.
- _diagramAI no longer assigns rule.nodeId while rendering; an unset
  target only displays as the first interactive node and is written on
  change, so render can't drift undo snapshots.

Destructive load:
- Open file, library Load, share-URL and autosave restore now parse and
  validate on a throwaway Diagram (_canLoadDiagram) before touching the
  real one; corrupt input toasts and leaves the diagram untouched
  instead of wiping it and throwing (raw alert() replaced with _toast).
- _initDiagram guards localStorage.getItem so blocked storage (Safari
  private mode / embedded iframe) can't abort the App constructor.

State hygiene on replace:
- _restoreState and _clearAll exit scrub mode, so undo/New no longer
  leave the renderer painting a dead run and a dead tl-range slider.
- _clearAll resets diagram.seed to the constructor default and both
  _clearAll and _commitReplace drop session checkpoints/branches
  (_dropScenarioState), keeping the Branch panel and timeline in sync.

Honest feedback and controls:
- _saveLibrary/_saveComponents report write failures; callers toast a
  storage-full error instead of a false Saved.
- Tool shortcuts ignore keystrokes while a <select> is focused.
- Changing speed mid-run restarts the tick interval without resampling
  'on play' custom variables (values preserved across stop/run).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@zntznt
zntznt merged commit 04c2949 into main Jul 3, 2026
1 check passed
@zntznt
zntznt deleted the fix/undo-persistence branch July 16, 2026 21:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant