Content infrastructure · Open source
Polynovea Content Operations Platform
An open-source, self-hosted content and data operations platform with headless CMS capabilities, covering structured content, schema modelling, editorial workflow, releases, delivery and governed developer access.
Overview
The Content Operations Platform, released as Polynovea CMS, is an open-source system for running content as an operation rather than storing it as records. It covers structured content models, visual schema modelling, editorial workflow and approvals, releases, delivery, discoverability and content health, all inside isolated workspaces.
It ships with a browser admin, a scoped developer API, a TypeScript SDK, a CLI and an MCP transport, so AI agents can work with content under the same permissions as people.
The problem
Headless CMSs are good at storing structured content and weak at everything around it: who may change what, how changes are reviewed, how a set of changes ships together, and what happened afterwards. Teams fill those gaps with spreadsheets, chat threads and manual publishing.
The platform started as Polynovea’s own content tooling, where an informal free-text “entity” column was standing in for a real ownership boundary. Making it open source meant replacing that with real tenancy and real governance.
Constraints
- Self-hostable. It has to run on infrastructure the adopter controls.
- Portable, within reason. It shouldn’t be locked to one provider, but promising every database engine would explode the scope.
- Secure by default. Browser clients must never hold privileged credentials, and every action must be attributable.
- Extensible without backdoors. Extensions and AI agents need access, but only what an administrator has granted.
My role
I designed the architecture and the product, and set the decision records that define it. The code is written with Claude, working to those decisions.
Reasoning and architecture
The design is recorded as architecture decision records in the repository. The key ones:
- Workspace is the security boundary (ADR-001). Brands, sites and entities are subordinate dimensions inside a workspace, not substitutes for one. The historical free-text column was not retrofitted into a boundary it was never designed to be.
- Portable PostgreSQL core (ADR-011). The contract is PostgreSQL-compatible across providers: Supabase, AWS RDS/Aurora, Azure and vanilla PostgreSQL. Not MySQL, MongoDB or anything else. A precise contract beats a vague “cloud-agnostic” promise.
- Provider features are adapters (ADR-012). Supabase-specific capabilities are used, but isolated behind narrow boundaries such as a single identity-to-actor translation point, so another deployment can swap them without touching the core.
- CMS actor versus external identity (ADR-013). Every request resolves to a CMS actor with workspace membership and role permissions. There is no hardcoded admin bypass; the first owner is created by a server-only bootstrap command.
- Browser
- Route handler
- Resolve CMS actor
- Check workspace permission
- Service layer
- Write audit evidence
Implementation
A Next.js application over PostgreSQL with Row-Level Security, 67 ordered migrations applied by a runner that stops on the first failure, and a persistent delivery worker for publishing, scheduled releases, webhooks, indexing, image processing and health checks. Media goes through an S3-compatible storage interface.
Developer access goes through least-scope workspace API tokens. Extensions declare their permissions, routes, events and network origins, and a workspace administrator must approve them before they activate. The MCP client follows the same scopes, approvals and audit rules as everything else.
Evidence and outcomes
- Public repository under the MIT licence, with self-hosting, upgrade and migration documentation.
- Architecture decision records covering tenancy, security, schema, portability and identity.
- Released as an alpha. Adoption figures aren’t claimed here.
Verdict
- Keep: a written portability contract (PostgreSQL across four providers, nothing else) with provider features behind adapters. It’s why the same core now runs self-hosted and as MellowBase.
- Change: make bare PostgreSQL a supported runtime. The application still relies on Supabase-compatible auth and data APIs, and the adapters are already in place to remove that dependency.