Alan Turing Institute · Data Study Group

CHIRPdb Data Dictionary

Every table and column in the CHIRPdb database - with, for each field, whether it came from a source report (MAIB or NTSB), from the MAIB Data Portal spreadsheet, was derived by the pipeline, or was generated by AI, and whether a human has verified it. A reference to dip into, not read cover to cover. See the dataset overview for orientation and the schema diagram.

Data dictionary for the CHIRPdb database prepared for the Alan Turing Institute Data Study Group. See the dataset overview for context, provenance and limitations. Content conventions follow DAMA-DMBOK.

What the database contains

This dictionary documents the full CHIRPdb schema. The database as delivered is populated end to end: every pipeline stage has run over the whole corpus. Expect data in:

Five tables are empty as delivered:

Some columns of otherwise-populated tables are empty too, and they are flagged where they appear. The ones most likely to be reached for: sentences.relevance_score; every contact field on organisations and authors; safety_issues.name and recommendations.action (the analyst-authored summaries - the report's own wording is in the passage, not here); and every is_verified / verified_at pair.

How to read this document

Every column is classified in the Source column as one of:

LabelMeaning
SourceSource-document field - value taken from the source report, MAIB or NTSB (PDF content or file metadata)
MAIBMAIB Data Portal field - value taken from the MAIB spreadsheet extract. Used only on the spreadsheet-fed tables, which hold UK incidents alone
PipelinePipeline-derived (deterministic) - computed by the ingestion pipeline with no model involvement
AI-UAI-generated (unverified) - produced by an LLM or NLP model, not confirmed by a human
AI-VAI-generated (human-verified) - AI-produced and confirmed by an analyst
SystemSystem metadata - surrogate keys, timestamps, status flags, generated search columns, seeded reference data
AnalystAuthored by a person in the review surface - never produced by the pipeline or a model, and empty until someone fills it in

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

Four conventions apply throughout:

  1. Row-level verification. Tables carrying an is_verified flag (passage_shield_codes, safety_issues, recommendations) hold AI-generated content whose verification status varies per row. Their content columns are marked AI-U (or Pipeline / AI-U where a deterministic extractor populates them today); treat rows where is_verified = true as AI-V. Sentences are the analogous case at document level: documents.status = 'verified' marks a document whose extracted text an analyst has confirmed.

    In this delivery, nothing has been verified. No row anywhere carries is_verified = true, no document is at status = 'verified', and the Analyst columns (safety_issues.name, recommendations.action) are empty. The AI-V and Analyst labels below therefore describe what a column would hold after review, not what it holds now - read every AI-U column as machine output no human has checked.

  2. Sentence text. Text is extracted by a vision LLM reading a rendered image of each page, with deterministic passes (structural-metadata normalisation, line rejoin, content-loss repair) applied on top of the model output. Sentence text and structure columns are therefore marked AI-U, qualified by the parent document's status.
  3. Two record sets, linked - not merged. Incident data comes from two sources kept in separate tables rather than reconciled into one row:
    • the MAIB Data Portal spreadsheet → occurrences and its children vessels / affected_persons, plus the vocabularies taxonomy_terms / ppe_items. Spreadsheet-only facts, UK-only; source_id / source_modified_at carry MAIB's per-record identifier and revision date, driving upsert on each refresh so only MAIB-revised rows are touched. Columns on these tables carry the MAIB label.
    • the report PDF, MAIB or NTSB → document_particulars (incident facts stated in the report) and document_vessels (vessels named in the report), each hanging off documents. Columns fed this way carry the Source label, which says nothing about which body published the report - read documents.jurisdiction for that.

    A MAIB report links to its occurrence through documents.occurrence_id, with documents.occurrence_matched_on recording how the link was made (publication_number or manual); several reports can point at the same occurrence (e.g. an interim report followed by the final one). NTSB documents have no occurrence to link to, so only the report-PDF set applies to them.

  4. Jurisdiction split. documents.jurisdiction is the column that separates the corpora - 'UK' for MAIB, 'US' for NTSB - and everything owned by a document (sentences, document_particulars, document_vessels, passages, safety_issues, recommendations, narrative_entities) inherits that split through its document_id. Field coverage differs between the two: see the per-column notes on documents, document_particulars and document_vessels, and the fill-rate figures in the README.

All tables carry created_at and updated_at (timestamptz, defaulting to now(), with updated_at maintained by a BEFORE UPDATE trigger). These are listed once per table without repeating the explanation.


1. Reports and incident record

documents

One row per ingested report PDF - MAIB or NTSB. The root of the ownership chain: deleting a document cascades to everything extracted from it. 1,252 rows: 796 with jurisdiction = 'UK' (MAIB), 456 with 'US' (NTSB).

Keys: PK id. UNIQUE hash. FK author_id → authors(id) ON DELETE SET NULL. FK occurrence_id → occurrences(id) ON DELETE SET NULL. CHECK documents_lease_requires_start (claim_expires_at set implies claim_started_at set); CHECK documents_occurrence_link_has_provenance (occurrence_id set implies occurrence_matched_on set); CHECK occurrence_matched_on is null or in ('publication_number', 'manual'); CHECK documents_jurisdiction_check (jurisdiction is null or in ('UK', 'US')).

ColumnTypeNullableDescriptionValid values / constraintsSource
iduuidnoSurrogate keydefault gen_random_uuid()System
author_iduuidyesInvestigating body that published the report (MAIB or NTSB)FK to authors; survives author deletion (SET NULL)Pipeline
titletextnoReport title-Source
urltextyesURL the report was retrieved from-Pipeline
filenametextyesFilename of the source PDF-Pipeline
hashtextnoHash of the source file; dedupes re-ingestionuniquePipeline
publication_numbertextyesPublisher's report reference: MAIB Publication_No for UK rows, NTSB report number for US rows. For MAIB it is also the key a report is matched to a spreadsheet occurrence onnull on 128 rows - 125 MAIB, 3 NTSB. NTSB values are prefixed MAB- (265), MIR- (167) or MAR- (21)Source
document_typetextyesGOV.UK publication class (Publication_Type), e.g. investigation-report, safety-bulletinMAIB rows only - set on 794 of 796, null for every NTSB documentSource
occurrence_iduuidyesThe spreadsheet occurrence this report describes; resolved from publication_number. Several reports (e.g. interim + final) may point at one occurrenceFK to occurrences, SET NULL; MAIB rows only (58 populated), always null for NTSB - see the note belowPipeline
occurrence_matched_ontextyesHow the occurrence link was madepublication_number (auto) or manual; required when occurrence_id is setPipeline
publication_datedateyesDate the report was published-Source
statusdocument_statusnoExtraction-pipeline stateenum: queued, extracting, extracted, verified, extraction_failed; default queuedSystem
extraction_fallbackbooleannoTrue if extraction fell back to a degraded result after retries were exhausteddefault falseSystem
records_pass_attimestamptzyesWhen the record pass last ran over this document; null means it never has, which is how a resumed pass finds its remaining work-System
records_rerunnablebooleannoTrue where the record pass left something worth another attempt - the only state a pass carries forward, so a resumed run re-picks the documentdefault falseSystem
records_fallbackbooleannoTrue where the record pass reached its result through an LLM route rather than the deterministic one alonedefault falseSystem
jurisdictiontextyesReporting jurisdiction; the column that separates the two corporadefault 'UK'; 'UK' = MAIB (796), 'US' = NTSB (456)Pipeline
page_countintegeryesPage count of the source PDF-Pipeline
pdf_subjecttextyesSubject field from PDF file metadata-Source
pdf_authortextyesAuthor field from PDF file metadata-Source
claim_tokenuuidyesLease token held by the worker currently extracting this document; guards against double-processing-System
claim_started_attimestamptzyesWhen the current extraction lease was taken-System
claim_expires_attimestamptzyesWhen the lease expires and the document may be re-queuedrequires claim_started_at (check-constrained)System
title_tsvtsvector-Full-text search index over titlegenerated column (always derived)System
created_at / updated_attimestamptzyesAudit timestamps-System

Document status lifecycle: queued → extracting → extracted → verified, with extracting → extraction_failed on an irrecoverable crash. extracted means the automated pipeline finished; verified means an analyst confirmed the results. The claim_* columns are the extraction lease used to recover documents stranded by a crashed worker. As delivered, all 1,252 documents are at extracted, and 201 carry extraction_fallback = true (182 MAIB, 19 NTSB).

The records_* columns track the separate record pass. As delivered every document has records_pass_at set - the pass has run over the whole corpus - and 981 carry records_fallback = true, meaning the deterministic extractor alone did not settle the result and an LLM route was used. That flag says how the records were reached, not whether they are wrong.

The report corpus and the spreadsheet barely overlap, and that is the database's sharpest limit. occurrence_id links only 58 reports to an occurrence. The cause is on the spreadsheet side: it only goes as far back as 2018. Since then, MAIB have investigated only 61 occurrences that get a publication_number, and 58 of which produced a report. So 738 of the 796 MAIB reports have no occurrence counterpart, and 9,005 occurrences have no adjoining report.

document_particulars

Incident facts as stated in the report PDF - the report-path counterpart to the spreadsheet's occurrences. One row per document (1:1), so 1,252 rows across both corpora. Columns are populated only where the report states the fact, and NTSB reports state fewer of them: of 456 NTSB rows, accident_date is set on 198, accident_location 208, accident_type 130, severity 71, loss_of_life 33 (MAIB, of 796: 796 / 731 / 279 / 305 / 183).

Keys: PK document_id. FK document_id → documents(id) ON DELETE CASCADE. CHECK loss_of_life is null or ≥ 0.

ColumnTypeNullableDescriptionValid values / constraintsSource
document_iduuidnoThe report these particulars are drawn fromPK, FK, cascade deletePipeline
accident_datedateyesDate of the incident as stated in the report-Source
accident_locationtextyesNamed place of the incidentfree text from reportSource
severitytextyesSeverity as stated in the reportfree text from reportSource
accident_typetextyesType of accidentfree text; ⚠ unreliable - often holds the voyage or vessel-operation type instead (see note)Source
loss_of_lifeintegeryesNumber of deathsnull or ≥ 0 (check-constrained)Source
created_at / updated_attimestamptzyesAudit timestamps-System

accident_type does not reliably hold the accident type. The extraction pass frequently picks up the report's statement of the voyage or vessel-operation type (what the vessel was doing) rather than what happened to it, so the column mixes the two. Do not treat it as an accident classification without reading the values first; for MAIB documents, the spreadsheet's occurrences.main_event_term_id (the main_event taxonomy) is the classification to use instead.

document_vessels

Vessels named in the report PDF - the report-path counterpart to the spreadsheet's vessels. The schema allows a document many vessel rows, but as delivered there are 1,252 rows and exactly one per document: an incident involving several vessels is not represented as several rows here. Coverage differs by corpus:

ColumnMAIB (of 796)NTSB (of 456)
vessel_name299400
vessel_type796395
port_of_origin2860
destination2620

Keys: PK id. FK document_id → documents(id) ON DELETE CASCADE.

ColumnTypeNullableDescriptionValid values / constraintsSource
iduuidnoSurrogate keydefault gen_random_uuid()System
document_iduuidnoOwning reportFK, cascade deletePipeline
vessel_nametextyesVessel name as stated in the report-Source
vessel_typetextyesVessel type as stated in the reportfree text from reportSource
port_of_origintextyesPort of origin-Source
destinationtextyesDestination-Source
created_at / updated_attimestamptzyesAudit timestamps-System

authors

Investigating bodies that publish reports (MAIB, NTSB). Shared reference data, not owned by any document. 22 rows as delivered, and they are not yet canonicalised: the same body appears under several name variants taken from PDF metadata (e.g. MAIB, Marine Accident Investigation Branch, www.maib.gov.uk; NTSB, National Transportation Safety Board, and the typo NSTB), alongside rows that are individual people named as the PDF's author. Group by the body yourself - or filter on documents.jurisdiction - rather than trusting authors.name as a key.

Keys: PK id.

ColumnTypeNullableDescriptionValid values / constraintsSource
iduuidnoSurrogate keydefault gen_random_uuid()System
nametextnoName of the publishing body-Source
emailtextyesContact email for the publishing bodyscraped, then manually curated/checked (final version); not populated herePipeline
phone_numbertextyesContact phonescraped, then manually curated/checked (final version); not populated herePipeline
addresstextyesPostal addressscraped, then manually curated/checked (final version); not populated herePipeline
website_urltextyesWebsitescraped, then manually curated/checked (final version); not populated herePipeline
created_at / updated_attimestamptzyesAudit timestamps-System

author_identifiers

Curated identifiers that canonicalise an author, one row per identifier - so name variants (e.g. "MAIB" vs "Maritime Accident Investigation Branch") resolve to a single author rather than many near-duplicates.

Keys: PK id. FK author_id → authors(id) ON DELETE CASCADE.

ColumnTypeNullableDescriptionValid values / constraintsSource
iduuidnoSurrogate keydefault gen_random_uuid()System
author_iduuidnoOwning authorFK, cascade deletePipeline
identifiertextnoCurated identifier used to resolve name variants to one canonical author (e.g. "MAIB" and "Maritime Accident Investigation Branch" → the same body)curated; empty as deliveredSystem
created_at / updated_attimestamptzyesAudit timestamps-System

occurrences

One incident as recorded in the MAIB Data Portal spreadsheet - what happened, when, where, how severe. Purely spreadsheet-sourced; it holds no report-PDF fields, and it is UK-only: NTSB has no counterpart feed, so this table and its children describe MAIB incidents alone. The report(s) describing an occurrence point to it via documents.occurrence_id, and the report's own view of the incident lives in document_particulars.

9,063 rows. Well filled: short_description, description and severity are set on every row, latitude / longitude on 9,062, main_event_term_id on 9,061. Only 61 rows carry a publication_number, which is why so few reports link (see documents).

Keys: PK id. UNIQUE source_id. FK main_event_term_id → taxonomy_terms(id) ON DELETE SET NULL.

ColumnTypeNullableDescriptionValid values / constraintsSource
iduuidnoSurrogate keydefault gen_random_uuid()System
source_idtextnoMAIB's stable per-incident identifier (Occurrence_Id); upsert key for spreadsheet refreshnot null, uniqueMAIB
source_modified_atdateyesMAIB's per-record revision date (Occurrence_Record_Modified_On); drives selective refresh-MAIB
publication_numbertextyesMAIB report reference (Publication_No); the value a report's documents.publication_number is matched against to set documents.occurrence_id-MAIB
accident_datedateyesMonth of the incident (Local_Date_Main_Event). ⚠ Month precision: the day is always 01 and carries no information - aggregate by month or year, never by day or weekday-MAIB
date_unconfirmedbooleanyesWhether MAIB's date is unconfirmed (Date_Main_Event_Unconfirmed)true on 127 rowsMAIB
severitytextyesIncident severity (Occurrence_Severity)clean 4-value vocab, no nulls: Marine Incident (5,000), Less Serious (3,294), Serious (457), Very Serious (312)MAIB
main_event_term_iduuidyesPrincipal event, as a taxonomy term (Main_Event_L1/L2)FK to taxonomy_terms (main_event)MAIB
short_descriptiontextyesBrief description of the incident-MAIB
descriptiontextyesFuller description of the incident-MAIB
latitudetextyesLatitude, captured verbatim (deliberately text, not a geo type)not validated as coordinatesMAIB
longitudetextyesLongitude, captured verbatim (see above)not validated as coordinatesMAIB
year_reportedintegeryesYear the incident was reported-MAIB
location_zonetextyesSea-area zone (Occurrence_Location)12 values in Family -> Detail form; split on -> for the family: Coastal waters <= 12 nm (4,044), Internal waters (3,692, mostly -> Port area), Open sea (784, -> Within EEZ / -> Outside EEZ), Inland waters (542)MAIB
accident_porttextyesNearest port to the incident (Port_Of_Accident_L2)-MAIB
state_reportingtextyesReporting jurisdiction (State_Reporting)UK / Non-UKMAIB
natural_lighttextyesNatural light at the incident (Natural_Light)-MAIB
sea_statetextyesSea state (Sea_State)-MAIB
visibilitytextyesVisibility (Visibility)-MAIB
weathertextyesWeather (Weather)-MAIB
wind_forcetextyesWind force (Wind_Force)-MAIB
sar_interventiontextyesWhether search-and-rescue was involved (SAR_Intervention)-MAIB
created_at / updated_attimestamptzyesAudit timestamps-System

main_event_term_id references the shared taxonomy_terms tree (see §4). Report-PDF incident facts (accident type, named location, loss of life) are not held here - they live in document_particulars, reached via documents.occurrence_id. A report is linked to its occurrence by documents.occurrence_id (the FK sits on documents, so several reports can share one occurrence).

vessels

Vessels involved in a spreadsheet occurrence - the particulars from the MAIB Data Portal, and so UK-only. An occurrence involves one or more vessels. Vessels as named in the report PDF are separate: see document_vessels.

9,830 rows over 9,063 occurrences, every one attached to an occurrence. ship_type_term_id and vessel_category_term_id are set on every row; place_on_board_term_id on 7,995. No vessel name is held here - the MAIB extract does not publish one.

Keys: PK id. UNIQUE source_id. FK occurrence_id → occurrences(id) ON DELETE CASCADE. FKs vessel_category_term_id, ship_type_term_id, place_on_board_term_id → taxonomy_terms(id) ON DELETE SET NULL.

ColumnTypeNullableDescriptionValid values / constraintsSource
iduuidnoSurrogate keydefault gen_random_uuid()System
occurrence_iduuidyesOwning occurrenceFK, cascade deletePipeline
source_idtextnoMAIB's per-vessel identifier (Vessel_Profile_Id); upsert keynot null, uniqueMAIB
source_modified_atdateyesMAIB's per-record revision date (Vessel_Record_Modified_On)-MAIB
flag_statetextyesFlag state (Flag_State)-MAIB
vessel_category_term_iduuidyesSize band as a taxonomy term (Vessel_Category_L1/L2)FK to taxonomy_terms (vessel_category)MAIB
ship_type_term_iduuidyesWhat the vessel is, as a taxonomy term (Ship_Craft_Type_L1-L4)FK to taxonomy_terms (ship_type)MAIB
is_commercial_vesselbooleanyesCommercial vs leisure (Is_Commercial_Vessel)-MAIB
hull_materialtextyesHull material (Hull_Material)-MAIB
gross_tonnagenumericyesGross tonnage (GT_Gross_Tonnage)-MAIB
length_metresnumericyesOverall length in metres (LOA_Length_Overall_in_Metres, fallback Registered_Length_In_Metres)-MAIB
year_builtintegeryesYear built-MAIB
port_of_origintextyesDeparture port (Port_Of_Departure_L2)-MAIB
voyage_segmenttextyesPhase of voyage (Voyage_Segment)e.g. Mid-water, Arrival, AnchoredMAIB
pilot_on_boardtextyesPilotage state (Pilot_On_Board)-MAIB
crew_countintegeryesCrew on the voyage (Crew_Voyage)-MAIB
place_on_board_term_iduuidyesWhere on the vessel the event occurred, as a taxonomy term (Place_On_Board_L1-L3)FK to taxonomy_terms (vessel_place_on_board)MAIB
did_vessel_sinkbooleanyesWhether the vessel sank (Did_The_Vessel_Sink)-MAIB
vessel_abandonedbooleanyesWhether the vessel was abandoned (Vessel_Abandoned)-MAIB
damage_severitytextyesDamage-severity grade (Loss_Of_Vessel_Damage), verbatim from the spreadsheet10 values in the same Family -> Detail form as occurrences.location_zone: No damage (7,669), Minor damage (less than material damage) (1,440), Material damage (504 across four spellings), Loss of ship (206). ⚠ Not case-folded: 11 rows read No DamageMAIB
damage_descriptiontextyesFree-text damage detail (Damage_Description); distinct from the grade-MAIB
pollution_resulttextyesPollution outcome (Pollution_Result)-MAIB
created_at / updated_attimestamptzyesAudit timestamps-System

Death and injury counts are not stored on vessels; count them from affected_persons by person_type and physical-condition outcome so there is one source of truth. Vessel classification lives entirely in taxonomy_terms references (vessel_category_term_id, ship_type_term_id); the report's own vessel names/types sit apart in document_vessels.

affected_persons

People affected aboard a vessel of a spreadsheet occurrence, so UK-only like its parents. A vessel carries zero or more affected persons. No names are stored - demographic and injury attributes only.

3,040 rows, every one attached to a vessel - so the great majority of the 9,830 vessels record no affected person. physical_condition_term_id is set on every row, deviation_term_id on 3,035, injury_type_term_id on 3,013, place_on_board_term_id on 2,854. person_type is Crew (2,132), Passenger (767) or Other (141); gender is Male (2,006), Female (743), Unknown (283) or Not available - PCF (8).

Keys: PK id. UNIQUE source_id. FK vessel_id → vessels(id) ON DELETE CASCADE. FKs physical_condition_term_id, injury_type_term_id, deviation_term_id, place_on_board_term_id → taxonomy_terms(id).

ColumnTypeNullableDescriptionValid values / constraintsSource
iduuidnoSurrogate keydefault gen_random_uuid()System
vessel_iduuidyesVessel the person was aboardFK, cascade deletePipeline
source_idtextyesMAIB's per-person identifier (Affected_Person_Id); upsert keyuniqueMAIB
source_modified_atdateyesMAIB's per-record revision date (Affected_Person_Record_Modified_On)-MAIB
sequence_nointegeryesPerson's order within the incident (Sequence_No)-MAIB
ageintegeryesAge-MAIB
gendertextyesGender as statedfree textMAIB
person_typetextyesRole category (Affected_Person_Type, e.g. crew, passenger)free textMAIB
ranktextyesRank or position aboardfree textMAIB
on_dutybooleanyesWhether on duty at the time-MAIB
nationalitytextyesNationalityfree textMAIB
physical_condition_term_iduuidyesOutcome / severity / incapacitation as a taxonomy term (Physical_Condition_L1-L3)FK to taxonomy_terms (physical_condition)MAIB
injury_type_term_iduuidyesInjury and subtype as a taxonomy term (Injury_Type_L1/L2)FK to taxonomy_terms (injury_type)MAIB
parts_of_body_injuredtextyesBody parts injured (Parts_of_Body_Injured)free textMAIB
deviation_term_iduuidyesAccident mechanism as a taxonomy term (Affected_Person_Deviation_L1/L2, e.g. slip/fall, body movement)FK to taxonomy_terms (deviation)MAIB
place_on_board_term_iduuidyesWhere the person was, as a taxonomy term (Affected_Person_Place_On_Board_L1-L5)FK to taxonomy_terms (person_place_on_board)MAIB
created_at / updated_attimestamptzyesAudit timestamps-System

Injury type is a taxonomy_terms reference (injury_type_term_id). PPE worn and lacking is recorded per person in affected_persons_ppe (below), one row per item.

affected_persons_ppe

Junction: which PPE items a person wore or lacked. One row per person per item, split out of the spreadsheet's comma-joined PPE_Used / PPE_Deficient values so items can be counted and filtered.

924 rows - 575 used, 349 deficient - covering a small minority of the 3,040 affected persons. Absence of a row is not evidence the item was absent: the spreadsheet records PPE only where MAIB captured it.

Keys: Composite PK (affected_person_id, ppe_item_id, status). FKs affected_person_id → affected_persons(id), ppe_item_id → ppe_items(id).

ColumnTypeNullableDescriptionValid values / constraintsSource
affected_person_iduuidnoThe personPK part, FKPipeline
ppe_item_iduuidnoThe PPE itemPK part, FKPipeline
statustextnoWhether the item was worn or missingused (from PPE_Used) / deficient (from PPE_Deficient)MAIB
deficiency_reasontextyesWhy the item was deficient, where recorded-MAIB
created_at / updated_attimestamptzyesAudit timestamps-System

2. Parsed text

sentences

Every sentence of every report, in original reading order - 341,057 rows, 293,454 from MAIB documents and 47,603 from NTSB ones. The atomic unit of text; everything in the analysis layer traces back here. Sentences carry no jurisdiction of their own: join through document_id to split the corpora. Text is produced by a vision LLM reading a rendered image of each page, with deterministic passes applied on top - the stored text reflects that output, with the parent document's status indicating how much to trust it.

There is no sections table: a row with text_type = 'heading' is a section boundary, and a section's contents are the sentences whose sort_order falls between that heading and the next.

By text_type: 155,117 paragraph, 77,222 list_item, 47,648 heading, 32,532 frontmatter, 17,455 caption, 7,907 footnote, 3,176 table. frontmatter is cover pages, contents lists and boilerplate - exclude it from most analyses.

Keys: PK id. FK document_id → documents(id) ON DELETE CASCADE. CHECK heading_level BETWEEN 1 AND 6. CHECK page_number is null or ≥ 1.

ColumnTypeNullableDescriptionValid values / constraintsSource
iduuidnoSurrogate keydefault gen_random_uuid()System
document_iduuidyesOwning reportFK, cascade deletePipeline
texttextnoSentence text-AI-U (vision-LLM extracted from the page image, deterministic passes on top; see documents.status)
text_typesentence_text_typenoKind of textenum: heading, paragraph, list_item, footnote, caption, table, frontmatterAI-U
sort_orderintegeryesPosition in original reading order (0-based)-Pipeline
relevance_scoreintegeryesAI-assigned score of a sentence's analytical relevance (e.g. ~0 for frontmatter, ~1 for a safety-issue / SHIELD-relevant sentence)⚠ empty - null on all 341,057 rows. The scoring pass was never runAI-U
heading_levelsmallintyesHeading depth; set only on headings1–6, check-constrained; null on 236 of the 47,648 headingsAI-U
page_numberintegeryesSource PDF page the sentence was extracted fromnull or ≥ 1 (check-constrained); populated on every rowPipeline
block_idtextyesIdentifier of the table a row came from - the only way to reassemble a table from its rowsset on table rows only: all 3,176 text_type = 'table' rows, and 3 othersPipeline
text_tsvtsvector-Full-text search index over textgenerated columnSystem
created_at / updated_attimestamptzyesAudit timestamps-System

passages

A grouped passage of consecutive sentences - the unit the analysis pipeline works on. Membership lives in passage_sentences, so the grouping strategy can change without touching sentence rows; the passage also carries its own document_id rather than relying on the transitive path through its sentences, which does not survive a re-extraction.

15,381 rows as delivered - 13,892 from MAIB documents, 1,489 from NTSB ones - all written by the record pass, every one carrying a document_id and non-null source_text. That count is exactly the number of findings (11,254 safety issues + 4,127 recommendations), one passage each.

Keys: PK id. FK document_id → documents(id) ON DELETE CASCADE. CHECK passages_source_valid (source in ('record_pass', 'manual')). A trigger (trg_validate_passage_document) rejects a document_id that contradicts the document derived from the passage's sentences; it validates rather than derives, so a passage with no sentences yet may name its document freely.

ColumnTypeNullableDescriptionValid values / constraintsSource
iduuidnoSurrogate keydefault gen_random_uuid()System
document_iduuidyesReport the passage belongs to, recorded directly rather than derived through passage_sentencesFK, cascade delete; nullable, but set on every delivered rowPipeline
sourcetextnoWhich writer created the passagerecord_pass or manual, CHECK-constrained; every delivered row is record_passSystem
source_texttextyesText of the passageTrigger-derived from member sentences; direct writes rejectedPipeline (derived from member sentences)
source_text_tsvtsvector-Full-text search index over source_textgenerated columnSystem
source_text_sha256byteayesHash of source_text, so an embedding can say which wording it was computed from and go stale when the passage is rewrittentrigger-derived alongside source_textSystem
created_at / updated_attimestamptzyesAudit timestamps-System

document_id is nullable only because two cases genuinely have no answer - a passage orphaned by a re-ingestion, and a passage whose sentences span more than one document - and neither occurs in the delivered data. Deleting a document deletes its passages, matching sentences, safety_issues and recommendations.

passage_sentences

Junction: which sentences belong to which passage, and in what order. 15,939 rows across the 15,381 passages - 14,382 from MAIB documents and 1,557 from NTSB ones. Record passages are short, most of them a single sentence.

Keys: Composite PK (passage_id, sentence_id). FKs passage_id → passages(id), sentence_id → sentences(id), both ON DELETE CASCADE.

ColumnTypeNullableDescriptionValid values / constraintsSource
passage_iduuidnoPassagePK part, FK, cascade deletePipeline
sentence_iduuidnoMember sentencePK part, FK, cascade deletePipeline
sort_orderintegeryesSentence position within the passageauto-assigned by trigger when nullPipeline
created_at / updated_attimestamptzyesAudit timestamps-System

narrative_entities

Canonical named things - people, vessels, organisations, locations, equipment and nine more types - extracted from a document's text, one row per distinct thing per document, with a normalised canonical name. Coreference resolution is persisted here: many surface forms, one entity.

545,649 rows as delivered: 446,735 from MAIB documents and 98,914 from NTSB ones, roughly 436 entities per report. By type, the largest are equipment (118,152), condition (61,836), location (60,738), procedure (54,427) and document (39,787); 10,942 rows fell outside the vocabulary and carry type = 'other' with the extraction's own suggestion in proposed_type.

Keys: PK id. FK document_id → documents(id) ON DELETE CASCADE. FK type → narrative_entity_types(name) ON DELETE RESTRICT (natural-key FK). A database trigger enforces that an entity's mentions can only anchor to sentences of the entity's own document.

ColumnTypeNullableDescriptionValid values / constraintsSource
iduuidnoSurrogate keydefault gen_random_uuid()System
document_iduuidnoReport the entity is scoped toFK, cascade deletePipeline
typetextnoEntity typeFK to narrative_entity_types(name), one of the 14 seeded typesAI-U
canonical_nametextnoNormalised name for the entity-AI-U
proposed_typetextyesThe type the extraction proposed for an entity the vocabulary has no term for, kept rather than discarded so the vocabulary can grow from what the corpus actually containsCHECK: set if and only if type is other, and non-blankAI-U
created_at / updated_attimestamptzyesAudit timestamps-System

narrative_entity_mentions

Each occurrence of an entity in the text: the exact words used and their character position within the sentence.

1,267,349 rows as delivered: 1,032,182 from MAIB documents and 235,167 from NTSB ones. By mention_type: 894,775 definite_description, 251,847 name, 70,390 split_antecedent, 50,337 pronoun. confidence is populated on every row.

Keys: PK id. FKs narrative_entity_id → narrative_entities(id), sentence_id → sentences(id), both ON DELETE CASCADE. CHECK: char_span non-empty with lower bound ≥ 0. CHECK: confidence null or between 0 and 1.

ColumnTypeNullableDescriptionValid values / constraintsSource
iduuidnoSurrogate keydefault gen_random_uuid()System
narrative_entity_iduuidnoEntity being mentionedFK, cascade deleteAI-U
sentence_iduuidnoSentence containing the mentionFK, cascade deleteAI-U
surface_formtextnoExact words used (e.g. "the Master", "Captain Smith")-AI-U
char_spanint4rangenoHalf-open character range into the sentence textnon-empty, lower ≥ 0 (check-constrained)AI-U
mention_typetextyesHow the entity is referred to at this mention - the distinction coreference turns on, since a pronoun carries no name to matchCHECK: null or one of name, definite_description, pronoun, split_antecedentAI-U
confidencerealyesThe extraction's own confidence in this mention belonging to the entity-AI-U
created_at / updated_attimestamptzyesAudit timestamps-System

3. Analysis and findings

analysis

Free-form per-passage analysis output - somewhere a future analytical pass can record results without a schema change. Several passes can sit side by side on the same passage. No verification flag exists, so any content here would be unverified.

Empty as delivered. Nothing in the current pipeline writes it.

Keys: PK id. FK passage_id → passages(id) ON DELETE CASCADE.

ColumnTypeNullableDescriptionValid values / constraintsSource
iduuidnoSurrogate keydefault gen_random_uuid()System
passage_iduuidyesPassage analysedFK, cascade deletePipeline
analysis_typetextyesOptional label an analyst supplies when uploading an analysis of a passagefree text; no controlled vocabularySystem (analyst-provided)
contenttextyesThe analysis output itself-AI-U
created_at / updated_attimestamptzyesAudit timestamps-System

passage_shield_codes

Application of a SHIELD causal-factor code to a passage - the link that makes incidents comparable and countable. Verification lives on the association itself, because an analyst verifies "this code applies to this passage".

Empty as delivered. All 113 SHIELD codes and all 15,381 passages are present and embedded, but no code has been matched to a passage yet.

What exists in place of it is a suggestion function, match_shield_codes(p_passage_id uuid, p_strategy text DEFAULT 'category_definition', p_limit integer DEFAULT 5, p_model text DEFAULT NULL). It ranks SHIELD codes by cosine proximity to the passage's stored vector and returns (shield_code_id, code, title, category, layer, similarity), where similarity is 1 - cosine_distance - higher is closer. It reads; it never writes. Populating this table from its output, and deciding what similarity is worth accepting, is open work.

Keys: Composite PK (passage_id, shield_code_id). FKs passage_id → passages(id), shield_code_id → shield_codes(id), both ON DELETE CASCADE.

ColumnTypeNullableDescriptionValid values / constraintsSource
passage_iduuidnoTagged passagePK part, FK, cascade deleteAI-U (the tagging is the AI judgement; AI-V where is_verified)
shield_code_iduuidnoApplied SHIELD codePK part, FK, cascade deleteAI-U (as above)
is_verifiedbooleanyesAnalyst has confirmed this code applies to this passagedefault falseSystem (records human verification action)
verified_attimestamptzyesWhen verifiedtrigger-stamped when is_verified flips true, cleared when falseSystem
created_at / updated_attimestamptzyesAudit timestamps-System

safety_issues

A named safety concern the report raises, owned by a document and optionally traced to the passage it was drawn from. passage_id cascades: a passage is deleted when it loses its last sentence, and the finding goes with it, because a finding whose source text no longer exists is not evidence of anything. The column stays nullable because a finding created standalone through the API has no passage at all.

11,254 rows as delivered: 10,038 from MAIB documents and 1,216 from NTSB ones. Split by record_type, 10,775 are safety_issue (9,734 MAIB / 1,041 NTSB) and 479 are safety_lesson (304 / 175). Every row came from the record pass; none is analyst-verified.

Keys: PK id. FK document_id → documents(id) ON DELETE CASCADE. FK passage_id → passages(id) ON DELETE CASCADE. CHECK safety_issues_record_type_valid (record_type in ('safety_issue', 'safety_lesson')). CHECK safety_issues_source_valid (source in ('record_pass', 'manual')). Partial index on record_type where record_type <> 'safety_issue' - nearly every row is a safety_issue, so lessons are the selective side worth indexing. A trigger validates (and derives, where unambiguous) document_id against the passage's actual document, falling back to passages.document_id when the passage has no sentences yet.

ColumnTypeNullableDescriptionValid values / constraintsSource
iduuidnoSurrogate keydefault gen_random_uuid()System
document_iduuidyesOwning reportFK, cascade delete; trigger-validated against passagePipeline
passage_iduuidyesPassage the issue was drawn fromFK, cascade deletePipeline (provenance link)
nametextyesAn analyst's name for the issue, where a nomenclature is being applied to group issues across reports. Not the report's own wording - that is the passage's sentences. Empty until reviewedfree text; no extraction pass writes itAnalyst
record_typetextnoWhether the row is a finding about this accident or a general safety lesson to the industrysafety_issue or safety_lesson, CHECK-constrained; default safety_issuePipeline / AI-U (AI-V where is_verified)
sourcetextnoWhich writer created the rowrecord_pass or manual, CHECK-constrained; every delivered row is record_passSystem
is_contributorybooleanyesDid this issue contribute directly to the accident?null means the report did not classify it (see note)Pipeline / AI-U (AI-V where is_verified)
is_addressedbooleanyesWas the issue addressed, or did it result in recommendations?null means the report did not classify it (see note)Pipeline / AI-U (AI-V where is_verified)
is_verifiedbooleanyesAnalyst has confirmed the findingdefault falseSystem (records human verification action)
verified_attimestamptzyesWhen verifiedtrigger-stampedSystem
name_tsvtsvector-Full-text search index over namegenerated columnSystem
created_at / updated_attimestamptzyesAudit timestamps-System

is_contributory and is_addressed split MAIB's four-way classification of safety issues (directly contributing, addressed or resulted in recommendations / other directly contributing / not directly contributing, addressed or resulted in recommendations / other not directly contributing) into the two independent facts it actually encodes. Both are nullable because only modern-era reports classify at all: mid-era reports print bare FINDINGS / OTHER FINDINGS, older ones list findings under a CONCLUSIONS part, and bulletins do not classify. Null means the report did not say - never "unknown, pending backfill". As delivered, is_contributory is set on 2,975 of the 11,254 rows and is_addressed on 3,035.

record_type distinguishes the two kinds of free-text observation the table holds. A safety_lesson is general advice to the industry, printed under a SAFETY LESSONS heading in bulletins and in the safety-flyer annexes of full reports; for several bulletins it is the only safety content in the document. Lessons share this table because they have the same shape as issues - free text, no addressee, no identifier - and simply leave the two classification booleans null.

recommendations

An action the report calls for, in the report's own words. Same shape and delete semantics as safety_issues.

4,127 rows as delivered: 3,854 from MAIB documents and 273 from NTSB ones. reference_number is set on 2,414 and addressee on 3,159; none is analyst-verified.

Keys: PK id. FK document_id → documents(id) ON DELETE CASCADE. FK passage_id → passages(id) ON DELETE CASCADE. CHECK recommendations_source_valid (source in ('record_pass', 'manual')). Partial index on reference_number where not null. Same document_id validation trigger as safety_issues.

ColumnTypeNullableDescriptionValid values / constraintsSource
iduuidnoSurrogate keydefault gen_random_uuid()System
document_iduuidyesOwning reportFK, cascade delete; trigger-validated against passagePipeline
passage_iduuidyesPassage the recommendation was drawn fromFK, cascade deletePipeline (provenance link)
actiontextyesAn analyst's summary of the action to take. Not the report's own wording - that is the passage's sentences. Empty until reviewedfree text; no extraction pass writes itAnalyst
reference_numbertextyesThe publisher's own reference for the recommendation, as printed (e.g. 2026/149, S2024/137M)set on 2,414 rows; indexed, deliberately not unique, so do not use it as a keyPipeline / AI-U (AI-V where is_verified)
addresseetextyesWho the recommendation is aimed at, in the report's own words with its lead-in frame removed (e.g. "Poseidon Trawlers Limited", not "Poseidon Trawlers Limited is recommended to:")free text; one lead-in governs several recommendations, so the same value repeats across rowsPipeline / AI-U (AI-V where is_verified)
sourcetextnoWhich writer created the rowrecord_pass or manual, CHECK-constrained; every delivered row is record_passSystem
is_verifiedbooleanyesAnalyst has confirmed the findingdefault falseSystem (records human verification action)
verified_attimestamptzyesWhen verifiedtrigger-stampedSystem
action_tsvtsvector-Full-text search index over actiongenerated columnSystem
created_at / updated_attimestamptzyesAudit timestamps-System

reference_number is the publisher's sequential identifier across its whole annual output, so one report's recommendations run consecutively and a recommendation made in one report can be cited by name in a later one. Coverage is uneven: every NTSB recommendation carries one (273 of 273), but only 2,141 of the 3,854 MAIB ones do, the rest predating the numbering scheme.

addressee keeps the report's own wording rather than pointing at organisations, because the party addressed is often a class of people ("All UK Operators of small commercial high speed craft…") rather than a nameable company. It is set on 2,904 MAIB and 255 NTSB rows.

safety_issue_legislation

Junction linking a safety issue to legislation that bears on it, with the passage of text that made the connection - so the citation itself is traceable. Empty, along with legislation itself.

Keys: Composite PK (safety_issue_id, legislation_id). FKs to safety_issues(id) and legislation(id), both ON DELETE CASCADE.

ColumnTypeNullableDescriptionValid values / constraintsSource
safety_issue_iduuidnoSafety issuePK part, FK, cascade deleteAI-U (the link is the AI judgement)
legislation_iduuidnoLegislation citedPK part, FK, cascade deleteAI-U
extracted_texttextyesThe passage that made the connection-AI-U
created_at / updated_attimestamptzyesAudit timestamps-System

recommendation_organisations

Junction linking a recommendation to the organisations it is directed at. Implementation is tracked per organisation, because each may act on the same recommendation at a different time.

Written by the record pass: each recommendation's addressee is cleaned of the report's own connective wording, split into the parties it names, and each party resolved - one row per party. That is why this is a junction rather than a foreign key on recommendations: "The International Chamber of Shipping, the International Maritime Pilots' Association and the International Harbour Masters' Association" is one addressee and three answerable bodies. The links are an enrichment; the verbatim addressee on the recommendation stays the record of who was addressed, and is what to fall back on where resolution produced no row.

3,658 rows as delivered - 3,342 from MAIB documents and 316 from NTSB ones - linking the 3,159 recommendations that name an addressee to the 802 organisations those addressees resolved to. Nothing has been marked implemented; is_implemented and implemented_at are for CHIRP's own follow-up and are empty.

Keys: Composite PK (recommendation_id, organisation_id). FKs to recommendations(id) and organisations(id), both ON DELETE CASCADE.

ColumnTypeNullableDescriptionValid values / constraintsSource
recommendation_iduuidnoRecommendationPK part, FK, cascade deleteAI-U (the directed-at link)
organisation_iduuidnoAddressee organisationPK part, FK, cascade deleteAI-U
is_implementedbooleanyesOrganisation has implemented the recommendationdefault falseSystem (records human tracking action)
implemented_attimestamptzyesWhen marked implementedtrigger-stamped when is_implemented flips true, cleared when falseSystem
created_at / updated_attimestamptzyesAudit timestamps-System

4. Lookup and reference tables

shield_layers

The four layers of the SHIELD taxonomy - the top tier, grouping categories. Seeded reference data (4 layers). Referenced by natural key from shield_code_categories.layer, so a category row names its layer without a join.

Keys: PK name. UNIQUE sort_order.

ColumnTypeNullableDescriptionValid values / constraintsSource
nametextnoLayer namePK; Acts, Preconditions, Operational Leadership, OrganisationSystem (seeded CHIRP taxonomy)
definitiontextnoWhat the layer covers, per the SHIELD paper-System (seeded CHIRP taxonomy)
sort_ordersmallintnoPosition in the taxonomy, sharp end downwardsunique; 1 = Acts … 4 = OrganisationSystem (seeded CHIRP taxonomy)
created_at / updated_attimestamptzyesAudit timestamps-System

shield_code_categories

Categories grouping SHIELD codes, each belonging to one layer. Seeded reference data (24 categories).

Keys: PK id. UNIQUE name, UNIQUE code. FK layer → shield_layers(name) ON UPDATE CASCADE (a layer can be renamed from its own row; categories follow).

ColumnTypeNullableDescriptionValid values / constraintsSource
iduuidnoSurrogate keydefault gen_random_uuid()System
nametextnoCategory nameuniqueSystem (seeded CHIRP taxonomy)
layertextnoLayer this category sits inFK, natural keySystem (seeded CHIRP taxonomy)
codetextnoShort category identifier (e.g. PPC)uniqueSystem (seeded CHIRP taxonomy)
definitiontextyesFull definition of the category-System (seeded CHIRP taxonomy)
created_at / updated_attimestamptzyesAudit timestamps-System

shield_codes

The SHIELD causal-factor taxonomy itself - CHIRP's controlled vocabulary of human factors in maritime incidents. Seeded reference data (113 codes in 24 categories under four layers); see Appendix A.

Keys: PK id. UNIQUE code. FK category_id → shield_code_categories(id) ON DELETE SET NULL (an uncategorised code remains valid).

ColumnTypeNullableDescriptionValid values / constraintsSource
iduuidnoSurrogate keydefault gen_random_uuid()System
category_iduuidyesGrouping categoryFK, SET NULLSystem (seeded CHIRP taxonomy)
codetextnoShort taxonomy identifier (e.g. PPC2)uniqueSystem (seeded CHIRP taxonomy)
titletextnoCode title (e.g. "Fatigue")-System (seeded CHIRP taxonomy)
definitiontextyesFull definition of the causal factor-System (seeded CHIRP taxonomy)
created_at / updated_attimestamptzyesAudit timestamps-System

narrative_entity_types

Controlled vocabulary of entity types. Seeded reference data (14 types); referenced by natural key from narrative_entities.type, which is ON DELETE RESTRICT - a type in use cannot be removed.

The 14: person, group_of_people, organisation, vessel, equipment, cargo_or_substance, location, event, condition, procedure, document, legislation, time, other. other is the escape hatch - an entity that fits none of the thirteen takes it and records what the extraction would have called it in narrative_entities.proposed_type, so the vocabulary can be grown from what the corpus actually contains rather than guessed at up front.

Keys: PK id. UNIQUE name.

ColumnTypeNullableDescriptionValid values / constraintsSource
iduuidnoSurrogate keydefault gen_random_uuid()System
nametextnoType nameunique; 14 seeded values, listed aboveSystem (seeded vocabulary)
descriptiontextyesWhat the type covers-System (seeded vocabulary)
created_at / updated_attimestamptzyesAudit timestamps-System

legislation

Legislation register shared across safety issues - one law can back findings in many reports. When this feature ships, an agentic AI attaches relevant legislation to a safety issue, sourced from the report itself or pulled from external legal sources; every attachment needs analyst verification. Not yet implemented - empty in this database.

Keys: PK id.

ColumnTypeNullableDescriptionValid values / constraintsSource
iduuidnoSurrogate keydefault gen_random_uuid()System
nametextnoName of the legislation-AI-U (AI-attached, requires verification)
referencetextyesFormal reference-AI-U (AI-attached, requires verification)
jurisdictiontextyesJurisdiction of the legislation-AI-U (AI-attached, requires verification)
urltextyesLink to the legislation-AI-U (AI-attached, requires verification)
created_at / updated_attimestamptzyesAudit timestamps-System

organisations

Parties that recommendations are directed at, resolved from each recommendation's addressee text as the record pass runs.

A row is not always a company. Reports frequently address a class of people - "All UK Operators of small commercial high speed craft…" - and the same class recurs across reports, so it earns a row of its own; kind says which sort of row it is. kind is guessed from the shape of the name and is an analyst's to correct.

802 rows as delivered: 710 company, 92 class. 71 are curated seeds; the other 731 were minted by resolution. Every contact column is empty - contact_name, email, phone_number, address and website_url are null on all 802. They exist for CHIRP's own follow-up workflow, which has not run; nothing in this delivery populates them.

One company is one row, enforced rather than intended: match_key is name normalised - case, accents, punctuation, a leading "The" and a trailing legal suffix folded away - and it is UNIQUE, so Poseidon Trawlers Ltd, Poseidon Trawlers Limited and The Poseidon Trawlers Ltd. cannot become three rows. Two limits follow. Resolution will not merge a name into one it merely resembles, so genuine near-duplicates that normalise differently survive as separate rows; and it trusts a curated row's spelling without re-parsing it, which is what is_curated marks and why only a person may set it.

Keys: PK id. UNIQUE match_key.

ColumnTypeNullableDescriptionValid values / constraintsSource
iduuidnoSurrogate keydefault gen_random_uuid()System
nametextnoOrganisation or class name-AI-U (extracted from the recommendation)
match_keytextnoname normalised for matchinggenerated always as org_match_key(name), stored; UNIQUE; NOT NULL, so a name that normalises to nothing is rejectedSystem (derived)
kindorganisation_kindnoWhether the row is a named company or a class of peopleenum: company, class; default companyAI-U (extracted from the recommendation)
is_curatedbooleannoTrue where a person put the row here - a seed or an analyst; false where the record pass minted it. Only a curated row may settle an addressee's spelling without parsing itdefault false; NOT NULLSystem curated
contact_nametextyesNamed contact at the organisationempty - null on all 802 rowsAI-U (planned: from text, else web search, else manual)
emailtextyesContact emailempty - null on all 802 rowsAI-U (as above)
phone_numbertextyesContact phoneempty - null on all 802 rowsAI-U (as above)
addresstextyesPostal addressempty - null on all 802 rowsAI-U (as above)
website_urltextyesWebsiteempty - null on all 802 rowsAI-U (as above)
created_at / updated_attimestamptzyesAudit timestamps-System

organisation_identifiers

Curated identifiers that canonicalise an organisation, one row per identifier - so spelling variants resolve to a single organisation rather than many near-duplicates. Mirrors author_identifiers.

It holds the spellings organisations.match_key cannot reach on its own: acronyms (BPA, UKMPG, OCIMF), predecessor names (the Marine Safety Agency, now the MCA), house styles and outright typos. Only a person adds one - by seeding, by merging two rows, or implicitly by renaming an organisation, which keeps the old spelling here so existing addressees still resolve. The record pass writes none.

The unique index on match_key spans the whole table, not one organisation: one spelling must never point at two organisations.

86 rows as delivered, all seeds. Coverage is therefore only as good as what was seeded - near-duplicate organisations that nobody has spotted remain separate rows.

Keys: PK id. UNIQUE match_key. FK organisation_id → organisations(id) ON DELETE CASCADE.

ColumnTypeNullableDescriptionValid values / constraintsSource
iduuidnoSurrogate keydefault gen_random_uuid()System
organisation_iduuidnoOwning organisationFK, cascade deletePipeline
identifiertextnoCurated identifier used to resolve name variants to one canonical organisationcuratedSystem
match_keytextnoidentifier normalised for matchinggenerated always as org_match_key(identifier), stored; UNIQUE across the table; NOT NULLSystem (derived)
created_at / updated_attimestamptzyesAudit timestamps-System

taxonomy_terms

Shared lookup for every tree-shaped MAIB classification - spreadsheet-sourced, so referenced only from the UK-side tables. One row per term; parent_id links a term to its parent; taxonomy names which tree the term belongs to. Built from the spreadsheet's parallel level-columns (_L1, _L2, …), collapsed into one tree so a query can group by a type without knowing which level each row happens to fill.

Keys: PK id. UNIQUE (id, taxonomy) and (taxonomy, parent_id, label). Composite self-FK (parent_id, taxonomy) → (id, taxonomy) ON UPDATE CASCADE ON DELETE CASCADE - a term's parent must live in the same taxonomy.

ColumnTypeNullableDescriptionValid values / constraintsSource
iduuidnoSurrogate keydefault gen_random_uuid()System
taxonomytaxonomy_namenoWhich tree the term belongs toenum: main_event, ship_type, vessel_category, vessel_place_on_board, person_place_on_board, physical_condition, injury_type, deviationMAIB
parent_iduuidyesParent term; null at the root of a treeself-FK, same taxonomyMAIB
labeltextnoThe term text (e.g. "General Cargo")-MAIB
created_at / updated_attimestamptzyesAudit timestamps-System

410 terms across the eight trees: ship_type (98), vessel_place_on_board (83), person_place_on_board (82), deviation (48), injury_type (44), main_event (32), vessel_category (15), physical_condition (8).

Referenced from: occurrences.main_event_term_id; vessels.vessel_category_term_id, ship_type_term_id, place_on_board_term_id; affected_persons.physical_condition_term_id, injury_type_term_id, deviation_term_id, place_on_board_term_id. Place-on-board is split into two trees - vessel_place_on_board (referenced by vessels) and person_place_on_board (referenced by affected_persons).

ppe_items

Controlled vocabulary of PPE items, split out of the spreadsheet's comma-joined PPE_Used / PPE_Deficient cells. Referenced from affected_persons_ppe. Nine items: life jacket, head protection, hand and foot protection, face and eye protection, anti-exposure suit, protection from falls, working clothes, protective clothing, hearing protection.

Keys: PK id. UNIQUE label.

ColumnTypeNullableDescriptionValid values / constraintsSource
iduuidnoSurrogate keydefault gen_random_uuid()System
labeltextnoPPE item name (e.g. "Life jacket")uniqueMAIB
created_at / updated_attimestamptzyesAudit timestamps-System

5. Embeddings

The pgvector layer behind SHIELD code suggestion: passages and SHIELD codes encoded under a registered model and compared by cosine distance. No API route exposes any of it - a separate worker container is the only writer of vectors, and the read path is the single function match_shield_codes, documented under passage_shield_codes.

Fully populated as delivered. embedding_models holds the single active encoder (BAAI/bge-large-en-v1.5, 1024 dimensions) and embedding_strategies the four assembly strategies. passage_embeddings carries a vector for every one of the 15,381 passages under that model, shield_code_embeddings all 452 vectors (113 codes × 4 strategies), and passage_embedding_queue is drained to 0 - no passage is awaiting or failing embedding.

Two properties are worth knowing before reading the tables:

The embedding columns are the only model output in this section. They are labelled AI-U because an NLP model produces them, but unlike other AI-U columns they assert nothing about an incident and no verification workflow applies - a vector is either current for its text or absent.

embedding_models

Registry of encoders. One row per model; the worker and queue use the single active one. Seeded reference data (1 row: BAAI/bge-large-en-v1.5).

Keys: PK id. UNIQUE name.

ColumnTypeNullableDescriptionValid values / constraintsSource
iduuidnoSurrogate keydefault gen_random_uuid()System
nametextnoModel identifier as the provider names itunique; e.g. BAAI/bge-large-en-v1.5System (seeded)
providertextnoWhich runtime loads the modelCHECK: sentence_transformers, openaiSystem (seeded)
dimensionsintegernoVector width the model emitsCHECK: must be 1024 - the width the columns indexSystem (seeded)
query_prefixtextnoInstruction string the model wants prepended on the passage sidedefault ''; bge models require oneSystem (seeded)
is_activebooleannoWhether this is the model the queue and worker act ondefault false; at most one row may be true (unique partial index)System (seeded)
notestextyesFree-text remarks on the model or its run-System
created_at / updated_attimestamptzyesAudit timestamps-System

embedding_strategies

Which parts of the SHIELD taxonomy a named strategy assembles into the text that gets embedded. One boolean per taxonomy field, tier by tier - so a new combination is an INSERT, not a schema change, and the name-to-fields mapping lives in exactly one place. Seeded reference data (4 strategies).

The database function shield_code_embedding_text(shield_code_id, strategy) reads the row named here and joins the selected fields; the seeder never rebuilds those strings in Python, so the two sides cannot drift apart.

Keys: PK name. Referenced by shield_code_embeddings.strategy.

ColumnTypeNullableDescriptionValid values / constraintsSource
nametextnoStrategy identifierPK; seeded: full, category_definition, title_definition, definitionSystem (seeded)
includes_layer_namebooleannoInclude the layer's name (shield_layers.name)true only for fullSystem (seeded)
includes_layer_definitionbooleannoInclude the layer's definitiontrue only for fullSystem (seeded)
includes_category_namebooleannoInclude the category's nametrue for full, category_definitionSystem (seeded)
includes_category_definitionbooleannoInclude the category's definitiontrue for full, category_definitionSystem (seeded)
includes_titlebooleannoInclude the code's titletrue for all but definitionSystem (seeded)
includes_definitionbooleannoInclude the code's definitiontrue for all fourSystem (seeded)
descriptiontextnoWhat the strategy is for, and when to reach for it-System (seeded)
created_at / updated_attimestamptzyesAudit timestamps-System (seeded)

The four seeded strategies, widest to narrowest: full (every field the taxonomy holds), category_definition (category name and definition grounding the code's title and definition - the shortlist strategy), title_definition (title and definition, no category), definition (the definition alone, where something downstream wants exactly one code).

passage_embeddings

One vector per passage per model. Written only by the embedding worker. 15,381 rows as delivered - one for every passage, under the single active model (13,892 MAIB, 1,489 NTSB).

Keys: PK (passage_id, model_id). FK passage_id → passages(id) ON DELETE CASCADE; FK model_id → embedding_models(id) ON DELETE RESTRICT (a model with vectors cannot be deleted out from under them). HNSW index on embedding (vector_cosine_ops).

ColumnTypeNullableDescriptionValid values / constraintsSource
passage_iduuidnoPassage embeddedPK part, FK, cascade deleteSystem
model_iduuidnoModel that produced the vectorPK part, FK, restrict deleteSystem
embeddingvector(1024)noThe passage's vectordimensions must match the model'sAI-U
source_text_sha256byteanoHash of the passage text this vector was computed fromtrigger-checked against passages.source_text_sha256; mismatch rejectedSystem
created_at / updated_attimestamptzyesAudit timestamps-System

shield_code_embeddings

One vector per SHIELD code per model per strategy - so the same code carries several vectors, one for each way of assembling its text. Written only by the seeder. At full coverage this is 113 codes × 4 strategies = 452 rows per model.

452 rows as delivered - full coverage under the single active model.

Keys: PK (shield_code_id, model_id, strategy). FK shield_code_id → shield_codes(id) ON DELETE CASCADE; FK model_id → embedding_models(id) ON DELETE RESTRICT; FK strategy → embedding_strategies(name) ON DELETE RESTRICT. No vector index - the table is small enough to scan.

ColumnTypeNullableDescriptionValid values / constraintsSource
shield_code_iduuidnoSHIELD code embeddedPK part, FK, cascade deleteSystem
model_iduuidnoModel that produced the vectorPK part, FK, restrict deleteSystem
strategytextnoWhich assembly of taxonomy fields was embeddedPK part, FK to embedding_strategies(name)System
embeddingvector(1024)noThe strategy string's vectordimensions must match the model'sAI-U
source_text_sha256byteanoHash of the assembled strategy string this vector was computed fromtrigger-checked against shield_code_embedding_text(...); a taxonomy edit invalidates itSystem
created_at / updated_attimestamptzyesAudit timestamps-System

passage_embedding_queue

Work list of passages awaiting embedding - one row per passage per model. Filled by trigger, not by application code: changing a passage's text enqueues it, and emptying a passage of text deletes its queue rows and its vectors together. A row leaves the queue when its vector is written. Empty as delivered, because every passage has been embedded - a non-zero depth means passage text changed after its vector was computed.

Keys: PK (passage_id, model_id). FK passage_id → passages(id) ON DELETE CASCADE; FK model_id → embedding_models(id) ON DELETE CASCADE.

ColumnTypeNullableDescriptionValid values / constraintsSource
passage_iduuidnoPassage awaiting embeddingPK part, FK, cascade deleteSystem
model_iduuidnoModel the work is queued forPK part, FK, cascade deleteSystem
target_sha256byteanoHash of the text the worker should embed - what the vector must end up naming-System
attemptssmallintnoFailed attempts so far; a row past the ceiling stops being handed out and stays for inspectiondefault 0System
claim_tokenuuidyesLease held by the worker currently processing the row; null when unclaimed-System
claimed_attimestamptzyesWhen the lease was taken; an expired lease is reclaimable by another workernull when unclaimedSystem
last_errortextyesError text from the most recent failed attempt-System
created_at / updated_attimestamptzyesAudit timestamps-System

Database-enforced behaviour

Constraints participants should know about when writing to (or reasoning about) the data:


Appendix A - SHIELD taxonomy

SHIELD is CHIRP's controlled taxonomy of human factors in maritime incidents: 113 factors in 24 categories under four layers. Each factor has a short code (e.g. PPC2), a title (e.g. "Fatigue") and a full definition; categories and layers carry their own codes and definitions too. The taxonomy is seeded reference data - the complete list is reproduced below and lives in the shield_layers, shield_code_categories and shield_codes tables.

SHIELD is presented as an iceberg: the visible acts at the tip, the preconditions that set them up below the waterline, the operational leadership decisions deeper still, and the organisation that shapes all of them at the base. For the model and its rationale, see the published paper: SHIELD Human Factors Taxonomy and Database for Learning from Aviation and Maritime Safety Occurrences (Safety, 2023).

LayerScopeSize
A · ACTSActive failures by operators - Perception; Planning and Decision Making; Intentional Deviation; Response Execution; Communicating5 categories, 19 codes
P · PRECONDITIONSConditions that set the stage - Physical Environment; Equipment and Workplace; Interpersonal Communication; Team/Group; Misperception; Awareness; Memory; Mental Workload; Personal Factors; Physiological Condition; Drugs and Nutrition; Competence, Skills and Capability12 categories, 62 codes
L · OPERATIONAL LEADERSHIPLeadership decisions affecting safety - Personnel Leadership; Operations Planning; Task Leadership3 categories, 15 codes
O · ORGANISATIONDecisions, policies or methods adopted at organisational level - Culture; Safety Management; Resources; Economy and Business4 categories, 17 codes

The full taxonomy

All 113 factors, grouped by their four layers and 24 categories. Layers appear in code-prefix order (A, L, O, P); the summary table above gives the taxonomy's own top-to-bottom order.

A · ACTS

Communicating

CodeTitleDefinition
AC1Incorrect/unclear transmission of informationThe operator transmits to other actors information which is incorrect or unclear, e.g. use of wrong callsign.
AC2No transmission of informationThe operator does not transmit information which is necessary for other actors to operate safely / effectively.

Intentional Deviation

CodeTitleDefinition
AI1Workaround in normal conditionsThe operator decides to intentionally deviate from an agreed procedure or practice in a normal operating condition.
AI2Routine workaroundThe operator habitually and intentionally deviates from an agreed procedure or practice on a regular basis.
AI3Workaround in exceptional conditionsThe operator decides to intentionally deviate from an agreed procedure or practice in an exceptional operating condition.
AI4SabotageThe operator decides to intentionally deviate from an agreed procedure or practice in order to create damage to the system or organisation.

Perception

CodeTitleDefinition
AP1No/wrong/late visual detectionThe operator does not detect (or detects too late or inaccurately) a visual signal necessary to formulate a proper action plan or make a correct decision.
AP2No/wrong/late auditory detectionThe operator does not detect (or detects too late or inaccurately) an auditory signal necessary to formulate a proper action plan or make a correct decision.
AP3No/wrong/late kinaesthetic detectionThe operator does not detect (or detects too late or inaccurately) a kinaesthetic signal necessary to formulate a proper action plan or make a correct decision.
AP4No/wrong/late with other senses (e.g. smell, temperature)The operator does not perceive (or perceives too late or inaccurately) information received with senses different from vision, hearing and touch, which is necessary to formulate a proper action plan or make a correct decision.

Planning and Decision Making

CodeTitleDefinition
AD1Incorrect decision or planThe operator fails to elaborate an action plan or make a decision which is insufficient to manage the situation.
AD2Late decision or planThe operator fails to elaborate a timely action plan or decision to manage the situation.
AD3No decision or planThe operator fails to elaborate any action plan or decision to manage the situation.

Response Execution

CodeTitleDefinition
AR1Timing errorThe operator has planned to take an action which is appropriate for the situation, but executes it either too early or too late.
AR2Sequence errorThe operator carries out a series of actions in the wrong sequence.
AR3Right action on the wrong objectThe operator has planned to take an action which is appropriate for the perceived situation but - when executing it - selects an object (e.g. lever, knob, button, HMI element) different from the intended one.
AR4Wrong action on the right objectThe operator selects the correct object (e.g. lever, knob, button, HMI element), but performs an action that is not the correct one.
AR5Lack of physical coordinationThe operator takes an action which is appropriate for the perceived situation, but executes it in a wrong manner, due to lack of physical coordination.
AR6No action executedThe operator has planned to take an action which is appropriate for the perceived situation, but does not execute it.

L · OPERATIONAL LEADERSHIP

Operations Planning

CodeTitleDefinition
LO1Inadequate risk assessmentOperations leader does not adequately evaluate the risks associated with a specific operation or scenario.
LO2Inadequate crew or team makeup or compositionOperations leader allows inadequate makeup or composition of crew or team for a given activity/operation.
LO3Inappropriate pressure to perform a taskInappropriate pressure by operational leader causes an operator to feel pressured to perform a task or activity.
LO4Directed task with inadequate qualification or currencyOperations leader allows an operator to perform a task, while the qualification or currency of the operator are not in line with the training requirements for the associated activity.
LO5Directed task with limited experienceOperations leader allows operators to perform a task, while their experience for a specific operation, event or scenario is too limited.
LO6Directed task with inadequate equipmentOperations leader directs operators to undertake an activity that is beyond the capabilities of their equipment.

Personnel Leadership

CodeTitleDefinition
LP1No personnel measures against regular risky behaviourAn operations leader does not identify an operator who regularly exhibits risky behaviours or does not institute the necessary remedial action.
LP2Inappropriate behaviour affects learningInappropriate behaviour of operations leader affects learning by operators, which manifests itself in actions that are either inappropriate to their skill level or violate standard procedures.
LP3Personality conflictA personality conflict exists between an operations leader and an operator.
LP4Lack of feedback on safety reportingOperations leader does not provide feedback to operator following his/her provision of information on a potential safety issue.

Task Leadership

CodeTitleDefinition
LT1Inadequate leadership or supervisionAvailability, competency, quality or timeliness of leadership or supervision does not meet task demands.
LT2No correction of unsafe practicesAn operations leader does not correct known unsafe practices, conditions, guidance or procedure, which allows hazardous practices within the scope of his / her authority.
LT3No enforcement of existing rulesOperations leader does not enforce organisational and operating rules.
LT4Allowing unwritten policies to become standardOperations leader allows policies that have not been formally recognized by the organisation to be perceived as standards.
LT5Directed deviationOperations leader directs a subordinate to deviate from existing regulations, procedures or technical guidance.

O · ORGANISATION

Culture

CodeTitleDefinition
OC1Safety cultureThere is a poor safety culture or a low company morale in the organisation, leading to a poor attitude to safety in the organisation.
OC2Multi-cultural factorsSociocultural barriers and conflicts cause misunderstandings between personnel and an unsafe working environment.

Economy and Business

CodeTitleDefinition
OE1ContractorsRelationships, communications, or inter-operability between the organisation and contractors are not optimal and this creates an unsafe working relationship.
OE2External business environmentStrong competition, poor relationships with other organisations (other than contractors) and changes in the market put pressure on the organisation which has a negative impact on safety.
OE3Economic pressureEconomic conditions and pressures to keep schedule and costs put a pressure on the organisation resulting in a negative impact on safety.
OE4Tempo of operationsThe speed with which an organisation is expected to operate leaves little space for anything else than getting the job done, thus reducing safety.

Resources

CodeTitleDefinition
OR1PersonnelThe organisation provides insufficient personnel who are suitably qualified and experienced to perform the tasks safely.
OR2BudgetsBudget is insufficient to allow the operation to proceed with adequate resources to operate safely.
OR3Equipment/parts/materials availabilityEquipment, materials, or parts that operators have to use is not available to them at the time that the task has to be performed.
OR4Inadequate training programThere are inadequate or unavailable training programs (either one-time, recurrent, upgrade, transition or any other local training program).
OR5Design of equipment or proceduresThe design of the equipment / procedure to support the operation / task is not suitable to allow the task to be performed safely. The equipment might also prevent operators working in an efficient manner and indirectly encourage short-cuts or workarounds.
OR6Operational informationOperational information necessary to perform the task safely, or meet the requirements of a safe operation is not available at the relevant points in the organisation. This information includes weather briefings/forecasts, intelligence, operational planning material or other information necessary for safe operations.

Safety Management

CodeTitleDefinition
OS1Organisation structure/policyManagement commitment and responsibilities are not clear or insufficient. It is not clear who is accountable for safety issues. The structure of the organisation is not clear about key safety personnel. Safety plans including emergency response planning are not coordinated or unavailable.
OS2Safety risk management (proactive)Identification of safety hazards and risk assessments and mitigation are not carried out, or are carried out but do not identify and make available relevant safety issues.
OS3Safety risk assurance (reactive)Safety risk assurance is ineffective in identifying and repairing safety shortfalls. Safety risk assurance includes performance monitoring (inspections, review of tasks), testing, and incident reporting.
OS4Safety promotionSafety promotion (education, communication) does not sufficiently reinforce the importance of safety.
OS5Publications/procedures/written guidancePublications and written documentation are not sufficient to ensure that a task can be carried out safely. Procedures may exist, but are poor and cannot be used to perform the task they support. Even where good procedures exist they do not account for all the operational circumstances within which they are expected to be applied (work as imagined versus work as done).

P · PRECONDITIONS

Awareness

CodeTitleDefinition
PAW1Channelized attentionOperator focuses all attention on a limited number of cues and excludes other cues of an equal or higher priority. This includes tunnel vision.
PAW2ConfusionOperator does not maintain a cohesive awareness of events and required actions, and this leads to confusion.
PAW3DistractionInterruption and/or inappropriate redirection of operator's attention.
PAW4InattentionOperator is not alert / ready to process immediately available information.
PAW5Geographically lostThe operator perceives to be at a different location compared to the one where s/he actually is.
PAW6Unsuitable mental modelOperator uses an unsuitable mental model to integrate information and arrives at a wrong understanding of the situation (e.g. wrong understanding of automation behaviour).
PAW7Pre-conceived notion or expectancyPrevalence of expectations on a certain course of action regardless of other cues degrades operator performance.

Competence, Skills and Capability

CodeTitleDefinition
PCS1Inadequate experienceOperator does not have sufficient experience with a task at hand.
PCS2Lack of proficiencyOperator capability to accomplish a task does not meet the performance levels expected from her/his skill level.
PCS3Inadequate training or currencyOperator does not meet general training or recurring training requirements for the task assigned to her/him.
PCS4Body size, strength or coordination limitationsBody size, strength, dexterity, coordination mobility or other biomechanical limitations of the operator degrade the task performance of the operator.

Drugs and Nutrition

CodeTitleDefinition
PDN1Recreational drugs and alcoholRecreational use of drugs or alcohol impairs or interferes with operator performance.
PDN2Prescribed drugs or OTC medicationsUse of prescribed drugs or over-the-counter medications or supplements interferes with operator task performance.
PDN3Inadequate nutrition, hydration or dietary practiceInadequate nutritional state, hydration or dietary practice degrade operator performance.

Equipment and Workplace

CodeTitleDefinition
PEW1Ergonomics and human machine interface issuesThe ergonomics of tools and human machines interface, including controls, switches, displays, warning systems and symbology degrade the operator's performance.
PEW2Technology creates an unsafe situationThe design, malfunction, failure, symbology, logic or other aspects of technical/automated systems degrade the operator's performance.
PEW3Workspace or working position incompatible with operationThe interior or exterior workspace layout or the working position are incompatible with the task requirements of the operator.
PEW4Personal protective equipment interferencePersonal protection equipment (helmets, suits, gloves, etc.) interferes with normal duties of the operator.
PEW5Communication equipment inadequateCommunication equipment is inadequate or unavailable to support task demands. Communications can be voice, data or multi-sensory.
PEW6Fuels or materialsWorking with fuels, chemicals or materials degrades the operator's performance.

Interpersonal Communication

CodeTitleDefinition
PCO1Briefing or handover inadequateIndividual or team has not well completed the briefing or handover of an activity.
PCO2Inadequate communication due to team members' rank or positionDifferences in rank or position within team limit or jeopardize team communication.
PCO3Language difficultiesCommunication between operators with different native languages degrades operator's performance.
PCO4Non-standard or complex communicationOperators use terminology / phrases or hand signals differing from standards and training, or they use complex messages that may lead to misunderstanding.

Memory

CodeTitleDefinition
PME1Forget actions/intentionsThe operator has a temporary memory lapse and forgets planned actions or intentions.
PME2No/inaccurate recall of informationThe operator does not retrieve or recall information accurately from memory.
PME3Negative habitThe operator uses a highly learned behaviour from past experiences which is inadequate to handle the present situation.

Mental Workload

CodeTitleDefinition
PMW1High workloadHigh workload degrades the operator's performance.
PMW2Low workloadLow workload imposes idleness and waiting, and it degrades operator's performance.
PMW3Information processing overloadAvailable mental resources are insufficient to process the amount of complex information.
PMW4Startle effectAvailable mental resources are insufficient to process sudden, high-intensity, unexpected information, leading to the startle effect.

Misperception

CodeTitleDefinition
PER1Motion illusionErroneous physical sensation of orientation, motion or acceleration by the operator.
PER2Visual illusionErroneous perception of orientation, motion or acceleration following visual stimuli.
PER3Misperception of changing environmentMisperceived or misjudged altitude, separation, speed, closure rate, road/sea conditions, aircraft/vehicle location within the performance envelope.
PER4Misinterpreted or misread instrumentMisread, misinterpreted or not recognized significance of correct instrument reading.

Personal Factors

CodeTitleDefinition
PPF1Emotional stateStrong positive or negative emotion degrade operator's performance.
PPF2Personality styleOperator's personality traits (e.g. authoritarian, over-conservative, impulsive, invulnerable, submissive) contribute to degraded performance and/or negatively affect interaction with other team members.
PPF3Confidence levelInadequate estimation by the operator of personal capability, of the capability of others or the capability of equipment degrades performance.
PPF4Performance/peer pressureThreat to self-image and feeling of pressure to perform an activity despite concerns about the risk associated degrades performance.
PPF5MotivationExcessive or inadequate motivation to accomplish a task or prevalence of personal goals over organisation's goals degrades operator performance.
PPF6Pre-existing psychological conditionPre-existing acknowledged personality, psychological or psychosocial disorder/problem degrades operator performance.
PPF7Risk underestimationFalse sense of safety or complacency brings the operator to ignore hazards or to underestimate the risks associated to them, thus degrading performance.

Physical Environment

CodeTitleDefinition
PPE1Vision affected by environmentEnvironmental conditions affect the operator's vision.
PPE2Operator movement affected by environmentEnvironmental conditions affect the operator's movement.
PPE3Hearing affected by environmentEnvironmental conditions affect the operator's ability to hear.
PPE4Mental processing affected by environmentEnvironmental conditions affect the operator's ability to mentally process or think about information.
PPE5Heat or cold stressExposure to heat or cold degrades the operator's performance capabilities.
PPE6Operation more difficult due to weather and environmentWeather conditions and/or environment make controlling the operation more difficult.
PPE7AccelerationForces acting on a body by acceleration or gravity degrade the operator's performance capabilities.
PPE8Vibration stressExcessive exposure to vibration degrades operator physical or cognitive performance.
PPE9Long term isolationAn individual is subject to long term isolation and this degrades operator performance.

Physiological Condition

CodeTitleDefinition
PPC1Injury or illness existed during operationPre-existing physical illness, injury, deficit or diminished physical capability due to the injury, illness or deficit, degrades operator performance. This includes situations where the operator intentionally performs duties with a known (disqualifying) medical condition.
PPC2FatigueDiminished mental capability due to fatigue, restricted or shortened sleep, mental activity during prolonged wakefulness or disturbance of circadian rhythm degrades operator performance.
PPC3Mentally exhausted (burnout)Exhaustion associated with the wearing effects of high operational and/or lifestyle tempo, in which operational requirements impinge on the ability to satisfy personal requirements degrades operator performance.
PPC4HypoxiaInsufficient oxygen supply to the body impairs operator performance.
PPC5Decompression sicknessDevelopment of nitrogen bubbles in the blood and tissues as a result of too quick reduction of atmospheric pressure causes operator chest pains, bends, difficult breathing, skin irritation, cramps.

Team/Group

CodeTitleDefinition
PTG1Team working towards different goalsTeam members are working towards different goals, leading to loss of shared situational awareness and not anticipating potential problems.
PTG2No cross-check and speaking-up by team memberDecisions or actions by team members are not crosschecked. There is no multi-person approach to execution of critical tasks / procedures and no communication of concerns, not necessarily due to rank or position.
PTG3No monitoring and speaking-up of team status and functioningTeam members do not monitor the status and functioning of each other for signs of stress, fatigue, complacency, and task saturation, or do not speak up if status and functioning are monitored as being incorrect.
PTG4No adaptation of team performance in demanding situationTeam does not adapt to demanding circumstances. There is no change in team roles and task allocation, there is no team priorisation of plans and tasks, no workload management, and no management of interruptions and distractions.
PTG5Long term team confinementLong term close proximity or confinement degrades team functioning and operator performance.
PTG6Group thinkExcessive tendency towards group, team or organisation consensus and conformity over independent critical analysis and decision making degrades operator performance.
← Back to the dataset overview