wordgraph-pass
The groupant beside wordgraph/src/pass.rs in the Mova repository: what the code computes, what it never does, how to go back from its outputs, its invariants, cost and checks.
Facts
Implementation material. A Mova code model describes this code at one source revision: partial models, finite checks and their stated scope. It is not a reviewed general exposition, and its labels are shown as written, never raised.
Components
| component | label | where |
|---|---|---|
| Approximant | partial | Approximant |
| Ast | partial | syntax.json |
| Composition | partial | Composition |
| Cost | partial | Cost |
| Descriptant | present | Descriptant |
| Invariant | partial | Invariant |
| Tests | executed bounded checks | Tests |
Obernants
The typed relations around the forward model: the behaviour complement (what the code never does), the reverse reconstruction (every input compatible with an output) and specialised views.
| relation | type | label | where |
|---|---|---|---|
| Behavior complement | behavior complement | partial source derived model | Behavior complement |
| Reverse reconstruction | reverse reconstruction | partial source derived model | Reverse reconstruction |
Model text
Descriptant
A pass reads a source (Wikipedia tier-1 shards: index TSV + concatenated zstd frames of JSON records; or CoNLL-U
files, optionally zstd) into one part per unit: a zstd stream WGPART01 | sorted OOV table | sorted unique (key, count) records, a JSON sidecar (counts, rules version, models seen, SHA-256) and the pass meta.json
(provenance). The negative control shuffle permutes dependents within each relation code. A pass resumes by
keeping parts whose files exist, and refuses parts made by other extraction rules.
Approximant
read_unit(u, seed) = (sort(OOV(u)), count(sort(remap(shuffle_seed(E(u)))))) where E(u) is the concatenated event list of the unit's sentences in input order, remap replaces interned numbers by ranks in the sorted OOV table, and count run-length-merges equal keys (saturating u32). run(units) = map over units in a rayon pool (order of completion irrelevant), then meta from sidecars sorted by part name.
Invariant
Part bytes depend only on the unit content, the rules version and the seed, not on thread count (measured: shards 0β2 byte-identical with 2, 3 and 6 threads). Records are strictly increasing; the OOV table strictly increasing; OOV ranks are < table length. The shuffle preserves every head, every relation, and the multiset of dependents per relation; it is a pure function of (events, seed ^ hash(part name)).
Cost
Time O(T + E log E) per unit (T tokens, E events); memory β 20 B Γ E events + the shard file (about 0.6 GB peak at 6 threads on tier 1, 2026-11-06). 100 shards: 35 s wall, 184 s CPU, 337 MB on disk.
Composition
Uses extract per sentence; its parts are read by compile through PartReader; meta.json is copied into the
graph's provenance.
Tests
shuffle_keeps_marginals_and_is_seeded (same seed same permutation; marginals kept; pairs changed β the red side),
today_is_a_date; the resume guard was shown red on 2026-11-06 against a version-1 part.
Behavior complement
Does not deduplicate inputs across passes (overlapping sources count twice), does not verify a resumed part's
SHA-256 against its sidecar, does not read the topic-corpus caches (*.jsonl.zst) or any non-CoNLL-U format,
does not lock the directory against concurrent writers, and does not delete anything.
Reverse reconstruction
From a part one recovers the multiset of packed events with OOV strings; not the order of sentences, sentence boundaries, articles, or which event came from which sentence. For a control part the original pairing is not recoverable without the seed and the pre-shuffle order.
Provenance
This page in Markdown β https://md.groupants.elamur.ai/free/en/mova/wordgraph/src/pass.rs.groupant/