<?xml version="1.0" encoding="UTF-8"?>
<spec xmlns="https://vibevm.org/spec/1">
  <title id="root">Собрать, упаковать и выложить проект</title>
  <status stage="doc" state="work" audience="user,author"/>
  <p p="1">Эта страница проводит проект от исходников до работающей выкладки тремя командами, показывает, что каждая оставляет на диске, и как снять выкладку, не гадая, чем она владела.</p>
  <prompt id="build-package-deploy" p="2">
    Для проекта VibeVM в текущей папке покажи мне план выкладки для профиля с именем local, затем выполни выкладку, перечисли выкладки, которые теперь есть на этой машине, и наконец сними тот же профиль. Остановись и спроси меня перед выкладкой и перед снятием.
    <needs>навык vibevm, установленный у вашего агента; проект, чей манифест объявляет артефакт сборки, цель выкладки с механизмом `deploy:vibe-bin` и профиль с именем `local`, как показывают таблицы на этой странице; `cargo` в `PATH`</needs>
    <outcome>план называет цели по порядку; после выкладки `vibe deployments` показывает профиль с поколением и статусом; после снятия каждый ресурс, которым владела квитанция, исчез, а список показывает профиль как снятый</outcome>
    <assert>vibe deploy --plan --profile local</assert>
    <assert>vibe deployments --json</assert>
  </prompt>
  <section id="what-happens" title="Что происходит">
    <p p="3">`vibe deploy --plan` прогоняет весь [жизненный цикл](../glossary/index.xml#lifecycle) `default` в режиме планирования и печатает, что сделала бы каждая [фаза](../glossary/index.xml#phase), заканчивая упорядоченными целями профиля; ничего не записывается. Настоящий `vibe deploy` затем проверяет, ставит, генерирует, собирает, тестирует, создаёт, верифицирует и упаковывает, пропуская каждый шаг, чьи входы не изменились, и применяет упакованные артефакты к целям профиля по порядку. На каждый созданный ресурс он пишет *[квитанцию](../glossary/index.xml#receipt)*: что и куда положено, под каким поколением, каким профилем владеется. `vibe deployments` читает квитанции, которые есть на этой машине. `vibe undeploy --profile local` обходит квитанции в обратном порядке зависимостей и удаляет ровно то, чем они владеют, отказываясь трогать путь, который изменился после выкладки.</p>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-054#R8-DEPLOY-RUNTIME" p="4"/>
  </section>
  <section id="by-hand" title="Руками">
    <p p="5">1. Объявите, что собирать, что выкладывать и куда. Цель называет артефакт и механизм, который его размещает; профиль — упорядоченный список целей:</p>
    <fence lang="toml" p="6">[[artifacts.build]]
id = "build-hello"
mechanism = "build:cargo"
outputs = [{ id = "hello", kind = "executable", select = { package = "hello", bin = "hello" } }]
config = { offline = true }

[[deploy.target]]
id = "local"
artifact = "hello"
mechanism = "deploy:vibe-bin"
config = { command = "hello" }

[deploy]
default_profile = "local"

[deploy.profiles.local]
targets = ["local"]</fence>
    <p p="7">Механизм `deploy:vibe-bin` размещает исполняемый файл как лаунчер в собственной папке `bin/` vibe на этой машине. После этого команда запускается из любого терминала; остальные механизмы перечислены в [спецификации](../glossary/index.xml#specification).</p>
    <p p="8">2. Соберите дистрибутивы, не трогая ни одного места назначения:</p>
    <example ref="package" p="9"/>
    <p p="10">3. Посмотрите план для профиля, затем выложите его:</p>
    <example ref="deploy-plan" p="11"/>
    <p p="12">4. Перечислите, что есть на этой машине, и снимите профиль:</p>
    <example ref="deployments" p="13"/>
    <p p="14">`vibe undeploy --profile &lt;name&gt;` откатывает этот профиль. Список никогда не показывает секретов.</p>
  </section>
  <section id="artifacts" title="Артефакты и цели">
    <p p="15">[Манифест](../glossary/index.xml#manifest) объявляет, что производит `build` и что собирает `package`, как цели-артефакты с зависимостями между ними. vibe сводит их в один проверенный граф и записывает каждый произведённый артефакт. Поэтому `package` потребляет ровно то, что проверил `build`, а `deploy` применяет ровно то, что собрал `package`. Артефакт или цель может объявить операционные системы, к которым относится, и цель, которая к текущей машине не относится, пропускается с пометкой.</p>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-054#R8-ARTIFACT-RUNTIME" p="16"/>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-054#R8-PLATFORM-APPLICABILITY" p="17"/>
    <p p="18">[Профиль выкладки](../glossary/index.xml#deploy-profile) называет свои цели по порядку и [провайдера](../glossary/index.xml#provider), который применяет каждую: папка на этой машине, проектная или пользовательская конфигурация агента и те жанры, что перечисляет спецификация. Установленный пакет может заменить встроенного провайдера точным пином, так что команда может поставлять собственный способ выкладки.</p>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-054#R8-NATIVE-DEPLOY-PROVIDER" p="19"/>
  </section>
  <section id="edge-cases" title="Особые случаи и правила">
    <p p="20">Две выкладки одного профиля не гоняются наперегонки: движок берёт замок от столкновений на профиль, и вторая ждёт или отказывается, но никогда не перемешивается с первой.</p>
    <p p="21">Квитанция — единственное основание для удаления. Если файл, которым владеет квитанция, правили после выкладки, `undeploy` оставляет его на месте и говорит об этом, вместо того чтобы удалить чью-то работу.</p>
    <p p="22">`--force` у глагола жизненного цикла игнорирует записанные [отпечатки](../glossary/index.xml#fingerprint) на один прогон; смысла прогона он не меняет.</p>
    <p p="23">Фаза выкладки применяет упакованные артефакты и ничего больше: шаг, которому нужен агент, например написать заметки о выпуске, принадлежит `create` и выполняется, только когда проект его включает.</p>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-054#PHASE-CREATE" p="24"/>
  </section>
</spec>
