Criminal Code Analysis
Relevant source files
The following files were used as context for generating this wiki page:
Criminal Code Analysis is a specialized feature that monitors and evaluates Telegram messages for potential violations of the Criminal Code of the Russian Federation (УК РФ). It uses a multi-stage pipeline involving semantic pre-filtering, Large Language Models (LLMs), and Retrieval-Augmented Generation (RAG) to identify specific legal articles, provide evidence, and calculate community risk levels.
This system operates as a Cloudflare Durable Object to ensure atomic processing and efficient caching. It integrates directly with AI providers like OpenAI and legal-specific RAG corpuses to maintain high accuracy while managing API costs through intelligent queueing and filtering logic.
System Architecture
The analysis infrastructure centers around the CriminalCodeAnalyzerDO class, which manages the lifecycle of a message analysis request. The system separates high-volume message intake from expensive AI reasoning by utilizing a tiered filtering approach.
Message Processing Flow
The following diagram illustrates the lifecycle of a message within the analysis system:
The diagram shows the multi-stage validation process that ensures only relevant messages reach the most complex AI models.
Sources: [src/durable-objects/criminal-code-analyzer-do.ts:133-210], [src/durable-objects/criminal-code-analyzer-do.ts:446-560]
Component Breakdown
1. Filtering Layers
To maintain performance and cost-efficiency, the system applies three distinct filters:
- Local Prefilter: Evaluates message length and simple heuristics (e.g., commands or extremely short text).
- Semantic Prefilter: Uses a "nano" LLM (e.g.,
gpt-4.1-nano) to determine if the message contains threats, incitement, extremism, or sexual violence before proceeding to legal verification. - RAG Quality Gate: Validates that retrieved legal references meet a minimum similarity score (default 0.58) before invoking a final judicial model.
Sources: [src/durable-objects/criminal-code-analyzer-do.ts:646-680], [src/durable-objects/criminal-code-analyzer-do.ts:892-910]
2. The Final Judge
When a message passes pre-filters and generates legal hits, the runOpenAIFinalJudge method invokes a high-reasoning model. This "Judge" evaluates the target message against the full text of retrieved УК РФ articles. It specifically looks for:
- Subjectivity: Does the author express personal intent or describe a third party?
- Grounding: Is the violation based on an exact quote from the message?
- Benign Context: Is the text a joke, a quote from a game, or a news discussion?
Sources: [src/core/providers/ai-provider.ts:149-250], [src/durable-objects/criminal-code-analyzer-do.ts:912-940]
3. Caching System
The system implements a two-tier cache to prevent redundant AI calls:
- KV Cache: Stores
CriminalAnalysisResultobjects using a SHA-256 hash of the normalized message text as the key. - Database Cache: Stores results in the
criminal_analysis_cacheD1 table as a persistent backup with defined expiration dates.
Sources: [src/durable-objects/criminal-code-analyzer-do.ts:1145-1215], [migrations/0003_criminal_code.sql:35-41]
API Endpoints
The CriminalCodeAnalyzerDO exposes several internal endpoints for managing the analysis lifecycle:
| Endpoint | Method | Purpose |
|---|---|---|
/analyze | POST | Performs immediate analysis of a single message and stores results. |
/enqueue | POST | Adds a message to a background queue for batched processing via alarms. |
/diagnose | POST | Runs a full diagnostic trace without persisting the violation to the database. |
/stats | GET | Retrieves aggregated violation statistics for a chat or specific user. |
/clear-cache | POST | Purges all cached analysis results from KV and D1 storage. |
Sources: [src/durable-objects/criminal-code-analyzer-do.ts:98-128], [tests/criminal-code-analyzer-do.test.ts:107-130]
Data Model
The system persists violations and statistics using the following D1 SQL schema:
CREATE TABLE criminal_violations (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL,
chat_id INTEGER NOT NULL,
article TEXT NOT NULL,
quote TEXT NOT NULL,
severity INTEGER CHECK (severity BETWEEN 1 AND 10),
confidence REAL CHECK (confidence BETWEEN 0.0 AND 1.0),
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
Sources: [migrations/0003_criminal_code.sql:8-20]
Risk Level Calculation
The bot calculates the riskLevel based on the sum of severity scores for all violations in a single message analysis:
| Severity Sum | Risk Level |
|---|---|
| 0 - 3 | low |
| 4 - 7 | medium |
| 8 - 15 | high |
| 16+ | critical |
Sources: [src/durable-objects/criminal-code-analyzer-do.ts:1044-1055]
Configuration
Analysis behavior is controlled via environment variables defined in the Env interface:
| Variable | Type | Default | Description |
|---|---|---|---|
CRIMINAL_AI_PREFILTER_ENABLED | boolean | true | Enables semantic AI pre-filtering to save tokens. |
CRIMINAL_PREFILTER_MIN_CONFIDENCE | number | 0.55 | Minimum AI confidence to proceed to RAG stage. |
CRIMINAL_FINAL_JUDGE_MODEL | string | gpt-5-nano | Model used for the final judicial decision. |
LEGAL_RAG_DAILY_QUERY_CAP | number | 250 | Daily limit for legal RAG vector searches. |
CRIMINAL_STORE_TEXT_PREVIEW | boolean | - | Whether to store message snippets in the DB. |
Sources: [src/core/env.ts:285-334], [src/durable-objects/criminal-code-analyzer-do.ts:1068-1100]
Summary of Logic
Criminal Code Analysis identifies potential illegal content by transitioning through high-recall/low-precision filters (Local/Semantic) into high-precision reasoning (Final Judge). It ensures that every stored violation includes a direct quote, a specific УК РФ article, and an explanation of the intent (whyNotBenign). Statistics are automatically updated via a TRIGGER on the criminal_violations table to provide real-time community safety metrics.
Sources: [migrations/0003_criminal_code.sql:50-75], [src/core/providers/ai-provider.ts:175-210]