@@ -50,12 +50,35 @@ export const REPORT_LABELS = {
5050 read : "read:" ,
5151 /** The footer heading. */
5252 nextSteps : "Next steps" ,
53- /** Shown beside the report's name when the data can't be trusted. */
54- staleBadge : "stale data" ,
55- staleNote :
56- "The telemetry behind this report is stale, so the numbers below are informational only." ,
5753} as const ;
5854
55+ /** The flag beside the report's name, and the caveat under its headline. */
56+ export type LayoutTrust = { badge : string ; note : string } ;
57+
58+ /**
59+ * Why a report's numbers can't be trusted, in its own words. Stale, absent and unmeasured are three
60+ * different states, and a snapshot with no telemetry feed must not be called stale.
61+ */
62+ const TRUST_CAVEATS : Record < string , LayoutTrust > = {
63+ telemetry_stale : {
64+ badge : "stale data" ,
65+ note : "The telemetry behind this report is stale, so the numbers below are informational only." ,
66+ } ,
67+ telemetry_absent : {
68+ badge : "no telemetry" ,
69+ note : "No telemetry reached this report, so the numbers below are a point-in-time snapshot rather than a measured window." ,
70+ } ,
71+ flow_unmeasured : {
72+ badge : "unmeasured" ,
73+ note : "Throughput could not be measured over this window, so the numbers below are informational only." ,
74+ } ,
75+ } ;
76+
77+ const TRUST_CAVEAT_FALLBACK : LayoutTrust = {
78+ badge : "unverified data" ,
79+ note : "The data behind this report could not be verified, so the numbers below are informational only." ,
80+ } ;
81+
5982/**
6083 * The report's sections, top to bottom. A renderer walks this order; a new section has to be added
6184 * here first, which is what keeps the surfaces aligned. `trust` spans two places: a flag beside the
@@ -87,13 +110,20 @@ const UNASSESSABLE_REASONS = new Set(["unknown", "flow_unmeasured"]);
87110const NEUTRAL_REASONS = new Set ( [ "freshness_unknown" , "flow_unmeasured" ] ) ;
88111
89112/**
90- * `facts.trustworthy === false` means the telemetry behind the verdict is stale, so the numbers are
91- * informational only. Absent = trustworthy (the common case, and what pre-`facts` snapshots imply).
113+ * `facts.trustworthy === false` means the numbers behind the verdict are informational only. Absent
114+ * = trustworthy (the common case, and what pre-`facts` snapshots imply).
92115 */
93116export function reportIsTrustworthy ( vm : { facts ?: Record < string , unknown > } ) : boolean {
94117 return vm . facts ?. trustworthy !== false ;
95118}
96119
120+ /** The caveat for an untrustworthy report, chosen by `facts.untrustworthyReason`. */
121+ export function reportTrust ( vm : { facts ?: Record < string , unknown > } ) : LayoutTrust | undefined {
122+ if ( reportIsTrustworthy ( vm ) ) return undefined ;
123+ const reason = vm . facts ?. untrustworthyReason ;
124+ return ( typeof reason === "string" ? TRUST_CAVEATS [ reason ] : undefined ) ?? TRUST_CAVEAT_FALLBACK ;
125+ }
126+
97127export function reportTone ( severity : Severity , reason ?: string ) : ReportTone {
98128 return reason !== undefined && NEUTRAL_REASONS . has ( reason ) ? "neutral" : severity ;
99129}
@@ -283,7 +313,7 @@ export type LayoutFooterEntry = {
283313export type ReportLayout = {
284314 header : { name : string ; meta : string } ;
285315 /** Present only when the data can't be trusted. */
286- trust ?: { badge : string ; note : string } ;
316+ trust ?: LayoutTrust ;
287317 headline : { tone : ReportTone ; glyph : string ; severity : Severity ; phrase : string ; text ?: string } ;
288318 /** The finding the headline speaks for, always expanded. */
289319 hero ?: LayoutFinding ;
@@ -343,14 +373,14 @@ export function buildReportLayout(vm: LayoutViewModel, messages: ReportMessages)
343373 . filter ( ( finding ) => finding . read !== undefined && ! UNASSESSABLE_REASONS . has ( finding . reason ) )
344374 . map ( ( finding ) => fillTokens ( messages . readMessage ( finding . read ! ) , tokens ) ) ;
345375
376+ const trust = reportTrust ( vm ) ;
377+
346378 return {
347379 header : {
348380 name : vm . title ,
349381 meta : [ vm . scope , vm . period , vm . baselineLabel ] . filter ( Boolean ) . join ( " · " ) ,
350382 } ,
351- ...( reportIsTrustworthy ( vm )
352- ? { }
353- : { trust : { badge : REPORT_LABELS . staleBadge , note : REPORT_LABELS . staleNote } } ) ,
383+ ...( trust === undefined ? { } : { trust } ) ,
354384 headline : {
355385 severity : vm . summary . severity ,
356386 tone : reportTone ( vm . summary . severity , heroStatement ?. reason ) ,
0 commit comments