Часть IV. Четыре читателя формата
Формат описывает приложение. Реализации читают формат и рендерят его в целевую среду. Четыре материализации архитектурно равноправны — ни одна не является «главной». Выбор материализации для конкретного use-case — свойство среды, не привилегия формата.
15. Pixels — runtime UI
Pixel-материализация — рендеринг артефакта в DOM (или эквивалент в другой host-среде). Читатель состоит из трёх слоёв:
- Renderer — интерпретирует структуру артефакта (архетип, слоты, controls, parameters) и строит дерево абстрактных UI-узлов
- Adapter — mapping между абстрактными узлами и конкретным UI-toolkit'ом (pluggable)
- Token Bridge — канонический contract CSS-переменных между адаптером и доменным кодом
Capability surface — декларативный список поддерживаемых адаптером primitive'ов и вариантов:
adapter.capabilities = {
primitive: {
chart: { chartTypes: ["line", "pie"] },
map: false,
statistic: true,
sparkline: true
}
}
Renderer консультируется с capability при выборе primitive'а. Mismatch → console.warn + fallback (SVG для chart/map, text для statistic). Unknown capability — assume supported (backward compatibility при добавлении новых primitive'ов).
Token Bridge — формальный contract. Адаптер обязан предоставить canonical CSS-переменные (--bg, --ink, --text-secondary, --accent, --success, --warn, --danger, --font, --radius, --shadow); domain-специфичный код (custom canvas) пишет только в canonical переменные, адаптер мапит их в свои значения. Это позволяет одному custom canvas работать через все адаптеры без модификации.
Граница pixel-материализации — analytical UI. Чарты, heatmap'ы, 2D-редакторы не кристаллизуются автоматически: они требуют authored custom canvas, который получает { world, viewer, exec, ctx, artifact } как props и рендерит всё сам. Custom canvas — escape hatch, не нарушающий формат: артефакт всё равно порождён кристаллизацией, но вместо generic рендера autor прикладывает специализированный компонент. Map-primitive и chart-primitive частично закрывают spatial / time-series случаи; sophisticated аналитика остаётся за custom canvas'ами.
16. Voice — speech-script
Voice-материализация превращает проекцию в структурированный speech-script. Функция:
materializeAsVoice(projection, world, viewer) → turns[]
Turn — речевая единица:
{ role: "system" | "assistant" | "prompts", text, items? }
Три формата вывода:
- json — для voice-agent (Claude Voice, OpenAI realtime, и других)
- SSML — XML для TTS-движков (SSML-разметка, паузы, ударения)
- plain — для debug или IVR
Brevity-правила — первоклассная часть voice-материализации:
- Catalog с более чем тремя элементами — озвучиваются top-3 с namescript «и ещё N»
- Money читается человеческим языком:
2500000 RUB → «два с половиной миллиона рублей» - Percentage и trend формируются как числительные, не символы
- Prompts — подмножество
role.canExecute, релевантные текущему состоянию viewer'а
Voice использует тот же filterWorldForRole, что pixel и agent API. Viewer-scoping транзитивен.
Все семь структурных архетипов поддерживаются voice-материализацией. Feed озвучивается как лента новейших, catalog — как обзор с навигацией, detail — как доклад о сущности, wizard — как диалог с подтверждением каждого шага.
17. Agent API — JSON + exec
Agent API превращает формат в schema + RPC для внешних LLM-агентов. Три endpoint'а:
GET /agent/:domain/schema?as=<role>— JSON-schema намерений, которые роль может инициировать, с описанием полей и условийGET /agent/:domain/world?as=<role>— viewer-scoped world snapshotPOST /agent/:domain/exec?as=<role>— подтверждение намерения с payload
Авторизация слоя — стандартный JWT plus role-based checks:
role.canExecute[intent]— разрешено ли роли инициировать данное намерениеrole.visibleFields— какие поля видит payload'уrole.scope/ownerField— какие сущности видны
Preapproval guard — декларативный лимитирующий слой для agent-base ролей:
role.agent.preapproval = {
createTrade: { active: true, maxAmount: 100000, dailySum: 500000 }
rebalance: { notExpired: true, csvInclude: ["AAPL","MSFT"] }
}
Пять типов предикатов:
- active — проверить, что у initiator'а есть активная сессия/подписка
- notExpired — проверить expiry отдельной preapproval-записи
- maxAmount — upper-bound числового поля payload
- csvInclude — поле payload должно быть в заранее одобренном списке
- dailySum — кумулятивная сумма за день не превышает предела
Guard проверяется перед любыми invariants онтологии. Если намерение не упомянуто в preapproval — no-op (backward compatibility).
Agent API — это не отдельная материализация в смысле «альтернативного вида UI»; это машинный интерфейс формата, равноправный с пиксельным. Внешний агент (Claude-как-ассистент, автоматизация, чатбот) видит тот же артефакт что человек, только сериализованный как JSON-schema.
18. Document — HTML / JSON граф
Document-материализация превращает проекцию в structured document-граф — статический или pre-rendered артефакт для чтения, печати, индексации. Функция:
materializeAsDocument(projection, world, viewer) → documentGraph
Document-граф — дерево узлов: sections, tables, fields, badges, citations, metadata. Формат узла независим от render-среды:
- Sections — заголовки, тело, подсекции
- Tables — коллекции с колонками (соответствуют catalog-архетипу)
- Fields — name-value пары с semantic type (money, percentage, ...)
- Badges — маркеры статуса, irreversibility, ролей
Два формата вывода:
- HTML — server-side rendered, для браузерного view / печати
- JSON — machine-readable, для индексации, экспорта, архива
Viewer-scoping — тот же filterWorldForRole. Document видит ровно то, что видит pixel и voice; отличие — только в форме представления.
Document больше не «альтернативная материализация» — это четвёртый равноправный читатель. Формат делает один и тот же контент доступным пользователю (pixel), голосом (voice), агенту (JSON API) и документом (HTML/JSON). Эта равноправность — структурное свойство формата, не имплементационный выбор.