mova-eel-autoencoder-round
The groupant beside tools/eel/src/autoencoder.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 source derived | Forward |
| Ast | partial | syntax.json |
| Composition | partial source derived | Composition |
| Cost | partial source derived | Invariant and cost |
| Descriptant | partial source derived | Descriptant |
| Invariant | partial source derived | Invariant and cost |
| Tests | finite evidence | 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 finite checks | Behavior complement |
| Reverse reconstruction | reverse reconstruction | partial source derived finite checks | Reverse reconstruction |
| Heldout exclusion | partial exclusion | partial source derived finite checks | Heldout exclusion |
Model text
Descriptant
The Eel's second round kind: an autoencoder round on CPU between parser rounds. The schedule
eel_autoencoder.every (β₯ 2) makes round n an autoencoder round when n mod every = every β 1; the
kind is chosen in step at the round boundary, after recovery, cooldown, retention and the storage
guard, and before the GPU probe. The round spawns the pinned native roundtrip wiki-round, checks its
files itself, and installs the candidate tables (en-lin.bin, domain.tsv) only when the dev
residual bits go down and every dev volume still comes back byte for byte. No GPU lease is taken,
no teacher or large model is called.
Forward
Let S be the state directory with current β gen-<m> (or none: the base model B), k = βn / everyβ.
The child writes train T_k, dev D, test E, candidate C and measurements (b_D, b'_D, b_E, b'_E,
x'_D, v). The Eel computes: sizes |T_k| = train_sentences, |D| = |E| = dev_sentences; articles(T_k)
β© articles(D βͺ E) = β
; hash(D), hash(E) equal the pin in S/dev.json (written by the first round);
the measured current model path is S/current/en-lin.bin or B. Decision: installed iff x'_D = v > 0
and b'_D < b_D; otherwise rejected with autoencoder_exact_gate or autoencoder_dev_bits_gate.
Any check failure, a timeout or a child failure is an error: failure.json, PAUSE, no retry.
Invariant and cost
The installed tables change only through install: under S/.eel-ae-install.lock, the parent hash
is rechecked, the candidate is copied to gen-<n> and hash-verified, then one rename of a symlink
switches current; the previous generation stays. The parser reject streak is carried unchanged.
state_dir must lie outside run_root. Cost: one child process (sample, two measures of D and E,
one Model::adapt over β€ domain_max sentences), file hashes of the base model (β150 MB) and the
roundtrip executable each round, two copies of β160 MB on install, retention of three older
generations. Measured cost of a real round: see History.
Composition
lib::step β kind β (autoencoder) round β spawn (roundtrip wiki-round) β check_sample,
pin_heldout β gate β install / refusal β lib::finish (receipt, counter, retention). The
summary keeps the parser receipt's lineage aliases (trainer_generation = hash of round.json,
actual_parent_weights_sha256, candidate_weights_sha256, installed_weights_sha256) so
evidence::inspect classifies it unchanged.
Behavior complement
Domain: rounds of a configured Eel. Observation: which work runs and what changes. Assumptions: the
schedule is validated at start. Relation: an autoencoder round never calls the parser trainer, never
probes or takes the GPU lease, never writes the parser model directory; a parser round never spawns
roundtrip; a refused candidate never changes current. Counterexample: a crash between the symlink
switch and the receipt leaves new tables without a receipt (the round directory then pauses the
controller for manual reconciliation). Evidence: finite fake-executable tests below.
Reverse reconstruction
Domain: receipts and gen-* manifests. Observation: an installed table hash. Relation: the manifest
of gen-<n> names its parent hash, base hash, dev/test/train hashes and the dev/test bits before
and after, so the chain of installs can be walked back to the base model; the window itself is
recovered from k and the corpus (deterministic sample). Not unique: the domain file is capped at
domain_max lines, so older windows are not recoverable from the tables alone.
Heldout exclusion
Domain: sentence ids wiki:<title>:<k>. Relation: a train id whose article is a dev or test
article fails the round before any install; a dev or test file whose hash differs from the pin fails
it too. This is an independent recheck of the child's own split, not a proof that the corpus split
function is used.
Tests
schedule_alternates_kinds_at_round_boundaries, worse_equal_or_inexact_candidates_are_refused_and_tables_stay,
dev_article_in_training_or_a_moved_dev_sample_pauses_without_install,
autoencoder_round_runs_without_the_gpu_lease_and_parser_round_still_waits,
a_switch_request_lets_the_parser_round_finish_then_stops,
unpinned_executable_or_base_pauses_before_any_autoencoder_work (in lib.rs). Red controls:
admitting equal bits, dropping the dev or test overlap check and ignoring the
pin each turned one test red (see History).
History
2026-11-06 Β· Invariant and cost
Measured 2026-11-06: 5β17 s wall, child peak RSS 1.07β1.18 GB (train 2,000, dev 500 or 2,000, 4 threads, nice 15).
2026-11-06 Β· tests
Red controls run by hand on 2026-11-06: admitting equal bits, dropping the dev or test overlap check
and ignoring the pin each turned one test red. A real hand run against Wikipedia (roundtrip wiki-round --lin-reverse) was refused by the dev gate: dev 380,329 β 380,577 bits.
Provenance
This page in Markdown β https://md.groupants.elamur.ai/free/en/mova/tools/eel/src/autoencoder.rs.groupant/