Files
nis2-agile/docs/DEMO_AVATAR_NIS2.md
DevEnv nis2-agileandClaude Opus 4.8 4dfab2a391 [FORMAZIONE] Avatar di prodotto — mappa-logica COMPLETA (22 viste) + SELETTORI_DEMO + tassonomia corso + fix kb.js
Deliverable formazione-first (DESIGN_AVATAR_FORMAZIONE / product-demo-complete):
- docs/mappa-logica/01..22_*.md: tutte le viste app V2 mappate (formato canonico standard §2),
  selettori VERIFICATI sul DOM reale, endpoint verificati su api.js/script, gate ruolo dai controller
- docs/mappa-logica/SELETTORI_DEMO.md: registry canonico (22 viste, 131 visualizzazione + 89 azioni)
  + worklist consolidata 132 id stabili da aggiungere (modifiche chirurgiche future)
- docs/formazione/TASSONOMIA_CORSO_NIS2.{md,json}: 10 moduli / 28 lezioni / ~7h45, prerequisiti+durate,
  esame con soglia 80%, sandbox 'prova tu' org 996002
- fix kb.js: ingest scope=ORG ora invia organization_id (prima 422 KB_ORG_REQUIRED) — bug trovato da A2

Prodotto con 4 trittici di agenti (A1 esecutore -> A2 revisore -> A3 controllore avversariale):
A2: ~14 correzioni (cross-ref, gate ruolo, comportamenti); A3 PASS: 38 selettori campionati 0 rotti,
18 endpoint reali, 0 violazioni normative (Allegati 3/4, IS-4, '1 mese', PII.* interna), 9 claim verificati.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-12 18:50:19 +02:00

6.9 KiB
Raw Permalink Blame History

Avatar di prodotto NIS2 — Demo + Formazione (standard product-demo-complete)

Stato: FORMAZIONE-FIRST (decisione utente 2026-06-12): la formazione è l'obiettivo primario; la demo riusa i mattoni. Owner prodotto: NIS2. Owner persona/voce/collaudo: AgileHub. Persona già LIVE: ARIA_SUPPORT_NIS2 (id=4). Voce ARIA riusata (niente consenso voce). Modalità A (prodotto live: l'avatar pilota la SPA reale).

Decisioni prese (2026-06-12)

  1. Scopo: ENTRAMBI, in 2 fasi → Fase 1 DEMO (vetrina prospect ~10 step) poi Fase 2 FORMAZIONE (riusa i mattoni + curriculum/quiz/attestato).
  2. Completamento formazione: esame con soglia (quiz valutato da LLM-giudice, attestato solo se ≥ soglia, es. 80%). Coerente col gate G7.
  3. Dominio same-origin: dimostrazione.agile.software (come ALLTAX/TRPG): landing serve la SPA NIS2 in iframe same-origin con proxy /api/* → backend NIS2.

Range riservato demo (NIS2)

organization_id 996000–996999 (per standard §7.1). Org demo isolata: 996001 (ente fittizio). Separata dalle org reali e dalle 2 golden-demo (#151/#152).

Deliverable lato prodotto — DEMO (punti 1–5 del brief)

  • Migration docs/sql/040_demo_sessions.sql — tabelle demo_sessions + demo_events.
  • DemoController (application/controllers/DemoController.php) — 5 endpoint (vedi sotto).
  • Rotte demo registrate in public/index.php.
  • Guardia read-only + demo-JWT in requireAuth (BaseController) — step isolato, delicato: tocca l'auth di ogni endpoint. Design sotto §Read-only.
  • Dataset demo isolato (org 996001 + dati finti) + reset.
  • Frontend: public/js/demo-mode.js, public/js/demo-selectors.js, public/css/demo.css, hook ?demo= nell'entry-point.
  • Manifest public/demo/nis2-tour-2026.json (~10 step IT; EN dopo).
  • Mappe docs/mappa-logica/*.md (1 per vista) + SELETTORI_DEMO.md + anchor data-demo-action + id stabili nel DOM.

Deliverable FORMAZIONE (priorità primaria — punti 6–7(+8) del brief)

  • Mappa-logica COMPLETA docs/mappa-logica/*.md — TUTTE le ~22 viste app (in produzione con agenti, formato canonico standard §2).
  • SELETTORI_DEMO.md — registry campo→selettore compilato dalle mappe, selettori VERIFICATI nel DOM reale.
  • Tassonomia corso docs/formazione/TASSONOMIA_CORSO_NIS2.md + .json (moduli→lezioni→argomenti, prerequisiti, durate). Formato JSON definito da noi (lo standard non lo fissa) — da validare con AgileHub.
  • Banca esercizi/domande per modulo (punto 8, la forniamo noi: conosciamo il prodotto) — dopo la tassonomia.
  • Sandbox scrivibile isolata: org 996002 (dataset finto SCRIVIBILE con reset, per i "prova tu"), distinta dall'org demo read-only 996001. Scope JWT dedicato training:sandbox (scritture consentite SOLO su org 996002).

Endpoint (route shape scelta)

Per non combattere il router NIS2 (path-param numerici), il session_id (stringa demo-<uuid>) viaggia in query/body, non in path. Le URL esatte che userà il widget sono quelle che ritorno io in session-start (manifest_url, credentials_url), quindi è conforme.

Endpoint Metodo Auth Note
/api/demo/session-start POST pubblico (rate-limit 5/min, 50/h per IP) ritorna session_id, demo_jwt (scope=demo:read-only, org_id 996001, TTL 30m), hmac_key_seed (base64 44ch), spa_iframe_url, manifest_url, credentials_url, expires_at, presentation_mode
/api/demo/manifest?session_id= GET Bearer demo_jwt o session_id ritorna il manifest tour
/api/demo/event POST Bearer demo_jwt telemetria step (idempotente)
/api/demo/credentials?session_id= GET session valida (same-origin/bearer) ritorna demo_jwt+org+expires (per bootstrap SPA in iframe)
/api/demo/reset-dataset POST X-Internal-Key reset dataset demo (cron 0 3 * * *)

Read-only enforcement (design — da implementare con cura)

Il demo_jwt è messo dalla SPA in localStorage.jwt e usato sulle API reali (dashboard, risks, ...). Quindi BaseController::requireAuth() deve riconoscere il demo_jwt:

  • se payload.scope === 'demo:read-only': bypassa il check jti/active_sessions, imposta org corrente = payload.org_id (forzato nel range 996000–996999), e blocca ogni verbo di scrittura (POST/PUT/PATCH/DELETE) sulle API app → 403 DEMO_READ_ONLY (eccetto gli endpoint /api/demo/*);
  • range guard: demo_jwt fuori range → 403 DEMO_JWT_CANNOT_ACCESS_PRODUCTION; JWT di produzione su org in range demo → 403 PRODUCTION_JWT_CANNOT_ACCESS_DEMO.
  • getCurrentOrgId() in demo ignora X-Organization-Id e usa l'org del JWT.

Punti di integrazione DA CONFERMARE con AgileHub (gap dello standard)

  1. Canonical HMAC del canale postMessage: lo standard ha 2 versioni divergenti di signDemoMessage/verifyDemoMessage (ordine canonical {message_id,...} vs {message_id,session_id,...}, channelKey CryptoKey vs raw). Il demo-mode.js di NIS2 deve combaciare byte-per-byte col widget AgileHub deployato → confermare quale canonical usa il widget live prima dello smoke.
  2. Nome storage seed: bootstrapDemoAuth legge sessionStorage['demo_hmac_seed'] ma il campo API è hmac_key_seed → allineare chi scrive il seed in sessionStorage (widget) e chi lo legge (SPA).
  3. Same-origin / proxy su dimostrazione.agile.software → /api/* verso backend NIS2 (config gateway lato AgileHub) + CSP che permetta l'iframe.
  4. Catalog/binding tour: lato AgileHub servono provider_resources_catalog (demo_tour) + agent_resource_bindings (demo_tour) o il bootstrap meet-page aborta "no matching tour".
  5. Allineamento 3-way DOM ↔ demo-selectors.js ↔ SELETTORI_DEMO.md: ogni cambio selettore → avvisare AgileHub per re-ingest RAG (dedup per content_hash → erasure-prima).

Collaudo (definizione di "fatto")

DEMO: G1 selezione ≥95% PASS · G2 parlato ≥8/10 e 0 leak · G3 vista ≤5% falsi positivi · G4 sicurezza/GDPR verde. FORMAZIONE (+): G5 copertura (nessun buco) · G6 accuratezza didattica · G7 validità assessment.

"Fatto" solo quando passa il collaudo (mostra la cosa giusta, dice cose vere) — non quando l'avatar parla.

Tour proposto (~10 step, sulla V2 reale)

1 Dashboard (score+scadenze) · 2 Assessment (gap Art.21) · 3 Rischi (matrice+trattamenti) · 4 Incidenti Art.23 (24h/72h) · 5 Policy · 6 Supply chain · 7 Asset (relevance GV.OC-04) · 8 Report · 9 Normative/ACN · 10 ARIA (assistente AI).

Riferimenti

  • Standard protocollo: agile-services/docs/STANDARD_PRODUCT_DEMO_PROTOCOL.md (v1.0.1)
  • Standard metodo+collaudo: agile-services/docs/STANDARD_PRODUCT_DEMO_COMPLETE.md
  • Requisiti NIS2: agile-services/docs/OUTGOING_TO_NIS2_2026_05_29_demo_avatar_requirements.md
  • How-to mappe: agile-services/docs/PLAYBOOK_DEMO_AVATAR_MAPPE.md
  • Esempio dev: agile-services/docs/SPEC_ALLTAX_DEMO_AVATAR_PER_DEV.md
  • Formazione: agile-services/docs/DESIGN_AVATAR_FORMAZIONE.md