PROP-029 — Fully-qualified addresses and mechanical refactoring
01Status: accepted 2026-07-12 (owner-ratified). Builds on: spec://org.vibevm.core/vibevm/modules/vibe-registry/PROP-008#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.
1. Every address is fully qualified
02A package address MUST carry its full coordinate — group and name — in every occurrence across the project:
- 03The occurrences it binds: manifests, lockfiles,
spec://citations,scope!markers,DEVIATESlines, code comments, and docs. - 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).
- Nothing on disk stores a bare name.
04Why 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 <group>.<name> 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.
05In vibevm the coordinate takes three textual carriers, one identity:
| Carrier | Form | Example |
|---|---|---|
| pkgref (manifests, lockfiles, prose) | [<kind>:]<group>/<name> |
stack:org.vibevm.ai-native/rust-ai-native-lang |
spec:// authority (the <module> segment) |
<group>/<name> — the name is the first path segment |
spec://org.vibevm.ai-native/rust-ai-native-lang/GUIDE#anchor |
| repo name (flat, one segment) | <group>.<name> — / is illegal in a repo name; the name is the last label |
org.vibevm.ai-native.rust-ai-native-lang |
- 07Where the surface allows a
/(pkgref,spec://) the<group>/<name>coordinate is byte-identical, so one substitution renames both. - 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).
2. Why — mechanical refactoring
- 08A 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
#modulesunit describes. - 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.
- 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.
3. The mechanical-refactoring foundation
- 09Address 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.
- The reference implementation today is a scripted
sedtransform with grep verification and a specmap re-mint. - 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. - The engine is only possible while §1 holds — the day one bare name lands on disk, a rename needs a resolver again.
4. Scope and exceptions
- 10<status stage="spec" state="void">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 rootvibe.toml, addressedspec://org.vibevm.core/vibevm/…like every other package; §1 binds it too. The retired short authorityspec://vibevm/…parses (undotted-authority grammar survives for fixtures and legibility) and never resolves — the resolver answersLegacyHostAuthoritywith a rename hint naming the self coordinate. The self coordinate resolves to the workspace's own authoredspec/tree, never avibedeps/slot. Migration record: 1 893 living-surface occurrences rewritten in one pass, 2026-08-04; rationale:vibevm/vibespecs/design/host-as-package.xml. This tombstone stays so the old sentence's name is never reused and inbound links do not break.</status> - The self coordinate. The root project declares its package identity in
[project](group+name, PROP-008 semantics); its authoredspec/tree answers tospec://<group>/<name>/…— the self coordinate, matched by the resolver before any slot lookup and never versioned (@versionon it is an error). A project that declares nogrouphas no self coordinate, and its authored tree is unreachable by address. - 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. - Changing a package's
groupis a new package, not a rename (PROP-008 §2.2). <status stage="spec" state="done">This PROP governs how an address is written and how a migration is performed mechanically — not the identity semantics, which PROP-008 owns.</status>
Changelog
- 11[2026-07-12] Created — ratified alongside the
org.vibevm→org.vibevm.ai-native/org.vibevm.worldgroup restructure, the first refactor performed under §3. - [2026-07-14] The addressing principle (fully-qualified module authority, joiner-never-
.) was extracted to theaddressable-specsflow's#modulesunit (reaching vibevm through redbook); §1–2 now cite it and keep only vibevm's concrete carriers, the mechanical-refactoring foundation, and the scope rules. - [2026-08-04] The host exemption retired (B-031, owner-approved). The root project became the package coordinate
org.vibevm.core/vibevm;##SCOPE-HOSTis a tombstone,##SCOPE-SELF-COORDINATEcarries 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. - [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
<group>.<name>— a valid reversed FQDN, split at the last dot.##joiner-whyand##CARRIER-REPO-SWAPrecord the divergence from the addressable-specs#modulesletter and why its premise no longer holds; PROP-008 §2.1/§2.5 carry the grammar and the convention. Live_-joined repositories invibespecsrename as a follow-up (pre-public, host redirects cover old names).