From trace to program
August 26, 2026 ยท View on GitHub
A single demonstration under-specifies intent, so openadapt-flow does not stop at replaying one. These capabilities layer onto the same $0, model-free runtime.
- A workflow program. Beyond the linear v0
bundle, the IR (
openadapt_flow/ir.py) expresses a parameterized program: states and guarded transitions, loops over worklists, subflows, typed parameters, predicates, and exception paths (ProgramGraph/State/Transition/LoopSpec/Guard/Predicate/ParamSpec). The flat trajectory is the degenerate case, so the migration is backward-compatible. Design:design/WORKFLOW_PROGRAM_IR.md. - A data-driven loop from one demonstration.
for-eachwraps a single linear bundle's body in one governed LOOP that runs once per record of a worklist (CSV or JSON), binding each record's columns to the workflow's parameters. Every iteration keeps the same gates: bounded by a hard--max-iterationscap, identity-checked and effect-verified per record, halting on an ambiguous or refuted write instead of skipping it. The column-to-parameter mapping is explicit and validated, so an unmapped column, a bound parameter with no value, or a ragged worklist fails at authoring time rather than emitting a bad bundle. This turns a replay of one recorded path into governed execution over a queue:openadapt-flow for-each bundle --records worklist.csv --out queue-bundle. - See what a demonstration compiled into.
visualizerenders a program-graph view of a bundle before it runs: the ordered steps, the resolution ladder each step will try, where an identity gate is armed, which writes carry an effect check, and every point the run can halt. Emit a self-contained offline HTML page, Mermaid for docs, or the shared JSON graph spec that the Cloud and desktop surfaces render (openadapt-flow visualize bundle -o graph.html). SeeVISUALIZE.md. - Multi-trace induction that refuses when it isn't sure.
induce_programaligns several demonstrations of the same task to recover the shared parameters, loops, and branches, deterministic and model-free at its core. When a branch condition or a value stays underdetermined it quarantines the program (certifiedisFalse) instead of guessing, anddisambiguatesurfaces the ambiguity as concrete multiple-choice questions rather than inventing an answer. - Effect verification against the system of record. The screen can lie: an
optimistic UI, a duplicate submit, a partial save all read as success. A step
may declare typed
effects, and when a run is given anEffectVerifierthe replayer checks the real record out of band, before and after the action, halting on a refuted or unverifiable write, still with zero model calls. The oracle is pluggable: SQL, REST (RestRecordVerifier), FHIR (FhirEffectVerifier), or a document hash (DocumentHashVerifier). A fault-model study found the screen-only oracle silently mishandles 5 of 7 transactional fault classes; all five halt through the real replayer once effects are declared (../benchmark/fault_model/FAULT_MODEL.md,design/EFFECT_VERIFIER.md). Two honest preconditions bound this: the compiler does not yet infer effects from a demonstration (they are authored per deployment against the app's system of record), and a run with no verifier configured falls back to the screen oracle. The net exists only when both are supplied; without them the write is exactly as silent as before. - An API actuator tier. Where the target app exposes a real API, driving its
GUI to make the write is the wrong tool. A step carrying an
ApiBinding, with anApiActuatorconfigured, performs the write by calling the API deterministically and confirms it with the sameEffectVerifier, theapileaf of the capability ladder (API, then DOM/UIA, geometry, OCR, template, VLM, human). It is an optimization whose safe fallback is always the GUI. - Policy: lint and certify.
lintreports a bundle's coverage gaps (unarmed clicks, vacuous postconditions, under-classified risk) with a severity each;certifyenforces a policy and exits nonzero, refusing a bundle before it deploys. Runnable is not the same as certified safe. Certification is optional and opt-in (an uncertified bundle still runs), and a policy only defines what a bundle must satisfy, so the honest claim is that a certified workflow can be configured to halt on the conditions its policy names, not that any workflow always halts. - Governed healing. Every fix under drift lands in the bundle as a reviewable diff, and a step classified irreversible will not act on a low-confidence match. Structure and the identity gate govern the heal; they are not bypassed by it.
- Durable checkpoint / resume. A run checkpoints verified progress
(
openadapt_flow/runtime/durable/) so a halt becomes a durable pause the operator can approve and resume from the last verified state (resume/approve), not a restart, and explicitly not "hand the rest to a free-form agent." - PHI-free identity. The wrong-patient identity check can run against a
salted-hash, shape-preserving
IdentityTemplateinstead of a plaintext name / DOB / MRN band, so a compiled bundle need carry no readable PHI while still enforcing identity (openadapt_flow/runtime/identity_template.py).
Compiled workflows can also be emitted as Agent Skills or MCP servers
(emit-skill / emit-mcp), so other agents can invoke them.
Answer a halt from a phone
An attended run can project one signed operational-halt task to an
authenticated phone view. The task identifies one exact tenant, runner, run,
pause, capability, bundle, event sequence, expiry, and idempotency scope. A
negotiated V2 task also binds the qualification project, revision, contract,
and exact step. It carries only closed enums, bounded counts, digests, and a
reviewed remote-safe entity class. A custom or missing class becomes the
signed neutral record or item label. The runtime does not infer that label
from a screenshot, OCR, a parameter, an application name, or a model.
The phone shows only the actions in the sealed pause capability. Depending on the exact halt, those can include verify and resume, skip, reject, teach, escalate, or reconcile. A tap does not actuate the target application and does not prove success. The hosted route supplies an AAL2-authenticated principal bound to the exact tenant and runner. The customer-controlled runner matches the current pause again, acquires the action lease, reads a fresh live state, and repeats the required session, identity, target, postcondition, and effect checks before it continues. Reconcile performs a read-only effect check after uncertain delivery; it never repeats the possibly completed action.
The hosted lane uses outbound HTTPS and sends no screenshot. The separate
Desktop portal can show protected evidence through a customer-operated HTTPS
boundary. Try the shared hosted interface with synthetic application data at
app.openadapt.ai/demo/attention, and
read the exact delivery and data-boundary contract in
DECISION_DELIVERY.md. A declared finite
business-policy choice is a different state and receipt contract; see
BUSINESS_DECISIONS.md.