Blog
Saved0

Visual policy rules for AI governance: no hidden scripts behind the diagram

The rule on screen required a second approver. A hidden script quietly turned it off. How to build visual policy rules whose facts, outcomes, conditions and tests are the same thing that actually runs.

LinkedIn
On this page
  1. The rule was visible. The exception lived in a hidden script.
  2. What makes a visual policy rule trustworthy?
  3. Rules, validations, decisions and policies aren't the same thing
  4. Facts need a source, a type and a meaning
  5. How should a policy rule handle missing data?
  6. Outcomes beyond allow and deny
  7. Conditions become runtime work
  8. When several rules apply, the combination is policy too
  9. Does every path actually cross the rule?
  10. Test semantics, not just examples
  11. Version everything the decision depends on
  12. Common anti-patterns
  13. Ten design rules for visual policy
  14. The result: rules people can read and trust
  15. Frequently asked questions
  16. How Frozion keeps the visible rule and the running rule the same
  17. Sources
The short answer

A visual policy rule is trustworthy only if what reviewers see is exactly what runs. That means typed facts with known sources, explicit handling of missing data, outcomes beyond allow and deny, conditions bound to the steps that enforce them, visible precedence between rules, and tests and versions that cover all of it.

The rule was visible. The exception lived in a hidden script.

A distributor runs an AI-assisted supplier refund process. The approved policy sits in a visual builder, clear enough for anyone to read: refunds above $25,000 need a second finance approver; so does any change to the beneficiary bank account; and both approvals must stay bound to the exact refund proposal.

On screen it reads: IF amount > 25,000 OR beneficiaryChanged THEN require second finance approval.

beneficiaryChanged is calculated by a custom expression behind a property panel. It was written when the refund record had a field called beneficiaryAccountId. A later schema version moved it to beneficiary.account.id. The diagram didn't change. The script still read the old field, found nothing, and returned false instead of an error.

An $18,000 refund to a newly supplied account skipped the second approval. The first approver checked the amount, the policy service returned a valid decision, and the payment API confirmed the transfer.

Nothing threw an error. The rule still showed the control, the script ran, the approver was eligible, the payload matched its schema. The failure wasn't using expressions; policy always needs them. It was letting one expression become a hidden, weakly typed, separately changing source of authority.

What makes a visual policy rule trustworthy?

A visual rule is trustworthy when the diagram is the policy rather than a picture of it: typed facts, defined handling of missing data, explicit outcomes and conditions, visible precedence, tests and versions, all in one definition that the runtime executes.

A readable canvas is useful, but readability isn't governance. Besides "does this evaluate to true?", a governed rule must answer:

  • What exactly is being evaluated, and for whom?
  • Which facts are authoritative, current and allowed for this decision?
  • What happens when a fact is missing, stale or conflicting?
  • Which outcome results, and which conditions come with it?
  • Which step enforces it, and what invalidates it later?
  • What evidence proves it constrained the real outcome?

Rules, validations, decisions and policies aren't the same thing

"Rule" gets used for at least six jobs, and they don't carry the same authority:

ArtifactQuestion it answersTypical outcome
Structural validationIs the payload shaped correctly?Valid / invalid
Business validationDoes it satisfy business invariants?Valid / invalid for the domain
Decision logicWhich route or result follows from the facts?Route A / route B / review
Authorization policyMay this actor do this, to this record, for this purpose?Permit / deny / not applicable / indeterminate
Human judgmentWhat does an eligible reviewer decide about this exact proposal?Approve / deny / ask for more
Model instructionHow should a model attempt the task?Guidance, not enforcement

Keep these visibly distinct. Otherwise a schema check gets mistaken for authorization, a routing rule for an approval, or a prompt for a control.

Facts need a source, a type and a meaning

A policy evaluates a whole proposition, not a user or a record in isolation: who started it, who's acting now, which software is running, the tenant and legal entity, the record and its revision, the action and purpose, the exact proposal, the current state, and the time and risk conditions. A role like "Finance Manager" is one input, not the decision.

Every fact in that proposition needs a contract. amount = 18000 means little until you know whether it's the proposed, approved, gross, net or estimated amount. beneficiaryChanged = false isn't defensible unless you can say which two records were compared, with which IDs and schema version, and whether either value was missing.

Fact typeExamplesWhat reviewers need to see
ActorRole, department, delegated scopeWho issued it, when it expires, which tenant
WorkloadService identity, deploymentWhich software is running, and is it allowed here
RecordOwner, classification, revisionWhich exact object and version
ActionRefund, disclose, approveWhich fields may change
PurposeSupport, payroll, fraud reviewWhy, and is that purpose allowed
EnvironmentTime, location, sign-in strengthWhich current conditions matter
ProposalAmount, beneficiary, termsWhat exactly will be enforced later

A visual builder should show where each fact comes from rather than presenting anonymous variables. Facts drawn from history (counts, totals, status over time) need the same contract, including how fresh they must be.

How should a policy rule handle missing data?

Missing, stale, conflicting or unauthorized facts are policy outcomes, not programming inconveniences. Each needs a declared response, because silently converting them to false, zero or a default is how controls disappear.

Scripts typically coerce a missing value into false, zero, an empty string, a default option or a swallowed exception. Any of those can quietly widen authority, exactly as beneficiaryChanged did. A governed rule names the states:

  • available, missing, stale, not authorized, conflicting, invalid, source unavailable;

and declares what each leads to: deny, refresh the data, request more evidence, send to a person, mark the decision indeterminate, or stop before any change. Nobody should discover months later that null == false is why a financial control vanished.

The diagram stayed correct. The script beneath it read a field that no longer existed and returned false.

Outcomes beyond allow and deny

Authorization standards already distinguish Permit, Deny, Not Applicable and Indeterminate. Business policy often needs more: review required, step-up sign-in required, reapproval required, wait for fresh data, permit with conditions, block.

Each of these is a state change with consequences, not a hint to the caller. "Review required" moves the case to a person. "Permit with conditions" isn't Permit plus optional notes; the conditions are part of what was permitted.

Conditions become runtime work

A rule may permit an action only if the runtime also redacts fields before the model sees them, uses an approved region, caps an amount, requires a second approver, asks for step-up sign-in, keeps a receipt, re-checks before the write, or retains evidence. Each of those must be tied to the specific step that performs it and produces proof that it did.

That's the point where many visual builders stop: they show the decision but not where it's enforced. A valid decision is not proof the policy was enforced. For how enforcement points work across an agent workflow, see runtime policy enforcement.

When several rules apply, the combination is policy too

Real decisions combine rules from enterprise governance, tenant settings, legal entity, product line, jurisdiction, data class, process and exceptions. How they combine has to be explicit: deny overrides, permit overrides, first applicable, explicit priority, merged conditions, or a person decides on conflict.

None is always right. Deny-overrides suits sensitive disclosure. Permit-overrides is only safe when the permitting rule is an authorized exception. First-applicable is dangerous if someone can reorder rows by dragging them. A visual builder should show not just the rules, but how several applicable rules become one decision.

Scope needs the same visibility. Reviewers should be able to see which workflows use a rule, which tenants or business branches inherit it (see taxonomy-scoped authorization), which exceptions narrow or widen it, and which paused cases are still bound to an older version.

Does every path actually cross the rule?

Only a coverage check answers that. A rule can be well written and well tested while one fallback branch, retry path or sub-workflow reaches the action without it.

Reviewing rules in isolation misses the path problem. The stronger question is structural: does every route to this consequential action pass the required check and produce the required evidence? A coverage view can expose one branch that reaches payment without a second approval, one fallback model route that skips the residency rule, one sub-workflow that drops the tenant, one retry that reuses an expired decision, or one output channel with no disclosure rule.

Test semantics, not just examples

Testing belongs in the policy definition, not in a separate spreadsheet.

TestQuestion
PositiveDoes an eligible actor get the intended result?
NegativeIs an ineligible actor or record denied?
BoundaryWhat happens at exactly $25,000, or one second before expiry?
Missing factDoes missing data fail safely rather than default open?
Stale or revokedIs an old role, approval or record revision rejected?
ConflictWhich rule wins, and are all conditions kept?
ConditionDoes every enforcement step carry out and record its condition?
Path coverageCan any route reach the action without the check?
RegressionDid a schema, mapping or taxonomy change alter earlier results?

Then simulate. Run the proposed version against synthetic and recorded cases, with changed facts, scopes and precedence, and compare outcomes, with no live side effects. A simulated result never authorizes a real action.

A rule change is a release: see what depends on it, compare, simulate, approve, then publish with a way back.

Version everything the decision depends on

A policy version number is incomplete if the decision can change because something else changed underneath it. A rule depends on fact schemas, sources, taxonomy versions, mappings, shared functions, combination rules, enforcement bindings and tests. The schema rename in the opening story was exactly this kind of unversioned dependency.

Paused work shouldn't automatically adopt the newest rule either. Each workflow should declare whether a waiting case stays on the version it started under, rechecks current authority and record state, needs reapproval, migrates, or stops. Decide that up front rather than letting it happen by accident.

Common anti-patterns

Anti-patternWhy it failsWhat to do instead
Visual shell, scripted coreReadable labels hide the conditions that matterTyped expressions and declared functions
Boolean-only policyLoses review, step-up, conditions and indeterminate statesExplicit, typed outcomes
Facts without provenanceVariables look trusted with no source or freshnessA contract for every fact
Missing data coerced to falseA schema change switches off a controlNamed missing-data states with declared responses
Row order as precedenceDragging a row changes which rule winsDeclare the combination strategy
Tests without enforcementThe logic passes, the path skips itTest path coverage and enforcement
Latest rule on resumePaused cases adopt rules they weren't approved underDeclare version behavior for waiting work
Prompt as policyA model instruction can't enforce anythingEnforce in the runtime

Ten design rules for visual policy

  1. Evaluate a complete proposition, not anonymous variables.
  2. Give every fact a type, source, scope, freshness and missing-data meaning.
  3. Keep validation, decision logic, authorization, human judgment and prompts distinct.
  4. Make outcomes and conditions explicit; never collapse them into a boolean.
  5. Tie every mandatory condition to the step that enforces it.
  6. Show how multiple rules combine and which one wins.
  7. Test boundaries, missing facts, conflicts, coverage and version changes.
  8. Bring custom code in as typed, versioned, tested functions.
  9. Version facts, mappings, taxonomies and enforcement together with the rule.
  10. Keep the decision, its enforcement and the confirmed outcome linked.

The result: rules people can read and trust

Visual policy isn't a replacement for precise policy semantics. It's how you make those semantics inspectable by the people accountable for them. Business owners see the intended control, security sees actor, record, action, purpose and scope, engineers see typed facts and enforcement steps, auditors trace decisions to outcomes, and the runtime executes the same published meaning.

The goal isn't to hide complexity behind friendly shapes. It's to make the complexity that matters visible, so nobody has to read a general-purpose script to find out whether a control is really on.


Frequently asked questions

What makes a visual policy builder safe for AI governance?

It's safe when the diagram is the policy, not a picture of it. Every fact needs a type and source, missing data needs a defined outcome, conditions must map to enforcement steps, and any custom code must be typed, versioned and tested like the rest of the rule.

How should a policy rule handle missing data?

Treat missing, stale, conflicting or unauthorized facts as explicit outcomes, not as false or zero. Each should lead to a declared response, such as deny, refresh, request more evidence, or send to a person, so a schema change can't silently switch off a control.

How do you test policy rules before publishing them?

Test positive, negative and boundary cases, missing and stale facts, rule conflicts, and whether every path to the action actually passes the check. Then simulate the new version against recorded cases with no live side effects and compare the outcomes.

How does this work for agents we already run?

Route the agent's tool calls through a governed runtime over MCP or HTTPS. Visual rules are then evaluated before and after every routed call, using facts from your systems and history, and each decision is recorded alongside the confirmed outcome.

With Frozion

How Frozion keeps the visible rule and the running rule the same

In Frozion, policies are built in the Visual Policy Builder and enforced before and after every step. Rules decide with history from the Feature Store, where features are authored in SQL or visually, with no pipeline code. Before a change ships, the dependency view shows every workflow that uses it, workflow versions are compared side by side, and the change is simulated in batch on recorded cases. Publishing needs approval, and rollback is built in. Behavior Intelligence & Replay lets reviewers inspect past cases without live side effects.


Sources

  1. OMG Decision Model and Notation (DMN)Human-readable, executable decision tables and expressions.
  2. OASIS XACML 3.0 Core SpecificationPermit, Deny, NotApplicable, Indeterminate, obligations and combining algorithms.
  3. NIST SP 800-162, Attribute Based Access ControlPolicy over subject, object, operation and environment attributes.
  4. NIST SP 800-207, Zero Trust ArchitecturePer-request decisions with no implicit trust.
  5. OWASP Authorization Cheat SheetDeny by default and validate permissions on every request.
  6. JSON Schema Draft 2020-12Typed structure for facts; structure isn't meaning.
  7. W3C SHACLComposable constraints with validation reports.
  8. NIST AI Risk Management FrameworkLifecycle governance, testing and documentation.
  9. W3C PROV-O: The PROV OntologyNeutral provenance for decision-to-effect evidence.
More in Governing AI agents

Governing AI agents

Identity & access 1
Runtime policy 2
Tools & MCP 1

Other topics

Pick up where you left off: