Skip to content

feat: packages and places — library, load-as-push, save-as-pull (M3)#72

Draft
Yona-Appletree wants to merge 1 commit into
feature/protocol-file-syncfrom
feature/packages-and-places
Draft

feat: packages and places — library, load-as-push, save-as-pull (M3)#72
Yona-Appletree wants to merge 1 commit into
feature/protocol-file-syncfrom
feature/packages-and-places

Conversation

@Yona-Appletree

Copy link
Copy Markdown
Member

Summary

Stacked on #70 (M2b) — merge that first; this diff then shows only M3.

Roadmap M3: the library becomes the source of truth and the sim an ephemeral place (D19/D20). Reload persistence is now real: the demo seeds into the library exactly once, opening pushes the library head to the sim (hash-verified, then a version probe baselines save-as-pull), and every committed save pulls the changed files back into the library with an lpc-history snapshot + Saved event.

  • lpa-studio-core/app/library: LibraryStore (list / create / duplicate-as-fork / rename / delete / open) over any LpFs, uid-minting manifest patcher with canonical key order, /.lp/meta.json provenance sidecar, slugs, zip import/export (fresh uid + ImportedZip provenance on import — shared zips can't collide identities).
  • lpa-studio-core/app/places: Place trait (kind/capacity), library + runtime places, connect-classify helper, device registry (/registry.json) + /.lp/device.json identity conventions for M5.
  • ProjectController: seed-once, open_seeded_demo_from_library, and the save-as-pull hook (empty pulls record nothing; a library-sync failure warns and retries next save — never fails the user's save). StudioCommand::AttachLibrary delivers the mounted store from the web shell before the connect action.
  • lpc-model: ProjectDef gains the authored uid slot (the pre-staged ProjectConfig adoption) + schema regen. Worth reviewer attention: without it, the slot codec hard-rejects library manifests as unknown-field typos — and the server's LoadProject failure mode for a root parse error is silence (no response at all), which made this the longest debugging session of the roadmap. A fw-browser regression test now covers uid'd + sidecar'd loads; the silent-failure server bug is filed separately.
  • lpa-client: replace_and_load_project composite.

Test plan

  • 292 lpa-studio-core tests (library CRUD/fork/history round-trips, canonical-order manifest patching verified through the real slot codec, zip round-trips incl. Finder-noise tolerance, places/registry/identity)
  • fw-browser wasm 5/5 incl. the new load_project_tolerates_library_artifacts A/B regression (plain / uid / sidecar / both)
  • Live in Chrome on real OPFS: seed-once (reload never reseeds), hash-verified load-as-push ("basic is loaded", editor renders library content), save hook, history events on disk. Caveats found and documented: hidden-tab timer throttling crawls the polling transport (existing M7 event-driven-receive note), and the fw-browser worker sidecar must be rebuilt when wire/model crates change (stale sidecar cost hours).
  • just build-ci / just test green; story baselines unchanged (532 + 14 tolerance); schema gen clean; clippy clean on all touched crates (just check still red on main's pre-existing lps-builtins issue)

The P6 review gate remains yours: the full edit→Save→reload demo in your own browser (note: pick a persisted edit — value edits, not the optional-enable toggles, which commit as transient).

🤖 Generated with Claude Code

The library becomes the source of truth and the simulator an ephemeral
place (roadmap D19/D20). Reload persistence is now real: the demo seeds
into the library exactly once, opening pushes the library head to the
sim (hash-verified), and every committed save pulls changed files back
into the library with an lpc-history snapshot + Saved event.

lpa-studio-core:
- app/library: LibraryStore (list/create/duplicate-as-fork/rename/
  delete/open) over any LpFs, uid-minting manifest patcher with
  canonical key order (the slot codec streams kind-first; serde_json
  maps are alphabetical), /.lp/meta.json provenance sidecar, slugs,
  zip import/export (fresh uid + ImportedZip provenance on import).
- app/places: Place trait (kind/capacity), library + runtime places,
  connect-classify helper, device registry (/registry.json) and
  /.lp/device.json identity conventions (M5 wires the flows).
- ProjectController: seed-once demo, open_seeded_demo_from_library
  (replace_and_load + hash verify + version probe), save-as-pull hook
  after successful commits (empty pulls record nothing; failures warn
  and retry next save — the user's save never fails on library sync).
- StudioCommand::AttachLibrary rides the command queue from the web
  shell once the store mounts, before the connect action.

lpc-model: ProjectDef gains the authored `uid` slot (the pre-staged
ProjectConfig adoption) — schemas regenerated. Without it the slot
codec hard-rejects library manifests as unknown-field typos, and the
server's LoadProject failure mode for that is silence (no response),
which cost this change its longest debugging session; a fw-browser
regression test now covers uid'd + sidecar'd project loads.

lpa-client: replace_and_load_project composite (StopAll → clear →
chunked writes → LoadProject).

Verified live in Chrome against real OPFS: seed-once (reload never
reseeds), hash-verified load-as-push, save hook, and the history log
gaining events — with the studio driven over the BrowserWorker
transport. Note: hidden-tab timer throttling makes the polling
transport crawl (existing M7 event-driven-receive note); the fw-browser
worker sidecar must be rebuilt when wire/model crates change.

Plan: Planning/lp2025/2026-07-06-packages-and-places (roadmap M3)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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