How these docs are layered
| layer | what it is | where it lives |
|---|---|---|
| Data type | the raw material of a single field — string, number, boolean, array | inside every schema below |
| Schema | the structure of one object — a StudyRecord, an EffectEstimate, an association row | outcome_schema.py (pydantic, the enforcing code) |
| JSON Schema (machine-readable docs) | the spec-driven contract — validates every payload the pipelines emit | platform-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 constraints | docs.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.pybuildsplatform-data.schema.jsonprogrammatically. Enums are pulled live fromoutcome_schema.py(enum = lambda E: sorted(e.value for e in E)), and the full-fidelityStudyRecordshape is embedded verbatim from pydantic's ownStudyRecord.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.
| field | type | required? | meaning | constraints / enum values |
|---|---|---|---|---|
corpus_version | string | yes | Version identifier of the evidence corpus this payload was built from | — |
generated_at | string | yes | Date the payload was generated | format: date |
extractor_version | string | no | Version of the extraction pipeline that produced the records | — |
source | string | no | Where the corpus came from | — |
counts | object | yes | Corpus size summary | keys below; all optional within counts |
counts.studies | number | no | Number of studies in the payload | — |
counts.outcomes | number | no | Number of flat outcome rows | — |
counts.mechanisms | number | no | Number of mechanism edges | — |
counts.claims | number | no | Number of graded claims | — |
counts.pubmed_slice | number | no | Size of the PubMed slice considered | — |
counts.extractor_queue | number | no | Items still queued for extraction | — |
gate_pass_rate | number | no | Fraction of records passing the gate battery | — |
2. lexicon — definition meter + dossier band machinery
Array of term objects.
| field | type | required? | meaning | constraints / enum values |
|---|---|---|---|---|
term | string | yes | The lexical term being banded | — |
system | string | no | Body system / domain the term belongs to | — |
lo | number | yes | Lower bound of the term's definition band | 0 ≤ value ≤ 100 |
hi | number | yes | Upper bound of the term's definition band | 0 ≤ 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
| field | type | required? | meaning | constraints / enum values | ||
|---|---|---|---|---|---|---|
study_id | string | yes | Canonical study identifier, e.g. pmid:38412907 | pattern `^(pmid | doi | preprint):` |
title | string | yes | Article title | — | ||
journal | string | null | no (default null) | Journal name | — | ||
year | integer | yes | Publication year | 1900 ≤ year ≤ 2100 | ||
design | StudyDesign enum | yes | Study design | rct, prospective_cohort, case_cohort, nested_case_control, case_control, cross_sectional, mendelian_randomization, ecological, other | ||
population | Population object | yes | Studied population (see 3.2) | — | ||
funding_coi | boolean | null | no (default null) | Industry funding / declared conflict of interest | — | ||
registration | string | null | no (default null) | Trial/protocol registration identifier | — | ||
outcomes | array of ExtractedOutcome | yes | All extracted effect estimates from this article (see 3.5) | minItems: 0 (empty array triggers gate G0-nonempty WARN) | ||
extraction | ExtractionMeta object | yes | Extraction provenance (see 3.6) | — |
3.2 Population
| field | type | required? | meaning | constraints / enum values |
|---|---|---|---|---|
description | string | yes | Free-text description of the population | — |
n_total | integer | yes | Total participants | > 0 (exclusiveMinimum: 0); gate G4 fails if n_cases > n_total |
n_cases | integer | null | no (default null) | Number of cases | ≥ 0 |
person_years | number | null | no (default null) | Total person-years of follow-up | — |
followup_years | number | null | no (default null) | Follow-up duration in years | — |
country | string | null | no (default null) | Country/countries of the cohort | — |
sex | string | null | no (default null) | Sex composition | — |
age_range | string | null | no (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.
| field | type | required? | meaning | constraints / enum values |
|---|---|---|---|---|
type | ContrastType enum | yes | Kind of exposure contrast | per_unit, category_vs_reference, pattern_score, presence_vs_absence |
label | string | yes | Verbatim contrast, e.g. 'per 50 g/day', 'Q5 vs Q1' | — |
unit | string | null | no (default null) | Unit of the exposure | required in practice for per_unit (gate G3 fails if missing) |
amount | number | null | no (default null) | Per-unit amount, e.g. 50 | required in practice for per_unit (gate G3 fails if missing) |
high_level | number | null | no (default null) | Median intake in the high category, if reported | gate G3 WARNs on category_vs_reference without it (per-unit conversion blocked) |
low_level | number | null | no (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.
| field | type | required? | meaning | constraints / enum values |
|---|---|---|---|---|
metric | EffectMetric enum | yes | Type of effect measure | RR, OR, HR, IRR, PR, MD (mean difference), SMD (standardized mean difference), BETA (regression coefficient) |
value | number | yes | Point estimate, raw scale | must lie inside [ci_low, ci_high] (pydantic validator); ratio metrics (RR/OR/HR/IRR/PR) must be strictly positive |
ci_low | number | yes | Lower confidence bound, raw scale | see above; ratio-metric CIs are checked for log-symmetry (gate G2) |
ci_high | number | yes | Upper confidence bound, raw scale | see above |
ci_level | number | no (default 0.95) | Confidence level of the interval | — |
p_value | number | null | no (default null) | Reported p-value | 0 ≤ p ≤ 1 |
model_tier | ModelTier enum | no (default maximal) | Adjustment tier of the reported model | crude, minimal, maximal |
adjusted_for | array of string | no (default []) | Covariates the model adjusted for | mediator terms (BMI, adiposity, …) trigger gate G6 WARN; energy covariates feed classify_energy |
evidence_span | string | yes | Verbatim sentence(s) from the source reporting this estimate | gate G5 verifies the span exists in the article AND that value/ci_low/ci_high appear inside it (deterministic, fail-closed) |
energy_adjusted | boolean | null | no (default null) | Whether the model adjusted for total energy intake | auto-derived from adjusted_for when null |
energy_scale | EnergyScale enum | no (default unspecified) | Scale of the exposure with respect to energy | absolute_intake (g/day, servings/day, mg/day), percent_energy (% of energy, %E), unspecified |
effect_question | EffectQuestion enum | no (default unspecified) | Which scientific question the number answers | absolute (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_strategy | boolean | null | no (default null) | Did the including meta-analysis discuss energy-adjustment strategy? | — |
3.5 ExtractedOutcome
| field | type | required? | meaning | constraints / enum values |
|---|---|---|---|---|
exposure_label | string | yes | Exposure as named in the source | — |
exposure_ref | string | null | no (default null) | Ontology reference for the exposure, e.g. foodprov:ssb | — |
outcome_label | string | yes | Outcome/disease as named in the source | — |
outcome_ref | string | null | no (default null) | Ontology reference for the outcome, e.g. mondo:0005148 | — |
contrast | ExposureContrast object | yes | Typed exposure contrast (see 3.3) | — |
effect | EffectEstimate object | yes | The span-grounded estimate (see 3.4) | a model validator re-runs classify_energy using the contrast label |
subgroup | string | null | no (default null) | Subgroup this estimate applies to, if any | — |
is_primary | boolean | no (default false) | Whether this is the article's primary result | — |
3.6 ExtractionMeta
| field | type | required? | meaning | constraints / enum values |
|---|---|---|---|---|
extractor | string | yes | Identifier of the extractor (model/pipeline) that produced the record | — |
confidence | number | yes | Extractor's self-reported confidence | 0 ≤ value ≤ 1 |
needs_review | boolean | no (default false) | Whether the record is flagged for human review | — |
review_reasons | array of string | no (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.
| field | type | required? | meaning | constraints / enum values |
|---|---|---|---|---|
outcome_id | string | yes | Unique row identifier | — |
study_id | string | no | Source study identifier | — |
pmid | string | no | PubMed ID | — |
doi | string | no | DOI | — |
exposure | string | yes | Exposure name | — |
disease | string | yes | Outcome/disease name | — |
metric | string enum | yes | Effect measure type | BETA, HR, IRR, MD, OR, PR, RR, SMD |
y | number | yes | Effect on the analysis scale — ln(effect) for ratio metrics | — |
se | number | yes | Standard error of y (ln scale for ratio metrics) | > 0 (exclusiveMinimum: 0) |
design | string enum | yes | Study design | case_cohort, case_control, cross_sectional, ecological, mendelian_randomization, nested_case_control, other, prospective_cohort, rct |
contrast_type | string enum | no | Kind of exposure contrast | category_vs_reference, pattern_score, per_unit, presence_vs_absence |
model_tier | string enum | no | Adjustment tier | crude, maximal, minimal |
def_term | string | no | Lexicon term this row's definition maps to | — |
def_lo | number | no | Lower definition-band bound for this row | — |
def_hi | number | no | Upper definition-band bound for this row | — |
dose | array of object | no | Dose–response points | each point requires x (number) and y (number, ln scale for ratio metrics); optional se (number) |
triage | string enum | yes | Gate-battery verdict for the source record | GOLD (all gates clean), REVIEW (any WARN), QUARANTINE (any hard FAIL) |
flags | array of string | no | Gate/quality flags attached to the row | — |
evidence_span | string | no | Verbatim source sentence backing the number | — |
claim_id | string | no | ID of the graded claim (association) this row supports | — |
title | string | no | Article title | — |
year | integer | no | Publication year | — |
n | integer | no | Sample size | — |
effect | number | no | Point estimate on the raw (published) scale | — |
ci_lo | number | no | CI lower bound, raw scale | — |
ci_hi | number | no | CI upper bound, raw scale | — |
contrast_label | string | no | Verbatim contrast, e.g. per 50 g/day | — |
energy_adjusted | boolean | null | no | Whether the model adjusted for total energy | — |
energy_scale | string enum | no | Exposure scale w.r.t. energy | absolute_intake, percent_energy, unspecified |
effect_question | string enum | no | Absolute vs substitution question | absolute, substitution, unspecified |
meta_acknowledged_energy_strategy | boolean | null | no | Did the including meta discuss energy-adjustment strategy? | — |
is_meta | boolean | no | Row comes from a meta-analysis | — |
effect_text | string | no | Human-readable effect statement | — |
foods | array of string | no | Food tags for the row | — |
nutrients | array of string | no | Nutrient tags for the row | — |
evidence_tier | string | no | Evidence-tier label | — |
journal | string | no | Journal name | — |
who | string | no | Population descriptor (who was studied) | — |
mechanism | string | no | Linked mechanism label | — |
population | string | no | Population description | — |
confidence | number | no | Extraction 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.
| field | type | required? | meaning | constraints / enum values |
|---|---|---|---|---|
id | string | yes | Association/claim identifier | — |
exposure | string | yes | Exposure name | — |
disease | string | yes | Outcome/disease name | — |
metric | string enum | no | Lead-estimate metric | BETA, HR, IRR, MD, OR, PR, RR, SMD |
effect | number | no | Lead pooled estimate (raw scale) | present only when effect_question is homogeneous |
lo | number | no | Lead-estimate CI lower bound | — |
hi | number | no | Lead-estimate CI upper bound | — |
unit | string | no | Unit of the lead contrast | — |
k | integer | no | Number of contributing studies/estimates | ≥ 0 |
N | integer | no | Total participants across contributing studies | ≥ 0 |
grade | string enum | yes | Evidence grade | HIGH, MOD, LOW, VLOW |
i2 | number | no | Heterogeneity (I²) | — |
dir | string enum | no | Direction of association | prot (protective), harm (harmful) |
contested | boolean | no | Whether the claim is contested | — |
flag | string | no | Caveat flag | — |
verdict | string | no | Narrative verdict | — |
gap | string | no | Identified evidence gap | — |
system | string | no | Body system / domain | — |
effect_question | string enum | no | Question the pooled estimate answers | absolute, substitution, unspecified |
effect_question_mix | boolean | no | True when contributing rows mix absolute and substitution questions (no lead estimate) | — |
claim_grade | string | no | Claim-level grade label | — |
6. feed — activity/update feed (also in the contract)
| field | type | required? | meaning | constraints / enum values |
|---|---|---|---|---|
t | string | yes | Timestamp/date of the feed item | — |
assoc | string | yes | Association ID the item refers to | — |
title | string | yes | Feed-item headline | — |
src | string | no | Source reference | — |
out | string | no | Outcome/result note | — |
tags | array of array of string | no | Tag pairs/tuples for the item | inner items are arrays of strings |
7. mechanisms — typed edges (dossier inner-workings, mermaid/graph exports)
| field | type | required? | meaning | constraints / enum values |
|---|---|---|---|---|
subject | string | yes | Edge subject (source node) | — |
relation | string | yes | Typed relation between subject and object | — |
object | string | yes | Edge object (target node) | — |
system | string | no | Body system / domain of the edge | — |
evidence_class | string enum | yes | How the edge is evidenced | MEASURED, INFERRED, CITED |
k | integer | no | Number of supporting sources | ≥ 1 |
status | string enum | no | Standing of the mechanism claim | SUPPORTED, PROVISIONAL, CONTESTED |
8. promises — 2030 tracker register (non-literature source: NCHS/ODPHP)
| field | type | required? | meaning | constraints / enum values |
|---|---|---|---|---|
id | string | yes | Tracker identifier | — |
code | string | no | External code (e.g. Healthy People 2030 objective code) | — |
name | string | yes | Human-readable indicator name | — |
unit | string | yes | Measurement unit of the indicator | — |
base | array of number | yes | Baseline point as [year, value] | exactly 2 items (minItems: 2, maxItems: 2) |
cur | array of number | yes | Current point as [year, value] | exactly 2 items |
target | number | null | no | 2030 target value | nullable |
ghost | boolean | no | Whether the target/indicator is a "ghost" (e.g. dropped or unofficial) | — |
series | array of arrays | yes | Full time series of [year, value] pairs | each inner array exactly 2 numbers |
knowledge | object | no | Free-form knowledge/annotation blob | unconstrained object |
Appendix A — Complete enum reference
| enum | values | source |
|---|---|---|
| EffectMetric | RR, OR, HR, IRR, PR, MD (mean difference), SMD (standardized mean difference), BETA (regression coefficient) | outcome_schema.EffectMetric; ratio metrics = {RR, OR, HR, IRR, PR} |
| StudyDesign | rct, prospective_cohort, case_cohort, nested_case_control, case_control, cross_sectional, mendelian_randomization, ecological, other | outcome_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} |
| ContrastType | per_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_absence | outcome_schema.ContrastType |
| ModelTier | crude, minimal, maximal (default) | outcome_schema.ModelTier |
| EnergyScale | absolute_intake, percent_energy, unspecified (default) | outcome_schema.EnergyScale |
| EffectQuestion | absolute, substitution, unspecified (default) | outcome_schema.EffectQuestion |
| GateStatus | PASS, WARN, FAIL | outcome_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 |
| triage | GOLD (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.grade | HIGH, MOD, LOW, VLOW | contract-defined |
| associations.dir | prot, harm | contract-defined |
| mechanisms.evidence_class | MEASURED, INFERRED, CITED | contract-defined |
| mechanisms.status | SUPPORTED, PROVISIONAL, CONTESTED | contract-defined |
Appendix B — ln-scale vs raw-scale fields
| field | scale |
|---|---|
outcomes[].y | ln(effect) for ratio metrics (RR/OR/HR/IRR/PR); raw for MD/SMD/BETA |
outcomes[].se | standard 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_hi | raw published scale (for display) |
records[].outcomes[].effect.value, ci_low, ci_high | raw published scale (validated: point inside CI; ratio metrics strictly positive; ratio CIs checked for log-symmetry) |
associations[].effect, lo, hi | raw 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:
/Users/morf/Downloads/morf-engineering/mealcoachai/dev/NUTRI-COLLECTIVE_0/nutri-collective/model test evidence tool 2/files (12)/platform-data.schema.json/Users/morf/Downloads/morf-engineering/mealcoachai/dev/NUTRI-COLLECTIVE_0/nutri-collective/model test evidence tool 2/files (12)/export_contract.py/Users/morf/Downloads/morf-engineering/mealcoachai/dev/NUTRI-COLLECTIVE_0/nutri-collective/model test evidence tool 2/model set 2/outcome_schema.py
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.
| register | shape | feeds |
|---|---|---|
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 100 | cost strip · ticker decomposition · impact footer money order |
DBM_BURDEN | {disease: {stock, flow}} — living affected vs deaths/yr | Diseases tab affected/deaths line |
DBM_IMPACT | {disease: millions} — barometer impact component | Success Prediction Barometer score |
OUTCOME_GROUPS | {name, re} — first-match keyword taxonomy; unknowns → Other | Health-outcomes filter + tab grouping |
BUZZWORDS | {v: verb, t: target, g: outcome group} — 120 demo phrases | Claim-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.").
| Layer | Title | Ontologies | Role (BFO grounding) |
|---|---|---|---|
| L1 | Food | FOODON | The edible entity itself (BFO material entity · edible product) — e.g. FOODON:03312087 salmon (raw) |
| L2 | Nutrient compound | ChEBI | The nutrient molecule (BFO molecular entity) — e.g. CHEBI:28364 icosapentaenoic acid |
| L3 | Biochemical mechanism | GO:MF · Reactome · Rhea | Molecular activity / pathway occurrent — e.g. GO:0016165 lipoxygenase activity, R-HSA-9018678 Biosynthesis of SPMs, RHEA:17929 fatty-acid oxygenation |
| L4 | Physiological effect | GO:BP · PATO | Biological process / quality — e.g. GO:0042593 glucose homeostasis, PATO:0000467 abnormal inflammatory response |
| L5 | Health outcome | MONDO · DOID · HPO | Disease / phenotype disposition — e.g. MONDO:0005148 type 2 diabetes mellitus, HP:0002155 Hypertriglyceridemia |
| RO | Relations | RO | Object properties connecting the layers, GO-CAM style |
| ANATOMY | (auxiliary) | UBERON, GO:CC | Cascade 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:
- Reactome — CC0 / public domain. Already wired in (the
R-HSA-…CURIEs inprinciples.json). Keep and deepen. - Rhea — CC-BY, free; natively ChEBI-keyed. Scoped as the next L3 integration ("Reactome for story, Rhea for stoichiometry").
- KEGG — subscription required for bulk/commercial use; avoid embedding content. At most a nullable crosswalk xref (identifiers only, never the maps), per the G2 guardrail "No full-text redistribution unless the license allows."
- BioCyc / HumanCyc — subscription (paywalled) and redundant with Reactome+Rhea for human metabolism. Skip.
- Pathway Commons — free but inherits member licenses; Reactome-heavy aggregator. Curation-time lookup tool only, never ingested.
- Noted gap: no
LICENSEfile or per-source license manifest exists yet; adata/SOURCES.md(source → license → redistribution posture) is flagged as the prerequisite for mixing CC0 and CC-BY sources.
Relation vocabulary (RO)
Eight RO object properties are seeded in bfo_stack_ontology.json (obo_layer: "RO"), all in_demo_stack: true:
| CURIE | Label |
|---|---|
RO:0002180 | has component |
RO:0000057 | has participant |
RO:0002327 | enables |
RO:0002411 | causally upstream of |
RO:0002213 | positively regulates |
RO:0002212 | negatively regulates |
RO:0002326 | contributes to |
RO:0002200 | has 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):
schema— const"fim.tie/v0";id(optional) — stable tie id, usuallytie:{claim_id}:{study_id}assertion_id— the sepio:Assertion (workspaceClaim.id)evidence_item_id— the sepio:EvidenceItem (workspaceStudyOutcome.id)evidence_line_id(optional) — the sepio:EvidenceLine (workspaceWeightedEvidence.idonce the tie is saved)
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: L1–L5, 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.py → platform-data.schema.json) and the repository's ontology sources. Regenerate this page whenever the contract version bumps.