fix(cacbg): преходът от режима преди #309 е декларирано оттегляне, не находка - #333
Conversation
… находка Snapshot заявката прави LEFT JOIN на interest_links към interest_link_evidence и мапваше липсващия ред към текущата RULES_VERSION (rules_version ?? RULES_VERSION). Схемата има rules_version NOT NULL, значи fallback-ът се задейства САМО когато няма ред за връзката - точно случая на 103-те връзки, публикувани преди #309 да въведе таблицата. Ефектът беше отпечатан: първото пълно пускане към staging след бумването на правилата (32736025202) стигна одита с 731/731 присъди и 277 нови публикувани, но гейтът за монотонност отчете 37 регресии и 0 декларирани оттегляния - режимът, който ги беше публикувал, вече не съществува, а fallback-ът маскираше това. Решението: премахни fallback-а. Липсата на ред остава null, а declaredRemoval в audit.mjs чете null !== RULES_VERSION → декларирано оттегляне. audit.mjs добавя изричен клон, който отпечатва точно това основание, вместо "rules change (null → tr-rules-2)". Тестове: 46 минават. Тестът в load.test.mjs симулира точно преходния случай - изтрива реда за евидиране между две пускания и чака null в експортирания snapshot. Убива връщането на fallback-а обратно.
Test coverage
✅ No workspace dropped below its baseline (tolerance 0.5pp). 📈 Coverage rose by more than 1pp — run |
|
Гейт-фиксът е коректен — проверих го при Едно нещо за отделна проверка — не блокер на този PR, и въпрос към #309 rebuild-а, не към гейта: 37-те връзки, които изпаднаха от публикувания сет при прехода (103 → 277 публикувани, но 37 от старите ги няма). Гейтът вече минава по тях като „оттеглени по регимен преход" — което е вярно САМО ако всичките 37 наистина не покриват evidence бара на #309 (нямат Струва си еднократен spot-check на staging: за 37-те |
Първата версия на печата имаше преходен капан от същия вид, който #332 и #333 вече ни удари: всички съществуващи кешове са отпреди печата, тоест ход без обхождане (понеделнишкият cron) щеше да откаже на extract - не защото корпусът е отрязан, а защото е СТАР. И поправката щеше да зависи от поредността "слей, после пусни full_crawl=true преди понеделник". Вместо това ходът се лекува сам. Нова стъпка след възстановяването проверява печата; краулът тръгва при full_crawl ИЛИ при липсващ печат. Върху пълен кеш това е ~2 минути (файловете на диска се прескачат) и сверява срещу живия регистър - авторитетния източник, а не евристика върху това какво има на диска. Запазването и проверката на кеша следват същото условие, за да не се изгуби довършеното. Стабилно състояние с печатан кеш остава без мрежа, по замисъла на графика: лекуването се задейства само за кеш, който никога не е бил потвърден цял - точно случаят, в който довярването му е бъгът. Гейтът в extract.mjs остава непроменен и вече означава друго: всички пътища дотам гарантират печат, значи задействането му е непредвидено състояние, не позната преходност. Fail-closed е верният отговор за това.
Какво
Snapshot заявката в
load.mjsвече оставяnullза връзка без ред вinterest_link_evidence, вместода я маскира с текущата
RULES_VERSION. Гейтът за монотонност вaudit.mjsвече чете това катодекларирано оттегляне и отпечатва точно основанието "the pre-evidence regime — predates §8 and #309".
Защо
interest_link_evidenceе добавена от #309 (acfcdcef). Връзки, публикувани преди това, нямат ред внея - на staging това са всички 103. Snapshot заявката прави LEFT JOIN и мапваше липсата с
r.rules_version ?? RULES_VERSION. Схемата държиrules_version TEXT NOT NULL, значи fallback-ът сезадейства САМО при LEFT JOIN пропуск, тоест точно на прехода.
Ефектът: първото пълно пускане към staging след бумването (
32736025202) стигна до одита с 731/731присъди и 277 публикувани, но гейтът отчете:
Режимът, който беше публикувал тези 103, вече не съществува.
tr-rules-2изисква регистърнодоказателство, а те нямат такова, защото таблицата не е съществувала. Но fallback-ът вкарваше
tr-rules-2за всичките - гейтът виждаше "изчезнала при непроменена версия" вместо "изчезнала присмяна на режима".
Поправката
Три части, всяка обяснена в коментарите:
load.mjs: премахнат?? RULES_VERSION.rules_versionе NOT NULL в схемата, така че липсатавинаги означава "няма ред", което е точно преходният случай. Пази null и предава семантиката.
audit.mjs:declaredRemovalвече четеnull !== RULES_VERSION→ true. Изричен клон всъобщението назовава основанието с думи ("the pre-evidence regime"), вместо да отпечатва "rules
change (null → tr-rules-2)".
audit.test.mjs- snapshot сrules_version: null→ декларирано оттегляне идумите се появяват. В
load.test.mjs- симулира преходния случай (изтрива реда за евидиранемежду две пускания) и чака null в експортирания snapshot. Убива връщането на fallback-а.
Всичко: 46 минават. Работният път (връзка с ред за евидиране) не се променя - fallback-ът е бил
неактивен при него от NOT NULL нататък.
Какво следва
При пускането след сливането: гейтът вижда 103-те стари като декларирани оттегляния, минава, а
пътят продължава към
Apply schema → Ship → Reindex.sigma-stage.midt.bg/conflictsсе напълва.Извън обхвата
Дали 37-те стари връзки трябва пак да се публикуват под
tr-rules-2е отделен въпрос заметодологията, не за гейта. Ако да - от следващото пускане ще имат ред за евидиране и ще се държат
нормално.