7e4a9f5edf
Brings in the last four out-of-scope mechanics: the nonlethal damage track (unarmed strikes, minimum damage), splash weapons (direct + scatter), combat skills (skill checks, Acrobatics Tumbling, Stealth/opposed Perception) and 3D flight over ground terrain (vertical line of effect deferred). Updates the out-of-scope and residual tables to drop the now-modeled items and marks the round-2 disposition tables as historical. Gate 1981.
458 lines
40 KiB
Markdown
458 lines
40 KiB
Markdown
# 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` | 1981 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
|
||
|
||
> Les tableaux de disposition ci-dessous (passe 2) sont **historiques** : les
|
||
> constats marqués « à corriger » / « résiduel assumé » ont depuis été corrigés
|
||
> ou reclassés dans les passes suivantes (voir les tableaux de commits ci-aprè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) 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). Le second correctif déplace la mort du gobelin au
|
||
> **round 5** (le « round 4 » du premier correctif est superseded).
|
||
|
||
### 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é ») |
|
||
|
||
### Correctifs de la passe 6 (suite) et de la passe 7
|
||
|
||
| Commit | Objet |
|
||
|---|---|
|
||
| `792cec1` | Les créatures **mourantes mais vivantes** occupent leur case (couvert mou + gabarits de zone) |
|
||
| `778d6a8` | Un **aveugle** ne peut ni charger, ni courir, ni retraiter |
|
||
| `2e468ba` | Cône/ligne pointé : plus d'exigence de ligne d'effet vers le point visé (bursts seulement) |
|
||
| `1e2de7f` | Cône/ligne : **tout le footprint** du lanceur est exclu de son propre gabarit |
|
||
| `24e208e` | `square_size_ft ≠ 5` rejeté au chargement (géométrie figée à 5 ft) |
|
||
| `2e2873f` | **Canal de soin** : le soin n'est plus compté comme `damage_dealt` |
|
||
| `7fefce4` | `run_encounter` ne **plante plus** quand une invocation apparaît (accumulateurs à la demande) |
|
||
| `0ad627c` | Saignement, dégâts récurrents et soin-sur-morts-vivants comptés dans `damage_taken` |
|
||
| `9459ade` | `downgraded:immediate_swift` ajouté au vocabulaire `ACTION_RESULT_REASONS` |
|
||
| `2ee19d3` | Formulation « snapshot figé » corrigée (les dicts internes sont des copies mutables) |
|
||
| `ba5eb4c` | Déploiement : deux camps sur la **même lettre de zone** rejetés |
|
||
| `9a087a4` | Exemples du README **rafraîchis** contre le moteur réel (Quick start 96,2 % ; exemple vérifié 33,0 %) |
|
||
|
||
### Correctifs de la passe 8 — vérification indépendante
|
||
|
||
Une passe de vérification adversariale a confirmé que les 15 correctifs High/Med
|
||
échantillonnés sont **réellement implémentés**, puis a trouvé des écarts
|
||
**jamais documentés** (politique par défaut, dés, outillage), tous corrigés :
|
||
|
||
| Commit | Objet |
|
||
|---|---|
|
||
| `31d47ae` | *Spell Combat* : garde `_has_slot` (sans emplacement, la policy ne provoque plus l'attaque à −2) |
|
||
| `bdf15aa` | Soin de la policy : contrôle **portée + ligne d'effet** (fini le tour perdu sur un contact hors portée) |
|
||
| `e8b7a73` | `parse_dice("d1"/"1d1")` lève bien `DiceParseError` (plus de `ValidationError` pydantique) |
|
||
| `f93c55b` | *Up Close and Deadly* émis seulement si un tir d'arme à feu suit (fini le grit gaspillé) |
|
||
| `c23fc36` | Seuil « < 50 % » exact (`hp*2 < hp_max`) |
|
||
| `6f01a8e` | Mode soin du canal : seuls les **vivants** comptent (un allié mort-vivant ne le déclenche plus) |
|
||
| `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) |
|
||
|
||
### Correctifs de la passe 10 — sorts utilitaires résiduels (lot 4)
|
||
|
||
| Commit | Objet |
|
||
|---|---|
|
||
| `08f9af9` | **Guidance** : nouveau type `OneShotEffect` (+1 compétence one-shot sur un unique jet d'attaque, non appliqué au jet de confirmation) — implémente le variant attaque du SRD |
|
||
| `1238c40` | **Resistance** : +1 résistance aux jets de sauvegarde (1 min) ; `_find_buff_spell` ignore désormais les cantrips sans emplacement (évite de préempter les buffs de niveau et de dégrader la policy) |
|
||
| `a8a65b1` | **Virtue** : 1 pv temporaire (track `temp_hp` consommé avant les vrais pv) |
|
||
| `f788613` | **Stabilize** : `StabilizeEffect` qui stabilise automatiquement une créature mourante |
|
||
| — | `spiritual_weapon` (attaque flottante persistante) et `saving_finale` (reroll immédiat) restent **différés** (mécanique porteuse absente) |
|
||
|
||
### Correctifs de la passe 11 — alignement (sorti du hors-périmètre)
|
||
|
||
| Commit | Objet |
|
||
|---|---|
|
||
| `f9e51e3` | Champ **`alignment`** sur `Combatant` (9 valeurs PF1e validées, défaut `N`) + dérivées `is_lawful/is_chaotic/is_good/is_evil` ; alignements renseignés pour tous les monstres et PJ (source KB/feuilles) ; exposé dans l'observation |
|
||
| `6a18d45` | Type **`AlignmentGate`** sur les dégâts : cible immunisée / neutre (moitié, sans condition) / pleine (dégâts + condition si sauvegarde ratée) ; *Shard of Chaos* (chaotique/loyal, condition `staggered`) et *Spear of Purity* (bon/mauvais, condition `blinded`) |
|
||
| `3be22b9` | Vocabulaire de conditions **`attacker_is_evil/lawful/good/chaotic`** câblé à l'attaquant réel ; **Protection from Evil/Law** (+2 CA déflexion et +2 sauvegardes contre l'alignement opposé) et variantes communales |
|
||
|
||
### Correctifs de la passe 12 — composantes & échec d'armure (sortis du hors-périmètre)
|
||
|
||
| Commit | Objet |
|
||
|---|---|
|
||
| `1f8f068` | Moteur : `components` sur `SpellSpec` (V/S/M/F/DF validés), `armor_spell_failure` + `arcane_caster` sur `Combatant` ; jets d'échec **conditionnels** (sourd + composante verbale → 20 % ; arcanique + somatique + armure → ASF d100), exposés dans l'observation |
|
||
| `91666d8` | Encodage des composantes SRD sur **107/108 sorts** (le 108e n'a pas de ligne Composants au KB) |
|
||
| `f6292f8` | `arcane_caster` / `armor_spell_failure` posés depuis les feuilles (liche, Thrune, misty, nairda arcaniques) |
|
||
| `9f72948` | README synchronisé |
|
||
|
||
### Correctifs de la passe 13 — objets / inventaire (sortis du hors-périmètre)
|
||
|
||
| Commit | Objet |
|
||
|---|---|
|
||
| `74f5d64` | **Sunder réel** : statistiques d'objet par arme (dureté/PV SRD, +2/+2 par point d'amélioration) ; dégâts réels de l'attaque moins la dureté ; arme *broken* à ≤ moitié des PV, détruite à 0 ; **arme cassée utilisable à −2** avec critique sur 20 naturel ×2 (réconcilié avec le *misfire*/*quick_clear*) |
|
||
| `d0f7f3a` | **`carried_items`** (objets portés, non tenus) sur le modèle + données depuis les feuilles ; **Steal** transfère réellement un objet porté ; **récupération** d'une arme lâchée (pickup au désarmement à mains nues) |
|
||
|
||
### Correctifs de la passe 14 — audit du rendu du transcript & des formats
|
||
|
||
Audit read-only de la dernière zone non vérifiée (`cli.py` rendu du transcript, `map.py`, `loaders/combatant.py`) : **14 bogues confirmés** (4 Med, 10 Low), tous corrigés.
|
||
|
||
| Commit | Objet |
|
||
|---|---|
|
||
| `9656ae8` | Clé `spell_slots` non numérique → `CombatantLoadError` (au lieu d'un `ValueError` brut qui plantait la CLI) |
|
||
| `b8e9629` | `features` non-liste (ou entrée vide/non-chaîne) → erreur propre (au lieu d'une perte silencieuse) |
|
||
| `9adc87c` | `level` normalisé de façon cohérente (fini le *Toughness* calculé au niveau 1 pour un niveau 4) |
|
||
| `a8c7e37` | Ressources validées de façon cohérente avant fusion des dons |
|
||
| `130087a` | Carte : rejet d'une couche `zones` sans `deployment` |
|
||
| `de9309c` | CLI : rejet d'un `--side` dupliqué |
|
||
| `e9c2a63` | Désambiguïsation d'ids : le suffixe saute les ids déjà pris |
|
||
| `10f811e` | `range_increment_ft` strictement positif (0 provoquait une division par zéro) |
|
||
| `c46e636` | `--round-cap` ≥ 1 |
|
||
| `205ddec` | Clés de légende à un seul caractère |
|
||
| `bce0a59` | Lignes vides dans une couche → erreur ; cellules d'espace final conservées |
|
||
| `53c6dc0` | Ids de combattant rejetant `": "` (qui cassaient le parsing du transcript) |
|
||
| `ee22f75` | Clés YAML dupliquées rejetées (SafeLoader dédié) |
|
||
| `dd0b42b` | `move_cost` omis documenté explicitement comme infranchissable |
|
||
|
||
### Correctifs de la passe 15 — hors-périmètre : non-létal, éclaboussures, compétences, vol
|
||
|
||
| Commit | Objet |
|
||
|---|---|
|
||
| `cba7bbf` | **Piste de dégâts non létaux** séparée ; *staggered* à non-létal = PV, *inconscient* au-delà ; immunité morts-vivants/artificiels ; le soin au-dessus du non-létal rend conscient |
|
||
| `83c6e54` | Sources non létales : **unarmed strikes** non létaux par défaut ; **minimum de dégâts** = 1 **non-létal** exact |
|
||
| `9cfcd67` / `2e60bbb` / `a1b1c29` / `678a4d8` | **Armes à éclaboussures** : touche directe = dégâts + 1 aux créatures à 5 ft ; échec = dispersion (d8) ; énergie (résistance/immunité), pas de RD ni de critique ; RNG inchangé pour les autres armes |
|
||
| `e0fb5be` | **Jet de compétence** général (d20 + rangs + car. + classe +3 si rangs + ACP) |
|
||
| `61686b5` | **Acrobaties « Tumbling »** : esquive d'AoO (DC = CMD, +5 si plus grand, +2 par adversaire), demi-vitesse, échec = l'AoO part et le déplacement s'arrête |
|
||
| `2c40994` | **Discrétion / Perception opposée** : action de se cacher, `hidden_from` par observateur (concealment total + +2/déni Dex), brisée en attaquant/courant |
|
||
| `2ae86ab` | **Vol au-dessus du terrain** : un volant ignore le terrain difficile et franchit les cases infranchissables au sol, sauf les murs `blocks_los` (pleine hauteur) ; LoE/couvert/high ground inchangés |
|
||
| `9210a54` | Documentation du vol et de la **LoE verticale/falaise différée** (pas de hauteur de mur dans les données) |
|
||
|
||
> Vérifiés conformes par l'audit : largeur d'affichage (accents NFC/NFD, CJK), repli en ligne brute sans perte, parsing des lignes conformes, capture du premier combat (`seed+0`), sémantique des nuls, normalisation du couvert (`cover_bonus`, `cover: true` → +4, `blocks_los` → +4), validations de déploiement/markers, ordre `(ligne, colonne)`, bande 3σ bornée.
|
||
|
||
> **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
|
||
|
||
| # | 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 |
|
||
| **Compétences hors combat** (Escalade, Natation, Diplomatie, Sabotage, Connaissances, Art de la magie…) | Seules les compétences utiles au combat sont modélisées (Acrobaties Tumbling, Discrétion/Perception, Évasion) |
|
||
| **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 %)** | Modélisé (composante verbale + `deafened`) |
|
||
| **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 — LoE verticale / falaise** | Le survol du terrain est modélisé ; la ligne d'effet verticale et les falaises ne le sont pas (les données n'expriment pas de hauteur de mur) |
|
||
| **`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 |
|
||
|---|---|---|
|
||
| **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** | **Modélisé** (piste séparée, sources unarmed, minimum de dégâts non létal) | Sorti du hors-périmètre |
|
||
| **Armes à éclaboussures** | **Modélisées** (touche directe + éclaboussure, dispersion d8) | Sorties du hors-périmètre |
|
||
| **Sorts utilitaires différés** | `spiritual_weapon` (attaque flottante persistante — pas d'attaquant sans porteur dans le moteur) et `saving_finale` (reroll immédiat — pas de crochet de réaction sur un jet de sauvegarde) restent hors d'atteinte ; `guidance`, `resistance`, `virtue` et `stabilize` sont désormais **modélisés** | Différés (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 désormais **audités** (passe 14, 14 bogues corrigés) ; toutes les zones sont couvertes | Couverture complète |
|
||
|
||
---
|
||
|
||
## 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 | 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 | 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 résiduels (lot 4) : guidance, resistance, virtue, stabilize, spiritual_weapon, saving_finale | `bg_9c989e12` | 4 implémentés, 2 différés | 4 correctifs (`08f9af9`..`f788613`) |
|
||
| 11 | **Hors périmètre — alignement** : champ + dérivées, Shard of Chaos / Spear of Purity, Protection from Evil/Law (+communales) | `bg_1a3b0faa`, `bg_6980098f`, `bg_07b3d604` | 3 correctifs | Alignement **sorti du hors-périmètre** |
|
||
| 12 | **Hors périmètre — composantes & ASF** : composantes sur 107 sorts, sourd 20 %, échec d'armure, `arcane_caster` | `bg_02d4b4e3`, `bg_84baec1d` | 4 correctifs | Composantes/ASF **sortis du hors-périmètre** |
|
||
| 13 | **Hors périmètre — objets/inventaire** : Sunder réel (dureté/PV), Steal, récupération d'arme | `bg_f9c69e32`, `bg_44d81a98` | 2 correctifs | Objets/inventaire **sortis du hors-périmètre** |
|
||
| 14 | Audit du rendu du transcript + formats (cli/map/loader) | `bg_dc36ad2f` | 14 bogues (4 Med, 10 Low), 0 High | 14 correctifs (`9656ae8`..`dd0b42b`) |
|
||
| 15 | **Hors périmètre — non-létal, éclaboussures, compétences, vol** | `bg_388b9b98`, `bg_22a32075`, `bg_137eb485`, `bg_edd042b7` | 15 correctifs | 4 chantiers **sortis du hors-périmètre** |
|
||
| 16+ | Reste structurel : LoE verticale/falaise, deux armes, multi-round `long`, squeeze, compétences hors combat, markers | — | — | Documenté (hors périmètre) |
|
||
|
||
---
|
||
|
||
## 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.
|