Skip to content

Evidence & nutrient density

Two things on this page are enforced by machines rather than promised by prose: every claim resolves to a real source, and every nutrient-density score is recomputed from its inputs at build time.

The audit that started it

Before the content pipeline existed, RAWLY's articles were generated the ordinary way. A source audit of those eight legacy articles found that the citations were not merely sloppy — they were invented:

[…] verification exposed systematic fabrication by the legacy generation: 4 hallucinated PMIDs pointing to unrelated papers, 1 nonexistent study, 1 invented author, and fabricated statistics even where a real study existed.

The failure mode worth understanding is the last clause. Where a real study existed, the numbers attached to it were still wrong:

Legacy article claimed The authority says
Citation de la O, Nutrients Nov 2024, PMID 39599604 de la O, Eur J Nutr 2022, PMID 34671828
What that PMID is an ML dietary-quality paper, unrelated the SUN cohort study actually described
Reported effect −26 % MACE, HR 0.74 (0.61–0.89) HR 0.45 (0.27–0.76), top vs bottom quintile

A reviewer checking that the PMID existed, or that the citation looked plausible, would have passed it. Both the identifier and the effect size were fabricated, in opposite directions from the truth.

What is enforced now

Every article and recipe passes a blocking gate before it ships (npm run validate:content), and the test suite encodes the invariants the audit exposed. These are verbatim test names from the suite:

  • a ref whose PMID is absent from sources[] failsno orphan proof link
  • a ref whose DOI is absent from sources[] failsDOI coverage, not just PMID
  • every claim is checked, not just the first
  • a recipe whose every ref resolves to sources[] passes
  • folder ↔ type mismatch is rejected

State of the repository as verified at v0.11.0:

Signal State
Content gate recipes 7 / 7 · articles 8 / 8 — passed
Test suite 172 passed, 0 failed
Scientific sources 33 distinct papers, listed across 40 source entries — 16 in the articles, 24 in the recipes — each carrying both a PMID and a DOI

Dual identifiers are the point: a PMID and a DOI can be cross-checked against each other, and the Fact-Checker resolves both, bidirectionally, from scratch.

Nutrient density

Recipes do not assert that they are nutritious. The score is computed from USDA FoodData Central entries, using NRF9.3 — a published, peer-reviewed index (Drewnowski 2005, PMID 16210699; validated in Fulgoni et al., J Nutr 2009, PMID 19549759):

NRF9.3 = Σ min(nutrient_i / DV_i, 1)·100
       − Σ (limit_j / MRV_j)·100

per 100 kcal of the recipe.

The first sum runs over the nine nutrients to encourage, each capped at 100 % DV. The second runs over the three to limit — saturated fat, added sugars, sodium — which are uncapped. Daily Values come from the FDA 2016 final rule (21 CFR 101.9), cross-checked against fda.gov. The cap is what stops a single fortified ingredient from buying an arbitrarily high score.

The score is not forgeable

The content JSON stores the computed nutrition.density block — but the build guard recomputes the score from the stored micronutrients and rejects the file if the two disagree. A hand-edited score fails the gate.

The reconciliation gate

Micronutrients are reconstructed through an independent ingredient → FDC path, then the reconstructed macros are compared against the recipe's authored macros. Tolerance is ±10 %, gated on kcal, protein and carb.

Fat is reported but not gated, deliberately: in oil-dressed dishes, fat is dominated by discretionary added culinary oil, counted at 100 % of the stated amount — a pure-fat entry times a stated quantity, with near-zero mapping uncertainty. Gating it at ±10 % would flag a culinary convention, not a mapping error. The kcal gate backstops it anyway: a grossly wrong fat mapping would blow the energy total.

A published score, verbatim

Verbatim excerpt from content/recipes/dishes/herb-roasted-chicken-thighs.json, the recipe the method was piloted on:

{
  "nrf93": 69.1,
  "kcal_basis": 972,
  "coverage": 0.96,
  "reconciliation": {
    "kcal_delta_pct": 5.9,
    "protein_delta_pct": -5.5,
    "fat_delta_pct": 20.1,
    "carb_delta_pct": 3.6,
    "passed": true
  },
  "method_version": "nrf9.3-fda2016-v1",
  "status": "published"
}

The three gated macros land within ±10 %. Fat sits at +20.1 % — reported, not gated, exactly as the rule above anticipates for a roast finished in oil.

When the gate refuses

Two of the seven recipes carry a computed score that the product never shows. sheet-pan-salmon reconstructs carbohydrate at −10.1 % and veggie-frittata at +12.3 % — both outside the band — so both blocks are stored with "status": "withheld", and the rendering surface reads that status and emits nothing.

The salmon is the more instructive of the two. Its recipe finishes with a squeeze of lemon rather than a stated weight; kcal, protein and fat all reconcile under 1 %, so the method is sound and only the carbohydrate check is undecidable. Assuming a larger lemon — the 24 g the chicken recipe states — brings it back inside the band at −1.4 %. Importing a quantity the recipe does not give, because it passes, is the fitting the gate exists to prevent, so the score stays withheld.

Honest scope

Score computed for all seven recipes · non-forgeable guard active · displayed in the app · 172 / 172 tests passing.

Five recipes of seven display a score. The other two are withheld by the reconciliation gate — not defaulted to a placeholder, and not published with a caveat attached. The score is an estimate built on USDA inputs, and the page labels it as one: the guard proves the number was not hand-written, not that the ingredient mapping behind it is beyond question.

RAWLY is informational content, not medical advice. Its authoring personas hold no professional certification; the evidence layer exists so that readers can check the sources themselves rather than trust the persona.