Черновики

Глава 1 (Приложение): Структура базы данных Vibe

Этот документ описывает структуру базы данных PostgreSQL, которая хранит и управляет Vibes. Эта структура является основой для принципов системы: неизменяемости, контентной адресации и проверяемого происхождения. В основе дизайна лежат две ключевые таблицы, vibes и refinements, а также мощный набор функций для динамического разрешения схем Vibe.

Основные таблицы

Таблица vibes

Таблица vibes — это сердце хранилища системы. Каждый Vibe, независимо от его типа (Запись, Роль, Процесс или Возможность), хранится как строка в этой таблице. Это неизменяемый журнал всех когда-либо произошедших взаимодействий.

Вот ключевые столбцы:

  • ref (Первичный ключ): Уникальная, удобочитаемая текстовая ссылка на Vibe, которая действует как его контентно-адресуемый идентификатор. Это основной способ ссылаться на Vibes во всей системе.
  • id, branches, revision: Эти столбцы вместе управляют версиями и идентификацией. Концептуальная идентичность Vibe — это его id, но он может существовать в нескольких branches (ветках, например, main, dev/feature-x) и иметь несколько номеров revision (ревизий) в этих ветках. Это позволяет реализовать мощные рабочие процессы для версионирования и экспериментов.
  • authorRef: Внешний ключ, ссылающийся на ref Vibe, который создал этот Vibe, устанавливая прямую линию происхождения.
  • prototypeRef: Ссылка на другой Vibe, который использовался как шаблон, что позволяет создавать по примеру.
  • refinementId: Ссылка на таблицу refinements, связывающая Vibe с конкретной операцией refine, в результате которой он был создан.
  • context, schema, solution: Эти три столбца типа JSONB хранят основную тройку {контекст, схема, решение}, которая определяет Vibe. schema хранится напрямую, но, как мы увидим, она может содержать ссылки на другие Vibes, которые необходимо разрешить.
  • schema_refs: Столбец типа TEXT[], который автоматически заполняется триггером и хранит массив всех ссылок aug:, найденных в schema. Это позволяет быстро находить Vibes, у которых есть зависимости в схеме.

Таблица refinements

Таблица refinements действует как транзакционный журнал для каждой операции refine. Она фиксирует входные данные и контекст каждого изменения состояния, обеспечивая полную и проверяемую историю.

Ключевые столбцы включают:

  • id: Первичный ключ для записи об уточнении.
  • targetRefs, instructionRefs, budgetRefs: Эти текстовые массивы хранят ref (ссылки) на Vibes, которые использовались как входные данные для вызова refine. Это явно записывает зависимости операции.
  • authorRef: ref Vibe, который инициировал уточнение.

Вместе эти таблицы создают надежный и взаимосвязанный граф всей активности в системе, где каждый Vibe можно отследить до его автора, входных данных и операции, которая его создала.

Таблица vibe_refs: Граф зависимостей

Для обеспечения полного и эффективного способа запроса связей между Vibes система поддерживает таблицу vibe_refs. Эта таблица хранит денормализованный, прямой граф всех зависимостей схемы.

Когда Vibe создается или обновляется, функция-триггер сканирует его schema на наличие ссылок aug: и заполняет эту таблицу.

Ключевые столбцы включают:

  • from_ref: ref Vibe, содержащего схему с зависимостью.
  • to_ref: ref Vibe, на который ссылаются внутри схемы.
  • type: Тип ссылки (например, 'schema').
  • branch, from_id, from_revision, to_id, to_revision: Эти столбцы фиксируют конкретные детали версионирования для обоих концов связи зависимости.

Эта таблица является оптимизацией производительности, которая позволяет системе быстро отвечать на вопросы вроде: «Какие Vibes будут затронуты, если мы обновим этот конкретный компонент схемы?», без необходимости сканировать содержимое JSONB всей таблицы vibes. Она делает граф зависимостей явной и запрашиваемой частью базы данных.

Динамическое разрешение схем и графы зависимостей

Ключевое нововведение в дизайне базы данных — это то, как обрабатываются схемы Vibe. schema Vibe — это не обязательно статический, самодостаточный документ. Это может быть составная структура, построенная из других Vibes, что обеспечивает мощные возможности повторного использования и композиции. Это достигается с помощью специальных ссылок aug: и функции базы данных, которая разрешает их в реальном времени.

Компонуемые схемы со ссылками aug:

В поле schema Vibe мы можем встраивать ссылки на другие Vibes, используя специальный формат URI, например aug:/common/schemas/address?1 или aug:~dev/user-profile. Эти ссылки указывают системе извлечь schema из упомянутого Vibe и встроить ее в текущий на шаге разрешения.

Это позволяет нам создавать библиотеку многоразовых компонентов схемы. Например, множество разных Record Vibes могут ссылаться на одну каноническую схему address вместо того, чтобы определять ее каждый раз заново.

Функция resolveVibeSchema и разрешение ссылок

Магия происходит в функции PostgreSQL resolveVibeSchema и окружающей ее логике приложения. Когда клиент отправляет Vibe, его schema может содержать неразрешенные ссылки, которые нужно обработать. Система спроектирована так, чтобы корректно обрабатывать несколько случаев.

Внутри схемы ссылка на другой Vibe может быть представлена объектом, содержащим определенные ключи:

  • $ref: Строка URI aug:, указывающая на концептуальный Vibe (например, aug:/schemas/user). Это означает, что система должна найти самую последнюю подходящую версию этого Vibe на основе текущего контекста (например, текущей ветки и временной метки).
  • $refOriginal: Строка URI aug:, указывающая на конкретный, версионированный Vibe (например, aug:/schemas/user?1). Это используется, когда клиент уже разрешил ссылку до конкретной версии и хочет использовать именно ее.
  • $refResolved: Это свойство добавляется системой в процессе разрешения. Оно содержит канонический, полностью разрешенный ref версии Vibe, которая была использована для заполнения схемы, обеспечивая постоянную запись точной зависимости.

Логика разрешения, обычно находящаяся в триггере базы данных или сервисе приложения, работает следующим образом:

  1. Она проходит по входящей schema в поиске объектов, которые содержат ключ $ref или $refOriginal, но еще не имеют ключа $refResolved.
  2. Если у объекта есть $ref, система запрашивает базу данных, чтобы найти правильную версию Vibe на основе URI и текущего контекста (ветка, дата и т. д.).
  3. Если у объекта есть $refOriginal, система использует именно эту версию Vibe.
  4. Как только правильный зависимый Vibe определен, его схема рекурсивно разрешается и встраивается.
  5. Затем система добавляет свойство $refResolved к объекту, сохраняя канонический ref использованной зависимости (например, main@schemas/user?1).

Это гарантирует, что все схемы полностью разрешены, и их зависимости явно записаны во время создания или обновления. Процесс идемпотентен; если схема обрабатывается снова, система видит свойство $refResolved и знает, что не нужно повторно разрешать эту зависимость.

Эта явная информация о зависимостях, зафиксированная в итоговой разрешенной схеме, бесценна. Она предоставляет полный, проверяемый граф зависимостей того, как устроен любой Vibe, что лежит в основе отслеживаемости системы и позволяет нам понимать точное влияние любого изменения.