# Использовать приватный реестр {#root}

@status:doc/work @audience:user

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

[p02]
```prompt
Добавь приватный реестр с именем acme по адресу git@github.com:acme-specs первым реестром проекта VibeVM в текущей папке, с аутентификацией по SSH, оставь публичный реестр vibespecs запасным и проверь, что оба доступны.
```

- needs: навык vibevm, установленный у вашего агента; SSH-ключ, который принимает приватный хост, загруженный у агента; проект с `vibe.toml`

outcome: `vibe registry list` показывает `acme` первым и `vibespecs` вторым; `vibe registry test` сообщает, что оба доступны

- assert: `vibe registry list --quiet`
- assert: `vibe registry test`

## Что происходит {#what-happens}

[p03] Агент выполняет `vibe registry add acme git@github.com:acme-specs --auth ssh --position primary`: команда записывает новый блок [реестра](../glossary/index.xml#registry) в начало списка в [манифесте](../glossary/index.xml#manifest). С этого момента каждое разрешение спрашивает сначала `acme`, потом публичный реестр, а пакет, который есть в обоих, приходит из `acme`. `vibe registry test` проверяет каждый реестр на доступность и аутентификацию, ничего не скачивая.

> [p04] 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.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-002#REGISTRY-WALK-ORDER>

## Руками {#by-hand}

[p05] 1. Добавьте реестр в проект. Адрес — корень организации, а не репозиторий пакета:

[p06] Example `registry-add` is copied from the source page at projection time.

[p07] 2. Выберите режим аутентификации флагом `--auth`. Значения: `none` для публичного чтения, `ssh` для ключей и `credential-helper` для системного помощника git. `token-env` читает токен из переменной окружения, названной по хосту.

> [p08] **Decision.** Each `[[registry]]` declares its authentication regime via an `auth` field. Four variants:
>
> <spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-002#AUTH-REGIMES>

[p09] 3. Проверьте командой `vibe registry test`: она сообщает по каждому реестру, ответила ли организация и какую аутентификацию приняла, ничего не скачивая.

## Для каждого проекта на машине {#machine-wide}

[p10] Положите тот же блок реестра в `~/.vibe/registry.toml`. Он подмешивается после собственного списка каждого проекта, так что проекты, которые называют свои реестры, ничего не замечают, а проекты без реестров наследуют машинные. Проект, который не называет ни одного реестра, а `vibe init` сегодня создаёт именно такие, пользуется списком машины; так корпоративное умолчание становится умолчанием каждого нового проекта.

> [p11] **Decision (corrected 2026-08-20 — the original text named the wrong file AND the wrong directory, and both were already settled in code).** A **user-level default registry configuration** lives in its own file, `~/.vibe/registry.toml`, beside — not inside — the general user settings at `~/.vibe/config.toml`. It supplies registry configuration when no project does, and seeds a new one:
>
> <spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-010#USER-LEVEL-REGISTRIES>

## Делегировать пакет другому реестру {#redirects}

[p12] Реестр может указывать на пакет, который живёт в другом месте. Вместо пакета репозиторий с его именем несёт один файл, `vibe-redirect.toml`, с таблицей `[redirect]`: `target_url` называет репозиторий, где пакет лежит на самом деле, а `ref_policy` говорит, какой тег там брать: тот же самый по умолчанию или один `pinned_ref` для всех версий. Потребитель, который ставит пакет, разницы не видит; резолвер идёт по указателю один раз, никогда по цепочке, и записывает адрес заглушки в [лок-файл](../glossary/index.xml#lock-file) полем `via_redirect`.

> [p13] **Decision.** A registry org may host a **stub repo** for a package — a normal `<org>/<kind>-<name>` repository whose content is **not** the package itself but a single file pointing at an external git repository where the package actually lives. The resolver, when fetching the package manifest, transparently follows the pointer; consumers `vibe install <pkgref>` see no difference from a direct registry-resolved package. The use case is **delegation**: an org owner wants the package to live in their namespace (so consumers find it via the org's `[[registry]]` walk without knowing about the external author) but offload the development, the PR queue, and the hosting platform's permission management to a different team or person who already has their own repo.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-002#REDIRECT-STUB>

> [p14] **Marker file.** A stub repo carries `vibe-redirect.toml` at its root **instead of** `vibe-package.toml`. Both files in the same repo at the same ref is rejected at parse as `AmbiguousStub`.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-002#REDIRECT-MARKER-FILE>

> [p15] **Hop limit: 1.** If `target_url`'s content-root is itself a stub (carries `vibe-redirect.toml`), reject with `RedirectChainNotAllowed`. There is no chain-following — stubs are flat indirection, not a redirect graph.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-002#RD-STEP-HOP-LIMIT>

[p16] Версии, которые видит потребитель, — это теги заглушки, а не цели: владелец реестра допускает каждую версию, помечая тегом заглушку. `vibe registry redirect` создаёт заглушку, `redirect-sync` после подтверждения копирует в неё теги цели, а `redirect-update` меняет указатель. Когда у заглушки меняется цель, потому что сопровождающий переехал на другой хост, потребитель принимает переезд флагом `--trust-redirect`; молча vibe за изменившейся целью не идёт.

> [p17] **Tag visibility.** `list_versions(stub_url)` returns the tags of the **stub** repo, not the target. The org owner controls which versions surface in their namespace by managing stub tags — which is exactly the gating mechanism a registry already has via `vibe registry publish`. Adding a new version to the namespace = `git tag v<ver> && git push origin v<ver>` against the stub repo (or `vibe registry redirect-sync <pkgref>` if it auto-mirrors target tags — see "Sync helper" below). The stub itself need contain no actual code — only `vibe-redirect.toml`, optionally a `README.md` for humans browsing the repo.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-002#REDIRECT-TAG-VISIBILITY>

> [p18] **Publish helper (`vibe registry redirect`).** A new CLI command:
>
> <spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-002#REDIRECT-CLI>

> [p19] **`--trust-redirect`** flag (parallel to `--trust-mirror` from §2.1) lets an operator accept a deliberate target switch — e.g. when the external maintainer migrates their hosting from GitLab to Forgejo. Never silent; always operator-initiated.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-002#RD-TRUST-FLAG>

> [p20] **Sync helper (`vibe registry redirect-sync`).** Org owner can run `vibe registry redirect-sync <pkgref>` to copy target-side tags into the stub repo (with operator confirmation per tag, or `--all` for batch). This is opt-in convenience tooling; the stub repo is just a normal git repo and tags can equally be managed by hand or CI.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-002#REDIRECT-SYNC-HELPER>

> [p21] **Lockfile shape.** A new `via_redirect` field per `[[package]]` records the stub URL when a redirect was followed. `null` (or absent) for non-redirected packages.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-002#REDIRECT-LOCKFILE-FIELD>

## Токены {#tokens}

[p22] Токен никогда не попадает в файл, который пишет vibe, и никогда не появляется в его выводе. С `--auth token-env` vibe читает его из `VIBEVM_REGISTRY_TOKEN_<HOST>` во время работы и отправляет только по шифрованному соединению. Держите переменную в профиле оболочки или в секретном [хранилище](../glossary/index.xml#store) вашего CI, а не в репозитории.

> [p23] **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.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-002#TOKEN-NEVER-ON-DISK>

## Особые случаи и правила {#edge-cases}

[p24] Приватный реестр без [индекса](../glossary/index.xml#index-registry) всё равно работает: поиск его пропускает, а установка клонирует, что нужно. Добавьте рядом с пакетами репозиторий индекса и укажите на него переменной `VIBEVM_INDEX_URL_ACME`, чтобы поиск и холодные установки стали быстрыми.

> [p25] **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.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-index/PROP-005#INDEX-OPTIONAL>

[p26] [Зеркало](../glossary/index.xml#mirror) — не второй реестр. Для альтернативного адреса тех же пакетов, проверяемых по тем же [отпечаткам](../glossary/index.xml#fingerprint), используйте `vibe registry set-mirror`; для другого источника пакетов — `registry add`.

> [p27] A `[[mirror]]` is an **availability copy of the same source** — same naming, same identity, same `content_hash`. The mirror walk falls through on **any availability failure** (`NetworkUnreachable`, `AuthFailed` on the mirror, server error, `content_hash` mismatch). `RepoNotFound` from a mirror bubbles up to the registry-walk layer (same policy as if the canonical primary had said `UnknownPackage`), because absence-of-package is a registry-level fact, not a mirror-level one.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-002#MIRROR-WALK-SEMANTICS>

[p28] В скрипте, который должен заметить, что приватный реестр лежит, передайте `vibe install` флаг `--auth-required`: тогда ошибка аутентификации останавливает установку, вместо того чтобы идти дальше к публичному запасному.

