# What a project contains {#root}

@status:doc/work @audience:user

[p01] After 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.

[p02]
```sh
vibe tree --plain --path hello-vibe
```

```output
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 {#the-files}

[p03] Start with the two files at the root, because everything else is derived from them.

[p04] `vibe.toml` is the *[manifest](../glossary/index.xml#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](../glossary/index.xml#registry) to fetch them from. It is the only file a teammate needs to reproduce your setup, together with the [lock file](../glossary/index.xml#lock-file) beside it.

[p05] `vibe.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](../glossary/index.xml#fingerprint) of each package's content. With it, a fresh clone installs the same bytes on any machine.

[p06] Below them sits one directory, `vibevm/`, with three children. This layout is the same in every project and every package, and it is not configurable.

> [p07] The layout: every project and every package carries ONE
> distinctive root directory `vibevm/`, holding `vibevm/vibespecs`
> (was `spec/`), `vibevm/vibepacks` (was `packages/`),
> `vibevm/vibedeps` (was root `vibedeps/`) and `vibevm/vibefacts`
> (was root `vibefacts/`). Nothing else moves; `vibe.toml` stays at
> the project root.
>
> <spec://org.vibevm.core/vibevm/common/PROP-052#THE-LAYOUT>

[p08] `vibevm/vibespecs/` is *your* tree: the [specifications](../glossary/index.xml#specification) 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.

[p09] `vibevm/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.

> [p10] `vibedeps/` is **committed** to the repository. A fresh clone is immediately bootable with no `vibe install`; the dependency corpus is visible and diffable; this matches the spec-driven principle that the committed spec corpus is the product.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-workspace/PROP-009#VIBEDEPS-COMMITTED>

[p11] `vibevm/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 {#the-boot-files}

[p12] The 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.

> [p13] Both artifacts are generated, git-tracked, and marked "generated — do not edit".
>
> <spec://org.vibevm.core/vibevm/modules/vibe-workspace/PROP-009#ARTIFACTS-GENERATED>

[p14] The agent finds the boot files through a short [managed block](../glossary/index.xml#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.

> [p15] `vibe` reads and rewrites only the content *between* the markers; every byte outside the block is treated as another tenant's property and preserved verbatim across every `vibe` operation.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-workspace/PROP-012#OUTSIDE-PRESERVED>

## Who writes what {#who-writes-what}

[p16]
| 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 |

[p17] The last row is the project's scratch space: caches and internal state, ignored by git and safe to delete. The machine-wide [store](../glossary/index.xml#store) of fetched packages is elsewhere, in your home directory, and is shared by every project on the machine.

> [p18] The `.vibe/` cache directory is gitignored and per-project.
>
> <spec://org.vibevm.core/vibevm/common/PROP-000#VIBE-DIR-IGNORED>

[p19] One 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](../glossary/index.xml#anchor) that disappeared or moved.

> [p20] **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.toml` for the host's own `spec/` tree, `vibefacts/<group>.<name>.toml` per 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.
>
> <spec://org.vibevm.core/vibevm/common/PROP-046#REGISTRY-HOME>

> [p21] **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); `adopt` fills absent entries only and reports added/kept (W2).
>
> <spec://org.vibevm.core/vibevm/common/PROP-046#LAW-SOVEREIGNTY>

> [p22] **`vibe 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).
>
> <spec://org.vibevm.core/vibevm/common/PROP-046#CLI-FACTS>

> [p23] **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 clean` is the revision pass that removes orphaned overlays of vanished packages; on dependency UPGRADE, `vibe facts sync` reports anchors that disappeared or moved (orphaned entries with candidates) rather than dropping them — the tombstone discipline, applied to overlays. Landed in W3: lockfile-driven `clean` with dry-run and named removals, the attended-only uninstall dialog (automation flags never imply consent to delete adoption data), spec.toml never an orphan.
>
> <spec://org.vibevm.core/vibevm/common/PROP-046#LAW-LIFECYCLE>

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

[p24] If you delete `vibevm/vibedeps/` or the generated boot files, `vibe reinstall` rebuilds them from the lock file and the store without touching the network.

> [p25] Without `--force` it recomputes the materialisation and the boot artifacts from the existing `vibe.lock` and the local cache — no fresh resolution.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-workspace/PROP-009#REINSTALL-NO-FORCE>

[p26] If 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.

> [p27] **L3 — no legacy reading.** The old layout is not read and
> not migrated silently: a project carrying root `spec/` beside
> `vibe.toml` (or root `vibedeps/`/`vibefacts/`) fails loudly with
> the migration recipe. The owner's ground: no project in the world
> carries a root `vibevm/` today, so the new root is unambiguous and
> the old one is retired whole.
>
> <spec://org.vibevm.core/vibevm/common/PROP-052#NO-LEGACY-LAYOUT>

[p28] If 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.

