From 154c3f69a070d5ce0568fe4bae1ba4a044586eaa Mon Sep 17 00:00:00 2001 From: ctan Date: Sun, 20 Sep 2026 00:46:08 +0200 Subject: [PATCH] docs(rules): conformance journal round 9 - assumed residuals closed (10 fixes, 1 deferred) Rounds 1-3 closed the assumed residuals: run bounded by CON endurance + Run feat, harmless spells forgo the save on willing targets, self-centered bursts for bless/bane, Selective Channeling, the lich stat block aligned to the KB, summon-stats disambiguation, healing_done exposure, multi-cell difficult-terrain move pricing, and the grazed-caster-cell cone/line fix. The burst intersection origin is deferred with a precise rationale. Rewrites the residual table to drop the now-fixed and stale rows, leaving only the genuinely remaining items. --- README.md | 2 +- docs/conformance-srd.md | 43 ++++++++++++++++++++++++----------------- 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index c730d06..83c0738 100644 --- a/README.md +++ b/README.md @@ -1997,7 +1997,7 @@ Limites de sorts (conformance D6-D9, documentées plutôt que bricolées) : La gate de validation complète (tests + lint + types) : ```bash -uv run pytest -q # 1647 tests +uv run pytest -q # 1691 tests uv run ruff check src tests uv run basedpyright src # mode strict ``` diff --git a/docs/conformance-srd.md b/docs/conformance-srd.md index 2e00f11..774ddf0 100644 --- a/docs/conformance-srd.md +++ b/docs/conformance-srd.md @@ -26,7 +26,7 @@ résiduel**. | Contrôle | Résultat | |---|---| -| `uv run pytest -q` | 1647 tests verts | +| `uv run pytest -q` | 1691 tests verts | | `uv run ruff check src tests` (`select=ALL`) | conforme | | `uv run basedpyright src` (strict) | 0 erreur | | Transcript doré depuis la passe 1 | inchangé | @@ -161,6 +161,21 @@ Une passe de vérification adversariale a confirmé que les 15 correctifs High/M | `238e5f2` | Hex : portée **close scalée** au niveau (25 ft + 5 / 2 niveaux) au lieu d'un 25 ft figé | | `1b43f4e` | README : `data/pcs/*.json` sont **canoniques** ; `foundry.py` est un outil one-shot incomplet (ne pas régénérer sans réappliquer les correctifs) | +### Correctifs de la passe 9 — résiduels assumés (lots 1-3) + +| Commit | Objet | +|---|---| +| `ea83529` | **Course** bornée par le score de **CON** (jet de CON DD 10 par round au-delà, échec → arrêt + repos 10 rounds) ; **don Run** (+4 au jet, conserve la Dextérité à la CA) ; armure lourde ×3 reclassée hors périmètre (pas de champ d'armure) | +| `4665a1c` | Sorts **« harmless »** : plus de jet de sauvegarde inutile sur cible consentante (drapeau `harmless` posé sur les 29 sorts SRD « (harmless) ») | +| `9f0d862` | Bursts **Bless/Bane centrés sur le lanceur** (`centered_on_caster` piloté par les données) | +| `5fe2b72` | **Selective Channeling** modélisé (exclusion par la policy, plafonnée au modificateur de Charisme, sans effet sans le don) | +| `4f8a131` | Fiche du **liche alignée sur le KB** (pv 111, For 10, Int 22, init +2, aura de terreur 60 ft/DD 18) — doré re-pinné (2 lignes, toutes deux SRD-correctes) | +| `5e7436b` | **Invocations** : identifiants désambiguïsés (chacune son emplacement de stats) | +| `e6021a6` | **`healing_done`** exposé par combattant et dans le rapport (« soins prodigués ») | +| `d347dde` | **Terrain difficile multi-cases en `move`** : le pas reflète le terrain le plus difficile sous tout le *footprint* | +| `d5ad3c3` | Un **cône/trait** ne perd plus de longueur à cause des cases du lanceur effleurées | +| `b775d46` | Origine des **bursts** (centre-à-centre vs intersection) : **différé** et documenté précisément (nécessite une coordonnée d'intersection dans le contrat) | + > **Registre des sorts clos** : les 35 derniers sorts ont été vérifiés champ par champ contre le KB — **0 divergence** (niveaux, sauvegardes, RM, portées, zones, formules conformes). Seuls 2 sorts sont absents du KB (`create_alcool`, `hidden_diplomacy`) et 1 nit de description subsiste (`detect_poison` mentionne « acid »). ### Passe 1 — sorts de buff, mouvement/grille, morts-vivants, armes naturelles @@ -302,22 +317,13 @@ ne pas être confondues avec des bogues. | Sujet | Nature de l'écart | Décision | |---|---|---| -| **Course — durée liée à la Constitution, don Run, armure lourde (×3)** | Le SRD limite la course à `CON` tours puis impose un jet de Constitution DD 10, et réduit la vitesse de course en armure lourde ; le moteur applique toujours ×4 | Assumé : aucun scénario courant ne course plus de quelques tours | -| **Dégâts non létaux** | Absents du modèle de PV | Assumé : aucune source de dégâts non létaux dans les données | -| **Armes à éclaboussures / dégâts d'éclaboussure** | Absents (pas d'objet concerné dans les données) | Assumé | -| **Sort « harmless » sur cible consentante** | Le moteur roule tout de même une sauvegarde (consommation de RNG) ; l'issue du soin n'en dépend pas | Assumé : fidélité de déterminisme, pas d'effet observable | -| **Réglages du liche non SRD** (pv 100 vs 111, Force, Intelligence, initiative, aura de terreur 30 ft/DD 22 vs 60 ft/DD 18) | Réglages d'équilibrage du scénario doré | Assumé : conservés pour ne pas casser la fiche dorée | -| **Dés énergétiques non multipliés par un critique** (contact du liche) | Règle moteur globale (exceptions CRB « Critical Hits ») | Assumé : cohérent avec les autres attaques | -| **`selective_channeling` non modélisé** | Le canal d'énergie affecte toutes les créatures du type visé dans la zone | Assumé (documenté au README) | -| **Effets de sorts différés (passe 4)** | `mirror_image` (1d4+1 images, ~67-78 % d'échec au lieu du flou 20 %), `spiritual_weapon` (attaque flottante persistante), buffs utilitaires sans mécanique cible (`guidance`, `resistance`, `virtue`, `stabilize`, `owls_wisdom`, `saving_finale`), `acid_arrow` (cap 7 rounds), `ice_slick` (+1/niveau), `charm_person` (condition *charmed*), `bleed` (seuil ≤ −1 pv), `bane` (pénalité −1), `bears_endurance` (+2 pv/DV), `aid` (pv temporaires), `tears_to_wine` (portée 10 ft) | Écart connu, non corrigé dans cette passe (correctifs à effet de bord potentiel sur le choix de sort de `default_policy`) | -| **20 écarts de dons/raciales (passe 4)** | Effets faux : *Exalted of the Society*, *Fortified Drinker* (Med, ce dernier ne s'applique **jamais** — condition « alcohol » non supportée) ; *Born Damned*, *Half-Forgotten Secrets*, *Axe to Grind*, *Thoroughbred*, *Extremely Fashionable*, *Lonely*/*Bitter* (drawbacks inversés en bonus), *Larger Than Life*, *Friendly Face*, *Breeze-Kissed* ; effets manquants : *Ambitious*, *Focused Study*, *Scaled Skin* ; valeur fausse : *Maw or Claw* (1d4 vs 1d6) ; noms inventés : *Whispering Wind*, *Like the Wind*, *Fey-touched*, *Pingre* | La parité feuille ↔ JSON est parfaite dans les deux sens (aucun don manquant ou en trop, aucun no-op silencieux), mais le résolveur mappe mal ces noms ou accepte des noms non-SRD — non corrigé | -| **Morts-vivants / objets / alignement** | Le moteur n'a ni alignement (Shard of Chaos, Spear of Purity, Protection from Evil), ni piste d'objets (Steal, Sunder), ni sous-système de compétences (Perception opposée, Acrobaties) | Hors périmètre : mécaniques absentes du modèle | -| **Zones d'effet / ligne d'effet — résiduels** | Vitesse de `move` sous terrain difficile mixte pour multi-cases (le *footprint* n'est testé que pour la charge — relâcher le *descent* réécrirait les chemins Dijkstra) ; origin mesuré centre-à-centre plutôt qu'intersection-à-intersection ; un caster multi-cases dont une case est « effleurée » consomme un slot de longueur | Résiduel assumé (approximations conservatrices) | -| **Statistiques** | Deux invocations de la même créature partagent un même emplacement de stats (ids non désambiguïsés) ; `healing_done` n'est pas exposé séparément | Limitation documentée | -| **Centrage du burst de *Bless*** | Le rayon de 50 ft est centré sur la cible résolue, pas forcément sur le lanceur (SRD : « centered on you ») ; le filtre « alliés » inclut bien le lanceur | Résiduel assumé (approximation) | -| **Non vérifiable (KB)** | `create_alcool`, `hidden_diplomacy` (absents du KB) ; ligne de description « acid » de `detect_poison` | Indéterminé / nit | -| **Sorts différés restants (passe 5)** | `spiritual_weapon` (attaque flottante persistante), `saving_finale` (reroll immédiat), `guidance`/`resistance`/`virtue`/`stabilize` (buffs utilitaires sans mécanique cible — dégradation du choix de sort envisagée) | Documentés (SRD vérifié, raison moteur consignée) | -| **Couverture d'audit** | Registre des sorts **clos** (108/108 couverts ; 35 vérifiés en passe 7, 0 divergence). Audit « cas limites moteur » initialement bloqué par épuisement de quota de l'oracle (replis mal configurés) — relancé via un agent fiable. Restent non audités : observation, runner/métriques désormais couverts (passe 7) ; subsistent des sous-systèmes annexes (rendu du transcript, formats de données avancés) | Couverture largement complète | +| **Origine des bursts** | Mesure **centre-à-centre** au lieu d'**intersection-à-intersection** avec la règle du bord lointain (SRD « Aiming a Spell ») ; l'exactitude exigerait une coordonnée d'intersection dans le contrat d'observation et un choix de coin du lanceur | Différé, documenté précisément (`areas.py`, `_creatures_in_range`) | +| **Course en armure lourde (×3)** | Le modèle n'a pas de champ d'armure ; la course est désormais bornée par la CON et le don Run est modélisé | Hors périmètre (reclassé) | +| **Dégâts non létaux** | Aucune source dans les données ; le minimum de dégâts est approximé en dégâts normaux | Hors périmètre (aucune source) | +| **Armes à éclaboussures** | Aucun objet concerné dans les données | Hors périmètre | +| **Sorts utilitaires différés** | `spiritual_weapon` (attaque flottante persistante), `saving_finale` (reroll immédiat), `guidance`/`resistance`/`virtue`/`stabilize` (buffs sans mécanique cible exploitable par la policy) | Documentés (SRD vérifié, raison moteur consignée) | +| **Non vérifiable (KB)** | `create_alcool`, `hidden_diplomacy` absents du KB ; nit de description de `detect_poison` (« acid ») | Indéterminé / nit | +| **Couverture d'audit** | Rendu du transcript et formats de données avancés non encore audités | À reprendre si besoin | --- @@ -352,7 +358,8 @@ Constats explicitement contrôlés et **confirmés conformes** : | 6 | Résiduels de dons (24) et d'effets de sorts (~13) | `bg_303e14a0`, `bg_151d5a57`, `bg_918e49cf` | 0 High, ~4 Med, ~30 Low | 16 correctifs (`d0db208`..`b95533d`) ; effets non exprimables documentés | | 7 | Registre des sorts (35 restants, champ par champ) ; moteur : Low documentés ; sous-systèmes runner/métriques/observation/CLI | `bg_0a3e3844`, `bg_2c4d185a`, `bg_cc8f0788` | 2 High, 2 Med, ~8 Low | 12 correctifs (`792cec1`..`9a087a4`) ; **registre des sorts clos (108/108)** | | 8 | Vérification adversariale (correctifs réels + chasse aux écarts non documentés : `dice`, `rng`, `foundry`, `map`, `default_policy`, transcript) | `bg_d8cba9d1`, `bg_1bac8900` | 15 claims vérifiés réels ; 2 High/Med + ~6 Low nouveaux | 8 correctifs (`31d47ae`..`1b43f4e`) ; reste = résiduels assumés et hors périmètre | -| 9+ | Sous-systèmes annexes (rendu du transcript, formats avancés) | — | — | À reprendre si besoin | +| 9 | Résiduels assumés (lots 1-3) : course/CON+Run, harmless, centrage Bless/Bane, Selective Channeling, liche, invocations, healing_done, terrain multi-cases, cône effleuré | `bg_0a5b0d6b`, `bg_b304c5a3`, `bg_b277ee2d` | ~10 correctifs, 1 différé | 10 correctifs (`ea83529`..`d5ad3c3`), doré re-pinné une fois (liche) | +| 10+ | Sorts utilitaires différés (guidance, resistance, virtue, stabilize, spiritual_weapon, saving_finale) ; origine des bursts ; rendu du transcript | — | — | **En pause** (demande utilisateur) | ---