# Версии и обновления {#root}

@status:doc/work @audience:user

[p01] Версия — это обещание о поведении, а не снимок файлов. Ваш проект просит диапазон, vibe записывает тот один номер, который выбрал, а обновление сдвигает этот номер намеренно. Сам vibe следует тому же правилу: один номер означает один контракт, сколько бы раз ни пересобирали бинарник за ним.

[p02] Example `outdated` is copied from the source page at projection time.

## Как попросить версию {#asking}

[p03] Версии пакетов следуют семантическому версионированию: три числа, первое из которых меняется, когда пакет ломает совместимость. В [манифесте](../glossary/index.xml#manifest) вы называете ограничение, а не версию: `^1.0` значит любая 1.x начиная с 1.0, `=1.2.0` — ровно эта, а голая [координата](../glossary/index.xml#coordinate) — новейший стабильный выпуск. Резолвер выбирает по одной версии на пакет так, чтобы удовлетворить каждое ограничение в графе, а [лок-файл](../glossary/index.xml#lock-file) записывает выбор.

> [p04] `flow:wal@^0.3` → semver range.
>
> <spec://org.vibevm.core/vibevm/common/PROP-000#CF-RANGE>

> [p05] `flow:wal` → latest stable.
>
> <spec://org.vibevm.core/vibevm/common/PROP-000#CF-LATEST>

[p06] [Семейство](../glossary/index.xml#family) пакетов, которые должны двигаться вместе, закрепляет своих членов точно, чтобы языковой гайд и сервер, отдающий его инструменты, всегда разрешались в один набор версий. Вы встретите такие пины в манифестах бандлов; они намеренные.

> [p07] The aggregator's exact pins are deliberate, not kind-mandated: a stack may pin
> its dependencies however it likes, but a family is a *tested version set*, so
> the aggregator holds its members equal.
>
> <spec://org.vibevm.core/vibevm/common/PROP-028#AGGREGATOR-PINS-DELIBERATE>

## Как сдвинуть пин {#moving}

[p08] `vibe outdated` читает лок-файл и [реестр](../glossary/index.xml#registry) и перечисляет пакеты, у которых есть версия новее; он ничего не меняет. `vibe update` подбирает версии заново и сдвигает пины, предпочитая оставить каждый пакет, который вы не назвали, на текущей версии, чтобы обновление одного пакета не тащило молча остальные.

> [p09] **`DepSolver` trait — minimal additions.** The trait gains one method:
>
> <spec://org.vibevm.core/vibevm/modules/vibe-resolver/PROP-003#TRAIT-PIN-PREFERENCES>

[p10] После обновления дерево зависимостей и стартовые файлы пересобираются, а диф лок-файла — это журнал того, что ваш агент теперь будет читать.

## Что обещает версия {#what-a-version-promises}

[p11] Номер версии — это контракт: версия 1 делает то, что версия 1 по документации должна делать. Внутри версии файлы за ней могут пересобирать, исправлять и переиздавать, и читатель документации этой кухни не видит. Так же vibe обходится и с собственными выпусками. Бинарник, который вы получаете через `vibe self install latest`, — это то, что ветка main держит сегодня, под одним номером версии. Руководство описывает контракт этого номера, а не файлы одной сборки.

> [p12] **A version is a behavioural contract, not a frozen set of files.** Inside a version the product changes as often as it likes — amend, rewritten history, `vibe self update --force` — and this is invisible by design. The only event by which the documentation computes «a difference between versions» is the owner's conscious bump of the version number: no checksums, no file hashes, no history.
>
> <spec://org.vibevm.core/vibevm/common/PROP-057#OBS-VERSION-CONTRACT>

[p13] Версия пакета по умолчанию — снимок в том смысле, какой у этого слова в Maven: её содержимое может меняться под тем же номером, и `vibe update` приносит свежее. Замороженная версия — исключение, которое объявляет издатель. До первого публичного выпуска ломающие изменения выходят без заметок о миграции; переключатель, который заканчивает этот режим, — только в руках владельца.

> [p14] **2a. Frozen and snapshot versions (owner rulings,
> 2026-08-10; terminology fixed 2026-08-13).** A version is a **snapshot by
> default** — the word carries its Maven sense, *mutable*: content may change
> under the same version string, `vibe update` brings the fresh content without
> regard for hash continuity, and the lockfile pins the delivered capture's
> `content_hash` plus an opaque provider locator for reproduction. The
> **freeze** is the package author's one-way act: `frozen = true` in the
> manifest — never a registry's opinion, never part of the version string. The
> carrier decisions and their reasons: *(i)* the flag lives **inside the hashed
> content**, so a frozen version self-describes even offline and every registry
> serving those bytes necessarily agrees — in a multi-registry world with no
> global journal, content is the only carrier that cannot diverge; registries
> merely *observe* a freeze in their journals and project it into catalogs;
> *(ii)* the version string carries version ordering **only** — two entities
> never share one name, which keeps the full matrix expressible: a frozen
> prerelease (an immutable published beta) and a mutable bare version (being
> stabilised in place) are both legal; *(iii)* the transition is **one-way and
> single** — unfreezing is forbidden, further work is a new version string; a
> registry may never accept a frozen coordinate's re-publication with different
> bytes; *(iv)* same coordinate + different bytes + any party claiming frozen =
> **loud conflict** through the candidate machinery, never a quiet pick.
> **Every surface that shows a version shows its frozen state** — machine
> outputs carry the field by schema; CLI, TUI, GUI and MCP render it always
> (the Maven lesson: mutability a human cannot see is mutability that will
> surprise them). Yank remains journal-borne — it is the act frozen content can
> no longer carry itself.
>
> <spec://org.vibevm.core/vibevm/common/PROP-044#THE-FREEZE-MODEL>

> [p15] **The pre-publication regime, and the switch only the
> owner can flip (owner ruling, 2026-08-10, near-verbatim: «я пока ничего не
> публиковал на большую публику… я хочу, чтобы мы не применяли миграции до тех
> пор, пока я не скажу, что состоялось первое представление публике… технически
> этот факт нельзя определить никак — только владелец может сказать, что это
> произошло»).** Until that declaration the system is in the pre-publication
> regime: breaking is free *and unmigrated* — no codemods run, no bot PRs, no
> parallel worlds, no sunset calendars; break machinery reports instead of
> demanding (corpora regenerate freely, break notes are optional records);
> readers of old shapes are conveniences deletable at will; the standing user
> recipe is «regenerate / re-init / re-fetch». The fact of the first public
> presentation is technically undetectable **by design** and must never be
> inferred from technical events — not from a push, not from the default
> registry filling, not from a tag; any earlier «de-facto publication» reading
> is superseded by this ruling. The switch is one owner-only line
> (`public = true` in `formats/EPOCHS.toml`), and flipping it is the single
> moment obligations, migrations, support windows and the handshake vow
> activate. The wave-0 slots (epoch markers, recipe identity, must-understand,
> yank) are still built early — not because the window is closing silently, but
> because they are cheap now, constrain today's breaking not at all, and are
> what makes the later freeze possible at all.
>
> <spec://org.vibevm.core/vibevm/common/PROP-044#THE-PUBLIC-SWITCH>

## Версии самого vibe {#vibe-itself}

[p16] Программа управляет собственными версиями через `vibe self`: `self install` собирает версию из исходников или ставит проверенный бандл, `self ls` перечисляет, что есть на машине, `self use` переключает активную, а `self rollback` возвращает предыдущую. Селектор `latest` означает вершину ветки main, `stable` — новейший выпуск с тегом, а голое `X.Y.Z` — этот тег.

> [p17] `latest` → tip of branch `main`.
>
> <spec://org.vibevm.core/vibevm/common/PROP-019#SEL-LATEST>

> [p18] `stable` → highest semantic-version git tag (the newest release).
>
> <spec://org.vibevm.core/vibevm/common/PROP-019#SEL-STABLE>

[p19] Переключение версий никогда не перезаписывает работающий бинарник и никогда не требует нового терминала: активная версия — это указатель, по которому шим идёт при следующем вызове.

> [p20] **Switching must not reload the console and must not overwrite a running
> file.** (v1's "env is truth" violated the first; see §9.1.) The model has
> four layers:
>
> <spec://org.vibevm.core/vibevm/common/PROP-019#ACTIVATION-LAW>

[p21] Менеджер заботится о программе на машине, а не о зависимостях проекта, и его папка лаунчеров попадает в `PATH` один раз. `self use` перенацеливает активную версию; `--eval` вместо этого печатает строку для оболочки, чтобы переключиться в одном терминале. `self update` идёт туда, откуда пришла работающая копия: чекаут исходников пересобирает вершину, а установленный бинарник переходит на новейший опубликованный выпуск. Тот же номер скачивается заново, только если выпуск под ним пересобрали; `self reinstall` скачивает работающую версию заново, не меняя, какая она. `self rollback` меняет на предыдущую версию и обратно. Активную версию нельзя удалить без `--force`, а работающую копию нельзя удалить вовсе. У каждого вопроса есть флаг, так что всё это работает из скрипта или от агента, а `vibe vars` печатает переменные, которые читает установка, без токена публикации.

> [p22] VVM manages *the vibevm tool itself* on *the machine* — a user-global
>   prefix, not a project's `vibedeps/`.
>
> <spec://org.vibevm.core/vibevm/common/PROP-019#VVM-IS-TOOL>

> [p23] **The shim dir on `PATH`** (stable; set once).
>
> <spec://org.vibevm.core/vibevm/common/PROP-019#PATH-SHIM-DIR>

> [p24] `self use <selector>` — make a version active by repointing the live
>   `current` file — **no console reload** (§2.5). `--eval` prints the shell
>   line for an integrity-checked shell-local override instead of touching the
>   durable environment.
>
> <spec://org.vibevm.core/vibevm/common/PROP-019#CMD-USE>

> [p25] `self update` follows the running origin, and moves versions FORWARD (owner
>   ruling 2026-09-14, replacing the v1 rule that a binary execution refreshes its
>   own number and never jumps). A source/worktree execution rebuilds its exact
>   source root at `latest`. A binary execution reads the release channel's
>   newest-release aggregate manifest and goes to the **newest published
>   release**: newer than the running version installs and activates it by the
>   same verified path an explicit `X.Y.Z` takes. The SAME version is not a no-op
>   — a release may be rebuilt under its own number, so the manifest's bundle
>   digest decides: changed bytes install a fresh immutable `#N`, unchanged bytes
>   reuse the instance already held and cost no bundle download at all. A newest
>   release OLDER than the running one (withdrawn on the far side) never walks the
>   machine backwards. `--force` installs a fresh `#N` whatever the digest says.
>   `self install stable` enters this same path, since `stable` IS the newest
>   release (§2.3).
>
> <spec://org.vibevm.core/vibevm/common/PROP-019#CMD-UPDATE>

> [p26] `self reinstall` refreshes the version that is RUNNING, without changing which
>   version that is: a binary execution refetches its own release's manifest and
>   bundle, a source/worktree execution rebuilds its exact source root — either
>   way landing a fresh immutable `#N`. It takes no `--force`, because a fresh
>   instance is the whole verb; `--profile` / `--release` steer the source lane
>   exactly as on `update`. The pair is deliberate (owner ruling 2026-09-14):
>   refetching the current version and moving to a new release are two acts, so
>   they carry two names.
>
> <spec://org.vibevm.core/vibevm/common/PROP-019#CMD-REINSTALL>

> [p27] `self rollback` atomically swaps to the immediate `previous` instance;
>   repeating it toggles the two pointers without deleting either generation.
>
> <spec://org.vibevm.core/vibevm/common/PROP-019#CMD-ROLLBACK>

> [p28] The **active** version and the **running** instance are protected:
>   removing an active but non-running instance needs `--force`; the actually
>   running instance is never removable, even with that flag.
>
> <spec://org.vibevm.core/vibevm/common/PROP-019#RM-PROTECTED>

> [p29] It is fully scriptable: every interactive prompt has a non-interactive flag
>   equivalent, so VVM works from a bare terminal, CI, or an agent transcript.
>
> <spec://org.vibevm.core/vibevm/common/PROP-019#FULLY-SCRIPTABLE>

> [p30] `vibe vars` prints the project's env-configurable variables —
>   `VIBEVM_INSTALL_ROOT`, `VIBEVM_HOME` (whose *actual* values are derived from
>   `current_exe`, §2.5), plus `VIBE_INVOKED_BY`, `VIBE_UNATTENDED`, `VIBE_LOG`
>   — in `NAME=VALUE` form. The publish token is deliberately excluded.
>
> <spec://org.vibevm.core/vibevm/common/PROP-019#VARS-CONTENT>

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

[p31] Два пакета с одной координатой и версией, но разными байтами — две разные вещи, и второй отвергается. Если сопровождающему нужно переиздать, меняется номер версии.

> [p32] **Consequence.** Fetching the same `(kind, name, version)` from two different URLs (canonical + mirror, original + fork, upstream + vendored copy) must produce the same `content_hash`. Mismatch is a fatal `IntegrityError`. The effect is:
>
> <spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-002#IDENTITY-CONSEQUENCE>

[p33] Ветка, взятая как [git-источник](../glossary/index.xml#git-source), — единственное исключение из закрепления по номеру: её запись в локе хранит установленный коммит, а обновление проходит ветку заново.

