← Back to Blog

Software's Missing Middle

Ryan Haney ·

The layer between intent and implementation

Every serious profession has a middle layer, a body of codified knowledge that sits between what someone wants to accomplish and how they actually accomplish it.

In civil engineering, it’s building codes. An architect designs a building. A structural engineer ensures the design meets the code. The code specifies minimum standards for safety, materials, load bearing, fire resistance, and accessibility. The engineer doesn’t invent these standards for each project. They reference a shared, evolving, professionally maintained body of knowledge.

In medicine, it’s clinical protocols and evidence-based guidelines. A doctor doesn’t decide from first principles how to treat pneumonia. They follow established protocols that have been tested, peer-reviewed, and refined over decades. Individual judgment still matters, but it operates within a framework of verified knowledge.

In law, it’s precedent and statute. A lawyer doesn’t argue each case from scratch. They build on prior rulings, established interpretations, and codified law. The institutional layer provides a foundation that individual practice builds on.

Software has no equivalent. There is no shared, maintained, professionally governed body of specifications that software engineers reference when building systems. Every team, every project, every company starts from scratch, defining its own standards, discovering its own edge cases, making its own mistakes.

This is the missing middle.

What building codes actually do

Building codes are misunderstood. They don’t tell engineers how to build. They specify what the result must achieve.

A building code might say: a load-bearing wall in a residential structure must support a minimum of 1,000 pounds per linear foot. It doesn’t say whether the wall should be built from wood, steel, or concrete. It doesn’t specify the construction method. It defines the performance requirement and leaves the implementation to the engineer.

This separation of what from how is exactly what makes building codes useful. The requirement is stable. The implementation evolves with materials, techniques, and economics. When a better building material is invented, you don’t need to rewrite the building code. The performance requirement hasn’t changed. Only the way you meet it has.

It’s the same principle behind specification-driven software development: define the behavior (the what), let the implementation (the how) vary across languages, frameworks, and platforms. The specification is the constant. The code is the variable.

What a software building code would contain

If software had building codes, what would they actually specify?

Not language conventions or style guides, those are cosmetic, not structural. Not framework preferences or architectural patterns, those are implementation choices, not behavioral requirements. The codes would specify behavioral standards that any implementation must meet, regardless of technology.

Authentication standards. A software building code for authentication might specify: passwords must be hashed using a current, approved algorithm (bcrypt, scrypt, or Argon2) with a minimum work factor. Session tokens must expire after a defined period of inactivity. Failed login attempts must be rate-limited after a threshold. Multi-factor authentication must be available for accounts with elevated privileges.

These are verifiable. You can test an implementation against each clause. And they’re technology-independent, they apply whether you’re building in Python, Java, Go, or anything else.

Data handling standards. Personal data must be encrypted at rest using AES-256 or equivalent. Data in transit must use TLS 1.2 or higher. Personally identifiable information must be purgeable within a defined timeframe upon request. Audit logs must record who accessed what data and when.

Error handling standards. External-facing error messages must not expose internal system details. All unhandled exceptions must be logged with sufficient context for diagnosis. System failures must degrade gracefully rather than fail silently or catastrophically.

API standards. Public APIs must validate all input against a defined schema. Rate limiting must be implemented with documented thresholds. Breaking changes must be versioned. Response formats must be consistent and documented.

Most experienced engineers already follow these practices. The difference is that they follow them from personal experience and institutional memory, not from a shared, maintained, authoritative standard.

Why the industry resists standardization

Software engineers have historically resisted standardization. The reasons are understandable.

The field moves too fast. Technologies that are standard today are obsolete tomorrow. Codifying practices into standards risks locking the industry into yesterday’s best practices. This is a legitimate concern, but it conflates implementation standards (which do change rapidly) with behavioral standards (which don’t). The requirement that passwords be hashed with a strong algorithm hasn’t changed in twenty years. Only the recommended algorithm has.

Every project is different. Software engineers are justifiably skeptical of one-size-fits-all rules. A startup’s API has different reliability requirements than a hospital’s medical records system. This is true, and it’s exactly how building codes work. Residential buildings have different codes than commercial buildings than hospitals than bridges. The standards are context-dependent. That doesn’t mean standards shouldn’t exist.

It would slow us down. Compliance with standards takes time. This is the same argument that every industry made before adopting professional standards. And in every case, the cost of compliance turned out to be dramatically lower than the cost of the disasters that occurred without it.

The resistance is breaking down. Not because engineers suddenly love bureaucracy, but because the stakes have gotten high enough that the absence of standards is becoming untenable.

The open-source parallel

Interestingly, the open-source ecosystem has created something like an informal building code, without calling it that.

When the entire Go ecosystem uses crypto/tls for TLS, that library is functioning as a de facto standard. Its behavior is the specification. Projects that use it inherit its security properties. When it’s updated, every project that depends on it gets the update.

Shared libraries are informal building codes. They encode verified behavior in a reusable form. The problem is that they’re tied to a specific language, they’re maintained by volunteers with varying levels of commitment, and there’s no authority that certifies their correctness or mandates their use.

A formal specification layer would provide what open-source libraries provide informally: verified behavioral standards that implementations can be validated against. The difference is that the specifications would be language-independent, professionally maintained, and authoritative.

Governance

Who writes software building codes? Who enforces them? Who updates them when the field evolves?

The hard part isn’t the technical design. It’s the institutional design.

Building codes in civil engineering are maintained by standards bodies like the International Code Council. They’re developed by committees of practitioners, updated on regular cycles, and adopted by jurisdictions that choose to enforce them. The process is slow, deliberate, and consensus-driven. Deliberately so: you don’t want building codes changing quickly.

A software equivalent would need similar governance: a body of practitioners who maintain the standards, a revision process that incorporates new research and real-world incidents, and an adoption model that allows organizations to opt in at the level appropriate to their risk profile.

This doesn’t have to be top-down regulation. It could start as an industry consortium, organizations that voluntarily adopt and contribute to a shared specification library. The specifications would be open. The validation tools would be open. Adoption would be driven by the same force that drives building code adoption in construction: the recognition that shared standards reduce risk for everyone.

The cost of no standards

The software industry’s lack of professional standards isn’t theoretical. It has consequences.

Data breaches that expose millions of records because basic security practices weren’t followed. Medical software that miscalculates dosages because edge cases weren’t specified. Financial systems that process erroneous transactions because error handling was incomplete. Voting systems that can’t be audited because there’s no specification of correct behavior.

Every one of these failures would have been caught, or prevented, by the kind of behavioral standards that other professions take for granted. Not because standards eliminate all errors, but because they establish a baseline of diligence that prevents the most common and most predictable ones.

The software industry has been fortunate that no single incident has been catastrophic enough to force mandatory regulation. That luck won’t last forever. When it runs out, the industry will either have standards it developed itself or standards imposed by legislators who don’t understand the field.

The missing middle isn’t just a professional gap. It’s a ticking clock.