Prodotto Vendibile 2 — Evidence Matrix 1-10¶
Data analisi: 2026-04-26
Repository analizzato: /Users/enrico/dwh
Commit base: e0287d9e
Scopo: trasformare la chiusura InitiativeV3 da “gate verde su superfici selezionate” a prodotto AML vendibile, provato da flussi reali, evidenze persistite e test che non mascherano AI slop.
1. Verdetto sintetico¶
Il prodotto è migliorato in modo sostanziale rispetto alla prima chiusura prodotto-vendibile.md, ma la reale vendibilità richiede una soglia più severa: non basta dimostrare che il DG può vedere task, approvare una run e firmare un documento quando parte dello stato viene predisposto da fixture di test. Serve dimostrare che un percorso operativo reale genera automaticamente lo stato vendibile.
Verdetto al termine di questa analisi:
- Vendibile per demo guidata controllata: sì, se si usa il tenant demo già predisposto e si resta sui flussi coperti dalla suite
product_ready. - Vendibile come prodotto reale senza regia tecnica: non ancora al 100%.
- Gap principale rimasto: manca una suite end-to-end “no-fixture” che parta da una nuova Operazione AML, faccia nascere organicamente task, approvazioni, firme, blocchi e archivio, e provi tutto con side effect DB più evidenze scaricabili.
- Fix P0 chiuso in questa passata: la firma del report Operazione AML non passa più da un endpoint server-side diretto; ora parte da GoeSign e la completion GoeSign aggiorna report,
sig_records, PDF archiviato e proiezione Archivio Unico.
2. Criterio di accettazione vendibile¶
Ogni riga della matrice 1-10 è verde solo se ha quattro prove:
- UI reale vista dal ruolo corretto.
- Side effect applicativo su DB/stato, non solo testo in pagina.
- Evidenza prodotta: documento, firma, audit event, archive index o pacchetto scaricabile.
- Test automatico che percorre il flusso senza update DB diretto per l’azione utente critica.
Se manca una delle quattro prove, la riga resta Parziale o Bloccante.
3. Mappa codice analizzata¶
| Area | Route UI/API | Codice reale | Stato analizzato |
|---|---|---|---|
| Setup tenant | /organizzazione/nuovo, /organizzazione/{tenant} |
internal/handler/view/tenant_setup_view.go, internal/service/tenant_setup_activation_svc.go |
Attiva tenant, utenti, baseline e issuer SSI. |
| Control room DG | /organizzazione/{tenant} |
internal/service/dg_control_room_svc.go, internal/service/dg_document_projection_svc.go |
Aggrega da fare, approvazioni, firme, eccezioni, documenti. |
| Operazioni AML | /operazioni/aml, /operazioni/aml/nuova, /operazioni/aml/{cod} |
internal/handler/view/aml_operation_intake_view.go, internal/service/aml_operation_* |
Intake, conferma, task, indicatori, downstream KYC/KYB, report. |
| Report operazione | /operazioni/aml/{cod}/report |
internal/service/aml_operation_report_svc.go, internal/handler/view/aml_operation_intake_view.go |
Quality gate, report versionato, firma, archivio. |
| Firma | /firme/sign, /goesign/ceremony/{id}, /api/signatures/complete |
internal/handler/signature_handler.go, internal/handler/goesign_handler.go, internal/service/signature_svc.go |
GoeSign/passkey, sig record, evidence refs, completion business. |
| Archivio Unico | /archivio, /archivio/{cod}/download, /archivio/consegna/{cod}/download |
internal/handler/view/archive_view.go, internal/service/archive_svc.go, internal/service/archive_index_svc.go |
Index federato, PDF canonicali, delivery ZIP. |
| AI approvals | /ai/approvals, /ai/approvals/{run} |
internal/handler/view/ai_view.go, internal/service/ai_approval_svc.go |
Approvazioni su task run e action plan. |
| Notai legacy | /notai/atti/* |
internal/handler/view/notarial_act_view.go, internal/service/notarial_act_svc.go, web/templates/pages/notai/* |
Ancora route attive; copy e placeholder ripuliti in questa passata. |
| QA product-ready | test_e2e/scripts/product_ready/* |
product-ready-matrix.spec.js, product_ready_db.js, product-ready-v2-anti-slop.spec.js |
V1 prova un journey misto; V2 aggiunge anti-slop su punti vendibilità critici. |
4. Matrice 1-10 con evidenza¶
| # | Promessa vendibile | UI | Origine stato | Evidenza | Test | Stato | Gap/fix |
|---|---|---|---|---|---|---|---|
| 1 | Il Superadmin crea un tenant operativo, non solo una riga anagrafica. | /organizzazione/nuovo → /organizzazione/{tenant} |
TenantSetupActivationService |
aziendas, tenant_setup_cases, utenti interni, issuer SSI tenant |
product_ready PV-001 |
Verde controllato | Il test esegue il wizard reale; rimane da legare questa prova al nuovo journey no-fixture 1-10. |
| 2 | Il DG entra e atterra su una control room utile. | /organizzazione/{tenant} |
DGControlRoomService.BuildControlRoom |
contatori, liste, task, firme, eccezioni | product_ready PV-002/003 |
Verde controllato | La control room funziona, ma i dati demo sono in parte preparati per il test. |
| 3 | Una nuova Operazione AML nasce da testo/bozza e diventa stato strutturato. | /operazioni/aml/nuova |
PreviewIntake, CreateDraftOperation |
aml_operations draft con soggetti, pagamenti, settore, testo sorgente |
Copertura parziale in test operativi e service test | Parziale | Serve E2E no-fixture che inserisca testo reale notaio/CASP e verifichi parsing, entity resolution e cockpit. |
| 4 | La conferma dell’operazione schedula lavoro reale: checklist, KYC/KYB, indicatori, downstream. | /operazioni/aml/{cod}/confirm |
ConfirmDraftOperation, ScheduleChecklistTasks, CorrelateIndicators, BootstrapDownstreamWorkloads |
checklist_tasks, indicator_sync_json, downstream_linkages_json, task_reconciliation_json |
Service test + copertura parziale | Parziale alto | Il codice esiste ed è coerente; manca test Playwright che dimostri il side effect partendo da UI reale. |
| 5 | L’analisi UIF/rischio spiega fatti → indicatori → nesso logico → decisione umana. | /operazioni/aml/{cod}, /indicatori |
AMLOperationIndicatorService, RunOperationQualityGates |
correlazioni indicatori, warnings/failures, decision state | Copertura service; no journey completo | Parziale | La logica è difendibile nel codice, ma la UI deve essere provata con casi concreti notaio e CASP. |
| 6 | Le approvazioni AI sono output governati legati a task reali, non fixture decorative. | /ai/approvals |
AIApprovalService, TaskRun, AIActionPlan |
ai_approvals, ai_approval_events, task aggiornato |
product_ready PV-005/011 |
Parziale critico | product_ready crea alcune run/task via seed DB. Serve provare che una Operazione AML reale genera run approvabili. |
| 7 | Ogni firma regolatoria passa da GoeSign/passkey e produce evidence. | /firme/sign, /goesign/ceremony/{id} |
SignatureHandler, GoesignHandler, SignatureSvc |
sig_records, evidence SHA, bundle hash, archive refs |
product_ready PV-010 + product-ready-v2-anti-slop PV2-001/003 |
Verde per firma regolatoria; migliorato per report operazione | Fix applicato: report Operazione AML ora firma via GoeSign completion; endpoint legacy /report/sign è fail-closed. |
| 8 | Il DG non può chiudere o firmare lavoro non difendibile. | /operazioni/aml/{cod}/report |
AMLOperationReportService.SignReport, RunOperationQualityGates |
quality_snapshot_json=failed, flash user-facing |
product_ready PV-012 |
Verde controllato | Validazione pre-cerimonia aggiunta per evitare firma GoeSign su report non firmabili. |
| 9 | Tutto ciò che è firmato/approvato finisce nell’Archivio Unico ed è scaricabile. | /archivio, /archivio/{cod}/download, /archivio/consegna/{cod}/download |
ArchiveService, ArchiveIndexService, DGDocumentProjectionService |
archive_document_indexes, document_artifacts, delivery ZIP |
product_ready PV-009/013/014 + PV2-004 |
Verde controllato | Fix applicato: download HTML non restituisce più JSON grezzo su 404. |
| 10 | La QA dimostra un flusso reale e blocca regressioni AI slop. | test_e2e/scripts/product_ready/*, test_e2e/scripts/quality/* |
Playwright + gate writer | sidecar qa-reports/*/gates/*.json |
product_ready, slop-gate, route-gate, product-ready-v2-anti-slop |
Parziale critico | V2 anti-slop copre bypass e copy; manca ancora suite organica no-fixture da nuova operazione a archivio. |
5. AI slop trovato e remediation¶
| Priorità | Slop trovato | Evidenza codice | Remediation |
|---|---|---|---|
| P0 | Il report Operazione AML aveva pulsante “Firma report” verso /operazioni/aml/{cod}/report/sign; l’handler chiamava direttamente SignReport e archiveSignedReport, senza cerimonia GoeSign. |
web/templates/pages/operations/report.html, internal/handler/view/aml_operation_intake_view.go |
Il form ora invia a /firme/sign con target_tipo=aml_operation_report; la completion GoeSign firma il report, crea PDF, collega archive index e proiezione. Il vecchio endpoint è fail-closed. |
| P0 | La prima matrice product-ready provava firma GoeSign su un sig_record predisposto, ma non la firma del report Operazione AML. |
test_e2e/helpers/product_ready_db.js |
Aggiunto gate product-ready-v2-anti-slop che impedisce il ritorno del bypass. Rimane da aggiungere il journey runtime completo. |
| P1 | Alcune route notariali legacy mostravano copy interno: “Decision room”, placeholder entity_type, support (available / missing / partial), bottoni “Esegui”. |
web/templates/pages/notai/* |
Copy riscritto in linguaggio professionale: “Decisione AML”, “Tipo soggetto”, select evidenze, “Avvia controllo”. |
| P1 | Archivio pagina poteva restituire JSON grezzo su download mancante/non autorizzato. | internal/handler/view/archive_view.go |
Download UI ora renderizza 404 user-facing; JSON resta solo sugli endpoint API. |
| P1 | Il report operativo esponeva “Quality gate e ragionamento AI”, “Warning”, “Decision state”, “Status”. | web/templates/pages/operations/report.html, operationReportSections |
Copy sostituito con “Controlli di qualità e motivazione”, “Avviso”, “Decisione”, “Stato report”. |
| P2 | Componenti legacy operazioni puntavano a route vecchie /report/firma. |
web/templates/pages/operations/components/cockpit-report.html |
CTA trasformata in apertura della pagina report canonica, dove parte la firma GoeSign. |
6. Gap residui da chiudere prima di dichiarare “vendibile senza regia”¶
G1 — Journey no-fixture da Operazione AML a Archivio¶
La piattaforma deve avere una suite Playwright seriale che faccia tutto senza creare direttamente task, approvazioni o firme via DB:
- Superadmin crea tenant.
- DG/RFA entra.
- RFA o DG crea Operazione AML da testo reale.
- Conferma operazione.
- Il sistema schedula task checklist e downstream KYC/KYB.
- Il sistema produce correlazioni UIF.
- Una run AI reale produce output approvabile.
- DG approva con motivazione.
- Report viene generato.
- Firma GoeSign completa il report.
- Archivio mostra PDF e delivery pack.
Finché questo non è verde, il prodotto resta vendibile solo come demo controllata.
G2 — Approvazioni AI nate da task reali¶
La suite V1 usa seedProductReadyWorkItems() per predisporre alcuni oggetti di lavoro. Questo è accettabile per test di superficie, ma non per dichiarare autonomia reale del motore AML.
Serve testare il percorso organico:
- task generato da operation checklist;
- task run creato da orchestratore/skill;
- action plan persistito;
- approvazione DG;
- task aggiornato;
- evidence emission collegata.
G3 — CASP e Notaio devono avere casi reali diversi¶
La stessa UI può servire CASP OTC e atto notarile, ma i dati attesi non sono identici. La prova vendibile deve includere almeno:
- CASP OTC: cliente, wallet/controparte, importo, Travel Rule/KYT, rischio fondi.
- Notaio: bozza atto, parti, mezzi di pagamento, titolarità effettiva, indicatori UIF, ragione economica.
G4 — Route legacy ancora attive¶
Le route /notai/atti/* sono ancora attive. Sono state ripulite nel copy, ma il prodotto dovrebbe decidere se:
- mantenerle come vista verticale “notaio”; oppure
- deprecarle e reindirizzarle completamente al modulo unico
/operazioni/aml.
La coesistenza è accettabile solo se non genera doppio significato commerciale.
7. Test aggiunti o usati in questa passata¶
| Test | Scopo | Stato locale |
|---|---|---|
go test ./internal/service ./internal/handler/view ./internal/handler |
Compilazione e regressioni service/handler/view toccati | Passato |
go build ./cmd/server/main.go |
Build locale server completo | Passato |
mkdocs build --strict |
Build documentazione pubblica | Passato |
node -c test_e2e/helpers/epic56_operations.js |
Sintassi helper E2E report operation signing | Passato |
node -c test_e2e/scripts/product_ready/product-ready-v2-anti-slop.spec.js |
Sintassi gate V2 | Passato |
BASE_URL=http://localhost:8065 QA_GATE_RUN_ID=product-v2-anti-slop-local-final-2 npx playwright test --project=product-ready --grep "product_ready_v2 anti-slop" --reporter=line |
Anti-slop su firma report, archivio, copy notai | Passato |
COMPOSE_PARALLEL_LIMIT=1 DOCKER_BUILDKIT=1 docker compose -f docker-compose.demo.yml --env-file .env.demo build app |
Rebuild runtime demo con GOMAXPROCS=4 |
Passato |
QA_GATE_ENV=docker QA_GATE_RUN_ID=epic66-merge-local-fixed-20260426T150321Z bash scripts/qa-gate.sh merge_gate |
EPIC66 merge gate Docker | Passato: merge_ready, 59/59 scenari, 8/8 gate |
QA_GATE_ENV=docker QA_GATE_RUN_ID=product-ready-local-receiptfix-20260426T151735Z BASE_URL=http://localhost:8065 npx playwright test --project=product-ready test_e2e/scripts/product_ready/product-ready-matrix.spec.js --reporter=line |
Journey product-ready reale: tenant, DG, firma GoeSign report, archivio, evidence pack | Passato |
QA_GATE_ENV=docker QA_GATE_RUN_ID=epic66-full-local-20260426T151855Z BASE_URL=http://localhost:8065 bash scripts/qa-gate.sh full |
Full regression Docker EPIC66 + product-ready | Passato: merge_ready, 80/80 scenari, 10/10 gate |
8. Nuova matrice operativa per chiudere davvero¶
Per arrivare al 100% vendibile, la prossima chiusura deve produrre un sidecar product-ready-v2-gate.json con 10 righe corrispondenti alla matrice sopra. Ogni riga deve contenere:
{
"id": "PV2-001",
"promise": "...",
"ui_route": "...",
"db_evidence": ["..."],
"document_evidence": ["..."],
"test_result": "pass|fail",
"fixture_level": "none|demo_data_only|db_seeded",
"verdict": "green|partial|blocked"
}
Regola fondamentale: fixture_level=db_seeded non può chiudere una promessa vendibile. Può solo preparare dati di contesto non critici.
9. Direzione prodotto¶
La direzione corretta non è aggiungere altre dashboard. Il prodotto vendibile deve avere un kernel semplice:
flowchart LR
Tenant["Tenant setup"] --> Operation["Operazione AML"]
Operation --> Tasks["Checklist e downstream KYC/KYB"]
Tasks --> Agents["Skill/AI run governate"]
Agents --> Human["Approvazione umana"]
Human --> Report["Report difendibile"]
Report --> Sign["Firma GoeSign/passkey"]
Sign --> Archive["Archivio Unico + pacchetto evidenze"]
Archive --> QA["QA product-ready no-fixture"]
Tutto ciò che non si collega a questo flusso è candidato a rimozione, nascondimento superadmin o deprecazione.
10. Conclusione¶
Questa passata ha corretto un P0 reale: la firma del report Operazione AML non è più una mutazione server-side diretta e non difendibile. Ha inoltre eliminato copy legacy imbarazzante su superfici notarili e impedito JSON grezzo nei download archivio UI.
La prossima soglia non deve essere un’altra lista di route verdi. Deve essere un test umano-simulato no-fixture che dimostra: nuova operazione → task reali → AI output reale → approvazione DG → report → GoeSign → Archivio Unico → pacchetto evidenze.
Fino a quel test, la dicitura corretta è: demo guidata molto più difendibile, non ancora prodotto vendibile senza regia tecnica.
11. EPIC67 — chiusura "Product Ready No-Fixture"¶
EPIC67 introduce la suite Playwright richiesta al §10:
test_e2e/scripts/product_ready/product-ready-no-fixture.spec.js. Esegue due
casi (Notaio + CASP OTC) end-to-end senza fixture sulle azioni utente
critiche e produce un sidecar JSON con la matrice di vendibilità 1-10
(PVNF-001..010).
Evidenze locali EPIC67:
qa-reports/epic67-local-20260426T212351Z/gates/product-ready-no-fixture-gate.json:merge_ready, 20/20 PVNF pass.qa-reports/epic67-local-stability2-20260426T212535Z/eqa-reports/epic67-local-stability3-20260426T212659Z/: stabilità 2×, 40/40 PVNF pass.qa-reports/fc5056c0-4f02-435b-a3b3-e0f1bbcf8e27/report.md: wrapper ufficialeproduct_ready,merge_ready, 41/41 scenari pass.qa-reports/50b5e78b-5b2b-475a-a4d5-a34d5ba470d8/report.md: regressionmerge_gate,merge_ready, 59/59 scenari pass.
Evidenze produzione EPIC67:
qa-reports/deploy/20260426T222257Z-220d91e4c/deploy-gate.json: deploy probe exit 0; health, GoeSign, LLM e anti-fixture probe ok.qa-reports/epic67-prod-final-20260426T222350Z/gates/product-ready-no-fixture-gate.json:merge_ready, 20/20 PVNF pass suhttps://aml.rivdigital.it.
Il prodotto è dichiarato "Vendibile" per il journey minimo EPIC67 Notaio +
CASP OTC perché i sidecar locale e produzione hanno entrambi
verdict=merge_ready. Vedi specs/067-product-ready-no-fixture/quickstart.md
per il comando one-liner.