Skip to content

feat(api,ui): showcase pipeline decision + portfolio lifecycle (#316)#318

Merged
w7-mgfcode merged 1 commit into
devfrom
feat/showcase-39-decision-portfolio-lifecycle
May 26, 2026
Merged

feat(api,ui): showcase pipeline decision + portfolio lifecycle (#316)#318
w7-mgfcode merged 1 commit into
devfrom
feat/showcase-39-decision-portfolio-lifecycle

Conversation

@w7-mgfcode
Copy link
Copy Markdown
Owner

Summary

PRP-39 — extends the showcase_rich demo pipeline with three new decision-phase steps and a new portfolio phase. A first-time visitor running /showcase with scenario=showcase_rich now walks through the operator's decision lifecycle (champion-compat verdict, stale-alias V mismatch, safer-Promote dialog) and a portfolio-batch preset, then sees cleanup restore the alias to the V2 winner.

  • Decision phase additions: champion_compat_compare (V1 vs V2 cross-V verdict), stale_alias_trigger (V-mismatch chip on /ops), safer_promote_flow (deliberate worse-WAPE alias swap).
  • New portfolio phase: batch_preset runs the quick_baseline_sweep (3 stores × 2 products × 3 baselines = 18 items) via /batch/forecasting.
  • R15 cleanup restore: step_cleanup restores demo-production to the original V2 winner so the demo finishes with the alias on the actual champion.

Slice B of the four-PRP /showcase upgrade epic (PRP-38..41).

Tracks #316 (parent epic #295).

Drift resolutions (from PRPs/ai_docs/prp-39-contract-probe-report.md)

  • D1RunCompareResponse has no top-level compatible flag. champion_compat_compare derives compatible + comparable_reason client-side, mirroring the existing frontend predicate.
  • D2quick_baseline_sweep preset stays frontend-only. The demo slice hard-codes the same 3 baseline model_types (naive, seasonal_naive, moving_average) into BATCH_PRESET_QUICK_BASELINE_SWEEP_MODELS and expands the preset into a standard BatchSubmitRequest payload (Option A — no backend preset_id).
  • D3POST /batch/forecasting normally settles synchronously. The 90 s poll loop is a safety net guarding against a future async-runner mode.

Test plan

  • uv run ruff check . && uv run ruff format --check . — green
  • uv run mypy app/ — clean (303 source files)
  • uv run pyright app/ — 0 errors, 129 warnings (pre-existing baseline)
  • uv run pytest -v -m "not integration" — 1635 passed
  • pnpm tsc --noEmit -p tsconfig.app.json — no NEW errors introduced (23 pre-existing on dev baseline → 23 after; full diff against baseline = 0)
  • cd frontend && pnpm lint — green on changed files
  • cd frontend && pnpm test --run — 225 passed
  • Vertical-slice grep guard: no NEW cross-slice imports in app/features/demo/
  • WebSocket schema diff: git diff app/features/demo/schemas.py empty
  • git diff --check: zero whitespace errors
  • PHASE_DEFS lockstep: backend _phase_table() + frontend PHASE_DEFS.ts show the same 18-row order under showcase_rich
  • Manual dogfood — deferred (per parent-agent task spec; B5 integration test covers e2e wall-clock)
  • uv run pytest -v -m integration tests/test_e2e_demo.py::test_run_demo_showcase_rich_decision_portfolio — deferred; sharing Postgres with Worker D (PRP-40)

PRP-39 — extend the showcase_rich demo pipeline with three new decision-
phase steps (champion_compat_compare, stale_alias_trigger,
safer_promote_flow) and a new portfolio phase (batch_preset). The
decision lifecycle now demonstrates V1-vs-V2 champion-compat verdicts,
the stale-alias V-mismatch chip on /ops, and the safer-Promote dialog
gates. The portfolio phase runs the quick_baseline_sweep preset (3
stores x 2 products x 3 baselines = 18 items) via /batch/forecasting.

Backend:
- app/features/demo/pipeline.py — 4 new step functions, PHASE_PORTFOLIO
  constant, BATCH_PRESET_QUICK_BASELINE_SWEEP_MODELS module constant,
  DemoContext additive fields (compat_compare_result,
  stale_alias_run_id, original_demo_alias_run_id, batch_id,
  batch_status), step_cleanup extension that restores the
  demo-production alias to its pre-swap target (R15).
- app/features/demo/tests/test_pipeline.py — 8 new unit tests (4 step
  functions, 2 skip paths, 2 cleanup scenarios) + extended canned
  responses for /ops/summary, /batch/forecasting, /registry/runs?...,
  /registry/aliases/{name}, /registry/compare/{a}/{b}; lockstep
  test_phase_table_showcase_rich expanded to 18 rows.
- tests/test_e2e_demo.py — new test_run_demo_showcase_rich_decision_
  portfolio integration test asserting the four new step events fire
  and R15 alias restoration completes.

Frontend:
- PHASE_DEFS.ts — appends 3 decision-phase rows + portfolio phase row;
  PHASE_ORDER + PHASE_LABEL extend with 'portfolio'.
- showcase.tsx — resolveInspectHref gains 4 new case arms targeting
  /explorer/runs/compare, /ops, and /visualize/batch/{batch_id}.
- demo-step-card.tsx — 4 new mini-summary chip-line components.
- demo-step-card.test.tsx (new) — 6 render tests covering chip-lines
  and Inspect button behaviour.
- PHASE_DEFS.test.ts + use-demo-pipeline.test.ts — extended to assert
  the new 18-step showcase_rich layout.

Docs:
- docs/_base/RUNBOOKS.md — 8 new failure-mode entries under the
  /showcase pipeline section covering the 4 new steps (skip / fail
  diagnostics, R15 cleanup recovery).

Drift resolutions (per PRPs/ai_docs/prp-39-contract-probe-report.md):
- D1 (compare envelope): champion_compat_compare derives compatible +
  comparable_reason client-side; mirrors the frontend
  computeCompatibility predicate.
- D2 (quick_baseline_sweep): preset expansion stays in the demo slice
  (Option A); no preset_id on BatchSubmitRequest.
- D3 (sync settle): /batch/forecasting normally returns terminal status
  on submit; the 90 s poll loop is a safety net.

WebSocket schema additive only — no StepEvent / DemoRunRequest field
changes. Relative-anchor phase insertion (PHASE_PORTFOLIO between
PHASE_DECISION and PHASE_VERIFY) keeps the slice merge-order
independent of PRP-40.
Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @w7-mgfcode, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 26, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: bb051e7f-00bd-437f-8f6d-6a9555b81972

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/showcase-39-decision-portfolio-lifecycle

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@w7-mgfcode w7-mgfcode merged commit babb6b3 into dev May 26, 2026
8 checks passed
@w7-mgfcode w7-mgfcode deleted the feat/showcase-39-decision-portfolio-lifecycle branch May 26, 2026 14:12
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