Skip to main content

Standard Library Overview

The Verum standard library — core — is written in Verum. It provides semantic-honest types, concurrency primitives, I/O, network, math, and a pure-Verum math library (replacing libc's libm).

Layered architecture

The layering is not a description — it is data, and it is enforced. core/rings.toml declares which ring each module belongs to, and scripts/ci/check_core_rings.py measures the actual mount graph against it on every PR.

When the law was first gated, on 2026-08-08:

[ok] ring law holds: 2557 modules, 5275 inter-module edges, 0 violations

Re-measured 2026-09-02, the gate reports four upward edges:

[fail] 4 UPWARD edge(s) across 4 mount site(s):
base.env(r1.0) -> text.format(r2.0)
sys.fs_watch(r1.0) -> text.format(r2.0)
sys.process_native(r1.0) -> text.format(r2.0)
sys.process_ops(r1.0) -> text.format(r2.0)

None of those four modules names a formatting dependency — each writes a selective root mount of primitives, mount core.{Maybe, Result, List, Text, Byte}. The edge comes from how the gate counts a root mount: as a dependency on everything core/mod.vr re-exports. That set gained text.format on 2026-08-23, when format_debug joined the prelude because the language itself inserts the name — f"{x:?}" desugars to a bare format_debug call, so it has to resolve everywhere.

So the layering itself is intact and the measurement is not. The distinction matters if you are reading this to decide where to put a module: the rings below are the law, and the four edges above are an artefact of counting, tracked separately.

Ring 5.5 integration-client the CLIENT halves: sigstore, tuf, oidc,
spiffe.workload_api, x509 revocation clients
Ring 5 domain net, security, database, storage, term, cli,
shell, mesh, redis, search, compress, money,
protobuf, architecture, theory_interop
Ring 4 language-services meta, cog, proof, verify, archive, script,
diagnostics
Ring 3 runtime async, runtime, concurrency, context, control,
tracing, metrics, signal, cache, action, eval
Ring 2 data collections, text, encoding, math, simd, logic,
io, time, sync, configuration, id
Ring 1.5 byte-primitive hash, mac, random, subtle,
security.{ecc, cipher, aead, kdf}
Ring 1 platform sys, mem, target (cohesive)
Ring 0 primitive base, types, intrinsics,
collections.{list, map, set}, text.text (cohesive)

The law: a module in ring N depends only on rings below N. A ring marked cohesive is one layer whose members are mutually dependent by design — Maybe.ok_or → Result and Result.ok → Maybe are paired conversions; an atomic that blocks IS a syscall, and the syscall layer cannot initialise without an atomic. Cutting either edge would duplicate one side, not improve anything, so cohesion is declared and the cycle check skips those rings only.

Placement follows measurement, not topic. Two consequences a reader will notice:

  • List, Map, Set and Text sit in ring 0, not with collections and text. They are the LANGUAGE's vocabulary — base uses them in 384 places and collections/list.vr depends on base, a genuine mutual dependency. The rest of collections (btree, deque, lru, bloom) and of text (regex, formatter) is ring 2.
  • Digests, MACs, entropy, constant-time operations and the ciphers, AEADs, curves and KDFs sit in ring 1.5, below security. They are computation over bytes: a Bloom filter needs a hash, not a dependency on the crypto stack, and TLS cannot encrypt a packet without an AEAD.

Sub-modules may carry their own ring where the parent's is wrong for them — runtime.{thread, pool} are ring 2 because async is BUILT ON them, while runtime.{spawn, supervisor} are ring 3 because they are built on async.

Top-level modules

ModulePurpose
baseMaybe, Result, Iterator, operator protocols, panic, environment
collectionsList, Map, Set, Deque, BinaryHeap, BTreeMap, BTreeSet
textText, Char, formatting, regex, tagged literals
memCBGR allocator, Heap, Shared, reference primitives
intrinsicscompiler intrinsics (SIMD, atomic, memory, CPU)
hashdigests grouped by GUARANTEE: checksum / fast / crypto / legacy
mackeyed authentication — HMAC, Poly1305
randomsecure (platform CSPRNG) vs deterministic (reproducible)
subtleconstant-time comparison, zeroization that survives optimisation
idunique identifiers — UUID, ULID, NanoID, Snowflake
iofiles, paths, stdio, processes, Read/Write protocols
timeDuration, Instant, SystemTime, timers
sysV-LLSI kernel bootstrap (direct syscalls)
term7-layer TUI framework
asyncFuture, Task, Channel, executors, generators
syncatomics, mutex, rwlock, condvar, barriers
runtimeruntime configurations, supervision trees
netTCP, UDP, HTTP, TLS, DNS
mathpure-Verum math (libm replacement), linalg, autodiff, tensors, neural networks
simdportable SIMD types and operations
metacompile-time programming (tokens, AST, quote, reflection)
proofproof carrying code, reflection protocol
theory_interopTheory registry, translation, coherence audit, JSON-RPC interchange protocol
contextscope, providers, context layers
securitysecurity labels, regions
databaseSQLite ("loom" — pure-Verum reimpl), Postgres, MySQL adapters; affine Transaction, online backup, hooks, typed pragmas, BLOB I/O, LISTEN/NOTIFY, COPY

Semantic-honest types — the cheat sheet

Use thisNot this (in other languages)
List<T>Vec<T>, vector<T>, ArrayList<T>
TextString, str
Map<K,V>HashMap<K,V>, dict, std.map
Set<T>HashSet<T>, set<T>
BTreeMap<K,V>TreeMap<K,V>, std.map
Heap<T>Box<T>, unique_ptr<T>
Shared<T>Arc<T>, Rc<T>, shared_ptr<T> (atomically refcounted; CBGR-tracked)
Cow<T>Cow<T> (clone-on-write borrow, owned-on-mutation)
Maybe<T>Option<T>
Result<T, E>Result<T, E>, expected<T, E>
Deque<T>VecDeque<T>, deque<T>
BinaryHeap<T>BinaryHeap<T>, priority_queue<T>

Naming conventions

  • Types: UpperCamelCase (List, MutexGuard).
  • Protocols: UpperCamelCase, verb-ish (Clone, Display, Iterator).
  • Functions: snake_case.
  • Constants: UPPER_SNAKE_CASE.
  • Modules: lower_snake_case.

Zero FFI

The stdlib has no Rust or C++ dependencies. The bootstrap layer (sys) uses direct syscalls on Linux, libSystem.B.dylib on macOS, and kernel32/ntdll on Windows — all via Verum's own FFI machinery. This means:

  • Cross-compilation doesn't also mean cross-building a C toolchain — the stdlib itself carries no C/C++ dependency to cross-compile. You still need a linker and sysroot for the target platform; see Build System → Cross-compilation.
  • Embedded targets are first-class.
  • Upgrading the compiler does not change stdlib ABI.

core vs std — the allocator boundary

The standard library splits in two at the allocator line:

  • core (this is the root cog) is allocator-free. It has no Heap<T>, no Shared<T>, no dynamic List<T>, no heap-backed Text. Everything lives on the stack or in static storage. core is the library you can link into a bare-metal target with a 16 KiB image budget.
  • std (also spelled core.* in imports) is everything else — the CBGR allocator, List, Map, Set, Text, async runtime, IO, network, TUI, tensors. std depends on core; core depends on nothing but compiler intrinsics.
FeatureIn coreIn std
Primitives (Int, Float, …)
Maybe<T>, Result<T, E>, Ordering
Eq, Ord, Hash, Clone, Copy, Default, Debug, Display, Drop, Send, Sync, Sized
Operator protocols (Add, Sub, …, Try)
MaybeUninit<T>, @intrinsic("...")
Panic handling (abort-based)
Heap<T>, Shared<T>, Weak<T>
List<T>, Text, Map<K,V>, Set<T>
Async runtime, channels, timers
IO, network, TLS, DNS
math, simd, tensor, gpu

Embedded and no_heap targets automatically compile with core only; attempting to mount an std-only module triggers a compile-time error that names the profile mismatch rather than producing a cryptic link error.

Tier-specific availability

Some stdlib features require a runtime that supports them:

Runtime kindAsyncHeapThreads
full
single_thread1
no_asynccompiled to syncoptional
embeddednostack-only1
no_runtimestubsno1

Configure via verum.toml:

[runtime]
kind = "full"

Browsing the stdlib

$ verum doc --open core # generate + open docs
$ verum doc --search "Iterator" # search
$ verum api --signature "fn map" # NOT IMPLEMENTED — see note below
warning
verum api does not exist

Measured 2026-09-03: verum api --help answers error: unrecognized subcommand. There is no signature-search command. verum doc generates documentation and is the nearest thing that ships.

Source lives at core/.

Stdlib status badge system

Every stdlib module page carries a conformance status badge at the top, rendered by the <StdlibStatus /> component. The badge tells readers, at a glance, how thoroughly the module's API contract has been pinned by the conformance suite at core-tests/, and which defect classes (if any) are still open.

Status keywords

The four-level status taxonomy is shared between core-tests/INVENTORY.md (the per-module inventory) and the website (the public-facing API reference). Renaming a status anywhere requires the same rename in both places.

StatusEmojiMeaning
completeAll public APIs covered by unit tests; algebraic laws pinned by property tests; cross-stdlib integration verified; audit findings landed or routed. The module's contract is fully exercised end-to-end on both the interpreter (Tier 0) and AOT (Tier 1) paths.
partial⚠️A subset of the API surface is covered. The reasons for partial coverage are cited in the module's audit.md. Typically: the module sits on top of an upstream defect class (e.g. Iterator.next dispatch) that gates entire feature areas.
regression-onlyThe module is gated by upstream defects. Few or no public-API tests pass yet — only @ignored regression pins exist (plus a small set of PASS-GUARDs for the bits that work). When the upstream defect closes, removing the @ignore on the regression test should turn the suite green automatically.
unauditedNo core-tests/<module>/ folder exists yet. The module surface is undocumented in conformance terms. New modules start here; aim to graduate to regression-only (write the tests, even if they all @ignore) before merging.

Frontmatter

Each module page declares its status in the YAML frontmatter so search / sidebar widgets can read it without parsing the body:

---
sidebar_position: 3
title: text
description: ...
status: partial
status_detail: 121/218 Text + 75/86 Char + ... unit tests pass on YYYY-MM-DD.
---

status_detail is a one-line summary of the conformance numbers. The badge component reads status directly; status_detail is mirrored into the visible badge.

Component usage

import StdlibStatus from '@site/src/components/StdlibStatus';

<StdlibStatus
status="partial"
detail="121/218 Text + 75/86 Char + … unit tests pass on 2026-05-13."
defects={[
{area: 'text', summary: '~18 defect classes — KMP find, Iterator.next dispatch, ...'},
{area: 'char', summary: '5 defect classes — &mut Char mutation, ...'},
]}
sweepDate="2026-05-13"
/>

Props:

  • status — one of complete | partial | regression-only | unaudited.
  • detail (optional) — string mirroring the status_detail frontmatter; rendered in the badge body.
  • defects (optional) — list of {area, summary} rows shown in a collapsible defect-class table.
  • sweepDate (optional) — last conformance-sweep date.

Updating status

When a module's conformance numbers change:

  1. Update the per-module core-tests/<...>/audit.md.
  2. Append the new sweep numbers to core-tests/INVENTORY.md (single-line row; do not restructure the table).
  3. Update the module's website page frontmatter (status, status_detail) to reflect the new sweep.
  4. Refresh the <StdlibStatus /> props (detail, defects).

The same status keywords appear in three places — INVENTORY.md, the module page frontmatter, and the <StdlibStatus /> status prop — to let parallel agents run audits without coordinating on a single source of truth.