# The manifest: vibe.toml {#root}

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

[p01] `vibe.toml` is the one file you write to describe a project or a package: its name, what it depends on, where packages come from, and what it delivers. This page lists every table and field with its meaning.

## One file, three roles {#one-file}

[p02] Every node, whether a consumer project, a publishable package or a workspace root, has a file named `vibe.toml`. The tables present decide the role: `[project]` marks a consumer that is never published, `[package]` a publishable package, `[workspace]` a coordinator of members; the first two exclude each other, the third composes with either or with neither.

> [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] Unknown keys are rejected, not ignored: a [manifest](../glossary/index.xml#manifest) written for a newer vibe than the one reading it fails to parse with the offending key named.

> [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]
| Field | Meaning |
| --- | --- |
| `name` | the package name, kebab-case, unique within its group |
| `group` | the publisher's namespace, a reversed domain such as `org.vibevm.world`; mandatory; `(group, name)` is the identity |
| `kind` | one of the eight kinds; metadata, not identity |
| `version` | semantic version of this package |
| `epoch`, `format` | the package's manifest epoch and its content form (`simple` by default, `normal` for the contract-and-source layout) |
| `authors`, `license`, `description`, `homepage`, `keywords` | the card every registry shows |
| `title`, `abstract` | the human-readable name and the four-question summary shown on documentation shelves; required for `doc` packages, optional otherwise |
| `authorship` | who wrote the prose of a `doc` package: `human`, `ai` or `mixed`; a reader's filter, not the commits' attribution |
| `describes` | the Package URL of an upstream library this package documents or wraps, for version-matched discovery |
| `publish` | the publishing posture of a workspace member |

> [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]` carries the same descriptive fields for a consumer, without a version line or a kind.

## [requires] and its neighbours {#requirements}

[p13]
| Table | Meaning |
| --- | --- |
| `[requires.packages]` | one key per required coordinate, the value a constraint string or an inline table with `version`, a `git` or `path` source, `link` for the boot inclusion type, and the visibility marks `access`, `friend` and `exclude` |
| `[visibility]` | `friends`, `unfriend`, `allow-friends` and `ignore-concept-warnings` for the package as a whole; see [Dependency visibility](../model/dependency-visibility.xml) |
| `[override]` (table) | rewrites the visibility marks of edges you do not own, keyed `"a -> b"`, or a provider's `allow-friends`, keyed by its coordinate |
| `[requires] capabilities` | abstract abilities any provider may satisfy, `namespace:name@constraint` |
| `[[requires_any]]` | a disjunction: exactly one of `one_of` must be satisfied |
| `[provides] capabilities` | the abilities this package offers |
| `[obsoletes]`, `[conflicts]` | packages this one supersedes, and packages that cannot coexist with it |
| `[features]` | optional, additive content sets with a `default` list; features may depend on features |
| `[compatibility]` | `min_vibe_version` and `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] A [feature](../glossary/index.xml#feature) adds content and never removes or contradicts any; `default` lists the features active when nothing is said, and `--no-default-features` omits them. When two packages require one package with different features, the resolver materialises it once with the union. On the command line `vibe install <coordinate> --features a,b`, `--no-default-features` and `--all-features` control activation.

> [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>

## Where packages come from {#sources}

[p27]
| Table | Meaning |
| --- | --- |
| `[[registry]]` | an ordered list of package sources: `name`, `url` (the organisation root), `naming`, `auth`, optional `index_url` and `token_env` |
| `[[mirror]]` | an alternative address for one registry or for any, tried by `priority` and verified by fingerprint |
| `[[override]]` | a replacement source for one coordinate, short-circuiting the registries |
| `[boot]` | workspace-wide loading settings; today a default `link` |
| `[i18n]` | `preferred` and `fallback` languages in a project; `canonical` and `available` in a package |
| `[workspace] members` | the member paths of a workspace, globs allowed |

> [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] A localised file sits beside the canonical one with a language tag before the extension, `README.ru.md` next to `README.md`. Every package ships the canonical form of every file it lists, and translations only add to it, so a project with no translation in its preferred language installs without an error. `vibe install --language ru` sets the preference for one run.

> [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>

## What a package delivers {#deliveries}

[p35]
| Table | Meaning | Legal in |
| --- | --- | --- |
| `[boot_snippet]` | `source`, the snippet file inside the package, and `category` for its place in the boot order; optional `when` and a suggested `link` | every kind but `doc` |
| `[[skill]]` | `name`, `path`, `description`, optional target `agents`: a [skill](../glossary/index.xml#skill) an agent may install | every kind |
| `[[binary]]` | `name` and `crate`: a tool vibe builds on install and runs through `vibe bin exec` | code-bearing kinds; not `doc` |
| `[[mcp_server]]` | `name`, `binary`, `args`: a server registered into agents | `mcp` only |
| `[hooks]` | `pre-install` and `post-install` script base paths | packages |
| `[[extension]]` | `id`, `point`, `handler`, optional selector and config: a contribution to the lifecycle | packages and projects |
| `[[embedded_source]]` | an immutable external source a package refers to without vendoring it | bridge packages |

> [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] A [skill](../glossary/index.xml#skill) is a manifest section, never a kind of its own. `include` narrows which files of `path` are projected into an agent's skill folder, and its absence projects the whole tree. A skill may take its body from a declared `[[embedded_source]]` and add resources below a `references/` folder, under the same include selection and traversal checks.

> [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 and its subjects {#documentation-tables}

[p47]
| Table | Meaning | Legal in |
| --- | --- | --- |
| `[[documents]]` | `package` and a `version` constraint: a [subject](../glossary/index.xml#subject) this documentation describes; required, repeatable | `doc` |
| `[documentation]` | `primary` (at most one coordinate) and `official` (any number): the documentation a package names as its own | every kind |
| `[translates]` | `package` and `version` of the documentation this translation mirrors | `doc` |
| `[navigation]` | `pinned`, the document paths listed first, and `[[navigation.section]]` rows with `id` and `title` for the folders of the page tree | `doc` |
| `[media]` | `icon`, `banner`, `preview`: source image files within the card limits | every kind |

> [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>

## A complete example {#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"
group = "org.vibevm.core"
version = "1.0.0"
kind = "doc"
title = "VibeVM Manual"
abstract = "What it covers: what VibeVM is and how it gives a coding agent the right text to read; installing vibe; creating a project; packages, registries, the lock file and the machine store; installing, updating, publishing and working offline; giving an agent the vibevm skill and asking it to do the work; the lifecycle from validate to deploy; a full command, manifest, lock-file and settings reference; writing packages of every kind, including documentation and its translations.\nFor whom: people who run vibe in their projects, people who write packages, and the agents that read on their behalf.\nWhat it assumes known: how to use a terminal and a text editor, what a coding agent is, and what a package manager does for a programming language.\nWhat it leaves out: the normative specifications themselves (this manual quotes them, never restates them), the internals of any one agent product, and the design history of vibe."
description = "The VibeVM manual: install vibe, understand packages and the boot lane, work with an agent, author and publish packages."
authorship = "ai"
authors = ["Oleg Chirukhin"]

[i18n]
canonical = "en"

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

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

[[navigation.section]]
id = "start"
title = "Start"

[[navigation.section]]
id = "model"
title = "Model"

[[navigation.section]]
id = "howto"
title = "How to"

[[navigation.section]]
id = "agent"
title = "Agent"

[[navigation.section]]
id = "lifecycle"
title = "Lifecycle"

[[navigation.section]]
id = "authoring"
title = "Authoring"

[[navigation.section]]
id = "reference"
title = "Reference"

[[navigation.section]]
id = "architecture"
title = "Architecture"

[[navigation.section]]
id = "diagnostics"
title = "Diagnostics"

[[navigation.section]]
id = "faq"
title = "Questions"

[[navigation.section]]
id = "glossary"
title = "Glossary"
```

[p54] The manifest of this manual, generated from the package itself, shows a `doc` package with a card, a [subject](../glossary/index.xml#subject) and a [skill](../glossary/index.xml#skill).

