Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

25 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Spyglass BPM logo

Spyglass BPM

Policy-governed AI decisions for Camunda 8 workflows.

Version Camunda 8 Docker Compose Deployment

Spyglass BPM adds a controlled AI decision step to a Camunda 8 process.

The model produces structured decision data and optional patch values. Spyglass validates that output against a policy, applies deterministic guardrails, and returns the result to the process. BPMN remains responsible for routing, while the process author keeps full control over how the result is mapped and used.


Why Spyglass

  • Controlled context — only policy-approved variables are read from Camunda.
  • Structured output — the model returns a governed response, not arbitrary text.
  • Safe updates — patch values are restricted and validated by policy.
  • Deterministic guardrails — business rules can override the model result.
  • Human-in-the-loop support — process authors can preserve a User Task for manual review or fallback.
  • Flexible integration — configure a connector task with the Element Template or let the Rewriter adapt an existing BPMN model.
  • Optional historical context — similar past decisions can be retrieved from Qdrant.

Console

Process overview

Upload, browse, and manage prepared processes in the Spyglass Console.

Spyglass Console process overview

Policy editor

Create and edit policies with a structured UI and live JSON preview.

Spyglass policy editor

BPMN rewrite preview

Preview the original and rewritten BPMN side by side before downloading the prepared process.

Original and rewritten BPMN preview


Architecture

flowchart
    subgraph DesignTime["Design time"]

        subgraph RewriterPath["Rewriter-assisted preparation"]

            SourceBpmn["BPMN model"]
            Policy["Policy"]
            Console["Spyglass Console"]
            Rewriter["BPMN Rewriter"]
            Rewritten["Rewritten BPMN"]

            SourceBpmn --> Console
            Policy --> Console
            Console --> Rewriter
            Rewriter --> Rewritten
        end

        subgraph DirectPath["Direct integration"]

            DirectBpmn["BPMN model"]
            Template["Spyglass Element Template<br/>policyId"]
            Modeler["Camunda Modeler"]
            Configured["Configured BPMN"]

            DirectBpmn --> Modeler
            Template --> Modeler
            Modeler --> Configured
        end
    end

    Rewritten --> Deploy["Deploy BPMN"]
    Configured --> Deploy

    subgraph Runtime["Runtime"]

        Camunda["Camunda 8 / Zeebe"]
        Connector["Spyglass Connector"]
        DecisionService["AI Decision Service"]

        Camunda <--> Connector
        Connector <--> DecisionService
    end

    Deploy --> Camunda

    subgraph Supporting["Supporting components"]

        PolicyStore[("Policy Store<br/>PostgreSQL")]
        EpisodeStore[("Episode Store<br/>Qdrant")]
        LLM["LLM provider"]
    end

    DecisionService -->|"load policy by policyId"| PolicyStore
    DecisionService -->|"retrieve / store episodes"| EpisodeStore
    DecisionService -->|"invoke model"| LLM
Loading

Camunda 8 is external to the Spyglass Docker Compose stack.


Runtime flow

sequenceDiagram
    participant Camunda as Camunda 8 / Zeebe
    participant Connector as Spyglass Connector
    participant AI as AI Decision Service
    participant Policy as Policy Store
    participant Model as LLM Provider

    Note over Camunda,Connector: Execute Spyglass connector task
    Camunda->>Connector: Activate decision job

    Note over Connector,Policy: Resolve controlled process context
    Connector->>AI: Request policy context specification
    AI->>Policy: Load and validate policy
    Policy-->>AI: Policy
    AI-->>Connector: Allowed variables and policy defaults

    Connector->>Camunda: Fetch allowed process variables
    Camunda-->>Connector: Filtered process context

    Note over Connector,Model: Evaluate decision
    Connector->>AI: Submit decision request

    AI->>Policy: Load and validate policy
    Policy-->>AI: Policy

    AI->>Model: Prompt and sanitized context
    Model-->>AI: Structured model response

    AI->>AI: Normalize and validate output<br/>Validate patch<br/>Apply guardrails<br/>Compute final auto flag

    AI-->>Connector: Structured DecisionOutput

    Note over Connector,Camunda: Return decision output to the process
    Connector-->>Camunda: Complete job with DecisionOutput
    Camunda->>Camunda: Apply configured output mappings
    Camunda->>Camunda: Evaluate BPMN conditions and continue execution
Loading

Integration options

Spyglass runtime does not depend on the BPMN Rewriter. A process can use the connector directly through the Element Template, or it can be adapted automatically by the Rewriter.

Element Template

The Element Template configures a Camunda Service Task as spyglass:ai-decision. It exposes the policyId and optional runtime overrides directly in Camunda Modeler.

Spyglass Element Template configuration in Camunda Modeler

The template only configures the connector task. It does not prescribe how the returned DecisionOutput must be mapped or used. The process author remains responsible for the surrounding BPMN model, output mappings, routing, and patch application.

BPMN Rewriter

The BPMN Rewriter is an optional design-time service that adapts an existing process around a selected User Task. Its purpose is not only to insert a connector task, but to generate a complete, policy-aware integration pattern that is immediately executable and can still be reviewed in Camunda Modeler.

BPMN process before and after Spyglass rewriting

Given the original BPMN model, a target userTaskId, and a policyId, the Rewriter:

  1. loads the BPMN XML and the associated policy;
  2. redirects the incoming flow of the selected User Task to a new Spyglass decision Service Task;
  3. configures the task as spyglass:ai-decision, including connector inputs and Element Template metadata;
  4. inserts an exclusive gateway after the decision task;
  5. creates an automatic path guarded by =spyglass.auto = true;
  6. keeps the original User Task on the default fallback path;
  7. reconnects both paths to the original continuation of the process;
  8. generates standard Spyglass output mappings and policy-specific mappings for patch variables;
  9. updates BPMN diagram layout information so the rewritten model remains readable.

The original User Task is therefore preserved. A confident and permitted result can continue through the automatic path, while any non-automatic result falls back to the human task.

Generated patch mappings

The connector returns a structured decision result under spyglass, including spyglass.auto and spyglass.patch. For every key declared in policy.patch.keys, the Rewriter generates a FEEL output mapping according to policy.patch.applyMode.

For onlyIfAutoTrue, the generated value is applied only when automatic execution is allowed:

=if spyglass.auto = true
 then spyglass.patch.<key>
 else <key>

The mapping target is <key>. On the automatic path, the AI-generated patch value replaces the process variable. On the fallback path, the existing value is preserved for the User Task.

For always, a valid patch value can also be propagated when the process continues to manual review:

=if spyglass.patch.<key> != null
 and spyglass.patch.<key> != ""
 then spyglass.patch.<key>
 else <key>

This supports prefill scenarios: the User Task remains active, but selected fields can already contain validated values prepared by Spyglass.

For never, patch values are kept in the structured decision output and are not mapped into business process variables.

This policy-specific mapping generation is the main convenience provided by the Rewriter. The Element Template only configures the connector; when it is used without the Rewriter, the process author decides independently how the returned DecisionOutput and patch values are mapped and applied.


Policy model

A policy defines what the model may see, what it may return, and when the result may be used automatically.

Section Responsibility
policyId Stable identifier referenced by the Service Task
scope Binds the policy to the applicable process and decision point
decision Allowed outcomes, confidence threshold, automatic execution
context Variable whitelist and redaction rules
patch Writable fields, validation schema, and application mode
guardrails Deterministic rules applied after model execution
history Episode storage and retrieval settings
prompt System instructions and task-specific guidance

Execution modes

Automation eligibility and patch propagation are configured independently.

The behavior below assumes that the BPMN process uses spyglass.auto for routing. The Rewriter generates this routing pattern automatically, while a direct integration may use the returned decision output differently.

Mode decision.autoExecution patch.applyMode Behavior
Automatic with human fallback true onlyIfAutoTrue Confident decisions may bypass the User Task. Patch values are applied only on the automatic path.
Automatic with fallback prefill true always Confident decisions may bypass the User Task. Fallback cases may still receive validated prefill values.
Prefill only false always The User Task is always executed, while validated patch values may prefill selected fields.
Decision only true or false never Spyglass returns decision metadata, but patch values are not written into business variables.

When the BPMN Rewriter is used, it generates the corresponding FEEL output mappings automatically. When the Element Template is used directly, the process author decides how the returned DecisionOutput and patch values are mapped.

Control boundaries

flowchart LR
    Vars[Camunda variables] --> Context[Whitelist and redact]
    Context --> Model[LLM]
    Model --> Validation[Validate outcome and patch]
    Validation --> Guardrails[Apply guardrails]
    Guardrails --> Result[Spyglass result]
    Result --> BPMN[BPMN routing]
Loading

The model does not receive arbitrary process data, cannot write arbitrary variables, and does not route the process directly.


Decision contract

Request

{
  "policyId": "loan_review_policy_v1",
  "processId": "loan_approval_demo",
  "processInstanceKey": 2251799813685249,
  "threshold": 0.8,
  "allowedOutcomes": ["Approve", "Decline"],
  "variables": {
    "requestedAmount": 1200,
    "annualIncome": 42000,
    "riskScore": 0.21
  }
}

Response

{
  "auto": true,
  "outcome": "Approve",
  "confidence": 0.91,
  "reason": "The application satisfies the configured approval criteria.",
  "evidence": [],
  "latencyMs": 842,
  "patch": {
    "decision": "Approve",
    "decisionReason": "Low risk and sufficient income."
  }
}

The final auto value is computed by Spyglass after validation and guardrails are applied.


Components

Component Technology Responsibility
Spyglass Console React, Vite Policy management and BPMN preparation
BPMN Rewriter Java, Spring Boot Optional BPMN transformation
Spyglass Connector Java, Camunda Connector SDK Executes spyglass:ai-decision jobs
AI Decision Service Python, FastAPI Policy evaluation, model invocation, validation, guardrails
Policy Store PostgreSQL Persistent policy storage
Episode Store Qdrant Historical episode storage and retrieval
LLM provider OpenAI, OpenAI-compatible API, or Ollama Produces the structured model output

Quick start

Requirements

  • Docker
  • Docker Compose
  • A reachable Camunda 8 environment
  • One configured LLM provider

1. Configure the environment

Copy the provided environment template:

cp .env.example .env

Then configure:

  • PostgreSQL password;
  • the selected LLM provider and its credentials;
  • Camunda addresses and authentication.

2. Start the stack

docker compose up -d --build

Open the Console:

http://localhost:5173

3. Create or upload a policy

Open the Spyglass Console, create or upload a policy, and keep its policyId for the connector configuration.

4. Optional: start with Ollama

docker compose --profile ollama up -d --build
docker compose --profile ollama --profile init up ollama-pull

5. Integrate Spyglass into BPMN

  • Element Template: configure a Service Task as spyglass:ai-decision and use the returned output however the process requires.
  • BPMN Rewriter: select a User Task in Spyglass Console and generate an adapted BPMN model with connector configuration and mappings.

6. Deploy and run

Deploy the BPMN process to Camunda 8, start a process instance, and inspect the result in Operate or Tasklist.


Camunda Modeler setup

The Spyglass Element Template is located at:

templates/spyglass-connector.json

For a project-local Camunda Modeler setup, place it under:

.camunda/element-templates/

The Element Template exposes the policy identifier and optional runtime overrides for the confidence threshold and allowed outcomes.


Repository structure

.
├── ai/
├── connector/
├── console/
├── docs/
│   └── images/
├── rewriter/
├── schemas/
│   └── policy.schema.json
├── templates/
│   └── spyglass-connector.json
├── .env.example
├── docker-compose.yml
├── pom.xml
└── README.md

Current scope

Spyglass BPM is currently intended for self-hosted deployments in a trusted environment.

  • single-tenant deployment
  • no built-in user authentication or role management
  • one active model-provider configuration per installation
  • policy versioning is not included yet

License

Copyright © 2026 Dariia Shumeiko. All rights reserved.

Spyglass BPM is currently released as a technical preview.

The source code is provided for evaluation, testing, and review purposes only. You may inspect the source code and run the software in your own environment for evaluation.

Redistribution, commercial use, offering the software as a service, or creating derivative commercial products is not permitted without prior written permission.

A permanent licensing model may be introduced in a future release.

About

Policy-governed AI decision automation for Camunda 8 BPMN workflows.

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages