%utils GitHub issue
- All %utils surfaces at a glance
- %utils.memory
- %utils.tmp
- %utils.random
- %utils.now
- %utils.argv
- %utils.env
- %utils.file_system
- %utils.network
- %utils.encryption
- %utils.forks
- %utils.broadcast
- %utils.register
- %utils.steps
- %utils.timer
- %utils.timeout
vibecode
{"vibecode": { "doc": "utils", "role": "catalog of %utils, the engine-granted convenience-utility capability. Contains all the global forms of engine-exposed capabilities (forks, networking, file system, encryption, etc.) plus a few standalone utilities (memory, timer). Single flat list at the top; detail sections below; cross-links to canonical homes where they exist.", "key_concepts": ["utils_capability", "utils_role", "low_sensitivity_helpers", "global_form_of_engine_capabilities", "single_flat_list_with_links_to_details"] }}
%utils is the engine-granted convenience-utility capability — a bag of common helpers, accessible from any role (subject to that role having been granted the capability).
Most surfaces under %utils are the global form of an %engine.X slot — see script-context.md for the engine-side view. A few (%utils.memory, %utils.timer, %utils.timeout) are utilities specific to %utils with no engine-slot counterpart.
Everything coming out of %utils is owned by the utils role.
All %utils surfaces at a glance GitHub issue
| Surface | Purpose | Canonical home |
|---|---|---|
%utils.argv |
Command-line arguments (array of strings) | script-context § argv |
%utils.broadcast |
Broadcast an event to listeners | events/ |
%utils.encryption |
Cryptographic primitives (signing, hashing) | this doc |
%utils.env |
Environment-variable accessor | this doc |
%utils.file_system |
Filesystem access (dirjails, file objects) | this doc |
%utils.forks |
Spawn forked child processes | forking/ |
%utils.memory |
Process memory introspection | this doc |
%utils.network |
Networking — HTTP client, raw sockets, UDS | network/ |
%utils.now |
Current timestamp | this doc |
%utils.random |
Random-value primitives (uuid, number, string) | this doc |
%utils.register |
Register an event handler | events/ |
%utils.steps |
Count Caspian-level steps around a block | steps.md |
%utils.timer |
Measure elapsed time around a block | this doc |
%utils.timeout |
Limit a block's wall-clock duration | this doc |
%utils.tmp |
Fresh temp dirjail per access | this doc |
%utils.memory GitHub issue
Read-only introspection of the current process's memory usage.
%utils.memory.used # bytes currently used by this process
Memory-management ideas (TBD) GitHub issue
A wider memory-management surface has been kicked around but is not specified. Sketched ideas, recorded so the slot doesn't get forgotten:
- A configured hard limit (
%utils.memory.limit) and anavailablederivation from it. - A settable soft threshold (working name
%utils.memory.raise) that raises an exception when usage crosses it, so handlers can unwind gracefully under pressure. - Engine-level enforcement (continuous, mid-allocation) rather than user-side polling.
None of the above is committed. Shape, names, and semantics are open until a concrete use case drives the design.
%utils.tmp GitHub issue
Each access to %utils.tmp returns a fresh dirjail backed by a new temp directory on disk. The dirjail is a directory jail — code that holds it can read and write inside but can't escape the directory.
Three lifetime patterns; choose the one that matches the scope you want.
Direct access GitHub issue
$dir = %utils.tmp
# use $dir as a regular directory handle
$dir.write 'scratch.txt', 'some bytes'
The dirjail is auto-deleted when $dir goes out of the surrounding scope (function returns, block ends, etc.). No cleanup boilerplate, no leak from a forgotten unlink.
Block form GitHub issue
For lifetime tied to a specific block rather than the surrounding scope, pass a do-block:
%utils.tmp do($dir)
$dir.write 'scratch.txt', 'some bytes'
# ... use $dir like any directory ...
end
# $dir is gone; the temp dir has been deleted
Created on block entry, deleted on block exit — whether the block returns normally, via early return, or via exception.
Explicit close GitHub issue
For cases where you need to release the dir before the surrounding scope or block ends, call .close:
$dir = %utils.tmp
# ... do work ...
$dir.close # directory deleted now, even though we're still in scope
After .close, the dirjail handle is unusable; subsequent operations raise.
Properties GitHub issue
- Directory-jail abstraction. The handle is a directory; it doesn't know or care where on the filesystem the directory actually lives. Code holding it isn't coupled to OS paths.
- Multiple accesses produce independent dirjails.
$work = %utils.tmpand$archive = %utils.tmpgive you two separate dirs. - Permission-based. Temp-dir creation is a capability the engine grants, not an ambient ability. If the engine didn't grant it,
%utils.tmpeither errors or is simply absent from%utils(exact mechanism TBD). - Explicit chain propagation only. A process that can create temp dirs does not automatically grant that capability to everything it calls. The capability has to be explicitly sent down the
%chain— same posture as%utils.forksand similar engine-granted capabilities. This is the no-dangerous-defaults pattern. - Engine-level slot.
%engine.tmpis the user-only named access to the same capability. See script-context.md §%engine.tmpfor the engine-side view.
Concerns to keep in mind GitHub issue
- Crash mid-block. If the process hard-crashes while inside the block, the OS's
/tmpcleanup sweeps eventually handle the abandoned directory — but it could persist for a while before that happens. Standard Unix posture; acceptable. - Forked subprocess outliving the block. If a forked child process is still writing in the temp dir when the parent's block ends, the dir disappears under the child. Best treated as a "don't do that" — engineering around it (refcounting, deferred deletion) would complicate the simple block-scope model.
- Untrusted code is a real attack vector. Granting the tmp capability to untrusted code lets it touch real disk — fill it, stash data, or coordinate with other components via the filesystem. Worse: untrusted code can intentionally abort to bypass block-exit cleanup, leaving the temp dir visible on disk until the OS cleanup sweep catches it. That's an intentional information-leak vector if the temp dir held anything sensitive. The mitigation is straightforward: don't grant tmp to untrusted code in the first place. The explicit-only-down-the-chain rule already enforces this by default; the warning is here so the implications of overriding that default are clear.
Implementation: disk-backed, not in-memory GitHub issue
The tmp is backed by a real OS temporary directory (/tmp or equivalent), not by an in-memory mikobase. The motivating use case for tmp is often "I need somewhere to put a huge file while I work on it" — uploaded videos, generated archives, multi-gigabyte intermediate data — and that's exactly where in-memory storage falls down.
The in-memory option stays interesting for other "scratch that vanishes with me" cases where the data is small (see Mikobase as filesystem § In-memory mode), but %utils.tmp isn't one of them.
%utils.random GitHub issue
Random-value helpers.
%utils.random.uuid GitHub issue
Returns a UUID v4 string. This method uses Lua's libsodium library. libsodium uses your operating system's random number generator. For example, on Linux you get a cryptographically secure. random value. This article discusses Linux's compliance with US government cryptographic standards.
Engine implementation note: every UUID comes fresh from libsodium per call — no caching, no PRNG state. See uuid-generation.md for the engine-level implementation guidance (one-C-function-per-call, hex lookup table, literal-dash writes, etc.) and the security rationale behind the no-caching rule.
%utils.random.number GitHub issue
Returns a random number in [min, max], both ends inclusive, drawn from the same cryptographically strong source as %utils.random.uuid (libsodium → OS CSPRNG).
%utils.random.number(1, 100) # 1 through 100
%utils.random.number(1, 6) # roll a six-sided die
%utils.random.number(1, 100, step: 0.1) # one of 1.0, 1.1, 1.2, ..., 100.0
%utils.random.number(0, 10, step: 3) # one of 0, 3, 6, 9
min and max are required. step defaults to 1. The two bounds can be passed in either order — if min > max, they're swapped before use. number(1, 100) and number(100, 1) are equivalent.
The result is always min + k * step for some non-negative integer k (after the swap, if any), picked uniformly via libsodium's unbiased range function (no modulo bias).
If max - min isn't an exact multiple of step, the reachable maximum is min + floor((max - min) / step) * step — the high end is truncated to the last step-aligned value, not the literal max. That's why number(0, 10, step: 3) never returns 10.
Errors: step <= 0.
%utils.random.string GitHub issue
Returns a random string of the given length, with each character drawn uniformly from a pool. Uses the same cryptographically strong source as %utils.random.uuid (libsodium → OS CSPRNG), via libsodium's unbiased range function (no modulo bias).
%utils.random.string(5) # 5 chars from the default :alphanum pool
%utils.random.string(16, from: :hex) # 16 hex chars
%utils.random.string(5, alphabet: 'abcde') # 5 chars from a custom alphabet
length is required (character count, not bytes). The pool comes from one of two mutually-exclusive keyword arguments:
from:— a symbol naming a predefined alphabet (see table below). Defaults to:alphanumif neither keyword is given.alphabet:— a string containing the exact characters to draw from. Repeats are allowed ('aaab'weightsathree times).
| Symbol | Characters |
|---|---|
:alphanum |
a-z, A-Z, 0-9 (62 chars; the default) |
:hex |
0-9, a-f (16 chars; lowercase) |
:base64 |
a-z, A-Z, 0-9, +, / (64 chars) |
:base64url |
a-z, A-Z, 0-9, -, _ (64 chars, URL-safe) |
:digits |
0-9 (10 chars) |
:letters |
a-z, A-Z (52 chars) |
:lower |
a-z (26 chars) |
:upper |
A-Z (26 chars) |
Length is character count, not bytes. string(16, from: :hex) returns a 16-character string, which carries 8 bytes of entropy (each hex char is 4 bits). If you want N bytes of randomness encoded as hex, ask for N*2 characters.
Errors: length <= 0; unknown from: symbol; empty alphabet: string; both from: and alphabet: passed in the same call.
%utils.now GitHub issue
Current timestamp from the engine-controlled clock.
$ts = %utils.now # timestamp object
Engine-controlled rather than direct from the OS so test harnesses can inject a fixed clock for deterministic runs. See script-context § %engine.now for the engine-slot view.
%utils.argv GitHub issue
Command-line arguments after the script name, as an array of strings.
$args = %utils.argv
$args is just a variable name a script chooses; bind to whatever reads cleanly. See script-context § %engine.argv.
%utils.env GitHub issue
Environment-variable accessor (hash-shaped). Read environment variables that were set when the script was launched.
$home = %utils.env['HOME']
%utils.env.has_key?('SHELL')
Hash-style interface ([], .has_key?, .each, .keys). Read-only — scripts can't mutate the environment of the running process through this surface.
%utils.file_system GitHub issue
Filesystem access — dirjails, file objects, directory traversal. The global form of the user-only %engine.root dirjail.
Working surface (full spec TBD; canonical home will likely live at built-in-classes/filesystem.md or a dedicated file-system spec):
$root = %utils.file_system # root dirjail
$file = $root['some/path.txt'] # file object
Gated by --allow-fs at launch. Without the grant, %utils.file_system is null.
%utils.network GitHub issue
Container for networking surfaces. Full spec at network/ and its sub-docs.
| Sub-surface | Purpose | Canonical home |
|---|---|---|
%utils.network.http_client |
HTTP client (often via %net.http_client / %net.fetch sugar) |
network/http/client/ |
%utils.network.sockets |
Raw TCP/UDP/SSL socket constructors | network/sockets.md |
%utils.network.uds |
Unix-domain-socket server constructor; foundation of $uds.share and $uds.mikobase |
network/uds/ |
The %net global is a further-shortened alias for %utils.network — %net.fetch(url) is the most common form for one-shot HTTP requests.
%utils.encryption GitHub issue
Container for cryptographic primitives. Two sub-surfaces:
%utils.encryption.signing GitHub issue
Ed25519 signing and verification. Used by the blockchain integration for signed library endorsements, signed authority blocks, and signed records.
| Method | Purpose |
|---|---|
.generate_keypair() |
Fresh Ed25519 keypair |
.sign($private_key, $bytes) |
Produce a signature |
.verify($public_key, $signature, $bytes) |
Check a signature; returns boolean |
.keypair_from_seed($seed) |
Deterministic keypair from a seed |
.import_key(...) / .export_key(...) |
PEM / DER / raw-bytes interchange |
NOT for password storage — see ideas/caspian/passwords/ for the separate passwords spec.
%utils.encryption.sha GitHub issue
SHA-family hashing primitives.
| Method | Purpose |
|---|---|
.sha256($data) |
SHA-256 digest as a hex string |
.sha512($data) |
SHA-512 digest as a hex string |
.hmac_sha256($key, $data) |
HMAC-SHA-256 |
.hmac_sha512($key, $data) |
HMAC-SHA-512 |
Slot is named sha rather than hash because it's SHA-family specifically. Other hash families (BLAKE2/3, etc.) would get their own slots when needed.
NOT for password storage — see ideas/caspian/passwords/.
%utils.forks GitHub issue
Spawn forked child processes. Three forms: %utils.forks.single(), %utils.forks.multiple(N), %utils.detach(). Each takes a do ... end block that runs in the child.
Full spec at forking/.
%utils.forks.multiple(20) do
# this runs in each of 20 child processes
end
%utils.broadcast GitHub issue
Broadcast an event to all registered listeners.
%utils.broadcast 'event_name', arg1, arg2
Full spec at events/.
%utils.register GitHub issue
Register a closure as an event handler.
%utils.register $source, 'event_name' do($broadcaster, $name, $args...)
# ...
end
Full spec at events/.
%utils.steps GitHub issue
Count Caspian-level evaluation steps inside a block. Off by default — zero overhead unless a %utils.steps call is active. One step = one call to eval or exec_stmt in the interpreter. Deterministic; engine-independent.
$count = %utils.steps do
# ... work whose steps are counted ...
end
Full spec at steps.md.
%utils.timer GitHub issue
Measure elapsed time around a block. Returns the duration in seconds.
$seconds = %utils.timer do
# ... work to measure ...
end
%utils.timer is null if the engine didn't grant %utils. Guard with if %utils if the caller can't assume the namespace.
%utils.timeout GitHub issue
Limit a block's wall-clock duration. Raises if the block doesn't return within the budget.
%utils.timeout(10) do
# work that must finish within 10 seconds
end
%utils.timeout(3600, unwind: true) do
# ...
end
unwind: kwarg controls whether a timeout raises a normal exception (default) or unwinds without raising. Full semantics TBD.