# Манифест: vibe.toml {#root}

@status:doc/work @audience:user,author

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

## Один файл, три роли {#one-file}

[p02] У каждого узла, будь то проект-потребитель, публикуемый пакет или корень рабочего пространства, есть файл с именем `vibe.toml`. Присутствующие таблицы решают роль: `[project]` помечает потребителя, который никогда не публикуется, `[package]` — публикуемый пакет, `[workspace]` — координатора участников; первые две исключают друг друга, третья сочетается с любой из них или ни с одной.

> [p03] **Decision.** `vibe-package.toml` is **retired as a distinct filename**. Every node — project root, workspace member, published package — carries a single `vibe.toml`; the role is expressed by which sections are present. This is the cargo model: one `Cargo.toml` carries `[package]` and/or `[workspace]`.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-workspace/PROP-007#ONE-MANIFEST>

> [p04] `[package]` and `[project]` are **mutually exclusive** in one file — a node is either a publishable package or a plain project, not both. (Decision 7-α from the design session: keep the two sections distinct rather than folding `[project]` into a `[package]` with optional `kind`. Explicitness wins; `kind` stays strictly mandatory wherever `[package]` appears.)
>
> <spec://org.vibevm.core/vibevm/modules/vibe-workspace/PROP-007#PACKAGE-XOR-PROJECT>

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

> [p06] `deny_unknown_fields` everywhere — vibevm never silently drops unfamiliar manifest keys; we'd rather fail loud and add the section to the schema than corrupt provenance.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-resolver/PROP-003#DENY-UNKNOWN-FIELDS>

## [package] {#package-table}

[p07]
| Поле | Смысл |
| --- | --- |
| `name` | имя пакета, kebab-case, уникальное внутри группы |
| `group` | пространство имён издателя, перевёрнутый домен вроде `org.vibevm.world`; обязательно; `(group, name)` — идентичность |
| `kind` | один из восьми видов; метаданные, а не идентичность |
| `version` | семантическая версия этого пакета |
| `epoch`, `format` | эпоха манифеста пакета и форма его содержимого (`simple` по умолчанию, `normal` для раскладки из contract и source) |
| `authors`, `license`, `description`, `homepage`, `keywords` | карточка, которую показывает каждый реестр |
| `title`, `abstract` | человекочитаемое имя и сводка из четырёх вопросов, показываемые на полках документации; обязательны для пакетов `doc`, иначе необязательны |
| `authorship` | кто написал прозу пакета `doc`: `human`, `ai` или `mixed`; фильтр читателя, а не атрибуция коммитов |
| `describes` | Package URL исходной библиотеки, которую этот пакет документирует или оборачивает, для поиска по совпадению версий |
| `publish` | позиция участника рабочего пространства при публикации |

> [p08] **Decision.** `[package]` gains a **mandatory** `group` field:
>
> <spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-008#GROUP-MANDATORY>

> [p09] Grammar (owner ruling 2026-08-13 — «настоящие домены»): dot-separated segments, each an **LDH hostname label** — `[a-z0-9-]+`, ASCII lowercase, hyphen never at a label edge; `_` is forbidden (it is not legal in a domain). Interior doubled hyphens stay legal, as DNS itself allows (`xn--…` punycode). A group is therefore grammatically a valid reversed FQDN even though semantically it is a claim, not a credential (§2.10). Enforced by `Group::parse`. *Considered and rejected:* keeping `_` (groups would not even be formally domains, and the flat `<group>.<name>` carrier §2.5 would lose its unambiguous split); recording "FQDN-like, not FQDN-valid" as a deliberate looseness (the ruling chose real domain rules). *Revisit:* a real-world group needing `_` appears — it cannot, if groups track domains.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-008#GROUP-GRAMMAR>

> [p10] The package manifest gains card fields; for kind `doc` `title` and `abstract` are REQUIRED, for the other kinds optional, and `[media]` is optional for all:
>
> <spec://org.vibevm.core/vibevm/common/PROP-057#CARD-FIELDS>

> [p11] A `doc` package MAY declare `authorship` in `[package]`: `human`, `ai` or `mixed` — who wrote the prose the package carries. It is metadata of the document, kept for the reader who filters a shelf by it; it is never an attribution of the commits or of the repository, whose authorship law is `spec://org.vibevm.core/vibevm/common/PROP-000#commits`. Absent means unknown: the site shows no badge and a filter by authorship leaves the package out of both named groups.
>
> <spec://org.vibevm.core/vibevm/common/PROP-057#CARD-AUTHORSHIP>

[p12] `[project]` несёт те же описательные поля для потребителя, без строки версии и без вида.

## [requires] и его соседи {#requirements}

[p13]
| Таблица | Смысл |
| --- | --- |
| `[requires.packages]` | по ключу на требуемую координату; значение — строка ограничения или инлайновая таблица с `version`, источником `git` или `path`, `link` для типа включения в старт и метками видимости `access`, `friend` и `exclude` |
| `[visibility]` | `friends`, `unfriend`, `allow-friends` и `ignore-concept-warnings` для пакета в целом; см. [Видимость зависимостей](../model/dependency-visibility.xml) |
| `[override]` (таблица) | переписывает метки видимости на рёбрах, которыми вы не владеете, ключом `"a -> b"`, или `allow-friends` провайдера, ключом по его координате |
| `[requires] capabilities` | абстрактные умения, которые может удовлетворить любой провайдер, `namespace:name@constraint` |
| `[[requires_any]]` | дизъюнкция: ровно одно из `one_of` должно быть удовлетворено |
| `[provides] capabilities` | умения, которые предлагает этот пакет |
| `[obsoletes]`, `[conflicts]` | пакеты, которые этот вытесняет, и пакеты, которые не могут сосуществовать с ним |
| `[features]` | необязательные, аддитивные наборы содержимого со списком `default`; фичи могут зависеть от фич |
| `[compatibility]` | `min_vibe_version` и `requires_kinds` |

> [p14] `[requires.packages]` inline-table entries accept an optional `link` field (§2.4): `"static" | "dynamic"`, default `dynamic`. Valid on registry-, path-, and git-source dependencies.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-workspace/PROP-009#SCHEMA-LINK-FIELD>

> [p15] **Decision.** A package's `vibe-package.toml` gains a `[features]` table describing optional, conditionally-activated components:
>
> <spec://org.vibevm.core/vibevm/modules/vibe-resolver/PROP-003#FEATURES-TABLE>

> [p16] `[requires].packages = ["kind:name@<constraint>", …]` — concrete pkgref requirements.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-002#CAP-REQUIRES-PACKAGES>

> [p17] `[requires].capabilities = ["<namespace>:<name>[@<constraint>]", …]` — satisfied by any package that provides that capability.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-002#CAP-REQUIRES-CAPABILITIES>

> [p18] `[[requires_any]] one_of = [ pkgrefs… ]` — disjunction; exactly one must be satisfied. Repeatable table for multiple independent disjunctions.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-002#CAP-REQUIRES-ANY>

> [p19] `[provides].capabilities = ["<namespace>:<name>[@<semver>]", …]` — abstract capabilities the package advertises.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-002#CAP-PROVIDES>

> [p20] `[obsoletes].packages = [ pkgrefs… ]` — the package supersedes these; the solver flags them for removal on upgrade.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-002#CAP-OBSOLETES>

> [p21] `[conflicts].packages = [ pkgrefs… ]` — mutually exclusive installs.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-002#CAP-CONFLICTS>

[p22] [Фича](../glossary/index.xml#feature) добавляет содержимое и никогда ничего не убирает и не противоречит; `default` перечисляет фичи, активные, когда ничего не сказано, а `--no-default-features` их опускает. Когда два пакета требуют один пакет с разными фичами, резолвер материализует его один раз с объединением. В командной строке активацией управляют `vibe install <coordinate> --features a,b`, `--no-default-features` и `--all-features`.

> [p23] **Additive only.** Enabling a feature can introduce additional content; never remove or contradict existing content. (Cargo enforces this informally; vibevm enforces it via `vibe check` since spec content collisions are easier to detect than code-level ones.)
>
> <spec://org.vibevm.core/vibevm/modules/vibe-resolver/PROP-003#KEEP-ADDITIVE>

> [p24] **Default features.** `default = [...]` lists features active when no override is given. `--no-default-features` on the install / update CLI omits them.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-resolver/PROP-003#KEEP-DEFAULT>

> [p25] **Feature unification across the dep graph.** If `pkg-A` and `pkg-B` both depend on `pkg-C` and request different features, the solver unifies — `pkg-C` is built/materialised once with the union of requested features.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-resolver/PROP-003#KEEP-UNIFICATION>

> [p26] `vibe install <pkgref> [--features <a,b,c>] [--no-default-features] [--all-features]` — control feature activation (cargo-shape).
>
> <spec://org.vibevm.core/vibevm/modules/vibe-resolver/PROP-003#CLI-INSTALL-FEATURES>

## Откуда берутся пакеты {#sources}

[p27]
| Таблица | Смысл |
| --- | --- |
| `[[registry]]` | упорядоченный список источников пакетов: `name`, `url` (корень организации), `naming`, `auth`, необязательные `index_url` и `token_env` |
| `[[mirror]]` | альтернативный адрес для одного реестра или для любого, пробуется по `priority` и проверяется по отпечатку |
| `[[override]]` | замена источника для одной координаты, в обход реестров |
| `[boot]` | настройки загрузки для всего рабочего пространства; сегодня `link` по умолчанию |
| `[i18n]` | языки `preferred` и `fallback` в проекте; `canonical` и `available` в пакете |
| `[workspace] members` | пути участников рабочего пространства, глобы разрешены |

> [p28] **Decision.** `vibe.toml` carries an array of registries:
>
> <spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-002#REGISTRY-ARRAY>

> [p29] **Decision.** `[[mirror]]` entries are parallel alternative URLs for a specific registry (or `*` for any). During fetch:
>
> <spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-002#MIRROR-LAYER>

> [p30] **Decision.** Adopt a **sidecar file naming pattern** with **BCP-47 language tags** as suffixes, plus first-class language-preference declarations at three levels (CLI flag, project manifest, package manifest).
>
> <spec://org.vibevm.core/vibevm/modules/vibe-resolver/PROP-003#I18N-DECISION>

[p31] Локализованный файл лежит рядом с каноническим, с тегом языка перед расширением, `README.ru.md` рядом с `README.md`. Каждый пакет поставляет каноническую форму каждого файла, который перечисляет, а переводы только добавляют к ней, так что проект без перевода на предпочитаемый язык ставится без ошибки. `vibe install --language ru` задаёт предпочтение на один запуск.

> [p32] A localised file is the canonical filename with a `.<lang>` segment inserted before the extension. `<lang>` is a [BCP-47](https://datatracker.ietf.org/doc/html/rfc5646) language tag — `en`, `ru`, `ja`, `zh-Hans`, `pt-BR`. We also accept short ISO-639-1 codes alone (`ru`, `ja`) as a convenience; they map to the BCP-47 tag with no region.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-resolver/PROP-003#SIDECAR-PATTERN>

> [p33] Critical invariant: **every package must ship the canonical form of every file it lists in `[content].files_written`**. Translations are additive. This is what makes step 3 always reachable; it also lets a project install a package that has zero translation coverage for the user's preferred language without seeing errors.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-resolver/PROP-003#I18N-CANONICAL-INVARIANT>

> [p34] **CLI flag**: `vibe install flow:wal --language ru` overrides everything else for this invocation.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-resolver/PROP-003#PREF-CLI-FLAG>

## Что доставляет пакет {#deliveries}

[p35]
| Таблица | Смысл | Где законна |
| --- | --- | --- |
| `[boot_snippet]` | `source`, файл фрагмента внутри пакета, и `category` для его места в порядке старта; необязательные `when` и предлагаемый `link` | все виды, кроме `doc` |
| `[[skill]]` | `name`, `path`, `description`, необязательные целевые `agents`: [навык](../glossary/index.xml#skill), который агент может установить | все виды |
| `[[binary]]` | `name` и `crate`: инструмент, который vibe собирает при установке и запускает через `vibe bin exec` | виды с кодом; не `doc` |
| `[[mcp_server]]` | `name`, `binary`, `args`: сервер, регистрируемый у агентов | только `mcp` |
| `[hooks]` | базовые пути скриптов `pre-install` и `post-install` | пакеты |
| `[[extension]]` | `id`, `point`, `handler`, необязательные селектор и config: вклад в жизненный цикл | пакеты и проекты |
| `[[embedded_source]]` | неизменяемый внешний источник, на который пакет ссылается, не вендоря его | пакеты-мосты |

> [p36] `[boot_snippet]` (package-role) drops the `filename` field (the `NN-` target name) and gains `category` (§2.5); `source` — the path to the boot file inside the package — is retained. It may carry an optional suggested `link` default, and an optional **`when`** activation condition — the declaration site for §2.3's dynamic-entry `when`, closing the gap Phase 4 flagged. For v1 the only `when` is an operating-system match, the wire string `"os:<name>"` with `<name>` one of `windows` / `macos` / `linux`; a snippet carrying a `when` is `dynamic` (§2.4). The package author owns this declaration: whether a boot snippet is OS-specific is the author's knowledge, not the consumer's.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-workspace/PROP-009#SCHEMA-BOOT-SNIPPET>

> [p37] The MVP section is an array-of-tables, matching the manifest's existing
> `[[requires_any]]` / `[[registry]]` / `[[mirror]]` shape:
>
> <spec://org.vibevm.core/vibevm/common/PROP-018#SKILL-TABLE-SHAPE>

[p38] [Навык](../glossary/index.xml#skill) — секция манифеста, а не отдельный вид. `include` сужает, какие файлы из `path` проецируются в папку навыков агента, а его отсутствие проецирует всё дерево. Навык может взять своё тело из объявленного `[[embedded_source]]` и добавить ресурсы под папкой `references/`, с тем же отбором include и теми же проверками обхода.

> [p39] **Decision.** A package declares which of its files are **skills** for
>   agents in a dedicated manifest section — **not** by introducing a
>   package kind of its own. The kind register (`package_ref.rs`,
>   `VIBEVM-SPEC.md` §4.1) stays closed to skills.
>
> <spec://org.vibevm.core/vibevm/common/PROP-018#SKILL-SECTION-NOT-KIND>

> [p40] When present, only matching files are
>   projected into the agent's skill directory, preserving their relative
>   structure; when absent or empty, the whole `path` tree is projected — the
>   existing §2.6 behaviour, unchanged.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-mcp/PROP-015#INCLUDE-SELECTIVE>

> [p41] A reference-backed bridge MAY select its body from a declared external
> source, and any skill MAY add authenticated source resources below a dedicated
> subdirectory:
>
> <spec://org.vibevm.core/vibevm/common/PROP-018#SKILL-EXTERNAL-SHAPE>

> [p42] `source` and `embedded_source` name a manifest `[[embedded_source]]`.
> Absent `source` retains the package-root meaning. Resource targets are portable
> relative paths below `references/`; they cannot replace the local `SKILL.md`,
> scripts, or another resource. Include selection, case-fold collision checks and
> no-follow traversal apply before any agent directory is changed.
>
> <spec://org.vibevm.core/vibevm/common/PROP-018#SKILL-EXTERNAL-LAWS>

> [p43] A code-bearing package declares each shipped tool in its `vibe.toml`:
>
> <spec://org.vibevm.core/vibevm/modules/vibe-workspace/PROP-025#BINARY-TABLE>

> [p44] The
>   `[[mcp_server]]` table (§2.2) is **legal only in this kind** — the kind
>   IS the taxonomy, enforced by `Manifest::validate`, not advisory.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-mcp/PROP-027#TABLE-ONLY-IN-KIND>

> [p45] Hooks live in a package-role `[hooks]` table in `vibe.toml`:
>
> <spec://org.vibevm.core/vibevm/modules/vibe-workspace/PROP-020#HOOKS-TABLE>

> [p46] A **contribution** binds a handler to a point. It is declared as an `[[extension]]` table — in a **package** manifest (the package ships and offers the behaviour) or in the **project** manifest (the host adds its own). The shape is one grammar for every family:
>
> <spec://org.vibevm.core/vibevm/common/PROP-054#CONTRIB-GRAMMAR>

## Документация и её предметы {#documentation-tables}

[p47]
| Таблица | Смысл | Где законна |
| --- | --- | --- |
| `[[documents]]` | `package` и ограничение `version`: [предмет](../glossary/index.xml#subject), который описывает эта документация; обязательно, повторяемо | `doc` |
| `[documentation]` | `primary` (не больше одной координаты) и `official` (сколько угодно): документация, которую пакет называет своей | все виды |
| `[translates]` | `package` и `version` документации, которую зеркалит этот перевод | `doc` |
| `[navigation]` | `pinned`, пути документов, которые перечисляются первыми, и строки `[[navigation.section]]` с `id` и `title` для папок дерева страниц | `doc` |
| `[media]` | `icon`, `banner`, `preview`: исходные файлы изображений в пределах ограничений карточки | все виды |

> [p48] `[[documents]]` is REQUIRED in a `doc` package, may list several subjects, and its `version` is a semver constraint.
>
> <spec://org.vibevm.core/vibevm/common/PROP-057#REL-DOCUMENTS-REQUIRED>

> [p49] `[documentation]` in the subject names coordinates **without versions**; `primary` names at most one package, `official` any number.
>
> <spec://org.vibevm.core/vibevm/common/PROP-057#REL-DOCUMENTATION-UNVERSIONED>

> [p50] A translation of documentation is a separate package of kind `doc`:
>
> <spec://org.vibevm.core/vibevm/common/PROP-057#LOC-PACKAGE-PER-LANGUAGE>

> [p51] Images are source files in the package tree, in PNG, JPEG or WebP; SVG is forbidden in this wave because it can carry scripts and the local reader serves the images of proprietary packages as they are. `vibe check` and the publish gate verify existence, format signature, proportions and size — by signature and dimensions, never by file extension. The limits are small on purpose: packages of ordinary kinds are materialised and committed at consumers.
>
> <spec://org.vibevm.core/vibevm/common/PROP-057#CARD-MEDIA-SOURCE>

> [p52] A documentation package MAY declare `[navigation]`: `pinned`, the document paths the site and the local reader list first, in the order given; and `[[navigation.section]]`, one row per top-level folder of the page tree with the title the navigation shows for it. Pinning changes only where the named pages stand; every other page keeps the manifest's order. A pinned path that names no page is an error of `vibe check`.
>
> <spec://org.vibevm.core/vibevm/common/PROP-057#NAV-PINNED>

## Полный пример {#example-manifest}

[p53]
```text
# Written by `vibe doc build-site`: the level-0 view of one published version
# (PROP-057 `##LEVEL-ZERO`). It is a render input and never a package.

[package]
name = "vibevm-docs-ru"
group = "org.vibevm.core"
version = "1.0.0"
kind = "doc"
title = "Руководство VibeVM"
abstract = "Что покрывает: что такое VibeVM и как он даёт агенту-кодеру нужный текст для чтения; установку vibe; создание проекта; пакеты, реестры, лок-файл и машинный store; установку, обновление, публикацию и работу без сети; навык vibevm для агента и работу через него; жизненный цикл от проверки до выкладки; полный справочник команд, манифеста, лок-файла и настроек; написание пакетов всех видов, включая документацию и её адаптации.\nДля кого: для тех, кто запускает vibe в своих проектах, для тех, кто пишет пакеты, и для агентов, которые читают за них.\nЧто считает известным: как пользоваться терминалом и текстовым редактором, что такое агент-кодер и что делает менеджер пакетов для языка программирования.\nЧего не покрывает: сами нормативные спецификации (руководство их цитирует, а не пересказывает), внутреннее устройство отдельных агентов и историю проектирования vibe."
description = "Руководство VibeVM по-русски: установить vibe, понять пакеты и стартовую полосу, работать с агентом, писать и публиковать пакеты."
authorship = "ai"
authors = ["Oleg Chirukhin"]

[i18n]
canonical = "ru"

[[documents]]
package = "org.vibevm.core/vibevm"
version = "^1.0"

[translates]
package = "org.vibevm.core/vibevm-docs"
version = "^1.0"

[navigation]
pinned = ["start/what-vibevm-is", "start/index"]

[[navigation.section]]
id = "start"
title = "Старт"

[[navigation.section]]
id = "model"
title = "Модель"

[[navigation.section]]
id = "howto"
title = "Как сделать"

[[navigation.section]]
id = "agent"
title = "Агент"

[[navigation.section]]
id = "lifecycle"
title = "Жизненный цикл"

[[navigation.section]]
id = "authoring"
title = "Авторам"

[[navigation.section]]
id = "reference"
title = "Справочник"

[[navigation.section]]
id = "architecture"
title = "Архитектура"

[[navigation.section]]
id = "diagnostics"
title = "Диагностика"

[[navigation.section]]
id = "faq"
title = "Вопросы"

[[navigation.section]]
id = "glossary"
title = "Глоссарий"
```

[p54] Манифест этого перевода, сгенерированный из самого пакета, показывает пакет `doc` с карточкой, [предметом](../glossary/index.xml#subject) и таблицей `[translates]`, которая называет источник.

