Il land riallineava dopo il verdetto, e le bozze restavano aperte per sempre - #86
Merged
Merged
Conversation
… che non atterra `tryMerge` fonde C2 = merge(C, main) mentre i check - i quattro comandi locali e le due righe CI - hanno misurato C, la consegna, in media 1,93 h prima. La CI di C2 non la legge nessuno: il push, la bozza e il giro di attesa sono avvenuti una volta sola, su C. `checks_commit` continuava a nominare C come se fosse cio' che e' atterrato. Misurato il 17/09 sugli ultimi 7 giorni: 32 land, 22 con la riga di riallineamento, e solo 4 di quei 22 hanno anche avvisato che il land era diverso dalla consegna. Diciotto sono passati muti - e da quando le righe CI sono vive l'affermazione e' piu' forte di prima, perche' la card non dice piu' «i comandi sono usciti zero» ma «la CI della PR e' verde». La nota del riallineamento adesso nomina il commit che i check hanno misurato, e `clearChecksCommit` toglie il puntatore lasciando in piedi stato, ora ed evidenza comando per comando: il verdetto su C resta vero e resta leggibile, sparisce solo la pretesa che parli del commit fuso. NON e' un merge-queue: ri-spingere C2 e rileggerne la CI costa 15-40 minuti per land ed e' una decisione del proprietario.
…dentro main `awaitCiEvidence` apre una bozza di PR per ogni consegna che entra in review, e in tutto il repo le chiamate a `gh` erano quattro, tutte li': `pr list`, `pr create`, `api .../runs|jobs`, `pr view`. Zero `pr close`, zero `push --delete`. Il gemello si misurava gia' senza le bozze: 41 rami `topics/*` su origin, 39 dei quali gia' dentro `main`, nessuno cancellato. Con 121 ingressi in review in 7 giorni le bozze si accumulano allo stesso ritmo. `closeCiDraft` chiude la bozza con la STESSA lookup che la apre (`openPullRequest`, estratta da `draftPullRequest`) e poi cancella il ramo su origin - in quest'ordine, perche' la PR chiusa tiene i commit raggiungibili via `refs/pull/N/head`. Un ramo gia' assente e' un esito, non un errore. Tre porte, quelle in cui il ramo e' finito per sempre: il land CONFERMATO da una rilettura di main (con `proof === null` il ramo resta, perche' e' il caso in cui la card chiede a una persona di andare a guardare), l'approvazione marcata `superseded` - il gesto esplicito che dice «questo ramo non atterrera'» - e l'archiviazione. NON l'approvazione semplice, che lascia lavoro vero sul ramo, e NON il rifiuto, che rimanda l'agente sullo stesso ramo a riconsegnare. La guardia che conta: una card girata in-place registra come ramo di consegna il ramo del checkout, cioe' `main`. Il ramo di integrazione e quello su cui il checkout e' fermo sono rifiutati, qualunque cosa dica la card. Pulizia, non un cancello: un `gh` scollegato finisce nel log e la card riceve la ricevuta solo di cio' che e' davvero successo, il land non fallisce mai.
… la bozza sbagliata Due difetti nello stesso giro, misurati sul DB vivo. IL RAMO CHE ATTERRA NON PERDE LA SUA BOZZA. `confirmLandedOnMain` rilegge il main LOCALE e niente in questo server pusha main: quando la spazzata gira, `origin/main` non ha ancora la fusione e una persona la spinge dopo. GitHub marca allora quella pull request MERGED da sola - la #78, 17/09, un minuto dopo il land. Un `gh pr close` che corre contro quel push ci stampa sopra «Closed», sulle circa 32 card che atterrano in una settimana. Da qui `closePr` sull'ingresso di `closeCiDraft`, senza default perche' la risposta cambia per porta: falso solo per il ramo che la fusione ha davvero portato su main, vero per ogni ramo che non atterrera' mai. UNA CARD HA PIU' DI UN RAMO. Ogni consegna che passa dal cancello dei check pusha il ramo del SUO worktree e apre la SUA bozza (`awaitCiEvidence` prende `port.branch(cwd)`), mentre la card ricorda solo l'ultimo in `delivery_branch`. Sul DB vivo: 151 card con due o piu' rami di tentativo distinti, 104 delle quali hanno anche un `delivery_branch`, e 83 rami appartengono a un tentativo `delivered` che non e' il ramo di consegna della card. Spazzarne uno solo lasciava indietro proprio quegli 83 - la perdita per cui T4.2 esiste. Ora la spazzata prende l'unione di `res.branch`, `delivery_branch` e le righe dei tentativi, deduplicata. IL RAMO SI CANCELLA ANCHE SENZA `gh`. `push --delete` e' git contro origin: un progetto il cui `origin` non e' GitHub usciva prima da `closeCiDraft` perche' `port.repo` non sapeva nominare un repo, e perdeva anche la meta' che con `gh` non c'entra. Ora il fallimento di `repo` salta solo la meta' della pull request. L'ORDINE chiudi-poi-cancella era dichiarato portante e nessun test lo misurava (invertito: 45 pass / 0 fail). La ragione vera: GitHub chiude da se' una pull request quando le si cancella il ramo di testa, quindi cancellare per primo fa arrivare la chiusura a una PR gia' chiusa, `openPullRequest` filtra `--state open` e non trova niente, e la `reason` - l'unica riga che su GitHub dice perche' quel ramo e' finito - non viene mai scritta. Il test modella quel comportamento; invertendo le due meta' va rosso. LA RICEVUTA DICE SOLO CIO' CHE E' SUCCESSO: togliendo il suo cancello (40 pass / 0 fail prima) la card con `gh` sloggato riceve «Pulizia su GitHub: .», e adesso c'e' il test che lo vede. La guardia su `main` resta, con la giustificazione vera al posto di quella inventata: `select count(*) from tasks where delivery_branch='main'` da' 0, perche' una card girata in-place non registra nessun ramo di consegna. E' un pavimento su un argomento che la funzione non controlla - arriva da tre posti diversi - su una mossa che il Mac non puo' annullare, non il rimedio a una riga che qualcuno ha visto.
…le il ramo `closePr: false` esiste perche' la bozza del ramo ATTERRATO la deve marcare MERGED GitHub, quando una persona spinge main. Ma `closeCiDraft` cancellava il ramo comunque, fuori dall'`if`, e cancellare il ramo di testa e' gia' un modo di chiudere la pull request — chiusa come Closed, mai come merged. Su questo repo #27 e #28, mai fuse, leggono `closed` e `head_ref_deleted` allo STESSO secondo dentro una raffica di dieci cancellazioni; #78, che e' atterrata davvero, ha `merged` 33 secondi PRIMA che il ramo sparisse. La porta del land puo' produrre solo il primo ordine: `confirmLandedOnMain` rilegge il main LOCALE e qui nessuno spinge main, quindi il `push --delete` precede sempre la spinta umana. Il flag non salvava la bozza: spostava chi la chiudeva, e per strada perdeva il commento con la ragione. Adesso «non chiudo la pull request» vuol dire anche «non cancello il ramo finche' origin/main non lo porta»: due `ls-remote` e un `merge-base --is-ancestor`, e una lettura che non conclude tiene il ramo — cancellare su origin e' l'unica mossa qui che il Mac non puo' disfare. Il ramo non resta orfano: la porta dell'archivio rispazza la stessa card con `closePr: true`, e a quel punto la bozza e' gia' MERGED e `--state open` non trova niente da chiudere. La prova non e' su uno stub: un origin bare vero, il ramo spinto, la fusione sul main locale, e il ramo che sopravvive; poi la spinta di main, e il ramo che se ne va. `gh` non entra mai. Seconda cosa, la coda. La spazzata era `await` dentro `landTask`, che gira in `landings.enqueue`, un land alla volta per progetto. La card peggiore del DB vivo porta 11 rami, ognuno `gh pr list` + `git push --delete` con cap 60 s: con `gh` sloggato o sotto rate limit un land teneva ferma la coda di tutti gli altri per ~22 minuti invece di ~3, e 124 card archiviate hanno rami di tentativo che non hanno mai consegnato, cioe' chiamate che non comprano niente. Niente a valle legge l'esito della spazzata, e le altre due porte la chiamavano gia' cosi'.
…, sette file `check:bloat` diceva NEW offender su `server/routes/tasks.landing.test.ts`, 1.076 righe contro una soglia di 800, e cadeva con lui il meta-test che pretende che la baseline del repo sia verde oggi. La soglia non si e' alzata: il file conteneva sette domande diverse, e ognuna adesso ha il suo file con la sua intestazione. tasks.landing.test.ts quale GESTO atterra, e l'interruttore della board tasks.landing-failures.test.ts ogni modo in cui tryMerge dice di no tasks.landing-success.test.ts cosa chiude il land riuscito, e chi ferma tasks.landing-realign.test.ts il riallineamento si dichiara (e i check misurati) tasks.landing-verdict.test.ts landed/unlanded/unverifiable/ask tasks.landing-superseded.test.ts chiusa apposta senza landare tasks.delivery-sweep.test.ts la meta' REMOTA della potatura: bozza e ramo su origin 45 titoli prima, 45 dopo: `bun test` sui sette file da 45 pass / 0 fail, e il confronto dei titoli ordinati fra la versione di HEAD e i sette file esce vuoto. Il piu' lungo adesso e' 269 righe. Tre nomi italiani (`cardConsegnata`, `mergiato`, `riallineato`) hanno seguito i test nei file nuovi: invece di traslocare il debito, pagati in inglese e tolti dalla baseline di `check:identifier-language`, che chiedeva esattamente questo.
# Conflicts: # server/routes/tasks.ts # server/services/tasks.ts
…vi: 180 righe riscritte in inglese Spezzare `tasks.landing.test.ts` in sette file era corretto (45 titoli prima, 45 dopo), ma la baseline di `check:comment-language` era agganciata al VECCHIO percorso - 154 righe alla riga 1268 di `scripts/comment-language-baseline.json` - e i file nuovi nascono a zero. Risultato: 180 righe di commento italiano contate come NUOVE, `check:comment-language` a 1 sul ramo e 0 su main, e la CI rossa sul passo «Static guard rails» (PR #86, run 35228750537). La baseline non si travasa: il cancello scende soltanto, e alzarla e' proprio la mossa che questa change vieta. Quindi i commenti sono riscritti in inglese, tenendo la misura e la trappola che ognuno inchioda: i 108 replay del verdetto dedotto (20 falsi allarmi), i $5,64 e $8,24 del turno rifatto, le 1,93 h medie in review con 18 land su 32 che non dicevano di aver riallineato, le tre card del 18/08 chiuse apposta e contate come debito, `git status` che tace solo su metadati rotti e non su `index.lock`. tasks.landing-verdict.test.ts 56 righe tasks.landing-failures.test.ts 41 tasks.landing-success.test.ts 37 tasks.landing-superseded.test.ts 22 tasks.landing-realign.test.ts 20 tasks.delivery-sweep.test.ts 4 Tre blocchi tolti invece che tradotti, perche' ripetevano parola per parola l'intestazione del file che li conteneva: la storia dell'11/08 in `landing-success` (ridotta al meccanismo, «promuoveva a done solo passando da review», che l'intestazione non diceva), la ricaduta del 13/08 in `landing-verdict` (ridotta al falsificatore: rimetti il verdetto dedotto e il test e' rosso) e il paragrafo delle 1,93 h in `landing-realign`, che era gia' scritto due volte nello stesso file. Due citazioni italiane restano perche' sono il DATO - la riga di storico «user -> In corso» e la nota «Land NON riuscito» - e portano l'unica scappatoia prevista dal cancello, `allow-italian:`. Nomi dei test e asserzioni non toccati.
zorahrel
added a commit
that referenced
this pull request
Sep 17, 2026
Conflitto reale fra le due ultime tornate: #86 ha aggiunto tredici test per closeCiDraft dentro ci-evidence.test.ts, che questo ramo aveva spezzato in tre. Risolto tenendo i test di main nel file rimasto, unendo i blocchi di import (lo split ne aveva tolti otto che quei test usano) e completando le due porte finte con i quattro metodi che la pulizia delle bozze ha aggiunto a GithubPort. Tolto il test "no commit beyond main is green with a note": la risoluzione lo aveva riportato indietro, ma questo ramo lo ha sostituito di proposito, perche' ownCommits === 0 non e' piu' un verde. Il sostituto sta in ci-evidence-verdict.test.ts, stesso input e quattro asserzioni in piu'. Due voci di baseline registrate invece che spezzate: ci-evidence.ts a 948 (680 su main, 765 qui) e routes/tasks.ts a 4.952 (+249). Nessuno dei due rami le sforava da solo. La ragione e' scritta dentro il file, e il taglio naturale -- il ciclo di vita della pull request contro la lettura della prova -- va fatto a freddo, non su codice appena uscito da quattro giri di verifica. 52 + 17 + 21 test verdi sui tre file, typecheck 0 su baseline 0, rail verdi.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Change approvata:
openspec/changes/coda-che-riparte-da-sola(T4.1, T4.2).Cosa cambia
checks_commit. La consegna misura C, i comandi e la CI danno verde su C, la card sta in review in media 1,93 ore, main avanza (32 land in 7 giorni), e al land si fondemerge(C, main)— che nessuno ha misurato. Osservato sul primo land passato dalle righe CI: il land ha creato596e828dde poi20a271a11, mentrechecks_commitrestava71e96ec13f. Non e' nato col PATCH, ma prima la card diceva «i comandi sono usciti zero» e adesso dice «la CI della PR e' verde», che e' un'affermazione piu' forte su un commit che non atterra. 22 land su 32 negli ultimi 7 giorni avevano la riga di riallineamento, e solo 4 producevano l'avviso: 18 passavano muti.gherano quattro, tutte per aprire e leggere: zeropr close, zeropush --delete. Oggi 41 ramitopics/*vivono su origin, 39 gia' dentro main, nessuno cancellato.La cosa che ha richiesto tre giri
Il primo tentativo chiudeva la PR guardando main locale, e niente nel server pusha main: la spazzata precedeva di secondi il push che marca la PR come fusa, quindi le circa 32 card che atterrano ogni settimana avrebbero letto «Closed» invece di «Merged». Il secondo metteva un flag
closePrma cancellava il ramo comunque — e GitHub chiude una pull request da se' quando le si cancella il ramo di testa: misurato su questo repo, le PR #27 e #28 risultanoclosedehead_ref_deletedallo stesso secondo. Adesso finche'origin/mainnon porta il commit non si tocca ne' la PR ne' il ramo, e il test gira su un origin bare vero, non su uno stub.La pulizia e' anche uscita dalla coda seriale dei land: una card con 11 rami faceva 11 volte (
gh pr list+push --delete) con cap 60 s ciascuna, e conghsloggato teneva ferma la coda di tutti gli altri fino a 22 minuti. Provato con la mutazione: rimettendo l'awaitil test della coda torna rosso.Residuo dichiarato
Quando
resolveLandingpubblica il ramo vivo invece di quello consegnato — il caso «il ramo consegnato non esiste piu'» su una card non-fan-out — quel ramo non e' scritto in nessun posto che la spazzata legge, quindi resta su origin con la bozza aperta. Non e' una regressione (main non chiude niente), ma la rete di sicurezza ha un buco nominabile.