FTS — исполняемые спецификации FTS pipeline и визуализация: один прогон и диаграмма модели
0%

FTS pipeline и визуализация: один прогон и диаграмма модели

FTS pipeline и визуализация: один прогон и диаграмма модели

Курс уже показал fts check, fts prove, fts certify и fts visualize как отдельные команды — у каждой свой JSON, свой exit code, своя причина упасть. В CI и в диалоге с агентом это неудобно: чтобы понять, готов ли документ, надо запустить четыре процесса и вручную сопоставить их вывод. Эта глава — про fts pipeline, который прогоняет всю цепочку одним вызовом и возвращает один JSON, и про fts visualize, который превращает модель в mermaid-диаграмму, — то есть в вопрос, который можно задать человеку, а не только компилятору.

Минимальный пример

категория «Исполнение заказа»

  объект Заказ
    номер является строкой
    клиент является строкой
    оплачен является признаком
    «склад подтвердил» является признаком
    «готов к отгрузке» является состоянием «Готов к отгрузке»

  морфизм «Готовый заказ можно отгрузить»
    если «Готов к отгрузке»
    то «Отгрузить заказ разрешено»

  теорема «Заказ ЗК-7781 можно отгрузить»
    дано Заказ имеет «готов к отгрузке» равное да
    в данных заказы найти где номер равен «ЗК-7781»
    по морфизму «Готовый заказ можно отгрузить»
    следовательно «Отгрузить заказ разрешено»

Это static/fts/models/order-shipment.fts — та же модель, что в главе про доказательства и сертификаты. Здесь она нужна по другой причине: в ней есть и структура, и морфизм, и теорема, а значит на ней можно показать все четыре поля PipelineResult сразу, а не только часть.

Что делает компилятор

fts check разбирает категорию и объект, проверяет, что состояние «Готов к отгрузке» объявлено, а морфизм ссылается на реально существующий факт. Если бы теорема ссылалась на несуществующее поле, компиляция упала бы здесь же, до всякого прогона данных.

Один прогон вместо четырёх команд

pipeline() в src/pipeline.ts — это не пятая команда, а последовательный вызов того же кода, что стоит за check, prove, certify и visualize, на одном уже скомпилированном документе:

export function pipeline(input: PipelineInput): PipelineResult {
  const rawDocument = typeof input.source === "string"
    ? compile(input.source)
    : normalizeDocument(input.document)
  const document = assertValid(rawDocument)
  const proof = document.proposition === null ? null : prove(document, input.context)
  const certificate = document.proposition === null ? null : certify(document, input.context)
  const viz = visualize(document, proof, input.viz ?? "all")
  return { document, proof, certificate, viz }
}

PipelineInput принимает либо строку source, либо уже разобранный document (для тех, кто получил канонический JSON из другого языка, — см. главу про cross-language), плюс опциональные context и viz. PipelineResult — это ровно { document, proof, certificate, viz }: если в модели нет теоремы (document.proposition === null), proof и certificate будут null, но document и viz всё равно вернутся — диаграмму можно построить и без теоремы.

Важно, чего в pipeline нет: он не запускает fts test и не вызывает generateTypeScript. Тесты примеров и генерация кода — отдельные шаги CI, намеренно не входящие в эту цепочку (одна из типичных ошибок ниже).

Практическая разница с четырьмя отдельными вызовами — не в количестве нажатий клавиш, а в форме отказа:

  • Одна точка отказа. assertValid бросает исключение с той же диагностикой, что и fts check, и весь pipeline останавливается на этом шаге — не нужно писать в CI check && prove && certify && visualize с ручной проверкой exit code на каждом шаге.
  • Один JSON для CI. Результат можно целиком сохранить как build-артефакт или один раз распарсить в скрипте, вместо четырёх файлов, которые могут разойтись по времени, если процесс упал между шагами.
  • Один JSON для агента. MCP-инструмент fts_pipeline (src/mcp.ts) описан так: «Compile, validate, prove, and visualize FTS in one deterministic call». Агенту не нужно делать четыре последовательных вызова инструмента и держать в контексте четыре промежуточных результата — он получает документ, доказательство, сертификат и диаграмму одним round-trip и с одним и тем же document_digest во всех частях ответа.

CLI-эквивалент:

fts pipeline order-shipment.fts --context order-shipment.context.json --mode category --pretty

Диаграмма категории

fts visualize строит mermaid из документа, а не рисует его вручную — диаграмма настолько же точна, насколько точна модель. Вот реальный вывод mermaidCategory для order-shipment.fts:

Вопрос, который снимает эта картинка: «сколько вообще типов в модели и какие переходы между ними объявлены» — без чтения .fts построчно. Узел структуры показывает все поля сразу, стрелка — направление морфизма от домена к кодомену. mermaidCategory собирает узлы по именам структур и функторов (document.structures, document.functors), поэтому диаграмма никогда не разойдётся с моделью: изменили поле — изменилась подпись узла при следующей генерации.

Диаграмма морфизмов и доказательства

Категорию с одним морфизмом читать легко и без диаграммы. Диаграмма нужна, когда морфизмов несколько и важен порядок композиции. На модели credit-limit.fts (кредитный лимит: скоринг → риск-проверка → лимит) mermaidFunctors рисует цепочку явно:

Вопрос, который снимает эта диаграмма: «в каком порядке на самом деле применяются морфизмы» — в JSON-выводе prove порядок композиции печатается слева направо в порядке объявления, а математическое читается справа налево (это отдельно разобрано в главе про доказательства). Картинка с двумя явными стрелками устраняет двусмысленность быстрее, чем разбор строки A ∘ B.

mermaidProof строит третью диаграмму — не из модели, а из результата prove на конкретных данных: цепочку применённых морфизмов и witness, которым закрывается вывод:

Вопрос здесь другой: «на основании какого именно факта система разрешила лимит для конкретной заявки». Пунктирная стрелка к узлу witness — это и есть ответ: конкретное поле конкретного объекта, а не абстрактный закон.

Кому и когда показывать диаграмму

  • Аналитику — диаграмму категории, до code review. Она проверяется глазами за минуту: совпадают ли имена узлов с ubiquitous language из задачи, не потерялся ли морфизм, который аналитик считал очевидным. Текст .fts для этого читать не обязательно.
  • Новому разработчику в команде — диаграмму категории и морфизмов при первом знакомстве с моделью. Один граф заменяет чтение файла целиком и сразу показывает границы: какие структуры существуют, какие переходы между ними объявлены, а какие похожие переходы в модели попросту отсутствуют.
  • При разборе инцидента — диаграмму доказательства (mermaidProof) на том снимке данных, что был в момент инцидента. Это единственная из трёх диаграмм, которая отвечает не «что вообще возможно», а «что именно произошло на этих данных»: конкретный путь и конкретный witness, а не общая схема модели.

Практика в песочнице

Вкладка «Диаграмма» вызывает mermaidCategory прямо в браузере — это тот же код, что и в fts visualize, но без установки CLI. Откройте эту модель и сравните диаграмму категории с диаграммой морфизмов из этой главы: два узла «Риск-проверка разрешена» в mermaidFunctors — это один и тот же узел модели, просто нарисованный дважды, для каждого морфизма отдельно.

Типичные ошибки

  • Ждать от pipeline тестов и генерации. Название звучит как «весь жизненный цикл модели», но pipeline() — это check + prove + certify + visualize, и ничего больше. fts test и fts generate остаются отдельными шагами CI (см. главу про генерацию и CI); включать их в pipeline бессмысленно ждать.
  • Перепутать позиции аргументов visualize. Сигнатура — visualize(document, proof, mode), три параметра, а не два. Вызов вида visualize(doc, "all") подставит строку "all" вместо proof и упадёт с TypeError: Cannot read properties of undefined (reading 'length') внутри mermaidProof — ровно эта ошибка воспроизводится, если проверить на вендорной сборке сайта. Третий аргумент обязателен, второй — либо null, либо результат prove.
  • Забыть про null в proof/certificate. Для модели без теоремы (document.proposition === null) pipeline не падает — он просто возвращает proof: null, certificate: null при полностью заполненном viz. Код, который читает result.proof.witness без проверки на null, упадёт не на модели с ошибкой, а на корректной модели без теоремы.
  • Считать functors синонимом «нет диаграммы». У --mode пять реальных значений — all, category, morphisms, functors, proof (morphisms и functors синонимичны в реализации visualize, оба ведут к mermaidFunctors); если в модели нет ни одного морфизма, mermaidFunctors вернёт пустую строку, но visualize в режимах morphisms/functors откатится на mermaid_category, а не на пустой вывод.

Чек-лист

  • Для CI и агента используется fts pipeline / fts_pipeline, а не последовательность из check, prove, certify, visualize.
  • Известно, что pipeline не подменяет fts test и fts generate — они остаются в конвейере отдельно.
  • Перед чтением result.proof или result.certificate проверено, что документ содержит теорема (иначе оба поля — null).
  • Диаграмма категории показана аналитику до code review, а не после.
  • Диаграмма доказательства строится на снимке данных инцидента, а не на абстрактной модели, если вопрос — «что произошло», а не «что возможно».

Кейсы каталога по этой теме

Нашли неточность? Выделите фрагмент текста — рядом появится жучок.

Нужен разбор именно вашей ситуации?

Статья описывает общий случай. Если у вас частный — можно разобрать его отдельно, платно. А если не хватает целого материала, предложите тему: её оплачивают вскладчину, и она выходит открытой для всех.

Доска запросов
Дальше