Skip to content

Escalation-Chain Tracking

Most moderation tooling scores a single piece of text in isolation. This tracks a source — an account, an outlet, a document stream, any caller-supplied source_id — across a sequence of observations, and computes:

  • current severity — the harm level of the most recent observation
  • rolling average severity over a configurable window (default: last 20 observations)
  • trendescalating / stable / de-escalating, from a first-half-vs-second-half average severity comparison over the window (simple, explainable arithmetic — not a black-box model)
  • risk levellow / watch / elevated / critical, derived from current severity bumped up one level when the trend is escalating

Why arithmetic instead of a model?

Because the whole point of this project is that a human reviewer, an auditor, or a journalist can look at why a source was flagged and verify it themselves — "the last 10 posts averaged severity 2.3 and the second half of the window is worse than the first half" is checkable by hand. A learned trend model might be more accurate but would trade away exactly the transparency this tool is trying to offer.

The severity ladder

narrative_harm_classifier/classifier/tracking/models.py defines:

none < narrative_distortion < demonization/objectification < animalization/criminalization <
direct_call_to_violence

This is a simplified, project-specific model inspired by general narrative-escalation research (see Why this exists). It is not a validated academic scale; it exists to give a consistent, explainable ordering for trend computation, not to represent a scientifically calibrated risk score.

Persistence

Uses SQLAlchemy against DATABASE_URL/TRACKING_DB_URL — SQLite by default (zero config), Postgres or Azure SQL for real deployments, same code path.

CLI

nhc track observe <source_id> "<text>"
nhc track show <source_id>
nhc track list
nhc track verify <source_id>

API

Endpoint Purpose
POST /tracking/{source_id}/observe Classify and append to a source's history
GET /tracking/{source_id} A source's escalation profile
GET /tracking All tracked sources, sorted by risk
GET /tracking/{source_id}/verify Recompute the hash chain and confirm it's intact