/* ============================================================ gp-plan.jsx — PLAN stage: master list + detail orchestration. The core audit surface. ============================================================ */ var { useState, useEffect, useMemo } = React; // ---- MASTER: day's plan grouped by strategy, with verdict dots ---- function PlanMaster({ decisions, selectedId, onSelect, summary }) { const groups = window.GP.STRATEGIES.map((s) => ({ strat: s, items: decisions.filter((d) => d.strategy_id === s.id), })); return (
{/* health summary */}
{summary.total} decisions
{summary.verified} {summary.flagged}
{groups.map(({ strat, items }) => (
{strat.label}
floor {(strat.floor * 100).toFixed(0)}% · {items.length} picks
{items.map((d) => { const r = window.GP.verify.checkDecision(d); const rob = window.GP.verify.robustness(d); const sel = d.id === selectedId; return (
onSelect(d.id)} style={{ display: "grid", gridTemplateColumns: "auto 1fr auto", alignItems: "center", gap: 10, padding: "10px 16px", cursor: "pointer", borderBottom: "1px solid var(--line-soft)", background: sel ? "var(--bg-2)" : "transparent", borderLeft: "2px solid " + (sel ? "var(--cyan)" : "transparent"), }}>
{d.asset.split("/")[0]} #{d.selection.rank} pick
comp {d.winner.composite_score?.toFixed(3) ?? "—"} · {rob.kind.toLowerCase()}
{r.verdict === "FLAGGED" ? review : #{r.winnerRank}/{r.validCount}}
); })}
))}
); } // ---- DETAIL HEADER ---- function DetailHeader({ decision }) { const a = window.GP.U(decision.asset); const strat = window.GP.STRATEGIES.find((s) => s.id === decision.strategy_id); const age = window.GP.fmt.ago(decision.sweep.finished_at, window.GP.NOW); return (
{decision.asset} {decision.strategy_class} {decision.group_id}
{decision.selection.tags.slice(0, 3).map((t) => ( {t} ))}
{window.GP.fmt.price(a.px)}
0 ? "var(--emerald)" : "var(--rose)"} size={11}>{window.GP.fmt.signedPct(a.chg)}
{decision.sweep_objective} {decision.sweep.sampled} of {decision.sweep.coarse_grid_size} combos {decision.bar_count} {window.GP.fmt.time(decision.sweep.finished_at)}Z · {age} ago
); } // ---- WINNER + selected-candidate comparison ---- function WinnerCompare({ decision, selectedIdx }) { const strat = window.GP.STRATEGIES.find((s) => s.id === decision.strategy_id); const winner = decision.winner; const sel = selectedIdx != null ? decision.sweep.candidates[selectedIdx] : null; const isWinnerSel = sel && JSON.stringify(sel.params) === JSON.stringify(winner.params); const keys = Object.keys(strat.paramSpace); const METRICS = window.GP.verify.METRICS; const Col = ({ title, cand, accent }) => (
{title}
{keys.map((k) => { const changed = sel && !isWinnerSel && cand !== winner && cand.params[k] !== winner.params[k]; return ; })}
{METRICS.map((m) => (
))}
); return (
comparing — amber = differs : committed to plan } />
{sel && !isWinnerSel && ( <>
)}
); } // ---- PLAN VIEW (master + detail) ---- function PlanView({ flagStyle, initialId }) { const decisions = window.GP.DATA.decisions; const summary = useMemo(() => window.GP.verify.summary(decisions), [decisions]); const [selectedId, setSelectedId] = useState(initialId || decisions[0].id); const [metricKey, setMetricKey] = useState("composite_score"); const [selCand, setSelCand] = useState(null); const [showRejected, setShowRejected] = useState(false); // follow jumps from other stages useEffect(() => { if (initialId) setSelectedId(initialId); }, [initialId]); const decision = decisions.find((d) => d.id === selectedId); const result = useMemo(() => window.GP.verify.checkDecision(decision), [decision]); useEffect(() => { setSelCand(null); setShowRejected(false); }, [selectedId]); return (
Source · data/daily_briefing.json → decisions[{decisions.indexOf(decision)}] · serialized by centaur.optimizer._export_daily_briefing (LL-049). All checks recomputed client-side from the raw candidate field.
); } Object.assign(window, { PlanView, PlanMaster, DetailHeader, WinnerCompare });