<?xml version="1.0" encoding="UTF-8"?>
<spec xmlns="https://vibevm.org/spec/1">
  <title id="root">PROP-029 — Fully-qualified addresses and mechanical refactoring</title>
  <status stage="spec" state="done" comment="B0 2026-07-24: accepted 2026-07-12, owner-ratified; re-marked at fact grain (re-pilot) same day"/>
  <p p="1"><fact id="status-line" status="spec/done">**Status:** accepted 2026-07-12 (owner-ratified). **Builds on:** [`spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-008#group`](../modules/vibe-registry/PROP-008-qualified-naming.xml#group) (the `group` field) and the **addressable-specs** flow, whose `#modules` unit defines the fully-qualified module authority and the joiner-never-`.` rule this PROP applies: `spec://org.vibevm.world/addressable-specs/flows/addressable-specs/ADDRESSABLE-SPECS-PROTOCOL#modules`.</fact></p>
  <section id="decision" title="1. Every address is fully qualified">
    <p p="2"><fact id="ADDR-LAW" status="spec/done" action="continue" actionstage="doc" audience="user,author">A package address MUST carry its full coordinate — `group` **and** `name` — in **every** occurrence across the project:</fact></p>
    <list ordered="false" p="3">
      <item><fact id="ADDR-SURFACES" status="spec/done">The occurrences it binds: manifests, lockfiles, `spec://` citations, `scope!` markers, `DEVIATES` lines, code comments, and docs.</fact></item>
      <item><fact id="ADDR-SHORT-NAMES" status="spec/done" action="continue" actionstage="doc" audience="user">Short or bare names survive only as a one-time human CLI input, resolved to the qualified form at the boundary (PROP-008 §2.6).</fact></item>
      <item><fact id="ADDR-NO-BARE-ON-DISK" status="spec/done">Nothing on disk stores a bare name.</fact></item>
    </list>
    <p p="4"><fact id="joiner-why" status="spec/done">Why the full coordinate is a self-contained global symbol is the addressable-specs `#modules` unit. On the **joiner** vibevm now diverges from that unit's letter by owner ruling (2026-08-13): the flat carrier joins with `.`, because the composite must obey real domain rules, and the unit's premise — «a dotted `&lt;group&gt;.&lt;name&gt;` hides the boundary» — does not hold here: the name grammar guarantees a single dot-free LDH label, so the **last dot** splits the boundary deterministically. That follow-up landed 2026-08-14: the upstream `#modules` unit no longer states joiner-never-`.` — it now carries the general law (`##A-JOINER-MUST-ADMIT-A-DETERMINISTIC-INVERSE-PARSE`: an out-of-alphabet separator, or a grammatical guarantee on one half, the guaranteed half deciding whether the first or the last occurrence is the boundary) and the flat-surface cost of a blanket ban (`##A-BLANKET-DOT-BAN-COSTS-THE-FLAT-SURFACES`). vibevm is therefore no longer a divergence from that unit but an instance of it, and the paragraph above records why the old letter fell rather than being deleted with it.</fact></p>
    <p p="5"><fact id="carriers-lead" status="spec/done">In vibevm the coordinate takes three textual carriers, one identity:</fact></p>
    <table p="6">
      <tr>
        <td>Carrier</td>
        <td>Form</td>
        <td>Example</td>
      </tr>
      <tr>
        <td><fact id="CARRIER-PKGREF" status="spec/done">pkgref (manifests, lockfiles, prose)</fact></td>
        <td><fact id="CARRIER-PKGREF-FORM" status="spec/done" action="continue" actionstage="doc" audience="user,author">`[&lt;kind&gt;:]&lt;group&gt;/&lt;name&gt;`</fact></td>
        <td><fact id="CARRIER-PKGREF-EXAMPLE" status="spec/done">`stack:org.vibevm.ai-native/rust-ai-native-lang`</fact></td>
      </tr>
      <tr>
        <td><fact id="CARRIER-SPEC-URI" status="spec/done">`spec://` authority (the `&lt;module&gt;` segment)</fact></td>
        <td><fact id="CARRIER-SPEC-URI-FORM" status="spec/done" action="continue" actionstage="doc" audience="author">`&lt;group&gt;/&lt;name&gt;` — the name is the first path segment</fact></td>
        <td><fact id="CARRIER-SPEC-URI-EXAMPLE" status="spec/done">`spec://org.vibevm.ai-native/rust-ai-native-lang/GUIDE#anchor`</fact></td>
      </tr>
      <tr>
        <td><fact id="CARRIER-REPO-NAME" status="spec/done">repo name (flat, one segment)</fact></td>
        <td><fact id="CARRIER-REPO-NAME-FORM" status="spec/done" action="continue" actionstage="doc" audience="author">`&lt;group&gt;.&lt;name&gt;` — `/` is illegal in a repo name; the name is the last label</fact></td>
        <td><fact id="CARRIER-REPO-NAME-EXAMPLE" status="spec/done">`org.vibevm.ai-native.rust-ai-native-lang`</fact></td>
      </tr>
    </table>
    <list ordered="false" p="7">
      <item><fact id="CARRIER-BYTE-IDENTITY" status="spec/done">Where the surface allows a `/` (pkgref, `spec://`) the `&lt;group&gt;/&lt;name&gt;` coordinate is byte-identical, so one substitution renames both.</fact></item>
      <item><fact id="CARRIER-REPO-SWAP" status="spec/done">The flat repo-name carrier swaps `/`→`.` (owner ruling 2026-08-13): GitHub / GitVerse names allow `[A-Za-z0-9._-]`, the dot is legal there, and with both halves LDH the whole composite is a valid reversed FQDN — a real domain string, split back at the last dot. The pre-ruling joiner was `_` (see PROP-008 §2.5 for the record and the rename of live `_`-joined repositories).</fact></item>
    </list>
  </section>
  <section id="rationale" title="2. Why — mechanical refactoring">
    <list ordered="false" p="8">
      <item><fact id="ADDR-STRUCTURE-FREE" status="spec/done">A fully-qualified address is structure-independent: it does not depend on where a package sits in the tree, which group currently owns it, or how its spec is filed — the stable global symbol the addressable-specs `#modules` unit describes.</fact></item>
      <item><fact id="ADDR-REFACTOR-PRECONDITION" status="spec/done">For vibevm that is the precondition for **deterministic, non-LLM address refactoring**: because every reference to a unit is the same self-contained string, a rename is a pure textual substitution.</fact></item>
      <item><fact id="ADDR-RENAME-IS-LOOKUP" status="spec/done">Change a name, a group, or an anchor, then rewrite every occurrence, and the inverse — a table lookup, not the judgment call a resolver-dependent short address would need.</fact></item>
    </list>
  </section>
  <section id="mechanical" title="3. The mechanical-refactoring foundation">
    <list ordered="false" p="9">
      <item><fact id="REFACTOR-LAW" status="spec/done">Address refactors — rename a package, move a group, rename a cited anchor — MUST be expressible as deterministic substitutions over fully-qualified strings, verified by grep-zero of the old coordinate.</fact></item>
      <item><fact id="REFACTOR-TODAY" status="spec/done">The reference implementation today is a scripted `sed` transform with grep verification and a specmap re-mint.</fact></item>
      <item><fact id="REFACTOR-TARGET" status="spec/done">The target is a first-class **rename engine** (a future FEAT) that takes `(old-coordinate → new-coordinate)` and rewrites every manifest, lockfile, spec URI, and marker, then regenerates the specmap and the derived lockfiles/vibedeps.</fact></item>
      <item><fact id="REFACTOR-DEPENDS-ON-LAW" status="spec/done">The engine is only possible while §1 holds — the day one bare name lands on disk, a rename needs a resolver again.</fact></item>
    </list>
  </section>
  <section id="scope" title="4. Scope and exceptions">
    <list ordered="false" p="10">
      <item><fact id="SCOPE-HOST" status="spec/void">&lt;status stage="spec" state="void"&gt;Retired 2026-08-04 by B-031 (owner-approved): the host exemption is gone — **the root project IS a package coordinate**, `group = "org.vibevm.core"`, `name = "vibevm"` in the root `vibe.toml`, addressed `spec://org.vibevm.core/vibevm/…` like every other package; §1 binds it too. The retired short authority `spec://vibevm/…` parses (undotted-authority grammar survives for fixtures and legibility) and **never resolves** — the resolver answers `LegacyHostAuthority` with a rename hint naming the self coordinate. The self coordinate resolves to the workspace's own authored `spec/` tree, never a `vibedeps/` slot. Migration record: 1 893 living-surface occurrences rewritten in one pass, 2026-08-04; rationale: [`vibevm/vibespecs/design/host-as-package.xml`](../design/host-as-package.xml). This tombstone stays so the old sentence's name is never reused and inbound links do not break.&lt;/status&gt;</fact></item>
      <item><fact id="SCOPE-SELF-COORDINATE" status="spec/work">**The self coordinate.** The root project declares its package identity in `[project]` (`group` + `name`, PROP-008 semantics); its authored `spec/` tree answers to `spec://&lt;group&gt;/&lt;name&gt;/…` — the *self coordinate*, matched by the resolver before any slot lookup and never versioned (`@version` on it is an error). A project that declares no `group` has no self coordinate, and its authored tree is unreachable by address.</fact></item>
      <item><fact id="SCOPE-FIXTURES" status="spec/done">**Test fixtures and grammar examples** (`spec://demo/…`, `spec://com.example.shop/…`, and the like) are illustrative, not real packages; they are out of scope and stay as written.</fact></item>
      <item><fact id="SCOPE-GROUP-CHANGE" status="spec/done">Changing a package's `group` is a **new package**, not a rename (PROP-008 §2.2). &lt;status stage="spec" state="done"&gt;This PROP governs how an address is written and how a migration is performed mechanically — not the identity semantics, which PROP-008 owns.&lt;/status&gt;</fact></item>
    </list>
  </section>
  <section id="changelog" title="Changelog">
    <list ordered="false" p="11">
      <item><fact id="CHANGELOG-CREATED" status="spec/done">[2026-07-12] Created — ratified alongside the `org.vibevm` → `org.vibevm.ai-native` / `org.vibevm.world` group restructure, the first refactor performed under §3.</fact></item>
      <item><fact id="CHANGELOG-EXTRACTED" status="spec/done">[2026-07-14] The addressing principle (fully-qualified module authority, joiner-never-`.`) was extracted to the `addressable-specs` flow's `#modules` unit (reaching vibevm through redbook); §1–2 now cite it and keep only vibevm's concrete carriers, the mechanical-refactoring foundation, and the scope rules.</fact></item>
      <item><fact id="CHANGELOG-B031" status="spec/work">[2026-08-04] **The host exemption retired (B-031, owner-approved).** The root project became the package coordinate `org.vibevm.core/vibevm`; `##SCOPE-HOST` is a tombstone, `##SCOPE-SELF-COORDINATE` carries the live rule, and the authority rename (`spec://vibevm/…` → `spec://org.vibevm.core/vibevm/…`, 1 893 living-surface occurrences) was performed under §3's mechanical-refactoring foundation in one scripted pass. Design record: [`vibevm/vibespecs/design/host-as-package.xml`](../design/host-as-package.xml).</fact></item>
      <item><fact id="CHANGELOG-DOT-JOINER" status="spec/done">[2026-08-13] **The flat carrier re-ruled to the dot join.** The owner's identity rulings («настоящие домены») narrowed group segments to LDH labels and made the repo-name carrier `&lt;group&gt;.&lt;name&gt;` — a valid reversed FQDN, split at the last dot. `##joiner-why` and `##CARRIER-REPO-SWAP` record the divergence from the addressable-specs `#modules` letter and why its premise no longer holds; PROP-008 §2.1/§2.5 carry the grammar and the convention. Live `_`-joined repositories in `vibespecs` rename as a follow-up (pre-public, host redirects cover old names).</fact></item>
    </list>
  </section>
</spec>
