Mova0.5 pre-release⌕
☰
home / docs / Training and rebuilding Mova

Training and rebuilding Mova

Get the data first: train/get-corpus.sh downloads the open Mova corpus (tales, summaries, questions, treebanks, math scripts) from Mova's releases, checks its SHA-256 and unpacks it into corpus/open/. The guides below assume it is there.

Mova is a small language model written in Rust. You can see how it works. Most of what it knows is written as plain markdown "seeds" and compiled into Rust tables. The rest is learned from open data by deterministic table and Markov models. No neural network is involved. Retraining Mova means editing seeds, retraining tables, and measuring honestly. These guides cover all three. Each guide is written for two readers: a person, and an AI coding agent working in this repository.

Gist

The big picture: three levels

levelwhat it holdswhen it changeswhere
1. Globalprinciples and values, concepts, shortcuts between concepts ("fall -> accelerate -> impact -> pain -> harm"), verb classes, relation properties, the exact arithmetic coreonly on a new build that passes the gatesglobal (seeds -> build.rs -> OUT_DIR/global.rs)
2. Domain modulesthe full depth of one field: grammar of English, word problems, story worlds, LaTeX, codeonly on a new builden, math, world, latex, ...
3. Contextthe state of the current document, task or dialogue: entities, quantities, events, who holds whatlives only while the task runsthe readers inside world, math, prag, ...

The key rule: the context level never invents knowledge. Level 3 combines facts from the text with links from level 1. When it cannot explain a step that way, it reports a gap, such as "verb gnaw has no class" or "state proud: unknown whether this is trouble or relief". Do not fix a gap by making level 3 memorize more. Fix it by adding a seed to level 1 (or a domain module) and rebuilding. layers wires the levels together. It routes a query to the global level, then to a domain module, and escalates when neither covers it. Every routing decision is logged with its score and threshold.

Seeds -> build.rs -> Rust tables

global/seeds/**/*.md  --(global/build.rs)-->  OUT_DIR/global.rs
   ```principle  ```concept  ```category              PRINCIPLES, CONCEPTS, LINKS, RELATIONS,
   ```link  ```verbs  ```relation                     fn verb_class(lemma) -> Option<(class, effect)>

Determinism

Mova must produce the same output for the same input every time. A gain that the next run cannot reproduce does not count.

Every judgment explained

When to use which guide

you want to ...read
teach Mova a new fact, verb class, relation or valueAdd a seed
retrain the English tagger and parser on your treebankRetrain the English tagger and parser
read another UD flavour, or write a conversion ruleMova's UD dialect and converters
solve or evaluate arithmetic word problems (SVAMP, GSM8K)Word problems: exact core, step solver, world scripts, world reader, SVAMP / GSM8K
work on bAbI, StepGame, SpartQA story worldsStory worlds: bAbI, StepGame, SpartQA
run the book and fairy-tale reading experimentsReading tales: world read, reader-, and qagen
adapt Mova to your own domain end to endAdapting Mova to your own domain

Steps (first session)

  1. Install stable Rust (edition 2024). The crates form one Cargo workspace: cargo build --release at the root builds them all into target/release/. To work on one crate, pass -p <crate> or --manifest-path, or cd into it.

  2. Build and test the global level. It takes seconds and has no dependencies:

    cargo test --release --manifest-path global/Cargo.toml
    
  3. Build the English module. It is the base of prag, world, math, coref and qagen:

    cargo build --release --manifest-path en/Cargo.toml
    cargo test --release --manifest-path en/Cargo.toml --lib seeds_all_parse
    
  4. Pick the guide for your task from the table above.

Example: what "explained" looks like

The global crate's own tests show the idea. A falling apple leads to harm through four declared links. An apple lying on a table produces nothing (a negative control):

let c = global::consequences("An apple fell on Newton's head.");
assert!(c.iter().any(|x| x.starts_with("fall → accelerate → impact → pain → harm")));
assert!(global::consequences("An apple lies on the table.").is_empty());

Pitfalls

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