{{ tier0_count + go_count }} Decisions {{ tier0_count }} Tier 0 · {{ go_count }} GO/NO-GO {% if paused_count and paused_count > 0 %} {{ paused_count }} Paused Workers awaiting answer {% endif %} {% if arc_close_count and arc_close_count > 0 %} {{ arc_close_count }} Arc Closure Close-ready arcs {% endif %} {{ ac_count }} Verifications Human ACs
{{ total_count }} Total
{% if pending_tier0 or pending_go %}

Decisions

{% elif deferred_count and deferred_count > 0 %}

No pending decisions. {{ deferred_count }} deferred inception{{ '' if deferred_count == 1 else 's' }} parked on the inception board (watching for promotion criteria).

{% endif %} {% if pending_tier0 %}

Tier 0 Approvals

Agent blocked — requires your decision
{% for item in pending_tier0 %}
{{ item.risk }}
{{ item.status }}
{{ item.timestamp or '' }}
{{ item.command_preview }}
{% if item.status == 'pending' %}
{% elif item.status == 'expired' %}

Expired — agent must retry the command to generate a new request.

{% endif %}
{% endfor %} {% endif %} {% if pending_go %}

Inception Decisions

{{ go_count }} pending GO/NO-GO
{% for t in pending_go %}
{# T-1537: agent recommendation verdict badge — parity with partial-complete cards (T-1531) #} {% if t.verdict is defined %} {% set _v = t.verdict %} {{ _v }} {% endif %} {# T-1569 / F3: reviewer agent's mechanical verdict — green PASS, red findings/needs_human #} {% if t.reviewer and t.reviewer.overall %} {% set _r = t.reviewer %} {% set _bad = (_r.findings and _r.findings > 0) or _r.needs_human or _r.overall in ('FAIL', 'WARN') %} Reviewer: {{ _r.overall }}{% if _r.findings %} · {{ _r.findings }}{% endif %}{% if _r.needs_human %} ⚠{% endif %} {% endif %} {{ t.task_id }}: {{ t.name }}
Pending
{% if t.problem_excerpt %}

{{ t.problem_excerpt }}

{% endif %} {% if t.artifacts %}
Research: {% for a in t.artifacts %} {{ a.name }}{% if not loop.last %}, {% endif %} {% endfor %}
{% endif %} {% if t.assumption_counts.total %}
Assumptions: {{ t.assumption_counts.validated }}/{{ t.assumption_counts.total }} validated{% if t.assumption_counts.source == 'body' %} (from body){% endif %}
{% endif %} {% if t.recommendation %}
Agent Recommendation: {% if t.rec_decision == 'GO' %} GO {% elif t.rec_decision == 'NO-GO' %} NO-GO {% elif t.rec_decision == 'DEFER' %} DEFER {% else %} {{ t.rec_decision }} {% endif %}
{{ t.recommendation }}
{% else %} {# T-1214: Fallback context when agent recommendation is missing #}
No agent recommendation written yet
{% if t.problem_full %}
Problem: {{ t.problem_full[:300] }}{% if t.problem_full|length > 300 %}...{% endif %}
{% endif %} {% if t.go_nogo_criteria %}
Go/No-Go Criteria
{{ t.go_nogo_criteria }}
{% endif %}
Review the full task for research findings, or ask the agent to write a recommendation.
{% endif %}
{% endfor %} {% endif %} {% if arcs_close_ready %}

Arc Closure

Arcs ready for review

{{ arc_close_count }} arc{{ '' if arc_close_count == 1 else 's' }} — completion ≥80% with agent ## Recommendation on anchor
{% for a in arcs_close_ready %}
{% set _v = a.verdict %} {{ _v }} {# T-2112: explicit hx-target="#content" on every cross-page navigation link inside this template. The wrapping #approvals-content div sets hx-target="this" for its own 10s polling (T-669 / T-2060); htmx INHERITS that to descendant anchors. Without these overrides, clicking Review or an anchor-task link swaps the destination INTO the polling div (so the old approvals shell breadcrumb/heading stays above it) and the next polling cycle (≤10s) overwrites the swapped content with /approvals/content — i.e. "bounces back". Triplet here = target + swap + push-url so the browser URL also updates correctly. #} {{ a.name }} {{ a.completed }}/{{ a.total }} — {{ "%.0f%%" % (a.completion_ratio * 100) }} {% if a.anchor %} · anchor {{ a.anchor }} {% endif %}
Review Approve / Override
{% if a.headline_mechanic %} {# T-2111: headline_mechanic moved out of .approval-meta (0.75rem muted) into the readable .headline-mechanic-box callout — body text + accent stripe on tinted primary bg. Same class as T-2110's arc_review.html. #}
{{ a.headline_mechanic }}
{% endif %}
{% endfor %} {% endif %} {% if paused_dispatches %}

Paused Dispatches

Workers Awaiting Resolution

{{ paused_count }} dispatch{{ '' if paused_count == 1 else 'es' }} — Worker emitted pause_requested, exited cleanly, waiting for your answer
{% for pd in paused_dispatches %}
{% if pd.severity == 'high' %}[HIGH] {% elif pd.severity == 'medium' %}[MED] {% elif pd.severity == 'low' %}[LOW] {% else %}[?]{% endif %} {{ pd.task_id }} — {{ pd.question_short or '(no question)' }}
Dispatch {{ pd.dispatch_id_short }} · paused {{ pd.age_label }} ago · severity: {{ pd.severity or '?' }} · likelihood: {{ pd.likelihood or '?' }} {% if pd.worker_kind %} · worker: {{ pd.worker_kind }}{% endif %} {% if pd.state_ref %} · state: {{ pd.state_ref }}{% endif %}
Answer via /review/{{ pd.task_id }} — the agent will read your resolution and re-dispatch (slice 5).
{% endfor %} {% endif %} {% if pending_acs %}

Verifications

Human Acceptance Criteria

{{ ac_count }} across {{ ac_task_count }} task{{ 's' if ac_task_count != 1 }} — rubber-stamp + review checks
{% if ready_count is defined and ready_count > 0 %}
{% endif %} {% set rubber_stamp_count = pending_acs | selectattr('sort_priority', 'equalto', 2) | list | length %} {% set review_count = pending_acs | selectattr('sort_priority', 'equalto', 0) | list | length %} {% set stale_count = pending_acs | selectattr('is_stale') | list | length %} {% set go_count = pending_acs | selectattr('verdict', 'equalto', 'GO') | list | length %} {% set defer_count = pending_acs | selectattr('verdict', 'equalto', 'DEFER') | list | length %} {% set nogo_count = pending_acs | selectattr('verdict', 'equalto', 'NO-GO') | list | length %} {# T-1540 iter1: ? verdict was invisible — no filter button. Add count + button. #} {# T-1576: split NO-REC ('agent owes a recommendation') from ? ('verdict unparseable'). #} {% set norec_count = pending_acs | selectattr('state', 'equalto', 'NO-REC') | list | length %} {% set unknown_count = (pending_acs | selectattr('verdict', 'equalto', '?') | list | length) - norec_count %}
{% if go_count %} {% endif %} {% if defer_count %} {% endif %} {% if nogo_count %} {% endif %} {% if norec_count %} {# T-1576: NO-REC = agent owes a recommendation (no `## Recommendation` section). #} {% endif %} {% if unknown_count %} {% endif %} {% if stale_count %} {% endif %}
{# T-2038: bound rendered height. Render the first _ac_cap (most-actionable, list is sorted by priority,age) normally; wrap the overflow in a collapsed
so it is display:none — excluded from scrollHeight and from full_page screenshots — yet still in the DOM and one click away (nothing dropped). T-2103: lowered cap 15 → 10. With 4 pending inception cards (~760px each, full Recommendation rendered open by default) + verbose AC cards (~285px each), the 15-AC cap pushed total to 8926px (>8000 cap). Cap=10 saves ~1425px → total ~7500px, comfortably under cap. Overflow group still surfaces N-10 remaining; sort already prioritises REVIEW + stale so top 10 are right 10. #} {% set _ac_cap = 10 %} {% for t in pending_acs %} {% if loop.index == _ac_cap + 1 %}
Show {{ pending_acs|length - _ac_cap }} more verification{{ 's' if (pending_acs|length - _ac_cap) != 1 }} — lower priority, all still actionable {% endif %}
{{ t.task_id }}: {{ t.name }}
{# T-1531: agent recommendation verdict badge — green=GO, amber=DEFER, red=NO-GO, grey=? T-1576: prefer state so NO-REC ('agent owes a recommendation') reads distinctly from ? ('verdict unparseable'). #} {% set _v = t.state if (t.state is defined and t.state == 'NO-REC') else (t.verdict if t.verdict is defined else '?') %} {{ _v }} {# T-1569 / F3: reviewer mechanical verdict — parity with inception cards #} {% if t.reviewer and t.reviewer.overall %} {% set _r = t.reviewer %} {% set _bad = (_r.findings and _r.findings > 0) or _r.needs_human or _r.overall in ('FAIL', 'WARN') %} R:{{ _r.overall }}{% if _r.findings %}·{{ _r.findings }}{% endif %}{% if _r.needs_human %}⚠{% endif %} {% endif %} {% if t.age_days is defined %} {{ t.age_days }}d{% if t.is_stale %} ⚠{% endif %} {% endif %} 📱 {{ t.status }}
{% set unchecked_count = t.human_acs | rejectattr('checked') | list | length %} {% for ac in t.human_acs %}
{% if ac.confidence == 'review' %} Review {% elif ac.confidence == 'rubber-stamp' %} Rubber-stamp {% endif %} {{ ac.text }}
{% if ac.steps or ac.expected or ac.if_not %}
{% if ac.steps %}
Steps:
    {% for step in ac.steps %}
  1. {{ step }}
  2. {% endfor %}
{% endif %} {% if ac.expected %}
Expected: {{ ac.expected }}
{% endif %} {% if ac.if_not %}
If not: {{ ac.if_not }}
{% endif %}
{% endif %}
{% endfor %} {% if unchecked_count == 0 %}
{% endif %}
{% endfor %} {% if pending_acs|length > _ac_cap %}
{% endif %} {% endif %} {% if not pending_tier0 and not pending_go and not pending_acs and not paused_dispatches %}

Nothing needs your attention.

Tier 0 gates, inception decisions, and human acceptance criteria will appear here when pending.

{% endif %} {% if resolved_tier0 %}

Recent

{% for item in resolved_tier0 %}
{{ item.risk }}
{{ item.status }}
{{ item.get('response', {}).get('responded_at', '') }} {% if item.get('response', {}).get('feedback') %} — {{ item.response.feedback }} {% endif %}
{{ item.command_preview }}
{% endfor %}
{% endif %}