Close the anchor gate blindness it was written to prevent, re-verify the gender debt entry against code, and record the draft-versus-editor boundary on row 199

This commit is contained in:
heaven 2026-08-23 01:20:01 +03:00
parent f68ead69a9
commit 8cbcab643a
3 changed files with 8 additions and 3 deletions

File diff suppressed because one or more lines are too long

View file

@ -67,7 +67,7 @@ grep sanitiz по backend/configs/pipeline-c2.yaml — 0 вхождений (exi
### [CONFIRMED_LOST] Строка 84: канон D39.21 «generic „гу" = средний род» без носителя
Канон ратифицирован (05-decisions-log.md:7, карта: «D39.21 = … generic-«гу» СРЕДНИЙ род, именные — по-термово из банка»), носителя в коде НЕТ: (1) enum рендера без neuter — genderConstraintNote принимает только male/m, female/f, hidden, любое иное значение МОЛЧА даёт "" (membank/memory.go:815-823); (2) инъекционные тексты пары — только GenderMale/GenderFemale/GenderHidden (lang/embedded.go:395-397,449-454), ключа gender_neuter нет; (3) схема БД комментирована «male|female|hidden|''» (store/migrate.go:183); (4) в backend/prompts/ и internal/ grep «средн|neuter» = 0 хитов; (5) схема сида ВЫРАЗИМА синтаксически (seed.go:68 Gender — свободная yaml-строка), но `gender: neuter` был бы ТИХИМ no-op: memseed.go:98 копирует без валидации, SeedLint (memseed.go:480) род не проверяет. Альтернативный носитель decl.Invariant существует (memory.go:128,151,311; seed.go:85), но несёт лишь несклоняемость формы, не род для согласования глагола/прилагательных.
Канон ратифицирован (05-decisions-log.md:7, карта: «D39.21 = … generic-«гу» СРЕДНИЙ род, именные — по-термово из банка»), **ПЕРЕ-СВЕРЕНО 23.08 (№19): ЧЕТЫРЕ пункта из пяти ПРОТУХЛИ — носитель в коде ПОСТРОЕН.** Было «носителя в коде НЕТ». Стало, по фактам: (1) `genderConstraintNote` принимает `neuter`/`n` и отдаёт `tx.GenderNeuter` (`backend/internal/membank/memory.go:842-850`=`case "neuter", "n":`) — прежний якорь `:815-823` съехал; (2) ключ пары ЕСТЬ`GenderNeuter` в структуре и в разборе (`backend/internal/lang/embedded.go:398`=`GenderNeuter string`, `:456`=`case "gender_neuter":`); (4) `neuter` встречается в `lang/embedded.go`, `lang/data/injection.txt`, `membank/memory.go` и двух тестах — грепа «0 хитов» больше нет; (5) род ВАЛИДИРУЕТСЯ: `knownGenders` включает `neuter`/`n`, а `GenderVocabViolations` ловит выход из словаря, и её собственный докстринг называет этот класс (`backend/internal/membank/memseed.go:503-513`=`var knownGenders = map[string]bool{`). **ЖИВЫМ ОСТАЁТСЯ РОВНО ПУНКТ (3):** комментарий схемы БД до сих пор перечисляет `male|female|hidden|''` без neuter (`backend/internal/store/migrate.go:184`=`male|female|hidden|`) — и прежний якорь звал `:183`, то есть был на строку мимо. Это косметика комментария, не поведение. Альтернативный носитель decl.Invariant существует (memory.go:128,151,311; seed.go:85), но несёт лишь несклоняемость формы, не род для согласования глагола/прилагательных.
**Фикс/скоуп:** Строка верна; уточнение в тело: (а) сегодня `gender: neuter` в сиде — ТИХИЙ no-op без линта, т.е. дыра хуже «невыразимо» — при стройке носителя добавить и seed-lint-отбраковку неизвестных значений рода; (б) «decl.invariant достаточно» закрывает только несклоняемость, не согласование — фиксировать это в формулировке альтернативы.

View file

@ -317,7 +317,12 @@ REPO_TOPS = {"backend", "docs", "eval", "frontend", "platform"}
# Первые сегменты ЗОННО-ОТНОСИТЕЛЬНЫХ якорей (`internal/pgstore/…`, `cmd/…`) — их в корпусе больше
# пятнадцати, и без этого множества сломавшийся зонный якорь молча переклассифицировался бы во
# «внешнюю ссылку» вместо «файла нет».
ZONE_TOPS = {pre.split("/", 1)[0] for pre in LINT_PREFIXES_RAW if "/" in pre}
# ⚠ ИСПРАВЛЕНО 23.08 (оркестратор №19): было `pre.split("/", 1)[0]` — ПЕРВЫЙ сегмент, из-за чего
# ZONE_TOPS выходил побайтно равен REPO_TOPS, условие ниже становилось тавтологией, и зонно-
# относительный якорь (`internal/…`, `cmd/…`), который НЕ резолвится, тихо числился «внешней
# ссылкой» вместо крика «файла нет» — ровно та слепота, против которой написан комментарий выше.
# Нужен ВТОРОЙ сегмент: из `backend/internal/` — `internal`, из `frontend/src/` — `src`.
ZONE_TOPS = {p.strip("/").split("/")[1] for p in LINT_PREFIXES_RAW if len(p.strip("/").split("/")) >= 2}
LINT_SKIP_DOCS = {
"docs/research/21-llm-transport-survey.md",
"docs/research/26-anthropic-guidance-digest.md",