{% extends "base.html" %} {% block title %}Submission {{ sub.id[:8] }} — {{ config.INSTANCE_NAME }}{% endblock %} {% block content %}
← Back to all submissions {% if sub.status in ['pending_inline','pending_llm'] %}
Review in progress — checks running against the bundle. Page auto-refreshes when verdict lands.
0s
{% endif %}

{{ sub.type }} · {{ sub.name | store_display_name }} {% if sub.version %}v{{ sub.version }}{% endif %}

{{ sub.id }}
Status (verdict)
{{ sub.status }}
Entity lifecycle
{%- if entity_visibility_status -%} {{ entity_visibility_status }} {%- if entity_visibility_status != sub.status %} live state — verdict immutable {%- endif %} {%- else -%} entity gone {%- endif -%}
Version
{%- if submission_version_no -%} v{{ submission_version_no }} {%- if entity_version_no and entity_version_no == submission_version_no %} current {%- elif entity_version_no %} superseded — current is v{{ entity_version_no }} {%- endif %} {%- else -%} — (legacy or hash not in history) {%- endif -%}
Bundle hash
{% if sub.version %}{{ sub.version }}{% else %}{% endif %}
Submitter
{{ sub.submitter_email or sub.submitter_id }}
Created
{{ sub.created_at.strftime("%Y-%m-%d %H:%M:%S UTC") if sub.created_at else "" }}
Last update
{%- if sub.updated_at -%} {{ sub.updated_at.strftime("%Y-%m-%d %H:%M:%S UTC") }} just now {%- endif -%}
Reviewed by model
{%- if sub.reviewed_by_model -%} {{ sub.reviewed_by_model }} {%- elif sub.status in ['pending_llm', 'pending_inline'] -%} ⟳ in flight {%- elif sub.status == 'blocked_inline' -%} — (inline-blocked, LLM skipped) {%- elif sub.status == 'approved' -%} — (guardrails disabled or no API key) {%- else -%} {%- endif -%}
Entity ID
{% if sub.entity_id %}{{ sub.entity_id }}{% else %}none — bundle purged or legacy row{% endif %}
Bundle size
{% if sub.file_size is not none %}{% if sub.file_size < 1024 %}{{ sub.file_size }} B{% elif sub.file_size < 1048576 %}{{ "%.1f"|format(sub.file_size / 1024) }} KB{% else %}{{ "%.1f"|format(sub.file_size / 1048576) }} MB{% endif %}{% else %}—{% endif %}
Bundle SHA256
{% if sub.bundle_sha256 %}{{ sub.bundle_sha256 }}{% else %}{% endif %}
Bundle status
{%- if sub.bundle_purged_at -%} purged on {{ sub.bundle_purged_at.strftime("%Y-%m-%d %H:%M:%S UTC") }} {%- elif sub.entity_id -%} on disk {%- else -%} no bundle (legacy row) {%- endif -%}
{# Action buttons — same JSON endpoints as the list page. #}
{% if sub.status in ['blocked_inline','blocked_llm','review_error'] and sub.entity_id %} {% endif %} {% if sub.entity_id %} {% endif %} {% if sub.entity_id and not sub.bundle_purged_at %} Download bundle {% endif %} {% if sub.status in ['review_error','blocked_llm'] and sub.entity_id %} {% endif %}
{# Help text: explain why override isn't shown on this row, when applicable. #} {% if sub.status == 'approved' %}

Already approved — no override needed. Use Rescan to re-evaluate against current rules; it may flip the verdict.

{% elif sub.status == 'overridden' %}

Already admin-overridden. Rescan to clear the override and re-evaluate.

{% elif sub.status in ['blocked_inline','blocked_llm','review_error'] and not sub.entity_id %}

No override available — inline-blocked submissions are rolled back at upload time, so there's no bundle to publish. Submitter must fix and re-upload.

{% endif %}
{# ── Version switcher ────────────────────────────────────────────────────── #} {# All submissions linked to this entity, newest first. Admin clicks any row to jump to its detail. Surfaces multi-version entities so verdicts across versions can be compared without bouncing back to the queue. #} {% if sibling_submissions and sibling_submissions|length > 1 %}

Submissions for this entity ({{ sibling_submissions|length }})

{% for s in sibling_submissions %} {% endfor %}
v# Status Hash Reviewed by Created
{% if s.version_no %} v{{ s.version_no }} {% else %} {% endif %} {% if s.version_no and s.version_no == entity_version_no %} current {% endif %} {{ s.status }} {{ (s.version or '')[:12] }} {{ s.reviewed_by_model or '—' }} {{ s.created_at.strftime("%Y-%m-%d %H:%M") if s.created_at else "" }} {% if s.is_current %} viewing {% else %} Open → {% endif %}
{% endif %} {# ── Override history ────────────────────────────────────────────────────── #} {% if sub.override_by %}

Override

Overridden by {{ override_email or sub.override_by }}{% if sub.updated_at %} on {{ sub.updated_at.strftime("%Y-%m-%d %H:%M:%S UTC") }}{% endif %}. {% if sub.override_reason %}
Reason: {{ sub.override_reason }}{% endif %}
{% endif %} {# ── Activity timeline ───────────────────────────────────────────────────── #} {# v37 split: per-submission events surface here. Entity-wide events (archive / install / hard-delete) — which apply to ALL versions of this entity — surface in the separate "Entity activity" card below so admin can tell version-scoped from entity-scoped at a glance. #} {% macro _render_timeline(rows) %} {% endmacro %} {% if submission_audit_rows %}

Activity timeline{% if submission_version_no %} v{{ submission_version_no }}{% endif %}

Recorded actions for THIS submission row only — accept / verdict / rescan / override / retry / bundle download. Use this to confirm a verdict is fresh (timestamp on the latest store.submission.rescan row matches the time you clicked Rescan).

{{ _render_timeline(submission_audit_rows) }}
{% endif %} {% if entity_audit_rows %}

Entity activity (all versions)

Entity-wide events that apply to every version of this entity — creation, archive, install / uninstall, hard delete. Same content shows on every submission for this entity by design.

{{ _render_timeline(entity_audit_rows) }}
{% endif %} {# ── Inline checks ───────────────────────────────────────────────────────── #} {# Each ``det-card`` below renders verdict data scoped to THIS submission row (i.e. one specific version). Section headers get a ``vN`` chip when ``submission_version_no`` is known so admin never confuses one version's verdict for another's. #} {% set ic = sub.inline_checks or {} %} {% macro _vchip() %}{% if submission_version_no %}v{{ submission_version_no }}{% endif %}{% endmacro %}

Manifest check{{ _vchip() }} {% if ic.manifest %}{{ ic.manifest.status or 'pass' }}{% endif %}

{% if ic.manifest and ic.manifest.issues %} {% else %}
No manifest issues.
{% endif %}

Static security scan{{ _vchip() }} {% if ic.static_security %}{{ ic.static_security.status or 'pass' }}{% endif %}

{% if ic.static_security and ic.static_security.findings %} {% for f in ic.static_security.findings %} {% endfor %}
SeverityCategoryFile:lineReasonSnippet
{{ f.severity }} {{ f.category }} {{ f.file }}:{{ f.line }} {{ f.reason }} {{ f.snippet }}
{% else %}
No security findings.
{% endif %}

Quality + templating{{ _vchip() }} {% if ic.quality %}{{ ic.quality.status or 'pass' }}{% endif %}

{% if ic.quality %}
Template placeholders found: {{ ic.quality.template_placeholders or 0 }}
{% if ic.quality.issues %} {% endif %} {% if ic.quality.template_recommendation %}
{{ ic.quality.template_recommendation }}
{% endif %} {% else %}
No quality data.
{% endif %}
{# ── LLM review ──────────────────────────────────────────────────────────── #}

LLM security review{{ _vchip() }} {% if sub.llm_findings and sub.llm_findings.risk_level %} {{ sub.llm_findings.risk_level }} {% endif %}

{% if sub.llm_findings %} {% if sub.llm_findings.error %}
Error: {{ sub.llm_findings.error }}
{% else %} {% if sub.llm_findings.summary %}

{{ sub.llm_findings.summary }}

{% endif %} {% if sub.llm_findings.findings %}

Security findings

{% for f in sub.llm_findings.findings %} {% endfor %}
SeverityCategoryFileExplanationFix hint
{{ f.severity }} {{ f.category }} {{ f.file }} {{ f.explanation }} {{ f.fix_hint or "" }}
{% endif %} {# Content-quality issues. Pre-fix the template only rendered the security findings table, so a submission blocked purely on content_quality (e.g. weak description) showed up as 'No findings — model verdict was clean' even though status was blocked_llm. Surfaced live by an admin investigating a blocked re-restore of an already-approved bundle. #} {% set cq = sub.llm_findings.content_quality %} {% if cq and cq.issues %}

Content quality issues {{ cq.verdict }}

{% for issue in cq.issues %} {% endfor %}
FileFieldIssueSuggested rewrite
{{ issue.file }} {{ issue.field }} {{ issue.issue }} {{ issue.hint or "" }}
{% endif %} {% if not sub.llm_findings.findings and not (cq and cq.issues) %} {% if sub.status in ['blocked_llm', 'review_error'] %}
Blocked but no findings recorded. This is usually a transient LLM non-determinism: the reviewer returned a fail verdict without enumerating the offending items. Click Rescan to re-run the pipeline, or Override with a written reason if you've verified the bundle offline.
{% else %}
No findings — model verdict was clean.
{% endif %} {% endif %} {% if sub.llm_findings.reused_from_submission_id %}
✓ Verdict reused from prior approved submission {{ sub.llm_findings.reused_from_submission_id[:8] }} (byte-identical bundle — LLM was not re-called).
{% endif %} {% endif %} {% elif sub.status in ['pending_inline', 'pending_llm'] %}
Review still in progress…
{% else %}
No LLM verdict (review skipped or not yet run).
{% endif %}
{# ── Other attempts by submitter ─────────────────────────────────────────── #} {% if other_count %}

Other attempts

View {{ other_count }} other submission{{ "" if other_count == 1 else "s" }} by {{ sub.submitter_email or sub.submitter_id }} →
{% endif %}
{% endblock %}