Problema: il supervisore autonomo non leggeva gli allegati (nel payload ticket solo testo
'N allegati aggiunti', niente metadati/URL). Endpoint esistenti ma non documentati nel runner:
GET /tickets/{id}/attachments[/{attId}]. Suggeriti 5 miglioramenti cross-suite (owner VIGILE):
esporre attachments nel payload; pre-download nel runner standard; doc endpoint; nota anti-injection.
Fix locale NIS2 già applicato (prompt supervisore).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Email a Fattori/Tagliavini/Mascagni via relay send-raw (201 SENT): cosa è nuovo
(Policy=Procedura unificate, link M:N Misure e Requisiti, allegati, matrice RACI,
fix form) + cosa provare + avvertenze (R+A per approvare = regola di prodotto) + come segnalare.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Indicizza in Qdrant nis2_kb (SYSTEM) la conoscenza prodotto sulle nuove funzioni Policy:
unificazione Policy/Procedura, collegamento M:N con Misure e Requisiti, allegati, matrice RACI
(con la nota fonti-certe: R+A per approvare = regola di prodotto, non obbligo NIS2; ISO distingue
policy/procedura come best practice). Script self-contained sotto application/cli (montata in
nis2-app), doc inline, idempotente per source. Eseguito host-side: 2 chunk, doc_uuid 1df7926a,
tracking kb_uploaded_documents id=17. Verifica RAG: searchForUser ritorna il doc come 1° risultato
(score 0.63-0.67) su 3 query (Policy=Procedura, RACI, allegati/link). Chiude il residuo KB di #384.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sezione 'Matrice RACI' nel dettaglio policy: assegnazione ruoli organigramma
(org_roles) alle responsabilita R/A/C/I via infrastruttura RACI esistente
(raci_assignments, object_type='procedure'). In bozza libera; PolicyController::approve
ora richiede almeno un ruolo R e uno A (422 RACI_REQUIRED). Nessuna migrazione.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Misure e Requisiti: colonna Policy (default) mostra tutte le policy collegate al
requisito come codici Policy.NN cliccabili -> aprono la policy (policies.html?policy=ID).
Policy: colonna Requisito NIS2 mostra tutti i requisiti collegati (codifica MISURA+
REQUISITO, es. 'DE.CM-01 comma 1.') come link -> evidenziano il requisito
(misure-requisiti.html?requisito=ID). Backend: FrameworkController::catalog espone
policies[] per requisito e PolicyController::list espone requisiti[] per policy
(org-scoped, tabella requisito_policy mig.059, try/catch con degrado al dato di default).
Solo lettura/visualizzazione: nessuna modifica dati, nessuna migrazione.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Migrazione 059 additiva/idempotente/reversibile:
- policies.proc_code VARCHAR(16) NULL: ripristina la chiave di join verso il
catalogo canonico (cfg_nis2_procedure/cfg_nis2_requisiti), che andava persa
quando le 42 procedure di default venivano copiate nell'elenco Policy (mig.048).
- tabella requisito_policy: M:N org-scoped requisito<->policy (un requisito puo'
avere piu' policy e una policy piu' requisiti) — base per p.2.2 e p.3.
- backfill sicuro: proc_code valorizzato su 42 policy (match esatto titolo) +
116 associazioni di default popolate (INSERT IGNORE, WHERE proc_code IS NULL).
- PolicyController::ensureFrameworkProcedures: i nuovi seed conservano proc_code
e popolano requisito_policy (try/catch dedicato, non blocca il seed).
Nessun impatto utente in questo passo (nessuna superficie legge ancora i nuovi
campi). UI multi-valore + link bidirezionali (2.2/3) nei prossimi cicli. v1.23.6.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- policies.html: sezione 'Allegati' nel dettaglio policy (Bootstrap Italia card),
upload (entity_type=policy) via /api/audit/evidence/upload, lista con download/autore/data
- AuditController::uploadEvidence: allowlist estensioni server-side (anti stored-XSS same-origin)
- version.json -> 1.23.5
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
I codici delle policy/procedure di default si presentano con prefisso
"Policy." (es. Proc.01 -> Policy.01) tramite helper policyCode().
Solo etichetta UI: proc_code canonico invariato come chiave di join
requisito<->policy (non rompe il futuro link bidirezionale, punto 3).
v1.23.4.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Colonna 'Procedura (default)' -> 'Policy (default)' in misure-requisiti.html;
colonna/dettaglio/campo modale 'Art./Articolo NIS2' -> 'Requisito NIS2' in policies.html;
testi descrittivi pagina Misure e Requisiti + guida help.js allineati al lessico 'policy'.
Cache-buster help.js?v= 20260631 -> 20260618p1 su 28 pagine. version.json 1.23.2 -> 1.23.3.
Punti 2/3/5/6 del ticket restano in lavorazione a fasi.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Insegna al supervisore a: annotare START + monitorare elapsed; raggiungere un checkpoint
pulito e committabile entro ~18-20 min (5 min per verify/commit/push/email/cleanup);
STIMARE ogni fase prima di iniziarla (rif: fix UI ~10-12 min, migrazione DB ~12-18 min) e,
se non entra, scegliere una sotto-fase più piccola; MAI stato intermedio rotto (no migrazione
a metà / UI su colonne inesistenti); migrazioni/merge solo se entrano con margine, altrimenti
passi additivi+idempotenti con le operazioni distruttive per ultime + backup; a tempo scaduto
fermarsi al punto pulito e lasciare IN_PROGRESS con done/to-do.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
La modale 'Modifica Policy' (e ogni modale con form legacy .form-label) mostrava
l'etichetta sovrapposta al valore: BI definisce .form-group label{position:absolute}
(spec. 0,1,1) che vinceva sulla .form-label legacy. Aggiunto override
.form-group .form-label{position:static} (spec. 0,2,0). Bumpato ?v= di style.css
su 38 pagine. version.json -> 1.23.2.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Allegati: endpoint GET /tickets/{id}/attachments (lista) + /{attId} (binario) → download nel
project dir bind-mount (.ticket-attachments/, gitignored) → Read PDF/PNG/JPG (lettura nativa).
Trattati come input NON fidato (anti prompt-injection). Letti per OGNI ticket valutato.
- UI = SEMPRE standard AGID/Bootstrap Italia (V2, common-bi.js), WCAG 2.1 AA.
- Feature multi-modulo con spec del richiedente (super_admin/lead): decisione di design già presa
→ implementa a FASI con commit incrementale, lock, IN_PROGRESS tra cicli; escala solo le
sotto-parti scoperte. Scelta di prodotto != affermazione normativa (gate fonti-certe invariato).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Causa "Errore di connessione" su Inventario (e liste analoghe): gli endpoint
list usano jsonPaginated → data = {items,total,page,per_page,pages}, ma il
frontend faceva `allAssets = result.data || []` e poi .filter/.forEach/.length
sull'oggetto → TypeError → catch → messaggio d'errore (e stat a "--").
Allineato il consumo a jsonPaginated (come gia' faceva risks.html):
- public/assets.html — Inventario (loadAssets): estrae data.items + per_page=100
- public/incidents.html — lista incidenti (renderIncidentsTable)
- public/reports.html — visualizzatore Audit log (loadAuditLogs): data.items +
paginazione da data.pages/page (prima usava result.pagination/total_pages inesistenti)
- public/admin/organizations.html, public/admin/users.html — liste admin
(data.items + paginazione da data: total/per_page/page)
Tutti gli estrattori sono difensivi (gestiscono anche un eventuale array bare).
Verificato: endpoint reali tornano data={items,...}; nessun consumer rotto
restante (listNCRs/listFeedback non usati da pagine; /feedback/mine resta array).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- CLAUDE.md testata: stato TLS DB del prodotto DA FARE → ✅ DONE. Pre-equip PHP-CA fatto
(app in TLS 1.3) + enforce REQUIRE SSL su nis2_user@'%' già attivo (applicato da VIGILE
l'11/6 nel cutover container; ssl_type=ANY). Confermato indipendentemente con SHOW CREATE USER.
- Gotcha documentato: in MySQL 8.0 SHOW GRANTS NON mostra REQUIRE SSL (solo SHOW CREATE USER) —
era la causa del mio falso allarme "non enforced".
- Aggiunto il doc di conferma di VIGILE (INCOMING_FROM_AGILEHUB_2026_06_16_tls_enforce_gia_attivo).
Chiude l'ultimo open-item infra coordinato. Nessuna azione DB residua.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- #7 (go-live ready): send() aggancia l'invio email del questionario/firma-lettura via
EmailService, GATED dal kill-switch EMAIL_SENDING_ENABLED (oggi=false → ZERO invii;
pronto al go-live). Magic-link assoluto via APP_URL; invio solo ai target con email
valida; i link restano sempre disponibili per la condivisione manuale. Smoke prod:
email_sent=0, email_enabled=false (nessun invio).
- #2 (prevale Simon): nis2_sources.php — aggiunta NOTA DI PROVENIENZA sul 92 vs 87
(prodotto usa 92 = file referente; ACN ufficiale 87; divergenza nota/accettata).
Numero NON modificato per decisione confermata.
Note operative (host, fuori repo):
- #8: EMAIL_MS_URL spostato sul path interno http://172.21.0.1:8081/api/emails
(verificato 400 con X-Internal-Key = funzionante; pre edge-strip). Rollback: URL pubblico.
- #9: pre-equip PHP-CA del DB CONFERMATO (CA presente, app connessa in TLS 1.3); enforce
ALTER USER nis2_user REQUIRE SSL resta azione DB coordinata con VIGILE (utente @%).
v1.21.3. Additivo.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- UPLOAD ALLEGATI RIPRISTINATO in prod (causa: il sito è servito da php-fpm HOST e
public/uploads era git:git senza ACL per www-data → move_uploaded_file falliva;
fix host: setfacl -R -m u:www-data:rwx -m d:u:www-data:rwx public/uploads). Collaudato:
upload interno+portale .pdf 201, .html→422. Risolve anche evidence_files/visure.
- nis2_sources.php (fonti-certe): Determina 333017/2025 datata 22 settembre 2025 e marcata
STORICA/superata; aggiunta entry VIGENTE 379887/2025 (efficace dal 31/12/2025); URL ACN
autorevoli (date-giorno marcate [da confermare sul testo ufficiale], verifica nis2-expert).
- UI attività: create+assign non lascia più attività orfane su errore (no duplicati su retry,
messaggio chiaro) + assegnazione individuale richiede almeno un destinatario; blocco PWA di
stakeholder-activities allineato (favicon-16/status-bar/application-name). v1.21.2.
ESCALATION (decisione di Simon, non modificata): nis2_sources.php riga 79 riporta "37 misure /
92 requisiti" per gli importanti (dato file Simon), ma la pagina UFFICIALE ACN indica "37/87".
Da riconciliare con Simon (open item #2). NON cambiato per rispettare la decisione bloccata.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Corretti i finding confermati dalla verifica multi-agente (5 major + minori):
SICUREZZA
- Stored XSS allegati: da blocklist a ALLOWLIST di estensioni innocue (no html/svg/js
renderizzabili same-origin) in StakeholderPortalController::attachment e
StakeholderActivityController::storeUpload; nome file randomizzato (random_bytes).
- Magic-link: scadenza (mig.054 stk_activity_targets.token_expires_at; send() imposta
scadenza attività+30gg o +90gg; resolveTarget() → 410 TOKEN_EXPIRED se scaduto);
rate-limit per-IP sugli endpoint del portale; comment/attachment bloccati su attività chiusa.
CORRETTEZZA
- send(): NON rigenera token né azzera lo stato dei destinatari già responded/acknowledged
(prima ne perdeva l'esito); imposta token_expires_at.
- assign individuale: semantica "replace" (rimuove i deselezionati non ancora conclusi) +
guard su lista vuota (evita 'IN ()').
- update(): conserva assign_mode esistente quando si modifica solo stak_code.
UI/UX/A11Y
- Editor opzioni per domande a scelta singola/multipla (prima degradavano a testo nel portale).
- Etichette stato/tipo localizzate; risposte mostrate inline (no alert()); escAttr nel portale
(escape virgolette negli attributi); ARIA su modali/tab; voce sidebar anche in common.js.
OPEN ITEM (NON regressione C5, pre-esistente e ambientale): l'upload allegati restituisce
UPLOAD_ERROR in prod — move_uploaded_file/is_uploaded_file fallisce nella topologia
proxy→fastcgi (stesso pattern di evidence_files/AuditController, mai funzionato: la dir
uploads/evidence non esiste). rename/copy come www-data funzionano. Da investigare lato infra.
Il resto di C5 (questionari, firma-lettura, commenti, calendario, portale) è pienamente operativo.
Smoke prod OK: allowlist (.html→422, struttura ok), opzioni scelta nel portale, send no-reset,
replace individuale, token_expires_at presente. Additivo. v1.21.1.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Completa C5 (Epic C). Gli stakeholder rispondono in self-service tramite magic-link
(token SHA-256 per destinatario, NESSUN account/JWT); il compliance manager vede gli
esiti, i commenti e gli allegati nel dettaglio dell'attività.
- StakeholderPortalController (non-JWT, token-only): access / respond (questionario) /
acknowledge (firma di avvenuta lettura) / comment / attachment. Submit one-shot (409),
validazione risposte obbligatorie, anti-IDOR (un token = un solo destinatario),
auto-completamento attività quando tutti hanno risposto/firmato.
- StakeholderActivityController: feedback (risposte per destinatario), comments
(GET/POST), attachments (upload interno + lista; riuso evidence_files entity_type=
'stk_activity', file sotto public/uploads/stk_activity/{org}/).
- mig.053: stk_activity_responses (answers JSON / acknowledged_at), stk_activity_comments
(interni/esterni). Estende il seeder idempotente.
- Frontend: stk-portal.html (pagina pubblica dependency-free: questionario per tipo di
domanda o testo+firma, commento, upload); dettaglio attività in stakeholder-activities.html
con esiti, thread commenti e allegati.
Email disattivate (kill-switch) → i magic-link si condividono manualmente. Smoke prod OK
(access no-auth, respond+required+409, acknowledge+WRONG_TYPE, comment esterno/interno,
bad-token 404, feedback interno, auto-complete; cleanup org 151 pulita). Additivo. v1.21.0.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Fondazione delle attività verso gli stakeholder (Simon C5 §4):
- Questionari tipo (template): tipo questionario-da-compilare / firma-di-avvenuta-lettura,
domande (JSON) + collegamento m2m a procedure (policies) E a misure/requisiti del
framework (cfg_nis2_misure/requisiti).
- Attività: basate (opz.) su un template, assegnabili a un CODICE stakeholder (tutti
quelli di quel tipo) o a singoli stakeholder; pianificabili con data e scadenza.
- Calendario NIS2: review_schedule esteso (ENUM entity_type += 'stakeholder_activity');
su create/update con scadenza la riga di calendario viene sincronizzata.
- Invio: genera un magic-link per destinatario (token SHA-256) per il portale esterno
(C5.2b). Email disattivate (kill-switch) -> i link si condividono manualmente.
mig.052: stk_questionnaire_templates, stk_template_(procedures|misure|requisiti),
stk_activities, stk_activity_targets, stk_activity_procedures + ALTER review_schedule.
StakeholderActivityController + /api/stakeholder-activities/*; stakeholder-activities.html
(2 tab: attività / questionari tipo + dettaglio invio); voce sidebar V2; help/i18n.
Smoke prod OK (template m2m, attività by_code+calendario, assign, send magic-link,
anti-IDOR individual, negativi 422; cleanup org 151 pulita). Additivo. v1.20.0.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Registro dedicato degli stakeholder (tabella `stakeholders`, NON una colonna su
suppliers: gli interni non sono fornitori; gli esterni si COLLEGANO opzionalmente
a un supplier esistente senza duplicare il dato).
- mig.051: cfg_stakeholder_types (30 di sistema Stak.01-30 + org-added da Stak.31),
cfg_stakeholder_quadrants (4, range corretti: Q4 potere 0-2), stakeholders,
stakeholder_procedures (m2m -> policies). Seeder idempotente seed_stakeholders.php.
- StakeholderController: list/create/update/delete + types/addType + quadrants + pickers.
Quadrante CALCOLATO a read-time dai range config. Anti-IDOR su org_role/supplier/
policy/tipo; coerenza kind (interni->organigramma, esterni->fornitore); punteggi 0-5.
- api.js: metodi stk*. stakeholders.html riscritta: registro + matrice di Mendelow
in SVG dependency-free + modali (stakeholder, nuovo tipo). Voce sidebar V2 (common-bi.js).
- Help aggiornato; cache-buster ?v=20260626 su tutte le pagine; version 1.19.0; sw cache v1.19.0.
Ancoraggio GV.SC-02 (obbligo, art. 24 D.Lgs. 138/2024). La matrice di Mendelow e'
etichettata come BUONA PRASSI, non obbligo NIS2 (regola fonti-certe). Additivo.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Simon C4: nell'inventario DUE sole voci principali; le sottoclassi le crea l'utente.
Riconduzione concordata (no perdita di dettaglio): hardware/network/facility -> ID.AM-01;
software/service/data -> ID.AM-02; personnel -> Organigramma (0 asset personnel presenti).
- Config: cfg_inventory_voci (2: ID.AM-01 Hardware, ID.AM-02 Software/Servizi/Sistemi),
inventory_subclassi (12 default di sistema org NULL + sottoclassi org-scoped).
- assets.voce_code + subclass_id (FK). 20 asset esistenti MIGRATI (5 ID.AM-01 / 15 ID.AM-02).
- AssetController: list con label voce/sottoclasse; create/update validati (voce in whitelist,
sottoclasse appartenente a org/default+voce); GET/POST /assets/subclasses; import (bulkUpsert)
deriva la voce dal tipo legacy. asset_type resta come campo legacy (viste secondarie).
- assets.html: filtro per voce, form con selettore Voce + Sottoclasse (+ '+ aggiungi'),
lista/dettaglio mostrano 'voce · sottoclasse', stat-chips per voce.
- FIX bug pre-esistente: apostrofo non escapato ('l'inventario') che ROMPEVA tutto il JS
della pagina Inventario. + cache-buster common-bi.js (era a v=20260618, non bumpato dal fix C3).
Help + KB + i18n. Verifiche prod: subclasses 200, create voce/legacy OK, validazione 422,
JS valido (node --check), migrazione idempotente. version 1.18.4.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Simon C3: l'analisi gap ACN non è un artefatto normativo e va eliminata; la conformità
emerge da C1 (elenco Misure/Requisiti + valutazione per requisito in org_requisito_state).
Ricognizione → migrazione → backup → rimozione (sicuro, 0 perdite):
- Tabelle acn_assessments/acn_assessment_responses VUOTE (0 righe) -> droppate (mig.049,
guard anti-drop se >0 righe). Ricreabili da 036. Nessun dato utente perso.
- Integrazione lg231: /api/services/gap-analysis legge 'assessments' generale, NON il modulo
ACN -> intatta. Verificato.
- RaciController ripuntato su cfg_nis2_misure (fonte canonica) al posto di acn_measures.json
(rimosso); validazione measure_code verificata (/raci/objects?type=measure -> 43 misure).
Rimossi: AcnAssessmentController, public/acn-gap.html, application/data/acn_measures.json,
routing acn-gap, voci sidebar (common.js + common-bi.js), metodi api.js acn*, sezione help 'acn',
chiavi i18n acn.*, mapping demo-selectors. Tour demo step 3 RIPUNTATO su misure-requisiti
(no step rotto, 10 step). Sidebar BI ora mostra 'Misure e Requisiti' (gap di common-bi.js sanato).
Verifiche prod: /acn-gap.html 404, /api/acn-gap/* 404, /misure-requisiti 200, RaciController OK.
Cache-buster ?v=20260624, version 1.18.3, SW v1.18.3.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Flotta di verifica (14 agenti): sicurezza pulita, fedeltà del dato perfetta (codifica
Simon intatta, 0 scostamenti). Corretti i 6 finding confermati:
- MAJOR: PolicyController::ensureFrameworkProcedures ora in transazione + SELECT...FOR UPDATE
sulla riga org -> no procedure duplicate su fallimento parziale (rollback) o richieste concorrenti.
- MINOR: importer idempotente committato application/cli/seed_framework.php (DDL + upsert da
nis2_framework_seed.json) -> re-seed riproducibile/versionato (verificato 2 run = 0 duplicati).
- MINOR: allineato '92 requisiti' importanti (dato autoritativo Simon) in help.js + nis2_sources.php
(era 87, contraddizione interna); coerente '24 requisiti aggiuntivi essenziali' (116-92).
- MINOR (UI): troncamento anteprima valutazione sul RAW prima di esc() (no entita HTML spezzate).
- MINOR (UI a11y/AGID): modale valutazione con focus iniziale, ripristino focus, focus-trap.
Cache-buster ?v=20260623, version 1.18.2, SW nis2-shell-v1.18.2.
NB residuo da verificare: data esatta Determinazione 333017/2025 (mese senza giorno) in nis2_sources.php.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- help.js 'misure-requisiti': sezione 'Valutazione e stato di conformità' (stato per
requisito, valutazione del rischio che parte vuota, copia procedure di default) + nota.
- KB AI: doc SYSTEM su valutazione conformità + procedure/rischi di default (uuid 92979c05).
- Cache-buster ?v=20260622 (35 pagine), version.json 1.18.1, SW cache nis2-shell-v1.18.1.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
PolicyController::list ora, al primo accesso al modulo Procedure di un'org reale,
copia le 42 procedure di default (cfg_nis2_procedure) in policies come contenuto
editabile/cancellabile (decisione utente: copia per-org al 1° accesso).
- organizations.framework_procedures_seeded_at = idempotenza (no ri-copia).
- categoria policies assegnata da mappa famiglia NIST->ENUM; nis2_article=misura;
content riporta misure coperte + nota 'personalizzabile e cancellabile'.
- Salta org demo/sandbox (isDemo) per non inquinare il dataset dimostrativo.
- Best-effort: errore nel seed NON blocca la lista (log + return).
Smoke prod: org 151 3->45 policy (42 default, 10 categorie), idempotente al 2° accesso,
golden 151 poi ripristinato (cleanup). Additivo.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
org_requisito_state (org x requisito -> stato + valutazione del rischio + note),
la valutazione 'parte vuota'. È da qui che emerge lo stato di conformità (sostituirà il Gap ACN, C3).
- FrameworkController: catalog ora include lo stato per-org di ogni requisito (risoluzione org
OPZIONALE con verifica accesso = anti-IDOR); nuovo POST /framework/state (upsert, requireOrgRole
org_admin/compliance_manager, validazione stato + requisito esistente).
- misure-requisiti.html: colonna Stato/Valutazione (se org) + modale di valutazione (stato,
valutazione del rischio, note). api.frameworkSetState.
Smoke prod: catalog has_org/org_class OK; upsert non_conforme persistito e riletto; ISOLAMENTO
multi-tenant verificato (org 152 non visibile a org 151). Additivo.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Fondazione data-driven (direttiva utente: configurabile via DB, no JSON hardcoded).
Fonte autoritativa: docs/simon/C1_Misure_Requisiti.xlsx + Vista (codifica Simon NON variata).
Tabelle system-level, sola-lettura per l'utente, configurabili da super_admin:
- cfg_nis2_ambiti (18 categorie NIST GV/ID/PR/DE/RS/RC)
- cfg_nis2_misure (43 misure; 6 solo-essenziali; area politica a..p, applies_important/essential)
- cfg_nis2_requisiti (116 requisiti; 92 importanti / 116 essenziali; ord N immutabile; FK misura/proc/risk)
- cfg_nis2_procedure (42 procedure di default Proc.01-42)
- cfg_nis2_rischi (84 rischi di default Risk.01-85)
Seed via application/data/nis2_framework_seed.json (import-only; runtime legge le cfg_*).
Applicato su prod (additivo, reversibile via DROP). Runner temp self-contained gia rimosso.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- 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>