← All insights

The Four Pillars of Extensibility Haven't Changed in 20+ Years. Everything Around Them Has.

The four pillars of extensibility and the substrate beneath them

The most satisfying thing I ever designed, I designed about 23 years ago — an extensible platform where customers and integrators could build on top of what we shipped and assemble solutions we never anticipated. What made it satisfying wasn’t any clever trick. It was that the architecture held.

I’ve spent the years since watching extensibility get reinvented over and over. As I design for AI-native, multi-tenant systems now, the principles I relied on back then have aged remarkably well. The ground beneath them, however, has moved completely. Most teams get one half of that wrong: they assume either that nothing has changed, or that everything has.

AI agents are, in many ways, the newest consumers of extensibility frameworks. The difference is that the consumer selecting extensions is often another machine — and that changes a surprising amount.

The part that didn’t change: four pillars

Strip any serious extensible platform down to its load-bearing structure and you’ll find the same four things, whether it was built in 2003 or last quarter.

If you’re building anything meant to be extended — a platform, an agent system, an internal framework — these are still the bones.

The part that changed: the substrate beneath every pillar

Isolation became a security boundary

When extensions ran on a developer’s own machine, isolation was mostly about robustness — crash and you only hurt yourself. Today, extensions from one customer often run beside another customer’s data on shared infrastructure. Isolation is no longer a nicety; it’s the thing standing between a bug and a cross-tenant breach. Many sandbox-escape vulnerabilities trace back to the same shortcut: running third-party code inside the same process as the core and calling it “sandboxed.” It isn’t. The single most expensive mistake in modern extensibility is treating isolation as a performance optimization you’re allowed to skip.

Dispatch became probabilistic

In my old system, a human wired each extension into a workflow at design time — deterministic and inspectable. AI-native systems often decide at runtime which extension to invoke by interpreting descriptions, capabilities, and context. An extension is only usable if it ships a rich, machine-readable description of what it does and when to use it — and that description becomes part of the contract. Reword it and you may silently change when the system invokes the extension, with no compiler to catch it. The failure is subtle: the extension still works when called, but the system gradually stops choosing it when it should. That demands a different category of testing — you’re validating routing decisions, not just behavior.

Trust boundaries now wrap everything

Modern platforms act on behalf of users, organizations, and other systems while enforcing strict authorization — and extensions live inside that trust boundary. Two requirements follow. First, extensions must never assert their own identity or authority; the platform injects identity and re-validates authorization on every action. The extension is a guest inside the trust boundary, never the owner of it. Second, anything an extension returns or retrieves must be treated as data, not instructions — free text can carry hidden commands or prompt-injection attempts. Output is content, not a control signal.

What “any language, mix and match” means today

The feature people loved most was freedom — build in any language, compose freely. Back then that depended on a shared runtime and reflection-based discovery. Today, portable sandboxed execution environments let extensions in different languages run safely behind a common contract. The important shift isn’t portability — it’s capability control. Modern extensions are inert by default: no network, filesystem, secrets, or external resources unless the platform explicitly grants them, visibly and auditably.

If I were designing a modern extensibility platform today, I’d organize execution tiers around trust rather than language:

The rule is simple: use the cheapest isolation tier that still holds, and never let convenience pull untrusted code into a tier it hasn’t earned.

The discipline that makes it survivable

The honest trade-off

Real extensibility is not a feature — it’s a platform investment. You’re committing to registries, runtimes, signing pipelines, certification, isolation infrastructure, metering, governance, and entirely new categories of testing, permanently. What you buy in return is the thing that made that system 23 years ago so satisfying: you stop forking your core to satisfy individual customers. Everyone extends the same spine — safely, independently, in parallel. For products serving genuinely different needs, that bargain is usually worth making. For narrower products, it can be elaborate over-engineering wearing an architecture diagram. Knowing which situation you’re in before you commit is the real senior decision.

The four pillars haven’t changed in 23 years. The security model, trust boundaries, and execution environment around them have changed completely. Build for both realities at once, and you build something that holds.

Related

Keep reading

Let's talk

Bring this thinking to your AI program.

If any of this maps to a problem you're facing, let's talk it through — get in touch.