Architecture

Technical system blueprint and scoring logic
STORM-01 ENCLAVE
Technical BlueprintSystem ArchitectureScoring LogicEU Regulatory Grounding

PDIP — Parliamentary Disinformation Intelligence Platform

A duty-desk console for EU policy and parliamentary offices to intake suspect content, score democratic-impact risk, ground every assessment in named EU regulations, draft counter-narratives, write an immutable audit trail, and optionally publish a DSA-style transparency ledger. This page is the technical reference for teams that want to evaluate, deploy, or extend the platform.

Frontend
Next.js 14 / React 18
Backend
FastAPI + SQLAlchemy
Primary DB
Postgres
Fallback DB
SQLite
Browser -> REST -> FastAPI -> SQLAlchemy -> Postgres/SQLite

1. Architecture At A Glance

System diagram
                ┌────────────────────────────┐
                │ Browser (Next.js / React)  │
                │  Mission Desk · Registry · │
                │  Dossier · Toolkit · Ledger│
                └──────────────┬─────────────┘
                               │ axios (REST/JSON)
                               ▼
   ┌──────────────────────────────────────────────────────┐
   │ FastAPI backend  (port 8000)                         │
   │  ┌─────────────┬────────────┬────────────────────┐  │
   │  │ analysis.py │ intelligence│ pdf_export.py      │  │
   │  │ (LLM +      │ (heuristics:│ (ReportLab + QR)   │  │
   │  │ heuristics) │ twins,      │                    │  │
   │  │             │ graph, geo, │ regulations.py     │  │
   │  │             │ lang, counter)                    │  │
   │  │             │             │ (citation library) │  │
   │  └─────────────┴────────────┴────────────────────┘  │
   │           │                                          │
   │           ▼ SQLAlchemy ORM                           │
   └──────────────────────────────────────────────────────┘
                               │
                ┌──────────────▼──────────────┐
                │ Postgres (pgvector image)   │
                │  items · audit_events ·     │
                │  toolkit_incidents ·        │
                │  app_settings               │
                └─────────────────────────────┘

Containerisation

docker-compose.yml runs three services: frontend, backend, and db. Backend falls back to SQLite when DATABASE_URL points at sqlite:///..., which keeps smoke tests and offline demos working.

Transport

The browser talks to the backend with axios over REST/JSON. The backend uses FastAPI response models and SQLAlchemy ORM sessions to keep payloads typed and predictable.

Core backend modules

analysis.py handles prompts and score assembly; intelligence.py handles deterministic dossier intelligence; regulations.py powers citation drawers; pdf_export.py produces the one-page brief.

Four core tables keep analysis, audit, manual incidents, and operational state separate

2. Data Model

items

Every dossier. Stores source text/URL, narrative, entities, claims, three core scores, confidence, headline, language/country, brief, legal flags, recommended actions, policy roadmap, status, and transparency state.

audit_events

Append-only trace of meaningful actions such as dossier creation, completed analysis, escalation, counter-narrative drafting, PDF export, and publication to the transparency ledger.

toolkit_incidents

Manual, non-LLM rapid-response incident logs from the toolkit. Captures the alert card, risk matrix inputs, chosen response, notes, and the saved risk band.

app_settings

Key/value store used for election-mode state, activation timestamp, and SLA duration. Keeps operational toggles separate from dossier data.

Schema migration approach

Startup runs ensure_items_table_columns() in backend/main.py to add new dossier columns when needed. It is intentionally lightweight and best-effort rather than a full Alembic migration pipeline.

Three core signals drive dossier posture and downstream operator actions

3. Scoring Engine

Synthetic media risk

deepfake_risk

Returned by analysis.analyze_content() as ai_probability, clamped to [0, 1]. Fallback path returns 0.5 when the LLM is unavailable.

Coordination signal

coordination_score

Returned by analysis.analyze_content() as coordination_score, clamped to [0, 1]. Fallback path returns 0.2.

Mislead-citizens risk

disinformation_impact

Primary escalation score. The current backend blends 35% model output with 65% heuristic output, then caps low-signal content so harmless political reporting does not get over-tagged.

Agreement band

confidence

Computed from the spread between the three core signals: 1 − stdev(values), clamped to [0.45, 0.97]. The UI renders this as the +/- band around each meter.

Current disinformation_impact heuristic
SignalExamplesCap added
Election termselection, polling station, parliament, candidate, campaignup to +0.16 (0.04 each)
Democratic-harm verbsmislead, fraud, rigged, cancelled, moved, boycott, disenfranchiseup to +0.38 (0.12 each)
Amplification cuesviral, share now, bot, coordinated, amplif…up to +0.22 (0.08 each)
Synthetic media cuesdeepfake, synthetic, voice clone, impersonat…up to +0.18 (0.07 each)
Guardrails that keep harmless content low-risk
  • Baseline score starts at 0.02 instead of a heavier default.
  • Benign context terms like report, committee, briefing, and interview activate a soft cap.
  • If the text is only about elections/politics and lacks harm, amplification, or synthetic cues, impact is capped at 0.22.
  • Benign political reporting is further capped at 0.15 where appropriate.
  • Final impact is a weighted blend: 35% model + 65% heuristic, not a blind max().
  • Low-signal contexts are capped at 0.25 even if the model score is aggressive.
Hard floors
"polling station" + ("moved" | "closed" | "cancelled") -> >= 0.92
Election-procedure sabotage is treated as near-emergency even on fallback logic.
"do not vote" | "voting postponed" | "election cancelled" -> >= 0.95
Direct voter suppression language is treated as an emergency scenario.
confidence = 1 - stdev(disinfo, deepfake, coordination)
Higher agreement between signals means a narrower meter band and more operator trust.
Frontend and backend keep the same risk bands and rationale framing

4. Threat Tiers

>= 0.85

Electoral emergency

DSA Art. 34-35; Reg. (EU) 2024/900

>= 0.65

Severe integrity threat

DSA Art. 34; AI Act Art. 50

>= 0.45

Heightened monitoring

DSA Art. 26; GDPR Art. 5

< 0.45

Routine surveillance

GDPR Art. 5

In election mode, the frontend adds a +0.12 lift before tier lookup, and the dashboard queue threshold drops from 0.45 to 0.30.

From intake to memo to escalation and public ledger publication

5. End-To-End Dossier Flow

1
create_item() saves a dossier with status='pending' and records dossier.created.
2
If the intake is a URL, scrape_url() uses requests + BeautifulSoup to pull a trimmed text payload.
3
extract_claims() asks gpt-4o-mini for structured claims and entities.
4
analyze_content() asks gpt-4o-mini for ai_probability, coordination_score, disinformation_impact, synopsis, threat_level, narrative, legal_flags, and recommended_actions.
5
Deterministic augmenters enforce legal citations, add compliance actions, and assemble a 90-day policy roadmap.
6
intelligence.py derives the headline, confidence band, language, country, twins, graph structure, and counter-narrative draft scaffolding.
7
generate_brief() produces the stored regulator-style memo in items.brief.
8
analysis.completed is written to the audit log. If disinformation_impact >= 0.85 the backend flips the dossier to escalated and records auto.escalated.
Each screen has a narrow operational job rather than acting like a generic admin panel

6. Product Surfaces

Mission Desk

/

Hero, KPI strip, live evidence ticker, intake form, escalation queue, EU heatmap, language pills, and the always-on policy framework block.

Case Registry

/items

Filterable dossier table with search, status filters, risk-tier filters, and links into each dossier.

Dossier

/items/[id]

Hero controls, claims/entities, confidence meters, regulatory exposure, coordination graph, narrative twins, audit log, PDF export, counter-narrative drawer, and policy roadmap.

Rapid Toolkit

/toolkit

Manual alert card, two-minute triage checklist, risk calculator, decision menu, templates, saved incidents, escalation contacts, and AI literacy modules.

Transparency Ledger

/transparency

DSA Article 24-style public log of redacted interventions, legal basis chips, and action summaries.

Architecture

/architecture

This page: a technical blueprint for implementers, reviewers, and deployment owners.

A single operational toggle that changes posture, urgency, and visual state across the app

7. Election Mode

What changes when enabled
  • Queue threshold drops from 0.45 to 0.30 in dashboard_stats().
  • Frontend risk tiering adds a +0.12 lift before threshold checks.
  • Pending dossiers display a live SlaCountdown pill using created_at + slaMinutes.
  • The topbar status pill switches to ELECTION MODE LIVE with an alert tone.
  • Every toggle writes election_mode.toggled to the audit log with legal basis DSA Art. 35.
Stored settings
election_modetrue | false
election_mode_activated_atISO timestamp
election_mode_sla_minutes30 by default
The legal layer is curated and readable, not just raw citations dumped from model output

8. Regulation Library And PDF Export

backend/regulations.py

A curated in-repo dict keyed like 2024/1689:50 stores article title, paraphrased excerpt, and source PDF filename. lookup(citation) powers the citation drawers, and parse_flag_to_citation(flag) turns natural-language legal flags into lookup keys.

AI Act 5/9/14/50DSA 26/34/35/40GDPR 5/6/9/22/25EU 2024/900 overview + Art. 7
backend/pdf_export.py

GET /api/items/{id}/pdf produces a one-page EP-style brief using ReportLab with a header, four metric cells, situation overview, regulatory exposure, recommended action, and a QR code back to the dossier endpoint. If ReportLab is unavailable, a minimal handwritten PDF fallback prevents runtime failure during demos.

Operational traceability and demoability are both first-class system concerns

9. Audit Log, Transparency, And Demo Replay

Audit log

Every state-changing route calls record_event(item_id, action, detail, actor, legal_basis). The UI maps those keys to human-readable labels and action tones.

Transparency ledger

Publishing requires a completed or escalated dossier, flips transparency_published to true, and emits a DSA Art. 24 audit event. Narratives are redacted to avoid re-amplification.

Demo replay

POST /api/demo/replay seeds three prewritten dossiers: Marin synthetic audio, Marseille polling-station network, and a promoted opposition deepfake. They are intentionally scripted so every major UI feature has data.

Where to look first when maintaining or extending PDIP

10. Important Files

FileRole
backend/main.pyAll routes, process_item(), auto-escalation, election mode, dashboard APIs, demo replay, transparency publication.
backend/analysis.pyLLM prompts, score augmentation, disinformation heuristic, legal flag enforcement, action generation, brief assembly.
backend/intelligence.pyHeadline extraction, confidence band, language/country detection, twins, graph, counter-narrative, redaction.
backend/regulations.pyCurated citation library and flag-to-citation parsing.
backend/pdf_export.pyOne-page EP-style PDF brief with QR fallback behavior.
backend/governance.pyEU policy and governance context injected into the LLM prompt.
backend/rules_engine.pyParallel/legacy rules checks for deepfake threshold, prohibited patterns, sponsored content, and data minimisation.
frontend/components/Layout.jsPersistent rail, topbar, election toggle, quick action launcher.
frontend/components/CommandPalette.jsKeyboard-first navigation and operational shortcuts.
frontend/lib/risk.jsThresholds, risk-tier labels, action labels, and event tones.
frontend/pages/index.jsMission Desk orchestration.
frontend/pages/items/[id].jsDossier composition and operator actions.
Operational, legal, and demo constraints all shape the implementation choices

11. Why It Is Designed This Way

Impact > origin

Impact > origin. Electoral harm and amplification matter more than synthetic provenance alone.

Conservative low-signal handling

Conservative low-signal handling. The backend now caps topic-only or benign reporting so ordinary political coverage does not drift into monitoring tiers.

Legal grounding is deterministic

Legal grounding is deterministic. The LLM writes prose, but augmenters guarantee AI Act, DSA, GDPR, and political-ads citations are present.

Auditability is a first-class feature

Auditability is a first-class feature. Every operator action and system action writes a reasoned event with legal basis where available.

Offline-friendly heuristics keep the demo explainable

Offline-friendly heuristics keep the demo explainable. Twins, graph, geo, confidence, and redaction all work without vector search or opaque external scoring services.

Cross-links

For the operational view, go back to the Mission Desk. For public reporting behavior, see the Transparency Ledger.