<?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">Всё, что устанавливает vibe, — пакет: папка с небольшим файлом описания и тем текстом или инструментами, которые она приносит. Пакеты бывают восьми видов, и вид говорит, для чего пакет нужен, ещё до того, как вы его откроете: способ работать, фича, технология, инструмент, языковой гайд, сервер для агента, документация или приложение.</p>
  <example ref="list" p="2"/>
  <section id="a-package" title="Что такое пакет">
    <p p="3">Пакет — это проект, который сделали устанавливаемым. У него та же раскладка, что у проекта: собственный `vibe.toml` и собственный `vibevm/vibespecs/`, и рядом может лежать код. Когда проект его ставит, опубликованное дерево пакета копируется в дерево зависимостей проекта дословно; ничего не извлекается, не переписывается и не сливается.</p>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-052#PACKAGES-CARRY-THE-LAYOUT-TOO" p="4"/>
    <p p="5">Пакет называется *[координатой](../glossary/index.xml#coordinate)*: группа, косая черта и имя, как в `org.vibevm.world/wal`. Группа похожа на перевёрнутое доменное имя и говорит, кто публикует; имя уникально внутри группы. Версия дополняет адрес, когда она нужна: `org.vibevm.world/wal@1.0.0`. Вид в имя не входит. Его можно написать префиксом в командной строке, `flow:org.vibevm.world/wal`, и тогда vibe проверит, что пакет действительно этого вида.</p>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-008#IDENTITY-TUPLE" p="6"/>
    <p p="7">Группа — заявление, а не удостоверение: никто не проверяет, владеет ли издатель `com.google/x` этим доменом, и никогда не проверит, потому что у vibe нет центрального проверяющего, которого можно спросить. Имя уникально внутри своей группы, так что координата сама по себе и есть идентичность. В командной строке префикс вида и группа необязательны; в [манифесте](../glossary/index.xml#manifest) координата всегда пишется полностью. В [реестре](../glossary/index.xml#registry) репозиторий называется группой и именем через точку, `org.vibevm.world.wal`, что само по себе корректное перевёрнутое доменное имя.</p>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-008#GROUP-IS-A-CLAIM" p="8"/>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-008#NAME-UNIQUE-IN-GROUP" p="9"/>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-008#PKGREF-GRAMMAR" p="10"/>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-008#SHORT-CLI-ONLY" p="11"/>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-000#IDENTITY-FORM" p="12"/>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-008#JOINER-UNDERSCORE" p="13"/>
    <p p="14">Где бы пакет ни назывался в проекте, стоит полная координата: `group/name` в требовании, `group.name` как имя репозитория, `group/name` как первый сегмент адреса `spec://`. Короткие имена живут только там, где человек один раз набирает их в командной строке.</p>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-029#ADDR-LAW" p="15"/>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-029#CARRIER-PKGREF-FORM" p="16"/>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-029#CARRIER-REPO-NAME-FORM" p="17"/>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-029#CARRIER-SPEC-URI-FORM" p="18"/>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-029#ADDR-SHORT-NAMES" p="19"/>
  </section>
  <section id="the-kinds" title="Восемь видов">
    <table p="20">
      <tr>
        <td>Вид</td>
        <td>Что приносит</td>
        <td>Пример</td>
      </tr>
      <tr>
        <td>`flow`</td>
        <td>способ работать: правила коммитов, заметки сессий, соглашения о ревью; обычно [стартовый фрагмент](../glossary/index.xml#boot-snippet), который агент читает каждую сессию</td>
        <td>`org.vibevm.world/wal`</td>
      </tr>
      <tr>
        <td>`feat`</td>
        <td>описание того, что построить, без слова о том, как</td>
        <td>страница приветствия, вход по электронной почте</td>
      </tr>
      <tr>
        <td>`stack`</td>
        <td>технологический контекст, который говорит, как с ним строится фича, или бандл членов семейства одной версии</td>
        <td>`org.vibevm.ai-native/rust-ai-native`</td>
      </tr>
      <tr>
        <td>`tool`</td>
        <td>скрипт или утилита, которую может вызвать шаг сборки</td>
        <td>обёртка над форматтером</td>
      </tr>
      <tr>
        <td>`lang`</td>
        <td>руководство о том, как писать на языке или в нотации</td>
        <td>`org.vibevm.ai-native/rust-ai-native-lang`</td>
      </tr>
      <tr>
        <td>`mcp`</td>
        <td>сервер, с которым разговаривает агент, собранный из кода самого пакета</td>
        <td>`org.vibevm.ai-native/rust-ai-native-mcp`</td>
      </tr>
      <tr>
        <td>`doc`</td>
        <td>документация других пакетов: читается, не устанавливается</td>
        <td>`org.vibevm.core/vibevm-docs`</td>
      </tr>
      <tr>
        <td>`app`</td>
        <td>самостоятельный продукт со своей выкладкой</td>
        <td>`org.vibevm.doc/web`</td>
      </tr>
    </table>
    <p p="21">Набор закрыт и растёт только поправкой к [спецификации](../glossary/index.xml#specification); [манифест](../glossary/index.xml#manifest) с неизвестным видом отвергается, а не угадывается.</p>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-000#KIND-SET" p="22"/>
    <p p="23">Вид — метаданные пакета, а не часть его идентичности: он решает, куда кладётся содержимое, что показывает фильтр `--kind` у `vibe list` и `vibe search` и принимается ли имя с префиксом вида. Два пакета разных видов не могут делить координату, потому что координата сама по себе и есть идентичность.</p>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-008#KIND-METADATA" p="24"/>
    <p p="25">`app` отличается от `tool` механически: инструмент живёт в проекте и запускается через `vibe bin exec` по [лок-файлу](../glossary/index.xml#lock-file), а приложение не живёт ни в каком проекте-потребителе и собирается и выкладывается само по себе.</p>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-057#KIND-APP-VS-TOOL" p="26"/>
  </section>
  <section id="families" title="Семейства и компаньоны">
    <p p="27">Некоторые [возможности](../glossary/index.xml#capability) приходят несколькими пакетами с общей основой имени: языковой гайд, сервер, который отдаёт его инструменты, и маленький бандл, который закрепляет оба на одной версии. Это *семейство*. Потребовать бандл — значит поставить семейство, а изменение любого члена поднимает всех до одной общей версии, так что части никогда не разъедутся.</p>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-028#UNISON-LAW" p="28"/>
    <p p="29">Сам бандл — самый маленький пакет из возможных: манифест и README, ни кода, ни [стартового фрагмента](../glossary/index.xml#boot-snippet). Его единственная работа — назвать членов семейства одной версии.</p>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-028#ROLE-AGGREGATOR" p="30"/>
    <p p="31">Документация — исключение. Руководство пакета — его *[компаньон](../glossary/index.xml#companion)* с суффиксом `-docs` в той же группе, и оно держит собственную линию версий. Исправленная опечатка в руководстве не выпускает инструменты, а новая версия инструмента не требует нового руководства. Руководство говорит, какие версии своего [предмета](../glossary/index.xml#subject) оно описывает, а сайт берёт самое новое руководство, которое подходит.</p>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-028#ROLE-DOCS" p="32"/>
  </section>
  <section id="on-disk" title="Как пакет ложится на диск">
    <p p="33">`[package].materialization` говорит, как пакет попадает в дерево потребителя. `copy` — умолчание и всё, что нужно обычному пакету; `hardlink` — то же содержимое, делящее байты с [хранилищем](../glossary/index.xml#store). Оба вендорятся: папка коммитится вместе с проектом и восстанавливается из него без сети. `in-place` держит живой git-чекаут с собственным `.git`, который git игнорирует и который свежий клон восстанавливает на закреплённом коммите, поэтому ему нужны сеть и [git-источник](../glossary/index.xml#git-source). Всё разрушительное над таким слотом — удаление, принудительная переустановка, смена версии — сначала спрашивает, а когда ответить некому, требует `--force`.</p>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-workspace/PROP-022#MODE-FIELD" p="34"/>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-workspace/PROP-022#SNAPSHOT-DEFAULT" p="35"/>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-workspace/PROP-022#VENDORED-COPY-MODES" p="36"/>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-workspace/PROP-022#IN-PLACE-NOT-VENDORED" p="37"/>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-workspace/PROP-022#IP-REQUIRES-GIT" p="38"/>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-workspace/PROP-022#DESTRUCTIVE-CONFIRM" p="39"/>
  </section>
  <section id="edge-cases" title="Особые случаи и правила">
    <p p="40">Смена группы или имени пакета создаёт новый пакет, а не переименовывает старый: версии не переносятся, а старые координаты никогда не используются повторно для другого содержимого.</p>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-008#GROUP-CHANGE-NEW-PACKAGE" p="41"/>
    <p p="42">Пакет документации нельзя установить в проект. `vibe install` отказывает и называет команду, которая вместо этого скачивает его для чтения.</p>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-057#KIND-DOC-NOT-INSTALLED" p="43"/>
    <p p="44">Короткое имя без группы, например `wal`, принимается в командной строке и разрешается через [индекс](../glossary/index.xml#index-registry) [реестра](../glossary/index.xml#registry); это удобство, а манифест всегда записывает полную координату.</p>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-008#ROW-SHORT-BEHAVIOUR" p="45"/>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-008#RESOLVE-ONCE-WRITE-QUALIFIED" p="46"/>
    <p p="47">Разрешить короткое имя можно только через индекс, по одному запросу на реестр; реестр без индекса коротких имён не предлагает, и нужна полная координата. Если лок-файл уже закрепил пакет с таким именем, короткое имя означает закреплённый. Когда два реестра предлагают под одним именем разные пакеты, vibe останавливается с кодом выхода 7 и перечисляет кандидатов, а вы повторяете команду с группой. Префикс вида проверяет результат и никогда не снимает неоднозначность, потому что два пакета разных видов не могут делить координату.</p>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-008#INDEX-DEPENDENCY" p="48"/>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-008#LOCKFILE-AUTHORITATIVE" p="49"/>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-008#COLLISION-BEHAVIOR" p="50"/>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-008#EXIT-CODE-7" p="51"/>
    <rule ref="spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-008#KIND-VALIDATION" p="52"/>
  </section>
</spec>
