Skip to content

feat(api,ui): showcase workspace — preserve, restore, and replay showcase runs #389

Description

@w7-mgfcode

Summary

The /showcase page is a fixed demo runner: every run creates model runs, scenario plans, registry aliases, and on-disk artifacts, but nothing records what was created — objects accumulate unlabeled in the DB and the only run memory is a localStorage FIFO of 5 entries (frontend/src/pages/showcase.tsx:166). The UI exposes only 3 of the 8 seeder presets even though the backend already accepts the full ScenarioPreset enum (app/features/demo/schemas.py:57). There is no way to name a showcase session, find its objects afterwards, or re-run an earlier configuration — the demo cleanup step intentionally deletes nothing (app/features/demo/pipeline.py step_cleanup), so preservation exists de-facto but with zero semantics or discoverability.

Approach

Additive, single-host, no new services or runtime dependencies. The demo slice gains its first persistence: a showcase_workspace table (new app/features/demo/models.py, batch-slice precedent) shipped via Alembic, storing name, seed, preset, scope, and the created run_ids / scenario_ids / batch_id / aliases / artifact paths as the pipeline records them. DemoRunRequest (HTTP + WS start frame) gains additive Optional fields only — preservation policy and workspace name — so legacy clients keep working byte-compatibly. Showcase-saved scenario plans reuse the existing GIN-indexed scenario_plan.tags column (["showcase", "workspace:<name>", "source:showcase"]). The frontend ScenarioPicker exposes all 8 presets as guided cards (backend change ~zero) and adds workspace save/restore UI. The linear streaming pipeline, the WS event taxonomy, and the seeder HTTP schema do NOT change shape; restore/replay re-submits a recorded configuration through the existing run path.

Decomposition

Out of scope (explicit)

  • Advanced seed config UI (25+ DimensionConfig/FactsConfig knobs) — reason: requires a new seeder HTTP schema surface; its own epic, while seed + date window are already exposed today.
  • Interactive per-phase configuration (mid-run panels) — reason: re-architects the linear streaming pipeline and contradicts the request/response design.
  • Artifact export bundle under artifacts/showcase/<workspace>/ — reason: no codebase grounding; disk-layout design unsettled.
  • Ops/approval-history phase enrichment — reason: /ops/* endpoints already cover most of it; the remaining need is unclarified.
  • Manual winner selection mid-pipeline — reason: no mid-run interactive gate infrastructure exists outside the agent HITL step.

Success criteria

  • A showcase run started with a workspace name creates exactly one showcase_workspace row recording seed, preset, scope, created run_ids, scenario_ids, batch_id, aliases, and artifact paths
  • All 8 ScenarioPreset values are selectable on /showcase and each runs to a green pipeline (or a documented expected-skip)
  • Showcase-saved scenario plans carry ["showcase", "workspace:<name>", "source:showcase"] and are retrievable via GET /scenarios?tags=workspace:<name>
  • A prior workspace can be restored: its config reloads into the UI and a replay with the same seed/preset completes without 409/500
  • Legacy clients are unaffected: a start frame without the new fields behaves byte-identically to today (demo_minimal, ephemeral)
  • Alembic migration applies and downgrades cleanly on a fresh DB; all five CI gates green

Risks

Risk Mitigation
Replay collides with registry duplicate detection #146/#324 verified fixed; add a replay regression test that runs the same config twice
SPARSE / short-window presets fail mid-pipeline (NaN WAPE, 75-day backfill gate) expected-skip semantics per preset card + runbook entry; pipeline already skips NaN folds
WS start-frame change breaks legacy clients additive Optional fields only; contract test for the legacy frame
demo slice's first DB table triggers an alembic cold-boot import cycle follow the batch-slice models.py precedent + lazy-import rules in docs/_base/ARCHITECTURE.md
localStorage run history diverges from server workspaces server is source of truth in workspace mode; localStorage stays for ephemeral runs only

Tracking

  • Source of truth: docs/flow-pack-methodology.md + working state .flow/state.md (brainstorm Round 4)
  • Milestone: showcase-workspace
  • One-pass confidence: 8/10 (backend already accepts all 8 presets and replay blockers are verifiably fixed; restore-vs-replay semantics need design in the E4 PRP)

Metadata

Metadata

Assignees

No one assigned

    Labels

    featNew featureflowflow: command-suite workumbrellaUmbrella initiative (scope owner)

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions