|
| 1 | +# Two-page dashboard merge design |
| 2 | + |
| 3 | +Status: local proposal awaiting approval. Do not merge or deploy yet. |
| 4 | + |
| 5 | +## Decision |
| 6 | + |
| 7 | +Publish one dashboard product with two real static pages: |
| 8 | + |
| 9 | +| Page | Proposed URL | Responsibility | |
| 10 | +| --- | --- | --- | |
| 11 | +| Live Forward Monitor | `dashboard.html` | Daily operational evidence, benchmark comparison, stability, the canonical stock-level view, and experiment history | |
| 12 | +| Horizon Comparison | `horizons.html` | Horizon-matched 5/10/20-session progress, validation context, model specifications, SHAP explanations, and pipeline health | |
| 13 | + |
| 14 | +Both headers use the same two-option page switcher. The selected page is visually |
| 15 | +active. Ordinary links are preferable to a hidden single-page application because |
| 16 | +browser back/forward works, each page can fail independently, and GitHub Pages can |
| 17 | +serve the files without a runtime. |
| 18 | + |
| 19 | +## Shared stock-level view |
| 20 | + |
| 21 | +The Horizon Comparison page does not implement another portfolio table. |
| 22 | + |
| 23 | +The existing Stock-level view remains the canonical component. Its model selector |
| 24 | +will be extended to understand both: |
| 25 | + |
| 26 | +- legacy daily live-forward snapshots; and |
| 27 | +- v2 Ridge/XGBoost arms for the 5-, 10-, and 20-session horizons. |
| 28 | + |
| 29 | +An `Inspect stocks` action on a horizon model will link to a URL such as: |
| 30 | + |
| 31 | +```text |
| 32 | +dashboard.html?decision=2026-07-29&family=xgb_ranker&horizon=20#stock-level |
| 33 | +``` |
| 34 | + |
| 35 | +The original page reads those parameters, selects the requested frozen portfolio, |
| 36 | +and scrolls to the shared Stock-level view. This avoids divergent filtering, |
| 37 | +sorting, return formatting, and holding-level evaluation logic. |
| 38 | + |
| 39 | +## Partial and mature evidence |
| 40 | + |
| 41 | +The horizon page reports three different evidence states without mixing them: |
| 42 | + |
| 43 | +1. **Awaiting entry** — the portfolio is frozen but its next-open entry has not |
| 44 | + occurred. |
| 45 | +2. **Interim mark** — one or more open-to-open observations exist. The page shows |
| 46 | + session progress and the compounded partial return immediately. |
| 47 | +3. **Matured label** — the complete 5-, 10-, or 20-session evaluation is available |
| 48 | + and may enter the formal prospective comparison. |
| 49 | + |
| 50 | +The page never displays validation return as live return. A zero-session portfolio |
| 51 | +is shown as `0 / horizon` and `Awaiting entry`, not as a zero realized return. |
| 52 | + |
| 53 | +## Explainability |
| 54 | + |
| 55 | +Every newly frozen v2 forecast writes `shap_summary.csv`. |
| 56 | + |
| 57 | +- Ridge uses linear SHAP contributions around the current eligible cohort as the |
| 58 | + background. |
| 59 | +- XGBoost uses exact TreeSHAP contributions from the fitted booster. |
| 60 | +- The dashboard publishes mean absolute SHAP, signed mean SHAP, positive |
| 61 | + contribution share, method, and explanation-row count. |
| 62 | + |
| 63 | +Each model card contains a collapsed `Show SHAP feature importance` control. |
| 64 | +Opening it displays a horizontal importance chart. Old immutable forecasts that |
| 65 | +predate this artifact state that SHAP was not captured; coefficients or XGBoost |
| 66 | +gain are not relabelled as SHAP. |
| 67 | + |
| 68 | +## Daily refresh contract |
| 69 | + |
| 70 | +The daily pipeline should: |
| 71 | + |
| 72 | +1. refresh data and generate the current snapshots; |
| 73 | +2. evaluate all available interim open-to-open observations; |
| 74 | +3. evaluate newly matured forecasts; |
| 75 | +4. generate SHAP summaries for new horizon snapshots; |
| 76 | +5. rebuild `dashboard.html` and `horizons.html`; |
| 77 | +6. run public-payload and browser smoke checks; and |
| 78 | +7. publish both pages together through the existing GitHub Pages action. |
| 79 | + |
| 80 | +Publishing must be atomic: a cycle should never expose one page with a newer data |
| 81 | +contract than the other. |
| 82 | + |
| 83 | +## Approval boundary |
| 84 | + |
| 85 | +The current local Horizon Comparison preview demonstrates the second page. After |
| 86 | +approval, the merge work will add the page switcher and v2 arm support to the |
| 87 | +original dashboard, generate the final `horizons.html`, update the refresh and |
| 88 | +deployment workflows, and then request approval before pushing. |
0 commit comments