livrare lot 2

This commit is contained in:
EVOTECH IT SRL 2026-07-10 03:39:53 -07:00
commit 8ecc78e729
763 changed files with 164593 additions and 0 deletions

View file

@ -0,0 +1,198 @@
% Raport de testare a integrării — DiDi Lot 1 (AI) ↔ Lot 2 (Backend)
% PNRR DIGI150 · contract 11.1.i3.c9
% Data testării: 2026-07-09
---
# 1. Obiect și scop
Prezentul raport documentează **testele de integrare** dintre **Lotul 2 — Backend**
(motorul de analiză `agent-v3` + `didiFramework` + workeri) și **Lotul 1 — Platforma AI**
(modelele LLM, deepfake, transcriere, extractoare, forensic, brain/RAG, domain-check).
Raportul de testare a API-ului Lotului 2 (`03_Raport_Testare_API_Lot2`) acoperă **strict
Lotul 2** și menționează explicit că serviciile AI (Lotul 1) „sunt testate separat, prin
testele de integrare". Documentul de față **este acea probă**: demonstrează pe mediul live
că cele două loturi **colaborează** — de la conectivitate punct-la-punct până la producerea
unui verdict complet pe fiecare tip de conținut, plus proprietățile de reziliență și
securitate ale integrării.
Testarea confirmă cerințele din caietul de sarcini privind consumul de **extractoare
specializate** (deepfake, NER, OCR, Whisper, YOLO), **modulul web-crawl/evidence**, **scorul
de credibilitate a sursei** și **orchestrarea fluxurilor ML end-to-end** prin backend.
---
# 2. Metodologie
Testarea a fost efectuată pe platforma live (`<HOST_IP>`, 2× H200), **non-distructiv**,
printr-un harness reproductibil (`scripts/integration/run-integration-tests.sh`) structurat
pe **trei niveluri**:
- **Nivel A — Conectivitate & contract.** Din interiorul containerului `agent-v3`
(consumatorul real), fiecare serviciu Lot 1 este sondat prin `didi-network`, pe nume de
container (nu IP). Dovedește că boundary-ul de rețea și contractul HTTP funcționează.
- **Nivel B — End-to-end pe tip de conținut.** Pentru fiecare din cele 5 tipuri (text, URL,
imagine, audio, video) se lansează o analiză reală prin `POST /api/v3/pipeline/analyze-async`
și se așteaptă verdictul persistat. Dovedește orchestrarea completă Lot2→Lot1→verdict.
- **Nivel C — Proprietăți transversale.** Fail-open (degradare grațioasă la indisponibilitatea
unui serviciu AI), rutarea către modelul LLM local (fără fallback plătit) și enforcement-ul
gateway-ului peste lanțul AI.
Fiecare test capturează **trei artefacte independente**: (1) request-ul emis de `agent-v3`,
(2) **access-log-ul serviciului Lot 1** care dovedește primirea cererii, (3) **verdictul
persistat în PostgreSQL** (`bos_analysis.analysis_session`). Toate artefactele brute sunt
salvate în `scripts/integration/results/evidence_<timestamp>/`.
Utilizatorul de test are credite alocate; strategia de dispatch este cea de producție (cozi
RabbitMQ + workeri Docker + agregator de verdict).
---
# 3. Rezultate
| Metric | Valoare |
|---|---|
| Teste de integrare rulate | **17** |
| — Nivel A (conectivitate) | 9 |
| — Nivel B (end-to-end) | 5 |
| — Nivel C (transversale) | 3 |
| **PASS** | **16** |
| **DEGRADED** (fail-open, comportament corect) | **1** |
| **FAIL** | **0** |
| Defecte identificate și remediate | 1 (Lot 1 — vezi §4) |
## 3.1 Nivel A — Conectivitate agent-v3 → servicii Lot 1
Toate cele 9 integrări din documentația de arhitectură (§9) răspund din chiar consumatorul
`agent-v3`, pe `didi-network`:
| # | Serviciu Lot 1 | Adresă (didi-network) | Cerință acoperită | Rezultat |
|---|---|---|---|---|
| A1 | LLM text (Qwen 3.5) | `llm-api:14011` | flux LLM / ML | **PASS** (HTTP 200, model `qwen3.5` încărcat) |
| A2 | LLM vision / OCR | `llm-api:14011` | extractor OCR | **PASS** (`qwen3.5` vision-capable) |
| A3 | Whisper transcriere | `audio-api:54300` | extractor Whisper | **PASS** (HTTP 200) |
| A4 | BusterX deepfake | `video-api:54600` | extractor deepfake | **PASS** (HTTP 200) |
| A5 | Extractoare | `extractors:54400` | NER/YOLO/OCR/EXIF | **PASS** (HTTP 200) |
| A6 | Forensic media | `forensic:8080` | analiză forensică | **PASS** (HTTP 200) |
| A7 | Web / evidence | `web-api:51100` | modul web-crawl | **PASS** (HTTP 200) |
| A8 | Brain / RAG | `brain-api:8090` | flux ML fact-check | **PASS** (HTTP 200) |
| A9 | Domain-check (T4) | `domain-check-api:11000` | scor credibilitate sursă | **PASS** (`POST /check/check``risk_score` real) |
## 3.2 Nivel B — Analize end-to-end (pipeline complet → verdict)
Fiecare analiză a rulat prin cozile RabbitMQ și workerii de producție, verdictul fiind
persistat în PostgreSQL. Coloana „Dovada Lot 1" citează access-log-ul serviciului apelat.
| # | Input | Lanț Lot 1 | Verdict (scor/categorie) | Dovada Lot 1 | Rezultat |
|---|---|---|---|---|---|
| B1 | Text dezinformare (microcipuri 5G) | llm-api | **DISINFORMATION / 92** | `POST /v1/chat/completions 200` | **PASS** |
| B2 | URL (bbc.com/news) | web + domain-check | **RELIABLE / 7** | `POST /api/v1/check/check 200` | **PASS** |
| B3 | Imagine (titlu fals) | vision-OCR + extractoare | **DISINFORMATION / 95** | `POST /v1/chat/completions 200` (OCR a citit titlul) | **PASS** |
| B4 | Audio (discurs) | Whisper → llm | **RELIABLE / 0** | `POST /v1/audio/transcriptions 200` | **PASS** |
| B5 | Video | media-preprocess → BusterX | **RELIABLE / 5** | `POST /analyze/video 200` | **PASS** |
> Nota B3: OCR-ul local (Qwen vision) a extras corect textul titlului fabricat din imagine,
> iar pipeline-ul l-a clasificat DISINFORMATION — dovadă directă a lanțului vision→verdict.
> Nota B5: verdict obținut după remedierea defectului D1 (vezi §4); BusterX a răspuns `200`.
## 3.3 Nivel C — Proprietăți transversale
| # | Test | Cerință | Rezultat |
|---|---|---|---|
| C1 | **Fail-open**: `didiAI-web-api` oprit temporar, analiză lansată | reziliență / fail-open servicii AI | **DEGRADED** — analiza s-a **terminat** cu degradare grațioasă (`status=completed`), fără eșec; serviciul a fost repornit |
| C2 | **Rutare model local**: analiză text | flux LLM local, fără fallback plătit | **PASS** — 5 apeluri către `llm-api:14011`, provider `qwen35` local; niciun apel OpenRouter plătit |
| C3 | **Gateway**: `POST /pipeline/analyze-async` prin Kong fără token | API Gateway + securitate | **PASS** — Kong răspunde **401**, păzind lanțul AI |
Rezultatul **DEGRADED** la C1 este comportamentul **corect și dorit**: afirmația de
reziliență din documentația de arhitectură (§6, „fail-open pe servicii AI") este validată
empiric — indisponibilitatea unui serviciu Lot 1 nu blochează analiza.
---
# 4. Defecte identificate și remediate
Testarea de integrare a identificat **1 defect real** (în Lotul 1), remediat și re-testat:
| # | Severitate | Serviciu | Defect | Cauză rădăcină | Remediere | Verificare |
|---|---|---|---|---|---|---|
| **D1** | major | `didiAI-video-api` (BusterX), Lot 1 | `POST /analyze/video`**500**; detecția deepfake nu rula (mascată de fail-open, care producea totuși verdict) | Bind-mount **stale** pe `/app/runs`: directorul host `local_gpu_stack/runs` fusese recreat după pornirea containerului → inode container (`6195429`) ≠ inode host (`6195434`) → `os.makedirs('/app/runs/<uuid>')` eșua cu `FileNotFoundError` | `docker restart didiAI-video-api` (re-rezolvă bind-mount-ul la inode-ul curent) | Inode host == container (`6195434`); test de scriere OK; `POST /analyze/video`**200**; verdict video RELIABLE/5 |
Observație importantă: defectul era **mascat** de mecanismul fail-open — analiza video se
finaliza cu verdict, dar BusterX nu se executa efectiv. Doar inspecția access-log-ului
serviciului Lot 1 (parte din metodologia acestui raport) a expus problema.
## 4.1 Măsuri de robustețe adăugate (ca defectul să nu se repete și să nu mai fie tăcut)
Pe lângă remedierea imediată, au fost adăugate două măsuri durabile:
1. **Healthcheck de scriere pe `video-api` (Lot 1).** Containerul `didiAI-video-api` a primit
un healthcheck care **verifică efectiv scrierea în `/app/runs`** (nu doar `GET /health`).
Un bind-mount stale îl face imediat `unhealthy` (vizibil în `docker ps` + dashboard), în loc
să producă un `500` tăcut. `local_gpu_stack/docker-compose.yml`.
2. **Degradare vizibilă în verdict (Lot 2).** Când BusterX era activat dar nu a returnat
rezultat, `media-preprocess-worker` scrie acum o santinelă `UNAVAILABLE`, iar
`video-2-track.ts` o **semnalează explicit** în verdictul persistat: indicator
`VID.2 „Verificare deepfake INDISPONIBILĂ — recomandată verificare manuală"` +
`coupling_context.for_verdict.deepfake_check = "unavailable"` + `needs_manual_review = true`.
Astfel un eșec al detecției deepfake **nu mai poate fi confundat** cu o verificare reușită.
Verificat controlat (2 rulări video pe același clip):
| Scenariu | `deepfake_check` | `needs_manual_review` | Indicator VID.2 |
|---|---|---|---|
| BusterX activ | *(absent)* | true | „BusterX deepfake detection: REAL" |
| BusterX oprit | **`unavailable`** | true | „Verificare deepfake INDISPONIBILĂ — verificare manuală" |
Fișiere: `agent-v3/src/queue/workers/media-preprocess-worker.ts`,
`agent-v3/src/queue/workers/component-worker-helpers/video-2-track.ts`.
---
# 5. Reflectarea integrării în specificația OpenAPI (Swagger)
Integrarea cu Lotul 1 constă în dependențe **outbound** ale `agent-v3` (apeluri HTTP către
servicii AI), nu în rute expuse de backend — prin urmare **nu** apare ca `paths` în
specificația OpenAPI. A fost documentată, în schimb, prin două mecanisme:
1. **Endpoint de sondă de integrare**`GET /api/v3/health/all` a fost extins să verifice
**toate cele 9 servicii Lot 1** (pe lângă infrastructura internă), *fail-open*: o
dependență AI indisponibilă produce `degraded` (HTTP 200), nu `unhealthy`. Endpoint-ul
este documentat în `openapi.yaml` prin schema `DeepHealthResponse` și servește simultan
ca **test de integrare live**, rulabil oricând.
2. **Bloc `x-integrations`** la nivel de specificație — listează cele 9 servicii Lot 1
consumate (cheie, variabilă de mediu, țintă pe `didi-network`, rol), contractul fail-open
și sonda de health. Extensie OpenAPI validă, informativă.
Ambele au fost validate cu `openapi-spec-validator` (rezultat: **VALID**, OpenAPI 3.0.3).
Verificare live a sondei extinse: 14 dependențe (4 interne + 10 AI), toate `healthy`.
---
# 6. Artefacte și reproducere
| Artefact | Locație |
|---|---|
| Harness de testare (reproductibil) | `scripts/integration/run-integration-tests.sh` |
| Fixturi (imagine, audio, video) | `scripts/integration/fixtures/` |
| Rezultate structurate (JSON) | `scripts/integration/results/results_2026-07-09.json` |
| Dovezi brute (access-log Lot 1, verdicte PG, health/all) | `scripts/integration/results/evidence_20260709_224124/` |
| Sondă de integrare + schema OpenAPI | `agent-v3/openapi.yaml` (`x-integrations`, `DeepHealthResponse`) |
| Tabel integrări Lot 1 | `docs/01_Arhitectura_Lot2.md` §9 |
Rulare: `bash scripts/integration/run-integration-tests.sh` (variabile opționale:
`AGENT_URL`, `TEST_USER`, `KONG_URL`).
---
# 7. Concluzie
Integrarea dintre **Lotul 2 (Backend)** și **Lotul 1 (Platforma AI)** este **funcțională și
verificată end-to-end** pe mediul live: **16/17 teste PASS**, 1 DEGRADED (comportament
fail-open corect), **0 FAIL**. Toate cele 9 servicii AI sunt raggiunse și consumate corect;
cele 5 tipuri de conținut produc verdicte complete; reziliența (fail-open), rutarea către
modelul local și enforcement-ul gateway-ului sunt confirmate. Singurul defect identificat
(D1 — bind-mount stale pe BusterX) a fost remediat și re-testat cu succes. Integrarea
Lot1↔Lot2 este **conformă și verificabilă**, iar starea ei live este observabilă permanent
prin `GET /api/v3/health/all`.