<?xml version="1.0" encoding="UTF-8"?>
<spec xmlns="https://vibevm.org/spec/1">
  <title id="root">Build, package and deploy a project</title>
  <status stage="doc" state="work" audience="user,author"/>
  <p p="1">This page takes a project from source to a running deployment with three commands, shows what each leaves on disk, and how to take a deployment down again without guessing what it owned.</p>
  <prompt id="build-package-deploy" p="2">
    For the VibeVM project in the current folder, show me the deploy plan for the profile named local, then run the deploy, list the deployments this machine now holds, and finally undeploy the same profile. Stop and ask me before the deploy and before the undeploy.
    <needs>the vibevm skill installed for your agent; a project whose manifest declares a build artifact, a deploy target with the mechanism `deploy:vibe-bin` and a profile named `local`, as the tables on this page show; `cargo` on the `PATH`</needs>
    <outcome>the plan names the targets in order; after the deploy `vibe deployments` lists the profile with a generation and a status; after the undeploy every receipt-owned resource is gone and the listing shows the profile as removed</outcome>
    <assert>vibe deploy --plan --profile local</assert>
    <assert>vibe deployments --json</assert>
  </prompt>
  <section id="what-happens" title="What happens">
    <p p="3">`vibe deploy --plan` runs the whole default [lifecycle](../glossary/index.xml#lifecycle) in planning mode and prints what each [phase](../glossary/index.xml#phase) would do, ending with the ordered targets of the profile; nothing is written. The real `vibe deploy` then validates, installs, generates, builds, tests, creates, verifies and packages, skipping every step whose inputs did not change, and applies the packaged artifacts to the profile's targets in order. For every resource it creates it writes a *[receipt](../glossary/index.xml#receipt)*: what was placed where, under which generation, owned by which profile. `vibe deployments` reads the receipts this machine holds. `vibe undeploy --profile local` walks the receipts in reverse dependency order and removes exactly what they own, refusing a path that changed after deployment.</p>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-054#R8-DEPLOY-RUNTIME" p="4"/>
  </section>
  <section id="by-hand" title="By hand">
    <p p="5">1. Declare what to build, what to deploy and where. A target names an artifact and the mechanism that places it; a profile is an ordered list of targets:</p>
    <fence lang="toml" p="6">[[artifacts.build]]
id = "build-hello"
mechanism = "build:cargo"
outputs = [{ id = "hello", kind = "executable", select = { package = "hello", bin = "hello" } }]
config = { offline = true }

[[deploy.target]]
id = "local"
artifact = "hello"
mechanism = "deploy:vibe-bin"
config = { command = "hello" }

[deploy]
default_profile = "local"

[deploy.profiles.local]
targets = ["local"]</fence>
    <p p="7">The mechanism `deploy:vibe-bin` places the executable as a launcher in vibe's own `bin/` folder on this machine. The command then runs from any terminal; other mechanisms are listed in the [specification](../glossary/index.xml#specification).</p>
    <p p="8">2. Assemble the distributables without touching any destination:</p>
    <example id="package" fixture="hello-deploy" p="9">
      <run>vibe package --path hello-deploy --assume-yes</run>
      <expect>  → will run `@vibe/package/skill/org.vibevm.world/wal/wal-status` — point=phase:package, handler=builtin:package-skill-project, provider=org.vibevm.world/wal tier=preset
  → package binding [org.vibevm.world/wal]: projected skill `wal-status` (claude=created, codex=created, opencode=created)
lifecycle `package`:
  → validate: ok
  → install: fresh
  → generate: no-op
  → build: no-op
  → test: no-op
  → create: no-op
  → verify: no-op
  → package: ok
  → verification: unavailable (0 input(s), 0 artifact(s))
vibe lifecycle: package completed (8 phases, 1 contribution(s) selected, 1 executed, 1 ok, 0 fresh, 0 notice(s))</expect>
    </example>
    <p p="10">3. See the plan for a profile, then deploy it:</p>
    <example id="deploy-plan" fixture="hello-deploy" p="11">
      <run>vibe deploy --plan --profile local --path hello-deploy</run>
      <expect>Deploy plan — profile `local` on `windows`
  → local [planned] provider=org.vibevm/vibe#vibe-bin via=the shipped builtin default — artifact `hello` has no record yet, so producing it is planned work
1 of 1 applicable target(s) would be deployed; 0 skipped; nothing was read, built or changed</expect>
    </example>
    <p p="12">4. List what this machine holds, and take a profile down:</p>
    <example id="deployments" fixture="hello-vibe" p="13">
      <run>vibe deployments</run>
      <expect>no deployments recorded on this machine</expect>
    </example>
    <p p="14">`vibe undeploy --profile &lt;name&gt;` reverses that profile. The listing never shows secrets.</p>
  </section>
  <section id="artifacts" title="Artifacts and targets">
    <p p="15">The [manifest](../glossary/index.xml#manifest) declares what `build` produces and what `package` assembles, as artifact targets with dependencies between them. vibe lowers them into one validated graph and records every produced artifact. So `package` consumes exactly what `build` verified, and `deploy` applies exactly what `package` assembled. An artifact or a target may declare the operating systems it applies to, and a target that does not apply to the current machine is skipped with a note.</p>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-054#R8-ARTIFACT-RUNTIME" p="16"/>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-054#R8-PLATFORM-APPLICABILITY" p="17"/>
    <p p="18">A [deploy profile](../glossary/index.xml#deploy-profile) names its targets in order and the [provider](../glossary/index.xml#provider) that applies each: a folder on this machine, an agent's project or user configuration, and the genres the specification lists. An installed package may replace a built-in provider through an exact pin, so a team can ship its own way of deploying.</p>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-054#R8-NATIVE-DEPLOY-PROVIDER" p="19"/>
  </section>
  <section id="edge-cases" title="Edge cases and rules">
    <p p="20">Two deploys of the same profile do not race: the engine takes a collision lock per profile and the second waits or refuses, never interleaves.</p>
    <p p="21">A receipt is the only authority for removal. If a file a receipt owns was edited after deployment, `undeploy` leaves it in place and says so, rather than deleting someone's work.</p>
    <p p="22">`--force` on a lifecycle verb ignores the recorded [fingerprints](../glossary/index.xml#fingerprint) for one run; it does not change what the run means.</p>
    <p p="23">The deploy phase applies packaged artifacts and nothing else: a step that needs an agent, such as writing release notes, belongs to `create`, and runs only when the project switches it on.</p>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-054#PHASE-CREATE" p="24"/>
  </section>
</spec>
