C.W.K.
Stream
Lesson 01 of 05 · published

No Blank-Check Shell

~10 min · no-blank-check, typed-kinds, fan-out

Level 0Lone Machine
0 XP0/37 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"'Run this command on every host' is not a feature. It's a loaded gun someone put a friendly label on."

A shell string is an unbounded promise

The most tempting fleet feature is also the most dangerous: an endpoint that takes an arbitrary command and a list of hosts and runs the one on the other. It feels powerful. It's a blank check. The API can't preview what that string will do, can't verify it, can't classify its risk, can't bound its blast radius. A durable operation that accepts arbitrary text isn't an operation — it's a promise to do anything, forever, to whoever's on the list.

Typed operation kinds instead

So the durable API speaks only in named kinds: enroll_host, restart_service, apply_update, sync_domain. Each has a fixed shape, a preview, a verification, and a risk class. You can reason about restart_service on the server before it runs — its inputs are known, its effect is bounded, its success is checkable. You cannot reason about bash: (arbitrary text), and neither can the machine you're about to point it at.

The string doesn't vanish — it's quarantined

This isn't a ban on ever typing a raw command; sometimes you genuinely need the unanticipated thing. Arbitrary shell still exists — but only behind the explicit interactive terminal, where a human drives and the target is impossible to miss. The escape hatch is real and clearly marked. It is simply never wired in as the automation contract, because an escape hatch bolted onto a fan-out is just a bigger gun.

Why it matters more at fleet scale

The danger multiplies with the target count. A typed kind fanned across nine machines is nine previewable, verifiable, per-target operations. An arbitrary string fanned across nine machines is nine simultaneous chances to be catastrophically, irreversibly wrong — one typo, nine bricked Macs. Typing is how you keep fan-out from turning every mistake into nine mistakes.

Automate verbs you can name; type the rest by hand. If the API can't say what an action is, it has no business fanning that action across your fleet.

Code

Named kinds, not a blank check·python
# WRONG -- the durable API accepts arbitrary text:
#   POST /run { "command": "<anything>", "hosts": [...] }
#   unpreviewable, unverifiable, unbounded. one typo -> N disasters.

# RIGHT -- the API speaks in typed kinds with fixed shapes:
restart_service(host="server", service="backup-agent")   # previewable, risk-classed, verifiable
apply_update(host="laptop", exact_build="25F84")         # frozen inputs, checkable effect

# Raw shell still exists -- but only in the interactive terminal,
# human-driven, target visible. It is never the automation contract.

External links

Exercise

Take one thing you'd want to do across several machines (restart a service, clear a cache, apply a config). Design it as a typed operation kind: name it, list its fixed inputs, and write how you'd verify it worked. Then write the blank-check version as a single 'run this string everywhere' call, and list what the API can no longer tell you about it.
Hint
The typed version lets you answer 'what will this do, on which machine, and how will I know it worked?' before running. The blank-check version answers none of those — which is exactly why it should live behind a terminal, not an API.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.