Написать пакет flow
01Flow говорит агенту, как работает команда: как коммитить, что проверить перед пушем, как вести заметки между сессиями. Эта страница пишет такой пакет с нуля, включая короткий текст, который агент читает на каждом старте сессии.
Создай пакет flow org.acme/review-notes в текущем проекте VibeVM, как пакет в дереве под vibevm/vibepacks/. Он должен научить агента оставлять короткую заметку REVIEW.md в корне проекта после каждого сделанного изменения, с датой и описанием, что изменилось. Напиши стартовый фрагмент, документ протокола и манифест, затем запусти vibe check на пакете.
навык vibevm, установленный у вашего агента; проект с vibe.toml в корне
vibevm/vibepacks/org.acme/review-notes/v0.1.0/vibe.toml объявляет пакет flow со стартовым фрагментом; фрагмент короче двухсот слов и называет протокол по адресу; у документа протокола разделы с якорями; vibe check --path vibevm/vibepacks/org.acme/review-notes/v0.1.0 не находит ошибок
vibe check --path vibevm/vibepacks/org.acme/review-notes/v0.1.0 --quiettest -f vibevm/vibepacks/org.acme/review-notes/v0.1.0/vibevm/vibespecs/boot/review-notes.xml
Что происходит
03Агент выполняет vibe init package org.acme/review-notes: команда добавляет в проект слот пакета по пути vibevm/vibepacks/org.acme/review-notes/v0.1.0/: манифест с таблицей [package], README и фрагмент-заглушку. Собственный реестр проекта видит слот, так что flow можно установить и попробовать на месте до публикации. Затем агент пишет три вещи. Стартовый фрагмент — короткая инструкция, которую агент проекта-потребителя читает на каждом старте сессии. Протокол — полный набор правил под vibevm/vibespecs/flows/review-notes/, с разделами-якорями, которые цитирует фрагмент. Таблица [boot_snippet] манифеста указывает на фрагмент с категорией flow. Наконец агент запускает на пакете vibe check, который проверяет манифест и раскладку так же, как у любого проекта.
04 Decision. A package has the identical on-disk shape as a consumer project:
Руками
051. Создайте слот пакета:
072. Отредактируйте манифест, который написал скаффолд: поставьте kind = "flow", заполните описание и направьте [boot_snippet] на ваш фрагмент. Как сгенерировано:
093. Внутри слота напишите фрагмент по пути vibevm/vibespecs/boot/review-notes.xml. Держите его коротким: что делать и адрес правила, которое говорит почему. Его читает каждый агент, в каждой сессии, каждого проекта, который установил ваш flow.
104. Напишите протокол под vibevm/vibespecs/flows/review-notes/: один раздел с якорем на правило, одна мысль на раздел, маркер статуса на каждом.
115. Проверьте и опубликуйте:
Фрагмент — самая дорогая часть
13За фрагмент платит каждый потребитель на каждом старте сессии. Пишите его как инструкцию, а не как объяснение: назовите правило, адрес, команду. Рассуждения положите в протокол, где агент прочитает их один раз, когда понадобится. И никогда не предполагайте, что установлен другой пакет: фрагмент, который говорит «как требует протокол WAL», в проекте без этого протокола отправляет агента искать правило, которого нет. Если ваш flow строится на другом, объявите концепцию, на которую он опирается, и дайте vibe предупредить, когда концепции нет.
14 Everything is layered by mutation frequency — the whole loaded context is one monotone gradient (owner, 2026-08-23, near-verbatim: «всё в приложении устроено слоями; на самой вершине — динамическая загрузка быстрых изменений»). Reading order equals stability order: the rarest-changing text reads first, because a change at depth N re-prices every byte after it — the earlier a layer sits, the more cache its mutation burns. The concrete gradient: (0) the instruction files (CLAUDE.md/AGENTS.md/GEMINI.md) — read first, so an edit there resets the ENTIRE cache; they carry only what must hit every session (the four rules, the standing directives) and change only for large causes, everything else living in specs loaded later; (1) the generated STATIC lane — structural-events-only (§3), and INTERNALLY sorted by the same law: contributions of rarer-changing packages belong earlier in the tape; (2) the INDEX manifest and the conditional dynamic lane — per-boot variability; (3) the live session tail — task text, tool results, fast state, which lives in context and is never compiled into any lane. This is a GLOBAL architectural idea for all of VibeVM, not a spec of any one mechanism (owner, 2026-08-23): whenever a new system is designed or an existing one changed, the design review checks it against this layering — where does each byte it adds sit on the gradient, and does anything fast-changing sneak ahead of anything slow.
15
A boot snippet never presupposes another
discipline. A snippet speaks unconditionally only about its OWN flow;
any mention of another flow's artifacts or duties is CONDITIONAL — and the
only lawful conditional form is structural, not verbal: the mention lives in
a snippet fragment guarded by when = "installed:<group>/<name>", so the
text physically enters a project's lanes only when that discipline is
actually installed. Prose hedges («if you keep a WAL», «or equivalent») are
NOT the lawful form — they are unverifiable by machine and still teach the
concept unasked. This is ##THE-LAYER-LAW's sibling: a presupposition must
never travel ahead of its own discipline.
16Потребитель решает, как подключить ваш фрагмент: скомпилировать в приоритетную полосу или перечислить в INDEX.md; умолчание можно предложить в [boot_snippet], и выбор потребителя побеждает.
17 A package MAY declare a suggested default inclusion type in its own[boot_snippet]; the consumer's declaration always wins. Absent both, the type isdynamic.
Поднавыки: содержимое, которое приходит, когда нужно
18Пакет может разделить содержимое на поднавыки, мельчайшие единицы, которые агент может активировать: каждый выглядит как крошечный пакет с собственным манифестом и файлами. Различает поднавыки их delivery, главная ось: eager кладёт содержимое на диск при установке, lazy-push и lazy-pull придерживают его, пока не сработает правило активации. Поднавык активируется, когда совпадает любой из его каналов, один раз. Для ленивых режимов обязательно description, потому что оно и есть весь триггер, и vibe check отказывает ленивому поднавыку без него.
19 A subskill is the smallest activatable content unit inside a package. Structurally it looks like a tiny package: own manifest, own files, own optional further subskill children (§2.5.5). What changes per subskill is the delivery mode (§2.5.0 below) and the activation rules (§2.5.2): together they decide when the subskill's content reaches the agent and how.
20
A subskill's delivery field is the primary axis of the manifest, not a follow-up bolt-on. It picks how the subskill's content reaches the agent. Three values, each well-defined:
21 A subskill becomes "active" if any one of these channels matches. Channels compose orthogonally; an active subskill activates once regardless of how many matched. The full set, more comprehensive than revision r1:
22descriptionis required fordelivery = "lazy-push"andlazy-pull. The activation trigger is the entire mechanism for those modes — without it,vibe-mcphas nothing to match against.eagermode also benefits but is not required.vibe checkerrors out (not warns) on a lazy-push subskill missingdescription.
Что где лежит
23Пути даны относительно корня пакета, слота vibevm/vibepacks/org.acme/review-notes/v0.1.0/.
| Путь | Назначение |
|---|---|
vibe.toml |
манифест: [package], [boot_snippet], необязательные [[skill]], [requires] |
README.md |
что такое этот flow; показывается в реестре и на сайте |
vibevm/vibespecs/boot/<name>.xml |
стартовый фрагмент |
vibevm/vibespecs/flows/<name>/ |
протокол и сопутствующие документы |
vibevm/vibespecs/skills/<skill>/SKILL.md |
навыки, которые flow предлагает агентам, объявленные в [[skill]] |
LICENSE.md |
лицензия; в публичном реестре только разрешительные |
25 Prompt/spec content lives under the package'sspec/subtree — boot snippets (vibevm/vibespecs/boot/), cards, guides, manifesto, appendix — laid out exactly as an ordinary project'sspec/(VIBEVM-SPEC.md§4.2).[boot_snippet].sourceis aspec/-relative path (e.g.spec/boot/20-stack-rust-ai-native.md).
26Всё под корнем пакета, кроме результатов сборки, и есть пакет: это то, с чего снимается отпечаток, что копируется потребителям и что показывает сайт.
27 Decision. A package's shippable tree is its directory minus a build-output denylist:
28Пакет по умолчанию simple: его файлы переносятся целиком и читаются, потому что присутствуют. format = "normal" включает разделение на contract/, маленький и дешёвый для загрузки, как заголовочный файл, и source/, тяжёлое тело, которое подтягивается, только когда директива его попросит; нормальный пакет, которым никто не пользуется, в сборку не входит вовсе.
29format = "simple"— the default (absentformat, a package issimple). Legacy / adapted prompts, carried whole, with no VibeVM-specific structure — for importing existing corpora without rewriting them, and the fail-safe posture. Rules: inclusion in[requires.packages]means (a) structural — the agent reads the file; (b) static — its text is compiled into the target. If[boot_snippet].sourcenames a file, only that file is read/spliced; absent even that, every file in the package is read/spliced by a recursive walk — the over-load is the author's problem, the deliberate cost of not adoptingnormal.
30format = "normal"— the VibeVM-native form, opt-in: thecontract/sourcesplit (§4), directives (§7), and the compiler (§8). Anormalpackage is not read just because it is present — it participates only when something actually#uses it (§7.2). This is tree-shaking; the optimized posture for authors who understand the machinery, at the price of structuring the package correctly.
31
contract/ — small, simple, boot-snippet-like. The surface a package exposes outward; short files, cheap to load. The analogue of a header.
32
source/ — large, heavy. The full implementation; pulled only when actually needed. The analogue of a translation unit.
33 Tree-shaking default. Aformat = "normal"package that nobody#uses does not participate — not read, not used, anywhere. The moment any text does#use spec://…, that package enters the build and MUST be linked before its user in topological order.
Особые случаи и правила
34Перекрёстные ссылки внутри пакета — адреса, spec://org.acme/review-notes/flows/review-notes/PROTOCOL#anchor, а не относительные пути к файлам; они переживают копирование в любого потребителя.
35 L1 — physics moves, addresses do not.spec://addresses, anchors, fact ids, specmap edges,scope!citations and recorded verdicts are LOGICAL and do not change: only the physical prefix maps differently (vibevm/vibespecs/common/PROP-000.xmlstill canonicalises to the samecommon/PROP-000document path). Any relayout step that would rename an address is a defect of the step.
36 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.
37Пока вы разрабатываете пакет внутри того же репозитория, правьте его исходник и запускайте vibe install: изменение доходит до дерева зависимостей без флага, обновления или принудительной переустановки.
38 No new flag (consistent with §2.5). This is automatic and source-aware — the author edits the in-repo source and runsvibe install; nothing to remember, and neithervibe updatenorreinstall --forceis needed for the local-authoring loop, while those bypasses remain for the immutable case.
39Версии никогда не двигаются: чтобы изменить опубликованный фрагмент, поднимите версию и опубликуйте снова. Потребитель увидит изменение при следующем обновлении, не раньше.
40Flow может требовать другие пакеты; потребитель, который ставит ваш, получает и их, и их фрагменты входят в полосу потребителя после вашего.