Conversation
…rilegge la stessa run Le righe unit-ci ed e2e-ci leggono la CI della PR, e NON MISURATO era un vicolo cieco: nessun ramo diceva che cosa fa uscire la card da li'. Misurato il 17/09: 15 delle ultime 100 sha con una run pull_request di ci.yml hanno come ULTIMA run una cancellata, cioe' sono gia' nello stato terminale. Su una di quelle il giro successivo non cambia niente - il push esce 0 perche' il ramo e' aggiornato, la bozza viene riusata, e latestCiRun ritrova la stessa run morta. - Una run completata dove OGNI riga aperta e' non misurata viene fatta ripartire UNA volta (il rerun cambia run_attempt, non lo sha) e il giro continua; se il rerun e' rifiutato la riga dice che serve un commit nuovo. Solo a run finita, cosi' un rerun non taglia uno shard ancora vivo per l'altra riga. - Si esce al primo rosso accertato, come i comandi locali: le righe rimaste diventano non misurate con la ragione del rosso, invece di consegnare 60 minuti dopo un rosso che era azionabile subito. - La sonda del conflitto si consuma solo su MERGEABLE o CONFLICTING: una risposta indeterminata o una lettura fallita la bruciavano al primo tentativo e restavano 55 minuti di attesa muta. - Un ramo senza commit propri oltre main non e' piu' due righe verdi: non ha misurato niente, ed e' la bugia che queste righe esistono per non dire. - Il contratto su ci.yml fissa anche la FORMA dei nomi dei job e2e: un secondo asse nella matrice li rinominerebbe in "e2e (1, chromium)", E2E_JOB non matcherebbe piu' niente e ogni consegna tornerebbe non misurata con la CI verde. Il passo di installazione scarica gia' Chromium + WebKit. L'uscita 97 si sposta in shared/board.ts accanto al flag notMeasured che accende: la scriveva anche ci-evidence.ts per conto suo.
…ndi e arrivavano solo col verdetto
Fra lane.release() e il push dei runs non c'era nessun recordChecks: la URL della
pull request e quella della run finivano solo nel tail, a verdetto avvenuto.
Misurato sulla run 35158365969: dalle 22:34:48 alle 22:49:48 la card diceva
"check 1/2" e non aveva niente da aprire.
Il lettore della CI fa risalire {prUrl, runUrl} al chiamante appena esistono
(callback onCiWait), e la rotta li scrive sulla spia running dentro checks_json,
come il progresso e per la stessa ragione: valgono per i minuti dell'attesa e
niente dopo, quindi niente colonna e niente migration. Solo link https:// - il
valore finisce in un href.
E formatChecksWait diceva "e' il cancello della board che misura" anche mentre a
misurare era GitHub: sulla riga CI qui non gira niente, il cancello ha gia'
restituito la corsia. La riga ora nomina la macchina giusta, e per saperlo legge
i comandi DICHIARATI invece dei soli nomi.
…posti sulla stessa card ChecksSection aveva un ramo per running e uno per pass, e tutto il resto cadeva nel blocco rose-500 con la parola "Checks ROSSI". Una riga NON MISURATA (uscita 97) arriva li' come checksVerdict = unknown, mentre Card.tsx la distingue gia' in ambra: rosso dice "il codice e' rotto, non approvare", non misurato dice "non lo sappiamo", e chi rivede decide diversamente nei due casi. Con le righe CI, che non misurano niente ogni volta che la run muore, e' la casella piu' probabile dopo il verde. Terzo ramo prima del return rosso, riga per riga l'icona e il colore seguono l'esito, e "exit 97" non arriva piu' a schermo: si legge "non misurato". Il numero resta una grafia sola, condivisa col server che lo scrive. Nella spia running compaiono i link della pull request e della run appena il server li manda: e' l'unica cosa apribile durante il quarto d'ora in cui misura GitHub.
…te al giorno `rerunTried` e' un locale della chiamata, ma la consegna che serve e' una riga su `pending_deliveries` che `resumePendingDeliveries` ri-emette sullo STESSO commit a ogni boot: 44 riavvii in 25,7 ore contro un'attesa CI di 15-25 minuti sono N rerun sulla stessa run, dove la spec ne vuole UNO. Lo stato che serviva era gia' li' e non lo leggeva nessuno: `run_attempt`, dichiarato sul tipo, citato in due commenti, falsificato nei test e mai letto. Sopra 1 il rerun e' gia' stato chiesto. Lo stesso campo chiude la lettura dopo un rerun accettato: `gh run rerun` esce zero quando GitHub accetta, non quando la nuova attempt e' elencata, e con `cancel-in-progress` puo' anche essere ricancellata subito. La lettura successiva era considerata conclusiva e chiudeva il giro con «serve un commit nuovo» mentre l'attempt che sarebbe andata verde girava. Ora si aspetta che `run_attempt` cresca, con le stesse cinque letture di grazia che ha ogni altra lettura GitHub di questo ciclo, non una. Terzo caso terminale della spec, quello completato senza il job o senza il passo che la riga legge: la riga cadeva a NON MISURATA mentre la run girava ancora, veniva chiusa sul posto e non si riapriva piu', cosi' quando la run arrivava a `completed` non restava niente di aperto e il rerun non partiva. Due sonde del verificatore uscivano con zero rerun e senza la frase che dice come sbloccarsi. La decisione ora guarda anche le righe gia' chiuse senza verdetto, e una riga senza verdetto non e' definitiva finche' la sua run non e' finita. Le due guardie portanti che nessun test difendeva ora hanno il loro test, verificato mutandole: senza `run.status === "completed"` un rerun taglierebbe gli shard ancora in corso, e senza la cancellazione delle righe non misurate la nuova attempt le rimisura ma la card tiene il verdetto vecchio.
Il giro precedente ha allargato la condizione del rerun a «una riga qualsiasi senza verdetto», e cosi' il rerun scattava anche quando un'altra riga era rossa DAVVERO. Il `continue` sta prima del ciclo che chiude le righe, quindi l'esito della prima attempt veniva buttato: con la seconda attempt verde un rosso misurato tornava alla card come «pass». E' «riprova finche' non passa» su un cancello di CI, e contraddice la regola ONE RED ENDS THE ROUND introdotta dallo stesso commit, perche' il controllo del rosso sta dopo il blocco del rerun. Forma raggiungibile: il job `check` muore prima del passo unit (Setup Bun, typecheck, `cancel-in-progress`) mentre uno shard e2e fallisce sul serio. Il rerun ora non parte se una riga ha gia' un rosso vero: il blocco resta dov'e', invece di spostare il controllo del rosso piu' in alto, perche' il ciclo che chiude le righe DEVE restare sotto il tentativo di rerun -- e' `deadEnd` a leggere `rerunTried` per aggiungere «serve un commit nuovo», e chiudendo le righe prima quella frase sparirebbe quando la richiesta fallisce. Stesso motivo, difetto gemello trovato qui: una riga chiusa a un poll PRECEDENTE, mentre la run era ancora in corso, non veniva piu' riletta, e con l'attempt gia' oltre 1 (il nostro rerun di un processo prima: la consegna e' rimessa in coda a ogni riavvio) il giro chiudeva sulla ragione nuda, senza la frase che dice cosa la sblocca. Ora le righe senza verdetto si riaprono quando il rerun viene speso, non solo quando viene accettato. KANBAN-86. Le due righe leggono una FETTA della prova -- il passo «Unit + integration tests» e i quattro shard -- ed e' la fetta giusta per quello che misurano, ma la card ne ricava una frase piu' larga. Il 17/09 due consegne vere su tre (`topics/clumsy-wren` run 35168540957, `topics/imperial-canal` run 35169547221) hanno scritto «checks pre-review verdi» con la run della loro PR `completed/failure`: il job `check` cadeva allo step «Bundle size budget», dopo il passo unit che era verde. Quando la run che le righe hanno letto e' `completed` con conclusione diversa da `success`, il giro non chiude verde: ogni riga tiene nella coda cio' che ha misurato davvero e porta il job e il passo caduti col link alla run, `ciRunRed` tiene il fatto e `checksVerdict` legge `fail`. Non e' un sesto cancello: non rimisura niente, e' un campo della stessa risposta che il poll aveva gia' in mano. Secondario, deciso e non fatto: con una sola riga dichiarata e una run che non completa, `mayStillRerun` porta l'attesa fino alla scadenza. Nessuna guardia -- quell'attesa E' il meccanismo che KANBAN-85 chiede, e il solo caso in cui non compra niente (una run che non finisce dentro l'ora) non si distingue in anticipo da una che finisce al minuto 59. Fissato invece il fatto che l'attesa finisce con la RUN e non con la scadenza, nel test della riga chiusa presto.
…a chiuso a meta' Tre cose, e la prima e' il motivo per cui questo ramo non si poteva fondere. I DUE RAIL ROSSI SU SE STESSO. `check:bloat` e `check:deadcode` giravano rossi nello stesso passo «Static guard rails» dei rail che questo ramo denuncia. La barra della tornata prima era piu' stretta del passo di CI: questa volta i quattordici check di quel passo, uno per uno, piu' typecheck e lint. bloat: `ci-evidence.test.ts` era 873 righe contro una soglia di 800, 499 su main. Spezzato per argomento e non a meta': i lettori di una singola risposta piu' i contratti di ci.yml restano nel file di partenza (197 righe), il giro di attesa va in `ci-evidence-wait.test.ts` (324), cio' che il giro CONCLUDE in `ci-evidence-verdict.test.ts` (371). I finti che tutti e tre usano stanno in `ci-evidence.testkit.ts`: un `fakePort` copiato tre volte e' un blocco duplicato da venti righe che lo stesso cancello conta. deadcode: `CI_RERUN_READS_MAX` era un alias di `CI_API_ERRORS_MAX`, per knip un duplicate export. Tolto invece di rinominato: e' una domanda sola, quante volte questo giro legge GitHub prima di dire che una risposta e' definitiva, e il motivo per cui al rerun ne serve piu' di una e' ora scritto sulla costante che resta. KANBAN-86 GUARDAVA LA RUN, E LA RISPOSTA E' NEI JOB. La chiusura tutta-verde non aspetta la run: scatta appena l'ultima riga dichiarata ha un verdetto, e li' `run.conclusion` e' ancora null. Sonda: run `in_progress` con un job vivo, `check` GIA' `completed/failure` a «Bundle size budget», passo unit verde, quattro shard verdi -> `rows.ok = [true, true]`, `ciRunRed = [null, null]`, esattamente la card verde su CI rossa. Oggi la finestra e' di secondi (su 33 run di ci.yml l'ultimo job e' sempre uno shard e2e, `check` finisce da 2,8 a 10,7 minuti prima) e si allarga appena `check`, o `tauri` con la cache Rust fredda, superano gli shard. Quando la run E' conclusa la sua conclusione prevale: la calcola GitHub su tutti i job, `continue-on-error` compreso. NESSUN COMMIT PROPRIO: NON MISURATO RESTA, LA RAGIONE NO. Tre card vere del 17/09 avevano questa forma (lavoro gia' dentro main) e con questo ramo tornano all'agente invece di entrare in review. Tenuto: da qui dentro quella forma e' indistinguibile da un commit sul ramo sbagliato, da una worktree riportata su main o da un ramo svuotato da un rebase, e due verdi sull'unico ingresso in cui non si e' misurato niente sono la bugia che queste righe esistono per non dire. Sbagliata era l'uscita offerta: «serve un commit nuovo» e' l'unica che un agente puo' prendere, e per una card gia' dentro main quel commit non esiste. Ora la ragione nomina prima l'uscita della persona.
…ardato Mutando code: 1 in code: 0 la suite restava verde: la riga sarebbe rimasta rossa ma etichettata "exit 0" nel dettaglio della card, che si legge come un cancello passato che ha fermato lo stesso. Una seconda piccola bugia dentro la riga che esiste per fermarne una. Con l'asserzione la mutazione muore: 16 pass / 1 fail.
… lasciato quello prima La CI della PR #87 e' rossa su «Bundle size budget» per 28 byte: entry eager 444.684 gz contro un tetto di 444.656. Prima di alzare qualcosa, le quattro misure, stesso commit del ramo unito a main: main, runner CI (run 35221404984) 444.618 gz (tetto 444.656) ramo, runner CI (run 35225290213) 444.684 gz ROSSO per 28 main, Mac locale 444.534 gz ramo, Mac locale 444.580 / 444.589 VERDE per 76 Due cose che si vedono solo mettendole in fila. La prima: il costo proprio di questo ramo e' 66 byte gz (195 raw), cioe' le sette voci italiane di `board.task.checks.*` del verdetto NON MISURATO. Stanno nell'entry perche' `i18n-it.ts` e' la lingua di default; `i18n-en.ts` e' gia' un chunk a parte e `TaskDetail.tsx` finisce in KanbanBoardPane, che e' pigro (verificato cercando la stringa nei chunk costruiti: sta in `index-*.js`, `checksCi` sta in `KanbanBoardPane-*.js`). Non c'e' nessun import da rendere pigro: qui non c'e' un import. La seconda, che e' il motivo vero del rosso: la baseline diceva 435.937 gz e main ne costruiva gia' 444.618. Degli 8.719 byte di tolleranza ne restavano 38. Il 2% aveva smesso di assorbire il rumore del minificatore ed era diventato un budget di crescita che ogni ramo di passaggio spendeva in silenzio; il ramo che arrivava dopo pagava il conto di tutti. Sono esattamente i rossi da 314 e da 28 byte della notte del 16/09, su due consegne che non avevano aggiunto una dipendenza. Quindi il ratchet si riallinea a una build vera invece di comprare altri 66 byte: entry_eager 1.411.389 raw / 444.684 gz, critical_path 2.018.595 raw / 603.702 gz a 5 file. I numeri scritti sono i PEGGIORI fra le due macchine, perche' il gz locale esce ~100 byte piu' piccolo di quello della CI a parita' di sorgente (444.534 contro 444.618 su main) piu' una decina di ballerino fra due build identiche: un `check:bundle` verde sul Mac con meno di ~150 byte di margine non e' una prova, ed e' precisamente come questo ramo si e' visto verde in locale mentre la CI lo chiamava rosso. `total_assets` SCENDE invece, da 8.848.497 a 8.282.484. Erano 566.013 byte di slack: il budget che esiste apposta per beccare una dipendenza pesante aggiunta come chunk pigro non poteva dire niente finche' non se ne fosse mangiata mezza mega. E' la stessa riga che lo script stampa da solo quando una misura scende, applicata al terzo budget, che quella stampa non guarda. Barra locale: i 18 comandi di «Static guard rails», typecheck, lint e check:bundle, tutti exit 0.
La nota della baseline attribuiva i 195 byte raw a "le sette voci italiane di board.task.checks". Le voci sono quattro (unknown, notMeasured, ciPr, ciRun); sette sono le RIGHE aggiunte a i18n-it.ts, tre delle quali sono un commento che non spedisce un byte. Non sposta nessuna misura, i 195 restano corretti. Ma e' un numero falso in un contratto permanente, ed e' esattamente la classe di difetto che questo ramo esiste per chiudere.
# Conflicts: # openspec/changes/coda-che-riparte-da-sola/specs/kanban/spec.md
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(KANBAN-85, KANBAN-86).Il pezzo nuovo, trovato su consegne vere
Stanotte due card su tre hanno scritto «checks pre-review verdi» mentre la run della loro pull request era
completed/failure: il jobcheckfalliva allo step «Bundle size budget» — 314 e 28 byte oltre il tetto — mentre lo step «Unit + integration tests» era verde e i quattro shard e2e pure. Le righe campionano una fetta della prova, e la card ne ricavava una frase piu' larga di cio' che sapeva.Prima del PATCH quella prova non esisteva e la card non poteva contraddirla. Adesso esiste, e' a due chiamate di distanza ed e' rossa. Provato sui dati veri, rigiocando le due run attraverso il lettore:
origin/mainok:[true,true]ok:[false,false], «job check at the step "Bundle size budget"»ok:[true,true]ok:[false,false], stessa riga[false,true][false,true](rosso e2e vero, invariato)Le righe restano vere: il passo unit era verde e dirlo e' corretto. E' la CARD che non puo' dichiararsi verde.
Il resto
run_attempt— un campo che era gia' nel tipo, citato in due commenti, falsificato nei test e mai letto dal codice. 15 delle ultime 100 sha erano gia' in quello stato.mergeable UNKNOWNe' la risposta NORMALE di GitHub nei primi secondi: misurato sulla bozza board: topics/milky-lily (card c4f53a85) #78, quindici secondi dopo l'apertura.unknowncome non misurato, non rosso.Quattro giri di refuta
Il secondo ha trovato che il rerun si rispendeva a ogni riavvio del server, perche' il «una volta sola» viveva in una variabile locale mentre la consegna in attesa e' persistita su DB: con 44 riavvii in 25,7 ore misurati da questa stessa change. Il terzo ha trovato che la condizione allargata faceva scattare il rerun anche accanto a un rosso VERO, buttando via quel rosso: un e2e fallito diventava verde alla seconda attempt, cioe' «riprova finche' non passa» su un cancello di CI. Il quarto ha trovato che il ramo consegnava due rail rossi su se stesso — un file di test a 873 righe contro 800 e un export duplicato — nello stesso passo di CI che aveva fatto rosso le card. Chiusi: barra intera 18 rail su 18 verdi, typecheck, lint, 237 test.
25 mutazioni lanciate, 24 uccise.