People describe what they want in sentences. Machines run on code. My research lives in the space between the two — in a language precise enough for a robot to act on, close enough to ordinary speech that the person beside it still recognises what they asked for, and exact enough that a computer can check, every instant, whether the promise is being kept.
"Pass me the wrench when I reach out, keep clear while I'm bent over the machine, and don't take longer than a couple of seconds."
Any human colleague understands this immediately. A machine cannot — not because the request is complicated, but because almost every word in it hides a decision.
What is missing is a middle language — one both sides can hold.
Signal Temporal Logic — STL — is a small language for saying how things should behave over time. It talks about quantities that change continuously, which is what the physical world is made of: distances, speeds, temperatures, forces, currents. And it has almost no vocabulary at all.
always · eventually · until · and a time window attached to any of them. That is the language.
The point is not the notation. It is that once a sentence is written this way, its hidden decisions are out in the open, and if the person disagrees with a number they can say so — before the machine moves, rather than after.
Most ways of checking a rule return yes or no. This language returns a number: how much room was left. Comfortably fine, barely fine, and just missed are three different answers, and a system that can tell them apart is one that can be improved, watched, and explained.
Until recently this language had a serious drawback: somebody had to write the statements, and that somebody had to be a specialist. That is changing. Language models turn what a person says into a candidate statement; vision-language models look at a scene and report what is actually there. The specialist's job shifts from writing the formulas to making sure they mean what the person intended.
The return direction matters just as much and gets discussed far less. Because the machine holds its requirements as explicit sentences rather than buried code, it can report back in the terms it was given: I slowed down because the clearance rule was getting tight. Not a log file, not a confidence score — the requirement the person themselves stated.
The language needs one thing from the world: quantities that vary over time. That is a low bar, and it is why the same sentences work whether the numbers come from a lidar, an event camera, a wristband, a fleet database or an agent's own execution log.
One detail matters for anyone building on small devices. These sentences do not have to be checked on a fixed clock. A requirement can only get closer to breaking when something actually changes, so a monitor can sleep through the quiet and wake on the events that matter — which is the natural way to run on a battery, and the same rhythm that asynchronous sensors and event-driven hardware already work in.
The reason to care about a middle language is that it is portable. A requirement about distance and timing does not know whether it is being kept by an arm, a wheeled robot, a piece of software, or a whole fleet — which means the same tooling, the same monitoring and the same explanations carry across communities that rarely share code.
Learned models are extraordinarily good at proposing what to do next, and have no way whatsoever of promising anything about it. Capable proposals, no promises: that is the situation the language was built for.
Rarely perfection. Usually: knowing what the machine will not do, and being told when it is getting close. That is a communication problem as much as a technical one.
So far this has been about understanding each other. The same writing does harder work when it needs to. Once a requirement is written down precisely, a small program can watch it continuously — and for the few rules that must never break, the system can be built so that they cannot be broken at all, whatever the model on top proposes.
There is one more subtlety, and it is the heart of my doctoral work. Decisions are made every so often; the world moves continuously in between. A promise checked only at the moments of decision says nothing about the gap between them — and the gap is where real accidents live.
Cheap, continuous, and useful even when nothing is guaranteed: a live reading of which requirement is under pressure, and by how much.
Expensive, and worth it for the short list of things that must never happen. Knowing which list is which is half the engineering.
All of this depends on the language actually being usable: fast enough to compute with, expressive enough for real rules, sound when a system has several layers, and honest when the world turns out to differ from what was agreed.
Rich requirements used to be too slow to compute with. Restructuring the problem around the shape of the logic makes it practical to plan against a full set of requirements inside a real control loop, in real time.
Operating rules written in prose by the engineers who run national infrastructure — limits, tolerances, exceptions, habits — carried into this language and run on the actual system, with a live reading of which rule is under pressure.
Real systems are layered: something decides what to do next, something else executes continuously underneath. I work on stating what each layer owes the other, so a promise made at the top survives all the way down to the hardware.
A requirement is a belief about the world, and beliefs go stale. Using vision-language models to compare what the machine sees against what it currently holds itself to — and to revise the statement when the two disagree.
Say it clearly. Act on it. Show your working.