---
title: "mova-eel-autoencoder-round — Mova code model"
description: "Mova code model of tools/eel/src/autoencoder.rs: components with their labels, obernants and the model text."
url: "https://groupants.elamur.ai/free/en/mova/tools/eel/src/autoencoder.rs.groupant/"
---
Elamur: [Mova](https://md.mova.elamur.ai/free/en/) · [Dictionary](https://md.dictionary.elamur.ai/free/en/) · [Research](https://md.research.elamur.ai/free/en/) · **Groupants**

This page as HTML: <https://groupants.elamur.ai/free/en/mova/tools/eel/src/autoencoder.rs.groupant/>

# 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

- **kind:** groupant
- **status:** partial source bound model
- **source:** [`tools/eel/src/autoencoder.rs`](https://github.com/ElamurAI/mova-free/blob/main/tools/eel/src/autoencoder.rs)
- **repository folder:** [`tools/eel/src/autoencoder.rs.groupant`](https://github.com/ElamurAI/mova-free/tree/main/tools/eel/src/autoencoder.rs.groupant)

> **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](#forward) |
| **Ast** | partial | `syntax.json` |
| **Composition** | partial source derived | [Composition](#composition) |
| **Cost** | partial source derived | [Invariant and cost](#invariant-and-cost) |
| **Descriptant** | partial source derived | [Descriptant](#descriptant) |
| **Invariant** | partial source derived | [Invariant and cost](#invariant-and-cost) |
| **Tests** | finite evidence | [Tests](#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](#behavior-complement) |
| Reverse reconstruction | reverse reconstruction | partial source derived finite checks | [Reverse reconstruction](#reverse-reconstruction) |
| Heldout exclusion | partial exclusion | partial source derived finite checks | [Heldout exclusion](#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

- **source SHA-256:** `6a6f00f86f5c1e8b…`
- **repository commit:** `c24d02b4c83b`
