Commit graph

128 commits

Author SHA1 Message Date
cb89060e34 [ADD] captures: badge control page and first sheet, rasterised from PDF
The walkthrough produces the retained plan's badge sheet through the
Badges section and rasterises the PDF under node with pdfjs at 96 dpi:
page 1 becomes the control page, page 2 the first sheet of four A6.
Manifest entries carry the PDF's sha256, so an unchanged PDF leaves the
images unchanged; two productions under the driven clock must hash the
same, and a missing canvas fails the step by name with nothing written.
No capture remains pending.
Checked: node 3787, browser 758, node-long 101 from the index alone.

--- FR ---

[ADD] captures : feuille de contrôle et planche, tramées du PDF

Le parcours produit la planche du retenu par la section Badges et trame
le PDF sous node par pdfjs à 96 ppp : la page 1 donne la feuille de
contrôle, la page 2 la première planche de quatre A6. Les entrées du
manifeste portent le sha256 du PDF : un PDF inchangé laisse les images
inchangées ; deux productions sous l'horloge pilotée ont même empreinte,
et un canevas absent fait échouer l'étape en le nommant, rien d'écrit.
Plus aucune capture n'est à venir.
Vérifié : node 3787, navigateur 758, longues 101 depuis l'index seul.

Assisted-by: Claude Opus 5.5
2026-10-10 14:36:21 -04:00
b72f3fe784 [ADD] captures: print preview of a draft and of the retained plan
The walkthrough photographs the printed plan twice from the same scroll
position: a proposal not retained carries BROUILLON and its own footer,
the retained plan carries neither watermark nor proposal timestamp. The
visible condition is judged on the whole box of each element, so a
label cut at the window edge fails the walkthrough; capture 19 now aims
at a seat that keeps the ghost and its label inside the plan. A failed
preview step closes the preview before the next tests run.
Checked: node 3777, browser 756, node-long 101 from the index alone.

--- FR ---

[ADD] captures : aperçu imprimé d'un brouillon et du placement retenu

Le parcours photographie deux fois le plan imprimé au même défilement :
une proposition non retenue porte BROUILLON et son propre pied, le
retenu ne porte ni filigrane ni horodatage de la proposition. La
condition visible se juge sur la boîte entière de chaque élément : un
libellé coupé au bord de la fenêtre fait échouer le parcours ; la
capture 19 vise un siège qui garde le fantôme et son libellé dans le
plan. Un échec à l'aperçu le referme avant les épreuves suivantes.
Vérifié : node 3777, navigateur 756, longues 101 depuis l'index seul.

Assisted-by: Claude Opus 5.5
2026-10-10 13:37:50 -04:00
365561272e [ADD] print: real PDF output proven, table sheets split by tour groups
Printing goes through Chromium's PDF with the CSS page size; a browser
command reads the PDF under node and returns pages, MediaBox and text
only. The tests prove pages = sheets for the cut plan in A4 and Letter,
the paper size within 0.25 mm, BROUILLON and the placement timestamp on
every page of a draft and none of a retained plan. The startup trial
prints the preview through the real shell. A table sheet whose tours do
not fit side by side splits them into groups of consecutive tours, so a
long name wraps inside its page instead of being clipped.
Checked: node 3776, browser 753, node-long 101; startup trial conforms.

--- FR ---

[ADD] impression : PDF réel prouvé, feuilles par table en groupes

L'impression passe par le PDF de Chromium à la taille de page CSS ; une
commande lit le PDF sous node et ne rend que pages, MediaBox et textes.
Les épreuves prouvent pages = feuilles du plan découpé en A4 et Lettre,
le papier à 0,25 mm, BROUILLON et l'horodatage du placement sur chaque
page d'un brouillon et sur aucune d'un retenu. L'essai de démarrage
imprime l'aperçu par la vraie coquille. Une feuille par table dont les
tours ne tiennent pas côte à côte les répartit en groupes consécutifs :
un long nom passe à la ligne dans sa page au lieu d'être coupé.
Vérifié : node 3776, navigateur 753, longues 101 ; essai conforme.

Assisted-by: Claude Opus 5.5
2026-10-10 13:33:35 -04:00
e71879e852 [ADD] badges: event section to prepare, produce and reissue the sheet
The Badges section follows Propositions. It offers the retained plan by
default, or the proposal chosen in Propositions, which always prints as
BROUILLON; the announcement names the source, the imposition and the
page count before anything is written. The paper question is asked
once per machine, refusals sit beside « Produire » with their remedy,
and a new production clears the previous sheet's path. Section buttons
narrow so eight still fit one line at 1 366 px.
Checked: node 3769, browser 745, node-long 101 from the index alone.

--- FR ---

[ADD] badges : section pour préparer, produire et rééditer la planche

La section Badges suit Propositions. Elle offre le retenu par défaut,
ou la proposition choisie dans Propositions, toujours BROUILLON ;
l'annonce nomme la source, l'imposition et le nombre de pages avant
toute écriture. La question du papier se pose une fois par machine, les
refus se posent à côté de « Produire » avec leur remède, et une
nouvelle production efface le chemin de la précédente. Les boutons de
section s'amincissent : huit tiennent sur une ligne à 1 366 px.
Vérifié : node 3769, navigateur 745, node-long 101 depuis l'index seul.

Assisted-by: Claude Opus 5.5
2026-10-10 11:11:33 -04:00
62f8406d78 [ADD] print: welcome list and table sheets, paginated with headers
The welcome list sorts names by their normalised key and gives each
round a column whose width comes from the longest seat it holds; the
table sheet puts the rounds in columns, or one sheet per table and
round under « Une feuille par tour ». Rows are measured and paginated
with the header repeated, never split across pages; names wrap
instead of being cut. Read-only and locked plans print the same.
Checked: node 3753, browser 730, node-long 101 from the index alone.

--- FR ---

[ADD] impression : liste d'accueil et feuilles par table, paginées

La liste d'accueil trie les noms par leur clé normalisée et donne à
chaque tour une colonne large de la plus longue place qu'elle porte ;
la feuille par table met les tours en colonnes, ou une feuille par
table et par tour sous « Une feuille par tour ». Les lignes sont
mesurées et paginées sous l'en-tête répété, jamais coupées entre deux
pages ; les noms passent à la ligne plutôt que d'être tronqués. Un plan
en lecture ou verrouillé s'imprime de même.
Vérifié : node 3753, navigateur 730, node-long 101 depuis l'index seul.

Assisted-by: Claude Opus 5.5
2026-10-10 11:07:03 -04:00
e5d9026b2a [ADD] print: seating plan cut into pages, with cartouche and scale
The printed plan draws every table in seat mode with its name lists,
whatever the zoom, and drops screen gestures: no selection, focus,
grab handle or highlight reaches paper. Each page carries a cartouche
(page p of n, column, row) and references to its neighbours; the cut
uses the band measured under the footer. Print marks resolve their
colour tokens from the printed document, so a dark screen theme
leaves the paper light.
Checked: node 3721, browser 720, node-long 101 from the index alone.

--- FR ---

[ADD] impression : plan découpé en pages, avec cartouche et échelle

Le plan imprimé dessine chaque table en régime sièges, avec ses listes
de noms, quel que soit le zoom, et laisse les gestes à l'écran :
sélection, focus, poignée et mise en évidence n'atteignent pas le
papier. Chaque page porte un cartouche (page p sur n, colonne, rangée)
et ses renvois aux voisines ; la découpe prend la bande mesurée sous le
pied. Les marques lisent leurs jetons dans le document imprimé : un
thème sombre à l'écran laisse le papier clair.
Vérifié : node 3721, navigateur 720, node-long 101 depuis l'index seul.

Assisted-by: Claude Opus 5.5
2026-10-10 11:03:12 -04:00
9994858904 [ADD] docs: usage and Windows guides, with how the search works
An operator who did not write the software must be able to prepare an
evening alone. GUIDE-USAGE.md follows an evening step by step on the
published captures, with the seed and stop count that reproduce them, and
explains why two searches give two placements and how the ranking picks
the best one. GUIDE-WINDOWS.md covers installation and the portable mode.
README.md carries the generated contrast and constant tables, and a
delivery build fails when a generated region differs.
Checked: the guide's numbers are bounded in the tests; 3699 node and 101
long tests green from the index alone.

--- FR ---

[ADD] docs : guides d'usage et Windows, fonctionnement de la recherche

Une personne qui n'a pas écrit le logiciel doit pouvoir préparer une soirée
seule. GUIDE-USAGE.md suit une soirée pas à pas sur les captures publiées,
avec la graine et le compte d'arrêt qui les reproduisent, et explique
pourquoi deux recherches donnent deux placements et comment le classement
choisit le meilleur. GUIDE-WINDOWS.md couvre l'installation et le mode
portable. README.md porte les tableaux engendrés des contrastes et des
constantes, et une construction de livraison échoue quand une région diffère.
Vérifié : les nombres du guide sont bornés dans les épreuves ; 3699 node et
101 longues vertes depuis l'index seul.

Assisted-by: Claude Opus 5.5
2026-10-09 17:14:56 -04:00
1e5039af5b [ADD] audit: first engine mutation audit, survivors killed in tests
The audit must say how much of the engine its tests really check. Of 2576
mutants, 2171 are killed, 207 time out, 61 are declared equivalent with a
reason a reviewer can check, and 137 survive, listed by file, operator and
line; the ranking, indicators and ceiling modules have none left. New
tests in classement, indicateurs and plafond kill the survivors found
there, each red under its mutant.
Checked: 3677 node and 101 long tests green from the index alone.

--- FR ---

[ADD] audit : premier audit par mutation du moteur, survivants tués

L'audit doit dire combien du moteur ses épreuves vérifient vraiment. Sur
2576 mutants, 2171 sont tués, 207 dépassent leur délai, 61 sont déclarés
équivalents avec une raison qu'un relecteur vérifie, et 137 survivent,
listés par fichier, opérateur et ligne ; le classement, les indicateurs et
le plafond n'en ont plus. De nouvelles épreuves de classement, indicateurs
et plafond tuent les survivants trouvés là, chacune rouge sous son mutant.
Vérifié : 3677 node et 101 longues vertes depuis l'index seul.

Assisted-by: Claude Opus 5.5
2026-10-09 17:12:23 -04:00
416d91a88f [ADD] badges: prepare, produce and save the sheet from the session
The operator needs the badge sheet as a file next to the event, built
from what the session shows at that moment. The session prepares an
announcement (sheets per paper, counts, namesakes, missing glyphs, draft),
then produces the PDF through a single deferred import of the PDF code and
writes it atomically; under the web build it downloads instead. A gesture
started during production waits its turn. A proposal sheet is always a
draft, and an unwritable file or a missing paper choice gives its refusal
with a remedy.
Checked: red first; 3670 node, 707 browser and 101 long tests green from
the index alone.

--- FR ---

[ADD] badges : préparer, produire et déposer la planche depuis la séance

L'opérateur a besoin de la planche en fichier, à côté de l'événement, tirée
de ce que la séance montre à cet instant. La séance prépare une annonce
(planches par papier, comptes, homonymes, glyphes absents, brouillon), puis
produit le PDF par un seul import différé du code PDF et l'écrit de façon
atomique ; sous web, elle le télécharge. Un geste lancé pendant la
production attend son tour. Une planche tirée d'une proposition est
toujours un brouillon, et un fichier non écrit ou un papier non choisi
donnent leur refus avec un remède.
Vérifié : rouge d'abord ; 3670 node, 707 navigateur et 101 longues vertes
depuis l'index seul.

Assisted-by: Claude Opus 5.5
2026-10-09 17:11:48 -04:00
858018323b [ADD] print: preview screen, printable sheet, paper question
Printed pages must show exactly what will come out of the printer. An
Imprimer button in the event header opens a preview screen where each page
is a sheet at paper size, light whatever the theme, with its footer and,
under the strict draft rule, BROUILLON in outline; a proposal shown on a
retained plan prints as a draft. The paper is asked once per machine and
can be changed there. The table sheets offer one sheet per round. A failed
print shows IMPRESSION_ECHEC. The captures are republished with the button.
Checked: red first; 3651 node, 707 browser and 101 long tests green from
the index alone.

--- FR ---

[ADD] impression : aperçu, feuille imprimable, question du papier

Une page imprimée doit montrer exactement ce que l'imprimante rendra. Un
bouton Imprimer de la tête de l'événement ouvre un aperçu où chaque page
est une feuille au format du papier, claire quel que soit le thème, avec
son pied et, sous la règle stricte, BROUILLON au trait ; une proposition
montrée sur un plan retenu s'imprime en brouillon. Le papier se demande une
fois par machine et s'y change. Les feuilles par table offrent une feuille
par tour. Une impression échouée affiche IMPRESSION_ECHEC. Les captures
sont republiées avec le bouton.
Vérifié : rouge d'abord ; 3651 node, 707 navigateur et 101 longues vertes
depuis l'index seul.

Assisted-by: Claude Opus 5.5
2026-10-09 17:11:37 -04:00
43dbfad8a5 [ADD] docs: photographed walkthrough publishes doc/captures
The screenshots must come from the tested walkthrough, not from a separate
script that can drift. The browser walkthrough runs on the simulated file
system with a driven clock and the direct executor, light theme, 1366 x
700 at scale 1, transitions off, and photographs each step once its
condition holds. make captures writes the images and the manifest; the
plain test run compares them instead. Eighteen captures are published, the
later ones named as postponed. The forged-names scan skips the manifest,
which records the demo names shown on screen.
Checked: red first; 3620 node, 681 browser and 101 long tests green from
the index alone.

--- FR ---

[ADD] docs : parcours photographié, publication de doc/captures

Les captures doivent venir du parcours éprouvé, non d'un script à part qui
dérive. Le parcours navigateur joue sur le système de fichiers simulé,
l'horloge pilotée et l'exécuteur direct, thème clair, 1366 × 700 au facteur
1, transitions coupées, et photographie chaque étape quand sa condition
tient. make captures écrit les images et le manifeste ; la série ordinaire
les compare au lieu de les écrire. Dix-huit captures sont publiées, les
suivantes nommées reportées. Le balayage des noms forgés saute le
manifeste, qui relève les noms de démonstration affichés.
Vérifié : rouge d'abord ; 3620 node, 681 navigateur et 101 longues vertes
depuis l'index seul.

Assisted-by: Claude Opus 5.5
2026-10-09 15:33:59 -04:00
ec3bca4717 [ADD] mutation: engine audit command and its versioned written report
Spec 14.13 asks for an audit that shows which engine mutants the tests
kill, written where a reviewer can read it. npm run mutation and make
mutation run the baseline, a coverage pass that stops early when nothing is
measured, then every mutant; survivors are replayed against the long
series. The report holds version, scope, source fingerprint and Node
version only, no duration, host or date, and refuses any other field.
Declared equivalent mutants live in a separate list of key and reason.
Checked: red first; 3612 node tests green from the index alone.

--- FR ---

[ADD] mutation : commande d'audit du moteur, rapport écrit et versionné

Le § 14.13 demande un audit qui montre quels mutants du moteur les épreuves
tuent, écrit là où un relecteur le lit. npm run mutation et make mutation
jouent la ligne de base, une passe de couverture qui s'arrête tôt si rien
n'est mesuré, puis chaque mutant ; les survivants se rejouent contre la
série longue. Le rapport ne porte que version, périmètre, empreinte du
source et version de Node, ni durée, ni hôte, ni date, et refuse tout autre
champ. Les mutants déclarés équivalents vivent dans une liste à part.
Vérifié : rouge d'abord ; 3612 node verts depuis l'index seul.

Assisted-by: Claude Opus 5.5
2026-10-09 15:29:08 -04:00
3e4fd03a4c [IMP] generation: duration estimate counts the slowdown of busy cores
A core runs slower when its neighbours work too, so the estimate that
divided the run by the number of workers promised too short a wait. The
estimate now multiplies by rho(W), linear from 1 on one core to the
registry constant RALENTISSEMENT_PLEINE_CHARGE when every logical
processor works; the cores setting itself is unchanged. A bench file
measures the curve. An out-of-range setting is refused before
AUCUN_EVENEMENT.
Checked: red first; 3582 node and 659 browser tests green from the index.

--- FR ---

[IMP] génération : l'estimation compte le ralentissement des cœurs

Un cœur va moins vite quand ses voisins travaillent aussi : l'estimation
qui divisait le calcul par le nombre de travailleurs promettait une attente
trop courte. Elle multiplie désormais par rho(W), linéaire de 1 sur un cœur
à la constante RALENTISSEMENT_PLEINE_CHARGE du registre quand tous les
processeurs logiques travaillent ; le réglage des cœurs ne change pas. Un
fichier du banc mesure la courbe. Un réglage hors domaine est refusé avant
AUCUN_EVENEMENT.
Vérifié : rouge d'abord ; 3582 node et 659 navigateur verts depuis l'index.

Assisted-by: Claude Opus 5.5
2026-10-09 15:28:49 -04:00
0b2b2dc303 [ADD] bench: frame time, readable seats and witness string thresholds
Spec 19.10 leaves three rendering thresholds to measurement: the frame time
of the plan while zooming, the smallest seat target that stays readable,
and the width of the witness string under the embedded font. Three bench
files measure them in Chromium, frame time throttled four times, and write
each measure with its own CPU factor into the record; seuils.js derives the
threshold from the samples. No value enters the registry from here.
Checked: red first; 3576 node tests green from the index; the bench
project runs the three measures.

--- FR ---

[ADD] banc : seuils du temps par image, sièges lisibles, chaîne témoin

Le § 19.10 laisse trois seuils de rendu à la mesure : le temps par image du
plan pendant un zoom, la plus petite cible de siège qui reste lisible, et
la largeur de la chaîne témoin sous la police embarquée. Trois fichiers du
banc les mesurent dans Chromium, le temps par image ralenti quatre fois, et
écrivent chaque mesure avec son propre facteur au relevé ; seuils.js tire
le seuil des échantillons. Aucune valeur n'entre au registre d'ici.
Vérifié : rouge d'abord ; 3576 node verts depuis l'index ; le projet du
banc joue les trois mesures.

Assisted-by: Claude Opus 5.5
2026-10-09 15:27:10 -04:00
8fb80324e7 [ADD] pdf: badge sheet production with control page and draft mark
The badge sheet must print at true scale and read back exactly what the
model says. Page 1 is the control sheet: badge size, paper, counts,
namesakes, missing glyphs and a 100 mm ruler; it continues on extra control
pages when a long reprint overflows. One page per sheet follows, with cut
lines, embedded Noto Sans subsets and a ToUnicode map, no metadata, so the
same model yields the same bytes. A draft carries BROUILLON in outline on
every page; the word comes from the caller, never from src/pdf.
Checked: red first, text read back through pdfjs; 3541 node and 101 long
tests green from the index alone.

--- FR ---

[ADD] pdf : production de la planche, page de contrôle, brouillon

La planche de badges doit s'imprimer à l'échelle et se relire exactement
comme le modèle le dit. La page 1 est la feuille de contrôle : taille du
badge, papier, comptes, homonymes, glyphes absents et règle de 100 mm ; elle
continue sur des pages de contrôle quand une longue réédition déborde. Suit
une page par planche, avec traits de coupe, sous-ensembles de Noto Sans et
table ToUnicode, sans métadonnées : le même modèle rend les mêmes octets.
Un brouillon porte BROUILLON au trait sur chaque page ; le mot vient de
l'appelant, jamais de src/pdf.
Vérifié : rouge d'abord, texte relu par pdfjs ; 3541 node et 101 longues
vertes depuis l'index seul.

Assisted-by: Claude Opus 5.5
2026-10-09 15:26:53 -04:00
8b7c732399 [ADD] platform: print bridge, atomic byte writes, badge sheet file name
Printed views and the badge sheet leave the app through the platform. Under
Electron a gtt:imprimer channel prints with the paper and orientation asked
for and reports sent, cancelled, failed or unknown; an exception is logged
to the console and never shown raw to the operator. Every file system,
real or simulated, writes bytes atomically from a copy taken at the call.
The sheet name carries event, date and imposition, and a failed print
becomes IMPRESSION_ECHEC.
Checked: red first, twelve mutations caught; 3502 node, 659 browser and 79
long tests green from the index alone.

--- FR ---

[ADD] plateforme : pont d'impression, octets atomiques, nom de planche

Les vues imprimables et la planche sortent de l'application par la
plateforme. Sous Electron, un canal gtt:imprimer imprime au papier et à
l'orientation demandés et rend envoyé, annulé, échec ou inconnu ; une
exception va à la console, jamais brute à l'opérateur. Chaque système de
fichiers, réel ou simulé, écrit des octets de façon atomique, depuis une
copie prise à l'appel. Le nom de la planche porte événement, date et
imposition, et une impression échouée devient IMPRESSION_ECHEC.
Vérifié : rouge d'abord, douze mutations attrapées ; 3502 node, 659
navigateur et 79 longues vertes depuis l'index seul.

Assisted-by: Claude Opus 5.5
2026-10-09 15:26:13 -04:00
8371e8f1ec [ADD] docs: generated regions in README and guides, checked on build
Tables in the documentation must come from the code, not be copied by hand.
scripts/documentation.js fills marked regions of README.md and the guides
from the single sources: settings, shortcuts, CSV columns, constants and
measured contrasts. A check mode reports any region that differs, and a
missing manifest blocks a delivery build. Editing a carrier document reruns
the documentation tests.
Checked: red first; 3454 node, 655 browser and 76 long tests green from the
index alone.

--- FR ---

[ADD] docs : régions engendrées du README et des guides, vérifiées

Les tableaux de la documentation doivent venir du code, non d'une copie à la
main. scripts/documentation.js remplit les régions marquées de README.md et
des guides à partir des sources uniques : réglages, raccourcis, colonnes CSV,
constantes et contrastes relevés. Un mode de vérification signale toute
région qui diffère, et un manifeste absent bloque une construction de
livraison. Modifier un document porteur relance les épreuves de la
documentation.
Vérifié : rouge d'abord ; 3454 node, 655 navigateur et 76 longues vertes
depuis l'index seul.

Assisted-by: Claude Opus 5.5
2026-10-09 13:06:01 -04:00
8bdc959183 [ADD] mutation: run one mutant through node --test with a loader hook
A mutant counts only when the tests that import its module actually run
against the mutated source. A loader hook (module.registerHooks) serves the
mutated text in place of the module; the import graph picks the tests that
reach it, and node --test runs them in a child with a deadline. The verdict
is killed, survived, timed out or error; an empty request, a missing test
or a non-positive deadline is refused before anything starts.
Checked: red first; 3418 node and 76 long tests green from the index,
including a real run on a small invented module.

--- FR ---

[ADD] mutation : jouer un mutant sous node --test, crochet de chargement

Un mutant ne compte que si les épreuves qui importent son module jouent
vraiment contre le source muté. Un crochet de chargement
(module.registerHooks) sert le texte muté à la place du module ; le graphe
des imports choisit les épreuves qui l'atteignent, et node --test les joue
dans un enfant sous délai. Le verdict est tué, survivant, délai ou erreur ;
une demande vide, une épreuve absente ou un délai non positif sont refusés
avant tout lancement.
Vérifié : rouge d'abord ; 3418 node et 76 longues vertes depuis l'index,
dont un vrai lancement sur un petit module inventé.

Assisted-by: Claude Opus 5.5
2026-10-09 13:04:14 -04:00
079b158587 [ADD] bench: headless Chromium harness, statistics and make banc entry
Rendering thresholds must be measured in a real browser, apart from the
test series that guard behaviour. A separate Vitest project runs
scripts/banc/**/*.banc.js in headless Chromium at 1366 x 700, scale 1,
without frame-rate limit, CPU throttling set per run; the statistics module
gives medians and spreads over repeated samples. Outputs go to an ignored
folder. make banc and npm run banc name the entry; its orchestrator comes
with the bench measures.
Checked: red first; 3410 node tests green from the index; the bench project
runs its harness.

--- FR ---

[ADD] banc : harnais Chromium sans tête, statistiques, entrée make banc

Les seuils de rendu se mesurent dans un vrai navigateur, à part des séries
qui gardent le comportement. Un projet Vitest distinct joue
scripts/banc/**/*.banc.js dans Chromium sans tête à 1366 × 700, facteur 1,
sans limite d'images, le ralentissement du processeur réglé par lancement ;
le module de statistiques rend médianes et dispersions sur des mesures
répétées. Les sorties vont dans un dossier ignoré. make banc et npm run banc
nomment l'entrée ; son orchestrateur vient avec les mesures du banc.
Vérifié : rouge d'abord ; 3410 node verts depuis l'index ; le projet du
banc joue son harnais.

Assisted-by: Claude Opus 5.5
2026-10-09 13:03:37 -04:00
307ee526fc [ADD] bench: versioned record format and its agreement with constants
Measured thresholds must be adopted by a developer, never written by the
bench into the code. The record holds the bench configuration and its
measures; its reader refuses an empty record, a measure without its
constant, and any field or value that looks like a host, an account or a
date. A guard in the constants test makes every registry value that claims
a bench origin agree with the record.
Checked: red first, eight mutations caught; 3392 node tests green from the
index alone.

--- FR ---

[ADD] banc : format du relevé versionné, accord avec les constantes

Un seuil mesuré s'adopte par un geste du développeur ; le banc ne l'écrit
jamais dans le code. Le relevé porte la configuration du banc et ses
mesures ; sa lecture refuse un relevé vide, une mesure sans sa constante,
et tout champ ou valeur qui ressemble à un hôte, un compte ou une date. Une
garde de l'épreuve des constantes accorde au relevé chaque valeur du
registre qui se dit tirée du banc.
Vérifié : rouge d'abord, huit mutations attrapées ; 3392 node verts depuis
l'index seul.

Assisted-by: Claude Opus 5.5
2026-10-09 13:03:20 -04:00
4e25e73a5d [ADD] badges: sheet model from the retained plan or a chosen proposal
Badges hang on guests' necks: their content must be exact and stable. The
model builds one badge per non-excluded person, from the retained plan or,
on demand, from a proposal, which always prints as a draft. Each round says
table, seat when seats are assigned, and a title only where a reservation
makes the person its holder there; a constant itinerary takes one line.
Names sort by code point, never by locale; namesakes carry their id, and a
reprint gives the same texts. Without any placement it refuses, pointing at
the proposals.
Checked: red first; 3343 node tests green from the index alone.

--- FR ---

[ADD] badges : modèle de planche, du retenu ou d'une proposition choisie

Les badges pendent au cou des invités : leur contenu doit être exact et
stable. Le modèle fait un badge par personne non exclue, depuis le retenu
ou, sur demande, une proposition, toujours imprimée en brouillon. Chaque
tour dit la table, le siège sous attribution, et un titre seulement là où
une réservation en fait la personne titulaire ; un itinéraire constant tient
en une ligne. Les noms se classent par points de code, jamais selon la
locale ; les homonymes portent leur identifiant, et une réédition rend les
mêmes textes. Sans aucun placement, il refuse et renvoie aux propositions.
Vérifié : rouge d'abord ; 3343 node verts depuis l'index seul.

Assisted-by: Claude Opus 5.5
2026-10-09 13:03:04 -04:00
270c27f7ed [ADD] pdf: badge layout with a sacrifice order and injected metrics
A badge must keep the name whole and readable whatever its length. The pure
layout picks the largest name size that fits in one to three lines, then
lays rounds on one or two columns down to the floor size, then drops the
event name from the footer and then the affiliation; past that it refuses.
A round line too wide shortens its title only, keeping at least one grapheme
of it, never the table or seat. Metrics are injected, so the same code lays
out under Noto Sans and under a fixed-pitch test font.
Checked: red first; 3299 node tests green from the index alone.

--- FR ---

[ADD] pdf : badge mis en page, ordre de sacrifice, métriques injectées

Un badge doit garder le nom entier et lisible, quelle que soit sa longueur.
La mise en page, pure, choisit le plus grand corps du nom qui tient en une à
trois lignes, pose les tours sur une ou deux colonnes jusqu'au corps
plancher, puis retire du pied le nom de l'événement, puis l'appartenance ;
au-delà, elle refuse. Une ligne de tour trop large n'abrège que son titre,
en garde au moins une grappe, jamais la table ni le siège. Les métriques
sont injectées : le même code se met en page sous Noto Sans et sous une
police d'épreuve à chasse fixe.
Vérifié : rouge d'abord ; 3299 node verts depuis l'index seul.

Assisted-by: Claude Opus 5.5
2026-10-09 13:02:53 -04:00
0ac686487f [ADD] geometry: cut the seating plan into printed pages
A plan too large to read on one sheet must print as a grid of pages that
join exactly. The cut picks the orientation that gives fewest pages, then
the larger scale, then landscape; tiles meet at exact equality on 2^-20 cm
coordinates, columns are lettered A to Z then AA, and a table or name block
that straddles two pages is reported on both. The print bounding box
includes measured name blocks but no handle or target.
Checked: red first, including a fast-check property on drawn plans, papers
and thresholds; 3245 node tests green from the index alone.

--- FR ---

[ADD] géométrie : découpe du plan de salle en pages imprimées

Un plan trop grand pour se lire sur une feuille doit s'imprimer en une
grille de pages qui se joignent exactement. La découpe choisit
l'orientation qui donne le moins de pages, puis la plus grande échelle, puis
le paysage ; les tuiles se touchent à l'égalité exacte sur des cotes de
2^-20 cm, les colonnes vont de A à Z puis AA, et une table ou un bloc de
noms à cheval sur deux pages se signale sur les deux. L'englobant imprimé
compte les blocs de noms mesurés, sans poignée ni cible.
Vérifié : rouge d'abord, dont une propriété fast-check sur plans, papiers
et seuils tirés ; 3245 node verts depuis l'index seul.

Assisted-by: Claude Opus 5.5
2026-10-09 13:02:18 -04:00
88d35f5979 [IMP] interface: Noto Sans everywhere, faces loaded before mounting
The screen must match the screenshots and the text the tests measure. The
interface now uses the embedded Noto Sans for every element, form controls
included, with a 1.3 line height. The entry point and the test mount wait
for both faces before mounting, so no text measurer caches the fallback
width; a face that fails to load is reported and the app mounts anyway.
The screens the wider font overflowed have their own CSS adjusted.
Checked: red first; 3216 node, 655 browser and 71 long tests green from the
index; the Electron start-up check loads the font from file://.

--- FR ---

[IMP] interface : Noto Sans partout, faces chargées avant le montage

L'écran doit ressembler aux captures et au texte que mesurent les épreuves.
L'interface emploie désormais Noto Sans, embarquée, pour tout élément,
contrôles de formulaire compris, avec un interligne de 1,3. Le point
d'entrée et le montage d'épreuve attendent les deux faces avant de monter :
aucun mesureur ne garde la largeur de repli ; une face qui ne se charge pas
est signalée et l'application se monte quand même. Les écrans que la police
plus large débordait ajustent leur propre CSS.
Vérifié : rouge d'abord ; 3216 node, 655 navigateur et 71 longues vertes
depuis l'index ; l'essai de démarrage charge la police par file://.

Assisted-by: Claude Opus 5.5
2026-10-09 13:01:49 -04:00
d8a6fb8202 [ADD] bench: a priori ceiling cost on the largest and worst events
Spec 17 point 4 asks whether the a priori ceiling is cheap enough to compute
on every check. The bench times plafondsAPriori and diagnostiquer on the
large demonstration, its variant without exceptions, and a pessimistic
event of 260 people, 33 tables of 8 and 10 rounds with every signature
distinct: about 0.075 ms, 0.04 ms and 11.5 ms. A long test guards each at
four times its reference, so losing the memoisation turns it red.
Checked: red first under that mutant; 3208 node and 71 long tests green.

--- FR ---

[ADD] banc : coût du plafond a priori, grand événement et pire cas

Le spec 17, point 4, demande si le plafond a priori se calcule assez vite
pour chaque contrôle. Le banc mesure plafondsAPriori et diagnostiquer sur
la grande démonstration, sa variante sans exception, et un événement
pessimiste de 260 personnes, 33 tables de 8 et 10 tours aux signatures
toutes distinctes : environ 0,075 ms, 0,04 ms et 11,5 ms. Une épreuve
longue garde chacun à quatre fois sa référence : perdre la mémoïsation la
rend rouge.
Vérifié : rouge d'abord sous ce mutant ; 3208 node et 71 longues vertes.

Assisted-by: Claude Opus 5.5
2026-10-09 04:53:10 -04:00
52bc5f0bc8 [ADD] mutation: engine mutant generator on Vite's parser
The engine's tests must be shown to fail when its code is wrong (spec
14.13). The generator parses each module of src/moteur with Vite's parseAst
and yields one mutant per site and operator: arithmetic, boundary,
negation, logic, update, numbers, booleans, branches, ternaries, min/max.
Strings, comments, templates and imports are never mutated, sites follow
source order, and a mutant key survives an unrelated line added above it.
2576 mutants on src/moteur, enumerated in tens of milliseconds.
Checked: tests red first; 3201 node tests green from the index alone.

--- FR ---

[ADD] mutation : générateur de mutants du moteur, analyseur de Vite

Il faut montrer que les épreuves du moteur échouent quand son code est faux
(spec 14.13). Le générateur lit chaque module de src/moteur par parseAst de
Vite et rend un mutant par site et par opérateur : arithmétique, frontière,
négation, logique, mise à jour, nombres, booléens, branches, ternaires,
min/max. Chaînes, commentaires, gabarits et imports ne sont jamais mutés,
les sites suivent l'ordre du source, et une clé de mutant survit à une
ligne sans rapport ajoutée au-dessus. 2576 mutants sur src/moteur, énumérés
en quelques dizaines de millisecondes.
Vérifié : rouge d'abord ; 3201 node verts depuis l'index seul.

Assisted-by: Claude Opus 5.5
2026-10-09 04:52:30 -04:00
aabb05e038 [ADD] docs: screenshot manifest with order, path and image checks
Screenshots and guides must stay in step with the software they show. The
manifest names each screenshot, its stage and its fingerprint; the checks
refuse a missing or out-of-order image, a guide reference to an unknown
capture, a wrong PNG size, and any absolute path outside the neutral root.
Captures planned for a later iteration are named as postponed and admitted.
Checked: 50 tests red first; 3169 node tests green from the index alone.

--- FR ---

[ADD] docs : manifeste des captures, contrôles d'ordre, chemins, images

Les captures et les guides doivent suivre le logiciel qu'ils montrent. Le
manifeste nomme chaque capture, son étape et son empreinte ; les contrôles
refusent une image absente ou hors d'ordre, un guide qui cite une capture
inconnue, une taille de PNG fausse, et tout chemin absolu hors de la racine
neutre. Les captures prévues pour une itération ultérieure sont nommées
reportées, et admises.
Vérifié : 50 épreuves rouges d'abord ; 3169 node verts depuis l'index seul.

Assisted-by: Claude Opus 5.5
2026-10-09 04:52:07 -04:00
9d4f203ead [ADD] interface: single sources for settings, shortcuts and CSV columns
The generated documentation must list exactly what the screen shows. The
generation settings, the keyboard shortcuts and the CSV columns each live in
one table that both the interface and the documentation read; the target
field of the proposals section reads its entry too. A guard reports any key
named in the interface without its shortcut entry. The LISTE_SUR_VOISINE
warning now shows its remedy, moving the covered neighbour.
Checked: 3116 node and 643 browser tests green from the index alone.

--- FR ---

[ADD] interface : sources uniques des réglages, raccourcis, colonnes CSV

La documentation engendrée doit lister exactement ce que l'écran montre.
Les réglages de la génération, les raccourcis clavier et les colonnes du
CSV vivent chacun dans une table que lisent l'interface et la
documentation ; le champ de la cible des propositions lit aussi la sienne.
Une garde relève toute touche nommée dans l'interface sans son entrée de
raccourci. L'avertissement LISTE_SUR_VOISINE montre désormais son remède,
le déplacement de la voisine couverte.
Vérifié : 3116 node et 643 navigateur verts depuis l'index seul.

Assisted-by: Claude Opus 5.5
2026-10-09 04:51:45 -04:00
0e9ff8c708 [ADD] outputs: dated placement, draft rule, page footer, machine paper
A badge or a printed page must say which placement it shows and whether it
is a draft. The retained plan and each proposal carry an optional
timestamp, set when their placement changes and kept when a command rebuilds
it unchanged, with or without an instant; format 1 is unchanged and the
shipped demonstrations stay byte-identical. Anything but the retained plan
under a retained or locked state prints as a draft, proposals included. The
footer names event, date, round, timestamp and visible version.
Checked: red first; 3085 node and 639 browser tests green from the index.

--- FR ---

[ADD] sorties : placement daté, règle du brouillon, pied, papier

Un badge ou une page imprimée doit dire quel placement il montre et s'il
est un brouillon. Le retenu et chaque proposition portent un horodatage
facultatif, posé quand leur placement change et gardé quand une commande le
reconstruit à l'identique, avec ou sans instant ; le format 1 ne change pas
et les démonstrations livrées restent identiques à l'octet. Tout ce qui
n'est pas le retenu sous l'état retenu ou bloqué s'imprime en brouillon,
propositions comprises. Le pied nomme événement, date, tour, horodatage et
version visible.
Vérifié : rouge d'abord ; 3085 node et 639 navigateur verts depuis l'index.

Assisted-by: Claude Opus 5.5
2026-10-09 04:50:31 -04:00
e1245dcc08 [ADD] outputs: pdf-lib, Noto Sans, paper sizes, badge imposition
Badges and printed views need a PDF writer, an embedded font whose metrics
the tests can measure, and the paper the machine prints on. pdf-lib with
fontkit writes the sheet; Noto Sans (OFL) ships with its provenance and
SHA-256, and travels into www/ with every third-party notice that the
minified bundle drops. The paper is kept per machine in reglages_locaux.json.
A4 and Letter derive the A6 grid from their dimensions; the PDF libraries
load in two deferred chunks, each under the 1000 kB threshold.
Checked: 3048 node, 639 browser and 67 long tests green from the index.

--- FR ---

[ADD] sorties : pdf-lib, Noto Sans, formats de papier, imposition

Les badges et les vues imprimables exigent un producteur de PDF, une police
embarquée que les épreuves mesurent, et le papier de la machine. pdf-lib et
fontkit écrivent la planche ; Noto Sans (OFL) arrive avec sa provenance et
son SHA-256, et voyage dans www/ avec chaque avis de tiers que le paquet
minifié retire. Le papier se garde par machine dans reglages_locaux.json.
A4 et Lettre dérivent la grille A6 de leurs dimensions ; les bibliothèques
PDF se chargent en deux morceaux différés, chacun sous le seuil de 1000 ko.
Vérifié : 3048 node, 639 navigateur et 67 longues vertes depuis l'index.

Assisted-by: Claude Opus 5.5
2026-10-09 04:49:18 -04:00
3028fca2ed [FIX] interface: ghost labels, keyboard, valid HTML, closed data-* list
The drag ghost names what releasing at the point changes, floor included.
Escape on a seat returns to its table, a refused Tab stays put, the legend
toggle exposes aria-expanded, and the header markup is valid HTML. Every
data-* attribute the interface sets belongs to one closed list that a guard
reads. The tree guards follow helpers a test imports, and the reporter says
the whole series stays watched under coverage on a small machine.
Checked: every new test red first; 3001 node, 635 browser and 63 long tests
green from the index alone.

--- FR ---

[FIX] interface : fantôme nommé, clavier, HTML valide, data-* fermés

Le fantôme du glisser nomme ce que relâcher au point modifie, sol compris.
Échap sur un siège remonte à sa table, un Tab refusé reste en place, la
bascule de la légende expose aria-expanded, et la tête est du HTML valide.
Chaque attribut data-* que l'interface pose appartient à une liste fermée
qu'une garde lit. Les gardes de l'arbre suivent les aides qu'une épreuve
importe, et le rapporteur dit la série entière surveillée sous couverture.
Vérifié : chaque épreuve rouge d'abord ; 3001 node, 635 navigateur et 63
longues vertes depuis l'index seul.

Assisted-by: Claude Opus 5.5
2026-10-09 04:02:03 -04:00
d5a1560915 [FIX] core: bounded geometry, dated lock, empty seat, neighbour lists
Non-finite scale ratios, view translations and handle counts now raise
instead of returning 0, NaN or looping forever. The lock carries the
instant from the single clock, a lock taken back in this session's name is
its own, and quitting releases held locks. An empty chair is null only, at
its exact path. A table grown over a neighbour warns LISTE_SUR_VOISINE once
per pair; successive remedies never aim at the same free cell.
Checked: every new test red first; 2983 node and 617 browser tests green
from the index alone.

--- FR ---

[FIX] cœur : géométrie bornée, verrou daté, chaise vide, listes voisines

Un rapport d'échelle, une translation de vue ou un compte de poignée non
finis lèvent au lieu de rendre 0, NaN ou de boucler sans fin. Le verrou
porte l'instant de l'horloge unique, un verrou repris au nom de la séance
est le sien, et quitter rend les verrous tenus. Une chaise vide est null
seulement, à son chemin exact. Une table agrandie sur sa voisine avertit
LISTE_SUR_VOISINE une fois par paire ; les remèdes successifs ne visent
jamais la même case libre.
Vérifié : chaque épreuve rouge d'abord ; 2983 node et 617 navigateur verts
depuis l'index seul.

Assisted-by: Claude Opus 5.5
2026-10-09 04:00:22 -04:00
94ea937ae4 [IMP] home: list shown at once, computed columns loaded per event
The event list waited until every event's ranking was evaluated, about
10 ms per event with propositions, before showing anything. It now shows
as soon as the folder is read; each line's retained-plan columns and best
proposition load one event at a time, yielding to the browser between
events, behind a rotating SVG spinner, and show as each result arrives.
Work for a list no longer shown is dropped. The spinner is the one named
exception to the no-animation rule: still under reduced motion, cancelled
for captures, announced once. Checked: 2935 node, 616 browser, 62 long.

--- FR ---

[IMP] accueil : liste aussitôt montrée, colonnes calculées par événement

La liste des événements attendait l'évaluation du classement de chaque
événement, environ 10 ms par événement qui a des propositions, avant de
rien montrer. Elle paraît dès la lecture du dossier ; les colonnes du
retenu et la meilleure proposition de chaque ligne se chargent un
événement à la fois, le navigateur reprenant la main entre deux, derrière
une icône SVG qui tourne. Le travail d'une liste qui n'est plus montrée
est abandonné. L'icône est la seule exception nommée à l'interdit
d'animation. Vérifié : 2935 node, 616 navigateur, 62 longues.

Assisted-by: Claude Opus 5.5
2026-10-08 17:07:31 -04:00
9eb1275f53 [ADD] home: best ranked proposition on every event line
Each event line of the home lists now names its rank-1 proposition and
its cumulated collisions, whether or not a plan is retained, with the
same label and tooltip as the generation block. One application function
picks the rank-1 proposition for both places, so the list, the generation
block and the propositions table show the same proposition and number.
The list reads the examined charge, as opening the event does, so a file
with a repeated proposition identifier no longer hides the whole folder.
Checked: 2923 node, 609 browser, 62 long tests, from the index alone.

--- FR ---

[ADD] accueil : meilleure proposition classée sur chaque événement

Chaque ligne des listes de l'accueil nomme sa proposition de rang 1 et ses
collisions cumulées, retenu ou non, avec le même libellé et la même
infobulle que le bloc de la génération. Une seule fonction d'application
désigne le rang 1 aux deux endroits : la liste, le bloc et le tableau des
propositions montrent la même proposition et le même nombre. La liste lit
la charge examinée, comme l'ouverture : un fichier dont une proposition
répète un identifiant ne fait plus disparaître tout le dossier.
Vérifié : 2923 node, 609 navigateur, 62 longues, depuis l'index seul.

Assisted-by: Claude Opus 5.5
2026-10-08 06:06:21 -04:00
5fc5ac9205 [ADD] home: retained plan's collisions and redundancy gap per event
The event list showed no outcome, so comparing events meant opening each.
Each line now shows, for the retained plan only, the cumulated collisions
(pair and tour) and the redundancy gap |target - sum of r(p)|, with an
explanation tooltip; an event without a measurable retained plan shows a
dash. The target is set per event in Propositions, 1000 by default: an
optional settings field, absent in every existing file and read as 1000,
written through one undoable command refused in reading mode. Listing
stays read-only. Checked: 2909 node, 604 browser, 62 long tests.

--- FR ---

[ADD] accueil : collisions et Diff de redondance du retenu par événement

La liste des événements ne montrait aucun résultat : comparer obligeait à
ouvrir chacun. Chaque ligne montre, pour le retenu seul, les collisions
cumulées (paire et tour) et la Diff somme d'appartenance, |cible - somme
de r(p)|, avec une infobulle ; sans retenu mesurable, un tiret. La cible
se règle par événement dans Propositions, 1000 par défaut : champ
facultatif des réglages, absent de tout fichier existant et lu 1000, écrit
par une commande qui se défait et se refuse en lecture. La liste reste en
lecture seule. Vérifié : 2909 node, 604 navigateur, 62 longues.

Assisted-by: Claude Opus 5.5
2026-10-08 05:35:48 -04:00
654cde4f10 [ADD] generation: best proposition block with its cumulated collisions
The generation screen gave no sign of where the ranking stood, so the
operator had to switch to the propositions to see whether another run was
worth it. A block at the top now names the rank-1 proposition and its
cumulated collisions (pair and tour), read from the same evaluation table
as the propositions, with the same explanation tooltip. It says so in
words when no proposition is ranked, and stays visible in reading mode,
on a blocked plan and during a generation.
Checked: 2886 node, 599 browser tests, from the index alone.

--- FR ---

[ADD] génération : bloc de la meilleure proposition, collisions cumulées

L'écran de génération ne disait rien du classement : l'opérateur devait
passer aux propositions pour juger si une autre génération valait la
peine. Un bloc en tête nomme la proposition de rang 1 et ses collisions
cumulées (paire et tour), lues dans la même table d'évaluation que les
propositions, avec la même infobulle d'explication. Il le dit en mots
quand aucune proposition n'est classée, et reste visible en lecture, sur
un plan bloqué et pendant une génération.
Vérifié : 2886 node, 599 navigateur, depuis l'index seul.

Assisted-by: Claude Opus 5.5
2026-10-08 05:27:32 -04:00
afdad31ef3 [ADD] propositions: explanation tooltips on criteria and column headers
The propositions table names its measures with the glossary's terms, which
an organiser cannot be expected to know. Each ranking criterion of the
order sentence and each column header now shows a short explanation on
hover or keyboard focus: what the number counts and whether lower or
higher is better, written from the spec and the engine. The tooltip is a
reusable primitive, read through aria-describedby, kept in the window,
never over its word, closed by Escape; the rendering guards measure it.
Checked: 2882 node, 592 browser tests, from the index alone.

--- FR ---

[ADD] propositions : infobulles d'explication des critères et colonnes

Le tableau des propositions nomme ses mesures par les termes du glossaire,
qu'un organisateur n'a pas à connaître. Chaque critère de la phrase de
l'ordre et chaque en-tête de colonne montre une courte explication au
survol ou au focus : ce que compte le nombre, et s'il vaut mieux bas ou
haut, écrite d'après le spec et le moteur. L'infobulle est une primitive
réutilisable, lue par aria-describedby, gardée dans la fenêtre, jamais sur
son mot, fermée par Échap ; les gardes du rendu la mesurent.
Vérifié : 2882 node, 592 navigateur, depuis l'index seul.

Assisted-by: Claude Opus 5.5
2026-10-08 04:56:52 -04:00
b969304c2a [ADD] generation: a pool of workers over the CPUs, cores setting
Generation ran in a single worker, one proposition after another, using
one core. A pool of workers now takes propositions by rank, as many as
the cores set: automatic by default (every logical CPU), or a count from
1 to that number. Each proposition is still computed from its own derived
seed, so the result is byte-identical whatever the core count, ordered by
identifier. One progress bar sums the workers; Cancel stops them all; the
duration estimate counts the cores. The setting is per session and never
written. Checked: 2872 node, 586 browser, 62 long; 5 workers in Electron.

--- FR ---

[ADD] génération : réserve de travailleurs sur les processeurs, cœurs

La génération tournait dans un seul travailleur, une proposition après
l'autre, sur un seul cœur. Une réserve de travailleurs prend maintenant les
propositions par rang, autant que de cœurs réglés : automatique par défaut
(tous les processeurs logiques), ou un nombre de 1 à ce total. Chaque
proposition se calcule toujours depuis sa graine dérivée : le résultat est
identique à l'octet quel que soit le nombre de cœurs, rangé par
identifiant. Une seule barre ; Annuler arrête tout ; l'estimation compte
les cœurs. Réglage de séance, jamais écrit. Vérifié : 2872, 586, 62.

Assisted-by: Claude Opus 5.5
2026-10-08 04:35:21 -04:00
8afa53ebba [ADD] plan: one hue and pattern per conflict rule, legend, appartenance
The plan drew every conflict in one hue, so a table that seats colleagues
together looked like one where people meet again. Each active rule now has
its own reserved hue and pattern: same appartenance hatched one way, met
again hatched the other, back at a table dotted; rules on one table
overlap, the badge keeps the total. A legend from the view bar shows each
active rule's sample. A table's tooltip names the appartenance that brings
a pair together. The hues are validated by computation in both themes and
the spec (7.5, 12.7) follows. Checked: 2848 node, 580 browser tests.

--- FR ---

[ADD] plan : une teinte et une trame par règle, légende, appartenance

Le plan dessinait tout conflit d'une seule teinte : une table qui réunit
des collègues ressemblait à une table où des gens se revoient. Chaque
règle active a sa teinte réservée et sa trame : même appartenance hachurée
dans un sens, voisins revus dans l'autre, table revue en pointillé ; les
règles d'une table se superposent, la pastille garde le total. Une légende
dans la barre de vue montre l'échantillon de chaque règle active.
L'infobulle nomme l'appartenance qui réunit une paire. Teintes validées
par calcul dans les deux thèmes ; spec § 7.5, § 12.7. Vérifié : 2848, 580.

Assisted-by: Claude Opus 5.5
2026-10-08 04:33:43 -04:00
5f62698c82 [ADD] participants: conflicts of the shown plan inside the list groups
When the list is grouped and a proposition is shown, or a plan retained,
each group whose people are in a conflict carries a mark and a count, and
lists every conflict: the tour, the table number, the people, and the
rule broken (same appartenance, met again, back at a table). The
conflicts are read from the engine's per-table conflicts, as the plan
reads them, from the same placement and the same earlier tours, so both
screens give the same numbers. Nothing is written to the event.
Checked: 2831 node, 571 browser tests, from the index alone.

--- FR ---

[ADD] participants : conflits du plan montré dans les groupes

Quand la liste est groupée et qu'une proposition est montrée, ou un plan
retenu, chaque groupe dont des personnes sont en conflit porte une marque
et un compte, et liste chaque conflit : le tour, le numéro de table, les
personnes et la règle enfreinte (même appartenance, se revoient, revient à
une table). Les conflits se lisent dans ceux du moteur par table, comme le
plan, sur le même placement et les mêmes tours antérieurs : les deux
écrans donnent les mêmes chiffres. Rien ne s'écrit dans l'événement.
Vérifié : 2831 node, 571 navigateur, depuis l'index seul.

Assisted-by: Claude Opus 5.5
2026-10-08 04:32:30 -04:00
fbff3a6c5f [ADD] participants: group the list by columns, with counts and collapse
The participants list can now be grouped by one or more columns, nested
level by level: appartenance (by its normalised key, labelled with its
first spelling), status, exclusion, or any text column. Each group header
shows its value, its count and a keyboard-operable collapse button, with
Collapse all and Expand all. The filter applies first, groups follow the
current sort, arrow keys skip headers and collapsed rows, and an edit
moves its row to its new group. Grouping is session state only and never
writes the event. Checked: 2811 node, 565 browser tests, index alone.

--- FR ---

[ADD] participants : grouper la liste par colonnes, compte et repli

La liste des participants se groupe par une ou plusieurs colonnes,
imbriquées niveau par niveau : appartenance (par sa clé normalisée, sous sa
première orthographe), statut, exclusion, ou toute colonne de texte.
Chaque en-tête de groupe montre sa valeur, son compte et un bouton de
repli au clavier, avec Tout replier et Tout déplier. Le filtre s'applique
d'abord, les groupes suivent le tri, les flèches sautent les en-têtes et
les lignes repliées, et une saisie déplace sa ligne dans son nouveau
groupe. État de séance seul, aucune écriture. Vérifié : 2811 node, 565.

Assisted-by: Claude Opus 5.5
2026-10-08 03:49:36 -04:00
57a2642b99 [ADD] propositions: a ranking criterion highlights its table column
The order sentence names the ranking criteria, but nothing tied a name to
the column holding its value. Each criterion name, and « l'identifiant
croissant », now highlights its column when hovered or focused: the header
and every cell get heavier side borders and the header an underline, so
text contrast is unchanged and the cue is not colour alone. The mapping
from criterion to column lives in the propositions model, and a criterion
without a column fails there. The sentence still reads word for word.
Checked: 2780 node, 554 browser tests, from the index alone.

--- FR ---

[ADD] propositions : un critère du classement surligne sa colonne

La phrase de l'ordre nomme les critères, mais rien ne reliait un nom à la
colonne qui porte sa valeur. Chaque nom de critère, et « l'identifiant
croissant », surligne maintenant sa colonne au survol ou au focus : l'en-
tête et chaque cellule prennent des bords latéraux plus épais et l'en-tête
un soulignement ; le contraste du texte ne change pas, le signe ne tient
pas qu'à la couleur. Le lien critère-colonne vit dans le modèle, et un
critère sans colonne y lève. La phrase se lit mot pour mot comme avant.
Vérifié : 2780 node, 554 navigateur, depuis l'index seul.

Assisted-by: Claude Opus 5.5
2026-10-08 03:39:25 -04:00
e59878d650 [IMP] build: chunk size warning at 1000 kB, a failing test beyond it
Vite warned on every build because its 500 kB threshold targets pages
fetched over a network; this page is read from the local disk once, and
one chunk holds the whole application with the generation worker inlined.
The threshold now sits at 1000 kB, so it only flags abnormal growth, and
the build test fails when any chunk exceeds it, naming the file and size.
Checked: the build is 658 kB with no warning; a 600 kB threshold turns the
test red.

--- FR ---

[IMP] construction : seuil d'avertissement à 1000 ko, épreuve au-delà

Vite avertissait à chaque construction, car son seuil de 500 ko vise les
pages chargées par le réseau ; cette page se lit sur le disque local, une
fois, et un seul morceau porte l'application entière, travailleur de
génération incrusté compris. Le seuil passe à 1000 ko et ne signale plus
qu'une croissance anormale ; l'épreuve de construction tombe quand un
morceau le dépasse, en nommant le fichier et sa taille. Vérifié : 658 ko
sans avertissement ; un seuil à 600 ko rend l'épreuve rouge.

Assisted-by: Claude Opus 5.5
2026-10-08 03:08:48 -04:00
fca74b6672 [ADD] tests: spec coverage guards, delivery checks, spec corrections
New guards close the spec coverage gaps: only the configuration and the
diagnostic read reservations in the engine, no second language in the
sources, the engine and geometry never read the version, a test lives
beside its module, fixtures never copy a shipped file, and the property
library stays in a closed list. The delivery test pins the www output and
the French language passed by the entry point. The spec names three test
projects and the three shell files. Checked: 2778 node, 550 browser and
62 long tests from the index alone; the version check passes.

--- FR ---

[ADD] épreuves : gardes de couverture du spec, livrable, spec corrigé

De nouvelles gardes ferment les manques de couverture : seules la
configuration et le diagnostic lisent les réservations dans le moteur,
aucun second langage dans les sources, le moteur et la géométrie ne lisent
pas la version, une épreuve vit près de son module, aucune donnée d'épreuve
ne copie un fichier livré, la bibliothèque de propriétés reste en liste
fermée. Le livrable fige la sortie www et la langue française du point
d'entrée. Le spec nomme trois projets et trois fichiers de coquille.
Vérifié : 2778 node, 550 navigateur, 62 longues ; version conforme.

Assisted-by: Claude Opus 5.5
2026-10-07 17:51:49 -04:00
ddd587da87 [FIX] iteration 3 review: seat targets, gestures, warnings, settings
The wheel no longer zooms during a gesture, so a drop lands under the
ghost. A seat is a target the size of its pitch. A floor drop refuses to
remove an every-tour reservation. A seat reservation the retained plan
does not hold is flagged at the seat, with its swap as remedy. DERIVE names
the person; capacities have an upper bound; Generate waits for a pending
setting; a worker that fails to load shows a refusal; § 5.3 constraints
get their switches. Commands are not re-entrant and a double click does not
confirm. Checked: 2755 node, 550 browser tests, from the index alone.

--- FR ---

[FIX] revue de l'itération 3 : cibles, gestes, avertissements, réglages

La molette ne zoome plus pendant un geste : le dépôt tombe sous le fantôme.
Un siège est une cible de la taille de son pas. Un dépôt sur le sol refuse
de retirer une réservation de tous les tours. Une réservation à un siège
que le retenu ne tient pas est relevée au siège, l'échange en remède. La
dérive nomme la personne ; les capacités ont une borne ; Générer attend un
réglage en cours ; un travailleur qui ne se charge pas donne un refus ; le
§ 5.3 a ses bascules. Les commandes ne sont pas ré-entrantes et un double
clic ne confirme pas. Vérifié : 2755 node, 550 navigateur, index seul.

Assisted-by: Claude Opus 5.5
2026-10-07 17:50:35 -04:00
03a6f73337 [ADD] build: no remote load in the bundle, portable startup trial
The delivery build is scanned for test modules, runner traces, the Vite
client and any loading http(s) URL, the worker bundle included and quote
entities decoded. The startup trial runs the real shell in portable mode
from separate exe, home and temp folders: it creates an event, loads the
small demonstration, generates in the worker, closes, and checks that the
files sit under exe/data and no lock is left. It runs only when launched
as itself, symlinks resolved, so it never exits green without running.
Checked: 2699 node, 62 long tests, make essai_demarrage conforme.

--- FR ---

[ADD] construction : rien de distant, essai de démarrage portable

La construction de livraison est balayée : ni module d'épreuve, ni trace du
lanceur, ni client de Vite, ni URL http(s) qui charge, paquet du travailleur
compris et entités de guillemets décodées. L'essai lance la vraie coquille
en mode portable, depuis des dossiers exe, home et temp distincts : il crée
un événement, charge la petite démonstration, génère dans le travailleur,
ferme, et vérifie les fichiers sous exe/data et aucun verrou restant. Il ne
part que lancé lui-même, liens résolus : jamais un vert sans essai.
Vérifié : 2699 node, 62 longues, make essai_demarrage conforme.

Assisted-by: Claude Opus 5.5
2026-10-07 16:08:15 -04:00
dd7ad19cc9 [UPD] spec: follow the code and the iteration 3 decisions
The spec now states what the code does: nothing persists between sessions
under Electron, the seat plan is planning and a removed person frees her
chair, the ranked table shows the minimum of encounters and r(p) by its
sum, refusals with no remedy form a named class, the diagnostic says what
would make a conflict avoidable while the quality segment never does, the
geometry layer is guarded on its own, and created tables keep name lists
off their neighbours. Checked against each module and its tests; the
version check passes all eight points of 18.5.

--- FR ---

[UPD] spec : suivre le code et les décisions de l'itération 3

Le spec dit ce que fait le code : rien ne persiste d'une séance à l'autre
sous Electron, le plan de places est une planification et une personne
retirée libère sa chaise, le tableau classé montre le minimum des
rencontres et r(p) par sa somme, les refus sans remède forment une classe
nommée, le diagnostic dit ce qui rendrait un conflit évitable et le segment
de qualité jamais, la géométrie est une couche gardée à part, et une table
créée garde les listes loin des voisines. Vérifié contre chaque module et
ses épreuves ; le contrôle de version passe les huit points du § 18.5.

Assisted-by: Claude Opus 5.5
2026-10-07 16:04:52 -04:00
b3d59f2079 [ADD] interface: operator walk, reading order, windows, read-only mode
One walk at 1366 x 700, by gestures only from a fresh folder: create an
event, import the edge-case CSV, sort and filter, tables, default and
tours, the plan at scale, two hosts, a refusal on its place, three
propositions retained, an adjustment, then reading mode where every plan
gesture leaves the state untouched and undo is refused. Non-destructive
gestures open no window; destructive ones name exactly what leaves, and
Cancel writes nothing. In reading mode and on a blocked plan, every gesture
family writes nothing. Checked: 517 browser tests, from the index alone.

--- FR ---

[ADD] interface : parcours, ordre libre, fenêtres, gestes en lecture

Un parcours à 1366 x 700, par gestes depuis un dossier neuf : créer un
événement, importer le CSV des cas limites, trier et filtrer, tables,
défaut et tours, le plan à l'échelle, deux animateurs, un refus sur sa
place, trois propositions dont une retenue, un ajustement, puis la lecture
où chaque geste du plan laisse l'état intact et défaire est refusé. Un geste
non destructeur n'ouvre aucune fenêtre ; un destructeur nomme exactement ce
qui part, et Annuler n'écrit rien. En lecture et sur un plan bloqué, aucune
famille de gestes n'écrit. Vérifié : 517 épreuves navigateur, index seul.

Assisted-by: Claude Opus 5.5
2026-10-07 16:02:33 -04:00
8186b06713 [FIX] event: page never scrolls, broken-support remedies always shown
At 1366 x 700 an open event that shows warnings no longer scrolls the page:
the warnings scroll within their zone and the plan keeps at least 75 % of
its height. A broken support never shrinks, so its three remedies stay in
view, the only way to write the event elsewhere (spec 8.6). Tests now
prove the working-folder path and duplicate nodes are visible, the guard
of « Remplacer » in import, and which header a refused re-alignment shows.
Checked: 2692 node, 499 browser tests, from the index alone.

--- FR ---

[FIX] événement : sans défilement, remèdes du support rompu visibles

À 1366 x 700, un événement ouvert qui montre des avertissements ne fait
plus défiler la page : les avertissements défilent dans leur zone et le
plan garde au moins 75 % de sa hauteur. Un support rompu ne rétrécit
jamais : ses trois remèdes, seul moyen d'écrire l'événement ailleurs
(§ 8.6), restent visibles. Les épreuves prouvent que le chemin et les
doublons du dossier sont visibles, la garde de « Remplacer » à l'import, et
l'en-tête que montre un réalignement refusé. Vérifié : 2692 node, 499.

Assisted-by: Claude Opus 5.5
2026-10-07 15:05:59 -04:00
a2812cddb9 [FIX] plan: named warning, one places state, highlight, table spacing
The unheld-reservation warning names the person and the table number
instead of their identifiers. The places state is computed once per change
and handed to the side panels, not once per panel. A person can be
highlighted from their menu or from the grid, and the view bar names them.
A created table takes a cell a full pitch away from every table, its own
capacity included, so no name list runs over a neighbour's chairs. The
rendering guards fail on an empty walk and also check focus and selection.
Checked: 2692 node, 496 browser, 60 long tests, from the index alone.

--- FR ---

[FIX] plan : avertissement nommé, état des places unique, évidence, pas

L'avertissement de réservation non honorée nomme la personne et le numéro
de la table plutôt que leurs identifiants. L'état des places se calcule une
fois par changement et passe aux panneaux, non une fois par panneau. Une
personne se met en évidence par son menu ou depuis la grille, et la barre
de vue la nomme. Une table créée prend une case à un pas plein de chaque
table, sa capacité comprise : aucune liste ne court sur les chaises
voisines. Les gardes du rendu échouent sur un parcours vide et éprouvent
aussi le focus et la sélection. Vérifié : 2692 node, 496 navigateur, 60.

Assisted-by: Claude Opus 5.5
2026-10-07 15:05:01 -04:00