Заплатки Яруса 1 (Лиепа), десневидная юбка, детектор неполноты, разбор A-09; маска synthetic и инварианты add-only.
Исполнитель: CC Fable 5. Основание: спайк result-dental-recon-spike-2026-07-12.md, принят
Артуром; канон честности — в редакции задачи RECON-PASS-1 (старые формулировки не применять).
https://dental.zaslart.website/cabinet/ (basic_auth artur).
Публичная версия отчёта + галерея приёмочных скринов:
https://dental.zaslart.website/reports/recon-pass1/ (тот же basic_auth, скрины с ?v=<mtime>).
Был завершён ДО этой задачи (отчёт result-dental-polish-2026-07-12.md, git b45b5a4,
в проде): ровный ободок, строгание линии среза, доудаление лоскутов, «крышка» A-09 —
closure 20/20, accept GO. Юбка Яруса 2 строится от этой чистой линии среза.
app/refine.py::_SynthTracker): 0=скан,
1=fill (заплата десневой дыры, канон смыкания), 2=patch (Ярус 1), 3=base (основание).
Маска проезжает весь пайплайн через два шва — _compact (все срезы) и точки добавления;
рассинхрон длины = RuntimeError (пайплайн падает, артефакт не пишется)._recon_guard) на каждой операции реконструкции
(fill_holes / заплатка Лиепы / build_base / build_socle): исходные вершины байт-в-байт,
исходные грани не переписаны, классы существующих вершин не изменены, добавленных
ЗУБНЫХ вершин нет. Нарушение роняет пайплайн автоматически.gingiva/tooth_<fdi> (только скан, зуб bit-exact к сегментации), synthetic_fill,
synthetic_patch, synthetic_zip (лента-камень), synthetic_skirt (та же лента в цвете
десны), synthetic_base. Плюс полная бухгалтерия в teeth.json (synthetic, doctored,
invariants).SYNTH_PATCH, классы её вершин = 0 → сабмеш зуба байт-цел; материал
во вьювере — эмалевый; в «оригинале» заплатки скрыты, дыры честно открыты._zip_rings детерминированный), в GLB — два визуальных узла:
synthetic_skirt (вершины кольца перекрашены в медианный тон реальной десны скана;
верх ленты несёт живой цвет кромки → визуальный стык с десной) и synthetic_zip
(нейтральный камень — прежний канон). Меш/АО/чек смыкания считаются на ОДНОЙ ленте —
дублируется только узел GLB.refine.completeness_census на стадии переписи спайка («перед fill_holes»):
дыры > 14 ИЛИ площадь дыр > 50 мм² ИЛИ кромка > 3800 вершин (~1.4×медианы) ИЛИ
баланс зубной поверхности Л/П < 60%.rim_verts зависит от плотности меша сканера.
Для боевой калибровки нужны: корпус нескольких сканеров, клиническая разметка
«полный/неполный» врачом, повторная перепись. До этого — индикатор, не диагноз.trim_beyond_arch
(баланс 56.5% → 30.1%; apron/demote/shelf/sail дают 0.0 п.п.). Механизм: воротник
честно срезает waxup-лоскут, на котором СТОИТ настоящая коронка 22 (объёмное тело
12 892 грани, λ3/λ1=0.40); коронка отсоединяется, и _keep_body выбрасывает её как
«остров». Та же граблина уже чинилась в close_shell (_keep_body_teeth_safe),
но в trim фикс не дошёл._keep_body больше никогда не
выбрасывает компоненту, несущую ОБЪЁМНОЕ зубное тело (λ3/λ1 ≥ 0.28 и ≥ 800 граней).
Плоские хлопья с ложной зубной меткой (все лоскуты 0.06..0.26) защиту не получают —
на здоровых сканах поведение байт-идентично (коронки прикреплены к телу).| Что | Врач | Пациент | Никто (только данные/логи) |
|---|---|---|---|
| Заплаты Яруса 1 (доработанный вид) | ✅ дефолт, с бейджем «Доработано» | ❌ | |
| Кнопка отката к оригиналу | ✅ | ❌ (переключателей нет вовсе) | |
| Десневидная юбка Яруса 2 | ✅ в «доработано» | ❌ (нейтральное основание) | |
| Плашка «скан неполный — пересканирование» | ✅ | ❌ | |
| Маска synthetic по вершинам, инварианты, слои | ✅ teeth.json + узлы GLB | ||
| Бухгалтерия заплат (площади, FDI) | ✅ (счётчик в бейдже) | ❌ | ✅ полная в teeth.json |
Пациенту НИЧЕГО нового не уходит: patient.js создаёт вьювер refined:false — заплатки |
|||
| скрыты, вместо юбки нейтральное основание, пометок и переключателей нет. Включение | |||
| доработанного вида пациенту — только отдельным решением Артура. |
qa/regen_real.py, бэкап app/artifacts.bak-cclaude-flap-20260712-215928):
20/20 без ошибок, 41–129 с/скан; present-наборы всех 20 идентичны прежним (14 зубов
везде, находки не тронуты). A-06 lower и A-09 lower перегнаны повторно после коррекции
порога детектора (артефакты консистентны финальному коду).v2_facts.py с DENTAL_RECON_PATCH=0
— прежняя семантика чека): 20/20 сомкнуты, 0 несмыканий/немногообразий/нетрассированных,
teeth_bitexact 20/20 — фикс _keep_body смыкание не сломал.qa/recon_invariants.py → qa/recon-invariants.log): 20/20 ✅ PASS —
add_only=pass, маска синхронна, synthetic-зубных вершин 0 у всех. Заплат Яруса 1
всего 17 на 8 сканах (A-01l ×1, A-04u ×1, A-04l ×1, A-05u ×4, A-06u ×2, A-06l ×3,
A-09u ×2, A-09l ×3; площади 0.07–18.8 мм²); кромок фрагментов защищено: 2 (A-09u).data/uploads не изменён
(базлайн qa/recon-md5-originals-before.txt, снят до регена).?v=<mtime>), подтверждено
скрин-скриптом по живым запросам GLB (0 запросов со статичным v=d4).qa/recon_shots_public.py):
все 20 сканов × 8 канонных ракурсов × 2 состояния (REF «доработано» / ORIG «оригинал
после отката»), 320 скринов, консоль чистая на всех 10 кейсах, бейдж «Доработано»
виден на каждом. Локально qa/shots/recon-accept/, копия — Drive
Дентист/qa-shots/recon-accept-20260713/. 8 ракурсов = дедуп углов слайда Артура
(front/occl/bottom/implants/debris/cutline/level/outside). Пары состояний сверены
пиксельным диффом (каждая пара различается ровно зоной доработки) + визуально
(юбка↔камень на фронтах A-01/A-09, изоляция челюсти корректна).
⚠️ Грабля повторена и снята: после регена capturePreviews страницы гоняет isolate —
скрин-скрипт теперь ждёт готовности превью (фикс в qa/recon_shots_public.py).git revert d5fa53e c1f6190 (изменения изолированы). Git: d5fa53e (ядро),
c1f6190 (порог детектора + QA), c36df09 (скрины/отчёт); запушено в github+gitea.app/artifacts.bak-cclaude-flap-20260712-215928 (до регена) +
update scans set preview=NULL.DENTAL_RECON_PATCH=0 в юните + реген.Поверх этой работы в том же дереве живёт АКТИВНАЯ сессия POLISH-PASS-2 (коммиты
5e045d0…28cadec, 13.07 12:00–14:19): она уже нашла и закрыла два хвоста моего
кода — немногообразия от дельоне-флипов Лиепы (nm 62/23 на A-01l/A-10l → 0,
живой счётчик рёбер) и сироту пилинга (A-04u) — и на момент закрытия этой сессии
перегенерировала артефакты своим кодом (A-09 GLB записан 14:50). Следствия:
- приёмочные числа/скрины выше — валидный снимок НА МОЁМ коде и моих артефактах
(инварианты и md5 прогнаны на них); финальное состояние прода определит
POLISH-PASS-2 — её приёмка/скрины будут свежее;
- скрины a-09/a-10 из recon-accept сняты в окно её регена — пересъёмка на её стороне;
- на Drive доехало 296/320: параллельная сессия очистила локальную папку скринов
до конца выгрузки — потеряны 24 кадра кейса A-10 (upper весь + половина lower).
Доснимать нечестно (артефакты A-10 уже перегенерированы её кодом, 14:54) —
A-10 целиком покроет приёмка POLISH-PASS-2. Остальные 19 сканов — полные пары.
Ничего из её работы не откатывать этим отчётом: она НАДСТРОЙКА над recon-pass-1.
qa/freeze_table.py).qa/recon-invariants.log; версия 12.07 сохранена как
qa/recon-invariants-20260712.log). Recon-состояние артефактов 12.07 сохранено
байт-в-байт в app/artifacts.bak-cclaude-flap-20260713-141905/.Дентист/qa-shots/recon-accept-20260713/ обновлена финальным сетом 320.






























































































































































































































































































































