Alan Turing Institute · Data Study Group

The CHIRPdb dataset

A structured database of maritime incident reports from two investigating bodies - the UK Marine Accident Investigation Branch (MAIB) and the US National Transportation Safety Board (NTSB) - hosted for you as a standard PostgreSQL database. This page orients you: what you have, how it was built, how the tables fit together, and - most importantly - how far to trust each field. The data dictionary is the per-column reference.

What you have

Read access to a running PostgreSQL database, the source report PDFs, and the paperwork to make sense of both. No access to CHIRP's application, pipeline or APIs; everything you need is in the four pieces below.

The database

A standard PostgreSQL instance your IT service hosts. Connect with any Postgres client and query it read-only.

This data dictionary

Every table and column defined, with the provenance and trust of each field. The companion page.

The schema diagram

The entity-relationship diagram - every table and every link between them, below.

The source PDFs

Every MAIB and NTSB report the database was built from, supplied as zip archives through your IT service. Match a document row to its file with documents.filename.

Working with the database

It is ordinary PostgreSQL - two things worth knowing before you query:

What the dataset is

Each published report (a PDF, from MAIB or NTSB) is broken into sentence-level text plus the report's own stated incident particulars. MAIB reports are additionally linked to structured incident data - occurrences, vessels, affected persons - drawn from the MAIB Data Portal spreadsheets; NTSB has no equivalent spreadsheet source, so that layer is MAIB-only. An analysis pipeline then extracts findings from the text: safety issues, recommendations, named entities, and causal-factor classifications from CHIRP's SHIELD taxonomy. Every extracted finding is traceable back to the exact sentences of the source report.

documents.jurisdiction separates the two corpora: 'UK' for the 796 MAIB reports, 'US' for the 456 NTSB reports - 1,252 documents in all.

What is actually populated

The schema documents the full system, but the database as delivered populates only part of it. Know which layers carry data before you build on them.

Populated
  • Reports & text - documents, authors, sentences, and the report-derived document_particulars / document_vessels. Both corpora, split by documents.jurisdiction.
  • Spreadsheet incident data (MAIB only) - occurrences, vessels, affected_persons, affected_persons_ppe, the report↔occurrence link on documents.occurrence_id, and the vocabularies taxonomy_terms / ppe_items. No NTSB document carries an occurrence_id.
  • Seeded vocabularies - shield_codes / shield_code_categories (full SHIELD taxonomy) and narrative_entity_types. Loaded but not yet referenced.
Empty
  • chunks, chunk_sentences, analysis - no chunking pass.
  • chunk_shield_codes - taxonomy loaded, no code applied to any passage yet.
  • safety_issues, recommendations and their junctions - no findings extraction.
  • narrative_entities, narrative_entity_mentions - no NER/coreference pass.
  • organisations, legislation, the identifier tables - nothing populates them at this stage.

How the data was produced

The data flows through pipeline stages, and the tables mirror them. Provenance is preserved as a chain of links, not copied data: any finding traces to its passage, the passage to its sentences, each sentence to its document and position.

Stage 1
Ingest

A report PDF - MAIB or NTSB - is registered as a documents row and each page is rasterised to an image; the report's own stated facts go to document_particulars and document_vessels, and documents.jurisdiction records which corpus it belongs to.

Stage 2
Extraction

A vision LLM reads each page image and returns its text and structure directly; deterministic passes then run on top (normalise metadata, rejoin broken lines, repair lossy pages), stored as ordered sentences. Lifecycle: queued → extracting → extracted → verified.

Stage 3
Spreadsheet enrichment

MAIB Data Portal data is loaded independently: occurrences → vessels → affected_persons, classified via taxonomy_terms, linked to MAIB reports through documents.occurrence_id. (MAIB only - NTSB publishes no comparable dataset.)

Stage 4
Analysis

Sentences are grouped into chunks and findings extracted against them: SHIELD taggings, safety issues, recommendations, entities. (Not populated in this database.)

How the tables fit together

Two incident-data sources are kept apart and linked, not merged: the report PDF's own account lives in document_particulars / document_vessels (both corpora); the MAIB Data Portal spreadsheet's account in occurrences / vessels / affected_persons (MAIB only); the two join through a nullable documents.occurrence_id FK - several reports can point at one occurrence (e.g. an interim then a final). Tree-shaped classifications (event type, ship type, place on board, injury, deviation) are normalised into taxonomy_terms. The full entity-relationship diagram:

100% Scroll to pan, or hold Ctrl/Cmd and scroll to zoom.
CHIRPdb entity-relationship diagram showing all tables and their relationships

The data dictionary is authoritative for table and column definitions; the diagram is the map, the dictionary the legend.

Where each value comes from - and how far to trust it

This is the point of the dictionary. The database shows you structure; it cannot tell you which values are source fact, which a model produced, and which a human has since confirmed. Every column is labelled with one of the five below - the first two both mean "the source said so", and differ only in which source: a report PDF, or the MAIB spreadsheet.

Source Source-document field - from the report PDF, MAIB or NTSB (content or file metadata).
MAIB MAIB Data Portal field - from the MAIB spreadsheet extract, on the tables it feeds (occurrences, vessels, affected_persons and their vocabularies). UK incidents only.
Pipeline Pipeline-derived, deterministic - computed on ingest, no model involved.
AI-U AI-generated, unverified - produced by an LLM or NLP model, not confirmed by a human.
AI-V AI-generated, human-verified - model output an analyst has confirmed.
System System metadata - surrogate keys, timestamps, status flags, generated search columns, seeded reference data.

A slashed label - Pipeline / AI-U - marks a column whose extractor is deterministic with a model fallback.

Two rules run throughout. Row-level verification: tables with an is_verified flag hold AI-generated content whose status varies per row - treat is_verified = true as AI-V, everything else AI-U. Sentence text is extracted by a vision LLM reading each page image, with deterministic passes on top, so it is AI-U, qualified by the parent documents.status (verified = analyst-confirmed).

Practical upshot: the analysis layer is empty here, so nearly all content is Source, MAIB or Pipeline. Where you do see AI-U - the sentence text - remember it is a vision model's reading of the page image, not a byte-exact copy of the PDF.

Known limitations

Read these before drawing conclusions from the data.

What is not included

Row counts

As of 17 August 2026. Populated tables carry data; the analysis and findings layer is empty in the database (see above). Seeded vocabularies are loaded reference data.

TableRows
documents1,252 (796 MAIB, 456 NTSB)
document_particulars1,252
document_vessels1,252
authors22
occurrences9,063 (MAIB only)
vessels9,830 (MAIB only)
affected_persons3,040 (MAIB only)
affected_persons_ppe924 (MAIB only)
taxonomy_terms410
ppe_items9
sentences341,057 (293,454 MAIB, 47,603 NTSB)
chunks · analysis · findings · entities0 (empty)
shield_codes96 (seeded)
shield_code_categories20 (seeded)
narrative_entity_types5 (seeded)
Full data dictionary →
Every table and column, with per-field provenance and constraints. The reference to keep open while you query.