Files
pf1e-simulator/docs/conformance-srd.md
T
ctan aa424fa385 docs(rules): conformance journal rounds 5-6 (31 fix commits) and final residual inventory
Rounds 5-6 covered the spell subsystem (metamagic DC, holding the charge,
summon duration, Extend, Combat Casting/entangled, ASF/bonus-spells/dismissal
docs), the 24 feat/racial residuals, the deferred spell effects (mirror image,
bleed, bane, acid arrow, ice slick, owl's wisdom, bear's endurance, aid...)
and the map/LoS area-of-effect findings (line truncation at barriers, cone/
burst line of effect, cover-to-Reflex, adjacent melee cover, charge/run
corner rule, charge footprint terrain). Records the 31 commits
(d0db208..9086038), the deferred/lower-severity residuals, and the audit
coverage gap (oracle quota exhausted).
2026-09-19 15:58:53 +02:00

329 lines
30 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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` | 1596 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) |
### Correctifs des passes 5 et 6 (commits)
| Commit | Objet |
|---|---|
| `d0db208` | *Exalted of the Society* → +1 canalisation/jour (`resource_grants`) ; *Fortified Drinker* → no-op (état « alcool » non modélisé) |
| `6d0ee1b` | *Born Damned* et *Axe to Grind* → no-ops documentés (descripteur « curse » absent ; « menacé par vous seul » inexprimable) |
| `a5ebbec` | *Friendly Face* et *Extremely Fashionable* → no-ops (attitude animale et port de vêtements non modélisés) |
| `b74baf1` | *Lonely* / *Bitter* → vraies penalties (fini les faux +1 Will) |
| `81a09c8` | Métamagie : **ne gonfle plus le DD** — seul Heighten (désormais supporté) |
| `418fdc8` | **Charge retenue** : un contact de mêlée manqué conserve le sort |
| `cec3c5f` | Durée d'invocation **1 round/niveau** (`SummonEffect.duration_rounds_per_level`) |
| `65a5e24` | Combat Casting : +4 retiré du jet *entangled* |
| `22724f5` | Extend Spell double la durée d'invocation |
| `b2739c5` / `1902877` / `17c06e1` | Documentation : échec d'armure, convention `spell_slots`, dissipation `(D)` |
| `2dd3fef` | *Larger Than Life*, *Ambitious*, *Focused Study* → no-ops documentés |
| `7262568` | Traits sylphes d'Esha + noms inventés (*Whispering Wind*, *Like the Wind*, *Fey-touched*, *Pingre*) → no-ops tracés |
| `2df9dd7` | *Scaled Skin* (résistance électricité 5) ; *Maw or Claw* morsure 1d6 |
| `13e4a27` | Couverture de test de tout le lot no-op |
| `d9b590e` | Acid Arrow (cap total 7) ; Ice Slick (+1/niveau, max +10) |
| `56310b1` | Mirror Image (images lancées + miss chance dynamique) ; Bleed (seuil ≤ −1 pv) ; Bane (−1 limité à la peur) |
| `35ce41e` | Owl's Wisdom (+2 Volonté) ; docs affinées des utilitaires différés |
| `b95533d` | Bear's Endurance (+2 pv/DV) ; Aid (moral limité aux sauvegardes de peur) ; Charm Person (portée close) |
| `5250763` | **Ligne** s'arrête au premier obstacle de ligne d'effet |
| `389e160` | **Cône** exige une ligne d'effet depuis son origine |
| `948edc1` | **Burst** n'affecte pas une créature en couvert total par rapport au centre |
| `8774e51` | **Couvert → Réflexes** (moitié du bonus de CA, couvert mou exclu) |
| `a2ca78f` | `blocks_los` documenté comme sémantique **ligne d'effet** (vision seule non modélisée) |
| `beb8421` | High ground +1 **mêlée uniquement** (vérifié conforme, Table 8-5) |
| `fb6f58a` | Règle des coins en diagonale documentée comme plus stricte que le RAW (approximation conservatrice assumée) |
| `9f8655d` | README synchronisé (truncature des lignes, LoE cône/burst, couvert Réflexes) |
| `27ce33b` | Couvert au **corps-à-corps adjacent** : règle « n'importe quelle ligne » du SRD |
| `5e478bf` | Charge et course appliquent la **règle des coins** |
| `9086038` | Charge : terrain difficile testé sur **tout le footprint** (« on ne se déplace qu'à la vitesse du terrain le plus difficile occupé ») |
### 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 |
| **Zones d'effet / ligne d'effet — résiduels (passe 6)** | 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 ; caster multi-cases inclus dans son propre cône/ligne ; `square_size_ft` chargé mais non consommé (géométrie figée à 5 ft) ; créatures inertes non traitées comme couvert mou ni par les gabarits ; un aveugle peut charger/courir/retraiter ; incantation par point d'un cône/ligne derrière un mur rejetée | Écart connu / approximation conservatrice assumée |
| **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** | Audit « cas limites moteur » initialement bloqué par épuisement de quota du modèle oracle (replis mal configurés) ; relancé via un agent fiable. ~60 sorts restent non vérifiés champ par champ (hors ceux couverts en passe 4) ; sous-systèmes non audités : invocation avancée, observation, runner/métriques, CLI | Lacune de couverture à reprendre |
---
## 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 | Sous-système des sorts (invocation, emplacements, métamagie, concentration, livraison) ; cas limites moteur (LoS/LoE, couvert, élévation, terrain, gabarits de zone) | `bg_938bceca`, `bg_27334a51` | 0 High, ~6 Med, ~15 Low | 15 correctifs (`81a09c8`..`9086038`) + documents ; 8 Low moteur résiduels |
| 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+ | ~60 sorts non vérifiés champ par champ ; sous-systèmes non audités (observation, runner/métriques, CLI) | — | — | À reprendre (audit oracle bloqué par quota, contourné via agent fiable) |
---
## 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.