{% import "_console_macros.html" as fs with context %} {% if render_mode != 'fragment' %} {% if domain %}{% endif %} Reachability VEX Coverage - Finite State Report {% include "_design_system.html" %} {% include "_console_shell.html" %} {% include "_echarts_ready.html" %} {% endif %} {# Recipe-local styles render in BOTH standalone and fragment modes so fragment_extractor (_STYLE_RE) collects them, scopes them under .fs-section-reachability-vex-coverage, and re-emits at the top of the fragment. #} {% if render_mode != 'fragment' %} {# Unscoped page-box + print rules, deliberately in their own style block that the fragment path never emits. css_scoper.py does not prefix @page selectors, so emitting these in a fragment would let this recipe override the host document's page geometry in a compound bundle (same reasoning as customer_brief.html). #} {% endif %} {# Defensive defaults — keep the template renderable when the transform short-circuited or a caller rendered it without a full result dict. #} {% set cov = coverage_summary | default({}) %} {% if not cov is mapping %}{% set cov = {} %}{% endif %} {% set rvc_notes = notes | default([]) %} {# `data` is now the per-project-version rollup, not a per-finding list. #} {% set main_rows = data | default([]) %} {% set by_version = coverage_by_version | default([]) %} {% set by_folder = coverage_by_folder | default([]) %} {% set status_mix = gap_status_breakdown | default([]) %} {% set reach_mix = reachability_mix | default([]) %} {% set sev_mix = gaps_by_severity | default([]) %} {% set ran_anywhere = cov.get('reachability_ran_anywhere', False) %} {# Platform deep links. Both macros fall back to plain text when the domain or the required id is missing, so a record with incomplete metadata still renders its name rather than a broken href. #} {% macro project_link(name, project_id) -%} {%- if domain and project_id -%} {{ name }} {%- else -%}{{ name }}{%- endif -%} {%- endmacro %} {% macro version_link(label, project_id, project_version_id) -%} {%- if domain and project_id and project_version_id -%} {{ label }} {%- else -%}{{ label }}{%- endif -%} {%- endmacro %} {% set floor = cov.get('min_severity') %} {% set coverage_pct = cov.get('coverage_pct') %} {% set auto_total = cov.get('auto_resolvable_total', 0) %} {% set auto_sev = cov.get('auto_resolvable_by_severity', {}) %} {% if not auto_sev is mapping %}{% set auto_sev = {} %}{% endif %} {% if render_mode != 'fragment' %} {{ fs.topbar( crumbs=["Finite State", "Reachability VEX Coverage"], meta=[ {"label": "Domain", "value": domain or "—"}, {"label": "Severity floor", "value": floor or "All severities"}, {"label": "Generated", "value": generated_at or "—"}, ], controls=[], ) }} {% endif %}

Reachability VEX Coverage

Findings proven UNREACHABLE by binary analysis should carry VEX status NOT_AFFECTED. This is how much of that triage is outstanding, by project version. {% if floor %}Scoped to severity {{ floor }} and above.{% endif %}

{# The headline. This is the number an operator is here for: how much noise a single --autotriage run would remove. It counts UNTRIAGED gaps that also carry the platform ids the VEX API needs — not the raw gap count, which would promise closures the apply step skips. #} {% if ran_anywhere %}
{{ "{:,}".format(auto_total) }} finding{{ "" if auto_total == 1 else "s" }} could be auto-resolved

Unreachable, still untriaged, and appliable — closing them with --autotriage --autotriage-status NOT_AFFECTED marks each NOT_AFFECTED / CODE_NOT_REACHABLE. {% if floor %}Counted at severity {{ floor }} and above only.{% endif %}

{% if auto_total %}
{% for tier, cls in [('critical','critical'), ('high','high'), ('medium','medium'), ('low','low')] %} {% set n = auto_sev.get('sev_' ~ tier, 0) %} {% if n %}{{ n }} {{ tier }}{% endif %} {% endfor %} {% if auto_sev.get('sev_other', 0) %}{{ auto_sev.get('sev_other') }} none/info{% endif %}
{% endif %} {% if cov.get('needs_review_total', 0) %}

A further {{ cov.get('needs_review_total') }} unreachable finding{{ "" if cov.get('needs_review_total') == 1 else "s" }} need a person, not automation, and {{ "is" if cov.get('needs_review_total') == 1 else "are" }} not in the number above. {{ cov.get('needs_review_status_conflict', 0) }} already carry a status someone chose — those need a decision, or --vex-override. {{ cov.get('needs_review_missing_ids', 0) }} lack the platform ids the VEX API needs — those need the id recovered, which no override will do. A gap with both problems is counted under each, so the two need not sum.

{% endif %}
{% endif %} {% if not ran_anywhere %}

Reachability analysis has not run in this scope

No finding here carries a reachability score, so VEX coverage cannot be measured. A gap count of zero means unknown, not clean — run a reachability (VULNERABILITY_ANALYSIS) scan before reading anything below as coverage.

{% endif %} {% for note in rvc_notes %}
{{ note }}
{% endfor %}
{{ fs.kpi_cell( ("VEX Coverage" ~ (" (" ~ floor ~ "+)" if floor else "")), (("%.1f" | format(coverage_pct)) ~ "%") if coverage_pct is not none else "—", dot=("critical" if (coverage_pct is not none and coverage_pct < 50) else ("high" if (coverage_pct is not none and coverage_pct < 100) else None)), ) }} {# An em dash, not 0, when reachability never ran anywhere. "0" in this cell reads as "nothing to close"; the truth is "not measured", which the hero band and the alert both say — but a reader scanning only the KPI row would take the zero at face value. The same reason coverage_pct prints an em dash rather than 0%. #} {{ fs.kpi_cell( "Auto-Resolvable", auto_total if ran_anywhere else "—", dot=("high" if (ran_anywhere and auto_total > 0) else None), ) }} {# Every measured figure reads n/a when reachability never ran. A 0 here is indistinguishable from a measured "nothing to do", which is precisely the null-vs-zero conflation this report exists to prevent — it would be odd to preserve that distinction in the data and then discard it in the KPI row. #} {{ fs.kpi_cell("Needs Review", cov.get('needs_review_total', 0) if ran_anywhere else "—", dot=("critical" if (ran_anywhere and cov.get('needs_review_total', 0) > 0) else None)) }} {{ fs.kpi_cell("Unreachable Findings", cov.get('unreachable_findings', 0) if ran_anywhere else "—") }} {{ fs.kpi_cell("Already NOT_AFFECTED", cov.get('unreachable_not_affected', 0) if ran_anywhere else "—") }} {{ fs.kpi_cell( "Versions Without Reachability", cov.get('versions_without_reachability', 0), dot=("high" if cov.get('versions_without_reachability', 0) > 0 else None), ) }}

Coverage is the share of UNREACHABLE findings carrying NOT_AFFECTED, counted only across the {{ cov.get('versions_with_reachability', 0) }} version(s) where reachability analysis actually ran. Reachability status is inferred from the finding data itself, not from scan history. {% if coverage_pct is none %}There is no coverage denominator in this scope.{% endif %}

{% include "_columns_schema.html" %} {# Fragment rendering (compound / workflow output) strips the chart {% if render_mode != 'fragment' %} {% include '_action_buttons.html' %} {% endif %}