moduleroleparity

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 13, 2026 License: AGPL-3.0 Imports: 4 Imported by: 0

Documentation

Overview

Package moduleroleparity — сверка ОБЪЯВЛЕННЫХ манифестом системных ролей модуля с тем, что лежит в живой базе (задача продукта #1891).

Предмет: манифест обязан ОБЪЯВЛЯТЬ то, что у модуля есть

Раздел `resources` каждого манифеста выводится из канона `fga_model.fga` — единственного документа, — и проверяется побайтовой сверкой. У раздела `roles` такого документа нет: действующее состояние ролей есть результат наложения применённых миграций, из которых ранние отменяются поздними. Поэтому объявление роли манифестом нельзя ни вывести, ни проверить чтением: угаданный раздел не остался бы бумажным — применитель (#1090) пишет им живые выдачи.

Отсюда способ доказательства: ПРОГОН против живой базы. Миграции исполняются по-настоящему, строки читаются оттуда, где они лежат, и объявление сверяется с НИМИ. Разбор SQL здесь не участвует ни одной строкой — он распознаватель, и молча пропустил бы форму записи, которой не знает.

Операнд «манифеста» производит ПРИМЕНИТЕЛЬ, а не копия его правил

Второй перевод «манифест → строка роли» разошёлся бы с первым молча: оба отвечают одинаково на законном входе. Поэтому сторона манифеста собирается вызовом настоящего применителя (`moduleroles.Applier`) с писателем, который вместо записи ЗАПОМИНАЕТ — см. пробу. Здесь, в чистом ядре, живёт только сравнение двух уже готовых наборов.

Почему сравнение — отдельная чистая функция

Способность гейта упасть доказывается инъекцией, а инъекция, требующая поднятой базы, стоила бы контейнера на каждое утверждение. Ядро чисто: `parity_injection_test.go` подаёт ему синтетические наборы и утверждает обе стороны по каждой оси.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Diff

func Diff(states []ModuleState, ledger []Postponement) []string

Diff — находки сверки. Порядок устойчив: находка читается человеком, и её перестановка между прогонами читалась бы как изменение.

Осей четыре, и каждая своя:

  1. модуль не объявил живых ролей и не стоит в ведомости;
  2. объявленная роль не найдена в базе — объявление шире действительности;
  3. живая роль не объявлена модулем, который ОБЪЯВИЛ хотя бы одну, — раздел неполон, и его неполнота молчит: применитель напишет объявленное и не тронет остальное;
  4. роль есть на обеих сторонах, а её содержание расходится.

Плюс две оси самоистечения ведомости.

func RulesLiteral

func RulesLiteral(rs domain.Rules) string

RulesLiteral — правила одной строкой, ДОСЛОВНО и без сортировки.

Приведение к канону здесь запрещено: применённая миграция несёт у ярусов чтения ровно `["read","list","get"]`, и сортировка либо разрешение снятого имени дали бы ДРУГУЮ строку — то есть сверка объявляла бы согласие там, где применитель записал бы иное.

Types

type Census

type Census struct {
	// Manifests — манифестов модулей прочитано.
	Manifests int
	// Declared — ролей объявлено манифестами суммарно.
	Declared int
	// Live — системных ролей прочитано из базы суммарно.
	Live int
	// Ownerless — живых ролей, чей первый сегмент НЕ член закрытого набора
	// модулей (`admin`, `edit`, `view`, `owner`, `kacho-system.*`). Манифестом
	// они невыразимы by construction и находкой быть не могут: сверять их не с
	// чем, и число названо именно поэтому.
	Ownerless int
	// Postponed — модулей, стоящих в ведомости #1891.
	Postponed int
}

Census — объём осмотренного. Печатается ВСЕГДА и до всякого вердикта: без него «ноль находок» неотличимо от «ноль прочитанного».

func (Census) String

func (c Census) String() string

String — перепись одной строкой.

type ModuleState

type ModuleState struct {
	// Module — имя модуля так, как его называет манифест.
	Module string
	// ManifestFile — координата манифеста: находка обязана называть, что править.
	ManifestFile string
	// Declared — роли, объявленные манифестом, в порядке объявления.
	Declared []Role
	// Live — роли этого модуля, прочитанные из живой базы.
	Live []Role
}

ModuleState — что известно об одном модуле закрытого набора.

type Postponement

type Postponement struct {
	// Module — модуль, чьё объявление отложено.
	Module string
	// Why — чем отложенное держится: причина и предикат снятия.
	Why string
}

Postponement — запись ведомости #1891: модуль, чьи роли ещё не объявлены.

Ведомость ИСТЕКАЕТ САМА, и это её несущее свойство: запись, чей модуль уже объявил свои роли, — находка, а не «уже не нужна»; запись модуля, у которого живых ролей нет вовсе, — тоже находка: откладывать нечего.

type Role

type Role struct {
	ID          string
	Name        string
	Description string
	Rules       domain.Rules
}

Role — системная роль в форме, общей для обеих сторон сверки.

Полей ровно четыре, и каждое ОБЪЯВЛЕНО манифестом либо ВЫВЕДЕНО из объявленного применителем:

  • `ID` выводится функцией имени (`domain.SystemRoleID`) — сверяется потому, что именно на него ссылаются выдачи: разошедшийся идентификатор означал бы новую строку рядом со старой, а не приведение старой;
  • `Name` — `roles[].id` манифеста дословно;
  • `Description` — назначение роли;
  • `Rules` — право роли.

Разрешения (`permissions`) здесь НЕ сверяются: они сворачиваются из правил одной функцией (`domain.CompileRules`), и сверка свёртки с её же результатом была бы утверждением о постоянстве функции, а не о согласии манифеста с базой. Их согласие — предмет собственного гейта, и он есть: расхождение свёртки с хранимой формой ловит сверка проекций посева.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL