{% extends "base.html" %} {% block title %}Change {{ change.change_id }} · ai-protect{% endblock %} {% block autorefresh %}window.AI_PROTECT_NO_AUTOREFRESH = true;{% endblock %} {% block content %} ← back to queue
{{ change.state.value }} Tier {{ change.tier }} {{ change.strategy }}

{{ change.summary }}

change: {{ change.change_id }} app: {{ change.app_name }} finding: {{ change.finding_id[:8] }}… confidence: {{ '%.0f' % (change.confidence * 100) }}%
{% if change.notes %}

Notes

{{ change.notes }}
{% endif %}

Proposed diff

{% if change.diff %}
{{ change.diff }}
{% else %}

No file changes — this remediation surfaces a snippet for manual application (see Notes).

{% endif %}

Tests

{% if change.tests %} {% for t in change.tests %} {% endfor %}
TestPathPre-apply (expect FAIL)Post-apply (expect PASS)
{{ t.name }} {{ t.path }} {% if t.pre_apply_passed is none %}— {% elif t.pre_apply_passed %}passed (unexpected) {% else %}failed (correct) {% endif %} {% if t.post_apply_passed is none %}— {% elif t.post_apply_passed %}passed {% else %}failed {% endif %}
{% elif change.test_status == 'not_generatable' %}
No unit test could be generated.

{{ change.test_status_reason or "This category does not produce a testable artifact." }} The change can still be applied — validation will rely on the post-apply re-scan.

{% else %}

No tests yet.

{% endif %}

Files affected

{% if change.files %} {% for f in change.files %} {% endfor %}
FileStatusBackupSHA before → after
{{ f.path }} {% if f.created %}created{% else %}modified{% endif %} {{ f.backup_path or "—" }} {{ (f.sha_before or '∅')[:10] }} → {{ (f.sha_after or '∅')[:10] }}
{% else %}

No files declared yet (proposed but not applied).

{% endif %}

Actions

{% set s = change.state.value %} {% if s in ('proposed','tests_generated','no_test_possible') %}
{% endif %} {% if s == 'approved' %} {% endif %} {% if s == 'applied' %}
{% endif %} {% if s == 'validated' %}
{% endif %} {% if s == 'deployed' %}
{% endif %} {% if s in ('rejected','reverted','accepted') %}

Terminal state. No further actions.

{% endif %}
{% if events %}

This change's history

{% for e in events|reverse %} {% endfor %}
TimeEventActorDetail
{{ e.ts }} {{ e.event }} {{ e.actor or "—" }} {% set extras = [] %} {% if e.from_state and e.to_state %}{% set _ = extras.append(e.from_state ~ " → " ~ e.to_state) %}{% endif %} {% if e.test_status %}{% set _ = extras.append("tests: " ~ e.test_status) %}{% endif %} {% if e.original_cleared is defined %}{% set _ = extras.append("cleared: " ~ e.original_cleared) %}{% endif %} {% if e.new_high_or_above is defined %}{% set _ = extras.append("new HIGH+: " ~ e.new_high_or_above) %}{% endif %} {% if e.reason %}{% set _ = extras.append("reason: " ~ e.reason) %}{% endif %} {{ extras|join(' · ') }}
{% endif %}
{% if change.state.value == 'approved' %} {% endif %} {% endblock %}