@@ -24,7 +24,7 @@ export function deriveOverviewSources(sources) {
2424 const disabledWorkflows = workflows . filter ( ( row ) => String ( row [ 'workflow-active' ] ) === 'false' ) . length ;
2525 const overviewMetadata = createOverviewMetadata ( sources ) ;
2626 const packageUsage = summarizePackageAicUsage ( workflows , usage ) ;
27- const securitySignals = buildSecuritySignals ( { workflows, runs, findings } ) ;
27+ const securitySignals = buildSecuritySignals ( { workflows, runs, findings, outcomes } ) ;
2828 const valueSignals = buildValueSignals ( { sources, graderObservations, operationalValues, outcomes } ) ;
2929 const costSignals = buildCostSignals ( sources . usage ) ;
3030
@@ -612,10 +612,11 @@ function buildSecuritySummary(input) {
612612}
613613
614614/**
615- * @param {{ workflows: Array<Record<string, unknown>>, runs: Array<Record<string, unknown>>, findings: Array<Record<string, unknown>> } } input
615+ * @param {{ workflows: Array<Record<string, unknown>>, runs: Array<Record<string, unknown>>, findings: Array<Record<string, unknown>>, outcomes: Array<Record<string, unknown>> } } input
616616 */
617617function buildSecuritySignals ( input ) {
618618 const workflowNames = new Map ( input . workflows . map ( ( row ) => [ String ( row . workflow ?? '' ) , String ( row [ 'workflow-name' ] ?? row . workflow ?? 'Unknown workflow' ) ] ) ) ;
619+ const outcomeIds = new Set ( input . outcomes . map ( ( row ) => String ( row [ 'safe-output' ] ?? '' ) ) . filter ( Boolean ) ) ;
619620 const signals = [
620621 ...groupRows ( input . runs . filter ( ( row ) => String ( row [ 'run-conclusion' ] ) === 'action-required' ) , ( row ) => String ( row . workflow ?? '' ) )
621622 . map ( ( [ workflow , rows ] ) => ( {
@@ -644,18 +645,24 @@ function buildSecuritySignals(input) {
644645 'navigation-page' : 'packages'
645646 } ) ) ,
646647 ...groupRows ( input . findings . filter ( isAuthoredWarning ) , findingWorkflowKey )
647- . map ( ( [ workflow , rows ] ) => ( {
648- priority : 3 ,
649- count : rows . length ,
650- tone : 'warning' ,
651- icon : 'issue' ,
652- kind : 'Authored warning' ,
653- title : workflowNames . get ( workflow ) ?? String ( rows [ 0 ] ?. [ 'finding-summary' ] ?? workflow ) ,
654- detail : `${ formatNumber ( rows . length ) } retained output${ rows . length === 1 ? ' contains' : 's contain' } an explicit warning block` ,
655- evidence : 'Output content' ,
656- action : 'View evidence' ,
657- 'external-link' : latestRow ( rows ) ?. [ 'external-link' ]
658- } ) )
648+ . map ( ( [ workflow , rows ] ) => {
649+ const latest = latestRow ( rows ) ;
650+ const outcomeId = String ( latest ?. finding ?? '' ) ;
651+ return {
652+ priority : 3 ,
653+ count : rows . length ,
654+ tone : 'warning' ,
655+ icon : 'issue' ,
656+ kind : 'Authored warning' ,
657+ title : workflowNames . get ( workflow ) ?? String ( rows [ 0 ] ?. [ 'finding-summary' ] ?? workflow ) ,
658+ detail : `${ formatNumber ( rows . length ) } retained output${ rows . length === 1 ? ' contains' : 's contain' } an explicit warning block` ,
659+ evidence : 'Output content' ,
660+ action : 'View evidence' ,
661+ ...( outcomeIds . has ( outcomeId )
662+ ? { 'navigation-href' : `#page-outcome-detail?outcome=${ encodeURIComponent ( outcomeId ) } ` }
663+ : { 'external-link' : latest ?. [ 'external-link' ] } )
664+ } ;
665+ } )
659666 ] ;
660667 return signals . sort ( ( left , right ) => left . priority - right . priority || right . count - left . count || left . title . localeCompare ( right . title ) ) ;
661668}
0 commit comments