{% extends "base.html" %} {% block title %}Drift Investigation — AgentPulse{% endblock %} {% block content %} {% set qs %}{% if task_type %}&task_type={{ task_type }}{% endif %}&compared=1&base={{ from_v }}{% for n in to_vs %}&to={{ n }}{% endfor %}{% if sort and sort != 'sev_desc' %}&sort={{ sort }}{% endif %}{% if request.args.get('db') %}&db={{ request.args.get('db') }}{% endif %}{% endset %}
Drift Investigation
Grouped workflow, findings, supporting signals, and related system changes.
Time Range {{ range_display }} {{ tz_label }}
{% for key,label,_ in ranges %} {{ label }} {% endfor %}
Pick from a calendar
Version Comparison {% if compare_on %}v{{ from_v }} vs {% for n in to_vs %}v{{ n }}{{ ', ' if not loop.last else '' }}{% endfor %}{% else %}v{{ from_v }}{% endif %}
Compare from
Compare to
{% for n in ver_options %}{% if n != from_v %}{% endif %}{% endfor %}
Compare all
{{ run_count }} runs
Findings · {{ investigations|length }} Sort: Severity {{ '↓' if sort=='sev_desc' else '↑' }}
{% set primary = investigations|selectattr('severity','in',['high','drift'])|list %} {% set secondary = investigations|rejectattr('severity','in',['high','drift'])|list %} {% macro inv_card(x) %}
{{ x.title }}
{{ x.kind_label }} · since run {{ x.drift_start }}
{% if x.metrics %}
{% for m in x.metrics %}{{ m.name }}{% if m.dir=='up' %}{% elif m.dir=='down' %}{% endif %}{% endfor %}
{% endif %}
Severity: {{ x.severity|sevlabel }} {% if x.confidence %}Confidence: {{ x.confidence|capitalize }}{% endif %}
{% endmacro %} {% for x in primary %}{{ inv_card(x) }}{% endfor %} {% if not primary and not secondary %}
No drift detected in this window.
{% endif %} {% if not primary and secondary %}
No high-confidence drift — only lower-confidence signals below.
{% endif %} {% if secondary %}
{{ secondary|length }} lower-confidence {% for x in secondary %}{{ inv_card(x) }}{% endfor %}
{% endif %}
{% if sel %}
{{ sel.title }}
{{ sel.subtitle }}
Severity: {{ sel.severity|sevlabel }} {% if sel.confidence %}Confidence: {{ sel.confidence|capitalize }}{% endif %}
{% if sel.kind=='chain' %}
What changed
    {% for w in sel.card.what_changed %}
  • {{ w }}
  • {% endfor %}
Why it matters
{{ sel.card.why }}
{% else %} {% if sel.route_change %}
From run {{ sel.route_change.window_start }} on (where the drift starts), {{ sel.route_change.off_rate_pct }}% of runs took a different route than usual.
Common route
The route most runs normally follow.
New route{{ 's' if route_variants|length > 1 else '' }} added removed
{% for v in route_variants %}
{{ v.pct }}% of runs since run {{ sel.route_change.window_start }}{% if v.first_run is not none %} · first appeared at run {{ v.first_run }}{% endif %}
{% endfor %} {% endif %} {% if sel.what_changed and not sel.route_change %}
What changed
    {% for w in sel.what_changed %}
  • {{ w }}
  • {% endfor %}
{% endif %} {% endif %}
Signals
Within range Drift Normal range (p10–p90) Version marker
{% else %}
Select a finding.
{% endif %}
{% if sel %} {% if related_changes %}
Potentially related changes
{% endif %}
Suggested next checks
    {% for n in sel.next_checks %}
  1. {{ n }}
  2. {% endfor %}
{% endif %}
Event timeline
{% if events_tl %}
{% set ns = namespace(drawn=false) %} {% for e in events_tl %} {% if not ns.drawn and drift_start is not none and e.run >= drift_start %}
drift started · run #{{ drift_start }}
{% set ns.drawn = true %} {% endif %}
run #{{ e.run }}{% if e.when %} · {{ e.when|et }}{% endif %}
{{ e.title }}
{% if e.detail %}
{{ e.detail }}
{% endif %}
{% endfor %} {% if not ns.drawn and drift_start is not none %}
drift started · run #{{ drift_start }}
{% endif %}
View full timeline → {% else %}
No events in this window.
{% endif %}
{% endblock %} {% block scripts %} {% endblock %}