# 18 — Онтология банка памяти: роли носителей, писатели, свежесть > **СТАТУС: РАТИФИЦИРОВАНО D39.158 (27.08.2026).** Топикальный вход (D39.126): НЕ источник истины, > при конфликте побеждает журнал решений. Собрано оркестратором №19 по консилиуму со сторонним > архитектором при приёмке четырёх паков входной двери шва. > > **Зачем страница.** Вокруг одного понятия — «состояние банка этой книги» — живут одиннадцать носителей. > Форма СТРОГАЯ: поток однонаправленный, у каждого источника единственный писатель, вид пересобирается > полностью на каждой границе прогона (D39.158 п.8). ## Пять ролей, и они не смешиваются ⚠ **Было ЧЕТЫРЕ до 17.09.** Пятую — «ПАМЯТЬ РЕШЕНИЙ» — завела эррата 17.09-д и построил пак базиса решённого. Заводить новый класс пришлось именно потому, что подпись существующего у́же: «ПАМЯТЬ ФЛАЖКА» определена как «что стоп уже предъявлял», писатель — стоп, а базис пишет ПРОГОН на своих границах и читает его денежный предикат ДО первой траты. Расширить чужую подпись значило бы сделать одну строку таблицы двузначной, чего эта страница не допускает нигде. | Роль | Носители | Писатель | Момент фиксации | |---|---|---|---| | **ИСТОЧНИКИ** — то, из чего банк собирается | `glossary_seed` · `.mined-delta.yaml` · `.mined-rejects.yaml` (слово ВЛАДЕЛЬЦА, рядом с `book.yaml`, едут с книгой в бэкапе и экспорте) · `.auto-bank.yaml` (слово ДВИЖКА, сидит при базе) · ruby-чтения в хранилище | у каждого РОВНО один. ⚠ Дверь `bank-apply` пишет ТОЛЬКО два файла решений: правка сид-терма ею ОТКЛОНЯЕТСЯ по имени (`internal/membank/decisions.go:359`=`Scoped to APPROVE`), потому что это перенос базового снапшота и пере-оплата черновой волны — другое решение (щель ратифицирована, строка 192). `glossary_seed` — рука владельца · `auto-bank` — прогон · ruby — хранилище | запись двери — под эксклюзивным флоком проекта; рука владельца флока не берёт (остаток — строка 222) | | **ВИД** — банк, каким его видят роли | строки глоссария в хранилище | только `seedGlossary`, и только полным пересбором | каждая граница прогона; один загрузчик, все гарды | | **ПРОЕКЦИИ** — то, что банк рассказывает наружу | `.bank.json` (единственный канал банка наружу) · карта подписи `.mined-signature.yaml` · человеческая таблица стопа `.bank-stop.txt` | прогон, на границе | ⚠ не одинаков: `bank.json` — ПОСЛЕ смены вида; карта подписи и `.bank-stop.txt` — при вычислении стопа, ДО пере-сида, а на стоп-границе вид вообще не меняется (остановившийся прогон авто-банк не пишет) | | **ПАМЯТЬ ФЛАЖКА** — что стоп уже предъявлял | таблица `bank_stop_presented` | стоп | ПОСЛЕ карты, никогда до | | **ПАМЯТЬ РЕШЕНИЙ** — что книга уже решила и на каких уликах | таблица `bank_basis` (отпечаток улик + консолидированный ответ) | **прогон**, и границ у него ДВЕ: `run-finished` и ветка стопа подписи | на выходной границе прогона, ПЕРЕД памятью флажка | **Поток однонаправленный: источники → вид → проекции.** Отсюда главное свойство, из-за которого рефактор не нужен: **расхождение источников с видом структурно невозможно дольше одной границы прогона**, потому что вид не патчится, а пересобирается целиком. ⚠ **Единственная петля — авто-провод, и она названа здесь нарочно:** прогон пишет собственный ИСТОЧНИК (`auto-bank`) и пере-сидит вид в той же границе. Это первое, куда ткнёт проверяющий однонаправленности. Петля реальна и защищена с двух сторон — `unsignedEngineSurfaces` держит границу подписанного, а `loadAutoBank` отказывает строке со статусом `approved`, — то есть слово движка не может присвоить себе слово владельца. Однонаправленность формулируется точно так: **петля есть, но она не может изменить подписанное.** ⚠ **ВТОРАЯ ПЕТЛЯ (пак базиса решённого, 17.09): базис → предикат → авто-банк.** Прежняя редакция называла авто-провод ЕДИНСТВЕННОЙ петлёй, и с этого дня это неверно: прогон пишет память решений на своей границе, а СЛЕДУЮЩАЯ покупка читает её предикатом до первого платного вызова и подставляет оттуда ответ, который уезжает в авто-банк. Защищена она тем же самым — слово движка не может присвоить себе слово владельца: подписанная строка записи в базис не получает (предикат отвергает её по статусу) и её передача базисом НЕ подменяется никогда. Формулировка однонаправленности не меняется, меняется число её членов: **петель две, и ни одна не может изменить подписанное.** ⚠ **Порядок на границе стопа — карта → таблица стопа → проекция банка → БАЗИС → память флажка**, и базис стоит ПЕРЕД памятью флажка по тому же правилу, которым правило 3 ниже объясняет саму асимметрию: последней пишется запись, чья потеря ДЕШЕВЛЕ. Потеря памяти флажка стоит одного доброкачественного лишнего стопа; потеря базиса стоит пере-покупки обеих банк-ролей из ПОЖИЗНЕННОГО потолка книги, исчерпание которого необратимо (ряд 356). ⛔ И писать базис РАНЬШЕ развилки нельзя: базис, оказавшийся на краш-резюме, сжимает состав батчей, чекпойнты по хешу запроса не находятся, и резюм перекупает уже оплаченное. ## Почему слово владельца и слово движка не сливаются Соблазн понятный: одобрения владельца и авто-строки движка — одинаковые по форме строки банка. Но слитые, они делают неразличимым то, ради чего банк существует: **какие переводы человек действительно одобрил.** Поэтому источники разнесены и по писателю, и по каталогу — решения владельца едут с книгой, состояние движка сидит при базе. ## Дисциплина проекции — норма, а не стиль Три правила, каждое куплено дефектом: 1. **У проекции обязан быть НАЗВАННЫЙ читатель.** Машинная таблица стопа `.bank-stop.json` была написана для пер-термного экрана подписи; экран упразднён D39.144, читателя не осталось ни в одной зоне — снесена D39.158. Свип наследия отменённой модели шёл по коду, гейтам и текстам, а её АРТЕФАКТ пережил его, потому что никто не смотрел на множество публикаций. 2. **У проекции обязан быть якорь свежести ВНУТРИ документа.** Отказ записи банк-экспорта — «громко, но не фатально» (деньги дороже проекции), и это верно; но «может быть устаревшим» жило только в ЛОГЕ. Потребитель не мог отличить проекцию этой границы от прошлой. Закрыто конвертом с меткой границы и идентификатором прогона. 3. **Порядок между носителями — инвариант, а не деталь.** Память флажка пишется ПОСЛЕ карты: падение между ними даёт лишний доброкачественный стоп, обратный порядок — запомненную поверхность, чьей карты не существует, то есть молчаливую потерю навсегда. Инвариант, живущий в комментарии, не держится ничем — держит его пин. ⚠ **КЛАСС A, названный этой страницей: проекция без контракта потребителя и без якоря свежести в самой себе.** Два известных члена: снесённая таблица стопа · банк-экспорт до конверта. Третий живёт строкой бэклога 224: банк-экспорт на стопе ПУСТ — проекция, наиболее пустая ровно в тот момент, когда её читает экран подписи. ⚠ **КЛАСС B — другой, и путать их нельзя: межносительный инвариант, живущий комментарием без пина.** Член — порядок «карта → память» до фикс3. Он НЕ подпадает под класс A: там дефект в том, что документ не несёт контракта, здесь — в том, что связь ДВУХ носителей держится только текстом, который ничего не проверяет. ⚠ **Второй ярус КЛАССА A (D39.159): носитель с ДВУМЯ писателями и НОЛЬ читателей.** Здесь опасность не в отсутствии потребителя — она в том, что расхождение писателей ничем не судится, пока читателя нет, а в день, когда читатель появится, разница СТАНЕТ семантикой, и разрешать её придётся задним числом по уже накопленной истории. Отсутствие потребителя из симптома делается отсрочкой платежа. Живой член — `books.chunker_version` в платформе (`PD-396`); родня по эту сторону шва — мёртвые поля шва и `ingest.StatusReport.UnsignedBankTerms`. Отсюда правило таблицы выше — «у каждого источника РОВНО один писатель» — читается в обе стороны: **два писателя без читателя судятся так же строго, как проекция без потребителя, и чинятся раньше, а не когда читатель придёт.** ⚠ **ЭРРАТА 07.09 (оркестратор, акт лендинга пака «гейт вместо прозы»): ТРЕТИЙ ЧЛЕН КЛАССА A ЗАКРЫТ СО СТОРОНЫ ДВИЖКА.** Стоп-граница теперь публикует свои предложения отдельной секцией того же сайдкара, который экран подписи уже читает, — то есть исполнено ровно то, чего требует правило этой страницы («чинятся раньше, а не когда читатель придёт»), а не рефактор под несуществующий экран. Следствия для текста ниже: клауза «на стоп-границе вид вообще не меняется» тоже стала неточной — секция едет в проекцию, не проходя через вид (⚠ при этом правило однонаправленного потока НЕ нарушено: глоссарий не тронут, снапшот байт-равен); фраза «читаемый банк несёт итоги БЕЗ предложений» с этого дня ЛОЖНА и читается как описание до-паковой формы; оговорка «когда экран закажут» относится к полному ДЖОЙНУ «предложено × решено × нерешено», который по-прежнему живёт только внутри движка и наружу не выносится. ⛔ **Долг, названный вслух:** у новой секции сегодня НОЛЬ читателей — платформа разбирает сайдкар аллоулистом и поле игнорирует; носитель обязательства сделать читателя названным — платформенная половина строки **224** (⚠ испр. 08.09: первая редакция эрраты называла 253, но её половина (а) ЗАКРЫВАЕТСЯ лендингом 224, а живая (б) — другой предмет; адрес, не разрешающийся в обязательство, которое он называет, — ровно класс, которым куплено правило 1 этой страницы). Пока она открыта, это проекция без потребителя, то есть класс A, заведённый сознательно и с адресом. ## Чего эта форма НЕ несёт Джойн «предложено × решено × нерешено» существует только внутри движка. Читаемый банк несёт итоги без предложений, карта — предложения без решений. Экран подписи при разморозке фронта заставит платформу пере-реализовать движковый закон у себя, что запрещено п.6 закона шва. Лечение — публиковать нерешённость движком, когда экран закажут; сейчас это ноль кода и строка бэклога, а не рефактор под несуществующий экран. ## Если проектировать с нуля То же самое, с одним отличием: дельта и список отказов — **один документ с двумя секциями**. Это правильнее с нуля (одна запись, одна точка фиксации, невозможность указать двумя ключами на один файл), но не стоит миграции схемы в полёте: снятие объявляемых ключей D39.158 уже закрыло тот дефект, ради которого слияние в первую очередь понадобилось бы.