Salta al contenuto principale

Progettare una Dark Factory AI Semi-Deterministica

Indice dei contenuti
Cosa succederebbe se un requisito di business potesse ispezionare il sistema a cui si riferisce, mettere in discussione le proprie ambiguità, diventare una specifica eseguibile e attraversare implementazione, review, deploy e acceptance test senza perdere il controllo umano? Ecco come abbiamo costruito una linea di produzione semi-deterministica attorno ad agenti probabilistici.

La maggior parte delle discussioni sullo sviluppo assistito dall’AI parte troppo tardi. Parte da un coding agent e da un prompt.

La parte difficile non è produrre codice. È trasformare una richiesta di business imprecisa in un requisito coerente con il sistema esistente, abbastanza circoscritto da essere implementato e abbastanza preciso da essere testato. Se l’input è debole, aggiungere altri agenti significa soltanto automatizzare l’ambiguità.

Abbiamo separato il problema in due sistemi:

  1. Il Requirements Agent trasforma l’intento di business in una specifica testabile e basata sul repository.
  2. La Dark Factory trasforma la specifica approvata in codice revisionato, lo valida in un ambiente reale e restituisce agli engineer la decisione finale.

Il Requirements Agent vive in TARS, il nostro engineering workbench per agenti conversazionali. TARS è il layer di intake e raffinamento. La Dark Factory è il layer di esecuzione.

La proprietà importante non è l’autonomia. È la progressione controllata attraverso gate espliciti.

Questa non è più soltanto un’architettura sulla carta. Nella sua prima esecuzione autonoma completa, la piattaforma ha lavorato per cinque ore implementando una funzionalità per se stessa, da un requisito approvato fino al deploy in un ambiente cloud di test. Ha recuperato errori di rete transitori senza intervento umano e ha completato l’intera parte automatizzata del ciclo SDLC senza escalation.

Il Flusso End-to-End
#

flowchart LR
    B[Requisito di business] --> R[Requirements Agent]
    R --> Q{Gap o blocker?}
    Q -->|Sì| A[Q&A a risposta chiusa]
    A --> R
    Q -->|No| S[Specifica eseguibile]
    S --> H1[Review degli engineer]
    H1 --> P[Planner Agent]
    P --> C[Loop seriale dei task]
    C --> E[Deploy nell'account AWS UAT]
    E --> U[UAT Agent indipendente]
    U -->|Fallisce| C
    U -->|Passa| D[Documentation Agent]
    D --> H2[MR finale per gli umani]

Gli umani approvano la specifica prima dell’implementazione e mantengono il merge finale. Tutto ciò che sta tra questi due gate è automatizzato, osservabile e recuperabile.

La Prima Esecuzione di Cinque Ore
#

La prima esecuzione completata con successo ha implementato un redesign dell’esperienza agentica della piattaforma stessa:

  • Un drawer riutilizzabile per avviare gli agenti dalla sidebar.
  • Un catalogo read-only contenente tutti gli agenti disponibili.
  • Un pannello che espone il system prompt dell’agente selezionato.
  • Una pagina di dettaglio full-width senza la precedente split-view del prompt.
  • Contratti backend, rate limiting e test richiesti dai guardrail del repository.

Il Planner ha prodotto cinque task di implementazione ordinati. La factory ha elaborato un task alla volta, aperto e revisionato cinque MR, eseguito il merge nell’integration branch e prodotto l’handoff finale. Il cambiamento aggregato ha modificato 19 file Go e React, con circa 2.500 righe aggiunte tra backend, middleware, UI, contratti e test.

Il risultato è stato poi compilato e deployato nell’account AWS di test. Test applicativi, controlli statici, build delle immagini, planning infrastrutturale, rollout e health verification hanno fatto parte del percorso di delivery.

La funzionalità è interessante, ma il loop di controllo durato cinque ore è il risultato più importante. Ogni risposta di un agente doveva rimanere compatibile con la successiva transizione di stato. Un piano malformato, un riferimento MR mancante, un verdetto di review obsoleto, un dispatch duplicato o un errore di rete classificato male avrebbero potuto fermare l’esecuzione.

Per questo l’obiettivo ingegneristico è la semi-deterministicità. Non possiamo rendere deterministico un LLM, ma possiamo rendere deterministici l’insieme degli output validi, le transizioni, i side effect e i percorsi di recovery che lo circondano.

Il Requirements Agent Non È un Generatore di Documenti
#

Il Requirements Agent è un chatbot, ma il suo lavoro non è riscrivere un ticket in un inglese migliore. Ha accesso in lettura al repository target, oppure ai repository rilevanti quando il target è un gruppo GitLab.

Prima di fare domande, ricostruisce lo stato corrente:

  • Legge i file CLAUDE.md root e quelli annidati.
  • Ispeziona codice sorgente, configurazione, contratti API, test, migrazioni e file di delivery.
  • Espande gruppi e sottogruppi, poi ordina i repository per rilevanza rispetto all’obiettivo.
  • Identifica i comportamenti già implementati, parzialmente implementati, mancanti o non chiari.
  • Preferisce la modifica minima che soddisfa l’obiettivo e preserva i comportamenti non coinvolti.

Il risultato è una As-Is Baseline. Le domande sono quindi basate sull’applicazione che esiste, non su un ipotetico progetto greenfield.

Per esempio, se la paginazione usa già offset e limit, l’agente non chiede quale stile di paginazione adottare. Registra quella convenzione come guardrail. Se un endpoint di retry esiste già ma la UI non lo espone, il requisito descrive il comportamento mancante nella UI e nell’autorizzazione invece di proporre una seconda API.

flowchart TD
    I[Intento di business + repository] --> X[Raccolta del contesto]
    X --> ASIS[Costruzione As-Is Baseline]
    ASIS --> GAP[Classificazione gap e blocker]
    GAP --> DEC{Rimane un'ambiguità materiale?}
    DEC -->|Sì| QA[Domande a risposta chiusa]
    QA --> ANS[L'utente seleziona le risposte]
    ANS --> ASIS
    DEC -->|No| DOC[Specifica completa]
    DOC --> READY[Readiness: open item = 0]

Gap e Blocker Sono Diversi
#

Un gap è una differenza tra il sistema corrente e il risultato richiesto. L’agente può documentarlo e proporre la modifica con impatto minimo.

Un blocker è una decisione che non può essere dedotta in sicurezza dal codice o dalle policy. Per esempio: quali ruoli possono rilanciare un’esecuzione fallita, se il retry deve essere idempotente, oppure se una migrazione dati può essere distruttiva.

L’agente non deve mai trasformare un blocker in un’assunzione soltanto per terminare il documento.

Un Protocollo, Non Soltanto un Prompt
#

Il loop di raffinamento è applicato tramite tool e stato applicativo. L’agente emette eventi strutturati come:

emit_commentary          spiega l'analisi corrente
emit_document_section    aggiorna una o più sezioni del requisito
emit_questions           presenta domande chiuse e possibili risposte
emit_readiness           dichiara il numero di punti non risolti
retrieve_context         recupera contesto persistito meno recente

L’invariante critica è semplice:

open_items_count > 0  =>  emit_questions è obbligatorio
open_items_count = 0  =>  la specifica può diventare ready

Se il modello emette readiness mentre rimangono open item, l’applicazione rifiuta la transizione e chiede all’agente di continuare. La conversazione non può terminare soltanto perché il modello sembra sicuro.

Le domande chiuse riducono anche la deriva interpretativa. Invece di chiedere “Come deve funzionare il retry?”, l’agente presenta scelte concrete:

  • Il retry crea una nuova esecuzione collegata a quella fallita.
  • Il retry riutilizza l’identificativo originale.
  • Il comportamento già definito da un’API esistente rimane invariato.

L’utente può comunque fornire una risposta personalizzata, ma ogni decisione aperta è esplicita, persistita e tracciabile nel requisito risultante.

Sessioni Lunghe Senza Perdita di Informazioni
#

L’analisi dei repository e i documenti di requisito possono diventare grandi. Reinviare l’intera conversazione al modello a ogni turno finirebbe per esaurire la context window.

La conversazione e il documento completi rimangono quindi persistiti come source of truth. Soltanto la copia inviata al modello viene compattata rispettando un token budget. Quando servono dettagli esatti, l’agente può recuperare un messaggio o una sezione precedente con retrieve_context.

Questo separa due problemi:

  • La persistenza deve essere lossless. Nessun dettaglio del requisito viene troncato silenziosamente.
  • Il contesto di inferenza deve essere limitato. I vecchi scambi di tool non devono essere riprodotti per sempre.

Gli aggiornamenti al documento sono aggregati quando possibile e emit_readiness è terminale quando l’invariante di readiness è soddisfatta. Questo evita una catena di chiamate al modello non necessarie dopo il completamento del documento.

Architettura Applicativa
#

L’utente vede l’applicazione chat React di TARS. Django gestisce autenticazione, conversazioni, documenti, domande, permessi e stato dei job. I turni lunghi sono messi in coda invece di rimanere all’interno di una richiesta HTTP. L’agente viene eseguito in Amazon Bedrock AgentCore con credenziali limitate al repository.

flowchart LR
    UI[UI React per chat e documenti] --> API[API Django]
    API --> DB[(PostgreSQL)]
    API --> QUEUE[Coda worker]
    QUEUE --> AC[Runtime Bedrock AgentCore]
    AC --> GIT[Repository Git, sola lettura]
    AC --> LLM[Foundation model]
    AC --> TOOLS[Tool per eventi strutturati]
    TOOLS --> API
    API --> STREAM[Stream live degli eventi]
    STREAM --> UI

La separazione è importante. AgentCore esegue l’analisi, ma Django possiede lo stato persistente del workflow. La risposta del modello è un input da validare, non un’autorità che può modificare arbitrariamente lo stato applicativo.

Com’è Fatto un Requisito Ready
#

Un requisito completo può essere lungo, ma la sua struttura deve essere prevedibile. Ecco un esempio abbreviato:

requirements/retry-failed-runs.md
# Retry delle esecuzioni fallite dalla UI

## Obiettivo
Permettere a un operatore di rilanciare un'esecuzione fallita senza
lasciare la pagina di dettaglio.

## As-Is Baseline
- Il backend espone già POST /api/runs/{id}/retry.
- L'endpoint crea una nuova esecuzione collegata tramite retried_from_id.
- La pagina React mostra gli errori ma non presenta un'azione di retry.

## Scope
- Aggiungere l'azione Retry per le esecuzioni fallite.
- Mostrare la nuova esecuzione e aprire la relativa pagina di dettaglio.
- Preservare la semantica di retry esistente nel backend.

## Non-Goals
- Nessun retry per esecuzioni queued, running o successful.
- Nessuna modifica allo scheduler o alla retention policy.

## Requisiti Funzionali
- FR-1: Solo gli operatori possono vedere e invocare Retry.
- FR-2: La UI deve impedire invii duplicati durante la richiesta.
- FR-3: Gli errori API devono lasciare visibile l'esecuzione originale.

## Criteri di Accettazione
- AC-1: Data un'esecuzione fallita e un operatore, quando viene selezionato
  Retry, allora viene creata una nuova esecuzione collegata e viene aperta
  la sua pagina di dettaglio.
- AC-2: Data un'esecuzione running, quando viene aperta la pagina,
  allora l'azione Retry non viene mostrata.

## Guardrail
- Riutilizzare l'API di retry e la policy di autorizzazione esistenti.
- Le API di lista rimangono paginate con limit-offset.
- Non modificare stati di esecuzione non coinvolti.

## UAT
- Verificare AC-1 e AC-2 tramite browser.
- Verificare l'uso da tastiera e la protezione dal doppio click.

## Open Items
None.

La riga più importante è l’ultima. “None” non è testo generato in modo ottimistico. È il risultato della chiusura di ogni domanda nel loop di raffinamento.

Entrare nella Dark Factory
#

Un engineer revisiona il requisito prima che entri nella factory. Questo gate verifica intento di prodotto, rischio, fattibilità e coerenza tra i vincoli dichiarati e le policy del team.

Dopo l’approvazione, la specifica diventa input immutabile per l’esecuzione. Gli agenti possono segnalare che è incoerente o impossibile, ma non possono reinterpretarla silenziosamente.

1. Pianificazione in Task Atomici e Ordinati
#

Il Planner Agent legge la specifica completa ed emette una lista strettamente ordinata di task limitati. Ogni task contiene:

  • Un singolo obiettivo e non-goal espliciti.
  • I file o le interfacce che probabilmente cambieranno.
  • I criteri di accettazione coperti.
  • I test attesi e i comandi di verifica.
  • I guardrail ingegneristici applicabili.
  • Una dimensione adatta a una review significativa.

La factory sceglie deliberatamente di non eseguire in parallelo un DAG dinamico. I coder paralleli sono attraenti in una demo, ma assunzioni sovrapposte, conflitti tra branch e ordine di completamento non deterministico rendono più difficile il recovery.

L’array dei task rappresenta l’ordine di esecuzione. È attivo esattamente un task di implementazione alla volta.

2. Coding, Unit Test e MR del Task
#

Per ogni task, il Coder Agent:

  1. Crea un task branch dall’integration branch corrente.
  2. Legge task, specifica, istruzioni del repository e codice rilevante.
  3. Implementa soltanto lo scope dichiarato.
  4. Aggiunge o aggiorna gli unit test.
  5. Esegue test e controlli statici del repository.
  6. Esegue il push e apre una merge request verso l’integration branch.

La MR è il prodotto del coder. Il coder non può approvarla o eseguirne il merge.

3. Due Review Indipendenti
#

La stessa MR del task viene ispezionata da due agenti con credenziali di sola lettura:

  • Code Review Agent: correttezza, contratti, regressioni, manutenibilità, test e convenzioni del repository.
  • Security Agent: autenticazione, autorizzazione, injection, segreti, SSRF, deserializzazione non sicura, dipendenze e permessi infrastrutturali.

Entrambi i verdetti sono legati allo SHA del commit corrente. Se il coder esegue il push di un altro commit, le approvazioni precedenti vengono invalidate.

flowchart TD
    T[Prossimo task ordinato] --> C[Coder implementa + unit test]
    C --> MR[MR del task verso integration]
    MR --> CR[Code Review Agent]
    MR --> SR[Security Agent]
    CR --> G{Entrambi passano sullo SHA corrente?}
    SR --> G
    G -->|No, finding blocking o major| RW[Coder in rework mode]
    RW --> C
    G -->|Sì| M[Il control plane esegue il merge]
    M --> N{Rimangono task?}
    N -->|Sì| T
    N -->|No| ENV[Promozione in UAT]

In rework mode, il coder riceve il task originale insieme ai finding blocking e major. Corregge lo stesso task branch, riesegue i test e aggiorna la MR esistente. Entrambi i reviewer ripartono. Le osservazioni minor possono rimanere per gli umani, ma finding blocking o major non risolti non possono superare il gate.

Il control plane, non un agente, valida i metadati canonici della MR ed esegue il merge. Questo impedisce a un agente di dichiarare che una MR non correlata ha superato la review.

UAT Senza Guardare il Codice
#

Quando tutte le MR dei task sono state integrate, il risultato viene promosso verso un branch che esegue il deploy in un account AWS dedicato all’acceptance.

Lo UAT Agent ha già derivato i propri scenari dal requisito approvato. Lo ha fatto senza vedere l’implementazione. Questa indipendenza è intenzionale: un autore di test che legge il codice tende a riprodurre le assunzioni dell’implementazione.

Lo UAT Agent usa Playwright contro l’applicazione deployata e verifica comportamenti osservabili dall’esterno:

  • User journey e confini tra ruoli.
  • Criteri di accettazione Given/When/Then.
  • Percorsi di errore e recovery.
  • Stato del browser, navigazione e interazioni rilevanti per l’accessibilità.
  • Scenari di regressione identificati nel requisito.

Se lo UAT fallisce, il control plane crea un task di rework limitato che contiene scenario fallito, evidenze e comportamento atteso. Il task entra nello stesso loop coder, review, merge, deploy e UAT. Lo UAT Agent non modifica direttamente il codice.

Se lo UAT passa, il software è funzionalmente pronto, ma non viene rilasciato automaticamente. La factory prepara una merge request finale e definitiva per gli umani.

La Documentazione È Parte del Prodotto
#

L’ultimo agente aggiorna la documentazione operativa e di sviluppo, inclusi i file CLAUDE.md. Questi file non sono istruzioni generiche per l’AI conservate fuori dal progetto. Sono conoscenza versionata del repository, usata dagli engineer e dai prossimi Requirements, Planner, Coder e Review Agent.

Per un repository grande, la documentazione è organizzata per directory seguendo le linee guida Claude Code per le codebase grandi:

repository/
  CLAUDE.md                         # architettura e regole globali
  .claude/
    settings.json                   # permessi e path generati esclusi
    rules/                          # regole trasversali basate sul path
  backend/
    CLAUDE.md                       # comandi Django, convenzioni API e migrazioni
    .claude/skills/
      api-testing/SKILL.md
    src/
  frontend/
    CLAUDE.md                       # comandi React, routing e componenti
    .claude/skills/
      component-testing/SKILL.md
    src/
  infrastructure/
    CLAUDE.md                       # Terraform, ambienti e vincoli di deploy

Il file root contiene soltanto regole applicabili ovunque. Un file annidato aggiunge comandi specifici dello stack, mappa dei moduli e vincoli non ovvi. Non duplica il root.

Il Documentation Agent aggiorna questi file nello stesso cambiamento del comportamento che descrivono. Verifica comandi e path prima di scriverli. Questo chiude il loop:

flowchart LR
    CODE[Codice modificato] --> DOC[Conoscenza aggiornata]
    DOC --> NEXT[Prossima analisi dei requisiti]
    NEXT --> PLAN[Planning più aderente alla realtà]
    PLAN --> CODE

Senza questo passaggio, ogni agente futuro parte da assunzioni obsolete e paga nuovamente il costo di discovery.

Progettare la Semi-Deterministicità
#

Un workflow agentico non è deterministico nel senso tradizionale. Lo stesso prompt può produrre ragionamenti, sequenze di tool e formulazioni differenti. Un workflow di cinque ore moltiplica anche la probabilità che almeno una risposta violi il contratto atteso.

La soluzione è una shell deterministica attorno a worker stocastici:

flowchart LR
    A[Output dell'agente] --> P[Parsing del contratto]
    P -->|Non valido| R[Retry limitato o escalation]
    P -->|Valido| V[Validazione invarianti]
    V -->|Non valido| R
    V -->|Valido| DB[(Stato persistito)]
    DB --> RED[Workflow reducer puro]
    RED --> RES[Reservation con dedup key]
    RES --> FX[Esecuzione di un side effect]
    FX --> OBS[Osservazione dello stato canonico]
    OBS --> DB

L’Output Strutturato È una Proposta Non Fidata
#

Ogni workflow agent ha un contratto di output ristretto. Il Planner restituisce un array tasks ordinato. Il Coder restituisce un riferimento a una MR. I reviewer restituiscono verdetti e finding.

Il control plane esegue parsing e validazione prima di persistere i risultati. Campi mancanti e campi vuoti rappresentano deliberatamente stati diversi. L’assenza del campo tasks è un output malformato. Un array vuoto accompagnato da una spiegazione concreta è un risultato planning-blocked valido. Le chiavi task duplicate vengono rifiutate.

Per il risultato del Coder, l’unica dichiarazione utile è l’IID della MR. Il control plane non considera affidabili branch, URL, target o SHA forniti dall’agente. Recupera i metadati canonici da GitLab tramite il client limitato alla singola esecuzione e verifica che la MR appartenga al progetto e alla topologia di branch attesi.

Questa distinzione è fondamentale:

output agente = proposta
stato validato nel database = verità del workflow
osservazione API esterna = verità del side effect

Un Reducer Puro e Level-Triggered
#

L’azione successiva viene calcolata da uno snapshot del database tramite un reducer puro. Date le stesse specifiche, task ordinati, MR aperte e review sullo SHA corrente, produce la stessa lista di azioni.

Non rappresenta il progresso come una fragile catena di callback. A ogni reconciliation tick chiede quale azione è giustificata dallo stato corrente:

  • Se nessun task è attivo, rilascia il primo task ready non ancora integrato.
  • Se una MR del coder è aperta, avvia il set fisso di reviewer.
  • Se entrambi i reviewer passano sullo SHA corrente, abilita il merge gate deterministico.
  • Se compare un nuovo SHA, avvia di nuovo entrambi i reviewer.
  • Se tutti i task sono integrati, crea o recupera la MR finale di handoff.

Le azioni usano una deduplication key e vengono riservate prima di avviare un agente. La riconciliazione può quindi ripetersi dopo il riavvio di un processo o un outage temporaneo senza lanciare due volte la stessa azione logica.

L’esecuzione seriale fa parte di questo design. Sacrifica throughput teorico per eliminare race tra branch, assunzioni sovrapposte tra task e scheduling non deterministico delle dipendenze.

Le Review Sono Fatti su un Commit, Non su una MR
#

Un verdetto di review viene memorizzato rispetto allo SHA corrente della MR. Un pass non è una proprietà permanente della merge request.

Se il rework esegue il push di un commit, entrambi i verdetti precedenti diventano irrilevanti. Finché Code Review e Security Review non passano il nuovo SHA, il merge gate restituisce hold. Un verdetto fail o non interpretabile restituisce blocked. Soltanto due pass sulla head corrente producono approve.

La lista dei reviewer è definita una volta sola e usata sia dal dispatch delle review sia dalla valutazione del merge. Questo impedisce una deriva di configurazione in cui il sistema avvia un insieme di review ma ne attende un altro.

Un Errore Transitorio Non Deve Diventare un Fallimento di Business
#

Le esecuzioni lunghe attraversano diversi confini inaffidabili: invocazioni AgentCore, proxy di rete, hosting Git, API dei modelli e control plane cloud. Un errore di trasporto transitorio non deve trasformare un workflow attivo in uno stato terminale.

Il poller distingue quindi:

  • Errore di trasporto: mantiene attiva l’esecuzione e riprova al reconciliation tick successivo.
  • Running: persiste il progresso soltanto quando avanza.
  • Job unknown: tollera più session-affinity miss consecutivi prima di dichiarare perso il runtime.
  • Runtime perso: lo classifica separatamente da un fallimento dell’agente, permettendo il recovery.
  • Errore dell’agente: persiste un vero fallimento terminale e applica la policy di recovery limitata dello stage.

Le operazioni Git seguono la stessa regola. La creazione dei branch e della MR finale è idempotente. Un errore transitorio di merge o delle API viene ritentato a partire dallo stato osservato in GitLab, senza assumere che il side effect sia fallito prima o dopo la sua esecuzione.

I fallimenti nelle review del Coder entrano in un loop limitato di rework sulla stessa MR. I conflitti di merge entrano in un loop limitato di conflict resolution. Soltanto dopo l’esaurimento di questi budget la piattaforma crea un’escalation per un umano.

La prima esecuzione di cinque ore ha incontrato errori di rete transitori, ma nessuno ha modificato lo stato logico del workflow. La riconciliazione ha osservato nuovamente il sistema e ha continuato. Questo recovery, insieme a cinque ore di output degli agenti conformi ai contratti, è il risultato che conta di più.

Il Control Plane È il Vero Prodotto
#

L’architettura funziona perché gli agenti non possiedono il workflow. Un control plane deterministico li vincola, osserva i loro side effect e decide cosa può accadere dopo.

È responsabile di:

  • Persistenza di specifiche, task, tentativi, finding ed evidenze.
  • Applicazione delle sole transizioni di stato valide.
  • Rilascio di esattamente un task alla volta.
  • Associazione dei verdetti di review agli SHA dei commit.
  • Cifratura delle credenziali della singola esecuzione e routing di identità least-privilege.
  • Retry limitati per errori transitori ed escalation per quelli terminali.
  • Merge delle MR dei task soltanto dopo entrambi i gate di review.
  • Mantenimento del merge finale come azione umana.

Questa è la lezione principale della costruzione di una Dark Factory: l’affidabilità non arriva da un prompt più grande o da un modello più capace. Arriva dal trattare gli output del modello come proposte non fidate all’interno di una state machine con invarianti esplicite. Gli agenti rimangono probabilistici, la linea di produzione diventa semi-deterministica.

Cosa Rimane agli Umani
#

Il processo automatizza analisi ed esecuzione, non la responsabilità.

Gli umani mantengono:

  • Intento di prodotto e priorità di business.
  • Approvazione del requisito finale.
  • Eccezioni alle policy architetturali e di sicurezza.
  • Accettazione del rischio per finding non bloccanti.
  • Merge definitivo e rilascio in produzione.

Questo è il confine che voglio. Gli agenti eseguono lettura, decomposizione, implementazione, test e raccolta delle evidenze ripetitive. Gli engineer prendono le decisioni che comportano responsabilità organizzativa e produttiva.

Considerazioni Finali
#

Una Dark Factory non dovrebbe essere una stanza piena di agenti che improvvisano sullo stesso repository. Dovrebbe essere una linea di produzione stretta:

intento
  -> requisito basato sul repository
  -> decisioni chiuse
  -> approvazione degli engineer
  -> task ordinati
  -> codice + unit test
  -> gate di code review e security
  -> UAT black-box sull'applicazione deployata
  -> documentazione aggiornata
  -> merge umano

Il Requirements Agent fornisce alla factory un input di qualità. Il control plane dà confini deterministici ad agenti probabilistici. Review indipendenti e UAT forniscono evidenze. I file CLAUDE.md organizzati per directory riportano ciò che è stato appreso nel ciclo successivo.

Il risultato non è software delivery autonoma. È software delivery in cui ambiguità, autorità e rischio vengono resi espliciti prima che il codice raggiunga la produzione.


Vuoi approfondire agentic software delivery, platform engineering o architetture AWS? Offro sessioni di coaching 1:1 adattate al tuo background e ai tuoi obiettivi. Visita la pagina coaching.

Articoli correlati