{% extends "base.html" %} {% block title %}{{ case.case_id }} — psyc{% endblock %} {% block content %}
← back to cases

{{ case.case_id }}

▶ case journey

{{ case.summary }}

The full record for one case — how Classifyline rated it, what Scoutline observed, the evidence Sealine encrypted, where Routeline may send it, and every ledger entry it produced.

how to use this view

How to use. Read the cards top-to-bottom — classification, observables, sealed package, routes, ledger. Hit ▶ case journey for the animated walk-through.

What you're seeing. Every worker line's output for this one case: how it was rated, what was observed, what was encrypted and to whom, where it would route, and the audit rows it produced.

Why it matters. Nothing sensitive leaves psyc without a human seeing the full reasoning chain — this page is that chain, for one case.

Classification

Severity
{% if case.classification.severity %}{{ case.classification.severity.value }}{% else %}—{% endif %}
TLP
{{ case.classification.tlp.value }}
Incident type
{{ case.classification.incident_type.value if case.classification.incident_type else '—' }}
Internal class
{{ case.classification.internal_class.value if case.classification.internal_class else '—' }}

Confidence

Level
{{ case.confidence.level }}
Source reliability
{{ case.confidence.source_reliability }}
Information credibility
{{ case.confidence.information_credibility }}

Source

Type
{{ case.source_type }}
Reference
{% if case.source_ref %}{% if case.source_ref.startswith(('http://', 'https://')) %}{{ case.source_ref }}{% else %}{{ case.source_ref }}{% endif %}{% else %}—{% endif %}
Observed
{{ case.observed_at.strftime('%Y-%m-%d %H:%M UTC') }}
Ingested
{{ case.ingested_at.strftime('%Y-%m-%d %H:%M UTC') }}

Observables

{% set obs = case.observables %} {% if obs.urls %}

URLs

    {% for u in obs.urls %}
  • {{ u }}
  • {% endfor %}
{% endif %} {% if obs.domains %}

Domains

    {% for d in obs.domains %}
  • {{ d }}
  • {% endfor %}
{% endif %} {% if obs.ips %}

IPs

    {% for i in obs.ips %}
  • {{ i }}
  • {% endfor %}
{% endif %} {% if obs.hashes %}

Hashes

    {% for h in obs.hashes %}
  • {{ h }}
  • {% endfor %}
{% endif %} {% if not (obs.urls or obs.domains or obs.ips or obs.hashes) %}

no observables

{% endif %}
{% if sealed_pkg %}

SEALED PACKAGE

{{ sealed_pkg.package_id }}
Created
{{ sealed_pkg.created_at.strftime('%Y-%m-%d %H:%M UTC') }}
Plaintext SHA-256
{{ sealed_pkg.plaintext_hash }}
Recipients
    {% for r in sealed_pkg.recipients %}
  • {{ r }}{{ (sealed_pkg.ciphertext_per_recipient[r] | length) // 4 * 3 }} B
  • {% endfor %}
{% endif %} {% if routes or blocked %}

Routes

{{ routes|length }} allowed · {{ blocked|length }} blocked
{% for r in routes %}
{{ r.destination_name }} priority {{ r.priority }} · {{ r.payload_kind }} · max_tlp {{ r.max_tlp_allowed.value }}
{% endfor %} {% for b in blocked %}
{{ b.destination_name }} {{ b.reason }}
{% endfor %}
{% endif %} {% if ledger %}

Ledger (this case)

{{ ledger|length }} entr{{ 'y' if ledger|length == 1 else 'ies' }}
{% for e in ledger %} {% endfor %}
Timestamp Destination Payload hash TLP Outcome
{{ e.timestamp.strftime('%H:%M:%S') }} {{ e.destination }} {{ e.payload_hash or '—' }} {{ e.tlp.value }} {{ e.outcome.value }}
{% endif %} {% endblock %}