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,SetandTextsit in ring 0, not withcollectionsandtext. They are the LANGUAGE's vocabulary —baseuses them in 384 places andcollections/list.vrdepends onbase, a genuine mutual dependency. The rest ofcollections(btree, deque, lru, bloom) and oftext(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
| Module | Purpose |
|---|---|
base | Maybe, Result, Iterator, operator protocols, panic, environment |
collections | List, Map, Set, Deque, BinaryHeap, BTreeMap, BTreeSet |
text | Text, Char, formatting, regex, tagged literals |
mem | CBGR allocator, Heap, Shared, reference primitives |
intrinsics | compiler intrinsics (SIMD, atomic, memory, CPU) |
hash | digests grouped by GUARANTEE: checksum / fast / crypto / legacy |
mac | keyed authentication — HMAC, Poly1305 |
random | secure (platform CSPRNG) vs deterministic (reproducible) |
subtle | constant-time comparison, zeroization that survives optimisation |
id | unique identifiers — UUID, ULID, NanoID, Snowflake |
io | files, paths, stdio, processes, Read/Write protocols |
time | Duration, Instant, SystemTime, timers |
sys | V-LLSI kernel bootstrap (direct syscalls) |
term | 7-layer TUI framework |
async | Future, Task, Channel, executors, generators |
sync | atomics, mutex, rwlock, condvar, barriers |
runtime | runtime configurations, supervision trees |
net | TCP, UDP, HTTP, TLS, DNS |
math | pure-Verum math (libm replacement), linalg, autodiff, tensors, neural networks |
simd | portable SIMD types and operations |
meta | compile-time programming (tokens, AST, quote, reflection) |
proof | proof carrying code, reflection protocol |
theory_interop | Theory registry, translation, coherence audit, JSON-RPC interchange protocol |
context | scope, providers, context layers |
security | security labels, regions |
database | SQLite ("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 this | Not this (in other languages) |
|---|---|
List<T> | Vec<T>, vector<T>, ArrayList<T> |
Text | String, 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 noHeap<T>, noShared<T>, no dynamicList<T>, no heap-backedText. Everything lives on the stack or in static storage.coreis the library you can link into a bare-metal target with a 16 KiB image budget.std(also spelledcore.*in imports) is everything else — the CBGR allocator,List,Map,Set,Text, async runtime, IO, network, TUI, tensors.stddepends oncore;coredepends on nothing but compiler intrinsics.
| Feature | In core | In 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 kind | Async | Heap | Threads |
|---|---|---|---|
full | ✓ | ✓ | ✓ |
single_thread | ✓ | ✓ | 1 |
no_async | compiled to sync | ✓ | optional |
embedded | no | stack-only | 1 |
no_runtime | stubs | no | 1 |
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
verum api does not existMeasured 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.
| Status | Emoji | Meaning |
|---|---|---|
complete | ✅ | All 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-only | ⛔ | The 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. |
unaudited | ❔ | No 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 ofcomplete | partial | regression-only | unaudited.detail(optional) — string mirroring thestatus_detailfrontmatter; 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:
- Update the per-module
core-tests/<...>/audit.md. - Append the new sweep numbers to
core-tests/INVENTORY.md(single-line row; do not restructure the table). - Update the module's website page frontmatter (
status,status_detail) to reflect the new sweep. - 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.