How Language Lineage is built

Every claim on this site is a typed record with a confidence score and an evidence URL. Research agents gather the raw facts, a person reviews every change, and a set of mechanical gates rebuilds and checks the whole site before anything ships. This page follows one fact through the machine.

152graph nodes
443typed edges
443/443edges with evidence
148/152nodes with cited facts
300+generated pages
0errors allowed at ship
Fig. 1 · One fact's path from public claim to published page. Click a station.Rebuilt in full on every deploy

One record, end to end

Here is a real record from the dataset, the one behind the answer to what Python is written in:

{
  "from_language": "lang:c",
  "to_language": "lang:python",
  "relationship": "runtime_written_in",
  "start_year": 1991,
  "end_year": null,
  "confidence": 0.98,
  "evidence_source": "https://github.com/python/cpython",
  "notes": "CPython reference implementation in C"
}
C node connected to Python node by a green runtime_written_in edge, annotated with confidence 0.98 and start year 1991. runtime_written_in C Python confidence 0.98 since 1991 evidence on GitHub
Fig. 2 · The same record as it appears in the graph

Every field is doing work:

The six relationship types

TypeMeaningEdgesMedian confidence
compiler_written_in what a compiler is written in 96 0.92
runtime_written_in what a runtime or VM is written in 67 0.92
bootstrap_written_in what the first compiler was written in, before self-hosting 15 0.90
influenced design ideas that shaped another language 252 0.85
transpiled_to compiles to another language as its output 11 0.95
rewritten_in an implementation ported to a new language 2 0.95

The medians come from the live dataset and they tell the truth: implementation edges are backed by source trees and score 0.92, while influence claims are softer by nature and score 0.85. The gap is shown, not smoothed over.

01 Sources

The pipeline draws on three classes of sources, chosen because each one can be checked by a machine and cited to a reader.

Human in the loop

Using structured claims instead of Wikipedia article text is a licensing decision a person made once and the pipeline enforces forever. Article prose is CC BY-SA and is never stored or pasted. Every page's narrative is synthesized from the structured facts, then cited back to both Wikipedia and Wikidata.

02 Research agents

Two harvest agents run offline, and both write an audit report on every run. They are deliberately boring: they fetch, resolve, and record. They do not decide anything.

Wikipedia API, Wikidata, and Commons feed the research agents, which emit enrichment_v5.json and an audit report. wikipedia api wikidata commons Research agents resolve · fetch · retry · log enrichment_v5.json 148/152 nodes cited audit report per run, with reasons
Fig. 3 · Three sources in, cited facts and receipts out

The fact harvester

scripts/harvestWikipediaContent.ts, run with npm run content:wikipedia. For each of the 152 nodes it:

Wikidata propertyWhat it captures
P287 / P170 designed by, creatorLanguage designers
P178 developerMaintaining organizations
P275 licenseLicense
P737 influenced byDesign influences, cross-checked against the graph's influence edges
P277 programmed inImplementation language, cross-checked against written-in edges
P856 official websiteProject site
P1195 file extensionFile extensions

Current coverage: 148 of 152 nodes carry cited facts. The remaining 4 (mrustc, Odin, Wren, SWC) have no Wikipedia article with a Wikidata item to cite, so their pages fall back to dataset facts alone rather than invented prose.

The logo harvester

scripts/harvestWikimediaLogos.ts, run with npm run logos:wikimedia. Its policy is strict:

96 of 152 nodes currently have a logo (51 from Devicon, 39 from Commons, 6 stand-ins). 56 have none, because the standing policy is that no logo beats a wrong logo.

Human in the loop

Every curated pin and every rejection above is a human call, written into the script where the next reviewer can see it. The agents execute those calls; they do not make them.

03 Assembly

npm run dataset:v5 (scripts/generateV5Dataset.ts) deterministically merges the base dataset, the harvested logo metadata, and a set of curated corrections into one file: lineage_v5.json, 152 nodes and 443 edges. Run it twice and you get the same bytes.

lineage_v4.json, enrichment, and logo overrides merge deterministically into lineage_v5.json. lineage_v4.json enrichment_v5 logo overrides Assembly generateV5Dataset.ts lineage_v5.json 152 nodes · 443 edges
Fig. 4 · Deterministic merge: same inputs, same bytes

Corrections travel with their reasons. Two real entries:

OverrideRecorded reason
Rust first_release_year set to 2010First appeared publicly in 2010; 1.0 came in 2015. The node's notes keep both dates and the original OCaml compiler.
GHC compiler_written_in start year set to 1990"GHC is written in Haskell; start year normalized to Haskell first-release year for dataset chronology."

The output is the single source of truth. The interactive graph fetches this exact file at runtime, every static page is generated from it, and the downloadable dataset is the same file, not an export.

Human in the loop

Nothing merges silently. Every override is a named entry in code with a written reason, so a reviewer reading the diff sees both the change and the argument for it.

04 Human review

Agents propose; they never merge. Every change to the dataset or the generators lands as a git diff that a person reads before it reaches the main branch. This is the real chronology fix from the current dataset, exactly as the reviewer saw it:

edge lang:haskell to tool:ghc · compiler_written_in "confidence": 0.99, - "start_year": 1989, + "start_year": 1990, + "notes": "GHC is written in Haskell; start year normalized to Haskell first-release year for dataset chronology."
Fig. 5 · A real correction as the reviewer sees it

This is the stage where judgment lives:

05 Validation gates

Before any change ships, three mechanical gates run. There is no override flag; a red gate stops the release until a person fixes the cause.

npm run type-check     # gate 1: strict TypeScript across app and pipeline
npm run seo:validate   # gate 2 and 3: dataset integrity + full site audit
npm run build          # regenerate everything, then compile

Gate 1: Types

The TypeScript compiler checks the application and every pipeline script against strict dataset interfaces, so a malformed record is a build error, not a surprise in production.

Gate 2: The dataset validator

validateDataset checks the graph itself, and it runs again in your browser every time the dataset loads:

Gate 3: The site auditor

scripts/validateSeo.ts audits every generated page and exits nonzero on any error. The bar it enforces:

$ npm run seo:validate OK: robots.txt has Sitemap directive OK: sitemap.xml uses canonical www host OK: All 152 language/tool pages valid OK: llms.txt lists every indexable page OK: All pages have unique titles OK: All pages have unique descriptions Validation complete: 0 errors, 0 warnings
Fig. 6 · The gate's verdict, in its own words

The required result is 0 errors, 0 warnings. Not few. Zero.

Human in the loop

Gates judge form, not truth. A person can be wrong about what rustc was written in and every gate will pass. That is exactly why stage 04 exists, and why every claim carries a source you can check yourself.

06 Publication

npm run build regenerates the entire site from the dataset: 131 language pages, 21 tool pages, 120 question pages, 13 guides, 6 relationship pages, the timeline, the directory, and this page. Over 300 static HTML documents, plus the sitemap and the llms.txt index for AI crawlers, both derived from the rendered pages rather than maintained by hand.

lineage_v5.json fans out to static pages, sitemap and llms.txt, the live graph at explore, and the dataset download. lineage_v5.json one source of truth 300+ static pages sitemap + llms.txt /explore live graph dataset download
Fig. 7 · One file fans out to every surface
Human in the loop

Nobody edits generated HTML. A fix goes into the dataset or the generator and the whole site is rebuilt, so a correction lands everywhere the fact appears, not just on the page where someone noticed it.

Corrections

Spot an error? Open an issue on GitHub. A correction is never a patch to one page: it becomes a dataset or generator change, re-enters the pipeline at the research or assembly stage, gets reviewed like any other diff, and has to clear every gate before it ships. The loop in the diagram is literal.

Agents scale, humans decide

The division of labor is strict, and it is the reason a two-person-scale project can maintain 443 sourced claims.

What the agents do

  • Fetch and resolve entities across the Wikipedia, Wikidata, and Commons APIs
  • Cross-reference labels with documented fallbacks
  • Rate-limit, retry, and log every failure
  • Regenerate 300+ pages from scratch on every change
  • Hold every page to the same format budget
  • Write an audit report for every run

What the humans do

  • Pin ambiguous names to exact articles
  • Assign all 443 confidence scores
  • Accept or reject every logo, with written reasons
  • Untangle bootstrap loops and contested dates
  • Write the 16 hand-authored deep dives
  • Read and sign every diff

Known limits

Explore the graph these gates protect →

Or go straight to the material: download the dataset, or read the pipeline source on GitHub.