<?xml version="1.0" encoding="UTF-8"?>
<spec xmlns="https://vibevm.org/spec/1">
  <title id="root">Versions and updates</title>
  <status stage="doc" state="work" audience="user"/>
  <p p="1">A version is a promise about behaviour, not a snapshot of files. Your project asks for a range, vibe records the one number it chose, and an update moves that number on purpose. vibe itself follows the same rule: one number stands for one contract, however often the binary behind it is rebuilt.</p>
  <example id="outdated" fixture="hello-vibe-registry" p="2">
    <run>vibe outdated --path hello-vibe</run>
    <expect>PACKAGE VERSIONS
GROUP                 NAME                          INSTALLED      LATEST         STATUS
org.vibevm.world      wal                           1.0.0           -               unknown

0 of 1 package have updates available</expect>
  </example>
  <section id="asking" title="Asking for a version">
    <p p="3">Package versions follow semantic versioning: three numbers, where the first changes when a package breaks compatibility. In the [manifest](../glossary/index.xml#manifest) you name a constraint, not a version: `^1.0` means any 1.x from 1.0 up, `=1.2.0` means exactly that one, and a bare [coordinate](../glossary/index.xml#coordinate) means the newest stable release. The resolver picks one version per package that satisfies every constraint in the graph, and the [lock file](../glossary/index.xml#lock-file) records the choice.</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">A [family](../glossary/index.xml#family) of packages that must move together pins its members exactly, so that a language guide and the server that serves its tools always resolve to one version set. You will meet these pins in the manifests of bundles; they are deliberate.</p>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-028#AGGREGATOR-PINS-DELIBERATE" p="7"/>
  </section>
  <section id="moving" title="Moving the pin">
    <p p="8">`vibe outdated` reads the lock file and the [registry](../glossary/index.xml#registry) and lists the packages with a newer version available; it changes nothing. `vibe update` re-resolves and moves the pins, preferring to keep every package you did not name at its current version, so that updating one package does not silently drag the others along.</p>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-resolver/PROP-003#TRAIT-PIN-PREFERENCES" p="9"/>
    <p p="10">After an update the dependency tree and the boot files are regenerated, and the diff of the lock file is the change log of what your agent will now read.</p>
  </section>
  <section id="what-a-version-promises" title="What a version promises">
    <p p="11">A version number is a contract: version 1 does what version 1 is documented to do. Inside a version the files behind it may be rebuilt, corrected or re-published, and a reader of the documentation does not see that kitchen. This is also how vibe treats its own releases. The binary you get from `vibe self install latest` is whatever the main branch holds today, under one version number. The manual describes the contract of that number rather than the files of one build.</p>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-057#OBS-VERSION-CONTRACT" p="12"/>
    <p p="13">A package version is a snapshot by default, in the sense the word has in Maven: its content may change under the same number, and `vibe update` brings the fresh content. A frozen version is the exception a publisher declares. Before the first public release, breaking changes ship without migration notes; the switch that ends that regime is the owner's alone.</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="Versions of vibe itself">
    <p p="16">The program manages its own versions with `vibe self`: `self install` builds a version from source or installs a verified bundle, `self ls` lists what the machine holds, `self use` switches the active one, and `self rollback` returns to the previous one. The selector `latest` means the tip of the main branch, `stable` the newest tagged release, and a plain `X.Y.Z` that tag.</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">Switching versions never overwrites a running binary and never requires a new terminal: the active version is a pointer the shim follows on the next call.</p>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-019#ACTIVATION-LAW" p="20"/>
    <p p="21">The manager looks after the program on the machine, not a project's dependencies, and its launcher folder goes on `PATH` once. `self use` repoints the active version; `--eval` prints a shell line for a one-terminal switch instead. `self update` follows where the running copy came from: a source checkout rebuilds at the tip, an installed binary moves to the newest published release. The same number is fetched again only when its release was rebuilt underneath it; `self reinstall` fetches the running version again without changing which one it is. `self rollback` swaps to the previous version and back again. The active version needs `--force` to be removed, and the copy that is running cannot be removed at all. Every prompt has a flag, so the whole thing works from a script or an agent, and `vibe vars` prints the variables the installation reads, without the publish token.</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="Edge cases and rules">
    <p p="31">Two packages with the same coordinate and version but different bytes are two different things, and the second is refused. If a maintainer needs to re-publish, the version number changes.</p>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-002#IDENTITY-CONSEQUENCE" p="32"/>
    <p p="33">A branch used as a [git source](../glossary/index.xml#git-source) is the one exception to pinning by number: its lock entry records the commit that was installed, and an update walks the branch again.</p>
  </section>
</spec>
