Skip to content

feat(ci): отставание реестра находок ловит механизм, а не следующий аудит - #1369

Merged
ArtVsMark merged 4 commits into
mainfrom
agent/audit-registry-guard
Aug 26, 2026
Merged

feat(ci): отставание реестра находок ловит механизм, а не следующий аудит#1369
ArtVsMark merged 4 commits into
mainfrom
agent/audit-registry-guard

Conversation

@ArtVsMark

Copy link
Copy Markdown
Owner

Без issue: правило родилось из инцидента этой смены; отдельной задачи не заводилось

Инцидент

Документ аудита объявляет собственное правило состояния: находка открыта, пока её
ID не значится в реестре PR. Правило было, механизма не было — и реестр отстал на
152 записи: 57 строк против 209 фактически закрытых находок.

Следствия не косметические. Состояние читают только из реестра, поэтому отставший
реестр числит закрытое открытым: следующий аудит переоткрывает сделанное, а
правило «документ переезжает в archive, когда закрыты все» не срабатывает
никогда — незакрытые не кончаются.

Сверка руками (PR #1366) долг закрыла, но не устранила причину: следующий
пропуск строки снова заметят через месяцы.

Механизм

scripts/check_audit_registry.py сверяет три источника: ID находок из таблиц
живых аудитов, реестр (строки | ID | что было | #PR |) и тела смерженных pull
request. Кандидат — ID, упомянутый в PR и отсутствующий в реестре; формулировка
вокруг упоминания разбирается.

Реестр ищется по форме строки, а не по заголовку раздела: переименование
секции не должно отключать проверку молча — тот же принцип, по которому запрет
MCP держится формой, а не именами.

Три ловушки разбора, каждая найдена на живых телах PR:

  • контекст — абзац, а не предложение: точки живут в путях (SECURITY.md), и
    обрезка по ним превращала «из подэпика 🎯 [Подэпик] Песочница и микробенч ломают верные решения и переворачивают рейтинг #986 остаются: …» в подтверждение
    закрытия;
  • заголовок сильнее формы строки: под «## Что осталось в файле» лежит ровно
    тот же список «ID — что не так», что и под «## Что сделано»;
  • частичное закрытие — не закрытие: «READER-1-04 (часть про URL)» оставляет
    вторую половину живой, и реестр её принять не должен.

Плюс отсев PR, которые находки заводят или ведут сам документ (docs(audit),
переписывание тел в чек-листы): они перечисляют ID десятками, включая открытые.

Что нашлось первым же прогоном

Две находки, пропущенные ручной сверкой: LNCH-1-01 (PR #1140) и DES-1-04
(PR #1276 — по более раннему PR она числилась оставшейся, и я поверил тексту, а
не последнему слову истории). Обе дописаны в реестр этим же PR.

Проверка

  • вживую: до правки — «реестр отстал на 2 записи», после — «реестр совпадает с
    историей мержей»;
  • 10 тестов на фикстурах, по одному на каждую ловушку разбора выше; в сеть не
    ходит ни один;
  • python scripts/preflight.py — чисто: 5370 passed, 98 skipped;
  • гард объявлен в tests/test_guard_scripts_are_wired.py.

Работа сделана вместе: @ArtVsMark — постановка, решения и приёмка; Claude Code — реализация.

…удит

Без issue: правило родилось из инцидента этой смены; отдельной задачи не заводилось

## Инцидент

Документ аудита объявляет собственное правило состояния: находка открыта, пока её
ID не значится в реестре PR. Правило было, механизма не было — и реестр отстал на
152 записи: 57 строк против 209 фактически закрытых находок.

Следствия не косметические. Состояние читают только из реестра, поэтому отставший
реестр числит закрытое открытым: следующий аудит переоткрывает сделанное, а
правило «документ переезжает в archive, когда закрыты все» не срабатывает
никогда — незакрытые не кончаются.

Сверка руками (PR #1366) долг закрыла, но не устранила причину: следующий
пропуск строки снова заметят через месяцы.

## Механизм

`scripts/check_audit_registry.py` сверяет три источника: ID находок из таблиц
живых аудитов, реестр (строки `| ID | что было | #PR |`) и тела смерженных pull
request. Кандидат — ID, упомянутый в PR и отсутствующий в реестре; формулировка
вокруг упоминания разбирается.

Реестр ищется **по форме строки, а не по заголовку раздела**: переименование
секции не должно отключать проверку молча — тот же принцип, по которому запрет
MCP держится формой, а не именами.

Три ловушки разбора, каждая найдена на живых телах PR:

- **контекст — абзац, а не предложение**: точки живут в путях (`SECURITY.md`), и
  обрезка по ним превращала «из подэпика #986 остаются: …» в подтверждение
  закрытия;
- **заголовок сильнее формы строки**: под «## Что осталось в файле» лежит ровно
  тот же список «`ID` — что не так», что и под «## Что сделано»;
- **частичное закрытие — не закрытие**: «`READER-1-04` (часть про URL)» оставляет
  вторую половину живой, и реестр её принять не должен.

Плюс отсев PR, которые находки заводят или ведут сам документ (`docs(audit)`,
переписывание тел в чек-листы): они перечисляют ID десятками, включая открытые.

## Что нашлось первым же прогоном

Две находки, пропущенные ручной сверкой: `LNCH-1-01` (PR #1140) и `DES-1-04`
(PR #1276 — по более раннему PR она числилась оставшейся, и я поверил тексту, а
не последнему слову истории). Обе дописаны в реестр этим же PR.

## Проверка

- вживую: до правки — «реестр отстал на 2 записи», после — «реестр совпадает с
  историей мержей»;
- 10 тестов на фикстурах, по одному на каждую ловушку разбора выше; в сеть не
  ходит ни один;
- `python scripts/preflight.py` — чисто: 5370 passed, 98 skipped;
- гард объявлен в `tests/test_guard_scripts_are_wired.py`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Artem Markitanov <86671904+ArtVsMark@users.noreply.github.com>
@ArtVsMark ArtVsMark added the merge-when-green Согласие смержить без автора: авто-мерж включится, как позеленеет label Aug 26, 2026
@ArtVsMark
ArtVsMark enabled auto-merge (squash) August 26, 2026 10:35
@claude claude Bot added area/ci CI/CD и скрипты (.github/, scripts/) enhancement New feature or request labels Aug 26, 2026
@ArtVsMark ArtVsMark added the needs-rebase Конфликт с main: очередь пропускает, нужно ручное слияние label Aug 26, 2026
claude and others added 2 commits August 26, 2026 14:19
Оба шага ночного прогона трекера оставлены: защита main (#1296) и реестр
находок. Конфликт был позиционный — обе стороны дописывали шаг в одно место,
логика ни одной не менялась.

Маркеры конфликта проверены прогоном, а не глазами: первое разведение съело
закрывающую скобку в реестре гардов, и тест сборки это поймал.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Artem Markitanov <86671904+ArtVsMark@users.noreply.github.com>
… agent/audit-registry-guard

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Artem Markitanov <86671904+ArtVsMark@users.noreply.github.com>
@ArtVsMark
ArtVsMark merged commit 7b06e22 into main Aug 26, 2026
17 checks passed
@ArtVsMark
ArtVsMark deleted the agent/audit-registry-guard branch August 26, 2026 14:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/ci CI/CD и скрипты (.github/, scripts/) enhancement New feature or request merge-when-green Согласие смержить без автора: авто-мерж включится, как позеленеет needs-rebase Конфликт с main: очередь пропускает, нужно ручное слияние

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants