What Keel does not own
Keel computes. Policy, stored records and pixels belong to Trident, MerDB and Thalassa.
- Keel math + simulation + ML
- Not policy no alarm or route thresholds
- Not storage no record ownership
- Not rendering no pixels
2027 · MerTek technology
Core system / System overview
Shared math kernels, with every decision kept in Trident
Keel is MTK's C library of math, geometry, simulation and machine-learning kernels. Trident programs reach it through typed calls such as t.collide, t.geo.carto, t.math and t.ml. A Keel kernel computes over the values it is handed and holds no thresholds, scenario values or decisions.
Worked example
A survey team flies drones along fixed legs past a row of wind turbines. Company policy keeps every leg at least 150 m from any turbine mast. Before the crew uploads a flight plan, a Trident program checks each leg against the masts on the site map.
Trident converts the planner's waypoints into a local frame. t.geo.carto.geodesicInverse solves the leg on the WGS 84 ellipsoid and returns its bearing and length. Leg 4 runs 2,402 m east-northeast at 120 m altitude. Its end lies 2,265 m east and 799 m north of its start.
const f64 wgs84SemiMajor = 6378137.0
f64 radians(f64 degrees) {
return degrees * t.math.pi() / 180.0
}
# East, up and north of the leg's end, in meters from its start.
dvec3 localEnd(f64 lat1, f64 lon1, f64 lat2, f64 lon2, f64 altitude) {
f64 flattening = 1.0 / 298.257223563
f64[4] solved = t.geo.carto.geodesicInverse(wgs84SemiMajor, flattening,
radians(lat1), radians(lon1), radians(lat2), radians(lon2), 100)
f64 azimuth = solved[2]
f64 meters = solved[3]
return dvec3(meters * t.math.sin(azimuth), altitude, meters * t.math.cos(azimuth))
}A Keel kernel measures the closest approach between the leg and mast T-12, modeled as a 135 m vertical segment. t.collide.segmentClosest returns the distance and the closest point on each segment. It knows nothing about drones, masts or the 150 m rule.
f64 closestApproach(dvec3 legStart, dvec3 legEnd, dvec3 mastBase, dvec3 mastTop) {
chest closest = t.collide.segmentClosest(legStart, legEnd, mastBase, mastTop)
f64 distance = closest.distance
return distance
}
f64 legFourAtT12() {
dvec3 legStart = (0.0, 120.0, 0.0)
dvec3 legFinish = (2264.98, 120.0, 799.23)
return closestApproach(legStart, legFinish,
(1250.0, 0.0, 573.0), (1250.0, 135.0, 573.0)) # 124.40
}The decision stays in Trident. The clearance is a named constant, and the verdict names the leg, the mast and the distance. Leg 4 passes T-12 at 124 m, 57 percent of the way along, so the program holds the route.
const f64 clearanceMeters = 150.0
# The rule lives here, in source, and nowhere in the kernel.
text legVerdict(text leg, text mast, f64 closest) {
if (closest < clearanceMeters) {
f64 shown = t.math.round(closest)
return "hold " + leg + ": " + mast + " at " + text(shown) + " m"
}
return "clear " + leg
}Bad input refuses by name. When a GPS dropout writes NaN into a waypoint, the kernel refuses with collide_nonfinite and publishes nothing. Without that refusal, a NaN distance fails every comparison, so closest < clearanceMeters reads false and the leg would pass as clear.
text checkLeg(dvec3 legStart, dvec3 legEnd, dvec3 mastBase, dvec3 mastTop) {
text outcome = "unchecked"
task {
chest closest = t.collide.segmentClosest(legStart, legEnd, mastBase, mastTop)
f64 distance = closest.distance
outcome = "closest " + text(distance) + " m"
} else (e) {
text why = e.message
outcome = "refused: " + why
}
return outcome
}The check held leg 4 at 124 m, 26 m inside the limit, and named T-12. The crew lead moved waypoint 5 150 m south, and the rerun measured 206 m and cleared. The planner laptop and the field tablet printed the same distance, because both called the same kernel with the same inputs.
System diagram
The fast function is generic. Trident supplies the scenario values and decides what to do with the result.
Inside the system
Follow the data, decisions, and access boundaries. Each diagram explains a concept used by applications.
Keel computes. Policy, stored records and pixels belong to Trident, MerDB and Thalassa.
Programs, simulations and the renderer call the same math kernels.
A typed `t.*` member exposes one parameterized kernel; the program supplies the values and decides what happens next.
Key parts
These are the main boundaries, inputs, outputs, and failure rules. The examples show a specific use of each part.
A Keel kernel is generic computation over the values its caller hands it. It holds no scenario value, no threshold and no runtime policy. Limits, holds and alerts live in Trident source, where a reviewer reads them.
t.collide.segmentClosest returns 124.4 m; the line const f64 clearanceMeters = 150.0 is what makes that a hold.
Keel kernels are deterministic. They read no clock, locale or hidden random source, and a random draw takes its seed from the caller. A planner, a field device and a replay get the same result from the same inputs.
A replay of Tuesday's flight recomputes every closest approach exactly as the live check did.
Each kernel reaches Trident as a t.* member with a declared signature, bounds and faults. A value outside a kernel's domain refuses with a named reason before any result is published.
A NaN coordinate refuses as collide_nonfinite, and a geodesic iteration ceiling of zero refuses as language.
Code
Each example is short and complete enough to read on its own. Hover a dotted word for its definition.
The filter step is the kernel; the motion model and the noise figures are the program's. The fix says 1,383.5 m, the model predicts 1,379.8 m, and the step returns 1,382.2 m at 11.84 m/s.
f64[] smoothFix() {
f64[] state = [1368.0, 11.8] # meters along leg, m/s
f64[][] spread = [[4.0, 0.0], [0.0, 0.5]] # covariance factor
f64[][] motion = [[1.0, 1.0], [0.0, 1.0]] # one-second step
f64[][] drift = [[0.3, 0.0], [0.0, 0.2]] # process factor
f64[] fix = [1383.5] # what the GPS reports
f64[][] measures = [[1.0, 0.0]] # GPS reads position only
f64[][] noise = [[3.0]] # GPS factor, meters
return t.math.filter.step(state, spread, motion, drift, fix, measures, noise)
}
The matrix product and softmax are Keel kernels. The 0.6 review threshold is a Trident constant, so a reviewer can change it without touching compute code.
const f64 crackReview = 0.6
text inspectPatch(tensor<dtype=f64> patch, tensor<dtype=f64> weights) {
tensor<dtype=f64> scores = t.ml.softmaxRows(t.ml.matmul(patch, weights))
f64[] classes = t.math.tensor.toList(scores) # clean, erosion, crack
f64 crack = classes[2]
if (crack > crackReview) {
return "send to blade engineer: crack " + text(crack)
}
return "no review needed"
}
The kernel returns the perimeter, the area and the closure residual of the ring. A 0.01 by 0.03 degree block near 36.24 N covers 2,992,154 square meters.
f64 blockArea(f64[] latitudes, f64[] longitudes) {
f64[] lat = []
f64[] lon = []
foreach (value in latitudes) { lat.add(radians(value)) }
foreach (value in longitudes) { lon.add(radians(value)) }
f64[3] solved = t.geo.carto.geodesicArea(wgs84SemiMajor,
1.0 / 298.257223563, lat, lon, 100)
return solved[1]
}
A capsule is a segment with a radius. The drone's 20 m corridor and the mast's 4 m envelope do not touch on leg 4. That is a separate question from the 150 m policy.
bool corridorTouchesMast() {
chest corridor = {dvec3 a = (0.0, 120.0, 0.0),
dvec3 b = (2264.98, 120.0, 799.23), f64 radius = 20.0}
chest mast = {dvec3 a = (1250.0, 0.0, 573.0),
dvec3 b = (1250.0, 135.0, 573.0), f64 radius = 4.0}
return t.collide.capsuleVsCapsule(corridor, mast)
}
The kernel finds every strict local maximum. Which peaks count as strong, here anything above 2 g, is the program's rule.
i64 strongPeaks(f64[] accel) {
i64[] peaks = t.math.signal.peaks(accel)
i64 strong = 0
foreach (index in peaks) {
if (accel[index] > 2.0) { strong = strong + 1 }
}
return strong
}
Uses
Review questions
Which calculations several tools must agree on exactly
Which thresholds and holds must stay in reviewable Trident source
Which inputs can arrive malformed, and what the program does when a kernel refuses