The stance reads coherently once one distinction is on the table. At every layer where an open specification exists, Actionary implements a thin adapter. At every layer where the “ecosystem” is an opinionated framework masquerading as a standard, Actionary owns the code.
The stance follows Cockburn’s Hexagonal Architecture (2005), Wiggins’s Twelve-Factor App (2011), and Martin’s Chapter 32 “Frameworks Are Details” from Clean Architecture (2017), applied consistently. The adapters are open because the point of an adapter is portability. The core is owned because business logic encodes decisions specific to the domain.
What’s open at the boundary
Seven substrates, each a public specification with multiple compatible implementations:
- PostgreSQL. A standard database dump produces a portable backup of the whole stack, including the vector retrieval index.
- S3-API. Object storage swaps between AWS S3, Cloudflare R2, MinIO, and Backblaze B2 through the same standard interface with a single configuration change. Presigned uploads are the industry-standard shape.
- Redis wire protocol. Any protocol-compatible store — Dragonfly, KeyDB, Valkey, ElastiCache, Upstash — is a swap target.
- OpenTelemetry. Traces, metrics, and logs emit through vendor-neutral OTLP. The application tier stays free of vendor-specific observability SDKs.
- Model Context Protocol. The agent surface is exposed through Anthropic’s open specification. Claude Desktop, Cursor, Zed, Sourcegraph Cody, and Continue.dev all speak it.
- OAuth with DCR and PKCE. IETF-standard trust flows for SSO and machine identity. Any DCR-compliant client can register; any OIDC IdP can be the identity source.
- HTTP with OpenAPI. The public REST surface is described by a machine-readable OpenAPI document; the SPA and any external SDK generate typed clients from it — zero hand-written API types.
Every LLM provider is an adapter too. Anthropic, OpenAI, Bedrock, Azure OpenAI, and Gemini ship as full streaming implementations behind one provider protocol. Per-tenant primary + fallback with automatic failover when a provider is unavailable.
What’s owned at the core
Five layers of code Actionary maintains directly, without an imported orchestration framework:
- The RAG pipeline — extract, chunk, embed, persist against Postgres with the standard vector extension. Hand-written for the domain, retrieval gated by the same per-row visibility the SPA uses.
- The workflow engine — durable execution on Postgres with FOR UPDATE SKIP LOCKED step claims. One fewer stateful service in the deploy topology.
- Agent orchestration — propose-then-execute on the MCP tool surface, with a destructive-confirm staging step. The loop is code the team owns end to end.
- The entity metadata layer — one schema drives the SPA, the admin API, and the MCP tool surface. Adding a field is a database row, not a code change.
- Permission enforcement — Postgres RLS keyed on the tenant setting under a NOSUPERUSER NOBYPASSRLS request role, plus a permissions contract computed server-side on every list response.
The roads not taken, named with reasoning
- LangChain, LlamaIndex. Orchestration middleware. Adopting them means adopting their chain / runnable / retriever abstractions and their breaking-change history. The chunker + embedder + retriever code that already exists is a few hundred lines and does exactly what the domain needs.
- Pinecone, Weaviate. Hosted vector stores. Adopting them means data leaves Postgres — backup surface splits in two, audit surface splits in two, the per-row visibility gate stops applying to the external store.
- Temporal, Airflow. Durable-execution frameworks. Adopting them means a second stateful service in the deploy topology when durable step execution on Postgres already delivers the same idempotent-step guarantee.
- Kafka, RabbitMQ. Dedicated brokers. Redis lists with an orphan sweep against a Postgres state table is enough at Actionary’s shape. A dedicated broker is the right choice when throughput or cross-region delivery guarantees demand it; that threshold is ahead of us.
Every one of these is a valid architecture for a codebase built around them. The stance is about which layer of the stack imports the framework.
Sixteen principles, 1974 to 2024
The architecture is assembled from foundational principles. The full catalogue traces every layer to a principle the industry has agreed on for two decades or more.
- Separation of Concerns — Dijkstra, 1974. Layered backend enforced at merge time.
- Least Privilege — Saltzer & Schroeder, 1975. Multiple DB roles scoped by purpose; RLS at the substrate.
- PoEAA — Repository, Service Layer, Domain Model — Fowler, 2002. One repository per aggregate. Zero inline SQL in routers.
- Domain-Driven Design — Evans, 2003. The metadata-driven entity model is DDD applied to a runtime substrate.
- Hexagonal Architecture — Cockburn, 2005. Two HTTP adapters (REST + MCP) over one application core.
- Twelve-Factor App — Wiggins, 2011. Twelve out of twelve.
- Clean Architecture — Martin, 2012 / 2017. Dependencies point inward; a merge-time check rejects the reverse.
- Trunk-Based Development — Forsgren, Humble, Kim, 2018. Health-gated rolling deploy, expand/contract migration policy.
- Contract-First API — OpenAPI Initiative, 2011 / 2017. Typed SDK regenerated on every schema change.
- OpenTelemetry — CNCF, 2019. Distributed tracing across every service and every LLM provider call.
- Row-Level Security — Postgres 9.5 (2016), popularised by Supabase. Enabled on every tenant-scoped table.
- Zero Trust — NIST SP 800-207 / Google BeyondCorp. Every request re-derives the session kind; every MCP tool call re-checks per-row visibility.
- Feature-Sliced Design — community, ongoing. Applied to the SPA with a merge-time isolation gate.
- Metadata-driven substrate — the industry pattern. Adding a field is a database row.
- One Voice — Kent Beck (1996), Hunt & Thomas (1999), Google Style Guides (2000s+). Every file in the codebase reads as if the same lead engineer wrote it. One naming convention, one error-handling shape, one place for SQL, one comment discipline, one migration shape. Enforced at merge time, not aspired to in code review.
- Model Context Protocol — Anthropic, 2024. One canonical MCP tool catalogue served to the embedded agent and every external MCP client.
One Voice — the codebase reads as if one lead engineer wrote it
An enterprise codebase that has grown feature by feature usually looks like it. Six variants of the same helper, four naming conventions for the same concept, three ways to raise an error. Every new hire reads seven variations of every pattern before they can safely change anything — the cost is paid on every hire, every audit, every acquisition due-diligence read, and every incident-response session at three in the morning when the on-call engineer has to reason about code they have not seen before under time pressure.
Actionary’s engineering rule — the Actionary house term is One Voice — says every file should look like the same lead engineer wrote it. One Generic Repository handles every entity. One place for SQL, checked at merge time. One SPA-to-API contract, verified against OpenAPI at every pull request. One typed SDK, generated from the schema. One error-capture path with no endpoint-level silent catches. One authentication contract — a session_kind string with three values, no boolean flag anywhere in the system that flips to elevate. One naming convention across the tree. One comment discipline: present state only. One migration shape: -- phase: declared, expand and contract sequenced.
The discipline is written down as a repo-wide arc — nine passes, substrate first, one commit per subsystem, the same ten-question audit applied to each chunk. Style consistency treated as on-going engineering practice, not one-off cleanup. Google, Airbnb, Uber, Meta, and the Rust ecosystem run on this bar. So does Actionary.
The takeaway
Every foundational principle is 15 to 50 years old. Every modern principle is production-proven at cloud-scale organisations today — Netflix, Uber, AWS, Microsoft, Apple, Google, Stripe, Supabase. The architecture is a coherent stack of those principles. The substrate it produces is portable at every wire boundary and coherent at every application layer. That is what enterprise-grade means.