store: при равной полноте точек побеждает пришедшая доставка
- байтовый порядок канонических форм остался тай-брейком только внутри одной доставки: на живом корпусе он решал 98,8% спорных координат и системно хранил меньшее значение, из-за чего step_count терял род и verify:archive был красным - правило перестало быть коммутативным осознанно, поэтому порядок свёртки приведён к журнальному: проход воркера прекращается на отложенной доставке, а свёртка вне порядка журнала пишет WARN - заведены счётчики PointsHeld и PointsErased — удержание полнотой и единственное направление, в котором правило теряет содержание
This commit is contained in:
@@ -0,0 +1,368 @@
|
||||
# Триаж: tie-break-equal-completeness
|
||||
|
||||
## Сводка
|
||||
|
||||
- **Профиль:** `deep`, режим — линейный (по слову оператора). База диффа
|
||||
`de2001d`.
|
||||
- **Гейт:** зелёный. Непокрытыми остались 9 изменённых строк — все ветки
|
||||
обработки ошибок (`internal/replay/worker.go:272-275`,
|
||||
`internal/store/bucket.go:488,564-565`, `internal/store/delivery.go:266-267`).
|
||||
- **Проходы поимённо, с исходом** (сверено с профилем: `deep` = 7–8 проходов по
|
||||
`docs/review.md`, здесь 7 на коде включая триггерный `reimpl` — расхождения с
|
||||
составом профиля нет):
|
||||
- `gate` — отработал, зелёный, 3 находки о покрытии тестами;
|
||||
- `specs` — отработал, 6 находок; отдельно подтвердил построчно, что
|
||||
переписанные тесты не подгоняют оракул;
|
||||
- `code` — отработал, 0 находок;
|
||||
- `adversary` — отработал, 4 находки + ответ на вопрос журнала (пути значения
|
||||
точки в лог выше `DEBUG` не найдено, 7 враждебных тел);
|
||||
- `ops` — отработал, 4 находки + ответ на вопрос журнала (результат — функция
|
||||
префикса журнала плюс порядка появления строк учёта);
|
||||
- `reimpl` — запускался по триггеру «новое правило слияния», 3 находки; поимённо
|
||||
назвал 6 мест, где существующее решение лучше его собственного, и снял одну
|
||||
чужую находку (стоящая голова очереди не нема: `internal/fold/fold.go:450`
|
||||
пишет `WARN` на каждую отложенную свёртку);
|
||||
- `architecture` — отработал, 2 находки + 2 замечания «дешевле до мерджа»;
|
||||
- до кода — профиль `design` (`specs`, `rubric`, `architecture`): находки
|
||||
отработаны в спеках и коде, повторно не поднимались.
|
||||
- **Вход/выход:** на входе 22 именованных находки семи проходов; после
|
||||
дедупликации, оракулов и отсева — 3 блокирующих, 4 «исправить сейчас»,
|
||||
6 гипотез, 3 promote-кандидата. Выброшено как вкусовщина 3 (названы в
|
||||
границах покрытия).
|
||||
- **Оракулы триажа** (добыты на временных базах, `./tmp/oracle/`, в `./data` не
|
||||
ходил): падающий тест на разрушительное направление слияния; замер
|
||||
`ParsedAfter` на 2 000/8 000/20 000 доставках; `EXPLAIN QUERY PLAN`.
|
||||
- **Разрешённые конфликты проходов:** O1 против R3 — оба замера верны, спор был
|
||||
об интерпретации; разрешён собственным замером (см. пункт 3 «Стоит
|
||||
исправить»). A1 сверен с корпусным замером оркестратора — конструкция
|
||||
воспроизводится, на живом корпусе 0 вхождений.
|
||||
|
||||
---
|
||||
|
||||
## Блокирует мердж
|
||||
|
||||
### 1. Обеднённая доставка стирает измеренное поле сохранённой точки, и ни один счётчик этого не видит
|
||||
|
||||
- Файл: `internal/store/bucket.go:561-605` (`resolve`, `pointLess`),
|
||||
`internal/canon/canon.go:267-283` (`Relate`)
|
||||
- Severity: critical
|
||||
- Confidence: high
|
||||
- Оракул: падающий тест триажа `tmp/oracle/a1_test.go`
|
||||
(`TestA1ОбеднённаяПришедшаяСтираетПолеБезСчётчика`): сохранено
|
||||
`{date, asleep:7.5, rem:1.2, deep:0.9}`, приехало
|
||||
`{date, asleep:7.4, deep:0.9}` — `Relate` даёт `equal` (значения общего ключа
|
||||
разошлись, разряд полноты гаснет), тай-брейк отдаёт победу пришедшей, в
|
||||
витрине остаётся точка **без `rem`**, `PointsHeld=0`, `Incomparable=0`,
|
||||
`Overwrites=1` (направления не различает). Подтверждает конструкцию
|
||||
`adversary` (A1).
|
||||
- Последствие: нарушение инварианта «Ничего не теряем молча» (`CLAUDE.md`,
|
||||
critical). До изменения этот исход был жребием байтового порядка; теперь он
|
||||
**детерминированно** в пользу обеднённой пришедшей, а новый счётчик
|
||||
`PointsHeld` считает только обратное, безобидное направление. Вероятность
|
||||
низкая: корпусный замер оркестратора — 0 вхождений на 80 129 спорных
|
||||
координат (2 координаты с потерей ключа — ровно 2 несравнимые пары, их
|
||||
считает `Incomparable`). Но порча с низкой вероятностью весит больше
|
||||
гарантированного неудобства, и молчание здесь полное.
|
||||
- Предложение — выбор владельца, оба варианта названы `adversary`:
|
||||
- (а) счётчик разрушительного направления: победитель `incoming`, а у
|
||||
проигравшего сохранённого есть содержательный ключ, которого нет у
|
||||
победителя → счётчик + координата в лог (зеркально `PointsHeld`, сравнение
|
||||
уже посчитанных `fields`, цена ~нулевая). Семантика слияния не меняется;
|
||||
на текущем корпусе счётчик будет нулевым — это и есть утверждение.
|
||||
- (б) сузить «побеждает пришедшая» до случая совпавших множеств
|
||||
содержательных ключей; при несовпавших — побеждает более полная по именам.
|
||||
Меняет правило слияния и текст дельты storage, требует прогона
|
||||
`verify:archive` заново.
|
||||
- Рекомендация триажа: (а) — восстанавливает наблюдаемость без смены
|
||||
семантики, соответствует уже принятому в проекте образцу («объединение
|
||||
полей отложено до счётчика, который заговорит»).
|
||||
- Действие: развилка
|
||||
- Найдено проходом: adversary; сверено с корпусным замером оркестратора
|
||||
|
||||
### 2. Стоящая голова очереди молчит меткой отставания — вопреки MUST дельты, а метка порядка при этом врёт и повторяется
|
||||
|
||||
- Файл: `internal/replay/worker.go:151-211` (`Pass`), `worker.go:184`
|
||||
(`warnOutOfOrder` до свёртки), `worker.go:290-298` (`warnLag`)
|
||||
- Severity: major
|
||||
- Confidence: high
|
||||
- Оракул: чтение кода — `warnLag` вызывается только в ветке пустой выборки
|
||||
(`worker.go:174`), а при `Deferred` проход возвращается из середины цикла
|
||||
(`worker.go:206`), не взводя и `startupDone`; значит доставка, которую
|
||||
занятость откладывает проход за проходом, в метку отставания не попадает
|
||||
никогда. Подтверждено живым замером `adversary` (блокировка 22.1 с: строк о
|
||||
задержке 0, об отложенной свёртке 1). Дельта ingest (строки 29-33) обещает
|
||||
дословно: «Стоящая голова очереди молчать MUST NOT… Метка отставания…
|
||||
покрывает этот случай». Обещание не выполнено. Та же ранняя точка выхода
|
||||
делает `warnOutOfOrder` лжецом: он пишется **до** свёртки, при `Deferred`
|
||||
утверждает свёртку, которой не было, и повторяется каждым проходом — против
|
||||
собственного комментария «одна запись на доставку».
|
||||
- Последствие: класс «молчание» — задолженность растёт при занятой базе, а
|
||||
единственный обещанный спекой сигнал о ней не срабатывает (частично прикрыто
|
||||
`WARN "delivery fold deferred"` из `internal/fold/fold.go:450` — этим
|
||||
находка понижена с потенциального critical); плюс ложный `WARN` о свёртке
|
||||
вне порядка, приучающий не верить именно той строке, по которой решают о
|
||||
`reindex`.
|
||||
- Предложение (инлайн, одна зона в `Pass`): вызывать `w.warnLag(ctx, lag)` и на
|
||||
выходе по `Deferred` (метка — одна строка на проход, шквала нет; подавление
|
||||
первого прохода можно сохранить, взводя `startupDone` по завершении первого
|
||||
прохода независимо от исхода); `warnOutOfOrder` писать после свёртки и только
|
||||
при исходе, реально записавшем разбор (не при `Deferred`).
|
||||
- Действие: инлайн
|
||||
- Найдено проходами: specs (F1, F4), adversary (A2), ops (O2) — одна причина:
|
||||
ранний выход `Pass` при `Deferred` не согласован с обеими метками
|
||||
|
||||
### 3. Документы в шести местах продолжают утверждать «победитель — функция множества», и следующий автор откатит починку молча
|
||||
|
||||
- Файл: `docs/architecture.md:937`, `docs/database.md:130`,
|
||||
`docs/conventions/storage.md:38-40`, `internal/store/winner.go:16-19`,
|
||||
`internal/store/entity_test.go:821-828`, `internal/replay/replay_test.go:173-174`
|
||||
- Severity: major
|
||||
- Confidence: high
|
||||
- Оракул: проверено чтением — `docs/architecture.md:937`: «Победитель — функция
|
||||
множества точек, а не порядка их поступления»; `docs/database.md:130`: «При
|
||||
столкновении выигрывает более полная точка, а не последняя пришедшая»;
|
||||
`docs/conventions/storage.md:38-40` утверждает «порядок свёртки порядку
|
||||
журнала не равен» — ровно то, что это изменение сделало неверным;
|
||||
`winner.go:16-19` ссылается на обещание architecture.md сменить тай-брейк «когда
|
||||
род будет измерен» — дизайн это отверг (Non-Goals). Риск назван самим
|
||||
`design.md`: «чтобы следующий автор не восстановил коммутативность „для
|
||||
чистоты“ и не откатил починку молча» — а шесть мест документации ровно к
|
||||
этому и приглашают.
|
||||
- Последствие: докдрейф на critical-инварианте («Ничего не теряем молча» —
|
||||
формулировка правила столкновения теперь в `CLAUDE.md` другая); строка
|
||||
таблицы двух правил завышает гарантию сущностей (на несравнимых версиях они
|
||||
тоже расходятся).
|
||||
- Предложение: привести все шесть мест к формулировке «функция множества **и
|
||||
позиции в журнале**»; заодно выполнить записанное правило `CLAUDE.md`
|
||||
(«причина отказа от готового решения — промоутом в `docs/adr/`»): причина
|
||||
отказа от LWW-Register/CRDT уже написана в `design.md`, её осталось поднять
|
||||
в ADR — это часть той же работы «документы догоняют правило».
|
||||
- Действие: инлайн
|
||||
- Найдено проходом: architecture (AR1 + замечание про ADR)
|
||||
|
||||
---
|
||||
|
||||
## Стоит исправить сейчас
|
||||
|
||||
### 1. Отчёт пересборки не называет удержанные точки (SHALL дельты), а одно из требований дельты невыполнимо как записано
|
||||
|
||||
- Файл: `cmd/healthlog/reindex_report.go:37-38`;
|
||||
`openspec/changes/tie-break-equal-completeness/specs/reindex/spec.md:30-46`
|
||||
- Severity: major
|
||||
- Confidence: high
|
||||
- Оракул: чтение — отчёт печатает `Partial, Incomparable, EntitiesHeld,
|
||||
EntitiesDiverging`, но не `PointsHeld`, хотя дельта reindex SHALL требует
|
||||
«называть число точек, удержанных правилом полноты против пришедшей
|
||||
доставки», и число уже лежит в `Report` (`internal/replay/replay.go:214`).
|
||||
Второе: дельта требует «число записей „свёртка вне порядка журнала“ прогон
|
||||
SHALL печатать рядом с отпечатком» — эти записи существуют только в логе
|
||||
живого сервиса, нигде не хранятся, а пересборке та же дельта проверку прямо
|
||||
запрещает (ingest:55). Требование структурно невыполнимо.
|
||||
- Последствие: SHALL дельты нарушен кодом (счётчик — единственный способ
|
||||
увидеть, что правило удержания стало слишком строгим, сходимость отпечатка
|
||||
его не проверяет по построению); невыполнимое SHALL, влитое в спеку, станет
|
||||
вечно красным пунктом для следующего читателя.
|
||||
- Предложение: `PointsHeld` — добавить в строку «слияние:» отчёта (инлайн,
|
||||
одна строка). Невыполнимую величину — переписать в дельте на то, что
|
||||
измеримо (например: «число `failed` печатает прогон; записи „вне порядка“
|
||||
наблюдаются в логе сервиса и в отчёт не входят»). Правка текста дельты —
|
||||
решение не оркестратора.
|
||||
- Действие: развилка (код — инлайн, но формулировка требования дельты требует
|
||||
решения владельца: что именно обязана печатать посылка равенства)
|
||||
- Найдено проходами: specs (F2, F5), reimpl (R1)
|
||||
|
||||
### 2. Сценарий дельты «отложенная занятостью доставка не разводит приём и пересборку» не проверен ни одним оракулом
|
||||
|
||||
- Файл: `openspec/changes/tie-break-equal-completeness/specs/reindex/spec.md:56-62`;
|
||||
тесты: `internal/replay/worker_internal_test.go` (барьер — на подменённой
|
||||
свёртке), `internal/replay/order_test.go` (сходимость — без отложенной)
|
||||
- Severity: major
|
||||
- Confidence: high
|
||||
- Оракул: отсутствие теста подтверждено чтением обоих файлов (specs, проверено
|
||||
и триажем): композиция «настоящий `Deferred` × сходимость отпечатков»
|
||||
не проверяется ничем; `task verify:busy` (зелёный) проверяет только «занятость
|
||||
оставляет доставку в очереди», без сверки отпечатков.
|
||||
- Последствие: равенство «пересборка = приём» — ровно то свойство, ради
|
||||
которого изменение существует (инвариант «Хранилище — свёртка по журналу»,
|
||||
critical), — в самом опасном режиме держится на рассуждении, а прецедент
|
||||
2026-08-01 показал, что такие рассуждения расходятся с кодом молча.
|
||||
- Предложение — варианты specs: (а) busy-тест в `internal/replay` под флагом
|
||||
`-healthlog.busy`: журнал с равнополными столкновениями, свёртка под
|
||||
удерживаемой блокировкой, сверка отпечатков живого пути и пересборки;
|
||||
(б) сузить сценарий дельты и записать ограничение в границы. Рекомендация:
|
||||
(а) — цена одного теста против цены молчаливого расхождения витрины.
|
||||
- Действие: развилка
|
||||
- Найдено проходом: specs (F3)
|
||||
|
||||
### 3. design.md утверждает «цена не измеряется» и «тот же индекс» — оба утверждения неверны, замер триажа прилагается
|
||||
|
||||
- Файл: `openspec/changes/tie-break-equal-completeness/design.md:157-159`;
|
||||
`internal/store/delivery.go:256-269`
|
||||
- Severity: minor (после разрешения конфликта O1/R3)
|
||||
- Confidence: high
|
||||
- Оракул: замер триажа `tmp/oracle/parsedafter_test.go` на временной базе:
|
||||
полный проход проверок по чистой задолженности — N=2000: 0.26 с; N=8000:
|
||||
3.12 с; N=20000: 19.8 с (форма квадратичная, экстраполяция N=110 000 → ~10
|
||||
мин, N=330 000 → ~1.5 ч). Установившийся режим — 0.0077 мс на вызов.
|
||||
`EXPLAIN QUERY PLAN`: `SEARCH delivery USING INDEX delivery_received_at` —
|
||||
**не** тот же индекс, что у `PendingDeliveries` (частичный `delivery_pending`
|
||||
требует `parse_status='pending'` и к предикату `IN ('parsed','partial')`
|
||||
неприменим).
|
||||
- Последствие: конфликт O1 (ops) против R3 (reimpl) разрешён: оба замера верны,
|
||||
неверна интерпретация O1 «часами не может разобрать бэклог из-за проверок» —
|
||||
часы даёт сама свёртка (~0.4 с/доставку по verify:archive: при N=20 000 это
|
||||
~2 ч свёртки против 20 с проверок, <2% накладных). Реалистичный потолок
|
||||
задолженности — архив квартала ~27 000 доставок (~300 строк/сутки) → ~35 с
|
||||
проверок. Оптимизация кода не нужна (правка была бы незаказанной); неверные
|
||||
утверждения в design.md — нужно поправить, иначе следующий читатель примет
|
||||
решение по ложному числу.
|
||||
- Предложение: заменить в design.md «цена не измеряется» на измеренные числа
|
||||
(квадратична по задолженности, ~1% от цены свёртки, 7.7 мкс в установившемся
|
||||
режиме) и «по тому же индексу» на `delivery_received_at`. Код не трогать.
|
||||
- Действие: инлайн
|
||||
- Найдено проходами: ops (O1), adversary (A3), reimpl (R3) — одна причина
|
||||
|
||||
### 4. 71 773 координаты живой витрины остаются на старом исходе до ручного `reindex`, и напоминания об этом нет нигде, кроме отчёта ревью
|
||||
|
||||
- Файл: процедура выкладки; `design.md` Risks («Этим изменением не выполняется»)
|
||||
- Severity: major
|
||||
- Confidence: high
|
||||
- Оракул: корпусный замер оркестратора — исход меняется на 75 494 координатах
|
||||
(95% — `basal_energy_burned/raw`); `verify:archive` после изменения зелёный с
|
||||
новым отпечатком `03aace91…`, значит рабочая витрина под старым отпечатком с
|
||||
новым правилом **не сойдётся**, пока её не пересоберут.
|
||||
- Последствие: до пересборки живая витрина расходится с тем, что даёт
|
||||
`import + replay` — «состояние, которое даёт пересборка» в этом проекте
|
||||
объявлено внешним поведением (`docs/review.md`). Подмена файла базы —
|
||||
необратимое действие человека (`CLAUDE.md`, спрашивается всегда), оркестратор
|
||||
выполнить его не вправе.
|
||||
- Предложение — готовый вопрос владельцу: «После мерджа витрина расходится с
|
||||
новым правилом на ~75 тыс. координат (95% — basal_energy_burned/raw).
|
||||
(а) выполнить `healthlog reindex` с остановкой сервиса и подменой базы сразу
|
||||
после выкладки; (б) отложить до планового окна, приняв расхождение витрины на
|
||||
этот срок; (в) не пересобирать — витрина сойдётся только по метрикам, которые
|
||||
переприедут доставками.» Рекомендация: (а).
|
||||
- Действие: развилка
|
||||
- Найдено проходами: ops (O4), architecture (замечание про подмену базы)
|
||||
|
||||
---
|
||||
|
||||
## Гипотезы без доказательства
|
||||
|
||||
- **Откат бинаря молча возвращает старое правило слияния** (ops O3, было major
|
||||
confidence medium → остаётся major-гипотезой без оракула). Миграций нет,
|
||||
откат стартует без слова, свёртка идёт по коммутативному правилу, и витрина
|
||||
расходится с пересборкой новым бинарём. Путь не построен и не воспроизведён;
|
||||
частично это плата, уже принятая проектом за «версия базы ниже бинаря — не
|
||||
отказ». Если владелец сочтёт класс важным — это та же развилка, что решалась
|
||||
в задаче про откат релиза.
|
||||
- **`failed`-доставка «в витрину ничего не записала» — посылка предиката
|
||||
`ParsedAfter` держится раскладкой кода, а не проверкой** (adversary). Если
|
||||
когда-нибудь `failed` начнёт писать частично, страж окна ослепнет молча.
|
||||
Оракула нет — гипотеза, потолок major.
|
||||
- **`hasIncomparablePair` не видит отмены и способен продлить свёртку за
|
||||
дедлайн под транзакцией записи** (reimpl R2, замер честный: ≈51 с при ~7000
|
||||
кандидатов на координате). Понижено до гипотезы о масштабе: на живом корпусе
|
||||
кандидатов на координате единицы, путь к ~7000 версий одной координаты не
|
||||
построен; `pickBest` при том же масштабе сам стоит 103 с — чинить пришлось бы
|
||||
оба, то есть это вопрос предела на кандидатов, а не пропущенного `ctx.Err()`.
|
||||
- **Порядок свёртки под конкурентным приёмом не проверяется ни одним тестом с
|
||||
параллельными писателями** (gate-3): `-race` зелёный на последовательных
|
||||
сценариях. Дефекта не построено; остаточное окно конкурентного приёма
|
||||
осознанно вынесено в `journal-order-on-ingest` (ops O5 туда же присоединился).
|
||||
- **Ветки ошибок нового кода не покрыты тестами** (gate-1, gate-2): отказ
|
||||
`ParsedAfter` → `warnOutOfOrder`/`ERROR`, отмена контекста в
|
||||
`resolve`/`pickBest` — 9 строк, названных оркестратором. Поведение веток
|
||||
прямое (залогировать и продолжить / вернуть ошибку), дефекта в них не
|
||||
предъявлено. Закроются заодно с правкой блокирующего пункта 2, если
|
||||
оркестратор добавит тест на `Deferred`-выход.
|
||||
- **Имя метрики из чужого тела уезжает в первичный ключ витрины без предела
|
||||
длины** (adversary A4). Подтверждено конструкцией (512 КиБ в ключе), но
|
||||
дефект предсуществующий, изменением не внесён — этому изменению не
|
||||
предъявляется. Конвенция уже записана (`docs/conventions/storage.md`: «любое
|
||||
значение из чужого JSON, попадающее в ключ… имеет названный предел длины») —
|
||||
значит это не promote, а невыполненное правило: заводится задачей вне этого
|
||||
изменения.
|
||||
|
||||
## Promote candidates
|
||||
|
||||
- **Ошибки уровня `store` не проходят через единую границу обрезки** (adversary):
|
||||
сегодня утечку значений в текст ошибки сдерживает дисциплина каждого
|
||||
call-site. Кандидат в `docs/conventions/errors.md`: текст ошибки хранения
|
||||
несёт род и координату, но не значение; проверяется тем же разобранным
|
||||
буфером, что и логи.
|
||||
- **Агрегат счётчиков (`Outcome.Add`, `MergeStats`) суммируется руками —
|
||||
забытая строка молча занулит счётчик** (architecture AR2): кандидат в
|
||||
конвенцию тестирования — рефлексивный тест «каждое числовое поле участвует в
|
||||
Add», или правило «новое поле счётчика приходит вместе со строкой в Add и
|
||||
тестом». Не находка против этого кода: все нынешние поля просуммированы.
|
||||
- **Проверка «в логе нет значения точки» для новых поверхностей вывода**
|
||||
(по мотивам A1/PointsHeldAt): координата в лог идёт через `clipMetric`, но
|
||||
правило «новая поверхность вывода получает тест на утечку» записано только
|
||||
для отчёта пересборки комментарием. Кандидат в `docs/conventions/testing.md`.
|
||||
|
||||
## Границы покрытия
|
||||
|
||||
**Запускалось:** профиль `deep`, линейно: `gate` (зелёный), `specs`, `code`,
|
||||
`adversary`, `ops`, `reimpl` (по триггеру «новое правило слияния»),
|
||||
`architecture`; до кода — профиль `design` (`specs`, `rubric`, `architecture`).
|
||||
Оркестратор дополнительно прогнал `task verify:archive` (до изменения красный —
|
||||
унаследованный `step_count`, после — зелёный, отпечаток `03aace91…`,
|
||||
воспроизведён дважды) и `task verify:busy` (зелёный) — то, что по
|
||||
`docs/review.md` числится «перестали проверять сознательно», в этой задаче
|
||||
прогнано, потому что она триггерная (правило слияния).
|
||||
|
||||
**Не запускалось:** `rubric` на коде — намеренно, только в `design` (его
|
||||
свойства легли приёмочными критериями задачи); других проходов профиля не
|
||||
пропущено.
|
||||
|
||||
**Что запущенные проходы не могли проверить в принципе (из charter'ов):**
|
||||
`specs` судит код против дельт, а не поведение под нагрузкой; `code` — только
|
||||
записанные конвенции; `adversary` назвал свойство без пути — постоянную
|
||||
остановку очереди построить не удалось (`Deferred` только из
|
||||
`ErrBusy`/`Canceled`); `ops` не наблюдал реальную ночную нагрузку и реальный
|
||||
рестарт с большой задолженностью (его замеры — синтетика, как и мои); `reimpl`
|
||||
переигрывал только правило слияния и порядок, не разбор; `architecture` не
|
||||
запускает код; триаж ничего нового не находит по определению — пропуск любого
|
||||
прохода был бы и моим пропуском.
|
||||
|
||||
**Целиком на человеке — два списка, намеренно раздельных.**
|
||||
|
||||
*Не проверит ни один проход:* реальный профиль нагрузки телефона (объём и
|
||||
частота меряются только по факту); поведение HAE за пределами наблюдённого —
|
||||
в том числе пришлёт ли он когда-нибудь ту самую «обеднённую точку с
|
||||
разошедшимся значением» из блокирующего пункта 1 (сегодня — 0 вхождений на
|
||||
корпусе); полнота словаря переводов после обновления iOS; секции, которых
|
||||
поток ещё не приносил (`symptoms`, `ecg`, `heartRateNotifications`,
|
||||
`cycleTracking`, `medications`); история инцидентов; завязка потребителей на
|
||||
текущее поведение витрины; вопрос «нужна ли эта функциональность вообще» —
|
||||
решён владельцем 2026-08-04 (тай-брейк — его выбор), но последствия выбора
|
||||
наблюдаются только эксплуатацией.
|
||||
|
||||
*Перестали проверять сознательно:* `verify:archive`/`verify:busy` вне гейта
|
||||
(в этой задаче прогнаны — см. выше; следующая задача без триггера их не
|
||||
увидит); класс «в Go так не пишут» — не покрыт вовсе после упразднения `idiom`
|
||||
(запись 2026-08-02), к этому диффу поимённая сверка со стайлгайдами не
|
||||
применялась; класс «чего нет в зрелой реализации такого узла» — вне профиля
|
||||
`design`, на коде не проверялся.
|
||||
|
||||
**Документы проекта:** всё, что нужно триажу, на месте — `CLAUDE.md` с
|
||||
инвариантами и severity (веса пунктам присвоены по ним, а не выведены заново),
|
||||
`docs/review.md` с разделами «Типовые ложноположительные» (использован: ни одна
|
||||
находка под шесть записанных классов не подпала, отсев шёл по общим критериям
|
||||
плюс этот раздел) и «Недоступно проверке» (перенесён выше двумя списками),
|
||||
`docs/security.md`, `docs/research/apple-health.md` (находка 54 — по ней
|
||||
`adversary` строил обеднённые тела). Ни один проход недостающего документа не
|
||||
заявил. Единственный документный пробел — не отсутствие, а протухание:
|
||||
`docs/database.md:130` и ещё пять мест из блокирующего пункта 3.
|
||||
|
||||
**Что не влезло в потолок и куда делось:** все понижения названы в «Гипотезах»
|
||||
поимённо, молча не выброшено ничего. Отсеяно как вкусовщина, целиком по трём
|
||||
критериям (не меняет поведения, не влияет на цену следующего изменения, не
|
||||
нарушает записанной конвенции): атрибут `waited_sec` в новом `WARN` (specs F6 —
|
||||
дельта ограничивает состав «без значений точек», и это выполнено; секунды
|
||||
ожидания значением точки не являются); схлопывание `Worker.player`+`fold` в
|
||||
замыкание (architecture); переименования/перестановки из generative-выводов не
|
||||
поступали. Замечания `reimpl` «где существующее решение лучше» — не находки, а
|
||||
подтверждение решений; перечислены в его сыром выводе и сохранены в истории
|
||||
задачи.
|
||||
Reference in New Issue
Block a user