<?xml version="1.0" encoding="UTF-8"?>
<spec xmlns="https://vibevm.org/spec/1">
  <title id="root">Write a lang package</title>
  <status stage="doc" state="work" audience="author"/>
  <p p="1">A lang package teaches an agent how to write in a language or a notation: the idioms, the constraints, the shape of a good file. This page writes one and explains how vibe recognises it as a language discipline.</p>
  <prompt id="write-a-lang-package" p="2">
    Create a lang package org.acme/sql-style in the current VibeVM project, as an in-tree package under vibevm/vibepacks/: a guide on how our team writes SQL. Give it a boot snippet that names the three rules an agent must always follow, and a guide document with the full idioms, examples and the reasons behind them. Run vibe check on it.
    <needs>the vibevm skill installed for your agent; a project with `vibe.toml` at the root</needs>
    <outcome>`vibevm/vibepacks/org.acme/sql-style/v0.1.0/vibe.toml` declares `kind = "lang"` with a boot snippet; the guide under `vibevm/vibespecs/` has anchored sections the snippet cites; `vibe check` reports no errors</outcome>
    <assert>vibe check --path vibevm/vibepacks/org.acme/sql-style/v0.1.0 --quiet</assert>
    <assert>grep -q "kind = \"lang\"" vibevm/vibepacks/org.acme/sql-style/v0.1.0/vibe.toml</assert>
  </prompt>
  <section id="what-happens" title="What happens">
    <p p="3">The agent creates the package skeleton, writes the guide and its snippet the way a flow's are written, and sets the kind to `lang`. The difference from a flow is the genre, not the mechanics. A flow says how the team works; a lang package says how to write in something. The kind tells an agent, a [registry](../glossary/index.xml#registry) and the site which is which before the file is opened.</p>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-000#KIND-SET" p="4"/>
  </section>
  <section id="what-a-lang-is" title="What a lang package is, and is not">
    <p p="5">The genre is wider than programming languages: a guide to a query language, a configuration notation, a documentation dialect or a house style of a language all fit. What does not fit is a bundle of tools; that is a stack. The examples in the public registry are the AI-Native language guides for Rust, TypeScript and Go, each shipping a guide, a set of cards and a runnable toolchain.</p>
    <p p="6">An AI-Native language is recognised by one thing only: its dependency on the shared discipline core, `org.vibevm.ai-native/core-ai-native`. Not by its group, not by its name. A third party may publish its own language discipline in its own group and be recognised the same way, so the discipline is not a closed club.</p>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-028#FAM-CORE" p="7"/>
  </section>
  <section id="families" title="When a language brings tools">
    <p p="8">A language guide that also ships tools, a checker, a formatter, a type oracle, becomes a [family](../glossary/index.xml#family). The guide package is `&lt;family&gt;-lang`; a server package `&lt;family&gt;-mcp` serves the same tools to agents; a bundle `&lt;family&gt;` pins both at one version. The members move in unison; a consumer requires the bundle and gets a tested set.</p>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-028#FAMILY-DEF" p="9"/>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-028#UNISON-LAW" p="10"/>
    <p p="11">The family stem leads every named surface: crates, binaries, [skills](../glossary/index.xml#skill) and the server all carry the `&lt;family&gt;` prefix, so everything of one language sorts and reads together.</p>
    <rule ref="spec://org.vibevm.core/vibevm/common/PROP-028#SURFACE-NAMING-LAW" p="12"/>
  </section>
  <section id="by-hand" title="By hand">
    <p p="13">1. Create the package slot, then set `kind = "lang"` in its [manifest](../glossary/index.xml#manifest):</p>
    <example id="init-lang" fixture="project" p="14">
      <run>vibe init package org.acme/sql-style</run>
      <expect>Creating package `org.acme/sql-style` in `&lt;TMP&gt;/work`
  ✓ created  vibevm/vibepacks/org.acme/sql-style/v0.1.0/vibe.toml
  ✓ created  vibevm/vibepacks/org.acme/sql-style/v0.1.0/vibevm/vibespecs/boot/10-tool-sql-style.md
  ✓ created  vibevm/vibepacks/org.acme/sql-style/v0.1.0/README.md
  • kept     vibevm/vibespecs/boot/INDEX.md (regenerated)
  • kept     CLAUDE.md (regenerated)
  • kept     AGENTS.md (regenerated)
  • kept     GEMINI.md (regenerated)

Done. Project `org.acme/sql-style`: 3 files created, 4 kept.

Next:
  • edit vibevm/vibespecs/boot/00-core.md and vibevm/vibespecs/common as your project takes shape
  • install packages with `vibe install &lt;kind&gt;:&lt;name&gt;` (e.g. flow:wal)</expect>
    </example>
    <p p="15">2. Inside the slot, write `vibevm/vibespecs/boot/sql-style.xml` with the rules an agent must follow every time. Put the guide under `vibevm/vibespecs/lang/sql-style/`, with the reasons, the idioms and the examples.</p>
    <p p="16">3. Declare `[boot_snippet] source = "vibevm/vibespecs/boot/sql-style.xml"`, `category = "stack"`, so that the language rules come after the team's flows in a consumer's reading list.</p>
    <p p="17">4. Check: `vibe check --path vibevm/vibepacks/org.acme/sql-style/v0.1.0`.</p>
  </section>
  <section id="edge-cases" title="Edge cases and rules">
    <p p="18">What a language brought that can be run is answered by `vibe tools`, not by the kind: the [boot lane](../glossary/index.xml#boot-lane) says which disciplines are installed, the tools registry says what they brought.</p>
    <p p="19">Before the `lang` kind existed, language guides were stacks; a `stack` package that is really a guide should move to `lang` at its next version, so that the word means one thing.</p>
  </section>
</spec>
