# Integrazione analisi `docs/nis2/` → NIS2 Agile > Data: 2026-05-29 (CEST) · Versione: v1.7.0 · Stato: **✅ DEPLOYATO ED ESEGUITO IN PRODUZIONE (Hetzner)** ## ✅ Eseguito in produzione (2026-05-29 ~17:06 CEST) - **Codice**: live su `/var/www/nis2-agile` (stesso filesystem del container dev via bind mount → nessuno scp necessario). 5 nuovi endpoint verificati live (HTTP 401 auth, routing OK). - **Migrazioni DB 020/021/022**: applicate e verificate (colonne assets/incidents + tabella `incident_pir` create). - **Ingest KB**: **287 chunk** normativi indicizzati in Qdrant `nis2_kb` scope SYSTEM (171 NIS2 + 77 CER + 25 Det.333017 + 9 Det.164179 + 5 Ambiti). Retrieval verificato (query "preallarme CSIRT" → Direttiva NIS2; "settori alta criticità" → Ambiti Allegati I/II). - **Backup**: `/root/backup_pre_v170_20260529_165447.sql`. ### ⚠️ Azione consigliata residua (richiede conferma — recreate container) **Qdrant IP drift**: il container `nis2-qdrant` non ha IP statico in `docker-compose.yml` ed è driftato da `172.21.0.5` → `172.21.0.3`. Fallback in `VectorService.php` aggiornato a `.3` (live). Per evitare ricorrenze: in `docker/docker-compose.yml` assegnare `ipv4_address` statico al servizio `qdrant` e allineare `QDRANT_URL`, poi `docker compose up -d --force-recreate qdrant app`. NB: nota anche che `kb_uploaded_documents` non esiste su questo DB (migrazioni KB 012-014 non applicate qui) → il tracking MySQL dei doc KB è saltato (best-effort), ma la ricerca RAG legge da Qdrant e funziona. --- Integrazione del materiale di analisi (mockup HTML + testi normativi PDF) nel prodotto NIS2 Agile. Tutto il codice è scritto e lint-clean (`php -l` / `node --check`). **Le migrazioni DB e l'ingest KB NON sono ancora stati eseguiti** (questo container dev non raggiunge il DB/Qdrant di produzione). --- ## Cosa è stato implementato ### Fase 1 — Asset Relevance Scoring NIS2 (GV.OC-04) Metodologia di scoring 0-100 su 6 criteri pesati, soglia rilevanza ≥40, classi critico/alto/medio/basso/trascurabile. - `docs/sql/020_asset_relevance.sql` — colonne `relevance_score`, `relevance_criteria` (JSON), `relevance_class`, `is_nis2_relevant`, `relevance_assessed_at/by` + indice - `application/services/AssetScoringService.php` — logica pura + griglia ufficiale in costante - `application/controllers/AssetController.php` — `GET scoringGrid`, `POST {id}/score`, `GET relevantSystems`, filtro `nis2_relevant` - `public/assets.html` — colonna "Rilevanza NIS2" + modale di valutazione a 6 criteri con anteprima punteggio - `public/js/api.js` — `getScoringGrid`, `scoreAsset`, `listRelevantSystems`, `deleteAsset` - Verifica: esempio ERP del mockup = **91/100 → critico** ✓ ### Fase 2 — Tassonomia incidenti (Determina ACN 164179/2025) - `docs/sql/021_incident_nis2_taxonomy.sql` — colonne `nis2_incident_type` ENUM(IS-1..IS-4), `entity_obligation` ENUM(essential/important) - `application/controllers/IncidentController.php` — `create()` deriva il regime (Allegato 3 essenziali / Allegato 4 importanti) e blocca IS-4 per gli importanti - `application/services/AIService.php` — `classifyIncident()` cita le fonti e restituisce `nis2_incident_type` + `notification_basis` ### Fase 3 — Post-Incident Review + metriche TTD/TTC/TTR - `docs/sql/022_incident_metrics_pir.sql` — timestamp di fase (`triaged_at`, `contained_at`, `eradicated_at`, `recovered_at`) + tabella `incident_pir` (5-Whys, metriche, costo, lesson learned) - `IncidentController.php` — `GET {id}/metrics`, `GET {id}/pir`, `POST {id}/pir`; `update()` timbra i timestamp di fase al cambio stato - `public/js/api.js` — `getIncidentMetrics`, `getIncidentPir`, `saveIncidentPir`, `aiClassifyIncident` ### Fase 4 — Layer mapping NIST CSF 2.0 (reference, non invasivo) - `application/controllers/AuditController.php` — `GET nistCsfMapping`: 43 controlli NIST CSF 2.0 → NIS2 Art.21/23 → modulo. **Nessuna migrazione**, nessuna modifica all'assessment esistente. ### Fonti normative certe (richiesta esplicita: AI + help citano fonti certe) - `application/config/nis2_sources.php` — **registry canonico citabile** (Dir. 2022/2555, Dir. 2022/2557, D.Lgs. 138/2024, Determina ACN 164179/2025, Determina ACN 333017/2025, Ambiti NIS2) - `application/services/AIService.php` — `authoritativeSourcesBlock()` iniettato nei system prompt (default, RAG, classifyIncident): impone di citare le fonti e vieta riferimenti inventati - `public/js/help.js` — riferimenti normativi italiani aggiunti a incidenti e asset - `scripts/ingest-nis2-sources.php` — indicizza i 5 PDF normativi nella KB (Qdrant `nis2_kb`, scope SYSTEM) per il grounding RAG ### Report - `ReportService::generateRelevantSystemsRegister()` + `GET /api/audit/relevantSystemsRegister` — registro formale "Sistemi Rilevanti NIS2" (GV.OC-04) HTML stampabile con citazioni. --- ## Deploy su Hetzner (da eseguire, in ordine — CHIEDERE CONFERMA UTENTE) ```bash # 0) Backup pre-migrazione ssh -i docs/credentials/hetzner_key root@135.181.149.254 mysqldump nis2_agile_db assets incidents > /root/backup_pre_v170_$(date +%F).sql # 1) Deploy codice (bind mount: PHP live; verificare path reale di produzione) cd /var/www/nis2-agile && git pull origin main # dopo push su Gitea # 2) Migrazioni DB (additive, idempotenti). NB: usare host MySQL, non docker exec nis2-db mysql -h localhost nis2_agile_db -e "source /var/www/nis2-agile/docs/sql/020_asset_relevance.sql" mysql -h localhost nis2_agile_db -e "source /var/www/nis2-agile/docs/sql/021_incident_nis2_taxonomy.sql" mysql -h localhost nis2_agile_db -e "source /var/www/nis2-agile/docs/sql/022_incident_metrics_pir.sql" # 3) Ingest fonti normative nella KB (richiede Qdrant + Voyage attivi) docker exec -i nis2-app php /var/www/nis2-agile/scripts/ingest-nis2-sources.php --dry-run # verifica docker exec -i nis2-app php /var/www/nis2-agile/scripts/ingest-nis2-sources.php # esegui # 4) Smoke test curl -s https://nis2.agile.software/api/assets/scoringGrid -H "Authorization: Bearer " | head ``` ### Rollback Ogni `.sql` contiene la sezione ROLLBACK in coda. Per la KB: cancellare i chunk scope=SYSTEM/source=normativa o ripristinare la collection. --- ## Note - **Phase 4** è volutamente reference-only (nessuna tabella/migrazione) per non toccare l'assessment Art.21 consolidato. - I PDF normativi restano in `docs/nis2/*.pdf` come libreria sorgente referenziata da `nis2_sources.php`. - I file `*copy.html` e `incidente_r00/` dei mockup non sono stati usati (duplicati/superati).