<?xml version="1.0" encoding="UTF-8"?>
<spec xmlns="https://vibevm.org/spec/1">
  <title id="root">Work offline</title>
  <status stage="doc" state="work" audience="user"/>
  <p p="1">On a plane or behind a firewall, vibe keeps working from what the machine already holds. This page fetches what you will need before you leave and installs from it without a network.</p>
  <prompt id="work-offline" p="2">
    Before I go offline, fetch into the machine store everything the VibeVM project in the current folder needs plus the package org.vibevm.world/multi-user-planning, then verify the store and show me that an offline install of this project succeeds.
    <needs>the vibevm skill installed for your agent; network access now; a project with `vibe.toml`</needs>
    <outcome>`vibe cache list` shows the project's packages and the extra one; `vibe cache check` reports every entry intact; `vibe install --offline` completes without a network request</outcome>
    <assert>vibe cache check</assert>
    <assert>vibe reinstall --force --offline --assume-yes</assert>
  </prompt>
  <section id="what-happens" title="What happens">
    <p p="3">The agent runs `vibe cache add` for the extra package, which resolves it and its whole dependency closure and fetches every node into the [store](../glossary/index.xml#store) without touching the project. It runs `vibe install` once online so the project's own packages are in the store too, then `vibe cache check` to verify every stored entry against its [fingerprint](../glossary/index.xml#fingerprint). Finally it runs `vibe install --offline`: resolution and fetch are satisfied from the store alone, and the command fails loudly if anything is missing rather than installing a partial graph.</p>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-010#OFFLINE-LOCAL-ONLY" p="4"/>
  </section>
  <section id="by-hand" title="By hand">
    <p p="5">1. Warm the store with a package and its dependencies. Inside a project its [registries](../glossary/index.xml#registry) are the source; outside one, the machine-wide registries:</p>
    <example id="cache-add" fixture="empty" p="6">
      <run>vibe cache add org.vibevm.world/wal</run>
      <expect>Pre-warming the machine store (&lt;TMP&gt;/home/cache)
  ✓ created  org.vibevm.world/wal@1.0.0

1 fetched, 0 already present — nothing materialised into any project.</expect>
    </example>
    <p p="7">2. See and verify what the store holds:</p>
    <example id="cache-list" fixture="hello-vibe" p="8">
      <run>vibe cache list</run>
      <expect>GROUP             NAME  VERSION
org.vibevm.world  wal   1.0.0

1 package in &lt;TMP&gt;/home/cache.</expect>
    </example>
    <example id="cache-check" fixture="hello-vibe" p="9">
      <run>vibe cache check</run>
      <expect>Integrity sweep of the machine store (&lt;TMP&gt;/home/cache)

1 ok, 0 mismatched, 0 unrecorded.</expect>
    </example>
    <p p="10">3. Install without a network:</p>
    <example id="install-offline" fixture="hello-vibe-empty" p="11">
      <run>vibe install org.vibevm.world/wal --path hello-vibe --offline --assume-yes</run>
      <expect>Resolving 1 root package…

Materialising 1 package into vibedeps/:
  org.vibevm.world/wal@1.0.0

closure diff:
  → + org.vibevm.world/wal@1.0.0 (root-edge)
  → lane vibevm/vibespecs/boot/INDEX.md: 737 -&gt; 854 B

Materialised 1 package into vibedeps/; regenerated boot artifacts for 1 node(s).</expect>
    </example>
  </section>
  <section id="switching-it-on" title="Three ways to switch offline mode on">
    <p p="12">The flag `--offline` on any command; the environment variable `VIBE_OFFLINE=1`; or the setting `offline = true` under `[net]` in `~/.vibe/config.toml`. The flag wins over the variable, and the variable over the setting. Online remains the default.</p>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-010#OFFLINE-LAYERING" p="13"/>
  </section>
  <section id="air-gapped" title="A whole team without a network">
    <p p="14">For a machine that never sees the registry, `vibe registry vendor` writes a folder holding every package the [lock file](../glossary/index.xml#lock-file) references, ready to be used as a [mirror](../glossary/index.xml#mirror) with a `file://` address on the other side. The fingerprints travel with it, so the mirror is verified like any other.</p>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-002#MIRROR-LAYER" p="15"/>
  </section>
  <section id="edge-cases" title="Edge cases and rules">
    <p p="16">If an offline install refuses a package the store already holds, the project's registries were never cloned on this machine and vibe cannot learn which versions exist; one online install in any project clones them, and a `file://` mirror needs no clone at all.</p>
    <p p="17">Offline resolution sees the store as of its last refresh: a version published after you went offline is invisible until you are back and run `vibe registry sync` or an online install.</p>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-010#AS-OF-LAST-REFRESH" p="18"/>
    <p p="19">A package in the store is usable even when its registry no longer lists it; a package that never reached the store is a hard error naming the missing [coordinate](../glossary/index.xml#coordinate).</p>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-010#OFFLINE-HARD-ERROR" p="20"/>
    <p p="21">The program's own version manager obeys the same posture: under it `vibe self update`, `install` and `reinstall` refuse before their first request, naming the address they would have needed, and `self ls`, `current` and `which` answer from the machine as usual.</p>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-019#CMD-OFFLINE" p="22"/>
  </section>
</spec>
