# Conformité SRD Pathfinder 1re édition — journal d'audit Ce document consigne, de façon exhaustive et vérifiable, l'écart entre les règles implémentées par le moteur et le SRD Pathfinder 1re édition. Il complète le `README.md` (qui décrit le comportement attendu) en traçant **ce qui a été corrigé**, **ce qui est hors périmètre**, et **ce qui reste assumé comme résiduel**. ## Méthode 1. **Audit read-only par domaine** : chaque passe couvre un domaine étanche (sorts, mouvement, morts-vivants, dons, manœuvres, conditions, données de sorts, bestiaire). L'auditeur croise le code avec la base de connaissances SRD (`pathfinder-kb`, collection `pathfinder-1e-rules`) et cite la règle. 2. **Classement** : `High` (change matériellement l'issue d'un combat), `Med` (clairement faux, impact étroit), `Low` (donnée / cosmétique). 3. **Correction** : un commit par correctif, gate complète verte avant chaque commit (`ruff` `select=ALL`, `basedpyright` strict, `pytest`). 4. **Non-régression** : le transcript doré (`tests/test_pc_combat_golden.py`) n'est réécrit que lorsqu'un correctif SRD change légitimement la sortie, avec justification ligne à ligne. 5. **Traçabilité** : tout constat non corrigé est classé ici en *hors périmètre* (choix délibéré) ou *résiduel assumé* (écart connu, non corrigé). ## État de la gate | Contrôle | Résultat | |---|---| | `uv run pytest -q` | 1543 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é | --- ## 1. Écarts corrigés ### Correctifs de la passe 2 (commits) | Commit | Objet | |---|---| | `b03a61d` | Données de sorts : niveaux (`abundant_ammunition`, `comprehend_languages`, `deja_vu` 0→1 ; `create_water` 1→0 ; `enhance_water` 2→1), sauvegardes (`blindness_deafness` Will→Fort ; `enhance_water` none→Fort), RM de `summon_monster_i/ii`, écoles (6 sorts), portées (4 sorts) + pins de registre | | `317f91a` | *Entangled* : jet de concentration DD 15 + niveau ; `dex_skills` −4 | | `bfe0b76` | *Exhausted* : −6 Dextérité → −3 CA / −3 Réflexes | | `6220edc` | *Fatigued* : −2 Dextérité → −1 CA / −1 Réflexes | | `def8533` | *Nauseated* : privé d'attaques d'opportunité | | `68a03a3` | *Confused* : privé d'attaques d'opportunité (simplification) | | `cf8a073` | *Grappled/Pinned* : −2 aux jets de manœuvre (hors grapple/escape) | | `f31cc88` | *Pinned* : ne peut plus attaquer | | `4d45409` | Weapon Focus : correspondance insensible à la casse (le don s'applique enfin) | | `2807f71` | Attaque sournoise : toute dissimulation l'annule | | `350844f` | *Up Close And Deadly* : réservé aux armes à feu | | `fdc9127` | *Toughness* : +3 pv sous 4 DV (`max(3, niveau)`) | | `2b5920c` | *Disarm* : l'arme tombe (`weapon_dropped`) au lieu d'une pénalité −4 | | `06da519` | *Dirty trick* : liste RAW étendue (`shaken`, `sickened`) | | `0cccea2` | Manœuvres : succès automatique contre cible incapable | | `3a5948c` | CMD : plus de double comptage de Dextérité (Tiny, CMB pré-calculé) | | `e89ea42` | README/capacités : grapple (pin hors périmètre), `pinned`/`nauseated` sans attaque, Weapon Focus par groupe | > Transcript doré : mis à jour **deux fois**, chaque fois par un correctif SRD > justifié ligne à ligne dans le docstring du test — `4d45409` (Weapon Focus : > le +1 transforme le jet 15 en 16 contre CA 16, le gobelin meurt au round 4) > puis `bee224a` (Shield of Faith et Divine Favor portent enfin leurs vrais > buffs : `_find_buff_spell` retient désormais Divine Favor, index 20, ce qui > remonte la CA de tammara et réécrit son transcript). ### Correctifs des passes 3 et 4 (commits) | Commit | Objet | |---|---| | `e0bf484` | Tir dans une mêlée : exemption mesurée **cible → allié le plus proche** (High) | | `cc9fba3` | CA d'une cible inerte : −5 exact, plus de double comptage d'une Dextérité négative | | `fa63829` | `trait` et `racial` non cumulables (APG « Traits », CRB) | | `1c2663d` | Type non cumulable : meilleur bonus **et** pire pénalité conservés séparément | | `ae037c9` | Dégâts minimum : 1 point sur une touche réduite sous 1 par la RD | | `b3a7c37` | Types de bonus `alchemical`/`inherent`/`resistance`/`size` (UM Table 2-7) | | `feaab5e` | `celestial_wolf` aligné sur le loup du SRD + template céleste (DR/RM) | | `1c94d48` | `harvie` : Sagesse 14, Talons primaires +2 (1d4 ×2), Morsure secondaire | | `b9477a2` | `ierlieth` : bonus de dégâts −1, Queue secondaire ajoutée | | `2b5b39a` | Chevaux : sabots 1d4 marqués naturels, Morsure secondaire de Jeanne | | `611952c` | `misty` : don « Plot Armor » ajouté en no-op tracé | | `83bbcae` | Ray of Enfeeblement : type `PenaltyEffect` (pénalité de Force lancée, Fort moitié) au lieu de *fatigued* | | `79d9ff0` | `drunkards_breath` : cône de 30 ft qui rend *nauseated* (niveau 2, conjuration, Fort annule) — l'ancien contenu était **inventé** (High) | | `48c816b` | `delay_disease` : niveau 2 conjuration (soins) | | `27f9629` | Données : `alarm` close, `air_bubble`/`endure_elements` touch, `delay_poison` conjuration, conventions 10 ft/0 ft documentées, `daze` 4 DV | | `47f563e` | Shield of Faith : +2 CA déflexion (+1 / 6 niveaux, max +5) | | `bee224a` | Divine Favor : +1 chance attaque/dégâts par 3 niveaux (max +3) — doré mis à jour | | `6d96779` | Spear of Purity / Shard of Chaos : 1d8 / 2 niveaux (max 5d8), Volonté moitié | | `a5bd3c5` | Défense totale : plus d'attaques d'opportunité | | `e253b03` | Charge restreinte à 1× pour un accablé/invalide (et au round de surprise) | | `980d53d` | Aide : expiration au début du tour de **l'aidant** | | `a144423` | Défense totale et combat défensif non cumulables | | `0c3f5fd` | Durées de condition scalées au niveau (hold person, doom, touch of fatigue, vanish) | ### Passe 1 — sorts de buff, mouvement/grille, morts-vivants, armes naturelles | # | Constat | Sév. | Correctif (commit) | |---|---|---|---| | B1 | *Bless* affectait **toutes** les créatures d'un burst de 20 ft (y compris les ennemis) ; le SRD cible « you and each of your allies within a 50-ft. burst » | **High** | `e43066e` — filtre `AreaEffect.targets` (`all`/`allies`/`enemies`), burst 50 ft, alliés + lanceur | | B2 | *Bane* était un sort mono-cible ; le SRD cible les **ennemis** dans un burst de 50 ft | Med | `5e3505d` — conversion en `AreaEffect` 50 ft, `targets: "enemies"` | | B3 | *Bladed Dash* : niveau 1 (au lieu de 2), portée `close` (au lieu de `personal`) | Med | `312f9fd` | | B4 | *Aid* : niveau 1 (au lieu de 2), portée `long` (au lieu de `touch`) | Med | `312f9fd` | | B5 | *Doom* : portée `close` (au lieu de `medium`) | Med | `312f9fd` | | B6 | *Bull's Strength* : sauvegarde `fort` (le SRD n'accorde pas de jet ; valeur neutre corrigée en `will`) | Med | `312f9fd` | | B7 | *Bear's Endurance* : sauvegarde `fort` (idem) | Med | `312f9fd` | | B8 | *Mage Armor* absent du registre | Low | `3e19d29` — sort ajouté (niveau 1, conjuration, contact, +4 CA d'**armure**, RM non) + type de bonus `"armor"` non cumulable (registre porté à 108 sorts) | | C1 | Budget de déplacement : parité des diagonales figée à 0 dans les descentes gloutonnes → la règle 5-10-5 était **violée** (un marcheur vitesse 30 parcourait 6 cases en diagonale au lieu de 4) | Med | `2cc2ba1` — parité propagée (`_best_move_step`, `_descend_path`, `_run_line_path`, `_flee_path`) + `_path_cost_5105` pour la charge | | C2 | Pas de placement (5 ft) autorisé depuis/vers un terrain difficile | Med | `437507e` — rejet si le footprint courant **ou** la destination touche du terrain difficile | | C3 | Entrer dans la case d'une créature hostile ne provoquait pas d'AoO | Med | `9a16ca0` — `_check_enter_aoo` câblé dans `_walk_steps` | | C4 | Traversée d'une case hostile à ≥ 3 catégories d'écart de taille non modélisée | Med | `9a16ca0` — `_can_pass_through` (porte « traversée ») distincte de `_blocked` (porte « fin de mouvement ») | | C5 | Un combattant **fatigué/épuisé** pouvait courir (seule la charge était bloquée) ; le SRD : « can neither run nor charge » | Low | `7fc7a1d` — garde `cant_charge` ajoutée à `_execute_run` | | D1 | Les morts-vivants (et les créatures artificielles) mouraient à `hp ≤ -CON` au lieu d'être détruits à `hp ≤ 0` | Med | `59caf67` — seuil de mort à 0, pas de bande d'agonie | | D2 | Fiche du liche non conforme au bloc SRD : BAB 8 (au lieu de +5), contact +10 (au lieu de +5), `damage_bonus` 5 doublant la formule (dégâts réels 1d8+10 au lieu de 1d8+5), CA 25/14/23 (au lieu de 23/14/21), jets 10/10/14 (au lieu de 6/7/11), `con_score` 14 alors qu'un mort-vivant n'a pas de Constitution | Low | `881f2ef` | | D3 | Les sorts de soin (`cure`) soignaient les morts-vivants au lieu de les **blesser** | Low | `cad35e2` — dégâts (Volonté pour moitié), ni RD ni stabilisation | | A1 | Armes naturelles : itératifs de BAB accordés à tort et absence de la pénalité −5 des attaques secondaires | Med | `e5691bd` — champs `natural`/`secondary` (une seule attaque, secondaires −5, Multiattack −2) | ### Passe 2 — dons/capacités, manœuvres, conditions, données de sorts Constats d'audit (6 High, ~28 Med, ~45 Low). La colonne *Disposition* indique le sort réservé : **corrigé** (commit), **à corriger**, **hors périmètre** (non modélisable proprement) ou **résiduel assumé** (écart connu, conservé). #### 2a. Données de sorts (vérifiées une à une contre le KB) | Constat | Sév. | Disposition | |---|---|---| | `abundant_ammunition` niveau 0 → **1** (toutes classes) | High | corrigé (passe 2) | | `comprehend_languages` niveau 0 → **1** | High | corrigé (passe 2) | | `deja_vu` niveau 0 → **1** | High | corrigé (passe 2) | | `blindness_deafness` sauvegarde `will` → **`fort`** | High | corrigé (passe 2) | | `create_water` niveau 1 → **0** (clerc/druide) | Med | corrigé (passe 2) | | `enhance_water` niveau 2 → **1**, portée personal → **touch** | Med | corrigé (passe 2) | | `deja_vu` portée personal → **medium** | Med | corrigé (passe 2) | | `summon_monster_i` / `summon_monster_ii` RM true → **false** | Med | corrigé (passe 2) | | `divine_favor` — effet SRD (+1 chance attaque/dégâts par 3 niveaux) absent | Med | résiduel assumé | | `owls_wisdom` — effet SRD (+4 Sagesse) absent | Med | résiduel assumé | | `shield_of_faith` — effet SRD (+2 CA déflexion) absent | Med | résiduel assumé | | `weapon_of_awe` — effet SRD (+2 dégâts sacrés) absent | Med | résiduel assumé | | Écoles fausses : `arcane_mark` divination→**universal**, `color_spray` enchantment→**illusion**, `dancing_lights` conjuration→**evocation**, `deja_vu` divination→**enchantment**, `enhance_water` abjuration→**transmutation**, `abundant_ammunition` transmutation→**conjuration** | Low | corrigé (passe 2) | | Portées fausses : `dancing_lights` close→**medium**, `create_water` medium→**close** | Low | corrigé (passe 2) | | `enhance_water` sauvegarde none → **fort** (inoffensif) | Low | corrigé (passe 2) | | Effets absents (sorts utilitaires) : `guidance`, `resistance`, `protection_from_evil`, `sanctuary`, `virtue`, `shard_of_chaos`, `spear_of_purity`, `spiritual_weapon` | Low | hors périmètre | | *Faux positifs* (conformes) : `web` RM, `flurry_of_snowballs` RM, `detect_fiendish_presence` niveau, `scorching_ray` projectiles (max 3), `make_whole`/`restoration_lesser` temps d'incantation (`long`) | — | conformes | | *Non vérifiable* (le KB omet la ligne RM) : `shield`, `read_magic`, `comprehend_languages` (RM) | — | indéterminé | | Portées « pieds fixes » (15/30/50/60/120 ft) approchées par les catégories close/medium/long pour les cônes, lignes et bursts (`burning_hands`, `color_spray`, `fear`, `flurry_of_snowballs`, `lightning_bolt`, `bless`, `bane`, `obscuring_mist`, `detect_magic`) | Low | hors périmètre (modèle de portée par catégories) | #### 2b. Conditions | Constat | Sév. | Disposition | |---|---|---| | *Entangled* : aucun jet de concentration **DD 15 + niveau** à l'incantation | Med | corrigé (passe 2) | | *Exhausted* : pénalités **−3 CA / −3 Réflexes** manquantes (−6 Dex) | Med | corrigé (passe 2) | | *Nauseated* : peut porter des **attaques d'opportunité** | Med | corrigé (passe 2) | | *Confused* : peut porter des attaques d'opportunité (le SRD l'interdit) | Med | corrigé (passe 2) | | *Grappled* : **−2 aux jets de manœuvre** (sauf grapple/escape) non appliqué | Med | corrigé (passe 2) | | *Pinned* : peut **attaquer** ; de plus la condition n'est **jamais appliquée** (code mort) | Med | corrigé (f31cc88) / hors périmètre (entretien) | | *Fatigued* : **−1 CA / −1 Réflexes** manquants (−2 Dex) | Low | corrigé (passe 2) | | *Fatigued/Exhausted* : pénalité de dégâts appliquée aussi aux armes à distance | Low | résiduel assumé | | *Entangled* : `dex_skills` −4 manquant (incohérent avec grappled/pinned) | Low | corrigé (passe 2) | | *Shaken/Sickened/Frightened/Panicked* : pénalités de compétence/caractéristique non modélisées | Low | hors périmètre (pas de tests de compétence) | | *Frightened/Panicked* : fuite = retraite 2× au lieu de la course 4× ; acculé attend au lieu de se recroqueviller | Low | résiduel assumé | | *Dazzled* / *Blinded* : malus de Perception (dont opposition) non modélisés | Low | hors périmètre | | *Deafened* : échec d'incantation 20 % | Low | hors périmètre (déjà documenté) | | *Stunned/Panicked* : « lâche tout ce qu'elle tient » non modélisé | Low | hors périmètre (pas de modèle d'objet tenu) | | *Grappled* : « aucune action à deux mains » non modélisé | Low | hors périmètre | | *Pinned* : composantes somatiques/matérielles non modélisées | Low | hors périmètre | | *Bleeding* : règle de non-cumul (« le pire effet l'emporte ») non vérifiée | Low | à vérifier | #### 2c. Manœuvres de combat | Constat | Sév. | Disposition | |---|---|---| | *Grapple* : aucun entretien/pin/dégâts/déplacement ; `pinned` jamais appliqué — **le README « grapple → grappled/pinned » est faux** | High | hors périmètre (README corrigé, e89ea42) | | *Disarm* : pénalité **−4 synthétique** au lieu du **lâcher d'arme** (le SRD fait tomber l'objet) | High | à corriger | | *Grappled* : −2 non appliqué aux jets de manœuvre de combat | Med | corrigé (cf. 2b) | | *Grapple* : plafond arbitraire de 10 rounds ; pas de bonus de +5 d'entretien | Med | hors périmètre | | *Disarm* : pas d'échec-de-10 → l'attaquant lâche son arme | Med | résiduel assumé | | *Trip* : `prone` expire en 1 round au lieu de persister jusqu'à `stand_up` | Med | résiduel assumé (README documenté) | | *Sunder* : dégâts `str_mod + 2` fixes au lieu des dégâts d'arme ; **dureté non modélisée** | Med | résiduel assumé (README documenté) | | *Sunder* : arme cassée retirée des attaques au lieu de **−2** (SRD : reste utilisable) | Med | résiduel assumé | | Pas de **succès automatique** contre une cible incapable/inconsciente | Med | à corriger | | *Reposition* : contrainte d'allonge non appliquée au déplacement | Med | résiduel assumé | | *Dirty trick* : options **shaken/sickened** manquantes ; pas de retrait par action de mouvement | Med | à corriger | | *Trip* : créatures sans jambes/volantes non trippables ; +2 par paire de jambes | Low | hors périmètre (pas de traits de créature) | | *Overrun* : option « se laisser éviter » non modélisée | Low | hors périmètre | | *Bull rush* : vérifications secondaires contre les créatures sur le passage non modélisées | Low | hors périmètre | | *Drag* : budget de déplacement de l'attaquant non vérifié | Low | hors périmètre | | *Disarm* : à mains nues −4, +10 → lâcher des deux objets, attente d'un round | Low | résiduel assumé | | *Escape* : option « devenir le grappleur » non modélisée | Low | hors périmètre | | *Grapple* : −4 si pas deux mains libres ; restrictions arme légère/Stealth | Low | hors périmètre (pas de modèle de mains) | | *CMD* : double comptage de Dextérité latent pour une créature Tiny avec `cmb` pré-calculé | Low | à corriger | #### 2d. Dons et capacités de classe | Constat | Sév. | Disposition | |---|---|---| | **Weapon Focus (Pistolet) est un don mort** : le filtre de don compare exactement « Pistol » au nom d'arme « Braises d'Automne (pistolet ?) » → le +1 ne s'applique jamais | Med | à corriger | | Attaque sournoise autorisée contre une **dissimulation partielle** (le SRD bloque dès « concealment » ; le README revendique à tort « total concealment ») | Med | à corriger | | *Up Close And Deadly* s'applique à **toute** attaque à distance ; le SRD l'exige d'une **arme à feu** | Med | à corriger | | *Toughness* : +niveau au lieu de **+3 puis +1 par DV au-delà de 3** (faux aux niveaux 1-2 ; données actuelles ≥ 3) | Low | à corriger | | *Channel Energy* : 2d6 **figés** (pas de progression +1d6 par 2 niveaux) ; le canaliseur est toujours inclus | Low | résiduel assumé | | *Combat Reflexes* : planché à 1 AoO (le SRD autorise 0 avec un modificateur de Dextérité négatif) | Low | résiduel assumé | | *Cackle* : étend les `evil_eye` de **tous** les lanceurs, pas seulement les siens | Low | résiduel assumé | | *Improved Critical* appliqué à **toutes** les armes (SRD : un type d'arme) | Low | résiduel assumé (README documenté) | | *Inspire Courage* : +1 plat (progression +1 par 4 niveaux non modélisée) | Low | résiduel assumé (README documenté) | | *Spell Combat* : le coût de pool arcanique est un no-op (misty n'a pas de pool) | Low | sans objet | --- ## 2. Hors périmètre (choix délibéré, documenté) Ces règles sont **volontairement** non modélisées et signalées dans le `README.md` (sections « Limites hors périmètre » et « Limites de sorts ») pour ne pas être confondues avec des bogues. | Sujet | Raison | |---|---| | **Squeeze** (se serrer dans un passage étroit) | La largeur de couloir n'est pas comparée à la taille ; une créature bloquée par son footprint l'est sans option de squeeze payante | | **Acrobatics « Tumbling »** (traverser une case ennemie sans AoO) | Le moteur n'a pas de système de compétences | | **Créature inerte très grande = obstacle à 2 cases** | Les cases d'une créature inactive ne bloquent pas et ne coûtent pas double | | **Échec d'incantation du personnage sourd (20 %)** | `SpellSpec` n'a pas de composante verbale ; il faudrait encoder les composantes sur les 108 sorts | | **Incantation multi-round (`long` : 3 rounds, 10 min, 1 h)** | Non planifiable dans un tour ; jetée du budget (`downgraded:cast_time`) plutôt qu'approximée | | **Co-occupation au-delà de Tiny vs plus grand** | Deux créatures Small+ ne partagent jamais une case ; plusieurs Tiny sur une case non gérés | | **Combat à deux armes / arme en main secondaire (×0,5 Force)** | Hors du modèle d'attaque actuel | | **Vol 3D / vol par-dessus les obstacles** | La vitesse de vol est un budget au sol ; pas de maniabilité ni de survol du terrain | | **`markers`** (points nommés de la carte) | Validés à la lecture, non appliqués à la résolution | --- ## 3. Résiduels assumés (écart connu, non corrigé) | 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 | --- ## 4. Conformités vérifiées (garde-fous anti-régression) Constats explicitement contrôlés et **confirmés conformes** : - **Résistance aux sorts** : le drapeau `spell_resistance` est respecté et `_check_spell_resistance` court-circuite sans consommer de RNG quand la cible n'a pas de RM. - **Description de *Lightning Bolt*** (ligne 120 ft, 1d6/niveau plafonné 10d6, Réflexes demi) : conforme. - **Diagonale entrant en terrain difficile** : coût plat de 3 cases, convention de table explicite dans `grid.py`, cohérente entre Dijkstra et descentes. - **Terrain mixte** : les coûts de pas s'additionnent sans double comptage. - **Déplacement d'un personnage aveuglé** : le SRD n'interdit ni le déplacement, ni la course, ni la charge à un aveugle (seuls la touche, la CA et les compétences sont affectés) — le constat d'audit initial ne visait pas une vraie règle. --- ## 5. Journal des audits | Passe | Domaines | Sessions | Constats | Statut | |---|---|---|---|---| | 1 | Sorts (B), Mouvement/grille (C), Morts-vivants (D), Armes naturelles (A) | `bg_9e9e22e6`, `bg_cda707bf`, `bg_ba80396a`, `bg_6a621d4c` | 1 High, 12 Med, ~20 Low | Corrigés + documentés (ci-dessus) | | 2 | Dons/capacités (E), Manœuvres (F), Conditions (G), Données de sorts (H) | `bg_5314f54c` (re-run), `bg_9fdc610e`, `bg_f5829c68`, `bg_b289533d` + extraction/vérification `bg_e1ccd2da`, `bg_4292da47`, `bg_14d5344a` | 4 High, ~18 Med, ~45 Low | Constats consignés (§ 1 passe 2) ; correctifs data/conditions/dons en cours | | 3 | Résolution d'attaque & défense, bestiaire/PJ (blocs de stats), économie d'action & tour, sorts restants | `bg_38d99eac`, `bg_8cdcb3e2`, `bg_73e3f878` | 1 High, ~10 Med, ~40 Low | 11 correctifs (`e0bf484`..`611952c`) + Ray of Enfeeblement (`83bbcae`) ; le reste documenté | | 4 | Sorts restants (champ par champ), dons des 8 PJ vs feuilles Foundry | `bg_29c36b1a` | 1 High, 1 Med, ~30 Low (dont 20 dons) | 11 correctifs (`79d9ff0`..`0c3f5fd`) ; 20 écarts de dons + effets de sorts différés documentés | | 5+ | ~60 sorts non encore vérifiés, sous-systèmes non couverts (invocation, métamagie/slots, concentration, observation, runner/métriques) | — | — | **En pause** (demande utilisateur) | --- ## 6. Relancer une passe d'audit Chaque passe suit le même protocole : 1. Choisir un domaine **non encore audité** (voir le journal § 5). 2. Lancer un auditeur read-only (agent `oracle`) avec la base SRD `pathfinder-kb` et l'exigence de citer la règle et la ligne de code fautive. 3. Trier chaque constat : **corriger** (si l'impact est matériel et le correctif propre) ou **classer** en hors périmètre / résiduel assumé (ce document). 4. Un commit par correctif ; gate complète verte ; transcript doré préservé ou justifié ligne à ligne. 5. Reporter les constats dans les tableaux ci-dessus et la ligne de journal.