# Как устроен vibe {#root}

@status:doc/work @audience:dev

[p01] vibe — один бинарник, собранный из набора библиотек на Rust, каждая из которых владеет одной заботой: прочитать описание проекта, выбрать версии, скачать оттуда, где пакеты опубликованы, записать дерево на диск, поговорить с агентами. Эта страница — карта библиотек, швов между ними и пути, который проходит через них установка.

## Пять слоёв {#five-layers}

[p02] Читайте продукт снизу вверх. *Идентичность*: пакет — это [координата](../glossary/index.xml#coordinate) плюс [отпечаток](../glossary/index.xml#fingerprint) содержимого, а вид — метаданные. *[Реестр](../glossary/index.xml#registry)*: упорядоченные источники пакетов с зеркалами, [переопределениями](../glossary/index.xml#override) и необязательным [индексом](../glossary/index.xml#index-registry). *[Хранилище](../glossary/index.xml#store)*: каждая скачанная версия пакета хранится на машине один раз.

[p03] *Материализация*: разрешённый граф, скопированный в дерево зависимостей проекта и записанный в [лок-файл](../glossary/index.xml#lock-file). *Вычисленный старт*: [вклады](../glossary/index.xml#contribution) пакетов, спроецированные в два сгенерированных файла, которые читает агент. Всё, что видит пользователь, — один из этих пяти слоёв или поверхность над ними.

> [p04] 21. Surface floor — which channels a capability owes
>
> <spec://org.vibevm.core/vibevm/common/PROP-000#surfaces>

## Крейты {#the-crates}

[p05]
| Забота | Крейты | Чем владеют |
| --- | --- | --- |
| базовый словарь | `vibe-core`, `vibe-wire` | манифесты, лок-файл, идентичности и хеши содержимого; сгенерированные типы каждого зарегистрированного машинного формата |
| спецификации | `vibe-spec`, `vibe-specdoc`, `progress-core`, `vibe-facts`, `vibe-trace` | адреса и детерминированный маршрутизатор; модель документа с её Markdown- и XML-фронтендами и бэкендами; парсер разметки статусов и отчёты; реестр фактов принятия; запросы прослеживаемости |
| реестры и хранилище | `vibe-registry`, `vibe-index`, `vibe-publish`, `vibe-package-source` | git-транспорт, зеркала и переопределения, кэш клонов и машинное хранилище; поисковый индекс и его сервер; публикация; единственная продуктивная композиция источников пакетов |
| разрешение и установка | `vibe-resolver`, `vibe-install`, `vibe-workspace`, `vibe-safefs` | швы и ячейки решателя; план и применение; обнаружение рабочего пространства, материализация, вычисленный старт; изменение файловой системы строго по выданным правам |
| жизненный цикл | `vibe-lifecycle`, `vibe-extension-registry`, `vibe-orchestrator`, `vibe-ext`, `vibe-native-loader`, `vibe-llm`, `vibe-scrape` | модель девяти фаз и цепочки; чистый реестр расширений; оркестрация, независимая от поверхности; безопасный SDK автора и карантинный загрузчик нативных расширений; шов провайдера модели; планирование зачистки |
| агенты и предпочтения | `vibe-mcp`, `vibe-agent-projection`, `vibe-settings`, `vibe-actions`, `vibe-requirements` | MCP-сервер и менеджер интеграций; проекция навыков в агентов; трёхуровневые предпочтения; действия, независимые от фронтенда; запрос требований только для чтения |
| поверхности и проверки | `vibe-cli`, `vibe-check` | командная строка; детерминированный линтер проекта |
| документация | `vibe-doc`, `vibe-doc-server`, `vibe-doc-shell` | конвейер страниц за `vibe doc`: сборка, проверка, манифест, снимки поверхности, очередь сопровождения и сборщик сайта; сервер локальной читалки на loopback-адресе; оболочка читалки внутри бинарника |
| зарезервированное и инструменты | `vibe-graph`, `vibe-test-support`, `xtask` | зарезервированный слот графа задач; изоляция домашней папки настроек в тестах; ворота сопровождающего: генерация кода, карта прослеживаемости, синхронизация движков, зеркалирование, сборка выпуска |

[p06] Направление зависимостей фиксировано: поверхность вызывает оркестратор, оркестратор вызывает библиотеку через шов, библиотека возвращает типизированные значения. Доменные библиотеки никогда не спрашивают, никогда не форматируют вывод терминала и никогда не решают вопросы аутентификации; эти решения принимаются в корне композиции, в CLI или в [MCP-сервере](../glossary/index.xml#mcp-server).

> [p07] 17. Production architecture in the prototype phase
>
> <spec://org.vibevm.core/vibevm/common/PROP-000#prod-arch>

[p08] Дерево держат вместе четыре решения. Репозиторий — один Cargo-workspace, все крейты под `crates/`. Каждое умение продукта живёт в библиотеке, а командная строка, терминальный интерфейс и MCP-сервер — тонкие поверхности над ней. Схемы JSON Type Definition — единственный источник истины для каждого машинного контракта. А дисциплина коммитов — установленное [семейство](../glossary/index.xml#family) git-practices, которое читают в начале каждой сессии.

> [p09] **Decision:** Single Cargo workspace at repo root. Crates live under `crates/` per `VIBEVM-SPEC.md` §10.2:
>
> <spec://org.vibevm.core/vibevm/common/PROP-000#WORKSPACE-LAYOUT>

> [p10] **Decision:** a capability lives in a **library**; the CLI, the TUI and the MCP server are thin surfaces over it. The rule and its vocabulary are the installed `omnichannel` flow: `spec://org.vibevm.world/omnichannel/flows/omnichannel/OMNICHANNEL-PROTOCOL#root`. This section declares only vibevm's own floor, which is what that flow asks each project to state for itself.
>
> <spec://org.vibevm.core/vibevm/common/PROP-000#SURFACE-DISCIPLINE-IS-THE-OMNICHANNEL-FLOW>

> [p11] **Decision:** JSON Type Definition (RFC 8927) schemas are the single source of truth for every client/server and machine-to-machine contract in this project.
>
> <spec://org.vibevm.core/vibevm/common/PROP-000#JTD-SSOT>

> [p12] The repository's commit-and-push discipline is the **git-practices** family (a host dependency), whose members carry the full text:
>
> <spec://org.vibevm.core/vibevm/common/PROP-000#GIT-PRACTICES-FAMILY>

## Путь установки {#the-install-path}

[p13] 1. Найти корень рабочего пространства и прочитать [манифесты](../glossary/index.xml#manifest), лок-файл, пользовательскую конфигурацию, реестры, зеркала, переопределения и локальные источники пакетов.

[p14] 2. Сравнить манифесты с лок-файлом; если ничего не изменилось, пропустить разрешение.

[p15] 3. Иначе квалифицировать каждую запрошенную координату и построить представление доступных версий для решателя. Решить весь граф, удерживая каждый пин, которого изменение не касается.

[p16] 4. Скачать каждую выбранную идентичность: попадание в хранилище переиспользуется, промах обходит разрешённые источники и кладёт проверенное дерево в хранилище.

[p17] 5. Построить план, проверить [управляемые блоки](../glossary/index.xml#managed-block) файлов инструкций и спросить подтверждения.

[p18] 6. Материализовать граф в дерево зависимостей через диф, перегенерировать стартовые файлы, убрать устаревшие слоты.

[p19] 7. Записать граф, происхождение и отпечатки в лок-файл.

[p20] 8. Отрисовать человеческий, тихий или JSON-отчёт.

> [p21] **Decision.** `vibe install` is understood as two phases, optimised independently — the current code conflates them.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-workspace/PROP-011#TWO-PHASES-SPLIT>

## Швы {#the-seams}

[p22] `GitBackend` изолирует git: продуктивная реализация вызывает системный git, так что SSH-агенты и помощники учётных данных ведут себя как везде. `Registry` перечисляет, разрешает и скачивает по локальным и git-источникам; `MultiRegistryResolver` владеет упорядоченным обходом, зеркалами, переопределениями, аутентификацией и офлайн-позицией. `DepProvider` — представление мира для решателя, а `DepSolver` превращает корни в граф; ячейка по умолчанию — resolvo, а ячейка SAT с откатами и наивная ячейка выбираются по желанию. `InstallSource` отделяет транзакцию от построения ячеек. `RepoCreator` изолирует создание репозиториев на хостах для публикации. У каждого шва больше одной реализации, и тесты гоняют шов, а не продуктивную ячейку.

> [p23] **Decision.** Add a second `DepSolver` impl, `SatDepSolver`, alongside `NaiveDepSolver`. Both implement the same `crates/vibe-resolver/src/lib.rs::DepSolver` trait (`fn solve(&self, roots: &[PackageRef]) -> Result<ResolvedGraph, SolveError>`). `NaiveDepSolver` stays in tree as the "small graphs / no features / no disjunctions" fast path. **The default clause is superseded** ([PROP-017](PROP-017-resolvo-resolver.xml)): both impls shipped (`naive.rs`, `sat.rs`), but the production default became **resolvo**, not `sat`.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-resolver/PROP-003#SOLVER-TWO-IMPLS>

## Проводные и авторские форматы {#wire-and-authored}

[p24] Границу продукта пересекают два вида текста. Машинные форматы, JSON-отчёты, записи лок-файла, манифесты выпусков, описаны схемами JSON Typedef, и их типы генерируются; рукописный парсер нашего собственного формата — дефект, который считает сборка. Авторские форматы, манифест и спецификации, разбираются рукописным кодом намеренно, потому что их пишет человек, и ошибки должны говорить на языке человека.

> [p25] 16. JTD + codegen for wire contracts
>
> <spec://org.vibevm.core/vibevm/common/PROP-000#jtd>

> [p26] **4.1 The format registry.** `formats/REGISTRY.toml`
> inventories every surface a foreign parser reads: id, epoch, schema path,
> recoverable-or-not, independent-parser count, sunset date, golden-corpus path.
> From it the `FormatId` enum is generated, and all wire I/O goes through
> `wire::publish(FormatId, …)` / `wire::load(FormatId, …)` — an unregistered
> format is *inexpressible in the type system*, not merely discouraged. An
> unnumbered format is a format that will be broken without anyone noticing.
>
> <spec://org.vibevm.core/vibevm/common/PROP-044#M-FORMAT-REGISTRY>

[p27] В языке схем нет 64-битного целого, поэтому любое целое шире 32 бит едет по проводу десятичной строкой.

> [p28] **4.2b Integers wider than 32 bits ride the
> wire as decimal strings** *(owner ruling 2026-08-20, the B-091 fork answered
> once and generally)*. JTD (RFC 8927) has no 64-bit integer type at all — the
> pinned generator rejects `uint64` and `int64` as InvalidType (measured
> 2026-08-15) — so every field wider than 32 bits would otherwise re-litigate
> the same bad trilemma: a `uint32` that is false at and above 2³², a `float64`
> that loses precision past 2⁵³, or an untyped `{}` that loses the field
> entirely. The general answer: such a field is encoded as a **canonical decimal
> string** — ASCII digits only, no sign, no leading zeros except `"0"` itself —
> the schema says `string`, the Rust type stays the true integer, conversion
> lives at the serde boundary, and non-canonical input is refused loudly rather
> than coerced. Timestamps are not this rule's business: they ride as RFC 3339
> through the `timestamp` vocabulary. First application: the catalog manifest's
> file `size` (`formats/breaks/003.md`).
>
> <spec://org.vibevm.core/vibevm/common/PROP-044#M-WIDE-INTEGERS-AS-STRINGS>

## Что читать дальше {#reading-order}

[p29] Спецификации — авторитет: `PROP-000` об основополагающих решениях, `PROP-009` о модели загрузки, `PROP-002` и `PROP-010` о реестрах и хранилище, `PROP-054` о [жизненном цикле](../glossary/index.xml#lifecycle) и машине расширений, `PROP-045` о модели документа, `PROP-057` и `PROP-058` о пакетах документации, сайте и о том, как сопровождается это руководство. Страница о прослеживаемости в этом руководстве объясняет, как код их цитирует и как спросить карту, какой код стоит за каким правилом. Руководство разработчика в репозитории описывает сборку, тесты и панель самопроверки.

