Overview
Inferences are the raw analytical findings produced by agent runs. Each inference represents a discrete insight — a trend spotted, a contradiction found, a pattern identified — backed by evidence references and a confidence score. Inferences are the primary analytical output of the platform.
Signals are higher-level alerts derived from inferences. While an agent run might produce dozens of inferences, only the ones that meet certain conditions (defined by signal rules or the agent's own judgment) get escalated to signals. Signals have a lifecycle — active, acknowledged, resolved — matching standard incident management patterns.
Key Concepts
- Inferences — Discrete analytical findings with evidence, confidence, and significance. Produced by agent runs, scoped to a feed.
- Evidence — A jsonb array of source references supporting the inference (document IDs, chunk references, quotes).
- Confidence — A numeric score (0.00 to 1.00) representing how certain the agent is about the finding.
- Significance — Categorical importance:
low,medium,high,critical. - Surface hints — Suggestions for how to visualise the inference (chart type, layout, emphasis).
- Supersession — An inference can be replaced by a newer one via
supersededBy, preserving history while keeping the latest analysis current. - Signal rules — User-defined conditions that automatically generate signals from inferences.
- Signal lifecycle —
active(needs attention) →acknowledged(seen, being worked) →resolved(addressed, with resolution notes).
Data Model
inferences
| Column | Type | Notes |
|---|---|---|
id | uuid (PK) | |
spaceId | uuid (FK → spaces) | Owning space |
agentRunId | uuid (FK → agent_runs) | The run that produced this inference |
feedId | uuid (FK → feeds) | The feed context for this inference |
inferenceType | text | Type/category of the inference |
title | text | Short summary |
description | text | Detailed explanation |
evidence | jsonb | Default []. Source references supporting the finding |
confidence | numeric(3,2) | 0.00–1.00 confidence score |
significance | text | Default "medium". One of: low, medium, high, critical |
category | text | Analytical category |
tags | jsonb | Default []. Free-form tags for filtering |
relatedDocuments | jsonb | Default []. Document references |
surfaceHints | jsonb | Default []. Visualisation suggestions |
status | text | Default "published". One of: published, superseded, archived |
supersededBy | uuid | Points to the newer inference that replaces this one |
createdAt | timestamp | |
updatedAt | timestamp |
signal_rules
| Column | Type | Notes |
|---|---|---|
id | uuid (PK) | |
spaceId | uuid (FK → spaces) | |
userId | uuid | Rule creator |
name | text | Rule name |
description | text | What this rule detects |
feedId | uuid (FK → feeds) | Optional — scope rule to a specific feed |
conditionType | text | Type of condition logic |
condition | jsonb | Condition definition (thresholds, patterns, etc.) |
severity | text | Default "warning". Severity of generated signals |
enabled | boolean | Whether the rule is active |
lastTriggered | timestamp | |
triggerCount | integer | Total times this rule has fired |
createdAt | timestamp | |
updatedAt | timestamp |
signals
| Column | Type | Notes |
|---|---|---|
id | uuid (PK) | |
spaceId | uuid (FK → spaces) | |
sourceType | text | What generated this signal (agent, rule, manual) |
inferenceId | uuid (FK → inferences) | The inference that triggered this signal |
ruleId | uuid (FK → signal_rules) | The rule that triggered this signal |
title | text | Alert title |
description | text | Alert details |
severity | text | Default "warning". One of: info, warning, critical |
category | text | Alert category |
suggestedActions | jsonb | Default []. Recommended next steps |
relatedDocuments | jsonb | Default []. Supporting documents |
status | text | Default "active". One of: active, acknowledged, resolved |
acknowledgedAt | timestamp | When someone acknowledged this signal |
acknowledgedBy | uuid | Who acknowledged it |
resolvedAt | timestamp | When it was resolved |
resolvedBy | uuid | Who resolved it |
resolution | text | How the signal was resolved |
createdAt | timestamp | |
updatedAt | timestamp |
How It Works
- Agent run completes — The research agent analyses documents in its assigned feeds and produces inference records.
- Evidence attached — Each inference includes an
evidencearray pointing back to specific documents and text chunks that support the finding. - Confidence scored — The agent assigns a confidence score based on the strength and consistency of the evidence.
- Surface hints generated — The agent suggests how the inference might be visualised (e.g., "show as trend chart", "highlight as a metric card").
- Signal rules evaluated — The agent signal worker checks all enabled signal rules against new inferences. If a rule's condition matches, a signal is created.
- Signals surfaced — Active signals appear in the user's alert feed. Users can acknowledge signals (marking them as seen) and later resolve them with notes.
- Supersession — When a newer agent run produces an updated inference on the same topic, the old inference's
supersededByis set and its status changes to"superseded".
Why It Works This Way
Separating Inferences from Signals
Not every analytical finding warrants an alert. An agent might produce 30 inferences in a run, but only 2 might be significant enough to interrupt a user. The two-tier model lets agents be thorough (producing detailed inferences) while keeping the signal-to-noise ratio manageable for users.
Surface Hints as a Contract
The surfaceHints field creates a loose contract between the analytical layer and the visualisation layer. Agents suggest how their findings should be displayed — "this is a comparison", "this is a trend over time" — without being responsible for rendering. The surface generation service reads these hints and produces the appropriate visualisation. This decoupling means agents can be improved independently of the UI.
Signal Lifecycle Matches Incident Management
The active/acknowledged/resolved lifecycle is borrowed from incident management (PagerDuty, Opsgenie). It provides a clear audit trail: when was the signal raised, who saw it, when was it resolved, and how. This is particularly important for compliance-oriented agents where you need to demonstrate that findings were acted upon.
Supersession Over Deletion
When analysis is updated, old inferences are not deleted — they are marked as superseded. This preserves the analytical history and allows users to see how understanding evolved over time. It also prevents broken references from signals or experiences that pointed to the original inference.
Code Reference
| File | Description |
|---|---|
packages/db/src/schema/signals.ts | inferences, signal_rules, and signals table definitions |
apps/data-plane/src/services/signal.ts | Signal processing and rule evaluation |
apps/data-plane/src/workers/agent-signal.ts | Worker that evaluates signal rules after agent runs |
Relationships
- Spaces — All inferences and signals are scoped to a space
- Agents — Agent runs produce inferences;
agentRunIdlinks back to the run - Feeds — Inferences are scoped to the feed that was analysed
- Surfaces & Experiences — Inferences can be rendered as surfaces via
surfaceHints