@@ -233,6 +233,8 @@ export function ReportBlocksView({ lite }: { lite: TestResultDataLite }) {
233233 const pro = asObj ( lite . proBenchmarkMetrics ) ;
234234 const wfa = asObj ( lite . walkForwardAnalysis ) ;
235235 const sens = asObj ( lite . parameterSensitivity ) ;
236+ const deploymentStatusGlobal = str ( sens ?. deploymentStatus ) ;
237+ const deploymentRejectedGlobal = / R E J E C T | F A I L / i. test ( deploymentStatusGlobal || "" ) ;
236238 const turnover = asObj ( lite . turnoverAndCostDrag ) ;
237239 const risk = asObj ( lite . riskAnalysis ) ;
238240 const actionPlan = asObj ( lite . strategyActionPlan ) ;
@@ -370,13 +372,16 @@ export function ReportBlocksView({ lite }: { lite: TestResultDataLite }) {
370372 { robustRows . map ( ( r ) => {
371373 const v = typeof r . value === "number" ? Math . round ( r . value ) : null ;
372374 const isBlocked = v != null && v <= 0 ;
375+ const isStabilityRow = r . key === "stability" ;
373376 const tone = scoreTone ( v ) ;
377+ const effectiveTone =
378+ isStabilityRow && deploymentRejectedGlobal && tone === "good" ? "warn" : tone ;
374379 const weight =
375380 r . key === "validation" ? 40 : r . key === "risk" ? 30 : r . key === "stability" ? 20 : r . key === "execution" ? 10 : 0 ;
376381 const barClass =
377- tone === "good"
382+ effectiveTone === "good"
378383 ? "text-emerald-400"
379- : tone === "warn"
384+ : effectiveTone === "warn"
380385 ? "text-amber-300"
381386 : "text-rose-400" ;
382387 return (
@@ -389,6 +394,14 @@ export function ReportBlocksView({ lite }: { lite: TestResultDataLite }) {
389394 >
390395 < p className = "font-medium text-foreground" >
391396 { r . label } < span className = "text-muted-foreground" > ({ weight } %)</ span >
397+ { isStabilityRow ? (
398+ < span
399+ className = "ml-1 cursor-help text-[10px] text-muted-foreground underline decoration-dotted"
400+ title = "Advisory metric: Parameter Stability reflects local sensitivity behavior and does not override deployment gates (Performance Decay, Risk Class, hard blockers)."
401+ >
402+ [?]
403+ </ span >
404+ ) : null }
392405 { isBlocked ? < span className = "font-semibold text-rose-400" > (blocking)</ span > : null }
393406 </ p >
394407 < div className = "flex items-center gap-2" >
@@ -398,7 +411,9 @@ export function ReportBlocksView({ lite }: { lite: TestResultDataLite }) {
398411 < p className = { "leading-tight " + ( isBlocked ? "font-medium text-rose-400" : "text-muted-foreground" ) } >
399412 { isBlocked
400413 ? "→ BLOCKED"
401- : r . key === "stability"
414+ : isStabilityRow && deploymentRejectedGlobal
415+ ? "→ Parameters stable in isolation, but deployment is blocked by audit gates"
416+ : r . key === "stability"
402417 ? "→ Parameters stable across sensitivity tests"
403418 : "→ Within threshold" }
404419 </ p >
@@ -748,16 +763,28 @@ export function ReportBlocksView({ lite }: { lite: TestResultDataLite }) {
748763 const row = asObj ( p ) ;
749764 const sensitivity = num ( row ?. sensitivity ) ;
750765 const status = str ( row ?. status ) || ( sensitivity != null && sensitivity >= 0.6 ? "Fragile" : "Stable" ) ;
766+ const topology =
767+ str ( row ?. topology ) ||
768+ str ( row ?. displayLabel ) ||
769+ ( sensitivity == null
770+ ? "n/a"
771+ : sensitivity >= 0.6
772+ ? "Sharp peak"
773+ : sensitivity >= 0.4
774+ ? "Moderate"
775+ : "Flat" ) ;
751776 const statusCls =
752777 / F R A G I L E | H I G H / i. test ( status ) ? "text-rose-400" : / T U N I N G | M O D E R A T E / i. test ( status ) ? "text-amber-300" : "text-emerald-400" ;
778+ const statusIcon =
779+ / F R A G I L E | H I G H / i. test ( status ) ? "🔴" : / T U N I N G | M O D E R A T E / i. test ( status ) ? "🟡" : "🟢" ;
753780 return (
754781 < div key = { idx } className = "space-y-1" >
755782 < div className = "grid grid-cols-[minmax(120px,1fr)_70px_64px_80px_100px] items-center gap-3" >
756783 < div className = "truncate" > { str ( row ?. name ) || `param_${ idx + 1 } ` } </ div >
757784 < div className = "text-right" > { str ( row ?. optimal ) || num ( row ?. optimal ) || "n/a" } </ div >
758- < div className = "text-right text-muted-foreground" > ~ </ div >
785+ < div className = "text-right text-muted-foreground" > { topology } </ div >
759786 < div className = "text-right" > { asNum ( sensitivity , 2 ) } </ div >
760- < div className = { "text-right font-semibold " + statusCls } > 🟢 { status } </ div >
787+ < div className = { "text-right font-semibold " + statusCls } > { statusIcon } { status } </ div >
761788 </ div >
762789 < div className = "text-xs text-muted-foreground" > Suggested Mitigation: { str ( row ?. mitigation ) || "Risk Neutral" } </ div >
763790 </ div >
@@ -794,21 +821,39 @@ export function ReportBlocksView({ lite }: { lite: TestResultDataLite }) {
794821
795822 < div className = "space-y-2 border-t border-dashed border-border pt-2 text-xs" >
796823 < p className = "font-semibold" > AUDIT VERDICT</ p >
824+ { ( ( ) => {
825+ const deploymentStatus = str ( sens . deploymentStatus ) || "APPROVED (no Decay check)" ;
826+ const deploymentCls = / R E J E C T | F A I L / i. test ( deploymentStatus )
827+ ? "text-rose-400"
828+ : / H O L D | W A R N | C A U T I O N / i. test ( deploymentStatus )
829+ ? "text-amber-300"
830+ : "text-emerald-400" ;
831+ const riskClass = str ( sens . riskClass ) || "LOW" ;
832+ const riskClassCls = / H I G H | R E J E C T | F A I L / i. test ( riskClass )
833+ ? "text-rose-400"
834+ : / M O D E R A T E | W A R N | C A U T I O N / i. test ( riskClass )
835+ ? "text-amber-300"
836+ : "text-emerald-400" ;
837+ return (
838+ < >
797839 < p className = "text-muted-foreground" >
798840 Deployment Status:{ " " }
799- < span className = "font-semibold text-emerald-400" > { str ( sens . deploymentStatus ) || "APPROVED (no Decay check)" } </ span >
841+ < span className = { "font-semibold " + deploymentCls } > { deploymentStatus } </ span >
800842 </ p >
801843 < p className = "text-amber-300" > Performance Decay: { str ( sens . performanceDecayNote ) || "n/a (min 3 periods required for decay check)." } </ p >
802844 < p className = "text-muted-foreground" >
803845 Risk Score:{ " " }
804846 < span className = "text-muted-foreground/90" >
805847 { str ( sens . riskScoreFormula ) || `Base ${ num ( sens . baseScore ) ?? DISPLAY_NA } - Penalty ${ num ( sens . penalty ) ?? DISPLAY_NA } ->` }
806848 </ span > { " " }
807- < span className = "font-semibold text-emerald-400" >
808- { str ( sens . riskClass ) || "LOW" } ({ num ( sens . riskScore ) ?? DISPLAY_NA } /100)
849+ < span className = { "font-semibold " + riskClassCls } >
850+ { riskClass } ({ num ( sens . riskScore ) ?? DISPLAY_NA } /100)
809851 </ span >
810852 </ p >
811853 < p className = "text-muted-foreground" > Pro-Note: { str ( sens . proNote ) || "Highest sensitivity parameter shown in table." } </ p >
854+ </ >
855+ ) ;
856+ } ) ( ) }
812857 </ div >
813858 </ AnalysisBlockCardLite >
814859 ) : null }
0 commit comments