Design rationale: the host becomes a package — org.vibevm.core/vibevm (B-031)
01Companion to: BACKLOG.md B-031 (closed by 1ef63a37) (the commissioning entry — the owner's 2026-08-02 direction verbatim), PROP-029 §4 (##SCOPE-HOST — the one contract line this design retires), PROP-035 §6 (the unified grammar and router the host joins), BACKLOG.md B-028 (closed by 93d92ec9) (the adjacent flow-grammar ruling, deliberately not folded in), and the census this design stands on: campaigns/packages-2026-09/harvest/e5-b031-evidence.md.
02Authority: non-normative proposal. On approval it lands as PROP edits (§7) and this document stays as the lore behind them.
1. The mandate and the true size
03The owner's direction (2026-08-02, recorded in B-031, verbatim): «не логичней ли самому корневому пакету vibevm в vibe.toml дать нормальное fully-qualified имя как у всех остальных пакетов, и дальше чтобы все ссылки работали по обычным правилам, без исключений? Резолвер при этом должен начать учитывать … адресацию внутри vibe.toml ВЕЗДЕ, включая корневой пакет. Таким образом мы теряем короткую нотацию spec://org.vibevm.core/vibevm/..., но получаем универсальность. Я бы назвал корневой пакет spec://org.vibevm.core».
04The census reshapes the filing's numbers (all figures: the E5 evidence, commands cited there). The filing's «1 384 цитаты» was the crates-only figure; the whole living tree carries 2 351 occurrences of spec://org.vibevm.core/vibevm: crates/ 1 375, campaigns/ 607 (of which 500 are historical evidence JSON), packages/ 322 (314 in canonical package sources — the cross-boundary half), spec/ 33, root md 12, xtask 2. Of the crates figure, ≈343 are synthetic test fixtures (spec://org.vibevm.core/vibevm/x/y#a and kin) and 95 cite the real root doc VIBEVM-SPEC (registered via specmap.toml's root_spec_docs). And the «exceptions» turn out narrower than filed: the contract carve-out is exactly one line (PROP-029:43 ##SCOPE-HOST; PROP-035 carries no host language at all), while the code's special-case is one resolver arm (spec_root, resolver.rs:66-77), one enum variant (Authority::Host, 6 sites), two HOST_NAMESPACE = "vibevm" constants, and specmap.toml:14 namespace = "vibevm".
05The «second half of the exceptions» dissolves on evidence. Doc-id truncation (PROP-000 → PROP-000….md) was filed as a host exception; the sweep shows resolve_doc is authority-agnostic (resolver.rs:60-63 — the same prefix-scan for host and packages) and package citations already use it (190 occurrences, 165 of them the real org.vibevm.ai-native → PROP-014). Truncation is not host-special and B-031 does not touch it; whether the flow publishes the rule is B-028's question and stays there.
2. The design in one paragraph
06The root project gains a package identity — group org.vibevm.core, name vibevm (the owner's ruling, 2026-08-04), address prefix spec://org.vibevm.core/vibevm/… (the joiner is / never ., PROP-035 §6; the manifest's name = "vibevm" does not change — only group is added). The resolver's host mapping dies: spec_root maps the self coordinate — the workspace's own [project] identity — to ws_root/spec exactly where it today maps the vibevm token, and every other authority resolves as a package slot; nothing else in resolution changes. The spec://org.vibevm.core/vibevm/… notation stops resolving: an address whose authority is not a known coordinate fails loudly with the rename hint («the host is org.vibevm.core/vibevm since B-031») — the B-011 fail-with-candidates posture, never a silent alias. One scripted, reviewed migration rewrites the living surfaces in one commit; historical machine records stay as written; the affected registry anchors re-judge through the standing seal path. Universality is the whole point: after this, §1 of PROP-029 binds everything, and the sentence «the root project is not a package with a group» is retired rather than exempted.
3. The load-bearing details
07Identity carrier. vibe.toml [project] gains group = "org.vibevm.core"; its name = "vibevm" does not change — the identity IS the coordinate (PROP-008: identity = (group, name)), and the ruled form keeps the manifest name intact, so nothing renames anywhere (the owner's ruling, 2026-08-04). The lockfile today carries no root identity block (evidence §7b) and does not need one — the resolver reads the self coordinate from the manifest it already has.
08Resolver shape. FileResolver::new(ws_root, host_namespace) becomes FileResolver::new(ws_root, self_coordinate) — the constructor takes the root's (group, name) instead of the undotted token; spec_root matches Authority::Package{group, name, ..} against the self coordinate first (→ ws_root/spec), then falls to the vibedeps slot lookup. The Authority::Host parse variant survives — an undotted authority is grammatically legal (PROP-029:44 keeps illustrative fixtures like spec://demo/… as written, and legacy addresses must fail legibly) — but no undotted authority resolves: the resolver's Host arm becomes one unconditional error carrying the migration hint. The two HOST_NAMESPACE constants die with their call sites. VIBEVM-SPEC keeps resolving through specmap.toml's root_spec_docs under the new namespace value.
09specmap.toml:14 — namespace = "vibevm" becomes the self coordinate ("org.vibevm.core/vibevm"). The build verifies the specmap engine treats the value as an opaque prefix (expected — it mints spec://{namespace}/… strings); if anything parses it, that surfaces in the slice as a named finding, not a silent fix. The specmap engine is vendored ×6, so any engine change (none expected) vendors forward the same pass.
10Migration. A python script under the campaign zone (reviewable, idempotent, dry-run first) rewrites spec://org.vibevm.core/vibevm/ → spec://org.vibevm.core/vibevm/ and bare spec://org.vibevm.core/vibevm (grammar tests) accordingly, across the living surfaces: *.rs (fixtures included — spec://org.vibevm.core/vibevm/x/y#a becomes spec://org.vibevm.core/vibevm/x/y#a, exercising the self-coordinate path; the handful of tests that assert the Host mapping itself are rewritten to assert the new error), *.md (spec/, campaigns/ docs, packages/ canonical, root), *.toml, xtask. Historical machine records are not rewritten: the 500 campaign evidence/baseline JSONs are dated records of what the tree said at their HEAD (the campaign's own-corpus law), and the registry keys anchors by file-path, never by these literals — so nothing downstream re-keys. The 314 canonical-package occurrences are in-slot edits accumulating to the pre-publication boundary per the release ruling (no version bumps now); cargo xtask sync-engines carries the crate-side ones forward.
11Re-judgements riding the landing. The two deferred ledger rows this build was named for — F-169 (2 anchors) and F-147 (3 anchors, its planning-granularity half B-032's) — re-judge after the migration per #close-2026-08-03; host-zone anchors whose fact texts carry migrated literals re-seal through mirror → merge-verdicts → seal, never chained. The B-011 lane preamble sentence («full spec:// addresses resolve against package sources under vibedeps/») gains the self-coordinate clause in the same generated-text edit.
4. What deliberately does not change
12Doc-id truncation (already universal; flow legalization = B-028). The flow-published grammar (B-028's ruling). SCOPE-FIXTURES — illustrative addresses stay as written. Disk layout — spec/ stays where it is; no file moves, no renames. The specmap engine (a config value changes, not the engine). Historical campaign JSON. Publication and version numbers (the release ruling stands).
5. Risks, named
13Two resolvers, one grammar. FileResolver (vibe-spec) and the specmap engine both resolve host addresses; the design changes one code path and one config value, and the build's acceptance must exercise both (a vibe check-class pass + a specmap re-mint over the migrated tree).
14A ~1 800-occurrence rewrite is a mass edit. Mitigations: scripted with a dry-run diff the boss reads; the panel and both gates green before commit; the lane regenerated and byte-compared (only expected lines move); anchors re-judged verdict-first rather than assumed.
15Muscle memory and stale citations. Every future hand-typed spec://org.vibevm.core/vibevm/… fails loudly with the hint — that is the designed behaviour, not a regression; the PROP-029 changelog carries the rename record (the addressable-specs tombstone law applied to an authority).
5.1 The refactor's own metadata survives the rename — the owner-assigned check, executed
16The owner's fourth point (2026-08-04, verbatim): «Также проверь что наш текущий рефакторинг не сломается от этого переименования (проверь сам, Fable!). То есть если мы для рефакторинга используем какие-то метаданные которые станут невалидными на следующем шаге от этого глобального переименования (например, метаданные progress), это проблема и с ней надо что-то делать.» Executed boss-side the same hour, layer by layer, each verified empirically:
- 17Campaign registry (progress metadata): keys are path-based, zero URI keys. Walked every key of
run/cache.json(142 literal occurrences — all inside evidence strings),run/state/corpus.json(142 — content),run/state/obligations.json(10 — evidence refs),baseline.json(217 — unit-text copies): 0 keys carryspec://org.vibevm.core/vibevmin any of them; anchors key as<file-path>#<ANCHOR-ID>, and anchor ids cannot syntactically contain an address. Verdict evidence strings are dated quotes and stay as written (the own-corpus law). The one obligation the landing carries: migrated files' seal hashes go stale, so W3 runsvibe progress mirror --campaign→ boss spot-checks the mechanical diff → mass re-seal of touched files — the seal's designed re-vouch («vouching for N verdicts against the text on disk»; per-file,refusedonly on substance —seal.rsverified). - specmap.json + the orphan ratchet: regenerated, consistently. The index carries 6 401 host-URI strings and 219 revision fields — and is engine-generated: the migration moves the
namespacevalue and the code-side#[spec(...)]/scope!literals in the same pass, so the re-mint is internally consistent; spec-unit↔code edges are preserved 1:1, so the orphan set (the ratchet's 37) does not move. The ratchet policy lives inspecmap.toml(exemptions), not in a URI-keyed baseline file — nothing to migrate there. - Revision pins
~rN(126 on living surfaces): unchecked today, therefore inert. The parser parses them and the resolver treats a pin as «a revision selector, not part of the identity» (address.rs:131), and no gate validates pin currency (the onlyrevisionhits outside vibe-spec are VVM/git, unrelated). The migration rewrites the address half of every pinned citation; the pins ride along. Recorded as a known-quiet surface: when a pin-checking engine lands (PROP-014's future half), it will see post-migration revisions — honest by construction. - The intent ledger: old slots become graceful misses by design. Cache keys hash URI-bearing subjects; the B-022 slice's structured key + the old-slot-is-a-soft-miss branch mean renamed subjects recompute instead of erroring — derived, git-ignored data.
baseline.json→ next-campaignrescan: seeing the rename is correct behaviour. The baseline is a close-out projection read by the next campaign'srescan --baseline; a rescan that flags migrated units as changed is doing its job (they did change) — re-verification, not breakage.
18Verdict: no metadata becomes invalid-and-load-bearing. Every surface is either path-keyed (stable), regenerated (consistent), unchecked (inert), soft-missing (recomputes), or honestly re-verified later. The two handling steps the landing MUST carry — the mass re-seal and the specmap/lane regeneration — are folded into §8's W3.
6. The forks the owner is asked to rule on
19Three forks, the boss's recommendation first. RULED 2026-08-04: (K) → the owner's own form — group org.vibevm.core, name vibevm (neither K1 nor K2 as presented: the group carries his full spelling, the manifest name never changes); (L) → L1; (P) → P1. The fork texts below stay as presented, the record of what was asked:
- 20(K) The coordinate's grammar form. (K1, recommended) group
org.vibevm, namecore→spec://org.vibevm/core/…— yourorg.vibevm.coremapped through the unified grammar (joiner/never.), landing in a group that already exists in the tree;[project]name becomescorewhile the product keeps the word «vibevm» everywhere human. (K2) grouporg.vibevm, namevibevm→spec://org.vibevm/vibevm/…— keeps the manifest name, diverges from your spelling and doubles the word. (K3) grouporg.vibevm.coreplus an invented name — mints a new group and still needs a name; nothing recommends it. - (L) What a
spec://org.vibevm.core/vibevm/…address does after the landing. (L1, recommended) hard error with the rename hint, no alias — the exception actually dies; migration is one commit; archives that keep the old form are dated records, not resolving surfaces. (L2) a resolving legacy alias for a transition period — keeps every consumer working but keeps the exception alive under a new name, and nothing external consumes host addresses today (the census: zero tools parse the host authority). - (P) The migration perimeter. (P1, recommended) all living surfaces (
*.rs,*.md,*.toml, xtask — ≈1 851 occurrences), historical evidence JSON untouched. (P2) rewrite the JSONs too — falsifies dated machine records for zero resolution gain (nothing resolves them). (P3) living-normative only (spec/ + crates/), campaign docs keep the old form — leaves ~600 markdown occurrences failing the L1 error in current campaign reading surfaces; refused by the loud-error design.
7. What becomes normative on approval
21PROP-029: ##SCOPE-HOST is retired-with-tombstone (the changelog records the authority rename and the self-coordinate rule: «the root project is a package at org.vibevm.core/vibevm; its docs resolve to the workspace's own spec/»); §1's binding sentence loses its host exemption. PROP-035 §6: one sentence — the router's self-coordinate mapping (the root's coordinate resolves to the authored spec/ tree, not a vibedeps/ slot). PROP-008: no edit (identity semantics already cover the root once it has a group). specmap.toml and the root vibe.toml change as §3. The B-031 backlog acceptance restates as: zero spec://org.vibevm.core/vibevm occurrences on living surfaces; both resolvers answer spec://org.vibevm.core/vibevm/…; the F-169/F-147 rows re-judged; panel green.
8. Implementation shape (after the ruling — the worker cut)
22Sequenced, one lane (the perimeters chain through the same crates): (W1) resolver + identity — vibe-core manifest [project].group, FileResolver self-coordinate, the Host-arm error with hint, the two constants retired, unit tests incl. the erroring legacy form (self-verify: check + targeted tests + clippy + wc -l ≤ 600); (W2) the migration script (dry-run mode, per-surface counts printed, idempotent) — boss reviews the dry-run diff, runs the wet pass, regenerates the lane and both indexes; (W3, boss) the §7 PROP edits, specmap.toml/vibe.toml identity, the §5.1 metadata pass — vibe progress mirror --campaign, the mechanical-diff spot-check, the mass re-seal of touched files — the re-judgements proper (F-169/F-147 through mirror → merge → seal, never chained), commits per topic, sync-engines for the vendored crate edits, panel, mirrors. The census's §3 site list is the perimeter map for W1; §1's per-area counts are W2's expected-diff oracle.