<?xml version="1.0" encoding="UTF-8"?>
<spec xmlns="https://vibevm.org/spec/1">
  <title id="root">Remove VibeVM from a project</title>
  <status stage="doc" state="work" audience="user"/>
  <p p="1">When a project is finished and must leave without a trace of the tool that helped build it, one operation removes every vibe file and reference while keeping the product and its build intact.</p>
  <prompt id="scrape" p="2">
    Show me the scrape plan for the VibeVM project in the current folder, then export a scraped copy of it into a new folder named product-clean beside the project, and prove that the copy builds without vibe.
    <needs>the vibevm skill installed for your agent; a project with `vibe.toml` and a scrape contract adapted to it: `vibe scrape contract init` writes a conservative default that refuses to delete files whose modification it cannot prove and checks health with `cargo`; the project's native build tool on the `PATH`</needs>
    <outcome>`../product-clean` exists, holds no `vibevm/` directory, no `vibe.toml`, no `vibe.lock` and no managed block in the agent instruction files, and its native build and tests pass</outcome>
    <assert>test ! -e ../product-clean/vibe.toml</assert>
    <assert>test ! -e ../product-clean/vibevm</assert>
  </prompt>
  <section id="what-happens" title="What happens">
    <p p="3">The agent creates the contract with `vibe scrape contract init` if the project has none and adapts it: for vibe's own trees you never edited it sets `modified = "delete"`, and it keeps a health check that fits the project. It runs `vibe scrape --plan`, which reads the contract, classifies every file the tool ever wrote or marked, and prints the complete plan without writing anything: what is deleted, what is rewritten, what is kept under a neutral name. Then it runs `vibe scrape --output` with the absolute path of the new folder, which creates the scraped copy and runs the project's health checks on it; the original is untouched. The copy is a plain project of its language: no [manifest](../glossary/index.xml#manifest), no [lock file](../glossary/index.xml#lock-file), no dependency tree, no boot files, no [managed block](../glossary/index.xml#managed-block), no source annotations that pointed at [specifications](../glossary/index.xml#specification).</p>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-056#SCRAPED-TREE" p="4"/>
  </section>
  <section id="by-hand" title="By hand">
    <p p="5">1. Create the contract. The default is conservative: it names vibe's trees, refuses anything it cannot prove unmodified, and checks health with `cargo`:</p>
    <example id="scrape-contract" fixture="hello-cargo" p="6">
      <run>vibe scrape contract init --path hello-vibe</run>
      <expect>Scrape contract
  ✓ created  &lt;TMP&gt;/work/hello-vibe/vibevm/scrape/contract.toml
Review the contract, then run `vibe scrape contract check`.</expect>
    </example>
    <p p="7">2. Adapt it. A fresh project has no modification baseline for vibe's files, so the two `[[classify]]` rules refuse them as unknown. If you never edited those trees, set `modified = "delete"` on both. Replace the `[[healthcheck]]` if the project is not a Rust workspace. Then validate: `vibe scrape contract check --path hello-vibe`.</p>
    <p p="8">3. Look at the plan:</p>
    <example id="scrape-plan" fixture="hello-vibe-scrape" p="9">
      <run>vibe scrape --plan --path hello-vibe</run>
      <expect></expect>
    </example>
    <p p="10">4. Export to a new folder, which must not exist yet and is named without `..`:</p>
    <example id="scrape-output" fixture="hello-vibe-scrape" p="11">
      <run>vibe scrape --output hello-clean --path hello-vibe</run>
      <expect></expect>
    </example>
    <p p="12">5. Or [scrape](../glossary/index.xml#scrape) in place, which is a recoverable transaction and requires explicit authorisation: `vibe scrape --in-place --assume-yes`. If it is interrupted, `vibe scrape --recover --path &lt;root&gt;` settles the pending transaction.</p>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-056#SCRAPE-RECOVER-COMMAND" p="13"/>
    <p p="14">The commands in one place. `vibe scrape contract init` writes a conservative default only when none exists, and `contract check` parses and plans it without writing. `vibe scrape --plan` is read-only and, given no mode, plans the in-place form, the larger risk. `--output` creates the export in a folder that must not exist and never changes the source tree. `--in-place` runs the journaled transaction, shows the census of modified and deleted files when interactive, and unattended needs `--assume-yes` after a green plan. Planning and checking run everywhere; in this first epoch the mutating modes run on Windows only, where the safety mechanics have been proven.</p>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-056#SCRAPE-CONTRACT-COMMANDS" p="15"/>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-056#SCRAPE-PLAN-COMMAND" p="16"/>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-056#SCRAPE-EXPORT-COMMAND" p="17"/>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-056#SCRAPE-INPLACE-COMMAND" p="18"/>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-056#SCRAPE-EXECUTION-PLATFORM-E1" p="19"/>
  </section>
  <section id="the-contract" title="The contract">
    <p p="20">What counts as vibe's and what counts as yours is not guessed from file names; a contract says it. The contract lives at `vibevm/scrape/contract.toml` in the project: `vibe scrape contract init` writes the conservative default, `vibe scrape contract check` validates one, and `--contract &lt;file&gt;` reads another. A contained contract is the last file removed, so the plan can be re-read until the end.</p>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-056#DEFAULT-CONTRACT" p="21"/>
    <p p="22">A scrape never deletes a path blindly: a build script that calls a vibe tool, generated product sources that sit beside disposable generated state, an authored specification that shares a tree with generated boot output, all are dispositioned by the contract, and untouched files stay byte-identical.</p>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-056#PRODUCT-PRESERVATION" p="23"/>
    <p p="24">The contract is strict: unknown tables and values are rejected, `schema` is 1, and every id is unique. Files you wrote under `vibevm/vibespecs` are never taken for generated because of their folder; a contract that wants zero residue names them for deletion or relocation itself. Generated code, tests and models the project accepted are product and stay unless a row names them. Globs only select; bytes change only through typed adapters, never through a regex or a shell rewrite. Zero residue means zero registered identities, paths and markers, not the word «vibe» in your prose.</p>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-056#CONTRACT-STRICTNESS" p="25"/>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-056#AUTHORED-SPECS" p="26"/>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-056#PRODUCT-CODE-SURVIVES" p="27"/>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-056#TYPED-ONLY" p="28"/>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-056#ZERO-RESIDUAL-SCOPE" p="29"/>
    <p p="30">You supply the policy, the engine supplies the mechanics and the verdicts. Anything the sealed contract and the observed tree cannot decide is a blocker, never a guess. The tool does not rewrite git history, does not publish, and does not remove what was deployed to your machine; those stay explicit operations.</p>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-056#ALGORITHMIC-BOUNDARY" p="31"/>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-056#NON-GOALS" p="32"/>
  </section>
  <section id="edge-cases" title="Edge cases and rules">
    <p p="33">Scrape is not clean. `vibe clean` removes what vibe can regenerate and keeps the relationship; scrape removes the relationship itself, which is why it needs a contract, a health proof and a recoverable commit.</p>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-056#RELATED-CLEAN" p="34"/>
    <p p="35">`--output` and `--in-place` are mutually exclusive; a plan is always available before either.</p>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-056#SCRAPE-MODE-EXCLUSIVITY" p="36"/>
    <p p="37">The words attach and detach are reserved for a future live-tool relationship, such as connecting a debugger; scrape is never an alias for them.</p>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-056#SCRAPE-TERM-BOUNDARY" p="38"/>
  </section>
</spec>
