Canopy

The OSCAR platform — an event-driven, governance-first operating system for dental practices and their revenue cycle, built on Azure.

What it is

Canopy runs the operational and financial backbone of a dental practice: scheduling, clinical charting, imaging, insurance, and the full revenue cycle — claims, payments, and reconciliation. What sets it apart isn't any single feature; it's that every change flows through one governed path and is provable.

The platform is built so that AI agents and humans operate through the exact same rails — the same writes, the same risk scoring, the same immutable audit trail. Autonomy is a first-class citizen, but it never bypasses governance.

System architecture

Nine bounded services communicate through an event backbone. State never changes by side effect: writes go through a single governed entry point that commits the change, an audit record, and an outbox event in one atomic transaction. A relay publishes those events to Service Bus, and downstream services react.

Action Gateway

Governed-write entry point

Every state change flows through one door. Each write is an atomic triple-write inside a single transaction — the state mutation, an immutable audit record, and an outbox event — and is scored by a risk engine + policy sidecar before it commits.

Agent Orchestrator

Agentic reasoning

Assembles context, reasons with an LLM, and executes tool calls under the same governance rules as humans. Authenticates to Azure OpenAI via managed identity.

Sentinel

Real-time risk scoring

Consumes the operational event stream and computes a live Practice Risk Score across six weighted dimensions. The gateway reads it live to elevate verdicts on risky actions.

Thread Intelligence

Practice snapshot

Maintains a capability-filtered, token-budgeted live view of each practice in Redis, kept fresh by watchers on the event stream — the context layer agents read from.

Outbox Relay

Transactional outbox

Polls the outbox table and publishes events to Service Bus with exactly-once intent. Dialect-aware row locking lets workers scale concurrently without double-publishing.

Delivery Service

Real-time fan-out

Streams events to live clients over WebSockets (Azure Web PubSub) with per-session ordered replay after reconnect.

RCM Engine

Revenue cycle

The dental claims pipeline — eligibility, 837D assembly, clearinghouse submission, and remittance ingestion (detailed below).

Imaging (Orthanc + OHIF)

DICOM pipeline

A DICOMweb store (Orthanc) and a web-based radiograph viewer (OHIF) for dental imaging, wired into the same platform.

Data flow

One write, one rulebook. Every governed change — whether a clinician posts a procedure, an agent submits a claim, or an ERA arrives from a payer — moves through the same path. Nothing bypasses it.

01 · Change
An operator or agent makes a request

A human action or an agent tool call arrives at one of nine bounded services. Both paths converge on the same entry point — there is no back door.

02 · Score
Risk engine + policy verdict

Sentinel's live Practice Risk Score is read; Open Policy Agent evaluates versioned policy; the action is banded auto-execute / propose-and-confirm / require-approval / block.

03 · Commit
Atomic triple-write transaction

State row, hash-chained audit row, and outbox row all commit in one SQL transaction. If anything fails, none of it lands — there is no partial state, ever.

04 · Relay
Outbox Relay publishes to Service Bus

A background worker polls the outbox with dialect-aware row locking, publishes the canonical event with exactly-once intent, and marks the row delivered. Workers scale concurrently without double-publishing.

05 · Fan-out
Service Bus topics + Delivery Service

Subscribers on Service Bus topics receive the event with filters generated from service manifests; the Delivery Service streams it to live web clients over Web PubSub with per-session ordered replay.

06 · React
Downstream services and live UI

RCM assembles a 837D, Thread Intelligence refreshes the practice snapshot in Redis, Sentinel updates the risk score, the UI re-renders. Each subscription is idempotent and survives retries.

07 · External
Clearinghouse round trip

When the reaction involves an external system — a claim to Vyne, a benefit check to a payer — responses (999, 277CA, 835 ERA) arrive back into the same backbone as new governed events, never as ad-hoc side effects.

Revenue cycle engine

The RCM engine turns clinical work into clean, payer-ready claims and tracks them end to end. The pipeline is deliberately pure — claim assembly does no I/O — so the same logic runs identically from a CLI, an API call, or a batch job, and every output is deterministic and testable against fixtures spanning the full dental code set.

  1. 01

    Eligibility

    Real-time benefit checks via X12 270/271 before work begins, so coverage is known up front.

  2. 02

    Claim assembly

    A clean domain model compiles into a deterministic 837D EDI file through a pure builder — no I/O — so the same pipeline runs from CLI, API, or batch.

  3. 03

    CDT line constraints

    Per-procedure validation across the full CDT taxonomy (D0100–D9999): allowed teeth, required surfaces, and age gates are enforced before submission.

  4. 04

    Payer routing

    A canonical receiver/payer table routes each claim to the right clearinghouse and carrier, with hard guards against ID collisions.

  5. 05

    Submission

    Claims are delivered to the Vyne clearinghouse over pinned-key SFTP, with deterministic, collision-proof filenames safe for parallel retries.

  6. 06

    Acknowledgements

    Functional acks (999) and claim-status responses (277CA) are ingested, de-duplicated, and traced back to the originating claim.

  7. 07

    Remittance

    Electronic remittance advice (835 ERA) is parsed and reconciled — paid amounts, patient responsibility, and per-claim detail preserved for posting.

Infrastructure

The whole estate is Azure-native and declared as code in Bicep — reproducible per environment, with no click-ops. CI/CD runs three sequential gates on every change: lint & tests, manifest and event-filter validation, then idempotent SQL migrations, container build, deploy, and smoke tests.

Azure Container Apps
Every service runs as an independently-scaled container app
Bicep IaC
The entire estate is declared as code, modular and parameterized per environment
Azure SQL
Entra-only authentication — no SQL passwords anywhere
Service Bus
The event backbone; topic filters generated from service manifests
Redis
Live practice snapshots, risk scores, and session state
Web PubSub
Real-time WebSocket delivery to clients
Azure OpenAI
LLM reasoning for the agent orchestrator, via managed identity
Key Vault
Secrets isolated from code and never logged
WORM Blob Storage
Immutable archive for the audit ledger
Private networking
VNet + private endpoints in front of data services
Governance & security

Healthcare data demands more than a login screen. Canopy enforces isolation, auditability, and least privilege at the database layer — below the application — so the guarantees hold no matter what calls in.

Multi-tenant by construction

Row-Level Security scopes every query to a single practice at the database layer — a query from one practice can never see another's rows, even on a shared connection.

Immutable audit ledger

Every governed change appends to a per-practice, SHA-256 hash-chained ledger. Database triggers block any UPDATE or DELETE — the record is provably tamper-evident.

Risk-banded verdicts

A deterministic risk engine assigns each action a verdict band — auto-execute, propose-and-confirm, require-approval, or block — and a live risk score can only escalate it, never relax it.

Role-based access

Six roles and ten permissions, enforced in the database, gate who can submit claims, post payments, approve write-offs, or export audit data.

Policy as code

An Open Policy Agent sidecar evaluates every governed write against versioned policy, with explicit fail-open / fail-closed modes.

Humans and agents, one rulebook

AI agents execute through the exact same governed-write path as people — same scoring, same audit, same approvals. Autonomy never bypasses governance.

Built with
PythonFastAPIAzure Container AppsBicepAzure SQL / T-SQLService BusRedisWeb PubSubAzure OpenAIOpen Policy AgentDockerGitHub ActionsX12 EDIDICOM

Want the rest of the story?

Ask Iris about Canopy, the rest of my work, or how to reach me directly.

Talk to Iris →