VibeVM
Contents
On this page
en
Publisher
org.vibevm.core
Version
1.0.0latest
Audiences
Reading time
7 min
Rendered
Read aloud
never

The gate grows per-language units — config surface, coverage invariant, flag rule

01Companion to: BACKLOG.md B-029 (closed by 1ef63a37) (neutral/per-language gate key + the config-surface enrichment, ruling 2.1 recorded in the row), B-034 (closed by f882cd46) (gated-or-exempt for Go/TS), B-039 (closed by 1f048058) (mount R-001 on the TS gate); the fork it carries is TOOLING-MAP.md §5 №2. Evidence: e8-r1-config-census.md (the config surface), e8-r2-gate-units-census.md (units, FlagSites, rosters). Non-normative; the PROPs and the backlog rulings win.

1. The measured basis, in five lines

02(1) Only Rust has a gate-unit notion: validate_against_tree classifies cargo-crate dirs against gated_crates/[[exempt]], called only by the Rust driver (census R1 Q4). (2) Go and TS scan [go]/[typescript] roots into a flat file list — no unit enumerator, no lists, no invariant (R2 Q1–Q2). (3) An empty/mis-scoped per-language roots inside a present conform.toml is a silent green for Go/TS; Rust is guarded by warn_vacuously_gated + the count summary (R1 Q8, R2 Q3). (4) The literal FlagSites mount on TS is impossible today: the rule keys on Fact::Ctor and cell(…)-attributed items, both emitted only by the Rust frontend; TS lacks the facts, the config field, and the cell-type notion (R2 Q4). (5) The migration surface of the root keys is tiny — three live gated_crates carriers, all Rust projects; Go/TS carriers: zero (R1 Q5–Q6).

2. The fork — RULED by the owner (map §5 №2, 2026-08-04)

03The units, ruled. On the presentation the owner confirmed the Rust unit and picked Go's by analogy, verbatim: «А что является единицей учета в Rust? Крейты? Если да, давай в Go сделаем пакеты» — Rust's unit IS the crate (census R1 Q4), so Go = package. For TS his conditional («А в Расте как сделано сейчас? Ячейка? Если да, давай делать ячейку») does not resolve literally — Rust's unit is the crate, not the cell — and his meta-directive below governs instead: the norm is each language's own native unit — the crate is Rust's, the package is Go's, and TS, having no crate/package analogue, contributes the discipline's own native TS unit — the cell. Non-cell dirs under the TS roots stay outside unit-accounting by the discipline's own boundary (cells are the domain), recorded, not silent.

04The homes, ruled by quality bar. On the third half the owner delegated the pick with an explicit bar, verbatim: «Какое решение максимально хорошо с точки зрения построения систем, расширяемо на новые языки (скоро добавится Python!) и вообще круто? Я не хочу делать плохие временные решения только потому что так было проще и это экономит какие-то незначительные рефакторинги. Хочется сделать хорошо и надолго. И это относится к предыдущим двум вопросам тоже». Under that bar the flat-Rust-root option dies (it is exactly the historical asymmetry that compounds per added language) and the answer is full symmetry, one section shape, N languages: every language a section, the root table carrying only the genuinely cross-language budget. Python is coming — a recorded planning fact; it lands as one more section with zero new vocabulary decisions.

05The uniform section shape (the systemic answer). Every language section carries the same five-slot shape — roots, exclude_substrings, gated (the unit list), [[<lang>.exempt]] {unit, reason}, floor_disable where the language's floor supports disablement — plus its own language-specific extras ([rust]: gated_pub_doctest, audit_crates, env_roots, registry_file, registry_gated_crate; [go]: cells_dir, seams_pkg, registry_pkg; [typescript]: cells_dir, seam). The gate key is the neutral spelling gated in an idiomatic home: the section names the language, the unit noun lives in each language's docs and error strings — no foreign term in any config (B-029's origin), no per-language alias sprawl, and the N+1th language adds a section, never a vocabulary debate. The root table keeps max_file_lines (read by all frontends) and nothing else.

06The old root keys die loudly with the hint. The root container keeps deny_unknown_fields; the retired flat keys (roots, exclude_substrings, gated_crates, gated_pub_doctest, audit_crates, env_roots, registry_file, registry_gated_crate, [[exempt]]) are declared as tombstone fields whose presence is a targeted parse-time error naming the move (gated_crates[rust] gated) — the house pattern (B-031's loud death with a rename hint), not serde's generic unknown-field message. Migration surface, measured: three in-tree carriers (host, fractality package, rust-demo) plus the Rust init template; zero external Go/TS carriers; pre-publication, so the break ships inside the refactor window.

3. The design past the fork (boss-settled, worker-elaborated)

07The Config restructure (the symmetric surface). The engine's Config becomes root = max_file_lines + three (later N) language sections; RustConfig is extracted to the uniform shape and the Rust-specific extras move inside it; the retired flat keys become loud tombstones per #fork-legacy. Store::at_repo re-points to the [rust] view (rename to the for_* symmetry at the worker's latitude). The exempt entry is one shared struct {unit, reason} across languages.

08The coverage invariant (B-034). The engine grows one generic core — enumerate units, require gated ∪ exempt coverage, reject duplicates/both-listed/empty reasons/ghost entries — parameterised by the unit noun so each language's six error strings speak its own word (crate/package/cell) and name the new keys ([rust] gated, never the retired spelling). validate_against_tree becomes the Rust-shaped wrapper over it, behaviourally stable. New per-language enumerators: Go — walk [go].roots for .go-bearing dirs (the excludes of the scanner apply, so the unit set matches the scanned corpus); TS — list cells_dir's immediate subdirs. The Go and TS drivers call their validator in run_check + run_freeze exactly where Rust does.

09The vacuous-green guards. Both drivers gain the two announce mechanisms Rust already has: a per-language warn_vacuously_gated (a gated unit the scan attributed zero files to) and the gated/exempt count summary; plus the sharper one the census showed missing everywhere it matters — a present config whose language roots enumerate zero units warns loudly instead of passing silently.

10The TS flag rule (B-039), TS-shaped. The literal R-001 mount being impossible (census R2 Q4), the rule is built in the TS frontend's own shape, enforcing the guide's own promise («flags read once at the composition root; no config reads in domain cells»): ts-extract emits a new census kind for environment/config reads (process.env, import.meta.env); a new engine rule flags such reads in files under cells_dir outside the configured composition root; [typescript] gains the root-naming field. The if (flag) half of the promise needs flag identity that no table provides yet — recorded as the rule's documented limit, not silently claimed. The demo instantiates the tier it currently only describes (a typed registry + composition root in research/ts-demo), so the guide's «described, never instantiated» note dies honestly.

11The Go half of B-039 routes to batch 2. The census found Go promising R-001 at the seam with a dead config key (registry_pkg, zero readers) and no rule; a registry is the sole cell importer rule is implementable today from existing import facts. It is the natural sibling of B-033 (the dedicated Go seam-error rule) and rides that batch rather than widening this one.

12The idiom lands in the carriers (ruling 2.1's second half). The Go/TS frontend docs, guides, skills and init templates speak the new keys from birth; the Go guide's «one spelling across the language stacks today» caveat and the frontend doc's apology die in the same change. Init templates mirror the Rust adoption posture (worker verifies what rust-ai-native init actually emits and mirrors it per language).

13Not built here: no per-language max_file_lines override (no measured need); no transition period accepting both spellings (three in-tree carriers, pre-publication — the loud tombstone is the whole migration aid); no foreign-linter ingest (B-026); no assertion-presence rules (B-030, batch 2); the Go sole-importer rule rides batch 2 (#design-go-registry).

4. The build cut (re-cut on the ruling)

14W1 — one thread, engine only: the Config v2 restructure (RustConfig, uniform gated/exempt {unit, reason}, legacy tombstones with move hints), the generic validator + three enumerators + three wrappers, vacuous helpers for all three languages, Store re-point, engine tests — canonical v0.8.0 only; self-verify is the canonical engine's own check/test/clippy/budget. The boss tail then fans the engine out (sync-engines ×6, vibedeps rematerialise) and migrates the three config carriers + the host xtask expectations in the same atomic landing.

15W2a ∥ W2b — after W1 lands, two lanes on disjoint packages: W2a (rust): the Rust FE re-points to config.rust.*, CLI init/health follow, rust-demo policy migrates, package tests green. W2b (go+ts): the Go/TS drivers wire their validators + vacuous guards into run_check/run_freeze, init templates emit the uniform shape, demo policies gain their unit lists, driver-run fixture configs mapped and migrated, package tests green.

16W3 — doc packet, after W2, disjoint files: the carriers sweep (frontend docs, guides, skills, READMEs) onto the new keys, the unit-per-language norm, and the death of the «one spelling across stacks» apology.

17W4 — the TS flag rule, after W2b: ts-extract census kind → engine rule → [typescript] root-naming field → TS driver mount → demo registry + composition root → guide re-point.

18The boss tail per slice: review by WORKER-REPORT, cargo xtask sync-engines from the host root, fmt per package manifests, panel bare with the tail read, rematerialise after canonical package edits, commits per Rules 1–4. After the batch: the B-035 loop pass re-runs the parity table and the F-185 family re-judgement drains through mirror → merge-verdicts → seal.

5. Acceptance

19Measured, not narrated: (1) the Go and TS drivers fail loudly on an unclassified unit and on ghost entries, six messages per language in the language's own noun; (2) an empty-scope run warns instead of passing silently — exhibited on a scratch tree; (3) the TS flag rule flags an env read inside a cell and stays quiet at the composition root — exhibited on the demo; (4) the three migrated carriers parse in the v2 shape and a file carrying any retired flat key fails with the targeted move hint — exhibited; (5) the panel green with the tail read; (6) F-185's re-judgement rides the landing.

For an agent

This page has a machine mirror. The citation carries the version rather than latest, so what an agent quotes does not move under it.

spec://org.vibevm.core/vibevm@1.0.0/design/gate-parity-config

.md.xmlllms.txt