Vai al contenuto principaleVai al footer
Caso studio production-ready

Da fabbricazione silenziosa di bonifici a cert confermata in dieci iterazioni

Uno script Python di 156 righe drafta bonifici, ingoia errori, e poteva marcare trasferimenti SUCCEEDED senza mai parlare con una banca reale. Dieci iterazioni di architect.validate + quattro review second-pass di architect.certify sul MCP di produzione. Validate è la review first-pass principio per principio; certify è un reviewer adversarial second-pass che gira solo dopo che validate ha allineato e cerca production blocker che il passo dei principi non può vedere. Il cert reviewer ha catturato un fallimento load-bearing diverso ogni volta, false-COMPLETE via task ancora AWAITING, false-COMPLETE nonostante FAILED stale, banca stubbata nell'audit, errore nella projection del money-at-risk, blocker non durabile tra passi. Iter 10 è la prima run in cui validate E cert passano entrambe pulite.

Fatti chiave

Iterazioni del validator
10 prod-MCP
Chiamate cert
4 review second-pass
Traiettoria score
0/F → 100/A
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 validator, non demo. Il badge prima collega all'Iter1 baseline (0/F/draft, lo script non governato completo); il badge dopo collega all'Iter10 cert-confermato (100/A/production_ready). Ogni iterazione intermedia è collegata nella traiettoria sotto.

Blueprint Readiness Score card, Iter10 cert-confirmed

Dopo, Iter10 cert-confermato

Traiettoria validator + cert

Dieci iterazioni, ogni run ID è pubblico

Ogni iterazione è una vera chiamata prod-MCP architect.validate. Iter 4, 5, 6 hanno poi preso review second-pass di architect.certify e ognuna ha downgrade lo score da 100/A a 74/C/emerging perché il cert reviewer ha catturato un fallimento production-blocking diverso ad ogni passo. Iter 7-9 sono poi regredite su validate quando i fix del cert-layer hanno smascherato gap più profondi. Iter 10 è la prima run in cui validate E cert passano entrambe pulite, il cert reviewer ha trovato zero blocker mancati.

IterCambiamentoPunteggioValidateCertRun ID
Iter1Script originale di 156 righe, niente audit, niente run_id, niente gate di approvazione0 / FHIGH_RISKac64d7d9-ce25-4d63-8537-4d866d78b8f1
Iter2Aggiunto datetime tz-aware + superficie run_id + enum di stato per-task30 / FHIGH_RISKb8d61c00-2b86-45f0-a533-526202371592
Iter3Audit ledger hash-chained + envelope di approvazione firmata60 / CHIGH_RISK15aa9649-84d8-4a75-aec7-fd101a5b0535
Iter4Rifiuto approvazioni su run terminali (cert downgrade: false-COMPLETE via task ancora AWAITING)74 / CALIGNED74 / C7e9bc0f6-8fd3-4586-851f-d26b720ac767
Iter5Run-status dalla projection completa dei task (cert downgrade: false-COMPLETE nonostante FAILED stale)74 / CALIGNED74 / Cb4799966-efdb-4f2a-8f07-44811ecb7ff1
Iter6BANK_MODE env esplicito + tag mock=True (cert downgrade: bank stubbato → SUCCEEDED nell'audit)74 / CALIGNED74 / Cdd3a9348-7c1b-488e-930a-7f77d433aa6c
Iter7Except ampio + contratto tipizzato `confirmed=True` (regressione validate: il fix di iter-6 ha smascherato gap più profondi)40 / DHIGH_RISKb1195c34-8d8a-495e-a91a-d30ed551ecc3
Iter8Stato SIMULATED_SUCCEEDED + evento submission_blocked (regressione validate: SUBMITTED_UNKNOWN non consuma il budget)30 / FHIGH_RISK5c1d5833-5f29-462f-b1a8-e774498c40fb
Iter9Budget guard da projection + reconcile broad-except (regressione: blocker non durabile tra passi)60 / CHIGH_RISK039064f9-c4e9-45de-8c16-1c160a01fca1
Iter10Preflight durabile + stati BLOCKED_ON_RECONCILIATION + CANCELLATION_PENDING_RECONCILIATION. Cert second-pass: confermato.100 / AALIGNEDConfirmed29b080f4-b9a3-439d-bb07-cf666a18300d

Valore del mandato cert

Ogni chiamata cert ha catturato ciò che il fix precedente aveva smascherato

Il validate di first-pass da solo ha restituito aligned tre volte di fila (Iter 4-6). Tre volte di fila il cert reviewer second-pass ha portato in superficie un fallimento production-blocking che la review first-pass non poteva vedere. Ogni fix del cert finding scatenava un NUOVO fallimento che diventava raggiungibile solo perché il fix precedente esisteva. Questo è l'argomento load-bearing per la certificazione second-pass a strati.

False-COMPLETE via task ancora AWAITING (P8 sev 88)

execute_approved_payments() iterava sui task APPROVED, skippava ogni task non-APPROVED senza controllare, poi impostava incondizionatamente RunStatus.COMPLETED. Qualsiasi task lasciato in AWAITING_APPROVAL aveva la sua run marcata COMPLETED pur restando non pagata.

Fix: Contare i task actionable prima della transizione terminale; tenere in AWAITING_APPROVAL se ne restano. Rifiutare approvazioni su run terminali.

False-COMPLETE nonostante FAILED stale (P8 sev 9)

any_failed si resettava ad ogni chiamata; i task FAILED da chiamate precedenti venivano ignorati. Un secondo passo con un nuovo SUCCEEDED poteva marcare COMPLETED mentre task FAILED vecchi restavano non pagati.

Fix: Derivare lo stato terminale dalla projection di tutti i task (failed_total, succeeded_total, actionable_total). Mai da un flag per-passo.

Esecuzione bank stubbata registrata come SUCCEEDED (P5 sev 10)

transfer_funds() restituiva un dict di successo fabbricato senza chiamare alcuna banca reale. L'audit ledger registrava SUCCEEDED con un mock transfer_id; un auditor leggendo il ledger non poteva distinguere mock da reale.

Fix: BANK_MODE env esplicito (live|mock), fail-closed su ambiguità; risposte mock taggate mock=True; rifiutare auto-promozione mock→SUCCEEDED.

✅ confirmed_production_ready · zero blocker mancati

Il reviewer adversarial second-pass non ha trovato alcun production_blocker, percorso silenzioso a risultato errato, o bypass del trust-boundary. Sommario verbatim: "il codice implementa visibilmente blocco durabile della riconciliazione per handoff bancari ambigui, stati cancellation-pending espliciti, controlli approval/hash firmati, ispezionabilità audit/inbox."

Fix: Badge cert emesso. Review URL pubblico è live.

Scorecard dei principi

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

Cinque principi nella traiettoria sono scattati come production_blocker / high_risk su almeno un passo validate o cert; la run Iter10 li chiude tutti. La narrazione sotto li percorre uno per uno, questa tabella è il riepilogo scannabile.

PrincipioClusterPicco traiettoriaIter10 production-ready
P1, Design for DelegationAutoritàHIGH_RISKALIGNED
P5, Replace Implied Magic with Clear Mental ModelsFiduciaHIGH_RISKALIGNED
P6, Expose Meaningful Operational StateVisibilitàHIGH_RISKALIGNED
P8, Make Hand-offs and Blockers ExplicitOrchestrazioneHIGH_RISKALIGNED
P10, Optimise for SteeringOrchestrazioneHIGH_RISKALIGNED

Scope del refactor

Iter1 non governato vs Iter10 cert-confermato

Numeri verbatim dal sorgente del package. Lo script originale di 156 righe non aveva audit, niente run_id, niente approval, niente idempotency, niente recovery. Iter 10 è ~2.384 righe perché il cert reviewer ha portato in superficie un fallimento load-bearing diverso ad ogni chiamata cert, ogni riga ha guadagnato il proprio posto contro un finding specifico.

AspettoIter1 non governatoIter10 cert-confermato
Righe di codice156~2,384 (durable preflight + 11-state lifecycle + projection-aware cancel)
Punteggio0 / F / draft100 / A / production_ready
Principi aligned0 / 1010 / 10
Iterazioni validate10 prod-MCP runs
Chiamate cert (second-pass)4 (Iter 4, 5, 6 downgrade · Iter 10 confirmed)
Stati ciclo di vita run1 (PENDING)11 (incl. BLOCKED_ON_RECONCILIATION, CANCELLATION_PENDING_RECONCILIATION)
Esiti handoff banca modellati1 (success)5 (FAILED · SUBMITTED · SUBMITTED_UNKNOWN · SUCCEEDED · SIMULATED_SUCCEEDED)
Audit ledgerNoneHash-chained JSONL with verify_chain() tamper detection
Gate di approvazioneNoneHMAC-SHA256 envelope bound to run_id, task_id, policy_hash, invoice_snapshot_hash, approver role
Esito certconfirmed_production_ready · 0 findings

Prima / Dopo

Prima

Il problema: ogni garanzia load-bearing era assente

Lo script originale draftava fatture, chiamava transfer_funds(), e ritornava. Non c'era run_id, quindi un crash di processo a metà run non lasciava alcuno stato recuperabile. Il blocco except ingoiava ogni eccezione silenziosamente. Non c'era gate di approvazione, lo script pagava in automatico ogni fattura classificata eligible. Non c'era idempotency key, quindi un retry pagava due volte. La storia di audit era un singolo print() alla fine del loop.

# Iter1 baseline (estratto, file completo è 156 righe)
def execute_invoice_run():
    invoices = fetch_due_invoices()
    for invoice in invoices:
        if eligible_for_auto_pay(invoice):
            try:
                response = transfer_funds(
                    iban=invoice.iban,
                    amount=invoice.amount_pence,
                    currency=invoice.currency,
                )
                print(f"Paid {invoice.invoice_id}: {response}")
            except Exception:
                pass  # silenzioso

# Niente run_id. Niente gate di approvazione. Niente idempotency.
# Niente audit. Niente recovery. Crash a metà loop = richieste banca orfane.
# Retry = doppio pagamento. Stub API banca = audit ledger mente.

Dopo

Dopo: preflight durabile, cancel projection-aware, approval firmata, audit hash-chained

Iter 10 rifiuta di fare qualsiasi chiamata bancaria mentre un task SUBMITTED_UNKNOWN esiste, il preflight durabile è il fix load-bearing di P8. Cancel durante esposizione transita a CANCELLATION_PENDING_RECONCILIATION (non CANCELLED terminale). Ogni approvazione è HMAC-bound a run_id + task_id + policy_hash + invoice_snapshot_hash + ruolo approver, falsificare richiede il segreto. L'audit ledger è JSONL hash-chained; verify_chain() rileva qualsiasi modifica post-hoc. Le submission mock prendono TaskStatus.SIMULATED_SUCCEEDED + un campo simulated:bool, mai confuse con conferma bancaria reale in nessuna superficie di audit.

# Iter10 cert-confermato: preflight durabile pre-execute
def execute_approved_payments(self, *, run_id):
    run = self._require_run(run_id)
    # Iter 10 P8 cert-fix: rifiuta di iniziare un passo di submission
    # mentre QUALSIASI task è SUBMITTED_UNKNOWN. Blocker è durabile
    # tra chiamate. L'operatore DEVE riconciliare l'esposizione
    # bancaria esistente prima di qualsiasi nuova chiamata bancaria.
    unresolved = [
        t for t in self.tasks[run_id].values()
        if t.status == TaskStatus.SUBMITTED_UNKNOWN
    ]
    if unresolved:
        self.ledger.append(
            run_id=run_id, task_id=None,
            event_type="run.execution_blocked_on_unresolved_exposure",
            payload={
                "unresolved_task_ids": [t.task_id for t in unresolved],
                "required_action": "reconcile_submitted_task o confirm_mock_simulation",
            },
        )
        run.status = RunStatus.BLOCKED_ON_RECONCILIATION
        return run  # NESSUNA chiamata banca. NESSUNA nuova esposizione.
    # ...

Output del validator

Cosa ha trovato il cert reviewer

Il Blueprint MCP ha eseguito architect.validate dieci volte e architect.certify quattro volte contro questo codice. Cinque blocker di produzione a livello di principio sono stati identificati nella traiettoria, ognuno un percorso perché un bonifico irreversibile parta sotto condizioni che l'operatore non ha mai autorizzato.

P1, Design for Delegation

execute_approved_payments() incrementava il contatore di budget (run_total_submitted) solo quando un task raggiungeva SUCCEEDED. Dopo che SUBMITTED_UNKNOWN è diventato raggiungibile (iter 8), un task in quello stato, dove la banca potrebbe già aver accettato il trasferimento, era invisibile al check del cap. Il loop continuava a sottomettere fatture, sforando policy.max_run_total_pence fino al ~20% nel caso peggiore (3 × £40k contro un cap di £100k).

P5, Replace Implied Magic with Clear Mental Models

Iter 6 transfer_funds() stubbato restituiva un dict di successo sintetico senza mai chiamare una banca reale. L'audit ledger registrava task.succeeded con un mock transfer_id, indistinguibile da un successo bank-confirmed reale. Il modello mentale che l'operatore vedeva, "l'agente ha pagato il fornitore", era disaccoppiato da ciò che era realmente accaduto, "l'agente ha fabbricato metadata di successo".

P6, Expose Meaningful Operational State

Dopo un handoff bancario ambiguo la run restava in RunStatus.AWAITING_APPROVAL, uno stato la cui etichetta suggerisce che il compito dell'operatore sia approvare la prossima cosa. Il compito reale era RICONCILIARE l'esposizione esistente. Il nome dello stato mentiva all'operatore su cosa fosse necessario; lo stesso disallineamento viveva sul percorso di cancel, dove una run poteva diventare terminale CANCELLED mentre l'esposizione bancaria restava non risolta.

P8, Make Hand-offs and Blockers Explicit

Iter 9 ha aggiunto un halt nel passo su SUBMITTED_UNKNOWN, ma il blocker non era durabile tra chiamate. Un secondo execute_approved_payments() avrebbe skippato il task unknown (non era più APPROVED), ricalcolato la projection del budget, e sottomesso la prossima fattura approvata se restava spazio nel cap. L'esposizione bancaria poteva accumularsi su due richieste outstanding con la prima non riconciliata.

P10, Optimise for Steering

cancel_run() flippava run.status a CANCELLED terminale incondizionatamente; anche quando restavano task SUBMITTED / SUBMITTED_UNKNOWN. _reconcile_run_status() ritornava presto su run terminali, quindi nessuna riconciliazione successiva poteva sistemare lo stato top-level. Un operatore poteva cancellare una run che aveva ancora richieste bancarie outstanding e perdere la capacità dell'audit di distinguere "riconciliato e cancellato" da "cancellato mentre i soldi si stavano ancora muovendo".

Come è stato risolto ogni blocker

Cosa hanno corretto le iterazioni

Ogni iterazione ha chiuso almeno un blocker di produzione. Iter 10 è la prima run in cui ogni principio segnalato raggiunge aligned e il cert reviewer second-pass trova zero blocker mancati.

P1, Design for Delegation

Proiettare l'esposizione a rischio dall'intero insieme di task, incluso SUBMITTED_UNKNOWN e SIMULATED_SUCCEEDED, prima di ogni submit. Il check del cap ora gira contro il worst-case money-at-risk, non solo il successo confermato.

P5, Replace Implied Magic with Clear Mental Models

BANK_MODE env esplicito (live|mock), fail-closed su ambiguità. Risposte mock taggate mock=True. Nuovo TaskStatus.SIMULATED_SUCCEEDED + campo simulated:bool sui task, esposti separatamente in inspect_run() così un reviewer non può mai confondere mock-confermato con bank-confermato.

P6, Expose Meaningful Operational State

Due nuovi stati run espliciti. BLOCKED_ON_RECONCILIATION sostituisce AWAITING_APPROVAL quando l'azione dominante è riconciliare-non-approvare. CANCELLATION_PENDING_RECONCILIATION sostituisce CANCELLED terminale mentre l'esposizione SUBMITTED / SUBMITTED_UNKNOWN resta; solo dopo che l'esposizione si chiude via reconcile / confirm-mock la run transita a CANCELLED terminale.

P8, Make Hand-offs and Blockers Explicit

Preflight durabile pre-execute in cima a execute_approved_payments(). Scansionare la projection dei task; se esiste un SUBMITTED_UNKNOWN, appendere run.execution_blocked_on_unresolved_exposure, postare un alert critico nell'inbox, transizionare la run a BLOCKED_ON_RECONCILIATION, e ritornare senza fare alcuna chiamata bancaria. Solo reconcile_submitted_task() / confirm_mock_simulation() possono chiudere il blocker.

P10, Optimise for Steering

cancel_run() è ora projection-aware. Con esposizione bancaria in-flight transita a CANCELLATION_PENDING_RECONCILIATION (non CANCELLED terminale). _reconcile_run_status() esclude ora gli stati pending dalla sua early-return list, così una volta che l'esposizione si chiude via reconcile / confirm-mock, la run promuove a CANCELLED terminale con piena continuità dell'audit-chain.

Risultato della ri-validazione

Iter 10: architect.certify ha confermato production_ready

L'implementazione di Iter 10 è stata ri-validata a 100/A/production_ready, poi certificata nella stessa sessione prod-MCP. L'esito cert è stato confirmed_production_ready, zero certification_findings. Sommario verbatim dal cert reviewer: "il codice implementa visibilmente blocco durabile della riconciliazione per handoff bancari ambigui, stati cancellation-pending espliciti, controlli approval/hash firmati, ispezionabilità audit/inbox, e nessun crash production-blocking specifico, percorso silenzioso a risultato errato, o bypass del trust-boundary è evidenziato."

Iter1 (prima)

High Risk · 0/F

0 di 10 principi aligned · niente audit · niente gate di approvazione

Iter10 (dopo)

Aligned · Cert confermata

10 di 10 principi aligned · 0 blocker mancati

Tempo per la correzione

Dieci iterazioni

Quattro chiamate cert · tre downgrade catturati · una conferma cert

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 (10 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

~255 ore @ $150/ora ≈ ~$38K 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, ~50 min / 10 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 architect.certify emette un badge pubblico come quello sopra, dopo una review adversarial second-pass.