Skip to content

fix(studio): survive damaged package meta; clean up OPFS write husks#116

Merged
Yona-Appletree merged 1 commit into
mainfrom
claude/safari-opfs-meta-resilience
Jul 17, 2026
Merged

fix(studio): survive damaged package meta; clean up OPFS write husks#116
Yona-Appletree merged 1 commit into
mainfrom
claude/safari-opfs-meta-resilience

Conversation

@Yona-Appletree

Copy link
Copy Markdown
Member

Summary

  • Bug: studio bricked on load in iOS Safari with missing session: library: meta: parse meta: expected value at line 1 column 1. Chain: a damaged (zero-filled) /.lp/meta.json + an event log that tolerates the same damage (a garbage log reads as empty via the torn-tail drop) routes PackageHandle::load into the strict read_meta origin fallback — one unparseable provenance sidecar then permanently fails every open of that project, including boot-time session restore.
  • read_meta now parses leniently: damage logs a warning and reads as absent (origin_event_for(None) already falls back to a Created origin). Provenance is a best-effort sidecar and should never be load-bearing — this matches the existing leniency in the event log and the gallery's skip-bad-cards behavior.
  • write_file in lpa-fs-opfs now removes the empty husk it created when the stage-and-swap fails on a file that did not previously exist. The createWritable atomic swap only protects content; getFileHandle(create: true) makes the entry immediately, so a tab jetsammed mid-flush (common on iOS) could persist an entry whose content never committed.
  • Note: serde_json says column 1 (not column 0/EOF), i.e. the file had non-JSON content — the zero-filled signature of size-persisted-but-content-lost, consistent with WebKit OPFS durability behavior under process kill.

Validation

  • New unit test: zero-filled and empty meta.json both read as absent.
  • cargo test -p lpa-studio-core: 453 passed.
  • just lpa-fs-opfs-test (real Chrome + real OPFS via chromedriver): 18 passed across the three suites, exercising the reworked write_file success path end-to-end. (The failure branch is not exercisable in Chrome, whose createWritable doesn't fail on demand.)
  • cargo check -p lpa-fs-opfs --target wasm32-unknown-unknown, just check: clean.

Contribution Terms

By opening this pull request, I confirm that I have the right to submit these
changes and agree to the contribution terms in CONTRIBUTING.md.

🤖 Generated with Claude Code

The studio bricked on load in iOS Safari with "missing session: library:
meta: parse meta: expected value at line 1 column 1": a damaged (zero-
filled) /.lp/meta.json. The history event log tolerates such damage (it
reads as empty), which routes PackageHandle::load into the strict
read_meta origin fallback — one unparseable provenance sidecar then
permanently fails every project open.

Two fixes:
- read_meta parses leniently: damage logs a warning and reads as absent;
  origin_event_for(None) already falls back to a Created origin.
- opfs write_file removes the empty husk it created when the
  stage-and-swap fails on a file that did not previously exist. The
  createWritable atomic swap only protects content — getFileHandle
  (create: true) makes the entry immediately, so a tab jetsammed
  mid-flush (common on iOS) persisted a lie.

Verified: lpa-studio-core suite (453 tests), lpa-fs-opfs real-browser
OPFS suite (18 tests via chromedriver), wasm32 check, just check.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Yona-Appletree
Yona-Appletree merged commit 0e576d9 into main Jul 17, 2026
3 checks passed
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