Перейти к основному содержимому

Часть 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 snapshot
  • POST /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). Эта равноправность — структурное свойство формата, не имплементационный выбор.