← Evidence hub · About

data dictionary · spec-driven — the docs are the schema

The Data Dictionary

How these docs are layered

layerwhat it iswhere it lives
Data typethe raw material of a single field — string, number, boolean, arrayinside every schema below
Schemathe structure of one object — a StudyRecord, an EffectEstimate, an association rowoutcome_schema.py (pydantic, the enforcing code)
JSON Schema (machine-readable docs)the spec-driven contract — validates every payload the pipelines emitplatform-data.schema.json, generated by export_contract.py from the pydantic models, so docs cannot drift from code
Data Dictionary (human-readable docs)this page — every schema, every field, its meaning and constraintsdocs.html
Ontology (relationship docs)how concepts relate — the causal spine, relation vocabulary, and evidence/claim provenance (SEPIO)the ontology stack, below

Platform Data Contract — Field-by-Field Data Dictionary

Contract: biology-as-code/platform-data/v1 (JSON Schema draft-07) — the single payload shape all four views read.

Top-level required sections: manifest, outcomes. additionalProperties: false at the root — no unknown top-level keys.

Optional sections: lexicon, records, associations, feed, mechanisms, promises.

How this schema is generated (and why it cannot drift): export_contract.py builds platform-data.schema.json programmatically. Enums are pulled live from outcome_schema.py (enum = lambda E: sorted(e.value for e in E)), and the full-fidelity StudyRecord shape is embedded verbatim from pydantic's own StudyRecord.model_json_schema(ref_template="#/$defs/{model}") into $defs. Because the contract is emitted from the same code that validates the data, the documented shape and the enforced shape are the same artifact — docs cannot drift from code.

1. manifest — provenance header (FDP-1 spirit: version, date, counts, gate rate)

Single object. Required.

fieldtyperequired?meaningconstraints / enum values
corpus_versionstringyesVersion identifier of the evidence corpus this payload was built from
generated_atstringyesDate the payload was generatedformat: date
extractor_versionstringnoVersion of the extraction pipeline that produced the records
sourcestringnoWhere the corpus came from
countsobjectyesCorpus size summarykeys below; all optional within counts
counts.studiesnumbernoNumber of studies in the payload
counts.outcomesnumbernoNumber of flat outcome rows
counts.mechanismsnumbernoNumber of mechanism edges
counts.claimsnumbernoNumber of graded claims
counts.pubmed_slicenumbernoSize of the PubMed slice considered
counts.extractor_queuenumbernoItems still queued for extraction
gate_pass_ratenumbernoFraction of records passing the gate battery

2. lexicon — definition meter + dossier band machinery

Array of term objects.

fieldtyperequired?meaningconstraints / enum values
termstringyesThe lexical term being banded
systemstringnoBody system / domain the term belongs to
lonumberyesLower bound of the term's definition band0 ≤ value ≤ 100
hinumberyesUpper bound of the term's definition band0 ≤ value ≤ 100

3. records — full-fidelity StudyRecords (pydantic-generated shape, gate-audited)

Array of StudyRecord objects ($ref: #/$defs/StudyRecord). The design atom is the effect estimate, not the study: one StudyRecord holds N ExtractedOutcomes.

3.1 StudyRecord

fieldtyperequired?meaningconstraints / enum values
study_idstringyesCanonical study identifier, e.g. pmid:38412907pattern `^(pmiddoipreprint):`
titlestringyesArticle title
journalstring | nullno (default null)Journal name
yearintegeryesPublication year1900 ≤ year ≤ 2100
designStudyDesign enumyesStudy designrct, prospective_cohort, case_cohort, nested_case_control, case_control, cross_sectional, mendelian_randomization, ecological, other
populationPopulation objectyesStudied population (see 3.2)
funding_coiboolean | nullno (default null)Industry funding / declared conflict of interest
registrationstring | nullno (default null)Trial/protocol registration identifier
outcomesarray of ExtractedOutcomeyesAll extracted effect estimates from this article (see 3.5)minItems: 0 (empty array triggers gate G0-nonempty WARN)
extractionExtractionMeta objectyesExtraction provenance (see 3.6)

3.2 Population

fieldtyperequired?meaningconstraints / enum values
descriptionstringyesFree-text description of the population
n_totalintegeryesTotal participants> 0 (exclusiveMinimum: 0); gate G4 fails if n_cases > n_total
n_casesinteger | nullno (default null)Number of cases≥ 0
person_yearsnumber | nullno (default null)Total person-years of follow-up
followup_yearsnumber | nullno (default null)Follow-up duration in years
countrystring | nullno (default null)Country/countries of the cohort
sexstring | nullno (default null)Sex composition
age_rangestring | nullno (default null)Age range of participants

3.3 ExposureContrast — the contrast is first-class

"per 50 g/day" and "Q5 vs Q1" are different objects; per-unit slopes are impossible without typed contrasts.

fieldtyperequired?meaningconstraints / enum values
typeContrastType enumyesKind of exposure contrastper_unit, category_vs_reference, pattern_score, presence_vs_absence
labelstringyesVerbatim contrast, e.g. 'per 50 g/day', 'Q5 vs Q1'
unitstring | nullno (default null)Unit of the exposurerequired in practice for per_unit (gate G3 fails if missing)
amountnumber | nullno (default null)Per-unit amount, e.g. 50required in practice for per_unit (gate G3 fails if missing)
high_levelnumber | nullno (default null)Median intake in the high category, if reportedgate G3 WARNs on category_vs_reference without it (per-unit conversion blocked)
low_levelnumber | nullno (default null)Median intake in the reference category, if reported

3.4 EffectEstimate — every number is span-grounded

Values here are raw (as published)value, ci_low, ci_high are on the metric's natural scale (e.g. an RR of 1.14, not ln 1.14). The ln transform happens downstream in the flat outcomes rows.

fieldtyperequired?meaningconstraints / enum values
metricEffectMetric enumyesType of effect measureRR, OR, HR, IRR, PR, MD (mean difference), SMD (standardized mean difference), BETA (regression coefficient)
valuenumberyesPoint estimate, raw scalemust lie inside [ci_low, ci_high] (pydantic validator); ratio metrics (RR/OR/HR/IRR/PR) must be strictly positive
ci_lownumberyesLower confidence bound, raw scalesee above; ratio-metric CIs are checked for log-symmetry (gate G2)
ci_highnumberyesUpper confidence bound, raw scalesee above
ci_levelnumberno (default 0.95)Confidence level of the interval
p_valuenumber | nullno (default null)Reported p-value0 ≤ p ≤ 1
model_tierModelTier enumno (default maximal)Adjustment tier of the reported modelcrude, minimal, maximal
adjusted_forarray of stringno (default [])Covariates the model adjusted formediator terms (BMI, adiposity, …) trigger gate G6 WARN; energy covariates feed classify_energy
evidence_spanstringyesVerbatim sentence(s) from the source reporting this estimategate G5 verifies the span exists in the article AND that value/ci_low/ci_high appear inside it (deterministic, fail-closed)
energy_adjustedboolean | nullno (default null)Whether the model adjusted for total energy intakeauto-derived from adjusted_for when null
energy_scaleEnergyScale enumno (default unspecified)Scale of the exposure with respect to energyabsolute_intake (g/day, servings/day, mg/day), percent_energy (% of energy, %E), unspecified
effect_questionEffectQuestion enumno (default unspecified)Which scientific question the number answersabsolute (addition: energy not held constant), substitution (instead-of: energy held / % energy), unspecified; derived by classify_energy when not explicit — pooling substitution with absolute effects is the failure mode gate G8 exists to prevent
meta_acknowledged_energy_strategyboolean | nullno (default null)Did the including meta-analysis discuss energy-adjustment strategy?

3.5 ExtractedOutcome

fieldtyperequired?meaningconstraints / enum values
exposure_labelstringyesExposure as named in the source
exposure_refstring | nullno (default null)Ontology reference for the exposure, e.g. foodprov:ssb
outcome_labelstringyesOutcome/disease as named in the source
outcome_refstring | nullno (default null)Ontology reference for the outcome, e.g. mondo:0005148
contrastExposureContrast objectyesTyped exposure contrast (see 3.3)
effectEffectEstimate objectyesThe span-grounded estimate (see 3.4)a model validator re-runs classify_energy using the contrast label
subgroupstring | nullno (default null)Subgroup this estimate applies to, if any
is_primarybooleanno (default false)Whether this is the article's primary result

3.6 ExtractionMeta

fieldtyperequired?meaningconstraints / enum values
extractorstringyesIdentifier of the extractor (model/pipeline) that produced the record
confidencenumberyesExtractor's self-reported confidence0 ≤ value ≤ 1
needs_reviewbooleanno (default false)Whether the record is flagged for human review
review_reasonsarray of stringno (default [])Reasons the record needs review

4. outcomes — flat per-effect rows the UIs consume directly (log scale)

Array of rows derived from records; feeds the hub ledger and dossier. Required top-level section.

Scale note: y (and dose-point y) are ln(effect) for ratio metrics (RR/OR/HR/IRR/PR); se is on that same ln scale. By contrast, effect, ci_lo, ci_hi are the raw published values for display.

fieldtyperequired?meaningconstraints / enum values
outcome_idstringyesUnique row identifier
study_idstringnoSource study identifier
pmidstringnoPubMed ID
doistringnoDOI
exposurestringyesExposure name
diseasestringyesOutcome/disease name
metricstring enumyesEffect measure typeBETA, HR, IRR, MD, OR, PR, RR, SMD
ynumberyesEffect on the analysis scale — ln(effect) for ratio metrics
senumberyesStandard error of y (ln scale for ratio metrics)> 0 (exclusiveMinimum: 0)
designstring enumyesStudy designcase_cohort, case_control, cross_sectional, ecological, mendelian_randomization, nested_case_control, other, prospective_cohort, rct
contrast_typestring enumnoKind of exposure contrastcategory_vs_reference, pattern_score, per_unit, presence_vs_absence
model_tierstring enumnoAdjustment tiercrude, maximal, minimal
def_termstringnoLexicon term this row's definition maps to
def_lonumbernoLower definition-band bound for this row
def_hinumbernoUpper definition-band bound for this row
dosearray of objectnoDose–response pointseach point requires x (number) and y (number, ln scale for ratio metrics); optional se (number)
triagestring enumyesGate-battery verdict for the source recordGOLD (all gates clean), REVIEW (any WARN), QUARANTINE (any hard FAIL)
flagsarray of stringnoGate/quality flags attached to the row
evidence_spanstringnoVerbatim source sentence backing the number
claim_idstringnoID of the graded claim (association) this row supports
titlestringnoArticle title
yearintegernoPublication year
nintegernoSample size
effectnumbernoPoint estimate on the raw (published) scale
ci_lonumbernoCI lower bound, raw scale
ci_hinumbernoCI upper bound, raw scale
contrast_labelstringnoVerbatim contrast, e.g. per 50 g/day
energy_adjustedboolean | nullnoWhether the model adjusted for total energy
energy_scalestring enumnoExposure scale w.r.t. energyabsolute_intake, percent_energy, unspecified
effect_questionstring enumnoAbsolute vs substitution questionabsolute, substitution, unspecified
meta_acknowledged_energy_strategyboolean | nullnoDid the including meta discuss energy-adjustment strategy?
is_metabooleannoRow comes from a meta-analysis
effect_textstringnoHuman-readable effect statement
foodsarray of stringnoFood tags for the row
nutrientsarray of stringnoNutrient tags for the row
evidence_tierstringnoEvidence-tier label
journalstringnoJournal name
whostringnoPopulation descriptor (who was studied)
mechanismstringnoLinked mechanism label
populationstringnoPopulation description
confidencenumbernoExtraction confidence

5. associations — ledger row spine (also in the contract)

One graded claim per row, with a lead estimate only when effect_question is homogeneous across contributing rows.

fieldtyperequired?meaningconstraints / enum values
idstringyesAssociation/claim identifier
exposurestringyesExposure name
diseasestringyesOutcome/disease name
metricstring enumnoLead-estimate metricBETA, HR, IRR, MD, OR, PR, RR, SMD
effectnumbernoLead pooled estimate (raw scale)present only when effect_question is homogeneous
lonumbernoLead-estimate CI lower bound
hinumbernoLead-estimate CI upper bound
unitstringnoUnit of the lead contrast
kintegernoNumber of contributing studies/estimates≥ 0
NintegernoTotal participants across contributing studies≥ 0
gradestring enumyesEvidence gradeHIGH, MOD, LOW, VLOW
i2numbernoHeterogeneity (I²)
dirstring enumnoDirection of associationprot (protective), harm (harmful)
contestedbooleannoWhether the claim is contested
flagstringnoCaveat flag
verdictstringnoNarrative verdict
gapstringnoIdentified evidence gap
systemstringnoBody system / domain
effect_questionstring enumnoQuestion the pooled estimate answersabsolute, substitution, unspecified
effect_question_mixbooleannoTrue when contributing rows mix absolute and substitution questions (no lead estimate)
claim_gradestringnoClaim-level grade label

6. feed — activity/update feed (also in the contract)

fieldtyperequired?meaningconstraints / enum values
tstringyesTimestamp/date of the feed item
assocstringyesAssociation ID the item refers to
titlestringyesFeed-item headline
srcstringnoSource reference
outstringnoOutcome/result note
tagsarray of array of stringnoTag pairs/tuples for the iteminner items are arrays of strings

7. mechanisms — typed edges (dossier inner-workings, mermaid/graph exports)

fieldtyperequired?meaningconstraints / enum values
subjectstringyesEdge subject (source node)
relationstringyesTyped relation between subject and object
objectstringyesEdge object (target node)
systemstringnoBody system / domain of the edge
evidence_classstring enumyesHow the edge is evidencedMEASURED, INFERRED, CITED
kintegernoNumber of supporting sources≥ 1
statusstring enumnoStanding of the mechanism claimSUPPORTED, PROVISIONAL, CONTESTED

8. promises — 2030 tracker register (non-literature source: NCHS/ODPHP)

fieldtyperequired?meaningconstraints / enum values
idstringyesTracker identifier
codestringnoExternal code (e.g. Healthy People 2030 objective code)
namestringyesHuman-readable indicator name
unitstringyesMeasurement unit of the indicator
basearray of numberyesBaseline point as [year, value]exactly 2 items (minItems: 2, maxItems: 2)
curarray of numberyesCurrent point as [year, value]exactly 2 items
targetnumber | nullno2030 target valuenullable
ghostbooleannoWhether the target/indicator is a "ghost" (e.g. dropped or unofficial)
seriesarray of arraysyesFull time series of [year, value] pairseach inner array exactly 2 numbers
knowledgeobjectnoFree-form knowledge/annotation blobunconstrained object

Appendix A — Complete enum reference

enumvaluessource
EffectMetricRR, OR, HR, IRR, PR, MD (mean difference), SMD (standardized mean difference), BETA (regression coefficient)outcome_schema.EffectMetric; ratio metrics = {RR, OR, HR, IRR, PR}
StudyDesignrct, prospective_cohort, case_cohort, nested_case_control, case_control, cross_sectional, mendelian_randomization, ecological, otheroutcome_schema.StudyDesign; observational = {prospective_cohort, case_cohort, nested_case_control, case_control, cross_sectional, ecological}; time-to-event = {rct, prospective_cohort, case_cohort, nested_case_control}
ContrastTypeper_unit (e.g. per 50 g/day), category_vs_reference (e.g. Q5 vs Q1), pattern_score (e.g. DASH score, per point/quintile), presence_vs_absenceoutcome_schema.ContrastType
ModelTiercrude, minimal, maximal (default)outcome_schema.ModelTier
EnergyScaleabsolute_intake, percent_energy, unspecified (default)outcome_schema.EnergyScale
EffectQuestionabsolute, substitution, unspecified (default)outcome_schema.EffectQuestion
GateStatusPASS, WARN, FAILoutcome_schema.GateStatus — per-gate result status in the gate battery (G0 nonempty, G1 CI, G2 log-symmetry, G3 contrast completeness, G4 population, G5 span grounding, G6 mediator, G7 design–metric coherence, G8 energy question); not serialized in the payload itself but determines triage and flags
triageGOLD (all gates clean), REVIEW (any WARN, no FAIL), QUARANTINE (any hard FAIL — fail-closed, never silently dropped or admitted)outcome_schema.triage(); appears as outcomes[].triage
associations.gradeHIGH, MOD, LOW, VLOWcontract-defined
associations.dirprot, harmcontract-defined
mechanisms.evidence_classMEASURED, INFERRED, CITEDcontract-defined
mechanisms.statusSUPPORTED, PROVISIONAL, CONTESTEDcontract-defined

Appendix B — ln-scale vs raw-scale fields

fieldscale
outcomes[].yln(effect) for ratio metrics (RR/OR/HR/IRR/PR); raw for MD/SMD/BETA
outcomes[].sestandard error on the same scale as y (ln scale for ratio metrics; derived as (ln ci_high − ln ci_low)/(2z) for ratio metrics, (ci_high − ci_low)/(2z) otherwise)
outcomes[].dose[].y (and .se)same convention as y
outcomes[].effect, ci_lo, ci_hiraw published scale (for display)
records[].outcomes[].effect.value, ci_low, ci_highraw published scale (validated: point inside CI; ratio metrics strictly positive; ratio CIs checked for log-symmetry)
associations[].effect, lo, hiraw scale (lead estimate)

Appendix C — Generation pipeline

export_contract.py (in files (12)/) imports StudyRecord, EffectMetric, StudyDesign, ContrastType, ModelTier, EffectQuestion, and EnergyScale directly from model set 2/outcome_schema.py, builds the contract dict with enum lists computed live from those Python enums, then embeds StudyRecord.model_json_schema(ref_template="#/$defs/{model}") into $defs (pulling in Population, ExposureContrast, EffectEstimate, ExtractedOutcome, ExtractionMeta, and the enum defs). Running it writes platform-data.schema.json. Because every enum and the entire record shape are emitted from the enforcing code, regenerating the schema after any model change keeps this dictionary's source of truth in lockstep — the contract cannot drift from the code that enforces it.

Source files:

Hub-side registers (client JS, demo-labeled)

The dashboard's own small registers live inline in evidence-hub-v2.html; each is one array or map, designed for real data to drop in without touching rendering.

registershapefeeds
DEEDS{y, n, k: study|law|program|commit, st: done|inflight|superseded|unmeasured, h:[money-rank indices], note}deeds timeline · intended-impact matrix · deed modal
MONEY[name, percent] — shares of COST_PER_YEAR, must sum to 100cost strip · ticker decomposition · impact footer money order
DBM_BURDEN{disease: {stock, flow}} — living affected vs deaths/yrDiseases tab affected/deaths line
DBM_IMPACT{disease: millions} — barometer impact componentSuccess Prediction Barometer score
OUTCOME_GROUPS{name, re} — first-match keyword taxonomy; unknowns → OtherHealth-outcomes filter + tab grouping
BUZZWORDS{v: verb, t: target, g: outcome group} — 120 demo phrasesClaim-language panel
WB_ROWS{s, k: kind, cov, vol, ph: 1–4, out}Workbench ingestion plan
LCD_DATA{year: [[cause, per100k, dietFraction]]}Leading-causes chart (overall vs diet-attributable)

Every register is demo-labeled in the UI and routes through the verification queue before public claims.

ONTOLOGY

How NutriCollective grounds its data in public biomedical ontologies: a five-layer causal spine of curated OBO terms, a small RO relation vocabulary, a SEPIO-profiled evidence-tie schema, and per-row CURIE stamps on principle records.

Sources: nutri-collective/backend/bfo_stack_ontology.json, nutri-collective/ontology.md, nutri-collective/fim-evidence-tool/src/schemas/fim.tie.sepio-profile.json, nutri-collective/backend/principles.json.

The L1–L5 causal spine

Defined in backend/bfo_stack_ontology.json (method: "BFO-grounded 5-layer stack terms (FOODON→ChEBI→GO/Reactome/Rhea→GO:BP/PATO→MONDO/DOID/HPO) + RO relations + expert-priority nutrition mechanisms. Curated seeds for graph/DB — not a full OWL import.").

LayerTitleOntologiesRole (BFO grounding)
L1FoodFOODONThe edible entity itself (BFO material entity · edible product) — e.g. FOODON:03312087 salmon (raw)
L2Nutrient compoundChEBIThe nutrient molecule (BFO molecular entity) — e.g. CHEBI:28364 icosapentaenoic acid
L3Biochemical mechanismGO:MF · Reactome · RheaMolecular activity / pathway occurrent — e.g. GO:0016165 lipoxygenase activity, R-HSA-9018678 Biosynthesis of SPMs, RHEA:17929 fatty-acid oxygenation
L4Physiological effectGO:BP · PATOBiological process / quality — e.g. GO:0042593 glucose homeostasis, PATO:0000467 abnormal inflammatory response
L5Health outcomeMONDO · DOID · HPODisease / phenotype disposition — e.g. MONDO:0005148 type 2 diabetes mellitus, HP:0002155 Hypertriglyceridemia
RORelationsROObject properties connecting the layers, GO-CAM style
ANATOMY(auxiliary)UBERON, GO:CCCascade organs/compartments — UBERON:0002107 liver, UBERON:0002108 small intestine, GO:0005739 mitochondrion

Curation posture (from the file's expert_recommendations): MONDO is primary at L5 (HPO for signs, DOID as crosswalk); prefer specific ChEBI IDs (EPA CHEBI:28364 / DHA CHEBI:28125) over class proxies; do not bulk-load GO — ~50–200 curated terms on causal paths, not a 40k dump; Reactome for multi-step human pathway "story," Rhea for single-reaction stoichiometry.

License posture (from ontology.md)

ontology.md records the L3 pathway-source decision for a commercial product:

Relation vocabulary (RO)

Eight RO object properties are seeded in bfo_stack_ontology.json (obo_layer: "RO"), all in_demo_stack: true:

CURIELabel
RO:0002180has component
RO:0000057has participant
RO:0002327enables
RO:0002411causally upstream of
RO:0002213positively regulates
RO:0002212negatively regulates
RO:0002326contributes to
RO:0002200has phenotype

Edge-strength rule (expert rec #6): the same relation type carries different evidence strength per outcome — RO:0002326 contributes to can be strong for CVD and contested for depression — so strength lives as a graph-edge attribute, never as a global grade on the relation type.

The SEPIO tie profile

fim-evidence-tool/src/schemas/fim.tie.sepio-profile.json ($id: bac.fim.tie.sepio-profile/v0, title FimTie) is a SEPIO profile for a Food-is-Medicine isolate↔claim tie: match is GRADE indirectness over four FIM axes, design is a NutriGRADE-shaped quality composite, and sure = match × design. A match of 0 means unlinkable, not a low weight.

SEPIO anchor fields (required unless noted):

pico — closed codes on both sides of the tie (OPEN if a side is uncoded; "never invent a match"): study_endpoint/claim_endpoint (enum EndpointCode: EnergyIntake, BodyWeight, HbA1c, FoodInsecurity, CVDMortality, CVDEvent, ObesityPrevalence, AllCauseMortality, SupplyPrevalence, TissueBurden, Type2Diabetes, Hypertension, Anxiety), study_exposure/claim_exposure (enum ExposureSystem: NOVA, HPF, SIGA, UNC, IARC, CHIPS, MNP, UNSTATED), study_layer/claim_layer (enum BindLayer: PACKET, INGESTION, HOST, CLINICAL, ORGANISM, SURFACE), plus free-text contrast.

match (required) — GRADE indirectness over the four FIM axes endpoint, contrast, exposure, layer, each a MatchLevel (0 | 0.5 | 1 — "1 same strain · 0.5 OPEN/partial · 0 no edge"); value is the min of the axes; a why object holds per-axis rationale strings. value = 0 ⇒ no sepio:EvidenceLine is emitted.

design (required) — NutriGRADE-shaped quality: value (0–1), edp_grade (A/B/C/D/OPEN), n_factor, deviation_penalty, provenance (high/moderate/low/unknown), causal_tier (1 ward/interventional · 2 cohort/umbrella), structure_layer (ANALYTE/MATRIX/TELEMETRY), gated + gate_why; optional full nutrigrade card (risk_of_bias, precision, heterogeneity, directness, publication_bias, funding_bias, study_design, effect_size, dose_response, total 0–10, band high/moderate/low/very_low) when a meta-analysis is the isolate.

sure (required, 0–1) — match.value × design.value, the posterior that this isolate belongs on this assertion. unlinkable — true iff match.value === 0. contribution — the sepio contribution: direction (supports/refutes/neutral), weight, and score (= weight × sure; 0 if unlinkable).

Companion packet schemas in the same directory (fim-evidence-tool/src/schemas/) define the workspace objects the ties bind: food.packet.schema.json (bac.fim.packet.food/v1 — id, kind, label, processing "whole vs extruded is the difference Hall measured", amount, nutrients "Analyte layer. Useful, never sufficient.", matrixNotes, provenanceId), provenance.packet.schema.json (bac.fim.packet.provenance/v1 — source, quality enum high/moderate/low/unknown, collectionMethod, collectedAt; "Downstream packets inherit this join"), plus env.packet, meal.packet, user.packet, food_packet.bac, and the runtime schemas PacketLoad, IngestionEvent, HostState, DigestRun.

How principles.json rows carry CURIEs

Each principle in backend/principles.json is a curated physiological pathway statement (with pillar PMIDs) that carries an ontology block mapping it onto the spine:

```json

"ontology": {

"mapped": true,

"method": "human-seed-v1+bfo-stack",

"terms": [

{ "curie": "GO:0019825", "label": "oxygen binding", "source": "go_mf", "obo_layer": "L3", "iri": "http://purl.obolibrary.org/obo/GO_0019825" },

{ "curie": "GO:0015671", "label": "oxygen transport","source": "go_bp", "obo_layer": "L4", "iri": "http://purl.obolibrary.org/obo/GO_0015671" },

{ "curie": "R-HSA-1237044","label": "Erythrocytes take up oxygen and release carbon dioxide", "source": "reactome", "obo_layer": "L3", "iri": "https://reactome.org/content/detail/R-HSA-1237044" },

{ "curie": "CHEBI:18248", "label": "iron atom", "source": "chebi", "obo_layer": "L2", "iri": "http://purl.obolibrary.org/obo/CHEBI_18248" },

{ "curie": "UBERON:0002107","label": "liver", "source": "uberon", "obo_layer": "ANATOMY", "iri": "http://purl.obolibrary.org/obo/UBERON_0002107" }

]

}

```

Every term entry has four required stamps plus the IRI: curie (the compact identifier), label (human-readable name), source (lowercase provider slug: foodon, chebi, go_mf, go_bp, go_cc, reactome, rhea, pato, mondo, doid, hpo, ro, uberon), obo_layer (which spine layer the term occupies: L1L5, RO, or ANATOMY), and iri (OBO PURL, or the provider's detail URL for Reactome/Rhea). The mapped: true / method: "human-seed-v1+bfo-stack" pair records that the mapping was human-curated against the BFO stack, not machine-generated — the same shape used by the master term list in bfo_stack_ontology.json, where entries additionally carry id, optional stack_node, in_demo_stack, priority: "expert", and notes.

Generated from the living contract (export_contract.pyplatform-data.schema.json) and the repository's ontology sources. Regenerate this page whenever the contract version bumps.