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
| component | label | where |
|---|---|---|
| Approximant | partial source derived | Forward |
| Ast | partial | syntax.json |
| Composition | partial source derived | Composition |
| Cost | partial source derived | Cost |
| Descriptant | partial source derived | Descriptant |
| Invariant | partial source derived | Invariant |
| Tests | finite unit controls and treebank gate control | 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 | source derived finite checks | Behavior complement |
| Reverse reconstruction | reverse reconstruction | source derived finite checks | Reverse 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/