VibeVM
Contents
On this page
ru
Publisher
org.vibevm.core
Version
1.0.0latest
Adapts
org.vibevm.core/vibevm-docs
Audiences
user
Reading time
7 min
Rendered
Read aloud
never

Реестры и индекс

01Пакеты публикуются в место, которое vibe умеет читать: по умолчанию это публичная организация на GitHub, по репозиторию на пакет. Проект перечисляет такие места в том порядке, в каком им доверяет. Каталог рядом с каждым из них отвечает на поиск, ничего не клонируя.

02

Что такое реестр

03Реестр — не сервер, который запускает vibe. Это хостинг-организация вроде https://github.com/vibespecs, где каждый пакет — собственный git-репозиторий, названный по координате пакета. Опубликовать — значит запушить репозиторий и поставить тег версии; установить — значит клонировать по тегу. Кому можно публиковать, решают права самого хостинга, так что у vibe нет собственных аккаунтов.

04 Each package is its own git repository — no monorepo. Per-package maintainer permissions are hosting-native (a package repo's owner controls access); no central merge queue.

05Проект объявляет свои реестры в манифесте упорядоченным списком. У каждой записи есть локальное имя, корневой адрес организации и соглашение об именовании, которое превращает координату в имя репозитория. Когда просят пакет, vibe идёт по списку по порядку, и первый реестр, где есть подходящая версия, выигрывает.

06 Resolution: the solver iterates registries in array order; the first that has a satisfying match for a pkgref wins. Versions of the same pkgref are not unioned across registries — this prevents a lower-trust registry from influencing resolve when a higher-trust one already has a valid answer.

07Список — массив в порядке приоритета; рядом с ним зеркало — второй адрес того же реестра, а переопределение обходит обход списка для одной координаты. url записи — корень организации, никогда не репозиторий пакета, и это обычный git-адрес: https://, ssh://, git@host: или file://, без сокращений под какой-либо хост. Его naming говорит, как координата становится именем репозитория; умолчание соединяет группу и имя точкой.

08 [[registry]] is an array, priority-ordered. [[mirror]] is a first-class fallback layer, transparent to the lockfile. [[override]] bypasses the resolver for pins. Schema and code path support all three from day one.
09 urlorganization root URL, not a package repo URL. A registry is a hosting-org; packages are children of it.
10 URL syntax is just git URLgit@host:…, ssh://, https://, file://. No github: / gitverse: shorthands. New hosts "just work" as long as git speaks to them.
11 naming — convention for mapping a pkgref to a package repo name under this org. Values: "fqdn" (defaultorg.vibevm.world/wal<org>/org.vibevm.world.wal; introduced and made the default by PROP-008 §2.5, shipped M1.19 as a _-joined form and re-ruled to the dot join 2026-08-13), "kind-name" (legacy — flow:wal<org>/flow-wal; the default this section originally declared, superseded by PROP-008), "name" (if name collisions are impossible in a given registry), "kind/name" (for hosts supporting nested repos). Other registries may ship with different conventions; the setting is per-registry, not global.

12К следующему реестру обход переходит, только когда один ответил, что пакета у него нет. Сбой соединения, ошибка сервера или испорченный манифест останавливают установку с этой ошибкой, потому что о простое или опечатке вы хотите знать. В реестре, объявленном публичным, требование учётных данных считается за «здесь нет», и обход продолжается; в реестре, который объявил режим аутентификации, это настоящий сбой.

13 A [[registry]] is a distinct package source — its own naming convention, its own publishing identity, its own trust scope. The priority-ordered registry walk falls through on UnknownPackage only: a registry that confidently answers "I don't have this package" is free to defer to the next one. Any other primary failure — connect-failure (DNS / TCP), auth-failure on a registry that explicitly requires authentication, server error, malformed manifest — halts the install with an actionable error. This is the same policy Cargo and npm apply to a registry that errors out: the operator wants to know about a typo or an outage, not paper over it with a different registry that may carry a different version.
14 auth-aware 401 classification (§2.2.1). On auth = "none" a 401 / 403 response is an UnknownPackage signal, not an auth-failure: the registry is declared public, anything that responds with "you cannot read this without credentials" is — from this consumer's standpoint — equivalent to "this package does not have a public answer here." The walk falls through to the next registry, exactly like a 404. This is what unblocks the common case where one host (GitVerse) returns 401 for a missing repo while another (GitHub) returns 404 — the resolver treats both uniformly. On auth = "token-env" or "credential-helper" a 401 is a real AuthFailed and halts: the registry was declared as authenticated, the credentials presented were rejected, this is information the operator must see.

15Запись можно выключить, не удаляя: enabled = false заставляет каждую команду пропускать этот реестр, пока вы не включите его обратно.

16 Decision. Every [[registry]] carries an enabled flag, default true. Setting enabled = false switches a registry off without deleting its entry — it is skipped by every resolution path (install / outdated / search / registry sync / vendor), because the filter lives at the one resolver-construction point (MultiRegistryResolver::from_manifest): a disabled registry is never built, so nothing downstream can consult it. Re-enable by flipping the flag back; no re-add. The default true is skipped on serialize, so only an explicit enabled = false appears in a written vibe.toml. The flag applies uniformly to a project vibe.toml and the machine-global ~/.vibe/registry.toml.

17Машина может добавить собственные реестры в ~/.vibe/registry.toml; они подмешиваются после проектных, и список проекта всегда сильнее машинного. Так компания нацеливает каждый проект на ноутбуке на свой приватный реестр, не правя каждый проект. Файл несёт те же секции [[registry]], [[mirror]] и [[override]], что и манифест проекта, для любого реестра, удалённого или локального; имя, объявленное в обоих местах, принадлежит проекту.

18 Project-level [[registry]] always overrides the user-level default — the same precedence the UserConfig [env] layer already follows (the project / live value wins).
19 Decision. Registry settings may also live in a per-user file resolved through the settings chokepoint (vibe_core::settings::registry_config_path~/.vibe/registry.toml, or $VIBE_SETTINGS/registry.toml). It carries the same [[registry]] / [[mirror]] / [[override]] sections as a project vibe.tomlany registry, not only local ones: a remote https:// / ssh:// / git@ org (with auth) is merged and searched exactly like a file:// / path repo. A common motivation is keeping machine-local registries (a file:// checkout, a path repo) out of a team-shared vibe.toml, where a hard-coded local path would differ per teammate; but a whole extra remote registry can be added machine-wide the same way. (Locality matters only to --offline, §2.2.2.1.)
20 Merge — project first, dedupe by name. The effective registry list is the project's [[registry]] entries followed by the global file's, with a name collision resolved in the project's favour (the project entry wins; the global one is dropped). Mirrors are concatenated (project first). Overrides are project-first, deduped by pkgref (project wins). The merge is a pure function (vibe_core::merge_effective), verified in isolation. A project's explicit declaration always outranks a machine default, so a shared vibe.toml stays authoritative for the team while each machine supplements it with its own local repositories.

21Набор доверия по умолчанию, который называет спецификация, — ровно два корня: https://github.com/vibespecs и https://gitverse.ru/vibespecs. Проект, который сегодня создаёт vibe init, не несёт блока реестров вовсе, так что перед первой установкой добавьте его через vibe registry add или дайте машинному файлу его подставить. Любому другому реестру доверяют только потому, что вы его добавили.

22 The default trust set is exactly two rootshttps://github.com/vibespecs and https://gitverse.ru/vibespecs — trusted by default as the registries vibe init writes. Every other registry is trusted only by the user's own act of adding it to their configuration (owner ruling, 2026-08-13).
23 Default in new projects. vibe init writes the default registry URL (DEFAULT_REGISTRY_URL in vibe_core::manifest) into every new vibe.toml's [[registry]] entry unless the operator passes --no-registry or overrides with --registry-url <URL> / --registry-ref <REF>.

Индекс

24Клонировать репозиторий, чтобы узнать, что в нём, — медленно, а перечислить организацию для поиска без аккаунта невозможно. Поэтому реестр может держать индекс: отдельный репозиторий рядом с пакетами, где для каждой опубликованной версии записаны сводка манифеста и отпечаток содержимого. vibe search читает индекс; свежая установка читает его, чтобы пропустить круг клонов.

25 Decision. The index layer is strictly additive. Every existing vibevm code path keeps working exactly as today when no index is present. No registry is required to have an index. No project is required to consume one; a consumer that finds none falls back to the live git ls-remote path that exists today.

26Индекс — кэш, никогда не истина. Если он расходится с репозиторием пакета, побеждает репозиторий, а пакет, разрешённый через индекс, всё равно сверяется с отпечатком содержимого, когда приходит. Реестр без индекса работает ровно как раньше, только медленнее; отсутствие индекса — не ошибка.

27 Decision. Package repositories are the source of truth for content (manifests, files, tags). The index is a derived hot cache, regeneratable from the authoritative package state.
28 This matters because it disambiguates the failure mode: if the index disagrees with reality, reality wins.

29Адрес индекса выводится из адреса реестра, и его можно переопределить для каждого реестра переменной окружения, названной по имени реестра, VIBEVM_INDEX_URL_<NAME>; буквальное значение none выключает обращения к индексу для этого реестра.

30 The environment variable VIBEVM_INDEX_URL_<REGISTRY> is the ladder's top rung — the operator's per-run re-point, no longer the only source. Until 2026-08-20 it was the sole locator, deliberately weaker than the manifest field it stood in for (per-shell, per-run, travelling with neither project nor lockfile) — which is why it never closed the requirement above. Now it overrides the key: env beats index_url beats the default, and none at either explicit rung disables the index. The name normalization (ASCII alphanumerics upper-cased, the rest to _``) is unchanged.

31Запись реестра может закрепить свой индекс через index_url; без него публичная организация на GitHub отображается в свой репозиторий index на хосте сырого содержимого, а любой другой хост — в <registry-url>/index. У пробы индекса три исхода: найден, отсутствует, отказано. Только «отсутствует» тихо проваливается к живому перечислению, потому что индекса никто не обещал; индекс, который есть, но не читается, — это сообщение об ошибке. vibe search задаёт вопрос каждому настроенному индексу напрямую, а не скачивает весь каталог.

32 Configurable but defaulted. A [[registry]] block pins a custom index location — the key exists in RegistrySection (one type serving both the project vibe.toml and the machine-global ~/.vibe/registry.toml, so the columns share one vocabulary), and this exact block parses (pinned by test prop005_index_url_example_parses, which carries it verbatim):
33 The bottom rung is host-aware. Canonical public https://github.com/<org> maps to https://raw.githubusercontent.com/<org>/index/<registry-ref>; other hosts retain <registry-url>/index. This makes both fresh and already- seeded GitHub configurations whose index_url field is absent consume the static repository rather than its HTML page. The full ladder remains env override → manifest key → host-aware default; exact none on either explicit rung disables lookup. Lookalike hosts, nested paths, userinfo, unsafe owners/refs, queries and fragments are never rewritten.
34 A probe answers found, absent, or refused, and the third is what keeps this section honest. «Absent» is the only outcome that falls through quietly, because it is the one that means what the fall-through assumes: nothing is published here. An index that IS there and cannot serve this consumer — it refused us (401/403), its body does not parse as a handshake, its handshake format is one this build does not read, or it publishes no world of this build's epoch — answers refused, carrying the offered epochs, this build's epoch, a recipe, and whatever the document said in min_client / notice / successor. Collapsing that into «absent» would make a private, broken or newer-than-us index indistinguishable from a missing one, which is the silence PROP-044 §2 forbids: a break that announces itself is normal life, a riddle is what strands users.
35 404 / connect-failure on the index → silent fallback to live ls-remote: no error message, because the operator never promised an index. This half is built, and it is the absent outcome of ##A-PROBE-HAS-THREE-OUTCOMES-NOT-TWO — the other two outcomes are never silent.
36 Walks every configured registry's index through the same client the resolver uses — probe, then query — rather than downloading primary.jsonl.gz and scanning it locally. The whole-file scan was the shape this document first imagined and is not what shipped: asking the index a question keeps the bandwidth proportional to the answer instead of to the catalog, and it puts one discovery ladder (§2.1) under every consumer instead of two. Index is the enabling layer for M2.10; vibe search is the headline consumer of this PROP.

Зеркала, переопределения и git-источники

37Зеркало — другой адрес того же реестра, к которому обращаются первым ради доступности и который сверяют по тем же отпечаткам; зеркало, отдающее под известной версией другие байты, отвергается, а не получает доверие. Зеркала никогда не попадают в лок-файл: записывается канонический адрес, так что смена зеркала ничего не меняет для ваших коллег.

38 Mirror integrity verification is mandatory, not optional. A mirror whose content_hash for (kind, name, version) differs from the lockfile pin fails the install with an actionable error. This closes the supply-chain hole where a hijacked mirror could substitute content.

39Переопределение заменяет один пакет копией из другого места — ради хотфикса или патча, который ждёт своей очереди наверху; оно обходит обход реестров для этой одной координаты и помечено в лок-файле, чтобы никто не принял его за опубликованную версию.

40 Decision. [[override]] bypasses the registry layer for a named pkgref:

41Переопределение ничего не ослабляет: отпечаток копии по-прежнему закреплён в лок-файле и сверяется при каждой установке, а запись несёт overridden = true.

42 The resolver short-circuits: it does not consult [[registry]] for this pkgref at all; it fetches directly from the given URL at the given ref. Content hash is still pinned in the lockfile and verified on each install — an override does not relax integrity. The lockfile records overridden = true on that entry. A vibe list --overrides flag is specified here and not shipped — the lockfile field is the only surface today.

43Зависимость может указывать и прямо на git-репозиторий — на тег, коммит или ветку. Тег и коммит закреплены; ветка при обновлении проходится заново, а лок-файл записывает коммит, который был установлен на самом деле.

44 Mutable branch. Lockfile records the resolved commit at install time; subsequent vibe update re-walks branch HEAD. Mutable — see "Mutability and vibe update" below.
45 Decision. A dependency may be declared as a first-class git-source in [requires.packages] — fetching the package from an arbitrary git repository instead of resolving it through [[registry]]. This is the vibevm analogue of Cargo's [dependencies] foo = { git = "..." }, npm's "foo": "git+https://...", Poetry's foo = { git = "..." }, Bundler's gem 'foo', git: '...', Go modules' baseline behaviour. The use cases are:

46Git-источник записывается инлайновой таблицей на требовании: адрес git и ровно одно из tag, rev или branch; ни одного или два — отказ, потому что угадывать ветку по умолчанию недопустимо там, где решается, какой код входит в ваш проект. auth источника объявляется на самом источнике и никогда не заимствуется у реестра на том же хосте. Когда репозиторий приходит, vibe читает собственный манифест пакета и отвергает тот, чьи вид и имя расходятся с тем, что вы потребовали.

47 Wire form. [requires.packages] becomes a TOML table whose values are either a version-constraint string (registry-resolved, the M1.13 shape) or an inline-table (registry-resolved with options, or git-source). The legacy array-of-strings shape (packages = ["flow:wal@^0.3"]) parses transparently into table-form on read; on round-trip the manifest writes table-form.
48 Exactly one of tag / rev / branch must be present in a git-source declaration. Zero is rejected at parse time with MissingRef. Two or more rejected with ConflictingRefs. There is no "default branch HEAD" fall-back — too magical for a security-sensitive surface; explicit > implicit.
49 Auth. Per-source auth is explicit, not host-derived. The resolver does not look at [[registry]] auth for the same host and apply it transitively to a git-source pointing at that host — too magical, creates implicit ordering dependencies between sections of the manifest. If a project has multiple packages from the same private host, the operator can either:
50 The pkgref <kind>:<name> is read from the package's vibe-package.toml [package] section on the resolved git ref (same path as registry-resolved manifest fetch via git archive). The resolver verifies that the (kind, name) declared in [requires.packages] matches what the repo actually carries; mismatch = PackageIdentityMismatch. This means a malicious git-source cannot impersonate flow:wal if its vibe-package.toml declares it as feat:auth.

51Источник требования выбирается в фиксированном порядке: сначала переопределение, затем git-источник, объявленный на требовании, затем обход реестров. За веткой идёт только vibe update; vibe install держит коммит, который записал лок.

52 Resolution order. When the resolver looks up a pkgref, the source is decided in this order:
53 Mutability and vibe update. Tags and revs are immutable by definition; force-push is detected via content-hash. Branches are explicitly mutable: vibe install against a branch resolves to the current branch HEAD and pins that commit in the lockfile. vibe update re-walks each branch-declared git-source, and if HEAD has moved, re-resolves and re-locks. vibe install (no flag) does not chase a branch's HEAD on subsequent runs — the lockfile's resolved_commit is authoritative until update is called. This matches Cargo's behaviour (cargo build does not bump branch deps; cargo update does).

Аутентификация

54Публичному реестру учётные данные не нужны, и vibe их не посылает: он глушит помощники учётных данных git, чтобы установка в скрипте никогда не зависла на запросе пароля. Приватный реестр объявляет свой режим в манифесте: токен из переменной окружения, системный помощник учётных данных или SSH-ключи. Токен приходит из вашего окружения и никогда не попадает в файл, который пишет vibe.

55 Token never lands on disk via vibevm. The token comes from the operator's environment. Vibe reads it, builds the credentialed URL in memory, hands it to the spawned git process, and discards. The lockfile's source_url field always carries the canonical URL (no embedded credentials) — symmetric with the [[mirror]] invariant in §2.3. Token discipline (PROP-000 §20) applies: the value is treated as surface-secret; it does not appear in any vibevm-emitted output. Modern git (≥2.31) auto-redacts passwords from its own stderr, so even on errors the token is not echoed.

Пакеты на этой машине

56vibe, собранный из чекаута исходников, считает пакеты из дерева этого чекаута встроенным реестром: у такой сборки он включён по умолчанию, у распространяемой выключен, а на одну команду выключается через --no-default-registry. Перечисление версий всё равно объединяет встроенный и объявленные реестры, так что более новая опубликованная версия видна; переопределение или git-источник на требовании остаются выше встроенного реестра. --embedded-short-circuit останавливает перечисление на встроенном реестре для пакетов, которые он отдаёт, так что полностью встроенный граф разрешается вообще без сети.

57 Its default follows the install origin: on for origin = "external", off for a distribution.
58 --no-default-registry (env VIBE_NO_DEFAULT_REGISTRY=1) suppresses the embedded registry entirely for a command.
59 But version enumeration (the candidate set the solver picks from) unions across embedded and declared by default, so the solver can see a newer published version even for a package the embedded registry already carries.
60 Resolution keeps PROP-002's explicit-source short-circuits above the embedded registry — an explicit per-dependency source or pin is always deliberate and always wins:
61 --embedded-short-circuit — keep the declared walk available, but short-circuit version enumeration at the embedded registry for any coordinate it serves: the network is reached only for packages the embedded registry lacks. A fully-embedded dependency graph resolves with zero network access (no enumeration round-trip, no credential prompt), while a genuinely missing package is still fetched from the network. Implies embedded-first precedence; mutually exclusive with --no-prefer-embedded.

62Пакет, разрешённый таким путём, записывается с source_kind = "embedded", и vibe check предупреждает, что такой лок непереносим. В --frozen и других неинтерактивных запусках встроенный реестр выключен, так что лок, который работает только на машине одного разработчика, не пройдёт на сборочном сервере.

63 A package resolved from the embedded registry records source_kind = "embedded" in vibe.lock (a PROP-002 SourceKind variant beside registry / git / override / path). Its source_url is the file:// path into <source_path>/packages.
64 Warn. vibe check warns (does not fail) when the lock carries any source_kind = "embedded" entry: "this lockfile depends on the embedded registry of a source install and is not portable; publish or vendor these packages before sharing the lock." A source_kind = "local" entry is portable and does NOT warn.
65 CI-off. In --frozen (and any non-interactive CI resolution), the vibe-embedded registry is disabled by default — CI must resolve from declared registries (and, since §3.3, project-local), so a machine-local lock cannot silently pass there. Project-local is NOT suppressed by this gate — it is per-project and portable.

66Проект, у которого рядом с манифестом лежит папка packages/, получает эту папку открытой как локальный реестр вообще без объявления. Пакеты, разрешённые из неё, записываются с source_kind = "local", и это переносимо, потому что каждый чекаут разрешает ту же папку в то же содержимое. --no-prefer-local обходит папку на одну команду.

67 REQ. A project carrying <project_root>/packages/ (where project_root is the directory holding the project's vibe.toml, resolved by resolve_project_root) gets that directory auto-opened as a LocalRegistry and composed into the local-registry family alongside the vibe-embedded registry. No [[registry]] block, no --registry <path>, no ~/.vibe/registry.toml machine entry needed.
68 REQ. A package resolved from project-local records source_kind = "local" in vibe.lock (§4) — distinct from embedded. Unlike embedded, it is portable and the reproducibility guard (§5) does NOT warn on it: every checkout of the project resolves the same packages/ to the same content.
69 REQ. --no-prefer-local suppresses project-packages discovery for one command (use when a project's packages/ is stale, broken, or deliberately bypassed). It does NOT suppress vibe-embedded — --no-default-registry remains the knob for that. --prefer-local is the explicit affirmation of the default (project-local wins the local family); mutually exclusive with --no-prefer-local.

Особые случаи и правила

70vibe, собранный из чекаута исходников, считает пакеты из дерева этого чекаута окружающим реестром, к которому обращается первым: разработчик vibe ставит разрабатываемые пакеты, не публикуя их. У распространяемого vibe такого реестра нет.

71 This PROP makes the in-tree packages/ of a source-installed vibe an ambient default registry — resolved automatically, with zero configuration in the consuming project.

72Репозиторий с исходниками самого vibe зеркалится на двух хостах, но это другое дело, чем реестр пакетов: зеркала несут исходники программы, реестр несёт пакеты, и учётные данные для них никогда не делятся.

73 This PROP governs the source repository; it is orthogonal to the package registry, and the two must not be conflated.

74С реестрами vibe работает через программу git в вашем PATH и проверяет её наличие до начала; VIBE_GIT_BINARY указывает ему на другую копию. Клон реестра старше часа обновляется перед установкой, моложе — берётся как есть, а vibe registry sync обновляет независимо от возраста.

75 Runtime dependency on git in PATH. Acceptable: our target audience is developers who already have git installed. We perform a preflight git --version check and emit an actionable error (with a pointer to https://git-scm.com/downloads) if it is missing.
76 Resolved — shipped as proposed. The VIBE_GIT_BINARY PATH override lives in git_backend/shell.rs and its comment cites §6 of this PROP; the env-var form was chosen over a CLI flag exactly to keep the CLI surface stable.
77 Decision: the default freshness TTL is 1 hour, checked against meta.toml.last_pulled_at. An install whose registry cache is older than the TTL triggers an implicit update. An install whose cache is younger skips the pull. vibe registry sync forces an update regardless of age.

78Файл, который нужен резолверу, манифест или заглушка перенаправления, читается прямо с хоста по HTTPS, когда хост — GitHub или GitVerse, с учётными данными в заголовке и никогда в адресе; промах решает вопрос только для тега или коммита, чьё содержимое неизменно, а на ветке следующим спрашивают git. Хост, которого нет в таблице, на этот путь не попадает никогда.

79 Before a single file is asked of git, the backend reads it over HTTPS from the host's own raw endpoint when the host is one it knows — github.com through raw.githubusercontent.com, gitverse.ru through its contents API — with any credential sent only as a bearer header, never in the address. A hit is the file. A miss is authoritative only for a tag or a commit SHA, whose content is fixed; on a branch, or for a manifest, the read falls through to git, whose answer stands as it always did. A host the table does not name never enters this path.

80Чтение, которое хост отверг на минуту, из-за лимита частоты или ошибки сервера, повторяется несколько раз с короткой паузой, прежде чем читатель откатится к git; обычное «не найдено» не повторяется никогда.

81 A raw read that the host refuses with 429 or a 5xx is retried a small, bounded number of times with a short pause, honouring Retry-After within that bound, before the read falls through to git as any other unexpected answer does. A 404 is never retried: on a tag or a commit it is authoritative, and on a branch it is what git will be asked about next.

For an agent

This page has a machine mirror. The citation carries the version rather than latest, so what an agent quotes does not move under it.

spec://org.vibevm.core/vibevm-docs@1.0.0/model/registries

.md.xmlllms.txt