{% extends "base.html" %} {% block title %}Pulse — psyc admin{% endblock %} {% block content %}

Pulse — autonomous heartbeat

{{ pipelines|length }} pipeline{{ '' if pipelines|length == 1 else 's' }}

Cron-style scheduler that drives every psyc line on a cadence without human input. Each pipeline has an autonomy mode and a cadence in seconds. The kill switch halts everything instantly — it overrides cadence, mode, and the enabled flag.

← back to admin

{% if flash %}
{{ flash }}
{% endif %}

Global kill switch

{{ 'ARMED' if kill_switch else 'OFF' }}
{% if kill_switch %}
✗ KILL SWITCH ARMED — every pipeline is paused. tick() returns "skipped" for everything. Run-now is also blocked. Toggle off to resume.
{% else %}
✓ Pulse is live — the background loop ticks every {{ tick_interval }}s.
{% endif %}

AUTO-RESPONSE STATE

{{ respond_auto_fired_24h }} auto-fired in last 24h

When the respond pipeline runs in auto-execute, every PROPOSED action that passes all three gates fires automatically. Below shows the live config + audit trail.

{# Mode badge — traffic-light coloring. auto-execute is "armed" (red), auto-propose is amber, manual is green/safe. #} {% if respond_mode == 'auto-execute' %}
MODE: auto-execute (ARMED)
{% elif respond_mode == 'auto-propose' %}
MODE: auto-propose (staging only)
{% else %}
MODE: manual (no proposals)
{% endif %}
Threshold: {{ respond_threshold|upper }}+
Quorum: {{ 'ON' if respond_require_quorum else 'OFF' }}
Local-only: {{ 'ON' if respond_local_only else 'OFF' }}
{% if respond_audit_recent %} {% for row in respond_audit_recent %} {% endfor %}
timestamp decision case detail
{{ row.timestamp }} {% if row.action == 'auto-fire' %}✓ {{ row.action }} {% elif row.action == 'error' %}✗ {{ row.action }} {% else %}⊘ {{ row.action }}{% endif %} {{ row.case_id or '—' }}{% if row.action_id %} · #{{ row.action_id }}{% endif %} {{ row.detail or '' }}
{% else %}

No auto-response decisions logged yet.

{% endif %}

Pipelines

{{ pipelines|selectattr('enabled')|list|length }} enabled

Mode: auto-execute fires the line, auto-propose stages proposals for human approval, manual runs only when you press “Run now”. Cadence is the gap between ticks; the loop wakes up every {{ tick_interval }}s.

{% for p in pipelines %} {% endfor %}
Pipeline Mode · cadence · enabled Last fired Next fire Last result
{{ p.title }}
{{ p.name }} · {{ p.description }}
{% if p.last_fired %}{{ relative(p.last_fired) }}{% else %}—{% endif %} {% if p.next_fire %}{{ relative(p.next_fire) }}{% else %}—{% endif %} {% if p.last_outcome == 'ok' %} {% elif p.last_outcome == 'err' %} {% elif p.last_outcome == 'skipped' %} {% endif %} {{ (p.last_result or '—')[:60] }}{% if (p.last_result or '')|length > 60 %}…{% endif %}
{% endblock %}