PROP-059 — User-local source applications
01vibe install -g PACKAGE, vibe update -g PACKAGE and vibe uninstall -g PACKAGE operate on exactly one fully qualified application package in the current user's Vibe settings root. The long spelling is --global. These routes run before project preparation and never mutate the current project's manifest, lock or dependencies. Ordinary invocations without this flag retain their existing semantics. The executable remains vibe; a second product-name alias is outside this change.
02An optional strict package-only application table declares id, installer_package (fully qualified and exactly pinned), runtime (node in the first implementation), entry (contained provider-relative regular file), and a nonempty unique commands list. This is explicit application metadata, never an automatically active project lifecycle extension. The root application coordinate and installer provider may differ; host code never branches on Zap's name or group.
03The application dispatcher supports an explicit local registry, the source-installed embedded registry, and the ordinary published registry walk used by a released binary Vibe. A published bridge package may declare one strict [application_source] Git proxy with a credential-free HTTPS URL, an explicit refs/heads/... tracked ref and a contained registry path. The same bridge may carry the exact lightweight [application] identity and distribution locator needed for binary selection; those two tables remain mutually exclusive on non-bridge packages. An ordinary binary-first install reads that bridge and release index without cloning the tracked source. Source materialization is deferred until --from-source is explicit or a valid binary is genuinely unavailable; it then resolves the mutable ref to an immutable commit plus portable sha256-tree/1 identity, opens the external registry, reads the exact installer provider, and refuses if the source application identity or distribution locator differs from the bridge. Legacy source-only bridges retain the eager compatibility path. Offline source operation never contacts Git and requires the tracked source to be cached.
04A real [application] may name one stable release-index locator: repository, release_tag and index_asset. Artifact URLs, byte lengths, SHA-256 digests and source commit/tree identities live only in the release-owned DISTRIBUTIONS.json, outside source Git, so publishing a binary cannot make its own source commit stale. The index binds the complete selected application identity and every target row; Linux rows additionally carry the explicit gnu or musl libc ABI selected from Vibe's own compile-time target environment. The selected ZIP descriptor must match that C1 identity exactly. Its files list exhaustively covers every archive entry except the descriptor, and its launchers cover every advertised command. Vibe verifies outer and per-file size/digest, portable depth/path/component laws, duplicate/case collision, links/special entries and exact platform before any extracted byte can execute.
05A matching verified platform binary is preferred. A binary-capable bridge does not fetch or clone its mutable source merely to ask whether newer source exists; --from-source is the explicit request that pays for and selects that revision. A legacy or already-materialized source observation may retain the attended source-versus-binary question, defaulting to No; JSON and unattended commands choose the binary. Missing release index, missing asset, empty target set or no current-platform row is typed absence and lazily falls back to source; malformed metadata, digest disagreement or unsafe archive content is a hard refusal. The durable record keeps selected C1 mode/commit/tree/commands separately from an actually observed C2 source, without inventing an observation when the source was never fetched.
06vibe update -g PACKAGE --binary explicitly returns a source-installed application to its verified published distribution. It suppresses the attended newer-source question and refuses when the release index has no valid current-platform binary rather than silently rebuilding source. --binary, --from-source and --local-source are mutually exclusive selection intents.
07A ready binary-to-source update atomically renames the complete binary-owned application host aside and suspends its verified launchers before invoking the source provider against a clean host path. Although the user-facing command remains update, the newly selected source provider receives its first operation as install because no source ownership marker exists yet; later source-to-source updates receive update. Source failure or application-index commit failure removes the replacement host and restores the exact prior host, launcher bytes and permissions; success retires the backup only after the new application record is durable. A source-to-binary update publishes the verified immutable binary generation and launchers transactionally while retaining the inactive source build cache as non-selected application data. A later binary-to-source transition moves that complete host aside, so stale binary or prior-source files cannot masquerade as the new source install.
08For development from a source checkout, vibe install -g PACKAGE --local-source and vibe update -g PACKAGE --local-source are exactly the composition --from-source --offline --registry <checkout-root>/vibevm/vibepacks. They search from the selected --path upward for the nearest in-tree vibevm/vibepacks, including standalone source repositories that intentionally have no root vibe.toml; absence is refused rather than guessed. They then enter the unchanged global-application resolver. The update spelling applies the same offline posture to both resolution and the application adapter. This is a shorthand, not a fourth source kind or a second resolver.
09Binary payloads publish as immutable application-host generations. Core-owned management binds the selected generation and delegates stable public launchers to its verified bundled management entry; bundled runtime and engine bytes mean binary launch needs no host Node or Rust. Windows bundles use .cmd management/public launchers; POSIX bundles use archive-mode-preserved executable launchers and a stable launch.sh. Extraction restores regular-file permission bits, publication reasserts executable launcher mode, and suspension derives the stable launcher genre from the verified bundle entry rather than assuming Windows. Source ready replies report exact receipt-owned launcher destinations and hashes. Vibe validates and persists that ownership so source-to-binary replacement and binary-to-source suspension are transactional: failure before the application index commits restores prior launcher and management bytes, while uninstall removes only exact recorded regular files and refuses drift or receipt paths outside settings/opt/bin and the owned host.
10The dispatcher supplies a strict versioned context file through VIBE_APPLICATION_CONTEXT and an owned reply path through VIBE_APPLICATION_REPLY. Context protocol is vibe-application-context/1; fields are operation, application { id, package { group, name, version }, installerPackage { group, name, version }, commands }, settingsRoot, hostRoot, registryRoot, vibeExecutable and offline. Paths are absolute; registryRoot is required for install/update and may be null for uninstall. The deterministic host is settingsRoot/opt/apps/application.id. Child execution uses structured arguments and a native runtime, without a shell-string evaluation.
11The installer writes vibe-application-result/1 with operation, applicationId, status (ready, undeployed or failed), hostRoot, management (runtime node and absolute entry, or null), commands and message. Success requires both exit zero and a matching validated reply. Ready replies must bind an existing retained management entry inside the owned host; original-source paths are invalid management entries. Failures never overwrite the prior successful application binding. A returned ready state does not replace the application's own deploy receipts.
12The generic user-local application index binds the requested package, exact selected provider, application id, host, retained management entry, advertised commands and latest successful state. Mutation is serialized. An application id already bound to another coordinate is refused. Records and paths are validated before dispatch. The underlying application owns its build and lifecycle machinery; published commands remain owned by the existing deployment provider's receipts. Uninstall invokes the retained management entry without resolving the original registry and preserves the documented user data and cache boundary. No implicit purge or machine-wide PATH mutation occurs.
13A deterministic fake application and colocated simulation exercise the generic CLI without LLM calls: binary-capable bridge selection without source resolution, lazy source fallback, dispatch, current-project preservation, strict reply failure, identity and path refusal, update retention and uninstall with original sources absent. Root acceptance uses an isolated settings directory and the real application through the new CLI, verifies that the normal binary install never starts a tracked-source clone, then verifies short launcher help, headless/browser startup, update and source-independent receipt-owned uninstall.