{% comment %} Shared activity-timeline content. Included by timeline.html (standalone) and timeline_hub.html (Hub), so the surface works in both mounts. The timeline is a PROJECTION of signals SAC already published. Nothing here invents activity: an agent the control plane cannot be asked about renders as `unreachable` (an outage), never as quiet. The initial render is SERVER-side so the page is useful with JS off and before the first poll. The poll then refreshes it in place, bounded and deduped. {% endcomment %}
Fleet

Activity timeline

Live signals from the SAC control plane — {{ listener }} {% if identity %} · acting as {{ identity }}{% endif %}
{{ summary.total }}entries
{{ summary.observed }}observed
{{ summary.stale }}stale
{{ summary.unreachable }}unreachable
{% comment %} Filters are real form controls so they work without JS (they are query params the SERVER applies). The JS poll reads the same values, so the two paths cannot diverge. {% endcomment %}
auto-refresh every {{ refresh_seconds }}s
{% if not entries %}

No timeline entries

{% if selected_agent or selected_kind %}No published signal matches this filter.{% else %}The control plane has published no runtime activity for the agents in your scope.{% endif %}

{% else %}
    {% for e in entries %}
  1. {{ e.agent }} {{ e.kind }} {% if e.value is not None %}{{ e.value }}{% else %}—{% endif %} {{ e.state_label }} {% if e.source %}{{ e.source }}{% endif %}
  2. {% endfor %}

Only runner-published state is shown. Unknown means SAC published no signal; stale means the last real observation has aged past {{ stale_after_seconds|floatformat:0 }}s; unreachable means the listener could not be asked, which is an outage rather than silence. Entries are deduped, so a refresh does not replay a row that has not changed.

{% endif %}