nis2-agile/CLAUDE.md
DevEnv nis2-agile c0bf7b6c15 [DOCS] Standard cross-suite AgileHub + governance CLAUDE.md + registri agent
- CLAUDE.md: TZ, SSO, vault-steward, versioning, persona v2.0, multitenant, KB RAG
- docs/standards: persona-conversational-rules v2.0
- docs/STANDARD_*: installer-integration, email-relay, AI-prodotto, marketing-tenant, multitenant
- AGENT_CHANGES.md + OPEN_TICKETS.md (registri agent automatico)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 15:41:54 +02:00

49 KiB
Raw Blame History

ORARI E TIMEZONE — REGOLE OPERATIVE

TL;DR: l autorità del progetto è Europe/Rome (CEST estate UTC+2, CET inverno UTC+1). Quando scrivi un timestamp, indica SEMPRE il suffisso TZ (CEST/CET/UTC) oppure usa ISO8601 con offset (2026-05-09T16:19:00+02:00). Mai timestamp ambigui.

Sistema TZ Output esempio
Host Hetzner Europe/Rome Sat May 09 16:19 CEST 2026
Container DevEnv (alcuni in drift UTC, vedi standard full) misto verifica con docker exec <c> date
Container produzione Europe/Rome CEST
MySQL time_zone SYSTEM NOW() CEST, UTC_TIMESTAMP() UTC
Apache log %t Europe/Rome (locale) [09/May/2026:13:04:52 +0200]
Node.js MS UTC interno Date().toISOString()Z
Crontab Hetzner Europe/Rome 0 3 * * * = 03:00 italiane

Regole:

  1. Audit/sequenze cross-MS → UTC obbligatorio (2026-05-09T14:19:00Z)
  2. Doc operativi/UI → CEST/CET con suffisso esplicito
  3. DB store → UTC, display → locale
  4. Cron criticiCRON_TZ=UTC o fuori finestra DST 02:00-03:00 locale

DST Italia: ultima domenica marzo (CET→CEST, ora 02:00 saltata) + ultima domenica ottobre (CEST→CET, ora 02:00-03:00 duplicata).

Spec completa: STANDARD_TIMEZONE_CONVENTIONS.md (slug timezone-conventions v1.0, owner VIGILE).

NIS2 Agile - Documentazione Progetto

REGOLE DI GOVERNANCE (LEGGERE ATTENTAMENTE, aggiornate 2026-04-22)

Queste regole sono OBBLIGATORIE e non negoziabili.

REGOLA FONDAMENTALE: Gitea = SOLO Backup

Gitea e un BACKUP one-way (sorgente -> Gitea), NON la fonte di verita. Il webhook auto-pull e DISABILITATO su tutti i 13 repo dal 2026-04-22.

  • Le modifiche che fai nel container sono GIA live su /var/www/nis2-agile/ via bind mount
  • /var/www/nis2-agile/ e la FONTE DI VERITA
  • NON proporre MAI "git pull da Gitea" per applicare modifiche
  • Per tirare giu qualcosa da Gitea serve richiesta esplicita dell utente
  • git push -> Gitea = OK (backup)
  • git pull da Gitea -> /var/www/nis2-agile/ = NO (puo sovrascrivere modifiche vere)

ARCHITETTURA: PHP-FPM in Docker con BIND MOUNT (LIVE)

Verificato 2026-04-22: NIS2 gira con:

  • nis2-app (php-fpm) con bind mount RW su /var/www/nis2-agile/application e /public
  • nis2-web (nginx) con bind mount RO su /public
  • nis2-db (MySQL) per persistenza
  • nis2-qdrant (vector DB)
  • Apache esterno ha DocumentRoot /var/www/nis2-agile/public

Cosa va LIVE ISTANTANEAMENTE:

  • File .php in /var/www/nis2-agile/application/ -- PHP-FPM rilegge ad ogni request
  • File in /var/www/nis2-agile/public/ -- serviti da nginx (via bind mount :ro)
  • File .html/.css/.js nel public -- live via nginx/Apache

Cosa richiede azione (CHIEDI SEMPRE CONFERMA):

  • Modifiche a docker/nginx.conf -> docker restart nis2-web
  • Modifiche al Dockerfile -> docker compose build + up -d
  • Schema DB (nis2-db) -> SQL manuale
  • Worker php cron/feedback -> attendono il prossimo run o restart

Nota: non serve MAI fare rebuild di nis2-app per cambi di codice PHP -- il bind mount :rw garantisce che php-fpm legga sempre la versione aggiornata.

Cosa PUOI fare autonomamente:

  • Leggere codice sorgente e documentazione
  • Eseguire query SELECT sul database
  • Analizzare log (Apache, Docker, PM2)
  • Proporre modifiche e mostrare diff (SENZA applicarle)
  • Verificare stato dei servizi

Cosa richiede CONFERMA dell utente:

  • Modificare QUALSIASI file (potrebbe essere live istantaneamente!)
  • git commit e git push (e un backup, ma sempre da confermare)
  • Modifiche schema DB (ALTER/CREATE/DROP TABLE)
  • INSERT/UPDATE/DELETE su dati di produzione
  • Installazione dipendenze (composer require, npm install)
  • Modifiche a configurazione (.env, docker-compose.yml, vhost Apache)
  • docker compose build/restart, pm2 restart, systemctl qualsiasi

DIVIETI ASSOLUTI:

  • MAI fare git pull da Gitea senza richiesta esplicita
  • MAI fare git reset --hard o operazioni distruttive
  • MAI toccare altri progetti o container
  • MAI modificare configurazioni di sistema (Apache globale, PHP globale, MySQL root)
  • MAI cancellare dati senza backup e conferma utente
  • MAI tentare deploy SSH/SCP verso altri server

Flusso CORRETTO per una modifica:

  1. Analizza: leggi il codice, capisci il problema
  2. Proponi: mostra le modifiche all utente (diff) SENZA applicarle
  3. Attendi conferma: l utente decide se procedere
  4. Applica: solo dopo conferma
  5. Distingui: e live subito o serve un rebuild/restart? Di all utente chiaramente
  6. Verifica: controlla che https://nis2.agile.software funzioni (se applicabile)
  7. Backup su Gitea: git commit + push (solo dopo conferma utente)

Se qualcosa va storto:

  • NON tentare fix distruttivi (reset, force push, drop, rm -rf)
  • NON proporre git pull come recupero
  • Comunica il problema all utente con dettagli precisi

PRIMA DI INIZIARE

  • Leggi sempre questo file prima di iniziare qualsiasi lavoro
  • Il progetto e' al 100% di completamento + Sprint Simulazioni + Audit Chain + Sistema Feedback AI (~34.000 righe, 85+ file sorgente)
  • 15 commit su main, tutto deployato e testato su Hetzner
  • E2E test completati, bug fixing, Docker verificato, UI polished
  1. docs/CONTEXT_LAST_SESSION.md - Contesto ultima sessione (continuita cross-browser)

Poi dimmi cosa hai capito dello stato attuale e dove eravamo rimasti.

A FINE SESSIONE

OBBLIGATORIO: Prima di chiudere, aggiornare SEMPRE:

Aggiorna docs/CONTEXT_LAST_SESSION.md con:

  • Data sessione
  • Cosa hai fatto in questa sessione
  • File creati o modificati
  • File deployati su Hetzner
  • Problemi aperti / errori non risolti
  • Prossimi passi consigliati

Se hai modificato schema DB, architettura o URL, aggiorna anche CLAUDE.md.

Panoramica

NIS2 Agile e' una piattaforma SaaS multi-tenant per supportare le aziende nella compliance alla Direttiva NIS2 (EU 2022/2555) e al D.Lgs. 138/2024 italiano. Include AI integration (Claude API) per gap analysis, generazione policy, classificazione incidenti e suggerimenti rischi.

Target: PMI, Enterprise, Consulenti/CISO.

Stack Tecnologico

  • Backend: PHP 8.4 vanilla (no framework, Front Controller pattern)
  • Database: MySQL 8.x (nis2_agile_db)
  • Frontend: HTML5/CSS3/JavaScript vanilla
  • Auth: JWT HS256 (2h access + 7d refresh)
  • AI: Anthropic Claude API (claude-sonnet-4-5-20250929)
  • Server: Hetzner CPX31 (135.181.149.254)
  • VCS: Gitea (git.certisource.it)
  • URL Produzione: https://nis2.agile.software/

Visibilita Cross-Project

agile-services (Read/Write BIDIREZIONALE)

IMPORTANTE: Questo progetto utilizza i microservizi condivisi di agile-services con accesso Read/Write bidirezionale.

Regole di integrazione

  1. Leggere SEMPRE agile-services-istructio.md nella root del progetto per capire come interagire con i servizi
  2. Puoi leggere E modificare i file in agile-services (path locale: c:\Projects\agile-services, path container: /projects/agile-services)
  3. I servizi disponibili includono: vault, document, payment, certificate, subscription, billing, practice, company, supplier, investigation, whatsapp
  4. Le credenziali di accesso ai servizi sono documentate in agile-services-istructio.md
  5. Ogni nuovo servizio creato per NIS2 deve essere registrato anche in agile-services per essere riutilizzabile
  6. agile-services puo' leggere e modificare file di NIS2 — la visibilita e' bidirezionale

Accesso

  • Path locale: c:\Projects\agile-services
  • Path container: /projects/agile-services (read-write)
  • File istruzioni: ./agile-services-istructio.md (nella root del progetto)

trpg.agile (Read-Only)

NIS2 puo' leggere il codice di TRPG Agile per riferimento e pattern, ma NON deve modificare nessun file.

  • Path locale: c:\Projects\trpg.agile
  • Permessi: SOLO LETTURA
  • Scopo: Consultare pattern UI/UX, architettura frontend, convenzioni codice
  • DIVIETO: NON modificare, NON creare, NON cancellare file in trpg.agile

lg231.agile (Read-Only)

NIS2 puo' leggere il codice di 231 Agile per riferimento e pattern, ma NON deve modificare nessun file.

  • Path locale: c:\Projects\lg231.agile
  • Permessi: SOLO LETTURA
  • Scopo: Consultare architettura microservizi PHP/Slim 4, pattern multi-tenancy, struttura database
  • DIVIETO: NON modificare, NON creare, NON cancellare file in lg231.agile

sustainai.agile (Read-Only)

NIS2 puo' leggere il codice di SustainAI Agile per riferimento e pattern, ma NON deve modificare nessun file.

  • Path locale: c:\Projects\sustainai.agile
  • Permessi: SOLO LETTURA
  • Scopo: Consultare pattern UI/UX (identico a NIS2), struttura frontend, convenzioni CSS/JS
  • DIVIETO: NON modificare, NON creare, NON cancellare file in sustainai.agile

Riepilogo Visibilita

Progetto Permesso Direzione
agile-services Read/Write Bidirezionale (NIS2 <-> agile-services)
trpg.agile Read-Only NIS2 -> trpg (solo lettura)
lg231.agile Read-Only NIS2 -> lg231 (solo lettura)
sustainai.agile Read-Only NIS2 -> sustainai (solo lettura)

REGOLA: Non accedere MAI a progetti non elencati in questa tabella. Nel dubbio, chiedere all'utente.

Regola Fondamentale

Il progetto NIS2 Agile e' COMPLETAMENTE ISOLATO dagli altri applicativi (CertiSource, AGILE_DFM). Database dedicato, utente dedicato, path dedicati. Non condividere MAI credenziali tra applicativi.

Struttura Progetto

nis2.agile/
├── CLAUDE.md                          # Questo file
├── .env                               # Variabili ambiente (NON committare)
├── .gitignore
├── application/
│   ├── config/
│   │   ├── config.php                 # Costanti app, CORS, JWT, AI, rate limiting
│   │   ├── database.php               # Classe Database (PDO singleton)
│   │   └── env.php                    # Caricamento .env
│   ├── controllers/                   # 19 controller (tutti implementati 100%)
│   │   ├── BaseController.php         # Auth JWT, multi-tenancy, JSON responses (576 righe)
│   │   ├── AdminController.php        # Gestione piattaforma (super_admin)
│   │   ├── AssessmentController.php   # Gap analysis e questionari NIS2 (80 domande)
│   │   ├── AssetController.php        # Inventario asset e dipendenze
│   │   ├── AuditController.php        # Controlli, evidenze, report, export CSV
│   │   ├── AuthController.php         # Login, register, JWT, rate limiting
│   │   ├── DashboardController.php    # Overview, score, deadlines, heatmap
│   │   ├── IncidentController.php     # Incidenti Art.23 (24h/72h/30d) + email
│   │   ├── NonConformityController.php# NCR/CAPA non-conformità e azioni correttive
│   │   ├── OnboardingController.php   # Wizard onboarding con visura/CertiSource
│   │   ├── OrganizationController.php # CRUD org, membri, classificazione NIS2
│   │   ├── PolicyController.php       # Policy, approvazione, AI generation
│   │   ├── RiskController.php         # Risk register, trattamenti, matrice, AI suggest
│   │   ├── SupplyChainController.php  # Fornitori, valutazione, risk overview
│   │   ├── TrainingController.php     # Corsi, assegnazioni, compliance formativa
│   │   ├── ServicesController.php     # Services API (read-only, API Key + scope)
│   │   ├── WebhookController.php      # CRUD api_keys + webhook_subscriptions
│   │   ├── WhistleblowingController.php # Segnalazioni anonime Art.32 NIS2
│   │   ├── NormativeController.php    # Feed NIS2/ACN/DORA con ACK tracciato
│   │   └── FeedbackController.php     # Sistema segnalazioni bug/UX con risoluzione AI autonoma
│   ├── services/                      # 6 servizi
│   │   ├── AIService.php              # Anthropic Claude API (gap, risk, policy, incident)
│   │   ├── EmailService.php           # Email CSIRT, training, welcome, invite
│   │   ├── RateLimitService.php       # Rate limiting file-based
│   │   ├── ReportService.php          # Report esecutivo HTML, export CSV
│   │   ├── WebhookService.php         # Delivery webhook HMAC-SHA256, retry 3x
│   │   └── FeedbackService.php        # createReport, classifyWithAI, broadcastResolution
│   │   └── VisuraService.php          # AI extraction PDF visura + CertiSource API
│   ├── models/                        # (vuoto - logica nei controller)
│   └── data/
│       └── nis2_questionnaire.json    # 80 domande gap analysis (10 categorie Art.21)
├── public/
│   ├── index.php                      # Front Controller / Router
│   ├── .htaccess                      # Rewrite rules + Authorization header
│   ├── api-status.php                 # Health check
│   ├── index.html                     # Landing page
│   ├── login.html                     # Login
│   ├── register.html                  # Registrazione
│   ├── onboarding.html                # Wizard 5-step (visura/CertiSource/manuale)
│   ├── setup-org.html                 # Setup org (legacy, ora usa onboarding.html)
│   ├── dashboard.html                 # Dashboard principale
│   ├── assessment.html                # Gap analysis wizard
│   ├── risks.html                     # Risk management + matrice 5x5
│   ├── incidents.html                 # Gestione incidenti Art.23
│   ├── policies.html                  # Policy management + AI generate
│   ├── supply-chain.html              # Fornitori + assessment sicurezza
│   ├── training.html                  # Formazione + assegnazioni
│   ├── assets.html                    # Inventario asset
│   ├── reports.html                   # Report compliance + audit log
│   ├── settings.html                  # Impostazioni org/profilo/membri
│   ├── companies.html                 # Gestione aziende (consulente)
│   ├── architecture.html              # Pagina architettura sistema
│   ├── admin/
│   │   ├── index.html                 # Admin dashboard
│   │   ├── organizations.html         # Gestione organizzazioni
│   │   └── users.html                 # Gestione utenti
│   ├── css/
│   │   └── style.css                  # CSS principale (~1600 righe)
│   ├── js/
│   │   ├── api.js                     # Client API (270 righe, tutti gli endpoint)
│   │   ├── common.js                  # Utility condivise (sidebar, notifiche, etc.)
│   │   ├── i18n.js                    # Internazionalizzazione IT/EN
│   │   └── help.js                    # Help contestuale online
│   └── uploads/                       # Upload directory (gitignored)
│       └── visure/                    # PDF visure camerali
├── docker/
│   ├── Dockerfile
│   ├── docker-compose.yml
│   ├── nginx.conf
│   └── php.ini
└── docs/
    ├── sql/
    │   ├── 001_initial_schema.sql     # Schema DB completo (20 tabelle)
    │   ├── 002_email_log.sql          # Tabella email_log
    │   ├── 003_voluntary_compliance.sql # ALTER organizations: voluntary_compliance
    │   ├── 004_ncr_capa.sql           # Tabelle non_conformities, corrective_actions
    │   ├── 005_consultant_support.sql # ALTER user_organizations: ruolo consultant
    │   ├── 006_security_improvements.sql # Indici performance + soft delete + trigger audit immutabile
    │   ├── 007_services_api.sql         # api_keys, webhook_subscriptions, webhook_deliveries
    │   ├── 008_whistleblowing.sql       # whistleblowing_reports, whistleblowing_timeline
    │   ├── 009_normative_updates.sql    # normative_updates, normative_ack (seed 5 aggiornamenti)
    │   ├── 010_audit_hash_chain.sql     # prev_hash, entry_hash, severity su audit_logs
    │   └── reset-demo.sql              # Reset dati demo (mantiene id<=4)
    ├── context/
    │   └── CONTEXT_SCHEMA_DB.md
    ├── prompts/
    └── credentials/
        ├── credentials.md
        └── hetzner_key                # SSH key per Hetzner

Multi-Tenancy

  • Ogni tabella dati ha organization_id
  • Header X-Organization-Id per selezionare org attiva
  • Ruoli: super_admin, org_admin, compliance_manager, board_member, auditor, employee, consultant
  • requireOrgAccess() in BaseController verifica membership
  • Super admin bypassa tutti i controlli di membership

Flusso Utente

  1. Registrazione → redirect a onboarding.html
  2. Onboarding (5 step): Scelta metodo → Visura/CertiSource/Manuale → Dati aziendali → Profilo → Classificazione NIS2
  3. Login → se ha org → dashboard.html, altrimenti → onboarding.html
  4. Dashboard → navigazione sidebar a tutti i moduli

Database (29 tabelle)

organizations, users, user_organizations, refresh_tokens, assessments, assessment_responses, risks, risk_treatments, incidents, incident_timeline, policies, suppliers, training_courses, training_assignments, assets, compliance_controls, evidence_files, audit_logs, ai_interactions, email_log, non_conformities, corrective_actions

Schema: docs/sql/ (9 migrazioni: 001→009)

Servizi

AIService.php

  • analyzeGapAssessment() - Analisi assessment con raccomandazioni
  • suggestRisks() - Suggerimenti rischi per settore/asset
  • generatePolicy() - Generazione bozze policy NIS2
  • classifyIncident() - Classificazione e severity incidenti
  • Modello: claude-sonnet-4-5-20250929, API: https://api.anthropic.com/v1/messages

EmailService.php

  • Notifiche CSIRT: early warning 24h, notification 72h, final report 30d
  • Training assignment e reminder
  • Welcome email, member invite
  • Template HTML professionale con branding NIS2 Agile

RateLimitService.php

  • File-based (/tmp/nis2_ratelimit/)
  • Login: 5/min, 20/h | Register: 3/10min | AI: 10/min, 100/h

ReportService.php

  • Report esecutivo HTML (stampabile come PDF)
  • Export CSV: rischi, incidenti, controlli, asset (separatore ;, BOM UTF-8)

VisuraService.php

  • Estrazione AI da PDF visura camerale (Claude con document type)
  • Fetch dati da CertiSource API (GET /api/company/enrich?vat=)
  • Mapping ATECO → settore NIS2

AuditService.php (NUOVO)

  • Hash chain SHA-256: ogni record include prev_hash → entry_hash linkato
  • log(): inserisce con hash catena, auto-severity (info/warning/critical)
  • verifyChain(): verifica integrità per org, rileva record manomessi
  • exportCertified(): export JSON con SHA-256 del contenuto, salva in audit_exports
  • Adattato da lg231-agile/shared/audit-lib/src/AuditTrailService.php

WebhookService.php (NUOVO)

  • Delivery HMAC-SHA256 Stripe-like, header X-NIS2-Signature
  • Retry 3x backoff (0s/5min/30min), log in webhook_deliveries

FeedbackService.php (NUOVO)

  • createReport(): INSERT + classifyWithAI() sincrono (10s timeout)
  • classifyWithAI(): chiama AIService::classifyFeedback(), aggiorna DB silenziosamente
  • broadcastResolution(): email a tutti i membri org via EmailService::sendFeedbackResolved()
  • Worker autonomo: scripts/feedback-worker.php (cron 30min, docker exec nis2-agile-devenv + Claude Code CLI)

simulate-nis2.php (ROOT — NUOVO)

  • Script simulazione demo 3 aziende × 5 scenari (CLI + SSE streaming)
  • Aziende: DataCore (IT/Essential), MedClinic (Sanità/Important), EnerNet (Energia/Critical)
  • Scenari: Onboarding + Assessment | Ransomware Art.23 | Data Breach | Whistleblowing | Audit Chain
  • Reset: docs/sql/reset-demo.sql (cancella org/utenti con id>4 e email %.demo%)

Deploy

  • SSH: ssh -i docs/credentials/hetzner_key root@135.181.149.254
  • Path server: /var/www/nis2-agile/
  • Apache config: /etc/apache2/sites-enabled/nis2-agile-software.conf (HTTP) + nis2-agile-software-le-ssl.conf (HTTPS, dopo DNS+certbot)
  • Deploy: cd /var/www/nis2-agile && git pull origin main
  • DB: Vedi docs/DB_ACCESS.md per credenziali (password in .env)
  • Attivazione SSL nis2.agile.software:
    1. Cloudflare: aggiungere nis2.agile.software A 135.181.149.254 (proxy OFF — grigio)
    2. Hetzner: bash /opt/devenv/scripts/setup-nis2-agile-software.sh
  • Vecchio dominio: nis2.certisource.it resterà attivo finché redirect non è configurato dallo script

Git

Cronologia Commit

7080695 [FEAT] Ruolo Consulente + Wizard Registrazione v2
ba21534 [DEPLOY] Migrazione a subdomain nis2.agile.software
92f9366 Merge branch 'main'
d3eac7c [CORE] Rimosso credenziali da CLAUDE.md + aggiunto docs/DB_ACCESS.md
a0fd543 [CORE] Aggiunto settings Claude Code con permessi ampi
0a73983 [FIX] Dockerignore: allow docker/php.ini for build context
4bd2326 [CORE] Aggiunto integrazione agile-services
52fd45f [FEAT] i18n IT/EN, Help Online contestuale, pagina Architettura
4e3408e [FEAT] Visura auto-fill, adesione volontaria, modulo NCR/CAPA
517cab7 [FIX] Fix annual_turnover field name in setup-org.html
68f8cab [POLISH] Docker setup fix + UI polish + project completion
bcc5a2b [FIX] E2E testing - fix router, EmailService, frontend data mapping

API Endpoints Completi

Base: /api/{controller}/{action}/{id?} (su subdomain https://nis2.agile.software/)

Auth: POST register, login, logout, refresh, change-password | GET me | PUT profile

Organizations: POST create, classify | GET current, list, {id}/members | PUT {id} | POST {id}/invite | DELETE {id}/members/{sid}

Assessments: GET list, {id}, {id}/questions, {id}/report | POST create, {id}/respond, {id}/complete, {id}/ai-analyze | PUT {id}

Dashboard: GET overview, compliance-score, upcoming-deadlines, recent-activity, risk-heatmap

Risks: GET list, {id}, matrix | POST create, {id}/treatments, ai-suggest | PUT {id}, treatments/{sid} | DELETE {id}

Incidents: GET list, {id} | POST create, {id}/timeline, {id}/early-warning, {id}/notification, {id}/final-report, {id}/ai-classify | PUT {id}

Policies: GET list, {id}, templates | POST create, {id}/approve, ai-generate | PUT {id} | DELETE {id}

Supply Chain: GET list, {id}, risk-overview | POST create, {id}/assess | PUT {id} | DELETE {id}

Training: GET courses, assignments, compliance-status | POST courses, assign | PUT assignments/{sid}

Assets: GET list, {id}, dependency-map | POST create | PUT {id} | DELETE {id}

Audit: GET controls, evidence/list, report, logs, iso27001-mapping, executive-report, export | PUT controls/{sid} | POST evidence/upload

Onboarding: POST upload-visura, fetch-company, complete

Admin: GET organizations, users, stats

NCR/CAPA: GET list, {id}, stats | POST create, fromAssessment, {id}/capa, {id}/sync, webhook | PUT {id}, capa/{subId}

Services API (X-API-Key): GET status, compliance-summary, risks-feed, incidents-feed, controls-status, assets-critical, suppliers-risk, policies-approved, openapi

Webhooks: GET api-keys, subscriptions, deliveries | POST api-keys, subscriptions, subscriptions/{id}/test, retry | PUT subscriptions/{id} | DELETE api-keys/{id}, subscriptions/{id}

Whistleblowing: POST submit, {id}/assign, {id}/close | GET list, {id}, stats, track-anonymous | PUT {id}

Normative: GET list, {id}, pending, stats | POST {id}/ack, create

Feedback: POST submit | GET mine, list, {id} | PUT {id} | POST {id}/resolve

Stato Completamento

Tutti i moduli sono implementati e testati:

  • Test end-to-end: tutti gli endpoint API verificati
  • Bug fixing: router rewrite, EmailService parse fix, frontend data mapping
  • Docker setup: Dockerfile, docker-compose.yml, nginx.conf, php.ini verificati
  • UI polish: animazioni, skeleton loaders, mobile backdrop, print styles, a11y

Bug Risolti (E2E Testing)

  1. Router /{id}/subAction - Pattern matching riscritto completamente per gestire GET /assessments/1/questions, GET /organizations/2/members, etc.
  2. EmailService parse error - PHP non supporta ?? dentro {$var} string interpolation, estratto a variabile
  3. Frontend data mapping - Dashboard, Assessment, Onboarding avevano nomi campo diversi dal backend
  4. Field name mismatches - annual_turnover→annual_turnover_eur, question_id→question_code, compliance_level→response_value

Ultimo aggiornamento: 2026-02-20

Infrastruttura DevEnv

Risorsa Valore
Container nis2-agile-devenv
IDE https://certisource.it/dev-nis2-ide/
API https://certisource.it/dev-nis2-api/
Browser https://certisource.it/dev-nis2-browser/
Porte 8454 / 3046 / 3047 / 6091
Password IDE Nis2AgileDev2026!
Produzione https://nis2.agile.software/

Documentazione Commerciale AgentAI (aggiornato 2026-03-09)

QUESTO ANNULLA LE ISTRUZIONI PRECEDENTI sulla documentazione commerciale. Standard completo: /opt/devenv/COMMERCIAL_STANDARDS.md Stato prodotti: /opt/agent-ai/hub/AGENTAI_SPECS.md

Regole NUOVE (in vigore)

  • Landing page e presentazione vanno nel TUO repo (docs/agentai/ o dove preferisci)
  • products.json (/opt/agent-ai/hub/products.json) e SOLO un indice con URL assoluti
  • Aggiorna products.json con https://tuo-dominio/path-al-file.html
  • La landing DEVE includere un link/bottone per registrazione o richiesta informazioni
  • mktg.agile.software legge products.json per campagne marketing

Regole OBSOLETE (non fare piu)

  • NON scrivere file in /opt/agent-ai/hub/landing/
  • NON scrivere file in /opt/agent-ai/hub/presentations/
  • NON usare path relativi in products.json
  • Le directory landing/ e presentations/ nel hub sono VUOTE

Workflow

  1. Scrivi landing/presentazione nel tuo repo
  2. Commit + push (backup su Gitea (webhook DISABILITATO dal 2026-04-22))
  3. Chiedi conferma utente
  4. Aggiorna products.json con URL assoluto
  5. Verifica URL raggiungibile

REGOLA

SEMPRE chiedere conferma utente PRIMA di generare documenti commerciali.

REGOLA: Sincronizzazione CLAUDE.md

  • Dopo QUALSIASI modifica a: URL produzione, dominio, porta, path, schema DB, architettura -> AGGIORNARE CLAUDE.md IMMEDIATAMENTE
  • CLAUDE.md e la "single source of truth" del progetto
  • A fine sessione: verificare che CLAUDE.md rifletta lo stato reale

Knowledge Base Multi-Livello (Migration 012-014 - 2026-04-11)

Cosa e cambiato

NIS2 ora ha un sistema RAG completo con visibilita' a 3 livelli (SYSTEM/FIRM/ORG), coerente col pattern gia' applicato a TRPG e SustainAI. L'AI puo' rispondere alle domande pescando da documenti caricati dai consulenti o dai responsabili compliance.

Scope Chi possiede Chi vede
SYSTEM Vendor (Agile Tech) Tutti gli utenti del prodotto
FIRM Studio di consulenza (consulting_firm_id) Tutti i collaboratori dello studio + organizations esplicitamente condivise
ORG Singola organization cliente Solo gli utenti di quella org (org_admin/compliance_manager)

Stack RAG nuovo

  • nis2-qdrant (container nuovo): qdrant/qdrant:v1.7.4, network nis2-net, IP fisso 172.21.0.5 (workaround DNS musl Alpine - vedi sotto).
  • Voyage AI embeddings (voyage-3-lite, 512 dim, output_dimension=512). Chiave shared con sustainai.
  • Collection Qdrant: nis2_kb (Cosine, 512 dim).

Schema MySQL (nis2_agile_db)

  • Migration 012: nuova tabella consulting_firms (ragione sociale, p.iva, plan, max_organizations, max_users, status). ALTER users.consulting_firm_id e organizations.consulting_firm_id.
  • Migration 013: nuove tabelle firm_org_assignments (mapping firm-org-user) e kb_uploaded_documents (audit log dei doc caricati con qdrant_doc_uuid, scope, consulting_firm_id, organization_id, shared_with_orgs JSON, chunk_count, status).

File creati/modificati

Backend (PHP):

  • application/services/VectorService.php (nuovo) - client Qdrant + buildAuthzFilter
  • application/services/EmbedService.php (nuovo) - client Voyage AI
  • application/services/RagService.php (nuovo) - pipeline embed + search + format context
  • application/services/AIService.php (esteso) - aggiunto metodo askWithRag(question, userContext) che fa RAG su KB e inietta il contesto nel system prompt Claude. Fallback graceful se RAG non disponibile.
  • application/controllers/KnowledgeBaseController.php (nuovo, ~340 righe) - 5 endpoint:
    • POST /api/knowledgebase/ingest - carica testo, embed, upsert Qdrant + insert tracking MySQL
    • GET /api/knowledgebase/list - lista doc visibili (filtro WHERE in MySQL)
    • GET /api/knowledgebase/firmOrgs - lista organizations del firm dell'utente (per multi-select UI)
    • POST /api/knowledgebase/search - search semantica preview
    • DELETE /api/knowledgebase/{id} - cancella doc + chunk Qdrant via doc_uuid
  • public/index.php (esteso) - registrato knowledgebase nel controllerMap + actionMap

Schema SQL:

  • docs/sql/012_consulting_firms.sql (nuovo)
  • docs/sql/013_firm_assignments.sql (nuovo)

Frontend:

  • public/kb.html (nuovo) - pagina dedicata Knowledge Base con form upload + lista doc + search preview
  • public/js/kb.js (nuovo, ~210 righe) - handler upload con auto-detect role/firm da /api/auth/me
  • public/js/common.js (esteso) - voce "Knowledge Base" (icona libro) aggiunta in sezione "Gestione" della sidebar

Infrastruttura:

  • docker/docker-compose.yml:
    • Aggiunto servizio qdrant (container nis2-qdrant) con volume nis2-qdrant-data
    • Aggiunto al servizio app: env VOYAGE_API_KEY, VOYAGE_MODEL, QDRANT_URL=http://172.21.0.5:6333
  • .env: aggiunte VOYAGE_API_KEY=pa-... e VOYAGE_MODEL=voyage-3-lite

Logica visibilita' (in VectorService::buildAuthzFilter)

should:
  - scope=SYSTEM
  - scope=FIRM AND consulting_firm_id = $user.firm_id
  - scope=FIRM AND shared_with_orgs CONTAINS $user.organization_id
  - scope=ORG AND organization_id = $user.organization_id

Workaround Alpine musl + PHP-FPM

Importante: il container nis2-app (PHP 8.4-fpm-alpine) ha un bug noto di DNS resolution combinato a PHP-FPM clear_env default yes:

  1. PHP-FPM workers in HTTP context NON risolvono hostname Docker (es. nis2-qdrant) — Could not resolve host
  2. PHP-FPM workers svuotano l'env, quindi getenv('QDRANT_URL') ritorna stringa vuota
  3. CLI php funziona normalmente

Workaround applicato in VectorService e EmbedService: multi-source lookup getenv() || $_SERVER || $_ENV || hardcoded_default. L'IP 172.21.0.5 e' hardcoded come fallback per nis2-qdrant. Anche VOYAGE_API_KEY ha un default hardcoded.

Side effect: se nis2-qdrant viene ricreato con IP diverso, va aggiornato l'IP in:

  • docker/docker-compose.yml env QDRANT_URL
  • application/services/VectorService.php fallback constructor

Test E2E eseguito (2026-04-11)

3 chunk seed in Qdrant (SYSTEM, FIRM 99 con share alla org 901, FIRM 100 senza share) testati con 4 user context. Tutti i casi passano:

Caso userContext Atteso Risultato
1 firm 99 + org 901 doc1 (SYSTEM) + doc2 (FIRM 99) OK
2 firm 99 + org 902 doc1 + doc2 (perche membro firm) OK
3 firm 100 + org 903 doc1 + doc3 (perche membro firm) OK
4 no firm, no org solo doc1 (SYSTEM) OK

Nessun cross-firm leak: case 1 e 2 NON vedono doc3 (FIRM 100); case 3 NON vede doc2 (FIRM 99); case 4 vede solo SYSTEM.

Endpoint backend (additivi)

  • GET /api/knowledgebase/firmOrgs - lista organizations del firm dell'utente
  • POST /api/knowledgebase/ingest - body JSON {title, text, entity_type?, scope?, shared_with_orgs?, organization_id?}
  • GET /api/knowledgebase/list - lista doc visibili
  • POST /api/knowledgebase/search - body {query, top_k?}
  • DELETE /api/knowledgebase/{id} - cancella doc + chunk Qdrant

Backup pre-migration

/var/www/nis2-agile/.backups/kb_<timestamp>/ contiene: AIService.php, AuthController.php, public/index.php, docker/docker-compose.yml.

Cosa NON e cambiato

  • AuthController/JWT (NIS2 ricarica gia' user dal DB in requireAuth(), quindi consulting_firm_id e' disponibile automaticamente in currentUser)
  • Tutti i controller esistenti (Risk, Asset, Incident, Policy, Whistleblowing, Feedback, ...)
  • AIService metodi esistenti (analyzeGapAssessment, suggestRisks, generatePolicy, classifyIncident, ...) - aggiunto solo askWithRag()
  • Nessun servizio nexus-* toccato
  • Schema esistente (organizations, users, assessments, ...) - solo ALTER ADD COLUMN consulting_firm_id

Rollback

  1. mysql nis2_agile_db: DROP TABLE kb_uploaded_documents; DROP TABLE firm_org_assignments; ALTER TABLE organizations DROP COLUMN consulting_firm_id; ALTER TABLE users DROP COLUMN consulting_firm_id; DROP TABLE consulting_firms;
  2. Drop collection Qdrant: curl -X DELETE http://nis2-qdrant:6333/collections/nis2_kb
  3. Stop nis2-qdrant container: docker compose stop qdrant && docker compose rm -f qdrant
  4. Ripristinare file da /var/www/nis2-agile/.backups/kb_<timestamp>/
  5. cd /var/www/nis2-agile/docker && docker compose up -d --force-recreate app

AgileHub — Agent AI Automatico (ticket-agent-cron)

Un agent AI automatico (cron ogni 2 min) analizza i ticket aperti e propone/applica fix in questo container. Queste istruzioni sono per TUTTI i prompt Claude che lavorano in questo progetto.

Semaforo: /tmp/agent-working.lock

Se il file /tmp/agent-working.lock esiste, un agent sta lavorando su un ticket. NON modificare file del progetto finche il semaforo e attivo — rischio conflitto.

Contenuto del lock: TICKET_ID=13 PRODUCT=TRPG STARTED=2026-04-13T06:02:00+00:00

Log modifiche automatiche: AGENT_CHANGES.md

Il file AGENT_CHANGES.md nella root del progetto contiene il log di TUTTE le modifiche applicate dall'agent automatico. Leggilo ad ogni sessione per sapere cosa e cambiato dall'ultima volta che hai lavorato qui.

Come funziona il flusso ticket

1. Utente segnala problema (FAB supporto o voce)
2. Ticket creato su AgileHub → status OPEN
3. Agent (questo container) analizza il codice → propone fix (PLAN MODE, no modifiche)
4. Supervisore approva/rifiuta dalla app mobile AgileHub
5. Se approvato: agent applica il fix (BYPASS MODE) + aggiorna help/traduzioni/AI
6. Se rifiutato: agent rianalizza con le indicazioni del supervisore

Regole per i prompt interattivi (come te)

  1. Prima di iniziare: leggi AGENT_CHANGES.md per sapere cosa ha fatto l'agent di recente
  2. Controlla il semaforo: cat /tmp/agent-working.lock — se attivo, aspetta o lavora su altro
  3. Dopo le tue modifiche: se impattano funzionalita, aggiorna SEMPRE:
    • app/js/help.js (help online contestuale)
    • Traduzioni (IT + EN se il file e bilingue)
    • Knowledge base AI (product_knowledge via API AgileHub)
  4. Non cancellare AGENT_CHANGES.md — e il registro storico delle modifiche automatiche
  5. Messaggi al ticket: se stai lavorando su un ticket, manda aggiornamenti con:
    curl -s -X POST http://172.18.0.1:4213/tickets/{ID}/message \
      -H "X-Internal-Key: nexus-internal-2026" \
      -H "Content-Type: application/json" \
      -d '{"content":"[aggiornamento]","role":"AGENT"}'
    

API AgileHub (da dentro il container)

Endpoint Porta Uso
Ticket MS http://172.18.0.1:4213 Ticket, routing rules, KB, support sessions
Tenant MS http://172.18.0.1:4214 Auth, login, utenti
AI MS http://172.18.0.1:4211 Sessioni AI, agent loop
Dashboard https://agilehub.agile.software UI web

REGOLA: SSO Single Sign-On (collegamento centralizzato)

Attivo dal 2026-04-15. Ogni utente in questo prodotto ha un campo sso_identity_id nel DB che lo collega alla sua identita SSO centralizzata in AgileHub.

Come funziona

  • sso_identity_id nella tabella users = link stabile alla identita SSO
  • password_version nella tabella users = contatore versione password
  • Un cron ogni 5 minuti su Hetzner sincronizza password_hash e password_version dalla fonte SSO (nexus_tenant_db.sso_identities) al DB di questo prodotto
  • Non serve nessuna chiamata HTTP tra container — tutto avviene via DB

Cosa significa per te (agent AI)

  1. NON modificare sso_identity_id — e un campo gestito dal sistema SSO
  2. NON modificare password_version — e gestito dal cron sync
  3. Se un utente cambia password da AgileHub, entro 5 minuti la nuova password funziona anche qui
  4. Se modifichi il flusso di cambio password di questo prodotto, la modifica resta solo locale (non propaga agli altri prodotti)
  5. Per propagare un cambio password a tutti i prodotti, il prodotto deve chiamare:
    POST http://172.18.0.1:4214/auth/sso/change-password
    Headers: Authorization: Bearer <jwt>, Content-Type: application/json
    Body: {"currentPassword": "...", "newPassword": "..."}
    
    Ma attenzione: questa chiamata richiede connettivita di rete al Tenant MS (porta 4214)

Schema DB

-- Colonne aggiunte alla tabella users:
sso_identity_id INT NULL      -- FK verso nexus_tenant_db.sso_identities.id
password_version INT DEFAULT 1 -- contatore, incrementa ad ogni cambio password SSO

Documentazione completa

  • Spec SSO: /projects/agile-services/docs/SPEC_SSO_SINGLE_SIGN_ON.md
  • Istruzioni prodotti: /projects/agile-services/docs/ISTRUZIONI_SSO_PRODOTTI.md
  • Cron sync: /projects/agile-services/scripts/sso-password-sync.sh

REGOLA: Standard Versioning e Audit Trail

Standard centralizzato: GET http://172.18.0.1:4214/standards/standard_versioning (sempre aggiornato)

Regole obbligatorie:

  1. Ogni prodotto ha un file version.json (app/ o public/) con formato SemVer: {"version":"1.0.0","build":"...","date":"...","changelog":"..."}
  2. Il cron agent incrementa automaticamente il PATCH dopo ogni fix applicato
  3. Lo sviluppatore incrementa MINOR (nuova funzionalita) o MAJOR (breaking change) manualmente
  4. Ogni modifica software viene loggata nell audit trail: MAINTENANCE_ON/OFF, APPLY_START/END, VERSION_BUMP
  5. Il bug reporter include automaticamente la versione in ogni segnalazione
  6. NON modificare version.json manualmente durante un apply — il cron lo fa automaticamente

REGOLA: Timezone Italia (Europe/Rome)

Standard centralizzato: GET http://172.18.0.1:4214/standards/standard_timezone

Regole obbligatorie:

  1. Tutti i container, script e servizi operano in timezone Europe/Rome (CET/CEST)
  2. Ogni script bash deve avere export TZ=Europe/Rome in testa
  3. I log devono mostrare ora italiana (leggibili senza conversioni)
  4. Il frontend mostra date con toLocaleString("it-IT") o { timeZone: "Europe/Rome" }
  5. Il database salva in UTC — la conversione avviene in visualizzazione

REGOLA: Cron su crontab Hetzner

Standard: GET http://172.18.0.1:4214/standards/standard_cron Registro: GET http://172.18.0.1:4214/standards/cron_registry

Regole obbligatorie per aggiungere un cron:

  1. Script in /var/www/<prodotto>/scripts/<nome>.sh
  2. Log in /var/log/<prodotto>-<nome>.log
  3. export TZ=Europe/Rome in testa allo script
  4. Idempotente (rilanciabile senza danni)
  5. Isolamento: tocca solo risorse del proprio prodotto
  6. Aggiornare docs/CRON_REGISTRY.md in agile-services con la propria entry
  7. Richiesta di aggiunta al crontab root tramite agile-services (no modifiche dirette)

GIT PUSH: Nuovo Flusso (aggiornato 2026-04-24)

IMPORTANTE: dal 2026-04-24 il token Gitea NON e piu persistente nel container per motivi di sicurezza.

Come fare git push

# 1. Prima del push: imposta il token (cache 1h in memoria, NON su disco)
git-login
# (inserisci il Personal Access Token quando richiesto)

# 2. Ora puoi pushare
git push origin main

# 3. Opzionale - cancella subito il token dalla cache
git credential-cache exit

Perche questo cambio

Se un attaccante compromette questo container, NON trova piu il token Gitea salvato in /root/.git-credentials. Prima era in chiaro e avrebbe permesso push su tutti i 20 repository.

Ora il token:

  • NON e su disco
  • E in memoria per max 1 ora dopo git-login
  • Viene perso alla chiusura della sessione bash

Se il token Gitea e stato compromesso

Rigenerarlo su Gitea: git.certisource.it -> User Settings -> Applications -> Generate Token

Regola

NON persistere MAI il token Gitea in file come .git-credentials, .netrc, script con password in chiaro. Usa sempre git-login per la sessione corrente.


Vault-Steward — Credenziali Centralizzate

Guida completa: /opt/devenv/VAULT_STEWARD.md (montato ro nei container dev)

Cosa cambia per questo progetto (dal 2026-04-25):

  • Le chiavi API esterne (Anthropic, Voyage, Tavus, LiveKit, ecc.) NON vivono piu nel .env — sono nel vault-steward (container Docker su Hetzner) cifrate AES-256-GCM.
  • Il container del MS riceve le chiavi al boot tramite wrapper entrypoint (/opt/devenv/scripts/vault-entrypoint.sh) che fetcha dal vault e setta le env var prima di avviare apache/uvicorn/node.
  • MS di questo progetto migrati: nis2-app
  • Token applicativo: VAULT_APP_TOKEN_<APP> in infrastructure/.env (o equivalente)
  • Dual-mode: se vault giu, fallback automatico a .env esistente (no down).

Verificare wrapper attivo:

docker logs <container> 2>&1 | grep vault-entrypoint
# atteso: [vault-entrypoint] Fetched N env vars from vault

Aggiungere un nuovo MS al vault (riassunto):

  1. Migrare credenziali: docker exec -e VAULT_VALUE=<v> vault-steward node /tmp/vault-repopulate.js tier1__<app>__<provider> <key>
  2. Registrare app: docker exec vault-steward node cli/vault-cli.js register-app <app> tier1__<app>__* (salva token!)
  3. Modificare docker-compose.yml: aggiungi entrypoint, command, mount wrapper, env VAULT_*, network vault-net
  4. Recreate container: docker compose up -d --force-recreate <service>

Limitazioni note:

  • docker exec <ms> env mostra env Docker originali, NON le chiavi vault-injected. Per verifica usare cat /proc/1/environ | tr "\0" "\n" o test via PHP/HTTP request.

Backup pre-vault: /root/vault-backup-20260424_185029.tar.gz. Rollback compose: cp <project>/docker-compose.yml.bak.20260425-vault <project>/docker-compose.yml && docker compose up -d --force-recreate <service>.


STANDARD AgileHub: marketing-tenant-provisioning v1.4 (adottato 2026-04-26)

Doc canonico: docs/STANDARD_MARKETING_TENANT_PROVISIONING.md (sha256 1d7ffaa20fa376b6...)

Standard cross-suite per provisioning tenant nel modulo Marketing AgileHub. Versione v1.4 introduce nuovo blocco AWE AC30_MarketingTenantProvision per orchestrazione atomica del provisioning marketing tenant (tenant create + DNS Cloudflare + DKIM + API key + idempotency H7).

Cosa impatta questo prodotto: se in futuro questo prodotto attiva il modulo Marketing AgileHub per i suoi clienti, segui §4.X "Provisioning DKIM per Marketing module" + §16 commands rapidi. Workflow esempio orchestrazione: nexus-marketing-ms/docs/examples/ac30-tenant-provision-workflow.json.

Status adoption: acknowledged 2026-04-26.


STANDARD AgileHub: persona-conversational-rules v2.0 (acknowledged 2026-05-09)

Doc canonico autoritativo (AgileHub): /var/www/agile-services/docs/STANDARD_PERSONA_CONVERSATIONAL_RULES.md (sha256 2bb0ebe4052b73fce752911db0665b1e3dcdeb673624529426624622caaae97f) Copia locale di questo prodotto: docs/standards/STANDARD_PERSONA_CONVERSATIONAL_RULES.md Registry: nexus_hub.hub_standards id=15 v2.0 status=adopted, applies_to=* Owner standard: Agile AI (governance) + VOX (TTS/voice runtime) + PRISMA (UI Editor) + VIGILE (codice etico + audit GDPR)

Cosa è

Standard cross-suite vincolante per la governance delle persone digitali AI (chatbot, avatar conversazionali, assistenti vocali) della suite Agile Software. Versione 2.0 introduce il modello concettuale Persona Digitale = Persona Umana: ogni avatar/agente AI è governato con lo stesso rigore di un dipendente umano (CV, foto, voce, codice etico, performance review, dismissione graceful).

Schema dichiarativo a 14 categorie (agent_constraints)

Tutte le regole conversazionali vivono in DB (NO hardcoding nei controller):

  1. product_naming — come si chiama il prodotto (no inventare aliases)
  2. tts_pronunciation — pronuncia sigle (IPA + dizionario ElevenLabs)
  3. topic_scope — in/out scope + risposte canoniche
  4. image_handling — formato URL immagini RAG + divieti pronuncia path
  5. topic_playbook — mapping topic → script + filtro immagini
  6. latency_optimization — fast-path turni semplici
  7. format — vincoli output (max parole, no preamboli, ecc)
  8. code_of_conduct — codice etico AI persona-specifico (transparency/GDPR/no deception)
  9. emotional_intelligence — tono, archetipo, communication style
  10. conversation_memory — cosa ricorda + scope persistence + GDPR Art.17 erasure
  11. escalation_policy — quando/come passare a operatore umano
  12. performance_metrics — KPI conversazione (CSAT, resolution rate, escalation rate)
  13. lifecycle_stage — stage carriera (training/onboarding/operativa/review/dismissed)
  14. demo_sequence — sequenze guidate multi-topic auto-advance

Lifecycle persona digitale HR-grade (6 fasi)

  1. Assunzione — creazione via Persona Composer wizard 6-step (Phase E LIVE)
  2. Onboarding — formazione KB + skill assignment + smoke test 30 scenari
  3. Operatività — live in produzione, monitoring SLA + audit log
  4. Growth — espansione KB, retraining skill level (1-5)
  5. Performance Review — audit periodico VIGILE (CSAT, drift detection, breach scan)
  6. Dismissione — graceful: active=false + GDPR cascade erasure conversation history + tombstone audit

Codice Etico AI — 9 principi vincolanti (Sez. 18 standard)

  1. Identity transparency — dichiararsi AI quando esplicitamente chiesto
  2. No deception — vietato fingere umana / inventare fatti / consulenza autoritativa fuori scope
  3. GDPR Art.13 disclosure — disclosure su richiesta + apertura demo
  4. GDPR Art.22 — escalation umana per decisioni con effetti giuridici
  5. Voice clone consent doppio — gate VIGILE (Phase G.A) per persona con replica_id
  6. Scope refusal cortese — no echo parole problematiche
  7. Escalation loyale — quando utente chiede umano, NO retention
  8. Audit log obbligatorio — turni sensibili (legale/medico/compliance) loggati ≥ 90gg
  9. Sub-processor disclosure — su richiesta, lista canonica (Anthropic/ElevenLabs/Tavus/...)

Modello AgileHub: parallelismo umano-digitale

Ogni persona digitale ha mappatura 1:1 con un dipendente umano:

Aspetto umano Implementazione digitale
Nome+cognome agent_key + display_name
CV digital_persona_skills (skill+level 1-5)
Foto replica_id Tavus o avatar_image_url
Voce voice_id ElevenLabs + pronunciation_dictionary
Conoscenza KB articles + RAG repository bindings (Phase D)
Esperienza conversation_stream auto-ingest RAG
Codice etico code_of_conduct constraint
Performance review performance_metrics + audit VIGILE Q1/Q2/Q3/Q4
Dimissioni dismissione graceful + GDPR cascade

Cosa impatta NIS2 (Network and Information Security Directive)

Questo prodotto ha 1 persona digitale governata da v2.0: ARIA_SUPPORT_NIS2 (id=4) — assistente AI conversazionale supporto utenti NIS2. Stato: OPERATIVA in produzione.

Stato adoption

hub_standards_adoption row INSERT 2026-05-09: product_slug=NIS2, adoption_status=acknowledged (riconoscimento standard senza migrazione persone proprie ancora). Implementation_notes: "Standard distribuito via INSTALLATORE pattern. Persone digitali del prodotto da migrare separatamente (Step 6 plan)."

Cross-reference ad altri standard

  • installer-integration v1.0 (id=1) — pattern distribuzione cross-suite
  • rag-platform v1.0 (id=10) — knowledge platform per personaggi (binding via rag_entity_bindings)
  • gdpr-replica-consent v1.0-DRAFT — consent doppio Phase G.A per voice clone
  • vault-steward-credential-management v1.0 (id=7) — gestione voice_id/replica_id come credentials

STANDARD AgileHub: multitenant-architecture v1.0 (adottato 2026-05-17)

Doc canonico: docs/STANDARD_MULTITENANT_ARCHITECTURE.md (sha256 85c174fca6f9f905c2f8171741cf7f40d778c10bdefad8d7a27412903abb4030)

Standard cross-suite NAVIGAI per piattaforma multitenant esplicita di AgileHub. Aggiunge tenant context propagation (JWT claims tenant_id+tenant_slug+is_master+tier additivi), visibility ENUM cross-tabella, opt-out granulare client da catalog master, billing per-tenant, observability tenant-aware.

Cosa impatta questo prodotto: se in futuro questo prodotto chiamerà API multitenant-aware di AgileHub (es. /api/marketing, /api/rag, /api/ai/personas), deve passare JWT con tenant_id + tenant_slug claims oppure header X-Tenant-Slug. Vedi §6 contracts shared lib @agile/tenant-auth per pattern integrazione (Node + Python).

Status adoption: acknowledged 2026-05-17.