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

# mova-whale-batch

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

Batches of papers for a pod of Whales: one open batch at a time, closed when every Whale passed or at its deadline (half a day by default); the next papers chosen deterministically from a pinned catalog (open licence, Markdown text, not local-only; priority ids, then papers our code cites, then the rest); learners run in parallel, each with its own terminal; review-only teaching candidates for the papers school and the dictionary of scientific writing. Source: `tools/whale/src/batch.rs`.

### Forward approximant

plan(config): validate (distinct Whales, state roots, profiles, sessions, owner markers, terminal roots); plan.lock; open batch -> statuses via learn::paper_status -> closed {all_passed | deadline} or remain open; candidates(): catalog hash, rows filtered (open_licence, .md, absolute, not local, not taken/excluded, cited or priority or include_uncited), sorted by (priority index | cited | rest, id), first n readable texts hashed; opened event + batch-NNN/<whale>.learn.json. run(config, live): plan, scoped threads learn::run with MovaTerminal or NoTerminal, collect (open-licence papers: school prompts with Mova's answer, dictionary entries with explanation and the paper's own context sentence, admission review_required), plan again.

### Invariant

A paper is assigned at most once over all batches; at most one open batch; batches.jsonl is append-only and fsynced; no terminal is shared; candidates come only from open-licensed papers and contain no terminal answer text; deterministic choice for a fixed catalog, cited set and priority.

### Cost

Opening a batch hashes and scans the catalog (338 MB, about 1.4 s, 2026-11-04) and hashes the chosen texts; running costs the learners' cost in parallel.

### Composition

Parent: whale-workers; uses learn.rs, knowledge.rs, terminal.rs, paper.rs (open_licence, PaperSource); CLI in main.rs (batch-plan, batch).

### behavior_complement

Not done: starting terminals or Crab workers, retrying a learner, admitting candidates (a reviewer does), choosing papers by topic, rebalancing Whales between batches, closing a batch early because its Whales stopped. A Whale that stopped on a limit keeps the batch open until the deadline. Evidence status: source-derived model with finite checks, not a proof.

### reverse_reconstruction

batches.jsonl gives every batch's assignments with text hashes, opening time, deadline and how it closed with each learner's status; the learner configs and the Whales' state reconstruct each paper's rounds.

### Epoch 2026-11-04 (keeping the pod busy)

Observed 2026-11-04: all five learners of batch 1 stopped `nothing_to_ask` within 40 minutes of opening, and the one-shot `batch` exited with the batch open until its 12-hour deadline (Crab worker `exited`, five idle learners). Chosen behaviour: a batch whose learners are all passed or asked out (`nothing_to_ask`, `round_limit`) closes at once as `exhausted`, recording every unpassed paper in `retry` with its learner, last words and the writer of its last round; the next batch opens immediately. A retry is assigned first, to the learner holding its knowledge, when the current `compose::WRITER` differs from the recorded one (old records without a writer count as different); under the same writer it is not retried again, so the catalog keeps moving. Learners stopped by a usage limit, timeout or terminal failure keep the batch open; the persistent `run` waits `wait_minutes` (30) and continues them (new questions only) until the deadline. `STOP` in the run root ends the loop; `--no-terminal` makes one pass. Rejected alternative: waiting for the deadline idles the pod for up to 11 hours per asked-out batch.

### Epoch 2026-11-04 (Whale rename)

The engine was renamed from Sharks to Whales; a deployment renamed its learners (`shark-N` → `owl-N`) while batch 1 was open. Model: a slot S answers to the label set L(S) = {S.whale} ∪ S.formerly; an assignment, retry record or status with label l maps to the unique slot with l ∈ L(S) (validate keeps all labels, state roots and terminal identities pairwise distinct, so the map is a function). Records written before the rename carry the field `shark`; `util::legacy` reads `whale`, then `shark`. New records name the slot's current label. Knowledge stays keyed by `state_root`, not by label, so a rename with an unchanged `state_root` keeps it. Evidence: `batch::tests::renamed_learners_keep_their_open_batch_retries_and_state` (old field names and labels open a batch; new labels without `formerly` are refused — negative control; with `formerly` the open batch continues under the old state roots and both unpassed papers are retried with the renamed learners; a label both current and former is refused). Removing `formerly` matching or the legacy field reader turns it red (checked 2026-11-04). Format identifiers `mova-shark-*-v1` are unchanged.

### Epoch 2026-11-04 (selection, extraction, pod, topic corpus)

`Selection`: priority, cited by our code, core topics, general NLP; by library then overall citations; never alphabetical; min_words of read prose; little-cited system descriptions skipped; refusals (`extraction`, `short`) recorded once, retries checked too. Learner configs carry pod, stall_rounds, batched, review, topic_corpus; plan builds the topic corpus on assignment. On a copy of the live run root the plan took peters-2018, linzen-2016, press-2023, kiperwasser-2016, marneffe-2019 instead of «a-2025…» workshop papers.

### tests.md


batch::tests::batches_choose_cited_open_papers_and_close_on_the_deadline (2026-11-04). batch-plan against the 186,435-row library snapshot into a scratch run root: the configured priority papers first, then the first cited open papers by id. Finite fixtures, not a proof.

batch::tests::an_asked_out_batch_closes_early_and_retries_under_a_new_writer (2026-11-04): a usage-limit stop keeps the batch open (negative control); all asked out -> `exhausted` with both papers in `retry`; retried with their learners under a different writer; not retried again under the same writer; new papers follow. Finite fixtures, not a proof.

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.
