<?xml version="1.0" encoding="UTF-8"?>
<spec xmlns="https://vibevm.org/spec/1">
  <title id="root">Версии и обновления</title>
  <status stage="doc" state="work" audience="user"/>
  <p p="1">Версия — это обещание о поведении, а не снимок файлов. Ваш проект просит диапазон, vibe записывает тот один номер, который выбрал, а обновление сдвигает этот номер намеренно. Сам vibe следует тому же правилу: один номер означает один контракт, сколько бы раз ни пересобирали бинарник за ним.</p>
  <example ref="outdated" p="2"/>
  <section id="asking" title="Как попросить версию">
    <p p="3">Версии пакетов следуют семантическому версионированию: три числа, первое из которых меняется, когда пакет ломает совместимость. В [манифесте](../glossary/index.xml#manifest) вы называете ограничение, а не версию: `^1.0` значит любая 1.x начиная с 1.0, `=1.2.0` — ровно эта, а голая [координата](../glossary/index.xml#coordinate) — новейший стабильный выпуск. Резолвер выбирает по одной версии на пакет так, чтобы удовлетворить каждое ограничение в графе, а [лок-файл](../glossary/index.xml#lock-file) записывает выбор.</p>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-000#CF-RANGE" p="4"/>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-000#CF-LATEST" p="5"/>
    <p p="6">[Семейство](../glossary/index.xml#family) пакетов, которые должны двигаться вместе, закрепляет своих членов точно, чтобы языковой гайд и сервер, отдающий его инструменты, всегда разрешались в один набор версий. Вы встретите такие пины в манифестах бандлов; они намеренные.</p>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-028#AGGREGATOR-PINS-DELIBERATE" p="7"/>
  </section>
  <section id="moving" title="Как сдвинуть пин">
    <p p="8">`vibe outdated` читает лок-файл и [реестр](../glossary/index.xml#registry) и перечисляет пакеты, у которых есть версия новее; он ничего не меняет. `vibe update` подбирает версии заново и сдвигает пины, предпочитая оставить каждый пакет, который вы не назвали, на текущей версии, чтобы обновление одного пакета не тащило молча остальные.</p>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-resolver/PROP-003#TRAIT-PIN-PREFERENCES" p="9"/>
    <p p="10">После обновления дерево зависимостей и стартовые файлы пересобираются, а диф лок-файла — это журнал того, что ваш агент теперь будет читать.</p>
  </section>
  <section id="what-a-version-promises" title="Что обещает версия">
    <p p="11">Номер версии — это контракт: версия 1 делает то, что версия 1 по документации должна делать. Внутри версии файлы за ней могут пересобирать, исправлять и переиздавать, и читатель документации этой кухни не видит. Так же vibe обходится и с собственными выпусками. Бинарник, который вы получаете через `vibe self install latest`, — это то, что ветка main держит сегодня, под одним номером версии. Руководство описывает контракт этого номера, а не файлы одной сборки.</p>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-057#OBS-VERSION-CONTRACT" p="12"/>
    <p p="13">Версия пакета по умолчанию — снимок в том смысле, какой у этого слова в Maven: её содержимое может меняться под тем же номером, и `vibe update` приносит свежее. Замороженная версия — исключение, которое объявляет издатель. До первого публичного выпуска ломающие изменения выходят без заметок о миграции; переключатель, который заканчивает этот режим, — только в руках владельца.</p>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-044#THE-FREEZE-MODEL" p="14"/>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-044#THE-PUBLIC-SWITCH" p="15"/>
  </section>
  <section id="vibe-itself" title="Версии самого vibe">
    <p p="16">Программа управляет собственными версиями через `vibe self`: `self install` собирает версию из исходников или ставит проверенный бандл, `self ls` перечисляет, что есть на машине, `self use` переключает активную, а `self rollback` возвращает предыдущую. Селектор `latest` означает вершину ветки main, `stable` — новейший выпуск с тегом, а голое `X.Y.Z` — этот тег.</p>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-019#SEL-LATEST" p="17"/>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-019#SEL-STABLE" p="18"/>
    <p p="19">Переключение версий никогда не перезаписывает работающий бинарник и никогда не требует нового терминала: активная версия — это указатель, по которому шим идёт при следующем вызове.</p>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-019#ACTIVATION-LAW" p="20"/>
    <p p="21">Менеджер заботится о программе на машине, а не о зависимостях проекта, и его папка лаунчеров попадает в `PATH` один раз. `self use` перенацеливает активную версию; `--eval` вместо этого печатает строку для оболочки, чтобы переключиться в одном терминале. `self update` идёт туда, откуда пришла работающая копия: чекаут исходников пересобирает вершину, а установленный бинарник переходит на новейший опубликованный выпуск. Тот же номер скачивается заново, только если выпуск под ним пересобрали; `self reinstall` скачивает работающую версию заново, не меняя, какая она. `self rollback` меняет на предыдущую версию и обратно. Активную версию нельзя удалить без `--force`, а работающую копию нельзя удалить вовсе. У каждого вопроса есть флаг, так что всё это работает из скрипта или от агента, а `vibe vars` печатает переменные, которые читает установка, без токена публикации.</p>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-019#VVM-IS-TOOL" p="22"/>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-019#PATH-SHIM-DIR" p="23"/>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-019#CMD-USE" p="24"/>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-019#CMD-UPDATE" p="25"/>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-019#CMD-REINSTALL" p="26"/>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-019#CMD-ROLLBACK" p="27"/>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-019#RM-PROTECTED" p="28"/>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-019#FULLY-SCRIPTABLE" p="29"/>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-019#VARS-CONTENT" p="30"/>
  </section>
  <section id="edge-cases" title="Особые случаи и правила">
    <p p="31">Два пакета с одной координатой и версией, но разными байтами — две разные вещи, и второй отвергается. Если сопровождающему нужно переиздать, меняется номер версии.</p>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-002#IDENTITY-CONSEQUENCE" p="32"/>
    <p p="33">Ветка, взятая как [git-источник](../glossary/index.xml#git-source), — единственное исключение из закрепления по номеру: её запись в локе хранит установленный коммит, а обновление проходит ветку заново.</p>
  </section>
</spec>
