Skip to content

refactor(playground): give generation one application owner - #109

Merged
leoafarias merged 3 commits into
mainfrom
refactor/generation-lifecycle
Sep 8, 2026
Merged

refactor(playground): give generation one application owner#109
leoafarias merged 3 commits into
mainfrom
refactor/generation-lifecycle

Conversation

@leoafarias

@leoafarias leoafarias commented Sep 8, 2026

Copy link
Copy Markdown
Member

Intent

Wizard generation, editor generation, and the debug generation lab each applied their results differently, and a slow generation could overwrite newer editor work.

This PR follows #108 and targets main. Its incremental diff contains the generation lifecycle changes.

Changes

One application owner — all three hosts now use GeneratedDeckResultApplier. The lab gets its own DeckDocumentStore, so its experiments cannot publish into the editor's document.

Application guard and asset lifetimeapply takes a required guard, serializes application per host, and returns GeneratedDeckApplication(published, cleanupError). It checks the guard before staging artwork and again after that asynchronous work, immediately before publishing. An abandoned attempt removes only the artwork it staged, keeping every asset the committed deck still uses. After a successful publication, a failed cleanup of replaced artwork is reported separately, so the deck no longer counts as a failed generation.

Protecting newer workDeckDocumentStore.revision and DeckFileSession.bindingRevision are read-only. Editor generation captures both when it starts and takes an injected binding-revision reader. Editing the document or switching decks invalidates the run, including a switch between two files with identical content, which the document revision alone cannot detect. The invalidated result is discarded and the editor header shows a non-blocking notice, because the generation panel can be closed before the deck arrives. clearResult() no longer erases that notice. Long notices wrap within the editor pane, including enlarged text, and the dismiss control has an accessibility label.

Wizard lifecycle — timing and result application respect the current operation identifier. A superseded run no longer adds its duration to, or stops the clock of, the run that replaced it.

Shared service setup — the four generation entry points share _withModelSession for model-client creation, executor construction, prompt loading, and disposal. Request budgets, retries, partial results, and tracing are unchanged. The configured models, thinking settings, prompts, and generation strategy are untouched.

Impacted packages

  • packages/playground

Tests

  • generated_deck_result_applier_test.dart — staged-asset removal on an invalidated application, committed artwork preserved when reused, cleanup failure reported after publishing, serialized queued applications, and recovery after an asset write throws. Cancellation also preserves a distinct committed theme and emits no preview update.
  • editor_header_test.dart — 600px layout, accessible dismissal, and normal/150% text size. Both layout cases fail on the original header and pass with the fix.
  • generate_deck_command_test.dart — discard on a document edit, discard on a deck switch with identical content, publication when nothing replaced the run, and notice survival across clearResult().
  • wizard_generation_controller_test.dart — the applier guard blocks a late application, a cleanup failure does not fail the generation, and a superseded run does not stop the current run clock.
  • deck_document_store_test.dart and deck_file_session_test.dart — revision counting and a binding change for identical content.

Commands run

fvm dart run melos run analyze --no-select         # Dart/DCM clean
fvm dart run melos run contracts:check --no-select # SUCCESS
fvm dart run melos run test --no-select            # 2,148 package tests passed on the combined stack

Plus the deterministic 10-slide generation checkpoint, which passed with qualityReport.passed and 10/10 slides captured.

Generation and UI verification

The live 10-slide smoke test passed on September 8 with three artworks, all ten slides replayed and captured, and 18.778 seconds of generation time. Its quality report passed with one non-blocking commitment-grounding diagnostic. This is one latency sample. No generation models, prompts, or thinking settings changed in the follow-up.

The actual editor header was also checked in an isolated macOS harness at 600px and 150% text size, using fake file storage. The notice wrapped and clicking dismiss removed it, with attached Flutter logs showing no runtime errors. Before/after screenshots are retained with the local review evidence; media is not attached to this PR. The full interactive Wizard/editor race walkthrough remains incomplete.

The follow-up also passed code generation, melos run fix, contract schema checks, and workflow lint, with no generated-file changes.

@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown

Visit the preview URL for this PR (updated for commit d895a86):

https://superdeck-dev--pr109-refactor-generation-ti7tupz3.web.app

(expires Thu, 08 Oct 2026 19:24:30 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

Sign: bd68fc230762285849207e7e120aaf87cd4ca2f9

@leoafarias
leoafarias force-pushed the refactor/generation-lifecycle branch from b9ca8ec to 20c0008 Compare September 8, 2026 19:00
Base automatically changed from fix/deck-runtime-lifecycle to main September 8, 2026 19:19
Wizard generation, editor generation, and the debug generation lab each
applied their results differently. Route all three through
GeneratedDeckResultApplier, and give the lab its own document store so its
experiments cannot publish into the editor's document.

The applier now takes a required application guard, serializes application per
host, and reports whether publication happened. It removes the artwork one
abandoned attempt staged while keeping every asset the committed deck still
uses. After a successful publication it reports a failed cleanup of replaced
artwork separately, so the deck no longer counts as a failed generation.

DeckDocumentStore and DeckFileSession expose read-only revisions. Editor
generation captures both when it starts, so editing the document or switching
decks — including a switch between files with identical content — discards
the generated deck. The editor header shows that non-blocking notice, because
the generation panel can be closed before the deck arrives.

Wizard timing and result application now respect the current operation
identifier, and the four generation entry points share one model-client
setup, prompt load, and disposal path.
The applier tests checked the document and the artwork but not the theme or
the preview. Assert all four states together for a published result, and
assert that an invalidated result leaves the committed theme in place.
@leoafarias
leoafarias force-pushed the refactor/generation-lifecycle branch from 20c0008 to d895a86 Compare September 8, 2026 19:19
@leoafarias
leoafarias merged commit 5aa463e into main Sep 8, 2026
5 checks passed
@leoafarias
leoafarias deleted the refactor/generation-lifecycle branch September 8, 2026 19:32
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