Methods & reproducibility

How this was built

Pipeline

Raw text → segmentation → named-entity detection → entity normalization → coreference → relation/event extraction → confidence scoring → human correction → network construction → analysis. Every stage is versioned and every release records the exact versions used, so a network can always be traced back to the code and data that produced it. This release of Njáls saga was built with:

Graph releasenjala-2026-09-07-46b49883
Source text SHA-2566d1fc58dfb48447c29f7a6804a92d9d60a1e6bd14fd17267a9a72b3e51c0def1
Segmentationseg-v1
Mention resolutionmention-v1
Coreferencecoref-v1
Relation rulesrel-rules-v2
spaCy modelen_core_web_sm-3.8.16
Entity tablenjala-entities-v6
Annotation revisionsannot-v0
Gold standardgold-v1
LLM extractionYuu no Sekai · relation_extraction_v1@9439178a1fc0 · scope: gold-chapters

Entity resolution

Njáls saga uses a hand-curated 116-entity canonical table (data/entities/njala.yaml): stable ids, canonical names, alias lists, patronymic/epithet fields, known parent links, and a curated chapter-window prior for disambiguating a bare given name shared by multiple entities. The other three sagas use a mechanically bootstrapped table (sagagraph.bootstrap_entities) seeded from the same frequency/patronymic/epithet discovery statistics, marked status: auto-bootstrap and not yet gold-checked — see Extraction for exactly which numbers rest on which table.

A bare given name shared by multiple entities resolves through a four-rung ladder, in order: (1) the surface form itself is qualified (patronymic/epithet) — confidence 1.0; (2) a qualified mention of exactly one candidate occurred in the previous 60 sentences — 0.85; (3) exactly one candidate's curated active-chapter window contains the current chapter — 0.7; (4) otherwise, the candidate with the most recent qualified mention or nearest window boundary, flagged low-confidence for review. Nothing is ever silently merged: every non-1.0 resolution is visible in the annotation review queue.

The full annotation toolkit spans two places. The review queue surfaces low-confidence mention resolutions and relations for verify / reject / retype / flag actions. A character’s own Curate this entitypanel (on every character profile page) handles the entity-level actions — confirming an alias, merging a duplicate into an existing entity, or splitting a bundled entity's mentions into a new one. Every action from either surface writes the same append-only revision record to data/annotations/<saga>/revisions.jsonl, applied on the next pipeline run; nothing is ever deleted, including a rejected relation, which stays in the release with status: rejected rather than disappearing.

Gold annotation

Ten chapters of Njáls saga were hand-annotated by the project author against a written guideline (mentions, a documented pronoun sample, and every kinship/marriage/friendship/conversation/conflict/killing/support relation, tagged explicit or implicit). This is a single-annotator gold set with no independent inter-annotator agreement measurement — see the paper's Limitations section for what that does and does not license.

What the network metrics mean (and don't)

A word of caution before the list: this site uses “edges” in two related but different senses, and both are visible on purpose. The saga browser and cross-saga comparison report a collapsed pair count (how many distinct pairs of characters share any semantic tie — 381 for Njáls saga) because that is what the network-metric algorithms below actually operate on. The interactive graph additionally reports typed edge records (one per (pair, relation type) — e.g. a pair linked by both kinship and conflict counts as two records but one collapsed edge), because the viewer draws one colored line per relation type between a pair. Neither number ever includes the sentence co-occurrence baseline layer.

All metrics were cross-checked against hand-derived values on synthetic graphs with known answers (star graphs, path graphs, the Zachary karate club's published betweenness values, disjoint cliques for community detection) before being trusted on saga data — see tests/test_metrics.py.

Cross-saga entity resolution

The Icelandic family sagas share a common "saga world": a handful of historical/narrative figures recur across multiple sagas.data/entities/cross_saga.yaml records a short, hand-verified list of such links — currently four persons: Hoskuld Dala-Koll’s son and his half-brother Hrut (linked between Njáls saga and Laxdæla saga, on matching genealogy independently narrated in both texts), Snorri the Priest/Godi (linked across all three sagas that mention him, on a distinctive epithet and consistent chronological placement), and Gudmund the Mighty (linked between Njáls saga and Grettis saga).

Every link was checked against the actual downloaded corpus texts, not asserted from outside knowledge of saga genealogy — each entry in the register quotes the specific passages compared. Building this register also caught a real entity-resolution bug: the bootstrapped Grettis saga table had merged the unrelated minor figure "Gudmund the son of Solmund" together with "Gudmund the Mighty" under one bare-name entity, discovered only when trying to verify the cross-saga link. That entity has since been split and both halves promoted to status: curated.

A cross-saga link never merges the underlying entities: each saga keeps its own separate mentions, edges, and centrality scores for "its" copy of the person. The link only records that two (or three) saga-scoped ids are believed to name the same person, with a confidence level (high / medium) and, where relevant, a caveat about what the link does notestablish. See a linked character’s profile page for the “Also appears in” section, or tests/test_cross_saga.py for the consistency checks the register is held to.

Feud-chain detection (a documented under-count)

A killing is flagged as retaliation for an earlier killing when its victim is the earlier killer (or their kin/declared ally) and its killer is kin/declared ally of the earlier victim. This structurally cannot detect feud propagation carried out throughemployment or fosterage loyalty rather than kinship or an explicitly stated alliance — which Njáls saga uses repeatedly (household servants killing on their employers' behalf). See the paper's Case Studies section for a worked example (chapters 35–45) where this causes a real, acknowledged miss.

Exports

Every saga release ships CSV (nodes/edges), JSON, GraphML, and a citation/provenance text file under its release's export/ directory.