## Summary
Reverts the Admissions → Forecast dashboard to the 6-stage funnel with the historical 5/50/50/73/73/95 moderate baseline, restoring the layout from the original Spotlight implementation. Drops the "Ongoing" scenario toggle and the per-stage ongoing-actuals comparator we'd added on top.
Two commits:
1. feat: revert to 6-stage funnel and historical baseline — restore stages, baseline, scenario semantics. Drop ongoing scenario toggle and the per-stage +N ong comparator.
2. refactor: match Spotlight pipeline-projection layout — restore the original chip-below layout: per-stage contribution renders as a separated accent chip beneath each card, treating Enrolled as a regular 7th card. Renames per-card "yield" → "conv." for parity with the connector label.
## Changes
### Stage model
- chat/components/dashboards/admissions/forecast/types.ts — ConversionRates is back to 6 keys (leadToShowcase, showcaseToApp, appToShadow, shadowToApproved, approvedToOfferSent, offerSentToEnrolled). ChainStage and FORECAST_STAGES extended to 6 stages, each with a single 1:1 backend ID. BASELINE_RATES set directly to the historical 0.05 / 0.5 / 0.5 / 0.73 / 0.73 / 0.95 (E2E yield ≈ 0.633%). Conservative / Optimistic restored to historical 0.9× / 1.1×. ScenarioPreset no longer includes "ongoing"; OngoingMartRates and FALLBACK_ONGOING_RATES removed.
- chat/components/dashboards/admissions/forecast/derivation.ts — getCumulativeRate is a 6-arm switch (each card's outgoing leg distinct, no shared yields). getStageToStageRate returns each stage's actual outgoing leg rate (no nulls). getCumulativeOngoingRate and getOngoingYieldForStage removed.
### View / scenario plumbing
- chat/components/dashboards/admissions/forecast/forecast-view.tsx — PRESET_LABELS reduced to 3 pills (Conservative / Moderate / Optimistic). The previous useMemo that picked synced baseline and ongoing rate rows from Convex collapsed to useMemo(() => buildScenarioPresets(BASELINE_RATES), []). Moderate is the canonical historical planning assumption — the synced baseline cohort row from Convex is intentionally not consumed. The "historical rates" yellow indicator is gone (no longer a fallback). Rates popover shows 6 sliders, no per-row ongoing comparator label.
### Pipeline projection layout
- chat/components/dashboards/admissions/forecast/pipeline-projection.tsx — Restores the original Spotlight chip-below layout:
- 7 cards in a single row (6 funnel stages + Enrolled). Enrolled is a regular card, not a teal-styled outlier.
- Each card contains: label / count / 12.7% conv. (cumulative-to-enrollment).
- Below each card, a separated accent chip: +N (the contribution from this bucket).
- Connector arrows between cards show the moderate scenario's outgoing-leg rate (5%, 50%, …).
- Header copy: "Stage conversion rates shown between cards".
- chat/components/dashboards/admissions/forecast/forecast-table.tsx — School-level breakdown grid is grid-cols-3 lg:grid-cols-7 (6 stages + New Enrolled). No ongoing comparator sub-line; per-card connector rate displayed for every stage (no nulls).
### Tests
- chat/components/dashboards/admissions/forecast/__tests__/derivation.test.ts — Refit fixtures for the 6-leg model: 3 presets, 6 stages in funnel order, baseline asserted to match 0.05 / 0.5 / 0.5 / 0.73 / 0.73 / 0.95, getCumulativeRate exercised at all 6 chain positions with each having a distinct yield, getStageToStageRate returns each stage's outgoing leg with no nulls. Removed the getOngoingYieldForStage and ONGOING_RATES blocks. 66 tests passing.
## Design decisions
- Moderate baseline is the planning assumption, not the observed cohort. The previous implementation pulled the synced baseline cohort rates (mature Aug–Dec window, ~14/55/77/54%) from the Convex conversionRates table whenever they were present — meaning the moderate scenario silently used live observed data instead of the team's planning model. We now hardcode the historical 5/50/50/73/73/95. The synced baseline row still gets written by the sync (for potential future use elsewhere), it's just no longer read on the frontend.
- Full 6-leg rate model, not a 4-leg collapse. An earlier pass collapsed the 6-leg historical model into 4 effective rates (0.025 / 0.5 / 0.5329 / 0.95), which produced mathematically-identical end-to-end yields but displayed 2.5% / 50% / 53% / 95% in the popover — visually divorced from the planning assumption. Reverted to a true 6-leg model so the sliders and connector rates show the canonical numbers directly.
- Per-stage ongoing comparator dropped, not stylized. The EduCRM funnel_dtl mart only emits 4 transition events (lead, student_applied, student_shadowed, student_offered, student_enrolled). With 6 stage cards, a bucket-level comparator would either fabricate values for the 2 unmeasured legs (Lead→Showcase, Approved→Offer Sent) or repeat the same number on paired cards. Both are misleading. Cleaner cutover than a half-honest decoration; can be re-added if/when the mart adds the missing event types.
- Spotlight chip-below layout, not in-card +N. Putting the contribution number inside the card body framed it as a property of the count, which (combined with the connector arrows implying flow) made the math feel disconnected from what each card was telling the reader. Moving +N to a separated accent chip beneath the card reads as "from this bucket, this many will enroll" — clearer that each card is a parallel cohort, not a downstream waterfall.
## What didn't change
- chat/convex/analyticsSchema.ts — conversionRates table stays 4-legged.
- chat/convex/dashboards/admissions.ts — getEnrollmentForecastData already returns 6-stage pipelineCounts; unchanged.
- chat/lib/contracts/admissions-stages.ts — already has all 6 stage definitions.
- sync/src/analytics/queries/educrm.ts — queryFunnelConversionRates already 4-legged; still writes both baseline and ongoing cohort rows.
## Test Plan
### Aerie-side (already green)
- [x] chat/components/dashboards/admissions/forecast/__tests__/derivation.test.ts — 66 tests pass with the new 6-leg fixtures.
- [x] pnpm --filter chat typecheck — clean.
- [x] pnpm --filter chat exec biome check components/dashboards/admissions/forecast — clean.
- [x] Pre-commit hooks (biome + typecheck-chat) green on both commits.
### Reviewer
- [ ] Open the Forecast tab. Confirm 3 preset pills (no "Ongoing"), 6 sliders in the rates popover at 5/50/50/73/73/95.
- [ ] Confirm the projection card layout: 7 cards (Lead, Showcase, App, Shadow, Approved, Offer, Enrolled) each with a separated +N chip below in accent. Connector arrows show 5%/50%/50%/73%/73%/95% between cards.
- [ ] Spot-check a high-pipeline campus: moderate +N per card should align with count × cumulative-conv. % shown on each card.
- [ ] Expand a school row in the table: 6 stage cards + Enrolled, each with conv. rate below count.