NEW The NOVA engine now understands Saudi dialects with higher accuracy

A developer's guide to governed orchestration

NOVA Team

In many organizations the split starts quietly. The operations team builds its flows on the visual canvas, under permissions and a record, while engineering writes its agents in code to gain speed and flexibility: and now there are two paths: one governed, the other "trusting that the developers know what they're doing." Months later, when the audit question arrives, everyone discovers that half of the organization's AI lives outside any visibility. This guide is about the principle that prevents that split: code and the visual canvas are just two interfaces to the same engine, subject to the same permissions and the same log. Governance is one layer, not two.

The principle: two interfaces, one engine

The common mistake is treating the API as a back door that bypasses the controls. The correct design is the exact opposite: the flow you create with an HTTP request is the same object that appears on the visual canvas. It carries the same owner, the same permissions, and it writes to the same audit log. The developer gains the speed of code: version control, review through pull requests, automated testing: without gaining a door that routes around governance. What a code-built agent may read or execute is bounded by exactly the same scope that bounds its visual counterpart.

The practical payoff is that the compliance team doesn't need to understand your programming language to trust your flow. They read the same log and the same permissions for every flow, regardless of how it was created. One question, one answer, across the whole organization.

Environments and promotion: from dev to prod

Governed orchestration doesn't mean one flow in one place: it means the same flow graduating across separate environments, each with its own permissions and data:

  • Development (dev): where the developer writes and tries the flow against synthetic or limited data, with narrow permissions, never touching production systems.
  • Staging: a near-production copy where flows are tested against real integrations but in an isolated scope, so permission and performance issues surface before they touch real data.
  • Production (prod): where the flow runs against real data and live systems, with the narrowest permissions necessary, under the highest degree of oversight and approval.

Promotion between environments is not copy-and-paste; it is a recorded event. When a flow is promoted from staging to production, it's logged: who promoted it, which version, when, and which new permissions were granted to it. That turns "how did this code reach production?" from an investigation into a query. The working rule: permissions are not equal across environments. What's allowed in dev against synthetic data is not automatically granted in prod; each environment grants its permissions by explicit decision.

The API-first agent

When you build an agent in code, you describe three things explicitly: what it does, which data and actions it is permitted, and where it stops to ask a human. That same description: not an attachment to it: is what the engine enforces and records. The example below is illustrative, to make the idea concrete, not a real API:

POST /v1/flows
{
  "name": "vendor-invoice-reconciliation",
  "environment": "staging",
  "owner": "team.finance-ops",
  "permissions": {
    "read":    ["erp.invoices", "erp.vendors"],
    "execute": ["erp.payment.draft"],
    "deny":    ["erp.payment.release"]
  },
  "approval_gate": {
    "on": "amount > 50000",
    "approver_role": "finance.controller"
  }
}

Read what this declaration says: the agent reads invoices and vendors, drafts a payment, but is explicitly denied the final payment release, and any amount above the threshold halts for a human controller's approval. These controls weren't written in a separate document; they are part of the agent's own definition, take effect the moment it runs, and generate a record automatically. Implicit permission: "the tool is available, do as you like": is not an option here; what isn't declared doesn't happen.

Audit by default

The essential difference between "we can log that" and "that is already logged" is the difference between a promise and evidence. In governed orchestration, logging is not a feature you switch on; it is the default behavior that doesn't switch off. Every API call, every promotion, every agent decision, every human approval writes a structured trace: who, what, when, under which permission, with what result. What matters is that this trace is generated by the act of operating itself: not by manual work the developer assembles the night before an audit.

The operational payoff is direct: when a security questionnaire arrives from a major customer asking "how do you govern your programmatic agents?", the answer is a query against the log, not a campaign to gather screenshots from developers' memory. And systems of this kind: running on recorded permissions with a complete trail: are designed to support your organization's audit readiness, not to promise it ready-made compliance. (This is a technical guide, not legal advice.)

Where do human approval gates fit?

Developers err in two directions: one team puts a human approval on every step and strangles the very speed code was meant to gain; another removes them all and ships irreversible decisions at machine speed. The right place sits between them, and is decided by a single question: is this decision reversible?

  • Reversible decisions run at machine speed: summarizing, classifying, drafting, a read-only query. Their errors are cheap and instantly correctable, so they don't warrant a human interception.
  • Irreversible decisions wait at a gate: releasing a payment, modifying a customer record, sending an external message in the organization's name, deleting data. This is where a documented human approval belongs: the point that genuinely deserves the machine to pause.

In a governed system, the gate is not an email lost in an inbox; it is a state in the flow itself: the agent halts, the designated approver is notified, and their decision: accept or reject: is recorded by name and time. So approval stays fast and traceable at once, and governance never becomes the bottleneck that pushes the team toward the workaround.

What a working day looks like

Put the pieces together into one cycle familiar to any developer: you write the flow in code and test it locally against synthetic data in dev. You open a pull request your colleague reviews like any other code: and the declared permissions are visible in the request itself, so the reviewer sees them plainly. On merge, the flow is promoted to staging automatically, running against real integrations in an isolated scope. When it proves out, its promotion to production is requested as a recorded event that grants it the narrowest production permissions. From the first moment, every step is in the log. The developer lost nothing of their speed or tooling; they gained only that their work is now defensible to an audit with no extra effort on their part.

The first step

Don't start by rebuilding all your programmatic agents. Start with one existing agent: ideally one that touches real data or a financial decision: and redefine it the governed way: declare its permissions explicitly (what it reads, what it executes, what is denied), define it across the three environments, and put one approval gate on its riskiest decision. Run it for a week, then open its log and ask: can I answer: who did what, under which permission, and where is the evidence? If the answer is a query rather than an investigation, you've felt the difference firsthand. That single agent becomes the template you measure the rest against, and you migrate them to it one at a time.

Our full methodology for engineering teams expands on the developer AI orchestration page, and the detail of integrations and API connection patterns lives in integrations.