Minbook
KO
The Gate Condition Is Written on the Diagram - Using BPMN as a Governance Spine

The Gate Condition Is Written on the Diagram - Using BPMN as a Governance Spine

M. · · 9 min read

The gateway in this process carries this name: “ConfDecay over_trust_gap > 0.2 OR final ≥ 4.5 OR runtime alert?” The condition is written on the diagram as a string, and that is the whole point of this arrangement. The tool that diagnoses AI workflows was drawn as a BPMN process, with the coded agent as one node inside it. How using a process engine as a wrapper differs from using it as the spine of judgment, and the three problems that actually blocked the run.

Part 3 ended with a design where the human gate is fired by arithmetic rather than by an operator’s judgment. The remaining question is where to hang that gate.

Drawing the diagnosis as a process

Counting elements in the process definition file gives 1 start event, 2 end events, 3 exclusive gateways, 2 parallel gateways, 9 service tasks, and 1 user task: 18 flow objects, joined by 20 flows.

The full Maestro BPMN process. The left gateway splits on whether AI intervention is needed, the coded agent runs the diagnosis, and the right gateway splits on whether human review is required.

Read it left to right. A workflow diagram arrives, a parser task using document understanding receives it, and the first exclusive gateway decides whether there is at least one AI intervention node. If not, it ends without diagnosis.

If so, a parallel gateway fans out three ways: general failure, security, handoff. Each axis is drawn as its own service task and they rejoin at a second parallel gateway. Incident retrieval and mitigation ordering follow, and the second exclusive gateway splits on human review.

The Maestro canvas view. An intervention gateway sits behind the parser, and a parallel split fans the three risk axes out.

In the deployed run, one coded agent takes that diagnosis segment. The entry point is run() in coded_agent_wrapper.py, and inside it the order is:

StageWhat it doesCharacter
ParseRead the node inventory table into a node listDeterministic
Select candidatesScore only nodes the ontology has cells forDeterministic
Attach evidenceRetrieve precedents per node from the incident corpusRetrieval-based
Handoff metricsCompute IPS, confidence decay, and judge per node pairParallel
Aggregate and gateWeighted sum, color band, gate condition evaluationDeterministic

The whole segment takes roughly 33 seconds. Three values come back: the per-node diagnosis list, the maximum score, and whether human review is required.

Of those three the process actually reads only the last. The gateway sees one boolean. The decision logic lives inside the agent and the process consumes the result, so a change in thresholds leaves the process definition untouched.

The condition is written on the diagram

The second gateway is named:

ConfDecay over_trust_gap > 0.2 OR final ≥ 4.5 OR runtime alert?

That is the core of this arrangement. What opens the gate is written on the process picture as a string. A regulatory reviewer does not have to open the repository or read Python to confirm that an over-trust gap above 0.2 escalates to a human.

The same condition exists in code. evaluate_hitl() checks the final score, the over-trust gap, the intent preservation score, and the judge score in order, accumulating the reasons it tripped as strings. The gateway’s name is the human-readable edition of that function. The two must not diverge, so the thresholds live in one place, held on a contract object that every execution path reads.

How far the input is actually wired

The parser task at the front of the process uses document understanding. What the coded agent parses, though, is a markdown node inventory table: node id, function, and how AI intervenes, as columns.

The repository holds a BPMN XML parser, a Mermaid parser, and a module that reads an image with a multimodal model and converts it to Mermaid, which then reuses the Mermaid parser. All three work, none is wired into the coded agent on the UiPath path, and the engine still carries a note that raw BPMN XML is not auto-converted yet.

The three input formats in the design: BPMN 2.0, Mermaid, and image

The reason to open the input wide is practical. At the moment a pre-deployment check is needed, the workflow is rarely a standard-format file. It is a photograph of a design-session whiteboard, a cluster of shapes on a slide, or a diagram inside a document. Narrow the input to BPMN files and redrawing the workflow becomes a prerequisite, and once that attaches, the tool is a project again.

Stated plainly, though: the design for opening it wide exists and the wiring is half done.

Wrapper versus spine

There are two ways to put an agent on top of a process engine. They look similar; what differs is where the judgment lives.

DimensionUsed as a wrapperUsed as a spine
Gate locationConditional inside agent codeGateway in the process definition
State ownershipThe agent processThe process engine
Human involvementThe agent sends a notificationThe process waits at a human task
Audit recordLog filesThe execution history itself
Changing rulesEdit code and redeployEdit the process definition
Non-developer readabilityRequires reading codeReadable as a diagram

The last two rows were decisive. Proving that human review was placed on the auto-approval node by screenshotting a conditional in a code repository carries different weight than pointing at a gateway in a process diagram.

State ownership is the same story. A human review task can wait for days. If the agent process holds the state, restarts and deployments and outages all become risks, and with several cases pending you need separate machinery to track each. Hand it to the engine’s durable execution and pending instances are managed as a list, with who approved when written into the execution history.

Part 3 named permanent retention of the reasoning trace as the must-fix mitigation for the auto-approval node, and this arrangement is why that retention can ride on the execution history rather than becoming a separate feature. Tracing why an auto-approved case was approved needs the diagnosis at that moment, the gate decision, and the approver, and all three are in the history.

---
config:
  look: handDrawn
  theme: neutral
---
flowchart TD
    subgraph W["Wrapper arrangement"]
      W1["Process engine"] --> W2["Agent<br/>judgment · gate · notify"]
      W2 --> W3["Log file"]
    end
    subgraph S["Spine arrangement"]
      S1["Process definition<br/>gateways · human task"] --> S2["Agent<br/>scoring only"]
      S2 --> S1
      S1 --> S3["Execution history = audit record"]
    end

This arrangement is not free

The price of the spine is flexibility. Writing the gate condition into the process definition means editing and redeploying the process to change it. What would be one configuration value with a code conditional becomes a diagram edit.

What the agent can do narrows too. A design where the agent decides mid-diagnosis that “this should go to a human” and alters the flow does not work here. The agent returns values; branching happens outside.

So the choice depends on use. For an agent doing exploratory work, the wrapper is right. When the output serves as regulatory material and the existence of the gate has to be provable, the spine is right. Which of flexibility and provability you need has to be settled before the arrangement can be.

Why BPMN

There are several ways to wire multiple agents together: a supervisor, a graph, a state machine, or code with the order baked in. As covered in Six Multi-Agent Workflow Patterns, the menu is not short.

BPMN was chosen on two criteria, neither of them expressiveness. A human task is a first-class element of the notation, and the notation has been the standard for drawing business processes for over twenty years.

The first is functional. Adding a human approval wait to a supervisor or graph arrangement means building the wait state and the resume point yourself. In BPMN the human task is already there and waiting and resuming are engine defaults.

The second is about people. Regulatory and audit staff have been reading process diagrams for years. Nobody has to learn a new notation to point at where the gate is. The deterministic-scaffold argument in Will No-Code Get Eaten, or Get More Valuable shows up here as a physical object. The scaffold around a language model’s judgment should be deterministic, and if it is a notation the organization already reads, one round of persuasion cost disappears.

Why the three axes fan out in parallel

On the canvas a parallel split sits behind the parser and the three axes separate. Exposing that split in the process definition was deliberate.

Scoring could have been one block with the result presented in three parts. Then one axis failing fails the whole diagnosis. In parallel, an axis blocked by an external reference problem still leaves the others, and the artifact records which axis was missing.

That property got used. Running without the embedding model means the handoff runtime metrics are not computed. The engine marks a degraded state, leaves a note reading “handoff metrics skipped, embedding model unavailable,” and finishes scoring on the ontology lookup alone. The 4.76 maximum with three RED from Part 3 is that state; with the metrics on it becomes 4.88 with four RED. Every ontology update is regression-checked against the degraded result, and the August cycle returned 3 RED for legal and 3 RED for credit underwriting, unchanged. Not making it all-or-nothing is what allowed a degraded state to exist at all.

What actually blocked the run

Three problems stood between the design and a working run. Two turned out to be platform issues and were filed on the public forum; one was packaging.

ProblemSymptomHandling
Solution publishDeploying a solution containing a Maestro flow failed to find the tool factoryRouted through the debug execution path
Human task creationCase folder and app folder binding mismatched, so task lookup failedDemonstrated human review separately
Serverless packagingThe agent failed during environment preparationExplicit wheel file selection and dependency split

The third took longest, with a two-layer cause. The packaging configuration did not specify which files to ship, so the build could not determine its targets, and the heavy libraries used for retrieval and embedding were pinned as hard dependencies, pushing install size to 1.5GB.

The fix did both: name the paths to include, and move the heavy libraries into optional dependencies, leaving exactly two hard ones. That was possible because every heavy import is lazy and a hash-based fallback exists when embeddings are absent. The credit underwriting sample was run in a clean virtual environment with none of those libraries present, confirming the human-review-required verdict still came out correctly, before the version was bumped.

The builder view of the human review screen. Values are still expression placeholders, but the fields that reach the approver are visible: workflow name, maximum risk score, count of nodes over threshold, escalation reason, summary, and an apply-must-fix checkbox.

The first two were worked around. With solution publish blocked, the process ran through the debug path; with automatic human task creation blocked, the diagnosis run and the approval screen were shown separately. The workaround is not the point; whether what was being verified still got verified is. The thing to confirm was that the repackaged agent runs inside the execution environment, and that is confirmed on the debug path too.

What came out of these three is less a technical lesson than a sense of schedule. Committing to a process engine as the spine means passing through its deployment paths, folder structures, and packaging rules. Having diagnosis code that runs locally and having it run inside the platform are different stages, and the second can take longer. In return, state management, waiting and resuming, human tasks, and execution history do not have to be built.

What was verified and what was not

The rule kept in the deck and the submission was to quote numbers only for what can be shown on screen.

Verified: with the repackaged build, the coded agent completes inside the execution environment in roughly 33 seconds without errors, the return value reaches the gateway and splits the path, and the process resumes after approval on the human review path. With metrics on, the credit underwriting sample surfaces four nodes over threshold.

Not verified, also recorded: the judge metric defaults to a mock backend, so a real judgment requires naming one. Observability integration is unresolved. A peer review module that has a separate model re-examine the diagnosis exists as a file but is not called by the engine. The retrieval quality figures for graph-based search were withdrawn: the gold set and the retriever’s filter derived from the same source, so the filter matched the gold set trivially, which is not an independent measurement. The graph itself, 8,287 nodes and 12,317 edges, remains valid; the performance numbers are pending re-measurement.

Those numbers were pulled from the submission and the deck for a simple reason: put in a number with no on-screen evidence and every other number gets doubted with it.

Closing - when the gate is a picture

This series started from the observation that pre-deployment review lives only inside consulting engagements, split that review into a scoring table and a gate, and ended by placing the gate into a process definition.

One thing runs through all four parts. Move judgment out of a person’s head into a table, keep the table as data rather than code, and keep the gate condition as a sentence on a picture rather than as code. The direction of each move is the same. Put judgment somewhere it can be read and re-running and proving come with it.

Consulting diagnosis was expensive not because a human judged, but because that judgment had never come out. As a table it can be re-run; as a gateway name it can be read by regulatory staff. The remaining value attaches to keeping the table current.


Sources

  • Process definition scripts/uipath/bpmn_diagnosis_workflow.bpmn (18 flow objects, 20 flows), agent entry point scripts/uipath/coded_agent_wrapper.py (public repository)
  • Gate conditions in scripts/core/tools.py (evaluate_hitl), thresholds in scripts/core/contracts.py (HitlThresholds)
  • Submission page: FDE Agent on Devpost
  • The two platform issues are filed on the official UiPath community forum (solution deployment, and human task lookup during case plan debugging)
Share

Related Posts