# qa-19 JUnit fail-closed popravka — MC #107337

# qa-19 JUnit fail-closed popravka — MC #107337

**Datum:** 2026-08-20  
**Komponenta:** `~/system/tools/qa-19.js`, check 6 — Tests Pass  
**Build:** GPT-5.6 high builder  
**Nezavisna verifikacija:** Claude Sonnet, završni verdict PASS, P0=0/P1=0  
**Commit:** `e3c787f8f5867639cdb82c361c1d57186ad40f2f`

## Problem

Prethodna popravka #107330 uklonila je lažni negativ na istinitom JUnit-u: riječi `failures` i `errors` više se nisu tretirale kao dokaz pada kada su njihovi atributi nula.

Nezavisni peer je zatim našao suprotan, opasniji kvar. Helper za čitanje numeričkih atributa vraćao je podrazumijevanu nulu kada atribut:

- nedostaje;
- nije broj, npr. `failures="unknown"`;
- bude odsječen u korumpiranom CI izlazu.

Takav korumpiran dokaz mogao je dobiti verdict PASS. Gate koji odlučuje smije li se task zatvoriti padao je otvoreno.

## Implementacija

`parseJUnitVerdict()` sada:

1. prepoznaje JUnit namjeru po `testsuite` tagovima;
2. strogo parsira svaki atribut bez podrazumijevanih vrijednosti;
3. zahtijeva `tests`, `failures` i `errors` kao nenegativne decimalne safe integer vrijednosti;
4. odbija nedostajuće, nenumeričke, duple, negativne, decimalne, eksponentne i overflow vrijednosti;
5. odbija malformed/truncated tagove, neočekivana zatvaranja i nemoguće brojeve gdje `failures + errors > tests`;
6. sigurno agregira više suite-ova;
7. zadržava postojeći plain-text put bez šireg redizajna.

## P1 pronađen u prvom reviewu

Prva builder runda bila je prestroga: zahtijevala je zatvaranje svakog opening taga. Time je odbila stvarni kanonski evidence iz Bilko builda 1150:

```xml
<testsuite name="storno-credit-note-106104.spec.ts" tests="5" failures="0" errors="0">
```

Taj evidence je namjerno sačuvan kao jedan, atributno kompletan opening-tag excerpt bez `</testsuite>`. Zbog regresije je `qa-19 check 107282` check 6 pao, iako je upravo taj slučaj #107330 morao dozvoliti.

## Round-2 korekcija

Dodan je uski izuzetak: non-self-closing opening tag bez završnog taga prihvata se samo kada:

- postoji tačno jedan `testsuite` tag;
- cijeli evidence nakon `trim()` čini upravo taj tag;
- nije closing ni self-closing tag;
- atributna sintaksa je potpuna;
- sva tri obavezna numerička atributa prolaze strogu validaciju.

Wrapper, body tekst, prefiks/sufiks, drugi tag, malformed drugi suite ili bilo koji drugi ne-whitespace sadržaj i dalje padaju zatvoreno.

## Mašinska verifikacija

```text
node --check tools/qa-19.js                         PASS
node --check tests/qa-19-junit-verdict.test.js     PASS
node tests/qa-19-junit-verdict.test.js              97/97, 31 slučaj
node tests/qa-19-task-type.test.js                   9/9
node tests/qa19-pipeline-marker-107356.test.js       15/15
git diff --check                                    PASS
```

Stvarna kontrola:

```text
node tools/qa-19.js check 107282
check 6: PASS — tests=5 failures=0 errors=0
ukupno: 13/16, očekivano zbog tri nepovezana GOTCHA checka
```

Završni nezavisni validator izvršio je ukupno 161 assertion/control, uključujući 40 vlastitih adversarijalnih slučajeva. Nije nađen P0 ni P1.

## Scope i hash-evi

Commit mijenja samo:

- `tools/qa-19.js`
- `tests/qa-19-junit-verdict.test.js`

```text
qa-19.js: 4d3167096fca8a67c971e64bc6b4453f387201fffe415d8c651900f4ca94bc5d
test:     7b7bd7da71962b945e2342768de330deaadd075ca9f80d55e543817abe994fe6
```

Prethodno staged stanje dijeljenog `~/system` repoa ostalo je netaknuto tokom path-scoped commita.

## Evidence

- `/Users/makinja/system/evidence/107337/gpt56-high-builder-2026-08-20.md`
- `/Users/makinja/system/evidence/107337/gpt56-high-builder-round2-2026-08-20.md`
- `/Users/makinja/system/evidence/107337/peer-validator-claude-sonnet-round2-2026-08-20.md`

## Namjerno van scopea

- Plain-text heuristika i dalje može biti prestroga prema tekstu `0 failures`; to nije novi regresijski put i zahtijeva zaseban task.
- Check 6 i dalje bira prvi evidence filename koji sadrži `test`; izbor najboljeg evidence fajla nije dio #107337.
- Parser je bounded JUnit parser, ne generalni XML validator.
- Nije bilo deploya ni produkcijske promjene; ovo je lokalni sistemski gate u kanonskom `~/system` repou.