{% extends "base.html" %} {% block title %}{{ task }} side by side — Nullius{% endblock %} {% block head %} {% endblock %} {% block crumb %}/ compare / {{ task }}{% endblock %} {% import "traces/_charts.html" as ui %} {# Same shape as the trial page's `view_url`, so the shared chart macros can call it without knowing which page they are on. Only the legend state rides in it: this page has no trace filter, so `f` is always the empty one. #} {% macro view_url(f, cf=none) -%} {{ url_for('compare_task', task=task, pick=picks, cohort=cohort, dataset=dataset, **((cf if cf is not none else chart_filter).query)) }} {%- endmacro %} {% block body %}
{{ panels|length }} runs side by side· back to the comparison· drag a column header to reorder
{{ 'Dataset not recorded' if dataset.startswith('[unidentified:') else dataset }} · {{ 'Matched tasks' if cohort == 'matched' else 'Whole runs' }}
{% if panels|selectattr('attempts', 'gt', 1)|list %}A run has repeated attempts on this task. This page shows the last indexed attempt, matching the task table; all attempts remain in the comparison totals.
{% endif %}{{ p.selection.workspace_label }}{% if p.attempts > 1 %} · {{ p.attempts }} attempts, last indexed shown{% endif %}
Didn't include this task.
{% else %} {# Check rows come from the dataset's Vocabulary. Panels compare one task, so every panel shares a dataset and the conditional rows stay aligned across the grid — the same property the unconditional rows below rely on. #} {% set vocab = p.trial.vocab %}{{ p.absent }}
{% endif %}Reported by the trace {%- if tr.totals.wall_ns %} · {{ tr.totals.wall_ns|nsdur }} {{ clocked }}{% endif %} {%- if tr.zero_measured %} · inferred, not measured{% endif %}
{% if tr.totals.segments %}The trace reports no totals.
{% endif %}Partitioned here · every instant charged once
{% set part = tr.baseline.segments %} {% if part %}No span carries a usable clock — nothing to partition.
{% endif %}Two accountings of the same {{ tr.totals.wall_ns|nsdur if tr.totals.wall_ns else 'run' }}, shown apart and never mixed. The first is the producer's own and is displayed as reported — producers differ, and one that sums its LLM spans can exceed its wall clock. The second charges every instant to exactly one category (waiting on a human beats real work, which beats the call it ran inside) and is the same arithmetic on every side of this page, so it is the strip to read across. Neither is summed from the charts above: spans nest, so adding them up double-counts.
{% else %}{{ p.absent }}
{% endif %}Broke {{ p.trial.p2p_fail }} passing:
| # | Kind | Target | Result |
|---|---|---|---|
| {{ c.step_id }} | {{ c.category }} | {{ c.target or '—' }} | {% if c.failure %}× {{ c.failure }} {%- else %}ok{% endif %} |
{{ p.traj.last_agent_message }}