Record that a paid run's database must be read by its own reader: the engine store either refuses it or migrates it in place

This commit is contained in:
heaven 2026-09-16 19:35:50 +03:00
parent 4098ec47fa
commit 6a515e41d4

View file

@ -219,3 +219,19 @@ UNKNOWN 1 — её, дошёл один раз до правок; десять
⇒ Практика: у любой пайплайн-команды, чей ноль несёт вывод, печатать `PIPESTATUS`/код возврата ПЕРВОГО звена,
а не только число строк. `find_exit=127` виден сразу, «0» — не виден никогда.
## ⛔ УЛИКА ПЛАТНОГО ПРОГОНА ОТКРЫВАЕТСЯ ТОЛЬКО СВОИМ РИДЕРОМ — движковый стор её либо не пустит, либо ПЕРЕПИШЕТ (16.09)
Нашла бэкенд-сессия на банк-паке, проверено мной деревом. База купленного прогона отстаёт по схеме от головы
(замерено: `A-after` на 16 при голове 18), и дальше развилка, у которой обе ветви плохи:
- `store.OpenReadOnly` (`backend/internal/store/store.go:161`=`current != len(migrations)`) на несовпадении
**ОТКАЗЫВАЕТ** `SchemaMismatchError` — прочитать улику им нельзя;
- обычный `store.Open` идёт через миграцию (`backend/internal/store/migrate.go:673`=`for v := current; v < len(migrations); v++`)
и **МОЛЧА ПРИВОДИТ СХЕМУ К ГОЛОВЕ** — то есть переписывает купленный прогон, и улика перестаёт быть уликой.
**Норма:** улики платных прогонов читаются собственным ридером на `mode=ro&immutable=1`, замеры снимаются на
КОПИЯХ, хеши копий печатаются. ⚠ `immutable=1` обязателен, а не желателен: обычный `mode=ro` создаёт рядом с
базой файл `-shm`, то есть трогает каталог улики (поймано первым же зондом той же сессии).
⚠ И общий класс, ради которого это здесь: **инструмент своей зоны, применённый к замороженному артефакту,
чинит его под себя.** Спрашивать надо не «пустит ли меня прибор», а «что он сделает с предметом, когда пустит».