---
title: "mova-whale-learn — Mova code model"
description: "Mova code model of tools/whale/src/learn.rs: components with their labels, obernants and the model text."
url: "https://groupants.elamur.ai/free/en/mova/tools/whale/src/learn.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/whale/src/learn.rs.groupant/>

# mova-whale-learn

The groupant beside tools/whale/src/learn.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/whale/src/learn.rs`](https://github.com/ElamurAI/mova-free/blob/main/tools/whale/src/learn.rs)
- **source SHA-256:** `72b5a2742b50d4a8…`
- **repository folder:** [`tools/whale/src/learn.rs.groupant`](https://github.com/ElamurAI/mova-free/tree/main/tools/whale/src/learn.rs.groupant)
- **repository commit:** `48f2e6f74146`

> **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 | [Forward approximant](#forward-approximant) |
| **ast** | partial | `syntax.json` |
| **composition** | partial | [Composition](#composition) |
| **cost** | partial | [Cost](#cost) |
| **descriptant** | present | [Descriptant](#descriptant) |
| **invariant** | partial | [Invariant](#invariant) |
| **tests** | finite evidence | `tests.md` |

## 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.

| id | type | label | where |
|---|---|---|---|
| `behavior_complement` | behavior_complement | partial source derived model | [behavior_complement](#behavior-complement) |
| `reverse_reconstruction` | reverse_reconstruction | partial source derived model | [reverse_reconstruction](#reverse-reconstruction) |

## Model text


### Descriptant

One Whale learns on one paper round after round until its own description passes the gates: read, write with all retained knowledge, gates; on failure a bounded set of never-asked questions about gaps to its own terminal; answers re-read and retained as knowledge; journal per round; stops on pass, terminal limit/timeout/failure, dry run, nothing left to ask, round limit or deadline. Source: `tools/whale/src/learn.rs`.

### Forward approximant

run(config, terminal): validate; terminal animal == whale; paper hash; learner.lock + terminal lease; status.json (first_start, deadline = min(first_start + hours, deadline_unix)); passed -> return; import earlier paper runs once; read once; loop k: round_limit/deadline checks; round-k dir (never reused); Known::of + Guard (all answers) -> compose -> gates -> files + journal draft/gates; pass -> stop; gaps (terms without facts and not asked, half the slots; one part with nothing restated; longest prose sentences without a clause; never asked keys) -> ask each once; answer: keep text privately, mark asked, facts -> retain item (provenance), journal; error: mark asked unless no terminal, journal no_answer, stop after the round; empty gaps -> nothing_to_ask.

### Invariant

No question key is ever sent twice (asked.jsonl before the next round, across invocations and papers); no retry after an error; answer text never enters a description (gate answer_overlap); one learner per Whale state and one Whale per terminal; a round directory is never reused; the deadline is fixed at the first round.

### Cost

Read once (about 1 s per paper, release); per round one compose + gates (milliseconds) plus at most max_questions terminal calls (seconds to minutes each with a live model); rounds <= max_rounds; wall time <= hours. Expected cost change before measuring: the learning loop adds no model call when the native draft passes and at most max_questions per round otherwise.

### Composition

Parent: whale-workers; composes reader.rs, compose.rs, gates.rs, knowledge.rs and terminal.rs; started by main.rs (learn) or batch.rs.

### behavior_complement

Not done: reaching a high configured minimum length by asking (term explanations add about 6-25 words per answered term), rewriting the writer from answers, resuming a question pending in the terminal, sharing knowledge across Whales, starting or stopping terminals. Measured 2026-11-04 with a fake tmux LLM (never a model): +6 to +12 words per round over 8 rounds; the round limit ends the loop below the configured minimum. Evidence status: source-derived model with finite checks, not a proof.

### reverse_reconstruction

journal.jsonl (round, draft words by kind, gates, question, answer hash, retained item, no_answer, stop) and round-NNN files reconstruct each round's description, its gates, what was asked and what was retained; the terminal's reasoning is not recoverable.

### Epoch 2026-11-04 (reopening and re-reading)

A paper stopped unpassed and assigned again with a later deadline (a later batch's retry) is reopened: journal `reopened`, the new deadline, `max_rounds` counted from `rounds_base`; knowledge, asked questions and earlier rounds stay. `last_round.writer` records `compose::WRITER`. `reread` re-reads the kept answers to this paper's sentence and section questions once per `knowledge::READER`, retaining new facts as new items (provenance `reread`); nothing is sent.

### Epoch 2026-11-04 (batched typed questions, pod, stall, review hints, topic corpus)

One call per round carries the round's questions, numbered, asking for typed shapes; parts are read per question. With a pod, claims stop cross-pod repeats and the pod's items join the writer's and the gates' knowledge. `stalled` after stall_rounds rounds without word gain after a round without a usable fact; an EXHAUSTED paper is not reopened under the same writer. Review hints when a round gains fewer than min_gain_words words and before a pass. Optional topic corpus: seed at round start (lock released for the child), cited.md per round. Replay measurement (fresh pod, today's 505 recorded answers, 10 papers, two identical runs): 62 rounds, 198 questions, 52 terminal calls (live today: 164 rounds, 549 questions, 549 calls); term facts kept per answered term 1.21 (live 1.04 with bare facts, which now go to review); sentence answers still give almost no facts (replayed answers are not typed); words per paper 462-4,882, 2 of 10 pass (live 3).

### tests.md


learn::tests::rounds_retain_knowledge_reuse_it_and_never_ask_twice, a_limit_stops_cleanly_a_pass_asks_nothing_and_the_deadline_holds, two_runs_are_identical (2026-11-04). Measurements in tools/whale/README.md («Learning on a paper»). Negative controls red then restored: asked set ignored; answers pasted into the draft.

2026-11-04: tests of the batched/pod/stall/review/grammar/filter/selection changes listed in the crate README «Checks»; negative controls (grammar gate always passing, pod claim ignored, stall off, extraction check off) each turned their tests red, restored.
