Часть III. Алгебра
11. fold — мир как функция от Φ
fold(Φ) → world — чистая операция reduce, применяющая эффекты журнала к начальному пустому состоянию в порядке их времени.
Детерминизм — жёсткое требование: один и тот же Φ даёт одно и то же состояние мира. Это следует из трёх свойств:
- α-квантование: каждый эффект описывает минимальный шаг (create entity, replace fields, remove, transition, commit). Последствия эффекта локализованы.
- Порядок устойчив: эффекты в Φ упорядочены по времени, и fold применяет их строго в этом порядке.
- Без сайд-эффектов в fold: fold — функция над данными, не читает внешние источники.
Из детерминизма следует, что rebuild from scratch — первоклассная операция. Тесты конформных реализаций пересчитывают мир от Φ, чтобы убедиться в интегрировании. Debug workflow использует fold как «машину времени»: проигрывая Φ до момента t, можно посмотреть на мир глазами любого viewer'а в прошлом.
Производные от fold:
foldFiltered(Φ, predicate)— пересчёт мира только по релевантным эффектам (для оптимизации больших журналов)foldView(Φ, viewerRole, ontology)— композиция fold и viewer-scoping (см. 14), даётviewerWorld
Читатели формата (материализации, agent-API, voice) работают не с Φ напрямую, а с миром, полученным fold'ом. Это означает, что журнал остаётся свидетельством, но взаимодействие с пользователем происходит на уровне текущего состояния.
12. Crystallization — артефакт как чистая функция
Кристаллизация — процедура, превращающая набор намерений и онтологию в артефакт (тип данных, описанный в 10). Её сигнатура:
crystallize(intents, ontology, projection, patternBank, features) → artifact
Все пять аргументов — input; артефакт — output. Никаких скрытых состояний, LLM-провайдеров или сетевых обращений. Это ключевое свойство формата: артефакт детерминированно выводится из декларативных данных.
Процедура состоит из шести фаз:
- deriveProjections — выводит скелеты проекций из (intents × ontology) по правилам R1–R8: группировка namespace, вывод архетипа, hub-absorption, shape-layer деривация.
- mergeProjections — shallow-merge авторских
projectionповерх derived-скелетов. - assignToSlots — распределяет намерения и данные по слотам согласно архетипу.
- matchPatterns — применяет Pattern Bank (см. 13) в matching-режиме; каждый сматченный паттерн становится witness'ом с
basis: "pattern-bank". - applyStructuralPatterns — для паттернов с
structure.apply— прогоняет apply-функцию, которая мутирует слоты (добавляет секции, меняет layout, переносит элементы). Feature-flagfeatures.structureApplyслужит emergency kill-switch. - wrapByConfirmation — оборачивает намерения в control-архетипы (
confirmDialog,formModal,composerEntry,clickForm, ...).
Детерминизм каждой фазы обязателен. Это делает артефакт:
- Перегенерируемым — новое preference на проекции → новый артефакт, без потери состояния других частей.
- Сравниваемым — два артефакта на одинаковых input'ах должны быть equal; diff показывает точное место расхождения.
- Проверяемым — инварианты формата (см. 23) могут быть подтверждены статически над артефактом.
Author-override через два механизма:
projection.patterns— input modifier. Изменяет вход, артефакт остаётся функцией. Preferred way.- Slot-override в
mergeProjections— output freeze. Автор фиксирует конкретный слот, bypass'а последующие фазы. Потеря: артефакт больше не чистая функция.
Формат рекомендует preference как первый выбор. Slot-override — escape hatch для случаев, когда паттерн принципиально не может быть выражен preference'ом.
13. Pattern Bank — декларативные правила деривации
Pattern Bank — формализованный реестр правил, которые угадывают структуру артефакта из конфигурации входа. Каждый паттерн — запись формата:
{
id: "subcollections",
archetype: "detail",
trigger: { match(projection, ontology, intents) → bool, ... },
structure: {
rationale: "...",
apply?: (slots, context) → mutated slots
},
falsification: { shouldMatch: [...], shouldNotMatch: [...] }
}
Три формы паттерна:
- Matching-only — паттерн имеет
triggerиrationale, но неapply. Роль: аннотация. Сматченный паттерн становится witness'ом, но не меняет слоты. Полезен для фиксации «мы распознали здесь структуру X». - Structure.apply — паттерн имеет чистую функцию
apply(slots, context) → slots, которая обогащает артефакт. Работает в фазе 5 кристаллизации. - Rationale-only — паттерн имеет только объяснительный narrative; используется для документации паттернов, которые ещё не формализованы.
Behavioral vs structural: поведение (monitoring, triage, execution, exploration, configuration) и структура (subcollections, grid-card-layout, hero-create, composer-entry, ...) — ортогональны. Behavioral паттерны классифицируют viewer'а в проекции (что он здесь делает); structural — скелет артефакта (как выглядит). Один артефакт может нести оба вида одновременно.
Falsification framework — обязательная часть каждого стабильного паттерна. Декларация shouldMatch фиксирует примеры, где паттерн должен сработать; shouldNotMatch — где не должен. Это не тесты в коде — это тесты в самом паттерне, запускаемые live-run viewer'ом. Если conformant реализация добавляет новый stable паттерн без falsification-примеров — это некорректная расширение банка.
Witnesses с basis: "pattern-bank" имеют reliability: "rule-based" — самый сильный класс после anchored. Эпистемически они формально выводимы: trigger-функция декларативна, результат детерминирован.
Author-preference через projection.patterns.{enabled, disabled} — способ автора влиять на применение банка без изменения самого банка. Это input-модификатор, не snapshot артефакта: банк остаётся универсальным, preference модифицирует вход кристаллизации.
14. Viewer-scoping — мир и артефакт как функции viewer'а
Один и тот же мир выглядит по-разному для разных ролей — не потому, что рендерер решает что-то скрыть, а потому, что viewerWorld — это отдельный тип данных.
Функция filterWorldForRole(world, viewer, ontology) → viewerWorld применяет row-filter по приоритету:
role.scope— m2m через bridge-сущность. Если роль имеет scope, viewer видит только те target-сущности, для которых bridge связываетviewerFieldс id viewer'а (опционально с фильтром поstatusAllowed).entity.kind: "reference"— справочные сущности видны всем с правильнымrole.visibleFields, без ownership-проверки.entity.ownerField— single-owner semantics: viewer видит сущности, гдеownerFieldсовпадает с его id.- none — если ни одного из правил не сработало, сущность не видна (privacy by default).
Base-таксономия роли усиливает viewer-scoping:
- owner — видит свои сущности, может инициировать все namespace намерений
- viewer — видит ограниченное подмножество (read-mostly)
- agent — видит то же, что owner, но каждое намерение проходит через preapproval guard: декларативные лимиты (maxAmount, csvInclude, dailySum, notExpired, active)
- observer — видит read-only view без привилегий; автоматически конфигурируется role-capability инвариантом
Материализации (pixel, voice, agent API, document) все используют один и тот же filterWorldForRole. Это значит, что viewer-scoping — единый механизм безопасности формата. Нет per-materialization hacks; добавление новой материализации не требует переписывания политик доступа.
Artifact тоже viewer-специфичен: кристаллизация видит только те намерения, которые role.canExecute позволяет, и только те поля, которые role.visibleFields открывает. Артефакт для advisor-роли и investor-роли — два разных артефакта, оба выведены из одной онтологии.