11.01 — Grammaire souveraine#
Pas de DSL imposé. Pas d’écosystème de plugins. Extension par composition, jamais par héritage.
Vision#
Citation du Holy Book (chapitre « Qu’est donc Ocarina ? ») :
Et si déléguer sa grammaire à des “standards” n’avait jamais été une bonne idée ?
Le vrai hiatus du test E2E n’est pas d’imposer la “meilleure” novlangue. Réponse simple : Ocarina est extensible.
On y crée les verbes et conjonctions que l’on veut, le tout régi par des règles strictes qui poussent l’ensemble à rester profondément cohérent.
Il reste alors à garantir la traçabilité et la robustesse.
« Retourner un ChainRunner »#
Citation du Holy Book (chapitre « Extensibilité ») :
La grammaire des scénarios de test repose sur un seul type :
ChainRunner[T]. Un scénario est unelist[ChainRunner]exécutée séquentiellement, court-circuitée au premier échec.drive_pagen’est qu’une fine enveloppe autour dechain_actions, qui construit unChainRunner. N’importe quelle fonction renvoyant unChainRunners’insère sans toucher au framework.
→ Un seul type d’extension : ChainRunner[T]. Tout ce qui en retourne un est composable.
« match_page ajouté après coup »#
Le Holy Book mentionne explicitement que match_page est un ajout post-conception :
match_pageetwhenont été ajoutés après coup, l’Igoristan était tellement aléatoire que le cas d’usage s’est imposé de lui-même. Leur implémentation a été simple, preuve de la flexibilité de la grammaire : d’autres structures analogues pourraient très bien suivre.
→ La preuve par l’exemple : si on a pu ajouter match_page sans toucher au DSL existant, on peut ajouter skip_if, repeat_n, ou n’importe quoi d’autre. Cf. ../02-ocarina/03-railway/07-match-page-when.md
« skip_if »#
Citation du Holy Book :
Autre exemple envisageable :
skip_if, qui court-circuiterait volontairement une portion du scénario sur une condition sans échouer (retournerait unOkneutre), utile pour des étapes optionnelles selon l’environnement ou les données de test.
→ Hypothétique idiome à implémenter soi-même. Implémentation triviale : retourne un ChainRunner[Any] qui appelle la condition, et soit exécute la branche, soit retourne Ok(None).
L’utilisateur peut l’écrire dans son projet dès maintenant, sans attendre de release de la part d’Ocarina.
Adapters projet#
Le projet utilisateur n’utilise jamais les classes Ocarina directement.
Il les wrappe dans des adapters :
# projet/lib/ext/ocarina/adapters/agnostic/act.py
def act(pom: TPOM, action: Callable[[TPOM], TPOM]) -> ActionStart[TPOM]:
def failure_hook(pom: TPOM, exc: Exception) -> Fail:
# ... policy projet ...
return create_act(pom, action, on_failure=failure_hook)
# projet/lib/ext/ocarina/adapters/selenium/test_suite.py
class TestSuite(OriginalTestSuite[WebDriver]):
def __init__(self, *, name, tests, drivers_pool, ...):
super().__init__(
...,
max_retries_per_test=8, # ← figé pour le projet
transient_errors=transient_errors, # ← scopé projet
...
)→ Chaque projet a son propre framework au-dessus du framework.
C’est la souveraineté grammaticale matérialisée.
Pas de version-locking forcé#
Si le framework évolue (par exemple ajoute un paramètre max_retries_per_test), le projet :
- Soit accepte le default (rien à faire).
- Soit met à jour son adapter
TestSuitepour figer une nouvelle valeur.
Pas de cascade de breaking changes dans tout le projet.
« Rétrécir »#
Le Holy Book (chapitre « Premiers pas », section TestSuite adapter) :
C’est l’adapter le plus important à comprendre.
TestSuiteexpose nativement un grand nombre de paramètres. L’objectif de cet adapter est de créer une façade : certaines valeurs sont figées une bonne fois pour toutes (hard-codées), d’autres sont exposées optionnellement avec des valeurs par défaut. C’est un rétrécissement.
→ L’adapter projet réduit la surface API d’Ocarina à ce dont le projet a besoin.
Pas d’écosystème de plugins#
Cf. ../01-philosophy/01-flip-the-problem.md :
Robot Framework, a essayé de la contourner avec un DSL (Domain Specific Language), incluant leur propre format et leur propre écosystème de plugins. Ainsi, RF impose de-facto ses propres standards : c’est le coût immédiat de sa promesse.
Ocarina refuse d’avoir un écosystème de plugins.
| Avec écosystème | Sans |
|---|---|
| Plugin marketplace, versions à suivre | Pas de marketplace, juste du code |
| Risque de plugin breaking au upgrade | Pas de risque |
| Standards de fait imposés (« comment écrire un bon plugin RF ») | Liberté de pattern |
| Dépendances cachées | Tout est local au projet |
→ Le « plugin » que tu cherches = pip install <ta lib>. La grande majeure partie du temps.
Aucun intérêt de refaire le monde.
Grammaire régie par des règles strictes#
Citation :
régi par des règles strictes qui poussent l’ensemble à rester profondément cohérent.
| Règle | En pratique |
|---|---|
ChainRunner[T] pour tout point d’extension | Type checking force la cohérence |
@final partout dans le DSL | Pas d’héritage utilisateur, composition obligatoire |
mypy strict = true | Aucune “liberté” de typage faible |
ruff select = ["ALL"] | Aucune “liberté” de style |
| Adapters projet rétrécissants | Aucune surface API par défaut, juste ce qui sert |
→ La liberté grammaticale vit au-dessus d’une discipline stricte. C’est la rigueur qui rend la liberté possible.
λ-calcul#
Cf. ../01-philosophy/04-citations-and-influences.md :
Ce que l’on pensait depuis les années 1930, depuis l’invention du λ-calcul, est enfin scalable à l’échelle que l’on aurait toujours voulu lui donner.
Le λ-calcul est l’exemple ultime de grammaire souveraine : cœur extrêmement minimal (λx.M), règles strictes (β-réduction, α-conversion, η-conversion), tout le reste se compose. Aucun « plugin λ ».
Ocarina suit la même posture.
La cohérence avec l’IA#
Une grammaire souveraine et statiquement typée est lisible par une IA parce qu’elle est petite et régie par des règles algébriques qui ont du sens. Pas de DSL ad-hoc à parser, pas de vues de l’esprit.
C’est ce qui rend ocarina-with-ai-example faisable : Claude lit le CLAUDE.md, comprend les règles strictes, applique. Il ne pourrait pas aussi bien collaborer sur un projet RF avec plugins exotiques puisqu’il devrait apprendre chaque plugin et passerait à côté de beaucoup de règles « tacites ».