Documentation
¶
Overview ¶
grant_removal_trace.go — миграция, СНИМАЮЩАЯ выдачи, обязана оставить след той формы, которую платформа для этого завела; и ни одна миграция не переносит выдачу с одной роли на другую.
Порт с монорепо (`internal/repohygiene/grantremovaltrace.go`, снят вынесением службы — `kacho#2597`; приёмка `seed-identity-names-its-own-service.md` §6 уже называла держателем `TestNoMigrationMovesGrantsBetweenRoles`, а он не существовал ни в одном файле — только в комментариях).
Предмет ¶
Строка `kaname.access_bindings` — это доступ, выданный арендатору. Миграция, удаляющая её, доступ ОТБИРАЕТ; и если рядом нет записи в журнал жизненного цикла выдачи, у которого есть читатель, то «отобрано» становится неотличимо от «никогда не выдавалось». Арендатор видит отсутствие права и не может узнать ни что оно было, ни когда исчезло, ни почему.
Замер на дне переезда (эта ревизия, `internal/migrations`) ¶
Корпус — 10 файлов. Ровно один называет таблицу выдач ОПЕРАТОРОМ удаления (`20260909202745_module_identities_leave_the_baseline.sql`), и он несёт след — вставку в `kaname.audit_outbox` — ДО удаления, в той же накатной половине. Храповик заведён нулём и это подтверждено переписью гейта, а не предположено: см. `TestMigrationRemovingGrantsLeavesATrace`.
Почему ХРАПОВИК, а не ведомость имён ¶
Применённую миграцию не правят (запрет #5) — значит найденную без следа придётся либо простить, либо держать ствол красным за прошлое. Ведомость имён растёт молча, и её никто не сверяет; число сверяется одним обходом и меняется только сознательно. Перечень имён при этом ПЕЧАТАЕТСЯ каждым прогоном — прощение остаётся видимым.
Храповик ДВУСТОРОННИЙ: находка приходит и на следующей миграции без следа, и на уменьшении числа прощённых. Односторонний потолок не истекает никогда и потому механизмом не является.
Почему снятие выдач У СУБЪЕКТА входит в класс ¶
Норма — про ОТОБРАННЫЙ ДОСТУП, а не про снятую роль: строки выдач исчезают одинаково, а служебная учётка — такой же первоклассный принципал, как человек.
Граница, названная честно ¶
Гейт судит НАКАТНУЮ половину: `DELETE` в откатной половине снимает СВОЮ ЖЕ вставку, откатываясь, и доступа не отбирает. Он не судит, ВЕРЕН ли текст оставленного следа и доедет ли он до читателя, — только что запись есть. И он ничего не говорит о выдачах, снятых прод-кодом: у того путь свой и свой журнал.
sql_text.go — исполняемая часть миграции: Up-секция без комментариев и без содержимого строковых литералов.
Порт с монорепо (`internal/repohygiene/migrationsqltext.go`, снят вынесением службы — `kacho#2597`). Поведение переносом не менялось: функции перенесены дословно и экспортированы, чтобы их звала внешняя тестовая обёртка (`package migrations_test`), а не только пакет-владелец.
Здесь у монорепо было НЕСКОЛЬКО инвентарей, зовущих эти функции; в этом дереве сегодня один владелец — `grant_removal_trace.go`. Заводя второй, проверь СНАЧАЛА, не завёл ли кто-то копию: две реализации одного разбора расходятся молча, и расходятся именно там, где расхождение не видно — на законном входе обе отвечают одинаково.
Index ¶
- Constants
- Variables
- func AuditGrantRoleReassignment(corpus []GrantMigrationSource) (moves []string, statements int)
- func GrantRemovalFinding(got int, names []string) string
- func GrantTableMentions(corpus []GrantMigrationSource) int
- func MigrationUpSection(body string) string
- func SQLBlankComments(s string) string
- func SQLBlankStrings(s string) string
- type GrantMigrationSource
- type GrantRemovalCensus
Constants ¶
const GrantRemovalRatchet = 0
GrantRemovalRatchet — сколько миграций корпуса СЕГОДНЯ снимают выдачи без следа. Число, а не перечень: см. шапку файла. Отклонение в любую сторону — находка.
Variables ¶
var FS embed.FS
FS — embedded миграции (squashed baseline в одном файле). Используется cmd/migrator/main.go через runner.Config.FS.
Functions ¶
func AuditGrantRoleReassignment ¶ added in v0.2.0
func AuditGrantRoleReassignment(corpus []GrantMigrationSource) (moves []string, statements int)
AuditGrantRoleReassignment — миграции, переставляющие выдачу с одной роли на другую, и число осмотренных операторов.
Второе число обязательно: ноль переносов при нуле прочитанных операторов означает «распознаватель ослеп», а не «переносов нет».
func GrantRemovalFinding ¶ added in v0.2.0
GrantRemovalFinding — текст находки. Отдельной функцией, чтобы обе стороны храповика (перебор и недобор) говорили ОДНИМ голосом и назывались вместе с перечнем.
func GrantTableMentions ¶ added in v0.2.0
func GrantTableMentions(corpus []GrantMigrationSource) int
GrantTableMentions — сколько операторов корпуса называют таблицу выдач ЛЮБЫМ глаголом. Общая предпосылка обоих гейтов файла: ноль означает, что корпус не прочитан либо таблица выдач из него исчезла.
func MigrationUpSection ¶ added in v0.2.0
MigrationUpSection — исполняемая часть миграции: Up-секция без комментариев.
Порядок двух шагов обязателен и обратим быть не может: маркер `-- +goose Down` САМ является комментарием, поэтому секция отрезается по СЫРОМУ тексту, и только потом забеливаются комментарии. Забелив сперва, разбор потерял бы границу секций и прочитал бы откат как часть наката.
func SQLBlankComments ¶ added in v0.2.0
SQLBlankComments заменяет содержимое SQL-комментариев пробелами, сохраняя длину строки и позиции переводов строк.
Приоритет состояний: строка > комментарий > код. Внутри строкового литерала `--` комментария не начинает; внутри комментария кавычка строки не открывает. Блочные комментарии Postgres ВЛОЖЕННЫЕ — глубина считается, а не ищется первый `*/`.
func SQLBlankStrings ¶ added in v0.2.0
SQLBlankStrings заменяет СОДЕРЖИМОЕ строковых литералов пробелами, сохраняя длину и позиции переводов строк.
Зачем отдельно от SQLBlankComments. Тот забеливает комментарии и при этом НАМЕРЕННО пропускает литералы целиком — иначе `--` внутри строки открыл бы комментарий. Но литерал не исполняется как SQL: прозаическое сообщение об ошибке, содержащее слова конструкции, для инвентаря по образцу неотличимо от самой конструкции.
Кавычки-границы ОСТАЮТСЯ на месте: забеливается содержимое, поэтому `WHERE x = 'DROP COLUMN'` остаётся синтаксически тем же и по-прежнему не склеивает соседние лексемы.
Types ¶
type GrantMigrationSource ¶ added in v0.2.0
GrantMigrationSource — один файл корпуса: имя для находки и текст для разбора.
func ReadMigrationCorpus ¶ added in v0.2.0
func ReadMigrationCorpus(paths []string, read func(string) ([]byte, error)) ([]GrantMigrationSource, error)
ReadMigrationCorpus — корпус миграций, состав берётся у вызывающего (индекс git либо `embed.FS`), а не с диска напрямую.
type GrantRemovalCensus ¶ added in v0.2.0
type GrantRemovalCensus struct {
FilesRead int
WithDelete int // удаление выдач где угодно в файле
InUpHalf int // из них — в накатной половине
}
GrantRemovalCensus — объём осмотренного. Три величины, а не одна: «ноль находок» обязано быть отличимо от «ноль прочитанного», а «ноль в накатной половине» — от «распознаватель перестал узнавать удаление вовсе».
func AuditGrantRemovalTrace ¶ added in v0.2.0
func AuditGrantRemovalTrace(corpus []GrantMigrationSource) (silent []string, c GrantRemovalCensus)
AuditGrantRemovalTrace — ядро гейта. Возвращает имена миграций, снимающих выдачи без следа, и перепись.