Closes the 12 MAJ raised by the release/0.5.0 audit pipeline (cf.
docs/audit/reports/release-0.5.0/summary.md → summary-reaudit.md).
Volet 1 — Reasoning architecture (audits 01/02/06/07 strengthening)
* Domain ports: LLMProvider, ReasoningRunner, ReasoningParseError
* Domain DTOs: LLMProviderType, ReasoningResult, ReasoningIteration
* infra/llm/ollama_provider.py — OllamaProvider with health_check
* infra/docling_agent_reasoning.py — runner adapter, encapsulates the
private _rag_loop call (tracked at docling-project/docling-agent#26),
commits OLLAMA_HOST once at boot (eliminates the per-request env race),
translates upstream IndexError into ReasoningParseError
* api/reasoning.py — zero coupling to docling-agent / mellea / docling-core,
consumes app.state.reasoning_runner via the port
* main.py — DI wires OllamaProvider + DoclingAgentReasoningRunner at boot
when REASONING_ENABLED=true and deps are importable
* Rename RAG_* env vars → REASONING_*, endpoint /rag → /reasoning,
type RAGResult → ReasoningResult, frontend feature flag wiring,
i18n strings, tests, docs (BREAKING — pre-1.0 surface, no external
consumers in production)
* 17 new tests: adapter unit tests with sys.modules stubs, OllamaProvider
httpx tests, R3 concurrent-host isolation, R6 multi-iteration trace
serialization, R13 Protocol conformance via isinstance
* E2E Karate scenario: nav-reasoning hidden when REASONING_ENABLED=false
* README — Live Reasoning section (env vars, archi, link to issue #26)
Bloc B — Security (audit 08, dev-only context)
* docker-compose.yml — DEV DEFAULTS header, OpenSearch DISABLE_SECURITY_PLUGIN
flagged as dev-only with link to OpenSearch security docs
* main.py — boot warning if NEO4J_URI is set with the default 'changeme'
password, so prod operators can't silently inherit it
Bloc C — DRY frontend (audit 05)
* shared/storage/keys.ts — STORAGE_KEYS centralised (theme, locale)
* features/settings/store.ts — dead apiUrl ref + orphan i18n keys removed
* api/schemas.py — DOCUMENT_STATUS_UPLOADED constant
Bloc D — Quality (audits 02/06/07/09/10/12)
* domain/ports.py — DocumentConverter.supports_page_batching property
(LSP fix, replaces isinstance(ServeConverter) check)
* domain/ports.py — VectorStore.ping() (encapsulation, replaces
_vector_store._client.info() reach-around)
* api/analyses.py + api/ingestion.py — path params {job_id} → {analysis_id}
aligned with the user-facing terminology (URLs unchanged)
* api/documents.py — Path.read_bytes() + generate_preview() wrapped in
asyncio.to_thread, unblocks the FastAPI event loop on /preview
* infra/docling_tree.py — PEP 604 union for isinstance (Ruff UP038)
* src/__tests__/integration/ — cross-feature integration test relocated
out of features/history/ so feature folders stay self-contained
* Tightened terminal `assert X is not None` checks (isinstance(.., datetime),
exact value comparisons)
Validation
* 446 backend pytest, 202 frontend vitest — all green
* ruff + ruff format + ESLint + Prettier + vue-tsc clean
* Re-audit verdict: 0 CRIT / 0 MAJ, score ~94/100, GO
Closes #200
6.1 KiB
Synthese d'audit — Release 0.5.0
Date : 2026-04-28
Branche : release/0.5.0
Commit audite : b2e0af3
Auditeur : claude-code
Tableau de bord
| # | Audit | Score | CRIT | MAJ | MIN | INFO | Verdict |
|---|---|---|---|---|---|---|---|
| 01 | Clean Architecture | 100 | 0 | 0 | 0 | 0 | GO |
| 02 | DDD | 91 | 0 | 1 | 1 | 0 | GO |
| 03 | Clean Code | 83 | 0 | 0 | 3 | 0 | GO |
| 04 | KISS | 87.5 | 0 | 0 | 1 | 2 | GO |
| 05 | DRY | 71 | 0 | 2 | 1 | 2 | GO CONDITIONNEL |
| 06 | SOLID | 85 | 0 | 1 | 1 | 0 | GO |
| 07 | Decouplage | 86 | 0 | 1 | 1 | 0 | GO CONDITIONNEL |
| 08 | Securite | 91 | 0 | 2 | 0 | 1 | GO CONDITIONNEL |
| 09 | Tests | 94 | 0 | 1 | 0 | 0 | GO |
| 10 | CI / Build | 91 | 0 | 1 | 0 | 0 | GO CONDITIONNEL |
| 11 | Documentation | 44 | 1 | 2 | 0 | 0 | NO-GO |
| 12 | Performance | 86.67 | 0 | 1 | 1 | 1 | GO CONDITIONNEL |
Score global (moyenne simple) : 84.2 / 100 Ecarts CRITICAL totaux : 1 Ecarts MAJOR totaux : 12 Ecarts MINOR totaux : 8 Ecarts INFO totaux : 6
Ecarts CRITICAL (tous audits confondus)
- [11] CHANGELOG.md sans section
[0.5.0]—CHANGELOG.md:7La derniere section listee est## [0.4.0] - 2026-04-13. Aucune entree[Unreleased]ni[0.5.0]. Tagger 0.5.0 depuis ce HEAD livrerait un changelog mensonger qui omet les nouveautes de la release (reasoning-trace viewer, Neo4j graph storage, RAG endpoints, feature flags). Bloquant absolu par regle master §3.
Top blockers (poids 3 / poids 2)
Bloquant (poids 3)
- [11] CHANGELOG sans section 0.5.0 —
CHANGELOG.md:7Ajouter## [0.5.0] - 2026-04-28avec sous-sectionsAdded/Changed/Fixedlistant les changements depuis 0.4.0.
Majeurs (poids 2) — a remediar pour passer a GO
- [11]
frontend/package.jsontoujours a0.4.0—frontend/package.json:3Bumper a"version": "0.5.0". - [11] Modifications de la release 0.5.0 non documentees —
CHANGELOG.mdResolu en meme temps que le CRIT. - [08] Mot de passe Neo4j par defaut
"changeme"—document-parser/infra/settings.py:30,133Forcer la lecture d'une variable d'environnement, supprimer le defaut, faire echouer le boot si absent en prod. - [08] OpenSearch security plugin desactive —
docker-compose.yml:26DISABLE_SECURITY_PLUGIN=truedoit etre off pour tout deploiement non-dev ; documenter explicitement le perimetre. - [05] URL d'API hardcodee en frontend —
frontend/src/features/settings/store.ts:23Centraliser dans une constanteAPI_BASE_URLlue depuisimport.meta.env. - [05] Cles localStorage en clair, dispersees —
frontend/src/features/settings/store.ts:24-27Centraliser dans une enum/objetSTORAGE_KEYS. - [02] Ubiquitous language "job" vs "analysis" —
document-parser/api/ingestion.py:49-67Aligner le vocabulaire HTTP sur le langage du domaine. - [06] LSP —
isinstance()sur adaptateur —document-parser/services/analysis_service.py:356Supprimer le check de type concret ou exposer la capacite via le port. - [07] Couplage inter-feature dans les tests —
frontend/src/features/history/navigation.test.ts:30-31,67,82-83,143-144,169-170,188Stubber les stores via injection au lieu d'imports directs. - [09] Assertions vagues
assert X is not None— 18 occurrences en backend Ajouter une assertion sur la valeur attendue, pas seulement sur la presence. - [10] Ruff UP038 — syntaxe
isinstance()union —document-parser/infra/docling_tree.py:101Appliquer la suggestion pyupgrade. - [12] I/O synchrone dans endpoint async —
document-parser/api/documents.py:115-116Wrapper l'acces fichier dansasyncio.to_thread(...)pour ne pas bloquer la loop FastAPI.
Quick wins (poids 1 — ameliorations rapides)
- [03] Trois fichiers Vue > 300 lignes —
frontend/src/views/StudioPage.vue(~1450L),frontend/src/.../ChunkPanel.vue(~801L),frontend/src/.../ResultTabs.vue(~690L). Extraire des sous-composants. - [03] Fonctions > 30 lignes (3 cas) et fonctions > 4 parametres (4 cas). Decoupage local.
- [04] Wrapper trivial
_to_response— utiliserPydantic.model_validate()directement. - [04] Accessors redondants dans
DocumentService. - [05] Magic string isolee —
document-parser/api/schemas.py:49. - [12] Polling avec setInterval/setTimeout imbriques —
frontend/src/features/settings/store.ts:27-39et store analysis.
Verdict final : NO-GO
Justification : 1 ecart CRITICAL non resolu dans l'audit 11 (Documentation) → regle absolue du master.md §3 : tout ecart [CRIT] non resolu = NO-GO quel que soit le score.
Bien que le score global (84.2/100) soit confortablement au-dessus du seuil GO et que 11 audits sur 12 soient au moins en GO CONDITIONNEL, le release 0.5.0 ne peut pas etre tague dans cet etat.
Conditions pour passer a GO
Bloquant absolu (1 action) :
- Ajouter la section
## [0.5.0] - 2026-04-28dansCHANGELOG.mdavecAdded/Changed/Fixed.
Pour passer de GO CONDITIONNEL a GO (4 actions, ~30 min) :
2. Bumper frontend/package.json a 0.5.0.
3. Remplacer "changeme" par lecture d'env var obligatoire (document-parser/infra/settings.py).
4. Documenter / corriger la desactivation du security plugin OpenSearch (docker-compose.yml).
5. Centraliser l'URL d'API et les cles localStorage du frontend (frontend/src/features/settings/store.ts).
Recommandation : apres remediation des 5 points ci-dessus, re-auditer uniquement les audits 11, 08 et 05 (commande : Re-audite uniquement les ecarts CRITICAL et MAJOR du rapport docs/audit/reports/release-0.5.0/summary.md). Les autres MAJ peuvent etre planifies pour 0.5.1 sans bloquer le tag.