{# P1-T06/T07/T08/T09/T16 — unified Step Trace as the new debug surface. Renders the per-scan Step Trace as the primary view at ``GET /debug/scans/{scan_id}``. Inputs (shape documented in ``routes/debug.py:get_debug_scan``): * ``trace_view`` — dict assembled by the route handler: - ``scan_id``, ``scan_id_short``, ``scan_id_accent`` (first 8 chars) - ``target_url``, ``owner_email`` - ``overall_status`` + ``overall_pill_class`` - ``error_banner`` (None or {step, name, message}) - ``total_duration``, ``total_cost`` - ``llm_call_count``, ``validation_endpoint_count`` - ``deleted_at_display`` - ``steps`` — list of per-row dicts (see ``_step_view_dict``) - ``llm_cost_rollup`` — list of {step, cost_str, pct} sorted desc + total row - ``duration_rollup`` — list of {step, duration_str, pct} sorted desc * ``is_admin``, ``is_super_admin`` — gate banners + sub-page links * ``trace_json_url`` — the P1-T05 raw-payload endpoint The page is a single scrollable document. House style comes from ``admin_layout.html`` (the T55 design tokens); the only local CSS rules add the trace-specific bits (indented sub-step rows, rollup panel layout, filter pill toggles). No emojis, no Tailwind, vanilla JS only. #} {% extends "admin_layout.html" %} {% from 'partials/help_tooltip.html' import tip, tip_styles %} {% block page_title %}admin :: scan :: {{ trace_view.scan_id_short }}{% endblock %} {% block breadcrumb %} admin/ scans/ {{ trace_view.scan_id_short }} {% endblock %} {% block head_extra %} {{ tip_styles() }} {% if trace_view.in_progress_banner %}{% endif %} {% endblock %} {% block content %} {# ============== Eyebrow + headline ============== #}
Unified Step Trace — every pipeline step (capture · deterministic · LLM · gate · validation · I/O) joined from scan_events, llm_calls, and validation_runs. Filter client-side; the JSON payload is one link below the rollups.
| # | step | type | started {{ tip("Wall-clock start. Hover shows the absolute UTC timestamp.", position="bottom") }} | duration | model | cost | status | s3 {{ tip("Opens the in-app viewer for this step's artifact. Hover for the full S3 key.", position="bottom") }} | |
|---|---|---|---|---|---|---|---|---|---|
| {{ step.index_padded }} |
{% if step.is_substep %}↳{% endif %}
{{ step.step_name }}
{% if step.error_class %}
{{ step.error_class }}
{% if step.error_excerpt %} · {{ step.error_excerpt }}{% endif %}
{% endif %}
|
{{ step.step_type }} | {{ step.started_rel }} | {{ step.duration }} | {{ step.model or '—' }} | {{ step.cost }} | {{ step.status_label }} | {% if step.s3_view_url %} view → {% else %} — {% endif %} | explore → |
Skips the 30-day grace and wipes the scan + LLM-call rows + S3 objects immediately. Audit log entries for this scan are anonymized so the compliance trail survives. This cannot be undone.