Furth FortuneEngineering reference
TECHNICAL DOCUMENTATION

2027 · MerTek technology

On this page

Engineering reference / System overview

Evidence and Verification

Every gate states its scope and leaves a verdict

The gate system is how MTK tests a change and gates a release. One planner turns a request into an ordered plan of gate leaves. Each leaf runs a declared command, keeps its evidence, and ends in pass, fail or hold.

Worked example

Proving the work queue survives a 90-second link loss

Line crews at the Cedar Valley water utility log work orders on tablets. The canyon roads drop cellular service for a minute or two at a time. Release 3.2 of their crewlog app promises that a 90-second link loss never loses or reorders a saved edit. The release manager will not ship that sentence until a gate backs it with evidence and a verdict.

  1. Write the claim as a source test. Any .tri program under a _test/ folder is a test, and its leading structured comment declares named data cases. Each case is one call to main, and only a true result passes.

    #{
      u16 schemaVersion = 1
      chest[] cases = [
        { text name = "link-up", chest arguments = { u64 applied = 40, u64 saved = 0 } },
        { text name = "drop-90s", chest arguments = { u64 applied = 40, u64 saved = 18 } },
        { text name = "drop-90s-late-ack", chest arguments = { u64 applied = 47, u64 saved = 18 } }
      ]
    }
    # One saved edit every 5 s: a 90-second drop holds 18 edits, 41 to 58.
    # After reconnect the tablet must still hold exactly the edits the server
    # has not applied, in the order the crew saved them.
    bool main(u64 applied, u64 saved) {
        u64[] held = []
        repeat (saved, u64 i = 1) {
            held.add(40 + i)
        }
        u64[] pending = a.queue.unsent(applied, held)
        u64 last = 40 + saved
        u64 expected = 0
        if (last > applied) { expected = last - applied }
        assert (u64(pending.count()) == expected, "no edit lost, none sent twice")
        u64 next = applied + 1
        foreach (seq in pending) {
            assert (seq == next, "sent in the order the crew saved")
            next = next + 1
        }
        return true
    }
  2. Run it the way the gate will. tri --test compiles the test in place of a/main.tri and runs each case in a fresh runtime over a fresh memory store. It exits 0 only when every case passed. A planted bug that resends the last applied edit slips past the drop-90s case and fails drop-90s-late-ack with both values printed.

    $ tri --test --list crewlog
    a/_test/link-loss.tri drop-90s
    a/_test/link-loss.tri drop-90s-late-ack
    a/_test/link-loss.tri link-up
    
    $ tri --test crewlog
    tri: test: a/_test/link-loss.tri drop-90s-late-ack: failed
    a/_test/link-loss.tri:21:5: fault [contract] assert 'no edit lost, none sent twice' failed in main: u64(pending.count()) == expected with u64(pending.count()) = 12, expected = 11
      at main (a/_test/link-loss.tri:21:5)
      help: S.assert: `assert (expr, "name")`
    $ echo $?
    1
  3. Declare the gate leaf. In the build graph the leaf has a stable name and a class that says how heavy it is. It also names the command that produces its verdict and every input that reruns it. The class bounded puts the leaf in every routine run.

    test_class_tri_app_test = bounded
    rule tri_app_test
      command = $python tools/edge_runner.py --stamp $out --memory-ceiling $testmemoryceiling -- ./$in --test $testargs
      description = tri-test $testargs
    
    build $builddir/crewlog-suite.stamp: tri_app_test $builddir/tri.exe | crewlog/a/main.tri crewlog/a/queue.tri crewlog/a/_test/link-loss.tri
      test_class = bounded
      testargs = crewlog
    build crewlog-suite-test: phony $builddir/crewlog-suite.stamp
  4. Keep the field run as a tape. A crew tablet records a real canyon drop, and the tape holds every input the session read. Replay reruns the session headless and answers every outside read from the tape, so the replay verdict backs the end-to-end claim.

    # On the tablet: record the session, tape part only.
    tri --record /data/crewlog-tapes --record-part tape crewlog
    
    # At the depot: replay that tape, pinned to its digest.
    tri --replay /data/crewlog-tapes/canyon-drop.tape --tape-digest <tape-digest>
    #   completed          every call reproduced its state and its result
    #   prefixReproduced   the tape ended early; only that prefix is proved
    #   diverged           a call answered differently; the first mismatch is named
    #   captureIncomplete  the tape lacks an answer the replay needed
  5. Run the release plan on each proof host. The release run is the full routine plan at the exact release commit, and each leaf reports through its exit status. A leg that cannot run on a host exits 2, writes no receipt, and holds the release.

    # One rule for every gate leaf, read from its exit status:
    #   0  pass   every case ran and passed, and at least one ran
    #   1  fail   a case failed and printed its expected and actual values
    #   2  hold   a leg this host cannot run: no device, toolchain or media
    # A leaf that ran nothing exits nonzero. A receipt is written only on 0.
    
    # On each proof host, at the release commit:
    ninja -k 0 test
What happened

The planted resend bug failed the late-ack case by name, long before it could reach a tablet. The first Windows release run held. One leaf needed a directory-symlink privilege the build account lacked, so it exited 2 instead of passing in silence. The release waited until that leaf passed, then shipped with the test, the tape and every receipt behind its one sentence.

System diagram

Claim-to-evidence path

A claim is accepted only when its required check produces a clear verdict and retained proof.

  1. Claim queue survives link loss
  2. Gate disconnect 90 s
  3. Evidence ordered records + timing
  4. Verdict PASS • no lost writes

Inside the system

How the parts work together

Follow the data, decisions, and access boundaries. Each diagram explains a concept used by applications.

Map 01

One planner, several entry points

A test lane, a node group, the full plan and the release run all expand through one planner into one ordered list of leaves.

  1. Requested profile scope + options
  2. Planner single authority
  3. Ordered sections declared groups
  4. Gate leaves one execution list
Map 02

Gate leaf anatomy

Each leaf names its scope, its command, its lane, the evidence it keeps and the rule that turns its exit status into a verdict.

  1. Identity stable gate name
  2. Scope what it covers
  3. Execution lane + command
  4. Evidence retained output
  5. Verdict pass • fail • hold
Map 03

Selection keeps identity

Filtering changes what runs, not what a gate means.

  1. Full plan all declared leaves
  2. Selection group • tag • name
  3. Chosen leaves same identities
  4. Result set scope recorded
Map 04

No pass on silence

A missing verdict, missing evidence or a run that executed nothing is never green. It is a fail or a hold.

  1. Command ends exit + output
  2. Verdict rule explicit result
  3. Evidence check required proof present?
  4. Pass • fail • hold never silence
Map 05

Shared-machine lanes

Heavy builds serialize while independent checks can run together.

  1. Gate plan resource needs
  2. Lane coordinator CPU • memory • cache
  3. Build cache shared authority
  4. Execution safe concurrency

Key parts

What the system does

These are the main boundaries, inputs, outputs, and failure rules. The examples show a specific use of each part.

One planner, one ordered plan

Every run, from one test lane on a laptop to a release, goes through the same build graph. A request names a target, and the planner expands it into the exact ordered set of leaves that target reaches. Nothing outside that graph decides what runs.

For example

A developer runs ninja -k 0 crewlog-suite-test before a push, and the release runs ninja -k 0 test. Both reach the same leaf with the same command.

A gate leaf states what it proves

Each leaf names its class, its command, the inputs that rerun it and the memory ceiling its processes run under. Its verdict is the exit status of that command. Choosing a smaller set of leaves changes what runs, never what a leaf means.

For example

The crewlog suite is bounded, so every routine run includes it. A device campaign is provisioned and runs only on a host equipped for it.

Pass, fail or hold

A leaf exits 0 when every case passed and at least one ran. It exits 1 when a case failed, and 2 when one of its legs could not run. Silence never turns green, and a test that ran nothing exits nonzero.

For example

A case that needs a camera the host lacks prints the leg and the cause and exits 2. The release cannot publish until that leg passes on a host that has the camera.

Code

Evidence and Verification in code

Each example is short and complete enough to read on its own. Hover a dotted word for its definition.

Shell

A transcript case with its expected output

A tricli --test case is a .tri file beside an .expected transcript. A refusal is asserted by its exact status and its exact standard error, so a changed message fails the case.

$ cat queue/outage-units.tri
#{ text kind = "refuse" }
# An outage is a duration, so a bare 90 cannot say whether it means
# seconds or milliseconds, and the compiler refuses it.
text main(text[] argv) {
    duration outage = 90
    return text(outage)
}

$ cat queue/outage-units.expected
exit=65
outage-units.tri:5:23: refused [L.int-unsuffixed] invalid literal at its destination's type `duration`: 90
  5 |     duration outage = 90
    |                       ^^
  help: L.int-unsuffixed: A decimal digit sequence or `0x`/`0X` hexadecimal magnitude is one integer token; its governing complete type reads it, otherwise it defaults to `i64`
tricli: falseStart: compile
tricli: 1 refusal in outage-units.tri
Shell

Gate profiles are targets in one graph

Each profile is a target the planner expands. A wider profile reaches more leaves; it never reruns a leaf whose inputs did not change, because the leaf's receipt still stands.

ninja -k 0 crewlog-suite-test   # one test lane, before a push
ninja -k 0 host-test            # every focused lane of one node
ninja -k 0 test                 # the full routine plan; the release runs this
ninja -k 0 deep                 # test plus long batteries and provisioned legs

# Run one test, or one case, by the identity the plan records:
tri --test crewlog -- a/_test/link-loss.tri drop-90s-late-ack
Shell

Heavy leaves take turns on a shared machine

A pool of depth 1 serializes the leaves that share fixed scratch names or a device. Leaves outside the pool still run in parallel beside it.

# The tape fixtures reuse fixed scratch names, so their leaves take turns.
pool crewlog_tape_pool
  depth = 1

build $builddir/crewlog-tape-test.stamp: cached_artifact_test $builddir/crewlog-tape-canary.exe
  pool = crewlog_tape_pool
  test_class = bounded
  testargs = --proof-group=bounded
  testtimeoutargs = --timeout-seconds 180
Shell

Every leaf runs under a memory ceiling

The edge runner refuses a leaf that names no ceiling. A process that crosses it fails its leaf by name instead of exhausting a shared machine.

# Every stamped leaf holds each of its processes to 4 GiB.
testmemoryceiling = 4294967296

test_class_test = battery
rule test
  command = $python tools/edge_runner.py --stamp $out --memory-ceiling $testmemoryceiling $testproductargs $testtimeoutargs -- ./$in $testargs $scratchargs
  description = test $in
Trident

A test with no parameters runs one case

A main with no parameters runs one case named default. The test calls the production module by its path and asserts against values the module did not compute.

# a/_test/unsent-order.tri
bool main() {
    u64[] saved = [41, 42, 43, 44]
    u64[] pending = a.queue.unsent(42, saved)
    assert (pending.count() == 2, "only the unapplied edits remain")
    assert (pending[0] == 43 && pending[1] == 44, "in the order the crew saved")
    return true
}

Uses

Example uses

  • Release claims backed by named tests
  • Field failures kept as replayable tapes
  • Device and host coverage across proof hosts

Review questions

What the team must decide

Which release claims need a named gate behind them

Which proof hosts and devices each release must run on

How long tapes and receipts are kept after a release

Contact us
FURTH FORTUNE / ENGINEERING REFERENCEBack to top ↑