What a project contains
01After the first install, a project holds a handful of files you wrote and a larger set that vibe wrote for you. This page names each of them and says who is allowed to change it, so nothing you edit gets overwritten and nothing vibe generates gets edited by hand.
vibe tree --plain --path hello-vibe
project: <TMP>/work/hello-vibe
STATIC.md: (none)
packages: 1 roots: 1
columns: load T=transitive C=condition S=in STATIC.md
org.vibevm.world/wal dynamic . . .
The files, one by one
03Start with the two files at the root, because everything else is derived from them.
04vibe.toml is the manifest. You write it, or vibe init writes the first version for you. It names the project, lists the packages it requires with a version range for each, and lists the registries to fetch them from. It is the only file a teammate needs to reproduce your setup, together with the lock file beside it.
05vibe.lock is the lock file. vibe writes it, you commit it, and you never edit it. It records the exact version of every package that was installed, including the ones your packages pulled in, and a fingerprint of each package's content. With it, a fresh clone installs the same bytes on any machine.
06Below them sits one directory, vibevm/, with three children. This layout is the same in every project and every package, and it is not configurable.
07 The layout: every project and every package carries ONE distinctive root directoryvibevm/, holdingvibevm/vibespecs(wasspec/),vibevm/vibepacks(waspackages/),vibevm/vibedeps(was rootvibedeps/) andvibevm/vibefacts(was rootvibefacts/). Nothing else moves;vibe.tomlstays at the project root.
08vibevm/vibespecs/ is your tree: the specifications and rules this project itself writes, in Markdown or in the project's XML dialect. vibe reads it and never writes into it, with one exception described below.
09vibevm/vibedeps/ is vibe's tree: one folder per installed package and version, holding that package's published files verbatim. You commit it, so a fresh clone is readable without running anything, but you never edit it. An edit there disappears at the next install.
10vibedeps/is committed to the repository. A fresh clone is immediately bootable with novibe install; the dependency corpus is visible and diffable; this matches the spec-driven principle that the committed spec corpus is the product.
11vibevm/vibepacks/ holds packages this repository develops in place: a project that also publishes packages keeps their sources here, and vibe treats the directory as a small local registry. Most projects do not have it.
The boot files
12The exception in your tree is vibevm/vibespecs/boot/. Two files there are yours: 00-core holds the project's foundations, 90-user holds your personal overrides, and vibe never touches either. Two files there are generated: INDEX.md, a manifest of what the agent reads, always present, and STATIC.md, the text it reads first and in full, present only when some package asked to be read that way. Both carry a header saying they are generated; the header is not decoration.
13 Both artifacts are generated, git-tracked, and marked "generated — do not edit".
14The agent finds the boot files through a short managed block at the end of CLAUDE.md, AGENTS.md and GEMINI.md, between the lines <vibevm> and </vibevm>. vibe rewrites what is between the two markers and nothing else in those files; the rest of the file is yours, and so is the position of the block once it exists.
15vibereads and rewrites only the content between the markers; every byte outside the block is treated as another tenant's property and preserved verbatim across everyvibeoperation.
Who writes what
| File or directory | Written by | Committed | Edited by hand |
|---|---|---|---|
vibe.toml |
you (first version by vibe init) |
yes | yes |
vibe.lock |
vibe | yes | never |
vibevm/vibespecs/ |
you | yes | yes |
vibevm/vibespecs/boot/00-core, 90-user |
you | yes | yes |
vibevm/vibespecs/boot/INDEX.md, STATIC.md |
vibe | yes | never |
vibevm/vibedeps/ |
vibe | yes | never |
vibevm/vibepacks/ |
you, when the repository develops packages | yes | yes |
the <vibevm> block in agent instruction files |
vibe | yes | only its position |
.vibe/ |
vibe | no | never |
17The last row is the project's scratch space: caches and internal state, ignored by git and safe to delete. The machine-wide store of fetched packages is elsewhere, in your home directory, and is shared by every project on the machine.
18
The .vibe/ cache directory is gitignored and per-project.
19One more folder appears once a project starts keeping track of which rules of its packages it has adopted: vibefacts/, committed, one small TOML file per package. Installing a package copies none of the author's statuses into it; adopting them is a deliberate act, vibe facts adopt, and vibe facts is the lever for everything else, listing, setting a status by address, syncing and reporting. Removing a package asks whether to keep or clean its adoption file; vibe facts clean removes the files of packages that are gone, and after an upgrade vibe facts sync reports the anchors that disappeared or moved.
20 Home and format.vibefacts/at the project root, tracked in git (it is project state a teammate must see), one TOML file per source:vibefacts/spec.tomlfor the host's ownspec/tree,vibefacts/<group>.<name>.tomlper installed package (the vibedeps slot-naming convention). Grep-friendly, small diffs, per-package lifecycle: removing a package's overlay is removing one file. Landed in W1.
21 L1 — consumer sovereignty: imported statuses are ignored. On package import the authored statuses in the package source are NOT copied into the registry — the package may use them for its own internal purposes, and the consumer's adoption state starts indeterminate. Acceptance of authored statuses is a deliberate act, never a default:vibe facts adopt --package <X> [--from-source] [filter]bulk-copies the author's statuses into the overlay in one auditable gesture (the escape hatch for implementation-shipping packages whose facts are done-by-construction). Landed: import never touches the registry by construction (W1);adoptfills absent entries only and reports added/kept (W2).
22vibe facts— the explicit lever. CRUD over the registry, search by attributes (package, status, stage, indeterminate-only), status transitions (vibe facts set <address> <status>),adopt(L1),sync(L2),clean(L5), and the adoption report (vibe facts report [--package X]— «12/40 adopted»). An agent flips a fact through the tool — an auditable command — never by editing derived files. Landed across W1–W3: list/get/set/rm/sync (W1), adopt with point re-derivation (W2), clean and the per-package report with?for unavailable denominators (W3).
23 L5 — lifecycle: removal keeps, cleaning reports. Removing a package does not silently erase its overlay;vibe uninstall(the CLI verb; built out if found unimplemented) asks whether to clean or keep the package's facts file.vibe facts cleanis the revision pass that removes orphaned overlays of vanished packages; on dependency UPGRADE,vibe facts syncreports anchors that disappeared or moved (orphaned entries with candidates) rather than dropping them — the tombstone discipline, applied to overlays. Landed in W3: lockfile-drivencleanwith dry-run and named removals, the attended-only uninstall dialog (automation flags never imply consent to delete adoption data), spec.toml never an orphan.
Edge cases and rules
24If you delete vibevm/vibedeps/ or the generated boot files, vibe reinstall rebuilds them from the lock file and the store without touching the network.
25 Without--forceit recomputes the materialisation and the boot artifacts from the existingvibe.lockand the local cache — no fresh resolution.
26If a project from before the current layout carries a root spec/ folder, vibe stops with a migration recipe rather than guessing. Old layouts are not read silently.
27 L3 — no legacy reading. The old layout is not read and not migrated silently: a project carrying rootspec/besidevibe.toml(or rootvibedeps//vibefacts/) fails loudly with the migration recipe. The owner's ground: no project in the world carries a rootvibevm/today, so the new root is unambiguous and the old one is retired whole.
28If you write into vibevm/vibedeps/ by accident, nothing breaks immediately; the next install overwrites the edit, because a package's folder there is a verbatim copy of what was published.