Skip to main content
View as Markdown

Changelog

Highlights from each Sovrium release, newest first. For the full commit-level history — every fix and internal change — see GitHub Releases, the canonical source. Sovrium follows semantic versioning; while it is pre-1.0, minor versions can still introduce changes.

Latest: v0.24.0 — 1 September 2026. · Subscribe via RSS

Every release below is listed in the On this page rail — jump straight to any version from there.

v0.24.0 — 1 September 2026

Reading one record and reading many are now two different operators. This is the change to look at before you upgrade. record.read takes a required id and no longer accepts filter. Condition-based reads move to the new record.list, which takes that same filter and adds fields, sort, limit and offset. The old shape was unsound in a way that was easy to miss: a read by condition returned the first row of an unordered query, so which record you got was whatever the database happened to hand back first. Reading by primary key and reading a set are different operations, and they now have different operators. If an automation in your config passes filter to record.read, change its operator to list. Run sovrium validate to find them: since v0.22.0 an unrecognised property fails the config rather than being ignored.

sovrium migrate brings a database's schema forward without booting the app. Until now the only thing that migrated a database was starting the server, which is a poor moment to discover that a migration will not apply. The command takes a config file and exits. Two modes make it usable as a deployment gate: --dry-run names what would change and writes nothing, and --check answers whether the database is safe to upgrade, exiting non-zero when it is not, so a pipeline can stop before it takes the running version down.

You can author a TypeScript config with nothing installed. sovrium types writes a sovrium.d.ts and a tsconfig.json into your directory, and that is the whole setup: no package.json, no node_modules, no install step. The types ship inside the binary, so they always describe the version you are actually running. The @sovrium/types npm package this replaces is retired. Existing versions stay published and a config that imports it keeps working, but new configs should not reach for it.

Inviting someone no longer means handing them admin. A role can now invite people into its own tenant without the full administrator rights that inviting used to demand, which is how team leads ended up administering things they had no business administering. Operators can send invitations and take them back from the console. And when an app asks for access on your behalf, the consent screen now names where it will send you, so you can see the destination before you approve it.

Signed-in users manage their own profile picture. Upload one, remove it, and the file is stored through your own bucket like any other upload. The route that used to accept an image URL from the client is closed: a profile image is something you upload, not a link you hand the server, which is what stopped an account from pointing its avatar at an arbitrary address.

Five things an instance was doing that it should not. A write into object storage is confined to the bucket that owns the key, and a stored file is confined to the bucket it was uploaded to, so a crafted key can no longer reach across buckets. A failed database connection no longer prints the password from DATABASE_URL into the error. A config carrying a __proto__ key is refused rather than silently dropped. And setting a user's password as an administrator now ends that user's existing sessions, which is the point of setting it.

Group grants reach the last gates that were ignoring them. v0.23.0 applied them across record writes and the comment read path; this release finishes the sweep. A caller granted access through a group now gets the write affordances on a page grid, can export a table, and passes the comment and row-level gates. The comment read gate also honours an app's top custom role rather than only the built-in one. If your app leans on group grants, more of it works than did last week.

Editing a grid holds on to your work. An inline edit is no longer lost to a network blip or to someone else saving the same row first. A Kanban card dropped into a new column persists to its bound table without extra configuration. A multi-step form keeps every step's answers when it is submitted rather than only the last step's, and a dropdown can express "no answer" instead of preselecting one for you. Large grids gained a cursor-paginated "load more", so a table with a lot of rows no longer has to arrive all at once.

Pages render a QR code inline, and automations drive short links. The QR component draws what you want encoded straight into the page. On the automation side, a workflow can mint a tracked short link, re-point it at a new destination and retire it, so the links in a campaign are created and redirected by the same automation that sends them. Agents can also read a filtered set of records now, rather than only the whole table.

Also in this release: a record list that selects a column the table does not have is refused; a listing returns the columns it was actually asked for; a record keeps its timestamps through a list field trim; a field type change SQLite would silently mis-store is refused at migration time; a code action whose execute() parameter carries no type annotation is accepted; reading a single record honours the timezone parameter; database errors stay readable so an auth-enabled app can be upgraded; the console shows a declared default the config author marked as non-secret; and the CLI reports a database as unreachable by driver code rather than by matching the text of its message.

v0.23.0 — 28 August 2026

The MCP server now authenticates with API keys instead of a static token. A long-lived shared secret in an environment variable was the whole of MCP access control, which meant it could not be scoped, attributed to anyone, or revoked without restarting the server. An MCP client now presents an API key, and a key belongs to an account, carries that account's permissions, and can be revoked on its own. Every MCP client you have configured needs re-credentialing before it will connect again. Clients that speak OAuth can instead request an access token bound to the MCP endpoint.

AVIF is gone from image transforms, and transforms now work in the compiled binary. They did not, and the way they failed was the worst kind: on a developer's machine the transform produced an AVIF file, and in the container it answered ERR_IMAGE_FORMAT_UNSUPPORTED, because the runtime Sovrium ships with on Linux carries no AV1 encoder. Transforms now produce WebP, which encodes everywhere, keeps transparency, and is roughly a quarter smaller than JPEG at the same quality. If you asked for avif output on an action, remove it — the option no longer exists. Committed AVIF artwork in your own repository is unaffected; this is about what the server encodes at runtime, not what a browser can display.

Three surfaces were removed. The write permission key under a table view is gone — it was never read, so a config that set it was describing a restriction that did not exist. The deprecated /api/admin/buckets/quota route is gone. The data.validateConfig automation action is gone; a sovrium action with a validateConfig operator replaces it. Run sovrium validate before upgrading: since v0.22.0 an unrecognised property fails the config rather than being ignored, so all three of these now stop a boot rather than passing silently.

Relationship columns are typed from the primary key they point at, on every migration path. Some paths inferred the column type independently, so a relationship could end up with a column that did not match the key it referenced — which works until it doesn't. Migrations generated on this version are correct; existing databases are migrated in place. This is the one breaking change with no action for you to take, and we would rather say so than leave you guessing.

Permissions now hold on the paths that were skipping them. This is the change most likely to alter what your app does today. Group grants are applied on every record write gate, on the comment and AI-chat read gates, and on batch create. Field-read permissions are checked on every filter shape and entry point, so a filter can no longer be used to infer a value from a column you cannot read. The ?deleted=true trash bypass is closed and trash is scoped per row. An agent is held to its declared trigger permission on every surface, RAG search is session-gated to tables you can read, and the row-level access-grants table is admin-only. An API key from a banned account is refused, and keys are no longer silently capped at ten requests a day. Where your app relied on one of those gaps, requests that used to succeed will now be refused.

Short links are a new part of the platform. Declare links in your config and Sovrium serves them at /l/{slug}, records the clicks, and generates a QR code for each one. A single link can send different visitors to different destinations, and the operator console shows the split per target alongside the click history. Outbound links a page already contains are now counted too, without you marking them up.

The design system became a console you can look at. A design key now carries your type scale, logo, imagery rules and per-zone voice, and the operator console renders the whole component catalog and every field type in your app's own theme, so you see what your configuration actually produces rather than a generic sample. You can export it as DTCG JSON or as a written brief for an agent, and publish it behind a share link you can revoke.

Automations learned dates, spreadsheets and real-world CSV. There is a date action for formatting, parsing and calendar arithmetic, with timezone- and locale-aware behaviour and a complete add/subtract grid, plus 54 template helpers that were documented but missing. Automations read and write .xlsx workbooks. The CSV actions handle the quoting and line endings that real files contain rather than the tidy ones. Batch record update, delete and upsert are implemented, as is conditional branching. A loop can continue past a failing item when you say so, and one OAuth credential can be shared across unattended automations instead of each one holding its own. You can pause and resume an automation from the console.

The operator console shows more of what the server is actually doing. It reports the running config and the environment variables this instance resolved, searches automation runs and form submissions on the server instead of in the browser, and adds saved views, analytics breakdowns, file deletion, an API-keys page, per-agent conversation history, and a Footprint page reporting the eco levers in force. Scheduled agents now fire on their cron in-process rather than needing an external trigger.

Several ways a value could escape into a page are closed. JSON emitted into a script block is escaped so a value cannot close the block, along with two further hazards that escaping < alone leaves open, and a stored record value is no longer rendered as markup. Query values in the data-source list and count builders are bound rather than spliced, as is the record id on the MCP internal read. Redirects reject a target that resolves to another origin, reject the three shapes that loop the browser, and compare both the verbatim and the canonicalized target. Non-public pages are kept out of sitemap.xml, and canonicalizing a redirect no longer discloses one.

SQLite behaves like Postgres in five more places. Volatile and chained formula fields compute, an agent can read its knowledge base, a capped form accepts submissions, the MCP tool-call audit trail records and reads back, and a view declared materialized is created as a plain view rather than failing. If you run the default single-file database, these were all silently doing nothing.

Erasure now erases. Deleting an account removes the personal data it was leaving behind and sheds the erased user's id from other people's impersonated sessions, activity-log rows past their retention window are actually deleted, and a data export includes the records owned through a custom-named authorship field.

The server exits when you tell it to. A signal handler was cancelling the default termination without replacing it, so SIGTERM was absorbed and the process lived until its supervisor escalated to SIGKILL — ten seconds of waiting on every docker stop. Shutdown is now bounded and exits cleanly, and sovrium stop and restart wait for the process to be gone before returning.

Also in this release: the CLI auto-discovers a config file in the working directory and type-checks code-action bodies during validate and build; app.json is no longer treated as a config candidate; the app theme no longer repaints the admin console; a typo'd ECO_* value is refused instead of silently running the default; configuration rejects non-finite numbers; a record filter or trigger condition naming a column that does not exist is refused rather than matching everything; the CSV export header omits columns you cannot read; the audit trail survives a restart; and declined writes are no longer reported as server errors.

v0.22.2 — 11 August 2026

Pages backed by markdown collections are now cached after their first render, so a documentation or blog page is built once and served from memory after that, with a cap on how much memory the cache may take so small servers stay safe. The stylesheet moved to a content-hashed URL with immutable caching, anonymous pages that skip the render cache may now be briefly cached by browsers and CDNs, and the translations dictionary is no longer embedded twice in every page — repeat visits do noticeably less work end to end.

Boot and search got faster too: the server binds its port before running background maintenance instead of after, so it answers requests sooner, and command-palette searches stop scanning every table unindexed. Database fan-outs are now bounded by the shared pool ceiling, which keeps one busy page from starving the rest.

Two small fixes: the versioned stylesheet route is served correctly and boot finishes before the ready banner prints, and redirects now reject protocol-relative targets (//example.com) instead of following them off-site.

v0.22.1 — 11 August 2026

sovrium build is about twenty-five seconds faster. The build crawls every route your app registers, and it was crawling the development live-reload stream along with them. That stream is built to stay open until its twenty-five second lifetime runs out, so every build sat waiting on it before writing anything. The development-only route is now left out of the crawl, and a minimal build finishes in about a second instead of about twenty-six.

v0.22.0 — 11 August 2026

A config property Sovrium does not recognise now fails validation instead of being ignored. This is the breaking part, and it finishes what v0.21.0 started. A misspelled property used to be accepted in silence, so a typo in a field name or a permissions block looked like it had been applied and did nothing at all. Sovrium now refuses the config and names the property, the path it sits at, and the file it came from. A config that validates and then configures nothing no longer starts either. validate, start and build read your file through the same code, so the three of them can no longer disagree about what it means.

Aliases and inert options are removed. Gone are the legacy config-shorthand rewriting pass, the short --template CLI aliases, the bare S3_* environment variable names, the off / on / auto spellings of ECO_MODE, the meta.priority and meta.changefreq sitemap fields, the currentDateTime automation helper, the boolean comment-moderation shape, the batch-delete route alias and its permanent query flag, and the /_admin/connect-ai alias. Run sovrium validate before upgrading: together with the change above, it now names anything in your config that no longer exists.

Sovrium provisions its own encryption key on first start. It used to refuse to boot without one, which turned the very first run into a configuration exercise before it could be anything else. A new instance now generates a key, stores it, and derives the authentication secret from it, so a fresh install starts with no environment variables set at all. If you already have a key, sovrium secret adopt persists it into the new arrangement. A server still refuses to start with no key rather than running unprotected, while CLI commands that never touch encrypted data run without one. Connections written under a different key now report that plainly instead of appearing to have lost their tokens, and an unreadable signing key is regenerated at boot rather than failing every request that needs it.

The compiled binary no longer embeds local runtime data. A build swept in whatever was sitting in the local runtime directory, which on a working machine can mean a database file and your environment. If you build and distribute your own binaries, rebuild them on this version.

Permissions hold on the paths that were skipping them. A table operation your permissions block does not mention is now denied instead of allowed. A view's read permission is honoured at every level rather than only the outermost one, and an AI agent is refused a knowledge table it is not allowed to read. Admin API routes are gated even when an app configures no authentication, the active-assignment cookie is checked against what the signed-in user may actually see, and role changes can no longer lock the last admin out of an instance or let one admin impersonate another. Where your app relied on one of those gaps, requests that used to succeed will now be refused.

The data grid became an editor. Every field type can be edited in place, including the eight that had no cell of their own and fell back to a raw value. A grid can group by up to three fields at once and summarise each group, a row opens into its full record in one line of config, and a select field can draw its choices from another table's rows. Kanban, calendar and gallery are reachable from the view switcher. The colour a select option declares is now painted wherever that option appears, including on kanban, calendar and timeline, and a grid can tint whole rows by a select field. A frozen column finally stays put when the grid scrolls sideways.

Two migration faults that moved or dropped data are fixed. Adding a table to the middle of your table list could move existing rows into a different table, and adding a field mid-list could drop a column you had declared, because both identities were taken from position in the file rather than from the name. SQLite foreign keys now also survive a table rebuild. Upgrading applies the corrected behaviour, but it does not undo a move an earlier version already made, so check your data if you added a table or a field mid-list on a previous version.

SQLite and PostgreSQL agree in more places. Formula fields compute on SQLite, a declared view works on the default engine, and the ARRAYUNIQUE rollup runs there. Array and attachment fields read back as arrays on SQLite rather than as JSON strings, list-valued fields store correctly when a PostgreSQL record is updated, and a stored duration is read as the seconds its schema declares.

The records API answers with the status code it means. A batch write reports a unique collision as 409 and an empty required value as 400, matching what a single write already did and using the same wording. Batch creates return a usable record id on tables with computed fields, store array values correctly, and no longer discard flat records without saying so. Search text is matched as text rather than as a pattern.

A new sovrium seed command loads relational sample data. A fresh app can be filled with linked records to develop against, and when the database rejects a seeded row the failure names the field and the value that caused it.

Also in this release: pages serve the language the URL asks for; the remaining engine-supplied control labels are translated; an AI field shows when it still holds a locally computed fallback, and a hand-written AI value is no longer reported as a failed computation; AI conversations keep their turns in the order they happened, and agents no longer appear as people in the users console; chart series take their colours from the app theme; and the rich-text and code editors load only on the pages that use them.

v0.21.0 — 1 August 2026

Eight page-component types and twelve config properties have been removed — this is the breaking part, and it takes nothing away. All twenty validated happily and then did nothing: the components never rendered, and the properties configured no behaviour at any point. If your config names one of them it was already inert, and the only change you will notice is that Sovrium now tells you so at validation time instead of accepting it in silence. An option you cannot observe is a promise the binary does not keep, and we would rather break the file than keep the promise.

A table's button field is now a real button. It renders as a control on the record, runs the automation it names, and can be gated per record so it only appears where it applies. Its action vocabulary is closed — a typo is rejected rather than ignored — the listing refreshes and reports the outcome once the run finishes, and the audit log records who pressed it. Automation runs now also carry the user who triggered them, whatever the trigger was.

Code blocks and tabs got the chrome they were missing. Every code block draws a header with a copy button, and can name the file it belongs in or present itself as a terminal session. Tab triggers now show which one is active — the active state was keyed on an attribute the underlying primitive never emitted, so until now no tab anywhere looked selected — and a trigger can carry a subtitle under its caption. Tab and accordion captions are translated like the rest of your copy. There is also a new marquee component, for a band of logos or notices that scrolls on its own.

theme.darkColors reaches the stylesheet. The schema has accepted it for some time and then discarded it; a dark palette declared there now compiles and applies.

Permissions and validation are enforced on the paths that were skipping them. Field-level write permissions and multi-select limits now hold on bulk updates as well as single ones. Rich text is sanitised on every write path, not only on create. Email and URL columns are validated on update. Delete and field-read permissions are enforced on every query path rather than on some of them. Rate limits can no longer be bypassed by forging a forwarding header, and a failed batch write reports what was wrong with the request instead of leaking database internals. If your data relied on any of those gaps, writes that used to succeed will now be refused — which is the point.

Erasing an account now erases all of it. Form submissions are covered by both export and erasure, three lingering traces are gone, and a user assigned on someone else's record can finally be erased at all: a foreign key made that impossible before.

SQLite and PostgreSQL agree in more places. Dynamic tables store timestamps as timestamptz, SQLite soft-delete timestamps are written in ISO-8601, and indexes are removed reliably when a table name contains spaces.

v0.20.0 — 27 July 2026

Collection pages and page data only worked if you set DATABASE_URL. The data-source reader opened its own connection instead of using the one the app runs on, and returned an empty result whenever that variable was unset — which is the shipped zero-config default, where Sovrium runs on SQLite. Nothing was thrown and nothing was logged, so the failure was silent: collection pages answered 404 as though the record did not exist, page data sources rendered empty, and row-level permission overlays granted nothing. Reads now go through the app's own connection on either engine. GREATEST and LEAST formulas also translate to SQLite, instead of working only on PostgreSQL.

Attachment fields now honour the bucket they declare — this is the breaking part. A field declaring bucket: documents had its URLs bound to default anyway, and the two documented attachment types were never enriched at all. Fixing both changes the shape of the value you read back: single-attachment returned a bare key string and multiple-attachments an array of them, and both now return objects carrying key and a bucket-bound signed URL — in records API responses, in exports, and over MCP. Rows that already stored metadata keep their existing fields.

That binding also closes a real exposure. The signed URL was minted without ever checking who is allowed to sign, so on a bucket gated sign: ['admin'] any reader of a record received an admin-equivalent, session-free download URL. Buckets now enforce the upload, download and delete permissions they declare, which config previously accepted and then ignored.

Forms say what is actually wrong. A request with several invalid fields reports every one of them instead of stopping at the first. Single-character values are accepted where the schema allows them, field errors surface on the form itself, and a record saves when a constrained field is simply left untouched. An upload rejected for being too large now says so, rather than failing without a reason. Forms served at a path you chose enforce the same access and availability rules as forms at their default path.

Comments. autoApprove.previouslyApproved is honoured, so a commenter you have already approved is not queued for review again. A rejected comment answers with a rejection instead of 201 Created.

Also in this release: a redirect can set localizeTarget: false when its destination should not follow the visitor's language prefix; deleted-by is accepted by sovrium validate, so the soft-delete audit pair passes validation; a field named user_id is no longer discarded by the records API; database failures answer with the status code they mean; reported errors carry their full cause chain to stderr and to your error backend; and the admin tables overview runs one query per table instead of fanning out.

v0.19.0 — 25 July 2026

Redirects. A config can now declare the URLs it used to serve. Add a redirects list naming each retired path and where it went, and Sovrium answers those requests with a real HTTP redirect instead of a 404 — so bookmarks and inbound links survive a restructure, and search engines carry the old URL's standing over to the new one. Path targets follow the visitor's language prefix, so one rule covers every locale.

Password recovery in the operator console. Signing in to the admin space now offers a reset flow, so losing an operator password no longer means editing the database by hand. Reset emails point at a path the app actually serves, which they previously did not.

Automations tidy up after themselves. File actions now reclaim their aged temporary files rather than leaving them to accumulate. Run history also redacts secrets from step output, so a token passed into a step no longer appears in the record of that step.

The default look changed — this is the breaking part. If your app sets its own theme colours, nothing moves. If it takes the defaults, it will look different after upgrading.

  • Colour is reserved for consequence. The default palette is achromatic, and error is the only ramp that keeps a hue. Success, warning and information states are carried by weight, position and wording instead. When colour appears in a Sovrium interface, something has gone wrong.
  • Self-hosted typography: IBM Plex Sans and JetBrains Mono now ship with the binary as inlined variable fonts. No Google Fonts request is made — by your app or by any starter template. The retired serif companion is removed.
  • The decorative accent is gone from the engine. An app that wants an accent declares its own colour key in app.theme.colors; the shipped default no longer imposes one.
  • Fixes surfaced along the way: the command palette now follows your theme and is legible in dark mode; subtle text meets WCAG AA on every render path; and interactions.click.animation: 'pulse' / 'bounce' play their intended click feedback instead of being overridden by a same-named framework animation.

Also fixed along the way: the command palette renders from theme tokens instead of hardcoded colour, so it is legible in dark mode; and interactions.click.animation: 'pulse' / 'bounce' play their intended animation instead of colliding with Tailwind's built-ins of the same name.

v0.18.1 — 25 July 2026

Corrections to the observability release and to two surfaces that were reporting the wrong thing.

  • Errors keep their status code. A reported error now arrives with the HTTP status it actually returned, so a 404 is no longer indistinguishable from a 500 in your issue tracker. Secrets are stripped from reports before they leave the instance.
  • Debug logs reach your collector. With LOG_LEVEL=debug, debug lines are now included in the OTLP export instead of printing to stdout only.
  • Admin overview counts are correct. Record, form-submission and storage totals on the operator overview were miscounted; they now match the data.
  • AI chat works on SQLite. Chat record queries and mutations failed on the default SQLite dialect and now behave as they do on PostgreSQL.

v0.18.0 — 24 July 2026

Sovrium can now report its own errors, logs and performance to an observability platform you run. Everything in this release is off by default and enabled per environment variable: no telemetry leaves an instance unless an operator points it somewhere.

  • Error reporting: uncaught errors can be sent to any Sentry-protocol endpoint — self-hosted GlitchTip, Sentry, or another compatible collector. The startup banner states plainly whether reporting is on and where it goes.
  • Structured log export: application logs can be exported over OTLP-HTTP while continuing to print to stdout, so adding a collector never costs you the logs you already read.
  • Performance transactions: HTTP requests can be sampled as timed transactions, at a rate you choose, to see where real time is spent.
  • Trace export: an OTLP trace layer ships dormant, ready for distributed tracing without another upgrade.
  • Configuration: every observability variable is documented in .env.example, so the full surface is visible before you turn any of it on.

v0.17.0 — 21 July 2026

Documentation pages gained clearer chrome and real syntax highlighting, and existing databases now survive schema evolution more reliably on both dialects.

  • Docs navigation: documentation breadcrumbs now anchor to the docs tab root, and every docs page ends with a contribution footer for suggesting edits or reporting issues.
  • Syntax highlighting: the code component renders with Shiki highlighting out of the box, and author-set attributes on code blocks are preserved through the highlighter.
  • Steadier live reload: watch mode debounces config reloads so a file save is never read mid-write.
  • Schema evolution fixes: an app now boots cleanly against existing PostgreSQL data when a CHECK constraint tightens, and against an existing SQLite database after schema changes.

v0.16.0 — 20 July 2026

The self-hosted engine sharpened its focus, and published demo instances gained a friendlier front door.

  • The managed-Cloud feature domain and the agent-templates feature were removed from the binary, keeping the self-hosted product config-code-only.
  • Publish a demo: instances published as demos can show an opt-in demo notice with one-click sign-in prefill, so visitors try a real app without hunting for credentials.
  • Smarter form redirects: post-submit redirects now resolve translation keys ($t:), $record.<column> variables, and embedded or hidden $query prefill.
  • Multi-select member fields build their validation on the option value, and the admin overview roll-up is bounded so it no longer times out under load.

v0.15.2 — 19 July 2026

A rendering and caching fix for the compiled binary — popup surfaces built from runtime theme variables now paint correctly, and asset cache-control headers no longer let a stale island chunk stick around.

v0.15.1 — 18 July 2026

Repeated upgrades are safe: re-initializing a dynamic table's schema on boot is now idempotent, so restarting on a newer version never re-runs work it already did.

v0.15.0 — 18 July 2026

A correctness and theming pass.

  • The default theme now ships shadcn-convention alias utilities, so components written against that vocabulary style correctly out of the box.
  • read: all tables are readable by anonymous visitors, as configured.
  • The data-table "new record" control is fully localized.
  • Kanban boards group correctly by a colored single-select field, and production hydration no longer breaks on empty island split-chunks.

v0.14.0 — 17 July 2026

Templates became a first-class way to start, and the navbar and docs grew up.

  • Start from a template: sovrium init can scaffold directly from a remote GitHub template repository, and every template ships with its own deploy and mirror files.
  • New business-app templates — projects, helpdesk, content calendar, people, events, assets, expenses, a knowledge base, automation recipes — plus the company-os flagship that ties them together.
  • The "Built with Sovrium" badge, on by default with a documented one-line removal.
  • Navbar hover-to-open dropdowns with badges and a rotating chevron.
  • The documentation sub-navigation was re-sliced into eight product tabs.
  • AI agents boot inert when no provider is configured — no key, no crash.

v0.13.0 — 14 July 2026

A hardening release across tables, forms, auth, and delivery.

  • Many-to-many fields split and resolve correctly on record create, update, and read, including on view-backed tables.
  • Admin-equivalent roles bypass field-level write permissions, and a resolved top custom role no longer gets caught by row-level scoping.
  • Embedded forms localize per host locale, and record actions are attributed to the triggering user.
  • The RSS feed's channel identity is driven by the page's own meta, and the docs "last updated" date renders in the active locale.
  • An opt-in, env-gated 301 redirect maps a legacy host to its canonical path.

v0.12.1 — 12 July 2026

Restored the released baseline migration's identity, undoing an illegal history squash — the upgrade path from earlier versions is safe again.

v0.12.0 — 12 July 2026

The native admin dashboard arrived, and every data component learned to read from the platform's own APIs.

  • Native admin dashboard: an auto-mounted, admin-only operational console at /_admin for viewing and operating on your app's runtime data — records, automation runs, form submissions, connected accounts, uploaded files, agent conversations, and page analytics. It is read-and-operate over data only; configuration stays code, edited in app.ts / app.yaml and re-deployed.
  • System data bindings: lists, tables, calendars, kanban boards, galleries, timelines, charts, KPIs, and record drawers can now bind directly to a platform read endpoint, so a page can render live operational data with no custom code.
  • A global, indexed admin search (⌘K) that deep-links straight to any record.
  • Docs authoring: an "Edit this page" link (contentDir.editUrl), a per-page markdown export, "Copy / View as Markdown", and a "Last updated" stamp.
  • GDPR self-service: data export and account erasure that work on the SQLite default, not only Postgres.
  • RSS feed items can be sourced from a markdown-file page.

v0.11.0 — 17 June 2026

The marketing site and the release engine both grew up.

  • Rebuilt the marketing website on Sovrium's own design system, with an ambitious hero and a real customer trust band.
  • Added a competitor-comparison SEO library at /compare — a single consolidated page family covering how Sovrium stacks up against common alternatives.
  • RAG Phase 2: opt-in sqlite-vec approximate-nearest-neighbour search plus FTS5 hybrid retrieval, so AI features can ground themselves in your own data on SQLite as well as Postgres.
  • Approval-gated automations: an automation run can now pause for a human decision and resume once someone approves or rejects it, and an alert-dialog confirmation on a page can dispatch its configured automation action.
  • Documentation overhaul: a new navbar and search, a collapsible sidebar, a "View as Markdown" link on every article, and table-of-contents scroll-spy.
  • Auto-generated /llms.txt and /llms-full.txt so AI agents can read the whole docs corpus in one request.
  • Cloud: usage rollups and monthly invoicing went live.
  • A theme toggle with a light-first default and no flash of the wrong theme on load.

v0.10.0 — 2 June 2026

AI came to SQLite, and the MVP reached feature-complete.

  • AI on SQLite: retrieval-augmented generation now works on SQLite via BLOB embeddings with app-side cosine similarity, and AI-compute fields run on both database engines — no Postgres requirement to use AI.
  • Public comments with moderation: guest identity is captured on submit, and an admin queue lists pending, approved, and rejected comments.
  • Cross-engine correctness: aligned SQLite and Postgres value serialization and ISO-8601 timestamps, and mapped numeric precision to SQL scale.
  • Sovrium reached a feature-complete MVP — the remaining work is production hardening, not net-new features.

v0.9.0 — 31 May 2026

A stabilization release, consolidating the large capability wave from v0.8.0.

v0.8.0 — 25 May 2026

The broadest single release so far — most of the page and form toolkit, the full CLI, and the admin consoles landed here.

  • Record detail pages: breadcrumbs, related-record lists, and previous/next navigation between records.
  • Runtime views: sort and column-visibility controls that readers can change without editing config.
  • Form controls: date and time pickers, combobox, slider, switch, checkbox, radio group, number input, and a drag-and-drop file dropzone.
  • Page layout components: tabs, accordion, callout/alert, dividers and spacers, an app shell with sidebar, a drawer, and a hover card.
  • The complete CLI: init, start, build, schema, validate, agents, version, and help, each fully specified.
  • Admin consoles for buckets, forms, and automation runs, plus an operator-controlled low-data render mode.
  • Database groundwork: SQLite dynamic tables now use INTEGER ids, and view-backed tables get INSTEAD OF triggers so computed columns stay writable.

v0.8.1 followed on the same day, preserving auto-generated lookup views across restarts.

v0.7.0 — 23 May 2026

Maintenance and release-tooling releases (through v0.7.2 on 24 May).

v0.6.0 — 22 May 2026

Markdown pages arrived — the same engine this changelog and the docs site run on.

  • Markdown pages: GitHub-flavoured markdown, Shiki server-side code highlighting, :::container::: directives that render as real components, $t: translations inside the body, and collection navigation with previous/next links.
  • CLI: three starter templates, with a paired AI agent auto-installed on sovrium init, and TypeScript config files supported in build and schema loading.
  • Runtime artifacts consolidated under a single .sovrium/ data directory.
  • Developer experience: live reload injected in dev (and absent in production), and cache bypass flags for fast iteration.

Patch releases v0.6.1 and v0.6.2 hardened the release pipeline.

v0.5.0 — 21 May 2026

Sovrium became a single self-contained binary.

  • Database migrations, client and island bundles, and the init example configs are all embedded in the compiled binary — no external files to ship.
  • The engine resolves its own version from a build-time define, so --version and the OpenAPI document are correct in a compiled binary.

Patch releases through v0.5.3 fixed declaration-emit and packaging details.

v0.4.0 — 14 May 2026

The first public distribution channels.

  • Homebrew tap, Scoop bucket, and checksummed release archives.
  • The zero-dependency @sovrium/types package published to npm for typed config authoring with defineConfig.

A run of same-day patch releases (v0.4.1–v0.4.10) stabilized the new release CI.

v0.3.0 — 8 May 2026

  • A "coming soon" feature-flagging system for marking work-in-progress capabilities (later retired once the platform reached feature-complete).
  • A firmer runtime contract for code automation actions.

v0.2.5–v0.2.11 — March 2026

The first tagged releases. The schema engine, dynamic tables, and the configuration interpreter took their initial shape.

Last updated September 1, 2026

Built with Sovrium