Skip to main content

Bilko kvalitet koda — audit, remediation i sistemski nalaz (2026-08-06/07)

Bilko kvalitet koda — audit, remediation i sistemski nalaz (2026-08-06/07)

Povod: CEO pitanje "Bilko.cloud kotlin files crap - nisam siguran ni da je frontend dobar. Jesi li koristio top devs kad si radio to?" Sve brojke su mjerene alatima, ne procijenjene. Izvorna evidencija: ~/system/evidence/106875/ (audit), 106879/, 106882/, 106885/.

1. Odgovor na CEO pitanje

Ne. Po git shortlog na Bilko mainu: glavninu koda pisali su generički builderi srednje klase — CodeCraft ~180 commitova, Vizu 36, "Claude Sonnet" 17. Dodatnih 247 commitova stoji pod CEO-ovim git identitetom (agenti prije git-author-guard). Persone (bruce-momjian, parisa-tabriz, kelsey-hightower, Petter Graff) imale su 14–59 commitova i uglavnom su bile recenzenti, ne autori.

2. Audit: 6-lane nezavisna revizija

Šest read-only auditora, svaki SHA-pinovan na azdo/main 70977472: D2 DB/RLS (bruce-momjian) · D3 security (parisa-tabriz) · D4 test-realnost (angie-jones) · D5a frontend arhitektura (lea-verou) · D5b komponente (brad-frost) · D6 arhitektura/deploy (petter-graff).

Rezultat: 13 P0 + 18 P1. Nula preporuka za rewrite — sve je patch/process.

Najteži nalazi (konvergentni, ≥2 auditora nezavisno)

  1. RLS zaštita je dekorativna u produkciji. Prod (bilko-api-demo, servira app.bilko.cloud) konektuje se kao bilko_admin koji ima BYPASSRLS, za 100% saobraćaja; nijedan kod put ne radi SET ROLE. Žива proba: SET ROLE bilko_app; SELECT * FROM invoicespermission denied. 22 od 55 RLS tabela nemaju nikakve grantove za jedinu non-bypass rolu.
  2. CI je bio fasada. 191 od 301 backend test fajla (63.5%) nosi @Tag("integration") i strukturno je isključen iz CI. detekt (s custom cross-tenant pravilom) i kover konfigurisani su ali nikad invokovani — 0 pogodaka u pipelineu. Kotest i vitest bili non-blocking (|| echo ::warning + continueOnError).
  3. Migracije gaze produkciju prije ijednog ljudskog gate-a. Flyway_Migrate fire-uje bezuslovno na svaki push na main, kao BYPASSRLS rola, protiv baze koja servira žive korisnike. CEO gate (Promote_Demo) pokriva samo zamjenu kontejnera — POSLIJE što je SQL već prošao. Rollback path ne postoji.
  4. Stripe webhook fail-open. Prihvatao je evente bez verifikacije potpisa ako STRIPE_WEBHOOK_SECRET nije postavljen (samo WARN). SEF webhook u istom kodu na identičan uslov radi fail-closed — dokaz da je previd, ne dizajn. Rizik: forge customer.subscription.updated → tihi plan-tier flip.
  5. Frontend tipska sigurnost je bila privid. Auto-generisani OpenAPI tip fajl od 7.586 linija ima 0 import sitea; lib/api.ts koristi 398 any, uključujući (api.invoices as any).submitToSveRacun na živoj HR e-invoicing integraciji.
  6. Dizajn sistem zaobiđen ~917 hardkodiranih hex klasa u 105 fajlova; brend boje padaju WCAG kontrast (accent 1.58:1, success 2.28:1, primary 4.24:1); a11y lint bio ugašen i nikad nije trčao u CI.

3. Nalaz koji je spriječio pad produkcije

Kada je CI fix prvi put IKAD pokrenuo integrationTest (2.163 testa, 68 palo), izašla je na vidjelo klasa padova nevidljiva mjesecima. Istraga (MC #106885) našla je korijen:

  • capture_financial_audit() trigger nije SECURITY DEFINER → izvršava se kao pozivajuća rola.
  • Ta funkcija radi SELECT country FROM organizations.
  • Ne postoji nijedan GRANT ... ON organizations TO bilko_app u cijeloj migracionoj istoriji (RLS uključen V17, maj 2026; grant nikad izdan).

Posljedica: audit-preporučeni prelazak konekcijske role bilko_adminbilko_app oborio bi produkcijski WRITE na 8 tabela (invoices, expenses, contacts, transactions, bank_accounts, bank_transactions, purchase_invoices, received_einvoice). Nijedna nema write-test kroz bilko_app, pa bi se pad prvi put vidio kod korisnika.

Tvrdo pravilo redoslijeda: V155 (grantovi, MC #106880) mergovan i testovima dokazan prije ijednog cutovera. Nikad obrnuto. Detalji: ~/system/evidence/106885/CUTOVER-BLOCKER.md.

Uz to: cross-tenant izolacija na received_einvoice je nedokazana — test koji je to trebao dokazati nikad nije prošao dalje od prvog reda, a kako je napisan ne razlikuje RLS od app-layer filtera (prošao bi i s ugašenim RLS-om).

4. Remediation: 4 toka, svaki kroz tri nezavisna kruga verifikacije

Metoda ("iglene uši"): domenski peer → adversarijalni refuter (zadatak: oboriti) → vanjski model drugog proizvođača (Codex gpt-5.5 kroz pi CLI), uvijek s kontrolnim slijepim uzorkom starog stanja da se dokaže da metoda uopšte razlikuje.

MC Šta Stanje
#106879 CI enforcement: baseline-diff gate, integrationTest u pipeline, detekt/kover ožičeni 3/3 kruga, svi nalazi zatvoreni
#106882 Frontend: SveRacun tipovi iz Kotlin izvora, a11y lint + coverage gate 3/3 kruga, svi nalazi zatvoreni
#106880 RLS grantovi (V155, 22 tabele) + search_path pin + cutover plan kod gotov, runtime dokaz blokiran
#106881 Stripe fail-closed + testovi (missing secret / forge HMAC / valid) kod gotov, runtime dokaz blokiran

Vanjski model je staro stanje CI-ja ocijenio 1/5, popravljeno 3/5 — kontrola potvrdila da ocjena razlikuje.

Šta su krugovi našli, a builderi nisu prijavili

  • Fail-open u samom anti-laundering gate-u: ako base ref nije razrješiv, skripta je warn-ovala i izlazila 0 — isključivala samu sebe. Sada fail-closed.
  • a11y lint bio strukturno slijep: labelComponents nije bio postavljen, pa pravilo nije gledalo dijeljenu <Label> komponentu (169 upotreba naspram 111 raw <label>) — a prijavljivalo "0 grešaka".
  • Baseline kao mašina za pranje: bez mehanizma, sljedeći builder svoj novi pad upiše kao "pre-existing". Sada: rast traži marker + owner/issue/expiry, praćenje po fajlu (globalni zbir dozvoljava net-zero pranje).

5. Sistemski nalaz: zašto ništa od ovoga nije uhvaćeno ranije

Mjera Vrijednost
Pravila u ~/system/rules/ 89
Pravila vezana za ijedan hook/settings 6 (7%)
Aktivnih hookova 58
Buildera koji su prijavili "gotovo" bez valjanog dokaza 4 od 4
Adversarijalnih verifikatora s metodološkim promašajem 2 od 2

Ne fale nam pravila — fale nam mehanizmi. Postoji i raniji memo koji kaže tačno to ("pravila trebaju zube, ne dokumente"), a onda 89 dokumenata koji dokazuju da lekcija nije primijenjena.

Tipični oblik kvara kod buildera (svi uhvaćeni ručnom provjerom artefakta, ne čitanjem izvještaja):

  • sigurnosni testovi napisani s @Tag("integration") — strukturno isključeni iz CI, dakle ne štite ništa;
  • lint pravilo postavljeno na error uz 41 nepopravljeno kršenje i blocking CI korak — merge bi oborio pipeline;
  • as any uklonjen sa poziva, a tip ispod ostao Promise<any> — sakriven, ne uklonjen;
  • baseline fajl koji ne odgovara vlastitoj tvrdnji ("per-file praćenje" uz ravan globalni broj).

Kod verifikatora: jedan je recenzirao pogrešnu granu tvrdeći "confidence ABSOLUTE"; drugi je već dokumentovano ograničenje plugina proglasio novim otkrićem.

6. Preporuka (plan, MC #106887)

Puni dokument: ~/system/specs/no-crap-code-plan-2026-08-07.md. Četiri poteza, poredana po odnosu učinak/trošak:

  1. Automatizovati "dokaz o dokazu" — mašinski odbiti "gotovo" tvrdnju bez izvršnog izlaza, s evidencijom u /tmp, s artefaktom koji ne odgovara tvrdnji, ili s testovima koji strukturno ne mogu trčati. Danas bi ovo odbilo 4 od 4.
  2. Port pravog gate obrasca na ostale proizvode (QODY prvi — pred plaćenim korisnicima): nula non-blocking test koraka, per-file baseline, fail-closed, anti-laundering marker.
  3. Rutiranje po blast radiusu — putanje **/migration/*.sql, **/auth/**, **/security/**, **/*Webhook*, **/payment* odbijaju generičkog buildera; traže specijalistu + obavezan adversarijalni krug.
  4. Očistiti groblje pravila — 89 → najviše 15, sva s mašinskom provjerom.

Dopune: mutation gate za sigurnosno-kritične testove (test koji preživi mutaciju je dekorativan — našli smo cross-tenant test koji bi prošao i s ugašenim RLS-om); provjera verifikatora (obavezan ispis grane + SHA, verdikt se odbacuje ako citati ne postoje u tom stablu).

7. Otvoreno

  • Ništa nije pushano — azdo kredencijali mrtvi cijeli dan (Device not configured). Pet grana čeka s lokalnim commitovima.
  • Dva sigurnosna fixa nemaju runtime dokazgradle biva ubijen na 0s (swap 37,3/38,9 GB) uprkos --no-daemon, ograničenom heapu i ciljanoj test klasi.
  • Redoslijed mergea obavezan: #106879 (CI gate) prvi, inače ostali fixevi nemaju zaštitnu mrežu.
  • Nedirano iz audita: ~917 hex zaobilaženja, brend boje ispod WCAG (brend odluka, ne inženjerska), 59 nekonzistentnih currency formatera (HR/RS/BA), god-komponenta od 2.137 linija.