Skip to content

Latest commit

 

History

History
249 lines (223 loc) · 88.2 KB

runtime-boundary.md

File metadata and controls

249 lines (223 loc) · 88.2 KB

VelarScript runtime and JavaScript boundary ledger

Status: required current architecture ledger

This document classifies how observable VelarScript semantics cross the generated JavaScript and host-runtime boundary. It does not define a second language. The language charter remains the authority for source-level and user-observable behavior. If this ledger, an implementation note, or a test conflicts with the charter, the charter wins and the other artifact must change.

The compiler architecture owns implementation and package responsibility. Tests prove the charter and this mapping; they do not create new semantics.

Boundary classes

Class Name Meaning
H Host-inherited The charter deliberately retains JavaScript representation or runtime behavior.
E Compile-erased The construct is checked or used for tooling, then has no independent runtime representation.
L Compiler-lowered The emitter rewrites the construct to preserve VelarScript evaluation and safety rules.
R Runtime-controlled Generated code calls a compiler- or extension-owned runtime contract.
C Checked foreign ABI A trusted declaration is checked statically; it is not an implicit runtime schema or sandbox.
U Explicit unsafe Source spelling opts out of checked guarantees, and the caller owns the risk.

Classes apply to operations, not whole types. A record uses host object identity (H), compiler-controlled construction (L), runtime validation (R), and a checked or unsafe foreign boundary (C or U) depending on how it entered the program. Collapsing those operations into one label would hide the boundary.

Runtime ABI authority

packages/compiler/src/runtime-abi.ts owns three independent identities:

  • VELAR_RUNTIME_REGISTRY_KEY identifies the one global registry slot shared by generated Core helpers and optional runtime-providing extensions. Change the key only when two runtime generations must never share a registry value.
  • VELAR_RUNTIME_SCHEMA_VERSION identifies the shape and semantics consumed by generated code. Change it when a required field or an observable field contract changes. It is intentionally independent from the language and npm package versions.
  • VELAR_TYPE_REGISTRY_KEY identifies the separate registry of compiler-known runtime Type objects shared by Core and every extension, including targets with no reactive runtime. Its global descriptor is immutable and validated; registration uses the captured WeakSet intrinsic rather than an overridable instance method.

packages/web owns the browser implementation of the current schema. It must validate an existing registry descriptor, schema version, field set, collection brands, and callable fields before reuse. Required Web consumers fail closed on an incompatible registry. Opportunistic Core adapters may ignore an absent or incompatible optional runtime capability and retain ordinary Core behavior.

Compiler extensions that consume or implement either registry import all identities from @velarscript/compiler/extension; they do not repeat string literals. Exact package pins reduce accidental mixing, while runtime validation protects generated modules that are nevertheless combined outside the package manager's graph.

Pins alone do not settle the compiler generation. The CLI resolves a compiler extension from the project before the toolchain, deliberately, so a project that declares its own copy of an official target extension routes around the CLI's pin entirely and brings that release's nested @velarscript/compiler with it; neither protocolVersion, which has never moved, nor apiVersion, which is compared against the extension's own manifest, can see the difference. The npm versions are the one generation marker both halves carry, so resolveExtensionPackages compares every project-resolved extension's version against the version this CLI was published against and refuses a mismatch, naming both packages and both versions. An extension this CLI does not pin, an extension resolved from the toolchain or the bundled registry, and a toolchain whose own manifest is unreadable are not refused: a CLI that cannot state its generation must not reject the project's. The official create-velar templates install every @velarscript/* dependency at an exact version rather than a caret range, so an ordinary install cannot pair a newer target extension with the pinned CLI. The one range they write is a component package's peerDependencies entry, which installs nothing and only states which target a consumer must already have.

Current boundary ledger

The proof column names the primary test area. A row may be covered by additional focused and acceptance tests.

ID Class Operation Observable contract Owner and primary proof
B-HOST-IDENTITY H Object and class-instance identity Values retain JavaScript reference identity and garbage-collection behavior. Charter section 18; class and identity execution tests in tests/compiler/analysis/classes.test.ts.
B-HOST-CLASS H+L+R Classes, prototypes, private members, and checked field reads Classes lower to native classes; source cannot reopen prototype-manipulation surfaces, and private members lower to native private names. The compiler-owned runtime captures Object/Reflect field discovery and reads plus TypeError identity at initialization. Standalone results inline it; project results share one internal module that has no public ModuleInterface. Public, private, inherited static, and own static reads therefore retain the language's no-undefined initialization boundary after later global or prototype replacement. Core analyzer, emitter, and class-field runtime; internal-module visibility and shared hostile-execution tests, permanent boundary guard, class hardening tests, and full post-initialization Object/Reflect/Error poisoning execution.
B-HOST-ASYNC H+L+R Async functions and Promises The host event loop and actual Promises are retained; checked results normalize undefined, preserve rejection, and reject magic thenables. A known resolved type cannot expose a callable top-level then or a then getter because native Promise resolution reserves that shape; nested values are unaffected. Concrete async returns are checked again before adoption so unknown, base-class, and cross-module widening cannot hide the reserved shape, and accessor rejection never invokes the getter. Promise normalization captures Object/Reflect/Symbol/WeakMap/Promise/Error operations and uses one immutable compiler-owned WeakMap registry. Standalone output inlines it; project modules import only normalizePromiseValue and/or asyncResolvedValue from a hidden internal module. Async-pull receiver validation remains module-local. Standard async helpers capture their host operations and bypass List instance overrides. Core analyzer/emitter/Promise runtime and ABI key; internal-module selection/visibility, direct and widened Promise-shape diagnostics, cross-module hostile async execution, registry ownership, and JavaScript-bridge tests.
B-ASYNC-PULL L+R async for pull iteration A source and its own data-valued next method are captured once; each actual Promise resolves to one value or null exhaustion, the optional second slot is a zero-based index, rejection propagates, and break stops without an extra pull or implicit cleanup. Captured Object, Reflect, WeakMap, and Promise operations prevent later ambient poisoning from redirecting the loop. Core analyzer/emitter; diagnostic, emitted-code, hostile-runtime, control-flow, formatter, and cross-module tests in tests/compiler/analysis/iteration.test.ts, plus the independent Lite stream drain.
B-DETACHED-TASK L+R detach <expression> detached execution A Promise-typed expression statement is rejected at compile time; the one detached spelling is the detach statement, whose expression must check as Promise<null>. The emitter hands the Promise to the compiler-owned __velarDetachedTask observer: globalThis.Promise.prototype.then and Reflect.apply are captured at module initialization so an ordinary lexical binding named Promise cannot redirect or dead-zone the observer, rejection is normalized to Error, and the failure is reported through the host error channel without ending the program — the captured console channel on Core/Node output, the velar/app error chain with the distinct detached phase (unhandled: true, registry looked up at report time with a captured microtask throw as the pre-runtime fallback) on Web output. A resolved detached task reports nothing. Core analyzer/emitter and Web emitter override; floating-promise and Promise<null> diagnostics, emitted-code assertions, Node no-crash stderr execution, and browser detached-phase report tests in tests/compiler/analysis/detached-async.test.ts.
B-USING-DISPOSE L+R using ownership and @dispose release A using binding lowers to a release frame around the rest of its block, so every exit — falling off the end, return, break, continue, or a throw — runs the contract exactly once, and nested bindings release in reverse declaration order. A class contract lowers to one prototype member under a key no source member name can spell, so it is unreachable from source; a standard capability handle delegates to the close()/stop() it already publishes. When an error is already in flight the original error keeps the throw and the release failure is normalized and reported through the captured console channel, whose reporter never throws outward; with no error in flight a failing release throws normally. Reflect.apply and the console channel are captured at module initialization so later ambient replacement cannot redirect the report. Core analyzer/emitter; exit-path, LIFO, idempotence, failure-precedence, async-scope, capability-handle, and rejection tests in tests/compiler/analysis/using-and-dispose.test.ts.
B-HOST-ESM H+L Module execution and unbundled output identity Generated modules use native ESM evaluation while the project compiler owns checked interfaces, dependency order, and invalidation. Hidden runtime-module dependencies are materialized transitively. Project source and compiler-resource paths must remain inside their lexical and canonical project/package roots before bytes are read, so a contained symlink cannot redirect compilation outside its owner. A directory build stages the complete current graph and then replaces its owned output, so removed source/package/runtime modules cannot remain executable as ghost artifacts and a failed rebuild preserves the last complete output. A single-file build may synchronize only its explicitly marked synthetic runtime package, refuses a foreign node_modules/velar, and removes obsolete owned CSS. The velar run execution adapter retains ownership of its spawned program: it forwards the first SIGINT/SIGTERM, escalates a second signal or its bounded launcher deadline, waits for inherited stdio to close, and preserves conventional signal exit status. Compiler and CLI project graph; module/project, canonical symlink containment, runtime-dependency closure, clean-rebuild, foreign-package refusal, stale-CSS, failed-rebuild preservation, and real child-signal lifecycle tests.
B-ERASE-TYPES E Type annotations and inferred types Types govern diagnostics, interfaces, and tooling but do not create a second runtime type system unless source explicitly requests a runtime Type. Core analyzer/semantic index; compiler type tests.
B-ERASE-NAMED-CALLS E+L Named arguments Names are checked statically; emitted calls preserve callee-first and source argument evaluation while passing native positional arguments. Core analyzer/emitter; named-call evaluation tests.
B-LOWER-OPERATORS L Operators and conditions The compiler rejects coercive combinations, maps strict equality deliberately, and preserves specified short-circuiting and source order. Core analyzer/emitter; operator and hardening tests.
B-LOWER-BINDINGS H+L+R Declaration/for Record/List binding patterns Sources evaluate once; only owned data fields or dense List elements bind, missing optional fields normalize to null, and rest copies use explicit indexed traversal. Generated modules reuse the initialization-captured Record/List reflection, allocation, definition, and Error ABI, so later Array/Object/Reflect, iterator, prototype, or error replacement cannot redirect binding. Structural match patterns remain separately owned by B-LOWER-MATCH. Core emitter helpers; permanent boundary guard, binding-pattern execution tests, and full post-initialization global/prototype poisoning execution.
B-LOWER-MATCH H+L+R Structural Record/List match patterns Each candidate reads its source once, treats malformed or nonmatching owned-data shapes as a case miss, never invokes accessors, and creates controlled rest snapshots. List length and element descriptors, Record fields, allocation, and definition reuse the initialization-captured collection ABI; generated matching uses explicit indexed traversal and a one-million-item bound, so later Array/Object/Reflect, iterator, or prototype replacement cannot redirect selection. Core structural-match emitter; permanent boundary guard, nested shape/semantic tests, and full post-initialization global/prototype poisoning plus malformed-shape execution.
B-LOWER-RECORDS H+L+R Record construction, spread, and copy Records retain host identity, but construction prevents __proto__ magic, invokes no accessors, rejects symbols, and copies in source order through explicit indexed part/field traversal. Definition, discovery, List rejection, and Error identities reuse the initialization-captured Record/List ABI; later Array/Object/Reflect, iterator, prototype, or error replacement cannot redirect literal/spread lowering. Core emitter runtime; permanent boundary guard, record construction/hardening tests, and synchronous/asynchronous post-initialization hostile execution.
B-RUNTIME-OPTIONAL L+R Optional, null, and unknown results Checked expressions convert JavaScript undefined to VelarScript null exactly once without changing errors or evaluation order. Core analyzer/emitter; undefined-normalization tests.
B-RUNTIME-ERROR H+R Thrown values and caught errors Native Error values remain native; non-Error JavaScript throws are normalized before entering checked VelarScript catch/reporting paths. The compiler-owned normalization ABI captures Object/Reflect/Error/String/TypeError identity and operations, including the prototype read that answers code: an error's code is the name declared by the class it was constructed from, so a relabelled host error reports "Error" and never disagrees with is (D51 rule 107). Standalone output inlines it; Core and Web project modules import one internal implementation with no public ModuleInterface. Web-owned report metadata, scheduling, handler collections, timestamps, and Promise rejection observation remain in the Web runtime state. Later ambient constructor, static-method, or prototype replacement cannot redirect Core catch normalization, Web reports, velar/app, or owned browser callback failures. Compiler error runtime, Web error host/runtime reporter, shared Core/Web module and visibility tests, permanent boundary guard, hostile post-initialization Core/Web tests, and owned-callback tests.
B-CORE-COLLECTIONS-HOST H+R Functional List snapshots, grouping Maps, uniqueness Sets, stable sorting, and the prelude range The functional List operations are compiler-owned members (D114 S3), so the pipeline helpers (unique, compact, flatten, chunk, partition, groupBy, keyBy, countBy, zip, repeat, keyed min/max, directed sorted) live in the collection lowering runtime and consume the captured collection host ABI of B-RUNTIME-LIST and B-RUNTIME-SET-MAP-HOST. Each works over one checked List copy and explicit index loops; later ambient or prototype replacement cannot redirect traversal, grouping, allocation, sorting, or joining. The prelude range keeps its own compiler-owned module, capturing Array, the numeric predicates it needs, Object.defineProperty, Reflect invocation, and Error identity when that module initializes. Compiler collection lowering and range runtime sources, permanent boundary guard, ordering/bounds/callback tests, subclass tests, and full post-initialization host poisoning execution.
B-CORE-JSON-HOST H+R Strict JSON validation, snapshot, and serialization The compiler-owned strict JSON runtime captures JSON parse/stringify, Array/Set traversal, descriptor/reflection, numeric/text/path operations, allocation, Reflect invocation, and Error identity. velar/json additionally consumes the same captured ordering operation for stableStringify, and velar/test calls the language's own equals for toEqual, so no second comparison implementation exists to disagree with it. Later ambient replacement cannot redirect any JSON consumer, while the explicit reactive runtime registry remains the only dynamic unwrapping seam. Compiler JSON and runtime-Type sources, Core standard module source, permanent boundary guards, lossy/cycle/accessor/cross-realm tests, and full post-initialization poisoning execution.
B-CORE-MATH-HOST H+R Numeric intrinsics and pseudo-random source velar/math captures numeric constants, every required Math/Number data operation, Reflect invocation, and Error identity when the module initializes. Later ambient replacement cannot redirect arithmetic or randomness. Dynamic inputs remain strictly numeric, random output remains finite in [0, 1), and missing/accessor-backed host operations fail closed during initialization. Core standard module source, permanent boundary guard, coercion tests, invalid-host tests, and hostile post-initialization poisoning execution.
B-CORE-URL-HOST H+R URL parsing, query iteration, and browser base location velar/url captures URL/URLSearchParams constructors and prototype accessors/operations, Map brands/iterators, component codecs, numeric/text/reflection helpers, Error identity, and the browser location object plus its href reader when the module initializes. Later ambient replacement cannot redirect parsing or query work. Navigation updates on the captured real Location object remain visible, while hostile text/results, iterators, accessors, and collection shapes fail closed. Core standard module source, permanent boundary guard, cross-realm and malformed-query tests, pre-initialization hostile result tests, and post-initialization global/prototype poisoning execution.
B-CORE-TIME-HOST H+R Wall/monotonic clocks, Date operations, and internationalization velar/time captures its clocks, Date constructor/prototype operations, Intl.DateTimeFormat constructor/format operations, numeric/text/RegExp helpers, result freezing, Reflect invocation, and Error identity when the module initializes. Later ambient replacement cannot redirect an initialized module. Host locale and time-zone data remain authoritative, while invalid clocks, malformed Intl results, accessor-backed parts, and missing/accessor-backed operations fail closed. Core standard module source, permanent boundary guard, deterministic parse/calendar tests, hostile pre-initialization host-result tests, and post-initialization poisoning execution.
B-CORE-ID-HOST H+R Secure UUID generation and validation velar/id captures the host crypto object, its data-valued randomUUID operation, RegExp matching, Reflect invocation, and Error identity when the module initializes. Later replacement of the global capability, source-object method, or ambient intrinsics cannot redirect UUID generation or validation. Missing/accessor capabilities fail closed, invalid results are rejected, and non-Error failures are wrapped without conversion hooks. Core standard module source, permanent boundary guard, hostile capability/result and post-initialization poisoning tests, plus independent Lite UUID consumers.
B-CORE-LOG-HOST H+R Structured logging clock, collections, Promise observation, and fallback console velar/log captures its clock, numeric/text operations, Map/Set constructors and prototype operations, iterator steps, Promise rejection observer, record construction/freezing, Error identity, and fallback console target/writers when the module initializes. Later ambient replacement cannot redirect record construction or delivery; setLevel and useSink remain the explicit behavior controls. Cross-realm Maps retain native brand compatibility, arbitrary thenables are not probed, and each sink receives an isolated fields snapshot. Core standard module source, permanent boundary guard, cross-realm/snapshot tests, hostile post-initialization poisoning test, and logging resource ceilings.
B-CORE-TEST-HOST H+R Matcher execution and bounded diagnostic display velar/test captures its Array/Map/Set/WeakSet graph operations, string slicing/search and joining, JSON quoting, numeric bounds, RegExp execution, real-Promise brand check, record reflection/freezing, Reflect invocation, and Error identities when the module initializes. Later ambient or prototype replacement cannot turn a matcher into a false result or redirect failure formatting. Display remains bounded to 1,000 nodes, depth 16, 50 collection items, and 256 string code units; arbitrary thenables and accessors remain outside the assertion contract. Core standard module source, permanent boundary guard, matcher strictness tests, and full post-initialization host poisoning execution.
B-CORE-TEXT-HOST H+R Text transformation, Unicode progress, patterns, line indexes, chunking, and bounded composition The compiler-owned String method runtime and velar/text capture Array/String/Number/Math/Object/Reflect/Error operations plus native RegExp construction and execution when the module initializes. Pattern replacement and splitting advance through captured exec rather than rediscovering mutable RegExp.prototype symbol hooks; Unicode loops use explicit code-unit offsets rather than mutable string/array iterators. Code-point length first proves an ordinary no-surrogate fast path through a captured RegExp execution, while astral/unpaired-surrogate text retains explicit scanning. lineStarts and chunks perform one bounded scan and return only code-point offsets or surrogate-safe pieces. Standalone results inline the method runtime; project results share one compiler-internal primitive-method module that remains absent from the public Standard API. Later ambient replacement cannot redirect receiver methods, transforms, indexes, pattern results, options, HTML escaping, or output budgets. Compiler text and primitive runtimes, Core standard module source, internal-module visibility test, permanent boundary guard, Unicode/replacement/allocation/line-index/chunk regressions, and full post-initialization global/prototype poisoning execution.
B-CORE-NUMBER-HOST H+R Checked Number receiver methods The compiler-owned Number method runtime captures Math/Number/Object/Reflect operations and Error identities when the generated module initializes. .abs(), .round(), .floor(), .ceil(), and .toFixed(digits) never re-read mutable globals or prototypes; dynamic receivers remain actual numbers, and toFixed digits remain safe integers from 0 through 100. Standalone results inline the runtime, while project results share it with String method lowering through one compiler-internal primitive module. Compiler Number and primitive runtimes and emitter, internal-module visibility test, permanent boundary guard, checked-member tests, and full post-initialization global/prototype poisoning execution.
B-RUNTIME-TEXT L+R String measurement, positioning, and checked methods Public string positions are Unicode code-point offsets across size, char, slice, literal index, and velar/text pattern matches; JavaScript UTF-16 offsets remain internal implementation details. Compiler-owned helpers validate receivers and arguments, capture the required prototype operations, bound allocation, and preserve code-point boundaries when locating literal text. Core analyzer/emitter/text runtime and velar/text; checked-member, Unicode-position, first-class method, pattern, and hostile prototype tests.
B-RUNTIME-LIST H+L+R List construction, indexing, iteration, and mutation Lists use Array identity but require bounded dense mutable data elements and compiler-owned operations. Foreign or application-boundary arrays receive a complete descriptor proof before use, so sparse, accessor-backed, frozen, or extended arrays fail closed without invoking getters. Lists created and mutated by the captured runtime are registered in a private WeakSet; size, indexed reads/writes, append, slice, transforms, and collection snapshot outputs reuse that ownership proof while checking the accessed element descriptor and current bound. This preserves the boundary contract without turning a normal indexed scan into O(n²). Core collection host/lowering runtime; hostile sparse/accessor/extended boundary tests, generated code execution, and 1 MiB pure VelarScript service performance gate.
B-RUNTIME-RECORD H+L+R Record<T> construction, indexing, iteration, mutation, and runtime validation Dynamic records retain plain-object identity and JSON representation while allowing only string keys and values checked against one invariant T. A structural object may alias a mutable Record<T> only when every existing field is invariant with T and writable; read-only Record views may widen fields covariantly. Missing reads return null; construction, indexing, runtime Type validation, and every operation reject non-plain objects, symbols, accessors, frozen/sealed/read-only fields, and oversized field sets without invoking getters. The complete mutable shape is proved before an operation, rather than failing later through a method that the static type promised. Map remains a separate native-identity collection and is not silently serialized as a record. Core type system/analyzer/emitter; Record<T> variance, diagnostic, execution, hostile runtime-Type and operation, strict JSON, cross-module package, and independent Lite provider-schema tests.
B-RUNTIME-SET-MAP H+L+R Set/Map construction and operations Native key identity and insertion order remain; construction and methods use bounded compiler helpers and native prototype operations, not overridable instance methods. Map.iterator() exposes an incremental key cursor whose next() returns a frozen {value} item or null exhaustion without materializing a List snapshot. Core emitter helpers; collection constructor/method/cursor tests.
B-RUNTIME-COLLECTION-IDENTITY H+R List/Set/Map/Record brands and runtime-Type traversal Compiler runtime modules capture Array, Map, Set, Object, Reflect, native size getters, iterator factories, and iterator next operations at initialization. Standalone output composes the captures inline; project collection consumers and the separate runtime-Type module reuse hidden compiler-owned host modules with no public ModuleInterface. When analysis proves a List, Map, Set, or Record receiver, indexing, size, membership, iteration, lookup, mutation, removal, clearing, and snapshots select that exact runtime helper; only genuinely dynamic receivers use the generic kind dispatcher. The lowering module owns its declared host/reactive dependency closure; ordinary algorithm consumers do not also import those transitive ABIs. Compiler/Core own the private module name and static identity/no-op implementation; the Web extension owns the registry-backed provider implementation and selects it only for Web composition. Only consumer-local Record construction, binding, or structural-match lowering declares a direct host/reactive dependency. Direct compiler-runtime imports select only named operations referenced by generated JavaScript identifier tokens and compiler-owned helper bodies; string/comment/template text and longer prefix-sharing identifiers cannot create false uses. The same liveness rule applies to primitive, runtime-Type, and class-field modules without changing their canonical export surfaces. Collection identity and value is List/Set/Map/Record checks therefore do not re-read mutable globals, prototypes, or iterator methods; dense List and owned-record descriptor rules remain fail closed. Sharing realm operations and stateless lowering code does not share application collection values, callbacks, generated operands, or application reactive state. Compiler collection identity/host/lowering and runtime-Type modules; Web-owned reactive provider bridge; exact helper/code-shape and named-import selection, source-text/prefix-collision regressions, direct/transitive dependency closure, visibility tests, permanent boundary guard, performance ceilings, and full post-initialization global/prototype/iterator poisoning execution.
B-RUNTIME-LIST-HOST H+L+R List validation, construction, indexing, snapshots, transforms, ordering, and mutation The compiler captures Array/Object/Number/Math/Reflect operations, native join/sort/reverse, and Error identities before application code runs. Standalone output inlines the host and algorithm fragments; project modules import stateless List algorithms, strict/optional bracket reads, and bracket writes from a hidden lowering module whose declared dependency imports the immutable collection-host and reactive ABIs. Application Lists and callbacks remain call arguments owned by their source module. IndexError has one internal project identity over the captured native RangeError and is not a public constructor; optional index thunks stay lazy on absent receivers. Ordinary List receiver methods and bracket helpers operate on one bounded dense-data snapshot or explicit indexed loops; later ambient replacement cannot redirect allocation, validation, iteration, callbacks, mutation, or ordering. Compiler collection List/host/lowering runtimes and emitter; transitive materialization, shared-module selection/visibility, permanent boundary guard, complete receiver semantics, and full post-initialization global/prototype poisoning execution.
B-RUNTIME-SET-MAP-HOST H+L+R Set/Map construction, native-slot traversal, snapshots, cursors, lookup, membership, copying, and mutation The compiler captures Map/Set constructors, native size accessors, every required prototype operation, iterator factories and iterator next, record-to-Map reflection, result freezing, Reflect invocation, and Error identities at initialization. Standalone output inlines the host and algorithm fragments; project modules import stateless Set/Map algorithms from a hidden lowering module with explicit host/reactive dependencies. Application collections, keys, values, and callbacks remain consumer-owned arguments. All ordinary Set/Map paths, including incremental Map cursor pulls, invoke captured operations and explicit iterator steps, so later global, prototype, iterator, or error replacement cannot redirect collection behavior. Compiler collection Set/Map/host/lowering runtimes and emitter; transitive materialization, shared-module selection/visibility, permanent boundary guard, complete constructor/receiver/iteration, and full post-initialization poisoning execution.
B-RUNTIME-RECORD-HOST H+L+R Record validation, indexing, traversal, snapshots, copying, and mutation The compiler captures own-name/symbol/descriptor discovery, definition, identity, deletion, freezing, Reflect invocation, and Error identities at initialization. Standalone output inlines the host and algorithm fragments; project modules import stateless Record algorithms from a hidden lowering module with explicit host/reactive dependencies, while each application Record remains consumer-owned. Record validation and every bracket, one-slot/pair iteration, get/set/has/remove/clear/copy/keys/values/entries path use explicit indexed field loops and captured operations; later Array/Object/Reflect or error replacement cannot redirect the data-object boundary. Record literal/spread and binding lowering remain separately owned by B-LOWER-RECORDS/B-LOWER-BINDINGS. Compiler collection Record/host/lowering runtimes, index and collection emitter paths; transitive materialization, shared-module selection/visibility, permanent boundary guard, complete operation tests, and full post-initialization poisoning execution.
B-RUNTIME-TYPE H+R Type.is, Type.parse, and compiler-known Type identity Runtime checks inspect owned enumerable data without invoking getters; validation proves the shape at that operation and does not constrain later Proxy behavior. A derived record validator checks the compiler-flattened inherited and local field contract; record inheritance creates no JavaScript prototype or runtime parent object. Identity and execution have separate owners: the shared registry captures Symbol, its immutable global descriptor, WeakSet operations, Reflect, and Error identity, while validation captures graph operations, collection traversal, Array/Promise/class brands, field descriptors, freezing, Reflect, and ValidationError identity. Standalone output composes these fragments inline; project modules import one internal implementation but keep generated predicates and Type objects in their declaring module. Acyclic concrete local type graphs emit straight-line validators and allocate no WeakMap/Set recursion state on successful is or parse; recursive, generic, and imported/opaque graphs receive fresh per-call state. The internal module has no public ModuleInterface. Recursive checks use captured operations and a bounded depth, reject cycles while accepting shared DAG nodes, and retain the original Promise, class, and error semantics after ambient constructor/prototype replacement. Compiler runtime type helpers, registry and validation sources; acyclic emitted-shape and performance ceilings, internal-module selection and visibility tests, permanent boundary guard, cross-module identity and record inheritance, recursive/DAG, accessor, Promise alias, class field, frozen Type object, record validation, and full post-initialization hostile host execution.
B-RUNTIME-TYPE-CARRIER E+R First-class Type<T> values T is preserved through generic inference, aliases, module interfaces, renamed and namespace imports, and semantic tooling, then erased. The runtime value must be a compiler-registered record, alias, or enum Type object; structural forgeries are rejected. Since the registry proves ownership but does not reify the target identity, Type<T> cannot itself be checked with is or embedded in a recursively runtime-validated type. Core parser/analyzer/type system/project interface; direct execution, rejection, renamed-import, namespace-import, and installed pure-Vel package tests.
B-RUNTIME-JSON R Strict JSON parsing, inspection, cloning, and serialization Values are bounded by size, depth, and node count; accessors, cycles, unsupported values, malformed reactive wrappers, and non-JSON structured-clone values are rejected without coercion. The compiler runtime captures the host parser/serializer once; JSON, Web/Node/Desktop HTTP, serve, and storage consumers cannot maintain ambient direct-parse paths beside it. IndexedDB persists the strict encoded text, so foreign structured-clone values fail closed before typed validation rather than being normalized by a second serializer. Compiler JSON runtime, standard/target modules, runtime-boundary guard, hostile JSON/storage tests, and Chromium browser acceptance.
B-RUNTIME-UTF8 R Transport sizing and declared lengths One compiler-owned, platform-neutral counter defines encoded byte budgets without depending on target-specific TextEncoder or Buffer behavior. Text.utf8Size exposes that exact counter so applications can compose aggregate budgets before an effect instead of reimplementing encoding rules. The same captured string/reflect intrinsics parse decimal declared lengths, so later application mutation cannot disable response or inbound-server preflight. Web, Node, and Desktop HTTP validate serialized JSON and text before effects with identical surrogate semantics; generated headers remain inside the validated aggregate budget. Browser storage and IndexedDB reuse the same counter for caller-selected read/write ceilings and reject invalid or oversized work before the relevant host effect. Compiler transport runtime; public text-module execution, shared parity/hostile-intrinsic tests, Web/Node/Desktop pre-effect HTTP regressions, and storage/IndexedDB budget tests.
B-HTTP-SHARED C+R Cross-target HTTP request and typed response semantics Web, Node, and Desktop share lazy request vocabulary, a 120-second default/10-minute maximum integer timeout contract, explicit zero timeout, and request/response parse(Type). Async runtime-Type inference is compiler-owned and rejects top-level callable then results before native Promise assimilation; each target validates the same immutable runtime-Type identity before starting or consuming a request. Concurrent buffered readers coalesce onto one pending body read and successful text remains repeatable; incremental streamText stays exclusive. A present body with a valid declared length above maxBytes is cancelled before its first read, while the running byte bound still applies and bodyless representation metadata does not fail. Accepted response metadata has an integer status from 100 through 599 and ok exactly classifies 200 through 299; contradictory host/bridge records fail before HttpResponseError or body processing. Non-2xx errors identify the final response URL after redirects and fall back to the initial request URL only for synthetic responses with an empty URL. Node and Desktop lazy requests retain only validated secret descriptors until the first effect; the Node runtime resolves the current environment value at request start and dispatches the resolved header only through its private host transport, while Desktop resolves it in its capability worker. An unavailable secret prevents any network effect. Web captures its in-process transport and required host operations at module initialization. Node instead keeps option/secret snapshots, URL/method validation, timers, Type parsing and host-result validation in the captured application-facing runtime, while the private isolated Node host owns HTTP/HTTPS clients, redirects, sockets, response streams, fatal incremental UTF-8 decoding and cancellation; later application prototype replacement cannot redirect Node transport internals. Desktop performs privileged dispatch in its isolated worker. Target-only bodies, credentials, URL policy, and host grants remain explicit capability differences. Core intrinsic analysis; Web/Node/Desktop interfaces and runtimes; private Node-host dependency and lifecycle guard, worker/renderer contract guard, compile probes, concurrent/repeated reader and declared-length cancellation tests, redirected-error identity tests, isolated metadata/UTF-8/chunk bounds, full post-initialization poisoning, lazy secret-rotation/missing-value tests, pre-effect invalid-Type tests, and real response parsing.
B-HTTP-FAILURE C+R Cross-target HTTP failure identity Web, Node, and Desktop preserve non-2xx, cancellation/deadline, and native network failure as separate HttpResponseError, HttpAbortError, and HttpTransportError contracts. Transport phase is the typed request/response enum; a response failure may follow delivered chunks. Protocol, UTF-8, bound, and consumer errors are not relabelled, and generic HTTP owns no hidden retry or replay policy. Node carries the phase through its private MessagePort record; Desktop carries and revalidates it through the Worker/WebView bridge. Three target interfaces and runtimes; request/response failure, consumer non-classification, structured bridge, real socket failure, and permanent boundary-guard tests.
B-SERVE-TYPED C+R Typed inbound server JSON ServeRequest.parse(Type, maxBytes) uses the same compiler-owned async Type inference and strict JSON boundary as outgoing HTTP. The immutable compiler-known Type identity is validated before the request body is read; body caching, positive integer byte budgets, RequestBodyTooLargeError, malformed JSON, and structural Type failures retain distinct behavior. Node interface/runtime; Core intrinsic analysis; compile, callable-then, forged-Type-before-body, real server, and boundary-guard tests.
B-RUNTIME-REGISTRY R Cross-module runtime registry One private compiler ABI has target-selected implementations. Compiler/Core own only the module name and static identity/no-op implementation; Core does not inspect a reactive registry. The Web package owns the provider-resolving implementation. Web standalone output keeps its self-contained local/general bridge as required; Web project compilation overrides the same hidden internal module with the registry-backed source so Core-shaped dependencies can converge after the Web owner initializes. That source captures global-object, Symbol, descriptor/prototype/extensibility, and Error operations; a genuinely absent provider is not cached, the first valid immutable provider and its data-valued operations are cached, and malformed ownership fails closed without invoking hooks. The internal ESM source is shared by execution adapters without becoming a Standard API module. Compiler ABI name and Core static bridge; Web-owned reactive provider bridge and runtime foundation; compile-result requirements and CLI project adapters; Core emitted-shape, Web ownership/sharing and late-binding, malformed-provider, internal-module visibility, permanent-guard, post-initialization hostile execution, bundle-size, and performance tests.
B-RUNTIME-TYPE-REGISTRY R Cross-module runtime Type identity Core, Web, CLI modules, and target extensions share one compiler-owned immutable registry descriptor. Accessor, mutable, replaceable, or non-WeakSet registries fail closed without invoking hooks; registration bypasses overridden instance methods. Compiler ABI constants, generated Core execution, Web and Node extension registry tests.
B-CHECKED-EXTERN C+L Manual extern module imports Declarations are trusted static ABI contracts, imported exports are presence-checked, and checked result adaptations are applied; no implicit runtime schema is promised. Core analyzer/emitter; extern and presence-check tests.
B-CHECKED-DTS C Limited TypeScript declaration bridge Only directly representable shapes enter the lightweight type system; unsupported or ambiguous shapes degrade to unknown with guidance. CLI declaration reader; declaration-bridge tests.
B-CHECKED-READONLY C Layer-specific readonly slots and guarded narrowing readonly protects the qualified record or collection's slots. Field values, elements, keys, and values retain their declared types through reads, callbacks, copies, destructuring, spreads, and modules. An already readonly record is assignable to its identical readonly view in both directions. Explicit nested qualifiers preserve independent permissions. Readonly containers can hold class and capability values; direct qualifiers on those values remain invalid. Mutable collections are invariant and readonly collections covariant in the actual nested contracts. No freeze, proxy, copy or runtime identity change implements the qualifier. Optimistic narrowing independently revalidates runtime evidence and reports a source-located NarrowingError. Core parser/type system/analyzer/emitter; readonly layer matrix, variance, aliases, generic and module contracts, copying, advisories and fixes, narrowing, runtime execution and Web props tests.
B-CHECKED-UNKNOWN C+R Untrusted host, network, storage, or plugin data Dynamic data enters as unknown and must pass an explicit runtime Type validator before typed use. Language type system and first-party modules; unknown/validator tests.
B-UNSAFE-JS U import js unsafe Values use any; checked result normalization, shape guarantees, and package trust are deliberately absent. Core parser/analyzer/emitter; unsafe import and CLI confinement tests.
B-TARGET-EXTENSIONS E+L Web, Desktop, Node, and future target language/capability composition Core carries only generic extension statements/expressions, type-family identity and traversal, semantic categories, formatting, analysis, module, and emitter seams. Each target owns its AST discriminants, named type resolution, family assignability, runtime members, formatter embedding, lowering, modules, and runtime. Compiler and Core depend on no target package; Web and Node layer independently on Compiler, Server adds Node, Desktop explicitly composes Web and Node, and CLI is the sole package that assembles every official target. Application composes metadata records public target API provenance without activating a second application extension; no target name may appear in Core AST/type/analyzer/parser/formatter/semantic ownership. Exact package dependency roster and compiler extension boundary guard; Web component contract diagnostics/module transport, emitted code and execution; target-neutral Game extension execution probe; explicit Desktop Web/Node composition checks.
B-WEB-REACTIVITY H+L+R state, computed, watch, reactive props, and collections The compiler lowers reactive reads/writes; the Web-owned shared runtime owns dependency tracking, batching, scheduling, cleanup, raw/proxy identity, and the registry-backed bridge implementation. Each generated reactive module captures Set, Map, WeakSet, WeakMap, Array, Object, Proxy, and Reflect operations when it initializes. Compiler-generated JavaScript arguments and collection helpers reach that owner through captured operation fields. A Web module that already installed and validated the owner uses a compact local adapter. For project compilation, Web overrides Core's static no-op bridge module with its late-binding implementation, so Core-shaped dependencies use the same private ABI and can initialize before their Web importer without moving provider lookup or validation code into Compiler/Core. Standalone output remains self-contained. Later ambient constructor, static-method, global-object, Symbol, descriptor, Reflect, or collection-prototype replacement cannot redirect observer subscription, raw conversion, collection dependency operations, cleanup, queue flushing, deep-record tracking, or watch comparison. Web reactive provider bridge, analyzer/emitter/runtime foundation, compiler ABI name, Core static bridge, Web shared-module selection tests, permanent boundary guard, hostile post-initialization graph/bridge tests, bundle-size evidence, performance ceilings, and browser reactivity hardening tests.
B-WEB-ASYNC H+R Component resource, component/module action, and tick The generated Web runtime captures Promise construction, resolution, rejection, and observation plus the Object operations used to expose managed state when its module initializes. Later ambient Promise/Object replacement cannot redirect work, turn start into an unowned synchronous escape, or alter action/resource surfaces. Resource generations suppress stale and post-destruction completions; a disposed reload is a resolved no-op. Actions retain concurrent pending ownership, publish only the newest failure, reject every failed call, and reject new component-action calls after destruction without invoking application code. Web emitter/runtime foundation, permanent boundary guard, stale/concurrency/destruction tests, hostile post-initialization Promise/Object execution, and browser application gates.
B-WEB-WORKER-MODULE C+R Shared Worker contract and browser implementation discovery Core is the sole owner of the checked velar/worker interface. Web owns its browser runtime source and enumerates that implementation in the public Web runtime roster, so generic CLI composition derives development import maps, test packages, and runtime routes without a hidden Web-specific exception. The development compiler includes every manifest-declared Worker entry as a project root, matching check/build, so the URL published by velar/worker-manifest always names emitted JavaScript. A target source roster may therefore contain a Core-contracted module that its target interface table deliberately does not repeat. Core Worker interface, Web runtime roster/source map and dependency graph, framework-host import-map and declared-entry route tests, packed module-roster acceptance, and real Chromium manifest-entry execution in development and production.
B-WEB-DATA-GUARDS L+R Official Web option records and List snapshots Router, Forms, HTTP, Storage, Files, and Realtime validate option records and dense Lists through shared guards. Each generated module captures the required Object, Array, Set, Symbol, and Reflect operations during initialization; later ambient constructor or prototype replacement cannot change field ownership, invoke accessors, redirect reactive-List reads, or corrupt the defensive snapshot. Allowed option fields are built through the same captured Set ABI rather than a live global constructor. Web shared runtime fragments, permanent source guard, hostile post-initialization intrinsic test, and complete browser application matrices.
B-WEB-DOM H+L+R JSX, components, lifecycle, and keyed lists Web owns DOM construction and cleanup through one small host ABI shared by emitted JSX and runtime-implemented velar/web components. Each generated module captures its Document/Node identity, creation/query operations, node mutation methods, bounded child collections, and the Array/Set/number/string intrinsics used by DOM rendering when that module initializes. Later global or prototype replacement cannot redirect element/text/fragment creation, mount, destroy, dynamic/keyed region replacement, or dense JSX List expansion. Explicit fake hosts may expose enumerable own data methods and fields; accessors are not an operational fallback. Props follow documented source order, dynamic regions update directly, and keys own item identity reuse. Event, mounted, and cleanup callbacks execute outside any enclosing reactive observer, preventing child-local lifecycle reads from subscribing a conditional parent render. Web DOM host runtime, emitter and velar/web consumers, permanent boundary guard, hostile post-initialization JSX/Router/Lazy tests, lifecycle non-tracking execution, reactivity tests, and Chromium application acceptance.
B-WEB-VISUAL H+L+R Look, class, and checked inline Style Look lowers to controlled selectors and per-element CSS variables, class remains an external stylesheet hook, and style:property is an explicit compatibility path to a real high-priority inline declaration. The analyzer shares one camelCase property/type contract between Look and Style; generated Style sources merge in stable component-host order, react to checked values, allow null removal, and restore lower or pre-existing inline declarations during cleanup. Native CSS specificity, source order, inline priority, and !important remain host cascade behavior. Raw JSX style strings/objects and conditional Style directive names remain unavailable. Web analyzer/emitter/editor, runtime visual source management, compile/runtime cleanup tests, CSS-order tests, and browser application matrices.
B-WEB-HOST-EVENT H+R Native events, composition/clipboard text, and realtime transport callbacks JSX handlers deliberately receive native browser Event values, including typed Input, Composition, Clipboard, Keyboard, and Pointer variants. Raw clipboard DataTransfer stays hidden: clipboardText/setClipboardText require a captured native ClipboardEvent/DataTransfer pair, allow only bounded text/plain, and use captured methods. Framework-owned modifier, Link, media, WebSocket, and EventSource reads likewise use captured native getters/methods or explicit data-descriptor test-host fallbacks. Synthetic accessors and replaceable instance methods cannot run inside the framework; invalid metadata is reported through the owned error channel. Web analyzer/emitter/runtime, direct extension-primitive is lowering proof, boundary guard, hostile clipboard host execution, and Chromium native-event acceptance.
B-WEB-HOST-PLATFORM H+R Browser snapshots, observers, timers, layout, element scrolling, pointer capture, dialogs, textarea selection, and navigation Official Web modules capture their browser objects, constructors, prototype getters/methods, timers, EventTarget operations, URL parsers, and navigation functions during module initialization. Element scroll metrics expose a frozen finite snapshot instead of writable DOM fields; element scrolling and pointer capture validate inputs and call captured prototype operations. Textarea selection converts between DOM UTF-16 and public Core code-point offsets, rejects surrogate-splitting or out-of-range selections, and never exposes raw units. Later ambient replacement or instance shadowing cannot change framework behavior; host snapshots accept native branded fields or explicit enumerable data fields only, validate every value, and retain native operational errors. Web/browser runtime and browser-test controller, boundary guard, scroll/pointer/textarea Unicode/codegen/hostile-prototype execution, and Chromium application acceptance.
B-WEB-HOST-STORAGE R Local/session storage and IndexedDB Storage areas, factories, request/result/error getters, database/transaction/object-store methods, DOMStringList checks, CustomEvent dispatch, EventTarget listeners, integer validation, and UTF-8 sizing are captured during module initialization. Global replacement, prototype mutation, instance shadows, or accessor injection cannot redirect a storage operation. get, set, watch, and database reads/writes accept a positive caller budget under the 16 MiB ceiling: invalid budgets fail before host work, oversized reads fall back before parse, and oversized writes fail before mutation. IndexedDB stores strict JSON text, resolves on transaction completion, preserves native failure, and closes stale connections. Web storage runtime, boundary guard, complete fake-WebIDL poisoning, exact multibyte budget and transaction tests, plus Chromium storage/database acceptance.
B-WEB-HOST-FORMS H+R Native form identity and submitted-value extraction velar/forms captures HTMLFormElement identity, FormData construction and get/getAll/has/forEach, result Map operations, and decimal parsing intrinsics when its generated module initializes. Later global replacement, constructor Symbol.hasInstance, or FormData prototype mutation cannot reject an already-owned form, intercept submitted values, change repeated-field grouping, or widen the documented decimal grammar. Runtime Type and decoder data are validated before FormData construction. DOM mutations are owned separately by B-WEB-HOST-FORM-DOM. Web Forms runtime, permanent source guard, hostile post-initialization WebIDL test, descriptor/budget tests, and real Chromium form application scenarios.
B-WEB-HOST-FORM-DOM H+R Form error nodes, accessibility metadata, focus, pending state, and reset The Forms module captures Document, Node, Element, HTMLElement, HTMLFormElement, control-brand getters/setters, HTMLCollection/NodeList snapshots, and its pending WeakMap operations during initialization. Real branded DOM values use captured prototype contracts; explicit test hosts may expose enumerable own data fields/methods, while accessor shadows are rejected without execution. Error nodes and ARIA tokens are bounded snapshots, duplicate owned errors clear together, every control disabled state is validated before any pending mutation, restoration uses the saved bool values, and reset restores owned state before invoking the captured native reset. Later global/prototype/instance replacement cannot redirect these operations. Web Forms runtime and source guard; complete hostile DOM lifecycle, accessor-containment, error-budget, pending-restore, and Chromium typed-form tests.
B-WEB-COMPONENT-ROOT L+R Component root identity, replacement, mount, and teardown Direct JSX roots remain stable hosts. Every non-direct WebNode root expression runs in a dedicated dynamic child scope so reactive conditions replace transactionally without rerunning component setup. Teardown removes the currently selected nodes, and one component instance accepts exactly one mount. Web emitter/runtime; generated-code assertion, fake-DOM execution, existing Router/lazy/dynamic-component lifecycle tests, and zero-npm Editor three-browser acceptance.
B-WEB-TEST-METRICS H+R Production-renderer navigation and interaction timing evidence velar/web-test installs a test-only runtime before application code and exposes bounded navigation/FCP snapshots plus measured click/fill/press actions. Interaction records separate input delay, synchronous dispatch processing, and the next animation frame; the last value includes queued framework DOM publication and rendering. The CLI validates every returned plain record and ordering invariant. No runtime field, arbitrary evaluation, clock callback, or event injector enters production modules or Vel source. CLI browser-test runner and typed Web test interface; controller-surface/codegen tests, production Web Chromium gate, and zero-npm Editor FCP/input/1-MiB samples.
B-CLI-WORKSPACE-INDEX H+R Session-persistent workspace text and symbol lookup Compiler semantic indexes remain the only VelarScript semantic facts and the CLI projects them through workspace/symbol. The LSP process separately retains literal-search text for the initialized .vel/JS/TS/JSON/Markdown/CSS workspace, overlays unsaved documents, consumes exact watcher invalidations, and rebuilds only on explicit rescan. Authority is bounded to initialized roots; .git, .velar, dist, and node_modules are excluded. The owner caps 50,000 files, 4 MiB per file, 128 MiB aggregate retained text, 1,024-code-unit queries, and 10,000 results. Watcher input is capped at 4,096 decoded paths, 4,096 code units per path, and 2 MiB total path text; malformed/overflow input becomes an authoritative rescan, while repeated decoded paths inside a legal entry envelope are removed before filesystem authorization. Exact changes are ancestor-normalized and invalidate retained records in one depth-bounded pass, with received/root/removed activity evidence. Active work yields every 128 files for framed cancellation, and coordinate tables exist only for matched files so newline density cannot multiply retained RSS. Resource-excluded unsaved overlays retain only an exclusion marker and remove any stale searchable disk snapshot; close restores disk through the bounded reader. This is an LSP-session cache, not persisted disk state or an Editor filesystem/parser workaround. CLI workspace-index and LSP owners; exact-change/open-overlay/resource-exclusion/Unicode/CRLF/ignored-path tests, standard workspace-symbol integration, request validation/cancellation/overflow-rescan, 20,000-file search plus 4,096-change latency/RSS gate, real 20,000-file disk probe, packaged LSP probe, and zero-npm Editor consumption.
B-CLI-BROWSER-TEST H+R Browser-test deadlines, process ownership, interruption, and cleanup Browser tests and the direct browser acceptance matrix run inside dedicated IPC-supervised workers. Tests have a 120-second deadline, a run has a 20-minute aggregate deadline, and cleanup has a 10-second deadline. Each browser is an explicit BrowserServer owner whose connection, server, and child process converge through close, kill, and SIGKILL fallback. POSIX workers own isolated process groups; the supervisor forwards SIGHUP/SIGINT/SIGTERM, preserves exit codes 129/130/143, kills residual group members before returning, and the worker treats parent IPC disconnect as SIGTERM. A timed-out VelarScript Promise or force-killed supervisor therefore cannot retain its Node timer, browser server, or renderer. CLI browser-process owner and browser-test runner, direct browser acceptance owner, permanent source guard, real Chromium non-settling-test deadline, signal, supervisor-SIGKILL/IPC-disconnect, descendant-observation, and post-exit process probes.
B-UNSAFE-HTML U unsafe:html Only an explicit string boundary bypasses owned DOM construction; sanitization and trust belong to the caller. Web analyzer/emitter; unsafe HTML diagnostics and browser tests.
B-UNSAFE-CSS U import css unsafe Native CSS is explicit and source-ordered but remains outside Look's controlled semantic model. Web parser/analyzer/host; CSS boundary tests.
B-CORE-HASH H+R Bounded UTF-8 SHA-256 text digests velar/hash.sha256Text is one target-neutral Core contract and implementation. It encodes text and computes SHA-256 through Core binary buffers, accepts at most 16 MiB of UTF-8 text, and returns exactly 64 lowercase hexadecimal characters without exposing an algorithm selector or mutable Hash handle. Node, Web, and Desktop consume the same source; later replacement of ambient reflection or string prototype operations cannot redirect the digest. Core module interface, runtime and dependency graph; known-vector, Unicode, bound, wrong-type, compile-contract, packaged execution, and post-initialization poisoning tests.
B-CORE-VALIDATION H+R Structural parsing plus composable semantic rules Compiler-owned Type.parse remains the only structural schema system. velar/validation composes bounded target-neutral rules, field/List paths, aggregate inspection, throwing validation, and safe parsing without coercion, defaults, I/O, or environment access. The runtime captures its Array, Number, Object, String, Reflect, and ValidationError operations at initialization; rules and issue aggregation have explicit ceilings. Core module interface, runtime and dependency graph; generic compile contracts, real generated execution, structural/semantic failure, path aggregation, and invalid-rule construction tests.
B-NODE-HOST R First-party Node standard modules Typed source contracts are provided by the Node compiler extension; Node implementations validate host values without importing CLI orchestration. Environment reads retain the initialized process.env identity and own data fields. Shutdown captures signal, exit, clock, timer, Promise and synchronous diagnostic operations, bounds registration and the total graceful deadline, and observes native cleanup Promises without a live then lookup. Filesystem, inbound-server, and outbound-HTTP effects share the private transitive runtime velar/node-host-v1, which has no public module interface: application-facing velar/fs owns captured path/number/UTF-8/typed-byte/result validation, velar/http owns lazy request values, option/secret snapshots, timers, Type parsing and host-result validation, while velar/serve owns handlers, strict JSON/runtime-Type boundaries and Vel request/response values. Their eagerly handshaken static-built-in Worker alone owns node:fs/promises, callback node:fs watchers, HTTP/HTTPS clients and servers, sockets, request/response streams, fatal HTTP UTF-8 decoding, redirects, static-file reads, writes and backpressure. createText reaches one OS exclusive-create operation, so existence checking and creation cannot be split by another actor or redirected through an entry that appeared between calls. replaceTextIfMatches compares exact bounded UTF-8 bytes and commits by same-directory rename; all file mutations for the same lexical/canonical identities in this Worker share one queue, while unrelated processes are explicitly outside this portable optimistic-edit contract. watchFiles exposes only a resource-owned async-pull invalidation stream: one active pull, 128 live handles, 4,096 distinct queued paths and 2 MiB path text. Safe paths are sorted/deduplicated; unknown native filenames and overflow collapse to an empty rescan=true batch. close() settles a pending pull with null, native failures are terminal, and active watchers retain the otherwise-idle private Worker until released. Its captured MessagePort proxy revalidates both directions, caps 1,024 pending operations, 128 active servers, 4,096 active inbound requests and 1,024 active outbound HTTP requests, wraps identities without colliding with live handles, releases idle imports, and retains active operations, servers, watchers and unread HTTP responses. One 128 MiB Worker-wide byte budget covers cached inbound request bodies, static files, buffered server responses and in-flight stream writes so per-request server limits cannot multiply without bound. Stable bytes are released only after transport completion/disconnect and all active host operations settle; stream chunks use separate flush-scoped reservations, preventing both leaks and close-time double release. A disconnected inbound request with application work still outstanding retains its bounded task until the next host operation reports a stable client-closed failure and releases ownership, rather than losing its terminal reason between stream writes. Process output uses the language pull protocol with enum-tagged stdout/stderr chunks, one reader, incremental UTF-8 decoding, and consume-before-wait lifecycle. Its child-process/EventEmitter/stream/decoder/Buffer transport completes an eager handshake in a separate static-built-in Worker; the captured MessagePort proxy revalidates every response, idle imports are unreferenced, active requests/children retain lifecycle, and 128 unreleased handles form the resource ceiling. stop() closes reads on first request but caches only successful confirmation: SIGTERM escalates to SIGKILL after two seconds, missing close rejects after five seconds without deleting the handle, and a later stop retries the same owner. Terminal arguments, queued lines, output, pending operations, and permanent close are likewise bounded, but line decoding/fd transport runs in its own static-built-in Worker because Node Readable/readline internals continue through public application-Realm prototypes. The proxy duplicates POSIX stdin before dependencies run, validates every response, releases idle imports, retains pending operations, and creates the Worker-side input stream only for the first readLine; close seals or destroys it and releases the owned descriptor after a closed handshake. None of these Workers, ports, streams, buffers, descriptors, private dependencies, or host records enters the VelarScript API. packages/node; Node platform, env/fs/serve/http/host/terminal hostile post-initialization execution, compiled file-watcher and terminal pull code, real external file invalidation and close behavior, process pull/ordering/UTF-8 lifecycle, retryable stop confirmation, active/idle/close Worker lifecycle, isolated-source/dependency/handle-wrap/aggregate-budget guards, strict serve data shapes, concurrent quota/release, real outbound HTTP redirect/cancellation/UTF-8/metadata/chunk behavior, real inbound HTTP/backpressure/disconnect/static-file behavior, and real-signal shutdown tests.
B-WORKER-FAILURE R Private Worker and capability-host crash convergence Every Node Worker proxy persists its first unexpected clean/non-zero exit, error, unreadable message, or invalid response as a terminal host-generation failure; all pending and future calls reject instead of posting to a dead port. Terminal failure remains an error rather than EOF, and invalid response validation occurs before removing the pending owner. The process Worker transfers handle/PID ownership before public start completion, fatal-drains children through live ChildProcess handles on uncaught failure, and leaves the proxy a bounded process-group kill fallback. Desktop emits the same private owned/settled events; its macOS shell tracks forwarded request IDs and PIDs, rejects pending/future bridge work on write, protocol, or worker failure, and reaps registered groups. No host silently restarts behind live numeric handles because resource identities cannot cross generations safely; application restart is the explicit authority reset. Node shared-host, terminal and process proxies; Node/Desktop fatal-drain workers; macOS native host; permanent source guards, injected Worker exits, transferred-child reaping, native compilation, and lifecycle-event integration tests.
B-SERVER-FRAMEWORK C+R Explicit server application assembly @velarscript/server is an explicitly activated application extension that composes, but is not built into, @velarscript/node. It alone owns velar/server, the checked project-relative server.configuration path, strict bounded YAML/JSON decoding, typed configuration validation, host/port/body-limit projection, application server assembly, provider-neutral request authentication, and generic application-scoped connection setup/cleanup. The selected entry executes startup and transport lifetime inside @main, matching Core, Web, and Desktop entry semantics. Authentication accepts only Node-owned security descriptors and a nullable async verifier, resolves once per request, preserves the descriptor's opaque 401 challenge for rejected credentials, and leaves verifier failures as server failures. The Node capability does not load application configuration. Concrete token/session/password implementations, identity stores, authorization policy, database models, drivers, pools, queries, migrations, and vendor policy remain installed-library or application-owned dependencies. Server extension manifest/compiler/runtime, entry/configuration typing and build-manifest tests, authentication typing and live 401/identity injection, package-boundary tests, generated-project acceptance, and OpenVoxel consumer validation.
B-DESKTOP-COMPOSITION L+R Single-project Desktop applications Desktop declares Web and Node API provenance through application composes, explicitly selects each public Web compiler layer, consumes selected public Node capability contracts/runtime fragments, and replaces only target-owned host modules. Object-spread inheritance is forbidden so a new Web layer cannot enter Desktop unnoticed; renderer/main/transport remain internal boundaries. packages/desktop compiler/host; boundary guard; Desktop project, package-metadata, and headless CLI tests.
B-DESKTOP-CAPABILITIES R+C Files, paths, processes, HTTP, environment, and secrets in Desktop The manifest independently grants bounded app-data/project file APIs, exact native executable launches, origins, readable environment, and disjoint host-only secrets. File content operations authorize canonical targets; metadata/move/removal authorize the final entry, and dangling links never become absent write targets. replaceTextIfMatches shares Node's optimistic-edit shape: exact bounded content, one capability-Worker mutation queue per canonical target, same-directory replacement commit, and no fictional lock over external processes. watchFiles preserves Node's invalidation-stream shape and bounds while additionally qualifying every handle by the current renderer owner and file grant; close, owner retirement, input shutdown, fatal drain, and project-root replacement release watchers and prevent old-root events from publishing. Path inputs, dense part Lists, combined outputs, native absolute path results, and environment snapshots are independently bounded and data-descriptor checked. platform() returns the finite DesktopPlatform enum (macos, test); a new native member is added only with a real host. The macOS Desktop path runtime follows the Node target's POSIX lexical semantics, including duplicate/trailing separators and unnormalized dirname/basename/extension operands; a generated differential corpus prevents the same public module from drifting across these targets. A process grant is explicit native-program authority, not an OS sandbox; product approval and argument policy stay outside the language package. Filesystem and process inputs/results cross strict bounded records, and process-only apps use the launch directory without gaining velar/fs. Process output crosses the isolated worker as enum-tagged pull chunks with one active reader, per-channel incremental UTF-8 decoding, aggregate bounds, and renderer/worker enforcement of the consume-before-wait lifecycle. A first stop request permanently closes reads, while renderer and worker retain an unconfirmed handle: transport rejection clears only the rejected cached Promise, the worker bounds confirmation at five seconds, and a later stop escalates again instead of treating intent as resource release. The renderer composes Node's canonical process host ABI instead of duplicating validation or result semantics; post-initialization intrinsic replacement cannot change either target's accepted values. Secret HTTP descriptors carry names, never values; the worker resolves them and strips derived headers across origins. Renderer proxies use a versioned, bounded, chunk-capable bridge; the isolated Node worker revalidates every request, canonical path, watcher, process, redirect hop, stream, cancellation, and size boundary. Headless tests reach the page bridge only through restricted velar/desktop-test controls. setPlatform selects the enum branch before that isolated test's first browser.open; it proves application branching, while native integration remains the evidence for operating-system behavior. Desktop renderer-runtime, file-watcher batch/List validation, external invalidation and root-switch release, process pull/ordering/UTF-8 lifecycle, retryable stop confirmation and intrinsic-poisoning, POSIX path differential corpus, bridge-transport, native-host, CLI-host, and worker integration tests.
B-DESKTOP-PROJECT-GRANT R+C User-selected single-project authority selectProjectDirectory() is available only with the manifest project file grant and owns the native directory chooser, bounded bookmark persistence, restoration, canonical-directory validation, and a no-timeout user decision. Cancel returns null; selectedProjectDirectory() distinguishes explicit/restored authority from the private fallback, while projectDirectory() reports the effective root. A successful replacement is ordered through a generation-qualified private host command before renderer completion. The capability Worker independently canonicalizes the new directory, cancels unpublished operations, drains project-owned processes and HTTP streams, retains already-committed filesystem settlement, replaces only the project root, and preserves the separate app-data root. Relative filesystem and default process cwd resolution use the new root; the synchronous path module reads a captured data-valued provider whose private cell is updated only by a validated native selection response. Renderer code cannot manufacture a Worker grant by mutating the exposed bridge. Desktop module interface/codegen, injected bridge, macOS bookmark/chooser host, capability Worker project-root command, hostile bridge execution, real root replacement/process-release integration, deterministic test picker, and zero-npm Editor open/save/conflict/recovery browser acceptance.
B-DESKTOP-PRODUCT-BOUNDARY R+C Language framework versus product tooling @velarscript/desktop owns only the checked Desktop language surface, capability bridge, native shell, and isolated capability Worker. Language servers, project-task orchestration, PTY sessions, project-change transactions, approval workflows, and editor UX are product concerns and are not bundled into every application or granted private bridge operations. A product installs and owns those services independently and may consume only documented compiler, filesystem, process, or protocol contracts. Desktop public-module and package manifests, native/Worker source guard, size-composition test, packed-consumer acceptance, and runtime-boundary gate.
B-DESKTOP-HOST-ABI R Desktop bridge identity and transport operations Every target module captures the bridge object, its own data-valued invoke operation, and module-specific snapshot fields during initialization. velar/service reaches the same one door: the shell dials and authenticates a declared service's loopback channel and the renderer receives an already-open channel, so the 128-bit token exists only in the host and in the service process's environment and never in application code. Later global replacement cannot redirect filesystem, path, process, HTTP, environment, or Desktop operations. The injected system-WebView transport independently captures its serialization, encoding, collection, timer, Promise, and native message-handler operations before application JavaScript runs. Desktop boundary guard, hostile global/prototype/transport poisoning tests, native bridge chunk tests, and packed application smoke.
B-DESKTOP-DOCUMENT-GENERATION R Reload/navigation response and resource ownership Every main document creates a private random generation. Native code maps (generation, page request id) to a host-global Worker request id and returns a response only to the matching generation, so restarted page counters and late responses cannot collide. A committed navigation retires pending delivery, process groups, and HTTP streams from the old generation; every Process/HTTP handle operation and post-await publication rechecks its owner. Completion hooks also require the private generation. Already-committed filesystem effects may finish but their retired results are discarded. Injected bridge, macOS native request ledger/navigation delegate, capability Worker; wrong-generation completion, same-page-id simulation, real process/HTTP owner-switch tests, real WKWebView reload with child reaping and a replacement capability call, native compilation, and permanent boundary guard.
B-DESKTOP-BACKPRESSURE R Bridge aggregate memory and request cancellation Page and native layers each cap pending serialized requests at 128 MiB, while page response assembly has an independent 128 MiB aggregate ceiling. A finite timeout sends a generation-qualified cancel record and retires native delivery without releasing/reusing its Worker ID before the terminal response. The Worker tracks active dispatches, aborts HTTP and drains unpublished/hidden processes on cancellation or host-input close, and leaves non-cancellable filesystem effects reserved until they settle. Late cancelled responses are discarded rather than classified as protocol attacks. Injected bridge, macOS request ledger/cancel transport, capability Worker; timeout-cancel bridge test, real cancelled HTTP-handle reuse and hidden-process reaping, native compilation, and permanent source guard.
B-DESKTOP-PACKAGING R Self-contained, signed system-WebView application bundle velar package loads a target-neutral application-package host. CLI owns one checked renderer build; Desktop owns native assembly and never imports or executes CLI. The bundle contains the native host, application renderer/assets, one capability Worker, icon, metadata, any desktop.services payloads, and one bare Node.js executable—no browser engine, compiler, language server, task runner, transaction service, or PTY host. The runtime version belongs to the toolchain generation, not the project: one pinned version and one official SHASUMS256 digest, downloaded at package time, verified, and cached per version/platform/architecture, with a corrupt cache entry read as absent and an offline miss naming the version and the cache directory. The build records every byte class and a streamed tree hash, holds the application's own components to one size budget, and holds the runtime to a separate toolchain-owned integrity ceiling. Layout follows signing: the runtime sits in Contents/MacOS because a Mach-O in Contents/Resources is sealed as a plain resource and never signed, and the bundle is signed inside-out—service payload Mach-Os deepest first, then the runtime with the language's minimal allow-jit entitlements, then the host, then the bundle—ad-hoc when no identity is configured. Identity, product entitlements, and notarization credentials are the product's and reach the build as a keychain-profile reference; none of them enters the manifest or a log line. Runtime discovery is a launch-time contract: an explicit absolute override, the bundled runtime, then absolute PATH entries and trusted system package-manager locations. Build-machine executable paths never enter the application or build manifest. applyUpdate replaces the installed bundle only with an archive carrying the same bundle identifier and Team ID, verified nested-code-inclusive before anything on disk is touched. Generic package-host validation, Desktop source-build and zero-npm packed-consumer acceptance, exact host-resource roster, runtime cache hit/miss/corrupt and digest-refusal tests, signing-plan and live codesign tests, and --headless-smoke run under a sandbox-exec profile that removes every external Node, including a fixture whose declared service must start, authenticate, reach ready, and converge.
B-SOURCE-PACKAGE-TARGET C+H Source-package target, frozen artifact, and host requirements Every installed Vel package declares velar.targets and velar.requires.capabilities. core is the target-neutral portability claim and is admitted by Core, Node, Web, and Desktop; target-specific declarations remain exact. A package may additionally declare one Core or Node ABI-1 receipt: the resolver verifies the receipt and its JS/map/interface hashes, checks target/capability compatibility, loads the portable interface, and does not read package source. Core artifacts may retain only compiler-runtime roots whose complete active-extension closure is target-neutral; Node-only roots and target-owned transitive implementations fail at production and consumption. Node artifacts require Node. Sandbox loaders preserve the installed package URL for npm ownership but serve only the authenticated entry/chunk bytes and inline source-map snapshots, so validation and execution do not reopen the artifact path. Without a compatible artifact, language generation is checked before source is read and the existing source fallback compiles. Stable nominal identities use package name, version, and source-relative path rather than installation paths. These fields select compatibility only; they cannot create Standard modules, host authority, or hidden compiler behavior. Source/artifact package resolver and builder, strict interface codec, package-contract gate, compiler-runtime target-closure tests, authenticated snapshot race execution, Core-to-Web portability, cross-generation invalid-source execution, tamper, incompatible-target/capability tests, and packed consumers.
B-APPLICATION-OWNERSHIP C Application libraries, external-service adapters, and product tooling Database models, connections, drivers, pools, queries and migrations, codecs, compression, procedural algorithms, provider deployment projections, editable-text engines, and non-VelarScript language services belong to the application or an independently maintained dependency. The toolchain supplies only public package, compiler-extension, framework-host, target capability protocols, and generic lifecycle composition; it does not publish privileged implementations or hide them in the CLI. Workspace package boundary test, packed synthetic source-package consumer, target rejection, and application-owned tests.
B-RESOURCE-CEILINGS L+R Source, collection, graph, JSON, output, and host-resource limits Compiler and runtime work is bounded and fails with explicit diagnostics or errors instead of unbounded traversal or coercion. Compiler/CLI/Web/Node/Desktop owners; hardening and performance tests.

For B-NODE-HOST and B-DESKTOP-CAPABILITIES, process completion now has two deliberately different recovery modes. Explicit stop() retains an unconfirmed handle and remains retryable. Natural root exit instead owns a bounded output-drain phase: the isolated host terminates the original process group, escalates after two seconds, and after five seconds closes only its own stdout/stderr read ends with a terminal error if an escaped descendant still holds the pipes. This bounds next()/wait()/run() without pretending that an exact executable grant is an OS sandbox. Desktop transports terminal stop errors as the same validated result/error envelope as Node.

wait() and run() preserve that ownership rule rather than treating every Promise rejection as a terminal child result. The private Node/Desktop host protocol returns a validated result/error/retained outcome: terminal outcomes release and remain idempotently cached, while unconfirmed termination retains the handle and clears only the rejected in-flight wait. Raw bridge rejection is also retryable because it cannot prove resource release. A wait following a retained outcome reissues forced termination. Concurrent waits coalesce, while a confirmed Stop outcome supersedes a stale concurrent wait cache before the handle is released. Since run() does not expose its temporary Process value, the shared runtime retains it after a non-terminal failure and retries stop confirmation in the background. Timeout and output-bound termination wake an already active wait and start their own five-second confirmation window, so missing exit/close cannot turn an execution deadline into an unbounded wait.

Required feature decision record

Every new public language, standard-module, Web, Node, Desktop, or JavaScript-bridge feature must answer these questions before implementation:

  1. What JavaScript or host representation carries the value?
  2. Which host behaviors are deliberately inherited?
  3. Which host behaviors are rejected, normalized, or replaced?
  4. Which boundary classes apply to each operation?
  5. What can the analyzer prove, and what still requires runtime validation?
  6. What is the exact evaluation order and evaluation count?
  7. What adaptation occurs when values enter and leave foreign code?
  8. What fails at compile time, module initialization, or ordinary runtime?
  9. Does the feature consume or change a cross-module ABI?
  10. Which diagnostic, emitted-code, and execution tests prove the contract?

A proposal is not implementation-ready while any answer is unknown. Product semantics belong in the charter first; implementation choices belong in the architecture and code only after that contract is fixed.

Verification gate

Boundary work is complete only when all relevant layers are present:

  1. A charter statement defines the user-observable behavior.
  2. This ledger classifies the operation and names its owner.
  3. A diagnostic test proves rejected source behavior.
  4. An emitted-code test proves lowering, ABI use, and single evaluation where relevant.
  5. An execution test probes hostile host values such as accessors, sparse arrays, poisoned prototypes, fake thenables, cross-realm values, incompatible runtime registries, and JavaScript undefined.

Purely host-inherited or compile-erased rows may not need all five layers, but the ledger must make that omission explicit rather than leaving it accidental.

One gate runs at a time per checkout. A gate rebuilds packages/*/dist through a clean step, binds fixed test ports, and writes .velar/ sandboxes inside examples/; that state belongs to the checkout rather than to the run, so two gates started in one working tree corrupt each other and the failure stops being about the code. The workspace scripts that start one — build:packages, check, gate, test, test:browser, test:packages, release:check, and velar — therefore run under scripts/gate-lock.mjs, which holds <checkout>/.velar/gate.lock for the duration; a later gate waits for it instead of starting. A recorded holder is reclaimed only when it names this host and its process is gone, so a running gate is never displaced. A lock file whose contents do not parse as a holder record was abandoned between creation and its first write: it names no host and no process to test, so it is reclaimed on age alone, ten seconds after its last modification. Individual checks invoked directly, such as check:docs, take no lock. The lock is re-entrant within one process tree, so a locked gate may call another locked script, and it lives inside the workspace it guards, so separate checkouts, git worktrees, CI jobs, and the temporary workspace built by scripts/isolated-toolchain-build.mjs never wait on each other. It is deliberately not in the system temporary directory: that directory is world-writable on a shared host and a path derived from the checkout is not a secret, so any local user could pre-create the lock naming a process that never exits and wedge every gate in the checkout for good. .velar/ is already ignored by git and already the CLI's own scratch namespace, so the lock never dirties the tree a release candidate checks.