{# Meta grid — 4 tiles: Stack / Anti-bot / Auth / Fingerprinting. Spec § 0c. #} {# Uses ``namespace()`` so loop-local rebinds propagate to the surrounding scope, #} {# which is the only Jinja idiom that lets a {% for %} update outer variables. #} {% set ns = namespace( stack='unknown', anti_bot='none detected', anti_bot_tier=-1, auth='none', fingerprint_parts=[], ) %} {% if report.analysis_result.framework_hints %} {% set _stack_hint = report.analysis_result.framework_hints[0] %} {% if _stack_hint.version %} {% set ns.stack = _stack_hint.name ~ ' ' ~ _stack_hint.version %} {% else %} {% set ns.stack = _stack_hint.name %} {% endif %} {% endif %} {% for f in report.detection_result.findings %} {% if f.kind == 'anti_bot' %} {% set _t = f.severity_tier or 0 %} {% if _t > ns.anti_bot_tier %} {% set ns.anti_bot_tier = _t %} {% if f.vendor and f.severity_label %} {% set ns.anti_bot = f.vendor ~ ' · ' ~ f.severity_label %} {% elif f.vendor %} {% set ns.anti_bot = f.vendor %} {% else %} {% set ns.anti_bot = f.severity_label or 'detected' %} {% endif %} {% endif %} {% elif f.kind == 'auth' %} {% set ns.auth = f.severity_label or (f.vendor or 'detected') %} {% elif f.kind == 'fingerprinting' %} {% set _label = f.vendor or f.severity_label or 'detected' %} {{- ns.fingerprint_parts.append(_label) or '' -}} {% endif %} {% endfor %} {% if ns.fingerprint_parts %} {% set ns.fingerprint = ns.fingerprint_parts | join(' + ') %} {% else %} {% set ns.fingerprint = 'none' %} {% endif %} {# Fix #4: per-phase scan timings. ``report.scan_timings`` may be empty #} {# for pre-fix-#4 captures -- in that case the timing tiles are simply #} {# omitted and the meta block stays at four tiles. ``validation`` is #} {# the only field that maps ``None`` to "skipped" (``--no-validation``); #} {# the others fall through to the formatter's em-dash. #} {% set timings = report.scan_timings or {} %} {% set has_timings = timings | length > 0 %} {% if has_timings %} {% set capture_secs = timings.get('capture_seconds') %} {% set scrub_upload_secs = timings.get('scrub_upload_seconds') %} {% set total_secs = timings.get('total_seconds') %} {# ``--no-validation`` writes ``validation_seconds: None`` -> "skipped". #} {# A missing key (pre-fix-#4 partial blob) falls through to the format #} {# filter's em-dash sentinel; we don't relabel that as "skipped". #} {% if 'validation_seconds' in timings and timings['validation_seconds'] is none %} {% set validation_label = 'skipped' %} {% else %} {% set validation_label = timings.get('validation_seconds') | format_duration %} {% endif %} {% endif %}
Stack
{{ ns.stack }}
Anti-bot
{{ ns.anti_bot }}
Auth
{{ ns.auth }}
Fingerprinting
{{ ns.fingerprint }}
{% if has_timings %}
Capture duration
{{ capture_secs | format_duration }}
Validation
{{ validation_label }}
Scrub + upload
{{ scrub_upload_secs | format_duration }}
Total wall-clock
{{ total_secs | format_duration }}
{% endif %}