Richieste di modifica
Come il lavoro svolto nelle sessioni raggiunge il branch predefinito tramite revisione.
Una richiesta di modifica (CR) unisce un branch git a un altro. Beeuni crea una CR dal branch della sessione (head_ref) al branch predefinito del progetto (base_ref, di solito main). La riga della CR contiene metadati; l’unione, il diff e i controlli dei conflitti vengono eseguiti come vere operazioni git sul repository del progetto. Una CR è l’unico modo in cui il lavoro di una sessione arriva al branch predefinito.
Perché il lavoro passa da una CR
Una sessione viene eseguita in una sandbox sul proprio branch, che prende il nome dall’ID della sessione. La sandbox non dura per sempre, ma il branch sì: git è l’unica registrazione durevole del lavoro di una sessione. Ogni nuova sessione parte dal branch predefinito. Finché una CR non viene unita, il lavoro resta sul proprio branch, senza revisione e invisibile a tutti gli altri agenti, trigger e collaboratori. Vale per ogni modifica: codice, agenti, skill e manifest (beeuni.yaml) — nesbeeuni eccezione.
Il mandato dell’agente
Per applicare qualsiasi modifica al branch predefinito del progetto, un agente deve aprire una CR. L’agente non unisce la propria CR: la decisione spetta all’utente. Segui queste regole:
- Esegui commit sul branch della sessione (
$BEEUNI_BRANCH_NAME). Crea commit piccoli e funzionanti. Non riscrivere la cronologia né eseguire push forzati. - Esegui il push del branch:
git push origin HEAD. - Apri la CR:
beeuni cr open --title "..." --description "...". Nella sandbox di una sessione,--heade--sessionhanno come valore predefinito$BEEUNI_BRANCH_NAMEe$BEEUNI_SESSION_ID.--baseha come valore predefinito il branch predefinito del progetto. - Comunica all’utente il numero della CR, così che possa esaminarla.
- Fermati. Non unire la CR personalmente.
Pratiche da evitare
- Eseguire un push forzato sul branch predefinito. Viola il processo di revisione, anche se il backend lo consente.
- «È sul mio branch, prendilo tu.» Il branch della sessione scompare quando la sandbox si arresta, a meno che nel frattempo una CR non lo abbia unito.
- Inviare la modifica come file, testo incollato o archivio. Il sistema delle CR risolve già questo problema.
Modello dei dati
Le CR risiedono nella tabella change_requests.
| Colonna | Tipo | Note |
|---|---|---|
cr_id |
uuid | Chiave primaria. Identificatore dell’API REST. |
project_id |
uuid | Progetto a cui appartiene la CR. |
number |
integer | Numero visualizzato nel progetto (#1, #2…). Univoco per progetto. Non viene mai riutilizzato. |
title |
text | Obbligatorio. |
description |
text | Per impostazione predefinita è una stringa vuota. |
base_ref |
text | Branch in cui viene eseguita l’unione. Di solito main. |
head_ref |
text | Branch da cui viene eseguita l’unione. In una sessione, è l’ID della sessione (un UUID). |
status |
enum | open, merged o closed. |
head_commit_sha |
text | Per le CR aperte, viene aggiornato a ogni lettura in base alla punta live di head_ref. Per le CR unite, viene acquisito al momento dell’unione. |
base_commit_sha |
text | Stessa regola, per base_ref. |
origin_session_id |
text | Sessione che ha aperto la CR. Viene impostato su null se la sessione viene eliminata. |
created_by |
uuid | Utente che ha creato la CR. |
merged_at / merged_by |
timestamp / uuid | Quando e chi ha unito la CR. |
merge_commit_sha |
text | Commit di unione. In caso di fast-forward, è uguale a head_commit_sha. |
closed_at / closed_by |
timestamp / uuid | Quando e chi ha chiuso la CR senza unirla. |
metadata |
jsonb | Contiene requested_changes, un elenco di voci {text, by, at} aggiunte da POST /:crId/request-changes. Le CR non hanno una tabella separata per i commenti. |
created_at / updated_at |
timestamp | Impostato alla creazione. Aggiornato a ogni cambio di stato o aggiornamento degli SHA. |
Un indice univoco su (project_id, number) consente di fare riferimento a una CR tramite il suo numero breve anziché il suo UUID.
Ciclo di vita
open ──(merge)──▶ merged (terminal)
open ──(close)──▶ closed ──(reopen)──▶ open
openè lo stato iniziale.closedè reversibile.POST /:crId/reopenlo riporta aopen.mergedè terminale. Non è possibile riaprire o chiudere una CR unita. Apri una nuova CR sullo stato risultante dall’unione.
Beeuni rifiuta di creare una CR se il branch non contiene commit in harness sperimentaleù rispetto al branch predefinito. Di solito significa che l’agente ha eseguito il commit in locale ma non ha mai fatto il push. Esegui il push dei commit e poi crea di nuovo la CR.
Aggiornamento degli SHA
Per una CR aperta, Beeuni aggiorna head_commit_sha e base_commit_sha in base ai branch live a ogni GET. Se il repository è irraggiungibile o manca un branch, Beeuni salta l’aggiornamento e restituisce gli ultimi metadati noti della CR. Una CR unita conserva gli SHA acquisiti al momento dell’unione: Beeuni non li aggiorna harness sperimentaleù.
Meccanismi di unione
POST /v1/projects/:projectId/change-requests/:crId/merge esegue questi passaggi.
- Beeuni legge il manifest (
beeuni.yaml) dahead_refe lo convalida rispetto allo schema del manifest. Un branch senza manifest supera il controllo. Un manifest non valido restituisce422concode: "MANIFEST_INVALID"e interrompe l’unione. - Beeuni esegue il fast-forward di
base_refsehead_refè strettamente harness sperimentaleù avanti. - Altrimenti, Beeuni crea un commit di unione. Il messaggio predefinito è
Merge CR #<n>: <title>; puoi cambiarlo conmessagenel corpo della richiesta. L’autore del commit èBeeuni <noreply@beeuni.com>. - In caso di conflitto, viene restituito
409con l’elenco dei conflitti. Prima dell’unione, puoi controllare lo stesso elenco conGET /:crId/merge-preview. - In caso di esito positivo, Beeuni imposta
statussumerged, registramerged_at,merged_byemerge_commit_sha, e invalida la cache git del progetto.
Se la CR non è open, l’unione restituisce 409.
Anteprima dell’unione
GET /:crId/merge-preview restituisce:
| Campo | Tipo | Significato |
|---|---|---|
base_sha |
string | Punta corrente di base_ref. |
head_sha |
string | Punta corrente di head_ref. |
merge_base |
string | null | Antenato comune. Null se le cronologie non sono correlate. |
is_up_to_date |
boolean | head_ref è stato unito completamente a base_ref. |
can_merge |
boolean | Nessun conflitto. |
can_fast_forward |
boolean | head_ref è strettamente harness sperimentaleù avanti di base_ref. |
conflicts |
string[] | Percorsi dei file che genererebbero conflitti. |
API REST
Tutte le route si trovano sotto /v1/projects/:projectId/change-requests.
| Metodo | Percorso | Note |
|---|---|---|
| GET | / |
?status=open|merged|closed|all. Senza filtro, restituisce tutti gli stati. |
| POST | / |
Corpo: {title, description?, head_ref, base_ref?, session_id?}. Restituisce 201. |
| GET | /:crId |
Restituisce la CR. Aggiorna gli SHA come effetto collaterale. |
| PATCH | /:crId |
Modifica title o description. 409 se non è open. |
| GET | /:crId/diff |
Patch unificata: elenco dei file, aggiunte, eliminazioni. |
| GET | /:crId/merge-preview |
Vedi Anteprima dell’unione sopra. |
| POST | /:crId/merge |
Corpo: {message?}. 422 in caso di manifest non valido. 409 in caso di conflitto o se non è open. |
| POST | /:crId/close |
409 se è già merged. |
| POST | /:crId/reopen |
409 se non è closed. |
| POST | /:crId/request-changes |
Corpo: {feedback}. Aggiunge a metadata.requested_changes e riattiva l’agente della sessione di origine. 409 se non è open. |
POST / rifiuta un head_ref che non contiene commit in harness sperimentaleù rispetto a base_ref: 422 code: "CR_HEAD_NOT_AHEAD". È l’errore che vede un agente se apre una CR prima di eseguire il push del branch.
Autorizzazioni
Le route di lettura richiedono l’accesso in lettura al progetto. Le route di scrittura richiedono l’accesso in scrittura. Ogni azione di scrittura richiede anche una capability, indicata di seguito per un token completo e per il token con ambito limitato di una sessione.
| Azione | Capability |
|---|---|
| Aprire una CR | project.gitops.push |
| Richiedere modifiche | project.review.act |
| Unire | project.gitops.merge |
Una capability per ogni azione, sia per un token completo sia per il token con ambito limitato di una sessione. Apertura e unione sono permessi distinti: un token può aprire richieste di modifica senza poterle unire. È questo il meccanismo alla base del mandato dell’agente descritto sopra.
project.cr.open e project.cr.merge erano i nomi precedenti al passaggio per project.gitops.push e project.gitops.merge, la stessa capability con un secondo nome. Un beeuni.yaml che ne elenca ancora uno continua a funzionare (quando viene risolto, il grant viene riscritto usando la dicitura corrente), ma per ogni nuovo elemento usa il nome gitops.
Una sessione non può mai unire una richiesta di modifica che ha aperto lei stessa, indipendentemente dai permessi ricevuti. Questa regola è strutturale, non è una capability.