Skip to content

Changelog

Every production release of Combine Data Controller, newest first.Subscribe by RSS.

v3.4.0

Processes can now handle their own failures, wait on time and end on purpose, and a new HTTP Process type gives every HTTP endpoint one clear shape. Two entries carry an upgrade step, so read "Before you upgrade" first.

Before you upgrade

  • Remove from each Draft process any BPMN element the save now refuses; Published versions keep running.
  • Give each plugin frontend a route path of /ext/ and one lowercase name that no other plugin uses, before its next publish.

New

Processes handle their own errors, wait on timers and end on purposebpmn-elementsAction required

A process can now route a failure instead of failing. An error boundary event on a task, an embedded sub-process or a Call Activity catches a task failure, after its retries, or an End error by its code, and the process goes on along the boundary flow. An event sub-process with an Error start handles every uncaught error of its scope in one place. An End error event ends a branch with a business error code and name, and a Tool Process that ends in one answers its Agent or MCP client with `process_error` and the code.

Escalation asks for attention without failing: Throw escalation and End escalation reach an Escalation boundary event, which can be interrupting or non-interrupting. A Terminate end event stops a whole process, or one sub-process, at once.

A Catch timer waits for a duration or until a date, survives a restart and fires once only across hosts. An Event-based gateway races a Message catch against a Catch timer, so a process can wait for a reply with a deadline. The Inclusive (OR) gateway runs every branch whose condition is true. A Conditional start starts a process when committed data of a Domain model meets a JSONata condition, read under the start's own identity.

Import, Draft save and publish now refuse, and name, a BPMN element the engine cannot run, so no event runs silently as another kind of event.

HTTP Process — one process type for every HTTP endpointprocesses

A new HTTP Process type answers an HTTP caller. Publish checks that it has one HTTP Start and that every path ends in an answer, and the designer palette offers only the elements an HTTP Process allows.

Convert a Process with HTTP elements in one step; its endpoint and Operations keep working. An import converts the matching Process on the target, so promotion needs no manual step. HTTP elements in a Process are deprecated and leave its palette; existing ones publish until the next major version.

Agent usage — see the tokens every agent and model usedagents

A new Agent usage page shows the tokens agents and models used over 12 months, by model, chat, process step and draft. Every model call now counts, stopped turns, tool loops and System model drafts included, and earlier usage is copied in.

A denied Egress step says why governance refused the readbpmn-elements

A denied Egress step now carries `reason` and `rules`, so a gateway can branch on why governance refused the read.

Plugin frontend types install from npmplugins

Plugin frontend authors can install the mount-context types as `@combinedk/plugin-host` from npm, with no token. Each CDC release publishes the package at its own version, so a plugin no longer keeps a copy of the types.

Endpoint plugins read a process's HTTP contract and a model's kindplugins

Endpoint plugins can now read a process's HTTP start and end events through IProcessDefinitionCatalog, and a model's kind, such as a Value model, and its description from IModelDefinition.

Improved

The designer palette drops the disabled "AI / Agent" elementbpmn-elements

Use the Agent task to run an agent as a step in a process.

A configured frontend origin applies in Development toosettings

Sign-in now works from any port the app runs on in Development.

Dependencies updatedsettings

Ten updates to the frontend libraries and one to the website's XML parser. None of them is visible on its own.

Fixed

A plugin frontend mounts at one checked /ext/ pathpluginsAction required

A plugin frontend now mounts at /ext/ and one lowercase segment; upload warns and publish refuses a bad or taken path. A sidebar item no longer opens nothing, and one plugin can no longer take over the pages of the others.

A read of an older model version hides fields only a newer version hasgovernance

A Placement now governs such a field on every read, and the Data Browser no longer refuses a page that mixes records written before and after a field was added.

A Placement on a retired field protects the older recordsgovernance

A Placement on a field that a newer model version dropped now applies on every read, so the Data Browser no longer shows such a field in clear text when it reads through the newest version.

The trail shows a read refused after its decision as Refusedgovernance

A read refused for a filter on a hidden field, or for an untreatable demand, now shows as Refused with its Rule. Reads refused before this release still show as allowed on the trail.

A large Ingest batch no longer fails other steps' audit writesinstances

A batch held the audit chain for 54 to 134 seconds, and other steps failed with "Master could not store the audit". It now holds the chain only while it commits.

Plugin pages load for every signed-in userplugins

A page that checks its own permission now reaches the people it is for. Reading or changing plugin data still needs the Plugins area scopes.

Endpoint plugins read enums stored by name, and refresh after one restartplugins

An endpoint plugin can now read its own entities when an enum value is stored by name, as the designers store them. In development, a rebuilt endpoint plugin serves its new routes after one restart instead of two.

A process with an HTTP start needs an HTTP end to publishbpmn-elements

Before, a process whose only ends were End errors passed, so a successful call would never get a response.

Aspire 13.6.5 fixes an elevation of privilegesettings

The AppHost now runs on Aspire 13.6.5, which fixes CVE-2026-120006.

A standalone Engine starts in Developmentengines

It no longer stops at start on services that only Master can run.

An agent run's label reads the same on every serverinstances

A run an agent starts is labelled "Agent · 09:41" on every server, not "Agent · 09.41" on a Danish one.

v3.3.0

AI now reaches CDC through governed paths only: publish an MCP server for Claude Code and other AI clients, give agents Tool Processes that return their output, and let CDC draft descriptions and prompts with a System model. Two entries carry an upgrade step, so read "Before you upgrade" first.

Before you upgrade

  • Create a Tool Process for each Agent or MCP server process tool, point the tool at it, and publish again.
  • Deploy Master and the engines together; a Master without this release refuses every Region mask Demand.

New

MCP server — reach governed data from Claude Code or any AI clientagents

Publish an MCP server and connect Claude Code or another AI client to CDC, signed in as yourself. Every read is governed exactly as in the web app, and a process that a call starts names you as its Requester, so the trail shows who asked.

Tool Processes — an agent's process tool now returns the process outputagentsAction required

An Agent or MCP server process tool now calls a Tool Process, waits for it to finish, and hands the process output back to the agent. The tool's picker offers only Tool Processes, and a publish refuses a process tool that points at any other kind of process.

System model — CDC drafts descriptions and System prompts for youagents

A new System → Settings page lets an administrator choose the System model: the AI connection and model CDC uses for its own help.

With it, Generate drafts the Description of an agent, an MCP server and every tool type, from processes and forms to domain queries and the admin tools. It suggests an agent's System prompt, or improves yours, and says when to call each tool. Generate all fills every empty start parameter Description of a process in one go. You review each draft before you save it.

Masks can keep the first characters, so a CPR number shows its birth dategovernanceAction required

A mask Rule can now keep the first characters instead of the last, and hide the rest. When a Region mask and a stricter Principal mask keep opposite sides, the field is anonymised, and the effective policy view says why. The Model mirror marks in advance a mask that will become anonymise for some Requesters, and gives the reason.

A plugin upload is a Draft you test before you publish itplugins

A plugin upload or import is now a Draft: test it in a debug run, then publish it with the processes that use it. Plugins can be archived, unarchived and deleted by the same rules as models and processes, and each step is audited.

Map a plugin task's input one field at a timeprocesses

A plugin task's input now maps one field at a time, as an Agent Task's Outbound Model does. Every value suggests paths and checks its JSONata, and a JSONata group or list opens its own editor with a skeleton to fill in.

Governance Models opens on an overview of every governed modelgovernance

A table lists every governed model with its fields classified, the Rules in force and its packages. Sort it, filter it by kind, and open any model's Model mirror from its row; the mirror links back to "All models".

A Rule's page shows every saved version, and who changed whatgovernance

A Rule's page lists every saved version, opens each one read-only, and shows who saved it and what it changed. While you edit, it shows your unsaved changes against the saved Rule before you save.

Every Governance page shows whether you run in permissive or strict modegovernance

The mode now sits beside the title of every Governance page. Point at it to see what the mode means, such as models not yet activated being delivered as stored.

Rename a chatagents

Point at a chat in the chat list, click the pencil icon and type the new name.

Improved

Agent Tasks — set up what goes in and what comes back, and the run carries onbpmn-elements

Set up an Agent Task as what goes to the agent and what comes back, with drag-and-drop Instructions. With an Outbound Model, the Instruction is plain text, so only the model's fields reach the agent. The answer schema follows the Inbound Model at each run, and the agent is told which fields to answer.

An Agent Task now gets the agent's answer and continues, where a run used to wait at the task for ever. An answer inside a markdown code fence is accepted, and the result arrives as success and data, so a gateway can route a failure. Long warnings now wrap inside their column.

Plugin contracts stay out of the way until you ask for themmodels

The models list, every model picker and the model export now show only the models a person made. Plugin contracts travel with their plugin, and importing the plugin generates them again. API clients get the same list from GET /model-definitions, and can pass generated=include for the rest.

Governance Models and the Work queue list only the Plugin contracts that a Draft or Published process uses, so stewards see real work. Tick Show unused Plugin contracts to list them all. A Plugin contract's page names the plugin and the method it comes from.

A plugin task's mapping preview runs the mapping, and can pin the resultprocesses

The preview now evaluates the mapping, and can pin or edit the result as the next run's input. The whole mapping opens in the JSONata editor over the form, and an amber bar shows where a dragged field lands.

Place a Rule straight from the Work queuegovernance

A field that no Placement reaches can now get a Rule placed directly from the Work queue, not only a Classification. The whole review of unreached fields can be done there, without opening each model.

Placing a Classification shows which fields a Rule already reachesgovernance

A field that a Rule already reaches is disabled, and a refused placement lists the routes. The Model mirror marks a redundant Placement, and impact previews list the Placements a change makes redundant.

The Model mirror tells Classifications from Rules at a glancegovernance

Classifications and Rules have different chip shapes, and each field shows its Inherited placements locked. The topbar lists what governs the whole model, and screen readers name every chip.

Rules and Classifications look the same on every Governance screengovernance

The same chips appear on every Governance screen and in the Data Browser governance panel, including the impact preview and the Rule picker. Rule outcomes name each Rule in bold.

Governance Models groups the models by typegovernance

Each group can be opened and closed, so the list stays short when an installation has hundreds of Exchange Models.

A governance change made by an API Client names the clientgovernance

The author now reads as the client, such as orders, instead of a raw subject id. Changes saved before the upgrade keep the author they were saved with.

A chat shows the tools an agent called on one lineagents

Tools an agent calls in a row now show as one grey "Used N tools" line above its answer. Click the line to see each call, and click a call to see its arguments and result.

Chat and Agents stay hidden until an AI provider is configuredagents

The menu no longer leads to pages that fail on an installation without an AI provider.

An agent's Dependencies open in a modalagents

Open them from the Dependencies icon in the agent's header, as on a model's page.

The designer's Variables list shows a start's parametersprocesses

The parameters a Manual or Timer start declares are listed, ready to drag into a mapping.

A new process opens straight in the designerprocesses

Create a process definition and start modelling it right away.

Retries no longer depend on the Polly library directlyengines

CDC gets Polly only through Microsoft's resilience packages. Retry behaviour is unchanged: a failed database write still retries up to two times, after 100 ms and then 200 ms.

Dependencies updatedsettings

Three updates to the frontend libraries, and the Aspire packages moved to 13.6.4. None of them is visible on its own.

Fixed

A refused operation on the Trail names the fact each Rule waited forgovernance

Continues the work on Rules that decide on the facts of the request, first released in v3.2.0.

A refused operation on the Trail page now shows the fact each refusing Rule waited for, such as requester.where. Operations stored before this release still name their refusing Rules, without the facts.

A new deployment's sign-in works from the first startaccess

The identity realm is set up again on first start, so the default Groups, Scopes and sign-in work. Keycloak had refused one scope description as too long, which left a fresh realm without them.

Act as group offers only the Groups in Accessprocesses

A typo on a start event can no longer slip past every Rule. Publishing refuses a Group that Access does not have, for every publisher, and names the start event and the Group.

An import of a model and its base model lands in any ordermodels

Before, an export zip of a model family often failed and rolled back with a database error.

A Rule in a Data Browser note opens the version that decided the readgovernance

It used to open the newest version. The branch that decided is marked and scrolled into view, so you see at once why.

AI agents and MCP clients can filter on a field inside a listagents

Filter records on a field such as lines[*].sku on an order's lines. A matches filter on such a list used to return nothing; it now explains the path to use instead.

A JSONata group or list keeps your text while you typeprocesses

It no longer resets or switches editor. Its check dot turns amber and names the required fields that the expression still leaves without a value.

Line numbers in the JSONata editor stay next to their linesprocesses

They stay in place in long, wide or scrolled mappings.

A run's default label shows its start time as 09:41 againinstances

On servers set to a culture such as Danish, manual starts and runs started by an agent or an MCP server read 09.41 before.

New agent says why it could not create the agentagents

The button on the Agents page used to do nothing.

A Domain query tool shows the model's nameagents

The agent's page used to show the model's id.

No take warning on an egress aggregation readprocesses

Publishing no longer warns that the read sets no take, since take has no effect on an aggregation.

v3.2.1

The first distributed 3.2 release. It carries everything listed under v3.2.0 below, including its upgrade steps, so read the v3.2.0 "Before you upgrade" steps first.

Before you upgrade

  • Follow every "Before you upgrade" step of v3.2.0, below, before you take this release.

Fixed

v3.2.1 is the first distributed 3.2 releaseenginesAction required

v3.2.0 was published but never distributed. v3.2.1 delivers the same product, so every change described under v3.2.0, below, arrives with this release.

v3.2.0

Governance now reaches every place data leaves or enters CDC outside the store: HTTP requests and responses, plugin tasks, messages and agents. And a publish no longer breaks what depends on it, because every definition now has Drafts, Published versions and a Dependency graph. Many entries carry an upgrade step, so read "Before you upgrade" first.

Before you upgrade

  • On a strict deployment, every plugin Task fails, naming its contract, until a steward activates the contracts of its plugin. Activate them before you upgrade. In strict mode, make each Event Model that a message element binds a governed Data Asset, or its messages are refused.
  • Run POST /api-internal/dependency-graph/rebuild and repair every version the response counts as unreadable, or deletes and archives stay refused. Publish any Draft model that a process pins from an event, value or script step before you publish that process. Deleting an agent or a Connection, and renaming or deleting a Group, is now refused while a Draft or Published definition uses it. Review any housekeeping that does these, and remove the uses that the refusal names first. In the 409 of a model, process or agent delete or archive, read referencedLineageId instead of referencedVersionId.
  • Run the Master host with --lineage-reference-dry-run first to see what the upgrade rewrites, and settle each conflict pair of Connections it lists. Drain message queues and restart Engine Workers during the upgrade. Outside publishers must send to the Event model id, not its name. The upgrade stops and lists every model or process that has more than one Draft, and every live model, process or agent whose name differs from another only in case. Delete the extra Drafts and rename those definitions, then upgrade again. Point every Ingest or Egress Data Store Reference at a Domain model, and raise Execution:CallChain:MaxDepth if a process nests calls over 100 deep. API clients: read workingRevisionId, workingRevisionNumber and workingStatus on an agent instead of the current fields; read the 409 name_in_use body for a taken name; and rename a process through rename, as its PUT now ignores a name.
  • Stop calling the release-plan, prepare-resolution and process upgrade-references endpoints. They are removed.
  • Find each API and webhook that never saved an authentication choice, and give its callers a token or save it as Open.
  • After upgrading, delete the cdc-claude-debug client in your Keycloak realm, then regenerate the cdc-scope-reader secret and set it in Keycloak:ScopeLookup:ClientSecret.

New

Governed exchanges — your Rules now act wherever data crosses the edge of CDCgovernanceAction required

A Rule can now govern the request an HTTP Start takes in, the response an HTTP End sends, what a plugin Task sends and receives, the messages that message elements send and receive, and what an Agent Task sends to its LLM provider. A refused crossing moves no data: a request returns 403 and starts no instance, a message is dead-lettered, and a prompt is never sent.

An Outbound Rule on a Domain model field acts through every mapping, so one Rule on Customer.ssn refuses an HTTP End whose response copies the ssn. A new Exchange model type describes payloads outside the store, and each plugin task's input and output appear as Exchange models that stewards can govern. Rules can also decide by the destination system or its Location, set on the Sources page.

The run monitor, debug panel, dead-letter queue, Node test runs and agent transcripts now apply your Rules for the viewer, and logs and traces no longer carry payload values.

Dependency graph — see what a change reaches before you make itmodelsAction required

CDC now keeps a Dependency graph of every model, process, agent, plugin, Connection, plugin entity and the governance that acts on them, current after every save, import and delete. The first start after the upgrade fills it once.

A Dependency graph page draws one definition or the whole deployment, a column per kind. Models, processes and agents get a Dependencies section that names what depends on them, what they need, and a dependent that has not taken an upgrade.

Deletes, archives and plugin uninstalls now answer from the graph, refuse while a Draft or Published version depends on them, and name each one. A publish reads the graph too, so it costs a handful of reads whatever the size of the deployment.

Drafts and Published versions — a publish no longer breaks what uses itmodelsAction required

Every reference now runs the latest Published version of the model, process or agent it names, and each run log step shows the version it used. A publish no longer breaks the processes, Ingests, events and agent tools that use it, and a new plugin version keeps every task and Connection working.

Agents get Draft, Published and Archived versions like models and processes. A Published version can no longer change, a debug run can use the Drafts of what it calls, and process settings apply to every version from its next start.

Models, processes and agents share one name rule, and a rename changes no stored record. A runaway Call Activity recursion now stops at a configurable depth.

A publish refuses a change that a follower cannot take, and names itmodelsAction required

A publish now refuses a change that a Published process or model cannot take, and names each one and why. The publish dialog shows every definition that follows yours, and lets you publish their Drafts together.

Publish a process and the models it needs in one stepprocesses

Publish a process Draft and the model Drafts it needs together, so neither has to wait for the other.

Choose a Classification's Rules, and see what a change reaches before it savesgovernance

Choose a Classification's Rules when you create it, and add or remove them later on the Classifications page. Where the Classification is placed, Save first shows every field the change reaches, says where each one gets stricter or looser with the riskiest first, and asks you to confirm. Place rule shows the same preview.

The rule builder offers every Action, not only refusegovernance

The rule builder now offers mask, anonymise, remove, record, retain and encrypt. A Rule that encrypts a field picks its Key custodian group from your Access groups, with no API call needed.

API keys — Power BI, Excel and scripts can call CDC without OAuthaccess

Issue an API key for an API client, and tools that cannot do OAuth call CDC as that client, with its scopes. The key is shown once, can expire, and stops working within seconds of a revoke.

Plugins can serve their own HTTP endpoints from Masterplugins

A plugin can now serve endpoints under /plugins/{plugin}/, behind CDC's sign-in. The plugin SDK adds readers for the plugin's own entities, published models and the calling user.

Improved

Classifications open as cards, and every removal asks for a reasongovernance

Classifications open as cards that show their Rules, a description and every place they are placed, each a link. Saving a Rule change shows what you changed, what gets riskier and where else it lands. Taking off a Rule or Classification now asks for a reason, so the trail explains each lost protection.

No hidden platform definitionsmodels

Every model and process is now a normal definition you can see, rename, export and edit. The upgrade deletes leftover hidden definitions that nothing uses and keeps every one that holds data.

Dependencies updatedsettings

Eight dependency updates to the frontend libraries and the Aspire packages, including Mermaid 12 and a DOMPurify security fix.

Fixed

An API or webhook with no saved authentication now requires a tokenaccessAction required

An API or webhook that never saved an authentication choice now requires a bearer token, as the designer showed. Before, it let anyone through while the designer called it Authenticated.

A deployed platform no longer creates Keycloak clients with known secretsaccessAction required

The debug client is created only on a developer machine, and the scope reader takes its secret from your configuration.

Rules decide on the facts of the request they judgegovernance

Ingest Rules now decide on the source system the Ingest element declares, on each field's Owning systems, and only on the fields an ingest writes. Location Rules decide on the Requester's Location, a run for a Declared group meets request.activation is declared, and a refusal names the fact it waited for.

Every ingest records its governance decisiongovernance

The governance trail of a record or a run now shows each write. A stored event and a dead letter again carry their correlation id, the user who wrote it and the sending run.

A Rule can no longer name a group that does not existgovernance

The rule builder picks groups from Access, with no free text. A group no longer in Access shows as not in Access, and the Rule saves only once it is removed or replaced.

Long dialogs stay inside the windowgovernance

Placing a Rule or Classification on a whole model no longer pushes Save off the screen. Long dialogs scroll their content, so Save and Cancel are always visible.

The designer shows the authentication an API Operation really requiresprocesses

The Api default is included. An Operation override can add scopes, but no longer looks like it removes the Api's requirement.

An endpoint plugin can resolve a model reference againplugins

References name their target model by lineage, and the plugin SDK's model catalog now finds the Published version of a lineage.

A fresh database upgrade no longer stops on a repeated migration versionsettings

On PostgreSQL and SQL Server, two migrations that shared one version no longer stop a fresh database upgrade.

The Users tab stays on the page you pickaccess

The tab no longer jumps back right after it opens, or when the search text only gains spaces.

v3.1.2

The first distributed 3.1 release. It carries everything listed under v3.1.0 below, including its breaking changes, so read the v3.1.0 "Before you upgrade" steps first.

Before you upgrade

  • Follow every "Before you upgrade" step of v3.1.0, below, before you take this release.

Fixed

v3.1.2 is the first distributed 3.1 releaseenginesAction required

v3.1.0 and v3.1.1 were published but never distributed. v3.1.2 delivers the same product, so every change described under v3.1.0, below, arrives with this release.

v3.1.1

The first distributed 3.1 release. It carries everything listed under v3.1.0 below, including its breaking changes, so read the v3.1.0 "Before you upgrade" steps first.

Before you upgrade

  • Follow every "Before you upgrade" step of v3.1.0, below, before you take this release.

Fixed

v3.1.1 is the first distributed 3.1 releaseenginesAction required

v3.1.0 was published but never distributed. v3.1.1 delivers the same product, so every change described under v3.1.0, below, arrives with this release.

v3.1.0

Your data stewards now write the governance Rules themselves, and every read and write answers to them, field by field, with an audit you can read. This release also brings declared indexes, an import wizard and one export dialog. It carries breaking changes, so read "Before you upgrade" first.

Before you upgrade

  • Set Governance:ComputeRegion to the engine's country code, such as IE, and replace cloud regions in sovereignty profiles with countries or the EU and EEA groups. An engine with a value such as eu-west-1 stops at start. The Owner attribute of model properties is deleted. Pick each field's Owning systems again in the Governance area after the upgrade. Remove every plugin class that implements IPolicyDefinition; CDC no longer loads it. If you override Governance:PrincipalClaims:AllowList, add groups and location to the list. In strict mode, activate or retire every Ungoverned model first, and give every host the same governance mode.
  • On PostgreSQL, plan a maintenance window: the upgrade rewrites the record and event tables and blocks ingest and reads while it runs. Write range filter dates in ISO form, such as 2026-09-25T10:00:00+02:00. A date such as 09/25/2026 or an offset such as +0200 now neither filters nor matches.
  • Scripts that call POST /model-definitions/import must read the outcomes overwritten and new-version, and send version ids.
  • Connection, model, plugin, process and source system files exported before this release cannot be imported. Export them again after you upgrade.
  • Check Egress elements for groupBy, orderBy or limit, numeric operators, a negative skip or take, an unknown sort, or a non-ISO asOf. Publish now refuses such a process, and a run fails instead of using a default. Clients of the Data Browser API must send asOf as an ISO-8601 timestamp and a skip of 0 or more. Check agent instructions that ask for a take outside 1 to 100 or an unknown sort; those tool calls are now refused.
  • On SQL Server, move to an engine with the native json type, such as SQL Server 2025, before you upgrade. A host on an older engine refuses to start.
  • Check that no record or process context holds a number with more than 38 digits. One such number stops the upgrade.
  • Model and process files exported before this release cannot be imported. Export them again after you upgrade.
  • Change the category of your own Docker-backed test classes from Integration to Docker, and update any test filter that names Integration.
  • Publish referenced models before the processes and models that use them. Dependents now move to a new version by hand.
  • A policy plugin that asks for redact or anonymise now blocks the read or ingest. Remove that request to allow it.

New

Governance Rules — your data stewards decide who sees each field, with no codegovernanceAction required

A new Governance area lets a data steward build a Rule in a form, read it back as one sentence, and place it on fields directly or through a Classification. A Rule can refuse, mask, anonymise, remove or encrypt a field, decided by the Requester's groups and country, and it is live when saved.

The Data Browser and every governed read show each person only what the Rules allow, with no admin exemption. A filter or sort on a hidden field is refused, so a masked value cannot be found letter by letter.

Every ingest and read stores its decision with the data, append-only and hash-chained, and the Trail page shows which Rule version decided each field. Signed Combine Rule packages can be imported, tuned, published and rolled back.

Declared indexes — tell CDC which filters must be fast, and it builds the indexmodelsAction required

On a Domain Model's page you describe a filter that must be fast, and CDC proposes the index, builds it after publish and keeps it in step with the model. Indexes cover number, date, text, id and yes/no properties for range, equals, in and starts-with filters, on PostgreSQL and SQL Server, and reads return the same records before, during and after a build.

One measured equals read on PostgreSQL went from 23,077 buffers to 5. A failed build shows as Failed, retries on its own, and is listed on the Operations page.

Import wizard — bring work from another CDC in one review, before anything landssettingsAction required

System > Export · Import now opens an import wizard. Drop export zips and files from another CDC in any mix: source systems, models, processes, plugins, plugin entities, Connections, Scopes, Groups and API clients.

The review shows what each file would do here before anything is written, and you untick what you do not want. A changed model or process lands as a Draft in the one it came from, references follow each file to where it lands, and an import never overwrites a Published version.

One export dialog — pick what to move, from every part of CDC, in one zipsettingsAction required

Models, processes, plugins, plugin entities, Connections, source systems, Scopes, Groups and API clients all export from one dialog, alone or together in one zip. A model or process offers its Draft beside its Published version.

Files never carry secrets: an API client file leaves out its secret, a Group file leaves out its members, and plugin entity and Connection files name the sensitive values they left out.

Referenced records come back inline — one read for an Order and its Customerplugins

A plugin read can name a reference field and get the referenced record back in place of its id. An Order read now returns its Customer in the same call, governed and audited by the Order read's own Rules.

See what a search or an ingest costs in database callslogs

Platform traces now carry one span for every database call, on SQL Server and PostgreSQL, so you can see what a record search or an ingest really costs in queries instead of inferring it.

Improved

A bad Egress query fails with every problem named, instead of being guessed atbpmn-elementsAction required

Publish, the run, the Data Browser API and agents now read a governed query by one grammar. Publish refuses exactly what a run would refuse, and lists every problem at once with its place, such as `filters[2].op`.

Bad sort, page or asOf values are refused instead of replaced with a default, and sort names are accepted in any case.

SQL Server stores governed JSON natively — long values are found, and storage halvesdata-browserAction required

On SQL Server, a filter now finds a text of any length; a value over 4000 characters used to return an empty result. Governed JSON takes about half the space. CDC is verified against SQL Server 2025, and a host on an older engine stops before any migration runs, so the database is never half-migrated.

Very large and very small numbers keep every digit and match their filtersdata-browserAction required

Governed records and process history, old and new, now store numbers in plain decimal form, so a very large or very small value is found by a numeric filter. A number wider than 38 digits is refused on every database, so no database ever stores a rounded or changed number.

Export files know which model or process they belong tomodelsAction required

A model or process export file now carries its lineage, the identity shared by every version. Its Published version and its Draft are known as one, and import refuses a file without a lineage and names it.

A page of governed records reads only its own modeldata-browser

A page of records now reads only its model's rows, not the whole table, in either sort direction. On SQL Server, one page of 50 from a 100,000-record model went from about 970 ms to about 30 ms.

Large ingests load the database lessbpmn-elements

An Ingest element commits each batch of records in one database transaction. A batch is all or nothing: a failed write rolls it back, and the redelivery commits the whole batch again.

The designer names the plugin task or connection it cannot findprocesses

A task that points at a missing plugin task or connection now names it, rather than showing as unconfigured. It also names the plugin version its connection belongs to, so side-by-side installs can be told apart.

Docker-backed plugin tests have their own test categorypluginsAction required

A test filter now says which runtime a skipped test needs: Docker tests are in the Docker category, beside Python. The test-convention check fails on a Docker-backed test class that still carries the old Integration category.

Dependencies updatedsettings

Seventeen automated dependency updates across the backend, the frontend and the public site, several of them security fixes, plus a manual lift of the .NET cryptography packages to a patched version. None changes behaviour you can see.

Fixed

Publishing a model or process no longer rewrites other definitionsprocessesAction required

A publish could leave another definition pinned to a retired model version. Publish now changes only its own definition, and a publish that references a draft model is refused and names the models to publish first.

A policy plugin can no longer ask for a transform that never happenspluginsAction required

A policy plugin that asked for redact or anonymise used to get the data back unchanged. That data is now blocked, and the audit trail records the block and the plugin name.

Processes on the Master host are governed tooprocesses

Processes on the Master host now run the governance check on every read and write, and record the decision. A host with governance enabled but no check installed refuses to start instead of skipping the check.

A waiting instance is no longer failed after ten minutesinstances

An instance that waits for a message, a reply, an agent or a child process now waits as long as it needs. Only an instance that no engine still works on is failed, and long plugin calls and retry delays count as work.

A failed or stopped child process fails its callersinstances

When a child process fails or an operator stops it, every caller up to the top now fails too. No live work is left behind, and a synchronous HTTP caller gets its failure answer from any engine.

A misconfigured task fails its instance and says whyinstances

A Task or Script Task that is misconfigured, or runs on an engine with no script runtime, used to leave its instance Running with no reason. The instance now fails, with a Failed step that names the element and the cause.

The debug step log shows debug runs onlyinstances

The debug step log could return every stored payload of a production run. It now shows only debug runs; production step payloads stay behind the process monitor's per-step detail view.

A replayed dead letter is governed againdead-letter-queue

Replaying a dead letter now runs the ingest governance check for the source again, so a Rule can refuse the replay. The record keeps its source as the actor, and the operator who replayed it is recorded.

A new model version keeps its governance tags and statusmodels

Publishing a new version of a model now keeps its governance tags, sovereignty profile and status, and a governance change on one version applies to every version.

The event history names the process behind a governed ingest againdata-browser

Every record ingested through governance showed "No process trace". The Data Browser's event history now names the process, version, step and trigger.

Egress reads over the message bus honour every filterbpmn-elements

A filter with no field, no operator or an unknown operator was ignored, and the read returned more records than the process asked for. That read now fails. A Matches filter, which used to fail every such read, now works.

Governed reads keep whole numbers wholebpmn-elements

A process that reads governed records now gets 42, not 42.0, and whole numbers above 9007199254740992 keep their exact value instead of being rounded.

A record that repeats a field name is dead-lettered, not storeddead-letter-queue

Such a record used to be stored, and every later update, backfill and point-in-time read of it failed. It is now dead-lettered as a schema error that names the field.

A process cannot publish, or keep running, without its connectionprocesses

Publishing is refused when a task's connection is missing, including the default one a task uses without naming it. Deleting a connection is refused while any task runs on it.

An agent cannot create a second process with a name in useprocesses

A name already in use is refused, and the agent is told which process holds it, so it can edit that process instead.

An agent can correct a filter with a numeric operatoragents

A filter operator written as a number, such as "99", is now refused as an unknown operator. The tool call used to fail with an internal error, so the agent could not correct it and try again.

A plugin upgrade leaves built-in platform processes aloneplugins

A plugin upgrade no longer rewrites or drafts a built-in platform process; that row reports a failure, and the other processes still upgrade.

A Python Script Task can return a UUID or a datebpmn-elements

A value JSON cannot hold, such as a UUID or a date, is now written as text. The step used to fail with "'str' object is not callable".

A host with the Python runtime stops cleanlyengines

A host with the Python runtime configured now stops instead of hanging on shutdown.

v3.0.0

The first release of the new platform generation, and the first entry in this changelog. Governance now runs before data lands, not after.

Before you upgrade

  • A policy that used to raise a warning now refuses the write. Review your policies before you upgrade.

New

Governance runs before the data lands, not afterprocessesAction required

Ownership, sovereignty and policy checks now run as a pre-hook, so a record that fails a check never enters the governed store.

Every decision is recorded against the process instance that triggered it, so a refused write is traceable to the rule that refused it.

A single place to see who owns whataccess

The Ownership Registry records the owning team for every asset and routes approvals and exceptions to them automatically.

Improved

Governed reads of many records got about five times fasterdata-browser

Egress aggregates the records it reads instead of fetching them one at a time, and caches the governance decision for the duration of the read.

Fixed

Replaying a dead-letter message no longer loses its correlation iddead-letter-queue

A replayed message kept its payload but started a new trace. The replay now continues the original trace.