Furth FortuneEngineering reference
TECHNICAL DOCUMENTATION

Platforms, languages and systems

On this page

Reference

Glossary

Every dotted word in the reference has an entry here. Hover over a dotted word, or tap it, to read its entry where you are. This page lists every entry, so each one is also reachable from the keyboard.

679 entries

#

.tri

The file extension for Trident source. A script is one.tri file, and an application is a folder whose a/ holds many. Opening a.tri file to read, check or index it never runs anything, because code runs only when the runner calls main.

Bug it prevents: importing a file only to inspect it and accidentally running its top-level code, which Python or JavaScript can do.

.x .y .z .w lane reads

Reads one part of a vector by name, like p.y. Several letters together pick and reorder parts at once, so p.zyx is the vector reversed. That reordering is called a swizzle.

dvec3 p = (1.5, -2.0, 4.0)
f64 y = p.y           # -2.0
dvec3 back = p.zyx    # (4.0, -2.0, 1.5)
p.z += 0.5
(a, b) lane tuple

Numbers in parentheses that fill a value's parts in order, like (1.0, 0.0, 0.0) for a 3D vector. The count must match the type: a 2D vector takes exactly two.

dvec3 p = (1.0, 0.0, 0.0)
interval lo = (0,1)
dvec2 bad = (1.0, 2.0, 3.0)   # refuses: three parts for two

Bug it prevents: a value built with a missing or extra part, which shifts every number into the wrong slot.

@ composition

Chains two transformations: m @ v applies matrix m to vector v, and q @ q applies one rotation after another. * never means that: it works part by part, or it refuses.

dmat2 grow = (2.0, 0.0, 0.0, 3.0)
dvec2 v = (1.0, 1.0)
dvec2 w = grow @ v        # (2, 3)
dquat spin = t.math.dquat.fromAxisAngle((0.0, 1.0, 0.0), 1.5707963)
dquat both = spin @ spin  # one turn after the other
dquat bad = spin * spin   # refuses: * is not composition

Bug it prevents: writing * and getting a part-by-part product when you meant to chain two rotations or apply a matrix.

** power

Raises a number to a whole-number power: 2 ** 10 is 1024. The exponent must be an integer; a fractional power, like a square root, is a named library call.

i32 k = 2 ** 10      # 1024
f64 cube = 1.5 ** 3  # 3.375
f64 root = 2.0 ** 0.5   # refuses: the exponent is an integer

Bug it prevents: a negative number raised to a fractional power, which has no real answer, quietly turning into NaN.

// rational constructor

Builds an exact fraction from two whole numbers: 1//2 is exactly one half, with no rounding. It is never a comment and never ordinary division, which is /.

rational half = 1//2
rational third = 1 // 3
rational sum = half + third   # exactly 5/6
f64 bad = 1.0 // 2   # refuses: // takes integers

Bug it prevents: one third stored as 0.333 and small rounding errors piling up. A fraction stays exact until you convert it.

& | ^ ~ bit and set operators

Bit operators on whole numbers, and set operators on flagsets: & keeps what both have, | what either has, ^ what exactly one has, and ~ flips. On a flagset, ~ flips only the named members.

u8 both = 6 & 3      # 2
u8 either = 6 | 9    # 15
i32 differ = 5 ^ 3   # 6
u8 flipped = ~0      # 255
bool odd = true & false   # refuses: & takes no bool

Bug it prevents: ~ flipping all 64 bits of a flag word and switching on dozens of flags nobody named.

# comment

A note for people reading the code. Everything from # to the end of its line is ignored. Trident has no // comment: // builds a fraction.

i32 tries = 3   # a comment runs to the end of its line
# a whole line can be a comment too
i32 left = tries
// 2   # refuses: // is no comment, so this reads as tries // 2
#! shebang line

An optional first line, #!/usr/bin/env tricli, that lets a Unix shell run the file as a program. In Trident it is an ordinary # comment, so no tool needs a special rule for it.

#!/usr/bin/env tricli
# the line above is an ordinary comment
i32 tries = 3
#{ } structured comment

Trident's one comment that can span several lines. Its body holds typed fields, like i32 since = 1, which the compiler reads and checks but never runs. Plain notes that span lines use several # lines instead.

#{ i32 since = 1
   text who = "Ada" }
i32 tries = 3

Bug it prevents: a multi-line comment left open that silently swallows the code after it. An unclosed or malformed #{ refuses.

% remainder

Gives what is left after whole-number division: 7 % 2 is 1. The sign follows the number being divided, so -7 % 2 is -1, and a == (a / b) * b + a % b always holds. Dividing by zero faults.

i32 r = 7 % 2      # 1
i32 s = -7 % 2     # -1: the sign follows -7
i32 zero = 0
i32 bad = 7 % zero   # faults: divide by zero
`…{x}…` interpolation

A text literal enclosed in backticks fills each {…} hole with a value, like `n={n}`. Each hole is converted with text(…), runs once, left to right. Formatting is a named call inside a hole, not a hidden mini-language.

i32 n = 5
text line = `n={n}`   # "n=5"
text bad = "n=" + n   # refuses: write text(n)

Bug it prevents: a number glued onto text with no visible conversion, as JavaScript's "n=" + n does.

+ - * /

Add, subtract, multiply and divide. Both sides must agree in type (two whole-number widths meet at one that holds both), and whole-number division rounds toward zero. Going past a type's limit, or dividing by zero, faults instead of wrapping around or giving infinity.

i32 total = 7 + 5 * 2   # 17
i32 half = 7 / 2        # 3: rounds toward zero
f64 precise = 7.0 / 2.0   # 3.5
i32 big = 2147483647
i32 over = big + 1   # faults: overflow

Bug it prevents: a whole number silently rolling over from its largest value to a negative one, like a car's odometer.

+= ++ and other updates

Shortcuts that update a variable in place: n += 4 means n = n + 4, and n++ adds one. Each follows the rules of the operator it stands for, and a const can never be updated.

i32 n = 1
n += 4     # 5
n *= 2     # 10
n++        # 11
const i32 limit = 3
limit += 1   # refuses: nothing writes a const
<, >, <=, >=

Compare two values by order and give a bool. Only kinds with a true order allow them: complex numbers, flagsets, intervals and bounding boxes refuse, because any order there would be made up.

i32 low = 2
bool less = low < 5
bool most = low >= 2
complex128 z = 1.0 + 1.0i
bool bad = z < z   # refuses: complex numbers have no order

Bug it prevents: sorting values that have no real order, so the result depends on a hidden rule nobody chose.

<< >> >>> shifts

Shift a whole number's bits left or right. >> keeps the sign of a signed number, and >>> always fills with zeros. A shift count outside the type's width faults.

i32 up = 1 << 4      # 16
i32 down = -8 >> 1   # -4
i32 logical = -1 >>> 1   # 2147483647
i32 count = 32
i32 bad = 1 << count   # faults: the count reaches the width

Bug it prevents: C's undefined result from shifting by 32 or more, which differs from one computer to the next.

==, !=

== asks whether two values are equal, and != whether they differ; each gives a bool. Both sides must be the same type, so comparing a number with text, or members of two different enums, refuses.

i32 n = 4
bool same = n == 4
bool other = n != 5
text word = "4"
bool mixed = n == word   # refuses: an i32 is never a text

Bug it prevents: comparisons like JavaScript's 4 == "4" being quietly true.

1h30m duration literal

A length of clock time written with its units, like 16ms or 1h30m, with larger units first. A month is a calendar span, not a fixed number of seconds, so 1mo refuses as a duration.

duration frame = 16ms
duration trip = 1h30m
duration total = frame + trip
duration month = 1mo   # refuses: a month is not a clock span

Bug it prevents: treating every month as 30 days, or mixing up milliseconds and seconds in a bare number.

4.0i imaginary literal

A number glued to i, like 4.0i, is the imaginary part of a complex number. 3.0 + 4.0i is an ordinary sum of a real number and an imaginary one, not a special two-part token.

complex128 z = 3.0 + 4.0i
complex128 n = -4.0i
complex128 w = z * n
5kg unit-suffixed number

A number glued to a unit, like 5kg or 9.81m/s^2, read in the unit family its destination's type names. So 5m is five meters at a length and five minutes at a time. With no family to read it in, it refuses rather than guess.

f64<mass> load = 5kg
f64<length> run = 5m    # five meters
f64<time> wait = 5m     # five minutes
f64<mass> heavy = 5m   # refuses: m is no mass unit
f64 plain = 5kg   # refuses: no family to read kg in

Bug it prevents: degrees used where radians were meant, or meters read as feet, giving a wrong number that looks fine.

A

a/

a/ is the folder that holds an application's source. Each.tri file under it is a module named by its path, so a/geometry/units.tri is module a.geometry.units, and a/main.tri (module a.main) is where the program starts. In a server-and-client app a/ holds the code both sides share.

Bug it prevents: two files claiming one module name, or a runner guessing which file to start; the path decides both.

aabb, daabb (axis-aligned bounding box)

An axis-aligned bounding box: the box, lined up with the x, y and z directions, that holds something. It is stored as its lowest corner, then its highest corner. Games use it for a quick "could these touch?" test. It may name a frame and a length unit. daabb stores more digits.

aabb crate = (0, 0, 0, 2, 3, 4)
aabb<frame=builtin:itrs,unit=km> zone = (-1, -2, 0, 1, 2, 3)
aabb<frame=builtin:itrs,unit=km> bad = (2, 0, 0, 1, 1, 1)   # refuses: the low corner is above the high one
bool less = crate < crate   # refuses: a box has no order

Bug it prevents: adding two boxes with + or ranking them with <. A box is a region, so joining boxes and testing what is inside are named calls instead.

Acknowledgment tier

The point a write must reach before its call returns. fast means the volume primary holds it in memory, and replicated means the standbys keeping up hold it too. durable means every confirmer the store names holds it. Each stored value records the tier it reached and what confirmed it, such as durable (synced, zone, 2 fallbacks).

Bug it prevents: Reporting a reading as saved when it existed only in one process’s memory.

AEAD

Authenticated encryption with associated data. t.security.secret.seal uses XChaCha20-Poly1305 with a 24-byte nonce it draws itself and a 16-byte tag. Opening fails unless the key, the associated data and every ciphertext byte match.

Affine map

A transform that can turn, stretch, slant and slide shapes while keeping straight lines straight and parallel lines parallel. In 2D it takes six numbers: four for turning and stretching, two for the slide. Trident's mat2x3 and dmat2x3 hold one as two rows of three.

Alba

Furth Fortune's C# platform for server-side web applications. Shared JSON definitions describe tables, service calls and events, and Wayland generates the C#, TypeScript, JavaScript and SQL from them. It runs on PostgreSQL and Redis and does not run Trident.

alias

Gives a module a short local name, like alias m = t.math. It only renames something the program already holds. It never downloads or searches for code.

alias m = t.math
f64 root = m.sqrt(2.0)
alias q = my.module   # refuses: no unit carries that id

Bug it prevents: a look-alike package from the internet loading in place of your own code. An alias that names nothing in the program refuses.

Allocation and allocator

Allocation is a program asking for a piece of memory to hold its data, and an allocator is the part of the system that hands those pieces out (in C, malloc). A Trident program never calls one: each kind of memory it uses has a limit the host declares, and a request past it is a typed fault.

Bug it prevents: a loop that keeps grabbing memory until the whole machine slows down or crashes.

almanac

One member of an almanac: a fixed lookup table whose members all share one set of properties and keep a permanent id number. The value stores only that id. Almanac source declarations, properties, module reaches, and retired-member rules work.

Ancestor proof

The check that a change's final commit is reachable from main after a fresh fetch. It is how a change is shown to be delivered, not just pushed somewhere.

git merge-base --is-ancestor "$sha" origin/main

Bug it prevents: work reported as done that sits on a branch nobody merges.

Animation clip

A named set of keyed channels that move a rig's joints or morph weights over time. Each channel states its joint, its path (translation, rotation, scale or weight), its interpolation and its key times.

API

An API (application programming interface) is the set of functions and rules one piece of software offers so other code can use it, like the buttons on a vending machine. Trident's own libraries form one catalog, and each is reached by its full path, such as t.text.bytes.

application

An application is a Trident program of more than one file: a folder holding a/main.tri, its identity in _app/app.draft and its lend in _grant/grant.draft. tricli calc compiles every.tri under calc/a/ into one program. Folders whose names start with _ hold facts about how the program is built and run.

Application generation

A published, validated version of an application's source and configuration. The host compiles it whole and installs it between calls; the generation before it stays retained as the rollback point.

Bug it prevents: an unreviewed edit running in production because saving the file was the same as publishing it.

application source

The Trident files under a/ plus the documents beside them that configure the program. It is the one record of what an application does. Wheelhouse, the node view and the command-line tools all change it through checked edits.

Arbitrary precision

An arbitrary-precision integer grows as its value needs more digits. Trident's varint is limited by admitted memory. Runtime work is not counted or priced.

varint x = 12345678901234567
varint y = 9876543210987654321
varint p = x * y   # exact, every digit kept

Bug it prevents: a hostile, giant input making one calculation run with no limit and freezing a server.

Arena

An arena is one big block of memory that a program fills piece by piece and then frees all at once, which is fast and simple. Trident's compiler uses a growable arena while it parses and compiles, and even that arena stops at its own declared limit.

Arity

Arity is how many arguments a function takes, or how many items a fixed group holds. Trident checks every call's count when it compiles, before any argument runs, and a fixed group such as i32[3] always holds exactly three.

i32 add(i32 x, i32 y) { return x + y }
i32 sum = add(1, 2)
i32 few = add(1)   # refuses: add takes two arguments
i32[3] rgb = [255, 128, 0]
i32[3] two = [1, 2]   # refuses: a group of three needs three
assert

A statement that checks a condition inside a function body and faults if it is false. The fault names the check and the values involved, like x == 4 with x = 3. It always runs.

i32 x = 3
assert (x > 0, "positive")
assert (x == 4, "is four")   # faults: assert 'is four' failed

Bug it prevents: a check compiled out of the shipped program, so the mistake it guarded against slips through.

Asset profile

The named, versioned document shape an imported asset becomes, such as image, texture, mesh, rig and clip, point, audio, video or font. Each fixes its fields, frame and units. A reader that expects one profile refuses a document of another.

Bug it prevents: an image quietly read as if it were a mesh.

Astronomical year numbering

Astronomers number years with a year 0: 1 BC is year 0, 2 BC is year -1, and so on. That keeps date math simple, since the usual calendar jumps straight from 1 BC to AD 1 with no year in between.

civildate start = 0000-01-01   # year zero exists
Async, await and coroutines

Async functions and coroutines let code pause while it waits, for example for a network reply, and pick up again later; await marks the pause. Trident has none: async, await, yield and spawn are refused for good, because they make when code runs depend on timing.

Audience

An application's own set of connection tiers, declared as a flagset, such as crew, partner and admin. The server grants members to each connection, and handlers and columns check them. One person can hold different audiences in different applications.

flagset audience { crew = 1, partner = 2, dispatcher = 4, admin = 8 }
Auth domain

A declared group of accounts and the methods they sign in with. It lives in the server's _auth folder, while issuers and keys stay in configuration the host controls.

auth, access

auth declares a group of users and how they sign in, and a handler receives a one-time proof of who is calling that cannot be copied or rebuilt. A trove can then state who may read each record.

Authenticated encryption

Encryption that also proves nobody changed the message, like a sealed envelope with a tamper-proof seal. Opening it either gives back exactly what was sealed or fails; it never hands back altered data. Cryptographers call it AEAD.

B

backend

A backend is the operating-system layer MerTek is built for: win32 (Windows), posix, linux, darwin (macOS), and wasm (WebAssembly, for browsers). MerTek's same C source builds for each, and a Trident program runs the same on all of them.

balance metric

A signed cumulative total that can rise or fall. A separate u64 generation marks a restart. A fall in one generation is valid change. The canonical declaration and reducer domain compile.

Bug it prevents: using a reducer or restart rule from a different metric class.

Bare metal

Bare metal means a program runs directly on a device's hardware with no ordinary operating system underneath, as in a microwave or a small sensor. Trident's answer is BenthOS, written in Cutlass, where MerTek itself supplies the device's operating system.

BenthOS

The device operating system MerTek supplies for purpose-built hardware. Written in Cutlass, it boots straight from the hardware into its own MerFS file system, checks each startup stage before the next one runs, and runs Trident applications on top.

Bug it prevents: a device that starts serving with a configuration nobody verified, because one boot step failed quietly.

bf16

"Brain float": a 16-bit number with the same range as f32 but only 2 or 3 significant digits. Machine learning uses it because range matters more than precision there. It is a different format from f16.

bf16 weight = 1.5
f16 half = weight   # refuses: two formats, no silent change

Bug it prevents: reading bfloat16 bytes as half precision, or the reverse, which gives a wildly wrong number.

binary64, binary32 and binary16

The IEEE 754 names for floating point numbers 64, 32 and 16 bits wide, often called double, single and half precision. More bits keep more digits: about 16 for binary64, 7 for binary32 and 3 for binary16. Trident's f64, f32 and f16 are these, and moving a value between them is a precision conversion.

f64 wide = 0.1
f32 narrow = wide   # refuses: binary32 cannot hold every binary64
f32 cast = f32(wide)   # faults: 0.1 is not on the binary32 grid

Bug it prevents: a 64-bit value quietly losing half its digits when it is stored in a 32-bit variable.

Binding (variable)

A binding gives a name to a value so the program can use it later, like a label on a jar; many languages call it a variable. Every Trident binding writes its full type, and the value can change later only at that same type.

i32 count = 3
count = count + 1
count = "four"   # refuses: count is an i32 for its whole life
bivector

A bivector is a flat patch of plane with a size and a turning direction, like a spinning coin seen from above. In 3D it has three numbers (xy, xz, yz). Every step with it is a named call; exp, for one, turns a patch into a rotation.

bivector<signature=euclid3> patch = (0, 0, 0.5)
dquat spin = t.math.geometricAlgebra.exp(patch)
dvec3 arrow = patch   # refuses: a turning patch is not an arrow
bivector<signature=euclid3> twice = patch + patch   # refuses: use a named call

Bug it prevents: treating a bivector as an ordinary arrow because both have three numbers in 3D. They mean different things, so they never mix.

Bless

The step that records an executable's SHA-256 as a host's pin, after its native gate run exits 0. Packages wrap only blessed bytes.

Bug it prevents: a package wrapping a fresh build that no gate ever ran.

Blue/green rollout

Running the old fleet (blue) and the new fleet (green) side by side on a compatible wire. Work moves to green once green is proven healthy. Blue keeps serving until the cutover, so backing out a bad release means leaving work where it was.

bool

A yes-or-no value: true or false. Use it for questions like "is the door open?" It is not a number, so it has no order and no math, only logic such as &&, || and !.

bool ready = true
bool both = ready && !ready   # false
bool odd = true < false   # refuses: a truth value has no order
i32 n = ready   # refuses: a bool is not a number

Bug it prevents: treating true as 1 and adding it to a count, or sorting by a yes/no flag, as C and JavaScript allow.

Boot ladder

The fixed order a BenthOS device starts in, from the loader's manifest check up to the MerFS root. Each step rests only on the steps below it, and normal service starts only when all of them succeed.

Bug it prevents: a device that starts serving after one startup check failed quietly.

Bootstrap compiler

The first Cutlass compiler, written in C. It builds a compiler written in a subset of Cutlass, which builds the full compiler. Once the full compiler rebuilds itself byte for byte, the C compiler stays only as a frozen input for rebuilding the chain from source.

Bug it prevents: a toolchain that can only be rebuilt from a binary nobody can audit.

Bounds check

A bounds check makes sure an index points inside a list before reading it; without one, C can read whatever memory sits past the end. Trident refuses an index it can prove is outside when it compiles, and checks every other index when it runs, faulting instead of reading the wrong memory.

i32[] xs = [10, 20, 30]
i32 first = xs[0]
i32 far = xs[7]   # refuses: every possible index is outside

Bug it prevents: reading past the end of an array and getting some other value's bytes, the root of many security holes.

Boxed value (untyped dictionary)

A boxed value is wrapped so it can hold anything, like a box with no label, and an untyped dictionary is a map whose values can be any type. Code that reads one has to guess what is inside. Trident has neither: every value has a complete type, and its documents are typed chests.

Bug it prevents: reading a number out of a box that held text, a failure that shows up far from where the wrong value went in.

Branch cut

Some math functions, like the square root of a complex number, have more than one possible answer. Mathematicians pick one by drawing a line on the number plane, the branch cut, where the chosen answer jumps. Two inputs on either side of that line, however close, get very different results.

break, continue

break leaves the innermost loop at once, and continue skips to its next pass. Both work only inside a loop.

i32 found = 0
repeat (10, i32 i = 1) {
    if (i == 2) { continue }
    if (i > 4) { break }
    found += i
}
break   # refuses: there is no loop to leave
Broadcasting

The rules that let two arrays of different shapes combine entry by entry, by stretching the smaller one to match. Adding a single number to a table adds it to every cell.

buffer

A run of raw bytes, written in hexadecimal such as 0x68656c6c6f.

buffer raw = 0x68656c6c6f
text word = raw   # refuses: bytes become text only by decoding

Bug it prevents: bytes read as text in the wrong encoding, turning one accented letter such as "é" into two garbage characters.

Build cache

A store of compiled objects keyed by everything that went into them. A compile whose inputs match a stored object returns that object instead of running the compiler again.

Bug it prevents: an edit to one header recompiling the whole tree, or a stale object surviving an edit it should have seen.

bus

A message bus is a set of named topics that keep every message posted to them, plus subscriptions that each remember how far one reader has read. push posts a message and pump reads them. The compiler checks every topic name and handler so a misspelled topic refuses at compile.

bvec2, bvec3, bvec4

A group of 2, 3 or 4 true-or-false values, one per lane, such as which of x, y and z passed a test. They combine lane by lane with & (and), | (or) and ! (not). They take no arithmetic.

bvec3 hit = (true, false, true)
bvec3 other = (false, false, true)
bvec3 both = hit & other
bool first = hit.x
bvec3 sum = hit + other   # refuses: true and false are not numbers

Bug it prevents: adding true to true and getting 2, which languages that treat a truth value as a number allow.

bytecode and the compiled image

Bytecode is the compact list of simple instructions the compiler makes from Trident source. The compiled image (the bytecode plus its records) carries fingerprints of the source and of the library catalog it was checked against, and it is verified before it is installed and run.

C

c/

The folder for client-only code, the part that runs on a user's own device. It builds only into the client, and it reaches the server only through send, which is checked at compile.

Call site

A call site is the exact spot in the code where a function is called. Trident keeps a call readable there: each function has one signature, with no defaults and no overloads, so the line shows exactly which function runs and what it gets.

Call stack

The call stack is the pile of function calls a program is in the middle of: each call adds a frame and each return removes one. Trident counts call depth against a declared limit inside its own virtual machine, so runaway recursion stops with a typed fault instead of crashing the process.

i64 factorial(i64 n) {
    if (n <= 1) { return 1 }
    return n * factorial(n - 1)
}
i64 f = factorial(10)

Bug it prevents: a stack overflow that kills the whole program with no message.

Canonical form

Canonical means the one standard way to write something when several ways mean the same thing, like always writing 1/2 instead of 2/4. Trident keeps one canonical spelling for its values and types, so a program prints its own types back in one form and a rewrite of the source comes out the same every time.

Capability admission

The check Thalassa runs before a render program touches a device. It derives each need from the program's own graph and compares it with the backend's measured features and limits. A missing feature refuses by name, and a varying limit may only select a lower rung the scene declared.

Bug it prevents: a scene that draws wrong, or blank, on a device that lacks one feature.

Capability tuple

A capability is four things together: a mechanism (what action), a tenant (whose boundary), a tier (which audience) and a policy (under which conditions). The platform owns the mechanism; the application owns the other three as data.

Bug it prevents: a broad role name standing in for permission, so a contractor reviewing one unit's training records can also read live operations data.

capsule, dcapsule

A capsule is a pill shape: a straight segment with a radius around it, so both ends are rounded. Games often use one for a character's body. dcapsule stores more digits.

text describe(capsule<frame=builtin:itrs> body) {
  point3<frame=builtin:itrs> top = body.end
  f32<family=length> thickness = body.radius
  return t.text.of(top)
}
capsule2, dcapsule2

A capsule2 is a flat pill shape, like a running track seen from above: a straight segment with a radius around it. dcapsule2 stores more digits.

Capture point

A source line where a running call publishes a snapshot and keeps going. The debugger sets a count and a minimum spacing, so a capture point is safe on a loaded service.

Bug it prevents: pausing a live service just to read one value.

Cast

A cast turns a value of one type into another, like a big whole number into a smaller one, and in many languages it quietly cuts off a value that does not fit. Trident writes the conversion as the target kind's name, such as i32(x): exact, or a fault. A loss on purpose is a named call.

i64 small = 7
i64 big = 3000000000
i32 fits = i32(small)
i32 wrapped = t.math.castWrapping(big, "i32")
i32 lost = i32(big)   # faults: 3000000000 does not fit an i32

Bug it prevents: a narrowing cast that turns 3000000000 into -1294967296 without a word.

catalog

The catalog is the fixed list of every library and member a program is compiled against, identified by a digest. A compiled image records the catalog digest it was checked against, so a name in the program always means the same code.

ceiling

A ceiling is a limit the host sets on one kind of memory or work, such as bytecode bytes, array elements or call depth (maxCallDepth). Going past it, or running out of memory below it, stops the work at once with a typed status, TRIDENT_LIMIT or TRIDENT_OUT_OF_MEMORY, and nothing grows beyond it.

Bug it prevents: runaway recursion or a huge array eating all of the machine's memory and taking other programs down with it.

cellid

The id of one cell in a grid laid over the Earth or a flat map (a discrete global grid), written resolution/index such as 9/74565. The grid is part of the type, so ids from two grids never mix.

cellid<grid=hexicosa> cell = 9/74565
cellid<grid=quadhilbert> other = cell   # refuses: two different grids
bool first = cell < cell   # refuses: a cell id has no order

Bug it prevents: reading a cell number from one grid system in another, where the same number names a different place.

Change feed

The ordered list of committed changes to one trove. Each event names a record id, its new version and whether it was deleted, and the consumer reads the record itself. A change appears only after it reaches the trove’s acknowledgment tier, so a consumer never acts on a write a failover could still lose.

resource<t.db.subscription> feed = t.db.subscribe("part", 0)
chest page = t.db.poll("part", feed, 64)

Bug it prevents: A service missing an update because it polled the table between two writes.

check row

A rule inside a trove that ties its columns together, such as a start that must not come after its end. A literal that breaks the rule refuses at compile, and a later write that breaks it faults.

trove Window { i64 start, i64 end, check ordered = start <= end }
Window w = { start = 1, end = 5 }
Window bad = { start = 9, end = 2 }   # refuses: breaks ordered

Bug it prevents: a time window that ends before it starts being saved and passed around as if it were valid.

Chemical species

One particular chemical substance as a chemist counts it: a kind of molecule, ion or atom, such as water (H2O) or a sodium ion (Na+). Two samples of the same species are made of the same kind of particle.

chest

A document value: a bundle of named fields, each with its own type, that is saved and loaded whole. Trident uses it for records and configuration.

chest sample = {
    u16 code = 7
    text label = "ready"
}
text label = sample.label
Chest

Chest is MerTek's one document format: typed fields that carry their own description, so a reader needs no separate schema. The same bytes serve as a value in memory, a file, a database row and a network message. Trident's chest kind is a value in this format.

ciphertext

An encrypted value plus the header that says how to open it. It has no ==, no order and no conversion to text, so secret data cannot be compared or printed by accident. Its literal stays quoted, because its text is machine-written base64url and a short one would read as a name.

bool same(ciphertext left, ciphertext right) { return left == right }   # refuses: no == on secrets
text show(ciphertext box) { return text(box) }   # refuses: never turned into text

Bug it prevents: an encrypted field printed into a log or compared byte for byte as if it were ordinary data.

circle, dcircle

A circle on a flat surface: a center point and a radius, in an app's own frame. dcircle stores more digits.

civil

A full calendar label: a date, a time of day and, if known, the offset from its calendar body's coordinated time, such as 1987-03-05T14:30:00+02:00. It is what a wall clock and calendar say, not an instant, and a label with no recorded offset stays that way. A label under another calendar names it in the type; under civil<calendar=darian> the zero offset is Coordinated Mars Time and the time of day counts the sol.

civil utc = 1987-03-05T14:30:00Z
civil local = 1987-03-05T14:30:00+02:00
civil nozone = 1987-03-05T14:30:00
bool same = utc == local   # false
bool before = utc < nozone   # faults: the offsets differ

Bug it prevents: treating a wall-clock time with no known time zone as UTC, which can be off by hours.

civildate

A calendar date such as 1987-03-05, with no time of day and no time zone. Use it for birthdays and due dates, which are days, not instants.

civildate day = 1987-03-05
civildate next = 1987-03-06
bool before = day < next
civildate later = day + 1   # refuses: date math is a named operation

Bug it prevents: a birthday shifting to the day before when a date is stored as midnight UTC and shown in another time zone.

civiltime

A time of day on a clock face, such as 14:30:00, with no date and no time zone. A time of a sol carries its calendar as civiltime<calendar=darian>. Use it for opening hours and alarms.

civiltime open = 09:00:00
civiltime close = 17:30:00
bool ok = open < close
civiltime late = 24:00:00   # refuses: hours run 0 to 23
Claim

A commit on main that marks one work item active and names the worktree, host and model doing it. It lands before any code, so two lanes never start the same work.

ACTIVE: payroll-overtime@ops-build-02@assistant-lane

Bug it prevents: two people finishing the same change on the same afternoon.

Classification label

A value of type label<Domain>: one level plus a set of compartments. A label is ordinary data. Writing or decoding one grants no read, classification or release authority.

Bug it prevents: trusting a label a client sent, as if spelling "public" made a record public.

Clearance

The highest label a person may read, held as a live entitlement with its tenant, purpose and time window. Clearance bounds reads. Where a value may be written depends on the value's own label.

Closure

A closure is a function made inside another function that remembers the local variables around it, even after the outer function has returned. Trident has no closures, by design: every function is declared at the top level of a module and captures nothing from where it is called.

text main(text[] argv) {
    i32 base = 10
    i32 addBase(i32 n) { return n + base }   # refuses: a function is a module-level declaration
    return "ok"
}

Bug it prevents: a callback that quietly reads a variable after it changed, or keeps a large object alive long after it should be gone.

Co-registered fields

Two grids of data are co-registered when their samples sit at exactly the same places, like two see-through sheets lined up hole for hole. Only then can they be added or subtracted sample by sample. Trident faults when two fields' axes differ.

Code point and code unit

Computers store text as numbers. A code point is the number Unicode gives one character, and a code unit is one storage piece of an encoding, so one character can take several code units. A Trident rune holds one Unicode scalar, and code that counts text must say which unit it means.

Coherent unit

A unit built from base units with no extra number in front. The newton is coherent, because it is exactly one kilogram meter per second squared, while the kilonewton carries a factor of 1000. When Trident multiplies two amounts, the result comes out in the coherent unit.

f64<length> side = 3m
f64<unit=m2> area = side * side   # meters times meters: square meters
collection epoch

Host's collection continuity period. A changed collection plan starts a new epoch and fences old batches. It is separate from the application's tally generation and the session's composition generation.

Bug it prevents: joining values across a policy change or source restart as one uninterrupted interval.

color

A color with its color space (the system its numbers are measured in) in the type, such as color<srgb>. Moving to another space is a conversion, never a relabel. Under a bare color, whose type names no space, the literal stays quoted as "srgb(1, 0.5, 0, 1)", because the value must name its space and srgb(…) is a call's shape.

color<srgb> orange = (1,0.5,0,1)
color<oklch> soft = (0.7,0.2,50,1)
color<oklch> wrong = orange   # refuses: a space change is a conversion
color<srgb> mix = orange + orange   # refuses: a color takes no arithmetic

Bug it prevents: reading the numbers of one color space as another, which shifts the color the viewer sees.

Color space

The rulebook that says what a color's numbers mean: which exact red, green and blue (its primaries), which white, and how numbers map to brightness. The same three numbers are a different orange in sRGB and in Rec. 2020. Trident puts the space in a color's type.

color<srgb> orange = (1,0.5,0,1)
color<oklch> soft = orange   # refuses: a space change is a conversion
vec4 lanes = orange   # refuses: four numbers do not say which space

Bug it prevents: numbers measured in one color space shown as if they were another, so colors look washed out or too strong.

Commit point

The one place where a write becomes accepted. In MerDB it is the volume primary that owns the record: it checks the write’s condition, commits it in a batch and acknowledges it. A write across several primaries records a single decision, and every part follows it.

Bug it prevents: Two nodes each accepting a different edit to the same record, with the later one silently winning.

Compartment

An independent category inside a security domain, such as finance or legal. A reader needs every compartment a label carries: restricted with finance cannot read restricted with legal.

Bug it prevents: admitting a reader who holds any one of a record's compartments instead of all of them.

compile (stage)

The compile stage turns checked source into bytecode for the virtual machine. Most of Trident's refusals happen here, so a mistake stops the program before a single line runs and nothing is left half done.

i32 count = 3
text label = "items: " + count   # refuses: write text(count)
text fixed = "items: " + text(count)

Bug it prevents: a wrong line that only fails, or prints nonsense, when it finally runs, perhaps in front of a customer.

Compile time and run time

Compile time is when the compiler checks and translates a program; run time is later, while the program actually runs. A mistake caught at compile time never reaches a user. Trident moves every check it can to compile time, and the rest become typed faults at run time.

i32 small = 5
i64 total = small   # refuses: caught at compile time
i32 zero = 0
i32 q = small / zero   # faults: caught at run time
Compiler

A compiler is a program that reads source code and translates it into a form a machine can run, checking it for mistakes on the way. Trident's compiler turns source into a bytecode image, and it refuses a program with a known mistake before any line of it runs.

complex64, complex128

A complex number: a real part and an imaginary part, stored as two f32 values (complex64) or two f64 values (complex128). Engineers use them for waves, signals and circuits.

complex128 z = 3.0 + 4.0i
complex128 w = z * z
complex64 small = (1, 2)
bool less = z < w   # refuses: complex numbers have no order

Bug it prevents: sorting complex numbers by an order that means nothing, such as their real parts alone.

cone, dcone

A cone is a party-hat shape: the center of its round base, a turn, a height, and the base's radius. dcone stores more digits.

text describe(cone<frame=builtin:itrs> hat) {
  point3<frame=builtin:itrs> base = hat.baseCenter
  f32<family=length> tall = hat.height
  return t.text.of(tall)
}
conicalfrustum, dconicalfrustum (conical frustum)

A conical frustum is a cone with its tip sliced off flat, like a bucket or a lampshade: a base center, a turn, a height, a base radius and a top radius. dconicalfrustum stores more digits.

text describe(conicalfrustum<frame=builtin:itrs> bucket) {
  f32<family=length> bottom = bucket.baseRadius
  f32<family=length> rim = bucket.topRadius
  return t.text.of(rim)
}
Conjugate

A number with the sign of its imaginary part flipped: the conjugate of 3 + 4i is 3 - 4i. For a quaternion of length 1, flipping its three axis parts gives the reverse rotation. Trident names the conjugate as its own operation instead of spelling it with a minus sign.

const

Marks a value that can never change after it is set. At the top of a file every value must be const and a plain literal, so no code runs before main starts.

const i32 limit = 3
const f64 half = t.math.pi() / 2.0   # refuses: a module constant is a literal
i32 tries = limit
limit = 4   # refuses: nothing writes a const

Bug it prevents: C++'s startup-order bug, where one global value reads another before it is set, and hidden work running when a file loads.

Consumer cursor

The feed position a consumer has acknowledged. poll never moves it; only ack does. A consumer that crashes before ack reads the same events again, and one that subscribes from a saved position continues with the next event.

u64 through = page.through
t.db.ack("part", feed, through)

Bug it prevents: Losing the events a consumer was handed when it failed halfway through a page.

Control plane

The part of a platform that decides what runs where: which runtimes exist, which generation each app runs and who may change it. It stays off the path that serves each customer request.

Bug it prevents: a deployment script on one person's laptop that nobody else can audit or repeat.

coord2, coord3 (and dcoord2, dcoord3)

A plain list of 2 or 3 coordinates that are always ordinary finite numbers (never infinity or not-a-number), used when nobody has shown yet whether they are a point, a direction or a normal. They take no arithmetic and no order. The only change allowed is between a coord and its d twin, which stores more digits.

coord3 raw = (1, -2.5, 0.5)
dcoord3 wide = dcoord3(raw)
coord3 sum = raw + raw   # refuses: coordinates with no role take no math
coord3 broken = (infinity, 0, 0)   # refuses: every coordinate is a finite number

Bug it prevents: an infinity or not-a-number slipping into a list of coordinates and then spreading through every later calculation.

Coprime

Two whole numbers are coprime when no number bigger than 1 divides both of them, like 8 and 15. A fraction is in lowest terms exactly when its top and bottom are coprime.

Coroutine (Cutlass)

A Cutlass function that can pause with yield and resume later, built by the compiler as a state machine in the caller's region. It has no stack of its own and needs no runtime. next() answers a value, pending or done.

Correlation

How much two uncertain values move together. Two readings taken with the same slightly-off ruler are wrong in the same direction, so their errors add up instead of canceling. When Trident combines measurements, the call must say whether they are independent or correlated, and how much.

measurement rod = (1.5, 0.25, 9)
measurement[] parts = [rod, rod]
f64[] weights = [1.0, 1.0]
f64[] linked = [1.0, 1.0, 1.0, 1.0]
measurement sum = t.math.uncertainty.combine(parts,
    weights, "correlation", linked, 3.0, 9.0)   # (3, 0.5, 9)
measurement twice = rod + rod   # refuses: a sum must state its correlation

Bug it prevents: counting one rod twice as if its two errors were independent, which reports 0.354 where the honest answer is 0.5.

Coverage factor and expanded interval

A standard uncertainty covers the true value only about two times in three. Multiplying it by a coverage factor, often 2, gives a wider expanded interval that covers it about 95 times in 100: 1.5 ± 0.25 becomes 1.5 ± 0.5.

crash

Ends the whole process at once with exit status 79. No fault handler, deferred cleanup, or on stop runs. An optional reason is one nonempty plain text literal; a computed reason refuses.

Compare crash, stop, and fail.

Cross product (of two fractions)

A way to compare two fractions without dividing: a/b is less than c/d when a × d is less than c × b. So 1/3 is less than 1/2 because 1 × 2 is less than 3 × 1. It uses only whole-number math, so the answer is always exact.

rational oneHalf = 1//2
rational third = 1//3
bool ordered = third < oneHalf   # compares 1 * 2 with 3 * 1
curvepoint

A point on an elliptic curve, stored in that curve's one standard encoding, with the curve in the type: curvepoint<curve=ed25519>. Digital signatures and key exchange use them. Its literal stays quoted, because a run of hexadecimal digits would read as a name or a numeral.

curvepoint<curve=ed25519> base = "5866666666666666666666666666666666666666666666666666666666666666"
curvepoint<curve=p256> other = base   # refuses: two different curves

Bug it prevents: feeding a point from one curve into math for another, which produces garbage keys.

cut

The core library every Cutlass program links without declaring it: the region allocator, Trident's kinds, text, collections, math, files and the portable host surface. A binary keeps only the parts it reaches.

cutarch

Cutlass's machine floor: each architecture's intrinsics, each target's start-up unit, and each host's kernel-entry mechanism. Only cut and cutrun reach it; a program that reaches cutarch directly is refused.

Cutlass

MerTek's systems language. It takes Trident's grammar and kinds, compiles straight to machine code, links no C library and has no undefined behavior. BenthOS and MerFS are written in it.

Bug it prevents: a buffer overrun or a use-after-free in kernel or driver code.

cutrun

Cutlass's declared concurrency and time: the thread table, channels, coroutine resume, fork-join, the clock, shared segments and capability tables. It lowers only what a program declares; there is no scheduler and no garbage collector.

cylinder, dcylinder

A cylinder is a can shape: a center, a turn, half its length, and a radius. dcylinder stores more digits.

text describe(cylinder<frame=builtin:itrs> can) {
  f32<family=length> halfHeight = can.halfLength
  f32<family=length> size = can.radius
  return t.text.of(halfHeight)
}

D

Data race

A data race happens when two threads use the same memory at the same moment and at least one is writing, so the result depends on luck and timing. Trident shares no mutable data: every copy is a value, and a job handler runs on its own runtime, sharing nothing.

Bug it prevents: two threads adding to one counter at once and losing updates, a bug that appears only sometimes and is hard to reproduce.

DataService

The Alba service that answers service calls and pushes server events to connected browsers over a WebSocket.

dd128, td192, qd256

Extra-precise numbers made of two, three or four f64 parts that add up to one value (the "double-double" family). dd128 holds about 32 digits, td192 about 48 and qd256 about 64. Use them when f64 rounding is too coarse.

dd128 x = (1.0, 0.0)
td192 y = (1.0, 0.0, 0.0)
td192 wide = x + y   # works at the wider kind, exactly
dd128 bad = (1, 1)   # refuses: the second part must be far smaller
dd128 zero = (0.0, 0.0)
dd128 q = x / zero   # faults: no infinity is made

Bug it prevents: a precise value quietly rounded down to a plain double in the middle of a long calculation.

Debug association

The one authenticated connection between a tri target and a Wheelhouse debugger. It carries a closed set of request and answer documents and checks the principal's level on every operation. It never delivers a byte to the target program.

Bug it prevents: a debug port anyone on the machine can find and attach to.

Debug level

What a debug principal may do: observe reads and captures, control pauses and steps, mutate writes state, and reveal shows withheld bytes. Each is granted per principal by the operator, never by the program.

text[] levels = ["observe"]
Debug snapshot

A copied Chest document of a program's state at one moment: frames, slots, regions and resources. It holds no pointer, live handle or allocator state, and raw bytes are withheld unless the viewer holds reveal.

Bug it prevents: a debugger that reads the target's live memory and corrupts it while looking.

Debugger

A debugger lets a person pause a running program, step through it line by line and look at its values; a breakpoint is a line where it stops.

decimal

An exact base-10 number with a fixed count of digits after the point, set in its type: decimal<scale=2> always has two. Use it for prices, rates and anything people count in tenths and hundredths.

decimal<scale=2> price = 0.10
decimal<scale=2> total = price + 0.20   # exactly 0.30
decimal<scale=2> odd = 0.125   # refuses: three places at scale 2
decimal<scale=1> three = 3.0
decimal<scale=2> third = price / three   # faults: not exact at two places

Bug it prevents: 0.1 + 0.2 printing 0.30000000000000004 on a price, or a division rounding a cent away without saying so.

Declared index

An index row in a trove file, such as index byChangedAt = changedAt, that names one way a program may look records up. The store updates it on every write, and a query runs only through one. A unique index also refuses a second record with the same key.

index byChangedAt = changedAt
unique index bySerial = t.text.ascii.lower(serial)

Bug it prevents: A new question quietly becoming a full-table scan on a production store as the data grows.

Default argument

A default argument is a value a function fills in when the caller leaves that argument out. It saves typing, but the call no longer shows everything the function receives. Trident has no defaults: every call names every argument, and the count is checked when it compiles.

i32 area(i32 w, i32 h) { return w * h }
i32 room = area(3, 4)
i32 strip = area(3)   # refuses: every argument is named at the call
Definite assignment

Definite assignment is the rule that a variable must surely hold a value before any code reads it. Trident's compiler proves it on every path, and an exhaustive when counts: if every arm assigns a local, the local is set after the when.

Degrees of freedom

How much evidence stands behind an uncertainty: roughly how many independent readings it came from, minus what the estimating used up. With few degrees of freedom the uncertainty itself is shaky. A Trident measurement keeps it as its third part; it must be above zero and may be infinite.

measurement rod = (1.5, 0.25, 9)   # nine degrees of freedom
measurement known = (1.5, 0.25, infinity)   # an uncertainty known exactly
measurement none = (1.5, 0.25, 0)   # refuses: zero degrees of freedom
Delegation

Acting for another subject through an explicit grant. Reach is the intersection of every hop, the chain keeps every actor, and the represented person's MFA and device proof never transfer.

Bug it prevents: an assistant agent quietly inheriting all of its owner's authority.

delta metric

Activity since the previous completed call. No generation field. Each call supplies its own batch. Zero is valid; a missing batch is unknown. Delta declarations and their reducer domain compile.

Bug it prevents: using a reducer or restart rule from a different metric class.

Denial of service

Hostile input can exhaust time or memory. Declared counts and exact allocation limits bound storage. Deadlines and cancellation use coarse polls; the operating system owns CPU quotas.

Deny by default

Every boundary starts from refusal. An omitted grant, predicate, anchor, placement class or entry admission refuses instead of falling back to something permissive.

Bug it prevents: a new endpoint or table that is open to everyone because nobody wrote a rule for it yet.

Dependency

A dependency is code a program relies on that someone else wrote, usually fetched by a package manager within a version range and pinned in a lock file. A Trident program's dependencies are fixed by its bundle and its build: there is no version range or lock file, and nothing that runs later can add one.

Dependency-confusion attack

A dependency-confusion attack tricks a package manager into installing an attacker's public package that has the same name as a company's private one. A running Trident program never looks a library up by name, and tripkg (still prelaunch) binds each prefix to exactly one registry source.

Bug it prevents: installing an attacker's look-alike package that runs its own code inside your build.

deployment

A deployment is a compiled program together with what it launches with, such as its configuration and starting data. It has its own digest, separate from the program's, so changing a setting changes how a program runs but never what the program is.

Derivative

How fast one quantity changes when another changes: the slope of a curve at one point. For y = 4 × x × x, the derivative at x = 3 is 24, so a tiny nudge to x moves y about 24 times as far. Trident's dual kind computes derivatives directly, with no guessed step size.

dual x = (3.0, 1.0)   # x is 3, and we track change along x
dual c = (4.0, 0.0)   # a constant does not change
dual y = x * x * c
f64 slope = t.math.dual.tangent(y)
assert (slope == 24.0, "the derivative")
Derived inventory

A checked-in file computed from the tree, such as the cross-node dependency graph or the type reference. It is regenerated after the final rebase and never merged by hand. Its generation lane refuses a copy that no longer matches the source.

Bug it prevents: a release shipping a dependency graph that still shows last week's edges.

Deterministic

A deterministic program gives the same output every time it gets the same input, with no hidden dependence on the clock, random numbers or timing. Trident is built for it: there is no ambient clock, time arrives through an explicit call or field, and async and await are refused for good.

Bug it prevents: a test that passes on one run and fails on the next because the code read the clock.

Diagnostic

A diagnostic is the message a compiler prints when it finds a problem: where it is, what is wrong, and ideally how to fix it. Trident's diagnostics name the edit to make, such as the conversion i32(digits), so the fix is in the message rather than in your head.

dict<K,V> dictionary

A typed lookup table from keys to values, like a phone book: dict<text,i32> maps text to whole numbers. Reading a missing key with m[k] faults; get lets you name a fallback instead.

dict<text,i32> scores = {"b" = 2, "a" = 1}
scores["c"] = 3
i32 fallback = scores.get("missing", 0)
i32 gone = scores["zzz"]   # faults: absentKey

Bug it prevents: a missing key quietly read as zero or as undefined, and a table that holds values of any type at all.

A dictionary layer also states length, distinctValues and its full write policy inside the same frame, after V. Lowest/highest key order defines its first/last entries. Read the collection rules.

Dictionary (map)

A dictionary, also called a map, stores values under keys, like a phone book that maps names to numbers. Trident's is dict<K,V>, with a declared type for its keys and its values; reading a key it does not hold is a fault, and get supplies a fallback instead.

dict<text,i64> prices = { "apple" = 50, "banana" = 30 }
i64 apple = prices["apple"]
bool hasPear = prices.has("pear")
i64 pear = prices["pear"]   # faults: the dictionary holds no key "pear"

Bug it prevents: a missing key quietly read as zero or undefined and carried into a total.

Diff

A diff shows the lines that changed between two versions of a file, and most code review reads one. Because every Trident binding writes its full type, a diff shows the same facts an editor would, and nothing in another file can quietly change what a line means.

Digest chain

A release record that links by SHA-256 the source, each gate verdict and its evidence, the artifact, and the record before it. Changing any linked byte changes a digest a reader can recompute.

Dimension (in physics)

What kind of thing a number measures, whatever its unit: length, time, mass, or a mix such as speed, which is length divided by time. Meters and feet share one dimension. Trident tracks seven dimension exponents, one per SI base quantity, so mass times acceleration comes out as a force by itself.

f64<mass> load = 5kg
f64<acceleration> g = 9.81m/s^2
f64<unit=kg*m/s^2> push = load * g   # a force
f64<mass> bad = load + push   # refuses: a mass plus a force

Bug it prevents: adding meters to seconds, or reading pound-force seconds as newton seconds, the mix-up that lost the Mars Climate Orbiter.

dir2, ddir2

A dir2 is a free arrow on a flat surface: a direction, or a change in position, with no fixed starting spot. It may be zero and may carry a quantity such as length. Like every flat kind, it uses an app's own frame. ddir2 stores more digits.

dir3, ddir3

A dir3 is a free arrow in 3D: a direction, or a change in position, with no fixed starting spot. Unlike a point it may be zero, and it may carry a quantity such as length or speed. Its frame is part of its type. ddir3 stores more digits.

dir3<frame=builtin:itrs,family=length> step = (0, 0, 2)
dir3<frame=builtin:itrs> still = (0, 0, 0)
dir3<frame=builtin:icrs,family=length> other = step   # refuses: a different frame

Bug it prevents: confusing where something is (a point) with which way it goes (a direction), which most libraries store as the same three-number vector.

Discrete global grid

A way of covering the whole Earth with numbered tiles, often hexagons, so that any place maps to one cell id. H3 is a well-known example. Trident's cellid kind carries which grid it belongs to in its type, so ids from two grids never mix.

Distance-field text

Text drawn from an atlas that stores each texel's distance to the glyph edge instead of its color. The shader turns that distance into coverage per pixel, so one atlas page draws a sharp edge at many sizes.

distinctValues: one value per dictionary key

No two dictionary entries may hold equal values. A write equal to a different key's value refuses without changing the dictionary. Null equals null, so a nullable value occurs at most once. The invert operation also requires the value type to be key-eligible.

dict<text,u32,distinctValues> ids = { "one" = 1 }
Docker

A tool that packages each service with everything it needs to run into a container. An Alba deployment runs the web service, data service, database and cache as separate containers.

Donor grant and narrowing

The donor grant is the default set of libraries and settings a host declares. An operator narrows it with an admitting document, which names what a deployment gets, or a revoking document, which names what it loses. Neither form can add a library the host never declared.

chest grant = {
    text[] revoke = ["t.net.http"]
    u16 schemaVersion = 1
}

Bug it prevents: a deployment quietly gaining network or process access because a lower configuration asked for more than its host allowed.

Draft

Draft is the plain-text way to write a Chest document, one typed line per field, such as i32 since = 1. Grant files, app identity files and endpoint records are Draft, so the compiler reads them as checked, typed data rather than as loose strings.

dual

A dual number: a value paired with its rate of change (its derivative). Arithmetic carries both along, so a calculation hands back its own slope, with no separate calculus step.

dual x = (3.0, 1.0)   # x = 3, changing at rate 1
dual y = x * x
f64 slope = t.math.dual.tangent(y)   # 6.0, the slope of x*x at 3
dvec2 v = x   # refuses: same bytes, different meaning

Bug it prevents: treating the pair as a plain 2D vector, which multiplies the parts separately and loses the product rule.

Durability barrier

The medium operation that returns only once earlier writes would survive power loss, covering both file bytes and the directory entries recovery needs. MerDB never acknowledges a durable write before the barrier returns, and a write past an honest barrier is stamped synced.

Bug it prevents: Treating a completed write call as stored, when the bytes were still in a volatile cache.

duration

A length of time, stored exactly, such as 90s or 1h30m. Use it for timeouts, delays and how long something took. The unit is part of the literal, so a bare number is never a time.

duration step = 1h30m
duration twice = step + step
duration triple = step * i64(3)
duration wait = 90   # refuses: 90 of what?
duration month = 1mo   # refuses: a month has no fixed length

Bug it prevents: sleep(90) meaning 90 seconds to one author and 90 milliseconds to another.

duty

A block that runs only while this copy of the program holds a named duty, such as being the one "conductor" among several machines. Its else arm runs otherwise.

Dynamic typing

In a dynamically typed language, such as Python or JavaScript, a value's type is checked only while the program runs, so a mismatch shows up when that line executes. Trident is statically typed instead: every type is known and checked before the program starts.

E

Ed25519

A fast elliptic-curve signature scheme with 64-byte signatures. A program signs through a key handle, and a named key's bytes never leave its custodian.

Elementwise (lane by lane)

Doing an operation separately on each matching pair of entries: (1, 2) times (3, 4) lane by lane is (3, 8). That is right for a list of numbers and wrong for a quaternion, whose four numbers make one rotation together. Trident's * on a vector, matrix or tensor is lane by lane.

dvec2 left = (1.0, 2.0)
dvec2 right = (3.0, 4.0)
dvec2 both = left * right   # (3, 8), lane by lane
dquat spin = (1.0, 0.0, 0.0, 0.0)
dquat bad = spin * spin   # refuses: four lanes are one rotation

Bug it prevents: multiplying two quaternions lane by lane, which runs and gives a rotation that is quietly wrong.

ellipse, dellipse

An ellipse is a flat oval: a center, a turn, and two half-widths (its semi-axes). dellipse stores more digits.

ellipsoid, dellipsoid

An ellipsoid is a stretched or squashed ball, like an egg or a football: a center, a turn, and three half-widths (its semi-axes). Earth itself is close to one. dellipsoid stores more digits.

text describe(ellipsoid<frame=builtin:itrs> egg) {
  vec3<family=length> halfWidths = egg.semiAxes
  return t.text.of(halfWidths)
}
Embedding a language

Embedding a language means running it inside a bigger application, the way many games run Lua scripts; the application is the embedder. Trident is built to be embedded: the host decides what a program may reach, and the program runs behind a declared boundary with its own limits.

endpoint

An endpoint is one address a server answers, such as GET /items/{id}. Trident declares routes in the language, so the compiler checks the route, the method and each parameter's type before the program runs.

Bug it prevents: two handlers claiming the same route, or an id read as text instead of a number, found only when a real request hits it.

Entry point

The entry point is the one function where a program starts running, often called main. A Trident source file runs nothing until the runner calls its entry point; a script's is main(text[] argv).

enum

A type with a fixed list of named members, such as Status.Ok and Status.Error. A member is a name, not a number, and two enums never mix even when their members share a name.

enum Status { Ok = 0, Warn = 5, Error = 10 }
enum Health { Ok = 1, Hurt = 2 }
Status s = Status.Ok
Health h = Status.Ok   # refuses: two enums never mix

Bug it prevents: passing a Health where a Status was expected because both are secretly integers.

enum declaration

Declares a type with a fixed list of named choices, each with its own number, like enum Status { Ok = 0, Warn = 5 }. A member written with its type name, as in Status.Ok, works anywhere; where the spot already expects a Status, the bare name Ok works too, and anywhere else a bare name is refused.

enum Status { Ok = 0, Warn = 5, Error = 10 }
Status now = Status.Warn
Status later = Warn   # the spot expects a Status
i32 raw = Status.Warn   # 5
i32 bad = Warn   # refuses: a member needs its enum name

Bug it prevents: comparing members of two unrelated lists. Status.Ok == Priority.Ok refuses instead of being silently true, as plain numbers in C would be.

Environment variable

Environment variables are named settings the operating system hands a program when it starts, such as a home folder. In most languages any line can read them. Trident has no ambient environment: a launch computes its configuration once, in on configure, before any store opens.

Bug it prevents: a setting read deep inside a function that is missing in production and fails only when that line first runs.

Epsilon

A tiny number programmers add, or compare against, to cover up rounding errors, as in "close enough". An epsilon-repaired value is one nudged by such a fudge so that a later step does not fail. Trident's math publishes no such value; it faults and names the problem instead.

Euclidean

Ordinary flat geometry, the kind taught in school: parallel lines never meet, a triangle's angles add up to 180°, and the Pythagorean theorem holds. Euclidean space is the usual 2D or 3D space of rulers and protractors.

Eval

Eval runs code that a program builds as text while it runs, and the new code gets the program's full access. Trident can compile source bytes it holds with t.code.compile, but it cannot freely run the result: only one function that a checker proves touches no clock, files or network may run.

Bug it prevents: running text an attacker supplied as code, a classic way to take over a server.

Evidence

The output a gate keeps to back its verdict: a receipt, a transcript, a tape, a captured frame or a digest. A release record binds that evidence to the exact commit, executable, compiler and host that produced it.

Bug it prevents: a verdict nobody can recheck because the run that produced it left nothing behind.

exact

An exact number that can include powers of pi: a fraction, times a power of ten, times a power of pi. It holds values such as Planck's constant over 2 pi with no rounding.

exact hbar = exact((662607015, 2, 42, -1))   # 662607015/2 x 10^-42 / pi
exact bad = exact((1, 0, 0, 0))   # refuses: zero denominator
Exact arithmetic

Math with no rounding at all: the answer is the true answer, as when you work fractions by hand. Trident's whole-number, rational, decimal, money and measure kinds compute exactly, and they fault or refuse where an exact answer cannot be kept instead of rounding behind your back.

decimal<2> dime = 0.10
decimal<2> twenty = 0.20
decimal<2> thirty = 0.30
assert (dime + twenty == thirty, "no rounding happened")

Bug it prevents: 0.1 + 0.2 printing 0.30000000000000004 on a price.

Exception

An exception is an error signal that jumps out of the running code until something catches it, usually with try and catch. Trident uses catchable faults instead: an on error handler is written before the statements it guards, and retry, resume or fail says what happens next.

i32 zero = 0
i32 result = 0
on error { resume }
result = 10 / zero
result = result + 1

Bug it prevents: a handler swallowing a mistake that should have stopped the program, because only run-time faults can be caught.

execute (stage)

The execute stage is when the program's bytecode actually runs. A fault here, such as dividing by zero, is the only kind a program can catch with on error or task, because the earlier stages finish before any handler exists.

i32 zero = 0
i32 lost = 1 / zero   # faults: division by zero

Bug it prevents: a catch block swallowing a compile or setup error as if it were an ordinary problem with one run.

Exhaustive check

An exhaustive check makes sure a choice covers every possible case. In Trident a when over an enum is exhaustive by default: it must name every member and takes no else, so adding a member flags every when that forgot it.

enum Light { Red = 0, Yellow = 1, Green = 2 }
Light now = Light.Red
text go = when (now) {
    is Light.Red { use "stop" }
    is Light.Yellow { use "slow" }
    is Light.Green { use "go" }
}
text bad = when (now) { is Light.Red { use "stop" } }   # refuses: Yellow and Green have no arm

Bug it prevents: a new case quietly falling into a default branch someone wrote years ago.

expect … else

Reads named fields from a document at complete declared types, all or nothing. A missing field or wrong type takes the required leaving else arm. The older spelling was guard. Whole-value expect has a proved trove-contract slice.

text describe(chest doc) {
    expect { text name, i64 age } = doc else {
        return "incomplete"
    }
    return name + " is " + text(age)
}
chest who = { text name = "Ada" }
text said = describe(who)   # "incomplete"

Bug it prevents: a missing field read as zero or empty, as Go's JSON decoding does, and code carrying on with a half-filled record.

Exponent rail

A floating point number is stored as digits times a power of two, and each format has a smallest and a largest power it allows. Those limits are its exponent rails. A result past the bottom rail is too tiny to keep at full precision, and Trident's expansion kinds fault there rather than quietly lose digits.

expose()

The one step that turns a secret into plain data. A release profile names every function that calls it, and each call writes an audit row that must be durable before the value moves.

Bug it prevents: a secret leaking through a quiet conversion nobody can search for.

F

f16

A small floating-point (decimal-point) number in 16 bits, the standard "half precision" format: about 3 significant digits, and nothing above 65,504. Use it to save space in graphics and machine-learning data where rough precision is enough.

f16 h = 1.5
f16 top = 65504
f16 over = 65520   # refuses: past the largest f16

Bug it prevents: a value too big for the format turning into infinity without a word.

f32

A 32-bit floating-point (decimal-point) number with about 7 significant digits. Use it for graphics, games and sensor data, where size and speed matter more than the last digits.

f64 half = 0.5
f32 single = f32(half)   # exact, so it converts
f64 tenth = 0.1
f32 near = t.math.castRounding(tenth, "f32")   # rounding, by name
f32 lost = f32(tenth)   # faults: 0.1 is not exact in an f32

Bug it prevents: digits lost without warning when an f64 is squeezed into an f32.

f64

A 64-bit floating-point (decimal-point) number with about 16 significant digits, the usual choice for science and measurement. In Trident an overflow or a divide by zero is a fault, not a quiet infinity.

f64 rate = 1.5
f64 far = 1.0e308 * 10.0   # faults: overflow
f64 zero = 0.0
f64 bad = rate / zero   # faults: divides by zero

Bug it prevents: a NaN ("not a number") or an infinity spreading quietly through a calculation until the final answer is garbage.

fail

Raises a fault on purpose, with an optional message: fail "no user row". A handler can catch it. Inside a handler, a bare fail passes the caught fault on unchanged.

i32 n = -1
if (n > 0) { fail "positive input" }
if (n < 0) { fail "negative input" }   # faults: fail raises a fault

Bug it prevents: a bad value carrying on silently because the code that spotted it had no clear way to stop.

Fallthrough

Fallthrough is when a switch runs the matching case and then keeps going into the next case unless a break stops it. Trident's when never falls through, and one is arm can list several values, which covers the usual reason to want it.

i32 day = 6
text kind = "weekday"
when (day) {
    is 6, 7 { kind = "weekend" }
    else { kind = "weekday" }
}

Bug it prevents: a missing break in C that runs the next case's code too.

false start

A false start is a launch that stops before main runs because a start-up step failed: the program did not compile, its grant and lend disagree, a store would not open, or on start said no. The program never limps along half set up.

Bug it prevents: a server starting with a missing database or a wrong setting and failing an hour later on the first real request.

Fast-forward

A push that only adds commits on top of the newest commit on main. When main has moved, the push is rejected and the lane rebases, rechecks what it needs and pushes again. Main is never rewritten with a force push.

Fathom

MTK's name for tri running two or more joined Trident runtimes: replicas on one store, a parent and its worker, or two hosts exchanging peer messages. It is a shape of running, not a separate server. The host lends every joint and sets every count.

Bug it prevents: a replica or worker that joins a deployment without the lend saying so.

fault

A fault is a typed error raised while a program runs, such as text that is not a number or a division by zero. The work stops at that line, and no made-up value takes its place. A program can catch an execute-stage fault with on error or a task block.

text digits = "twelve"
i32 n = i32(digits)   # faults: twelve is not an i32

Bug it prevents: a bad value such as NaN, or a number that wrapped around, traveling silently into every later result.

FBX

A 3D interchange format common in modeling tools. Nautilus treats it as one more supplier format: it is decoded at the import edge, and nothing downstream reads FBX.

field

Values sampled over a grid, such as temperatures across a map or readings over time, with each axis described. Two fields combine sample by sample only when their grids match exactly. Its literal stays quoted, because its header holds braces and =.

field<dtype=u8> heights = "u8{x=2;c=1}0x0102"
field<dtype=u8> doubled = heights * u8(2)
u32 axes = t.quantity.rank(heights)   # 2

Bug it prevents: adding two maps whose grid points sit in different places, which mixes values from different spots.

fieldelem

A number in a finite field: math that wraps around at a fixed prime number, as cryptography uses. The prime is part of the type, such as fieldelem<modulus=p256>.

fieldelem<modulus=l25519> k = 7
fieldelem<modulus=l25519> minus = -7   # refuses: field values are never negative
bool less = k < k   # refuses: a finite field has no order

Bug it prevents: mixing numbers reduced by two different primes, such as the P-256 field prime and its group order.

File anchor

A named directory the host opens and pins before a program starts. The program passes the anchor's name and a relative path to t.io. Empty components, . and .. are refused, so no spelling leaves the anchor.

text notes = t.io.readText("photos", "route-14/notes.txt", 4096)

Bug it prevents: a program walking out of its folder with ../, or a path built from user input reaching a system file.

Finite-difference gradient

The old way to estimate a slope: nudge the input by a small step h and see how far the output moves. Too big a step measures the curve's bend; too small a step lets rounding errors swamp the answer. A gradient is the slope in every input direction at once.

Bug it prevents: a slope that is mostly rounding noise, with nothing to warn you that the step size was wrong.

Flag table

The named lines in the checked-in build graph that hold every build choice: compiler flags, optimization levels per node and provider package roots. A host compiler's defaults never add a choice of their own.

cflags = -std=c11 -fno-fast-math -ffp-contract=off -Werror -I.
thalassa_optimization = -O3
flagset

A set of named on/off switches packed into one value, such as file permissions. You combine sets with |, & and ~ and test one with has. A set is not a number.

flagset Access { Read = 1, Write = 2, Exec = 4 }
Access rw = Access.Read | Access.Write
bool canRead = rw.has(Access.Read)
Access more = rw + 1   # refuses: a set is not a number

Bug it prevents: adding 1 to a set of flags and flipping a permission nobody meant to grant.

flagset declaration

Declares a set of named on/off flags kept in one 64-bit word, like file permissions. Flags combine with set operators (|, &, ^, ~) and are tested with has, never with arithmetic. Where the spot already expects that flagset, as the argument of has does, a flag may drop its type name, as in rw.has(Write).

flagset Access { Read = 1, Write = 2, Exec = 4 }
Access rw = Access.Read | Access.Write
bool canRead = rw.has(Access.Read)
bool canWrite = rw.has(Write)   # Write reads as Access.Write
u64 bits = rw   # 3, only at a u64
Access more = rw + Access.Exec   # refuses: a set is not a number

Bug it prevents: ~ flipping all 64 bits and switching on flags nobody named, or adding flags like numbers so a bit lands in the wrong place.

fleet

A fleet is all the running copies (runtimes) of one deployment that share one store, on one machine or many. The fork and duty statements start runtimes in the fleet and give one of them a named role, and a program whose lend has no fleet line cannot fork.

Flight recorder

A rolling tape of a session's most recent calls, kept within a byte budget. After a fault, the call that failed can be replayed from it in a separate child with every effect denied.

Bug it prevents: a fault that happened at 2 a.m. and cannot be reproduced at 9.

Floating point

The way computers store numbers that have a fractional part, like scientific notation in binary: some digits times a power of two. It reaches huge and tiny numbers, but most decimals, such as 0.1, can only be stored approximately, so small rounding errors creep in.

f64 sum = 0.1 + 0.2
bool same = sum == 0.3   # false: both sides were rounded to binary
Floor division

Division that always rounds down, so the remainder is never negative: -7 divided by 2 is -4 with remainder 1. C rounds toward zero instead (-3 with remainder -1), which breaks calendar math for negative years. In Trident, // is not floor division: it builds an exact fraction.

rational half = 7 // 2   # 7/2 as a fraction, not 3
foreach … in

Runs a block once for each element of an array, or each key and value of a dictionary. It walks the collection as it was when the loop began, so changing it inside the loop never changes the walk.

i32[] values = [1, 2, 3]
i32 sum = 0
foreach (value in values) {
    sum += value
}
foreach (i32 v in values) { sum += v }   # refuses: the binding states no type

Bug it prevents: changing a list while looping over it, which crashes in Java and silently skips or repeats items in other languages.

Foreign function interface (FFI)

A foreign function interface lets a program call code written in another language, usually a C library. It is powerful, but that code runs with none of the language's safety checks. A Trident program has no FFI: it reaches only the t.* libraries the host links in.

fork

A reserved word for a statement that starts another copy of the running program, on this machine or another one in its group (the fleet), which talks back only through the shared data store. The word is kept so no program can use it as a name.

i32 forks = 1
i32 fork = 1   # refuses: a future keyword is not a name
Fork-join

Running several branches at once and continuing when all of them finish. In Cutlass, parallel on group { a(); b(); c() } runs each branch on one member of a declared thread group. A branch that blocks, touches a channel or writes what another branch writes is refused, so the result never depends on timing.

Bug it prevents: a race between parallel branches that shows up once in a thousand runs.

Format string

A format string is text with placeholders, like "%f kN", that a function such as printf fills with values. Trident has no format specifiers: each hole in an interpolated text is text(x), and how a value looks is a named call, such as t.measure.format.

Bug it prevents: a unit typed by hand into a format string that no longer matches the number it prints.

Forward-mode differentiation

A way for a computer to work out derivatives: every number carries its value and its rate of change, called its tangent, side by side, and each operation updates both by the rules of calculus. Nothing is estimated with small steps. Trident's dual kind is this pair, a first-order Taylor pair.

frameid (frame)

A frame is the point of view the numbers are measured from, like "from the center of the Earth, turning with it" or "from the camera". A frameid is the name of one frame. The built-in frames cover Earth, the sky and the Moon, including the lunar frame lcrs, and an app can name its own. Spatial types carry their frame in the type.

frameid earth = builtin:itrs   # turns with the Earth
frameid sky = builtin:icrs   # fixed to distant stars
bool same = earth == sky
bool less = earth < sky   # refuses: a frame name has no order

Bug it prevents: mixing coordinates from two frames, such as using a camera-space point as a world-space point. The frame is part of the type, so the mix refuses.

Framework

A framework is a large library that provides the skeleton of an app, such as a web framework that sends each request to your code. Where other languages reach for a web framework, Trident declares endpoints in the language itself, so a routing mistake is refused when it compiles.

full: a policy for a growing write

At a declared maximum, reject refuses the write, dropFirst removes the first items and dropLast removes the last. An array uses element order; a dictionary uses key order. Received data is validated without trimming. This policy never turns a null collection into a present one.

Function declaration

A function starts with the type it returns, then its name and its typed parameters: i32 add(i32 x, i32 y). There is no function keyword. Every call passes exactly the listed arguments, with no defaults or overloads.

i32 add(i32 x, i32 y) {
    return x + y
}
i32 sum = add(2, 3)
i32 few = add(2)   # refuses: a call names every argument

Bug it prevents: a call with a missing or extra argument that only misbehaves once the program runs.

Function value (callback)

A function value is a function stored in a variable or passed to another function. A callback is one handed over to be called later, and a comparator is one that tells a sort which item comes first. Trident has no function values, by design: every call names a declared function.

i32 twice(i32 n) { return n * 2 }
i32 thrice(i32 n) { return n * 3 }
i32 scale(i32 mode, i32 n) {
    if (mode == 2) { return twice(n) }
    return thrice(n)
}
i32 six = scale(2, 3)
fxrate

An exchange rate with both currencies in its type: fxrate<EUR,USD,4> is the price of one euro in dollars, to four places. A conversion is a named call that rounds once, and a rate works only in the direction it names.

fxrate<EUR,USD,4> rate = 1.0850
money<EUR> price = 10.00
money<USD> zero = 0.00
money<USD> cost = t.finance.fx.convert(price, rate, zero, "halfEven")
money<EUR> back = t.finance.fx.convert(cost, rate, price, "halfEven")   # refuses: the rate runs EUR to USD

Bug it prevents: applying a euro-to-dollar rate backwards and charging the wrong amount.

G

Gamut

The set of colors a screen, a printer or a color space can actually show. A color outside it has to be pulled inside, which is called gamut mapping.

Garbage collection (GC)

Garbage collection frees memory automatically: a collector finds data nothing uses anymore and takes it back. A tracing GC scans everything still reachable, which can pause the program. Trident runs no collector at all; a scope's memory reservation is refunded when the scope ends.

Bug it prevents: a game frame that stutters while the collector stops to clean up.

Gate

A check the system runs before it accepts a change or a release. Each gate is a leaf in the build graph with a command, its inputs and a verdict.

Bug it prevents: release notes that say "tested" with no run behind them.

Gate leaf

One runnable check in the build graph. It has a stable name, a class, a command, the inputs that rerun it and a memory ceiling, and its exit status is its verdict. Plans schedule leaves, and receipts record them.

build $builddir/crewlog-suite.stamp: tri_app_test $builddir/tri.exe | crewlog/a/queue.tri
  test_class = bounded
  testargs = crewlog
Gate profile

A named selection of gate leaves: one test lane, one node's group, the full routine plan, or the release run on each proof host. A profile changes which leaves run, never what a leaf means.

ninja -k 0 crewlog-suite-test   # one lane
ninja -k 0 test                 # the full routine plan
Generic function

A generic function is written once for several types. Trident has no source-level generic function. An outline parameter admits records that satisfy its structural contract.

i32 twice(i32 n) { return n * 2 }
i64 twiceWide(i64 n) { return n * 2 }
i32 eight = twice(4)
i64 wideEight = twiceWide(i64(4))
i64 wrong = twice(i64(4))   # refuses: twice takes an i32
Genesis baseline

The recorded first state a deployment starts from: its first runtime release, host documents and application generation, provisioned by hand from a trust root. Every later state is a recorded change from it, so any node's history can be traced back to a known start.

Geodesic

The shortest path between two points along a curved surface, like an airliner's route over the globe. On the Earth it is not a straight line on a flat map, which is why subtracting two latitude and longitude pairs does not give the distance between them.

Bug it prevents: subtracting two latitude/longitude pairs and treating the result as a distance, which is off by about cos(latitude) east to west.

geodetic (geodetic coordinates)

A place on Earth: latitude and longitude (angles, in radians) plus height in meters, measured on a named model of Earth's shape called a datum, such as wgs84, the one GPS uses. It refuses order, arithmetic and conversion: a place has no order, and a distance or a change of datum is a named calculation.

geodetic<datum=wgs84> home = (0.7, -1.3, 120)
geodetic<datum=wgs84> work = (0.71, -1.31, 80)
geodetic<datum=wgs84> gap = home - work   # refuses: distance on a curved Earth is a named calculation

Bug it prevents: subtracting two latitude and longitude pairs and calling the result a distance, which gets more wrong the farther you are from the equator.

Geodetic datum

The agreed model of the Earth's shape and position that latitudes and longitudes are measured against, such as WGS 84, which GPS uses. One spot can have slightly different coordinates under two datums. Moving coordinates between them is a datum transform, a named call in Trident (t.geo.carto.datumShift).

Geometric algebra

One algebra that treats directions, flat patches (bivectors), rotations and reflections as things you can add and multiply, where each piece has a grade: 1 for a direction, 2 for a flat patch. The even grades hold rotations; in 3D that even subalgebra is the quaternions. Trident spells its products as named t.math.geometricAlgebra calls, never as operators.

Ghost fill

In grid simulations, a block of cells keeps an extra border of "ghost" cells copied from its neighbors, so a calculation at its edge can look one step past it. Ghost fill is copying values into that border.

GLB and glTF

The Khronos 3D transmission format. glTF is JSON plus binary buffers, and GLB packs the same content into one file. Nautilus imports a GLB as a mesh profile, or as a rigClip profile when the model carries a skeleton.

Glint

Glint is Thalassa's shader language: small programs that run on the graphics card to shape and color what is drawn. Its written form follows Trident's grammar wherever both languages share a construct and a companion page compares it with other shader languages.

Glint IR

The typed, checked form of a shader. Thalassa parses Glint source once, checks every type and stage rule, and names the result by a SHA-256 digest. Every backend lowers from that same checked IR, and the Soft renderer runs it directly.

Bug it prevents: a shader that compiles on one driver and fails on another because each driver parsed its own copy of the source.

grant

The grant is the exact, fixed list of libraries and services a running program may call. The host builds it at launch from what the source reaches and what the lend allows, and it never changes while the program runs. Every t.* call is grant-gated: a call the grant does not admit is denied.

Bug it prevents: a program reaching the network or a key store that nobody approved, hidden somewhere among its imports.

Granted scope

A MerFS folder handed to one application as a capability, with quotas for bytes, files, open handles and how long a write may stay volatile. Every file call starts from it, and a name is one component, so .. or a slash cannot reach anything outside it.

Bug it prevents: An application reading another application’s files, or the boot manifest, by spelling a longer path.

Graph snapshot

A saved set of linked records in which every link is a stable key. A link is either an id the store issued or a vertex position inside a graph value. It holds no memory addresses, so it restores to the same relationships on any machine.

Bug it prevents: A saved plan whose links pointed at memory that no longer exists after a restart.

graph: vertices and arcs

A collection of typed vertex values and arcs between indexed vertices. Arc values can be a scalar or record. Counts, degree, simplicity, direction, cycles, connectivity and bipartition are checked rules. Graph values are separate from execution resources such as a render graph. Graph rules and examples.

graph<text,acyclic> tasks = [ "parse" { 1 }, "compile" ]
Grapheme cluster

A grapheme cluster is what a reader sees as one character, even when it is stored as several Unicode scalars, like a letter plus an accent mark, or a flag emoji. Trident asks which count you mean: t.text.graphemes counts these, while t.text.scalars and t.text.bytes count the others.

text word = "héllo"
i64 n = word.count()   # refuses: say which unit you are counting

Bug it prevents: cutting a name in half in the middle of an accented letter or an emoji.

Graphics backend

The GPU interface a device draws through: Metal, Direct3D 11, Vulkan or WebGPU, beside the Soft renderer on the CPU. Each backend reports its measured features and limits, and Thalassa admits a render program against those facts. The host selects the backend explicitly; Thalassa never swaps one in silently.

Bug it prevents: a program quietly falling back to a different renderer when the GPU it asked for is missing.

Greatest common divisor

The biggest whole number that divides two numbers evenly. For 12 and 18 it is 6. Dividing the top and bottom of a fraction by it puts the fraction in lowest terms: 12/18 becomes 2/3.

rational r = 12//18
assert (r == 2//3, "kept in lowest terms")
guard: an older statement name

Trident's older guarded field read is now spelled expect. the old guard statement is refused. A selector on a check row is a separate record constraint.

Bug it prevents: using a retired statement spelling or mistaking a record constraint for a field read.

guid

A 128-bit id written as 32 hexadecimal digits (0-9 and a-f) in five groups, like a serial number nobody else ever reuses. Use it to name records and objects. It is never a number and never plain text.

guid id = 00000000-0000-0000-0000-000000000000
guid copy = id
bool same = id == copy
bool first = id < copy   # refuses: an id has no order
u128 n = id   # refuses: an id is not a number

Bug it prevents: doing math on an id, or comparing an id with any string that happens to look like one.

H

Half-open range

A range that includes its start but not its end, like "from 9:00 up to, but not including, 10:00". Back-to-back ranges then meet with no gap and no overlap, so every instant belongs to exactly one. A Trident timerange is half-open.

Handler

A handler is a block of code that runs when something happens, such as an error or an incoming request. Trident declares its handlers ahead of time: on error before the statements it guards, and on request, on event and on job at module level. No program can add a handler while it runs.

Hash and digest

A hash function turns any data into a short, fixed-size fingerprint called its digest. Change one byte and the digest changes completely, and finding two inputs with the same digest is practically impossible. So naming a file by its digest guarantees you get exactly those bytes back.

Bug it prevents: a library swapped for different code under the same name and version.

Heap

The heap is the large pool of memory a program draws from for data whose size or lifetime is not known ahead of time; a garbage collector or the programmer must give it back. A Trident program never manages it: each kind of memory has a declared limit, and a scope's reservation is refunded when the scope ends.

Heap family: a complete priority tree

A complete binary tree: every level is full except possibly the last, which fills from the left. A max heap keeps each parent priority at least its children; a min heap reverses that comparison. Siblings need not be sorted. This is distinct from the memory allocator called a heap.

tree<job,family=heap,heap=max(priority)> work = []
histogram bound

A fixed dividing value between buckets. The selected rule puts equality in the bucket that starts at the bound. Bounds are nonempty, finite, strictly ascending, and exactly projected.

Bug it prevents: placing the same boundary value in different buckets on different collection paths.

history cut

The exact Store scope and publication versions a page reads. It includes the collection anchor, owner, and ordered stripe positions. Multiple stripes keep their actual positions; there is no invented global version number.

Bug it prevents: presenting a partly applied publication as complete history.

HLSL

High-Level Shading Language, the shader text Direct3D 11 compiles on Windows. Thalassa lowers checked Glint IR to HLSL for the Direct3D 11 backend.

Hold

The verdict of a leaf that could not run on this host: a missing device, toolchain, privilege or media. The leaf prints the leg and the cause and exits 2. A hold blocks a release the same way a fail does.

Bug it prevents: a test that skips itself on an unequipped host and exits 0, so the release counts a leg nobody ran.

host

The host is the program that runs a Trident program, such as tricli or tri. It opens files, windows, stores and the network, decides what the program may touch, compiles the program and calls it. A Trident program reaches the outside world only through what its host lends it. The host configuration defines those permissions.

Bug it prevents: a program grabbing a file, the clock or the network that nobody gave it.

Host adapter

The code inside a host that turns a service into the operating system's own calls. It uses Win32 on Windows, procfs and sysfs on Linux, and Mach and libproc on macOS; on a BenthOS device, the BenthOS platform backend plays this part. Applications never see which adapter ran.

Host table

The fixed set of typed services a host lends a runtime at launch: files for t.io, a process supervisor for t.proc, a peer plane for t.net.peer. Each executable compiles in its own set, so nothing registers a new service while a program runs.

Bug it prevents: a program reaching the operating system through a side door that no lend lists.

HTTP

HTTP is the set of rules web browsers and servers use to send requests and answers, such as GET a page or POST a form. Trident builds HTTP routing into the language with on request, and its outbound HTTP client is the t.net.http library.

hvec2, hvec3, hvec4

A vector of 2, 3 or 4 half-size decimal numbers (binary16), using half the memory of a vec. It suits storing many colors or surface arrows for a graphics card, where fewer digits are fine. Mixing it with a full-size vector needs an explicit conversion.

hvec3 small = (1, -2.5, 0.5)
vec3 full = vec3(small)
hvec3 mixed = small + full   # refuses: convert one side first
hvec2 tiny = (70000, 0)   # refuses: too big for a half-size number

Bug it prevents: mixing half-size and full-size numbers in one sum and losing digits at a spot nobody chose.

I

I/O

I/O (input and output) is any way a program talks to the world outside it: files, the network, the screen, the keyboard. In Trident, I/O happens only through granted library calls, and a module constant can never do I/O while the program loads.

i128

A whole number stored in 128 bits, up to 39 digits long either way. Use it when even an i64 could run out, as in exact totals over huge data.

i128 huge = 170141183460469231731687303715884105727
i128 next = huge + 1   # faults: past the largest i128
i16

A whole number stored in 16 bits, from -32,768 to 32,767. Use it for audio samples and other compact signed data.

i16 sample = -32768
i16 lower = sample - 1   # faults: past the smallest i16
i16 over = 40000   # refuses: 40000 does not fit in an i16

Bug it prevents: a loud audio sample wrapping from the top of the range to the bottom and turning into a click.

i32

A whole number stored in 32 bits, from about -2.1 billion to 2.1 billion. It is the everyday choice for counts and ordinary whole numbers.

i32 count = 3
i64 total = count   # refuses: a destination never widens
i64 wide = i64(count)   # the conversion is written out
i32 big = 2147483647
i32 over = big + 1   # faults: past the largest i32

Bug it prevents: a number silently changing size, or wrapping past its largest value to a large negative one.

i64

A whole number stored in 64 bits, up to about 9.2 quintillion either way. Use it for large counts and byte sizes. It is also the width a plain numeral takes when nothing else says.

i64 bytes = 3000000000
i32 small = bytes   # refuses: the conversion must be written
duration step = 2s
duration longer = step * i64(3)   # a duration scales by an i64

Bug it prevents: a large value silently chopped down to fit a smaller integer.

i8

A whole number stored in 8 bits, from -128 to 127. Pick it for small signed values when space matters, such as a tiny offset.

i8 top = 127
i8 low = -128
i8 over = 128   # refuses: 128 does not fit in an i8
i8 next = top + 1   # faults: past the largest i8

Bug it prevents: 127 plus 1 silently wrapping around to -128.

IDE and language server

An IDE (integrated development environment) is an editor built for code that shows errors and types as you work; a language server is the helper program that feeds it those facts.

Identity evidence

What a verified sign-in establishes: the method, the issuer, user presence and verification, freshness and binding facts. It feeds account admission, and on its own it grants no permission.

IEEE 754

The worldwide rulebook, first published in 1985, for how computers store floating point numbers and round their results; nearly every processor follows it. It also defines special values: infinity, NaN and a negative zero. Trident uses its formats but faults where the rulebook would hand back an infinity or a NaN.

f64 zero = 0.0
f64 x = 1.0 / zero   # faults: IEEE 754 would answer infinity

Bug it prevents: a division by zero turning into infinity, then NaN, and showing up far away as a report full of "nan".

if, elseif, else

Runs a block only when a condition is true; elseif tries another condition and else catches the rest. The condition must be a bool. Written where a value belongs, an if can also produce one with use.

i32 n = -3
text sign = "zero"
if (n < 0) {
    sign = "negative"
} elseif (n > 0) {
    sign = "positive"
}
if (n) { sign = "?" }   # refuses: a condition is a bool

Bug it prevents: C's if (x = 5), which assigns instead of comparing, and numbers or empty text quietly counting as true or false.

Immutable and mutable

An immutable value can never change after it is made; a mutable one can be changed in place. In Trident a const binding refuses every write, and every copy of a value is its own, so changing one copy never changes another.

const i32 limit = 10
i32 room = limit - 1
limit = 11   # refuses: a const binding is never written
Implicit conversion

An implicit conversion is a type change the language makes for you without being asked, like turning a number into text. Trident allows exactly one: two integer widths inside an operator meet at the smallest width that holds both. A destination never converts.

i32 left = 3
u32 right = 4
i64 product = left * right
i64 copy = left   # refuses: a destination never converts
f64 wide = 1.5
f32 narrow = wide   # refuses: float widths never mix

Bug it prevents: "5" + 3 becoming "53", or a float quietly losing digits as it is squeezed into a smaller one.

Import

An import brings code from another file or library into the current one, and in many languages importing a file runs its code. Trident's one declared import is alias, which only shortens a name the compile already holds, and every import is settled before any function body compiles.

alias tm = t.math
alias missing = my.module   # refuses: no unit in this bundle has that id
Import recipe

The _import.draft file that governs one folder under _assets/. It lists the formats it admits, the profile they become, and intent such as a color space or a level count. It never names a platform, and a source outside its formats refuses by name.

text[] formats = ["glb"]
text group = "file"
chest intent = {
    u8 levels = 4
}
text profile = "mesh"

Bug it prevents: a build that guesses a file's format from its first bytes and imports the wrong thing.

Infinity

A floating point value meaning "larger than any number", which IEEE 754 makes when a result is too big to store or when you divide by zero. In Trident arithmetic never makes one: it faults. You can write f64(infinity), which still orders above every number, but computing with it faults.

f64 top = f64(infinity)
bool above = top > 1.0e308   # true: an infinity keeps its order
f64 far = 1.0e308 * 10.0   # faults: too big for binary64

Bug it prevents: an overflow quietly becoming infinity and then NaN a few steps later.

infinity, nan

Reserved words for a float's special values: infinity is infinity and nan means "not a number." You can write them on purpose, but arithmetic on them faults instead of spreading a bad value into later math.

f64 top = infinity
f64 bottom = -infinity
f64 more = top + 1.0   # faults: an infinity is not finite
f64 infinity = 1.0   # refuses: infinity is a reserved word

Bug it prevents: a NaN from one bad calculation silently flowing into every number computed after it.

Information flow

Protection that follows data through computation. Values derived from a labeled input keep its label. Control decisions join into the call's observation watermark, so every later effect carries what the call saw.

Bug it prevents: a restricted value deciding whether a harmless-looking public message gets sent.

ingot

The exact, immutable record type: a value carries exactly the listed fields, and every field states a default. A program declares one as ingot Name { Type field = default }, and no statement writes into its value.

Ingress

Anything that enters a program from outside: network bytes, a plan file, command-line arguments. The host admits ingress in a fixed order, framing and size first, then the sender's identity, then decoding and policy. Only admitted input becomes an application event.

Bug it prevents: a parser running on unauthenticated bytes, or a handler reading a half-checked message.

Init bundle

The signed, immutable set the loader hands the kernel: the first supervisor's image, its grants, the MerFS profile and the recovery choice. The boot manifest signs its digest, so one changed byte stops the boot. It is never a writable filesystem.

Integer join

Trident's one automatic conversion. When two whole numbers of different widths meet inside an operator, they meet at the smallest width that holds both, exactly: an i32 times a u32 is an i64. It never happens on assignment, and floats never mix.

i32 count = 300
u32 scale = 2
i64 product = count * scale   # the two widths meet at i64
i32 bad = count * scale   # refuses: the product is an i64

Bug it prevents: C's signed and unsigned mix-ups, where -1 can compare as larger than 1.

Interface (trait)

An interface, which Rust calls a trait, is a promise that a type has certain methods, so code can work with any type that keeps the promise. Trident has no methods or interfaces, and interface, trait and class are reserved words no program can use as a name.

Interpreter

An interpreter runs a program step by step, reading each instruction and carrying it out, instead of first turning the whole program into machine code. Trident compiles source to a bytecode image, and its virtual machine interprets that image while counting each call's depth and work.

interval

A range of numbers, low to high, that is sure to contain the true answer. Every step rounds outward, so rounding error can never push the answer outside the range.

interval lo = (0, 1)
interval hi = (1, 3)
interval s = lo + hi   # (1, 4)
interval bad = (2, 1)   # refuses: the low end is above the high end
bool less = lo < hi   # refuses: overlapping ranges have no order

Bug it prevents: trusting a floating-point answer whose rounding error has quietly grown larger than the answer.

Intrinsic

A cut or cutarch function declared with no body, whose lowering the compiler owns, such as cutarch.x64.rdtsc(). One registry row states its signature, privilege and effects, and each back end's table states the instructions it becomes.

Bug it prevents: inline assembly with undeclared effects that the optimizer moves or deletes.

ip

One IP address: IPv4 like 192.0.2.1 or IPv6 like 2001:db8::1. The type can pin the version, so ip<v4> holds only IPv4. It is neither text nor a number.

ip host = 2001:DB8::1
ip same = 2001:db8::1
bool equal = host == same   # true: one address
ip mapped = ::ffff:192.0.2.1
ip<v4> four = 2001:db8::1   # refuses: not an IPv4 address

Bug it prevents: comparing addresses as text, where "2001:DB8::1" and "2001:db8::1" look like two different machines.

ipprefix

A block of IP addresses: a network address and a length, such as 192.0.2.0/24. A prefix whose address has bits set past its length, such as 10.0.0.1/8, is refused rather than quietly rounded.

ipprefix lan = 192.0.2.0/24
ipprefix six = 2001:db8::/32
ipprefix bad = 10.0.0.1/8   # refuses: bits are set past /8

Bug it prevents: a firewall rule that covers a different range of addresses than its text seems to say.

ISO 8601 and RFC 3339

Two standards for writing dates and times as text, such as 1987-03-05T14:30:00Z: year, month and day, then the time and its offset from UTC. RFC 3339 is a stricter internet profile of ISO 8601. They differ on small points, such as what an offset of -00:00 means.

Iterator

An iterator is the marker a loop uses to walk through a collection one item at a time. Changing the collection mid-walk can crash the loop or make it skip items. Trident's foreach walks a snapshot taken when the loop began, so adding items inside the loop never extends the walk.

i32[] xs = [1, 2, 3]
foreach (x in xs) {
    xs.add(x)
}
assert (xs.count() == 6, "walked_three_items")

Bug it prevents: a loop that never ends because it keeps adding to the list it walks, or a C++ loop reading through an iterator after the list moved.

ivec2, ivec3, ivec4

A group of 2, 3 or 4 whole numbers that may be negative (each an i32), such as a tile's column and row on a game map. Math works lane by lane, and every lane is checked so it cannot overflow.

ivec2 tile = (3, -4)
ivec2 right = tile + (1, 0)
i32 row = tile.y
ivec2 huge = tile * 1000000000   # faults: a lane would overflow

Bug it prevents: a grid position quietly wrapping around to a wrong tile when one of its numbers grows too big.

J

JIT compilation

JIT (just-in-time) compilation turns code into machine code while the program runs, to speed up the busiest parts. It adds speed and also complexity. Trident has no JIT: it interprets bytecode, and its design refuses a JIT tier until measurements ask for one.

job

A job is a piece of work the host runs in the background for a program, such as a nightly report. MerJob records each job, so it keeps one identity through every retry, whether it runs here or on another machine.

Bug it prevents: a retried task running twice as two different jobs.

JSON

JSON is a common text format for data, written with braces and quotes, like {"name": "Ada"}. It carries no real types, so every program must check what it reads. Trident's documents are typed chests whose field types travel with them, and expect reads one at declared types.

K

Keel

Keel is MerTek's core library of math and computing routines, written in C. t.math and many other t.* libraries call into it. It is deterministic, so the same inputs give the same answer every time.

Keel kernel

One generic computation in Keel, such as a segment distance, a Kalman step or a matrix product. It computes over the values its caller hands it and holds no scenario value, threshold or policy. Trident reaches it through a typed t.* member.

chest closest = t.collide.segmentClosest(legStart, legEnd, mastBase, mastTop)
f64 distance = closest.distance

Bug it prevents: a safety threshold buried in low-level C where no reviewer looks for it.

Key resource

A handle to a key that holds no key bytes in the program. It cannot be printed, stored in a record or written to a log; the program spends it only through t.security members.

Bug it prevents: a key copied into a variable and later written to a log or a config file.

Kind(value) conversion

Converts a value by writing the target type like a function call: f32(x), i64(n), text(n). The result is exact, or the program faults and names what would be lost. On text it parses, so i32("42") is 42. This form is called an introducer.

f64 half = 0.5
f32 single = f32(half)   # exact
text digits = "42"
i32 n = i32(digits)      # 42, or a fault
f64 tenth = 0.1
f32 lost = f32(tenth)   # faults: 0.1 is not on the f32 grid

Bug it prevents: a silent cast that drops digits or wraps a number, as C, Java and Go allow. When losing data is the goal, a named call such as t.math.castRounding says so.

L

Large object

A value too big to keep inside its record, such as a photo or a firmware image. It lives in an external column, stored in chunks beside its row, and a large body arrives through staged writes that commit as one. A reader sees the old bytes or the new bytes, never a prefix.

buffer? body = null with { storageClass = external }

Bug it prevents: A list screen loading 14 MB of photo for every row it shows.

Layer

A level in MTK's dependency order: core mechanisms, Trident libraries, applications, products. A layer may use the layers below it and never the ones above, so a mechanism never carries one application's policy.

Bug it prevents: a storage engine that quietly changes behavior for one customer's app.

Leap second

An extra second, written 23:59:60, that is sometimes added to UTC because the Earth's spin is slightly uneven. 27 have been added since 1972. Trident's civil labels accept second 60 as a leap label and never roll it over into the next minute.

civil leap = 2016-12-31T23:59:60Z   # a real leap second

Bug it prevents: a timestamp of 23:59:60 crashing a date parser or being shifted into the next minute.

lend

A lend is the list the person running a program hands it of what it may use, like a hall pass: libraries and their settings, stores, folders, network endpoints and size limits. An application keeps it in _grant/grant.draft. The host works out what the code needs and checks it against the lend both ways.

Bug it prevents: forgotten permission. A launch stops if the code reaches a library the lend does not cover, or if the lend allows something no code uses.

Level

One rung of a security domain's ordered list, such as internal or restricted. Order comes from the declaration, never from a number, so a level keeps its identity when the list changes.

lex, parse, verify, install (stages)

Every Trident fault names the step where it stopped. lex reads characters into words, parse builds the sentence structure, compile makes bytecode, verify double-checks that bytecode, install loads it into the runtime, and execute runs it. Other steps include grant, where permissions are checked.

Lexicographic order

Ordering the way a dictionary does: compare the first parts, and only if they tie, compare the next ones. "cat" comes before "cub" because the c's match and a comes before u. Trident orders its expansion kinds this way over every lane, so the whole value decides, not only the first lane.

Library config

A library's own policy inside its grant row: t.io anchors, t.proc program rows, the security libraries' credential names and uses. Each library defines how a narrower config may differ, and that relation only removes access.

Bug it prevents: a child process launched with arguments or environment nobody reviewed.

Limb (of a big number)

A big integer stores its digits in fixed-size chunks called limbs. Operand size determines required storage. Trident reserves memory, but it does not count limb products or impose a runtime work budget.

line2, dline2

A line2 is a straight line on a flat surface that goes on forever both ways. It is stored as a normal (which side it faces) and an offset (how far it sits from the origin). dline2 stores more digits.

line3, dline3

A line3 is a straight line in 3D that goes on forever both ways, stored as one point on it and a direction. dline3 stores more digits.

text describe(line3<frame=builtin:itrs> track) {
  point3<frame=builtin:itrs> onIt = track.origin
  dir3<frame=builtin:itrs> heading = track.direction
  return t.text.of(heading)
}
Linking

Linking joins separately built pieces of a program, and its libraries, into one thing that can run. Trident's linking is closed-world: everything is resolved before the program runs, with no search path and no resolver a running program calls, so the whole call graph can be checked first.

Linter and syntax highlighter

A linter reads code and warns about likely mistakes or messy style; a syntax highlighter colors code so it is easier to read. Trident keeps its grammar plain for both: # starts the one line comment, so even a shebang line needs no special case.

Literal

A literal is a value written straight into the code, like 42, 1.5 or "hello". In Trident a literal reads at the type its destination declares, so i64 total = 0 needs no suffix, and a literal that does not fit is refused when the program compiles.

i64 total = 0
f32 ratio = 1.5
u8 level = 300   # refuses: 300 does not fit in a u8
Live edit

A change to a running application's rules or configuration, published as a new generation with no restart. It is validated and claimed first, and the prior generation's bytes stay stored, so rollback is a replay.

lock, lock?

Runs a block while holding a lock on a named key, under a policy such as exclusive or shared use. The lock is released however the block ends. lock faults if its wait runs out; lock? runs its else arm instead.

text key = "ledger"
chest policy = t.sync.policy.exclusive(0ms, 1s, false)
lock (key, policy) {
    # held here, and released however the block ends
}
lock? (key, policy) { } else { }
lock (key) { }   # refuses: a lock names its policy

Bug it prevents: a lock left held forever because an early return or a fault skipped the unlock.

logical type

What a value means, as MerTekTypes names it: a duration, a guid, a length written f64<family=length>. Trident, MerDB and Rune all read that one name. Two types can share a byte width and still be different logical types.

guid workOrder = 0190f3a2-7c41-7b9e-a2d4-5f8c1e6b9a30
# u128 raw = workOrder   refuses: no conversion exists

Bug it prevents: An identifier treated as a number, or a length treated as a mass, because both had the same bytes.

Lowering

The step that turns checked Glint IR into one backend's shader: WGSL, HLSL, SPIR-V or MSL. Each lowering writes Glint's edge rules, such as integer division by zero, into its own output, so no driver default changes the answer.

Bug it prevents: a shader whose result depends on which vendor's compiler handled a zero divisor.

M

main

The function where a script starts: text main(text[] argv). Opening or reading a source file runs nothing; code runs only when the runner calls main. argv holds the words typed after -- on the command line.

text main(text[] argv) {
    if (argv.count() == 0) {
        return "no arguments"
    }
    return "first: " + argv[0]
}

Bug it prevents: importing a file only to read it and having its top-level code run, as Python, Ruby or JavaScript allow.

mat2, mat3, mat4 (and dmat2, dmat3, dmat4)

A matrix: a square grid of numbers (2 by 2, 3 by 3 or 4 by 4) that stretches, turns or moves vectors. The @ operator applies a matrix to a vector or chains two matrices, while * works lane by lane. The numbers are listed column by column. The d versions store more digits.

mat2 stretch = (2, 0, 0, 3)
vec2 step = (1, 1)
vec2 stretched = stretch @ step   # (2, 3)
mat2 twice = stretch @ stretch
bool less = stretch < twice   # refuses: a matrix has no order

Bug it prevents: writing * where you meant the matrix product. Here * is always lane by lane and @ is always the product, so the two never get confused.

mat2x3, dmat2x3

A matrix with 2 rows and 3 columns: a flat (2D) turn or stretch plus a move, like placing a sticker on a page. Apply it with @ to a vec3 whose last number is 1 to get the moved vec2. dmat2x3 stores more digits.

mat2x3 slide = (1, 0, 0, 1, 20, 30)   # move by (20, 30)
vec3 spot = (1, 2, 1)
vec2 moved = slide @ spot   # (21, 32)
mat3x4, dmat3x4

A matrix with 3 rows and 4 columns: a turn or stretch plus a move, for 3D. Apply it with @ to a vec4 whose last number is 1, and you get the moved vec3. Its type may name the frame it maps from and the frame it maps to. dmat3x4 stores more digits.

mat3x4 slide = (1, 0, 0, 0, 1, 0, 0, 0, 1, 5, 0, 0)   # move 5 along x
vec4 spot = (1, 2, 3, 1)
vec3 moved = slide @ spot   # (6, 2, 3)
measure

An exact amount with a unit and a kind of quantity attached, such as 90deg:angle or 2m:length. Its math stays exact, even with pi in it, and units must agree. Use it when an answer must be exact, not rounded.

measure quarter = 90deg:angle
measure inRad = t.measure.to(quarter, "rad")   # exactly pi/2
measure d = 2m:length
measure secs = 3s:time
measure bad = d + secs   # faults: meters plus seconds

Bug it prevents: adding meters to seconds, or getting 1.5707963267948966 where the true answer is exactly pi/2.

measurement

A reading and its uncertainty as one value: the estimate, its standard uncertainty (how far off it may be) and the degrees of freedom (how much data that uncertainty rests on). Combining readings is a named call that says how their errors relate.

measurement rod = (1.5, 0.25, 9)
f64 estimate = rod.estimate
f64 spread = rod.standardUncertainty
measurement two = rod + rod   # refuses: a sum must state how errors relate

Bug it prevents: adding two readings and assuming their errors are unrelated, which can understate the real uncertainty.

Memory management

Memory management is how a program gets memory for its data and gives it back. Most languages use a garbage collector, manual frees or ownership rules. Trident uses none of these: there is no free and no pointer, each kind of memory has a limit the host declares, and a scope's reservation is refunded when the scope ends.

MerDB

MerTek's database engine. It stores typed records in troves and reads them only by key, through an index the trove declares, or by following an ordered change feed. Every write passes one commit point.

Bug it prevents: a dashboard query that quietly turns into a scan of every record as the table grows.

MerDurable

The layer between MerDB and storage media: local disks, network drives, cloud volumes and object stores. It checks the two facts the engine relies on: a medium can create a named file exactly once, and its durability barrier really reaches stable storage. A medium that cannot prove a fact is reported as weaker, never assumed to be stronger.

Bug it prevents: A database acknowledging a write as durable on a drive whose cache silently drops it at power loss.

MerFS

The filesystem a BenthOS device runs. Applications reach files only through scopes the device grants them, and a new file version gets its name only after its complete body and metadata validate. It is a separate engine from MerDB and shares no format or persistence machinery with it.

Bug it prevents: A device booting from a half-written configuration file after a power cut.

MerJob

MerJob is MerTek's durable job ledger: it keeps each scheduled or submitted job as rows in the store, so a job survives a restart and keeps one identity across retries. It holds no clock; every operation takes the time reading its caller passes in.

MerMount

The hosted feature that shows selected Store rows as read-only files on Windows, Linux or macOS. The host names each visible file and the row and column behind it, and a read returns those stored bytes unchanged. It is a projection, not a filesystem format or a storage engine.

Bug it prevents: A desktop tool editing a database row behind the store’s back through a writable file.

mertek launcher

The small program the site installer puts beside tricli, tri and wheelhouse. It fetches the signed release index and objects only when a person runs one of its commands, verifies every digest, and switches releases by moving one pin. No executable ever overwrites itself.

Bug it prevents: a half-applied update that leaves tri from one release and its manual from another.

MerTek.io

The MTK application at mertek.io for release discovery, manuals, examples, downloads, developer accounts and hosted development services. It routes a signed-in person to the applications their team may reach, and each application keeps its own data and permissions.

MerTekStak

The control plane for hosted MTK runtimes. It provisions runtimes, decides which application generation runs, and keeps the records behind each release. It is itself an MTK application with its own store.

MerTekTypes

MerTekTypes is MerTek's one table of every kind (data type), with its units, text rules and spellings. Chest, MerDB and Trident all read this one table, so a type means exactly the same thing in a file, a database and a program.

Bug it prevents: several copies of a type table drifting apart, which the previous generation had to police with a test.

Mesh

A triangle surface: positions plus optional normals, texture coordinates and colors, stored in meters in a right-handed, Y-up frame. A mesh family can carry up to five smaller levels for distant objects and small screens.

Metaprogramming and macros

Metaprogramming is code that writes or changes other code, often while compiling; a macro is a common form that expands into more code first. Trident has none: no macros, no compile-time code and no text splicing like C's #include, so the code you read is the code that runs.

Bug it prevents: a macro that expands into code nobody can see in the source, hiding where a bug lives.

metric history query

A typed request for one qualified collection, series, interval, resolution, and exactness choice, under row, byte, and cursor bounds. The constructor performs no Store read. Host later returns an available page or an unavailable result.

Bug it prevents: mistaking request construction for an immediate or authorized database read.

metric publisher

The complete record identifying the population that supplied a reading. The application example uses a shard field. Host separately supplies its actual runtime and call context; an application label grants no native identity or authority.

Bug it prevents: joining readings from unrelated producers because their display labels look alike.

metric reducer

A permitted way to combine readings, such as total, rate, maximum, or bucket counts. Each metric class has its own typed reducer set. A reducer works only with compatible types, populations, units, and time coverage.

Bug it prevents: combining values with a rule that does not match their metric class.

metric rollup

Retained sufficient statistics for a declared time window and tier. The record keeps covered time, gaps, consumed ranges, and needed evidence. Reading tiers merge integrals and durations; histogram tiers merge counts.

Bug it prevents: averaging averages or merging percentiles after the facts needed for a correct answer are lost.

Metric signature

The recipe that picks which geometric algebra you are in: how many basis directions square to +1, how many to -1, and how many to 0. euclid3 is (3,0,0), ordinary 3D space; projective3 is (3,0,1); conformal3 is (4,1,0). Trident puts it in the type, so two signatures never mix.

bivector<euclid3> xy = (0, 0, 1)
dvec3 v = xy   # refuses: a plane of rotation is not a direction
rotor<euclid3> r = (1, 0, 0, 0)   # refuses: that rotor ships as dquat
metric temporality

Whether a publication describes a cumulative total or one delta batch. The approved class word fixes this choice: histogram is cumulative and event is delta. There is no separate authored temporality property.

Bug it prevents: adding cumulative totals as if each were a fresh batch.

Migration

A migration is a step that moves stored data from an old shape to a new one, such as renaming a column. In Trident's design each migration step is one file checked when the program compiles, and the final schema must equal the declared one.

Module

A module is one file or unit of code with its own names, so a large program can be split into parts. A Trident module's id is its path under the application root, so a/geometry/units.tri is a.geometry.units, and other modules reach its names through that path.

Module closure

The set of authored Glint modules a scene carries, each keyed by its digest and stage. A material or text material names one entry by that key. An entry no declaration names refuses, so the scene holds exactly what it binds.

Modulus

The number you wrap around at in clock arithmetic: on a 12-hour clock the modulus is 12, so 9 + 5 lands on 2. Cryptography does this math with huge prime moduli. A fieldelem carries its modulus in its type, so numbers under two different moduli never mix.

money

An exact amount of one currency, with the currency in the type: money<USD>. The number of decimal places comes from the currency, and two currencies never add.

money<USD> price = 12.50
money<USD> total = price + 1.25   # 13.75, exact
money<EUR> other = 12.50
money<USD> sum = price + other   # refuses: two currencies
money<JPY> yen = 100   # the yen has no decimal places

Bug it prevents: adding dollars to euros because both were plain decimals with the currency kept in a separate field.

Motor

In projective geometric algebra, a motor is a rotor that turns and slides an object in one step, like a screw driven into wood. rotor<projective3> holds one in eight lanes, and two motors combine through the named call t.math.geometricAlgebra.motorCompose, never through @.

f64 tolerance = 0.000000001   # how far from length 1 a motor may drift
rotor<projective3> still = (1, 0, 0, 0, 0, 0, 0, 0)   # no motion
rotor<projective3> twice = t.math.geometricAlgebra.motorCompose(still, still, tolerance)
rotor<projective3> both = still @ still   # refuses: motors combine by a named call
MSL

Metal Shading Language, the shader text Apple's Metal compiles. Thalassa lowers checked Glint IR to MSL for the Metal backend.

MT9

The earlier MerTek generation. MTK keeps its product shape, its Trident language contract and its proven algorithms, and rebuilt the layers underneath. MTK reads no MT9 wire format.

Bug it prevents: MT9 kept four copies of its type table and needed a test to keep them aligned. MTK keeps one.

MTK

MerTek's application platform: a C runtime, the Trident language, and shared systems for data, rendering, assets, compute and host access. An application is a folder of Trident source and configuration that a host runs under a grant it builds at launch.

mTLS

Mutual TLS: both ends of a connection prove who they are, not only the server. MTK peers get that property from a signed handshake in which each side proves its Ed25519 key against the other's pin table. The TLS carrier adds encryption and per-frame integrity.

Bug it prevents: a server that trusts any client able to open a socket.

multivector

A multivector holds every piece geometric algebra has at once: a plain number, arrows, plane patches and more. In 3D that is 8 numbers. Its steps, such as the geometric product, are named calls in t.math.geometricAlgebra, never operators.

multivector<signature=euclid3> one = (1, 0, 0, 0, 0, 0, 0, 0)
multivector<signature=euclid3> square = t.math.geometricAlgebra.product(one, one)
bool same = square == one
multivector<signature=euclid3> sum = one + one   # refuses: use a named call

N

Named argument

A named argument is passed by its parameter's name instead of its position, like area(width: 3, height: 4) in some languages. Trident has none: arguments go in the order the signature lists them, and their count and types are checked when the program compiles.

Named type and semantic domain

A declaration such as type Email = text gives its base a distinct identity. The module path and name determine that identity unless an origin pin states it. Declarations work.

Example and current boundary.

Namespace

A namespace is a family of names kept apart from others, so two things can share a short name without clashing. In Trident each enum and each module is its own: two enums may both declare Ok, and Status.Ok and Health.Ok stay separate.

enum Status { Ok = 0, Failed = 1 }
enum Health { Ok = 0, Sick = 1 }
Status s = Status.Ok
Health h = Health.Ok
NaN (not a number)

The special floating point value that means "no answer", such as 0 divided by 0 or the square root of -1, and in most languages it quietly spreads through every later step. Trident never computes one: the operation faults instead. You can still write f64(nan) as a stored marker.

f64 zero = 0.0
f64 bad = zero / zero   # faults: no NaN is made
f64 marker = f64(nan)

Bug it prevents: the square root of a negative number quietly making a NaN that turns every later total into "nan".

Narrowing and widening

Widening moves a value into a bigger type, like i32 into i64; narrowing moves it into a smaller one, where it may not fit. Many languages do both silently on assignment. In Trident a destination never converts either way: the program writes i64(n) or i32(n), and a narrowing that loses the value faults.

i32 n = 5
i64 wide = i64(n)
i64 big = 9
i32 back = i32(big)
i32 narrow = big   # refuses: a destination never narrows
Nautilus

MTK's asset import boundary. It decodes supplier files once into MerTek-owned profiles, builds their smaller levels, and publishes them to a store. Renderers and programs read only those profiles, by name and within a byte budget.

Bug it prevents: a renderer that grows a new file parser every time a supplier sends a new format.

Newline ends a statement

A statement ends at the end of its line, or at the } that closes its block. There is no semicolon to type, and ; is refused, so two statements never share one line.

i32 width = 4
i32 height = 3
i32 area = width * height   # one statement per line
i32 depth = 2;   # refuses: no semicolon

Bug it prevents: a second statement hidden at the end of a long line, or C's stray ; after an if, which makes the next block run every time.

Newton and newton second

The newton is the SI unit of force, about the weight of a small apple; a kilonewton (kN) is 1000 newtons. A newton second measures impulse, a push kept up over time. The pound-force second is the US unit for the same thing and equals about 4.45 newton seconds.

f64<force> push = 2kN   # 2000 newtons

Bug it prevents: reading pound-force seconds as newton seconds, the mix-up that lost NASA's Mars Climate Orbiter in 1999.

Node declaration

The manifest each core node keeps beside its source: its areas, public and internal headers, exported symbol prefixes and allowed includes. The build checks the real tree and the built archives against it.

node view

A visual view of a Trident program in Wheelhouse, with functions, branches and calls drawn as connected nodes. An edit made there is a checked edit to the same source, so the node view and the script view always show one program.

Bug it prevents: A workflow diagram that says one thing while the deployed code does another.

Nominal typing

Nominal typing means two types are different because they have different names, even when they hold the same fields. Trident's enums are nominal: an enum's identity is minted from the module that declares it, so two enums never mix, even when their members match.

enum Status { Ok = 0, Failed = 1 }
enum Health { Ok = 0, Sick = 1 }
Status s = Status.Ok
Health h = Health.Ok
bool same = s == h   # refuses: two enum types never compare

Bug it prevents: comparing a status code to a health code and getting a silent true, because both were plain integers underneath.

nonfinite

A floating point value that is not an ordinary number: an infinity or a NaN. nonfinite is also the name of the fault Trident raises when one reaches arithmetic or a comparison, so a stored infinity or NaN can be kept and checked but never computed with.

f64 top = f64(infinity)
f64 more = top + 1.0   # faults: nonfinite
normal2, dnormal2

A normal2 is an arrow sticking straight out of a flat edge, like an arrow showing which side of a fence on a map is "outside". It can never be all zeros, and it uses an app's own frame. dnormal2 stores more digits.

Bug it prevents: a zero normal, which points nowhere and breaks every later test of which side something is on.

normal3, dnormal3

A normal is an arrow sticking straight out of a surface, like a pin pushed into a ball. It says which way the surface faces. It can never be all zeros, and its frame is part of its type. dnormal3 stores more digits.

normal3<frame=builtin:itrs> up = (0, 0, 1)
normal3<frame=builtin:itrs> flat = (0, 0, 0)   # refuses: a zero normal points nowhere

Bug it prevents: a zero normal, which points nowhere and turns lighting or bounce math into not-a-number garbage.

Nuclide

One exact kind of atomic nucleus, set by its number of protons and neutrons. Carbon-12 and carbon-14 are two nuclides of the same element: both have 6 protons, but one has 6 neutrons and the other 8.

Null

Null is a special value that means "no value here." Reading a null as if it were a real value is one of the most common crashes in programming. In Trident only a T? type may hold null, and a read is refused until a null test, such as if (x != null), proves the value is present.

Bug it prevents: a null pointer crash from reading a missing value as if it were there.

Number literal

A number written in code, like 42, 1.5, 0xff (base 16) or 1e3 (1 times 10 to the 3rd). It takes the type of the place it lands, so there are no width suffixes like C's L. A number too big for that type refuses.

i64 wide = 3000000000
i32 mask = 0xff   # 255
f32 narrow = 1.5
i8 small = 0xff   # refuses: 255 does not fit in i8

Bug it prevents: a forgotten suffix that silently cuts a number short, or a value too large for its type wrapping around.

Numerics declaration

The first line of a Glint module that states how exact its results must be. numerics reference; is the default and demands the exact answer; numerics bounded; with an accuracy row admits a stated error bound.

O

obb, dobb (oriented bounding box)

An oriented bounding box is a box that can be turned to any angle: a center, a turn (a quaternion), and half its size along each of its own edges. It hugs a tilted object more tightly than an axis-aligned box. dobb stores more digits.

text describe(obb<frame=builtin:itrs> crate) {
  quat tilt = crate.rotation
  vec3<family=length> halfSize = crate.halfExtents
  return t.text.of(halfSize)
}
obb2, dobb2

An obb2 is a flat box that can be turned to any angle: a center, a turn, and half its size along each of its own edges, like a tilted card on a table. dobb2 stores more digits.

Object key

The stable key a record holds to reach another stored value, such as an inspection row’s link to its photo. It is the id the store issued, never a memory pointer and never a hash of the contents. A row that references an unsaved value saves both in one commit, so the key always names something that exists.

ref photo? image = null

Bug it prevents: A record pointing at a photo by file path, which breaks when the photo moves or is rewritten.

observation declaration

A module declaration that names metrics from one supplied record. Its paths, types, units, reducers, and scopes are checked before execution. Reading, tally, histogram, balance, and delta metadata work.

observation orders(Publication supplied) { ... }

Bug it prevents: a metric that reads the wrong field type or changes its unit between readings.

observation histogram

A cumulative distribution with fixed bounds, exact bucket counts, a sum, and a generation. Count comes from the bucket sum. Bounds are checked at the sum's type and must project exactly to binary64. The application declaration compiles and verifies.

Bug it prevents: merging unrelated bucket layouts or publishing a count that disagrees with its buckets.

Observation subject

One thing a person inspects, such as the timer table, the clock, input devices or the jobs a run owns. Each subject's owner publishes one document for it, and every subject answers the same request: a name, a key and a window.

Observation token

An opaque value MerFS returns when a program looks up a name, recording which version, or which absence, it saw. A replace or retire must present it. If another writer changed the file in between, the call returns a conflict instead of overwriting.

Bug it prevents: A stale editor silently erasing a newer file because the last writer always wins.

observationPublications

The completed-call return array of source/document rows. Source selects one compiled observation declaration. Document supplies the actual record. Host admits or reports loss after the call; building this array alone emits nothing.

Bug it prevents: treating a local telemetry document as proof that a collector or durable Store received it.

OIDC

OpenID Connect, the sign-in protocol most company identity providers speak. MTK uses the authorization code flow with PKCE S256 and checks the exact issuer, audience and nonce. An ID token is never treated as an API access token.

Oklab and OkLCh

Color spaces published in 2020 and built so that equal steps in the numbers look like equal changes to the eye. OkLCh describes the same colors as lightness, chroma (how colorful) and hue (the angle around the color wheel), which helps when picking smooth gradients and palettes.

on configure

A handler in the entry file that runs at most once, before any store opens, and returns the settings the launch adds. A mistake there stops the launch cleanly instead of leaving a half-set-up program running.

Bug it prevents: a wrong setting read from an environment variable that only breaks at whichever line first uses it.

on endpoint

An endpoint declared as its own file, whose name gives its method and route, handled by on endpoint with typed path and query parts. It replaces on request.

on error

Sets up a handler for the statements after it in the same block. If one of them faults while running, the handler runs and can retry, resume or fail. Mistakes found before the program runs never reach a handler.

i32 zero = 0
text trail = "start"
on error (caught) {
    trail = "handled"
    resume
}
i32 lost = 1 / zero

Bug it prevents: a handler swallowing a mistake that should have stopped the program; only real run-time faults can be caught.

on event

Declares the handler for a named event that the system running the program (the host) delivers, such as "Damage", along with its payload's type. Each event name gets exactly one handler.

on event("Damage", const i32 amount) {
    i32 doubled = amount * 2
}
on event("Damage", const i32 hits) { }   # refuses: one handler per name

Bug it prevents: two handlers registered for one event, with the order they fire in left to chance.

on exit

Declares cleanup that runs exactly once whenever the block is left, by a normal return or by a fault. Several run newest first. Cleanup cannot return, so it can never change the answer.

text trail = "start"
on exit {
    trail = trail + "|exit"
    return "early"   # refuses: cleanup cannot change the answer
}
trail = trail + "|body"

Bug it prevents: Java's return inside finally, which silently throws away the real result or an error in flight.

on job

Declares the handler for a named background job. Each job runs as one call with set limits, on its own worker, sharing nothing with other jobs.

on job("sumSamples", const chest context, const chest input) {
    return input
}
text main(text[] argv) {
    return "ok"
}
on request

Declares a web endpoint and its handler in the language itself. The compiler checks the route, the method and each parameter's type, so the {id} in a path arrives already as a number. A duplicate or mistyped route refuses before the program runs.

on request({ method = "GET", pattern = "/items/{id}",
    parameters = [{ name = "id", source = "path",
        typeSpelling = "u64" }] }, const p) {
    u64 id = p.id
    chest out = {}
    out.id = id
    return out
}

Bug it prevents: a routing mistake, like two handlers for one path, that only shows up when a real request hits it in production.

on start

The launch's vote before the entry runs. A bare return accepts. A returned refusal document or an uncaught fault prevents the entry from running.

Launch sequence and example.

operator profile

An operator profile is a document, written by the person who runs a program (the operator), that lists which web servers and settings outbound HTTP may use. A script names a profile and its digest on the command line; it can never describe one itself.

Bug it prevents: code widening its own network access by editing a list of addresses it controls.

Operator spacing (whitespace law)

Trident reads spacing to tell what an operator is. A two-sided operator has a space on each side, as in 7 - 5, and a one-sided one is glued to its value, as in -x. That is how 5m/s stays one unit while a / b divides.

i32 d = 7 - 5
i32 neg = -d
i32 bad = 7-5   # refuses: write 7 - 5

Bug it prevents: code that a reader takes one way and the compiler another. A glued minus refuses and names the spaced form.

ORM

An ORM (object-relational mapper) is a library that lets code treat database rows as ordinary objects. Trident's typed database is its t.db linked library, and a trove declaration gives each row's columns a type.

outer assembly

An outer assembly (also called a composition root) is one finished program file that MerTek builds by linking a chosen set of its parts: tricli, tri, desktop, browser, xr, worker and render. All of them run the same Trident; they differ in which libraries and abilities they include.

outline

An open record type: the fields a value must carry, with extra fields allowed. A function taking an outline accepts any record that has those fields. Outline declarations, include rows, checks, and module-path reaches work.

Outward rounding

Rounding an interval's low end down and its high end up, so the range still contains the true answer after rounding. The interval may get a little wider, but it is never wrong. Trident works out that rounding from an exact remainder, without touching the processor's rounding mode.

Overflow

When an answer is too big for the space it has to fit in, like a car's odometer rolling from 999999 back to 000000. Many languages quietly wrap around to a wrong number. Trident faults instead, for whole numbers and floats alike; overflow is that fault's name, and an on error handler can catch it.

i32 big = 2147483647
i32 over = big + 1   # faults: overflow

Bug it prevents: a counter or a balance silently wrapping from the largest value to a negative one.

Overlay

A debug view drawn on top of a rendered scene, such as object bounds, a route input or a timing label. It reads published facts and changes nothing the program computes.

Overloading

Overloading lets several functions share one name and differ by their parameters, and the compiler picks one for each call. Trident has no overloading: a name is one function with one signature, and a call matches it or is refused when the program compiles.

i32 size(i32 n) { return n }
i32 size(i64 n) { return 1 }   # refuses: one name is one function
Ownership and borrowing

Ownership is Rust's memory rule: each value has one owner that frees it, and other code may only borrow it for a while, checked by the compiler. Trident does not use it: from a program's view every copy is its own value, and memory is reserved against declared limits instead.

Ownership guard

The check every control-plane write passes first: the application, the tenant and the expected generation it names must match what is stored. Any mismatch refuses with a named reason and writes nothing.

if (want.expectedGeneration != newest) { fail "stale generation" }

Bug it prevents: a slow edit overwriting a newer one it never saw.

P

P-256

A standard elliptic curve, a curve whose points can be "added" together, used to secure websites and passkeys. It comes with two huge numbers: the prime its coordinates are computed modulo, and the group order, the number of points on the curve. Math under one must never be mixed with the other.

Package manager and registry

A package manager downloads libraries other people published to a public registry and installs them into a project. A running Trident program has no package manager or registry to call. tripkg, still prelaunch, fetches a library and checks its exact bytes before a launch, never during one.

Parity check

A comparison of a backend's output with the Soft renderer's for the same program, declared before the run. Integer lanes match exactly; float storage states an absolute, relative or ULP rule; image channels state a maximum code-value delta.

Bug it prevents: loosening a tolerance after seeing a device miss it.

Parsing (lexer and parser)

Parsing reads text and works out its structure, the way you might diagram a sentence. A lexer first splits code into tokens, and then a parser builds the structure from them. Trident names the stage that refused a program (lex, parse or compile), and a parse refusal names what it found.

Partial application

Partial application calls a function with only some of its arguments and gets back a new function that waits for the rest, a habit of Haskell. Trident has no function values, so a call that leaves out an argument is refused when the program compiles.

Passkey

A WebAuthn credential held by a device or security key. Sign-in signs a single-use challenge bound to the site's origin, so a lookalike site gets nothing it can replay.

Pattern matching and destructuring

Pattern matching checks a value against a shape and, in the same step, pulls its parts out into names, which is called destructuring. Trident has a partial form: expect reads named fields from a document at declared types and binds them, or takes its else arm if any field is missing or mistyped.

chest doc = { text name = "Ada", i64 age = 36 }
expect { text name, i64 age } = doc else { return "missing" }
i64 next = age + 1
Pending record

A durable note of a write whose outcome is not known yet. Before a transaction leaves a runtime, the runtime mints its identity and keeps a sealed receipt. After a crash it asks the store to resolve that receipt. A missing decision stays unresolved and is never read as an abort.

Bug it prevents: Saving an inspection twice, or dropping it, because a crash hid whether the first save committed.

PHC string

A standard one-line text format, from the Password Hashing Competition, for a stored password check: the method (such as Argon2id), its cost settings, a random salt and the resulting hash. It never contains the password itself. Trident's pwhash kind is written this way.

phrase

Declares a translatable message. A call like welcome(user.name, unread) builds a value that carries the message and its inputs, so each reader sees it in their own language. A retired phrase keeps old values readable.

Physical constant

A fixed number of nature, like the speed of light. Some are exact by definition (the meter is defined so that light travels exactly 299,792,458 meters per second), while others are measured, carry an uncertainty, and are republished in new editions as labs improve.

Placement map

The host's record of where a deployment's runtimes run: which pools of machines, and how many runtimes in each. It lives in the host folder, which no program reads, so moving an application to more machines leaves its digest unchanged.

Bug it prevents: server addresses written into application source, so scaling out needs a new build.

plane, dplane

A plane is a flat surface that goes on forever, like an endless floor. It is stored as a normal (the way it faces) and an offset (how far it sits from the origin). dplane stores more digits.

text describe(plane<frame=builtin:itrs> floor) {
  normal3<frame=builtin:itrs> facing = floor.normal
  f32<family=length> distance = floor.offset
  return t.text.of(facing)
}
Planner

The part of the build that expands a requested target into the exact ordered set of gate leaves it reaches. It reads only the checked-in build graph, so a leaf runs the same command in a local run and a release run.

Point data

A set of points, each with its own position and optional normal and color, with nothing joining one point to another. A laser scan of a room is the usual example. It is its own profile, never a mesh with no triangles.

point2, dpoint2

A point2 is a spot on a flat surface, like a map or a game board, measured in an app's own frame. Every built-in frame is three-dimensional, so a flat point refuses them. As with point3, two points cannot be added. dpoint2 stores more digits.

# an app's own frame, written by its long ID
point2<frame=static:0000000000000000000000000000000000000000000000000000000000000001:1> spot = (1, -2.5)
point2<frame=builtin:itrs> lost = (1, -2.5)   # refuses: a flat point needs an app's own frame
point3, dpoint3

A point3 is a spot in 3D space, in meters from the origin of a named frame, and the frame is part of its type. Two points cannot be added, because "home + school" means nothing. dpoint3 stores more digits.

point3<frame=builtin:itrs> home = (1, 2, 3)
point3<frame=builtin:itrs> school = (4, 5, 6)
bool same = home == school
point3<frame=builtin:itrs> nonsense = home + school   # refuses: a point plus a point means nothing
point3<frame=builtin:icrs> sky = home   # refuses: a different frame

Bug it prevents: adding a point to a point, or using a camera-space point as a world-space point. Both refuse before the program runs.

Pointer

A pointer is a value that holds the memory address of other data, like a note saying which locker to open. Pointers are fast but risky, because they can point at freed or wrong memory. Trident has no pointer type at all, so a program never holds a raw address.

pose, dpose

A pose is where something is and which way it faces: a move (in meters) plus a turn (a quaternion). Its type names two frames, from and to. dpose stores more digits.

pose<from=builtin:itrs,to=builtin:icrs> arm = (1, 0, 0, 0, 0, 0, 1)
vec3<family=length> offset = arm.translation
quat facing = arm.rotation
pose<from=builtin:itrs,to=builtin:icrs> broken = (1, 0, 0, 0, 0, 0, 0)   # refuses: an all-zero turn faces nowhere

Bug it prevents: a pose whose turn is all zeros, which faces no direction at all and turns every later calculation into garbage.

PostgreSQL

The relational database Alba applications store their records in. Wayland writes its table and function scripts from the shared definitions.

Precondition and postcondition

A precondition is what a function requires to be true when it is called; a postcondition is what it promises about its result. Trident writes them as require and ensure clauses on the signature. They always run, and a broken one is a catchable fault naming the clause and the function.

Bug it prevents: a function quietly returning a wrong answer for an input it was never meant to take.

prelaunch

Before MerTek's first public release. In this period the language's rules can change, because no outside program depends on them.

private

Keeps a function, constant, enum, flagset, almanac, trove, outline, ingot or named type inside the file that declares it. Other files cannot reach it, and the runner cannot call a private function.

private const i32 limit = 3
private i32 helper() {
    return limit
}
private alias m = t.math   # refuses: private has no place on an alias
i32 got = helper()

Bug it prevents: another file starting to depend on a helper that was meant to stay internal.

Product rule and chain rule

Two rules of calculus: the product rule gives the rate of change of two changing things multiplied together, and the chain rule gives it for one function inside another, like the area of a circle whose radius is growing. Forward-mode arithmetic applies both at every step.

program bundle

A program bundle is the exact, ordered list of source files a host compiles into one program. Each row holds a module id, the source text and its SHA-256 fingerprint. Names are looked up only inside the bundle, so there is no search path.

Bug it prevents: a program picking up a stray file that happens to have the right name in some folder on a search path.

Program root

One of the folders that holds an application's code. a/ holds code every build shares, s/ the server build and c/ the client build. The root a unit sits under decides which builds compile it.

a/audience.tri    every build
s/holds.tri       server build only
c/scan.tri        client build only
programReplace, childSpawn

Rows a session program can return to ask its host for a change. programReplace asks the host to compile named source and replace the program between calls; childSpawn asks it to start a separate, narrower child runtime. The host acts only after the call returns, so a program never swaps its own code.

Projective and conformal geometric algebra

Two larger geometric algebras for 3D. The projective one, signature (3,0,1), adds a direction that squares to zero, so one rotor can turn and slide at once; the conformal one, (4,1,0), adds two more, so spheres and circles become elements too. Robotics and graphics use both.

Proleptic Gregorian calendar

Our everyday calendar, the Gregorian one adopted in 1582, used for dates before it existed, as if it had always been in force. Every past date then gets one clear label, without switching to older calendar rules.

civildate old = 1000-03-01   # before 1582, by today's rules
Proof host

A machine that runs the release plan natively for one target, such as Windows on x86-64 or macOS on ARM. A Windows run proves Windows; it never stands in for Linux or macOS.

Bug it prevents: shipping a Linux build whose tests only ever ran on a Windows laptop.

Protection floor

The lowest label every row of a trove carries. A row's protectionBy column may raise it, and a property may raise it again. The effective label is the join, so no property goes below its floor.

Bug it prevents: a new field added to a sensitive table that silently defaults to public.

Provenance

The record of where release bytes came from: the source commit, the compiler and flags, the proof host, the gate receipts and the bless. A reader can reopen each referenced artifact and rehash it.

Bug it prevents: an executable on a kiosk that nobody can tie to a commit.

Provider and custodian

A provider is the host-side service behind a library, such as the file system, the network or a key store. A custodian is the provider that holds key bytes. The program names a credential, spends one use and gets back a signature, a ciphertext or a yes or no.

Bug it prevents: a private key copied into application memory, where a log line or a crash dump can carry it away.

provider grant

A provider is a service the host plugs in, such as a clock, a log, a job runner or a key store. A provider grant admits one by name. t.clock, t.log, t.job and t.security.crypto each need one, so a program reads the time or a key only when the host chose to provide it.

Push guard

A pre-push hook that refuses a push while a rebase, merge, cherry-pick or revert is still in progress in that worktree. It refuses the operation, never the content.

Bug it prevents: a chained rebase and push that lands eight of nine commits from a half-finished rebase.

pwhash

A stored password check (an Argon2id hash): the settings, random salt and hash that a login attempt is tested against. It cannot be compared with ==, sorted or turned into text; checking a password is a named library call. Its literal stays quoted, because the stored text opens with $, which starts no token, and only the hashing call ever writes one.

bool same(pwhash left, pwhash right) { return left == right }   # refuses: never compared with ==
text show(pwhash stored) { return text(stored) }   # refuses: never turned into text
bool missing(pwhash? stored) { return stored == null }

Bug it prevents: a password hash written to a log, or checked with a plain == that can never match a fresh hash.

Q

quantity

A physical amount with its unit, whose type also names how the number is stored, such as quantity<amount=f64>. Sums check that the dimensions match, and products build new ones: meters times meters is square meters.

quantity<amount=f64> d = 2.5m:length
quantity<amount=f64> area = d * d   # square meters
quantity<amount=f32> small = 2.5m:length
quantity<amount=f64> bad = d + small   # refuses: two number formats

Bug it prevents: adding a 32-bit amount to a 64-bit one and silently rounding one of them.

quat, dquat (quaternion)

A quaternion: four numbers (x, y, z, w) that together describe one turn in 3D space. The @ operator chains two turns, and a quat @ a vec3 turns the vector. dquat is the twin that stores more digits; it chains turns with @, and turning a dvec3 is a named call.

quat quarterTurn = (0, 0, 0.7071068, 0.7071068)   # 90 degrees around z
vec3 east = (1, 0, 0)
vec3 north = quarterTurn @ east
quat halfTurn = quarterTurn @ quarterTurn
quat wrong = quarterTurn * quarterTurn   # refuses: four lanes are one turn

Bug it prevents: a quaternion multiplied lane by lane. Most vector libraries run it, and the result is a turn that is slightly wrong and drifts over time.

R

Radian

A way to measure angles using the circle's own radius: a full turn is 2π radians (about 6.28), so a right angle is π/2. Math functions like sine and cosine expect radians, which is why mixing them up with degrees is a classic mistake.

measure quarter = 90deg:angle
measure turn = t.measure.to(quarter, "rad")   # exactly pi/2

Bug it prevents: passing 90, meant as degrees, to a function that reads it as 90 radians, more than 14 full turns.

Rank (of a tensor)

How many indexes it takes to find one number in a tensor. A single number is rank zero, a list is rank one, a table (a matrix) is rank two, and a stack of tables is rank three.

rational

An exact fraction such as 1//3, always kept in lowest terms. Use it when a fraction must stay exact, as in musical timing or a recipe scaled by thirds.

rational third = 1//3
rational half = 1//2
rational sum = third + half   # 5//6, exact
rational same = rational(2//4)   # stored as 1//2
rational zero = 2//0   # refuses: zero denominator

Bug it prevents: 1/10 + 2/10 coming out as 0.30000000000000004 instead of exactly 3/10.

ray, dray

A ray is a starting point plus a direction, going on forever one way, like a laser beam. Games use rays to ask "what does this line of sight hit?" Its direction cannot be zero. dray stores more digits.

text describe(ray<frame=builtin:itrs> beam) {
  point3<frame=builtin:itrs> start = beam.origin
  dir3<frame=builtin:itrs> aim = beam.direction
  return t.text.of(aim)
}

Bug it prevents: a ray with a zero direction, which points nowhere and makes every hit test answer nonsense.

ray2, dray2

A ray2 is a flat ray: a starting point plus a direction, going on forever one way across a flat surface, like a flashlight beam on a map. It uses an app's own frame. dray2 stores more digits.

reach

The libraries, store slots and services a program can call, derived by the compiler from its source, dead branches included. A launch compares the reach with the grant and stops if the grant does not cover it. tricli --reach prints the reach and runs nothing.

Bug it prevents: A rarely used code path that calls the network and is discovered only in production.

reading metric

A value at one moment. No generation field. A new reading replaces the current value. The canonical declaration and reducer domain compile.

Bug it prevents: using a reducer or restart rule from a different metric class.

Rec. 2020, Rec. 2100, scRGB, ACEScg and CMYK

More color spaces: Rec. 2020 and Rec. 2100 are the standards for ultra-HD and high dynamic range (HDR) television, with far more colors than sRGB, and scRGB stretches sRGB past its usual 0 to 1 range. ACEScg is the film industry's working space for rendering. CMYK describes printing ink: cyan, magenta, yellow and black.

rect, drect

A rect is a flat rectangle lined up with the x and y directions, stored as its lowest corner and its highest corner, like a window on a screen. drect stores more digits.

Redis

An in-memory store Alba uses as a cache shared by every server instance, so a value computed on one instance is visible to the others.

Reef

Thalassa's render program: the passes a scene needs, the resources each pass reads and writes, and the order they run in. The scene compiler derives it from the scene. Reef verifies the graph, schedules it and runs it on the selected backend, and it owns every GPU resource.

Bug it prevents: two passes racing on one texture because nothing declared which one writes first.

Reference counting

Reference counting frees memory by counting how many places use each value and freeing it when the count reaches zero; a cycle collector cleans up values that only point at each other. A Trident program never sees a count, though inside the runtime a shared block of bytes stays charged until its last holder lets go.

Reflection

Reflection lets a program look at its own structure while it runs: list a type's fields, find a function by its name, or inspect the runtime's state. Trident has no reflection over the runner's own state, and a program's whole call graph is fixed before its first line runs.

refusal

A refusal is Trident saying no to a program, with a message that points at the exact spot and, when it can, the exact edit that fixes it. Most refusals happen at compile, before anything runs; others stop a launch before main, or arrive as faults while the program runs.

text digits = "12"
i32 bad = digits   # refuses: the message names i32(digits)
i32 n = i32(digits)

Bug it prevents: an error you have to look up or decode. This one names the line to write, i32(digits), instead of an error code.

Region (Cutlass)

Cutlass's one allocator: a chain of fixed-size memory chunks that is released all at once. Every function body and every loop pass is a region, and region (bytes = 64KiB) { ... } adds one with an explicit bound. Nothing is freed one value at a time.

Bug it prevents: use-after-free, double free, and the slow leak of a value nobody remembered to free.

Release build and debug build

Many languages build a program two ways: a debug build with extra checks for testing, and a release build that drops checks to run faster, so the program you ship is not the one you tested. Trident's checks are the same in every build: contract clauses always run, and overflow always faults.

i32 x = 3
assert (x == 3, "x_is_three")
assert (x == 4, "x_is_four")   # faults: an assert runs in every build

Bug it prevents: code that stopped on overflow in testing and silently wrapped in the shipped release.

Release decision

An approved lowering of protection for one exact artifact, one destination and one policy generation. Changing the content, the receiver or the policy voids the approval, and a receipt cannot be reused for another payload.

Bug it prevents: an approval for one public report later covering a different, edited report.

Release record

The manifest that names one release: its version, source commit and required targets. For each target it names the proof host, the executable digests and the gate and bless receipts. It is published last, after every object it names reads back.

repeat

Runs a block a set number of times, like repeat (3). An optional counter, repeat (5, i32 i = 0), can be read but never changed. Every loop states its limit before it starts; a search that may stop early uses a bound and break.

i32 seen = 0
repeat (3) { seen++ }
repeat (5, i32 i = 0) {
    seen += i
}
repeat (3, i = 0) { seen++ }   # refuses: the counter states its type

Bug it prevents: a loop that never ends because its condition never turns false.

REPL

A REPL (read-eval-print loop) is an interactive prompt where you type a line of code and see its result at once. tricli has one, but the host itself compiles and installs each line, never a call the program can reach, so even the REPL cannot make a program run another program.

replay

Running a program again against a tape. Every outside read is answered from the recording, and each result is compared with what happened the first time. A program reads nothing a tape cannot record, so a replay reproduces the run exactly.

Bug it prevents: a failure that happened once at a customer site and never again at a developer's desk.

require, ensure, result

Promises written on a function's signature. require checks the arguments when a call starts; ensure checks the answer, named result, at each return. A broken promise raises a fault naming the clause, and the checks always run, release builds included.

i32 halve(i32 n) require (
        n > 0, "positive") ensure (
        result <= n, "no larger") {
    return n / 2
}
i32 four = halve(8)
# halve(-2) faults: require 'positive' failed in halve

Bug it prevents: a safety check that silently disappears in a release build, as assert does in C, Java and Python.

Resampling

Making new samples of a field at different places than the old ones, by estimating values in between the known samples, like resizing a photo.

Reserved words

Words the language keeps for itself, like if, return and null, so no variable can use them as a name. Future keywords are a second list, such as fork and while, kept for features that plan rows own or for other languages' habits.

i32 count = 1
i32 if = 1   # refuses: a reserved word is not a name
i32 fork = 1   # refuses: a future keyword is not a name

Bug it prevents: a variable named after a word that a new feature turns into a keyword, which breaks the program.

Resource binding

A shader's declared input or output from Thalassa: a uniform, texture, storage buffer or storage image, with a type and an explicit slot. Thalassa owns the memory behind the slot; the shader only names it.

Bug it prevents: two shaders that disagree about which slot holds the tint.

Resource limits

A limit bounds memory, input capacity, or time. Trident has no deterministic work budget or work price. CPU quotas belong to the operating system.

resume

Used inside an on error handler: carries on with the statement after the one that faulted, so a handler can repair things and continue instead of giving up the whole block.

i32 zero = 0
text trail = "start"
on error (caught) {
    resume
}
i32 lost = 1 / zero
trail = "carried on"
resume   # refuses: only a handler can resume
retired

A retired enum, flagset, or almanac member remains readable in supported predicates and stored values, but new code cannot construct it.

enum Plan { Free = 0, retired Trial = 1, Paid = 2 }
Plan p = Plan.Paid
bool wasTrial = p == Plan.Trial
Plan q = Plan.Trial   # refuses: a retired member is never chosen

Bug it prevents: deleting an option and breaking every stored record that still holds it, or new code quietly writing an option that is being phased out.

retry

Used inside an on error handler: runs the protected statements again from the start, for example to give a flaky step a few more tries.

i32 tries = 0
i32 zero = 0
on error (caught) {
    if (tries < 3) { retry }
    resume
}
tries++
i32 lost = 1 / zero   # the handler retries until tries is 3

Bug it prevents: retry logic hidden in a while (true) loop around a try, where a reader has to guess the intent.

return

Ends a function and hands back its result. A function that declares a result must return one, and a void function must not return a value.

i32 twice(i32 n) {
    return n * 2
}
void note(i32 n) {
    return n   # refuses: a void function returns nothing
}
i32 four = twice(2)

Bug it prevents: a function that runs off its end and hands back garbage. In Trident that faults instead.

Rig

The skeleton that moves a mesh: joints, their parent links, rest poses and inverse bind matrices. A skinned glTF primitive imports as one rigClip document that carries the rig, its blend shapes and its animation clips together.

Rigid motion

Moving an object without bending or stretching it: a turn plus a slide. Every distance and angle inside the object stays the same, the way a chair stays a chair as you carry it across a room. Trident's rigid carriers (pose, twist and wrench) describe such a motion, its speed and the push behind it.

Role

A role is a named set of grants. It is not a rank: an administrator role grants exactly the permissions it lists and carries no clearance, release authority or classification power.

Bug it prevents: treating "admin" as a key to every door, including payroll fields and classified records.

Rollback point

A retained, complete earlier state the system returns to in one step: the previous application generation, or the previous runtime generation on a node. Rollback selects it; it never rebuilds it.

Bug it prevents: a rollback that has to rebuild yesterday's release and comes out different.

rotor

A rotor is geometric algebra's way to write a turn, or a turn plus a slide (called a motor). Its signature, in the type, names which kind of space it lives in. In plain 3D space a rotor is exactly a quaternion, so that spelling refuses and you use dquat.

rotor<signature=projective3> still = (1, 0, 0, 0, 0, 0, 0, 0)
rotor<signature=projective3> both = t.math.geometricAlgebra.motorCompose(still, still, 0.000000001)
rotor<signature=euclid3> plain = (1, 0, 0, 0)   # refuses: in plain 3D, use dquat

Bug it prevents: combining a turn from one kind of space with a value from another. The signature is part of the type, so the mix refuses.

Round half to even

A rule for ties: when a value sits exactly halfway between two choices, pick the even one, so 2.5 rounds to 2 and 3.5 rounds to 4. Ties go up half the time and down half the time, so long sums do not drift. In Trident, nearestEven is a snap policy a number type can state.

i32<multiple=4,snap=nearestEven> step = 0
i32 x = 10
step = x   # 10 is 2.5 steps of 4, so it lands on 8
assert (step == 8, "the tie went to the even step")
Rounding

Rounding replaces a number with a nearby one that fits, like 2/3 becoming 0.67. Done silently, small rounding errors can pile up into big ones. Trident never rounds inside an assignment: f32(x) is exact or faults, and a program that wants rounding names it with t.math.castRounding.

f64 wide = 0.1
f32 near = t.math.castRounding(wide, "f32")
f32 quiet = wide   # refuses: a rounding is never silent
f32 strict = f32(wide)   # faults: 0.1 has no exact f32 value

Bug it prevents: a rounded tenth of a second that adds up over a hundred hours, as in the 1991 Patriot missile failure.

Rounding mode

The rule for which nearby number to keep when an exact answer does not fit: the nearest one, or always toward zero, up or down. Many languages keep one hidden setting on the processor that every calculation reads. Trident has no such hidden setting; a call that rounds says how.

Bug it prevents: an interval library flipping the processor's rounding setting and silently changing unrelated math on the same thread.

Routing

Routing decides which code answers a web request, based on its path and method, like a mail sorter. Most languages leave it to a framework that finds a mistake only when a request arrives. Trident checks its on request declarations when the program compiles, so a duplicate route or a wrong parameter type is refused.

Bug it prevents: two handlers claiming the same route, found only when a real request hits it in production.

rune

One Unicode scalar: a single character code, written like U+0041 for "A". Runes have an order but no math, because a character plus one is not always a character.

rune first = U+0041
rune second = U+0042
bool before = first < second
rune next = rune(u32(first) + 1)   # the step is written out
rune bad = first + 1   # refuses: a character is not a number

Bug it prevents: stepping a character into a code that is not a real character, which breaks the text around it.

Rune

MerTek’s typed binary document format. A Rune document carries each field’s name and complete type beside its value, so any reader can check what it holds. Trident holds one as a chest value, and the same bytes sit in memory, in MerDB and inside network frames.

buffer bytes = t.chest.encode(update)
chest again = t.chest.decode(bytes)

Bug it prevents: A receiver guessing what untyped bytes mean, such as reading a torque value as a bin number.

Rung

One declared step of a quality ladder, such as a mesh level or a 1.5x upscale ratio. A device limit can move a scene down to a rung its author declared. A rung may reduce samples, resolution or detail; it never changes units, color space or what an object means.

config = t.recon.declareRatio(config, "1.5x")
i32 level = t.media.targetMeshLevel(396.0, 484.0,
    [1600.0, 1000.0, 600.0, 0.0], [0, 1, 2, 3])

Bug it prevents: a small device quietly dropping the warning color to save memory.

runtime

The runtime is the engine inside a host that holds one installed Trident program and runs its calls, counting every byte and step against the host's limits. More loosely, "at runtime" means while a program is running, as opposed to when it is compiled.

runtime prelude

The fixed sequence a launch runs before main: resolve, compile, grant, configure, open stores, recover jobs, reconcile troves, apply seed rows, build assets, then deliver on start. main runs only when every step succeeds; a failed step is a false start that names it.

Bug it prevents: A program starting against a store that did not open or a schema that no longer matches its code.

S

s/

The folder for server-only code in an application that has a server and a client. Code under s/ builds only into the server. The client reaches it only with send, which the compiler checks against the server's handle by name and type.

Bug it prevents: server-only code or secrets shipping inside the app that customers or players download.

Sandbox

The set of folders, network paths, child programs and devices a workload's grant declares, and nothing else. Process separation is one layer of it; each stronger containment names its platform mechanism.

Saturation

Handling a too-big answer by stopping at the largest value that fits, like a speedometer needle pinned at the top, instead of wrapping around. Trident never saturates on its own. When clamping is what you want, t.math.castSaturating says so out loud.

i64 big = 5000000000
i32 top = t.math.castSaturating(big, "i32")   # 2147483647
i32 fits = i32(big)   # faults: it does not fit
SBOM

Software bill of materials: the list of third-party components inside a release, with each one's version, origin, license, digest and how it is linked. MTK keeps it in the release record, beside the executables it describes.

Bug it prevents: a library advisory that nobody can match to the builds already in the field.

Scalar

In math, a scalar is a single plain number, as opposed to a vector or a matrix. A scalar factor scales every part of a value by the same amount, like doubling every ingredient in a recipe.

Scene tick and timer folds

Declared handlers that receive retained state and return its next value. The scene pump passes each successful result to the next step. A fault keeps the previous state. Monotonic and session timers use on event.

Handler examples.

Schema

A schema describes the shape of some data: which fields it has and the type of each. A Trident chest carries its schema in its own bytes, and a trove declares its columns, so a misspelled column is refused when the program compiles.

Schema fingerprint

A SHA-256 over a document’s schema section and its schema version. Equal shapes give equal fingerprints whatever the values; adding, removing or retyping a field changes it.

chest facts = t.chest.digests(t.chest.encode(doc))
sha256? shape = facts.schemaDigest

Bug it prevents: Accepting a message because its name matched, when one of its fields had changed type.

Schema identity

What makes two Rune documents the same shape: their field names and each field’s complete type, including units, nullability and array shape. Values play no part, and neither does the order a program added the fields in.

Bug it prevents: Treating f64<family=angle,unit=rad> and f64<family=dose,unit=rad> as one field because both are 64-bit floats.

Scope

A name's scope is the part of the program where it can be used, usually the block or file it was declared in. In Trident a name resolves only inside the unit that wrote it, a block's local ends with its block, and a scope's memory reservation is refunded when the scope ends.

script mode

Script mode runs one.tri file: tricli main.tri compiles exactly that file as module a.main and calls main(text[] argv). The person who writes it is the person who runs it, so most local libraries are granted, but the network and saved credentials stay off unless the command line names them.

Bug it prevents: a downloaded script reaching the internet only because you ran it. Network access needs an explicit --http profile and its digest.

script view

The text view of a Trident program: the .tri source itself. It is the program's record. The node view is drawn from it and writes back to it through the same checks.

Sealed document

A Rune document whose header carries SHA-256 digests of its schema and value sections. Every read recomputes both before it looks at a field. Documents get sealed where they cross a boundary, such as a save or a send, and values passed around inside a program skip the hashing.

Bug it prevents: A bit flipped on disk or in transit reaching application code as a plausible value.

Sealing

Encrypting bytes under a key handle into an opaque ciphertext. open authenticates the whole value before it returns a secret buffer, and a column's ciphertext cannot be opened through this path.

Bug it prevents: choosing a nonce by hand and reusing it under the same key.

Search path and resolver

A search path is a list of folders a language looks through to find a module by name, and a resolver (or solver) picks which version of each library to use. Both decide at the last moment what code you get. A running Trident program has neither: the runtime never opens a source file.

secret

Marks a value, like a password or a key, that must never reach an ordinary output, such as a log or a plain variable. Anything computed from a secret is secret too.

private i32 digits(secret text pin) {
    secret text kept = pin
    text shown = pin   # refuses: a secret reaches a plain local
    return 4
}

Bug it prevents: a password copied into an ordinary string and then printed, logged or sent back by mistake.

Security domain

A declaration of ordered levels and independent compartments, written once per application. Labels, dominance and joins all refer to it, and two deployments never compare labels by spelling alone.

security organization {
    levels = public < internal < confidential < restricted
    compartments = finance | legal
}
segment2, dsegment2

A segment2 is a straight piece of line on a flat surface, from a start point to an end point, like a wall on a floor plan. It uses an app's own frame. dsegment2 stores more digits.

segment3, dsegment3

A segment3 is a straight piece of line in 3D, from a start point to an end point, like a stick. dsegment3 stores more digits.

text describe(segment3<frame=builtin:itrs> stick) {
  point3<frame=builtin:itrs> first = stick.start
  point3<frame=builtin:itrs> last = stick.end
  return t.text.of(first)
}
send, handle

In an app with a client and a server, send calls a server handle by name, and the compiler matches the two, so a mismatched or dead call refuses before the program runs. retract takes back a row that clients have cached.

sensitive

Marks private data, like a session token, that code may still use and compare but must never write to a log. Values computed from it stay sensitive. It is one level below secret.

sensitive text token = "session-token"
bool same = token == "session-token"
sensitive text label = `token={token}`
t.log.info(label)   # refuses: a sensitive value never reaches a log

Bug it prevents: a user's token or personal details ending up in log files that many people can read.

Serialization

Serialization turns a value into bytes that can be saved or sent, and deserialization turns the bytes back. Usually a separate library does it, and the bytes carry no checked types. A Trident chest is already a typed, self-describing document, so it keeps its types after it leaves the program.

Service view

The debug view for a program with no scene, such as a headless service. It shows the same typed facts an overlay would, as panels for queues, timers, jobs and the last commit.

session

A session is a long-running host loop, as in tri or the desktop host, that keeps one runtime open and keeps delivering events, input and frames to the program. A one-shot run, by contrast, calls main once and exits.

sha256

A SHA-256 digest: a 32-byte fingerprint of some bytes, written as 64 hexadecimal digits. Use it to check that a file or message has not changed. Its literal stays quoted, because 64 digits with no separator would read as a name or a numeral.

buffer data = 0x616263
sha256 digest = t.buffer.sha256(data)
sha256 known = "BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD"
bool same = digest == known   # true: case does not matter
bool first = digest < known   # refuses: a digest has no order

Bug it prevents: comparing a digest written in uppercase letters with the same one in lowercase and calling them different.

Shader

A shader is a small program that runs on a graphics card to draw pixels, shapes and light. Thalassa's shader language is Glint, which has its own companion comparison page.

Shadowing

Shadowing happens when a new name hides an older one with the same spelling, so the older one cannot be reached there. In Trident two enums may both declare Ok and neither shadows the other, because each member is reached through its own enum: by its enum's name, or bare where the spot already expects that enum.

Shared mutable data

Shared mutable data is one piece of data that several parts of a program can reach and change, so a change made through one name shows up through another. Trident has none: every copy is a value, so changing one copy never changes another.

i32[] mine = [1, 2]
i32[] yours = mine
yours.add(3)
assert (mine.count() == 2, "mine_kept_its_own_copy")

Bug it prevents: a function that changes a list it was handed, quietly changing the caller's list too.

shared systems

The C components every MTK application runs on. MerDB keeps records, Rune encodes them, Thalassa renders, Nautilus imports assets, Keel does the math and the host reaches the operating system. They hold mechanisms and take every threshold and decision from Trident source.

Bug it prevents: A business rule buried in renderer or database code, where no reviewer of the application can see it.

SI (International System of Units)

The world's shared measuring system. Its seven base units are the meter, kilogram, second, ampere, kelvin, mole and candela, and every other unit, like the newton or the watt, is built from them. Each base unit is fixed exactly by a constant of nature.

Sigil folder

A folder whose name starts with _, such as _db/, _app/ or _test/. It holds facts about how a program is built and run, and every sigil name is a registered row, so a misspelled one refuses.

Bug it prevents: a misspelled _asets/ folder that silently imports nothing.

Signed and unsigned integers

A signed integer can be negative; an unsigned one cannot, so it reaches higher with the same bits, like u8 holding 0 to 255. Mixing the two is a classic trap. In Trident i32 and u32 meet at i64 inside an operator, and a mix no width can hold is refused.

i32 debt = -3
u32 stock = 4
i64 net = debt + stock
u128 huge = 5
i64 bad = debt + huge   # refuses: no width holds both

Bug it prevents: C finding -1 bigger than an unsigned 1, because -1 was silently read as 4294967295.

Signed release index

The list of editions for each product line, with each release's version, manifest digest and publication order, signed by the publisher. A client trusts the signature and the digests, not the connection it downloaded them over, and refuses an older index than one it has already accepted.

Signed zero

Floating point numbers keep a plus or minus sign even on zero, so +0.0 and -0.0 are two values. Usually you cannot tell them apart, but for a complex number the sign says which side of a branch cut it sits on, so a square root or a logarithm answers differently.

complex128 n = -4.0i   # (-0.0, -4.0)
complex128 s = 0.0 - 4.0i   # (+0.0, -4.0)
bool same = n == s   # false: the zeros have different signs
slab

Declares state the system keeps from one game tick to the next as fixed-size rows, such as game units or terrain cells, and says how much of it a client may see.

Smith's algorithm

A careful way to divide complex numbers, published by Robert Smith in 1962. It divides by the larger part of the divisor first, so the in-between numbers do not overflow or lose digits when one part is huge or tiny. Trident's complex division uses it.

Soft renderer

Thalassa's CPU renderer, built into every MTK binary. It runs checked Glint IR with fixed evaluation order and no driver math. Its image is the reference every GPU backend is compared against. It also renders on a machine with no graphics card or display.

Bug it prevents: calling a GPU result correct because it looks right on the one card the team owns.

source generation

One published version of an application's source. An edit names the generation it was prepared against and refuses if the source moved since then, so two editors cannot overwrite each other's change.

Bug it prevents: Two people saving over each other, or a tablet and a service running different versions of one rule.

Source test

An ordinary Trident program under an application's _test/ folder. It runs in place of a/main.tri, and each named data case is one call to its main, which passes only by returning true. Release packages never ship test folders.

bool main() {
    assert (a.queue.unsent(42, [41, 42, 43]).count() == 1, "one unsent")
    return true
}
sphere, dsphere

A sphere is a ball: a center point and a radius in meters, which is never negative. dsphere stores more digits.

text describe(sphere<frame=builtin:itrs> ball) {
  point3<frame=builtin:itrs> middle = ball.center
  f32<family=length> size = ball.radius
  return t.text.of(size)
}
SPIR-V

The binary shader format Vulkan devices load. Thalassa lowers checked Glint IR straight to SPIR-V words, with no text step in between.

sRGB

The standard color space of the web and most screens since 1996. Its numbers are not proportional to light: they follow a curve, its transfer function, because eyes notice changes in dark shades more than in bright ones.

Staged rollout

A runtime or driver update that reaches a pilot group first, then widens in recorded waves: prepared, staged, serving, then expanded or rolled back. Each transition is a durable record, so a paused wave shows exactly which nodes run what.

Bug it prevents: a driver fix pushed to every node at once, taking the whole floor down when it fails.

Standard library

A standard library is the set of ready-made tools that ships with a language, like text, math and file functions. Trident's are its t.* linked libraries, part of the language's own catalog rather than installed packages, and a program can call one only when the host allows it.

Standard uncertainty

How far a measured value might be off, given as one typical spread (one standard deviation). A rod measured as 1.5 m with a standard uncertainty of 0.25 m is likely within about 0.25 m of 1.5. A Trident measurement carries it beside the estimate, and it can never be negative.

measurement rod = (1.5, 0.25, 9)   # estimate, uncertainty, degrees of freedom
measurement bad = (1.5, -0.25, 9)   # refuses: an uncertainty is never negative

Bug it prevents: a negative uncertainty being accepted and then squared into a variance that looks valid.

state3, dstate3

A state3 is a snapshot of something moving: a moment in time, where it is, and how fast it moves at that moment. Its type names the frame and the time scale (such as tt, one astronomers use). Satellites are tracked this way. It is written as a nested tuple. dstate3 stores more digits.

state3<frame=builtin:gcrs,domain=tt> satellite = (1700000000, (7000000, 0, 0), (0, 7500, 0))

Bug it prevents: pairing a position from one moment with a speed from another, because the time stamp travels inside the value.

Static initialization order

In C++, constants in different files can run setup code before main, in an order the language never defines, so one constant may read another that is still zero. Trident's module constants must be literals, so no code runs before main at all.

const i32 base = 10
const i32 doubled = base * 2   # refuses: a module constant is a literal
Static typing

A statically typed language checks every value's type before the program runs, so putting text where a number belongs is caught early; the tool that checks is a type checker. Trident is statically typed all the way: every binding states its type, and a mismatch is refused when the program compiles.

text digits = "12"
i32 count = i32(digits)
i32 wrong = digits   # refuses: text never becomes an i32 by assignment

Bug it prevents: the text "12" plus 1 printing 121, as JavaScript does.

Stop-the-world pause

A stop-the-world pause is when a garbage collector freezes the whole program for a moment to clean up memory, which can make games stutter and servers lag. Trident has none: nothing ever collects, because memory is reserved and refunded on a budget instead.

stop, on stop

stop asks the system running the program to end it once the current call returns; the rest of that call, and its cleanup, still finish. An on stop handler sees every exit, and its cause shows when the program asked to stop.

void closeLaunch() {
    stop
}
closeLaunch()
text after = "this line still runs"
stop 1   # refuses: stop takes no operand
storage form

The bytes MerDB keeps for a value. A length is kept as one coherent amount in metres and a duration as one exact span; the unit written in source, or chosen for display, lives in the type. Changing how a column displays never rewrites its stored rows.

Bug it prevents: Rows written in two units by two releases, with no way to tell which is which.

Store seam

The fixed contract between a running program and the database engine. A call names a trove’s slot and an operation and carries Rune documents. A result comes back stamped with the record’s id, version and the acknowledgment it reached. The program never learns which engine or medium sits behind it.

Bug it prevents: Application code that only works against one storage backend because it reached past the contract.

Store slot

A named binding from a program's symbolic slot to one table. It carries two authority axes: access over rows (none, read, write, readWrite) and database tokens over the typed companion, such as query and feed.

{
    u16 schemaVersion = 1
    text name = "employee"
    text table = "hr/employee"
    text access = "read"
    text[] database = ["query"]
}

Bug it prevents: a reporting job that only needed to read rows also dropping an index or acknowledging another consumer's feed.

stream

A reference to a large block of data kept somewhere else: the name of where it lives, a starting offset and a length. It does not hold the data itself, so a huge file can be passed around cheaply. Its literal stays quoted, because its value text is a call's shape around a quoted name.

stream clip = "stream(\"video\",offset=0,length=10,extent=100)"
stream copy = clip
Struct

A struct is a named group of fields stored together, like a form with labeled boxes. In C, Go or Rust each struct declaration is its own type. Trident's records are chest documents that carry their own field types, and a trove declares a fixed set of columns.

Structural typing

Structural typing treats two types as the same when they have the same shape (the same fields with the same types), whatever they are named. TypeScript works this way. Trident's record kinds outline and ingot are structural; outline and ingot declarations work.

Symbol table

A symbol table is the compiler's list of every name in a program and what each one refers to. A Trident enum's identity does not depend on it: it is 32 bytes minted from the declaring module, so it means the same thing outside the program.

Symmetric and triangular matrices

Shapes a square matrix can have: symmetric means it mirrors across its diagonal, lower triangular means every entry above the diagonal is zero, and upper triangular means every entry below it is. A Trident tensor can declare one of these as its structure, and every value is checked against it.

SystemLogic

The hand-written C# layer of an Alba application, where its rules live. Generated code calls into it, and regeneration never overwrites it.

Bug it prevents: a hand edit to generated code that disappears the next time the definitions change.

T

T? nullable and null

A ? after a type means the value may be missing, which is written null. It can be used as a plain value only where a test, like if (x != null), proves it is there. The ? can sit at each level, so i32?[] and i32[]? differ.

i32? maybe = null
i32? seven = 7
i32 sure = seven   # proved present by its write
if (maybe != null) {
    i32 inside = maybe   # proved by the test
}
i32 unsure = maybe   # refuses: nothing proves it present

Bug it prevents: the null crash, reading a missing value as if it were there. A read that nothing proves refuses before the program runs.

t.* libraries

Trident's built-in libraries all have names that start with t., such as t.math or t.log. Each is linked into the program that runs Trident, not downloaded. A program may call one only if its grant admits it, so everything a program can touch is on one list.

Bug it prevents: a program quietly using a library nobody approved, such as the network.

t.assets

Reads the application's imported assets by name from the asset store the host lends. It answers a family's state and pinned identity, or the finest level within a byte budget. t.assets.limit narrows this runtime's picks per profile.

chest picked = t.assets.pick("models.pump",
    {text kind = "decodedBytes", u64 maxBytes = 8388608})
t.buffer

Immutable byte buffers: raw bytes that are not text. It builds and joins them, checks signatures, and computes hashes such as SHA-256, a 64-character fingerprint that changes if any byte changes.

buffer bytes = t.buffer.fromText("hello")
sha256 digest = t.buffer.sha256(bytes)
text shown = text(digest)

Bug it prevents: treating raw bytes as text, or text as bytes, without saying how they are encoded.

t.clock

Reads the time: t.clock.now() for the calendar clock and t.clock.monotonic() for a timer that never jumps backward. It is the only way a program learns the time, and only when the host provides a clock, so a test or a replay can supply a fixed time instead.

Bug it prevents: code that secretly reads the current time and so gives a different answer every run, making bugs impossible to reproduce.

t.code

Compiles Trident source that the program already holds as text and returns a checked report: the program's digest, the catalog it was checked against and its entry module. It never runs the result; only the host can install and run a program.

chest image = t.code.compile("i32 twice(i32 n) { return n * 2 }")
text entry = image.entryModule
assert (entry == "a.main", "the entry module")

Bug it prevents: eval running code the instant it is produced, with full access to everything the caller can touch.

t.collide

Collision geometry: whether a point sits inside a shape, whether two shapes overlap, where a ray hits, and how far apart two shapes are. Every answer comes out the same way on every run, so a game or simulation can be replayed exactly.

t.contract

A library that checks a document against a shape described while the program runs, for data whose fields no program declares, such as a file from outside. The provider member named on this page belongs to an earlier design that was withdrawn; a rule the application must decide comes back as a request the program answers.

t.db

The typed database library: read and write rows, run queries and follow a table's change feed, through a store slot the host grants. Each kind of action needs its own access (read, write, query and so on), so a program granted only read access cannot write.

Bug it prevents: a report meant only to read data accidentally deleting rows.

t.edit.action

The editing engine behind Trident's editor. It applies changes to source code, or to a code graph, as all-or-nothing steps with undo and redo. Like t.code, it never runs the code it edits.

t.finance.fx

Currency conversion. t.finance.fx.convert changes an amount from one currency to another at a rate whose type names both currencies, rounding once in the way you choose. Assigning euros to a dollar variable refuses instead.

Bug it prevents: euros quietly becoming dollars through an assignment, or a rate applied backwards; both stop the program from building.

t.finance.money

Exact money math and the list of world currencies. t.finance.money.allocate splits an amount by weights so the parts always add back up to the total, with the leftover cent placed on purpose instead of lost to rounding.

money<USD> total = 10.00
money<USD>[] parts = t.finance.money.allocate(total, [1, 1, 1])
assert (parts[0] + parts[1] + parts[2] == total, "no cent lost")

Bug it prevents: splitting $10.00 three ways as $3.33 each and losing a penny every time a bill is divided.

t.geo.carto

Ellipsoid geometry over caller-supplied parameters: geodesic and rhumb-line distance and bearing, geodesic area, map projections and datum shifts. Angles are radians, and the ellipsoid is an argument, never a hidden default.

f64[4] solved = t.geo.carto.geodesicInverse(6378137.0, 1.0 / 298.257223563,
    lat1, lon1, lat2, lon2, 100)

Bug it prevents: mixing two datums because a library assumed one.

t.geo.grid

Global grids: the Earth's surface cut into numbered cells at many sizes. It finds the cell at a latitude and longitude, and a cell's parent, children, neighbors and area.

t.gfx

Graphics: turns text into shaped glyphs and builds the typed rows a program uses to describe a Thalassa scene. Thalassa, MerTek's renderer, does the drawing. A program can use it only when its grant admits t.gfx.

t.job

Builds a job's outcome (done, failed, a checkpoint or progress) and talks to the host's job runner to submit, cancel or inspect jobs. It needs a host that runs jobs, so the one-shot tricli runner does not grant it.

Bug it prevents: a retried background task running as a second, separate job.

t.log

Writes log messages at a level: trace, debug, info, warn or error. The host's grant decides which levels are allowed, which is why an application's lend names t.log with a threshold such as info.

t.log.info("starting")
bool chatty = t.log.enabled("debug")
t.math

The general math library: square roots, pi, clamping, rounding, vectors, matrices and more. Its answers are plain 64-bit floating-point numbers, computed the same way every run. It needs no line in a lend.

f64 root = t.math.sqrt(2.0)
f64 kept = t.math.clamp(5.0, 0.0, 1.0)
assert (kept == 1.0, "clamped to the top")
f64 bad = t.math.sqrt(-1.0)   # faults: no NaN takes its place

Bug it prevents: sqrt(-1) returning NaN, which then spreads silently through later math until a far-off number prints as nan.

t.math.castRounding, castSaturating, castWrapping

A plain conversion such as f32(x) is exact or it faults: t.math.cast: digits when the value cannot be stored exactly, t.math.cast: range when it is too big. When losing something is the point, you name the loss: castRounding rounds, castSaturating clamps to the largest value, castWrapping wraps around like a car's odometer.

f64 wide = 1.0e300
f32 capped = t.math.castSaturating(wide, "f32")
i64 big = 300
u8 wrapped = t.math.castWrapping(big, "u8")
assert (wrapped == 44, "300 wraps to 44")
f32 narrow = f32(wide)   # faults: t.math.cast: range

Bug it prevents: a narrowing cast that silently cuts off or wraps a number, as C and Go allow.

t.math.complex

Math on complex numbers (a real part plus an imaginary part): size, angle, square roots and logarithms. Complex numbers have no less-than, so to compare sizes you call t.math.complex.abs on each side, where a reader can see it.

complex128 z = 3.0 + 4.0i
f64 size = t.math.complex.abs(z)
assert (size == 5.0, "a 3-4-5 triangle")
complex128 w = 1.0 + 1.0i
bool less = z < w   # refuses: complex numbers have no order

Bug it prevents: z < w quietly comparing only the real parts, or only the sizes, and answering a believable but wrong true or false.

t.math.daabb

Members for daabb, a bounding box whose sides line up with the x, y and z axes. They answer whether a point is inside, whether two boxes overlap, and which box holds both. Boxes have no + or <, because neither has one honest meaning.

daabb box = (0,0,0, 1,1,1)
bool inside = t.math.daabb.contains(box, (0.5, 0.5, 0.5))
assert (inside, "the center is inside")
daabb both = t.math.daabb.union(box, box)

Bug it prevents: box + box compiling into something that looks reasonable but answers a question nobody asked.

t.math.dquat

Members for dquat, a quaternion: four numbers that together describe one 3D rotation. You can build one from an axis and an angle and rotate a point with it. Two rotations combine with @, never *, because the four numbers are one rotation, not four separate values.

dquat spin = t.math.dquat.fromAxisAngle((0.0,1.0,0.0), 1.5707963)
dvec3 turned = t.math.dquat.rotate(spin, (1.0, 0.0, 0.0), 1e-9)
dquat both = spin @ spin
dquat bad = spin * spin   # refuses: no lane-by-lane product

Bug it prevents: multiplying two quaternions part by part, which compiles in most languages and gives a meaningless rotation.

t.math.dual

Members for dual, a number that carries its own derivative (how fast it is changing) beside its value. Arithmetic on duals applies the calculus rules for you, and t.math.dual.value and t.math.dual.tangent read the two parts back.

dual x = (3.0, 1.0)
dual y = x * x
f64 value = t.math.dual.value(y)
f64 slope = t.math.dual.tangent(y)
assert (slope == 6.0, "the slope of x squared at 3")

Bug it prevents: estimating a slope from two nearby points with a step that is too big or too small, and nothing telling you which.

t.math.extended

Members for the extra-precision kinds dd128, td192 and qd256, which add two, three or four 64-bit floats together to hold more digits. t.math.extended.of builds one, and t.math.extended.toF64 reads it back as one plain f64, a name that admits it keeps only the leading part.

dd128 one = t.math.extended.of(1.0, "dd128")
f64 back = t.math.extended.toF64(one)
assert (back == 1.0, "round trip")
t.math.geometricAlgebra

Members for geometric algebra, a branch of math that handles rotations, reflections and intersections with one set of rules. It provides the geometric product, the wedge, exp and log, and applying a rotor or a motor. The algebra's kinds take no arithmetic operators, so every operation is a named call.

t.math.tensor

The dense number-array library: one block of numbers with a shape (rows, columns and more), plus members that build, read and reshape it. t.math.tensor.from builds a tensor from a list of numbers or a list of equal-length rows.

t.math.uncertainty

Tools for saying how well a measurement is known. combine merges the uncertainties of several measurements through a calculation and states how they are related; effectiveDegreesOfFreedom reports how much evidence the result rests on.

Bug it prevents: adding two uncertain measurements with + and silently assuming they are unrelated, which can hide how large the real error is.

t.measure

Members for measure, an exact physical amount with its unit, such as 90 degrees. t.measure.to converts exactly or refuses, so a quarter turn becomes exactly one half pi radians. t.measure.format prints in a unit it checked, never one typed into a format string.

measure quarter = 90deg:angle
measure inRad = t.measure.to(quarter, "rad")
assert (text(inRad) == "0.5pirad:angle", "exactly pi/2")

Bug it prevents: a report that prints "kN" from a format string while the number underneath is really in newtons.

t.media

Reads imported asset documents: a family's level menu, one level's bytes or identity, and decoded mesh, point, texture, audio or video levels. Each reader refuses a document of the wrong profile.

t.ml

Machine-learning kernels over tensors: matrix products, activations, normalization, attention, losses and metrics, optimizer steps and seeded sampling. A random draw always takes the program's own seed.

tensor<dtype=f64> scores = t.ml.softmaxRows(t.ml.matmul(patch, weights))
t.net.http

Makes outbound web (HTTP) requests, but only to what an operator profile allows. A script gets no network at all unless the command line names a profile and its digest, so the code cannot decide on its own where to connect.

Bug it prevents: a library deep inside a program sending data to a web address nobody approved.

t.net.peer

Direct connections between running MerTek programs (peers) over named lanes: connect, send a message, watch and close. The operator lists which peers the program may reach and in what role, and any other endpoint is refused before a byte is sent. It grants no web (HTTP) access.

Bug it prevents: a program connecting to a machine the operator never listed.

t.nodecanvas

Keeps the state of a node canvas, a visual editor where boxes (nodes) connect by wires: which nodes exist, which are selected and where each one sits. It works out layout and drawing shapes the same way every time, and never runs the code it shows.

t.proc

The process library starts only programs the lend admits, by name and argument prefix, from a pinned directory. It returns an opaque child handle, never a process id, and runs no shell and no PATH search.

resource<t.proc.child> child = t.proc.spawn(["meterconv", "--to", "png", "M-88213.jpg"],
    { text stdout = "capture", text stderr = "inherit" })

Bug it prevents: an argument built from user input turning into a shell command.

t.quantity

Members for numbers that carry a physical family and unit, such as a length in meters: convert units, take roots and change how the amount is stored. The square root of an area comes back as a length.

f64<family=area> square = 9.0m2
f64<family=length> side = t.quantity.root(square, 2)
f64 meters = t.quantity.inUnit(side, "m")
assert (meters == 3.0, "3 m on a side")

Bug it prevents: taking the square root of an area, forgetting it is now a length, and adding it to an area.

t.recon

Reconstruction policy for noisy render signals. A program declares the tier, the upscale rung and every resource temporal reconstruction reads. resolveRequest admits the request or names the first missing prerequisite.

chest resolved = t.recon.resolveRequest(config)
text? reason = resolved.reason

Bug it prevents: temporal smoothing that ghosts because nobody supplied motion vectors.

t.render.offline

Renders one frame of a scene document on the renderer the one-shot host lends, usually the Soft renderer. It returns the encoded render result with its digests and captures, and needs no window or graphics card.

t.security

The security family: t.security.crypto for passwords, keys, signing and secure random numbers, and t.security.secret for comparing and sealing secret values. Each needs a security provider grant from the host, so code cannot reach keys on its own.

t.security.crypto

Password hashing and checking (passwordHash and passwordCompare), secure random numbers, named public keys, signing and certificate requests. A stored password hash (pwhash) can be checked only through passwordCompare.

Bug it prevents: comparing password hashes with ==, or turning one into text that ends up in a log; both refuse at compile.

t.slab

The library for slabs, blocks of fixed-size typed rows that the host keeps between ticks of a game or simulation, such as every unit's state.

t.sync

Named locks, which stop two pieces of work from changing the same thing at once. t.sync.policy builds the rule (exclusive, shared or counted, with a wait limit), and the lock statement holds it for one block and releases it however the block ends.

i32 count = 0
chest policy = t.sync.policy.exclusive(0ms, 1s, false)
lock ("ledger", policy) {
    count = count + 1
}

Bug it prevents: a lock left held forever because an error skipped the unlock line.

t.telemetry

Builds metric, histogram, timing-span and frame-profile records as plain documents. You pass every number and timestamp in, so the same inputs make the same record and a replay matches the original run.

chest hits = t.telemetry.metricDeclare("hits", "counter", [])
text kind = hits.kind
t.text

Turns values into text and back: the exact text of a value, a number shown with a set count of decimal places, and parsing text into a value. A conversion such as i32(digits) uses its parser and faults when the text is not a number.

text shown = t.text.display(2.5, 2, {})
assert (shown == "2.50", "two decimal places")

Bug it prevents: text such as "12abc" quietly read as the number 12.

t.text.bytes, t.text.scalars, t.text.graphemes

Three ways to count and index text. bytes counts the stored UTF-8 bytes, scalars counts Unicode code points, and graphemes counts what a reader sees as one character. "héllo" is 6 bytes but 5 letters, so a bare count() on text refuses and makes you pick.

text word = "héllo"
i64 bytes = t.text.bytes.count(word)
i64 letters = t.text.graphemes.count(word)
assert (bytes == 6, "six bytes")
assert (letters == 5, "five letters")

Bug it prevents: cutting a name in the middle of an accented letter or an emoji because the length counted bytes when you meant letters.

t.time

Exact dates, times and durations. Each time scale has its own library, such as t.time.unix, with add, sub and compare and a conversion to a calendar label. Nothing here reads the clock; you pass the instant in.

timepoint<unix> start = 0
timepoint<unix> later = t.time.unix.add(start, 90m)
civil label = t.time.unix.toCivil(later)
assert (text(label) == "1970-01-01T01:30:00Z", "ninety minutes in")
t.time.map

Converts an instant between time scales (Unix, atomic TAI, TT, GPS and UTC calendar labels) using pinned tables whose digest is checked. If the tables do not cover an instant, it refuses instead of guessing. A program must be granted it, and a plain script is not.

Bug it prevents: comparing a GPS time with a computer timestamp directly while they silently differ by leap seconds.

t.timer

Schedules an event for later: after a delay, every so often, or once things go quiet. The event arrives at an on event handler. Only a runner that keeps going after main returns can deliver it, so tricli refuses t.timer and points you to tri --headless.

T[] and T[N] arrays

An ordered list of values of one type. i32[] can grow with add; i32[2] is a fixed group of exactly two that never grows. A foreach walks a snapshot, so adding during the walk never extends it.

i32[] values = [1, 2, 3]
values.add(4)
i32[2] pair = [10, 20]
i32 first = pair[0]
i32 bad = pair[2]   # refuses: index 2 is outside a pair

Bug it prevents: reading past the end of a list. An index the compiler can prove is out of range refuses, and any other is checked when it runs.

tally baseline

The first accepted total in one compatible tally segment. Later readings measure change from that segment. A new generation starts a new baseline, and a fall under the same generation creates a gap.

Bug it prevents: computing a negative rate across a reset or assuming an earlier value was zero.

tally generation

A nonnullable scalar u64 field that marks one continuous tally segment. Zero is valid. It is separate from the total; a new generation starts a new segment.

Bug it prevents: calculating a rate across two unrelated tally segments.

tally metric

A cumulative total that only rises within one generation. A separate u64 generation marks a restart. A fall without a new generation is a gap. The canonical declaration and reducer domain compile.

Bug it prevents: using a reducer or restart rule from a different metric class.

tape

A tape is a recording of a run: every input the program read from outside, such as input events, call arguments and clock readings, and what it did. A Trident program reads nothing a tape cannot record, so a tape can be replayed later and must give the same results.

Bug it prevents: a bug that happened once on someone's machine and can never be reproduced. The tape is the bug report.

task … else

Runs a block in a walled-off region. If anything inside faults, the block stops and its else arm runs once with the fault. A region can only tighten the time and memory limits it inherits, never loosen them. It does not run code in parallel.

text trail = "no fault"
task {
    i32 zero = 0
    i32 lost = 1 / zero
} else (raised) {
    trail = "the block faulted"
}

Bug it prevents: a library call deep inside quietly using more time or memory than its caller allowed.

Telemetry

Telemetry is data a program reports about itself while it runs, such as counts, timings and errors. Trident's t.telemetry is a pure, deterministic linked library.

Temperature point and temperature difference

A thermometer reading (20 °C) and a change in temperature (20 degrees warmer) are different things. Adding a change to a reading makes sense; adding two readings does not. Absolute zero, 0 kelvin or -273.15 °C, is the coldest possible temperature, and it is a point, not a difference.

Tenant

The organization or unit a record belongs to, stored as a reference on the row. Access rules read declared tenant relations such as tenant.member(who.subject), and a tenant name alone grants nothing.

Bug it prevents: one customer's query returning another customer's rows because the filter lived in application code that someone forgot.

tensor

A block of numbers with any number of dimensions (a list, a table, a cube and beyond), all of one element type such as f64. Science and machine learning use them. * works element by element and @ is the matrix product. A literal of its value text stays quoted, because its header, an element type and a bracket list, would read as a type and an index.

tensor<f64> m = t.math.tensor.from([[1.0, 2.0], [3.0, 4.0]], "f64")
tensor<f64> product = m @ m   # matrix product
tensor<f64> lanes = m * m   # element by element
tensor<f32> other = m   # refuses: the element type is part of the type

Bug it prevents: multiplying element by element when a matrix product was meant, or the reverse.

Tensor contraction

Combining two grids of numbers by multiplying entries along a shared axis and adding them up. Matrix multiplication and the dot product are both contractions. Trident's @ contracts along the trailing (last) axes.

Test lane

A target that runs one focused set of gate leaves, such as one node's product tests. A developer runs the lanes a change needs on the rebased commit before pushing it.

Bug it prevents: paying for a 35-minute sweep on every change when a one-minute lane holds the changed contract.

Texel

One pixel of a texture, the image a 3D program wraps over a surface. Texels are often stored in special packed formats. A Trident binary16 vector holds plain IEEE half-precision numbers, not a texel format.

text

A string of characters, stored as strictly valid UTF-8, the standard way to write text as bytes. Use it for names, messages and anything people read. A number joins text only through an explicit text(n) or a {n} slot in a `...` string.

text name = "Ada"
i32 age = 36
text line = `{name} is {age}`
text joined = name + " " + text(age)
text bad = "age " + age   # refuses: a number is not text

Bug it prevents: a number glued into text by accident, like JavaScript's "1" + 1 giving "11".

Texture

An image prepared for the GPU: a complete set of mip levels in one storage format, with its color space and alpha mode. Nautilus keeps the stored format exactly; a block-compressed level stays block-compressed.

Thalassa

Thalassa is MerTek's renderer and scene engine, written fully in C. A program describes a scene with t.gfx and Thalassa draws it. It never reads the wall clock on its own: a frame's time arrives as a field the host writes.

Thread and concurrency

A thread is one line of work inside a program; with several threads a program can do many things at once (concurrency), at the risk of data races.

Tier test

Four questions asked in order to place a capability: core mechanism, authoring kit, application or product. The first yes decides. A scenario value compiled into core C is the defect it catches.

Time scale (Unix, TAI, GPS, TT)

A rulebook for counting seconds. Unix time counts from 1970 as if no leap second ever happened; TAI averages atomic clocks and runs 37 seconds ahead of UTC; GPS time is TAI minus 19 seconds; TT, used in astronomy, is TAI plus 32.184 seconds. A Trident timepoint carries its scale in its type.

timepoint<unix> start = 0
timepoint<tai> atomic = start   # refuses: a scale change is a named map

Bug it prevents: subtracting a GPS time from a Unix time and silently missing the 18 leap seconds between them.

timepoint

One exact instant on a named clock, such as Unix time or atomic time (TAI). The clock, called the time domain, is part of the type: timepoint<unix>. timepoint<domain=tcl> counts Lunar Coordinate Time. Use it for timestamps.

timepoint<unix> start = 0
timepoint<unix> later = start + 1h30m
duration gap = later - start
timepoint<tai> atomic = start   # refuses: a clock change is a named step

Bug it prevents: subtracting timestamps from two different clocks, which can disagree by tens of seconds, as if they were one clock.

timerange

A span between two instants on one clock, written [start, end), the half-open bracket mathematics writes: it includes the start but not the end. So back-to-back ranges meet without overlapping.

timerange<unix> shift = [1700000000,1700028800)
timerange<unix> empty = [5,5)
bool same = shift == empty   # false
timerange<unix> bad = [2,1)   # refuses: the end is before the start

Bug it prevents: an event at exactly 9:00 being counted in both the 8-to-9 slot and the 9-to-10 slot.

Token

A token is the smallest meaningful piece of code, like a word in a sentence: a name, a number or an operator. In Trident a unit suffix is part of its number's token, so 5kg is one token, while 5 kg with a space is a number and a name, and is refused.

f64<mass> load = 5kg
f64<mass> gap = 5 kg   # refuses: 5 and kg are two tokens
Toolchain

A toolchain is the set of programs used to build software, such as a compiler, a linker and a build tool. Some languages need a different toolchain for each target. Trident runs the same source everywhere; what changes per target is which libraries are linked and which capabilities are lent.

Top-level code

Top-level code is code written outside any function, which many languages run as soon as a file is loaded or imported. Trident runs none: a source file holds only declarations, so opening one to read or lint it can never run anything.

const i32 limit = 10
i32 counter = limit + 1   # refuses: a module holds only declarations
text main(text[] argv) {
    return "ok"
}
torus, dtorus

A torus is a donut shape: a center, a turn, a major radius (from the center to the middle of the ring) and a minor radius (how thick the ring is). dtorus stores more digits.

text describe(torus<frame=builtin:itrs> donut) {
  f32<family=length> ring = donut.majorRadius
  f32<family=length> tube = donut.minorRadius
  return t.text.of(tube)
}
TPM rollback floor

A counter in the device's TPM that holds the lowest boot-manifest generation the loader will accept. A lower generation refuses as rollback, so an attacker cannot reinstall an older, vulnerable image that is still validly signed.

transaction

A block that gathers its writes and saves them all at once, or none at all. Nothing is held while it runs, and if another write conflicts at the end, its else arm runs. The storage design reserves the word.

Bug it prevents: half of a money transfer saved while the other half is lost.

Transfer function

The curve that turns a color's stored numbers into real light, and back. Screens use one because eyes notice small changes in dark shades far more than in bright ones, so more of the numbers go to the darks. Rec. 2100 has two, PQ and HLG, for high dynamic range (HDR) video.

Transpose

A matrix flipped across its diagonal, so its rows become its columns: a table 2 rows by 3 columns becomes 3 rows by 2. Some graphics libraries store the transpose of the same transform, so the same numbers line up the other way.

tree: a hierarchical value

A collection whose nodes form ordered roots and children. Node values have one complete type. A layer can constrain root count, arity, depth, node count, distinctness and sibling order. A family adds its own invariant, such as a complete heap or a balanced search tree. Tree rules and examples.

tree<i32,roots=1,arity=[0,2]> values = 9 { 7, 4 }
tri

tri is the windowed runner beside tricli. It runs the same scripts and applications the same way, and it can also open windows, sound and input devices and keep running to deliver events and timers (tri --headless does that with no window).

triangle2, dtriangle2

A triangle2 is a flat triangle given by its three corners, a, b and c, in an app's own frame. dtriangle2 stores more digits.

triangle3, dtriangle3

A triangle3 is a triangle in 3D given by its three corners, a, b and c. 3D models are built from many of them. dtriangle3 stores more digits.

text describe(triangle3<frame=builtin:itrs> face) {
  point3<frame=builtin:itrs> corner = face.b
  return t.text.of(corner)
}
tricli

tricli is the command-line runner for Trident. tricli main.tri compiles that one file and calls main; tricli calc compiles a whole application folder. It opens no window, and with no file named it starts a prompt that runs one line at a time.

Trident

The language MTK applications are written in. Rules, workflows, event handlers and tests are Trident source, and the shared C systems underneath take their parameters from it. One source runs under every MTK host, from a command-line check to a windowed tablet or a headless service.

text main(text[] argv) {
    return "Hello from Trident"
}

Bug it prevents: The same rule rewritten by hand for each device and drifting apart.

trident_exec_promote

A runtime call that moves a value's memory charge from a call's short-lived scratch space into a longer-lived account, so the value can outlive the call. It moves the bookkeeping, not the bytes, and a refused move leaves both accounts as they were.

trident_program_compile, trident_runtime_install

The two C calls a host uses to compile a program bundle and install the result in a runtime. They belong to the host alone: no t.* library offers them, so a running Trident program can never start or swap in other code by itself.

Trigonometry

The math of angles and triangles. Sine, cosine and tangent turn an angle into ratios of a right triangle's sides, which is how programs aim, rotate, and draw circles and waves.

tripkg

tripkg is MerTek's package tool. Before a launch, it looks up a package by name, checks its bytes against a digest (a fingerprint), and copies it into the project as a stored library pinned by that digest. A running program can never fetch a library itself.

Bug it prevents: dependency confusion, where a public registry serves an attacker's package under your private package's name. Each prefix, mer or pkg.<publisher>, maps to exactly one source.

trove

Declares the named columns a record must have, like the header row of a table: trove user { text name, text email }. A local bound to it is still a flexible record, but a misspelled column refuses before the program runs. In the database a trove is also the collection of those records.

trove user { text name, text email }
user u = { name = "Ada", email = "ada@example.org" }
u.email = "ada@example.com"
u.emial = "x"   # refuses: no column of that name

Bug it prevents: a typo like emial quietly creating a new, unused field while the real one keeps its old value.

true, false

The two values of a bool: yes and no. A condition must be a real bool, so a number like 1 or 0 is never accepted in place of one.

bool ready = true
bool done = false
bool bad = 1   # refuses: a number is not a bool

Bug it prevents: a zero, an empty string or an empty list quietly counting as false.

Truthy and falsy

In some languages any value can stand in for true or false: 0, empty text or null count as false (falsy) and almost everything else as true (truthy). Trident's if takes a bool and nothing else, so an integer is never a condition.

i32 count = 1
if (count > 0) { count = 2 }
if (count) { count = 3 }   # refuses: an integer is never a condition

Bug it prevents: C's if (x = 5), which assigns instead of comparing and is always true.

Tuple

A tuple is a small, fixed list of values kept together in order, like (3, 4). Trident has no tuple type a program declares.

dquat spin = (0,0,0,1)
dquat twice = spin @ spin
dquat partial = (0,0,1)   # refuses: a dquat has four parts
twist, dtwist

A twist is how fast something moves and spins: a speed along x, y and z (meters per second) plus a spin rate around each (radians per second). Its type names what moves, what it moves relative to, and the frame of the numbers. dtwist stores more digits.

twist<moving=builtin:itrs,relative=builtin:icrs,frame=builtin:icrs> earthSpin = (0, 0, 0, 0, 0, 0.0000729)
vec3<family=speed> moving = earthSpin.linear
vec3<family=angularFrequency> turning = earthSpin.angular
vec3<family=speed> mixed = moving + turning   # refuses: a speed is not a spin rate

Bug it prevents: adding a speed to a spin rate because both are three numbers. The two halves read out as different quantities, so the sum refuses.

Type A and Type B evaluation

Two ways to work out an uncertainty. Type A uses statistics on repeated readings, such as measuring a rod ten times; Type B uses other knowledge, such as a maker's spec sheet or a calibration certificate. Both give a standard uncertainty.

Type erasure

Type erasure means a language checks types while compiling and then throws them away, so the running program no longer knows them; TypeScript's types are gone once it becomes JavaScript. Trident keeps a value's complete type while it runs and when it is stored, so a document read back still knows its types.

Type inference

Type inference lets the compiler work out a variable's type from its value, so you can write var x = 1. It saves typing but hides the type from the reader. Trident has none: every binding states its full type, and var is an ordinary name, not a keyword.

i64 total = 0
f32 ratio = 1.5
var count = 1   # refuses: write the type, i32 count = 1
Type name = value

Creates a named value and states its complete type first, like i32 count = 3. Trident never guesses a type, and a value never changes type on the way in: a different width needs a written conversion.

i32 count = 7
i64 total = 0            # the literal reads at i64
i64 wide = i64(count)    # the conversion is written out
i64 bad = count   # refuses: write i64(count)

Bug it prevents: a variable's type silently changing when code in another file is edited, or a value quietly widened or cut short on assignment.

Type system

A type says what kind of value something is, such as a whole number, a piece of text or an amount of money, and which operations make sense on it. A type system is a language's set of rules about types. In Trident's, the same bytes are never the same type: a guid is not a u128.

Type<...> type parameters

Settings in angle brackets after a type name, like f64<mass> or money<USD>, that make the setting part of the type. Each can be written by name or by position: f64<family=mass> and f64<mass> are one type.

f64<family=mass> heavy = 5kg
f64<mass> alsoHeavy = 5kg   # the same type, written short
f64<range=[0,1]> chance = 0.5
f64<range=[0,1]> bad = 1.5   # refuses: outside its range

Bug it prevents: a value in the wrong unit, or outside its allowed range, passing as an ordinary number.

U

U+0041 rune literal

Writes one Unicode character by its code number: U+0041 is the letter A. A rune can be compared but not added to; to step to the next character, convert through u32 and back.

rune first = U+0041
rune next = rune(u32(first) + 1)   # B
rune bad = first + 1   # refuses: no rune arithmetic

Bug it prevents: adding to a character code and landing on a number that is not a valid character.

u128

A whole number from 0 up to a 39-digit number, stored in 128 bits. It is a number; an id of the same size is a guid, a different type.

u128 big = 340282366920938463463374607431768211455
guid id = 00000000-0000-0000-0000-000000000000
u128 n = id   # refuses: an id is not a number
u16

A whole number from 0 to 65,535, stored in 16 bits. Use it for port numbers, small codes and compact counts that are never negative.

u16 port = 8080
u16 over = 70000   # refuses: 70000 does not fit in a u16
u32

A whole number from 0 to about 4.3 billion, stored in 32 bits. Use it for sizes, ids and counts that are never negative.

u32 size = 4294967295
u32 none = 0
u32 under = none - 1   # faults: a u32 holds no negative number

Bug it prevents: 0 minus 1 wrapping around to 4,294,967,295.

u64

A whole number from 0 to about 18.4 quintillion, stored in 64 bits. Use it for very large counts, sequence numbers and bit patterns.

u64 events = 18446744073709551615
u64 none = 0
u64 under = none - 1   # faults: a u64 holds no negative number
u8

A whole number from 0 to 255, stored in one byte. Use it for bytes, color channels and small counts that can never be negative.

u8 level = 255
u8 bad = -1   # refuses: a u8 holds no negative number
i32 big = 300
u8 b = big   # refuses: the conversion must be written
u8 capped = t.math.castSaturating(big, "u8")   # 255, and it says so

Bug it prevents: 300 quietly turning into 44 when it is stored in a byte.

UEFI

The firmware interface modern PCs and servers start through. On a BenthOS device the firmware authenticates the BenthOS loader with Secure Boot, and from then on the loader checks everything it starts.

Unbounded growth (memory leak)

Unbounded growth is memory use that keeps climbing while a program runs, often from a leak: memory that is never given back, until the machine runs out. In Trident each kind of memory has a declared limit, so growth stops at a typed fault instead of taking the whole machine down.

Undefined behavior

Undefined behavior is what C and C++ call an operation the language gives no meaning, such as signed integer overflow. The compiler may then do anything, even delete your safety check. Trident has none of it: overflow, division by zero and the other bad operations are catchable faults.

Bug it prevents: a C compiler deleting the if (x + 1 < x) check written to catch an overflow.

Unicode

Unicode is the worldwide standard that gives a number to every character, from A to a Chinese character to an emoji. Trident's text is always valid Unicode stored as UTF-8, and code that counts or indexes text must say which unit it means: bytes, Unicode scalars or graphemes.

unit

A unit of measure as a value, such as m (meters) or kg. A program can store, pass and compare units, but a unit is not a number and takes no math. Its literal stays quoted, because m is a name and m/s would read as two names and a division.

unit meters = "m"
unit seconds = "s"
bool same = meters == seconds   # false
unit odd = meters + seconds   # refuses: a unit takes no arithmetic
Unwinding

Unwinding is what happens when an error leaves a function early: the program backs out through each call, running cleanup code as it goes. In Trident an on exit block runs on every leave, a fault's unwind included, and resume can continue after a faulting statement instead of unwinding past it.

use

Inside an if or when that produces a value, use hands back that branch's answer. Every branch must supply one of the destination's type, so a value if needs an else. Only the chosen branch runs.

i32 n = -3
text sign = if (n < 0) {
    use "negative"
} else {
    use "not negative"
}
text bad = if (n < 0) { use "negative" }   # refuses: needs an else

Bug it prevents: a variable left unset because one branch forgot to assign it.

Use-after-free

A use-after-free bug reads or writes memory after the program has given it back, when it may already belong to something else. It is a top cause of crashes and security holes in C and C++. Trident cannot express it: there is no free and no pointer type.

Bug it prevents: an attacker placing their own data where freed memory used to be, and the program trusting it.

UTC (Coordinated Universal Time)

The world's reference clock for everyday time: time zones are written as offsets from it, so +02:00 means two hours ahead and Z means UTC itself. It follows atomic time but adds a leap second now and then to stay in step with the Earth's spin. In Trident, UTC appears on civil labels.

civil utc = 1987-03-05T14:30:00Z
civil nozone = 1987-03-05T14:30:00
bool before = utc < nozone   # faults: an unknown offset cannot be placed
UTF-8 and UTF-16

UTF-8 and UTF-16 are ways to store Unicode characters as bytes: UTF-8 uses 1 to 4 bytes per character, and UTF-16 uses 2-byte units. Trident's text and its source files are strict UTF-8.

uvec2, uvec3, uvec4

A group of 2, 3 or 4 whole numbers that are never negative (each a u32), such as an image's width and height in pixels. Math works lane by lane, and a lane that would drop below zero stops the program.

uvec2 size = (640, 480)
uvec2 doubled = size * 2
uvec2 small = size - (700, 0)   # faults: 640 - 700 would go below zero

Bug it prevents: a size that subtracts past zero and wraps around to about four billion pixels.

V

Value constraint

A rule in a complete type that limits its values. For example, f64<range=[0,1]> admits only numbers from zero through one. Each destination of that type enforces the rule before it publishes a value.

f64 input = 0.75
f64<range=[0,1]> chance = input
# chance = 2.0 faults; chance stays 0.75.

Read the constraint examples and comparison.

Value preparation

An explicit type policy can change a private candidate during a source write, then check it before publication. For example, outside=clamp moves an out-of-range amount to the nearest admitted boundary. A received value is only validated; it is never repaired.

i32<range=[0,100],outside=clamp> score = 120
# score holds 100.
Variadic function

A variadic function accepts any number of arguments, like C's printf. Trident has none: every function has a fixed parameter list, and a call names exactly that many arguments.

Variance and covariance

Variance is a spread measured in squared units: the standard uncertainty multiplied by itself. Covariance is the same idea for two values together, how much they vary in step. A positive covariance means that when one reads high, the other tends to read high too.

varint

A whole number with no fixed size: it grows to as many digits as it needs, up to 4,096 bits (about 1,200 digits). The cost of each step is counted before it runs, so a giant number cannot hang the program.

varint x = 12345678901234567
varint y = 9876543210987654321
varint p = x * y   # exact: no overflow
i64 small = p   # refuses: the conversion must be named

Bug it prevents: a product overflowing a 64-bit integer and wrapping to a negative number.

vec2, vec3, vec4 (and dvec2, dvec3, dvec4)

A short list of 2, 3 or 4 decimal numbers that travel together, like the x, y and z of an arrow. Games and graphics use them for positions, speeds and colors. Math works lane by lane (one number at a time). The d versions store more digits per number.

vec3 step = (1, 2, 3)
vec3 longer = step * 2.0
f32 height = step.y
dvec3 fine = (1.1, 2, 3)
vec3 rough = fine   # refuses: the d version never quietly loses digits
vec3 kept = vec3(fine)   # faults: 1.1 has no exact copy with fewer digits

Bug it prevents: a precise dvec3 losing digits as it is squeezed into a vec3 with nobody noticing. The plain copy refuses, and vec3(fine) stops the program rather than round.

Verdict

The result of one gate leaf, read from its exit status: 0 is pass, 1 is fail, 2 is hold. No tool parses a printed count to decide it.

Bug it prevents: a summary line that says "all passed" while a case failed underneath.

virtual machine (VM)

A virtual machine is a program that runs bytecode one instruction at a time, like a player piano reading a paper roll. Trident's VM counts its call depth against a limit instead of using the computer's own stack, and it has no JIT (a mode that turns busy code into machine code while it runs).

Bug it prevents: deep recursion overflowing the real stack and crashing the whole process instead of raising a fault.

void

The result type of a function that returns no value. It can appear only there: no variable or parameter can be void.

void greet(text name) {
    text line = "hi " + name
}
greet("Ada")
void nothing = greet("Bob")   # refuses: void is not a binding type

Bug it prevents: using the result of a function that does not produce one.

Volatility window

How long a published MerFS file version may stay visible before it is durable. Zero means the commit returns only after the new root is durable. The device caps the window per volume and per grant, and a crash inside it returns the last durable root, never a torn file.

Bug it prevents: Assuming a file survived a power cut because a read just after the write saw it.

Volume primary

The one runtime that accepts writes for a volume of MerDB storage. It holds each record’s latest version in memory, checks every write against it, commits writes in batches and copies each batch to standby runtimes. If it fails, a standby takes over and keeps every sequence number.

Bug it prevents: Two machines both believing they own the same records after a network split.

W

Wayland

The Alba code generator. It reads the shared JSON definitions for tables, fields, service calls, events and localized text, and writes the matching C#, JavaScript, TypeScript and SQL.

Bug it prevents: a column renamed in the database but not in the client, which then sends the old name and fails at run time.

WebAssembly (wasm)

WebAssembly is a compact code format that web browsers can run almost as fast as native programs.

WebPublic

The Alba service that serves pages and browser assets to users. It holds no application rules of its own.

WebSocket

A long-lived connection between a browser and a server that both sides can send messages over at any time. Alba uses one so the server can push events without the browser asking.

webtricli

A build of the Trident runner that works inside a web browser as WebAssembly, with no window of its own.

Wedge product

A product of two directions that builds the flat patch they span, a bivector, with a turning direction. Its size is the area of the parallelogram the two directions outline. t.math.geometricAlgebra.wedge computes it for multivectors.

multivector<euclid3> e1 = (0, 1, 0, 0, 0, 0, 0, 0)   # the x direction
multivector<euclid3> e2 = (0, 0, 1, 0, 0, 0, 0, 0)   # the y direction
multivector<euclid3> patch = t.math.geometricAlgebra.wedge(e1, e2)   # the xy patch
WGSL

WebGPU Shading Language, the shader text WebGPU devices compile. Thalassa writes it by lowering checked Glint IR; nobody writes WGSL by hand for an MTK scene.

Wheelhouse

The MTK editor and debugger, its own executable. It edits application source, runs it, and attaches to a tri target over a debug association, always in a process of its own.

when unguarded

A partial enum selection. It may omit members and may have an else arm. Duplicate members still refuse. An ordinary enum when must cover all admitted members.

Bug it prevents: confusing an intentionally partial selection with a complete one.

when, is

Picks one branch by matching a value against is arms; an arm can list several values, and no arm falls through into the next. Over an enum, a when must name every member and takes no else. when unguarded is the deliberate partial form.

enum Light { Red = 0, Amber = 1, Green = 2 }
Light now = Light.Amber
text say = ""
when (now) {
    is Light.Red { say = "stop" }
    is Light.Amber, Light.Green { say = "go" }
    else { say = "?" }   # refuses: an enum when takes no else
}

Bug it prevents: a new enum member silently landing in an old default branch. Every when over it refuses until it handles the new case.

while (not in Trident)

Trident has no while loop. Every loop states how many passes it may take before it starts, so a loop that runs until something changes is written as repeat with a limit and break.

i32 left = 3
repeat (10) {
    if (left == 0) { break }
    left--
}
while (left > 0) { left-- }   # refuses: no while loop

Bug it prevents: an endless loop that hangs the program because its exit condition is never met.

wire form

The bytes a value travels as between processes and sites. In MTK they are the same canonical document bytes MerDB stores: every field carries its name and complete type, so a receiver checks a record before reading it.

Bug it prevents: A receiver reading a field whose type changed in the sender's last release.

Workload identity

The identity of a service or job rather than a person, issued by a trusted issuer and pinned to its credential and deployment generations.

Worktree

A separate working copy of the repository, checked out from main for one change. Each lane edits, builds and tests in its own, so one lane's half-finished edit never enters another lane's commit.

Bug it prevents: a peer's uncommitted edit swept into your commit, or erased by your reset.

wrench, dwrench

A wrench is a push plus a twisting push: a force along x, y and z (in newtons) and a torque around each (in newton-meters), in one frame. Robot arms and physics engines use it. dwrench stores more digits.

wrench<frame=builtin:itrs> shove = (10, 0, 0, 0, 0, 2)
vec3<family=force> push = shove.force
vec3<family=torque> twistingPush = shove.moment
vec3<family=force> mixed = push + twistingPush   # refuses: a force is not a torque

Bug it prevents: adding a force to a torque because both are stored as three numbers.

FURTH FORTUNE / ENGINEERING REFERENCEBack to top ↑