Elamur Groupants⌕
☰

fish-fr-contract

The groupant beside tools/fish/src/fr.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

componentlabelwhere
Approximantpartial source derivedForward
Astpartialsyntax.json
Compositionpartial source derivedComposition
Costpartial source derivedCost
Descriptantpartial source derivedDescriptant
Invariantpartial source derivedInvariant
Testsfinite unit controls and treebank gate controlTests

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.

relationtypelabelwhere
Behavior complementbehavior complementsource derived finite checksBehavior complement
Reverse reconstructionreverse reconstructionsource derived finite checksReverse reconstruction

Model text

Model

French Fish contract: task, request and reply gates

Forward

Domain: a French task (schema 1, kind mova_fish_fr_v1, 1..8 targets, at most 8 context lines, each target with one CoNLL-U draft block whose sent_id/text equal the target, rule labels in their closed sets) and a reply object with the six AnnotationDraft fields. Map: evaluate(task) -> (task_sha256 = SHA-256 of the compact serialized task, bindings, per-draft registry/alignment observations, findings); render -> exact English prompt P with |P| <= 100000 bytes; validate(reply) -> accept with witness numbers, or reject. Accept(r) iff bound(r) and blocks(r) = targets in order with exact id/text and for every block: shape(b) and registry(b) and aligned(b,text) and labels(row) in the closed sets.

Behavior complement

What it does not do: it never repairs a reply (no feature reordering, no range insertion, no label aliasing), never reads a corpus or the pass, never calls a model itself (the shared transport does, Terra only), never accepts empty nodes, never checks semantic correctness of attachments or labels (witness disagreement is a finding, not a rejection), never authorizes training. The feature registry is the UD validator's observed-per-UPOS data: a pair absent from that data is rejected even when linguistically plausible (a false-negative domain); a pair present can still be wrong for the word.

Reverse reconstruction

From a validated reply one recovers exactly the surface token sequence of the text (alignment is injective on non-whitespace characters given the token order) but not the whitespace pattern beyond SpaceAfter marks, and not the draft (many drafts map to one reply; the draft is retained in the task). From a rejection message one recovers the first failing target and gate, not the set of all failures. task_sha256 identifies the typed task up to serialization of its fields; pretty and compact files with equal content share it.

Invariant

Every validation record carries review_only=true, training_authorized=false, semantic_correctness "not established". The number of accepted blocks equals the number of targets; every accepted block has one root, no cycle, consecutive ids and non-overlapping ranges. Findings never change acceptance.

Cost

Let T<=8 targets, n<=150 words per block (the pass's cap), R ranges. Parse and registry checks O(T*(n+R)) with BTreeSet lookups O(log |registry|), |registry| ~ 530 lines; cycle check O(n^2) worst case per block; the witness LCS O(n_draft * n_reply) per block (<= 22500 cells). Prompt rendering is linear in the task bytes (observed 20-29 KB for 5-8 targets of encyclopedic French, 2026-11-06).

Composition

Private materializer (eelfr fish-pages) -> FrTask file -> swarm/pager (unchanged) -> fish-fr annotation-execute -> execute::run_fr -> fr::evaluate/render -> execute::transport (shared with English) -> Codex -> AnnotationDraft parse -> fr::validate_draft -> receipt -> eelfr fish-collect -> Eel parser-fr/prag-fr inputs.

Descriptant

The French side of the Fish: the request explains UD French GSD conventions (multiword contractions, elision, inverted clitics, AUX/cop, French subtypes, feature order) and the French pragmatics labels (six schema labels, address, cond_polite, variety). Gate control 2026-11-06: GSD dev 1476/1476 pass, GSD train 14445/14450, Sequoia train 2230/2231. First live reply (dry run, 2026-11-06) was rejected for a feature order (NumType before Number): the gate holds; the prompt now states the case-insensitive order.

Tests

fr::tests: a good reply passes with witness numbers; negative controls reject an unaligned reply, a non-French relation, a non-UD UPOS, a feature outside the registry, two roots, a cycle, a changed text, a non-auxiliary AUX lemma, a non-être copula, labels outside the sets, a wrong header and another task's hash; witness disagreements stay findings; malformed tasks fail before any request.

Provenance

This page in Markdown → https://md.groupants.elamur.ai/free/en/mova/tools/fish/src/fr.rs.groupant/