Mova0.5 pre-release⌕
☰
home / docs / annot — the Mova annotator subproject

annot — the Mova annotator subproject

annot is the teacher side of annotation: it sends sentences, with our drafts and context, to a large model in batches, checks the answers with Rust gates, and writes silver data for training. The large model teaches; it never answers for Mova at test time.

The hand-annotated corpus is small. So Opus takes random sentences: it annotates them, looks at the output of the Rust annotator, checks that output, and checks whether its own initial annotation had errors. Such annotation can train all the task classes the modules otherwise learn from small annotated corpora.

The en modules learn from 14,400 UD sentences (EWT + ESLSpok). The annotator grows this corpus with silver: Opus annotation checked by the Rust annotator and gates.

Full UD

Annotation. Both Opus and Rust produce full CoNLL-U: UPOS, XPOS, FEATS, lemma, head, and relation with subtype. In Rust, UPOS and FEATS are computed by tables over the graph (en::ud).

Gate — the UD 2.18 registry for English (en::udreg, data en/data/ud-registry-en.tsv):

Positive control: EWT (train and test) and GUM give 0 violations; ATIS gives 3.2% (the old feature PronType=Int,Rel).

Metrics — CoNLL 2018 (en::ud::Scores).

Third opinion — UDPipe 2 (LINDAT, english-ewt-ud-2.17), for cross-checking only. Idea: also run open-source annotators and compare their output with ours.

Silver is appended to our own corpus corpus/mova-silver-en.conllu, with the source and license of every sentence. Description — Mova's own corpus: silver UD for English. Sentences come from two sources: Tatoeba (CC0) and open papers from the library (CC BY, annot sentences).

Max vs high (25.09.2026, 20 EWT sentences, full UD)

Effort is set via --settings.

modeoutput tokens per sentencetime for 20 sentencesAllTagsLASMLAS
max, final~27k85 min95.092.985.3
max, first look + FEATS from Rust~10.6k32 min93.392.082.0
high, final~1.6k4 min90.591.180.2
high, first look + FEATS from Rust~0.9k2.5 min91.191.681.0
UDPipe 2 (EWT, NC)—seconds95.090.886.6

High on 300 sentences (25–26.09.2026, EWT test, full UD)

Limitation of the measurement: sentences were only 5–30 tokens. A filter dropped short sentences and long complex ones, so the measurement is easier than the real thing. Calibration, silver and bronze take sentences of any length; that measurement is below ("Honest measurement on sentences of any length").

Two-pass high: first look and check, batches of 20, ANNOT_FEATS=rust. Report — calib-ud-high300.log.

annotationUPOSUFeatsAllTagsLemmasUASLASMLASBLEX
Opus high, first look96.8694.5291.8297.3893.3790.8879.3885.02
Rust94.7694.3190.7596.7884.2280.1467.3771.87
Opus high, final + FEATS from Rust (25.09)97.1495.6893.1997.5993.7191.2581.4985.65
same, Rust FEATS with agreement (26.09)97.1497.9095.4197.5993.7191.2584.7785.65
UDPipe 2 (EWT, NC — cross-check only)97.4398.3896.2097.4694.3992.5886.2986.90
patch mode high + FEATS from Rust (26.09)97.6198.1496.1098.0495.0493.0086.6588.16

Cycle (per batch of sentences)

  1. First look. Opus annotates sentences with fixed tokens in CoNLL-U: lemma, PTB tag, head, UD relation.

  2. Rust annotator (en: tagger, morphology on the in-code dictionary, parser) annotates the same tokens.

  3. Second look. Opus sees both annotations and the list of differences and gives the final one: it chooses its own, Rust's, or a third option, and also checks places where both agree.

  4. Gates in Rust (ann.rs, test with negative controls):

    • forms match the given tokens;
    • tag is from enum Tag, relation from enum Rel;
    • heads within the sentence, exactly one root, no cycles.

    A block that fails does not go into the corpus.

Model and effort — Opus on max, variables ANNOT_MODEL and ANNOT_EFFORT. Invocation — claude -p in an empty directory with no tools. Time, token and cost accounting — calls.jsonl.

Calibration before trust

annot calib — the same cycle on sentences from the UD test set, where gold is known. It measures the accuracy of the Opus first look, the Rust annotator and the final annotation against gold. Only after that can annotation of random sentences (annot silver) be trusted.

First measurement (25.09.2026)

20 sentences of EWT test (seed 7), 238 tokens. All blocks passed the gates.

annotationtaglemmaUASLAS
Opus, first look97.199.296.291.6
Rust annotator89.996.680.372.3
Opus, final97.999.696.292.4

Commands

annot calib  <UD train>... -- <UD test.conllu> <n> <seed> <out-dir>
annot silver <UD train>... -- <sentences.tsv> <n> <seed> <out-dir>
annot report <out-dir> <test.conllu>                  what the check changed in the first look
annot refeat <UD train>... <out-dir> <test.conllu>    FEATS from Rust on top of Opus annotation
annot feats-diff <file.conllu> <test.conllu> [top]    where features diverge from gold
annot seed-examples en/seeds <out.tsv>                examples from seeds
annot bronze <UD train>... -- <sentences.tsv> <corpus.conllu>   bronze: Rust only

Output:

Source of random sentences: English Tatoeba from the CC0 subset (41,512 sentences, tatoeba-eng-cc0.tsv, provenance alongside).

Next

Licence

Elamur Cosmic License (Elamur Cosmic License). Third-party data keeps its own terms, as noted where it is used.

This page in Markdown → https://md.mova.elamur.ai/free/en/docs/annot/