Elamur GroupantsβŒ•
☰

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

componentlabelwhere
ApproximantpartialApproximant
Astpartialsyntax.json
CompositionpartialComposition
CostpartialCost
DescriptantpresentDescriptant
InvariantpartialInvariant
Testsexecuted bounded checksTests

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.

relationtypelabelwhere
Behavior complementbehavior complementpartial source derived modelBehavior complement
Reverse reconstructionreverse reconstructionpartial source derived modelReverse 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/