DEV Community

Scott Miller
Scott Miller

Posted on

The Brittleness Problem in Infrastructure Automation

Why today’s automation keeps breaking—and how resource-oriented shells change everything

Infrastructure automation was supposed to make our systems reliable, predictable, and self-healing.

Instead, for many teams, it has become:

  • Fragile
  • Hard to debug
  • Dangerous to change
  • Almost impossible for AI to reason about safely

We’ve automated more than ever… yet outages from automation mistakes keep increasing.

This is the Brittleness Problem.

Let’s talk about why this happens—and what a fundamentally better model looks like.


What Do We Mean by “Brittle” Automation?

A brittle system is one that:

  • Works perfectly under expected conditions
  • Fails catastrophically under slightly unexpected ones
  • Gives you very little signal about why it failed

Most modern automation is built on top of string-based shells:

systemctl status nginx | grep active
Enter fullscreen mode Exit fullscreen mode

This looks innocent—but it depends on:

  • Output formatting
  • Locale
  • The exact wording of systemctl
  • The behavior of grep
  • Exit codes mapped correctly
  • The shell not being in a weird state

If any one of those changes, the automation silently misbehaves.

And that’s not even counting:

  • Race conditions
  • Partial failures
  • Stale files
  • Mixed init systems
  • Permission drift
  • Or cloud edge cases

We built massive mission-critical systems on text parsing and hope.


Why Traditional Shells Are the Root of the Problem

Classic shells (Bash, Zsh, Fish, etc.) were designed for:
✅ Humans
✅ Interactive workflows
✅ Small scripts

They were not designed for:
❌ Autonomous agents
❌ Deterministic automation
❌ Typed system control
❌ Machine reasoning
❌ Long-lived orchestration logic

They operate on:

  • Strings
  • Exit codes
  • Environment variables
  • Implicit state

This makes them:

  • Hard to validate
  • Hard to simulate
  • Hard to audit
  • Hard to reason about mathematically
  • Almost impossible for AI to safely control at scale

The Hidden Cost: Why AI + Shell Automation Is So Dangerous Today

Right now, most “AI DevOps” agents work like this:

LLM → generate shell command → execute → parse output → guess what happened
Enter fullscreen mode Exit fullscreen mode

This is extremely dangerous because:

  • The AI has no guarantees about output structure
  • Error conditions are inconsistent
  • Partial success looks like success
  • Rollback logic is brittle
  • Security boundaries are unclear

We are giving autonomous systems root access through a text parser.

That’s not automation. That’s roulette.


The Real Architectural Problem

The core issue is this:

We treat critical system resources as text instead of typed objects.

Files, services, processes, network interfaces, logs, secrets, containers, and cloud resources are all exposed through:

  • Disconnected tools
  • Human-formatted output
  • Inconsistent semantics
  • One-off command conventions

There is no universal, typed, machine-readable control layer for the operating system.

So every automation stack rebuilds one from scratch—badly.


What a Non-Brittle Model Looks Like

A stable automation foundation needs:

Typed resources (not strings)
Uniform addressing
Structured JSON output
Deterministic verbs
Cross-platform semantics
Audit-friendly behavior
AI-safe control surfaces

Instead of this:

ps aux | grep nginx | awk '{print $2}'
Enter fullscreen mode Exit fullscreen mode

You want something closer to this:

proc://nginx.status
Enter fullscreen mode Exit fullscreen mode

And instead of:

curl | jq | sed | grep
Enter fullscreen mode Exit fullscreen mode

You want:

http://api.example.com.items.json(method="GET")
Enter fullscreen mode Exit fullscreen mode

Where every result is:

  • Structured
  • Typed
  • Predictable
  • Machine-verifiable

The Resource-Oriented Shell Concept

This is why a new class of tooling is emerging:
Resource-Oriented Shells

Instead of treating the OS as:

“a stream of text commands”

They treat it as:

“a graph of typed, addressable resources with verbs”

Examples of resource handles:

  • file://
  • proc://
  • svc://
  • http://
  • net://
  • mq://
  • secret://
  • snapshot://
  • config://

Each resource exposes:

  • Explicit verbs
  • Defined inputs
  • Structured outputs
  • Predictable errors

This makes automation:

  • Safer
  • Testable
  • Observable
  • Replayable
  • AI-controllable

Brittleness vs. Resilience

Traditional Shell Resource-Oriented Shell
Text parsing Typed JSON output
Implicit state Explicit state
Tool chaining Resource verbs
Weak validation Strong schemas
Hard to test Deterministic tests
Unsafe for AI AI-native by design

This isn’t about “replacing Bash.”

It’s about giving automation a real operating system API.


Why This Matters Long-Term

We are rapidly moving toward:

  • Autonomous remediation
  • Self-healing infrastructure
  • AI-operated platforms
  • Zero-touch operations
  • Agent-based cloud management

All of that demands immutability, determinism, and machine-verifiable behavior.

Text-based shell automation simply cannot scale safely into that future.


Final Thought

The brittleness problem in infrastructure automation is not a tooling issue.

It’s an architecture issue.

We built automation on:

  • Strings instead of types
  • Side effects instead of contracts
  • Hope instead of verification

Resource-oriented shells represent a fundamental correction to that mistake.

And as AI becomes a first-class operator, that correction becomes non-negotiable.

Top comments (2)

Collapse
 
fralau profile image
Laurent Franceschetti • Edited

Among the things you are pointing at, there is something very fundamental: the limits of the string-based pipeline system developed by Ken Thompson and Dennis Ritchie at Bell Labs for the Unix shell in 1973, on a proposal by Douglas McIlroy. Piping was used to condensate a whole workflow on one line of code.

The piping system is powerful and remains valid. What needed to change, however, was what travels on it; text strings (as you remarked), are indeed too brittle. I can see why it doesn't scale well, and why it doesn't fail gracefully (making it hard to debug).

Microsoft tried to solve that problem on Windows with Powershell (Jeffrey Snover 2000-2004), which introduced a system of object pipeline, which enforced integrity, but that idea failed to gain traction. There is a simple reason: they had gone overboard in the other direction. Since there are so infinite classes of objects, what came out one script was rarely fitting into the next one. Hence programmers had to fight to pipe the output of any utility into the input of any other; writing workable pipes became slow and exhausting (and they were still brittle, because the evolution of one object could break the chain).

What was needed, was simple "structured format" that was universal, stable and unambiguous, and yet sufficiently general to carry a large number of objects: why not tables?

In 2019, Jonathan Turner (ex‑Microsoft, ex‑Rust core team) and Yehuda Katz (Ember.js, Rust design team) invented Nushell, a shell based on table-native pipeline model.

It's a powerful and elegant idea; however (in my view), asking a large project, much less a company, to switch to another shell is too heavy of consequences: especially because that would break many existing scripts (defeating the purpose of changing). Hence that limits the adoption of Nushell.

My idea is to retrofit the current dominant shells (essentially bash and zsh) with an ecosystem of new tools that could implement table pipeline; and could absorb the output of traditional shell utilities, or csv files, if a way that is as safe as reasonably possible. I developed a complete set of tools (which I never published).

The format is the JSON/split format (already used by Pandas), e.g.

{
  "columns": ["col1", "col2", ...],
  "data": [
    [row1col1, row1col2, ...],
    [row2col1, row2col2, ...]
  ]
}
Enter fullscreen mode Exit fullscreen mode

I published a proof of concept, based on a Json format that is essentially a JSON structure representing tables (a header and a list of lists). If you perceive any interest around you for that, let me know.

Collapse
 
smiller profile image
Scott Miller

This is an excellent and thoughtful analysis — you’ve articulated the historical arc of the problem very well.

I agree with your core framing: the Unix pipeline itself isn’t the issue. McIlroy’s idea of composition remains one of the most powerful abstractions we have. The real failure mode is what travels on the pipe, and how little semantic stability plain text provides as systems grow more complex.

You’re also right about the two extremes we’ve seen so far:

  • Classic Unix: universally composable, but semantically fragile
  • PowerShell: semantically rich, but overly coupled to object shapes, making composition brittle in a different way

Nushell is a genuinely important step in the middle — and I agree with you that tables are a much more natural “least common denominator” than arbitrary object graphs. In practice, though, as you note, adoption is limited by the cost of switching shells and the blast radius of breaking existing scripts.

resh deliberately takes a different cut at the problem.

Instead of trying to make all pipelines structured, resh draws a hard boundary between two worlds:

  1. Typed, schema-defined resources that resh owns
  2. Opaque text streams that resh treats honestly as text

For resh, structure doesn’t emerge from parsing legacy output or inferring schemas. It comes from defining first-class resources (file://, svc://, net://, http://, backup://, etc.) with explicit verbs and contracts. Those contracts return stable JSON envelopes with known fields, error codes, and deterministic ordering.

This avoids both pitfalls you described:

  • We don’t attempt to retrofit structure onto arbitrary tools — that’s inherently heuristic and brittle.

  • We don’t expose unbounded object graphs — schemas are intentionally narrow, versioned, and resource-specific.

In that sense, resh is closer to systemd’s D-Bus APIs or Kubernetes’ resource model than to a traditional shell pipeline. The “pipe” still exists conceptually, but it’s a pipe of resources and results, not text or arbitrary objects.

On the table question specifically: I think your instinct is absolutely right that tables are one of the most composable shapes we have. In resh, tables tend to appear inside results (lists of rows with known fields), but they’re always wrapped in a higher-level envelope that carries context, errors, and metadata — so failure modes remain explicit and debuggable.

Your JSON/split format is very reasonable, and in fact quite close to how resh internally models many result sets. The key philosophical difference is that resh only emits those structures when it can guarantee the meaning of the columns — never by inference.

I’d definitely be interested in seeing your proof of concept. There’s a lot of shared ground here, and I think the space between “pure text” and “fully object-oriented pipelines” is still underexplored. Your work fits squarely into that missing middle.

Thanks for taking the time to write such a deep comment — this is exactly the kind of discussion I hoped the article would spark.