# The lifecycle: from validate to deploy {#root}

@status:doc/work @audience:user,author

[p01] Building software has a fixed order of steps, and vibe names them: check the tree, produce generated sources, build, test, let an agent create what only an agent can, verify, assemble, deploy. Each step runs only when something it depends on changed.

[p02]
```sh
vibe deploy --plan --profile local --path hello-deploy
```

```output
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
```

## The nine phases {#the-phases}

[p03] vibe has two [lifecycles](../glossary/index.xml#lifecycle). `clean` has one [phase](../glossary/index.xml#phase) and removes derived state. `default` has nine phases in a fixed order: `validate`, `install`, `generate`, `build`, `test`, `create`, `verify`, `package`, `deploy`. Naming a phase runs every phase before it as well: `vibe test` validates, installs, generates, builds and tests.

> [p04] `vibe <phase>` executes every default-lifecycle phase up to and including the named one, in order — the Maven ritual verbatim. `vibe clean <phase>` runs the clean lifecycle first, then the default lifecycle up to `<phase>` (§4.4). A phase with no contributions and no built-in binding **completes as a no-op** — Maven's empty-phase law, which is what makes nine slots cost nothing for a prompt-only project (its `deploy` chain degenerates to validate+install).
>
> <spec://org.vibevm.core/vibevm/common/PROP-054#INVOKE-RUNS-PRIORS>

[p05]
| Phase | What it does |
| --- | --- |
| `validate` | the cheap preflight: the manifest parses, the declared extensions and profiles are well formed; no network |
| `install` | the package install described elsewhere in this manual: resolve, fetch, copy, generate the boot files |
| `generate` | derived sources from specifications and prompts, written where the project's stack says |
| `build` | the deterministic build of the project's stack |
| `test` | deterministic checks: the stack's test runner and the discipline gates the installed packages contribute |
| `create` | the optional agentic step: work that only an agent can do, long and non-deterministic, off unless the project switches it on |
| `verify` | the late quality gate over what was built and created |
| `package` | assemble distributables without touching any destination |
| `deploy` | apply the packaged artifacts to explicit destinations through a named profile |

> [p06] vibe has **two** lifecycles. **`clean`** — one phase, exactly PROP-053. **`default`** — nine phases, in this fixed order:
>
> <spec://org.vibevm.core/vibevm/common/PROP-054#LIFECYCLES>

> [p07] **`build`** — the deterministic algorithmic build. The engine prepares selected native groups, replays pending compiler lanes, executes dependency-ordered artifact targets through exact mechanisms, then phase rows. Builtin Cargo, compatibility `[[binary]]` lowering and package-supplied native Build replacement are commissioned; the foreign adapter consumes exact prepared carriage, owns staged output proof/A2 records and preserves provider freshness through rollback.
>
> <spec://org.vibevm.core/vibevm/common/PROP-054#PHASE-BUILD>

> [p08] **`package`** — assemble distributables without mutating destinations. Verified artifact records feed builtin static-skill, Agent Plugin/client projection and deterministic Windows-zip providers, plus package-supplied native Package replacement. The foreign adapter resolves and revalidates the real Build A2 record before invocation and retains engine-owned fingerprints, proof and records.
>
> <spec://org.vibevm.core/vibevm/common/PROP-054#PHASE-PACKAGE>

> [p09] **`deploy`** — apply selected package artifacts to explicit destinations through profiles, exact providers, plan/lock/intent/receipt/recovery/inverse ownership. Builtin local/client providers and a real package-supplied native replacement are commissioned; live remote publication remains subject to ordinary red lines.
>
> <spec://org.vibevm.core/vibevm/common/PROP-054#PHASE-DEPLOY>

## Nothing runs twice for nothing {#fresh}

[p10] Every phase run records a [fingerprint](../glossary/index.xml#fingerprint) of the inputs it declared; the next run skips a phase whose inputs did not change. Freshness is judged per [contribution](../glossary/index.xml#contribution), so one stale step re-runs alone and its neighbours stay skipped. This is what makes `vibe deploy` cheap to type twice: the second time it mostly reports that everything is fresh.

> [p11] **Every phase execution owns a fingerprint** — a hash over its declared inputs (for install: manifest+sources, already built; for build: the slot sources + project sources the preset names; for create: the prompt documents + their spec closure). A phase whose fingerprint matches the recorded one **skips**, reporting `fresh` per contribution — the Gradle up-to-date property grafted onto the Maven ritual. This is the design answer to «если vibe.toml не поменялся, инсталлировать пакеты не нужно», generalised to all nine phases because create (tokens) and build (native compile time) are even more expensive than install.
>
> <spec://org.vibevm.core/vibevm/common/PROP-054#PHASE-FINGERPRINT>

> [p12] Freshness is judged **per contribution**, not only per phase: one stale execution re-runs alone; its peers stay skipped. A handler MAY declare extra inputs in its manifest entry (`inputs = ["spec/prompts/**"]`); a handler that declares none is conservatively re-run whenever the phase's own inputs move.
>
> <spec://org.vibevm.core/vibevm/common/PROP-054#FRESHNESS-IS-PER-CONTRIBUTION>

## Seeing before doing {#the-plan}

[p13] `--plan` reports what a phase run would do and changes nothing; every real run prints, before executing, the contributions it will run: their id, the point they bind to, the kind of handler, and where they came from. Nothing in the lifecycle runs invisibly.

> [p14] **Nothing runs invisibly.** Every phase run prints the contributions it will execute (id, point, handler kind, providing package) before running them — the narrator genre the tooling already speaks (`[k/n]` lines). A ritual whose steps are secret is not a ritual. The full instrument rack is §3.5.
>
> <spec://org.vibevm.core/vibevm/common/PROP-054#SURFACE-THE-RITUAL>

[p15] `vibe clean <phase>` chains the clean lifecycle in front of any default phase: `vibe clean build` removes the derived state and then validates, installs, generates and builds.

> [p16] **`vibe [clean] <phase> [<pkgref>…] [flags]`.** Any default-lifecycle phase may be named; `clean` before it runs the clean lifecycle first. `vibe clean install org.x/y --offline` keeps its exact PROP-053 semantics (wipe → world from lock → refresh the named) as the special case it already was. This section IS the «own semantics ruling» PROP-053 `##CHAIN-ONLY-INSTALL` required before any wider grammar — that anchor is superseded by this one **at build time, by a status move and a successor note beside it, never by deleting or renaming it**. Pkgrefs remain meaningful only to the install phase (they scope what refreshes); other phases take flags, not pkgrefs, until a ruling says otherwise.
>
> <spec://org.vibevm.core/vibevm/common/PROP-054#CHAIN-GENERAL>

## Where the steps come from {#where-steps-come-from}

[p17] The phases are fixed; what runs inside them is contributed by packages. A stack package binds the language's build and test runners, a discipline package binds its gates, a project may bind its own scripts. Installing a package is the consent for its contributions to run, and the [manifest](../glossary/index.xml#manifest) of the project can switch a contribution off or replace it by its id.

> [p18] **Installing a package IS the consent to run its extensions** (owner ruling 2026-08-25, `##LIFE-MANDATE-NO-CONSENT`). No allow-lists, no first-run prompts, no `--allow-…` flags — the Gradle/Webpack/Clang posture: an ecosystem of native extensions where the trust decision is made once, at dependency selection, like `build.rs` and `postinstall` before us. The safety model is not permission dialogs but **total observability** (§3.5). PROP-020 §2.3 now records this successor at its owning anchors; the old allow-list/first-run/non-interactive permission design remains historical text only.
>
> <spec://org.vibevm.core/vibevm/common/PROP-054#INSTALL-IS-CONSENT>

[p19] The lifecycle is a framework, not a universal coding agent: it runs deterministic mechanics and hands agentic work to whatever agent hosts it.

> [p20] **Owner ruling (2026-08-27): VibeVM builds the mechanics, not a universal coding agent.** The lifecycle is a passive, extensible execution framework: phases, contributions, fingerprints, artifacts, reports, durable park/resume and CLI/MCP adapters. It contains no built-in Plan/Act policy, no automatic `create → verify → create` transition, no replanning heuristic, no hidden attempt/token loop and no rule for when a human must intervene. Any human, Codex, Claude Code, OpenCode or future agent may orchestrate repeated invocations; a reference coding agent is explicitly a separate future campaign.
>
> <spec://org.vibevm.core/vibevm/common/PROP-054#LIFECYCLE-IS-FRAMEWORK>

## Edge cases and rules {#edge-cases}

[p21] A failing step stops the chain; the phases before it keep their results, and the failure names the contribution that failed.

> [p22] **Failure semantics generalise PROP-020 §2.5:** a failing contribution in validate/install/generate/build/test **stops the chain** (the phase reports which execution failed); a failing create/verify contribution stops before package (nothing half-created is packaged); package/deploy failures stop the chain trivially (they are last). `slot:pre-install` keeps its rollback; `slot:post-install` keeps installed-but-flagged. A `skip` reply is bookkept, never an error.
>
> <spec://org.vibevm.core/vibevm/common/PROP-054#FAILURE-BY-PHASE>

[p23] The older verbs keep their meaning beside the lifecycle: `vibe check`, `vibe bin build`, `vibe skill` and `vibe cache` are not phases.

> [p24] Existing verbs are untouched: `vibe check`, `vibe bin build`, `vibe skill`, `vibe cache …` keep their meanings as directly-invoked tools — Maven's «a goal not bound to any build phase could be executed outside of the build lifecycle by direct invocation». `vibe install` the verb IS the install phase invoked directly (one implementation, two spellings of the same thing). Mixing direct verbs into a phase chain on one command line (Maven's `mvn clean dependency:copy-dependencies package`) is **not** adopted now — each verb keeps its own invocation; revisit behind this anchor if the need shows.
>
> <spec://org.vibevm.core/vibevm/common/PROP-054#EXISTING-VERBS-STAY>

[p25] Fingerprints and last-run records live in `.vibe/lifecycle.toml`, machine state that is not committed; deleting it costs one full run.

> [p26] Fingerprints and last-run records live in `.vibe/lifecycle.toml` at the workspace root — machine state beside the project settings that already live in `.vibe/`, inside the shippable-tree denylist (PROP-024 §2.2), never committed, never hashed. `vibe clean` does NOT remove it (it describes work, it is not derived prompt state); a `--force` flag on any phase ignores it for one run.
>
> <spec://org.vibevm.core/vibevm/common/PROP-054#PHASE-STATE-HOME>

