# Bilko repo higijena — grane i worktree čišćenje (2026-08-23)

<!-- ALAI-MC:900163:BEFORE -->
CEO nalog 2026-08-23: očistiti tonu git grana (222 na azdo) i lokalne worktree-ove (154). Politika i izvještaj — u izradi (MC task u opisu).

## MC #900163 — rezultat 2026-08-23 (FlowForge)

### Politika (kako je primijenjena)

**Remote grane (azdo, repo Bilko):**
1. Dohvaćeni SVI completed (301), active (16) i abandoned (7) PR-ovi preko REST API-ja, paginirano.
2. SAFE-DELETE = grana postoji na azdo I ima completed PR I nije `main`/`feat/900153-landing-v4` I nema drugi aktivan PR na istom imenu. Squash merge čini git ancestry nepouzdanim, pa je dokaz mergea **completed PR status**, ne merge-base provjera.
3. Prije brisanja snimljena kompletna lista (grana, PR#, closedDate, head SHA) — recovery mogućnost sačuvana.
4. Brisanje REST-om (ref update na `0000...`) u batchevima od 25; svaki batch verifikovan pojedinačno, pa cijeli rezultat provjeren protiv `git ls-remote` (ne samo API odgovora).

**Lokalni worktree-ovi (154, kanonski repo):**
5. `git worktree remove` (čuva granu) samo ako: git status čist, grana potvrđeno backovana na azdo (provjereno protiv snapshot-a od 222 grane PRIJE brisanja, jer smo mi sami upravo obrisali 151 remote grana — provjera protiv trenutnog azdo stanja poslije vlastitog brisanja bila bi samopobjeđujuća), fajlovi stariji od 48h, i putanja nije na isključenoj listi (kanonski checkout, `bilko-900153-landing-v4`, `bilko-107242-build-requires-ci-gates`).
6. Za svaku granu bez lokalnog "backed" statusa provjereno je i `git log --not --remotes=azdo` (postoje li komiti van remote-a) — otkriveno 3 slučaja gdje je ovaj signal bio LAŽNO pozitivan zbog squash-merge SHA divergencije (vidi Nalazi ispod); sadržaj provjeren `diff` protiv `main` prije konačne ocjene.
7. Na kraju `git worktree prune` + finalno brojanje.

### Rezultati

| Kategorija | Broj |
|---|---|
| Remote grane prije | 222 |
| Remote grane obrisane (completed PR, safe-delete) | 151 |
| Remote grane preostale (active PR: 16, bez PR-a: 48, abandoned-only: 5, protected: 2) | 71 |
| Worktree-ovi prije | 154 |
| Worktree-ovi uklonjeni (`git worktree remove`, grane sačuvane) | 4 |
| Worktree-ovi preostali | 150 |

Razlozi zašto 146/150 preostalih worktree-ova NIJE uklonjeno: 138 prljavo (neuskladištene/nepraćene izmjene — provjereno, stvaran rad, ne generisani artefakti), 9 grana bez potvrđenog backupa na azdo, 3 isključena politikom.

### Nalaz: lažno pozitivan "jedini primjerak" signal (squash merge)

Tri worktree-a (`bilko-wt-107298-security`, `bilko-wt-107299-security`, `bilko-wt-107300-security`) su Azure DevOps sam obrisao s remote-a odmah nakon completed PR-a (352/353/354/356, sve 2026-08-18), pa lokalni git repo ima zastarjele remote-tracking reference. `git log --not --remotes` je za sve tri prijavio "1 neuskladišten komit", što je izgledalo kao rizik gubitka podataka. `diff` protiv `main` je potvrdio da je sadržaj **bajt-identičan** onome što je već u `main` (squash merge mijenja SHA ali ne sadržaj). Nije nalog za akciju — samo dokumentovan da se ovaj signal ne čita bez provjere sadržaja.

### Praksa "after work done" (preporuka, bez implementacije)

1. Builder poslije uspješnog mergea PR-a sam briše svoj lokalni worktree (`git worktree remove`) i svoju feature granu (lokalno i na remote-u, ako azdo to već ne radi automatski).
2. Ako builder to propusti, sedmični/mjesečni sweep ponavlja politiku iznad: completed PR = kandidat za brisanje grane, provjera protiv active/abandoned prije diranja.
3. Provjera "backed on azdo" mora koristiti snapshot OD PRIJE bilo kakvog brisanja u istoj sesiji — nikad trenutno stanje poslije vlastite akcije (samopobjeđujuće).
4. Squash merge čini `git log --not --remotes` nepouzdanim signalom za "izgubljen rad" — uvijek provjeriti sadržaj (`diff` protiv `main`) prije nego se nešto označi kao rizik.
5. Preporuka: `task-postflight` dobije korak "obriši svoj worktree + granu po merge-u" kao dio zatvaranja taska (ovo je preporuka, nije implementirano u ovom MC-u).

Evidencija: `~/system/evidence/900163/deleted-branches.tsv` (151 grana: branch, pr_id, closedDate, head_sha).