Skip to content

fix(cacbg): фантомни редове и --limit обезсилваха гейта за пълнота - #281

Merged
todorkolev merged 2 commits into
mainfrom
fix/cacbg-completeness-gate
Aug 4, 2026
Merged

fix(cacbg): фантомни редове и --limit обезсилваха гейта за пълнота#281
todorkolev merged 2 commits into
mainfrom
fix/cacbg-completeness-gate

Conversation

@todorkolev

Copy link
Copy Markdown
Collaborator

Предпоставка за първото зареждане с данни към staging. Без нея пълният обход на регистъра завършва с ненулев изход и ship изобщо не се стига. Двете находки са от прегледа на #226 (моята за parseList, тази за --limit е на @ydimitrof) и са описани в #279.

1. Фантомни редове в parseList

parseList обявяваше всеки ред с истинен xmlFile. Регистърът обаче издава и редове-заместители, които не именуват документ:

<Declaration><Sent>False</Sent><xmlFile>U</xmlFile><Title>Уведомление</Title></Declaration>

Има 87 такива в 15 от 35-те набора. U минаваше проверката за истинност, значи краулерът обявяваше декларация, която не съществува, после не успяваше да я изтегли и записваше грешка. Резултатът: тези 15 набора никога не можеха да удовлетворят гейта - пълен обход завършва с изход 1 и няма как да се публикува.

Поправката иска формата на име на файл, взета от guard.mjs: isXmlFile е булевият близнак на safeXmlFile, тоест формата остава на едно място. parseList не бива да хвърля, защото липсата на име там не е грешка, а нормален заместител.

2. --limit заобикаляше гейта

announced се четеше след среза, значи нарочно частичен обход докладваше announced == obtained и гейтът минаваше върху корпус, който никога не е бил опитван.

Само преместването на announced преди среза не стига: неопитаните редове не пораждат грешки, а incomplete се извеждаше от грешките. Всеки обявен ред попада в точно една кофа, тоест пълен обход изпълнява announced == obtained + sourceGaps + unfetched; излишъкът значи неопитани редове. Броим го като notAttempted и гейтът пада на него.

Проверка

Срещу пълния корпус: 256 286 обявени реда, от които 87 фантомни; останалите 256 199 се покриват точно от 255 582 изтеглени плюс 617 липсващи в източника (404). Тоест пълен обход вече докладва „пълен".

Тестовете са мутационно проверени - връщането на всяка от двете поправки поотделно чупи точно нейните тестове (2 и 1). Всичките 84 теста в scripts/cacbg минават с командата на CI.

Затваря частично #279 (§12 и последната точка от раздел 1).

…ness gate

Two ways the corpus completeness gate could report a verdict it had not earned.

parseList announced any row with a truthy xmlFile. The register also emits placeholder
rows that name no document — <Sent>False</Sent><xmlFile>U</xmlFile> with
<Title>Уведомление</Title>, 87 of them across 15 of the 35 sets. 'U' passed the
truthiness test, so the crawler announced a declaration that does not exist, failed to
fetch it, and booked an error. Those 15 sets could therefore never satisfy the gate: a
full crawl of the register ends in a non-zero exit and no ship, forever. Require the
filename shape instead, reusing guard.mjs's — isXmlFile is the boolean twin of
safeXmlFile, one source of truth for what a declaration file looks like.

--limit truncated the work before `announced` was read, so a deliberately partial crawl
reported announced == obtained. Read `announced` from the set, before the slice. That
alone is not enough: rows never attempted produce no errors, and `incomplete` was derived
from errors, so the gate still passed. Every announced row lands in exactly one bucket, so
a full pass satisfies announced == obtained + sourceGaps + unfetched; a surplus means rows
were never tried. Count it as notAttempted and fail on it.

Verified against the full corpus: 256 286 announced rows, of which 87 phantoms; the
remaining 256 199 are matched exactly by 255 582 obtained plus 617 source-side 404s, so a
complete crawl now reports complete. Both fixes are mutation-checked — reverting either
one fails exactly the tests written for it.

Refs #279
@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown

Test coverage

Workspace Lines Δ Branches Δ Functions Statements
apps/etl 74.05% +0.05pp 58.22% +0.02pp 70.21% 71.42%
apps/web 91.02% +1.32pp 82.50% +0.70pp 91.19% 89.73%
packages/config 92.85% +0.05pp 72.22% +0.02pp 92.85% 89.18%
packages/db 94.54% +0.34pp 79.38% +0.38pp 87.19% 91.55%
packages/ingest 86.37% +0.57pp 80.46% +0.46pp 79.27% 84.40%
packages/shared 95.50% +0.10pp 80.83% +0.83pp 92.30% 89.56%
Total (informational) 91.03% 80.34% 86.94% 88.78%

✅ No workspace dropped below its baseline (tolerance 0.5pp).

📈 Coverage rose by more than 1pp — run node scripts/check-coverage.mjs --update locally and commit coverage-baseline.json to ratchet the threshold up.

@todorkolev
todorkolev merged commit f72306c into main Aug 4, 2026
5 checks passed
lyubomir-bozhinov added a commit to lyubomir-bozhinov/sigma that referenced this pull request Aug 4, 2026
…acbg gate midt-bg#281)

Two commits landed on main while the midt-bg#226 sync was in flight — an undici
override bump to ^7.29.0 and a cacbg completeness-gate fix (phantom rows /
--limit). Clean merge; the surface is pnpm-workspace.yaml + scripts/cacbg,
none of it inside the six measured workspaces, so the coverage baseline is
untouched and the gate stays green.

Verified against the merged tree: scripts tests 51 pass, cacbg pipeline tests
84 pass (run via the register-ts loader, as the CI job does), coverage ratchet
green for all six workspaces.
LyuboslavLyubenov added a commit to LyuboslavLyubenov/sigma that referenced this pull request Aug 5, 2026
Clean automatic merge: no conflicts. Upstream advanced 3 commits since the
PR's previous rebase (related-persons midt-bg#226, undici bump midt-bg#282, cacbg fix midt-bg#281);
none of those touch the PR's test-only surface (apps/web/test/integration/*,
docs/spec/integration-testing.md, apps/web/vitest.integration.config.ts).
The single auto-merged file is docs/README.md, which gained a new ADR entry
in upstream (0032); the merge preserves the alphabetical/numerical ordering
without re-flowing the PR's content.

Verification (local):
- pnpm typecheck → 7/7 packages clean
- pnpm --filter @sigma/web test → 530 passing (52 files, 8 integration files,
  41 integration tests, 0 .skip)
- pnpm lint → (run separately)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants