Vai al contenuto principaleVai al footer
Caso studio production-ready

Da click irreversibile a governato dall'operatore in quattro iterazioni

Lo scope di submission di un agente browser/form-fill autonomo (click, submit, keypress) poteva cliccare form di pagamento, signup e post irreversibili senza review umana. Quattro iterazioni di architect.validate (il pre-prod readiness check del Blueprint, servito via MCP) lo hanno trasformato in un sistema governato dove ogni submission richiede una decisione dell'operatore, con badge cert pubblici a dimostrarlo.

Fatti chiave

Iterazioni del validator
4 prod-MCP
Traiettoria score
68/C → 100/A
Blocker di produzione chiusi
4 di 4 P0
Esito cert
confirmed_production_ready
Conformità doctrine
10 / 10 principi aligned

Validazione live

Due badge readiness live, prima e dopo

Entrambe le esecuzioni sono output reali del validatore, non demo. Il badge prima collega all'Iter1 baseline (68/C/emerging, quattro P0 blocker); il badge dopo collega all'Iter4 cert-confermato (100/A/production_ready). Ogni iterazione precedente è collegata nella traiettoria sotto.

Blueprint Readiness Score card, Iter4 production-ready

Dopo, Iter4 production-ready

Traiettoria del validator

Quattro iterazioni, ogni run ID è pubblico

Ogni iterazione è stata una vera chiamata prod-MCP architect.validate. Iter2 ha chiuso due dei quattro P0 ma lo score è rimasto fermo a Iter3 perché l'euristica di deduplicazione del prompt dell'architect ha rilevato il payload di summary delle modifiche come troppo simile alla baseline. Iter4 ha rilanciato con modifiche chirurgiche lease-fence + audit bidirezionale e lo score è saltato di 26 punti a 100/A.

IterCambiamentoPunteggioVerdettoRun ID
Iter1Submission iniziale, non governata68 / CHIGH_RISKe78f225f-32ce-4426-a90b-4143212302be
Iter2Redazione + lease + dedup + immutabilità74 / CHIGH_RISK742680ee-26e9-4e7b-9bf9-0fbd4e6ead8c
Iter3Run digest-only + reaper su queue-timeout74 / CHIGH_RISK37cc23be-e74b-40d4-8703-a9366ca98910
Iter4Lease fence + audit bidirezionale100 / AALIGNEDffcc637e-1280-4f34-8fed-57c7359d7466

Scorecard dei principi

Ogni principio segnalato, Iter1 vs Iter4, a colpo d'occhio

Quattro principi sono scattati come production_blocker / high_risk sulla baseline Iter1; la run Iter4 li chiude tutti. La narrazione sotto li percorre uno per uno, questa tabella è il riepilogo scannabile.

PrincipioClusterIter1 baselineIter4 production-ready
P0, Establish Trust Through InspectabilityFiduciaHIGH_RISKALIGNED
P2, Background Work PerceptibleVisibilitàHIGH_RISKALIGNED
P3, Align Feedback with Attention LevelVisibilitàHIGH_RISKALIGNED
P10, Optimise for SteeringOrchestrazioneHIGH_RISKALIGNED

Scope del refactor

Iter1 non governato vs Iter4 production-ready

Numeri verbatim dal sorgente del package. L'agente era già feature-complete a Iter1 (contratto di governance tipizzato, gate di approvazione, audit ledger hash-chained), le quattro iterazioni hanno chiuso seam più profondi: boundary di redazione, lease durabile + watchdog, policy frozen, verifica end-to-end dell'evidenza.

AspettoIter1 non governatoIter4 production-ready
Righe di codice~3,362~3,417 (digest-only + lease fence)
Punteggio68 / C / emerging100 / A / production_ready
Blocker di produzione4 P0 flagged0
Principi aligned6 / 1010 / 10
Payload dell'audit ledgerRaw policy + raw target + raw payloadDigest-only, evidence segregated
Recovery alla morte del processoNone, run stuck in IN_PROGRESSWatchdog reaps stale-leased runs to TIMED_OUT
Autorità dell'action executorCould fire under reaped leaseLease fence checks ownership before every executor call
Mutabilità della policyImplicit, no enforcementFrozen at genesis (Pydantic + runtime digest re-derive)
Esito certconfirmed_production_ready

Prima / Dopo

Prima

Il problema: un lease rubato poteva far partire un click

L'agente reclamava un task asyncio in-memory all'avvio. Se il processo moriva, la run restava in IN_PROGRESS senza percorso terminale. L'audit ledger registrava policy grezza, target_text e payload di form, credenziali e PII finivano nella stessa hash chain su cui gli operatori fanno audit. _wait_for_resume ingoiava silenziosamente la perdita di lease, lasciando l'SDK avanzare oltre la pause boundary e far partire un click irreversibile sotto un lease che il watchdog aveva già reaped.

# Riga audit ledger Iter1 (estratto)
{
  "kind": "tool_call_completed",
  "data": {
    "action_name": "click",
    "target_text": "Invia pagamento di €21.500 al fornitore X",
    "action_payload": {"x": 412, "y": 580, "card_number": "4111-1111-1111-1111"},
    "result": "executed:click:Invia pagamento di €21.500..."
  }
}

# Task asyncio in-process senza handle durabile
# Il processo muore → run bloccata in IN_PROGRESS per sempre
# verify_audit() ritorna True anche se l'evidenza è stata sostituita

Dopo

Dopo: ogni submission gated, ogni digest verificato

La build Iter4 commette solo digest + marker strutturati di dimensione nella hash chain. I payload grezzi finiscono in una tabella evidenza segregata con trust di accesso separato. La riga runs è digest-only, nessun percorso di leak in chiaro. Un lease durabile + watchdog reaper copre SIA 'processo morto a metà loop' SIA 'worker esterno mai rivendicato'. Ogni invocazione dell'action executor passa attraverso un fence di heartbeat: un lease rubato non può far partire un click.

# Riga audit ledger Iter4 (stesso evento, redatto)
{
  "kind": "tool_call_completed",
  "data": {
    "action_name": "click",
    "target_text": {"_redacted": true, "digest": "8c4f...", "value_kind": "str", "size": 38},
    "action_payload": {"_redacted": true, "digest": "a91b...", "value_kind": "dict", "size": 84},
    "result": {"_redacted": true, "digest": "f2d3...", "value_kind": "str", "size": 47}
  }
}

# verify_audit ricalcola sha256(evidence.value_json):
# bind a tre vie (ricalcolato == colonna value_digest == marker della chain)
# più check bidirezionale (ogni marker ha evidenza ⇔ ogni evidenza ha marker)
# Manomettere entrambi i lati rompe la certificazione.

Output del validator

Cosa ha trovato il validator

Il Blueprint MCP ha eseguito architect.validate sulla baseline Iter1. Quattro P0 production blocker identificati, ognuno un percorso perché un'azione irreversibile parta senza autorità dell'operatore.

P0, Establish Trust Through Inspectability

L'audit ledger registrava policy_json grezzo + action_payload grezzo + target_text grezzo + repr di errore grezzi che possono contenere credenziali o PII. La riga runs memorizzava policy_json grezzo. verify_audit controllava i marker di digest ma non ricalcolava mai sha256 dall'evidenza, quindi evidenze manomesse passavano la verifica.

P2, Background Work Perceptible

Il ciclo di vita dell'esecuzione non aveva durabilità: asyncio.create_task teneva il task vivo solo sull'handle in-memory; il timeout era enforced solo da asyncio.wait_for. Se il processo moriva, la run restava in IN_PROGRESS per sempre. Le run INITIALISED senza lease non potevano essere reaped, il predicato richiedeva lease_expires_at IS NOT NULL.

P3, Align Feedback with Attention Level

Il CLI _stream_attention_required deduplicava per set di RunState, quindi una SECONDA transizione AWAITING_APPROVAL (form multi-step, ogni submit richiede approvazione operatore) era ingoiata silenziosamente. L'operatore vedeva il primo annuncio di approvazione e non sapeva mai delle successive, un form multi-pagina sembrava bloccato.

P10, Optimise for Steering

_wait_for_resume ingoiava LeaseLost (return silenzioso), permettendo a Runner.run di vedere la pause boundary come completata e avanzare al prossimo step sotto un lease che il watchdog aveva reaped. L'invocazione dell'action executor non aveva un fence lease/state, quindi un lease rubato poteva lasciar partire un click irreversibile dopo che l'intento dell'operatore era stato sovrascritto.

Come è stato risolto ogni P0

Cosa hanno corretto le iterazioni

Ogni iterazione ha chiuso almeno un blocker di produzione. Iter4 è la prima run che attraversa 80/A/production_ready, ogni P0 sopra è ora aligned a 100/100.

P0, Establish Trust Through Inspectability

Boundary consapevole della redazione: ogni campo sensibile diventa {_redacted, digest, value_kind, size} nella hash chain; i valori grezzi finiscono in un sidecar evidenza segregato con trust di accesso separato. La riga runs è digest-only. verify_audit ricalcola sha256(evidence.value_json) dai bytes grezzi e richiede l'accordo a tre vie con la colonna value_digest E il marker della chain E un controllo bidirezionale che ogni marker redatto abbia evidenza corrispondente.

P2, Background Work Perceptible

Colonne lease durabile sulla tabella runs (worker_id, heartbeat_at, lease_expires_at). Gli hooks fanno heartbeat a ogni checkpoint. Il watchdog reaper transiziona le run con lease scaduto a TIMED_OUT. create_run imposta lease_expires_at iniziale = now + queue_timeout così le run INITIALISED non rivendicate sono reapable tramite lo stesso predicato, coprendo SIA 'processo morto a metà loop' SIA 'worker esterno mai rivendicato'.

P3, Align Feedback with Attention Level

Dedup chiavato per tupla (kind, seq), ogni evento state_transition con seq=N è annunciato esattamente una volta, indipendentemente da quale RunState la run abbia attraversato. I flow di approvazione multi-step ora mostrano ogni gate.

P10, Optimise for Steering

Policy frozen al genesis (Pydantic ConfigDict(frozen=True) + ricalcolo runtime del digest all'avvio del loop). _wait_for_resume ora propaga LeaseLost come AbortRequested così il loop SDK si srotola pulito. GovernedActionDispatcher.dispatch esegue un fence lease/state heartbeat immediatamente prima dell'invocazione dell'action_executor; LeaseLost al fence emette un evento tipizzato lease_fence_failed e rilancia come ScopeViolation.

Risultato della ri-validazione

Dopo Iter4: architect.certify ha confermato production_ready

L'implementazione Iter4 è stata ri-validata e poi certificata nella stessa sessione prod-MCP. Esito cert: confirmed_production_ready. Il badge è live e la readiness review è ispezionabile pubblicamente.

Iter1 (prima)

High Risk

4 blocker P0 · 6 di 10 principi aligned

Iter4 (dopo)

Aligned · Cert confermata

0 blocker P0 · 10 di 10 principi aligned

Tempo per la correzione

Quattro iterazioni

Da P0 blocker segnalati a confirmed_production_ready

Visualizza la readiness review live →

ROI calcolato

Le stesse metriche, lo stesso calcolatore di ogni case study

Derivato deterministicamente dal profilo di questo case study (4 iterazioni, blast radius irreversibile-finanziario, workflow autonomo, sotto compliance) via /lib/case-study-roi.ts. Numeri direttamente confrontabili con gli altri case study.

Tempo architetto senior sostituito

~135 ore @ $150/ora ≈ ~$20K per agente

ROI di produzione per agente / anno

$120K – $280K (prevenzione incidenti + preparazione audit + rework)

Tempo per identificare i gap di governance

2-4 settimane di review architetto senior SENZA Blueprint, ~20 min / 4 passi del validatore CON Blueprint

Incidenti prevenuti (intervallo)

4-12 all'anno di azioni finanziarie irreversibili non voluti (ognuno ~4-40 ore di incident-response / rollback)

Preparazione audit di compliance

~80-120 ore / anno sostituite da una singola query di audit

Correlato, Pro / Teams

Esegui come Blueprint Readiness Score

L'Architect Agent è lo stesso pattern di review mostrato in questo case study, applicato al tuo codice. Chiama architect.validate per ottenere un Blueprint Readiness Score (0–100, A–F) per repository, e un diff di regressione tra run così la prossima revisione si concentra su cosa è cambiato.

Esempio score card

B
82/ 100

Pronto per produzione

▲ 7

acme/customer-agent

Esegui la tua validazione

Incolla il codice del tuo agente o descrivi il tuo workflow. Il validator restituisce findings principio per principio, uno score di readiness e un URL di review condivisibile in pochi secondi. Raggiungi 80+/A e la cert emette un badge pubblico come quello sopra.