Skip to main content

The investigation story, end to end

The clearest way to understand Atlas is to follow a single investigation from the moment an analyst starts it to the moment they read the report. Every subsystem in the platform plays a part in this story.

Step by step

  1. Start. The analyst starts an investigation from the Console. The API (investigation_router.py) creates a record and launches a durable Temporal workflow. The request returns immediately — the work happens asynchronously.

  2. Gather. The workflow runs the seven OSINT modules in parallel. Each module is an LLM-driven crew that uses MCP tools (web search, scraping, maps) in an agentic loop and returns structured findings. Sync providers such as KVK and NorthData contribute registry and financial data through the same pipeline.

  3. Resolve. Findings from every source are matched against existing entities, reconciled, and merged. Conflicting attributes become competing claims; survivorship rules pick the winner and record a mutation. See Entity resolution and Claims & survivorship.

  4. Persist & sync. Canonical entities, relationships, claims, and mutations are written to PostgreSQL, then synced to the Neo4j property graph for relationship queries (ownership chains, shared addresses, common connections).

  5. Score. Per-module risk rules generate risk indicators, and any assigned risk matrix is evaluated to produce a portfolio-level risk level.

  6. Report. A report is rendered from the canonical graph using Jinja2 templates, PII is sanitised, a PDF is generated and stored in MinIO, and the investigation is marked complete. See Reporting.

  7. Review. The analyst reads the report in the Console — risk gauge, findings, evidence bundle, ontology graph, and data lineage — and resolves any conflicts flagged for human review via the mutation queue.

Every one of these steps is tenant-scoped: the workflow inherits the tenant from the request and all database access is filtered by Row-Level Security.