Skip to content

Make Lavish captain boards permanent and durable - #66

Open
ruby-dlee wants to merge 2 commits into
mainfrom
fm/lavish-fork-captain-surface
Open

Make Lavish captain boards permanent and durable#66
ruby-dlee wants to merge 2 commits into
mainfrom
fm/lavish-fork-captain-surface

Conversation

@ruby-dlee

Copy link
Copy Markdown
Owner

Summary

Makes the Lavish captain surface a permanent property of the fork while preserving its bounded durable file protocol: no server, listener, resident process, shared browser profile, or shared port.

Captain requirements

  • Per-item annotations: boards capture question notes and comments keyed by individual option values, and lavish-axi collect persists them as first-class schema-version-2 answer data.
  • Picture and screenshot spots: visual evidence under each decision visuals/ directory renders inline as self-contained data URLs.
  • Relvino design system: the fork vendors the dark-default Relvino tokens, including Inter, Ruby green, blue-500 #007AFF, semantic aliases, and 16px cards.
  • Separate browser with no leaks: bin/fm-lavish-board.sh opens a named headed chrome-devtools-axi session with a throwaway profile; the fork itself remains bounded and serverless.
  • Captain-shell operation: the helper resolves its co-located Lavish fork and accepts an explicit Firstmate home, without depending on FM_HOME or a stale global install.

Durable-submission defect fixed

The first implementation persisted submission only in window.__lavishPayload plus the LAVISH-SUBMIT v2 document-title marker. If the page closed before the polling check read that live JavaScript state, if the captain submitted in a different browser, or if polling had not run yet, the complete answer disappeared without a trace. That exact failure lost the captain a full board of answers tonight.

The submit handler now serializes the complete structured payload, builds a JSON Blob, creates an object URL, and clicks a synthetic download anchor named lavish-answer-<decision-id>.json before emitting the live-page marker. The done screen also shows the formatted raw JSON in a read-only selectable textarea when downloads are blocked. No localStorage fallback was added because file:// access can throw SecurityError.

The one-shot checker searches fresh deterministic downloads first, atomically copies a matching payload into its declared durable state destination, and only falls back to the live-page marker when no download exists. It accepts browser collision suffixes while rejecting stale, malformed, and wrong-decision files.

Closed-page proof

A real self-contained file:// board was opened in an isolated headed Chrome session. I selected the durable-download option, entered a question note, an option comment, and an overall note, reviewed the batch, and submitted it. Chrome wrote lavish-answer-closed-page-proof.json. I then opened a blank tab, closed the actual board tab, confirmed only about:blank remained, and ran the checker afterward. The checker recovered the downloaded JSON into the durable payload destination with the selected value and all three annotations intact.

In other words: a submitted answer is recoverable after the page is closed. This directly covers the failure that lost the captain a full board of answers tonight; the proof did not read window.__lavishPayload from a live board.

Other validation

  • bash tests/fm-lavish-board.test.sh passed, including a closed-page download-first test that makes live-page evaluation fail if attempted.
  • Focused board DOM/contract coverage passed before the final ordering-only change; a later rerun hit the known host-load ps ENOBUFS test-harness failure rather than a product assertion.
  • bin/fm-lint.sh bin/fm-lavish-board.sh tests/fm-lavish-board.test.sh tests/lib.sh passed with pinned ShellCheck 0.11.0.
  • node --check tools/lavish/src/board.mjs and git diff --check passed.

Deliberately not built

  • No server, listener, resident collector, filesystem watcher, shared port, or access to the captain main Chrome profile.
  • No localStorage transport.
  • No mutation of existing live decisions.
  • No automatic answer acceptance without lavish-axi collect manifest validation.

This PR must not be merged without captain approval.

@ruby-dlee
ruby-dlee force-pushed the fm/lavish-fork-captain-surface branch from 9768c83 to 6aa0f18 Compare August 1, 2026 21:43
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