Skip to content
LogoLogo

VIP-31: runtime guarantees

Status: accepted, 2026-10-29, under Will's standing approval of recommendations ("assume I accept now. I will interrupt you if I need to").

Decision

  • No runtime semantics of VibeLang's own. Every accepted construct is exact sugar for Effect, so failures, defects, interruption, finalizer order and Cause combination are Effect 4's.
  • The guarantee. Compiled output gives the same Exit as the Effect TypeScript shown in each VIP: success, failure, defect or interruption, with finalizers in the same order.
  • Interruptor identifier equality. Renaming preserves the native equality classes of Cause.interruptors: repeated NaN identifies one interruptor, Infinity and -Infinity identify different interruptors, and 0 and -0 identify the same interruptor. For an interrupt-only failure Exit, identifiers [NaN, Infinity, -Infinity, NaN] have the canonical identity sequence [0, 1, 2, 0]; identifiers [NaN, NaN, NaN, NaN] have [0, 0, 0, 0].
  • Checking it. Each VIP's VibeLang and Effect TS pair is a differential test that compiles one, runs both, and compares their Exits. The fuzz suite generates more pairs.
  • Encoded reason tags. An encoded cause reason's _tag must be the string Fail, Die or Interrupt, including in nested encodings; any other tag value fails the comparison with an encoding error.
  • Runtime helpers are limited to small shims, such as defining Symbol.customMatcher where an engine lacks it (VIP-7).
  • Clarified 2026-11-03: global matcher initialization. Where absent, the runtime defines an own global Symbol.customMatcher with value Symbol.for("Symbol.customMatcher"), non-writable, non-enumerable and non-configurable. A pre-existing host symbol keeps its identity. The runtime export and all matcher keys share the actual symbol; emitted VibeLang modules using it request the synchronous initialization dependency first, before every other import or re-export dependency, preserving source dependencies' relative order. This orders dependencies first reached through that module, not modules already evaluated through another path. Types alone execute nothing; TypeScript modules, including VIP-40 bodies, keep ordinary dependency order and arrange initialization before using the key, normally with import "vibelang-runtime" first. See Runtime guarantees for the ordering contract. This completes the existing shim authorization and the accepted VIP-7 counterparts; it does not promise symbol transport across agents.
  • Effect handlers (handle/resume) would need a continuation runtime, and are decided separately.
  • Amended 2026-10-29: differential tests compare the canonical Exit. A pair agrees when both runs end with the same canonical Exit (CanonicalVIPExit in typescript/tsc/internal/vibelangfuzz/vip.go: ordered keys, Cause reasons in their order, payloads by class name, name, message and own enumerable fields with stack dropped, fiber ids renamed by first appearance) and the same finalizer trace. Object identity is never compared; a fixture that needs more names its extra check. Decided by the agent on 2026-10-29 under Will's rule "when I state a principle, the agent derives the concrete rule and acts; I can override later" (decided detail 91).
  • Amended 2026-10-30: observer payloads and source completions. A provide or interruption region preserves its source completion separately from the primitive Effect success value. Normal completion and outward break/continue give primitive success undefined; a source return value gives that exact value, and bare return gives undefined. Nested regions apply this at each boundary. Finalizers observe these generator payloads, never compiler control records; a normal source value still contributes to an enclosing do. Real returned Effects and record-shaped objects remain data. Completion state is fresh for each execution/item, and failed, dying or interrupted bodies/finalizers transfer no pending source completion. This preserves the original generator counterpart and Effect's own finalization rules; see Region bodies.

History

Old VibeLang's Part III (continuations, region ownership, its own rules for combining cleanup failures) served features that VIP-8, VIP-17, VIP-21 and VIP-22 denied or redefined as sugar. Its findings, including the round-2 and round-3 blockers about disposal ownership, don't apply.