qproj eye icon qproj design docs

Quell reading notes: design

design · draft · NLP and argumentation · edited 2026-11-04

The player reads in-world texts, highlights passages, and writes free-text notes. NPC dialogue is canned and gated on what the player has engaged with, so the game needs concept ids out of highlights and notes. This design covers the data format (shared by the lab and, eventually, the game) and the lab that measures interpreters. Background research: “Local ‘System One’ models for reading notes and NPC talk” (2026-10-20).

The texts are philosophical, not lore dumps: one passage carries several overlapping topics, and structure (arguments, objections, references) matters as much as topics. Training material is excerpted from real books and is never committed or published.

Scope

Tiers 0–2 of the research doc only:

tierapproachoutput
0authored annotations; highlight → concepts by coveragescore per concept, no model
1embedding similarity (MiniLM / BGE-small / e5-small class)cosine score per concept
2schema-driven encoders (GLiNER2, GLiNER / GLiClass)concept, stance, slots with scores

Few-shot only for now (tier 1 proto arm: concept anchored by its dev-split example notes). Fine-tuning is deferred until the designer has finalized materials; there isn’t a big enough corpus yet.

Data format

A data set is a directory (misc/note-lab/data/<set>/; everything except data/fixture/ is gitignored):

pathcontents
texts/*.txtPlain text, exactly as the player reads it.
texts/*.jsonOptional W3C annotation page for the same-named text.
concepts.tomlConcept ids with label and description; the closed stance and slot sets.
notes.jsonlOne note per line: text, highlighted span, gold labels, dev/holdout.

Offsets are [start, end) in Unicode code points over the text file, read as UTF-8 with no newline translation. A Rust port must convert to/from byte offsets.

Annotations use a subset of the W3C Web Annotation Data Model (Recommendation, 2017): chosen because overlap is free, it gives the Rust side a stable spec, and it can be replaced later if needed.

{ "type": "AnnotationPage", "items": [
  { "id": "a2", "type": "Annotation", "motivation": "classifying", "layer": "argument",
    "body": [{ "type": "TextualBody", "purpose": "tagging", "value": "slave_morality" }],
    "target": [
      { "source": "genealogy.txt", "selector": [
          { "type": "TextPositionSelector", "start": 118, "end": 260 },
          { "type": "TextQuoteSelector", "exact": "…", "prefix": "…", "suffix": "…" } ] },
      { "source": "genealogy.txt", "selector": { "type": "TextPositionSelector", "start": 530, "end": 610 } } ] } ] }

Layers and relations

In annotation tools a layer is a kind of annotation with its own fields, relations and overlap rules; values within a layer are labels. The designer wants both: many overlapping concepts at different scales (one layer, plus a concept hierarchy in concepts.toml if needed) and different kinds of structure (argument structure, cross-references, rhetorical moves), where relations matter (premise supports conclusion, passage answers Kant). In W3C, a relation is an annotation whose targets are other annotations (motivation linking). Not read yet; tiers 0–2 don’t use them.

Possible later unification: the player’s own highlights (highlighting) and notes (commenting) fit the same model, so the game could store authored tags and the notebook in one format.

Authoring

JSON is not hand-authored: it is the output of a labelling pipeline (tool export → converter → our format). The tool is swappable; the designer is evaluating:

Open: notes and their gold labels must also come out of the pipeline; notes.jsonl is hand-written today.

Tier 0

Text.concepts_at(start, end, layer=None) returns, per concept, the share of the highlight covered by the union of that concept’s ranges (optionally one layer). On the fixture it already shows the limits: a broad argument annotation scores both its concepts 1.0 for any highlight inside it (including the “nice willows” note that should map to nothing), and an untagged passage returns nothing. The note text has to do the rest; that’s tiers 1–2.

Lab method (misc/note-lab)

Modelled on misc/hex-lab.

What depends on real data

Decided only after a pilot export from the labelling tool:

Independent of data: the prediction record, tier 1–2 inference, and the latency/throttle harness.