- public/js/help.js: rimossa unica occorrenza <i class="fas fa-comment-alt"></i>
(residuo non renderizzato dopo lo swap a Bootstrap Italia V2) + collassato lo
spazio ridondante, nella guida "Come aprire una segnalazione".
- Cache-buster mirato: help.js?v=20260613 -> 20260614 su 35 pagine public/*.html
(sibling common-bi.js/i18n.js/common.js/api.js/style.css lasciati invariati).
- public/version.json: 1.14.0 -> 1.14.1.
- Nessuna modifica a dati o schema DB. Ticket #367 (collaudo release supervisore).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Aprendo il pannello ARIA ora si nascondono nx-bar (campana/supporto) + ai-chat-fab -> niente overlap;
la X e Esc chiudono e ripristinano i pallini. Prima la X era fragile e il pannello copriva i bottoni.
Bump common.js?v=20260613d. (TRPG usa ai-assistant.js con stesso pattern toggle/hide.)
NIS2 aveva DUE sistemi feedback: feedback.js (pill cyan 'Segnala/Feedback' + modale scuro) + bug-reporter
AgileHub (campana+supporto). TRPG/ALLTAX usano solo bug-reporter (verificato: trpg ha app/js/bug-reporter.js,
nessun feedback.js). Rimosso l'auto-inject di feedback.js da common.js -> resta il trittico pallini
(notifiche + supporto + ARIA) come la suite. Verificato headless: feedback-fab assente, nx-bell/nx-bug/ai-chat
presenti. Bump common.js?v=20260613c (auto-refetch). feedback.js/api restano nel repo, non iniettati.
Risolve il 401 del bug-reporter ('Header X-API-Key o Authorization Bearer richiesto'): il widget ora
manda X-API-Key -> gateway ticket AgileHub OK (tenant 7, provenance corretta). Chiave fornita da AgileHub
(full tenant-key, va nel JS pubblico = stesso compromesso TRPG/ALLTAX; debito 'token low-priv' rimandato).
Bump versione common.js -> auto-refetch senza hard-refresh.
Risolve 'le modifiche non si vedono': /js/help.js era senza ?v -> browser serviva la versione cached
vecchia. 281 ref su 57 pagine + injection demo/bug-reporter aggiornate.
Harness same-origin sui 10 step ha trovato 1 difetto reale: step 9 puntava a #quick-qs/#chat-input che
il JS non renderizza (tab chat non-default, assenti nel DOM) -> ri-ancorato a #portfolio-header (presente,
highlightApplied:true confermato). Gli altri 'NOT_FOUND' erano artefatti --virtual-time-budget: incidents
#crit-*, policies #ai-*, supply-chain #assessment-live-score sono presenti nel DOM renderizzato (dump 7s),
il vero avatar li trova al loro at_ms. 10/10 step ora risolvibili.
Harness same-origin temp sul sottodominio + headless chrome: ready -> highlight #compliance-gauge ->
classe nis2-demo-hl applicata, 0 errori. Il SPA esegue i comandi del widget in un browser vero.
Resta solo il giro completo 10 step col widget AgileHub live (conferma di produzione).
Il collaudo curl validava il backend ma non l'esecuzione JS nel browser. Con google-chrome --dump-dom:
1) common-bi.js: sync api.token/orgId IN-MEMORY (api.js crea l'istanza prima leggendo localStorage vuoto
→ checkAuth vedeva token null → redirect a login). Ora la SPA si auto-autentica.
2) demo-mode.js boot(): non bloccare sul seed quando HMAC_ENFORCE=false (cross-origin il seed non arriva;
non serve, HMAC off) → il runtime (banner/listener/ready) ora parte.
Verificato headless su dashboard/risks/incidents: login:0, banner+nis2-demo-on presenti.
Sottodominio nis2.dimostrazione.agile.software live (reverse-proxy). DEMO_BASE allineato (3e8a90f).
Punto coordinamento #2 (same-origin) marcato RISOLTO via sottodominio. Collaudo E2E in corso.
Chiude il gap auth: la SPA demo si auto-autentica col demo_jwt (token API nis2_access_token + org dal
payload) PRIMA di checkAuth, cross-origin (niente sessionStorage same-origin). spa_iframe_url ora atterra
su /dashboard.html?demo=..#djwt=... DemoController.DEMO_BASE override via env DEMO_BASE_URL (switch a
sottodominio senza codice). USR2 richiesto per DemoController.
Il postMessage widget->SPA e il canale runtime avatar (non external/v1): server-to-server usa
X-Internal-Key (gia su reset-dataset), il postMessage si fida di ev.origin (same-origin). HMAC verify
resta flag-gated (HMAC_ENFORCE=false) da riaccendere solo se al collaudo il widget firma.
Stato punti 1,2,3,4,6,7,8 = FATTI/deployati/collaudati. Da coordinare: HMAC canonical messaggio,
ops same-origin dimostrazione.agile.software, data-demo-action anchors, sweep 132 id (non bloccante).
Steps: dashboard/assessment/acn-gap/risks/incidents/policies/supply-chain/isms/cross-analysis/reports.
Highlight su selettori ESISTENTI verificati dalle mappe (non i 132 da-aggiungere). Narrazione senza
numeri inventati (ARIA usa RAG sul dataset 996001). express_subset [1,4,5,9]. Servito da GET /api/demo/manifest.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Avatar di prodotto, product-demo-protocol v1.0.1 (NIS2 multi-page):
- public/js/demo-mode.js: runtime canale postMessage (inbound navigate/highlight/scroll_to/
trigger_action/open_tab/...; outbound ready/spa_state_changed/step_animation_done/...),
verifica origin+HMAC (chiave SHA-256(jwt:seed:demo-control-channel))+idempotency, banner read-only.
- public/js/demo-selectors.js: whitelist 17 viste (view->url) + azioni read-only sicure.
- public/css/demo.css: highlight pulse-blue/halo + banner.
- common-bi.js: hook che inietta gli asset SOLO con ?demo= (no-op per utenti normali).
NOTE: (a) HMAC canonical del MESSAGGIO da riconciliare con AgileHub al collaudo (canonicalize()).
(b) manca il manifest (steps+selettori) — dipende dagli id stabili in corso.
node --check OK su tutti.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Ancorata a tassonomia + mappe-logiche, risposte fondate su FONTI CERTE (Allegati 3/4, IS-4 solo
essenziali, ciclo 24h/72h/1mese, SoA 111 controlli, soglia rilevanza asset 40, ecc.). Formato per
motore quiz (esame soglia 80%). Esercizi pratici eseguibili nella sandbox org 996002.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- application/services/DemoSeedService.php: logica seed/clone golden #151 -> 996001/996002 (riusabile)
- DemoController::resetDataset: re-seed reale via service (?scope=demo|sandbox|default both), non piu stub
- scripts/seed-demo-dataset.php: thin CLI wrapper sul service
Testato prod: POST /api/demo/reset-dataset (X-Internal-Key) scope=sandbox -> 200, 996002 ri-seedata.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Increment backend formazione-first (product-demo-protocol v1.0.1):
- BaseController::applyDemoGuard() — SAFE-BY-CONSTRUCTION (flusso auth normale invariato):
riconosce demo_jwt scope=demo:read-only (blocca scritture 403 DEMO_READ_ONLY) e
training:sandbox (scritture solo su org sandbox); contesto sintetico user=0 ruolo
compliance_manager su org range 996xxx; mai super_admin. Short-circuit in requireAuth/
requireOrgAccess/requireOrgRole. php -l OK. DA DEPLOYARE (USR2) + testare quando host disponibile.
- scripts/seed-demo-dataset.php — clona golden DataCore #151 in 996001 (demo RO) + 996002
(sandbox scrivibile), idempotente, richiamabile da resetDataset. php -l OK. DA ESEGUIRE su host.
NB: chiave ssh host revocata a meta-sessione → seed/USR2/push in attesa di ri-provisioning.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
ARIA ora conosce la nuova interfaccia V2 (docs/kb/V2_UI_NAVIGAZIONE.md indicizzato in
Qdrant nis2_kb scope SYSTEM). Header documenta il workaround mount (copia sotto application/).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Promosse le pagine -bi a nomi ufficiali (contenuto BI), link -bi->plain, titoli '(BI)' rimossi.
La vecchia UI delle pagine app e sostituita. Backup: git (commit 36967f9) + /tmp/nis2-v1-backup.
Promosse (27): auth (login/register/onboarding/forgot/reset) + app (dashboard/assessment/
risks/incidents/policies/supply-chain/training/assets/reports/settings/isms/acn-gap/normative/
whistleblowing/kb/cross-analysis/service-continuity/guida/companies) + admin (index/orgs/users).
common-bi.js: sidebar BI ora linka le pagine ufficiali.
ESCLUSA: index.html (landing marketing 1298 righe) -> conversione dedicata a parte (la -bi
era 557 righe, rischio perdita contenuti). Pagine marketing/demo (presentation/simulate/
workflow/architecture/index-en) restano vecchio stile (fuori scope app autenticata).
Verifica produzione: 27/27 servite 200 con BI, 0 link -bi residui, 0 '(BI)' nei titoli,
auth intatta (401 su pwd errata), common-bi.js node --check OK.
Rollback: git revert HEAD (oppure ripristino da /tmp/nis2-v1-backup).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Completa la copertura V2 al 100% delle pagine app autenticate (pre-swap).
Additivo: nessun file live HTML promosso ancora (lo swap e separato).
- 9 pagine app -bi: isms, acn-gap, normative, whistleblowing, kb, cross-analysis,
service-continuity (doc standalone), guida, companies
- admin/{index,organizations,users}-bi.html (path corretti, common-bi.js)
- help.js: +89 righe help contestuale pagine V2 (vincolo fonti certe)
- docs/kb/V2_UI_NAVIGAZIONE.md: doc UI/navigazione V2 per la KB AI (ARIA)
- Verifica: tutte servite 200, 0 CDN/FontAwesome, sprite validi, parita ID
Prodotto via Workflow a trittici (run wf_c4962fbe-93f) + fix manuale companies/sprite.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Pipeline a trittici (Esecutore->Revisore->Controllore avversariale), 6 trittici T1-T6.
Tutto ADDITIVO: nessuna pagina/JS live modificata, produzione intatta. Swap non incluso.
- public/vendor/bootstrap-italia/ : BI v2.18.1 self-hostato (CSS+JS bundle+16 woff2+sprite), MAI CDN
- 16 pagine *-bi.html (login/register/onboarding/forgot/reset/index + dashboard/assessment/
risks/incidents/policies/supply-chain/training/assets/reports/settings)
- public/js/common-bi.js : sidebar/topbar in markup BI (additivo, riusa stessi ID + common.js)
- Verifica sul path servito reale: 16/16 -> 200, 0 CDN, 0 FontAwesome residui, parita ID/hook completa, WCAG AA
- docs/SISTEMA_TRITTICI_AGENTI.md : design del sistema a trittici
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Riscrittura completa: istruzioni concrete (login, registrazione 3 step, onboarding
4 step con campi reali, navigazione), per ogni modulo "cosa trovi e come si usa"
estratto dall'help contestuale del prodotto (help.js), FAQ, glossario. Rimosse le
interruzioni di pagina che lasciavano pagine vuote. Generatore self-contained
(estrae i contenuti da public/js/help.js via node).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Lezione 2026-06-10 (3 outage): forzare SSL su una connessione via socket (DB_HOST
'localhost'/vuoto/path) da' PDOException [2002] "Cannot connect to MySQL using SSL"
su ogni richiesta -> app giu'. sslOptions() ora ritorna [] (resta in chiaro + log) se
DB_HOST indica un socket, anche col flag/env attivo. SSL si applica solo alle
connessioni TCP. Il socket e' IPC locale: nessun transito di rete da cifrare.
Cosi' riaccendere .db_ssl_on mentre l'app e' su socket NON puo' piu' causare outage.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
CONTEXT/runbook aggiornati con le conclusioni 2026-06-10 sera:
- L'app HTTP (php-fpm) usa il MySQL HOST via UNIX SOCKET (localhost), NON il container
(la "scoperta container" precedente era basata sul path CLI = falso positivo).
- TLS su socket non si applica e rompe (outage rientrato: rm flag + USR2).
- Switch socket→TCP via vault-net (172.30.0.1): CLI(root) OK ma fpm(www-data) esce con
source=gateway → masquerade → 135.x → 1045. Switch NON eseguito (sarebbe outage).
- Lezione: validare SEMPRE sul path fpm reale (diag servito da php-fpm), mai CLI/docker exec.
- Pre-equip codice resta committato e inerte (flag OFF); attivabile quando il path TCP
fpm sarà grantabile (bind 172.21 in finestra con restart MySQL).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
database.php: Database::sslOptions() — TLS verso MySQL gated (env DB_SSL=true o
flag-file application/config/.db_ssl_on), DEFAULT OFF. PDO::MYSQL_ATTR_SSL_CA +
VERIFY_SERVER_CERT=false; fail-safe se CA assente (resta in chiaro + log: un
VERIFY=false senza CA connetterebbe in chiaro silenziosamente). Merge con '+'
(preserva chiavi-intere PDO). Default-OFF provato inerte (base + [] === base).
Validato da 2 agenti: runtime app coperto 100% da Database::getInstance (0 raw PDO
in application/); review adversariale = SICURO default-OFF, nessun bug.
.gitignore: flag-file + db-ca.pem. Runbook: docs/TLS_DB_PREEQUIP_NIS2.md.
NB topologia verificata: l'app usa il DB CONTAINER (db->172.21.0.4, 8.0.45), non il
MySQL host -> CA + enforce vanno sul container db (a cura VIGILE).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
La regola .form-group input {width:100%} si applicava ANCHE al checkbox del
consenso, gonfiandolo a tutta la riga e spingendo il testo a capo parola per
parola. Aggiunto override .consent-label input[type=checkbox] {width:16px}.
Ora testo in linea su 2 righe, colore normale, link Privacy policy + asterisco cyan.
Verificato con render headless Chrome.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Due bug nel form 'Richiedi accesso':
1. La regola generica .form-group label span {color:red} (pensata per l'asterisco
obbligatorio) coloravadi rosso TUTTO il testo del consenso.
2. Lo <span> dentro il label flex non aveva larghezza -> andava a capo parola per
parola (incolonnato verticalmente).
Fix: classe dedicata .consent-label con span flex:1 + min-width:0 + colore normale;
l'asterisco resta cyan. Testo ora in linea accanto al checkbox.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>