{% if render_mode != 'fragment' %} {% if domain %}{% endif %} Finding Diff - Finite State Report {% include "_design_system.html" %} {% include "_console_shell.html" %} {% endif %} {% if render_mode != 'fragment' %} {% endif %} {% import "_console_macros.html" as fs with context %} {# Defensive defaults #} {% set summary = summary | default({}) %} {% if summary is not mapping %}{% set summary = {} %}{% endif %} {% set port_fixes_left_to_right = port_fixes_left_to_right | default([]) %} {% set port_fixes_right_to_left = port_fixes_right_to_left | default([]) %} {% set empty_side = empty_side | default(None) %} {% set left_label = summary.get('left_label', 'Left') if summary is mapping else 'Left' %} {% set right_label = summary.get('right_label', 'Right') if summary is mapping else 'Right' %} {% set inventory_available = summary.get('inventory_available', True) if summary is mapping else True %} {# Leader direction — injected by the two-pass engine (§5.0) as data.left_leads / data.leader_label / data.laggard_label. Defaults keep the standalone path (no compound) rendering left→right. The PRIMARY worklist is leader→laggard; the reverse is collapsed. #} {% set left_leads = left_leads | default(True) %} {% set leader_label = leader_label | default(left_label) %} {% set laggard_label = laggard_label | default(right_label) %} {# Primary = leader→laggard rows; reverse = the other direction. #} {% set primary_rows = port_fixes_left_to_right if left_leads else port_fixes_right_to_left %} {% set reverse_rows = port_fixes_right_to_left if left_leads else port_fixes_left_to_right %} {% set primary_count = (summary.get('fixed_left_open_right_count', 0) if left_leads else summary.get('fixed_right_open_left_count', 0)) if summary is mapping else 0 %} {% set reverse_count = (summary.get('fixed_right_open_left_count', 0) if left_leads else summary.get('fixed_left_open_right_count', 0)) if summary is mapping else 0 %} {% if render_mode != 'fragment' %} {{ fs.topbar( crumbs=["Finite State", "Finding Diff"], meta=[ {"label": "Left", "value": left_label}, {"label": "Right", "value": right_label}, {"label": "Generated", "value": generated_at or "—"}, ], controls=[], ) }} {% endif %}

Finding Comparison

{{ left_label }} vs {{ right_label }}

{% if empty_side %}
{% if empty_side == 'both' %}

Both scopes had no findings data.

{% elif empty_side == 'left' %}

{{ left_label }} scope had no data — nothing to compare.

{% elif empty_side == 'right' %}

{{ right_label }} scope had no data — nothing to compare.

{% endif %}
{% else %} {# Inventory unavailable note #} {% if not inventory_available %}
Note: Component inventory was not available for one or both scopes. Findings absent from the other scope's finding list are excluded from the port-fix tables (conservative default). Run with component inventory enabled for full fix-evidence classification.
{% endif %} {# ---- counts pulled once from summary (defensive) ---- #} {% set fix_lr = summary.get('fixed_left_open_right_count', 0) if summary is mapping else 0 %} {% set fix_rl = summary.get('fixed_right_open_left_count', 0) if summary is mapping else 0 %} {% set both_n = summary.get('needs_action_in_both_count', 0) if summary is mapping else 0 %} {% set supp_n = summary.get('suppressed_divergence_count', 0) if summary is mapping else 0 %} {# Section intro: data-derived lede + scope tag #}

{{ fix_lr }} fixed in {{ left_label }}, open in {{ right_label }} · {{ fix_rl }} the reverse · {{ both_n }} open on both · {{ supp_n }} suppressed on one side only.

● {{ left_label }} {{ right_label }} ●
{# KPI summary row #}
{{ fs.kpi_cell("Needs action — both", both_n, delta="shared backlog") }} {{ fs.kpi_cell("Port: " ~ left_label ~ " → " ~ right_label, fix_lr, delta="fixed left, open right", dot=("high" if fix_lr > 0 else None)) }} {{ fs.kpi_cell("Port: " ~ right_label ~ " → " ~ left_label, fix_rl, delta="fixed right, open left") }} {{ fs.kpi_cell("Suppressed divergence", supp_n, delta="see Triage §04", dot=("medium" if supp_n > 0 else None)) }}
{# ---- PRIMARY worklist: leader → laggard, grouped by the UPGRADE that clears each component. Per-row FIX TARGET column replaces the decorative risk gauge; Project column + owner rollup bind to row.project_names (the needs-action laggard variants). ---- #} {% if primary_rows and primary_rows | length > 0 %}

Grouped by the upgrade that clears them — {{ leader_label | short_scope }} → {{ laggard_label | short_scope }}

Fixes resolved in {{ leader_label | short_scope }}, still open in {{ laggard_label | short_scope }}. The action is the component bump at the top of each group; the CVE rows are the drill-down of what it clears.

{% for component, rows in primary_rows | groupby('component_name') %} {% set rows = rows | list %} {% set g_crit = rows | selectattr('severity', 'eq', 'CRITICAL') | list | length %} {% set g_high = rows | selectattr('severity', 'eq', 'HIGH') | list | length %} {% set g_med = rows | selectattr('severity', 'eq', 'MEDIUM') | list | length %} {% set g_low = rows | selectattr('severity', 'eq', 'LOW') | list | length %} {% set ev = namespace(absent=0) %} {% for r in rows %}{% if 'not present' in (r.fix_evidence or '') %}{% set ev.absent = ev.absent + 1 %}{% endif %}{% endfor %} {% set ev_absent = ev.absent %} {% set ev_vex = (rows | length) - ev_absent %} {# Group fix_target: the single leader version off the rows (one per component). Target-only header; the exact per-row arrow lives in the FIX TARGET column. #} {% set ft = namespace(v=None) %} {% for r in rows %}{% if ft.v is none and r.fix_target %}{% set ft.v = r.fix_target %}{% endif %}{% endfor %} {% set group_target = ft.v %} {# Owner rollup: union of the group's rows' project_names. #} {% set owner_ns = namespace(items=[]) %} {% for r in rows %}{% for p in (r.project_names or []) %}{% if p and p not in owner_ns.items %}{% set _ = owner_ns.items.append(p) %}{% endif %}{% endfor %}{% endfor %} {% set group_owners = owner_ns.items | sort %} {% set tbl_id = 'fdp_' ~ loop.index %}
{% if group_target %}Upgrade {{ component or '—' }} {{ group_target }}{% else %}Rebuild {{ component or '—' }}{% endif %} Clears {{ rows | length }} · evidence: {% if ev_vex > 0 %}{{ ev_vex }} VEX resolved{% endif %}{% if ev_vex > 0 and ev_absent > 0 %} · {% endif %}{% if ev_absent > 0 %}{{ ev_absent }} component change{% endif %}{% if ev_vex == 0 and ev_absent == 0 %}—{% endif %} {% if group_owners %} Affects{% for o in group_owners %}{{ o | short_scope }}{% endfor %} {% endif %} {% if g_crit > 0 %}{% endif %} {% if g_high > 0 %}{% endif %} {% if g_med > 0 %}{% endif %} {% if g_low > 0 %}{% endif %} {{ g_crit }}C · {{ g_high }}H · {{ g_med }}M · {{ g_low }}L {{ rows | length }}fixes
{% for row in rows %} {% set is_absent = 'not present' in (row.fix_evidence or '') %} {% set sev = row.severity or 'UNSPECIFIED' %} 10 %} class="mc-row-hidden"{% endif %}> {% endfor %}
CVESeverityFix targetStatus — {{ leader_label | short_scope }} → {{ laggard_label | short_scope }}Fix evidenceProject
{{ row.display_id or '—' }} {{ row.severity or '—' }} {% if row.fix_target %}{% if row.component_version %}{{ row.component_version }}{% endif %}{{ row.fix_target }}{% else %}rebuild {{ row.component_name or '' }}{% endif %} Resolved{{ row.status or 'Open' }} {% if is_absent %}{{ row.fix_evidence }}{% else %}{{ row.fix_evidence or '—' }}{% endif %} {{ (row.project_names | join(', ')) if row.project_names else '—' }}
{% if rows | length > 10 %} {% set hidden_n = (rows | length) - 10 %}
{% endif %}
{% endfor %}
{% endif %} {# ---- REVERSE worklist: laggard → leader, collapsed in a disclosure ---- #} {% if reverse_rows and reverse_rows | length > 0 %} {% set r_crit = reverse_rows | selectattr('severity', 'eq', 'CRITICAL') | list | length %} {% set r_high = reverse_rows | selectattr('severity', 'eq', 'HIGH') | list | length %} {% set r_med = reverse_rows | selectattr('severity', 'eq', 'MEDIUM') | list | length %} {% set r_low = reverse_rows | selectattr('severity', 'eq', 'LOW') | list | length %}
Port back — {{ laggard_label | short_scope }} → {{ leader_label | short_scope }} {{ reverse_count }} fixed in {{ laggard_label | short_scope }}, open in {{ leader_label | short_scope }}. Severity: {{ r_crit }} Critical · {{ r_high }} High · {{ r_med }} Medium · {{ r_low }} Low. {{ reverse_count }}reverse
{% for component, rows in reverse_rows | groupby('component_name') %} {% set rows = rows | list %} {% set g_crit = rows | selectattr('severity', 'eq', 'CRITICAL') | list | length %} {% set g_high = rows | selectattr('severity', 'eq', 'HIGH') | list | length %} {% set g_med = rows | selectattr('severity', 'eq', 'MEDIUM') | list | length %} {% set g_low = rows | selectattr('severity', 'eq', 'LOW') | list | length %} {% set ft = namespace(v=None) %} {% for r in rows %}{% if ft.v is none and r.fix_target %}{% set ft.v = r.fix_target %}{% endif %}{% endfor %} {% set group_target = ft.v %} {% set tbl_id = 'fdr_' ~ loop.index %}
{% if group_target %}Upgrade {{ component or '—' }} {{ group_target }}{% else %}Rebuild {{ component or '—' }}{% endif %} Clears {{ rows | length }} {% if g_crit > 0 %}{% endif %} {% if g_high > 0 %}{% endif %} {% if g_med > 0 %}{% endif %} {% if g_low > 0 %}{% endif %} {{ g_crit }}C · {{ g_high }}H · {{ g_med }}M · {{ g_low }}L {{ rows | length }}fixes
{% for row in rows %} {% set is_absent = 'not present' in (row.fix_evidence or '') %} {% set sev = row.severity or 'UNSPECIFIED' %} 10 %} class="mc-row-hidden"{% endif %}> {% endfor %}
CVESeverityFix targetStatus — {{ laggard_label | short_scope }} → {{ leader_label | short_scope }}Fix evidenceProject
{{ row.display_id or '—' }} {{ row.severity or '—' }} {% if row.fix_target %}{% if row.component_version %}{{ row.component_version }}{% endif %}{{ row.fix_target }}{% else %}rebuild {{ row.component_name or '' }}{% endif %} Resolved{{ row.status or 'Open' }} {% if is_absent %}{{ row.fix_evidence }}{% else %}{{ row.fix_evidence or '—' }}{% endif %} {{ (row.project_names | join(', ')) if row.project_names else '—' }}
{% if rows | length > 10 %} {% set hidden_n = (rows | length) - 10 %}
{% endif %}
{% endfor %}
{% endif %} {# ---- No portable candidates at all ---- #} {% if not primary_rows and not reverse_rows %}

No portable fix candidates found between {{ left_label }} and {{ right_label }}.

{% endif %} {# ---- "Open on both" + "Suppressed divergence" disclosure ---- #} {% if both_n > 0 or supp_n > 0 %}
Open on both sides {{ both_n }} findings need action in both scopes — open on both, so nothing to port. {{ both_n }}shared

Both sides carry these findings, so a comparison cannot make them portable. Surfaced to account for the full finding population.

{% if supp_n > 0 %}

Suppressed divergence ({{ supp_n }}): suppressed on one side, open on the other — a triage judgment, not a code fix. Reconciled in Triage Status §04.

{% endif %}
{% endif %} {% endif %}{# end empty_side else #}
{% if render_mode != 'fragment' %} {{ fs.status_bar(items=[ "Recipe: Finding Diff", "Left: " ~ left_label, "Right: " ~ right_label, generated_at | default(''), ], version='fs-report ' ~ (fs_report_version | default('dev'))) }} {% include '_action_buttons.html' %} {% endif %}