Files
houseplan-card/docs/reviews/SPEC-REVIEW-331-r3.md
T
2026-08-28 01:33:02 +00:00

11 KiB
Raw Blame History

SPEC-REVIEW-331-r3

Issue: #331 — «Ограничения стыков (#329): пограничная точность даёт ложные отказы и невидимые дубли» ТЗ: docs/specs/331-junction-limit-precision.md Материал раунда: ревизия 3, SHA 4423d285 (issue-комментарий автора называет этот SHA явно: «Ревизия 3 (4423d285)»). Предыдущий раунд: r2, вердикт «жёлтый», документ docs/reviews/SPEC-REVIEW-331-r2.md, материал на SHA 2d703543. Трек: полный (не small) — issue не помечен small (метки: bug, P1, S4-spec-review), ТЗ по-прежнему живёт в docs/specs/331-*.md; дифф r2→r3 трек не меняет. Заход: r3 · блокирующих циклов израсходовано 2 из 4 (r2 жёлтый цикл израсходовал 2-й; зелёный вердикт бюджет не тратит и цикла не образует — см. системную инструкцию по #227).

Скоуп разбора (дельта, не заново)

Дельта раунда — git diff 2d703543..4423d285 -- docs/specs/331-junction-limit-precision.md. Затронуто три места: статус-строка (сводка ревизии), AC6 (§4), формулировка риска (2) в §6. Обе находки r2 (M-r2-1, L2) — предмет этой правки, других разделов дифф не касается. Это ровно тот случай, когда объём разбора сокращается до дельты: изменение локально (два абзаца), не меняет трек, не задевает новую подсистему, не является ребейзом. Полный повторный разбор не требуется; но каждая из двух правок проверена по существу — совпадает ли новый текст с тем, что r2 явно потребовал, и не рвёт ли он согласованность с остальным документом (§2.5, §2.6, AC5).

Как проверялось

  1. git diff 2d703543..4423d285 -- docs/specs/331-junction-limit-precision.md — построчно.
  2. Текст находки M-r2-1 (docs/reviews/SPEC-REVIEW-331-r2.md:78-108) — сверен пункт за пунктом с новым текстом AC6 (docs/specs/331-junction-limit-precision.md:144-150): ожидались два явных случая по образцу AC5, требование выполнено дословно.
  3. Текст находки L2 (SPEC-REVIEW-331-r2.md:112-125) — сверен с новой формулировкой риска (2) (:170-171): «максимальная ветвь» → «сумма коллинеарной компоненты», совпадает буквально с текстом §2.3 (:76-78, не тронут этим диффом).
  4. Перечитан §2.5 (:88-94) и §2.6 (:96-105) — не тронуты диффом r2→r3 — чтобы убедиться, что новый текст AC6 не противоречит нормативному тексту, который он тестирует: candidate → «честная ошибка WS, fail-closed, как §2.5»; previous → «прежний широкий фолбэк "нет базы для наследования"». Формулировка AC6 (а)/(б) слово в слово повторяет эту асимметрию.
  5. Перечитан AC5 (:141-143, не тронут) — «по образцу AC5» из статус-строки и текста AC6 действительно означает структурное подобие: два явных случая по сторонам с разным исходом, как у AC5 (кандидат/baseline).
  6. Прочитан полный файл docs/specs/331-junction-limit-precision.md целиком (не только дельту) — на предмет новых внутренних противоречий, которые правка могла случайно внести в соседние разделы (§3, §5, §6 целиком). Противоречий не найдено.
  7. Issue #331 — комментарии перечитаны (gh issue view 331 --json comments): вердикт r2 (жёлтый, M-r2-1 + L2) и хендофф автора о ревизии 3 — оба совпадают с тем, что видно в диффе; SHA назван автором явно.

Гейты typecheck/test/build/check-docs/инварианты модели/смоки/ golden/backend-pytest/perf — не гонялись и не нужны: дифф раунда — исключительно docs/specs/331-*.md (класс C, стадия spec), исполняемого кода нет ни в этом диффе, ни накопительно с r1 (весь путь #331 пока — только спецификация).

Закрытие раунда r2

Находка r2 Чем закрыта в r3 Где это видно
M-r2-1 — AC6 не различал сторону (previous/candidate); реализация с перепутанной или отсутствующей асимметрией §2.6 формально проходила байт-в-байт тот же текст, что был до правки §2.6 AC6 переписан на два явных случая по образцу AC5: (а) TypeError кандидата → честная ошибка WS; (б) TypeError previous → запись проходит фолбэком «нет базы для наследования»; отдельно оговорено, что перепутанные стороны или отсутствие асимметрии красят хотя бы один из двух юнитов docs/specs/331-junction-limit-precision.md:144-150. Текст (а)/(б) сверен слово в слово с нормативным §2.6 (:100-105, не тронут этим диффом) — не расходится и не изобретает нового поведения. Критерий теперь однозначно различает две реализации, которые старый AC6 не различал. Закрыто.
L2 — §6 «Риски» (2) описывал механизм «максимальная ветвь», которого §2.3 в редакции r2 уже не содержит (там — «сумма компоненты связности») Формулировка риска (2) заменена на «сумма коллинеарной компоненты» :170-171. Совпадает буквально с текстом §2.3 (:76-78). Рассинхрон между разделами устранён. Закрыто.

Обе находки r2 закрыты содержательными правками текста, а не декларацией в статус-строке (хотя статус-строка тоже обновлена корректно — :3 перечисляет обе находки r2 и подтверждается фактическим диффом).

Унаследовано из r2 (без повторной проверки)

Ниже — то, что r2 (docs/reviews/SPEC-REVIEW-331-r2.md, материал @ 2d703543) проверил и признал корректным, и что дельта r2→r3 не затрагивает (ни один символ в этих разделах не изменился между 2d703543 и 4423d285):

  • H1 (квантование ключа, формула канонизации) — сверено побайтово с coordinate-canonicalization.ts/.py в r2; §2.1/AC1 не тронуты этим диффом.
  • M1 (порог инцидентности 2e-7, арифметика примера) — §2.1/AC1 не тронуты.
  • M3 (обход по рёбрам вместо DFS, O(E), развилка и П1) — §2.3/AC3 не тронуты; вывод r2, что любая «развилка» и так нарушает П1 по углу независимо от версии §2.3, наследуется без повторной проверки кода.
  • M4 (USER-GUIDE в Release) — §6/Release не тронут этим диффом (правка риска (2) — другая строка того же раздела, не пересекается с абзацем Release).
  • Нормативный текст §2.6 (сама асимметрия candidate/previous) — введён и проверен в r2, этим диффом не тронут; проверялся сейчас только для сверки с новым AC6 (см. «Как проверялось», п.4), не как повторный аудит §2.6 с нуля.
  • Скоуп/не-скоуп, структура «один AC на пункт», i18n, touch, обязательство по docs/specs/329-*.md — унаследовано ещё из r1 через r2, дельтой r3 не задето.

Что проверено и признано корректным (эта ревизия)

  • AC6 в новой редакции действительно способен различить две реализации, которые старая редакция не различала: пропущена или перепутана асимметрия candidate/previous — хотя бы один из двух явно описанных юнитов красный.
  • Новый текст AC6 не вводит поведения, которого нет в нормативном §2.6 — сверено дословно.
  • Формулировка риска (2) в §6 синхронизирована с текущим текстом §2.3.
  • Полный документ (не только дельта) перечитан на предмет новых противоречий — не найдено.

Чего не проверял

  • Всё, что унаследовано из r2/r1 (список выше) — не перепроверялось повторно.
  • Исполняемого кода по-прежнему нет — гейты typecheck/test/build/ check-docs/инварианты/смоки/golden/backend-pytest/perf не применимы к этой стадии (spec) и не гонялись.
  • Фактическая реализация AC6 — она ещё не написана; проверялась только формулировка критерия, а не код, который по нему будет писаться.

Вердикт

Обе находки r2 (M-r2-1, L2) закрыты содержательными правками, сверенными построчно с текстом находок и с остальным документом. Новых находок в дельте r2→r3 нет. High нет, Medium нет.

Вердикт: зелёный · заход r3 · блокирующих циклов 2/4 · High: 0 · Medium: 0