DEV Community

Cover image for You are in the cockpit now. Nobody gave you instruments.
hyuga
hyuga

Posted on

You are in the cockpit now. Nobody gave you instruments.

I noticed recently that I have stopped typing.

The agent writes the code. What I do is look at what comes back and press y. Dozens of times a day.

And — you probably recognize this — somewhere around the tenth one, I stopped reading.

"Same as the last one." It usually is. But if one of those fifty had touched production, would you have caught it? I wouldn't have.

That is not supervision. That is a rubber stamp.

Am I flying this, or am I a passenger?

Here is the thing I keep coming back to.

A pilot does not see the outside world directly. They see instruments: fuel, damage, remaining ordnance, whether the limiter is engaged. Reaction time matters, but knowing what is happening right now comes first.

An aircraft with broken instruments is not the same aircraft with a small problem. It is a different aircraft.

So: everyone running an AI agent is already sitting in a cockpit. You don't move the controls yourself; the machine acts and you decide at the moments that matter. That is a pilot's job description.

You are just sitting there without an instrument panel.

What you can see is one approval dialog at a time. What you cannot see: what this session has done in total, how far into dangerous territory it has gone, what it got wrong last time.

I wanted that panel, so I built it.

npx @hyuga/airframe install
Enter fullscreen mode Exit fullscreen mode

The panel

It says nothing most of the time. Silence is the correct state. You look when you want to look.

$ airframe status

sortie   2026-08-30T07-07-43-412Z-18aa80
form     strike / fire
limiter  0
wingmen  0
fuel     0 (no budget set)
mounted
  + airframe      the vessel
  + redline       limiter — counts the sortie, not the call
  + habit         learns from the corrections you make by hand
  + carbon        keeps the draft about to be written over — cruise only
  + groundtruth   completion gate — called from your code, not from a hook
  + llm-safe-sql  runs the write, measures it, rolls back — from your code
Enter fullscreen mode Exit fullscreen mode

The vocabulary is aviation, partly because I like it and partly because it turned out to be the right shape:

  • sortie — one run of work. What the last one left unfinished survives into the next
  • limiter — how much irreversible ground this sortie has covered
  • wingmen — how many subagents were launched
  • fuel — how many moves are left

limiter 0 means nothing dangerous has happened yet. When it climbs, the machine is pushing into something.

A limiter is not there to slow you down

This is the part I most want to land.

"Guardrails" sounds like friction. It is the opposite.

The limiter is what lets you open the throttle.

Without instruments there is exactly one safe way to operate: go slow, always. And that is what everyone does — confirm every step, never look away. Sitting in a fast machine, driving at walking pace forever.

With a number on the panel, "safe to let it run" and "hold the reins" become different situations. Zero? Leave it alone. Climbing? Pay attention. It is a part that makes you faster.

My own instrument lied to me

Then the instrument lied to me.

While publishing this repository, the limiter — threshold 3 — reached 20. More than six times over.

I looked at what it had charged for. Every single one was a search.

grep -n "npm publish" .github/workflows/release.yml    # +3
grep -rn "rm -rf" packages/                             # +3
Enter fullscreen mode Exit fullscreen mode

Looking for the string npm publish scored the same as actually publishing. The limiter was matching a regex against the whole command as one blob of text.

The problem is not that it was too strict. The problem is that once you learn 19 of 20 charges are noise, you skip the 20th too. And the one you skip is the one that mattered.

A broken instrument is worse than no instrument, because it lets you feel watched while nothing is watching.

Fixed the same day:

Command Before After
grep "npm publish" README.md 3 0
grep "npm publish" README.md && npm publish 3 3
npm publish 3 3

The arguments to grep are text, not actions. But sed, xargs and node -e are still charged on what they contain — their arguments are commands, and nothing here can tell whether that string is about to run or about to be printed.

Charging when the answer is genuinely unknown is design. Charging when the answer was obvious was the bug.

Past the limit, it does not stop you

When the score goes past the threshold, the machine does not stop. It says:

This sortie has spent 20 against a limit of 3. You are flying it, so it is your call — but say out loud that you are past the edge before going on.

It does not stop because there is no guarantee the machine is more right than the person in the seat. The call belongs to the pilot.

One exception: set AIRFRAME_AUTONOMY to the reason you are running unattended — a loop, a timer — and then it will halt. With nobody in the seat there is nobody to advise.

Advise when someone is aboard. Halt when nobody is. The condition for releasing the limiter is decided by the seat, not by the machine.

Converging and diverging are opposite jobs

One more thing you switch by hand.

airframe mode strike   # implement it, fix it, ship it
airframe mode cruise   # draft, design, decide what to build
Enter fullscreen mode Exit fullscreen mode

While you are implementing, you want the gate: did those rows actually land? Stop me if not.

While you are drafting, the same gate is a wrist being grabbed mid-sentence. An idea that has not taken shape yet gets reported as "unmet." The better the idea, the earlier it closes.

Opposite jobs. Tune for one and you break the other.

And the machine never guesses which one you are in. Guessing wrong is the same bug as not having the two. You type it. It takes a second.

In cruise, the draft keeper runs: when the agent is about to overwrite a file git does not have, the previous version is kept.

$ carbon list
2026-08-30T07-32-32-255Z-0bef6e1d.md    1832 bytes
Enter fullscreen mode Exit fullscreen mode

Files git already tracks are never copied — git show gets those back. Only what git is not keeping. For anyone who has had an agent overwrite a draft and found git diff empty.

Three CI files that had never run once

One more thing that actually happened.

When I merged the parts into one repository, I moved each part's .github/workflows/ along with it, into the package folders. GitHub only reads .github/ at the repository root.

Three CI files. Three release files. After the merge, not one of them had run.

And nothing says so. Nothing is failing. On the GitHub UI, "zero failures" and "zero runs" look exactly the same.

Which is the general form of what the completion gate does: at the moment something claims "done", go re-fetch the actual state.

groundtruth verify --probe "psql -tAc 'select count(*) from t where batch=123'" --count 45
Enter fullscreen mode Exit fullscreen mode

Told 45 rows landed? Go count them. Zero? Stop there. No LLM, no API key — the raw output of the command you gave it, shown as evidence.

Where this actually pays off

Honestly: this thing helps in a narrow set of situations, and it is worth naming them.

Late in a long day. Work with an agent from morning to evening and your judgment degrades. You cannot feel it happen. The approval dialog asks you from scratch every time, so the tenth one looks exactly like the first. The limiter is the opposite: a number that does not go down. Name your production paths and the day's total is right there.

{ "production": ["/var/www/", "/srv/client-sites/"] }
Enter fullscreen mode Exit fullscreen mode

When it runs unattended. Set AIRFRAME_AUTONOMY to the reason — a loop, a timer — and the machine really does halt. With nobody in the seat, "advise" means nothing. I don't know of another brake that works for unattended runs.

When you are writing prose with an agent. Articles, proposals, design notes. Overwriting a file git does not track, in cruise, keeps the previous version. And the completion gate goes quiet, so a draft never gets reported as "unmet."

Just as clearly, where it does not help:

  • Short one-off tasks — it's over before you'd look at the panel
  • Local, reversible experiments — nothing to count
  • Overwrites via sed -i or a formatter — those never pass through a hook, so the draft keeper cannot see them
  • Judgment calls — "is this design good" has no probe, so the gate has nothing to check

Long sessions, a lot delegated, hard to undo. The more of those three you have, the more this earns its place. None of them? Don't install it.

Where I think this goes

Soon enough:

  • agents will run while you sleep
  • you will fly several at once, not one
  • a single run will last hours, not minutes

When that happens, I don't think the bottleneck is model quality. It is whether a human can stay in the loop at all.

You wake up to eight agents' worth of work. Can you reconstruct what happened? Which of them touched production? Did any of them quietly revert the fix you made by hand yesterday?

That is why status has a wingmen row. How many were launched is a number a pilot should be able to see afterwards, and there is no other way to know it.

Whether "AI does the work" means you are in command or you are being carried is decided, I think, by the cockpit rather than by the model.

What none of this buys

It does not make the agent correct. None of these parts read your code. They watch what happens around the work.

The limiter is a gauge, not a guard. Its number is summed out of a ledger the agent can write to. It is built for the agent that has lost count, not the one trying to get past you — anything that can run commands on your behalf is already inside the boundary.

The draft keeper matches names, not contents. .env is never copied; a draft with a key pasted into the third paragraph is copied like any other draft. A part that opens every draft to judge it is a part that opens every draft. I liked that less.


npx @hyuga/airframe install
Enter fullscreen mode Exit fullscreen mode

Node 18+. No dependencies, no daemon, no network, no LLM. MIT.

github.com/hyuga611/airframe

If you are sitting in the seat, look at the instruments.

Top comments (0)