Часть II. Объекты формата
4. Φ — лог событий как единственный источник истины
Φ (phi) — это упорядоченная по времени последовательность эффектов, каждый из которых достиг состояния confirmed. Она одна содержит всё изменение мира приложения.
Каждый эффект — это запись вида:
- α — вид изменения:
create,replace,remove,transition,commit - entity — тип сущности, которую эффект затрагивает
- fields — полезная нагрузка (значения полей)
- context — метаданные: кто инициировал, к какой сессии относится, какая степень необратимости (см. 23), ссылки на другие эффекты
Мир не хранится отдельно. Состояние любой сущности в любой момент — результат fold(Φ) (см. 11), применённого к эффектам, видимым к этому моменту. Это свойство даёт три следствия, которые проходят через весь формат:
- Audit trail бесплатный: каждое изменение в мире имеет свидетеля в Φ. Нет in-place мутаций, которые обошли бы журнал.
- Rebuild from scratch — первоклассная операция. Тесты, дебаг, миграция — всё это частные случаи перевычисления мира от Φ.
- Причинность сохраняется: rejected эффекты тоже остаются в журнале (в отдельной зоне), чтобы можно было понять, что именно было отвергнуто и почему.
Жизненный цикл эффекта: proposed → { confirmed | rejected }. Переход — отдельный шаг валидации, в котором проверяются инварианты онтологии, препятствия типа irreversibility и условия намерения. Confirmed эффекты попадают в Φ и становятся частью мира; rejected — не попадают, но сохраняются отдельно.
5. Δ — черновики, session-scoped namespace
Δ (delta) — это пространство черновиков: эффектов, инициированных, но не достигших статуса confirmed. Черновики видны только инициатору и живут до момента commit, cancel или истечения сессии.
Структурная функция Δ в формате — позволить автору намерения накапливать состояние до решения его зафиксировать. Форма-wizard с четырьмя шагами — череда черновиков, где каждый шаг добавляет поля; финальный шаг превращает accumulated draft в confirmed effect. До этого момента ни один другой viewer не видит промежуточное состояние.
Промоция Δ → Φ происходит атомарно при подтверждении намерения. Rejected черновики уничтожаются (не становятся частью Φ, не остаются в rejected-зоне — это чистый рабочий процесс автора, не свидетельство в мире).
Множественные черновики одного инициатора могут существовать параллельно: пользователь может работать одновременно над несколькими намерениями, и черновики не мешают друг другу, потому что каждый привязан к session-context внутри инициатора.
6. Intent — конструктивные частицы
Intent — это декларативное описание возможности изменить мир, которая может быть предложена viewer'у.
Намерение — не функция и не handler. Оно — запись формата:
- id — стабильный идентификатор
- ownerRole — какая роль авторизована его инициировать
- requiredFields — какие поля должны быть заполнены до подтверждения
- conditions — предикаты над миром, которые должны выполняться
- effects — список эффектов, которые будут эмитены при подтверждении
Пять первичных видов намерений (α / β / χ / τ / ω), соответствующих пяти видам эффектов: создание, замена, удаление, переход состояния, commit workflow. Шестой вид — системные намерения: schedule_timer, revoke_timer — конструкты темпорального слоя (см. 8.5).
Generic effect handler формата механически применяет объявленные effects к Φ. Это свойство — ключевое: намерения не несут императивный код. Domain-автор описывает, что должно произойти; движок гарантирует, как это произойдёт.
Намерение не знает о пользовательском интерфейсе; интерфейс не знает о намерении напрямую — только через проекцию, которая связывает намерения в логически связный вид. Это разделение делает намерения переиспользуемыми между рендерами: одно и то же create_appointment показывается в pixel-форме, voice-диалоге, agent-API schema и document-варианте без модификации.
7. Effect — атомы изменения мира
Эффект — квант изменения: минимальная единица, которая может быть записана в Φ. Каждый эффект порождается намерением и подчиняется формату:
{ α, entity, fields, context }
Поле α принимает одно из пяти значений:
- create — добавить новую сущность
- replace — заменить поля существующей сущности
- remove — удалить сущность (с ограничением irreversibility)
- transition — изменить состояние workflow'а
- commit — зафиксировать завершение сложной частицы (wizard, batch)
Поле context несёт метаданные, важные для валидации и интерпретации:
__irr: { point, at, reason }— степень необратимости:point = "high"блокирует последующиеremoveпослеat- ссылки на инициирующее намерение, инициатора, session-id
- external refs — если эффект отражает вовне-мировое событие (платёж, сообщение в мессенджер)
Честная граница (particle uniformity): generic effect handler формата покрывает большинство намерений, но не все. Domain-автор может поставить custom effect builder для доменно-специфичных инвариантов (например, real-time mirror в messenger или cascade cleanup в workflow). Это свойство реализации, не формата: формат гарантирует, что эффекты всегда имеют форму {α, entity, fields, context} — а путь их порождения может быть generic или custom.
8. Ontology — тип данных домена
Онтология — центральный объект формата. Она определяет, что такое «домен»: какие сущности существуют, какие роли ими манипулируют, какие инварианты должны выполняться, какие правила автоматики движок исполняет.
8.1 Entities
Сущности — типы данных домена. Каждая имеет:
- fields — типизированные поля с read/write matrix по ролям
- ownerField — поле, указывающее single-owner (foreign key на роль)
- kind — таксономический маркер:
internal(implicit default) — обычная сущность, принадлежит одному viewer'уreference— справочная сущность без owner'а (видна всем с правильным role.visibleFields)assignment— bridge-сущность для m2m-связей черезrole.scope
Приоритет row-filter: role.scope > entity.kind:"reference" > entity.ownerField > none.
8.2 Roles и base-таксономия
Роли — это viewer-типы. Каждая роль имеет:
- base — семантическая таксономия:
owner | viewer | agent | observer | admin - visibleFields — какие поля каждой сущности она видит
- canExecute — какие намерения она может инициировать
- scope — декларативное m2m-присоединение через bridge-сущность:
role.advisor.scope.Portfolio = {
via: "Assignment", // bridge
viewerField: "advisorId", // поле в bridge, сопоставляемое с viewer
joinField: "portfolioId", // поле в bridge, ссылающееся на target
localField: "id" // поле в target, сопоставляемое с joinField
}
Base-таксономия не заменяет доменные имена; она даёт cross-domain инструментам (SDK defaults, авторские линтеры, тесты) возможность узнавать структурный паттерн: «все agent-роли обязаны иметь preapproval», «observer-роли не могут эмитить α-эффекты», «admin-роли видят все записи независимо от ownerField (row-override в filterWorldForRole)».
Базы устроены как открытое множество прецедентов, не closed enum: пятый класс admin появился post-v2.0 после стресс-теста spec-v0.1 на library-домене (librarian не вписался в существующие четыре). Конформная реализация MUST принимать любую строку в role.base; нормативную семантику задают только перечисленные классы.
8.3 Invariants — ∀-свойства
Инварианты — декларативные предикаты, которые должны выполняться для состояния мира всегда. Шесть видов:
- role-capability — какие роли могут инициировать какие намерения (
observerне можетreplace) - referential — referential integrity (foreign keys, ссылочная целостность)
- transition — допустимые переходы workflow (state machine)
- cardinality — N-to-M кардинальности (Portfolio имеет ровно один риск-профиль), composite groupBy поддерживается
- aggregate — свойства агрегатов (
sum(portfolio.positions.weight) = 1.0) - expression — row-level predicate с доступом к
world/viewer/context: авторская функция или строковое JS-выражение; служит для cross-entity предикатов (SoD: approver≠preparer через lookup вworld.approvals), dynamic-threshold (нужное число подписей зависит отrow.amount) и viewer-aware блокировок (auditor не мутирует). Добавлен после 13-го полевого теста (compliance/SOX ICFR); predicate — trusted authored code, не пользовательский input.
Инварианты проверяются при каждом confirm effect. Нарушение блокирует эффект и каскадно отклоняет зависимые — то есть инвариант не «проверяется позже», а формирует барьер между proposed и confirmed.
8.4 Rules — Reactive Rules Engine
Правила — декларативные event-condition-action автоматы. Каждое правило имеет триггер (событие в Φ), условие (предикат над миром), действие (список эффектов).
Четыре расширения базовой event→action модели:
- aggregation: счётчик per-user, срабатывает на каждое N-е событие
- threshold: предикат над последними N записями (lookback window)
- schedule: темпоральный триггер — частный случай 8.5
- condition: JS-выражение (whitelisted Math), evaluator для сложных предикатов
Состояние правил (rule_state: counter, last_fired_at) хранится per (rule, user).
8.5 Scheduler — темпоральный слой
Расписание — частный случай rule. Декларация:
rule.schedule = { after: <duration> }
| { at: <ISO timestamp> }
| { after: ..., revokeOn: <effect patterns> }
Движок поддерживает priority-queue таймеров. Таймеры — обычные эффекты (τ=scheduled_timer) в Φ, не отдельный state: hydration из мира при рестарте происходит автоматически. Revoke — удаление таймера по id, эмитируется системным намерением.
Системные намерения темпорального слоя:
schedule_timer(afterMs | atISO, target, revokeOn?)— создать таймерrevoke_timer(timerId)— отменить
Любое доменное правило со schedule разворачивается во внутренний schedule_timer при fire'е, с автоматическим self-rescheduling при повторяемости.
8.6 Field roles — семантические типы
Поле сущности имеет тип (string, number, enum, ...) и, опционально, семантическую роль:
- pure-data:
money,percentage,trend,ticker - spatial:
coordinate,address,zone - temporal:
datetime,duration
Семантические роли — advisory hints для читателей формата. Pixel-материализатор консультируется с adapter capability surface: если адаптер поддерживает нативный рендер money (форматирование с валютой, выравнивание), он использует его; если нет — fallback на text.
Честная граница: нативный рендер семантических ролей зависит от адаптера. Некоторые адаптеры реализуют fallback тонко, другие — грубо. Формат гарантирует, что роль будет prosledeна в артефакт; качество рендера — свойство читателя.
9. Projection — авторский контракт
Projection — декларация автора о том, какие намерения и сущности образуют один «экран», «диалог», «страницу». Она содержит:
- список намерений, которые должны быть доступны в этой проекции
- предпочтительный архетип (
catalog,detail,form,feed,canvas,dashboard,wizard) илиauto - preference по паттернам Pattern Bank'а:
patterns: { enabled: [...], disabled: [...] } - опциональный slot-override для конкретных мест в артефакте
Projection — это input для кристаллизации; artifact — output. Автор влияет на результат через два механизма:
- Projection.patterns — preference, модификатор входа. Артефакт остаётся перегенерируемым из
(intents, ontology, projection, patterns, features): тот же вход → тот же выход. - Slot-override (через
mergeProjections) — freezing output. Автор фиксирует конкретный слот, bypass'а кристаллизацию для этой части. Потеря: артефакт больше не чистая функция от входа.
Разница принципиальная. Preference сохраняет инвариант «артефакт = f(input)»; slot-override жертвует им ради локального контроля. Рекомендация формата: preference first, slot-override только когда preference принципиально не выражает нужное поведение.
10. Artifact — кристаллизованный результат
Артефакт v2 — это тип данных, не результат рендеринга.
Структура артефакта:
- archetype — один из семи:
feed,catalog,detail,form,canvas,dashboard,wizard - slots — именованные контейнеры содержимого (
header,body,footer,toolbar,sidebar, ...) - witnesses — structured findings о свойствах артефакта, см. ниже
- shape — деривационный слой над архетипом (
timeline,directory,default) - pattern annotations — матченные паттерны Pattern Bank'а с basis
pattern-bank
Witnesses — свидетельства свойств артефакта. Каждый witness — запись вида:
{ basis, reliability, pattern?, requirements?, ... }
Три основных basis:
- heuristic — вывод через эвристику, например
inferFieldRoleопределяющую семантическую роль поля.reliability: "heuristic", требует promotion через анкеринг для продвижения в надёжное знание. - pattern-bank — formal match паттерна банка.
reliability: "rule-based": trigger и structure/apply — декларативные функции, результат детерминированный. - anchored — constructive proof через witness-of-proof (частица 15 field-теста). Самый сильный класс; anchoring promotion writer — открытая epistemic задача.
Артефакт не рендерится напрямую. Его читают разные материализации (часть IV): pixel-рендерер собирает DOM, voice-материализатор строит speech-script, agent-API сериализует в JSON-schema, document-генератор строит HTML-граф. Все четыре читают один и тот же артефакт.
Семь структурных архетипов описывают скелет артефакта (какие слоты есть, как они организованы); пять behavioral паттернов (monitoring, triage, execution, exploration, configuration) — перпендикулярны архетипу и описывают поведение (что делают viewer'ы на этой проекции). Signal Classifier выводит behavioral pattern из группы намерений через взвешенный scoring; rendering strategy определяет itemLayout, emphasisFields, preferControl.
Артефакт — компактное, сериализуемое, машинно-читаемое описание проекции. Это делает возможным сравнение артефактов (diff для code review), перегенерацию (rebuild from input), кеширование (content-addressable storage) и audit (stable reference для инвариантов).