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
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 |
| ast | partial | syntax.json |
| composition | partial | Composition |
| cost | partial | Cost |
| descriptant | present | Descriptant |
| invariant | partial | 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 |
reverse_reconstruction | reverse_reconstruction | partial source derived model | 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.
This page in Markdown → https://md.groupants.elamur.ai/free/en/mova/tools/whale/src/batch.rs.groupant/