{% from "fragments/_chips.html" import chip, needs_review_chip %} {# Run-detail body (issue #160). Every form posts to the existing /runs/{id}/... action endpoints. The page heading and primary navigation (Audio / Transcript / Review) live in the wrapper templates' command-bar blocks, not in this partial. #}

Summary

Status
{{ chip(run.status) }} {% if run_archived %}{{ chip("archived") }}{% endif %}
Current stage
{{ humanize_stage(run.current_stage) if run.current_stage else "Not started" }}
{% if run.error %} {% set nerr = normalize_error(run.error) %}

{{ nerr.label if nerr else run.error }}

{% if nerr and nerr.hint %}

{{ nerr.hint }}

{% endif %} {% if nerr and nerr.raw != nerr.label %}
Raw error
{{ nerr.raw }}
{% endif %} {% endif %} {% if run.status == "failed" and shell.can_write %}
{# Carry the revision we rendered so a stale tab's requeue 409s (exact-revision CAS). #} Retries the failed stage ({{ run.current_stage or "not started" }}).
{% if run.current_stage in ("transcribe", "diarize_embed") %} {# Static guidance only; no live probe on this page (a health check here would add model-service latency to every failed-run view and flap with service health; the setup wizard's SERVICES step owns live reachability). #}

This stage needs the model services (ASR / diarizer / embedder). If they aren't running, start a compute tier: docker compose -f compose.yaml -f compose.gpu.yaml up -d (NVIDIA GPU) or docker compose -f compose.yaml -f compose.cpu.yaml up -d (no GPU), wait for them to come up, then requeue. The shipped models run offline; an HF_TOKEN is only needed if you overrode diarization to a gated pipeline.

{% endif %} {% endif %} {% if run.status in ("queued", "running") and shell.can_write %}
{% if run.status == "running" %} Holds the run after the current stage ({{ run.current_stage or "not started" }}) finishes. The stage now running completes first, then no further stages start until you resume. {% else %} Holds this run in the queue. It will not start processing until you resume it. {% endif %}
{% endif %} {% if run.status in ("queued", "running", "awaiting_adjudication") and shell.can_write %}
{% if run.status == "running" %} Stops the run. The stage now running ({{ run.current_stage or "not started" }}) finishes first; cancel is cooperative, not an immediate kill. No further stages start. Media and any partial results are left in place (delete is separate). {% else %} Stops the run; no further stages will run. Media is left in place (delete is separate). {% endif %}
{% endif %} {% if run.status == "paused" and shell.can_write %}
Resumes processing from where it was paused ({% if run.current_stage %}{{ run.current_stage }}{% else %}the beginning{% endif %}).
Cancels this paused run. Media is left in place.
{% endif %}
{# Gate on the live status too: a bookmarked/refreshed ?enqueue=deferred URL must not keep asserting "is queued" after the sweep already republished it. #} {% if enqueue_deferred and run.status == "queued" %}

The initial enqueue was deferred because the task broker was unavailable. This run is queued and will start automatically once the broker recovers; no action needed.

{% endif %} {% if media_delete_result %}

Deleted {{ media_delete_result.files }} derived audio file{{ "" if media_delete_result.files == 1 else "s" }}{% if media_delete_result.missing %} ({{ media_delete_result.missing }} already gone){% endif %}{% if media_delete_result.failed %}, {{ media_delete_result.failed }} could not be removed and will be swept later{% endif %}. The original source recording was kept.

{% endif %} {% if run_archived %}

This run is archived, hidden from the runs list and the review queue. All its data is intact; un-archive to restore it.

{% endif %} {% if run_terminal and shell.can_write %} {# Archive / un-archive + derived-media deletion (issue #5). Only terminal runs (completed / failed / cancelled); a live run must be cancelled first. #}

Manage

{% if not run_archived %} {% set full_requires_void = restart_impact and restart_impact.requires_void %} {% set full_label_risk = restart_impact and restart_impact.label_scope_decisions > 0 and not full_requires_void %} {% set full_editorial = restart_impact and restart_impact.has_editorial_work %}
{% if full_requires_void %}
{% else %} {% endif %} {% if full_label_risk %}
{% else %} {% endif %} {% if full_editorial %}
{% else %} {% endif %} Prior stage results are kept in the ledger as earlier attempts.
{% endif %} {% if run_archived %}
Restores this run to the runs list and review queue.
{% else %}
Hides this run from the runs list and review queue. Keeps all its data; reversible.
{% endif %}
Frees disk by removing this run's preprocessed and chunked audio. Irreversible; the original source recording is kept.
{% endif %} {# Content sections (source metadata, operator notes, enrichments, speaker timeline) moved to the media editor page (issue #567). The run page is now a pure technical job record. #} {% if run.status == "completed" %}

Open in editor Transcript, enrichments, speaker timeline, and notes.

{% endif %}
Technical details

Source

{{ run.media_item.source_path }}

{% if provenance %} {# URL runs only: the acquisition source, shown as a bare host; never the raw source_url, whose query could carry a signed token. #}

Source: {{ provenance }}

{% endif %} {% if source_metadata and source_metadata.extractor %}

Extractor: {{ source_metadata.extractor }}{% if source_metadata.extractor_version %} (yt-dlp {{ source_metadata.extractor_version }}){% endif %}

{% endif %}
Revision
{{ run.revision }}
Created
{{ run.created_at.strftime("%Y-%m-%d %H:%M:%S") }}
Updated
{{ run.updated_at.strftime("%Y-%m-%d %H:%M:%S") }}

Complete run archive (JSON) {% if transcript_available %} · transcript & subtitle exports are on the Transcript page{% endif %} {% if media_reclaimed_at %} · Media reclaimed on {{ media_reclaimed_at.strftime("%Y-%m-%d") }} (transcript and decisions kept; re-run from source to restore audio). {% elif not audio_available and not transcript_available %} · No audio or transcript yet. {% endif %}

Pipeline models

The model each stage saw just before it ran. This is observed immediately before the attempt, not read back from the output, so it records which model answered rather than proving the exact build.

{% for stage in model_provenance %}

{{ stage.label }}{% if stage.recorded and stage.attempt and stage.attempt > 1 %} (from attempt {{ stage.attempt }}){% endif %}

{% if not stage.recorded %}

Not recorded. This run finished before model provenance was added, no attempt of this stage completed, or the latest completed attempt did not record it.

{% else %}
{% for role in stage.roles %}
{{ role.label }}
{% if role.reachable %}
{% if role.model %}{{ role.model }}{% else %}no model name reported{% endif %} {% if role.engine %} engine {{ role.engine }}{% endif %} {% if role.revision %}
revision {{ role.revision }}{% endif %} {% if role.decode_config_hash %}
decode config {{ role.decode_config_hash[:12] }}{% endif %}
{% else %}
Not observed{% if role.detail %} ({{ role.detail }} when the stage ran){% endif %}.
{% endif %} {% endfor %}
{% endif %}
{% endfor %}
{# Glossary provenance (issue #123): the exact vocabulary hint whisper decoded this run with, the operator's glossary unioned with the pack's words. Read-only; NULL means the run had no vocabulary or predates this record. #}

Glossary applied

The vocabulary hint transcription saw for this run, the terms from your glossary and the run's domain pack. It records what the model was told to expect, not that every term was spelled this way.

{% if run.initial_prompt %}

{{ run.initial_prompt }}

{% else %}

Not recorded. This run has not been transcribed yet, had no vocabulary, or it finished before Voxint began recording the applied glossary.

{% endif %}
{# Detected language (issue #124): what whisper decided when it transcribed this run. The score is whisper's own detection probability, shown with honest framing: it is not a calibrated confidence and says nothing about a recording that switches languages mid-way. #}

Detected language

{% if run.detected_language %}

{{ language_label(run.detected_language) }}

{% if run.detected_language_probability is not none %}

Language detection confidence: {{ confidence_band(run.detected_language_probability) }}. This is the model's own assessment of its language guess, not a measure of transcript accuracy. It reflects the whole recording as one language; a recording that mixes languages still gets a single detected language. Short or mostly silent recordings can produce low or arbitrary detections.

{% else %}

No detection score was recorded for this run.

{% endif %} {% else %}

Not recorded. This run has not been transcribed yet, or it finished before Voxint began recording the detected language.

{% endif %}

Stage ledger

{% if not stage_runs %}

No stage attempts recorded yet.

{% else %}
STAGEATTEMPTSTATUSWORKER STARTEDFINISHEDLEASE EXPIRESERROR
{% for s in stage_runs %}
{{ s.stage }} {{ s.attempt }} {{ chip(s.status) }} {{ s.worker_id or "-" }} {{ s.started_at.strftime("%Y-%m-%d %H:%M:%S") if s.started_at else "-" }} {{ s.finished_at.strftime("%Y-%m-%d %H:%M:%S") if s.finished_at else "-" }} {{ s.lease_expires_at.strftime("%Y-%m-%d %H:%M:%S") if s.lease_expires_at else "-" }} {% if s.error %}{{ s.error }}{% else %}-{% endif %}
{% endfor %}
{% endif %}
{#- Plugin run-detail panels (issue #138): each active plugin's fragments, in (slot, order) order. Empty registry ⇒ no iterations ⇒ zero bytes. -#} {%- for panel in plugin_run_detail_panels %} {% include panel.template %} {%- endfor %}