Furth FortuneEngineering reference
TECHNICAL DOCUMENTATION

2027 · MerTek technology

On this page

Core system / System overview

Trident

Application rules with units, bounds and named failures

Trident is the language MTK applications are written in. Every value states its type, every loop its pass count and every enum branch its members, and the compiler checks all three. A program reaches files, the network and devices only through the grant its host builds at launch.

Worked example

A transformer alarm that pages one crew, once

Ridgeline Power runs 14 substations, and each transformer's gateway reports top-oil temperature. Oil above 85 °C for 90 seconds means the on-call crew gets paged. Readings arrive as loose documents, two gateways can report the same substation, and the alarm service may reach exactly one paging endpoint.

  1. Write the limits with their units. Oil temperature is a measure, a value that carries its unit and family (85degC:temperature), and the hold time is a duration. If a gateway sends a reading in millimetres, the comparison faults with a dimension error instead of treating it as the number 85.

    const measure oilLimit = 85degC:temperature
    const duration holdFor = 90s
    
    enum Severity { Watch = 1, Alarm = 2, Trip = 3 }
    
    Severity classify(measure oil, duration over) {
        if (oil > oilLimit && over >= holdFor) {
            return Severity.Alarm
        }
        return Severity.Watch
    }
  2. Admit each reading with expect. A gateway document is a chest, so its fields are only claims until something checks them. expect checks every named field and its complete type before it binds any of them. A reading that fails takes the else arm, and that arm must leave. The when names all three severities, so adding a fourth stops the build at every when that does not handle it.

    text admit(chest reading) {
        expect { text station, measure oil, duration over } = reading else {
            t.log.warn("reading refused: station, oil or over is missing")
            return "refused"
        }
        Severity level = classify(oil, over)
        return when (level) {
            is Severity.Watch { use "log" }
            is Severity.Alarm { use "page" }
            is Severity.Trip { use "page and shed load" }
        }
    }
  3. Scan the replay with a stated bound. After a 90-second link drop, a gateway replays up to 600 buffered readings. repeat fixes its pass count before the first pass, and Trident has no while, so the scan ends when the buffer does.

    i32 firstHot(measure[] backlog) {
        i32 found = -1
        repeat (backlog.count(), i32 i = 0) {
            measure reading = backlog[i]
            if (reading > oilLimit) {
                found = i
                break
            }
        }
        return found
    }
  4. Page once per substation, under a deadline. The host delivers each alarm to the on event handler as one bounded call. lock? holds the key page:SS-07 under an exclusive policy, so the second gateway's alarm takes the else arm instead of paging again. The page itself runs in a task with a 2-second deadline; a timeout or a refused request runs the task's own else arm, and the handler carries on.

    void pageCrew(text station) {
        chest policy = t.sync.policy.exclusive(0ms, 10m, false)
        lock? ("page:" + station, policy) {
            task (duration = 2s) {
                buffer body = t.buffer.fromText(`station={station} reason=oil`)
                chest reply = t.net.http.post("https://pager.ridgeline.example", "/v1/pages", [], body)
            } else (e) {
                text why = e.message
                t.log.error(`page for {station} failed: {why}`)
            }
        } else {
            t.log.info("page already open for " + station)
        }
    }
    
    on event("OilAlarm", chest alarm) {
        expect { text station, measure oil, duration over } = alarm else {
            return
        }
        if (classify(oil, over) == Severity.Alarm) {
            pageCrew(station)
        }
    }
  5. Run it under a grant. Every library call goes through the grant the host builds at launch, and the application's _grant/grant.draft can only narrow it. The compiler derives every library the program calls, so a grant that revokes outbound HTTP stops the alarm service before main runs and names the call that needed it. The real service revokes only process launch.

    $ cat oilalarms/_grant/grant.draft
    u16 schemaVersion = 1
    text[] revoke = ["t.net.http", "t.proc"]
    
    $ tricli oilalarms
    tricli: lend: revoked: t.net.http
    tricli: a/ reaches t.net.http.post, and _grant/grant.draft revokes t.net.http
    tricli: falseStart: grant
What happened

The service pages each substation's crew once, gives up on a page after 2 seconds, and logs every refused reading by name. The units, the branches and the loop bounds are checked when the program compiles, and the grant is checked before main runs. Nothing in the source assumes a unit, a loop end or a network route that it does not state.

System diagram

Track review as a node program

The node view and script view edit the same program. The branch, task budget, error path, and lock are visible before the workflow runs.

Event TrackUpdated
Guard typed trackId + source
Branch confidence ≥ 0.85?
yes
Task correlate • 50 ms
Lock track:{id} • 100 ms wait
Publish shared status board
no / invalid
Error hold + named reason

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 type authority

The language and database accept the same declared types.

  1. Type registry one approved list
  2. Trident parser language declarations
  3. MerDB parser column declarations
  4. Refusal unknown spelling stops
Map 02

Qualified call resolution

A call must pass each namespace and implementation boundary.

  1. t.name reserved namespace
  2. Installed library allowed dependency
  3. Native or Trident verb resolved implementation
  4. Host edge optional platform call
Map 03

Task memory budget

Temporary work is bounded and failure is catchable.

  1. Task starts declared budget
  2. Arena allocates task-local values
  3. Budget check within limit?
  4. Result or error return or OutOfMemory
Map 04

Two execution engines

Both engines must produce the same typed result.

  1. Source parse once
  2. Static checks types + names
  3. Tree walk reference execution
  4. Lowered engine optimized execution
  5. Parity same result or refusal
Map 05

Faults are data

A failure carries a code, message, origin, and retry state.

  1. Operation fails named cause
  2. err value structured fields
  3. Handler retry • fallback • fail
  4. Evidence same reason recorded
Map 06

Policy or kernel?

Scenario choices stay visible; reusable compute stays shared.

  1. Question choice or generic compute?
  2. Trident value + sequence + policy
  3. C kernel parameterized operation
  4. Result fast work, visible choice

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.

Every value has a complete type

A binding states its type, and a computed value never converts on assignment. Units, time domains, currencies and nullability are part of the type, so the compiler checks them like any other mismatch.

For example

i64 total = count refuses and names i64(count). A speed compared with a bare f64 refuses and names the call that strips the unit.

Every limit is written down

A loop states its pass count before it starts. A task states its deadline or memory budget, and a lock policy states how long to wait and how long to hold. Work that runs until someone stops it belongs to a session's frame calls, not to a loop.

For example

The replay scan is repeat (backlog.count(), i32 i = 0), and the page runs under task (duration = 2s).

Access comes from the host

A program names libraries; the host decides which ones it lends. The compiler derives the list the program reaches, and the launch stops if the grant does not cover it. A library the grant leaves out is absent from the program's catalog, so a call to it refuses before any argument is evaluated.

For example

Revoking t.net.http stops the alarm service at launch with a/ reaches t.net.http.post, and _grant/grant.draft revokes t.net.http.

Code

Read the language

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

Trident

Typed values, units and durations

A literal reads at its destination's type, and a unit travels inside the value or the type. 1h30m prints as 90min because a duration keeps one exact amount.

const i32 stations = 14
const duration holdFor = 90s

text main(text[] argv) {
    i64 readings = 0                       # the literal reads at i64
    f64<family=velocity> vibration = 4.2mm/s
    measure oil = 91.5degC:temperature
    duration handover = 1h30m              # prints as 90min
    return text(handover)
}
# i64 total = stations     refuses and names i64(stations)
# duration billing = 1mo   refuses: a month is a calendar span
Trident

Bounded loops

foreach walks a snapshot of the array, and repeat takes its pass count first. A while refuses and names repeat, foreach or a session's frame as the spelling to use.

text main(text[] argv) {
    text[] stations = ["SS-01", "SS-02", "SS-07"]
    i32 checked = 0
    foreach (station in stations) {
        checked++
    }
    i32 attempts = 0
    repeat (5, i32 attempt = 1) {
        attempts = attempt
        if (attempt == 3) { break }
    }
    return `{checked} stations, {attempts} attempts`
}
Trident

Complete enum branches

A when over an enum names every member and takes no else. Add Flood = 4 to Severity and this function stops compiling with "no arm names Flood".

enum Severity { Watch = 1, Alarm = 2, Trip = 3 }

text crewAction(Severity level) {
    return when (level) {
        is Severity.Watch { use "log only" }
        is Severity.Alarm { use "page on-call crew" }
        is Severity.Trip { use "page crew and shed load" }
    }
}

text main(text[] argv) {
    return crewAction(Severity.Trip)
}
Trident

Guarded field reads with expect

A plain read of a missing field faults while the program runs: partial.oil raises absentField. expect turns the same gap into an ordinary branch the author wrote.

text describe(chest reading) {
    expect { text station, measure oil } = reading else {
        return "incomplete reading"
    }
    return station + " at " + text(oil)
}

text main(text[] argv) {
    chest partial = { text station = "SS-09" }
    return describe(partial)
}
Trident

Structured faults

A fault carries a reason, a message and the call chain. The handler reads the reason as a member of the system enum fault and decides whether to retry, resume or fail.

measure parseOil(text raw) {
    if (raw == "") {
        fail "empty oil reading"
    }
    return 0degC:temperature
}

text main(text[] argv) {
    text trail = "start"
    on error (caught) {
        fault why = caught.reason
        text message = caught.message
        when unguarded (why) {
            is language { trail = trail + " | " + message }
        }
        resume
    }
    measure oil = parseOil("")
    return trail
}
Trident

Task regions with budgets

A task runs its block in its own fault region. It may narrow the deadline, the scratch memory or the call depth it inherits, never widen them, and a fault inside runs its else arm once.

text main(text[] argv) {
    text trail = "ok"
    task (duration = 50ms) {
        i32 zero = 0
        i32 lost = 1 / zero
    } else (raised) {
        trail = "task faulted; the call goes on"
    }
    task (scratchBytes = 65536) {
        text[] lines = ["SS-01 ok", "SS-07 hot"]
    } else (raised) {
        trail = "over budget"
    }
    return trail
}
Trident

Locks with a policy and a busy path

The policy states how long to wait and how long the lease lasts. lock releases however its block ends. lock? never waits on a busy key: its else arm runs instead, with no fault.

text key = "ledger"
chest policy =
    t.sync.policy.exclusive(0ms, 1s, false)

lock (key, policy) {
    # held; released however it ends
}

lock? (key, policy) {
    # held
} else {
    # busy: no fault, this arm runs
}

Uses

Example uses

  • Sensor alarms and paging rules
  • Maintenance approval and tag-out workflows
  • Admission of field and gateway input

Review questions

What the team must decide

Which rules need units, time domains or currencies in their types

Which loops, calls and locks need written bounds

Which libraries each application should be lent, and which revoked

Contact us
FURTH FORTUNE / ENGINEERING REFERENCEBack to top ↑