Files
oto-enterprise-os-dtp/05_deliverables_mvp/qa/regression/out/regression_plan.json
T
Claude Code DTP Worker 5af86e3518 [DTP-Worker 20260812_073055] hardening correctness · rendu HTML publiciste — percent-encode le SEUL segment d'URL restant (code) dans le url('…') CSS
Durcissement d'uniformité (pas bug déclenchable aujourd'hui) qui COMPLÈTE le fix
correctness de la session 070054 (aeb30b8). Ce fix-là a percent-encodé
hero['fichier'] dans src=f"/static/projets/{code}/{quote(fichier)}", mais dans la
MÊME url('…') CSS il restait un 2ᵉ segment dynamique — `code` — interpolé brut puis
html-échappé via _esc(src). C'est exactement l'anti-pattern identifié par 070054
(html.escape = mauvais encodeur pour un segment d'URL), appliqué de façon incomplète.

Fix : src = f"/static/projets/{quote(code)}/{quote(hero['fichier'])}" — quote() est
le SEUL encodeur correct pour un segment d'URL ; le CONTEXTE, pas la donnée courante,
dicte l'encodeur. Zéro dérive : codes réels = P01..P09 (§Projets), quote("p01")=="p01"
→ byte-repro inchangé. Cas frère exact de 060044/criteria.py (« durcir le SEUL membre
non-durci d'une famille ») : ici le SEUL segment d'URL non-encodé de la même url().

Test à dents (test_hero_media_code_segment_percent_encoded) : code théorique "P'X" →
prouvé FAIL sans quote(code), PASS avec. Suite publiciste 25→26, matrice 630/613→631/614.

Défaut d'abord : classe encodage-contextuel balayée sur tous les modules HTML/CSS/URL ;
2 candidats Explore réfutés non-défauts (chat mount_html = persona forcée Amélie par
invariant 7 + portail_key enum ; code segment = théorique mais durci par uniformité).
Cascade régénérée dans l'ordre (quality_report en DERNIER) · 3 fiches compteurs réalignées.
run_ci 33/0/0 · NFC-clean · zéro code moteur V18 (bloqué D-06 #6) · zéro gate (#5) · zéro invention (#6).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-12 07:41:05 +00:00

311 lines
7.5 KiB
JSON

{
"matrix": "OTO QA · Matrice de régression exhaustive",
"version": "1.0",
"reference_cadre": "Roadmap Sprint 8 · QA « Regression tests exhaustifs » · CLAUDE.md #5 (zéro régression silencieuse · niveau 4Big)",
"self_module": "qa/regression",
"thresholds": {
"min_test_files": 1,
"min_methods_per_suite": 8
},
"discover_cmd": [
"python3",
"-m",
"unittest",
"discover",
"-s",
"tests"
],
"coverage": {
"ok": true,
"suites_count": 24,
"gated_in_ci": 25,
"self_module_excluded": "qa/regression",
"self_module_gated": true,
"missing_tests_dir": [],
"not_in_gate": [],
"orphan_tests_dirs": []
},
"suites": [
{
"id": "crm.commissions",
"path": "crm/commissions",
"jobs": [
"crm-commissions-tests"
],
"in_gate": true,
"has_tests_dir": true,
"test_files": 1,
"test_methods": 25
},
{
"id": "crm.dossier_vente",
"path": "crm/dossier_vente",
"jobs": [
"crm-dossier-vente-tests"
],
"in_gate": true,
"has_tests_dir": true,
"test_files": 1,
"test_methods": 31
},
{
"id": "crm.financement_bancaire",
"path": "crm/financement_bancaire",
"jobs": [
"crm-financement-bancaire-tests"
],
"in_gate": true,
"has_tests_dir": true,
"test_files": 1,
"test_methods": 35
},
{
"id": "crm.workflow_vente",
"path": "crm/workflow_vente",
"jobs": [
"crm-workflow-vente-tests"
],
"in_gate": true,
"has_tests_dir": true,
"test_files": 1,
"test_methods": 25
},
{
"id": "demo.scenarios",
"path": "demo/scenarios",
"jobs": [
"demo-scenario-tests"
],
"in_gate": true,
"has_tests_dir": true,
"test_files": 1,
"test_methods": 39
},
{
"id": "devops.deploy_runbook",
"path": "devops/deploy_runbook",
"jobs": [
"devops-deploy-runbook-tests"
],
"in_gate": true,
"has_tests_dir": true,
"test_files": 1,
"test_methods": 29
},
{
"id": "faisabilite.bancable",
"path": "faisabilite/bancable",
"jobs": [
"bancable-tests"
],
"in_gate": true,
"has_tests_dir": true,
"test_files": 1,
"test_methods": 22
},
{
"id": "faisabilite.generator",
"path": "faisabilite/generator",
"jobs": [
"faisabilite-gen-tests"
],
"in_gate": true,
"has_tests_dir": true,
"test_files": 1,
"test_methods": 17
},
{
"id": "fiscal.ecf_dgii",
"path": "fiscal/ecf_dgii",
"jobs": [
"fiscal-ecf-tests"
],
"in_gate": true,
"has_tests_dir": true,
"test_files": 1,
"test_methods": 39
},
{
"id": "frontend.chat_otoia",
"path": "frontend/chat_otoia",
"jobs": [
"chat-otoia-tests"
],
"in_gate": true,
"has_tests_dir": true,
"test_files": 1,
"test_methods": 31
},
{
"id": "frontend.portails",
"path": "frontend/portails",
"jobs": [
"frontend-portails-tests"
],
"in_gate": true,
"has_tests_dir": true,
"test_files": 1,
"test_methods": 19
},
{
"id": "legal.confotur",
"path": "legal/confotur",
"jobs": [
"legal-confotur-tests"
],
"in_gate": true,
"has_tests_dir": true,
"test_files": 1,
"test_methods": 44
},
{
"id": "mobile.app_config",
"path": "mobile/app_config",
"jobs": [
"mobile-app-config-tests"
],
"in_gate": true,
"has_tests_dir": true,
"test_files": 1,
"test_methods": 22
},
{
"id": "pie.manifest",
"path": "pie/manifest",
"jobs": [
"pie-manifest-tests"
],
"in_gate": true,
"has_tests_dir": true,
"test_files": 1,
"test_methods": 20
},
{
"id": "publiciste",
"path": "publiciste",
"jobs": [
"publiciste-tests"
],
"in_gate": true,
"has_tests_dir": true,
"test_files": 1,
"test_methods": 26
},
{
"id": "qa.acceptance",
"path": "qa/acceptance",
"jobs": [
"qa-acceptance-tests"
],
"in_gate": true,
"has_tests_dir": true,
"test_files": 1,
"test_methods": 37
},
{
"id": "qa.audit_4big",
"path": "qa/audit_4big",
"jobs": [
"qa-audit-4big-tests"
],
"in_gate": true,
"has_tests_dir": true,
"test_files": 1,
"test_methods": 37
},
{
"id": "qa.audit_5d",
"path": "qa/audit_5d",
"jobs": [
"qa-audit-5d-tests"
],
"in_gate": true,
"has_tests_dir": true,
"test_files": 1,
"test_methods": 37
},
{
"id": "rbac",
"path": "rbac",
"jobs": [
"rbac-tests"
],
"in_gate": true,
"has_tests_dir": true,
"test_files": 1,
"test_methods": 10
},
{
"id": "rbac.apply_plan",
"path": "rbac/apply_plan",
"jobs": [
"rbac-applyplan-tests"
],
"in_gate": true,
"has_tests_dir": true,
"test_files": 1,
"test_methods": 16
},
{
"id": "rbac.fixtures_gen",
"path": "rbac/fixtures_gen",
"jobs": [
"rbac-fixtures-tests"
],
"in_gate": true,
"has_tests_dir": true,
"test_files": 1,
"test_methods": 11
},
{
"id": "rbac.roleprofile_gen",
"path": "rbac/roleprofile_gen",
"jobs": [
"rbac-roleprofile-tests"
],
"in_gate": true,
"has_tests_dir": true,
"test_files": 1,
"test_methods": 11
},
{
"id": "rbac.userperm_gen",
"path": "rbac/userperm_gen",
"jobs": [
"rbac-userperm-tests"
],
"in_gate": true,
"has_tests_dir": true,
"test_files": 1,
"test_methods": 12
},
{
"id": "seo",
"path": "seo",
"jobs": [
"seo-tests"
],
"in_gate": true,
"has_tests_dir": true,
"test_files": 1,
"test_methods": 36
}
],
"under_threshold": [],
"totals": {
"suites": 24,
"test_files": 24,
"test_methods": 631,
"min_methods": 10,
"under_threshold": 0
},
"verdict": "PASS",
"notes": [
"Harnais de MÉTA-NIVEAU : agrège l'exécution de TOUTES les suites de tests gated du mandat en une seule matrice + un verdict PASS/FAIL. Sprint 8 · QA « Regression tests exhaustifs ».",
"Périmètre PROUVÉ, pas déclaré : les suites sont DÉRIVÉES de .gitea/workflows/ci.yml (réutilise q4lib/registry.parse_ci — zéro duplication · #5), jamais listées à la main. Tout job de test ajouté au CI entre automatiquement dans la matrice.",
"Séparation des pouvoirs (ISA 315) : le harnais s'exclut lui-même (self_module) — il ne s'auto-exécute pas (évite la récursion) et ne se compte pas dans le total régression.",
"ANTI-INVENTION (#6) : le `build` (plan) ne contient AUCUN compteur de résultats (0 test vert écrit à la main) ; seuls des FAITS de disque (fichiers/méthodes test_*) et de CI (job, gate) y figurent. Les compteurs verts/rouges sont produits UNIQUEMENT par `run`, en parsant la sortie réelle de unittest.",
"Distinct de l'audit 4Big : audit_4big note la QUALITÉ statique par module (doc/schema/CLI/hand-off) ; ce harnais prouve que chaque suite S'EXÉCUTE AU VERT et fournit le compte agrégé faisant autorité (« N tests verts »). Axes complémentaires, non redondants."
]
}