Články

Kontrola měří něco jiného, než si myslíš

· 4 min čtení

Špatná odpověď se většinou pozná. Číslo nesedí, test spadne, něco svítí červeně. Horší je odpověď na jinou otázku, než jakou jste položili. Vypadá úplně stejně jako ta správná: má správný tvar, přišla ze správného příkazu a nikde nic nehlásí. Jen neměří to, co si myslíte.

Stavím s pomocí AI, takže spoustu věcí ověřuju skripty, kontrolami a audity. O to víc mě zajímá, kdy kontrola lže. Tady jsou tři případy z jediného dne a pravidla, která mi z nich zůstala.

Padesát dva commitů s klíčem, který tam nebyl

V poznámkách, které držím v gitu, se našlo pár API klíčů. Stává se. Vyčistil jsem je z historie přes git filter-branch a pak spustil kontrolu: projdi všechny commity a hledej ten klíč.

Výsledek: klíč je pořád v 52 commitech. Takže čištění nefungovalo? Fungovalo. filter-branch si původní historii pro jistotu odkládá stranou, do refs/original/. A přepínač --all bere všechny reference, tedy i tuhle zálohu. Kontrola poctivě našla klíč v záloze, kterou jsem si před chvílí sám vyrobil.

Zrádné je to oběma směry. Kdo číslu věří, čistí donekonečna něco, co je dávno čisté. A kdo mávne rukou, že je to jen záloha, a pošle na server všechno, pošle tam i tu zálohu. I s klíči.

git rev-list main          # jen to, co se opravdu odesílá
git update-ref -d refs/original/refs/heads/main
git rev-list --all         # teprve teď má --all smysl

Sedmdesát osm nálezů, které byly jeden

Jiný repozitář, týž den. Sken na klíče k API (začínají sk-ant-) hlásil 78 zásahů. A to už bylo po pushi, takže studený pot.

Ve skutečnosti šlo o jediný nález, a ani ten nebyl klíč. V README stálo ANTHROPIC_API_KEY=sk-ant-..., tedy ukázka formátu s tečkami místo tajemství. Sedmdesát osm vyšlo proto, že git grep -c vypsal řádek za každý commit, ve kterém ta věta byla, a wc -l ty řádky poslušně sečetl. Počítal jsem commity, ne nálezy.

Plynou z toho dvě věci. Vzor musí být přísný: ne holý prefix, ale prefix a za ním dost dalších znaků, aby to vůbec mohl být skutečný klíč. A nález si musí někdo přečíst očima, protože číslo neřekne, co počítalo.

Odpověď byla na druhém řádku

Třetí případ mě stál hodinu. Zkoumal jsem, jestli proxy před jednou službou propouští WebSocket. Zkouška byla jednoduchá: poslat požadavek na upgrade a podívat se na první řádek odpovědi.

curl -sS -i -N --http1.1 ... 2>&1 | head -1
curl: (28) Operation timed out ... with 0 bytes received

Timeout, nula bajtů. Proxy upgrade zahazuje, jasná věc. Hodinu jsem ji pak ladil. Jenže upgrade prošel a 101 Switching Protocols leželo na druhém řádku. Curl WebSocketem dál mluvit neumí, takže i po úspěšném upgradu skončí timeoutem. Jeho hláška jde na stderr, který jsem si přes 2>&1 vmíchal do výstupu, a do roury dorazila dřív než hlavičky ze stdout. head -1 pak vybral přesně tu jednu větu, která nic neříkala.

Chyba nebyla v proxy. Byla v mé zkoušce.

Co si z toho beru

Všechny tři příkazy fungovaly správně. Odpověděly přesně na to, na co jsem se zeptal. Jen jsem se ptal na něco jiného, než jsem chtěl vědět. Proto si teď u každé kontroly kladu pár otázek:

Totéž platí u AI. Když mi asistent napíše „hotovo, ověřeno", ptám se, čím to ověřil. A jestli ta kontrola nenašla sama sebe. Hledání slova v souboru, kde to slovo stojí v komentáři vysvětlujícím, co se hledá, projde pokaždé.

Proto taky kontrola webu tady na webu nevrací jen jedno číslo. Ukáže sedm oblastí a u každého nálezu napíše, co přesně nesedí.

Další článek: Změna v repu není změna na serveru