diff --git a/.github/workflows/secret-scan.yml b/.github/workflows/secret-scan.yml
index 7f8909d361..86ece39b0c 100644
--- a/.github/workflows/secret-scan.yml
+++ b/.github/workflows/secret-scan.yml
@@ -48,4 +48,34 @@ jobs:
# --log-opts=HEAD scans the full history of the checked-out commit (the
# PR merge commit, or main). Without it gitleaks scans every fetched
# branch, so one branch's finding fails every other pull request.
- run: gitleaks git . --config .gitleaks.toml --redact --no-banner --log-opts=HEAD
+ run: |
+ set -euo pipefail
+ report_dir="$(mktemp -d "${RUNNER_TEMP}/gitleaks-report.XXXXXX")"
+ trap 'rm -rf -- "$report_dir"' EXIT
+ report_path="${report_dir}/metadata.tsv"
+ template_path="${report_dir}/metadata.tmpl"
+
+ # Gitleaks' JSON Finding includes fields beyond redacted Secret,
+ # Match, and Line (including optional Fragment). Use its supported
+ # template reporter to serialize only these four metadata fields.
+ # Base64 avoids control-character delimiters in repository paths.
+ cat > "$template_path" <<'EOF'
+ {{range .}}{{printf "%s\t%s\t%d\t%s\n" (.RuleID | b64enc) (.File | b64enc) .StartLine (.Commit | b64enc)}}{{end -}}
+ EOF
+
+ # Never let scanner output enter Actions logs. The template report
+ # contains only RuleID, repository-relative file/line, and commit.
+ set +e
+ gitleaks git . \
+ --config .gitleaks.toml \
+ --redact=100 \
+ --no-banner \
+ --log-opts=HEAD \
+ --report-format=template \
+ --report-template "$template_path" \
+ --report-path "$report_path" \
+ >/dev/null 2>&1
+ scanner_exit_code=$?
+ set -e
+
+ python3 scripts/ci/gitleaks_metadata.py "$report_path" "$scanner_exit_code"
diff --git a/.gitleaksignore b/.gitleaksignore
index f1ecf70645..fb9d5d009f 100644
--- a/.gitleaksignore
+++ b/.gitleaksignore
@@ -64,3 +64,40 @@ e8ec96725c4451aa64cb97230c18d04b55d98503:packages/flow/tests/e2e/test_mcp_teach_
# container with a fixed synthetic superuser token (a run of hex digits, never a
# credential for any real system); the harness now generates it per run.
9922cee8dbbbaa4494b1c69ec6c71e4899305de6:packages/flow/benchmark/api_generalization/apps/nb.py:generic-api-key:60
+# Bundle compatibility fixtures (PR #1928, part of #1899): the generic-api-key rule
+# matched `source_hashes` entries in the pinned 2.2.0/2.5.0/2.6.0 provenance.json
+# fixtures. Each value is the SHA-256 of that source file at the fixture's pinned
+# release commit (verified for all 33). Content digests, not credentials.
+8ccf2cf3360b7d7720af04c36eee4f8e756bdf6e:packages/flow/tests/fixtures/bundle_compatibility/2.2.0/provenance.json:generic-api-key:66
+8ccf2cf3360b7d7720af04c36eee4f8e756bdf6e:packages/flow/tests/fixtures/bundle_compatibility/2.2.0/provenance.json:generic-api-key:182
+8ccf2cf3360b7d7720af04c36eee4f8e756bdf6e:packages/flow/tests/fixtures/bundle_compatibility/2.2.0/provenance.json:generic-api-key:193
+8ccf2cf3360b7d7720af04c36eee4f8e756bdf6e:packages/flow/tests/fixtures/bundle_compatibility/2.2.0/provenance.json:generic-api-key:248
+8ccf2cf3360b7d7720af04c36eee4f8e756bdf6e:packages/flow/tests/fixtures/bundle_compatibility/2.2.0/provenance.json:generic-api-key:290
+8ccf2cf3360b7d7720af04c36eee4f8e756bdf6e:packages/flow/tests/fixtures/bundle_compatibility/2.2.0/provenance.json:generic-api-key:348
+8ccf2cf3360b7d7720af04c36eee4f8e756bdf6e:packages/flow/tests/fixtures/bundle_compatibility/2.2.0/provenance.json:generic-api-key:397
+8ccf2cf3360b7d7720af04c36eee4f8e756bdf6e:packages/flow/tests/fixtures/bundle_compatibility/2.2.0/provenance.json:generic-api-key:416
+8ccf2cf3360b7d7720af04c36eee4f8e756bdf6e:packages/flow/tests/fixtures/bundle_compatibility/2.2.0/provenance.json:generic-api-key:428
+8ccf2cf3360b7d7720af04c36eee4f8e756bdf6e:packages/flow/tests/fixtures/bundle_compatibility/2.5.0/provenance.json:generic-api-key:85
+8ccf2cf3360b7d7720af04c36eee4f8e756bdf6e:packages/flow/tests/fixtures/bundle_compatibility/2.5.0/provenance.json:generic-api-key:155
+8ccf2cf3360b7d7720af04c36eee4f8e756bdf6e:packages/flow/tests/fixtures/bundle_compatibility/2.5.0/provenance.json:generic-api-key:190
+8ccf2cf3360b7d7720af04c36eee4f8e756bdf6e:packages/flow/tests/fixtures/bundle_compatibility/2.5.0/provenance.json:generic-api-key:275
+8ccf2cf3360b7d7720af04c36eee4f8e756bdf6e:packages/flow/tests/fixtures/bundle_compatibility/2.5.0/provenance.json:generic-api-key:351
+8ccf2cf3360b7d7720af04c36eee4f8e756bdf6e:packages/flow/tests/fixtures/bundle_compatibility/2.5.0/provenance.json:generic-api-key:414
+8ccf2cf3360b7d7720af04c36eee4f8e756bdf6e:packages/flow/tests/fixtures/bundle_compatibility/2.5.0/provenance.json:generic-api-key:488
+8ccf2cf3360b7d7720af04c36eee4f8e756bdf6e:packages/flow/tests/fixtures/bundle_compatibility/2.5.0/provenance.json:generic-api-key:508
+8ccf2cf3360b7d7720af04c36eee4f8e756bdf6e:packages/flow/tests/fixtures/bundle_compatibility/2.5.0/provenance.json:generic-api-key:528
+8ccf2cf3360b7d7720af04c36eee4f8e756bdf6e:packages/flow/tests/fixtures/bundle_compatibility/2.5.0/provenance.json:generic-api-key:570
+8ccf2cf3360b7d7720af04c36eee4f8e756bdf6e:packages/flow/tests/fixtures/bundle_compatibility/2.5.0/provenance.json:generic-api-key:643
+8ccf2cf3360b7d7720af04c36eee4f8e756bdf6e:packages/flow/tests/fixtures/bundle_compatibility/2.5.0/provenance.json:generic-api-key:655
+8ccf2cf3360b7d7720af04c36eee4f8e756bdf6e:packages/flow/tests/fixtures/bundle_compatibility/2.6.0/provenance.json:generic-api-key:85
+8ccf2cf3360b7d7720af04c36eee4f8e756bdf6e:packages/flow/tests/fixtures/bundle_compatibility/2.6.0/provenance.json:generic-api-key:132
+8ccf2cf3360b7d7720af04c36eee4f8e756bdf6e:packages/flow/tests/fixtures/bundle_compatibility/2.6.0/provenance.json:generic-api-key:168
+8ccf2cf3360b7d7720af04c36eee4f8e756bdf6e:packages/flow/tests/fixtures/bundle_compatibility/2.6.0/provenance.json:generic-api-key:254
+8ccf2cf3360b7d7720af04c36eee4f8e756bdf6e:packages/flow/tests/fixtures/bundle_compatibility/2.6.0/provenance.json:generic-api-key:316
+8ccf2cf3360b7d7720af04c36eee4f8e756bdf6e:packages/flow/tests/fixtures/bundle_compatibility/2.6.0/provenance.json:generic-api-key:379
+8ccf2cf3360b7d7720af04c36eee4f8e756bdf6e:packages/flow/tests/fixtures/bundle_compatibility/2.6.0/provenance.json:generic-api-key:468
+8ccf2cf3360b7d7720af04c36eee4f8e756bdf6e:packages/flow/tests/fixtures/bundle_compatibility/2.6.0/provenance.json:generic-api-key:490
+8ccf2cf3360b7d7720af04c36eee4f8e756bdf6e:packages/flow/tests/fixtures/bundle_compatibility/2.6.0/provenance.json:generic-api-key:511
+8ccf2cf3360b7d7720af04c36eee4f8e756bdf6e:packages/flow/tests/fixtures/bundle_compatibility/2.6.0/provenance.json:generic-api-key:554
+8ccf2cf3360b7d7720af04c36eee4f8e756bdf6e:packages/flow/tests/fixtures/bundle_compatibility/2.6.0/provenance.json:generic-api-key:630
+8ccf2cf3360b7d7720af04c36eee4f8e756bdf6e:packages/flow/tests/fixtures/bundle_compatibility/2.6.0/provenance.json:generic-api-key:642
diff --git a/packages/flow/docs/BUNDLE_SCHEMA.md b/packages/flow/docs/BUNDLE_SCHEMA.md
new file mode 100644
index 0000000000..2312742855
--- /dev/null
+++ b/packages/flow/docs/BUNDLE_SCHEMA.md
@@ -0,0 +1,40 @@
+# Bundle schema and sealed identity
+
+`Workflow.load` checks the original bundle's manifest-free canonical payload
+before upgrading its schema or constructing the current model. Each supported
+schema has one canonical projection. A digest mismatch refuses the bundle.
+Schema 2's reviewed default omissions apply only at explicit IR ownership
+positions; arbitrary request bodies and mappings remain sealed content.
+
+A missing schema version means legacy schema 1. Upgrades run one registered
+step at a time on a copy. Malformed versions, future versions and missing
+upgrade steps refuse loading. A breaking format change requires a schema bump,
+a canonical format rule and an explicit upgrader.
+
+Loading preserves the original files and content identity. The loaded object
+retains the original canonical bytes plus a fingerprint of the upgraded model
+and its integrity-manifest fields. Later verification checks both representations
+and the sealed assets. Changing the workflow, asset hashes, integrity manifest
+or asset bytes requires a new seal. Loading with `verify_integrity=False` does
+not make a broken original seal pass a later integrity check.
+
+Admission and authorization use `content_identity_digest` to retain a verified
+original identity across model upgrades. It checks the loaded model, original
+payload, integrity manifest and supplied asset hashes before returning that
+identity. Callers checking live assets must hash their bytes or call
+`verify_integrity` as well.
+
+`Workflow.save(..., seal_manifest=True)` creates a seal over the current
+serialization; this is also the default save behavior. Saving a loaded sealed
+object with `seal_manifest=False` refuses. A format upgrade can change the new
+seal's identity, so existing admissions must be evaluated against the new seal.
+`compute_content_digest` continues to calculate current-format content for new
+seals.
+
+The frozen compatibility fixtures cover synthetic linear and program bundles
+produced and self-verified by the pinned 2.2.0, 2.5.0 and 2.6.0 source releases.
+Their original bytes and provenance were frozen before testing the current
+loader. The fixture README records the historical environment limitations.
+Current controls verify loading, integrity, tamper refusal and one exact input
+in an owned synthetic headless Chromium page. Content digests provide integrity;
+run authorization still applies its policy, identity and effect checks.
diff --git a/packages/flow/openadapt_flow/admit_pipeline.py b/packages/flow/openadapt_flow/admit_pipeline.py
index 0d63dfe9ec..f8ae813231 100644
--- a/packages/flow/openadapt_flow/admit_pipeline.py
+++ b/packages/flow/openadapt_flow/admit_pipeline.py
@@ -206,15 +206,15 @@ def _now() -> str:
def _bundle_digest(bundle: Path) -> str:
from openadapt_flow import sealed_set
from openadapt_flow.bundle_validation import (
- compute_content_digest,
compute_file_hashes,
+ content_identity_digest,
)
from openadapt_flow.ir import Workflow
workflow = Workflow.load(bundle)
# A sealed bundle's crops are ciphertext on disk; hash the plaintext.
assets = workflow.decrypted_templates() if sealed_set.is_sealed(bundle) else None
- return compute_content_digest(
+ return content_identity_digest(
workflow, compute_file_hashes(workflow, bundle, assets=assets)
)
diff --git a/packages/flow/openadapt_flow/admitted_composition.py b/packages/flow/openadapt_flow/admitted_composition.py
index ed716e825d..dc6f9065e6 100644
--- a/packages/flow/openadapt_flow/admitted_composition.py
+++ b/packages/flow/openadapt_flow/admitted_composition.py
@@ -401,8 +401,8 @@ def live_bundle_content_digest(workflow: Workflow, bundle_dir: Path | str) -> st
"""SHA-256 of the live admitted bundle, independent of the envelope."""
from openadapt_flow.bundle_validation import (
- compute_content_digest,
compute_file_hashes,
+ content_identity_digest,
)
bundle = Path(bundle_dir)
@@ -410,7 +410,7 @@ def live_bundle_content_digest(workflow: Workflow, bundle_dir: Path | str) -> st
file_hashes = dict(workflow.manifest.file_hashes)
else:
file_hashes = compute_file_hashes(workflow, bundle)
- return compute_content_digest(workflow, file_hashes)
+ return content_identity_digest(workflow, file_hashes)
def load_child_envelope(
diff --git a/packages/flow/openadapt_flow/authorization_summary.py b/packages/flow/openadapt_flow/authorization_summary.py
index a8e71e1eea..6ce5648b25 100644
--- a/packages/flow/openadapt_flow/authorization_summary.py
+++ b/packages/flow/openadapt_flow/authorization_summary.py
@@ -51,17 +51,15 @@ def __init__(self, code: str, detail: str = "") -> None:
def bundle_digest(bundle_dir: Path) -> str:
- """Recompute a bundle's content digest from its files (not from its manifest)."""
+ """Verify content identity against the original seal and current asset bytes."""
from openadapt_flow.bundle_validation import (
- compute_content_digest,
compute_file_hashes,
+ content_identity_digest,
)
from openadapt_flow.ir import Workflow
- workflow = Workflow.model_validate_json(
- (Path(bundle_dir) / "workflow.json").read_text(encoding="utf-8")
- )
- return compute_content_digest(workflow, compute_file_hashes(workflow, bundle_dir))
+ workflow = Workflow.load(bundle_dir)
+ return content_identity_digest(workflow, compute_file_hashes(workflow, bundle_dir))
def matching_bundle(digest: str, candidates: Sequence[Path]) -> Optional[Path]:
diff --git a/packages/flow/openadapt_flow/bundle_validation.py b/packages/flow/openadapt_flow/bundle_validation.py
index 78c3044234..115f9ee8db 100644
--- a/packages/flow/openadapt_flow/bundle_validation.py
+++ b/packages/flow/openadapt_flow/bundle_validation.py
@@ -39,6 +39,7 @@
from __future__ import annotations
+import copy
import hashlib
import json
from dataclasses import dataclass
@@ -375,6 +376,147 @@ def _apply_sealed_canonical_omissions(
)
+# Schema-2 ownership is a format rule, not a recursive key-name filter. Only
+# these typed IR positions can own a compatibility omission; arbitrary mapping
+# values (for example an API request body) remain byte-semantically sealed.
+_SOURCE_V2_CHILDREN = {
+ "Workflow": {
+ "steps": ("Step", "list"),
+ "program": ("ProgramGraph", "one"),
+ "subflows": ("ProgramGraph", "map"),
+ "undo_steps": ("UndoStep", "list"),
+ "interstitials": ("Interstitial", "list"),
+ "halt_cleanup": ("HaltCleanup", "one"),
+ },
+ "ProgramGraph": {"states": ("State", "map")},
+ "State": {
+ "step": ("Step", "one"),
+ "transitions": ("Transition", "list"),
+ "decision": ("BusinessDecisionSpec", "one"),
+ },
+ "BusinessDecisionSpec": {"revalidation": ("Predicate", "list")},
+ "Transition": {"guard": ("Predicate", "one")},
+ "UndoStep": {"steps": ("Step", "list")},
+ "HaltCleanup": {"steps": ("Step", "list"), "start_state": ("Predicate", "one")},
+ "Interstitial": {
+ "detect": ("Predicate", "one"),
+ "clearance": ("Predicate", "one"),
+ "dismiss_anchor": ("Anchor", "one"),
+ },
+ "Step": {
+ "anchor": ("Anchor", "one"),
+ "drag_end_anchor": ("Anchor", "one"),
+ "effects": ("Effect", "list"),
+ "api_binding": ("ApiBinding", "one"),
+ "wait_until": ("Predicate", "one"),
+ "guard": ("Guard", "one"),
+ },
+ "Guard": {"predicate": ("Predicate", "one")},
+ "Predicate": {"anchor": ("Anchor", "one"), "operands": ("Predicate", "list")},
+ "Anchor": {"structural": ("StructuralLocator", "one")},
+ "ApiBinding": {"effects": ("Effect", "list")},
+}
+
+
+def _source_v2_omissions(content: object, owner: str = "Workflow") -> None:
+ if not isinstance(content, dict):
+ return
+ for rule in _SEALED_CANONICAL_OMISSIONS_BY_VERSION[2]:
+ if (
+ rule.owner.__name__ == owner
+ and rule.field_name in content
+ and any(content[rule.field_name] == value for value in rule.omitted_values)
+ ):
+ content.pop(rule.field_name)
+ for field_name, (child_owner, shape) in _SOURCE_V2_CHILDREN.get(owner, {}).items():
+ child = content.get(field_name)
+ if shape == "one":
+ _source_v2_omissions(child, child_owner)
+ elif shape == "list" and isinstance(child, list):
+ for value in child:
+ _source_v2_omissions(value, child_owner)
+ elif shape == "map" and isinstance(child, dict):
+ for value in child.values():
+ _source_v2_omissions(value, child_owner)
+
+
+def source_canonical_payload(raw: dict, file_hashes: dict[str, str]) -> bytes:
+ """The original format's canonical payload, before parsing or migration.
+
+ No current Workflow is constructed or serialized here. Every format has
+ exactly one canonical projection; a mismatch never tries another digest.
+ """
+ version = bundle_schema_version(raw)
+ content = copy.deepcopy(raw)
+ content.pop("manifest", None)
+ if version == 2:
+ _source_v2_omissions(content)
+ elif version != 1:
+ raise BundleSchemaError(f"no canonical format rule for schema {version}")
+ return json.dumps(
+ {"workflow": content, "files": dict(sorted(file_hashes.items()))},
+ sort_keys=True,
+ separators=(",", ":"),
+ ensure_ascii=False,
+ ).encode("utf-8")
+
+
+@dataclass(frozen=True)
+class _LoadedSeal:
+ original_payload: bytes
+ runtime_digest: str
+ content_digest: str
+ file_hashes: tuple[tuple[str, str], ...]
+ schema_version: int
+ encrypted: bool
+
+
+def verify_original_content(raw: dict, stored: BundleManifest) -> bytes:
+ payload = source_canonical_payload(raw, stored.file_hashes)
+ if stored.content_digest and _sha256_bytes(payload) != stored.content_digest:
+ raise BundleIntegrityError(
+ "bundle original content digest mismatch before migration"
+ )
+ return payload
+
+
+def remember_original_content(
+ workflow: "Workflow", payload: bytes, stored: BundleManifest
+) -> None:
+ # The original payload is immutable; this second fingerprint detects later
+ # mutation of the upgraded runtime object without reserializing the source.
+ workflow._loaded_seal = _LoadedSeal(
+ payload,
+ compute_content_digest(workflow, stored.file_hashes),
+ stored.content_digest,
+ tuple(sorted(stored.file_hashes.items())),
+ stored.schema_version,
+ stored.encrypted,
+ )
+
+
+def _verify_workflow_content(workflow: "Workflow", stored: BundleManifest) -> None:
+ loaded = workflow._loaded_seal
+ expected = stored.content_digest
+ if loaded is not None:
+ if (
+ stored.content_digest != loaded.content_digest
+ or tuple(sorted(stored.file_hashes.items())) != loaded.file_hashes
+ or stored.schema_version != loaded.schema_version
+ or stored.encrypted != loaded.encrypted
+ or _sha256_bytes(loaded.original_payload) != stored.content_digest
+ ):
+ raise BundleIntegrityError(
+ "bundle original manifest integrity changed after loading"
+ )
+ expected = loaded.runtime_digest
+ recomputed = compute_content_digest(workflow, stored.file_hashes)
+ if recomputed != expected:
+ raise BundleIntegrityError(
+ "bundle content digest mismatch: the workflow was modified after the manifest was sealed"
+ )
+
+
def _referenced_asset_paths(workflow: "Workflow") -> set[str]:
"""Every bundle-relative image path the IR references (templates, identifier
crops, postcondition template crops), across the linear steps AND every
@@ -504,6 +646,28 @@ def compute_content_digest(workflow: "Workflow", file_hashes: dict[str, str]) ->
return _sha256_bytes(canonical.encode("utf-8"))
+def content_identity_digest(workflow: "Workflow", file_hashes: dict[str, str]) -> str:
+ """Return current content identity or an unchanged loaded seal's identity.
+
+ A loaded original seal is reusable only while its original payload, upgraded
+ model, integrity manifest and supplied asset hashes still verify. This does
+ not read assets: callers that need a disk check supply freshly hashed files
+ or separately call verify_integrity. New serialization/build_manifest always
+ uses compute_content_digest instead, so a new seal covers its new format.
+ """
+ loaded = workflow._loaded_seal
+ if loaded is None:
+ return compute_content_digest(workflow, file_hashes)
+ if workflow.manifest is None:
+ raise BundleIntegrityError("loaded bundle lost its original manifest")
+ _verify_workflow_content(workflow, workflow.manifest)
+ if tuple(sorted(file_hashes.items())) != loaded.file_hashes:
+ raise BundleIntegrityError(
+ "bundle asset hashes changed since the original seal"
+ )
+ return loaded.content_digest
+
+
def build_runtime_parameter_schema(workflow: "Workflow") -> list[dict]:
"""Return the canonical hosted parameter contract without runtime values.
@@ -604,25 +768,46 @@ def build_manifest(
from openadapt_flow.ir import SCHEMA_VERSION # noqa: E402
-def migrate_bundle_dict(data: dict) -> dict:
- """Migrate a raw ``workflow.json`` dict to the current schema version.
-
- v2 is a strict, ADDITIVE superset of v1 (typed params, program graph,
- manifest, ... all default-empty), so migrating a v1 bundle needs no field
- transforms -- it only stamps the current ``schema_version`` so downstream
- code can rely on it. A bundle with no ``schema_version`` key is treated as
- the original v1 shape. Returns the SAME dict, mutated in place, for
- convenience. Forward-compatible: a bundle already at (or above) the current
- version is left untouched."""
+class BundleSchemaError(ValueError):
+ """The bundle format is unsupported or lacks a deterministic upgrade step."""
+
+
+def bundle_schema_version(data: dict) -> int:
+ if not isinstance(data, dict):
+ raise BundleSchemaError("workflow.json must contain an object")
version = data.get("schema_version", 1)
- if not isinstance(version, int):
- version = 1
- if version < SCHEMA_VERSION:
- # --- future field transforms would live here, gated on `version` ---
- data["schema_version"] = SCHEMA_VERSION
+ if type(version) is not int or not 1 <= version <= SCHEMA_VERSION:
+ raise BundleSchemaError(f"unsupported bundle schema version: {version!r}")
+ return version
+
+
+def _upgrade_v1_to_v2(data: dict) -> dict:
+ # Schema 1 has no integrity manifest. Schema 2 is additive, so the only
+ # representation change is the explicit version stamp, on a copy.
+ data["schema_version"] = 2
return data
+_BUNDLE_UPGRADERS = {1: _upgrade_v1_to_v2}
+
+
+def migrate_bundle_dict(data: dict) -> dict:
+ """Upgrade one explicit format step at a time without changing the source."""
+ version = bundle_schema_version(data)
+ upgraded = copy.deepcopy(data)
+ while version < SCHEMA_VERSION:
+ upgrader = _BUNDLE_UPGRADERS.get(version)
+ if upgrader is None:
+ raise BundleSchemaError(f"no upgrader from bundle schema {version}")
+ upgraded = upgrader(upgraded)
+ if bundle_schema_version(upgraded) != version + 1:
+ raise BundleSchemaError(
+ f"upgrader from schema {version} did not advance one step"
+ )
+ version += 1
+ return upgraded
+
+
# ---------------------------------------------------------------------------
# Integrity
# ---------------------------------------------------------------------------
@@ -660,19 +845,13 @@ def verify_integrity(
Only meaningful for a bundle that carries a persisted manifest with a
non-empty digest; legacy (pre-v2) bundles have no sealed digest to compare
against, and the caller skips this check for them."""
- if not stored.content_digest:
+ if not stored.content_digest and workflow._loaded_seal is None:
return
# 1. Recompute the digest over the loaded workflow content using the SEALED
# file-hash list (NOT re-hashed from disk), so post-seal template
# additions do not move it -- only a workflow.json edit (or a change to
# the sealed asset set) breaks this.
- recomputed = compute_content_digest(workflow, stored.file_hashes)
- if recomputed != stored.content_digest:
- raise BundleIntegrityError(
- "bundle content digest mismatch: expected "
- f"{stored.content_digest[:16]}..., recomputed {recomputed[:16]}... "
- "-- the workflow.json was modified after the manifest was sealed"
- )
+ _verify_workflow_content(workflow, stored)
# 2. Each sealed asset must still hash to its recorded value.
bundle = Path(bundle_dir)
for rel, expected in stored.file_hashes.items():
diff --git a/packages/flow/openadapt_flow/ir.py b/packages/flow/openadapt_flow/ir.py
index dd946abc4b..151d6fd0bf 100644
--- a/packages/flow/openadapt_flow/ir.py
+++ b/packages/flow/openadapt_flow/ir.py
@@ -3224,15 +3224,9 @@ def _verify_sealed_template_integrity(
mismatch. Skipped for a bundle with no sealed digest."""
from openadapt_flow import bundle_validation as _bv
- if not stored.content_digest:
+ if not stored.content_digest and workflow._loaded_seal is None:
return
- recomputed = _bv.compute_content_digest(workflow, stored.file_hashes)
- if recomputed != stored.content_digest:
- raise _bv.BundleIntegrityError(
- "bundle content digest mismatch on decrypt: expected "
- f"{stored.content_digest[:16]}..., recomputed {recomputed[:16]}... "
- "-- the workflow.json was modified after the manifest was sealed"
- )
+ _bv._verify_workflow_content(workflow, stored)
for rel, expected in stored.file_hashes.items():
data = decrypted.get(rel)
if data is None:
@@ -3400,6 +3394,8 @@ class Workflow(BaseModel):
# from ``model_dump`` / the content digest (a private attribute). The
# resolver consumes a decrypted crop via :meth:`decrypted_template`.
_decrypted_templates: dict[str, bytes] = PrivateAttr(default_factory=dict)
+ # Immutable source seal + upgraded-model fingerprint; never serialized.
+ _loaded_seal: Any = PrivateAttr(default=None)
@model_validator(mode="after")
def _undo_ids_are_unique(self) -> "Workflow":
@@ -3522,6 +3518,13 @@ def save(
Returns the path actually written (``workflow.json`` or, when encrypted,
``workflow.json.enc``).
"""
+ from openadapt_flow import bundle_validation as _bv
+
+ _bv.bundle_schema_version({"schema_version": self.schema_version})
+ if self._loaded_seal is not None and not seal_manifest:
+ raise _bv.BundleIntegrityError(
+ "a loaded sealed bundle requires explicit resealing before serialization"
+ )
do_encrypt = encrypt or key is not None
bundle = Path(bundle_dir)
from openadapt_flow import sealed_set as _sealed
@@ -3548,6 +3551,15 @@ def save(
self.manifest = _bv.build_manifest(self, bundle)
serialized = self.model_dump_json(indent=2)
+ resealed_payload = None
+ if (
+ self._loaded_seal is not None
+ and seal_manifest
+ and self.manifest is not None
+ ):
+ resealed_payload = _bv.verify_original_content(
+ json.loads(serialized), self.manifest
+ )
plaintext_path = bundle / "workflow.json"
encrypted_path = bundle / "workflow.json.enc"
if do_encrypt:
@@ -3578,6 +3590,8 @@ def save(
(bundle / "manifest.json").write_bytes(
self.manifest.model_dump_json(indent=2).encode("utf-8")
)
+ if resealed_payload is not None and self.manifest is not None:
+ _bv.remember_original_content(self, resealed_payload, self.manifest)
return path
def _save_sealed_set(
@@ -3612,7 +3626,19 @@ def _save_sealed_set(
from openadapt_flow import bundle_validation as _bv
self.manifest = _bv.build_manifest(self, bundle, assets=assets)
- writer.write("workflow.json", self.model_dump_json(indent=2).encode("utf-8"))
+ serialized = self.model_dump_json(indent=2).encode("utf-8")
+ resealed_payload = None
+ if (
+ self._loaded_seal is not None
+ and seal_manifest
+ and self.manifest is not None
+ ):
+ from openadapt_flow import bundle_validation as _bv
+
+ resealed_payload = _bv.verify_original_content(
+ json.loads(serialized), self.manifest
+ )
+ writer.write("workflow.json", serialized)
if self.manifest is not None:
writer.write(
"manifest.json", self.manifest.model_dump_json(indent=2).encode("utf-8")
@@ -3620,6 +3646,8 @@ def _save_sealed_set(
self._decrypted_templates = dict(assets)
if owned:
writer.finalize()
+ if resealed_payload is not None and self.manifest is not None:
+ _bv.remember_original_content(self, resealed_payload, self.manifest)
return bundle / ("workflow.json" + _sealed.SEALED_SUFFIX)
@classmethod
@@ -3684,19 +3712,30 @@ def load(
raw = json.loads(decrypted)
else:
raw = json.loads(plaintext_path.read_bytes())
- raw = _bv.migrate_bundle_dict(raw)
- # A manifest may be embedded in workflow.json OR sit in a sidecar; the
- # embedded one wins, else the sidecar, else it is computed fresh.
+ _bv.bundle_schema_version(raw)
+ # Verify the original canonical representation before upgrading or
+ # constructing today's model. Embedded manifest precedence is unchanged.
persisted = raw.get("manifest")
- wf = cls.model_validate(raw)
-
- if wf.manifest is None:
+ if persisted is None:
sidecar = bundle / "manifest.json"
if sidecar.is_file():
- wf.manifest = BundleManifest.model_validate_json(
- sidecar.read_text(encoding="utf-8")
+ persisted = json.loads(sidecar.read_text(encoding="utf-8"))
+ stored = None
+ original_payload = None
+ if persisted is not None:
+ _bv.bundle_schema_version(persisted)
+ stored = BundleManifest.model_validate(persisted)
+ if stored.content_digest:
+ original_payload = (
+ _bv.verify_original_content(raw, stored)
+ if verify_integrity
+ else _bv.source_canonical_payload(raw, stored.file_hashes)
)
- persisted = wf.manifest
+ wf = cls.model_validate(_bv.migrate_bundle_dict(raw))
+ if stored is not None:
+ wf.manifest = stored
+ if original_payload is not None and stored is not None:
+ _bv.remember_original_content(wf, original_payload, stored)
if sealed_assets is not None:
wf._decrypted_templates = sealed_assets
diff --git a/packages/flow/openadapt_flow/run_gate.py b/packages/flow/openadapt_flow/run_gate.py
index 22f86aa973..5b4197ac00 100644
--- a/packages/flow/openadapt_flow/run_gate.py
+++ b/packages/flow/openadapt_flow/run_gate.py
@@ -1089,9 +1089,15 @@ def build_runtime_authorization(
if report.policy_contract_sha256 is None:
raise ValueError("run gate report has no exact admitted policy digest")
- from openadapt_flow.bundle_validation import compute_content_digest
+ from openadapt_flow.bundle_validation import (
+ BundleIntegrityError,
+ content_identity_digest,
+ )
- recomputed = compute_content_digest(workflow, workflow.manifest.file_hashes)
+ try:
+ recomputed = content_identity_digest(workflow, workflow.manifest.file_hashes)
+ except BundleIntegrityError as exc:
+ raise ValueError("workflow changed after the run gate evaluated it") from exc
if recomputed != report.bundle_content_digest:
raise ValueError("workflow changed after the run gate evaluated it")
diff --git a/packages/flow/openadapt_flow/runtime/authorization.py b/packages/flow/openadapt_flow/runtime/authorization.py
index 807ead3e0b..75aec110ed 100644
--- a/packages/flow/openadapt_flow/runtime/authorization.py
+++ b/packages/flow/openadapt_flow/runtime/authorization.py
@@ -862,9 +862,20 @@ def validate_workflow(self, workflow: Workflow) -> str | None:
"workflow effect-verification minimum changed after authorization"
)
- from openadapt_flow.bundle_validation import compute_content_digest
+ from openadapt_flow.bundle_validation import (
+ BundleIntegrityError,
+ content_identity_digest,
+ )
- recomputed = compute_content_digest(workflow, workflow.manifest.file_hashes)
+ try:
+ recomputed = content_identity_digest(
+ workflow, workflow.manifest.file_hashes
+ )
+ except BundleIntegrityError:
+ return (
+ "governed run authorization no longer matches the current "
+ "in-memory workflow semantics"
+ )
if recomputed != self.bundle_content_digest:
return (
"governed run authorization no longer matches the current "
diff --git a/packages/flow/tests/fixtures/bundle_compatibility/2.2.0/linear/canonical.json b/packages/flow/tests/fixtures/bundle_compatibility/2.2.0/linear/canonical.json
new file mode 100644
index 0000000000..4bc7b3c700
--- /dev/null
+++ b/packages/flow/tests/fixtures/bundle_compatibility/2.2.0/linear/canonical.json
@@ -0,0 +1 @@
+{"files":{"templates/button.png":"fa53ee8e6f7730a17a6b8ea30ebab860d2811526204fcf2c76946850b582b493"},"workflow":{"contains_phi":false,"created_at":"2026-01-02T03:04:05+00:00","data_sources":{},"encrypted":false,"name":"release-compatibility","param_specs":{},"params":{},"phi_scrubbed":false,"program":null,"recording_id":null,"schema_version":2,"secret_params":[],"steps":[{"action":"click","anchor":{"click_point":[80,70],"context_text":null,"identifier_crop":null,"identifier_region":null,"identity_template":null,"landmarks":[],"ocr_text":"Apply","region":[40,50,80,40],"search_pad":80,"structural":{"automation_id":null,"name":null,"role":null,"selector":"#apply","window_name":null},"structured_identity":null,"template":"templates/button.png"},"api_binding":null,"effects":[],"expect":[],"guard":null,"id":"apply","identifier_crop_missing_reason":null,"identity_armed":null,"identity_unarmed_reason":null,"intent":"apply synthetic change","key":null,"param":null,"risk":"reversible","scroll_dx":null,"scroll_dy":null,"secret":false,"text":null,"timeout_s":10.0,"wait_until":null}],"subflows":{},"viewport":[320,200]}}
\ No newline at end of file
diff --git a/packages/flow/tests/fixtures/bundle_compatibility/2.2.0/linear/manifest.json b/packages/flow/tests/fixtures/bundle_compatibility/2.2.0/linear/manifest.json
new file mode 100644
index 0000000000..fa6a38875a
--- /dev/null
+++ b/packages/flow/tests/fixtures/bundle_compatibility/2.2.0/linear/manifest.json
@@ -0,0 +1,22 @@
+{
+ "schema_version": 2,
+ "content_digest": "f44b31062baf7e119b04bea142ad87120568cf5c9f94712a0c3e137a123edf7b",
+ "file_hashes": {
+ "templates/button.png": "fa53ee8e6f7730a17a6b8ea30ebab860d2811526204fcf2c76946850b582b493"
+ },
+ "provenance": {
+ "compiler_version": "2.2.0",
+ "source_recording_sha256": null,
+ "compiler_config_sha256": null,
+ "created_at": "2026-01-02T03:04:05+00:00",
+ "policy_name": null,
+ "certified": false,
+ "certification_status": null,
+ "certified_at": null,
+ "expires_at": null,
+ "certification_invalidated_at": null,
+ "certification_invalidation_reason": null,
+ "governed_authorization_template": null
+ },
+ "encrypted": false
+}
\ No newline at end of file
diff --git a/packages/flow/tests/fixtures/bundle_compatibility/2.2.0/linear/templates/button.png b/packages/flow/tests/fixtures/bundle_compatibility/2.2.0/linear/templates/button.png
new file mode 100644
index 0000000000..797e0782c9
Binary files /dev/null and b/packages/flow/tests/fixtures/bundle_compatibility/2.2.0/linear/templates/button.png differ
diff --git a/packages/flow/tests/fixtures/bundle_compatibility/2.2.0/linear/workflow.json b/packages/flow/tests/fixtures/bundle_compatibility/2.2.0/linear/workflow.json
new file mode 100644
index 0000000000..57f4091e52
--- /dev/null
+++ b/packages/flow/tests/fixtures/bundle_compatibility/2.2.0/linear/workflow.json
@@ -0,0 +1,103 @@
+{
+ "schema_version": 2,
+ "name": "release-compatibility",
+ "recording_id": null,
+ "contains_phi": false,
+ "phi_scrubbed": false,
+ "encrypted": false,
+ "created_at": "2026-01-02T03:04:05+00:00",
+ "viewport": [
+ 320,
+ 200
+ ],
+ "params": {},
+ "param_specs": {},
+ "secret_params": [],
+ "steps": [
+ {
+ "id": "apply",
+ "intent": "apply synthetic change",
+ "action": "click",
+ "anchor": {
+ "template": "templates/button.png",
+ "structural": {
+ "selector": "#apply",
+ "frame_path": null,
+ "role": null,
+ "name": null,
+ "automation_id": null,
+ "window_name": null
+ },
+ "region": [
+ 40,
+ 50,
+ 80,
+ 40
+ ],
+ "click_point": [
+ 80,
+ 70
+ ],
+ "ocr_text": "Apply",
+ "context_text": null,
+ "structured_identity": null,
+ "identity_template": null,
+ "identifier_crop": null,
+ "identifier_region": null,
+ "landmarks": [],
+ "search_pad": 80
+ },
+ "text": null,
+ "param": null,
+ "secret": false,
+ "field_label": null,
+ "selection_commit_key": null,
+ "selection_region": null,
+ "key": null,
+ "modifiers": [],
+ "drag_end_anchor": null,
+ "scroll_dx": null,
+ "scroll_dy": null,
+ "expect": [],
+ "effects": [],
+ "api_binding": null,
+ "risk": "reversible",
+ "risk_explanation": null,
+ "risk_review_required": false,
+ "wait_until": null,
+ "guard": null,
+ "timeout_s": 10.0,
+ "identity_armed": null,
+ "identity_unarmed_reason": null,
+ "identifier_crop_missing_reason": null,
+ "submit_binding": null,
+ "submit_binding_unbound_reason": null
+ }
+ ],
+ "interstitials": [],
+ "program": null,
+ "subflows": {},
+ "data_sources": {},
+ "manifest": {
+ "schema_version": 2,
+ "content_digest": "f44b31062baf7e119b04bea142ad87120568cf5c9f94712a0c3e137a123edf7b",
+ "file_hashes": {
+ "templates/button.png": "fa53ee8e6f7730a17a6b8ea30ebab860d2811526204fcf2c76946850b582b493"
+ },
+ "provenance": {
+ "compiler_version": "2.2.0",
+ "source_recording_sha256": null,
+ "compiler_config_sha256": null,
+ "created_at": "2026-01-02T03:04:05+00:00",
+ "policy_name": null,
+ "certified": false,
+ "certification_status": null,
+ "certified_at": null,
+ "expires_at": null,
+ "certification_invalidated_at": null,
+ "certification_invalidation_reason": null,
+ "governed_authorization_template": null
+ },
+ "encrypted": false
+ }
+}
\ No newline at end of file
diff --git a/packages/flow/tests/fixtures/bundle_compatibility/2.2.0/program/canonical.json b/packages/flow/tests/fixtures/bundle_compatibility/2.2.0/program/canonical.json
new file mode 100644
index 0000000000..0ee4c36a3b
--- /dev/null
+++ b/packages/flow/tests/fixtures/bundle_compatibility/2.2.0/program/canonical.json
@@ -0,0 +1 @@
+{"files":{"templates/button.png":"fa53ee8e6f7730a17a6b8ea30ebab860d2811526204fcf2c76946850b582b493"},"workflow":{"contains_phi":false,"created_at":"2026-01-02T03:04:05+00:00","data_sources":{},"encrypted":false,"name":"release-compatibility","param_specs":{},"params":{},"phi_scrubbed":false,"program":{"entry":"apply","states":{"apply":{"id":"apply","kind":"action","loop":null,"on_exception":null,"outcome":null,"reason":"","step":{"action":"click","anchor":{"click_point":[80,70],"context_text":null,"identifier_crop":null,"identifier_region":null,"identity_template":null,"landmarks":[],"ocr_text":"Apply","region":[40,50,80,40],"search_pad":80,"structural":{"automation_id":null,"name":null,"role":null,"selector":"#apply","window_name":null},"structured_identity":null,"template":"templates/button.png"},"api_binding":null,"effects":[],"expect":[],"guard":null,"id":"apply","identifier_crop_missing_reason":null,"identity_armed":null,"identity_unarmed_reason":null,"intent":"apply synthetic change","key":null,"param":null,"risk":"reversible","scroll_dx":null,"scroll_dy":null,"secret":false,"text":null,"timeout_s":10.0,"wait_until":null},"subflow":null,"transitions":[{"guard":null,"label":"","target":"done"}]},"done":{"id":"done","kind":"terminal","loop":null,"on_exception":null,"outcome":"success","reason":"","step":null,"subflow":null,"transitions":[]}}},"recording_id":null,"schema_version":2,"secret_params":[],"steps":[],"subflows":{},"viewport":[320,200]}}
\ No newline at end of file
diff --git a/packages/flow/tests/fixtures/bundle_compatibility/2.2.0/program/manifest.json b/packages/flow/tests/fixtures/bundle_compatibility/2.2.0/program/manifest.json
new file mode 100644
index 0000000000..7f449a30b0
--- /dev/null
+++ b/packages/flow/tests/fixtures/bundle_compatibility/2.2.0/program/manifest.json
@@ -0,0 +1,22 @@
+{
+ "schema_version": 2,
+ "content_digest": "7694ed3afd395c21a26e3fbe1b675aa1770b3dc9e2937843f84d48e935b686e2",
+ "file_hashes": {
+ "templates/button.png": "fa53ee8e6f7730a17a6b8ea30ebab860d2811526204fcf2c76946850b582b493"
+ },
+ "provenance": {
+ "compiler_version": "2.2.0",
+ "source_recording_sha256": null,
+ "compiler_config_sha256": null,
+ "created_at": "2026-01-02T03:04:05+00:00",
+ "policy_name": null,
+ "certified": false,
+ "certification_status": null,
+ "certified_at": null,
+ "expires_at": null,
+ "certification_invalidated_at": null,
+ "certification_invalidation_reason": null,
+ "governed_authorization_template": null
+ },
+ "encrypted": false
+}
\ No newline at end of file
diff --git a/packages/flow/tests/fixtures/bundle_compatibility/2.2.0/program/templates/button.png b/packages/flow/tests/fixtures/bundle_compatibility/2.2.0/program/templates/button.png
new file mode 100644
index 0000000000..797e0782c9
Binary files /dev/null and b/packages/flow/tests/fixtures/bundle_compatibility/2.2.0/program/templates/button.png differ
diff --git a/packages/flow/tests/fixtures/bundle_compatibility/2.2.0/program/workflow.json b/packages/flow/tests/fixtures/bundle_compatibility/2.2.0/program/workflow.json
new file mode 100644
index 0000000000..9d677ab2c4
--- /dev/null
+++ b/packages/flow/tests/fixtures/bundle_compatibility/2.2.0/program/workflow.json
@@ -0,0 +1,133 @@
+{
+ "schema_version": 2,
+ "name": "release-compatibility",
+ "recording_id": null,
+ "contains_phi": false,
+ "phi_scrubbed": false,
+ "encrypted": false,
+ "created_at": "2026-01-02T03:04:05+00:00",
+ "viewport": [
+ 320,
+ 200
+ ],
+ "params": {},
+ "param_specs": {},
+ "secret_params": [],
+ "steps": [],
+ "interstitials": [],
+ "program": {
+ "entry": "apply",
+ "states": {
+ "apply": {
+ "id": "apply",
+ "kind": "action",
+ "step": {
+ "id": "apply",
+ "intent": "apply synthetic change",
+ "action": "click",
+ "anchor": {
+ "template": "templates/button.png",
+ "structural": {
+ "selector": "#apply",
+ "frame_path": null,
+ "role": null,
+ "name": null,
+ "automation_id": null,
+ "window_name": null
+ },
+ "region": [
+ 40,
+ 50,
+ 80,
+ 40
+ ],
+ "click_point": [
+ 80,
+ 70
+ ],
+ "ocr_text": "Apply",
+ "context_text": null,
+ "structured_identity": null,
+ "identity_template": null,
+ "identifier_crop": null,
+ "identifier_region": null,
+ "landmarks": [],
+ "search_pad": 80
+ },
+ "text": null,
+ "param": null,
+ "secret": false,
+ "field_label": null,
+ "selection_commit_key": null,
+ "selection_region": null,
+ "key": null,
+ "modifiers": [],
+ "drag_end_anchor": null,
+ "scroll_dx": null,
+ "scroll_dy": null,
+ "expect": [],
+ "effects": [],
+ "api_binding": null,
+ "risk": "reversible",
+ "risk_explanation": null,
+ "risk_review_required": false,
+ "wait_until": null,
+ "guard": null,
+ "timeout_s": 10.0,
+ "identity_armed": null,
+ "identity_unarmed_reason": null,
+ "identifier_crop_missing_reason": null,
+ "submit_binding": null,
+ "submit_binding_unbound_reason": null
+ },
+ "loop": null,
+ "subflow": null,
+ "transitions": [
+ {
+ "guard": null,
+ "target": "done",
+ "label": ""
+ }
+ ],
+ "on_exception": null,
+ "outcome": null,
+ "reason": ""
+ },
+ "done": {
+ "id": "done",
+ "kind": "terminal",
+ "step": null,
+ "loop": null,
+ "subflow": null,
+ "transitions": [],
+ "on_exception": null,
+ "outcome": "success",
+ "reason": ""
+ }
+ }
+ },
+ "subflows": {},
+ "data_sources": {},
+ "manifest": {
+ "schema_version": 2,
+ "content_digest": "7694ed3afd395c21a26e3fbe1b675aa1770b3dc9e2937843f84d48e935b686e2",
+ "file_hashes": {
+ "templates/button.png": "fa53ee8e6f7730a17a6b8ea30ebab860d2811526204fcf2c76946850b582b493"
+ },
+ "provenance": {
+ "compiler_version": "2.2.0",
+ "source_recording_sha256": null,
+ "compiler_config_sha256": null,
+ "created_at": "2026-01-02T03:04:05+00:00",
+ "policy_name": null,
+ "certified": false,
+ "certification_status": null,
+ "certified_at": null,
+ "expires_at": null,
+ "certification_invalidated_at": null,
+ "certification_invalidation_reason": null,
+ "governed_authorization_template": null
+ },
+ "encrypted": false
+ }
+}
\ No newline at end of file
diff --git a/packages/flow/tests/fixtures/bundle_compatibility/2.2.0/provenance.json b/packages/flow/tests/fixtures/bundle_compatibility/2.2.0/provenance.json
new file mode 100644
index 0000000000..511183f1b7
--- /dev/null
+++ b/packages/flow/tests/fixtures/bundle_compatibility/2.2.0/provenance.json
@@ -0,0 +1,505 @@
+{
+ "bundles": [
+ {
+ "content_digest": "f44b31062baf7e119b04bea142ad87120568cf5c9f94712a0c3e137a123edf7b",
+ "files": {
+ "canonical.json": "f44b31062baf7e119b04bea142ad87120568cf5c9f94712a0c3e137a123edf7b",
+ "manifest.json": "e2867647468248a79343d3360464b146463a5d1bf8bbf7416d3e120ca83a8bc8",
+ "templates/button.png": "fa53ee8e6f7730a17a6b8ea30ebab860d2811526204fcf2c76946850b582b493",
+ "workflow.json": "6d3d8d97495c8469c9f4aacf373d1a7f0b2917bbfe1c4e8089fd04c4851fb15e"
+ },
+ "shape": "linear"
+ },
+ {
+ "content_digest": "7694ed3afd395c21a26e3fbe1b675aa1770b3dc9e2937843f84d48e935b686e2",
+ "files": {
+ "canonical.json": "7694ed3afd395c21a26e3fbe1b675aa1770b3dc9e2937843f84d48e935b686e2",
+ "manifest.json": "4e3888284ed3e7fdf38a65df0fef51f13861bd4ddf1023e427f7524fd66356aa",
+ "templates/button.png": "fa53ee8e6f7730a17a6b8ea30ebab860d2811526204fcf2c76946850b582b493",
+ "workflow.json": "015310b2acac4bcc38d3d4ad51a312f4f0539c2eb22ad2499deb45b54fbf4936"
+ },
+ "shape": "program"
+ }
+ ],
+ "commit": "98c437f12b04f11e44fbc864e051252e480a848e",
+ "generator_sha256": "d995443471ee4a6fd6854e53a15da4d3681c798a5af9ffde7d3506d8c5015e28",
+ "original_release_load_verified": true,
+ "pydantic": "2.13.4",
+ "python": "3.12.16",
+ "release": "2.2.0",
+ "source_hashes": {
+ "packages/flow/openadapt_flow/__init__.py": "4fd8206219079fa507c86fd5de4a76a7ceb6f37c0cbe52b6c6bf93fe8f674205",
+ "packages/flow/openadapt_flow/__main__.py": "edb75bbd97a4e7089f2a5848fbe2a0e9cb076c5dab5f32c59cd417ae250c1acd",
+ "packages/flow/openadapt_flow/_browser_setup.py": "d259bd323de12fa03b4bf529d77ccb6350d50f665309c377e6df182525c37e6f",
+ "packages/flow/openadapt_flow/_prewarm.py": "4024f33b41a2fac44b995dfc85a922366b98c18697f6a2b623cb26d72264ed48",
+ "packages/flow/openadapt_flow/action_evidence.py": "d965cd391032e66d42c207330e1ae242ff3b4cb32756b1d167488cdc3346f317",
+ "packages/flow/openadapt_flow/adapters/__init__.py": "2eca3615b0a12e39a4a51fd7bf2c274785014c548e609597029ef7d8299c9a09",
+ "packages/flow/openadapt_flow/adapters/capture.py": "1bb420989121dfb787e3224fd77a87e124cb8404c655836748de823e3d04069f",
+ "packages/flow/openadapt_flow/adapters/desktop_recorder.py": "7f05b9bf03bc1da900d0acceae4cd4ae0a82efc4a3b9ef011c6649e1044b3454",
+ "packages/flow/openadapt_flow/admitted_composition.py": "0fcf3b21a233c9ccf0ee71fec2848a80f755fa941ba5f462a47dd544e8aeeeff",
+ "packages/flow/openadapt_flow/agent/__init__.py": "a08c79b09e45150bd065c5008a2585081ac6c10a1d9c4489dad01718fbb94973",
+ "packages/flow/openadapt_flow/agent/__main__.py": "5780b9a3b365c96d71fa42a6ea977a1518d711ed5c4b4f37b54b16ffbc9d0419",
+ "packages/flow/openadapt_flow/agent/approval.py": "a345a90e0e3fa788b520fd26150971a0a5aaff16173a663541f92845ecf409d7",
+ "packages/flow/openadapt_flow/agent/attended.py": "5fa4c761de375be9ce0f6cf7f72f0230253ccd7546658382a267da2f01cb0f1b",
+ "packages/flow/openadapt_flow/agent/authoring.py": "4726bc89fd69f9db972db851381b209c3862f6e4dee5632d4bfa59d4230d0127",
+ "packages/flow/openadapt_flow/agent/bridge.py": "a5e1e04977d373a5b1474bff1aeecafb0f25ce34a03878ad19dbff2c527e4646",
+ "packages/flow/openadapt_flow/agent/bundles.py": "a3e2d63576adc99fd8e4d53e0fa64f1bec914a070d5c0151ba9278ea923809c9",
+ "packages/flow/openadapt_flow/agent/cards.py": "45ecfb3da287aeb5de1160d1adbcc3590c6cc8c20f7b1b7ab983f643228f62b5",
+ "packages/flow/openadapt_flow/agent/cli.py": "5b67586e704f9ff28a76d83079d9ae15e2196bdb99f7ecd4e44792c2826a17ff",
+ "packages/flow/openadapt_flow/agent/contract.py": "008abebad7df519224e3fc952727186a1f65b042ac92c6da9f94e712a81722c4",
+ "packages/flow/openadapt_flow/agent/copy.py": "9afe666441689375fcb5aaf54632db2e39e0a32edeb95570789f0d7ce4b55423",
+ "packages/flow/openadapt_flow/agent/delegated.py": "49414a62704b93999fcf668db4df737121f4b5d9d22f1b36a94de705d171371e",
+ "packages/flow/openadapt_flow/agent/flow_service.py": "b5bb10bf1cb819bb0aba9185de9e9d1246a823ff343996a7464d8e481785f2dd",
+ "packages/flow/openadapt_flow/agent/mailbox.py": "410999800e632f47507929adc3426d68ebfd6625c1303893a23891cd4184f4a3",
+ "packages/flow/openadapt_flow/agent/mcp.py": "1be16fcbaaf82ddcc95716f1104adb4b88d26b496916bee9abdeba5d6e06399e",
+ "packages/flow/openadapt_flow/agent/mcpb_entry.py": "23db9f1b3af8bed52ee472b36b0272430d11526f045179602724addc92a22ac8",
+ "packages/flow/openadapt_flow/agent/repair.py": "d8490f2524e210a34158627a9f714601f933be925e9d3e5fd0a4713eafd3e614",
+ "packages/flow/openadapt_flow/agent/runner.py": "7f3440168984ec9af708190837b627480c5f1c9c8330d24509c3fe0ad209cb63",
+ "packages/flow/openadapt_flow/agent/runner_bind.py": "91d4006e99378c61af2eb50fc9c03ebfb477cdf9f0d27fa070ee9936fb073e96",
+ "packages/flow/openadapt_flow/agent/runs.py": "abd7041cd1eae1b6017c208e0cf4b083caf965cd2147d0497e896a013cd5cb25",
+ "packages/flow/openadapt_flow/agent/sandbox.py": "5f8d2b611a38a7cc00b255e2c32ccb67f54971b54acac373f13e48d77a8b34c9",
+ "packages/flow/openadapt_flow/agent/seal.py": "7d28c6df1e95e71bb6812889214fd48e477e6c1703070104360e22001d19ed4f",
+ "packages/flow/openadapt_flow/agent/seal_cli.py": "fcae30891db50c28e6a23282ff94a0dce9796c15c7fea46b8fdc34694ff8acc1",
+ "packages/flow/openadapt_flow/agent/service.py": "c8c0b6d83ec0c5f25933339802124369da66dfde9ab1ce942b3f622d8ec9960b",
+ "packages/flow/openadapt_flow/agent/skill.py": "7f1637d4bcfdb54ff5920b06dd3bbf913e6fdbc0030605b455e9223672ad2173",
+ "packages/flow/openadapt_flow/agent/tutorial.py": "ac42a64169cb23fac79943a0ef8e4678922d120d51aa97944e2be707addb3232",
+ "packages/flow/openadapt_flow/api.py": "7a34b5b4a7d5b3b815c4008d9d3efab1badddb77dac7477e17308602d1e532b1",
+ "packages/flow/openadapt_flow/approval_mode/__init__.py": "7d802c15089999853ed4a0b55bdaa1962998f2b8e9ee0170695c7de2ec5c3e10",
+ "packages/flow/openadapt_flow/approval_mode/approver.py": "401c5971cb4e330d8791e5e4e1b89101e730ae2b46701c6e3166a8f06691fe71",
+ "packages/flow/openadapt_flow/approval_mode/coverage.py": "1d91811ed3afeab6fdc5aab965e1076cf36fd8356da790e51fc3c1902cb0e84b",
+ "packages/flow/openadapt_flow/approval_mode/durable_carry.py": "89ae4481314e6da7b693765b6809f57852ccb934df23fe55379000b9e0c4b0a7",
+ "packages/flow/openadapt_flow/approval_mode/form_state.py": "f2548b7f2527e9d648623fc5bafa841feabe8272d6a5822e23d4c937e910ae53",
+ "packages/flow/openadapt_flow/approval_mode/gate.py": "b01d10ba090151c71295a605fac2d9ec26c1a7614ee302b2f7f8df4cbe88841e",
+ "packages/flow/openadapt_flow/approval_mode/item_approval.py": "7479ccc08c25c87cdcfcea4b46617a42e4cb508edcd6e27fbb62220c31e13e27",
+ "packages/flow/openadapt_flow/approval_mode/model.py": "42f121b2a7fc992bc1201ccb8c587d7134fec6fdbc54eb12dacd71ff4a00774a",
+ "packages/flow/openadapt_flow/approval_mode/post.py": "954d2114ae019bdb2291c05e188e231144c400592338a47a3b7c47ee20dfe165",
+ "packages/flow/openadapt_flow/approval_mode/requirements.py": "4f8ba1eff008e45651365929bbbaee873301d993c714168e78456009b06b402b",
+ "packages/flow/openadapt_flow/approval_mode/signed_policy.py": "4dc065c007d6c3112de2af004e36ecd8559ceac8a76eaf9853c1d49f7363c757",
+ "packages/flow/openadapt_flow/approval_mode/switch.py": "d52deeeba1eb097dcc2df472946da375c72e03407fb68e5fe580efe2317e7b57",
+ "packages/flow/openadapt_flow/assurance.py": "5b042e814da9a7aaa448d5d0247cf33f89fd67558dbb2e686e99d9c73cb5d318",
+ "packages/flow/openadapt_flow/attest_bridge.py": "449502e879bc629b851087b86353a0dbd5761508daec92989083f30fdad14fee",
+ "packages/flow/openadapt_flow/authoring.py": "54e35e803a0b70d6d3147f6663625d63baea8269d957723013cb58ec184fbb93",
+ "packages/flow/openadapt_flow/backend.py": "1c8e9ea8524e1bd8172f8dd1b96a55a1a75f2855c64f30d727b297e32af749ae",
+ "packages/flow/openadapt_flow/backends/__init__.py": "c76aa599a2ea0205a3fffb4a33124dbe6637e4b93f0f14d4c604ffa05c2a1869",
+ "packages/flow/openadapt_flow/backends/_browser_process.py": "1f90beb147f32ddc276884c3e6488e3e533a5bb374ccf675fadc16754cb4e137",
+ "packages/flow/openadapt_flow/backends/_page_quiescence.py": "2a8b70efd7f6b006fa8141b02a7e59fe5733e7552eeacfc7e34326c0dde147c0",
+ "packages/flow/openadapt_flow/backends/citrix_workspace.py": "2bc912cfecac2d7d1c4c543cda17a2cbe4b25af195fd8a1d015f6b02661e9665",
+ "packages/flow/openadapt_flow/backends/factory.py": "0d504c4763bcc11a21b838ff3d00c56d7894e7cd68798b48ed6b54c389936552",
+ "packages/flow/openadapt_flow/backends/linux_backend.py": "ff1d40d12c841088e827c572f1f0f886015b831bd2a23c95ceaf1223d1000420",
+ "packages/flow/openadapt_flow/backends/macos_backend.py": "03670f73a133f19edccee54a0be8c52dcf08391223ec9e902683b239a94e5423",
+ "packages/flow/openadapt_flow/backends/parallels_vm.py": "e724f9ec49210e5220d1cc508ab8a1ef984ac43854535b90548b209985109d0c",
+ "packages/flow/openadapt_flow/backends/playwright_backend.py": "35eb3030d07796ac9b5cbe6314b3e52ac3d0258e3260447be389ac2f90084990",
+ "packages/flow/openadapt_flow/backends/rdp_backend.py": "f0275c34c544c469bceca130021a0d2bfecdf42e1c1a5318edfafe57e20468b0",
+ "packages/flow/openadapt_flow/backends/remote_display.py": "838482cb5e45c921e9c70cb76b2b4c053c9d249947e39135dd40d82f0e79bc6c",
+ "packages/flow/openadapt_flow/backends/win32_window_client.py": "17003fee023495f45d18043c07768d5a569d8e0b615003822cfdb96c921315b8",
+ "packages/flow/openadapt_flow/backends/win_agent/__init__.py": "cdba9a2b13137a43d83ff03e4eb02c9e250fbaee84ddd6f174c72d5902da553a",
+ "packages/flow/openadapt_flow/backends/win_agent/server.py": "121a738e1349707212cf4c0534ea5604f066e7fc729f06b35580426fb3db7363",
+ "packages/flow/openadapt_flow/backends/win_agent/tls.py": "51f2af9d258c3acfd095d5a7c83d40d3719bbd2161be7963c03c84687f8922cc",
+ "packages/flow/openadapt_flow/backends/windows_backend.py": "0c37d81c063bf245d52cb281a846b37cc1faca46a17522517b6d78819d64d683",
+ "packages/flow/openadapt_flow/backends/xfreerdp.py": "d0605a82901222b870ae433cd6d2ec8ab49123917526af9663c1d177feb8325f",
+ "packages/flow/openadapt_flow/bench.py": "e90fc71ac1c2033a42b06b872de09550fdd9db02b175d176d250e91c207cedba",
+ "packages/flow/openadapt_flow/benchmark/__init__.py": "c5d84d097f5e007ebd1a4f86a3ae02c6a897939cdfa11f030b263e5e12c0278d",
+ "packages/flow/openadapt_flow/benchmark/agent_baseline.py": "74ac7a8df7b5ca25f31b53062fb89bce4154e10f1c01f2e09c801d87d663df53",
+ "packages/flow/openadapt_flow/benchmark/chart_fonts.py": "e60660a947e09a566567b6d84332d009e4b969f4a450b2cecc81299c5b07ba2e",
+ "packages/flow/openadapt_flow/benchmark/desktop_benchmark.py": "8ed16bb044b338db4814374ddadda57b151d1e7e2a4cb2474d45ce6703116e54",
+ "packages/flow/openadapt_flow/benchmark/dom_arm.py": "62dd7e06840a286d859b442b79ea9b7bd05df56cdc700f140cc2e5cf37d195cc",
+ "packages/flow/openadapt_flow/benchmark/effectbench/__init__.py": "045dfe7dbace5245e7f6ff742984b73cca9e36d973ac0ce4736167a04ae764e6",
+ "packages/flow/openadapt_flow/benchmark/effectbench/metrics.py": "65f74dbfeac3d8761265531b04618270cddca773fb30cbabd49ab79d2f01c95f",
+ "packages/flow/openadapt_flow/benchmark/effectbench/oracle.py": "ec8628819a2c2f29efe36124175b2d349499936efcfe2cedaec5ebb6da9b9fbd",
+ "packages/flow/openadapt_flow/benchmark/effectbench/runner/__init__.py": "a1153140a9bd236aa7afbb551edd305e0d16e14e999ba575dc609d24760c2030",
+ "packages/flow/openadapt_flow/benchmark/effectbench/runner/__main__.py": "eb36799a1ff3168eb049d25a500cca903d3a5e439283d84ade20f21300f3d312",
+ "packages/flow/openadapt_flow/benchmark/effectbench/runner/arms.py": "8cc93711483ffa21e06796b2b9f100effc6811c33c3204e5e9ffd35137b06cd5",
+ "packages/flow/openadapt_flow/benchmark/effectbench/runner/baselines.py": "9d235db2891ce32c088d89edba3553fbbc2911031d29a9ada5caa00c964dd7bd",
+ "packages/flow/openadapt_flow/benchmark/effectbench/runner/compound.py": "c407b37ba39bf066214aa62014c920815be16dffef934f7f3478ee20ef3dc341",
+ "packages/flow/openadapt_flow/benchmark/effectbench/runner/harness.py": "e7848000829d040a35f25ccbbb82041fd460664492dfecee1173092ab492671c",
+ "packages/flow/openadapt_flow/benchmark/effectbench/runner/reference_tasks.py": "c588c8f654e44d035a091b4ca0c861c8e916592d63f387b75ba9702af8da3d7b",
+ "packages/flow/openadapt_flow/benchmark/effectbench/runner/substrate.py": "0cb036fc7c0b97ff776e946de714a1904d0cc36846fcd1c86b4e7820f5c90542",
+ "packages/flow/openadapt_flow/benchmark/effectbench/schema.py": "640848a9ab5932006d2a65f9975b3369146aa1b892b2bd44b879dbe7fe11ef47",
+ "packages/flow/openadapt_flow/benchmark/frappe_lending.py": "4b9c17ab23191dba8ca81d03b924c14e3fdd12280fe9aabe7d4a7e7691229ef0",
+ "packages/flow/openadapt_flow/benchmark/hybrid_benchmark.py": "f37c53370526fe0b3c47a728c3003d6d59aa23b71471f3fc51ae545adaf931ea",
+ "packages/flow/openadapt_flow/benchmark/openemr_benchmark.py": "acb8bc88dc7a175f1f5eb90a6f83371a26e4082b8e1903a69f7d35f8d6737244",
+ "packages/flow/openadapt_flow/benchmark/openemr_local.py": "2f1e9156719eccb745a96d9ef16dc185d73346710d649046512c024b89a1d65a",
+ "packages/flow/openadapt_flow/benchmark/reliability.py": "4510a7983bf200528ebc9795436d15ad5d8cc19bbd9cd88266a17ef8d8d1ae5b",
+ "packages/flow/openadapt_flow/benchmark/run_benchmark.py": "6f001c4c53d7aa6abb744053c347f489c1ce343b117e76f347371179bfc3ace2",
+ "packages/flow/openadapt_flow/benchmark/silent_wrong_action.py": "072d3c16360ff5a1f66786196560d8c62948c38d1600ec99e78ba547b2fa90c5",
+ "packages/flow/openadapt_flow/benchmark/verify.py": "d823f244fdf423381cd30b7f6a2bb6322bf6ed4ee79634c670ae583f5bc48bbc",
+ "packages/flow/openadapt_flow/bundle_sealing.py": "a5b3d8f5ff9f350ee455b929bc34cb436e1945795997d59ab0db6b0ee90d94cb",
+ "packages/flow/openadapt_flow/bundle_validation.py": "1919432f951cc7a8ee035262e15d4d60329ffc5b22c2a71fca38330b786707a3",
+ "packages/flow/openadapt_flow/check_level.py": "114517071438d4445a2251eebe99e2d3a5379efe49d25d9c51a340cc88699ee8",
+ "packages/flow/openadapt_flow/cli_admit.py": "013025769ae2fcdfe4a91d8b8d5f3cbe80db42e345b300fbfaf26d5937c29699",
+ "packages/flow/openadapt_flow/cli_check.py": "12cdfc5c3ef3d1e900c1e0fb577fc46203016c1c5cb9405acda6dfc8156a2425",
+ "packages/flow/openadapt_flow/cli_compose.py": "965a63427ec37964451cdb00fad92065833b6f7cab936c80526c05984b5a68ec",
+ "packages/flow/openadapt_flow/cli_config.py": "a68b1b9db2c60feee3ec0b4ea079bbacc7b90bb052f9660c87b2e7067c593557",
+ "packages/flow/openadapt_flow/cli_fleet.py": "a4678b9b48c6c4817673fcccbd18be21966ae6d64dd89fb143bf26f3dce3c7ff",
+ "packages/flow/openadapt_flow/cli_hints.py": "de2a50cf8968951e13d4e328a5a2d89bc0d79741f3e2c1b628dbc18b12085dce",
+ "packages/flow/openadapt_flow/cli_known_ids.py": "ed965f2369489a87cefb27ea9c9241bdc9b6058c72fc56450006be9951737897",
+ "packages/flow/openadapt_flow/cli_local_seal.py": "a6bd43499da2bae9b26feb29b8914a8a919e47f1c38c383026ff1f23b07f06b3",
+ "packages/flow/openadapt_flow/cli_no_outbound.py": "1afedf45d1874e4aeeabc8cf1d36572f6df8b7ddf54bfcb75189d0bb0f149b47",
+ "packages/flow/openadapt_flow/cli_process.py": "9986948521929660937af2fbd37d0fd396acbc9fc613563d5363e0b1b9e89bbf",
+ "packages/flow/openadapt_flow/cli_service.py": "172c06cc25ada99b0532dee35aa4e4510671cc7e7b24871e8b7294abed8cea0e",
+ "packages/flow/openadapt_flow/cloud_seal.py": "dd473bf2ce29f708e1c1638d70f8b54a3feaf140f27aada14481f31c1d2517ad",
+ "packages/flow/openadapt_flow/compiler/__init__.py": "e38510f5baea14d9d357ab594954ff42f5aff608589ea8ae5d7060e8cf0fa380",
+ "packages/flow/openadapt_flow/compiler/annotate.py": "672ae37ffc79429a812ac607faec3adfd52d272d7fd386121bc728044d8f89de",
+ "packages/flow/openadapt_flow/compiler/binding_admission.py": "5113f27876d3109ebad880c75255e138c67375a7846d4966ac0ab9d9e2f69ee9",
+ "packages/flow/openadapt_flow/compiler/codegen.py": "8d986264d3e5ef17aa9bcde6b0b0e18ab312df9d5fbd9bce9e556fb96a292d2a",
+ "packages/flow/openadapt_flow/compiler/compile.py": "b6bc3d726698f070472f35bcd01dd219af616aa509c22e7fca70c340144e9289",
+ "packages/flow/openadapt_flow/compiler/compose_authoring.py": "84132f230f6cd811d86a1588d08809375282b61227e40f64f5f9fcf2807cfaa1",
+ "packages/flow/openadapt_flow/compiler/disambiguation.py": "2761afc6683f1b72b1126a2482bf1e02f34651489dd28f71a2f57aaddced7fb5",
+ "packages/flow/openadapt_flow/compiler/distill.py": "777d85d85072ef9e1a43fac066aa6767a9ff57a7c7c6ad0724db473342bc91bf",
+ "packages/flow/openadapt_flow/compiler/effect_mining.py": "5e2f472b0d7399e60a03af00103b8a215df3304e26dbe19d971c6619414010eb",
+ "packages/flow/openadapt_flow/compiler/fixup_passes.py": "166d6ac64aa6c5346428b479c4b874e557785bf2043aa71e7f6c2c4b61f84449",
+ "packages/flow/openadapt_flow/compiler/induction.py": "657f20a215735cbcd98dc2f3083d6f514d55bdecc6b046c83a6566764836ff50",
+ "packages/flow/openadapt_flow/compiler/loop_authoring.py": "f9ac89cc50e238a35411741aebb3eee7d76c2b263008957d21cdcb49e89b0ee9",
+ "packages/flow/openadapt_flow/compiler/param_confirm.py": "169fc5abea5ee1554342e6bd050b7fb271e4992767e86a471cc866216c6914eb",
+ "packages/flow/openadapt_flow/compiler/qualification_pins.py": "cd13d0909442a5ee0af9300731b25e313b70f2d69f2dc8441b660cfdd1e8c4c9",
+ "packages/flow/openadapt_flow/compiler/qualification_proposer.py": "d2a27d01b3fc5adf9042052bbcd8acff6381a45201bc87e217a0d12935aed73b",
+ "packages/flow/openadapt_flow/compiler/readback_authoring.py": "add4754707c7f9fdd6a49786bf66dc2995858175b51fe8cc1292d140dc925672",
+ "packages/flow/openadapt_flow/composition.py": "fefffc27473a38c1284b58e298ee15e099d848741aeb9ad50876516034fdcec7",
+ "packages/flow/openadapt_flow/connector/__init__.py": "ea1c554a0de295db995f57f837669419855c9fa1d2fcf958ae4e2feeec37106e",
+ "packages/flow/openadapt_flow/connector/client.py": "1f55a56123fda690c4bb4dfbd6407f4a96c85c2575eb8928cb7aed30b3a20145",
+ "packages/flow/openadapt_flow/connector/config.py": "8dd9f662151ce609e21ead89d4019c77a4ab185a0f1b5690df20dac166701c4d",
+ "packages/flow/openadapt_flow/connector/daemon.py": "3ea5444af51cb28dc84addc4a5db15a6a75486f4ecee93d3b6c09ed7e7ce1366",
+ "packages/flow/openadapt_flow/connector/executor.py": "463aeafed9092b16a654191611445bb5688334ca87ac0703699d6dfa7f449748",
+ "packages/flow/openadapt_flow/connector/protocol.py": "963162e5dc20fe0e220fda67e59d138b791fcc6bbaf626776ab192d6cfe3a203",
+ "packages/flow/openadapt_flow/connector/storage.py": "4ba816b98860b5f6973909b6b6d30138b429a8bcd120423408bf0ade7cc1a916",
+ "packages/flow/openadapt_flow/console/__init__.py": "3a5ad4c010c98c3afee9c00a4fb7b4209e914b27e48d0cef09d8d4d3eccbbb57",
+ "packages/flow/openadapt_flow/console/actions.py": "097dd73b8cc61d19cb9cb5752103663a413cae0b822cb708419966413d188850",
+ "packages/flow/openadapt_flow/console/app.py": "c1d814387a178d0762827a098ee5624a4d5ca611efa8e41484cf002fdeebb678",
+ "packages/flow/openadapt_flow/console/attention.py": "cd4dff1f27d8c0ef022dc92d64eabf2976fcff3ea0a06a5c363af169899f9cef",
+ "packages/flow/openadapt_flow/console/data.py": "80359fd5e16d13b73a821034b4ac12de7a52cf4dd81c4211c18b2b23154a86e1",
+ "packages/flow/openadapt_flow/console/decision_context.py": "27bbda92c8479f6be02ee9855a85f8f192a24d690c80bdf6ba5716419b2efa33",
+ "packages/flow/openadapt_flow/console/decision_relay.py": "d5320404d4342dbb52be1f2ead1cdb5cf0e22877feaaa1e47974b301df697292",
+ "packages/flow/openadapt_flow/console/decision_supervisor.py": "a5496779de6c05a21c03fb91cf3a3565951bf97922952cf6606a2c185dea6d69",
+ "packages/flow/openadapt_flow/console/halt_detail.py": "aec2d5554f62c99645a82d350802d574d6d50e88e5adadea908307b1258faf56",
+ "packages/flow/openadapt_flow/console/human_decisions.py": "715e1cf4e2cb800cf19aba4ddda0e0774e8b8eb85b5952ac6997c5a3814966ff",
+ "packages/flow/openadapt_flow/console/json_artifacts.py": "e908d47f34bc040e83b257b953c55a7f3cec9b2b74a4519369d85c3a12e6cb7a",
+ "packages/flow/openadapt_flow/console/save_approvals.py": "b4cc6c6e03730becbc88ca61b27b78a4dd6ee9f2b1c5c9b8edda44a5fa18f4f3",
+ "packages/flow/openadapt_flow/console/server.py": "07fea6ba09c3b1e6de7a43d9fd1e27ebd70ae6028944bc41d22029ea33dabb5f",
+ "packages/flow/openadapt_flow/contracts/__init__.py": "1a977515b318b47ec75a5d645ac42120261321d159d1e5efc906c73c407e2c10",
+ "packages/flow/openadapt_flow/contracts/_compat.py": "ee3d2026b24aea3480971ac13ec271aa2d07ebba5347c02d4fcba3a547fc88b5",
+ "packages/flow/openadapt_flow/contracts/action.py": "0ec10f7e6a840c09a48492abbf501d3ebe807fd06671657ae4f4c62137fba61e",
+ "packages/flow/openadapt_flow/contracts/approval.py": "408228cd1595b260b72f30b314d594dc07278b4c48a8072a5f969fa3bb94c194",
+ "packages/flow/openadapt_flow/contracts/authentication.py": "5aa591e0d8b7df2c5933eede186dcb34e5d04807718d2ab4441195d8e22c8073",
+ "packages/flow/openadapt_flow/contracts/authoring.py": "f83894d07ccec6ebc70c715da30b25f2060a5c0e6fc0b570783f739d403e6fc9",
+ "packages/flow/openadapt_flow/contracts/benchmark.py": "59fbd6ea07e38794239eababc408e724418d99982ef8b39d5ad4f5b36aefcf2a",
+ "packages/flow/openadapt_flow/contracts/business_decision.py": "55f7a89917369b360a0d29c30d851e36f883f120c7c00b89baada6e992cfa804",
+ "packages/flow/openadapt_flow/contracts/clinic_job.py": "4719877cb2a1dee680d74d66a1d2f182bab8f86fbb7d81c3e82baf1bdab79d07",
+ "packages/flow/openadapt_flow/contracts/computer_state.py": "c2063f22364e9012ee852ff36f8a2a13f5015655a0b0d634fcd5755f813dbfa7",
+ "packages/flow/openadapt_flow/contracts/control_overlay.py": "3aa01f89b43e12478c9e2ff1a9e61689397370691d15247ded9dcd5b05242790",
+ "packages/flow/openadapt_flow/contracts/control_overlay_tracking.py": "bd5a5965e70839567c22314984b8046797308723512c3b032d6582c7dc7ce0fa",
+ "packages/flow/openadapt_flow/contracts/episode.py": "5ace88d9e278d099c0e7939cc19e99bf18cbbb80d6ea7d606e3950c027baa8a9",
+ "packages/flow/openadapt_flow/contracts/execute.py": "abbf796c7d906a18e84676b72f2cf6a0f8595e960841fb5197ff495d772bdece",
+ "packages/flow/openadapt_flow/contracts/execute_client.py": "9d3d151ae28b01db64a2bc45f116e0bb3177196883561f935b09519910be5200",
+ "packages/flow/openadapt_flow/contracts/execute_openapi.py": "213aafc74f50e9a6fa1447535069bc2a29965db8dcfca4f60921f4cb45f9d473",
+ "packages/flow/openadapt_flow/contracts/execution_requirements.py": "405b79b6fd84c5b606969808c13b07806be177b0e086ef49c123e6711caa7897",
+ "packages/flow/openadapt_flow/contracts/failure.py": "26efb6e04d17c10cae8bbd688249ee44bcd7844a62be6736de984a6e881fa0bf",
+ "packages/flow/openadapt_flow/contracts/human_decision.py": "0bb39a3575f511e10d01d92858b340982adee2f0fc20d2409441dbc0b2c55c4f",
+ "packages/flow/openadapt_flow/contracts/oracle.py": "14baea846ad123e588cfe46f02af05b9bc15a78bf8ff6129356265fafc32c255",
+ "packages/flow/openadapt_flow/contracts/parsing.py": "70088df15ad4b0bcdca120a242d6d1fdf8f5fa433be5f99973a6b3324e72b8bd",
+ "packages/flow/openadapt_flow/contracts/plain_results.py": "6eaced64df53ed29f594435ae346eacf898e3a0eac10d10d2dcc733c0263f9ac",
+ "packages/flow/openadapt_flow/contracts/process_capability.py": "d3aceb649b7eb9cb11413c2c4948b9f2709d11b6e2eee85e60371301a0d7703d",
+ "packages/flow/openadapt_flow/contracts/production_lifecycle.py": "046f30559dac66e4105ad830a274cfb31e0374f95a7a8b0adc1b7dff2aba9449",
+ "packages/flow/openadapt_flow/contracts/reward.py": "5d6b41aee1c7b533505b16d8e76fa921ea57369e4304297fca2c2898127f5c9b",
+ "packages/flow/openadapt_flow/contracts/runner_capability.py": "26fd3c1d96a5558c70886cf203c999d524b9bf927cde23d90735c90be9e2b427",
+ "packages/flow/openadapt_flow/contracts/schemas/__init__.py": "965365ce3faee699154d06428c2dd83414c18632ca3ba39516ef513523b8d618",
+ "packages/flow/openadapt_flow/contracts/seal.py": "2d342e90350348ce887b2c65a7fa8a0505793528e9051d8338eb56c29276a6d2",
+ "packages/flow/openadapt_flow/contracts/vocabulary/__init__.py": "ad80651c5dfd169faa3d478ca69d6f56518c7b70d8fd474f2ef6337586e5a886",
+ "packages/flow/openadapt_flow/contracts/vocabulary/__main__.py": "aa13a269d89f443dbdac5e3c4950b0b870aec327b0b200881cd0023a95342b8c",
+ "packages/flow/openadapt_flow/contracts/vocabulary/lint.py": "5678a73947249cbcab4fdee7b1ecd26b804b039a0720a5eca1a01523bf068a89",
+ "packages/flow/openadapt_flow/countersign/__init__.py": "727c18b4914e681256d727bf6a13285bd9b43c84430c7cbb610efd6721d7edba",
+ "packages/flow/openadapt_flow/countersign/cli.py": "bbb2f1b833297dab3d90fab4ee8bc60b71598b93d0da1dcd30baa6de6dfe8886",
+ "packages/flow/openadapt_flow/countersign/commitments.py": "2ec3967924a7142facbaee575d6c76c0241f9187e4ce2c4b497f479b5e432339",
+ "packages/flow/openadapt_flow/countersign/document.py": "4006e95e33af2523d13f42a20e215ef71e41f0d53696ec66326910a7f23ade7e",
+ "packages/flow/openadapt_flow/countersign/dossier.py": "1ea1151f03b55a6b8a73333b46079cf2cc31d338e6b413490636d2b3ef16033b",
+ "packages/flow/openadapt_flow/countersign/exceptions.py": "26733b2322d2a9ac1a99cf6bb34f27fbf300862b3e89c1884a1441cb7b30ac6c",
+ "packages/flow/openadapt_flow/countersign/render.py": "daabc152f67f1279e978c6b80a1f83477d1a7aa4895738ff77d262416394349f",
+ "packages/flow/openadapt_flow/countersign/tsa.py": "c3597122c33e80b3eb2cb129551e1cd50b6021f45cbad01c20869f13699f8200",
+ "packages/flow/openadapt_flow/countersign/vault.py": "71ea45df4993a00a384791c227328eab67a2e5d3d1d75896e7c841765d5ed1bc",
+ "packages/flow/openadapt_flow/crypto.py": "e7df0c8ba675532234424b5beeb0ee51faea571bcd65764809c6fd9cf175b04a",
+ "packages/flow/openadapt_flow/decision/__init__.py": "32b2b08051ab45571c55af1d44f2b68fd4106eec9ceb078d6769c2d306403550",
+ "packages/flow/openadapt_flow/decision/calibration.py": "51b2adc7ee624d78120a12ebf02d6eb6b9408ce90642e064647fe678e5578051",
+ "packages/flow/openadapt_flow/decision/cli.py": "b0f453ad2616e4b0f99249e983967d1fa7b929e4692662b8adab47053cdf027d",
+ "packages/flow/openadapt_flow/decision/eligibility.py": "86e77ae372f8eef0c31eb9ff694e17cadc7f278155c76d46f0a40be0dc766cb8",
+ "packages/flow/openadapt_flow/decision/feature_model.py": "af7207d471e531377ea653448fd2487f1988a4e8c0b3c7c36d7983a369621077",
+ "packages/flow/openadapt_flow/decision/features.py": "cc5e21ecf0ca93982645791724fd41afcb9e77ed4c526cfa2ea7d3c6cee3931d",
+ "packages/flow/openadapt_flow/decision/labels.py": "924fa2fa32cdde259a2900d0c8af3c3f54b07c30bcbbb9f4af7289663a2889c2",
+ "packages/flow/openadapt_flow/decision/minimize.py": "9c0695866985ecda25a0c96d251d3358d15ab7ee57e66a3b4528e66f4df65ace",
+ "packages/flow/openadapt_flow/decision/provider.py": "3e14c3b013533925a62e67bdd9b82ddf99f969a2552914db1630498ee7f4bcbf",
+ "packages/flow/openadapt_flow/decision/review.py": "47822513196daa1cb3e827e3cb846763f41165738c3576c2df946f6135676098",
+ "packages/flow/openadapt_flow/decision/rules.py": "59a33e0bec5f19fc35621652c96c79ee6d6cc719854ff402853c9cf9c143b31c",
+ "packages/flow/openadapt_flow/decision/synthetic.py": "2ee2fc309a5342a5a3e050a47054b6b1730e21d8d20592956f7bc83f8e7389c6",
+ "packages/flow/openadapt_flow/decision/triage.py": "201235c57ce21e631c4e2f5990628f40ce3bae95e239f0bba29ce7738d95f96b",
+ "packages/flow/openadapt_flow/decision_delivery.py": "e3fd372d84ecb8a13fd811e115255362fae2f96e5b073e59d1d7f123c2bd85a8",
+ "packages/flow/openadapt_flow/demo_driver.py": "96d2dae078eee394b9c92a050cda498f98a61ad7926040a19996f31612007639",
+ "packages/flow/openadapt_flow/demo_proof.py": "5fa9ac103d839fba9c8b8dc08ff0aaa29d4eaed5d972b7db6dbf1d2d53b01694",
+ "packages/flow/openadapt_flow/deployment.py": "25fa8dfd76e2efdefaafbb559530510131266b0eadd1ec4a4924b0715976d6e9",
+ "packages/flow/openadapt_flow/desktop_record.py": "a162df0e593b9f437bca86aa723be013836dd5e0c93acd5fcff7876ba16e3110",
+ "packages/flow/openadapt_flow/eligibility/__init__.py": "c4b10f081ff9c6d3ec3a3017d8a12aa7eb67b41488ae931000a8f84f08d9c54c",
+ "packages/flow/openadapt_flow/eligibility/artifact.py": "686eae18906a58b42fb6219fe6c4fa7b98638192db8169f0098601403ab274b9",
+ "packages/flow/openadapt_flow/eligibility/client.py": "9ddd6ca4512b64b8ad7ce7fad6c31d037209f3a19e9c52c605e9eb508c0f63e6",
+ "packages/flow/openadapt_flow/eligibility/waterfall.py": "15e15b5c8efed40cdeba907b74a279c217434ccf62a378f2ed4a05feba0d44ec",
+ "packages/flow/openadapt_flow/emit/__init__.py": "f9d028ad70f3eda13321fdab9d23845016781cb7360160d71eab82a1752419cb",
+ "packages/flow/openadapt_flow/emit/l1_artifact.py": "8e590b6013d1aedb6b722745d616bc394451c703642a1b7b0159359d94a4a868",
+ "packages/flow/openadapt_flow/emit/mcp_tool.py": "604f48f64f5e012094f9cb609ecf73fa49a9e4dec4f81a17f981921d59786a80",
+ "packages/flow/openadapt_flow/emit/skill.py": "b1975e4ff587a3b4e6531738052d19eaf3e6078bed67665709871c33212c18de",
+ "packages/flow/openadapt_flow/execute/__init__.py": "769684783844a34810850275aba3647c303acc2cd6eced1d8c350c4a2e774d54",
+ "packages/flow/openadapt_flow/execute/app.py": "5957329f8c4cad30a59f8c0a9484fae1e54a6138f91d9414c7ac8ee6e8d4469a",
+ "packages/flow/openadapt_flow/execute/dispatch.py": "56ea5111a17472ca46a40ae2a851b7de1072f09901b9b806add011a45cffa8cb",
+ "packages/flow/openadapt_flow/execute/keys.py": "f43c622ef1df57efb3ed52db6aafc9d98d78100f2e25fff50dcc8b75489f9750",
+ "packages/flow/openadapt_flow/execute/models.py": "bfbac12c75f4fc52c0f9bf89652e876828f208c13a7827dab8bc741b112a5e6a",
+ "packages/flow/openadapt_flow/execute/registry.py": "d687121bec318dd4b56faa1db195a181501fde92263f7b851fb33607de903642",
+ "packages/flow/openadapt_flow/execute/service.py": "88f6ae53c6843de0769f31686b68a908e6154c869d530a29459d34bce0a9c286",
+ "packages/flow/openadapt_flow/execution_profiles.py": "9da970b34f1c88da46485eb1983a85c88ed50bd21d495527c4e30a04b863b46c",
+ "packages/flow/openadapt_flow/failure_signals.py": "63090631a784bf6626859f3a2f7c95551b019d1baac79573255fb41c98f7d8c9",
+ "packages/flow/openadapt_flow/fleet/__init__.py": "3196cac4fbcf1ac5974955e8d9f4dbd0295b516ad5b758e1f67e4f6f545a95b7",
+ "packages/flow/openadapt_flow/fleet/_lock.py": "b877076335ab50d6b240e3b6b0f131d0c699ba706e4af738858320c3fbfe45a1",
+ "packages/flow/openadapt_flow/fleet/canary.py": "275a8acf693d566f17858a2656df9d1b6315becc6c9153149046902bede9c1db",
+ "packages/flow/openadapt_flow/fleet/export.py": "f3c4385716ceb71c0f2e93e4552a32aa22fc31561d0497f9b4c5f13f09c64937",
+ "packages/flow/openadapt_flow/fleet/feed.py": "f229589e292195b387f9c756fbd549eacede2cbaaac2a43d782ae89fc69a7a34",
+ "packages/flow/openadapt_flow/fleet/fingerprint.py": "f641b80642a5bdabf97e44b7f9796ab413c8c5e1ec64355c333ecf91ccda6e00",
+ "packages/flow/openadapt_flow/fleet/hub.py": "5605dd4b5cc620f400bf101c8a94b3fd386dcdbea91329ce9fd2dac087e12f8a",
+ "packages/flow/openadapt_flow/fleet/intake.py": "c6390b6814eff7f0dc424711a6502145baf13bc7ba32031de827f1458184b267",
+ "packages/flow/openadapt_flow/fleet/optin.py": "c6a02feef8c31dfda435fa7b5c9ae2313775979cf68ba0643fe1f284142d3eb5",
+ "packages/flow/openadapt_flow/fleet/patch.py": "50fbd5f28c25c5af1a74ab79534bfc45d80335bf50971d88937d6f48a8047caa",
+ "packages/flow/openadapt_flow/fleet/policy.py": "d9a6dfc09ace5a6446f421728f636d77ac40c4e8e3068685d54cf12a52091729",
+ "packages/flow/openadapt_flow/fleet/signing.py": "9761c1e080a04ddcbb0f54f75ca37fd74a1801399be32218e527ef1c5b71bc89",
+ "packages/flow/openadapt_flow/fleet/simulator.py": "bb9deae25e4e6b6df6503df08b175d146b73cdf347f2997cff32ef34bd94af50",
+ "packages/flow/openadapt_flow/fleet/status.py": "2be462c6f00fda3b783e7825c12a5a031346b11e34c10c6465de75fa79c650a5",
+ "packages/flow/openadapt_flow/hosted.py": "232f7cb2d68e0e1f57ec7b4caa10b866da16a5555c6867d41d978a89bc946683",
+ "packages/flow/openadapt_flow/identity_signals.py": "46e1392fe0fdc7473bc28bb25562f31a6dcc6c90f95d7900de255bc750bf7287",
+ "packages/flow/openadapt_flow/image_hash.py": "4dea419ca5617104d6072ebddf8141e8f9809227aaf833969e390eb3d5c7d73e",
+ "packages/flow/openadapt_flow/instrument/__init__.py": "8bcf6fb0892a9dcdd6cdd3a787a084548479d2ac2ac4e439a772e45dbd924250",
+ "packages/flow/openadapt_flow/instrument/competitor_drift.py": "f124cc086c52eec9b930088b1eb9bf264075cc121f9d06a09ca98ea76527de56",
+ "packages/flow/openadapt_flow/intake/__init__.py": "76815b0b2ecd679c7b076f28f1bb48c66a6be007f208fe8a6ab2746477b3ddc0",
+ "packages/flow/openadapt_flow/intake/cli.py": "0572e2e12addba1cfc36ef92dc2c331d60b96945dd77790f5e432b26b56dc160",
+ "packages/flow/openadapt_flow/intake/document.py": "b71b232d18d509e336d9d950063b14c6dd703383319a25b845e08fa5731b6f32",
+ "packages/flow/openadapt_flow/intake/extract.py": "d2497ca3f25d6d54c48012f5553237ad22ae6e8e1c2bec5044fdeb62b547d2cb",
+ "packages/flow/openadapt_flow/interactive_recorder.py": "fd88ce0bd851a5414a2f6647543aac78ec94b8eb1a0e857e29d5ce135490a76f",
+ "packages/flow/openadapt_flow/interop/__init__.py": "803d6e9b00f130d0282e8d3c26a8d3087033c0fc299a1817b51191431ff4a960",
+ "packages/flow/openadapt_flow/interop/business_decision.py": "98cdcd8357452d322360ff59cf0e26175e23131abad559374e6ab82a16427dc6",
+ "packages/flow/openadapt_flow/interop/business_decision_cloud.py": "825b76362877a90db6a3e2fe3a0f081d67414e285fbe4940a54dcf09bda8edea",
+ "packages/flow/openadapt_flow/interop/business_decision_supervisor.py": "d39d6bf9cfd1d4c84804b5565a99f0ac9560ac15e2838deee4c81426503b521b",
+ "packages/flow/openadapt_flow/interop/decision_relay_transport.py": "31a2f2ecea1d39f108747dbb81b123d2d7d1b0421fe75b97c6abac1d94652a51",
+ "packages/flow/openadapt_flow/interop/types.py": "24cd2d528026400014798c78e6ea1655220466b4bc3c8348abb5c1441592419c",
+ "packages/flow/openadapt_flow/ir.py": "8eddc936cd049d17e48d453e663f67972094a6639b3c341608dccbd436f66ad2",
+ "packages/flow/openadapt_flow/jit/__init__.py": "52f8c8cd9ce8e72cb92e637a30edb34a67b7d3288da6b956e2da75f90515e168",
+ "packages/flow/openadapt_flow/jit/adapters.py": "2b821bb69bf9a08c82d23f3cc5061b6b1adba97706bbebb99ee6c069b6207f61",
+ "packages/flow/openadapt_flow/jit/authority.py": "d4e20fffe1fd61363da76ea5192d98a4fefda06ef4622909b4ab75a662ad4171",
+ "packages/flow/openadapt_flow/jit/cli.py": "daf17cfe4a6258153b53d2dee6c24689496ef04d1906782246860c77e3b6e003",
+ "packages/flow/openadapt_flow/jit/compile_agent.py": "05417355deda4e6a584816478221bc9037f8386edd69ddbdfca3f3e50ed224c3",
+ "packages/flow/openadapt_flow/jit/keys.py": "8d4b0674a351a69011e590ca9bbe5e09ccfd3c55868ff03db7584bbc6e2d530d",
+ "packages/flow/openadapt_flow/jit/lifecycle.py": "df252f3021b23f0e0c95e9474003d4c98bcc4f24559d86f932c5b94010c4f3c0",
+ "packages/flow/openadapt_flow/jit/lift.py": "3a6d5fb196628d77273503a785cda62fc180a5f6e1822c716cdbbdcc0a7a2c51",
+ "packages/flow/openadapt_flow/jit/recorded.py": "3dac2027d3bc1d0e7028dc39f85e7c072c115656ef556d3e21e003f9cdb2a8aa",
+ "packages/flow/openadapt_flow/jit/signature.py": "b32222f42a8b653c67e495693c6ba2a04b261f453a2456bff67c5fd686240075",
+ "packages/flow/openadapt_flow/judgment_cases.py": "021f312ad721f06c6ee0f99cd2061d32c82eea7bfe6f87c4b182e36a4f445db9",
+ "packages/flow/openadapt_flow/learning/__init__.py": "3a47506779959eafc8b85ca26a779fadded553711544021ca4915a87504857d4",
+ "packages/flow/openadapt_flow/learning/branch_teach.py": "7a22ff5f12ef1e04198bd3b4826516e4afe1c8a2465d21fa74574eca5b9dfed9",
+ "packages/flow/openadapt_flow/learning/clustering.py": "50173d350b1c936e2f667db1612dae7721df7a81b40c07eef11abf10c9c0f1c4",
+ "packages/flow/openadapt_flow/learning/gate.py": "f34fd9f3ec74d7a5cb7f111be658db9debd032ceaa12d9254e2adc25f0becbf5",
+ "packages/flow/openadapt_flow/learning/halt_loop.py": "7db231e6902ee3b7fcfde914b2d1ce9c93a61f371d87b31c0156991b664b4566",
+ "packages/flow/openadapt_flow/learning/interpreter.py": "606d336216a899b11651c2e4eb341748d8cc91a10508bd33a63c7d50a44318aa",
+ "packages/flow/openadapt_flow/learning/library.py": "bd3443f46255070368827dc766ff89b9d77cbb92c828b5a0dec06de4581fc7e7",
+ "packages/flow/openadapt_flow/learning/loop.py": "f3e5c1127b4fa21f3e112516670edce15daf05322c554642b8057bf268adb7cb",
+ "packages/flow/openadapt_flow/learning/synth_stream.py": "23ab8b60ed0ba8c3f241c480fddb3901a18aee4bbce79e8828d87c41c1178c80",
+ "packages/flow/openadapt_flow/learning/teach.py": "f03226cef5666ce7940c954cd381e34e1df38de3c97ede3b318b6955a6c1c851",
+ "packages/flow/openadapt_flow/learning/trace.py": "323bc17cfa3fc3876ac030abda028c73e8af02d5e30b2cbe9c9b9faa4639c524",
+ "packages/flow/openadapt_flow/lookup_capabilities.py": "6f8068a05f005e0eac994d14d0ca3e6b1ce7a4e532471bf4b8d9dc15c0fe1b4a",
+ "packages/flow/openadapt_flow/mockloan/__init__.py": "06beb30be301dde52a522064ed192864a4c2bc1f167ebb5800c173eaa72f4735",
+ "packages/flow/openadapt_flow/mockloan/fault_server.py": "0f6f6e4ca4622c5674dca6e49b9dc67360f34b9071ba1346727683aed16682ca",
+ "packages/flow/openadapt_flow/mockloan/server.py": "6d81bda0dd715a71e54306c92d739b49ca3b3a75fac65ee7a70a3d18027ecaa7",
+ "packages/flow/openadapt_flow/mockmed/__init__.py": "223bb05087540a7e0e90f72b83a5dd3634318b95dc0a6874cbc82fd38ce5ee9b",
+ "packages/flow/openadapt_flow/mockmed/chart_pages.py": "38db2fb4d34d14d8745c7c9b31a6c729a4e0afc545333c164296fde5044bf395",
+ "packages/flow/openadapt_flow/mockmed/fault_server.py": "d07cad7aaa74bbd54028744b65b9e74384e73c1e18b2fd1807b138e48a4bf025",
+ "packages/flow/openadapt_flow/mockmed/server.py": "9fbeaf2b0c873dcdce478b4f54990b954844c057a0760ab763705e6aa3f202ab",
+ "packages/flow/openadapt_flow/network_scope.py": "c64d2288c98fde49c437a0a44b53af4a4b1884a8130b99bee098c2046e249033",
+ "packages/flow/openadapt_flow/no_outbound.py": "af14df863d40d81d046acbbcc102e2f96912b24114111e052ebf5440348673ec",
+ "packages/flow/openadapt_flow/no_outbound_allow.py": "b60aa14551bd39ed333389290ae4a9069863b370532e1016d74441a8dde5dd2a",
+ "packages/flow/openadapt_flow/offline_seal.py": "9f9895ae7cfd254eeb7ea5931c61ebba62ff7c08a3f8793988f52ee1fca1bfb3",
+ "packages/flow/openadapt_flow/onprem_reboot.py": "5897eda697e7111ef3ad944c7e397b64ed39abdb225085f9eea0f47b6630879e",
+ "packages/flow/openadapt_flow/onprem_service.py": "2edbde7b9a179b1c2bf63d1b955113a9d9fa3f909e4d9db875e7b626b0e9a792",
+ "packages/flow/openadapt_flow/pf_firewall.py": "adff9c485d303b5b07efa910c45d39762e12285c843f8cd782ffecac5631e0de",
+ "packages/flow/openadapt_flow/plain_outcome.py": "bb5005e368de8b70a355e3c1290b38a8da2519ad0a1d1a5828c83e51b3539270",
+ "packages/flow/openadapt_flow/policy.py": "fd198457b1a34edcdecaaddb3d0d92a6af5e89bf1216ccde7af909dda22c3631",
+ "packages/flow/openadapt_flow/policy_packs.py": "8df13eaf8e7e4ac7492c2f8c25063ce387833174f3c82dfec3f8c68de4bbaaf7",
+ "packages/flow/openadapt_flow/privacy.py": "81734c0bc6ae78ca0a54545e44bd2bf58755aaec677a594b7ddb0167200fcc53",
+ "packages/flow/openadapt_flow/private_file.py": "eae5ffdae6a76c57bc999278baae8ad0bbabfe87813818777e825beddc22f135",
+ "packages/flow/openadapt_flow/production_qualification.py": "c5c9911c7fcaa12bbd513fe737c4c17a3bd64522b98100880c1a05fddfff3aef",
+ "packages/flow/openadapt_flow/qualification.py": "6d2ac075bc373b03b007518bccb5c89506ee1ae5d282d22dc10ad121898f10e7",
+ "packages/flow/openadapt_flow/qualification_admission.py": "73a43db18fd383fde7c5e11823ace50046e0784e662b56c76b82289f61616cf0",
+ "packages/flow/openadapt_flow/qualification_admission_v2.py": "10d8241a38b24767953e6b98986c838773a02399652924a53e53c7ec7c7c5e56",
+ "packages/flow/openadapt_flow/qualification_admission_v4.py": "5a11934e42fdea85c7ff792ab6d33754b974a719783154e8e6144e9a90db1292",
+ "packages/flow/openadapt_flow/qualification_campaign_authority.py": "cea191889f3b3f8da5c078e0cb020e7e0ebe9c4100035f5f1bb2b17ace75c3d7",
+ "packages/flow/openadapt_flow/qualification_campaign_permit.py": "1468882d9627f0355673873cd493c2709ab7cec2506dac3b1efa32d1c16f0637",
+ "packages/flow/openadapt_flow/qualification_dev_signer.py": "db70cdacae8235acc73f13a3281e667a7a5e502c246151854db4dd921caf8643",
+ "packages/flow/openadapt_flow/qualification_drills.py": "71c9627c1ad14f178c785121af656392d4ec71ef6ae5c331fee875747eda173e",
+ "packages/flow/openadapt_flow/qualification_environment.py": "842f5dd827750f55d9e1046613a804fa6b27c2a41981d4d7fbd6b04d9acc8131",
+ "packages/flow/openadapt_flow/qualification_faults.py": "ff4661bab2327788598b8d1616d81d9e5c09b2165b1e1b07979083945ce7a800",
+ "packages/flow/openadapt_flow/qualification_identity_evidence.py": "6aede36f2bb8c91ee8ef077a1e4af1751893f13237ef70415858bfee0e3bdee8",
+ "packages/flow/openadapt_flow/qualification_oracle_gate.py": "39e12170e33cece3aa72f463afed7d6c342909995afbe3d861592dc47c912d77",
+ "packages/flow/openadapt_flow/qualification_proposal.py": "92eb5e6a4a530aed87db7a40aacafe48347d5cfdd4cc8a68039154d1711949be",
+ "packages/flow/openadapt_flow/qualification_web_session.py": "3766e5b5f03a92f91a5f51988b1764542b74aeaf634d72e18c9a9b1b6ffc4fdd",
+ "packages/flow/openadapt_flow/qualified_business_decisions.py": "9b56b3d0923440b589e6ff010dda1cab88c893aa01e92861e796e6cae2c83c34",
+ "packages/flow/openadapt_flow/qualify/__init__.py": "a3d7b8e30c06fb77be32b75996ce1f3ea8f96264e74edef2646f122ebbbdc1f6",
+ "packages/flow/openadapt_flow/qualify/campaign.py": "4ddd41a30d63b74c24f26183d0a0c3c3533dcd709296c648e2cf04bfda57df10",
+ "packages/flow/openadapt_flow/qualify/config.py": "58271767026adfe6e1268ca172cfcf7e330c961e435590aaea71eab862d9505c",
+ "packages/flow/openadapt_flow/qualify/environment.py": "ebfb7128e9292715d5af31e8625cf8e548b25e7201455a80589f460f20b5f74c",
+ "packages/flow/openadapt_flow/qualify/faults.py": "69f6cde4c844c22bbee45383ae1a545497936fc9dc688e97c409f07c6cfcc192",
+ "packages/flow/openadapt_flow/qualify/keys.py": "fb2e94913ad0db0fcc697943faaeef3f3391a83fe045af703d249b9344afc556",
+ "packages/flow/openadapt_flow/qualify/result.py": "7877e368072eff08d4e62e527500fe88b0c7f56e53f80ec2c0a7e63a88c5668f",
+ "packages/flow/openadapt_flow/qualify/session.py": "281c003e690606d7d68cdf365a4042424ab3fc1b2cded916c4ae10c3d16ef1f0",
+ "packages/flow/openadapt_flow/receipt.py": "d118970b58510fd3b5fad7ee0eb67872a004607f4351c14318cddc35e3759c1c",
+ "packages/flow/openadapt_flow/record_check_binding.py": "0102012ebea2f78e09e610310c32a555ea95b9484099181ba6409265b7773be4",
+ "packages/flow/openadapt_flow/record_sor.py": "f3d083dd2875b9c31bf3b5e31332b1d2a946bffc7079f034b030e15273545b4d",
+ "packages/flow/openadapt_flow/recorder.py": "d4501500f3d689ce7b3d44dbedead74df482ecb365c853e4d63b0de7ee005f04",
+ "packages/flow/openadapt_flow/registry.py": "586eb7e8380ba33055ceff29c164e005aec441ace73a7a70e1001f3f9cb02824",
+ "packages/flow/openadapt_flow/release_admission.py": "5afdf674f30073b10ed5b4ee06fd3818db26e74cc935c649548256cb60160f7a",
+ "packages/flow/openadapt_flow/remote_frame_contract.py": "745c8e9a6731ea89b722092183f760527d9e6f329a5a7ef61152870114e77406",
+ "packages/flow/openadapt_flow/repair/__init__.py": "db1e673372764eb9ba76be658980a94b9747a0d716b5ec1a8d5f74d69ca909ee",
+ "packages/flow/openadapt_flow/repair/agent_teach.py": "ec9995ba2d3ccaee0ee623e77cd30f0d30a565235befcfbb003fb81d4b7f2920",
+ "packages/flow/openadapt_flow/repair/campaign.py": "520e08184f5abe0bb53a4e08eb2d314e89ad3cc0636069573ca26bdfa82f20db",
+ "packages/flow/openadapt_flow/repair/candidate.py": "e5ec96fbcc6fbad6ebb9477d46bf975712cfc9122cf1fb78b127b9a736435f5f",
+ "packages/flow/openadapt_flow/repair/cli.py": "aff7dad26018f77bd8c25fada6c8d614c33a730034ca28bca0025c15c4147c16",
+ "packages/flow/openadapt_flow/repair/cloud_review.py": "eae37867caa636115ae63adb6018987c322bfceb78a25c4178f4287bd13bc6d9",
+ "packages/flow/openadapt_flow/repair/dialog_fixture.py": "7969fe9c3e4373e32873a237867e182f8c2933397e2c47614216c5ced59a4e9f",
+ "packages/flow/openadapt_flow/repair/dialog_identity.py": "77e828471626051c74e502c29bce3ec2356926b38b6ddd83489b7bdc3fff3dd8",
+ "packages/flow/openadapt_flow/repair/hold.py": "48169c9c5d4e0099f64f36278435eca64b11d49783b7dcf0273478c331af746f",
+ "packages/flow/openadapt_flow/repair/invariants.py": "c645ffc37b7135018e0783955b77a067e719e99765d70ccfc26812b3e0336d45",
+ "packages/flow/openadapt_flow/repair/lifecycle.py": "19130a17a32b5da0a8d6c0015f7106a1c7e0535d3eba02dd5b99f85cd96cb3b3",
+ "packages/flow/openadapt_flow/repair/registration.py": "2eebf2d1683568c2893615eb47041467d6f8943c76de81c1c9a9582f9c61e8cc",
+ "packages/flow/openadapt_flow/report.py": "50ef36ec2721f6c279ebf669a3f11bb825783ea07987117f70b38db886e5df59",
+ "packages/flow/openadapt_flow/reward/__init__.py": "a16f606b5333fa2a0732ba0a3ae643125e6831f8c923fd17940194fab25eff76",
+ "packages/flow/openadapt_flow/reward/calibration.py": "b91fbbf5de6022d6f37e3ed4b9ab06dc04ec51e17060af500dd07b86b938e44d",
+ "packages/flow/openadapt_flow/reward/callables.py": "3526b4ec44fb82d7697c1f94c3a91e28a56f66c275d575bda9eda1058d3c37c8",
+ "packages/flow/openadapt_flow/reward/models.py": "b497ad11cae280c28deed0bf1dde5952528b20de51937d44dc0a443b4590532f",
+ "packages/flow/openadapt_flow/reward/oracles.py": "93572f5ada086d441e467651e9509e7352f5c97b576751dc6db2d53380b1230a",
+ "packages/flow/openadapt_flow/reward/seed.py": "1f84a01302b03dffe41d56c1d63b6421f9b47019ab055ccd9eea2542289f2462",
+ "packages/flow/openadapt_flow/reward/serve.py": "c8bf963939d991c1ad55ca7ac4ba50d3d632f70693793b92a2fc07fbb003e5da",
+ "packages/flow/openadapt_flow/reward/worker.py": "cb9e330242f0a7cc1eb4dba137b37e77fcb286165b80382c762a789b316d948d",
+ "packages/flow/openadapt_flow/risk.py": "258584ef460de27eb199abf57c3e334fca2368d222d844ec17aa5aa4c781da80",
+ "packages/flow/openadapt_flow/run_gate.py": "b3ab89e10c8d558a4e36e57ee36150ec9042780186126d72ae9abf2722f50299",
+ "packages/flow/openadapt_flow/runner/__init__.py": "1111900db86ee0f61faa093996a6e64a1405c9052bb74f186afa1a84a60ffcc0",
+ "packages/flow/openadapt_flow/runner/business_decision_service.py": "97bab36f3c9dbc9974129a34a5c636dba08e7fbf3c56fc522ed507feae216bd4",
+ "packages/flow/openadapt_flow/runner/commands.py": "92a62d244b406c405cdfd51c3189a835878f0e334fc74e16e98a1acfbca47ba3",
+ "packages/flow/openadapt_flow/runner/config.py": "ba84ed0b0638ee12de51f40fe3fa4da13c14effafbbba7bceab256e56664fc2d",
+ "packages/flow/openadapt_flow/runner/dispatch_envelope.py": "4a867de3740e46b67ecf90b74120f53ad038d7c0aae9b17c6bcefef998ec674d",
+ "packages/flow/openadapt_flow/runner/evidence.py": "4f884203b69f3368b56e7bd0a31df123a28f5c7b464fa73a69b1da742fd7fe76",
+ "packages/flow/openadapt_flow/runner/flow_release_receipt.py": "1e80b5d956de0debc12e5a14f4595256eb13caba16d387e8193ad1737be4ae18",
+ "packages/flow/openadapt_flow/runner/hosted_adapter.py": "06f84a0357c5f40bc6949828aab76214fcb3405fe2b8241566a648c109979d66",
+ "packages/flow/openadapt_flow/runner/inputs.py": "711464bd021afbde06b9c4d132ea782c3b6a321ea48bcb24c3f565f8609f8a9d",
+ "packages/flow/openadapt_flow/runner/lease.py": "9ba80da689f4eeec85d44a860a27851e2408e3772b135bd01e4c4a0996d77c60",
+ "packages/flow/openadapt_flow/runner/outbox.py": "19454f29bb30bd8707f452a00e6fcb3511a1fce1b70ee2401d5d40d2e11e496e",
+ "packages/flow/openadapt_flow/runner/product_release.py": "072ad1a818fd1ccd7bfbe2995ee90825111890dfb4c1bd9b72275350107adab3",
+ "packages/flow/openadapt_flow/runner/protocol.py": "02ab8b7ce4a936d8533cf99a58f68fb5281b2afce2f17b99dbba27b0eeaf7e82",
+ "packages/flow/openadapt_flow/runner/verify.py": "473bab048ac39adfd9020816e81ea969c05856993e4029e17ce9bc9ba237d92c",
+ "packages/flow/openadapt_flow/runtime/__init__.py": "fa78a3356ae6470aaab3c3093c57502ac8aef9b1ecb03ec2f4ccbc2a0c0b9f0b",
+ "packages/flow/openadapt_flow/runtime/actuators/__init__.py": "597b6f56b00bb79c7f3a4452f602d1746aa0acc99bebc1683ce71ceece5af59d",
+ "packages/flow/openadapt_flow/runtime/actuators/api.py": "05fb4e35a9cbb2c85874bdc3d5df1aeaf4f5ba1e011ec0e4ae8b02aaaab78a13",
+ "packages/flow/openadapt_flow/runtime/admitted_composition.py": "1518f9c4791fb6f1c1169d6414e4bf2e456dd1121d4c02796d2388c6a539627e",
+ "packages/flow/openadapt_flow/runtime/authorization.py": "006e9d67a27bca1f900d676781e7863f953050f90dc592e0743532839f7ba02f",
+ "packages/flow/openadapt_flow/runtime/composition.py": "cc10476194e0a5f44e9421476317b72b1233f44eeb0bf95196426f9f609e752e",
+ "packages/flow/openadapt_flow/runtime/control_overlay.py": "bd07ab6981d9e49dd212221b87c98cbfcc5f885224f80034ad8721900be23e06",
+ "packages/flow/openadapt_flow/runtime/durable/__init__.py": "32d5846e0775819d84e903485f1c32a14774d2ee3d4f3322335182afd68f8826",
+ "packages/flow/openadapt_flow/runtime/durable/approval.py": "6388bfb60298c9579dbc196657707e9653b33b2b4acddddc4e9d8087db24f7d4",
+ "packages/flow/openadapt_flow/runtime/durable/attended.py": "7af7a9b4be2e7b162b8abb734166e32369909870537b5097ad11b9ff0e4c28c6",
+ "packages/flow/openadapt_flow/runtime/durable/attended_service.py": "13b45a376e37ff032c072334df0d3585318dbda3472c5b671b398c4ca6b30f47",
+ "packages/flow/openadapt_flow/runtime/durable/authority.py": "e9c2f928ac8a0345afcb80cfdc89ce3de4d90012007ded7f10128ec8e59e5f3d",
+ "packages/flow/openadapt_flow/runtime/durable/business_decision.py": "dff9bb63163561045318f2416420e9d96c1c69fc6f1f31eaa00e50fc41083e63",
+ "packages/flow/openadapt_flow/runtime/durable/checkpoint.py": "24694ab18b1f6a142d90f66dcf63d3591986f210c20396f6da8c969d1aadcdfc",
+ "packages/flow/openadapt_flow/runtime/durable/continuation.py": "f9d3248848417f9c137886cb24befaa3755c444c926b8991aecc2d4f6ca330a6",
+ "packages/flow/openadapt_flow/runtime/durable/controller.py": "fa65769ca2ac99351996718cf561baaad58dcb75b78d537b43703e14102f9e28",
+ "packages/flow/openadapt_flow/runtime/durable/program_checkpoint.py": "1945df32ff1d418c5eac7f9f02fe29297da315d6e07e395cb706312ab1d2cf53",
+ "packages/flow/openadapt_flow/runtime/durable/resume.py": "bce914258a73b5d4faa9e275b1f4f631d3dba967093cb901c241636de7885eba",
+ "packages/flow/openadapt_flow/runtime/effects/__init__.py": "ca3e5432400acf4dabc353f08f8c9b44ea8a23157c1020b10794ab6666962ee0",
+ "packages/flow/openadapt_flow/runtime/effects/_common.py": "e235206c1353bb5d58d43ec47c9be7e4ffea4f830ac0ee27a8645a3cece197b6",
+ "packages/flow/openadapt_flow/runtime/effects/adapter.py": "6b44cda61a78ce3934db28a6b2ce1ccadac5a52a99f8bbc225346f602116b5a4",
+ "packages/flow/openadapt_flow/runtime/effects/auth.py": "af0c2be6ab49f998aaf404800a0f5c8a3a35f30f08dda609cafa8b49ea622f91",
+ "packages/flow/openadapt_flow/runtime/effects/compensation.py": "3e6feb4924e61ffb67802151907218b47c627923362206f5c83aea86a00da3db",
+ "packages/flow/openadapt_flow/runtime/effects/document_arrival.py": "1f62bb1c46f0f9521610a152fe68340a96014bc4a8d293d6681ef5099acc1307",
+ "packages/flow/openadapt_flow/runtime/effects/document_hash.py": "5c64f1ffc187cd03114d61dff3518080e59b817f8b1c3424dbc4b57db30e1f04",
+ "packages/flow/openadapt_flow/runtime/effects/effect.py": "89652d08269cbe36fdba23d323f2e7265c2a56b54774ce872f58d72e6fa19641",
+ "packages/flow/openadapt_flow/runtime/effects/email_delivery.py": "bca21113e2c8fc3f3820fd1c0e27c16f2c5db920ccdd05275477bd08884b6ce2",
+ "packages/flow/openadapt_flow/runtime/effects/fhir.py": "446fb684445c6eed847dd124e0729f3538a749592c36ceeb4f7bc79de434b94a",
+ "packages/flow/openadapt_flow/runtime/effects/file_arrival.py": "8a5dcb94534e9f3ef40fa820cc18ae73e45f626137f0de856941c3adcfc235e5",
+ "packages/flow/openadapt_flow/runtime/effects/graphql.py": "cebae9844af5046963fdaba3abaed3ed1f9b1084dedd1a8948ac454b64990e26",
+ "packages/flow/openadapt_flow/runtime/effects/onscreen.py": "87285b4dc7e58435b1c3ad24f0a3283e32d2bb18eb644cc871b01b3227f1bfe6",
+ "packages/flow/openadapt_flow/runtime/effects/readback_values.py": "7d9bce37cbb3d6a6dcdbdf5337a61becbaf54b611177928a024e63869a84ab2e",
+ "packages/flow/openadapt_flow/runtime/effects/rest.py": "44af95a068db190bec496f81140a23698bdf6883c96c30185d063d7fb9c3e104",
+ "packages/flow/openadapt_flow/runtime/effects/smart_auth.py": "57dc86cbd4249d528148d6c47a0bb5eec56d9c2e854ede8e0a97a7dbe8cda15d",
+ "packages/flow/openadapt_flow/runtime/effects/sql.py": "53ead9fbc0ac87e831abbde14dceccfed5d05c917b5752a6aa6d8c59a8f9830b",
+ "packages/flow/openadapt_flow/runtime/effects/ui_readback.py": "9f4b2eab01eb854066cc45a21c405e959aa652a101ea5f0fa860c329189cff6f",
+ "packages/flow/openadapt_flow/runtime/grounder.py": "f9d6916310a7ce4a184b363fb073f99e783f09f7546a3d3c68574a5d403b7ea2",
+ "packages/flow/openadapt_flow/runtime/heal.py": "73567f8f02cadd52137736934618ceef8873b5d09ca0bb8e1d2f2ecb24efd516",
+ "packages/flow/openadapt_flow/runtime/healing/__init__.py": "7f2b58eb0e8d53394d9764066378e228f4dcbd8fd48b143b3497c11167b6ad80",
+ "packages/flow/openadapt_flow/runtime/healing/governance.py": "f3a755d46bbd7eedbe6b0ebc962cc2073714551eee34c7f5f2faf002623d3222",
+ "packages/flow/openadapt_flow/runtime/healing/patch.py": "2a918bfbe9523c7946085581465bc6fae5735ba9d9e46e2a0a04e4a841fdadb7",
+ "packages/flow/openadapt_flow/runtime/healing/perturbation.py": "18159ae5a273b33b90ee677164e44fe794bff4c8cfa96a9d3d0f9f8d12166f18",
+ "packages/flow/openadapt_flow/runtime/healing/pipeline.py": "100adcd9230ffa734c2ad85146c1c4af5e065c5c882ab1a36cc7a4391a516909",
+ "packages/flow/openadapt_flow/runtime/identity.py": "b467655b862df4b6d68ad753e25cda8b9290ad1f82605b9733ff2ce934e84154",
+ "packages/flow/openadapt_flow/runtime/identity_template.py": "2b08165c1b59f7cb8503f959ad2953c2ab9161f6dbff1715081e9e6ae2f83dcd",
+ "packages/flow/openadapt_flow/runtime/identity_vlm.py": "be1151e8bdb3cafe428b5dd25579d6c5d7ef7b47c18ff3f9687d56f94a229428",
+ "packages/flow/openadapt_flow/runtime/known_ids.py": "b92cd3dbbce15a2d0e14ee3a828a8796785632e2d6cc7d26e67bc399e29a8d28",
+ "packages/flow/openadapt_flow/runtime/layout_drift.py": "09bbcfce5564a95ab383ac455d68ff065fb274f8100fa240a9a0e0d7fa338fc4",
+ "packages/flow/openadapt_flow/runtime/process_v1.py": "b6fc68e4abb2e6555002194f7af1c2a4e21be27d6f5075b491e14341b6d3e84a",
+ "packages/flow/openadapt_flow/runtime/program_predicates.py": "3e76056ee036464a35dcd0a001f167d00b78eb97e73aa2100270dc6ea6563106",
+ "packages/flow/openadapt_flow/runtime/remote_vlm.py": "cc00a062f99e2f4abe608346fef912da5f2eaed9d90fc2d6a4c4f17debf7fd97",
+ "packages/flow/openadapt_flow/runtime/replayer.py": "1cbff1714df1586f11e2068b502997091c46e6e3a638d9d28ff387865bfc9e47",
+ "packages/flow/openadapt_flow/runtime/resolver.py": "9f6aa55a51197ae7ed9865469bd3516c67784eba7c5225f36782b4ab2e9a987f",
+ "packages/flow/openadapt_flow/runtime_validation.py": "18675d6b4c40458394febb36cbe28e99f410cb65b4cab138b68df3cacc6f7dd4",
+ "packages/flow/openadapt_flow/sanitized_artifact.py": "4271c2e9b21f666d5010122176d7884571a6f12ff153356eea7eb9413224806a",
+ "packages/flow/openadapt_flow/scaffold_verifier.py": "2451720bdc8ae78cf41e06636d2968d00cce92c165db2b97def7c689b9640f40",
+ "packages/flow/openadapt_flow/seal_batch.py": "c93b91fb0401d7fb3810b304c1e99a5817b82c346927c83c96cfd77892d31415",
+ "packages/flow/openadapt_flow/services/__init__.py": "f38b556ba34b1fc674267a2c386edf9beb542d5a98c8e266b70f61ec6a617ba4",
+ "packages/flow/openadapt_flow/services/vlm_service/__init__.py": "da71deb7edc5ea6c30c250faf4cb39b4a76b532801debe6f64598b5d2ed8978e",
+ "packages/flow/openadapt_flow/services/vlm_service/__main__.py": "3844e4479038b670ef897697c71c05bb8e9f92136425ff899137501b3fc60966",
+ "packages/flow/openadapt_flow/services/vlm_service/app.py": "808094e2285b70965cc7f84a2c6037749ef29304318e1986c3dbbf7e4a1ec9c0",
+ "packages/flow/openadapt_flow/services/vlm_service/backends.py": "771df17902dc1c31e44517880706468f0c3dd13ee8dedc161ca60f159e1d9255",
+ "packages/flow/openadapt_flow/services/vlm_service/batching.py": "545ceb328637acbbaf343566059bcd23ba61ae9b385c6d32b14844a08c074971",
+ "packages/flow/openadapt_flow/services/vlm_service/config.py": "0bf363d7be1419ed1dd1597230a2be87d880473e5d19df4a9b8ef5e2f33a1bee",
+ "packages/flow/openadapt_flow/services/vlm_service/prompts.py": "f3af38485a7f61ad96fdaf066387c4809cf34b60cb96147ac186caa828cff1c3",
+ "packages/flow/openadapt_flow/services/vlm_service/schemas.py": "ca2de9068dcdfc45ca2b33a73fe5b51edaef0c27299b901ec5b340aa0143462f",
+ "packages/flow/openadapt_flow/submit_binding.py": "d7e24dbc08795e500dadb3272d50fd0ddf6afcd290d95434387c68ed2c805657",
+ "packages/flow/openadapt_flow/surface_selection.py": "228f4737a19d6aa1c3364166bbab72a3f87235f3ff1687ea843f6a40a4213bb5",
+ "packages/flow/openadapt_flow/terminal_verification_v2.py": "3bc44d80abc3679cebdeec123b34bcc5656cd2624b1c8943bb22352c0efc3261",
+ "packages/flow/openadapt_flow/transaction.py": "c3bd88b18d8c5851970cc22021c0e721ddcc67e9ba0075727186c4d7c542d150",
+ "packages/flow/openadapt_flow/traversal.py": "4bec0fcd5877649e71f7273a17a2073d56c83af6cb7fcd595d0eb9bd7f7a387b",
+ "packages/flow/openadapt_flow/tutorial.py": "870a3de4ea966830d24902920290f2fe25f51d3e6b2df605800030d452658b42",
+ "packages/flow/openadapt_flow/validation/__init__.py": "d7f94f2027a19347364cf9491a94f9e6d8c497cd4a67e555e9d200d406e35e0f",
+ "packages/flow/openadapt_flow/validation/dense_surface.py": "926327c242a21f32bf06500ec43229e10bbcaceaa3dab8d9506c831e638c6512",
+ "packages/flow/openadapt_flow/validation/governed_run.py": "e5385fb7dda147a162d8e5d3f41999068fd0f424ab901bc94824c1e39ef97407",
+ "packages/flow/openadapt_flow/validation/hardening/__init__.py": "f54bdcaf0e0e1c8706e1262d983b7d57dba12e7c3912c50aaec148cc4a6a352a",
+ "packages/flow/openadapt_flow/validation/hardening/__main__.py": "6a2637d07c62e55e6d46dbd277e7c5d499426044120e949532010efe988aeb75",
+ "packages/flow/openadapt_flow/validation/hardening/corpus.py": "927d3f60d1971b82175c6a40a4b45116ba1339e8bb644da5750981e3770e068f",
+ "packages/flow/openadapt_flow/validation/hardening/fixtures.py": "44e85d3c03f03bd46c017a15e46ebff0fee483aed0d76045120e3c43e631318b",
+ "packages/flow/openadapt_flow/validation/hardening/harness.py": "f214c456ded5c2b27eec1fbe1810c5c7d0467960459baecb04c810df4f978e18",
+ "packages/flow/openadapt_flow/validation/hardening/perturbations.py": "fe634c8e6878766beea377bd0c62a6ea681d7ff883ff2896c98941a6f3112583",
+ "packages/flow/openadapt_flow/validation/identity_ladder.py": "834dd30ecbd3ab1195beac4e7fd50e5d3d9df539c7250de76d2bc2d19eae2735",
+ "packages/flow/openadapt_flow/validation/identity_rates.py": "d0648e8e94b96677366ac5372453de797f6221a8aa5c799fe2327674d90c851c",
+ "packages/flow/openadapt_flow/validation/known_ids_dense.py": "9dfcc761b649e83f781e3390077b1c7eea60b4bd16c92e2dae9dd02173192835",
+ "packages/flow/openadapt_flow/validation/pixel_identity_aligned.py": "dff6c6f9d7ae1788f906c42b2cf443e34f93baf3d26d645413b2c84b54933053",
+ "packages/flow/openadapt_flow/validation/pixel_identity_probe.py": "66095f52fe8de431a3ab0cf68ba02202bb459b46927e98d7ae6bcf4c68d7ef49",
+ "packages/flow/openadapt_flow/validation/structural_action.py": "1f231ebe02d241ad34b3d9867be26850748a487fb586f646350192d0487dda49",
+ "packages/flow/openadapt_flow/validation/vlm_identity_probe.py": "f3641e289f0a02e80fcb31ff76c34c0ed150c647fa9954252425db2b7659b713",
+ "packages/flow/openadapt_flow/verification.py": "0bb9f564b4d3dccce7fbebad64abaae1cbd4bd600ffa1b58ec18d9025df52ff2",
+ "packages/flow/openadapt_flow/verify_run.py": "c4495eedc9622b76d3084f237f206f453cc56f1f27196d4610604bb47baf2020",
+ "packages/flow/openadapt_flow/vision/__init__.py": "f41b931a97bf4ac5a8f1f141dc905bec4367bb350e8ccc90446842eb63765bd5",
+ "packages/flow/openadapt_flow/vision/hashing.py": "60d5b56a991100310163007d6778d6bec8521826c3f586f6b88e6e1a76f1d70e",
+ "packages/flow/openadapt_flow/vision/imgops.py": "9cd252bcb3a8bab46795098bc29cd5cf988d77c96abd9687ba93b9252e3f53c9",
+ "packages/flow/openadapt_flow/vision/match.py": "24b301455f7418155ce2757baf126548d0fc663b806b200a1c2c6d866e077458",
+ "packages/flow/openadapt_flow/vision/ocr.py": "2e6482a3069b324c1b7686ac1ba8cd073165ea9527b4171f840d488356ee9eda",
+ "packages/flow/openadapt_flow/vision/ocr_backends.py": "c49ef78611856dcd0b11aff0836b1683ae1ed734e33e5e7289a71779aee8e0f9",
+ "packages/flow/openadapt_flow/vision/settle.py": "f9cc521dc55ffddefedf529d4c748715b03d27d45b40521a819a7e255044e0c5",
+ "packages/flow/openadapt_flow/visualize/__init__.py": "a55d38dcb0fac704b35136a4134d89ffcc3343000f50b2624b8bc7093ce34d90",
+ "packages/flow/openadapt_flow/visualize/admitted_composition.py": "9758fb49a8d3e587204e3df921a42cf823921cb25f8c66e08cfec748337be8d7",
+ "packages/flow/openadapt_flow/visualize/builder.py": "b655235b48739e81e0bed3d0c9d01511c302d582952455175610744c23778fff",
+ "packages/flow/openadapt_flow/visualize/composition.py": "52d42000d0747af577a6f4e2af0b4326c22790c3cf7fc2e6ebd05b83baef91d0",
+ "packages/flow/openadapt_flow/visualize/projection.py": "bb8801775904799de53d4b40eacfe65c4661ecb6478569e70af6f08a7508547a",
+ "packages/flow/openadapt_flow/visualize/render.py": "400589d8b3dcd7bbb9daa738aac2a338675aad80095b116922ce10de645f565f",
+ "packages/flow/openadapt_flow/visualize/spec.py": "fc9bb2dd0fe5cefbb20aa66d90794aff50fa7983784a8582ee862712c28b27c0",
+ "packages/flow/openadapt_flow/volatility.py": "117c9df0dcbeff9669f78b27455c5bc1ada762798c9a64393c30fdab5c29dfa1",
+ "packages/flow/pyproject.toml": "00e8071c36123320d4c2bbe009ea6cdde50f047d82a45ddcc21aca1869e1ea1b",
+ "packages/flow/uv.lock": "90f90b155fbcbdd826e204e4fd2293b4a24e095777a470638e2247311bd918cd",
+ "packages/types/openadapt_types/__init__.py": "9359d2e723c383afbc214e6dde7964505eb2b21acc52631e2349f7a50f3acfbf",
+ "packages/types/pyproject.toml": "5b81ba48e6555c4c218393d9d46f5e4126fa9e60de1d2d6cde96a6a6b2ccc687"
+ }
+}
diff --git a/packages/flow/tests/fixtures/bundle_compatibility/2.5.0/linear/canonical.json b/packages/flow/tests/fixtures/bundle_compatibility/2.5.0/linear/canonical.json
new file mode 100644
index 0000000000..4bc7b3c700
--- /dev/null
+++ b/packages/flow/tests/fixtures/bundle_compatibility/2.5.0/linear/canonical.json
@@ -0,0 +1 @@
+{"files":{"templates/button.png":"fa53ee8e6f7730a17a6b8ea30ebab860d2811526204fcf2c76946850b582b493"},"workflow":{"contains_phi":false,"created_at":"2026-01-02T03:04:05+00:00","data_sources":{},"encrypted":false,"name":"release-compatibility","param_specs":{},"params":{},"phi_scrubbed":false,"program":null,"recording_id":null,"schema_version":2,"secret_params":[],"steps":[{"action":"click","anchor":{"click_point":[80,70],"context_text":null,"identifier_crop":null,"identifier_region":null,"identity_template":null,"landmarks":[],"ocr_text":"Apply","region":[40,50,80,40],"search_pad":80,"structural":{"automation_id":null,"name":null,"role":null,"selector":"#apply","window_name":null},"structured_identity":null,"template":"templates/button.png"},"api_binding":null,"effects":[],"expect":[],"guard":null,"id":"apply","identifier_crop_missing_reason":null,"identity_armed":null,"identity_unarmed_reason":null,"intent":"apply synthetic change","key":null,"param":null,"risk":"reversible","scroll_dx":null,"scroll_dy":null,"secret":false,"text":null,"timeout_s":10.0,"wait_until":null}],"subflows":{},"viewport":[320,200]}}
\ No newline at end of file
diff --git a/packages/flow/tests/fixtures/bundle_compatibility/2.5.0/linear/manifest.json b/packages/flow/tests/fixtures/bundle_compatibility/2.5.0/linear/manifest.json
new file mode 100644
index 0000000000..978a6ef5f9
--- /dev/null
+++ b/packages/flow/tests/fixtures/bundle_compatibility/2.5.0/linear/manifest.json
@@ -0,0 +1,22 @@
+{
+ "schema_version": 2,
+ "content_digest": "f44b31062baf7e119b04bea142ad87120568cf5c9f94712a0c3e137a123edf7b",
+ "file_hashes": {
+ "templates/button.png": "fa53ee8e6f7730a17a6b8ea30ebab860d2811526204fcf2c76946850b582b493"
+ },
+ "provenance": {
+ "compiler_version": "2.5.0",
+ "source_recording_sha256": null,
+ "compiler_config_sha256": null,
+ "created_at": "2026-01-02T03:04:05+00:00",
+ "policy_name": null,
+ "certified": false,
+ "certification_status": null,
+ "certified_at": null,
+ "expires_at": null,
+ "certification_invalidated_at": null,
+ "certification_invalidation_reason": null,
+ "governed_authorization_template": null
+ },
+ "encrypted": false
+}
\ No newline at end of file
diff --git a/packages/flow/tests/fixtures/bundle_compatibility/2.5.0/linear/templates/button.png b/packages/flow/tests/fixtures/bundle_compatibility/2.5.0/linear/templates/button.png
new file mode 100644
index 0000000000..797e0782c9
Binary files /dev/null and b/packages/flow/tests/fixtures/bundle_compatibility/2.5.0/linear/templates/button.png differ
diff --git a/packages/flow/tests/fixtures/bundle_compatibility/2.5.0/linear/workflow.json b/packages/flow/tests/fixtures/bundle_compatibility/2.5.0/linear/workflow.json
new file mode 100644
index 0000000000..872d60f9cc
--- /dev/null
+++ b/packages/flow/tests/fixtures/bundle_compatibility/2.5.0/linear/workflow.json
@@ -0,0 +1,112 @@
+{
+ "schema_version": 2,
+ "name": "release-compatibility",
+ "recording_id": null,
+ "contains_phi": false,
+ "phi_scrubbed": false,
+ "encrypted": false,
+ "created_at": "2026-01-02T03:04:05+00:00",
+ "viewport": [
+ 320,
+ 200
+ ],
+ "params": {},
+ "param_specs": {},
+ "secret_params": [],
+ "steps": [
+ {
+ "id": "apply",
+ "intent": "apply synthetic change",
+ "action": "click",
+ "anchor": {
+ "template": "templates/button.png",
+ "structural": {
+ "selector": "#apply",
+ "frame_path": null,
+ "role": null,
+ "name": null,
+ "automation_id": null,
+ "window_name": null
+ },
+ "region": [
+ 40,
+ 50,
+ 80,
+ 40
+ ],
+ "click_point": [
+ 80,
+ 70
+ ],
+ "ocr_text": "Apply",
+ "context_text": null,
+ "structured_identity": null,
+ "identity_template": null,
+ "identifier_crop": null,
+ "identifier_region": null,
+ "form_identity": null,
+ "landmarks": [],
+ "search_pad": 80
+ },
+ "text": null,
+ "param": null,
+ "secret": false,
+ "field_label": null,
+ "selection_commit_key": null,
+ "selection_region": null,
+ "key": null,
+ "modifiers": [],
+ "drag_end_anchor": null,
+ "scroll_dx": null,
+ "scroll_dy": null,
+ "expect": [],
+ "effects": [],
+ "api_binding": null,
+ "risk": "reversible",
+ "risk_explanation": null,
+ "risk_review_required": false,
+ "wait_until": null,
+ "guard": null,
+ "read": null,
+ "read_gate": null,
+ "surface": null,
+ "opens": [],
+ "surface_origin": null,
+ "closes_surface": false,
+ "dialog": null,
+ "timeout_s": 10.0,
+ "identity_armed": null,
+ "identity_unarmed_reason": null,
+ "identifier_crop_missing_reason": null,
+ "hover": null,
+ "submit_binding": null,
+ "submit_binding_unbound_reason": null
+ }
+ ],
+ "interstitials": [],
+ "program": null,
+ "subflows": {},
+ "data_sources": {},
+ "manifest": {
+ "schema_version": 2,
+ "content_digest": "f44b31062baf7e119b04bea142ad87120568cf5c9f94712a0c3e137a123edf7b",
+ "file_hashes": {
+ "templates/button.png": "fa53ee8e6f7730a17a6b8ea30ebab860d2811526204fcf2c76946850b582b493"
+ },
+ "provenance": {
+ "compiler_version": "2.5.0",
+ "source_recording_sha256": null,
+ "compiler_config_sha256": null,
+ "created_at": "2026-01-02T03:04:05+00:00",
+ "policy_name": null,
+ "certified": false,
+ "certification_status": null,
+ "certified_at": null,
+ "expires_at": null,
+ "certification_invalidated_at": null,
+ "certification_invalidation_reason": null,
+ "governed_authorization_template": null
+ },
+ "encrypted": false
+ }
+}
\ No newline at end of file
diff --git a/packages/flow/tests/fixtures/bundle_compatibility/2.5.0/program/canonical.json b/packages/flow/tests/fixtures/bundle_compatibility/2.5.0/program/canonical.json
new file mode 100644
index 0000000000..0ee4c36a3b
--- /dev/null
+++ b/packages/flow/tests/fixtures/bundle_compatibility/2.5.0/program/canonical.json
@@ -0,0 +1 @@
+{"files":{"templates/button.png":"fa53ee8e6f7730a17a6b8ea30ebab860d2811526204fcf2c76946850b582b493"},"workflow":{"contains_phi":false,"created_at":"2026-01-02T03:04:05+00:00","data_sources":{},"encrypted":false,"name":"release-compatibility","param_specs":{},"params":{},"phi_scrubbed":false,"program":{"entry":"apply","states":{"apply":{"id":"apply","kind":"action","loop":null,"on_exception":null,"outcome":null,"reason":"","step":{"action":"click","anchor":{"click_point":[80,70],"context_text":null,"identifier_crop":null,"identifier_region":null,"identity_template":null,"landmarks":[],"ocr_text":"Apply","region":[40,50,80,40],"search_pad":80,"structural":{"automation_id":null,"name":null,"role":null,"selector":"#apply","window_name":null},"structured_identity":null,"template":"templates/button.png"},"api_binding":null,"effects":[],"expect":[],"guard":null,"id":"apply","identifier_crop_missing_reason":null,"identity_armed":null,"identity_unarmed_reason":null,"intent":"apply synthetic change","key":null,"param":null,"risk":"reversible","scroll_dx":null,"scroll_dy":null,"secret":false,"text":null,"timeout_s":10.0,"wait_until":null},"subflow":null,"transitions":[{"guard":null,"label":"","target":"done"}]},"done":{"id":"done","kind":"terminal","loop":null,"on_exception":null,"outcome":"success","reason":"","step":null,"subflow":null,"transitions":[]}}},"recording_id":null,"schema_version":2,"secret_params":[],"steps":[],"subflows":{},"viewport":[320,200]}}
\ No newline at end of file
diff --git a/packages/flow/tests/fixtures/bundle_compatibility/2.5.0/program/manifest.json b/packages/flow/tests/fixtures/bundle_compatibility/2.5.0/program/manifest.json
new file mode 100644
index 0000000000..4d87825396
--- /dev/null
+++ b/packages/flow/tests/fixtures/bundle_compatibility/2.5.0/program/manifest.json
@@ -0,0 +1,22 @@
+{
+ "schema_version": 2,
+ "content_digest": "7694ed3afd395c21a26e3fbe1b675aa1770b3dc9e2937843f84d48e935b686e2",
+ "file_hashes": {
+ "templates/button.png": "fa53ee8e6f7730a17a6b8ea30ebab860d2811526204fcf2c76946850b582b493"
+ },
+ "provenance": {
+ "compiler_version": "2.5.0",
+ "source_recording_sha256": null,
+ "compiler_config_sha256": null,
+ "created_at": "2026-01-02T03:04:05+00:00",
+ "policy_name": null,
+ "certified": false,
+ "certification_status": null,
+ "certified_at": null,
+ "expires_at": null,
+ "certification_invalidated_at": null,
+ "certification_invalidation_reason": null,
+ "governed_authorization_template": null
+ },
+ "encrypted": false
+}
\ No newline at end of file
diff --git a/packages/flow/tests/fixtures/bundle_compatibility/2.5.0/program/templates/button.png b/packages/flow/tests/fixtures/bundle_compatibility/2.5.0/program/templates/button.png
new file mode 100644
index 0000000000..797e0782c9
Binary files /dev/null and b/packages/flow/tests/fixtures/bundle_compatibility/2.5.0/program/templates/button.png differ
diff --git a/packages/flow/tests/fixtures/bundle_compatibility/2.5.0/program/workflow.json b/packages/flow/tests/fixtures/bundle_compatibility/2.5.0/program/workflow.json
new file mode 100644
index 0000000000..59c2a9c9d1
--- /dev/null
+++ b/packages/flow/tests/fixtures/bundle_compatibility/2.5.0/program/workflow.json
@@ -0,0 +1,142 @@
+{
+ "schema_version": 2,
+ "name": "release-compatibility",
+ "recording_id": null,
+ "contains_phi": false,
+ "phi_scrubbed": false,
+ "encrypted": false,
+ "created_at": "2026-01-02T03:04:05+00:00",
+ "viewport": [
+ 320,
+ 200
+ ],
+ "params": {},
+ "param_specs": {},
+ "secret_params": [],
+ "steps": [],
+ "interstitials": [],
+ "program": {
+ "entry": "apply",
+ "states": {
+ "apply": {
+ "id": "apply",
+ "kind": "action",
+ "step": {
+ "id": "apply",
+ "intent": "apply synthetic change",
+ "action": "click",
+ "anchor": {
+ "template": "templates/button.png",
+ "structural": {
+ "selector": "#apply",
+ "frame_path": null,
+ "role": null,
+ "name": null,
+ "automation_id": null,
+ "window_name": null
+ },
+ "region": [
+ 40,
+ 50,
+ 80,
+ 40
+ ],
+ "click_point": [
+ 80,
+ 70
+ ],
+ "ocr_text": "Apply",
+ "context_text": null,
+ "structured_identity": null,
+ "identity_template": null,
+ "identifier_crop": null,
+ "identifier_region": null,
+ "form_identity": null,
+ "landmarks": [],
+ "search_pad": 80
+ },
+ "text": null,
+ "param": null,
+ "secret": false,
+ "field_label": null,
+ "selection_commit_key": null,
+ "selection_region": null,
+ "key": null,
+ "modifiers": [],
+ "drag_end_anchor": null,
+ "scroll_dx": null,
+ "scroll_dy": null,
+ "expect": [],
+ "effects": [],
+ "api_binding": null,
+ "risk": "reversible",
+ "risk_explanation": null,
+ "risk_review_required": false,
+ "wait_until": null,
+ "guard": null,
+ "read": null,
+ "read_gate": null,
+ "surface": null,
+ "opens": [],
+ "surface_origin": null,
+ "closes_surface": false,
+ "dialog": null,
+ "timeout_s": 10.0,
+ "identity_armed": null,
+ "identity_unarmed_reason": null,
+ "identifier_crop_missing_reason": null,
+ "hover": null,
+ "submit_binding": null,
+ "submit_binding_unbound_reason": null
+ },
+ "loop": null,
+ "subflow": null,
+ "transitions": [
+ {
+ "guard": null,
+ "target": "done",
+ "label": ""
+ }
+ ],
+ "on_exception": null,
+ "outcome": null,
+ "reason": ""
+ },
+ "done": {
+ "id": "done",
+ "kind": "terminal",
+ "step": null,
+ "loop": null,
+ "subflow": null,
+ "transitions": [],
+ "on_exception": null,
+ "outcome": "success",
+ "reason": ""
+ }
+ }
+ },
+ "subflows": {},
+ "data_sources": {},
+ "manifest": {
+ "schema_version": 2,
+ "content_digest": "7694ed3afd395c21a26e3fbe1b675aa1770b3dc9e2937843f84d48e935b686e2",
+ "file_hashes": {
+ "templates/button.png": "fa53ee8e6f7730a17a6b8ea30ebab860d2811526204fcf2c76946850b582b493"
+ },
+ "provenance": {
+ "compiler_version": "2.5.0",
+ "source_recording_sha256": null,
+ "compiler_config_sha256": null,
+ "created_at": "2026-01-02T03:04:05+00:00",
+ "policy_name": null,
+ "certified": false,
+ "certification_status": null,
+ "certified_at": null,
+ "expires_at": null,
+ "certification_invalidated_at": null,
+ "certification_invalidation_reason": null,
+ "governed_authorization_template": null
+ },
+ "encrypted": false
+ }
+}
\ No newline at end of file
diff --git a/packages/flow/tests/fixtures/bundle_compatibility/2.5.0/provenance.json b/packages/flow/tests/fixtures/bundle_compatibility/2.5.0/provenance.json
new file mode 100644
index 0000000000..809b75f13c
--- /dev/null
+++ b/packages/flow/tests/fixtures/bundle_compatibility/2.5.0/provenance.json
@@ -0,0 +1,673 @@
+{
+ "bundles": [
+ {
+ "content_digest": "f44b31062baf7e119b04bea142ad87120568cf5c9f94712a0c3e137a123edf7b",
+ "files": {
+ "canonical.json": "f44b31062baf7e119b04bea142ad87120568cf5c9f94712a0c3e137a123edf7b",
+ "manifest.json": "ef26a2860b09b15fbfeff39f31f0ef58c45fc129f71dddd37b672e2877e6c0f5",
+ "templates/button.png": "fa53ee8e6f7730a17a6b8ea30ebab860d2811526204fcf2c76946850b582b493",
+ "workflow.json": "c16508dea245f5291a21c08231a4afddbce9c727aae8db81d3f1cb34d35e1689"
+ },
+ "shape": "linear"
+ },
+ {
+ "content_digest": "7694ed3afd395c21a26e3fbe1b675aa1770b3dc9e2937843f84d48e935b686e2",
+ "files": {
+ "canonical.json": "7694ed3afd395c21a26e3fbe1b675aa1770b3dc9e2937843f84d48e935b686e2",
+ "manifest.json": "b458dd746697c74200d3b21eb285b3278d26adc690db2fd6fc003e2a34528c56",
+ "templates/button.png": "fa53ee8e6f7730a17a6b8ea30ebab860d2811526204fcf2c76946850b582b493",
+ "workflow.json": "a8095810ee4a0b1657d65c73b67d72b57e70c335e4e8fe90be6bf6688620e54f"
+ },
+ "shape": "program"
+ }
+ ],
+ "commit": "5a3bf49a0bf2d662430386295a1c34036c064d58",
+ "generator_sha256": "d995443471ee4a6fd6854e53a15da4d3681c798a5af9ffde7d3506d8c5015e28",
+ "original_release_load_verified": true,
+ "pydantic": "2.13.4",
+ "python": "3.12.16",
+ "release": "2.5.0",
+ "source_hashes": {
+ "packages/flow/openadapt_flow/__init__.py": "52562986a73b76e4b8b8e6e2ad784f63a6d1c88eb4949a63f314c80456ebb51d",
+ "packages/flow/openadapt_flow/__main__.py": "6637fe40f77b88e55d51eec353302c393e25b5db7694e998d548ac0a4e8db9c2",
+ "packages/flow/openadapt_flow/_browser_setup.py": "d259bd323de12fa03b4bf529d77ccb6350d50f665309c377e6df182525c37e6f",
+ "packages/flow/openadapt_flow/_prewarm.py": "4024f33b41a2fac44b995dfc85a922366b98c18697f6a2b623cb26d72264ed48",
+ "packages/flow/openadapt_flow/action_evidence.py": "8f361a151589fcea66c392bf4913ae22b20844921941fe9ab1f2135e7bdd8b0a",
+ "packages/flow/openadapt_flow/adapters/__init__.py": "2eca3615b0a12e39a4a51fd7bf2c274785014c548e609597029ef7d8299c9a09",
+ "packages/flow/openadapt_flow/adapters/capture.py": "8a2c0af76e13cc968015852296d32b0621cb626823a69c6011abcd7391072825",
+ "packages/flow/openadapt_flow/adapters/desktop_recorder.py": "7f05b9bf03bc1da900d0acceae4cd4ae0a82efc4a3b9ef011c6649e1044b3454",
+ "packages/flow/openadapt_flow/admit_pipeline.py": "8caea372aeae2d40624fad965c75efca1cab4dd3ce0d733428bfc2fa03b9afc3",
+ "packages/flow/openadapt_flow/admitted_composition.py": "0fcf3b21a233c9ccf0ee71fec2848a80f755fa941ba5f462a47dd544e8aeeeff",
+ "packages/flow/openadapt_flow/after_stop.py": "6395400f6a578d0013fe284141b6778c0d77321cc16918c7bf42ae2a36153de2",
+ "packages/flow/openadapt_flow/agent/__init__.py": "a08c79b09e45150bd065c5008a2585081ac6c10a1d9c4489dad01718fbb94973",
+ "packages/flow/openadapt_flow/agent/__main__.py": "5780b9a3b365c96d71fa42a6ea977a1518d711ed5c4b4f37b54b16ffbc9d0419",
+ "packages/flow/openadapt_flow/agent/admission.py": "2fc9add3c7dc983d49e583d920dd145a95b5152c01e6215bc6dee6a2fd5dcf3e",
+ "packages/flow/openadapt_flow/agent/approval.py": "a345a90e0e3fa788b520fd26150971a0a5aaff16173a663541f92845ecf409d7",
+ "packages/flow/openadapt_flow/agent/attended.py": "5fa4c761de375be9ce0f6cf7f72f0230253ccd7546658382a267da2f01cb0f1b",
+ "packages/flow/openadapt_flow/agent/authoring.py": "87afc6deb8fd2ed6a1e670c37978648fd633deea8c380b0ca937b369bbb452af",
+ "packages/flow/openadapt_flow/agent/bridge.py": "8675f0c4df081f7573e6df6aa6d943be72103cb8669ab7bae4611560f21d1f79",
+ "packages/flow/openadapt_flow/agent/browser_teach.py": "4c12fc8dbc62b3efc5009f8e8ab40218923ebb095823c9f662eada6ea806d843",
+ "packages/flow/openadapt_flow/agent/bundles.py": "a3e2d63576adc99fd8e4d53e0fa64f1bec914a070d5c0151ba9278ea923809c9",
+ "packages/flow/openadapt_flow/agent/cards.py": "45ecfb3da287aeb5de1160d1adbcc3590c6cc8c20f7b1b7ab983f643228f62b5",
+ "packages/flow/openadapt_flow/agent/cli.py": "1a6c15f8371a39acfd958bb3f82f182866d097b4ed281f95b95de2d055340394",
+ "packages/flow/openadapt_flow/agent/contract.py": "4a265a3a961578dcd4cd5e26be85d6eb0799ac4f557924a36b00e17ffdc39c67",
+ "packages/flow/openadapt_flow/agent/copy.py": "9afe666441689375fcb5aaf54632db2e39e0a32edeb95570789f0d7ce4b55423",
+ "packages/flow/openadapt_flow/agent/delegated.py": "49414a62704b93999fcf668db4df737121f4b5d9d22f1b36a94de705d171371e",
+ "packages/flow/openadapt_flow/agent/example_app.py": "847ba77d93cc438e7e54143f5e7686d53733499154e2cde979e20e5f4b871f7e",
+ "packages/flow/openadapt_flow/agent/flow_service.py": "b5bb10bf1cb819bb0aba9185de9e9d1246a823ff343996a7464d8e481785f2dd",
+ "packages/flow/openadapt_flow/agent/guard_tools.py": "6c61c36f77ed394797d07466a430387bbe8e9a383877833d769514b13d7dd843",
+ "packages/flow/openadapt_flow/agent/ledger.py": "e0911cb91a52570a8244ae4e72c9985c0110f30eeacf3d1a19a1c394e2938a8b",
+ "packages/flow/openadapt_flow/agent/ledger_demo.py": "de6fca47b663553749c6e432c3c96897dad3aa9313d1c1752162d2ab5b707eb8",
+ "packages/flow/openadapt_flow/agent/mailbox.py": "c5c8c9a305ddbe8caa985066e0c6f587df4d3703f3d67c7e6643076ab2a709fc",
+ "packages/flow/openadapt_flow/agent/mcp.py": "6c180e6d5310ec5b242a7757e42d469bacfb6cf7d4a5bbd72485b1bbeb8594ee",
+ "packages/flow/openadapt_flow/agent/mcpb_entry.py": "23db9f1b3af8bed52ee472b36b0272430d11526f045179602724addc92a22ac8",
+ "packages/flow/openadapt_flow/agent/repair.py": "31c92c511930b602b90f43e66623e97ada890eb91c4954da49e77ca793b78628",
+ "packages/flow/openadapt_flow/agent/runner.py": "a8c30b966efe0532cd9f114b5f5773eac6107d2785df98cd7562d200343d8378",
+ "packages/flow/openadapt_flow/agent/runner_bind.py": "91d4006e99378c61af2eb50fc9c03ebfb477cdf9f0d27fa070ee9936fb073e96",
+ "packages/flow/openadapt_flow/agent/runs.py": "abd7041cd1eae1b6017c208e0cf4b083caf965cd2147d0497e896a013cd5cb25",
+ "packages/flow/openadapt_flow/agent/sandbox.py": "ee78c7959d8213dbd3d4b75eb64ecb2a797147410f90516eef57e6c2bb9edb01",
+ "packages/flow/openadapt_flow/agent/seal.py": "ea0585e2564f23a59ccc41763b58357a176e53363f3107ab7b54639d902de439",
+ "packages/flow/openadapt_flow/agent/seal_cli.py": "fcae30891db50c28e6a23282ff94a0dce9796c15c7fea46b8fdc34694ff8acc1",
+ "packages/flow/openadapt_flow/agent/service.py": "275da34a73890b0c85fb5c06965403162adcacfc499a7493736aab236b5538ac",
+ "packages/flow/openadapt_flow/agent/skill.py": "7f1637d4bcfdb54ff5920b06dd3bbf913e6fdbc0030605b455e9223672ad2173",
+ "packages/flow/openadapt_flow/agent/teach.py": "e68371be5b7986097f70b9241c5d0e1ce7576e21fe55ed35eae677ee0ac85640",
+ "packages/flow/openadapt_flow/agent/tutorial.py": "ac42a64169cb23fac79943a0ef8e4678922d120d51aa97944e2be707addb3232",
+ "packages/flow/openadapt_flow/agent/verify_tools.py": "057b72b0456a88b802afc87d219853ad5c19717ab8237243660cb3aaadb933e4",
+ "packages/flow/openadapt_flow/agent_guard/__init__.py": "e1f1ec33d219e845e1de18b61752fe06fff4ba1e12d403870b58d4ef5094c1fa",
+ "packages/flow/openadapt_flow/agent_guard/cdp.py": "e0a59d4f49dee5a9b0e8b6d3c16db794c923a5b4c8af4fa1418e8da13478d8ca",
+ "packages/flow/openadapt_flow/agent_guard/cli.py": "e4792c7ce115eeace17871dd5c8cee569a6b9e7a5365acc53d82946677cddd9b",
+ "packages/flow/openadapt_flow/agent_guard/commit_guard.py": "bcf7cc8d91ce7ab804745766ee4b838b648095364467f2a203f78864ba09090c",
+ "packages/flow/openadapt_flow/agent_guard/config.py": "b25c4e327836f3d2c9167d421eb85d72fbca5c7e8bf7f31de25da3625470caf1",
+ "packages/flow/openadapt_flow/agent_guard/handoff.py": "7f84e49d42717d304f60257a429b36305c4a32cb7e14566185d4789634283ff5",
+ "packages/flow/openadapt_flow/agent_guard/requests.py": "92e42c8462ff7a6effc0e7437dd01ace72f02e04c3072ae29495902787cd0d26",
+ "packages/flow/openadapt_flow/agent_guard/session.py": "9a419ef69572516f5da12efe0d07b72e8effe15634fe1d57635b257abd28a8b4",
+ "packages/flow/openadapt_flow/anthropic_defaults.py": "e22dec3d87dae9724a5a4d7b547fccc60fffccf952f4d951ff2fa76b312e6778",
+ "packages/flow/openadapt_flow/api.py": "7a34b5b4a7d5b3b815c4008d9d3efab1badddb77dac7477e17308602d1e532b1",
+ "packages/flow/openadapt_flow/app_profiles/__init__.py": "c01c098dec84e3831e31628afa6806f4830f9efffd037b4af7e9e70a0a4c8ce4",
+ "packages/flow/openadapt_flow/approval_mode/__init__.py": "7d802c15089999853ed4a0b55bdaa1962998f2b8e9ee0170695c7de2ec5c3e10",
+ "packages/flow/openadapt_flow/approval_mode/approver.py": "2e314d0ae6432f81972cdc84a8db1635161a6d17dd8fe0e9cb656fd254db7197",
+ "packages/flow/openadapt_flow/approval_mode/approver_roster.py": "85fb6593d6fb418d8ccb180207cab84d20cfdee59326a8df22a90c0c5c442aef",
+ "packages/flow/openadapt_flow/approval_mode/coverage.py": "1e5875a9d2d2d87791dcc27af30617c8cf6ed1d8a559f733e5fb634898604b91",
+ "packages/flow/openadapt_flow/approval_mode/demo_approver.py": "463281495181c3f97969517391a6912a4464a9431ef7c4fd49ba451f61155b80",
+ "packages/flow/openadapt_flow/approval_mode/durable_carry.py": "0f0c5c204fe6cfabef54bd988a3050b58ed6a0a13b178c2615cbeafc2fb7b7d8",
+ "packages/flow/openadapt_flow/approval_mode/form_state.py": "f2548b7f2527e9d648623fc5bafa841feabe8272d6a5822e23d4c937e910ae53",
+ "packages/flow/openadapt_flow/approval_mode/gate.py": "f1e35292d0ca73d7273ade289d5cc838580ecb643e13c9a454c3ebf2a346a20c",
+ "packages/flow/openadapt_flow/approval_mode/human_attestation.py": "eca372e1fa68d9a626ac80046dbf6ab401e97b08a185bd162b278003505883f3",
+ "packages/flow/openadapt_flow/approval_mode/item_approval.py": "98874c9985f0ead33c5e5cc84d3853f9c5f2b809f56d8c7e6018053d9d30f688",
+ "packages/flow/openadapt_flow/approval_mode/model.py": "42f121b2a7fc992bc1201ccb8c587d7134fec6fdbc54eb12dacd71ff4a00774a",
+ "packages/flow/openadapt_flow/approval_mode/post.py": "91134523827840f5d4de7652513b4a70a906abf64ddda9c367b9fb814045a006",
+ "packages/flow/openadapt_flow/approval_mode/requirements.py": "4f8ba1eff008e45651365929bbbaee873301d993c714168e78456009b06b402b",
+ "packages/flow/openadapt_flow/approval_mode/signed_policy.py": "4dc065c007d6c3112de2af004e36ecd8559ceac8a76eaf9853c1d49f7363c757",
+ "packages/flow/openadapt_flow/approval_mode/switch.py": "2fa2cc31eef6b27e490897eb7997f8679e843cb86508f41b72cc8b5fbe67cbf8",
+ "packages/flow/openadapt_flow/assurance.py": "fba477ecf901039ebefb8d2d9be340accf9bcfa96314a243febc35157ba48fd5",
+ "packages/flow/openadapt_flow/attest_bridge.py": "449502e879bc629b851087b86353a0dbd5761508daec92989083f30fdad14fee",
+ "packages/flow/openadapt_flow/authoring.py": "ad9f67263b07a748e2752c87025556f797fea0b0d3eaf53902168553cbae84b7",
+ "packages/flow/openadapt_flow/authorization_summary.py": "1057cfc2a597b02bd230654c1df030b3680ce8b6300619b145fcf0e994be866f",
+ "packages/flow/openadapt_flow/backend.py": "c7d80e64fa012afa5a6a78b2e0e52390f164a335e1f7dfc8c30ff05f32819858",
+ "packages/flow/openadapt_flow/backends/__init__.py": "c76aa599a2ea0205a3fffb4a33124dbe6637e4b93f0f14d4c604ffa05c2a1869",
+ "packages/flow/openadapt_flow/backends/_browser_process.py": "1f90beb147f32ddc276884c3e6488e3e533a5bb374ccf675fadc16754cb4e137",
+ "packages/flow/openadapt_flow/backends/_page_quiescence.py": "2a8b70efd7f6b006fa8141b02a7e59fe5733e7552eeacfc7e34326c0dde147c0",
+ "packages/flow/openadapt_flow/backends/_server_responses.py": "d20bfd20078304288462c56c17e1348707df9b3dc56388e292822405776900bb",
+ "packages/flow/openadapt_flow/backends/citrix_workspace.py": "2bc912cfecac2d7d1c4c543cda17a2cbe4b25af195fd8a1d015f6b02661e9665",
+ "packages/flow/openadapt_flow/backends/factory.py": "0702f58a5c3ac8b00c110f2064d59a2c31469839023a6a12dc70510f18bb26f6",
+ "packages/flow/openadapt_flow/backends/linux_backend.py": "c7c333cc1a592a1db64ed0ef5f1e410080469ae22080142329a90b780899d525",
+ "packages/flow/openadapt_flow/backends/macos_backend.py": "f6f2e25c03403340a756ecf9e18c4a2b30fb028881b122b54370450d36c8ea8a",
+ "packages/flow/openadapt_flow/backends/parallels_vm.py": "e724f9ec49210e5220d1cc508ab8a1ef984ac43854535b90548b209985109d0c",
+ "packages/flow/openadapt_flow/backends/playwright_backend.py": "f2221cec049a0e378c76fdfaa5b4b70c8465257ca6c6e1487032f283d6335552",
+ "packages/flow/openadapt_flow/backends/rdp_backend.py": "f6ea77fdbef04bf6064ba68466dba85c627fd633bf188c14d9988b5f0e7a4242",
+ "packages/flow/openadapt_flow/backends/remote_display.py": "c834ea454565c99978f381317e3874c081c5dce7dec19b35d796f6b51df705aa",
+ "packages/flow/openadapt_flow/backends/win32_window_client.py": "ac4a3a324b2ec2fa9f2fa64a7a1687b78ccab8e522d5c81e2c3b8accb79988ef",
+ "packages/flow/openadapt_flow/backends/win_agent/__init__.py": "cdba9a2b13137a43d83ff03e4eb02c9e250fbaee84ddd6f174c72d5902da553a",
+ "packages/flow/openadapt_flow/backends/win_agent/server.py": "68a3fd16e64fba41f5d290cda7713c9e2deb4ba1790738950d3ddfd561bfaa52",
+ "packages/flow/openadapt_flow/backends/win_agent/tls.py": "51f2af9d258c3acfd095d5a7c83d40d3719bbd2161be7963c03c84687f8922cc",
+ "packages/flow/openadapt_flow/backends/windows_backend.py": "24f6d760963f91f5e6d7d9a2c5568812952b4e9eaa968553e01ea3537ff967d8",
+ "packages/flow/openadapt_flow/backends/xfreerdp.py": "fce4e624ba91a39a08b6dec0cc367251b8e04bff3b356879e644ffadda595b56",
+ "packages/flow/openadapt_flow/bench.py": "e90fc71ac1c2033a42b06b872de09550fdd9db02b175d176d250e91c207cedba",
+ "packages/flow/openadapt_flow/benchmark/__init__.py": "c5d84d097f5e007ebd1a4f86a3ae02c6a897939cdfa11f030b263e5e12c0278d",
+ "packages/flow/openadapt_flow/benchmark/agent_baseline.py": "af2857e65b9393812180eed8ec6c721e6848a3209d0b57e637038262fddf1bc7",
+ "packages/flow/openadapt_flow/benchmark/chart_fonts.py": "e60660a947e09a566567b6d84332d009e4b969f4a450b2cecc81299c5b07ba2e",
+ "packages/flow/openadapt_flow/benchmark/desktop_benchmark.py": "8ed16bb044b338db4814374ddadda57b151d1e7e2a4cb2474d45ce6703116e54",
+ "packages/flow/openadapt_flow/benchmark/dom_arm.py": "62dd7e06840a286d859b442b79ea9b7bd05df56cdc700f140cc2e5cf37d195cc",
+ "packages/flow/openadapt_flow/benchmark/effectbench/__init__.py": "045dfe7dbace5245e7f6ff742984b73cca9e36d973ac0ce4736167a04ae764e6",
+ "packages/flow/openadapt_flow/benchmark/effectbench/metrics.py": "65f74dbfeac3d8761265531b04618270cddca773fb30cbabd49ab79d2f01c95f",
+ "packages/flow/openadapt_flow/benchmark/effectbench/oracle.py": "ec8628819a2c2f29efe36124175b2d349499936efcfe2cedaec5ebb6da9b9fbd",
+ "packages/flow/openadapt_flow/benchmark/effectbench/runner/__init__.py": "a1153140a9bd236aa7afbb551edd305e0d16e14e999ba575dc609d24760c2030",
+ "packages/flow/openadapt_flow/benchmark/effectbench/runner/__main__.py": "eb36799a1ff3168eb049d25a500cca903d3a5e439283d84ade20f21300f3d312",
+ "packages/flow/openadapt_flow/benchmark/effectbench/runner/arms.py": "8cc93711483ffa21e06796b2b9f100effc6811c33c3204e5e9ffd35137b06cd5",
+ "packages/flow/openadapt_flow/benchmark/effectbench/runner/baselines.py": "9d235db2891ce32c088d89edba3553fbbc2911031d29a9ada5caa00c964dd7bd",
+ "packages/flow/openadapt_flow/benchmark/effectbench/runner/compound.py": "c407b37ba39bf066214aa62014c920815be16dffef934f7f3478ee20ef3dc341",
+ "packages/flow/openadapt_flow/benchmark/effectbench/runner/harness.py": "e7848000829d040a35f25ccbbb82041fd460664492dfecee1173092ab492671c",
+ "packages/flow/openadapt_flow/benchmark/effectbench/runner/reference_tasks.py": "c588c8f654e44d035a091b4ca0c861c8e916592d63f387b75ba9702af8da3d7b",
+ "packages/flow/openadapt_flow/benchmark/effectbench/runner/substrate.py": "0cb036fc7c0b97ff776e946de714a1904d0cc36846fcd1c86b4e7820f5c90542",
+ "packages/flow/openadapt_flow/benchmark/effectbench/schema.py": "640848a9ab5932006d2a65f9975b3369146aa1b892b2bd44b879dbe7fe11ef47",
+ "packages/flow/openadapt_flow/benchmark/frappe_lending.py": "4b9c17ab23191dba8ca81d03b924c14e3fdd12280fe9aabe7d4a7e7691229ef0",
+ "packages/flow/openadapt_flow/benchmark/hybrid_benchmark.py": "f37c53370526fe0b3c47a728c3003d6d59aa23b71471f3fc51ae545adaf931ea",
+ "packages/flow/openadapt_flow/benchmark/openemr_benchmark.py": "acb8bc88dc7a175f1f5eb90a6f83371a26e4082b8e1903a69f7d35f8d6737244",
+ "packages/flow/openadapt_flow/benchmark/openemr_local.py": "2f1e9156719eccb745a96d9ef16dc185d73346710d649046512c024b89a1d65a",
+ "packages/flow/openadapt_flow/benchmark/reliability.py": "20851d3dfebbb647f8db689e87c9ca35b0364c3127262305f6b361bc42d43d1c",
+ "packages/flow/openadapt_flow/benchmark/run_benchmark.py": "6f001c4c53d7aa6abb744053c347f489c1ce343b117e76f347371179bfc3ace2",
+ "packages/flow/openadapt_flow/benchmark/silent_wrong_action.py": "072d3c16360ff5a1f66786196560d8c62948c38d1600ec99e78ba547b2fa90c5",
+ "packages/flow/openadapt_flow/benchmark/verify.py": "d823f244fdf423381cd30b7f6a2bb6322bf6ed4ee79634c670ae583f5bc48bbc",
+ "packages/flow/openadapt_flow/bundle_sealing.py": "b0487d600888d7b467e00898c99b9991d242e5dbf84f5528b14c91509b9ded80",
+ "packages/flow/openadapt_flow/bundle_validation.py": "63532fb8e49f25a8aba8dccca505362a9293b8db9cbc0f2904dd8f9a6e23fea8",
+ "packages/flow/openadapt_flow/check_level.py": "cb5a4bb2bc25f70c7de05ee1814b8b8a422ebf307809d96ed74c8106f8e3a9d5",
+ "packages/flow/openadapt_flow/cli_admit.py": "e337d734c1e69b28dd80609f55293040e07798e92028b5ab7afe24d6c613b29b",
+ "packages/flow/openadapt_flow/cli_api.py": "f1fc34f3fc53056b561a3e5573591f031763d5ae85a730839e4f6ad6a937599a",
+ "packages/flow/openadapt_flow/cli_check.py": "1206d3821e98e418379c03287e5f9c8cac6d9487dd6b21337f8782e8433736eb",
+ "packages/flow/openadapt_flow/cli_cleanup.py": "74e6dbd940e5b6cc7dacf5e68a5089aa18ebbb108e3f59f7fa56a69e08ab820f",
+ "packages/flow/openadapt_flow/cli_compose.py": "965a63427ec37964451cdb00fad92065833b6f7cab936c80526c05984b5a68ec",
+ "packages/flow/openadapt_flow/cli_config.py": "a68b1b9db2c60feee3ec0b4ea079bbacc7b90bb052f9660c87b2e7067c593557",
+ "packages/flow/openadapt_flow/cli_deferred.py": "058cc58d256276f36db2b1e4f6e0105b505c88c1f65ca9f8e01e5f37f79ddeab",
+ "packages/flow/openadapt_flow/cli_fleet.py": "a4678b9b48c6c4817673fcccbd18be21966ae6d64dd89fb143bf26f3dce3c7ff",
+ "packages/flow/openadapt_flow/cli_hints.py": "6589faad4aefc66d6a80fe7875909cb9d335fa5624d9c761a95d5afe772a260f",
+ "packages/flow/openadapt_flow/cli_known_ids.py": "ed965f2369489a87cefb27ea9c9241bdc9b6058c72fc56450006be9951737897",
+ "packages/flow/openadapt_flow/cli_local_seal.py": "33c1f1406afa3de7c85bd661befad02b51fc5018f5eefa94546bd6381bf5c37f",
+ "packages/flow/openadapt_flow/cli_no_outbound.py": "1afedf45d1874e4aeeabc8cf1d36572f6df8b7ddf54bfcb75189d0bb0f149b47",
+ "packages/flow/openadapt_flow/cli_process.py": "700238b5cfb5edef883d2e57a209d9628fdb12fdc7aee6ea7c4a519999d28d64",
+ "packages/flow/openadapt_flow/cli_redact_report.py": "3e9d35b83f8d74e7b085e670787de410aebcb70a3a0de4ff1760bc44c91e48cf",
+ "packages/flow/openadapt_flow/cli_rollback.py": "f9f80f3d84b1e50241527a5fd09736941f8eac0782fb05acbab2e4765b9747e9",
+ "packages/flow/openadapt_flow/cli_sections.py": "21d0a362860703f030fea5a2ddcbd0a14a48a4799fcbf117d526a38fcccb04ea",
+ "packages/flow/openadapt_flow/cli_self_repair.py": "759088c91cc14ae9b8422d6a0859088e40f18e21da120ce32da61f42d3176ea7",
+ "packages/flow/openadapt_flow/cli_service.py": "172c06cc25ada99b0532dee35aa4e4510671cc7e7b24871e8b7294abed8cea0e",
+ "packages/flow/openadapt_flow/cli_shadow.py": "be027e80721d1b59bcc0bb2ba03048fbe2b864a5df43f521de61899fb45f6e1a",
+ "packages/flow/openadapt_flow/cli_undo.py": "93b527aaffe833b02ea1e990bf03c908fa88c3f60d764007130a00449b75185d",
+ "packages/flow/openadapt_flow/cli_variants.py": "4d214beab05bdf5765559004c8e83bada54567624ac1ae704d0a979e127f15c6",
+ "packages/flow/openadapt_flow/cli_worklist_pool.py": "74b4164f79865db4ae7a41b063ba2f671077c02645021fc2e42424f628431777",
+ "packages/flow/openadapt_flow/cloud_seal.py": "dd473bf2ce29f708e1c1638d70f8b54a3feaf140f27aada14481f31c1d2517ad",
+ "packages/flow/openadapt_flow/compatibility.py": "c869b05daece5b5bca489a27f71d2de07354624913d7480135ca0d6354e3516c",
+ "packages/flow/openadapt_flow/compile_agent/__init__.py": "1f70909ee8780e62513f41d717b8c07cee89dbdc430bf84ea08904998502af3d",
+ "packages/flow/openadapt_flow/compile_agent/agents.py": "6dcb2a0f9a49999e0fd289c488b642dac5280602609bbdf7b6c97630c2262c6c",
+ "packages/flow/openadapt_flow/compile_agent/cli.py": "fb3480bc92c925c0f647f8b02b3f1de0562cac48d1006859160042b60bed0c58",
+ "packages/flow/openadapt_flow/compile_agent/code_action.py": "f0f2cc963dbd1199eec285571c3441f506fcb3a9dec719db9e1bc6ee938c8edc",
+ "packages/flow/openadapt_flow/compile_agent/driven.py": "16dad5aa77be22181920343ae7dba069576c3a293bfa1dd0d292fb71f7d71ae8",
+ "packages/flow/openadapt_flow/compile_agent/emit.py": "405411124cfc94b52c45c90c195537ea53b0ef3b242cebf212102c49c0111403",
+ "packages/flow/openadapt_flow/compile_agent/harness.py": "d528543c8411b2d7403929d3a71e056bd5f93e33bdf16fb741bf14bb7c5e8106",
+ "packages/flow/openadapt_flow/compile_agent/observe.py": "b2a82ff94383acdf113ae4f4c9e75114df3e1c0e7ef1782495eaeed249e41206",
+ "packages/flow/openadapt_flow/compile_agent/pipeline.py": "3f52eb024386ef046c61cb29642fd463575ad6a7bd1fc28474591170338979db",
+ "packages/flow/openadapt_flow/compile_agent/sandbox.py": "0df910a8f3c7f9a4d1a76c2ad97d62cab868694ee67f5ec70ddb2ca0f9d26e97",
+ "packages/flow/openadapt_flow/compiler/__init__.py": "e38510f5baea14d9d357ab594954ff42f5aff608589ea8ae5d7060e8cf0fa380",
+ "packages/flow/openadapt_flow/compiler/annotate.py": "0cd0afb521e50c82906c5d47e12bca09a12d0caa9127bae433f830339b41622a",
+ "packages/flow/openadapt_flow/compiler/api_proposal.py": "9d4aaf53c753a62fa33adf7a2268dbbb2e40738301a6d14871eb67750a198978",
+ "packages/flow/openadapt_flow/compiler/binding_admission.py": "5113f27876d3109ebad880c75255e138c67375a7846d4966ac0ab9d9e2f69ee9",
+ "packages/flow/openadapt_flow/compiler/codegen.py": "327bcc7ca46c1249ba11caad31305171dc36fd11f02073ef6484aa4939f4772c",
+ "packages/flow/openadapt_flow/compiler/compile.py": "daedc14eb1caa6be95c2d5037a92141f4fa0b871b1a6280783b220935d048a93",
+ "packages/flow/openadapt_flow/compiler/compose_authoring.py": "84132f230f6cd811d86a1588d08809375282b61227e40f64f5f9fcf2807cfaa1",
+ "packages/flow/openadapt_flow/compiler/disambiguation.py": "2761afc6683f1b72b1126a2482bf1e02f34651489dd28f71a2f57aaddced7fb5",
+ "packages/flow/openadapt_flow/compiler/distill.py": "3169f571e0f8c63c14f324c626400ae78ad55aab83c03e54b8396e304757fc75",
+ "packages/flow/openadapt_flow/compiler/effect_mining.py": "5f37b4e4a6191141a9cf80c3c2738de0d4db7849f2981dc44ac325eaa8f0c02a",
+ "packages/flow/openadapt_flow/compiler/fixup_passes.py": "153276b86f37fb1108d332497328f27af11d1ea0418c7ee7baa1050606d25b30",
+ "packages/flow/openadapt_flow/compiler/induction.py": "dbe2a0dd41d733f686cd0f86f82583fe2ca32557518d99d2b5d01d414c8c28d9",
+ "packages/flow/openadapt_flow/compiler/local_edit.py": "867f0ca4d79dccc88367da10e75b180727438a1aeae30a49d407ef5cdff04981",
+ "packages/flow/openadapt_flow/compiler/lookup_detect.py": "9515fde8bf759f19e5698e3c00f0fe918a790abb0f30f9db911e03d12e84b402",
+ "packages/flow/openadapt_flow/compiler/loop_authoring.py": "f9ac89cc50e238a35411741aebb3eee7d76c2b263008957d21cdcb49e89b0ee9",
+ "packages/flow/openadapt_flow/compiler/loop_shapes.py": "b46f39bd5c4c3216c87ed52ebdb919ad1fa87ca0df29ccac376cfb107ec36a8e",
+ "packages/flow/openadapt_flow/compiler/motif_induction.py": "920c2fb7a409ce90437376ccea3261cf71fd1b029baea8f5a6f2d8de7aefe360",
+ "packages/flow/openadapt_flow/compiler/narration_rules.py": "2be904090c00ce014a4f1854393770d3b4172943e4d2ec1b35e1e58e5a26d199",
+ "packages/flow/openadapt_flow/compiler/param_confirm.py": "4cc6c8402a4f30626098e09156bc283f7755d68b6b108c28f2db4c069e5a7cd9",
+ "packages/flow/openadapt_flow/compiler/probing.py": "e6ee7dedc5f7a8bfa768bf0a0cb6b1271ed6da2b1c1a956968ad34dfbb3f8b48",
+ "packages/flow/openadapt_flow/compiler/qualification_pins.py": "8392cb44ef2cb33956ae58e235a8611295f07553a0c1ea2aa5b2ef010a997787",
+ "packages/flow/openadapt_flow/compiler/qualification_proposer.py": "ab4bfa3e51aca8dd5fb2360e5be9c3b454197e09d6365ef20ba0632210997d30",
+ "packages/flow/openadapt_flow/compiler/readback_authoring.py": "f9b170cf4a7b8a66bd0a19803a2d2f540b30e9729fff66e4d48be091ac034a20",
+ "packages/flow/openadapt_flow/composition.py": "fefffc27473a38c1284b58e298ee15e099d848741aeb9ad50876516034fdcec7",
+ "packages/flow/openadapt_flow/connector/__init__.py": "ea1c554a0de295db995f57f837669419855c9fa1d2fcf958ae4e2feeec37106e",
+ "packages/flow/openadapt_flow/connector/client.py": "1f55a56123fda690c4bb4dfbd6407f4a96c85c2575eb8928cb7aed30b3a20145",
+ "packages/flow/openadapt_flow/connector/config.py": "8dd9f662151ce609e21ead89d4019c77a4ab185a0f1b5690df20dac166701c4d",
+ "packages/flow/openadapt_flow/connector/daemon.py": "3ea5444af51cb28dc84addc4a5db15a6a75486f4ecee93d3b6c09ed7e7ce1366",
+ "packages/flow/openadapt_flow/connector/executor.py": "463aeafed9092b16a654191611445bb5688334ca87ac0703699d6dfa7f449748",
+ "packages/flow/openadapt_flow/connector/protocol.py": "963162e5dc20fe0e220fda67e59d138b791fcc6bbaf626776ab192d6cfe3a203",
+ "packages/flow/openadapt_flow/connector/storage.py": "4ba816b98860b5f6973909b6b6d30138b429a8bcd120423408bf0ade7cc1a916",
+ "packages/flow/openadapt_flow/console/__init__.py": "3a5ad4c010c98c3afee9c00a4fb7b4209e914b27e48d0cef09d8d4d3eccbbb57",
+ "packages/flow/openadapt_flow/console/actions.py": "097dd73b8cc61d19cb9cb5752103663a413cae0b822cb708419966413d188850",
+ "packages/flow/openadapt_flow/console/app.py": "c85d6e1038cbe1ec0737cc51deca93b490f83496a55b0b3b60681575dd07e386",
+ "packages/flow/openadapt_flow/console/attention.py": "cd4dff1f27d8c0ef022dc92d64eabf2976fcff3ea0a06a5c363af169899f9cef",
+ "packages/flow/openadapt_flow/console/data.py": "80359fd5e16d13b73a821034b4ac12de7a52cf4dd81c4211c18b2b23154a86e1",
+ "packages/flow/openadapt_flow/console/decision_context.py": "e5d7297c636d5e5c429558d6ed54ce294b4a3e97629150346369409bfa309d8c",
+ "packages/flow/openadapt_flow/console/decision_relay.py": "d5320404d4342dbb52be1f2ead1cdb5cf0e22877feaaa1e47974b301df697292",
+ "packages/flow/openadapt_flow/console/decision_supervisor.py": "a5496779de6c05a21c03fb91cf3a3565951bf97922952cf6606a2c185dea6d69",
+ "packages/flow/openadapt_flow/console/halt_detail.py": "08b88a082568b45038b47e09549aaeb5e9f2f74dd1942d6db372871f82b17226",
+ "packages/flow/openadapt_flow/console/human_decisions.py": "02651ad8888a5c17bfff6fb47165ba861193243dc0f7c951f8b94f544ca19477",
+ "packages/flow/openadapt_flow/console/json_artifacts.py": "e908d47f34bc040e83b257b953c55a7f3cec9b2b74a4519369d85c3a12e6cb7a",
+ "packages/flow/openadapt_flow/console/save_approvals.py": "1c180720a593e160720421a72cb5676a13f399a5e2bd3fd07ccc063b5bd8c00b",
+ "packages/flow/openadapt_flow/console/server.py": "d250a4e486053343eb92e38887fdb59c55c5c3cde64b69756e432b3b074f7367",
+ "packages/flow/openadapt_flow/console/standard_changes.py": "29f34f8fb06b4b412e825892fa340bea11f07e21c6560ae4936c0bab19972505",
+ "packages/flow/openadapt_flow/contracts/__init__.py": "cc4213ad8ee43060894281df685a4d2554b9e0869bcd267f0509b965d81d19cc",
+ "packages/flow/openadapt_flow/countersign/__init__.py": "727c18b4914e681256d727bf6a13285bd9b43c84430c7cbb610efd6721d7edba",
+ "packages/flow/openadapt_flow/countersign/cli.py": "bbb2f1b833297dab3d90fab4ee8bc60b71598b93d0da1dcd30baa6de6dfe8886",
+ "packages/flow/openadapt_flow/countersign/commitments.py": "2ec3967924a7142facbaee575d6c76c0241f9187e4ce2c4b497f479b5e432339",
+ "packages/flow/openadapt_flow/countersign/document.py": "3e4760c7ad0f6949b8cde441217d647c5caf7ea13f63c25bfeffee92c0c6e375",
+ "packages/flow/openadapt_flow/countersign/dossier.py": "1ea1151f03b55a6b8a73333b46079cf2cc31d338e6b413490636d2b3ef16033b",
+ "packages/flow/openadapt_flow/countersign/exceptions.py": "effb4425752f60d44e133ee7b2d704f25473bcb46e168fd17780f50320cf1ee7",
+ "packages/flow/openadapt_flow/countersign/render.py": "754b6858cb5a3de7db6489103c5225f8f5a62f7ec91af5027b68c0d0c9e7e5cc",
+ "packages/flow/openadapt_flow/countersign/tsa.py": "c3597122c33e80b3eb2cb129551e1cd50b6021f45cbad01c20869f13699f8200",
+ "packages/flow/openadapt_flow/countersign/vault.py": "71ea45df4993a00a384791c227328eab67a2e5d3d1d75896e7c841765d5ed1bc",
+ "packages/flow/openadapt_flow/crypto.py": "88f8f0b462775b4f06d89ab63e84954de763292a8a8bcd356f40f15f1a56b9dd",
+ "packages/flow/openadapt_flow/decision/__init__.py": "32b2b08051ab45571c55af1d44f2b68fd4106eec9ceb078d6769c2d306403550",
+ "packages/flow/openadapt_flow/decision/calibration.py": "51b2adc7ee624d78120a12ebf02d6eb6b9408ce90642e064647fe678e5578051",
+ "packages/flow/openadapt_flow/decision/cli.py": "b0f453ad2616e4b0f99249e983967d1fa7b929e4692662b8adab47053cdf027d",
+ "packages/flow/openadapt_flow/decision/eligibility.py": "86e77ae372f8eef0c31eb9ff694e17cadc7f278155c76d46f0a40be0dc766cb8",
+ "packages/flow/openadapt_flow/decision/feature_model.py": "af7207d471e531377ea653448fd2487f1988a4e8c0b3c7c36d7983a369621077",
+ "packages/flow/openadapt_flow/decision/features.py": "cc5e21ecf0ca93982645791724fd41afcb9e77ed4c526cfa2ea7d3c6cee3931d",
+ "packages/flow/openadapt_flow/decision/labels.py": "924fa2fa32cdde259a2900d0c8af3c3f54b07c30bcbbb9f4af7289663a2889c2",
+ "packages/flow/openadapt_flow/decision/minimize.py": "9c0695866985ecda25a0c96d251d3358d15ab7ee57e66a3b4528e66f4df65ace",
+ "packages/flow/openadapt_flow/decision/provider.py": "3e14c3b013533925a62e67bdd9b82ddf99f969a2552914db1630498ee7f4bcbf",
+ "packages/flow/openadapt_flow/decision/review.py": "47822513196daa1cb3e827e3cb846763f41165738c3576c2df946f6135676098",
+ "packages/flow/openadapt_flow/decision/rules.py": "59a33e0bec5f19fc35621652c96c79ee6d6cc719854ff402853c9cf9c143b31c",
+ "packages/flow/openadapt_flow/decision/synthetic.py": "2ee2fc309a5342a5a3e050a47054b6b1730e21d8d20592956f7bc83f8e7389c6",
+ "packages/flow/openadapt_flow/decision/triage.py": "201235c57ce21e631c4e2f5990628f40ce3bae95e239f0bba29ce7738d95f96b",
+ "packages/flow/openadapt_flow/decision_delivery.py": "e3fd372d84ecb8a13fd811e115255362fae2f96e5b073e59d1d7f123c2bd85a8",
+ "packages/flow/openadapt_flow/demo_driver.py": "96d2dae078eee394b9c92a050cda498f98a61ad7926040a19996f31612007639",
+ "packages/flow/openadapt_flow/demo_proof.py": "dd9d11d97e4ed264593ecd33052910bea4784934ac575a5365d5cd4c8099f110",
+ "packages/flow/openadapt_flow/deployment.py": "24a8bb0e5f3ac6036a69d5bd32a66bb74fde73fee45e3bbb335c62882c9b0ae2",
+ "packages/flow/openadapt_flow/desktop_record.py": "a162df0e593b9f437bca86aa723be013836dd5e0c93acd5fcff7876ba16e3110",
+ "packages/flow/openadapt_flow/ed25519ph.py": "c8bb9e5d64adc44715e27c06f437e7801f6cac56aca1f15d8a577e629c649282",
+ "packages/flow/openadapt_flow/eligibility/__init__.py": "c4b10f081ff9c6d3ec3a3017d8a12aa7eb67b41488ae931000a8f84f08d9c54c",
+ "packages/flow/openadapt_flow/eligibility/artifact.py": "686eae18906a58b42fb6219fe6c4fa7b98638192db8169f0098601403ab274b9",
+ "packages/flow/openadapt_flow/eligibility/client.py": "9ddd6ca4512b64b8ad7ce7fad6c31d037209f3a19e9c52c605e9eb508c0f63e6",
+ "packages/flow/openadapt_flow/eligibility/waterfall.py": "15e15b5c8efed40cdeba907b74a279c217434ccf62a378f2ed4a05feba0d44ec",
+ "packages/flow/openadapt_flow/emit/__init__.py": "f9d028ad70f3eda13321fdab9d23845016781cb7360160d71eab82a1752419cb",
+ "packages/flow/openadapt_flow/emit/l1_artifact.py": "8e590b6013d1aedb6b722745d616bc394451c703642a1b7b0159359d94a4a868",
+ "packages/flow/openadapt_flow/emit/mcp_tool.py": "7852e44e2451103612a282b8fe3224a631c4b7261203418636949f82e80b4ba7",
+ "packages/flow/openadapt_flow/emit/skill.py": "43bd4116c93a662ef628a07a81c0ee2777351b6eb790ddc58b91151df672267e",
+ "packages/flow/openadapt_flow/ensure_record.py": "78e64c9298bc29c3f01a74be6b47a0ffa7be5df615eab383d36b8b8810dae21d",
+ "packages/flow/openadapt_flow/execute/__init__.py": "769684783844a34810850275aba3647c303acc2cd6eced1d8c350c4a2e774d54",
+ "packages/flow/openadapt_flow/execute/app.py": "fde39916331f18c8ec84948cebce74b2e1c31d3c06cdaadcdb8225eda4df92d5",
+ "packages/flow/openadapt_flow/execute/dispatch.py": "9cea78d3955ca6ef30e7ebe74b8ad752e6bafcba0289f2db4a746342ba1bf2f9",
+ "packages/flow/openadapt_flow/execute/keys.py": "f43c622ef1df57efb3ed52db6aafc9d98d78100f2e25fff50dcc8b75489f9750",
+ "packages/flow/openadapt_flow/execute/models.py": "bfbac12c75f4fc52c0f9bf89652e876828f208c13a7827dab8bc741b112a5e6a",
+ "packages/flow/openadapt_flow/execute/registry.py": "d687121bec318dd4b56faa1db195a181501fde92263f7b851fb33607de903642",
+ "packages/flow/openadapt_flow/execute/service.py": "1453344697293a8b76ef7a5788930408b19e60981e8770e8680c852dd307af88",
+ "packages/flow/openadapt_flow/execution_profiles.py": "2de96a2fa6fcdaa17303d336a74f0c54bb702289575cd4f0e3e83229b48503d3",
+ "packages/flow/openadapt_flow/failure_signals.py": "63090631a784bf6626859f3a2f7c95551b019d1baac79573255fb41c98f7d8c9",
+ "packages/flow/openadapt_flow/fault_gate.py": "e667d86a5eecc8e28da6e61c28c9c1034b00e2c9143533eb0a031757bdcade8f",
+ "packages/flow/openadapt_flow/fleet/__init__.py": "3196cac4fbcf1ac5974955e8d9f4dbd0295b516ad5b758e1f67e4f6f545a95b7",
+ "packages/flow/openadapt_flow/fleet/_lock.py": "b877076335ab50d6b240e3b6b0f131d0c699ba706e4af738858320c3fbfe45a1",
+ "packages/flow/openadapt_flow/fleet/canary.py": "275a8acf693d566f17858a2656df9d1b6315becc6c9153149046902bede9c1db",
+ "packages/flow/openadapt_flow/fleet/export.py": "f3c4385716ceb71c0f2e93e4552a32aa22fc31561d0497f9b4c5f13f09c64937",
+ "packages/flow/openadapt_flow/fleet/feed.py": "f229589e292195b387f9c756fbd549eacede2cbaaac2a43d782ae89fc69a7a34",
+ "packages/flow/openadapt_flow/fleet/fingerprint.py": "f641b80642a5bdabf97e44b7f9796ab413c8c5e1ec64355c333ecf91ccda6e00",
+ "packages/flow/openadapt_flow/fleet/hub.py": "5605dd4b5cc620f400bf101c8a94b3fd386dcdbea91329ce9fd2dac087e12f8a",
+ "packages/flow/openadapt_flow/fleet/intake.py": "c6390b6814eff7f0dc424711a6502145baf13bc7ba32031de827f1458184b267",
+ "packages/flow/openadapt_flow/fleet/optin.py": "c6a02feef8c31dfda435fa7b5c9ae2313775979cf68ba0643fe1f284142d3eb5",
+ "packages/flow/openadapt_flow/fleet/patch.py": "50fbd5f28c25c5af1a74ab79534bfc45d80335bf50971d88937d6f48a8047caa",
+ "packages/flow/openadapt_flow/fleet/policy.py": "d9a6dfc09ace5a6446f421728f636d77ac40c4e8e3068685d54cf12a52091729",
+ "packages/flow/openadapt_flow/fleet/signing.py": "9761c1e080a04ddcbb0f54f75ca37fd74a1801399be32218e527ef1c5b71bc89",
+ "packages/flow/openadapt_flow/fleet/simulator.py": "bb9deae25e4e6b6df6503df08b175d146b73cdf347f2997cff32ef34bd94af50",
+ "packages/flow/openadapt_flow/fleet/status.py": "2be462c6f00fda3b783e7825c12a5a031346b11e34c10c6465de75fa79c650a5",
+ "packages/flow/openadapt_flow/generate/__init__.py": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
+ "packages/flow/openadapt_flow/generate/demo_analysis.py": "414ceb12ebb29cf11a66e1c625c0ad386714d7cd16647bf845a17dfd23b26aa7",
+ "packages/flow/openadapt_flow/generate/ensure_contract.py": "fad470bcceb721f83b7d5285058c31c6c51a49abfee88b5c3d16de44e9ef394f",
+ "packages/flow/openadapt_flow/generate/fhir_tables.py": "efe58cb353bb8e660c69773f4b057410165b74adf782d1a49e39e676a7a904ca",
+ "packages/flow/openadapt_flow/generate/sql_store.py": "25ab4c17799a59d4affc667fd6efb84f79cfd2577e647179a936336dd40aa2fb",
+ "packages/flow/openadapt_flow/generate/verify_contract.py": "e3050d86dfc0465eb2bc8645637ae10e76f5c35e2df7a185b3d23aff96ea9ff0",
+ "packages/flow/openadapt_flow/guard.py": "9a002384f9564d7bf379fbe855cabbb4484ff2c18a7ba5412502c818f11213cc",
+ "packages/flow/openadapt_flow/guard_demo.py": "b60288fb0ab86afdca9d12c34bd61dcf41f8905629e6c812d151426060e71931",
+ "packages/flow/openadapt_flow/halt_cleanup.py": "c1e0e58b170519c683faf97593fb36e91523392f17a1726223d90b47738c3cae",
+ "packages/flow/openadapt_flow/hosted.py": "232f7cb2d68e0e1f57ec7b4caa10b866da16a5555c6867d41d978a89bc946683",
+ "packages/flow/openadapt_flow/identity_signals.py": "46e1392fe0fdc7473bc28bb25562f31a6dcc6c90f95d7900de255bc750bf7287",
+ "packages/flow/openadapt_flow/image_hash.py": "4dea419ca5617104d6072ebddf8141e8f9809227aaf833969e390eb3d5c7d73e",
+ "packages/flow/openadapt_flow/instrument/__init__.py": "8bcf6fb0892a9dcdd6cdd3a787a084548479d2ac2ac4e439a772e45dbd924250",
+ "packages/flow/openadapt_flow/instrument/competitor_drift.py": "f124cc086c52eec9b930088b1eb9bf264075cc121f9d06a09ca98ea76527de56",
+ "packages/flow/openadapt_flow/intake/__init__.py": "76815b0b2ecd679c7b076f28f1bb48c66a6be007f208fe8a6ab2746477b3ddc0",
+ "packages/flow/openadapt_flow/intake/cli.py": "332e14ae4367185c4cb51f3f704c4de63cfb277e22689972bfae7ad841971465",
+ "packages/flow/openadapt_flow/intake/document.py": "b71b232d18d509e336d9d950063b14c6dd703383319a25b845e08fa5731b6f32",
+ "packages/flow/openadapt_flow/intake/extract.py": "61a1db7580d8fcd47943337ece067980527a541520929a62e0de321c23fd6f37",
+ "packages/flow/openadapt_flow/integrations/__init__.py": "f963112195eca4e46543778de92d5e5ad6e3afffccd999fb94377f4c75199606",
+ "packages/flow/openadapt_flow/integrations/agents/__init__.py": "280e431a4b07bb961e3ff7ddd8f2e8225faaad139fe00d091eda18ddc77b2bdd",
+ "packages/flow/openadapt_flow/integrations/agents/claude_sdk.py": "c2b4fe00a75c8ea95652a29b438269608c2f5f3cfd7cdbe80538b3bc87570120",
+ "packages/flow/openadapt_flow/integrations/agents/crewai.py": "a93a5a2222c20e77e89161c3587cc9e90769739465e1045f2666e80da91b7718",
+ "packages/flow/openadapt_flow/integrations/agents/langgraph.py": "ffe07ab4063cf8d053d89d63586fe114babec53e75274f2b406179de845c90b4",
+ "packages/flow/openadapt_flow/integrations/agents/openai_agents.py": "0a5d6e04f3bbe6e568c9eda5b63f76f86343c686f6ab103e209b6d410605ffe8",
+ "packages/flow/openadapt_flow/integrations/agents/skills.py": "0dca940f3f8f046df12d580599ea8ef909c5c0b2116dbcf2208000ab7aaf0e84",
+ "packages/flow/openadapt_flow/integrations/harness2/__init__.py": "1675bc0ab764041b3d579205435dd4bac547709c17016cc7805ed158e9fe4ead",
+ "packages/flow/openadapt_flow/integrations/harness2/adapter.py": "a02f3f471346106d3a70a7132c1cf14760ffbab41adaf93a21cb0a41e56f5916",
+ "packages/flow/openadapt_flow/integrations/harness2/agent.py": "bf8960db7127ec06e0d24e108893012ffa60a7aeaa521e5c7f354d9a85bd90fb",
+ "packages/flow/openadapt_flow/integrations/harness2/apps.py": "127522d89a834eaaf533a9fc4b5b90ec69cfa7cd179685b50b50f0c6a8dd00c7",
+ "packages/flow/openadapt_flow/integrations/harness2/llm.py": "7e2300d3ab7b5a9d4291fc8d6996e7e0cab0332d6b2d17cc86bd1b302bca4623",
+ "packages/flow/openadapt_flow/integrations/harness2/pixels.py": "be07c7a4ad99c5ea6a28458a49338425ccffb71e2b4b88d25aebe47cb8f3c641",
+ "packages/flow/openadapt_flow/integrations/harness2/proposers.py": "e554fcad5900a9fcc9c0c134e832f5ac7f02042a356e29b5b4856593920f647e",
+ "packages/flow/openadapt_flow/integrations/harness2/rollout.py": "4519c4c180ffa259cddebe0dcab6d00d2706b91cb911dd5f3d974a7d45bf5fa4",
+ "packages/flow/openadapt_flow/integrations/harness2/scorer.py": "c4a07d140d31920a57ad518b40817d1e78c87f20bde6810cbe3036d309df9ead",
+ "packages/flow/openadapt_flow/integrations/harness2/selection.py": "e08682bf22e8fd3fa698c146ef36d42de1d6b7c436769b98e5e2e7e87f9ae0d7",
+ "packages/flow/openadapt_flow/integrations/harness2/tasks.py": "a95df9907d871fbaead65763e853f62676f9208098a9664505b9de19fea2b8f2",
+ "packages/flow/openadapt_flow/integrations/harness2/traces.py": "91a71bf087a51494032fe347e439ff5014853fe73307eadb6e81ecae62b1383d",
+ "packages/flow/openadapt_flow/interactive_recorder.py": "69cb3d8a3c448e5e0749a17fda751ed3ada89093da7289df43c40fba008f495d",
+ "packages/flow/openadapt_flow/interchange/__init__.py": "b40b98268f7317e7539f123a6fca9b507d6492280d6f679525673493dbe24718",
+ "packages/flow/openadapt_flow/interchange/__main__.py": "8eba812ea2fcab0984b05def3fcc596cc4e523756ea3d8daecd23eb4a5c2cd1b",
+ "packages/flow/openadapt_flow/interchange/conformance.py": "50d7192c78d9b1fffad09fa37dc9abe7b33e84d66a395af955fa852912a99adb",
+ "packages/flow/openadapt_flow/interchange/l1.py": "438d2b59a856017cdc2f0256e6efd7e605c68ce54ecf9825282a34f09b24c7e3",
+ "packages/flow/openadapt_flow/interchange/model.py": "eedfe5e24508b82b24fabc05edf003fe3fc3c89e414d0436d6ca4c0d682c7444",
+ "packages/flow/openadapt_flow/interop/__init__.py": "fe8f034e12327da65230f887cd17fef5a21b8ec350a77d22fa0693f728f11d03",
+ "packages/flow/openadapt_flow/interop/business_decision.py": "264c35835b5d7e5693d140a0b6fc6515c719b73d42aba57bbb685f1dd1140743",
+ "packages/flow/openadapt_flow/interop/business_decision_cloud.py": "85b3a01a0642f28bdf2ec704b8b39bb8f81b5e16ab716791b56ea25990a890f2",
+ "packages/flow/openadapt_flow/interop/business_decision_supervisor.py": "d39d6bf9cfd1d4c84804b5565a99f0ac9560ac15e2838deee4c81426503b521b",
+ "packages/flow/openadapt_flow/interop/decision_relay_transport.py": "31a2f2ecea1d39f108747dbb81b123d2d7d1b0421fe75b97c6abac1d94652a51",
+ "packages/flow/openadapt_flow/interop/types.py": "1f2a45fcf456d31cf15534ab6d1417fd3c52612c3ab948bdb14f5a0b6f814945",
+ "packages/flow/openadapt_flow/ir.py": "efb7fdce6fa625f631901389ca767b016f4db3111caa2905321ff3da675e376d",
+ "packages/flow/openadapt_flow/jit/__init__.py": "351ae6f83405a8dedb9585ea031ad068416a8595504edb21b39e623a67a1f489",
+ "packages/flow/openadapt_flow/jit/adapters.py": "c7af4267e8a1704e1390dee295a2ec3696ae9c932e506a2785023ac88a71c879",
+ "packages/flow/openadapt_flow/jit/authority.py": "421e369b815c16578f5aa54158065c8c0700105124a32b6e8a0aa0020ed1de60",
+ "packages/flow/openadapt_flow/jit/cli.py": "d530b05349a076d8aa2a044f2fd98e4b0f491f274c96c1cfbdf23d6610871c33",
+ "packages/flow/openadapt_flow/jit/compile_agent.py": "fdb65297497d3855a925c43e73dd85391fed9aa37c6db88d79af21d36726b2e9",
+ "packages/flow/openadapt_flow/jit/keys.py": "8d4b0674a351a69011e590ca9bbe5e09ccfd3c55868ff03db7584bbc6e2d530d",
+ "packages/flow/openadapt_flow/jit/lifecycle.py": "3fac468fd4ddfc77a9e5e83651430f8a3393d5d7ebcfa716dbcc90ad2c78b0de",
+ "packages/flow/openadapt_flow/jit/lift.py": "dccb48c58846119218ddf2da17263aa4f72637a53e50565bc5df4b2102dbb7aa",
+ "packages/flow/openadapt_flow/jit/recorded.py": "3dac2027d3bc1d0e7028dc39f85e7c072c115656ef556d3e21e003f9cdb2a8aa",
+ "packages/flow/openadapt_flow/jit/signature.py": "b7f68b753c10c89fe57ef6912baf2e857637a5cdde5c23dfeb105f27c43c67e1",
+ "packages/flow/openadapt_flow/judgment_cases.py": "021f312ad721f06c6ee0f99cd2061d32c82eea7bfe6f87c4b182e36a4f445db9",
+ "packages/flow/openadapt_flow/learning/__init__.py": "3a47506779959eafc8b85ca26a779fadded553711544021ca4915a87504857d4",
+ "packages/flow/openadapt_flow/learning/branch_teach.py": "521659c92f3498a43983e5f444ec3981c3cff7326036bef47cd190f32f3228f3",
+ "packages/flow/openadapt_flow/learning/clustering.py": "50173d350b1c936e2f667db1612dae7721df7a81b40c07eef11abf10c9c0f1c4",
+ "packages/flow/openadapt_flow/learning/gate.py": "f34fd9f3ec74d7a5cb7f111be658db9debd032ceaa12d9254e2adc25f0becbf5",
+ "packages/flow/openadapt_flow/learning/halt_loop.py": "7db231e6902ee3b7fcfde914b2d1ce9c93a61f371d87b31c0156991b664b4566",
+ "packages/flow/openadapt_flow/learning/interpreter.py": "606d336216a899b11651c2e4eb341748d8cc91a10508bd33a63c7d50a44318aa",
+ "packages/flow/openadapt_flow/learning/library.py": "bd3443f46255070368827dc766ff89b9d77cbb92c828b5a0dec06de4581fc7e7",
+ "packages/flow/openadapt_flow/learning/loop.py": "f3e5c1127b4fa21f3e112516670edce15daf05322c554642b8057bf268adb7cb",
+ "packages/flow/openadapt_flow/learning/synth_stream.py": "23ab8b60ed0ba8c3f241c480fddb3901a18aee4bbce79e8828d87c41c1178c80",
+ "packages/flow/openadapt_flow/learning/teach.py": "f03226cef5666ce7940c954cd381e34e1df38de3c97ede3b318b6955a6c1c851",
+ "packages/flow/openadapt_flow/learning/trace.py": "323bc17cfa3fc3876ac030abda028c73e8af02d5e30b2cbe9c9b9faa4639c524",
+ "packages/flow/openadapt_flow/lookup_capabilities.py": "6f8068a05f005e0eac994d14d0ca3e6b1ce7a4e532471bf4b8d9dc15c0fe1b4a",
+ "packages/flow/openadapt_flow/mockloan/__init__.py": "06beb30be301dde52a522064ed192864a4c2bc1f167ebb5800c173eaa72f4735",
+ "packages/flow/openadapt_flow/mockloan/fault_server.py": "0f6f6e4ca4622c5674dca6e49b9dc67360f34b9071ba1346727683aed16682ca",
+ "packages/flow/openadapt_flow/mockloan/server.py": "6d81bda0dd715a71e54306c92d739b49ca3b3a75fac65ee7a70a3d18027ecaa7",
+ "packages/flow/openadapt_flow/mockmed/__init__.py": "223bb05087540a7e0e90f72b83a5dd3634318b95dc0a6874cbc82fd38ce5ee9b",
+ "packages/flow/openadapt_flow/mockmed/chart_pages.py": "38db2fb4d34d14d8745c7c9b31a6c729a4e0afc545333c164296fde5044bf395",
+ "packages/flow/openadapt_flow/mockmed/fault_server.py": "acdd45ef82111d50e1ebbd242d55ad14094f0a0c457c43049855be5efa8ecb70",
+ "packages/flow/openadapt_flow/mockmed/server.py": "9fbeaf2b0c873dcdce478b4f54990b954844c057a0760ab763705e6aa3f202ab",
+ "packages/flow/openadapt_flow/mockmed/teach_scope.py": "50d70c32aed4a582343d7f05ed4ee927a47de51d0420e22b3d48554303c287eb",
+ "packages/flow/openadapt_flow/narration.py": "1293e9c0858ba925275bf67a42eb602e1e803e544d068a3ef66b2fb628ec2d2f",
+ "packages/flow/openadapt_flow/network_capture.py": "d291ed5754d64a8a0bf635018ba7ecd50d8bd74121c5098d4cdf7f528a423a33",
+ "packages/flow/openadapt_flow/network_scope.py": "c64d2288c98fde49c437a0a44b53af4a4b1884a8130b99bee098c2046e249033",
+ "packages/flow/openadapt_flow/no_outbound.py": "af14df863d40d81d046acbbcc102e2f96912b24114111e052ebf5440348673ec",
+ "packages/flow/openadapt_flow/no_outbound_allow.py": "b60aa14551bd39ed333389290ae4a9069863b370532e1016d74441a8dde5dd2a",
+ "packages/flow/openadapt_flow/offline_seal.py": "cc7b0a2dd8d946e6cae740af7d7fb250253a58276c11de4f8a9122b91819d54b",
+ "packages/flow/openadapt_flow/onprem_reboot.py": "5897eda697e7111ef3ad944c7e397b64ed39abdb225085f9eea0f47b6630879e",
+ "packages/flow/openadapt_flow/onprem_service.py": "2edbde7b9a179b1c2bf63d1b955113a9d9fa3f909e4d9db875e7b626b0e9a792",
+ "packages/flow/openadapt_flow/operator_profile.py": "88e013511d1a7fcb7b8e46841c6d7291433a631cb3baec349da42e7a300c5934",
+ "packages/flow/openadapt_flow/pf_firewall.py": "adff9c485d303b5b07efa910c45d39762e12285c843f8cd782ffecac5631e0de",
+ "packages/flow/openadapt_flow/plain_outcome.py": "1a74681faaf317377af006d37557e114f0ba7f5bb561a33331565da0addb4de2",
+ "packages/flow/openadapt_flow/policy.py": "730c8a74c8c1d2e65454407665b62517a48eecb7bcebc9bfb7b6ca3f8fb25079",
+ "packages/flow/openadapt_flow/policy_packs.py": "8df13eaf8e7e4ac7492c2f8c25063ce387833174f3c82dfec3f8c68de4bbaaf7",
+ "packages/flow/openadapt_flow/privacy.py": "73f9ac693a9d1b9a819fb0a2c3fae77bf9f702f782246d1c910f9d1420113288",
+ "packages/flow/openadapt_flow/private_file.py": "eae5ffdae6a76c57bc999278baae8ad0bbabfe87813818777e825beddc22f135",
+ "packages/flow/openadapt_flow/production_qualification.py": "c5c9911c7fcaa12bbd513fe737c4c17a3bd64522b98100880c1a05fddfff3aef",
+ "packages/flow/openadapt_flow/provenance.py": "0865fd3f0362eb6a7b4ced98070b5e399b91e1530288b9a002bc933c86d90879",
+ "packages/flow/openadapt_flow/qualification.py": "d46302cdb42e1e44f179eea69ac12ad5f8b07eee618369efb909e12843104f10",
+ "packages/flow/openadapt_flow/qualification_admission.py": "73a43db18fd383fde7c5e11823ace50046e0784e662b56c76b82289f61616cf0",
+ "packages/flow/openadapt_flow/qualification_admission_v2.py": "10d8241a38b24767953e6b98986c838773a02399652924a53e53c7ec7c7c5e56",
+ "packages/flow/openadapt_flow/qualification_admission_v4.py": "5a11934e42fdea85c7ff792ab6d33754b974a719783154e8e6144e9a90db1292",
+ "packages/flow/openadapt_flow/qualification_campaign_authority.py": "cea191889f3b3f8da5c078e0cb020e7e0ebe9c4100035f5f1bb2b17ace75c3d7",
+ "packages/flow/openadapt_flow/qualification_campaign_permit.py": "1468882d9627f0355673873cd493c2709ab7cec2506dac3b1efa32d1c16f0637",
+ "packages/flow/openadapt_flow/qualification_dev_signer.py": "db70cdacae8235acc73f13a3281e667a7a5e502c246151854db4dd921caf8643",
+ "packages/flow/openadapt_flow/qualification_drills.py": "6fecf639ee1db59b8f15f857f01765d2e5b4dd116da44f664aef0350fc715173",
+ "packages/flow/openadapt_flow/qualification_environment.py": "842f5dd827750f55d9e1046613a804fa6b27c2a41981d4d7fbd6b04d9acc8131",
+ "packages/flow/openadapt_flow/qualification_faults.py": "b4e437aae822c648fca54f8a57b722ca9c940d56f6a906a52292877ba16cc9ff",
+ "packages/flow/openadapt_flow/qualification_identity_evidence.py": "7b94bde4ec7e2d1eb9522bd456aec407ef7d1063f5cc7518a21b40be1464bdb4",
+ "packages/flow/openadapt_flow/qualification_oracle_gate.py": "39e12170e33cece3aa72f463afed7d6c342909995afbe3d861592dc47c912d77",
+ "packages/flow/openadapt_flow/qualification_proposal.py": "1c13d44a189dd798244dbd69186aa78856d304e0b21213d5262450bb9c3861a6",
+ "packages/flow/openadapt_flow/qualification_web_session.py": "3766e5b5f03a92f91a5f51988b1764542b74aeaf634d72e18c9a9b1b6ffc4fdd",
+ "packages/flow/openadapt_flow/qualified_business_decisions.py": "9b56b3d0923440b589e6ff010dda1cab88c893aa01e92861e796e6cae2c83c34",
+ "packages/flow/openadapt_flow/qualify/__init__.py": "a3d7b8e30c06fb77be32b75996ce1f3ea8f96264e74edef2646f122ebbbdc1f6",
+ "packages/flow/openadapt_flow/qualify/campaign.py": "c9e520fc316c59e9c6d77cebb83125f729b6c863e42552a008c82bd47bf25755",
+ "packages/flow/openadapt_flow/qualify/config.py": "508c4bc77d022425b57d4fb9b6659ca9c0829161ce6296a1d4102fc1f9dd507c",
+ "packages/flow/openadapt_flow/qualify/environment.py": "be85934985a000c6dfef8d1f35f3d790c1c4974a14bea893d58386e533ec45da",
+ "packages/flow/openadapt_flow/qualify/faults.py": "4a78131403af4aff905bdfaf1056c332f890acee1b991283f3c7e2424a9539a5",
+ "packages/flow/openadapt_flow/qualify/keys.py": "fb2e94913ad0db0fcc697943faaeef3f3391a83fe045af703d249b9344afc556",
+ "packages/flow/openadapt_flow/qualify/result.py": "ae2b8b1198e2ff0e36c54875a9b6d0e6005f50f36f2f16aeedd789cbf8af4c31",
+ "packages/flow/openadapt_flow/qualify/session.py": "029a8876e81649514d0dbc9862ba6c80eb6fb00eb283ff3ef7302929a69749c9",
+ "packages/flow/openadapt_flow/readback_ladder.py": "7706e14c0531e31677ccaffeefc5e78734ba2434b1ba43360d7144ce44d08ea2",
+ "packages/flow/openadapt_flow/receipt.py": "b90c51a048182475d49db793b00afe5396ac03933042d2ca74b5661375957755",
+ "packages/flow/openadapt_flow/record_check_binding.py": "eb63af93699861344ec27013c52a5ea0a1308081e73c99e6b01d032fe9c155f1",
+ "packages/flow/openadapt_flow/record_check_identity.py": "2538298c5343919a80fd5bfe3eb6db0143faaf833f05a1f132c38ab1145c4864",
+ "packages/flow/openadapt_flow/record_check_proof.py": "26104f4de1283d01dd6646768ed50ef624bb143293cb30c62e6427efec9a2111",
+ "packages/flow/openadapt_flow/record_check_synthesis.py": "c71614f451dc2e50332bbf45c4463ba4cb6570fc25fef7491c42e21f38648fdf",
+ "packages/flow/openadapt_flow/record_sor.py": "8ee6cc9530482a50712f61441622d1cd9ce787e3460309173744e178819bc008",
+ "packages/flow/openadapt_flow/recorder.py": "17a543d79da468d57e7313a729148f14f0023bf577d02aff201f68ef98ae3e48",
+ "packages/flow/openadapt_flow/records/__init__.py": "5d05312df045601b1b65183587135e6f7ba908cc3d880b18a4b74487a8d06a45",
+ "packages/flow/openadapt_flow/records/export.py": "644bbae324cf146e24f2c97e8ba1c959ebfacfd33b58056e6819909b9dfd4abf",
+ "packages/flow/openadapt_flow/records/read.py": "09b8d3948f4bd9b75b12ded13e98ae22d4846ff67a8db250e69941a62fe2dc3b",
+ "packages/flow/openadapt_flow/records/review.py": "de530c3d3617e40d0c0254c9f04d6b70ee453877a130cfb4dfc27348704e1945",
+ "packages/flow/openadapt_flow/records/run.py": "a9ec68f5ca19b2396aea6e9d9e0198cdb5e63b63fbc0fe2854773e9a7888c6b2",
+ "packages/flow/openadapt_flow/records/schema.py": "abcd330ec4ddcf2660a509c2b0485fafb30601dadff2a36f821c325397a94d3e",
+ "packages/flow/openadapt_flow/registry.py": "6203135d2768776f95a8a5d46765aa76cc2e16904b46b06ba83852d18416d215",
+ "packages/flow/openadapt_flow/registry_attest.py": "8a8375762ac6bc2a2f717359c1002d220295997f01c012b5c42b7dcd09709676",
+ "packages/flow/openadapt_flow/release_admission.py": "5afdf674f30073b10ed5b4ee06fd3818db26e74cc935c649548256cb60160f7a",
+ "packages/flow/openadapt_flow/remote_frame_contract.py": "745c8e9a6731ea89b722092183f760527d9e6f329a5a7ef61152870114e77406",
+ "packages/flow/openadapt_flow/repair/__init__.py": "db1e673372764eb9ba76be658980a94b9747a0d716b5ec1a8d5f74d69ca909ee",
+ "packages/flow/openadapt_flow/repair/agent_teach.py": "ec9995ba2d3ccaee0ee623e77cd30f0d30a565235befcfbb003fb81d4b7f2920",
+ "packages/flow/openadapt_flow/repair/auto_repair.py": "dd4270718c906eef6d89939d5bfdc5ae63d842ab78bdc55f45b5afd425507c79",
+ "packages/flow/openadapt_flow/repair/campaign.py": "520e08184f5abe0bb53a4e08eb2d314e89ad3cc0636069573ca26bdfa82f20db",
+ "packages/flow/openadapt_flow/repair/candidate.py": "4cbe98e2ea47727906a8c46139ecec4923befd35426a81d5816a5196796ffe2e",
+ "packages/flow/openadapt_flow/repair/cli.py": "b600b9920a3dc6e993f96c38d4914fc44458a9b9bcdfee807f58660a41b342dc",
+ "packages/flow/openadapt_flow/repair/cloud_review.py": "eae37867caa636115ae63adb6018987c322bfceb78a25c4178f4287bd13bc6d9",
+ "packages/flow/openadapt_flow/repair/dialog_fixture.py": "7969fe9c3e4373e32873a237867e182f8c2933397e2c47614216c5ced59a4e9f",
+ "packages/flow/openadapt_flow/repair/dialog_identity.py": "77e828471626051c74e502c29bce3ec2356926b38b6ddd83489b7bdc3fff3dd8",
+ "packages/flow/openadapt_flow/repair/element_identity.py": "7598d14cc362585fc6c3fb5be341b3a1b64599ed343e42e4bb30f8fe9cc3f5ee",
+ "packages/flow/openadapt_flow/repair/hold.py": "9b34c9d1bb9fb12d4077d18bf19e9e389ca98ae0e2ea8faecc40e2da267d11ec",
+ "packages/flow/openadapt_flow/repair/invariants.py": "c645ffc37b7135018e0783955b77a067e719e99765d70ccfc26812b3e0336d45",
+ "packages/flow/openadapt_flow/repair/lifecycle.py": "b12e47d7ca37d21631616d94292b09195364268e540e0900a0c22dbc9ccd53ca",
+ "packages/flow/openadapt_flow/repair/preflight_queue.py": "9ca1d23b744218745a660fd3b57233f41366c72c9603673347326854cca49b5d",
+ "packages/flow/openadapt_flow/repair/readmission.py": "39a35fcc0a2c804b2465054aa0a8803a6b934d2abb8427fc7f79bd5c59629630",
+ "packages/flow/openadapt_flow/repair/registration.py": "2eebf2d1683568c2893615eb47041467d6f8943c76de81c1c9a9582f9c61e8cc",
+ "packages/flow/openadapt_flow/repair/relabel.py": "a1b870b14175f073153fbf9b80733d7fd34ac766921a2924e292f4e86a96921f",
+ "packages/flow/openadapt_flow/repair/self_repair.py": "b7a136c7a1d7076739c71980b75d40ce5eee25f7e00a61512783e1047889b92c",
+ "packages/flow/openadapt_flow/repair/standard_change.py": "b67523f9d78a4a544a90fb79694e321a90601e9885ade8f302f09d39d96ff741",
+ "packages/flow/openadapt_flow/report.py": "288b62601328e4630f2db0f1a7af48b3fcf9db36340c370c51628dfe889ca373",
+ "packages/flow/openadapt_flow/report_redaction.py": "c232d124f4f97f109e46b93dd21748c5b0ce41f2303fced29a13a7a9a0632933",
+ "packages/flow/openadapt_flow/reports/__init__.py": "51b2ae3769609912e56518619972b551128a0ae9bd2af0e7661ed32629ce16bc",
+ "packages/flow/openadapt_flow/reports/parse.py": "5732213e6b7290ad8339bd9559d2e25394fe631c0ee289a5bf34d32991f79817",
+ "packages/flow/openadapt_flow/reward/__init__.py": "a16f606b5333fa2a0732ba0a3ae643125e6831f8c923fd17940194fab25eff76",
+ "packages/flow/openadapt_flow/reward/calibration.py": "5d54500f75cbd442e5194cde11674099bf3428d72611d8e8aea2a49e1c0a8a61",
+ "packages/flow/openadapt_flow/reward/callables.py": "a5736681e02b8862da15a81c95be78112d2d61741177f3895ae05941e5c4b913",
+ "packages/flow/openadapt_flow/reward/models.py": "dd560ca283720d68159c4fd733f2fa865e9d3eefd2a63b73937f69f2436b8ca8",
+ "packages/flow/openadapt_flow/reward/oracles.py": "26d890de9154ac8714f125e54bdb6dcbf763f45de8a3e0a0df1649ea44f6c00e",
+ "packages/flow/openadapt_flow/reward/seed.py": "f2286355ff807f8548cfc77d244abf110ccf88d42864f2c071284ffc09cce19c",
+ "packages/flow/openadapt_flow/reward/serve.py": "c8bf963939d991c1ad55ca7ac4ba50d3d632f70693793b92a2fc07fbb003e5da",
+ "packages/flow/openadapt_flow/reward/worker.py": "af50ba23db77b40d156302a8565c46efa4bd219779563152713d58cd4e04e379",
+ "packages/flow/openadapt_flow/risk.py": "98d412586a8b7bc51c377aa2fc37b51457017c911515359e9b856889c17e1ebb",
+ "packages/flow/openadapt_flow/rollback.py": "524627a9a27a636880f27fcce42d3b25aded6c125c63cbbc625d9d8d92df246e",
+ "packages/flow/openadapt_flow/rollback_qualify.py": "81d47df7b8f669d029833772365f6ef507aaa95f8a7bdfcb0c2cd1765352ef85",
+ "packages/flow/openadapt_flow/rollback_state.py": "b229722eafde96741d21fc01e5e2cd0ec81a029a15f57f81eec7aff082324f6e",
+ "packages/flow/openadapt_flow/run_authorization.py": "eef848a71340e8951d80f421872d82ffc79098025fe9e9d4d3d2aecb50d93464",
+ "packages/flow/openadapt_flow/run_gate.py": "2297a7c84efe4b10788808d2e0fdd189d6be3a5a20dfb33be338365fad7306cf",
+ "packages/flow/openadapt_flow/runner/__init__.py": "1111900db86ee0f61faa093996a6e64a1405c9052bb74f186afa1a84a60ffcc0",
+ "packages/flow/openadapt_flow/runner/business_decision_service.py": "97bab36f3c9dbc9974129a34a5c636dba08e7fbf3c56fc522ed507feae216bd4",
+ "packages/flow/openadapt_flow/runner/commands.py": "92a62d244b406c405cdfd51c3189a835878f0e334fc74e16e98a1acfbca47ba3",
+ "packages/flow/openadapt_flow/runner/config.py": "ba84ed0b0638ee12de51f40fe3fa4da13c14effafbbba7bceab256e56664fc2d",
+ "packages/flow/openadapt_flow/runner/dispatch_envelope.py": "4a867de3740e46b67ecf90b74120f53ad038d7c0aae9b17c6bcefef998ec674d",
+ "packages/flow/openadapt_flow/runner/evidence.py": "4f884203b69f3368b56e7bd0a31df123a28f5c7b464fa73a69b1da742fd7fe76",
+ "packages/flow/openadapt_flow/runner/flow_release_receipt.py": "1e80b5d956de0debc12e5a14f4595256eb13caba16d387e8193ad1737be4ae18",
+ "packages/flow/openadapt_flow/runner/hosted_adapter.py": "0e2f0e5e96a609dac3e78e516ceb8e6a0050f6406a8a6e4e74f93381781e3eb2",
+ "packages/flow/openadapt_flow/runner/inputs.py": "711464bd021afbde06b9c4d132ea782c3b6a321ea48bcb24c3f565f8609f8a9d",
+ "packages/flow/openadapt_flow/runner/lease.py": "9ba80da689f4eeec85d44a860a27851e2408e3772b135bd01e4c4a0996d77c60",
+ "packages/flow/openadapt_flow/runner/outbox.py": "19454f29bb30bd8707f452a00e6fcb3511a1fce1b70ee2401d5d40d2e11e496e",
+ "packages/flow/openadapt_flow/runner/product_release.py": "072ad1a818fd1ccd7bfbe2995ee90825111890dfb4c1bd9b72275350107adab3",
+ "packages/flow/openadapt_flow/runner/protocol.py": "02ab8b7ce4a936d8533cf99a58f68fb5281b2afce2f17b99dbba27b0eeaf7e82",
+ "packages/flow/openadapt_flow/runner/verify.py": "473bab048ac39adfd9020816e81ea969c05856993e4029e17ce9bc9ba237d92c",
+ "packages/flow/openadapt_flow/runtime/__init__.py": "fa78a3356ae6470aaab3c3093c57502ac8aef9b1ecb03ec2f4ccbc2a0c0b9f0b",
+ "packages/flow/openadapt_flow/runtime/actuators/__init__.py": "597b6f56b00bb79c7f3a4452f602d1746aa0acc99bebc1683ce71ceece5af59d",
+ "packages/flow/openadapt_flow/runtime/actuators/api.py": "05fb4e35a9cbb2c85874bdc3d5df1aeaf4f5ba1e011ec0e4ae8b02aaaab78a13",
+ "packages/flow/openadapt_flow/runtime/actuators/web_form.py": "ceab0e7909c601a2e69a18af012d1448830ac4e1999aac540d9afc897fac3808",
+ "packages/flow/openadapt_flow/runtime/admitted_composition.py": "cbe722002872533c37797183d6efd3b42a5e65f95759e0e8d28a5dbc1794ec07",
+ "packages/flow/openadapt_flow/runtime/authorization.py": "c2abcc4dde938c401e6b470d3732a96716f3e251c7895088f80ad7f1a3cbc88f",
+ "packages/flow/openadapt_flow/runtime/composition.py": "cc10476194e0a5f44e9421476317b72b1233f44eeb0bf95196426f9f609e752e",
+ "packages/flow/openadapt_flow/runtime/control_overlay.py": "b141f20afa76036f7ab20ae19d97293f7dc0ee20b0aea2c7d23061dca4bb3aa1",
+ "packages/flow/openadapt_flow/runtime/durable/__init__.py": "32d5846e0775819d84e903485f1c32a14774d2ee3d4f3322335182afd68f8826",
+ "packages/flow/openadapt_flow/runtime/durable/approval.py": "2b3e5eb95ae02d11dfe75d3970cbb65f8b04cf8c7f066ed8b8aa1bba3da034ba",
+ "packages/flow/openadapt_flow/runtime/durable/attended.py": "a5405650f6d1ec6b054ddf2de6725efa4dbed5c0c399a0fab07d33488d84c99f",
+ "packages/flow/openadapt_flow/runtime/durable/attended_service.py": "d621f4785ec37afa9baf1ab18622745cae498eda0f91d903a7e3b8ffd54f2426",
+ "packages/flow/openadapt_flow/runtime/durable/authority.py": "9d10239dbe97ae34476c996f69685d0a2aff5d2f996dde3df38c4e6b73fce39a",
+ "packages/flow/openadapt_flow/runtime/durable/business_decision.py": "dff9bb63163561045318f2416420e9d96c1c69fc6f1f31eaa00e50fc41083e63",
+ "packages/flow/openadapt_flow/runtime/durable/checkpoint.py": "186179fd070087acaa9c5cde3fb64378dd3ec465eea16ed04a26bd5457db9662",
+ "packages/flow/openadapt_flow/runtime/durable/continuation.py": "5eb5319b3b5a1a52c73d6472418aeefbf961fff41743412a9c82afde9df9b542",
+ "packages/flow/openadapt_flow/runtime/durable/controller.py": "80e5c6f25b6171475660055708bdfd37e29f8a52065f56c29e059f212f22da61",
+ "packages/flow/openadapt_flow/runtime/durable/program_checkpoint.py": "1945df32ff1d418c5eac7f9f02fe29297da315d6e07e395cb706312ab1d2cf53",
+ "packages/flow/openadapt_flow/runtime/durable/resume.py": "195d252291db265cbfa9a8ba6cd6a12a0f6bef6f826e2d494ceb245ad41de82c",
+ "packages/flow/openadapt_flow/runtime/effects/__init__.py": "26ee73ae1d836050ff796e5211f649d89a416ba171a9aa7449ff8079795cfd6d",
+ "packages/flow/openadapt_flow/runtime/effects/_common.py": "98c528f40bf94344a951531751fd5c4f382673b76d88bb1c32b35184e3c58eda",
+ "packages/flow/openadapt_flow/runtime/effects/adapter.py": "6b44cda61a78ce3934db28a6b2ce1ccadac5a52a99f8bbc225346f602116b5a4",
+ "packages/flow/openadapt_flow/runtime/effects/auth.py": "af0c2be6ab49f998aaf404800a0f5c8a3a35f30f08dda609cafa8b49ea622f91",
+ "packages/flow/openadapt_flow/runtime/effects/compensation.py": "3e6feb4924e61ffb67802151907218b47c627923362206f5c83aea86a00da3db",
+ "packages/flow/openadapt_flow/runtime/effects/db_snapshot.py": "49da015f0357c4d18f748a292219488915a8f46cf5ffc7d511dbb233b2fcfcb2",
+ "packages/flow/openadapt_flow/runtime/effects/deferred_report.py": "f0e94087724acedad688e46c6a6375b1e6c24aa42abeafb10682eee71d9b9526",
+ "packages/flow/openadapt_flow/runtime/effects/desktop_readback.py": "6d6861ad7d15f17f0c031275006b630cf7dab9210d0c0d3f9910fd1fcb30493a",
+ "packages/flow/openadapt_flow/runtime/effects/desktop_readback_sessions.py": "85cf7364d4aaa4fdc6673610c4ff387e602a349ff5082acda446f048a82fbf92",
+ "packages/flow/openadapt_flow/runtime/effects/document_arrival.py": "1f62bb1c46f0f9521610a152fe68340a96014bc4a8d293d6681ef5099acc1307",
+ "packages/flow/openadapt_flow/runtime/effects/document_hash.py": "5c64f1ffc187cd03114d61dff3518080e59b817f8b1c3424dbc4b57db30e1f04",
+ "packages/flow/openadapt_flow/runtime/effects/effect.py": "57bd51878348da55b0dc8ff4b95ab1019fa85a0c92e979970da03778bd3e471f",
+ "packages/flow/openadapt_flow/runtime/effects/email_delivery.py": "bca21113e2c8fc3f3820fd1c0e27c16f2c5db920ccdd05275477bd08884b6ce2",
+ "packages/flow/openadapt_flow/runtime/effects/fhir.py": "1ab6f6f65170463c57c289dad3a455f81dff5da3e2e71a80785629026d4031bb",
+ "packages/flow/openadapt_flow/runtime/effects/file_arrival.py": "8a5dcb94534e9f3ef40fa820cc18ae73e45f626137f0de856941c3adcfc235e5",
+ "packages/flow/openadapt_flow/runtime/effects/frame.py": "2e5b98bcaa8f5611e9875ed88d7686b3e05100794236f09046cc8052768dded4",
+ "packages/flow/openadapt_flow/runtime/effects/fresh_session.py": "49ad12c9ae70e5191e99c1039743b1c6a9857ea8a523adaf4ad2ad622aaffc3d",
+ "packages/flow/openadapt_flow/runtime/effects/graphql.py": "cebae9844af5046963fdaba3abaed3ed1f9b1084dedd1a8948ac454b64990e26",
+ "packages/flow/openadapt_flow/runtime/effects/late_write.py": "66e97de5eddd1f8094f7cf71f0d7ef49de4f77605c7a42d86b11a5c7c3611e6c",
+ "packages/flow/openadapt_flow/runtime/effects/onscreen.py": "39de63f4ea9a75b45670edd1fd2573a10066dfae890ba9e71ec02fa1c2ab5ec7",
+ "packages/flow/openadapt_flow/runtime/effects/readback_values.py": "447e06cc67ea338fce7a5c2b1bb826bdcce325d874a2e8ec5e48c65374ab932c",
+ "packages/flow/openadapt_flow/runtime/effects/rest.py": "3db9cbda4babee7267bbea4425edec6324d3c0b6643b69eeba241fdfbff8f295",
+ "packages/flow/openadapt_flow/runtime/effects/sealed.py": "d763c49a9e4382c4160e33e0f8e6de2e1c86b59ea9cccd9b41a7328264c6f141",
+ "packages/flow/openadapt_flow/runtime/effects/smart_auth.py": "57dc86cbd4249d528148d6c47a0bb5eec56d9c2e854ede8e0a97a7dbe8cda15d",
+ "packages/flow/openadapt_flow/runtime/effects/sql.py": "42210633b40a3dcc0f9ec6742c10ddb6656db2a1e2c90b9c92281488ab4ad330",
+ "packages/flow/openadapt_flow/runtime/effects/surfaces.py": "5841fc1d7e97dd481964e354df5185136aa8759cd90c94d5ef2e71a21cec423d",
+ "packages/flow/openadapt_flow/runtime/effects/ui_readback.py": "94a7291c95e672d8611949a4d923a26061d5b938a74d706159644b23ce7eb476",
+ "packages/flow/openadapt_flow/runtime/effects/versions.py": "4050203e4bbdcb7e142a581e151d554d0f0be2e022a347e2b07c8becadc7e27d",
+ "packages/flow/openadapt_flow/runtime/grounder.py": "75e90667e536b4fd10612a29fe19b183da72bf8ef08f8939c59e1425b1339e4f",
+ "packages/flow/openadapt_flow/runtime/heal.py": "73567f8f02cadd52137736934618ceef8873b5d09ca0bb8e1d2f2ecb24efd516",
+ "packages/flow/openadapt_flow/runtime/healing/__init__.py": "7f2b58eb0e8d53394d9764066378e228f4dcbd8fd48b143b3497c11167b6ad80",
+ "packages/flow/openadapt_flow/runtime/healing/governance.py": "f3a755d46bbd7eedbe6b0ebc962cc2073714551eee34c7f5f2faf002623d3222",
+ "packages/flow/openadapt_flow/runtime/healing/patch.py": "2a918bfbe9523c7946085581465bc6fae5735ba9d9e46e2a0a04e4a841fdadb7",
+ "packages/flow/openadapt_flow/runtime/healing/perturbation.py": "18159ae5a273b33b90ee677164e44fe794bff4c8cfa96a9d3d0f9f8d12166f18",
+ "packages/flow/openadapt_flow/runtime/healing/pipeline.py": "100adcd9230ffa734c2ad85146c1c4af5e065c5c882ab1a36cc7a4391a516909",
+ "packages/flow/openadapt_flow/runtime/hover_evidence.py": "bafe2cb6ff8ee205a510cca79bf1324a316d0ebc5728e5b9e8581290fcdd0790",
+ "packages/flow/openadapt_flow/runtime/identity.py": "420fa5e0478493da4145517be1cb0ffc9b40cd4b6ead3fae9decb34ec40c11f5",
+ "packages/flow/openadapt_flow/runtime/identity_census.py": "690cd1dc5083b53d18ef5d8d7d768dde12b0c4a87dafe769f7883eff3f903be3",
+ "packages/flow/openadapt_flow/runtime/identity_looks.py": "3a80471cb4b3c71f5d1a6e0be455ad7bff3d05c19a3be278233672b5c4674eaf",
+ "packages/flow/openadapt_flow/runtime/identity_template.py": "3146c491b30325bf2b20526f9e69476e21c2446930709bcd78a6bb5bb5ad26c4",
+ "packages/flow/openadapt_flow/runtime/identity_vlm.py": "be1151e8bdb3cafe428b5dd25579d6c5d7ef7b47c18ff3f9687d56f94a229428",
+ "packages/flow/openadapt_flow/runtime/known_ids.py": "42e719c1f2618431a5a722b50e6d832873f059534e22922fe57f6454c543ead1",
+ "packages/flow/openadapt_flow/runtime/layout_drift.py": "b385273433c782841482c331ceb3e1819d5a9362a1acdbc168d1da395f9ad56a",
+ "packages/flow/openadapt_flow/runtime/list_guard.py": "9471aa4b414fd795a156726758ffbb12998a8d7b40766c005c7475a29db495dd",
+ "packages/flow/openadapt_flow/runtime/list_source.py": "603aa2ba02841f9ab8f7c71911d7288302edac3acbca87bb54046111cc8b158d",
+ "packages/flow/openadapt_flow/runtime/local_grounder.py": "97820b33e69270f07c84873a224a93d5e5cf78c80ee6e0e8fb8e1be4992ee83d",
+ "packages/flow/openadapt_flow/runtime/process_v1.py": "8c4c42640d2051cc84965353af63382101d4ee04d2b11b2b120a9587702ca1b9",
+ "packages/flow/openadapt_flow/runtime/program_predicates.py": "3e76056ee036464a35dcd0a001f167d00b78eb97e73aa2100270dc6ea6563106",
+ "packages/flow/openadapt_flow/runtime/readback_pipeline.py": "8251eb238d5f33efaa561ffac7c8cdbd0d5e02d9f651e31308693b2c65069296",
+ "packages/flow/openadapt_flow/runtime/remote_vlm.py": "cc00a062f99e2f4abe608346fef912da5f2eaed9d90fc2d6a4c4f17debf7fd97",
+ "packages/flow/openadapt_flow/runtime/render_scale.py": "81cf507214e432ac9279bb09398dc20ac187c1d749913afc8586af49accd5638",
+ "packages/flow/openadapt_flow/runtime/replayer.py": "645983f97fcb51f8213b9a9aafa65f1611825b37c13bb7761b1a4a263782b7d6",
+ "packages/flow/openadapt_flow/runtime/resolver.py": "ced3df05eb587ea25e970053314154ac97c22b333e596d5b14f0962d10a7fa23",
+ "packages/flow/openadapt_flow/runtime/speed.py": "3ea92c67afa3766fb0e1aacc34b3d2bcc5fcc1d397a23904cc20d10adab3d088",
+ "packages/flow/openadapt_flow/runtime/step_timing.py": "8d0f0f851eeb4c4c331b52c9376e6527a3e40134f2500204804cc1a9ce269ef8",
+ "packages/flow/openadapt_flow/runtime/surfaces.py": "34e5142a4138cfae191a404950c04d8efe48b7526e8a4dce3b05953f4191cb28",
+ "packages/flow/openadapt_flow/runtime/target_param.py": "43de5d0653b793d90066c6b386c4e64bef87a70a903623480a380a2f87ae7bf3",
+ "packages/flow/openadapt_flow/runtime/variant_router.py": "9012abb40a0c71c0ce04c4b144ab6851d42b3d0d8026d8688e9eb2dda7951e26",
+ "packages/flow/openadapt_flow/runtime/variant_stamp.py": "9bba7d2fa3b81008040cbfdae52311b6c79ac24bb85e3799e3e136c08491809b",
+ "packages/flow/openadapt_flow/runtime/worklist_pool.py": "1b7c81f738dc7997e0ff174052ce98b757b0f6f00bb1ecf0c96fa3df62bd110f",
+ "packages/flow/openadapt_flow/runtime_validation.py": "a5a220f570c5ee5769ac2f21d8d140bb69373d4de2ccc0ebfd08540122883f0e",
+ "packages/flow/openadapt_flow/sanitized_artifact.py": "fcb0a49a2ffe8f4785b4e221bd023c6341846ba4e17d19004f6c59f5461563ac",
+ "packages/flow/openadapt_flow/scaffold_verifier.py": "f95b2a577f5f5ba4c4ad3934f4820282e3c164351ad96917663ade04d247e938",
+ "packages/flow/openadapt_flow/seal_anchor.py": "97d63252915648d78ff81c044397ade698a35d748401279c814956d9fe004713",
+ "packages/flow/openadapt_flow/seal_batch.py": "c93b91fb0401d7fb3810b304c1e99a5817b82c346927c83c96cfd77892d31415",
+ "packages/flow/openadapt_flow/seal_keys.py": "63c80bad5675fd97808fe0093fd1a01b0c9919c3545fd11b30197feb86ad7e71",
+ "packages/flow/openadapt_flow/seal_timestamp.py": "9d39f36b4dd56bdc5f7a0ceb526e9208a790f648e7108a5684fd24670e4f6f66",
+ "packages/flow/openadapt_flow/sealed_set.py": "ade6e8a77cf05a342f355e2aca55f69ef4a5eb2f320ff0f627ad56c9fbef1a72",
+ "packages/flow/openadapt_flow/section_capture.py": "cbb98dd22dc57ad01b887180f9dc47d4af616a5f556eb225d91eddae005d07fa",
+ "packages/flow/openadapt_flow/sections.py": "4001315490d7a921f2ab7d08b47f248ba26facb4dcbc858d79a357cb91fb7c6a",
+ "packages/flow/openadapt_flow/services/__init__.py": "f38b556ba34b1fc674267a2c386edf9beb542d5a98c8e266b70f61ec6a617ba4",
+ "packages/flow/openadapt_flow/services/vlm_service/__init__.py": "da71deb7edc5ea6c30c250faf4cb39b4a76b532801debe6f64598b5d2ed8978e",
+ "packages/flow/openadapt_flow/services/vlm_service/__main__.py": "3844e4479038b670ef897697c71c05bb8e9f92136425ff899137501b3fc60966",
+ "packages/flow/openadapt_flow/services/vlm_service/app.py": "808094e2285b70965cc7f84a2c6037749ef29304318e1986c3dbbf7e4a1ec9c0",
+ "packages/flow/openadapt_flow/services/vlm_service/backends.py": "771df17902dc1c31e44517880706468f0c3dd13ee8dedc161ca60f159e1d9255",
+ "packages/flow/openadapt_flow/services/vlm_service/batching.py": "545ceb328637acbbaf343566059bcd23ba61ae9b385c6d32b14844a08c074971",
+ "packages/flow/openadapt_flow/services/vlm_service/config.py": "0bf363d7be1419ed1dd1597230a2be87d880473e5d19df4a9b8ef5e2f33a1bee",
+ "packages/flow/openadapt_flow/services/vlm_service/prompts.py": "f3af38485a7f61ad96fdaf066387c4809cf34b60cb96147ac186caa828cff1c3",
+ "packages/flow/openadapt_flow/services/vlm_service/schemas.py": "ca2de9068dcdfc45ca2b33a73fe5b51edaef0c27299b901ec5b340aa0143462f",
+ "packages/flow/openadapt_flow/shadow.py": "4b37bc04380ff4d8e40c654bad306b8731cfec8d73fe895f606b3bebd5c31696",
+ "packages/flow/openadapt_flow/shadow_report.py": "ea79a2129bc99189171c418931fdb57fee55fe8a638977cc88dd21733167e428",
+ "packages/flow/openadapt_flow/skills.py": "6a2d779837cc9890f971b34b2f2ebde13d33d05f8dc11e1f1d4f4831a6813660",
+ "packages/flow/openadapt_flow/ssh_sig.py": "095ab479ed182611a416b442a25bbb86c811f1cc671b08e99e631ae8ef157d88",
+ "packages/flow/openadapt_flow/submit_binding.py": "985fe6d313ef281d3360e104cd12c65f72838e1940daebfb6ea40851d4641369",
+ "packages/flow/openadapt_flow/surface_bindings.py": "6b5f02db23ce8ec01bce2eecad6f822d743445547f62a0fe9c6286d50f36d762",
+ "packages/flow/openadapt_flow/surface_selection.py": "150481be4c3509a07e69a5e2a9ec2ebc8d8f48578d16c14f1633feb5a5b613fd",
+ "packages/flow/openadapt_flow/teach_scope.py": "56e709f4ff3740bc58e51f3145bb595894537456d6830dcbb73661ae226a7165",
+ "packages/flow/openadapt_flow/terminal_verification_v2.py": "3bc44d80abc3679cebdeec123b34bcc5656cd2624b1c8943bb22352c0efc3261",
+ "packages/flow/openadapt_flow/transaction.py": "2d1da876951335d06301757d01607d588dac9146e51e55ca212f120542dde179",
+ "packages/flow/openadapt_flow/traversal.py": "4bec0fcd5877649e71f7273a17a2073d56c83af6cb7fcd595d0eb9bd7f7a387b",
+ "packages/flow/openadapt_flow/tutorial.py": "51a21f2bd8aa99ba1d97a3f0a3e8f2cefc856e3c52d8294449b9eabab576c6d8",
+ "packages/flow/openadapt_flow/undo_proposal.py": "e09883af1fd9741ed876c75a3209ef16bae42b99790c4ca0506aac559f5ae7e9",
+ "packages/flow/openadapt_flow/validation/__init__.py": "d7f94f2027a19347364cf9491a94f9e6d8c497cd4a67e555e9d200d406e35e0f",
+ "packages/flow/openadapt_flow/validation/behavioral_generalization.py": "1540c508721eb77fcf1ae5f4b8dc19d88c59e65ec93a71e4ddb88e86878bda3e",
+ "packages/flow/openadapt_flow/validation/dense_surface.py": "c851d7d90704c59eb2bae9bf1c589df44956190989961ef001a60ac7434211f6",
+ "packages/flow/openadapt_flow/validation/governed_run.py": "d7fefab39d409381c338b015b9b44f4c757f6bcff693699eef78d73f1f2a9659",
+ "packages/flow/openadapt_flow/validation/hardening/__init__.py": "f54bdcaf0e0e1c8706e1262d983b7d57dba12e7c3912c50aaec148cc4a6a352a",
+ "packages/flow/openadapt_flow/validation/hardening/__main__.py": "6a2637d07c62e55e6d46dbd277e7c5d499426044120e949532010efe988aeb75",
+ "packages/flow/openadapt_flow/validation/hardening/corpus.py": "927d3f60d1971b82175c6a40a4b45116ba1339e8bb644da5750981e3770e068f",
+ "packages/flow/openadapt_flow/validation/hardening/fixtures.py": "44e85d3c03f03bd46c017a15e46ebff0fee483aed0d76045120e3c43e631318b",
+ "packages/flow/openadapt_flow/validation/hardening/harness.py": "f214c456ded5c2b27eec1fbe1810c5c7d0467960459baecb04c810df4f978e18",
+ "packages/flow/openadapt_flow/validation/hardening/perturbations.py": "fe634c8e6878766beea377bd0c62a6ea681d7ff883ff2896c98941a6f3112583",
+ "packages/flow/openadapt_flow/validation/identity_ladder.py": "4fcb0e3313de20fa3a148d2917aa2b3517d4438561aa140b244b931dc5081880",
+ "packages/flow/openadapt_flow/validation/identity_looks_dense.py": "ae482b821207e4dc5e6ea825f2d4bedf3cd8528dbbf516e732edbaaca6fb57ef",
+ "packages/flow/openadapt_flow/validation/identity_rates.py": "d0648e8e94b96677366ac5372453de797f6221a8aa5c799fe2327674d90c851c",
+ "packages/flow/openadapt_flow/validation/known_ids_dense.py": "9dfcc761b649e83f781e3390077b1c7eea60b4bd16c92e2dae9dd02173192835",
+ "packages/flow/openadapt_flow/validation/pixel_identity_aligned.py": "dff6c6f9d7ae1788f906c42b2cf443e34f93baf3d26d645413b2c84b54933053",
+ "packages/flow/openadapt_flow/validation/pixel_identity_probe.py": "66095f52fe8de431a3ab0cf68ba02202bb459b46927e98d7ae6bcf4c68d7ef49",
+ "packages/flow/openadapt_flow/validation/structural_action.py": "1f231ebe02d241ad34b3d9867be26850748a487fb586f646350192d0487dda49",
+ "packages/flow/openadapt_flow/validation/vlm_identity_probe.py": "f3641e289f0a02e80fcb31ff76c34c0ed150c647fa9954252425db2b7659b713",
+ "packages/flow/openadapt_flow/variants.py": "f28513f0bc42968b608a6f0957bc8c8117572dc7835fb0838f0734015cdf97ac",
+ "packages/flow/openadapt_flow/verification.py": "0bb9f564b4d3dccce7fbebad64abaae1cbd4bd600ffa1b58ec18d9025df52ff2",
+ "packages/flow/openadapt_flow/verifier.py": "5d0dd45d84592772acc96fcd5245b8defb27fd79ffa7bac5420e2fefbd9583cd",
+ "packages/flow/openadapt_flow/verify.py": "26b3e327a1dec09f8c9a968133f090dababb58cf6178be3e89b11101bc9478f7",
+ "packages/flow/openadapt_flow/verify_run.py": "f5f262fd0418e31cc37b9b1a1e9a372655af1e9eef6a68bad6447e8d17a31725",
+ "packages/flow/openadapt_flow/vision/__init__.py": "f41b931a97bf4ac5a8f1f141dc905bec4367bb350e8ccc90446842eb63765bd5",
+ "packages/flow/openadapt_flow/vision/hashing.py": "60d5b56a991100310163007d6778d6bec8521826c3f586f6b88e6e1a76f1d70e",
+ "packages/flow/openadapt_flow/vision/imgops.py": "9cd252bcb3a8bab46795098bc29cd5cf988d77c96abd9687ba93b9252e3f53c9",
+ "packages/flow/openadapt_flow/vision/match.py": "b4d34620ef7aa9f68e922659554c02f51e2c20f9469febd88457d158163d213e",
+ "packages/flow/openadapt_flow/vision/ocr.py": "9a60f5f3c760592a5e7874de1949189c1d2f65028b6fe6f2a927a667b8cd6714",
+ "packages/flow/openadapt_flow/vision/ocr_backends.py": "3b38a83eeeb4a9191ad729c1f8e15ecb239ff7d061239b2fd1c3b65c98e35b26",
+ "packages/flow/openadapt_flow/vision/settle.py": "d81049501c6dc41a4713ddc3d4d8fbc506f4e2320ff7e5ca6a4a769e6a7a18f6",
+ "packages/flow/openadapt_flow/visualize/__init__.py": "8d791c4ae4fff8a56e5860fdd95c42e441ae462eb029cdc268d771eb0ade4c96",
+ "packages/flow/openadapt_flow/visualize/admitted_composition.py": "9758fb49a8d3e587204e3df921a42cf823921cb25f8c66e08cfec748337be8d7",
+ "packages/flow/openadapt_flow/visualize/builder.py": "53749366b83db4a49596cecd41859213ef38bb62f8fd98ed41c3b53dd7ea5211",
+ "packages/flow/openadapt_flow/visualize/composition.py": "52d42000d0747af577a6f4e2af0b4326c22790c3cf7fc2e6ebd05b83baef91d0",
+ "packages/flow/openadapt_flow/visualize/projection.py": "8993aa3c33779eac81490f055e31143f09120d047cadd43e94e226b6dadba9ae",
+ "packages/flow/openadapt_flow/visualize/render.py": "87887e31698e1ffbda8984f5212de5e2743fcd6fd637f5b20643cc8fc5a2c65a",
+ "packages/flow/openadapt_flow/visualize/spec.py": "68db48c9d4ffba499b9901a2016d2e95bf7f78f89af17d521ed47da16381e6d0",
+ "packages/flow/openadapt_flow/volatility.py": "117c9df0dcbeff9669f78b27455c5bc1ada762798c9a64393c30fdab5c29dfa1",
+ "packages/flow/openadapt_flow/wire_check.py": "f3ee4c8c5313b02428129128478c1fd30152f11fa5f77e5592debbceeea2fca7",
+ "packages/flow/openadapt_flow/write_ledger.py": "d4a57b4fdbb22840dce0eda7659b7a4f58ff9f4e4fef2d23a509fd2fd28160f9",
+ "packages/flow/pyproject.toml": "95f434d5e62c07a32afe5f84a17a04e6e7a7fb48bef18c3f0d449ef5e545f739",
+ "packages/flow/uv.lock": "45cc4434d0f1ba6df316b2dff1f08eaf5359ca2a141ec215345480d49833af20",
+ "packages/types/openadapt_types/__init__.py": "8cc924b5be7b9b926263a1bdb9b4d9120af85c805fb2762c877b3a28632e2351",
+ "packages/types/openadapt_types/_compat.py": "b4889a9291687aec404b5b6a83d98c4090f98f9d1aabf270798df0252d998147",
+ "packages/types/openadapt_types/action.py": "0ec10f7e6a840c09a48492abbf501d3ebe807fd06671657ae4f4c62137fba61e",
+ "packages/types/openadapt_types/approval.py": "27ed4f73dcb7c71dca80acd51e8b1087b55c6105c8c1e12c9796e94c98a0f0b9",
+ "packages/types/openadapt_types/authentication.py": "5a9d88de3de6f659e41ad3817abfc40902b3f3bbdcb6d55906a0fc1d83ffd3f1",
+ "packages/types/openadapt_types/authoring.py": "658383bed9a542b0e7ecc9dd451bc7de3e0771646e9da826acbcf5d2e69231b8",
+ "packages/types/openadapt_types/benchmark.py": "23640632a9c95cee35cd664d75aa8aa8ca5585259ead7221aaaff610f469d321",
+ "packages/types/openadapt_types/business_decision.py": "05932e2d37641390e2693520673bf926d5ceba388f8d702d9213582f66b0a3c6",
+ "packages/types/openadapt_types/check_level.py": "c999b800924fbeaf872b829607b453b63be8d5d4207d79733f641d6eac6c4ad0",
+ "packages/types/openadapt_types/clinic_job.py": "4719877cb2a1dee680d74d66a1d2f182bab8f86fbb7d81c3e82baf1bdab79d07",
+ "packages/types/openadapt_types/computer_state.py": "c2063f22364e9012ee852ff36f8a2a13f5015655a0b0d634fcd5755f813dbfa7",
+ "packages/types/openadapt_types/control_overlay.py": "3aa01f89b43e12478c9e2ff1a9e61689397370691d15247ded9dcd5b05242790",
+ "packages/types/openadapt_types/control_overlay_tracking.py": "af8d934f0572c5f4e9c63ba720d4a1d0e73c8cdf3f7b87cc4562c01a8a551755",
+ "packages/types/openadapt_types/episode.py": "5ace88d9e278d099c0e7939cc19e99bf18cbbb80d6ea7d606e3950c027baa8a9",
+ "packages/types/openadapt_types/execute.py": "a577cdd2d2c4e5db235acdb38ee92d15521fcba60267b8835d3bf68d228d346f",
+ "packages/types/openadapt_types/execute_client.py": "ed73a52a1f364646263b25132a2cd60db68deec2b33dfae2b92230402afccb57",
+ "packages/types/openadapt_types/execute_openapi.py": "4600dd2c8995e909c797e2022c22d7745e522123d28627d61e3dab9e7bf405c9",
+ "packages/types/openadapt_types/execution_requirements.py": "58a3fdb2a43b06af0f27b01abd812ccef6b226b6cfa5307f0b6ceff5f197fba2",
+ "packages/types/openadapt_types/failure.py": "26efb6e04d17c10cae8bbd688249ee44bcd7844a62be6736de984a6e881fa0bf",
+ "packages/types/openadapt_types/human_decision.py": "0bb39a3575f511e10d01d92858b340982adee2f0fc20d2409441dbc0b2c55c4f",
+ "packages/types/openadapt_types/oracle.py": "47a3060d5a49529d4f6506fc3116a0bf902e8b30431456154604ce8371195cde",
+ "packages/types/openadapt_types/parsing.py": "aae2ceaeead749c3b67619a271b87ecf2388496d37d5bf524834a884ff87a720",
+ "packages/types/openadapt_types/plain_results.py": "a1fc8b54434af25314e179fbd2670c60f9e52a2a08a4757c8b16d281cbc68951",
+ "packages/types/openadapt_types/process_capability.py": "8fa70ad62c586534884a73290710c9706291160d63397cb5543de1f2646114d9",
+ "packages/types/openadapt_types/production_lifecycle.py": "046f30559dac66e4105ad830a274cfb31e0374f95a7a8b0adc1b7dff2aba9449",
+ "packages/types/openadapt_types/reward.py": "17376a9797ab7136d54285c0ecb9f87792a64b7b0ea9cbd2d802896e5b0ecf6f",
+ "packages/types/openadapt_types/runner_capability.py": "26fd3c1d96a5558c70886cf203c999d524b9bf927cde23d90735c90be9e2b427",
+ "packages/types/openadapt_types/schemas/__init__.py": "965365ce3faee699154d06428c2dd83414c18632ca3ba39516ef513523b8d618",
+ "packages/types/openadapt_types/seal.py": "bf4ac2e28b561b3ed80b3e1da2bb5cb0eb005a0cdc151dcf805fd02157bf5143",
+ "packages/types/openadapt_types/vocabulary/__init__.py": "b5f060d92bea3c0d8b1c15468c1564c3cf5ee864ee4bddf2393debca8f269bb4",
+ "packages/types/openadapt_types/vocabulary/__main__.py": "0d132037f99fe1d1588a9233ed179df7de0dcbf2d36ffb0fec294c98bd1d7acf",
+ "packages/types/openadapt_types/vocabulary/lint.py": "ee2a8c6279aa3c737fa2f49e09092c7f652dedaef513e59baf63dd19ba661060",
+ "packages/types/pyproject.toml": "4904ddc18342be5bf7da91f315d1bed91e60b35dc55d1aa3bdfb149af13415c6"
+ }
+}
diff --git a/packages/flow/tests/fixtures/bundle_compatibility/2.6.0/linear/canonical.json b/packages/flow/tests/fixtures/bundle_compatibility/2.6.0/linear/canonical.json
new file mode 100644
index 0000000000..4bc7b3c700
--- /dev/null
+++ b/packages/flow/tests/fixtures/bundle_compatibility/2.6.0/linear/canonical.json
@@ -0,0 +1 @@
+{"files":{"templates/button.png":"fa53ee8e6f7730a17a6b8ea30ebab860d2811526204fcf2c76946850b582b493"},"workflow":{"contains_phi":false,"created_at":"2026-01-02T03:04:05+00:00","data_sources":{},"encrypted":false,"name":"release-compatibility","param_specs":{},"params":{},"phi_scrubbed":false,"program":null,"recording_id":null,"schema_version":2,"secret_params":[],"steps":[{"action":"click","anchor":{"click_point":[80,70],"context_text":null,"identifier_crop":null,"identifier_region":null,"identity_template":null,"landmarks":[],"ocr_text":"Apply","region":[40,50,80,40],"search_pad":80,"structural":{"automation_id":null,"name":null,"role":null,"selector":"#apply","window_name":null},"structured_identity":null,"template":"templates/button.png"},"api_binding":null,"effects":[],"expect":[],"guard":null,"id":"apply","identifier_crop_missing_reason":null,"identity_armed":null,"identity_unarmed_reason":null,"intent":"apply synthetic change","key":null,"param":null,"risk":"reversible","scroll_dx":null,"scroll_dy":null,"secret":false,"text":null,"timeout_s":10.0,"wait_until":null}],"subflows":{},"viewport":[320,200]}}
\ No newline at end of file
diff --git a/packages/flow/tests/fixtures/bundle_compatibility/2.6.0/linear/manifest.json b/packages/flow/tests/fixtures/bundle_compatibility/2.6.0/linear/manifest.json
new file mode 100644
index 0000000000..208fac00f3
--- /dev/null
+++ b/packages/flow/tests/fixtures/bundle_compatibility/2.6.0/linear/manifest.json
@@ -0,0 +1,22 @@
+{
+ "schema_version": 2,
+ "content_digest": "f44b31062baf7e119b04bea142ad87120568cf5c9f94712a0c3e137a123edf7b",
+ "file_hashes": {
+ "templates/button.png": "fa53ee8e6f7730a17a6b8ea30ebab860d2811526204fcf2c76946850b582b493"
+ },
+ "provenance": {
+ "compiler_version": "2.6.0",
+ "source_recording_sha256": null,
+ "compiler_config_sha256": null,
+ "created_at": "2026-01-02T03:04:05+00:00",
+ "policy_name": null,
+ "certified": false,
+ "certification_status": null,
+ "certified_at": null,
+ "expires_at": null,
+ "certification_invalidated_at": null,
+ "certification_invalidation_reason": null,
+ "governed_authorization_template": null
+ },
+ "encrypted": false
+}
\ No newline at end of file
diff --git a/packages/flow/tests/fixtures/bundle_compatibility/2.6.0/linear/templates/button.png b/packages/flow/tests/fixtures/bundle_compatibility/2.6.0/linear/templates/button.png
new file mode 100644
index 0000000000..797e0782c9
Binary files /dev/null and b/packages/flow/tests/fixtures/bundle_compatibility/2.6.0/linear/templates/button.png differ
diff --git a/packages/flow/tests/fixtures/bundle_compatibility/2.6.0/linear/workflow.json b/packages/flow/tests/fixtures/bundle_compatibility/2.6.0/linear/workflow.json
new file mode 100644
index 0000000000..5a5aad4b5c
--- /dev/null
+++ b/packages/flow/tests/fixtures/bundle_compatibility/2.6.0/linear/workflow.json
@@ -0,0 +1,112 @@
+{
+ "schema_version": 2,
+ "name": "release-compatibility",
+ "recording_id": null,
+ "contains_phi": false,
+ "phi_scrubbed": false,
+ "encrypted": false,
+ "created_at": "2026-01-02T03:04:05+00:00",
+ "viewport": [
+ 320,
+ 200
+ ],
+ "params": {},
+ "param_specs": {},
+ "secret_params": [],
+ "steps": [
+ {
+ "id": "apply",
+ "intent": "apply synthetic change",
+ "action": "click",
+ "anchor": {
+ "template": "templates/button.png",
+ "structural": {
+ "selector": "#apply",
+ "frame_path": null,
+ "role": null,
+ "name": null,
+ "automation_id": null,
+ "window_name": null
+ },
+ "region": [
+ 40,
+ 50,
+ 80,
+ 40
+ ],
+ "click_point": [
+ 80,
+ 70
+ ],
+ "ocr_text": "Apply",
+ "context_text": null,
+ "structured_identity": null,
+ "identity_template": null,
+ "identifier_crop": null,
+ "identifier_region": null,
+ "form_identity": null,
+ "landmarks": [],
+ "search_pad": 80
+ },
+ "text": null,
+ "param": null,
+ "secret": false,
+ "field_label": null,
+ "selection_commit_key": null,
+ "selection_region": null,
+ "key": null,
+ "modifiers": [],
+ "drag_end_anchor": null,
+ "scroll_dx": null,
+ "scroll_dy": null,
+ "expect": [],
+ "effects": [],
+ "api_binding": null,
+ "risk": "reversible",
+ "risk_explanation": null,
+ "risk_review_required": false,
+ "wait_until": null,
+ "guard": null,
+ "read": null,
+ "read_gate": null,
+ "surface": null,
+ "opens": [],
+ "surface_origin": null,
+ "closes_surface": false,
+ "dialog": null,
+ "timeout_s": 10.0,
+ "identity_armed": null,
+ "identity_unarmed_reason": null,
+ "identifier_crop_missing_reason": null,
+ "hover": null,
+ "submit_binding": null,
+ "submit_binding_unbound_reason": null
+ }
+ ],
+ "interstitials": [],
+ "program": null,
+ "subflows": {},
+ "data_sources": {},
+ "manifest": {
+ "schema_version": 2,
+ "content_digest": "f44b31062baf7e119b04bea142ad87120568cf5c9f94712a0c3e137a123edf7b",
+ "file_hashes": {
+ "templates/button.png": "fa53ee8e6f7730a17a6b8ea30ebab860d2811526204fcf2c76946850b582b493"
+ },
+ "provenance": {
+ "compiler_version": "2.6.0",
+ "source_recording_sha256": null,
+ "compiler_config_sha256": null,
+ "created_at": "2026-01-02T03:04:05+00:00",
+ "policy_name": null,
+ "certified": false,
+ "certification_status": null,
+ "certified_at": null,
+ "expires_at": null,
+ "certification_invalidated_at": null,
+ "certification_invalidation_reason": null,
+ "governed_authorization_template": null
+ },
+ "encrypted": false
+ }
+}
\ No newline at end of file
diff --git a/packages/flow/tests/fixtures/bundle_compatibility/2.6.0/program/canonical.json b/packages/flow/tests/fixtures/bundle_compatibility/2.6.0/program/canonical.json
new file mode 100644
index 0000000000..0ee4c36a3b
--- /dev/null
+++ b/packages/flow/tests/fixtures/bundle_compatibility/2.6.0/program/canonical.json
@@ -0,0 +1 @@
+{"files":{"templates/button.png":"fa53ee8e6f7730a17a6b8ea30ebab860d2811526204fcf2c76946850b582b493"},"workflow":{"contains_phi":false,"created_at":"2026-01-02T03:04:05+00:00","data_sources":{},"encrypted":false,"name":"release-compatibility","param_specs":{},"params":{},"phi_scrubbed":false,"program":{"entry":"apply","states":{"apply":{"id":"apply","kind":"action","loop":null,"on_exception":null,"outcome":null,"reason":"","step":{"action":"click","anchor":{"click_point":[80,70],"context_text":null,"identifier_crop":null,"identifier_region":null,"identity_template":null,"landmarks":[],"ocr_text":"Apply","region":[40,50,80,40],"search_pad":80,"structural":{"automation_id":null,"name":null,"role":null,"selector":"#apply","window_name":null},"structured_identity":null,"template":"templates/button.png"},"api_binding":null,"effects":[],"expect":[],"guard":null,"id":"apply","identifier_crop_missing_reason":null,"identity_armed":null,"identity_unarmed_reason":null,"intent":"apply synthetic change","key":null,"param":null,"risk":"reversible","scroll_dx":null,"scroll_dy":null,"secret":false,"text":null,"timeout_s":10.0,"wait_until":null},"subflow":null,"transitions":[{"guard":null,"label":"","target":"done"}]},"done":{"id":"done","kind":"terminal","loop":null,"on_exception":null,"outcome":"success","reason":"","step":null,"subflow":null,"transitions":[]}}},"recording_id":null,"schema_version":2,"secret_params":[],"steps":[],"subflows":{},"viewport":[320,200]}}
\ No newline at end of file
diff --git a/packages/flow/tests/fixtures/bundle_compatibility/2.6.0/program/manifest.json b/packages/flow/tests/fixtures/bundle_compatibility/2.6.0/program/manifest.json
new file mode 100644
index 0000000000..db82032f59
--- /dev/null
+++ b/packages/flow/tests/fixtures/bundle_compatibility/2.6.0/program/manifest.json
@@ -0,0 +1,22 @@
+{
+ "schema_version": 2,
+ "content_digest": "7694ed3afd395c21a26e3fbe1b675aa1770b3dc9e2937843f84d48e935b686e2",
+ "file_hashes": {
+ "templates/button.png": "fa53ee8e6f7730a17a6b8ea30ebab860d2811526204fcf2c76946850b582b493"
+ },
+ "provenance": {
+ "compiler_version": "2.6.0",
+ "source_recording_sha256": null,
+ "compiler_config_sha256": null,
+ "created_at": "2026-01-02T03:04:05+00:00",
+ "policy_name": null,
+ "certified": false,
+ "certification_status": null,
+ "certified_at": null,
+ "expires_at": null,
+ "certification_invalidated_at": null,
+ "certification_invalidation_reason": null,
+ "governed_authorization_template": null
+ },
+ "encrypted": false
+}
\ No newline at end of file
diff --git a/packages/flow/tests/fixtures/bundle_compatibility/2.6.0/program/templates/button.png b/packages/flow/tests/fixtures/bundle_compatibility/2.6.0/program/templates/button.png
new file mode 100644
index 0000000000..797e0782c9
Binary files /dev/null and b/packages/flow/tests/fixtures/bundle_compatibility/2.6.0/program/templates/button.png differ
diff --git a/packages/flow/tests/fixtures/bundle_compatibility/2.6.0/program/workflow.json b/packages/flow/tests/fixtures/bundle_compatibility/2.6.0/program/workflow.json
new file mode 100644
index 0000000000..6f9eb3feb4
--- /dev/null
+++ b/packages/flow/tests/fixtures/bundle_compatibility/2.6.0/program/workflow.json
@@ -0,0 +1,142 @@
+{
+ "schema_version": 2,
+ "name": "release-compatibility",
+ "recording_id": null,
+ "contains_phi": false,
+ "phi_scrubbed": false,
+ "encrypted": false,
+ "created_at": "2026-01-02T03:04:05+00:00",
+ "viewport": [
+ 320,
+ 200
+ ],
+ "params": {},
+ "param_specs": {},
+ "secret_params": [],
+ "steps": [],
+ "interstitials": [],
+ "program": {
+ "entry": "apply",
+ "states": {
+ "apply": {
+ "id": "apply",
+ "kind": "action",
+ "step": {
+ "id": "apply",
+ "intent": "apply synthetic change",
+ "action": "click",
+ "anchor": {
+ "template": "templates/button.png",
+ "structural": {
+ "selector": "#apply",
+ "frame_path": null,
+ "role": null,
+ "name": null,
+ "automation_id": null,
+ "window_name": null
+ },
+ "region": [
+ 40,
+ 50,
+ 80,
+ 40
+ ],
+ "click_point": [
+ 80,
+ 70
+ ],
+ "ocr_text": "Apply",
+ "context_text": null,
+ "structured_identity": null,
+ "identity_template": null,
+ "identifier_crop": null,
+ "identifier_region": null,
+ "form_identity": null,
+ "landmarks": [],
+ "search_pad": 80
+ },
+ "text": null,
+ "param": null,
+ "secret": false,
+ "field_label": null,
+ "selection_commit_key": null,
+ "selection_region": null,
+ "key": null,
+ "modifiers": [],
+ "drag_end_anchor": null,
+ "scroll_dx": null,
+ "scroll_dy": null,
+ "expect": [],
+ "effects": [],
+ "api_binding": null,
+ "risk": "reversible",
+ "risk_explanation": null,
+ "risk_review_required": false,
+ "wait_until": null,
+ "guard": null,
+ "read": null,
+ "read_gate": null,
+ "surface": null,
+ "opens": [],
+ "surface_origin": null,
+ "closes_surface": false,
+ "dialog": null,
+ "timeout_s": 10.0,
+ "identity_armed": null,
+ "identity_unarmed_reason": null,
+ "identifier_crop_missing_reason": null,
+ "hover": null,
+ "submit_binding": null,
+ "submit_binding_unbound_reason": null
+ },
+ "loop": null,
+ "subflow": null,
+ "transitions": [
+ {
+ "guard": null,
+ "target": "done",
+ "label": ""
+ }
+ ],
+ "on_exception": null,
+ "outcome": null,
+ "reason": ""
+ },
+ "done": {
+ "id": "done",
+ "kind": "terminal",
+ "step": null,
+ "loop": null,
+ "subflow": null,
+ "transitions": [],
+ "on_exception": null,
+ "outcome": "success",
+ "reason": ""
+ }
+ }
+ },
+ "subflows": {},
+ "data_sources": {},
+ "manifest": {
+ "schema_version": 2,
+ "content_digest": "7694ed3afd395c21a26e3fbe1b675aa1770b3dc9e2937843f84d48e935b686e2",
+ "file_hashes": {
+ "templates/button.png": "fa53ee8e6f7730a17a6b8ea30ebab860d2811526204fcf2c76946850b582b493"
+ },
+ "provenance": {
+ "compiler_version": "2.6.0",
+ "source_recording_sha256": null,
+ "compiler_config_sha256": null,
+ "created_at": "2026-01-02T03:04:05+00:00",
+ "policy_name": null,
+ "certified": false,
+ "certification_status": null,
+ "certified_at": null,
+ "expires_at": null,
+ "certification_invalidated_at": null,
+ "certification_invalidation_reason": null,
+ "governed_authorization_template": null
+ },
+ "encrypted": false
+ }
+}
\ No newline at end of file
diff --git a/packages/flow/tests/fixtures/bundle_compatibility/2.6.0/provenance.json b/packages/flow/tests/fixtures/bundle_compatibility/2.6.0/provenance.json
new file mode 100644
index 0000000000..2aa9d0cd12
--- /dev/null
+++ b/packages/flow/tests/fixtures/bundle_compatibility/2.6.0/provenance.json
@@ -0,0 +1,660 @@
+{
+ "bundles": [
+ {
+ "content_digest": "f44b31062baf7e119b04bea142ad87120568cf5c9f94712a0c3e137a123edf7b",
+ "files": {
+ "canonical.json": "f44b31062baf7e119b04bea142ad87120568cf5c9f94712a0c3e137a123edf7b",
+ "manifest.json": "0607eb43b30f75aa4c2cc818bd393cb31fe888b0fef486b407af144aa5f532f7",
+ "templates/button.png": "fa53ee8e6f7730a17a6b8ea30ebab860d2811526204fcf2c76946850b582b493",
+ "workflow.json": "e6dd7f1136bb635dd1722561f4bdba27d4e525d9fd87a43c9e8e25e280e59e79"
+ },
+ "shape": "linear"
+ },
+ {
+ "content_digest": "7694ed3afd395c21a26e3fbe1b675aa1770b3dc9e2937843f84d48e935b686e2",
+ "files": {
+ "canonical.json": "7694ed3afd395c21a26e3fbe1b675aa1770b3dc9e2937843f84d48e935b686e2",
+ "manifest.json": "888a65a3ec8852537794a80beb82aa86222ecdb02a6ddc0869571da567489ec4",
+ "templates/button.png": "fa53ee8e6f7730a17a6b8ea30ebab860d2811526204fcf2c76946850b582b493",
+ "workflow.json": "95372f2287548b78c018de503e6fc6a3c188abf13e452de2bfdf1fa432ac81e8"
+ },
+ "shape": "program"
+ }
+ ],
+ "commit": "1c832365d11e9dbe2a166485b13f7b8effd6d8d0",
+ "generator_sha256": "d995443471ee4a6fd6854e53a15da4d3681c798a5af9ffde7d3506d8c5015e28",
+ "original_release_load_verified": true,
+ "pydantic": "2.13.4",
+ "python": "3.12.16",
+ "release": "2.6.0",
+ "source_hashes": {
+ "packages/flow/openadapt_flow/__init__.py": "4861ba1a0e969d169fe649ef20dd8bd56a2a5815ac1c15444ecd57ec5b2a4e65",
+ "packages/flow/openadapt_flow/__main__.py": "e8be5ac631fbf313bb7088cb3fde43694cf0fbefc85a0760eda2fd2446abe007",
+ "packages/flow/openadapt_flow/_browser_setup.py": "d259bd323de12fa03b4bf529d77ccb6350d50f665309c377e6df182525c37e6f",
+ "packages/flow/openadapt_flow/_prewarm.py": "4024f33b41a2fac44b995dfc85a922366b98c18697f6a2b623cb26d72264ed48",
+ "packages/flow/openadapt_flow/_windows_directory.py": "8c65c3ec7a3482a8ca600b81b6340014a0d181d6fdcfdbedd91ab34acd7544bc",
+ "packages/flow/openadapt_flow/action_evidence.py": "72e32ee09d2adb1d71e585aeaeb24277257a76915e7b98f753db2874e3624b52",
+ "packages/flow/openadapt_flow/adapters/__init__.py": "2eca3615b0a12e39a4a51fd7bf2c274785014c548e609597029ef7d8299c9a09",
+ "packages/flow/openadapt_flow/adapters/capture.py": "8a2c0af76e13cc968015852296d32b0621cb626823a69c6011abcd7391072825",
+ "packages/flow/openadapt_flow/adapters/desktop_recorder.py": "7f05b9bf03bc1da900d0acceae4cd4ae0a82efc4a3b9ef011c6649e1044b3454",
+ "packages/flow/openadapt_flow/admit_pipeline.py": "81014276a1749064b07959ac4cbd2ce35361d8f82d881a35fafcb7c852a49fd4",
+ "packages/flow/openadapt_flow/admitted_composition.py": "e52d45e89fccde58bc345ea420afec1b7f334239b957a0e73b257d0094596803",
+ "packages/flow/openadapt_flow/after_stop.py": "6395400f6a578d0013fe284141b6778c0d77321cc16918c7bf42ae2a36153de2",
+ "packages/flow/openadapt_flow/agent/__init__.py": "a08c79b09e45150bd065c5008a2585081ac6c10a1d9c4489dad01718fbb94973",
+ "packages/flow/openadapt_flow/agent/__main__.py": "5780b9a3b365c96d71fa42a6ea977a1518d711ed5c4b4f37b54b16ffbc9d0419",
+ "packages/flow/openadapt_flow/agent/admission.py": "2fc9add3c7dc983d49e583d920dd145a95b5152c01e6215bc6dee6a2fd5dcf3e",
+ "packages/flow/openadapt_flow/agent/approval.py": "a345a90e0e3fa788b520fd26150971a0a5aaff16173a663541f92845ecf409d7",
+ "packages/flow/openadapt_flow/agent/attended.py": "5fa4c761de375be9ce0f6cf7f72f0230253ccd7546658382a267da2f01cb0f1b",
+ "packages/flow/openadapt_flow/agent/authoring.py": "87afc6deb8fd2ed6a1e670c37978648fd633deea8c380b0ca937b369bbb452af",
+ "packages/flow/openadapt_flow/agent/bridge.py": "8675f0c4df081f7573e6df6aa6d943be72103cb8669ab7bae4611560f21d1f79",
+ "packages/flow/openadapt_flow/agent/browser_teach.py": "ecd9bcd0e2d0c1b7b5c454327d6fc89e24dfde87eb0839ee8f2412b33d3b0350",
+ "packages/flow/openadapt_flow/agent/bundles.py": "a3e2d63576adc99fd8e4d53e0fa64f1bec914a070d5c0151ba9278ea923809c9",
+ "packages/flow/openadapt_flow/agent/cards.py": "45ecfb3da287aeb5de1160d1adbcc3590c6cc8c20f7b1b7ab983f643228f62b5",
+ "packages/flow/openadapt_flow/agent/cli.py": "861da55c75558c4636e66dc748125e7a374b1f141f3002b90941b2dd10d057cd",
+ "packages/flow/openadapt_flow/agent/contract.py": "4a265a3a961578dcd4cd5e26be85d6eb0799ac4f557924a36b00e17ffdc39c67",
+ "packages/flow/openadapt_flow/agent/copy.py": "9afe666441689375fcb5aaf54632db2e39e0a32edeb95570789f0d7ce4b55423",
+ "packages/flow/openadapt_flow/agent/delegated.py": "49414a62704b93999fcf668db4df737121f4b5d9d22f1b36a94de705d171371e",
+ "packages/flow/openadapt_flow/agent/example_app.py": "847ba77d93cc438e7e54143f5e7686d53733499154e2cde979e20e5f4b871f7e",
+ "packages/flow/openadapt_flow/agent/flow_service.py": "b5bb10bf1cb819bb0aba9185de9e9d1246a823ff343996a7464d8e481785f2dd",
+ "packages/flow/openadapt_flow/agent/guard_tools.py": "6c61c36f77ed394797d07466a430387bbe8e9a383877833d769514b13d7dd843",
+ "packages/flow/openadapt_flow/agent/ledger.py": "e0911cb91a52570a8244ae4e72c9985c0110f30eeacf3d1a19a1c394e2938a8b",
+ "packages/flow/openadapt_flow/agent/mailbox.py": "c5c8c9a305ddbe8caa985066e0c6f587df4d3703f3d67c7e6643076ab2a709fc",
+ "packages/flow/openadapt_flow/agent/mcp.py": "780409af40aa212e12997c75d41f6873d17583c70e2b13585344675340032296",
+ "packages/flow/openadapt_flow/agent/mcpb_entry.py": "23db9f1b3af8bed52ee472b36b0272430d11526f045179602724addc92a22ac8",
+ "packages/flow/openadapt_flow/agent/repair.py": "235045291bbcf525d19ee2d186b0d61e0f505e2097721361ffe54466604e970a",
+ "packages/flow/openadapt_flow/agent/runner.py": "a8c30b966efe0532cd9f114b5f5773eac6107d2785df98cd7562d200343d8378",
+ "packages/flow/openadapt_flow/agent/runner_bind.py": "91d4006e99378c61af2eb50fc9c03ebfb477cdf9f0d27fa070ee9936fb073e96",
+ "packages/flow/openadapt_flow/agent/runs.py": "abd7041cd1eae1b6017c208e0cf4b083caf965cd2147d0497e896a013cd5cb25",
+ "packages/flow/openadapt_flow/agent/sandbox.py": "ee78c7959d8213dbd3d4b75eb64ecb2a797147410f90516eef57e6c2bb9edb01",
+ "packages/flow/openadapt_flow/agent/seal.py": "ea0585e2564f23a59ccc41763b58357a176e53363f3107ab7b54639d902de439",
+ "packages/flow/openadapt_flow/agent/seal_cli.py": "fcae30891db50c28e6a23282ff94a0dce9796c15c7fea46b8fdc34694ff8acc1",
+ "packages/flow/openadapt_flow/agent/service.py": "275da34a73890b0c85fb5c06965403162adcacfc499a7493736aab236b5538ac",
+ "packages/flow/openadapt_flow/agent/skill.py": "7f1637d4bcfdb54ff5920b06dd3bbf913e6fdbc0030605b455e9223672ad2173",
+ "packages/flow/openadapt_flow/agent/teach.py": "1b7523c08d05ca72ee18c349f0bdf3e2eccd0cc1f060335a6ca989b18cca3d6c",
+ "packages/flow/openadapt_flow/agent/tutorial.py": "ac42a64169cb23fac79943a0ef8e4678922d120d51aa97944e2be707addb3232",
+ "packages/flow/openadapt_flow/agent/verify_tools.py": "2cb850a7368d517335639c00377130625e7a3d3f8381a2fb4d9bb770e562d657",
+ "packages/flow/openadapt_flow/agent_guard/__init__.py": "e1f1ec33d219e845e1de18b61752fe06fff4ba1e12d403870b58d4ef5094c1fa",
+ "packages/flow/openadapt_flow/agent_guard/cdp.py": "e0a59d4f49dee5a9b0e8b6d3c16db794c923a5b4c8af4fa1418e8da13478d8ca",
+ "packages/flow/openadapt_flow/agent_guard/cli.py": "e4792c7ce115eeace17871dd5c8cee569a6b9e7a5365acc53d82946677cddd9b",
+ "packages/flow/openadapt_flow/agent_guard/commit_guard.py": "bcf7cc8d91ce7ab804745766ee4b838b648095364467f2a203f78864ba09090c",
+ "packages/flow/openadapt_flow/agent_guard/config.py": "b25c4e327836f3d2c9167d421eb85d72fbca5c7e8bf7f31de25da3625470caf1",
+ "packages/flow/openadapt_flow/agent_guard/handoff.py": "7f84e49d42717d304f60257a429b36305c4a32cb7e14566185d4789634283ff5",
+ "packages/flow/openadapt_flow/agent_guard/requests.py": "92e42c8462ff7a6effc0e7437dd01ace72f02e04c3072ae29495902787cd0d26",
+ "packages/flow/openadapt_flow/agent_guard/session.py": "9a419ef69572516f5da12efe0d07b72e8effe15634fe1d57635b257abd28a8b4",
+ "packages/flow/openadapt_flow/anthropic_defaults.py": "46ae2109269142f49be399c719347f84794c9e1ce7fe176d647d0485b9750579",
+ "packages/flow/openadapt_flow/api.py": "7a34b5b4a7d5b3b815c4008d9d3efab1badddb77dac7477e17308602d1e532b1",
+ "packages/flow/openadapt_flow/app_profiles/__init__.py": "8fb0cd9f3f5cd6a7003a0cb5cc009314f45b45e2aba085f8698c0a906ffd52c3",
+ "packages/flow/openadapt_flow/approval_mode/__init__.py": "7d802c15089999853ed4a0b55bdaa1962998f2b8e9ee0170695c7de2ec5c3e10",
+ "packages/flow/openadapt_flow/approval_mode/approver.py": "2e314d0ae6432f81972cdc84a8db1635161a6d17dd8fe0e9cb656fd254db7197",
+ "packages/flow/openadapt_flow/approval_mode/approver_roster.py": "85fb6593d6fb418d8ccb180207cab84d20cfdee59326a8df22a90c0c5c442aef",
+ "packages/flow/openadapt_flow/approval_mode/coverage.py": "1e5875a9d2d2d87791dcc27af30617c8cf6ed1d8a559f733e5fb634898604b91",
+ "packages/flow/openadapt_flow/approval_mode/demo_approver.py": "463281495181c3f97969517391a6912a4464a9431ef7c4fd49ba451f61155b80",
+ "packages/flow/openadapt_flow/approval_mode/durable_carry.py": "0f0c5c204fe6cfabef54bd988a3050b58ed6a0a13b178c2615cbeafc2fb7b7d8",
+ "packages/flow/openadapt_flow/approval_mode/form_state.py": "f2548b7f2527e9d648623fc5bafa841feabe8272d6a5822e23d4c937e910ae53",
+ "packages/flow/openadapt_flow/approval_mode/gate.py": "f1e35292d0ca73d7273ade289d5cc838580ecb643e13c9a454c3ebf2a346a20c",
+ "packages/flow/openadapt_flow/approval_mode/human_attestation.py": "eca372e1fa68d9a626ac80046dbf6ab401e97b08a185bd162b278003505883f3",
+ "packages/flow/openadapt_flow/approval_mode/item_approval.py": "5e452cbeb32a98963c553bbd0e96153ea2690d3294abf70ffedb4eafb79571ab",
+ "packages/flow/openadapt_flow/approval_mode/model.py": "42f121b2a7fc992bc1201ccb8c587d7134fec6fdbc54eb12dacd71ff4a00774a",
+ "packages/flow/openadapt_flow/approval_mode/post.py": "91134523827840f5d4de7652513b4a70a906abf64ddda9c367b9fb814045a006",
+ "packages/flow/openadapt_flow/approval_mode/requirements.py": "4f8ba1eff008e45651365929bbbaee873301d993c714168e78456009b06b402b",
+ "packages/flow/openadapt_flow/approval_mode/signed_policy.py": "4dc065c007d6c3112de2af004e36ecd8559ceac8a76eaf9853c1d49f7363c757",
+ "packages/flow/openadapt_flow/approval_mode/switch.py": "2fa2cc31eef6b27e490897eb7997f8679e843cb86508f41b72cc8b5fbe67cbf8",
+ "packages/flow/openadapt_flow/artifacts.py": "15acc61097ac814d1de0320a0a11db7d03da89ee70d68eac1cbd59aed63e3ac0",
+ "packages/flow/openadapt_flow/assurance.py": "fba477ecf901039ebefb8d2d9be340accf9bcfa96314a243febc35157ba48fd5",
+ "packages/flow/openadapt_flow/at_rest.py": "6a8a43e959fd44a90c813fd2727e3c8d23706f8536f9b4f2567f49f7487d32bc",
+ "packages/flow/openadapt_flow/attest_bridge.py": "449502e879bc629b851087b86353a0dbd5761508daec92989083f30fdad14fee",
+ "packages/flow/openadapt_flow/authoring.py": "ce9f98d8e5e7a294b53d761014569e6531ec857f1c4b33eba8121de66a567d5b",
+ "packages/flow/openadapt_flow/authorization_summary.py": "1057cfc2a597b02bd230654c1df030b3680ce8b6300619b145fcf0e994be866f",
+ "packages/flow/openadapt_flow/backend.py": "71e7fdc2cf1d7f8555f9f2182d36957d8d7d0a9cf133e5bc8774a4e19550ee77",
+ "packages/flow/openadapt_flow/backends/__init__.py": "c76aa599a2ea0205a3fffb4a33124dbe6637e4b93f0f14d4c604ffa05c2a1869",
+ "packages/flow/openadapt_flow/backends/_browser_process.py": "1f90beb147f32ddc276884c3e6488e3e533a5bb374ccf675fadc16754cb4e137",
+ "packages/flow/openadapt_flow/backends/_page_quiescence.py": "2a8b70efd7f6b006fa8141b02a7e59fe5733e7552eeacfc7e34326c0dde147c0",
+ "packages/flow/openadapt_flow/backends/_server_responses.py": "d20bfd20078304288462c56c17e1348707df9b3dc56388e292822405776900bb",
+ "packages/flow/openadapt_flow/backends/citrix_workspace.py": "2bc912cfecac2d7d1c4c543cda17a2cbe4b25af195fd8a1d015f6b02661e9665",
+ "packages/flow/openadapt_flow/backends/factory.py": "0702f58a5c3ac8b00c110f2064d59a2c31469839023a6a12dc70510f18bb26f6",
+ "packages/flow/openadapt_flow/backends/linux_backend.py": "bad95c06151d66ed66833a00384a032749de5b1ccd9e581ce6ddbd3d5075bd4b",
+ "packages/flow/openadapt_flow/backends/macos_backend.py": "4ecaab0930039fbd2b2dcba320974eb17bda337e9c0b9324789eab25912cbbc7",
+ "packages/flow/openadapt_flow/backends/parallels_vm.py": "e724f9ec49210e5220d1cc508ab8a1ef984ac43854535b90548b209985109d0c",
+ "packages/flow/openadapt_flow/backends/playwright_backend.py": "17dfa88e10dc873a5a2d9b1a0d72360be60f27d5dd3f17f80d6b2f275d76fa5a",
+ "packages/flow/openadapt_flow/backends/rdp_backend.py": "f6ea77fdbef04bf6064ba68466dba85c627fd633bf188c14d9988b5f0e7a4242",
+ "packages/flow/openadapt_flow/backends/remote_display.py": "f17e9eae67ed966e9938a2d9287ce287c1ca6aa4efd86f4a5773ffac0d3f9b73",
+ "packages/flow/openadapt_flow/backends/win32_window_client.py": "ac4a3a324b2ec2fa9f2fa64a7a1687b78ccab8e522d5c81e2c3b8accb79988ef",
+ "packages/flow/openadapt_flow/backends/win_agent/__init__.py": "cdba9a2b13137a43d83ff03e4eb02c9e250fbaee84ddd6f174c72d5902da553a",
+ "packages/flow/openadapt_flow/backends/win_agent/server.py": "eb0bfab1f3e4e442e3db184efb92418e2f60c9860616b598cdff974d942270cd",
+ "packages/flow/openadapt_flow/backends/win_agent/tls.py": "51f2af9d258c3acfd095d5a7c83d40d3719bbd2161be7963c03c84687f8922cc",
+ "packages/flow/openadapt_flow/backends/windows_backend.py": "77b3d9c931e290afcaa94bdbc191c904e2ca454d99712836760d46fdd06efa82",
+ "packages/flow/openadapt_flow/backends/xfreerdp.py": "b529b6e1a6683b5a4829a3574e963c514c6079f8e2d273a8f94b816231d11443",
+ "packages/flow/openadapt_flow/bench.py": "e90fc71ac1c2033a42b06b872de09550fdd9db02b175d176d250e91c207cedba",
+ "packages/flow/openadapt_flow/bundle_sealing.py": "b8c6c54d53d1e80ced9ce99307af08b670f3690051552488c32afe14334f85ca",
+ "packages/flow/openadapt_flow/bundle_validation.py": "63532fb8e49f25a8aba8dccca505362a9293b8db9cbc0f2904dd8f9a6e23fea8",
+ "packages/flow/openadapt_flow/check_level.py": "cb5a4bb2bc25f70c7de05ee1814b8b8a422ebf307809d96ed74c8106f8e3a9d5",
+ "packages/flow/openadapt_flow/cli_admit.py": "e337d734c1e69b28dd80609f55293040e07798e92028b5ab7afe24d6c613b29b",
+ "packages/flow/openadapt_flow/cli_api.py": "c110d5247ef49389e5fa1e7ca28c3e5eda6ba5cd34524c8e9b5d160d6ada1203",
+ "packages/flow/openadapt_flow/cli_check.py": "33485cd4d0e1d58b937475a00a348033c630ddd07a568b2982918cb912eb70d9",
+ "packages/flow/openadapt_flow/cli_cleanup.py": "74e6dbd940e5b6cc7dacf5e68a5089aa18ebbb108e3f59f7fa56a69e08ab820f",
+ "packages/flow/openadapt_flow/cli_compose.py": "965a63427ec37964451cdb00fad92065833b6f7cab936c80526c05984b5a68ec",
+ "packages/flow/openadapt_flow/cli_config.py": "a68b1b9db2c60feee3ec0b4ea079bbacc7b90bb052f9660c87b2e7067c593557",
+ "packages/flow/openadapt_flow/cli_deferred.py": "058cc58d256276f36db2b1e4f6e0105b505c88c1f65ca9f8e01e5f37f79ddeab",
+ "packages/flow/openadapt_flow/cli_fleet.py": "a4678b9b48c6c4817673fcccbd18be21966ae6d64dd89fb143bf26f3dce3c7ff",
+ "packages/flow/openadapt_flow/cli_hints.py": "6589faad4aefc66d6a80fe7875909cb9d335fa5624d9c761a95d5afe772a260f",
+ "packages/flow/openadapt_flow/cli_known_ids.py": "ed965f2369489a87cefb27ea9c9241bdc9b6058c72fc56450006be9951737897",
+ "packages/flow/openadapt_flow/cli_local_seal.py": "33c1f1406afa3de7c85bd661befad02b51fc5018f5eefa94546bd6381bf5c37f",
+ "packages/flow/openadapt_flow/cli_no_outbound.py": "1afedf45d1874e4aeeabc8cf1d36572f6df8b7ddf54bfcb75189d0bb0f149b47",
+ "packages/flow/openadapt_flow/cli_process.py": "700238b5cfb5edef883d2e57a209d9628fdb12fdc7aee6ea7c4a519999d28d64",
+ "packages/flow/openadapt_flow/cli_receipt.py": "c887eed402e7e2ac7979410cccd58068dc2a666f507d004e93d4a37e28e6749e",
+ "packages/flow/openadapt_flow/cli_redact_report.py": "3e9d35b83f8d74e7b085e670787de410aebcb70a3a0de4ff1760bc44c91e48cf",
+ "packages/flow/openadapt_flow/cli_rollback.py": "f9f80f3d84b1e50241527a5fd09736941f8eac0782fb05acbab2e4765b9747e9",
+ "packages/flow/openadapt_flow/cli_sections.py": "21d0a362860703f030fea5a2ddcbd0a14a48a4799fcbf117d526a38fcccb04ea",
+ "packages/flow/openadapt_flow/cli_self_repair.py": "3d75c98c8078de6d74b98f75274a82ba4d865b5585ca4ffd2e38aaa566cb2322",
+ "packages/flow/openadapt_flow/cli_service.py": "172c06cc25ada99b0532dee35aa4e4510671cc7e7b24871e8b7294abed8cea0e",
+ "packages/flow/openadapt_flow/cli_shadow.py": "8b419d698a5a46b3133b942832b493edcff39bad527b7705b68f0b54c04329d5",
+ "packages/flow/openadapt_flow/cli_undo.py": "93b527aaffe833b02ea1e990bf03c908fa88c3f60d764007130a00449b75185d",
+ "packages/flow/openadapt_flow/cli_variants.py": "4d214beab05bdf5765559004c8e83bada54567624ac1ae704d0a979e127f15c6",
+ "packages/flow/openadapt_flow/cli_worklist_pool.py": "74b4164f79865db4ae7a41b063ba2f671077c02645021fc2e42424f628431777",
+ "packages/flow/openadapt_flow/cloud_seal.py": "dd473bf2ce29f708e1c1638d70f8b54a3feaf140f27aada14481f31c1d2517ad",
+ "packages/flow/openadapt_flow/compatibility.py": "c869b05daece5b5bca489a27f71d2de07354624913d7480135ca0d6354e3516c",
+ "packages/flow/openadapt_flow/compile_agent/__init__.py": "1f70909ee8780e62513f41d717b8c07cee89dbdc430bf84ea08904998502af3d",
+ "packages/flow/openadapt_flow/compile_agent/agents.py": "c7b7375b27ed3d7925ce035782092c00ee56ada4c2fd3461c3feee6427aa59b1",
+ "packages/flow/openadapt_flow/compile_agent/cli.py": "1ad904e8732ab6c65a0b33df8d85f56eae384c47beefdf2e2de8a1cb29920e6d",
+ "packages/flow/openadapt_flow/compile_agent/code_action.py": "ec0ebc2ec7b41ac36bbe36c7deab28c38d84e46c8515b04799ebd79379f8acb8",
+ "packages/flow/openadapt_flow/compile_agent/driven.py": "06aff15b79c938ba13065669317ee37101e8cfeffcb0c00e693ea3eef781bf6f",
+ "packages/flow/openadapt_flow/compile_agent/emit.py": "405411124cfc94b52c45c90c195537ea53b0ef3b242cebf212102c49c0111403",
+ "packages/flow/openadapt_flow/compile_agent/harness.py": "3eb4543f919c6dbf6778612829c5eb773078b480dbe89e857a771bae0b78722f",
+ "packages/flow/openadapt_flow/compile_agent/observe.py": "b2a82ff94383acdf113ae4f4c9e75114df3e1c0e7ef1782495eaeed249e41206",
+ "packages/flow/openadapt_flow/compile_agent/pipeline.py": "2715b6fa231a0c0ac94726133734da4e38dd3e9255cff46bb6e5ec0129091431",
+ "packages/flow/openadapt_flow/compile_agent/sandbox.py": "0df910a8f3c7f9a4d1a76c2ad97d62cab868694ee67f5ec70ddb2ca0f9d26e97",
+ "packages/flow/openadapt_flow/compiler/__init__.py": "e38510f5baea14d9d357ab594954ff42f5aff608589ea8ae5d7060e8cf0fa380",
+ "packages/flow/openadapt_flow/compiler/annotate.py": "0cd0afb521e50c82906c5d47e12bca09a12d0caa9127bae433f830339b41622a",
+ "packages/flow/openadapt_flow/compiler/api_proposal.py": "89f5ed6889c8f5d6d78cbc70b96f3aca14db416aee903731c9a42c002b8d2e45",
+ "packages/flow/openadapt_flow/compiler/binding_admission.py": "a288a9d32f7e48631197682b4c886b8da15c2833c31cffa097776a5d6e95d71b",
+ "packages/flow/openadapt_flow/compiler/codegen.py": "327bcc7ca46c1249ba11caad31305171dc36fd11f02073ef6484aa4939f4772c",
+ "packages/flow/openadapt_flow/compiler/compile.py": "77f574eebec81f39482a8a7e976a7836131efbb10b1ef79a2185f70f3659f0f1",
+ "packages/flow/openadapt_flow/compiler/compose_authoring.py": "8ebb7649c73a4bf250dd98db3dbf6e9dccca317130e199632398102e57070a6d",
+ "packages/flow/openadapt_flow/compiler/disambiguation.py": "2761afc6683f1b72b1126a2482bf1e02f34651489dd28f71a2f57aaddced7fb5",
+ "packages/flow/openadapt_flow/compiler/distill.py": "3169f571e0f8c63c14f324c626400ae78ad55aab83c03e54b8396e304757fc75",
+ "packages/flow/openadapt_flow/compiler/effect_mining.py": "c35a6339c75323c00104aa370ea7070631e93c9b0ae978d7b4d59b26f7e51122",
+ "packages/flow/openadapt_flow/compiler/empty_result_guard.py": "7511f2aa9adec3ed244eb21cad8c382a1954f36b625497ba3267c0e314e833a1",
+ "packages/flow/openadapt_flow/compiler/fixup_passes.py": "daab90b0f9b4441a7d430e8038813e69d2676504936f0ab86e6197ed14cc86ae",
+ "packages/flow/openadapt_flow/compiler/induction.py": "c7e5d8e4f7dfa4ecd78cb831b1b98f9424b5a267936a1ed66dfb5df2f96ef160",
+ "packages/flow/openadapt_flow/compiler/local_edit.py": "867f0ca4d79dccc88367da10e75b180727438a1aeae30a49d407ef5cdff04981",
+ "packages/flow/openadapt_flow/compiler/lookup_detect.py": "9515fde8bf759f19e5698e3c00f0fe918a790abb0f30f9db911e03d12e84b402",
+ "packages/flow/openadapt_flow/compiler/loop_authoring.py": "f9ac89cc50e238a35411741aebb3eee7d76c2b263008957d21cdcb49e89b0ee9",
+ "packages/flow/openadapt_flow/compiler/loop_shapes.py": "b46f39bd5c4c3216c87ed52ebdb919ad1fa87ca0df29ccac376cfb107ec36a8e",
+ "packages/flow/openadapt_flow/compiler/motif_induction.py": "920c2fb7a409ce90437376ccea3261cf71fd1b029baea8f5a6f2d8de7aefe360",
+ "packages/flow/openadapt_flow/compiler/narration_rules.py": "2be904090c00ce014a4f1854393770d3b4172943e4d2ec1b35e1e58e5a26d199",
+ "packages/flow/openadapt_flow/compiler/param_confirm.py": "4cc6c8402a4f30626098e09156bc283f7755d68b6b108c28f2db4c069e5a7cd9",
+ "packages/flow/openadapt_flow/compiler/probing.py": "e6ee7dedc5f7a8bfa768bf0a0cb6b1271ed6da2b1c1a956968ad34dfbb3f8b48",
+ "packages/flow/openadapt_flow/compiler/qualification_pins.py": "8392cb44ef2cb33956ae58e235a8611295f07553a0c1ea2aa5b2ef010a997787",
+ "packages/flow/openadapt_flow/compiler/qualification_proposer.py": "ab4bfa3e51aca8dd5fb2360e5be9c3b454197e09d6365ef20ba0632210997d30",
+ "packages/flow/openadapt_flow/compiler/readback_authoring.py": "6020b8ef5fc22b0ffa8ede900c6b60b37b60f35dc61b288f5cba238deef5053c",
+ "packages/flow/openadapt_flow/composition.py": "cc79d2e4215f77b6c3daf2370a853d0cba410c9da3df209d59e1879222af3ea6",
+ "packages/flow/openadapt_flow/connector/__init__.py": "ea1c554a0de295db995f57f837669419855c9fa1d2fcf958ae4e2feeec37106e",
+ "packages/flow/openadapt_flow/connector/client.py": "1f55a56123fda690c4bb4dfbd6407f4a96c85c2575eb8928cb7aed30b3a20145",
+ "packages/flow/openadapt_flow/connector/config.py": "8dd9f662151ce609e21ead89d4019c77a4ab185a0f1b5690df20dac166701c4d",
+ "packages/flow/openadapt_flow/connector/daemon.py": "3ea5444af51cb28dc84addc4a5db15a6a75486f4ecee93d3b6c09ed7e7ce1366",
+ "packages/flow/openadapt_flow/connector/executor.py": "463aeafed9092b16a654191611445bb5688334ca87ac0703699d6dfa7f449748",
+ "packages/flow/openadapt_flow/connector/protocol.py": "963162e5dc20fe0e220fda67e59d138b791fcc6bbaf626776ab192d6cfe3a203",
+ "packages/flow/openadapt_flow/connector/storage.py": "4ba816b98860b5f6973909b6b6d30138b429a8bcd120423408bf0ade7cc1a916",
+ "packages/flow/openadapt_flow/console/__init__.py": "3a5ad4c010c98c3afee9c00a4fb7b4209e914b27e48d0cef09d8d4d3eccbbb57",
+ "packages/flow/openadapt_flow/console/actions.py": "097dd73b8cc61d19cb9cb5752103663a413cae0b822cb708419966413d188850",
+ "packages/flow/openadapt_flow/console/app.py": "c85d6e1038cbe1ec0737cc51deca93b490f83496a55b0b3b60681575dd07e386",
+ "packages/flow/openadapt_flow/console/attention.py": "cd4dff1f27d8c0ef022dc92d64eabf2976fcff3ea0a06a5c363af169899f9cef",
+ "packages/flow/openadapt_flow/console/data.py": "80359fd5e16d13b73a821034b4ac12de7a52cf4dd81c4211c18b2b23154a86e1",
+ "packages/flow/openadapt_flow/console/decision_context.py": "e5d7297c636d5e5c429558d6ed54ce294b4a3e97629150346369409bfa309d8c",
+ "packages/flow/openadapt_flow/console/decision_relay.py": "d5320404d4342dbb52be1f2ead1cdb5cf0e22877feaaa1e47974b301df697292",
+ "packages/flow/openadapt_flow/console/decision_supervisor.py": "a5496779de6c05a21c03fb91cf3a3565951bf97922952cf6606a2c185dea6d69",
+ "packages/flow/openadapt_flow/console/halt_detail.py": "03d136781ae0324f0fafa16af5cbae52af15360e73963a01ac116967df5c6c12",
+ "packages/flow/openadapt_flow/console/human_decisions.py": "02651ad8888a5c17bfff6fb47165ba861193243dc0f7c951f8b94f544ca19477",
+ "packages/flow/openadapt_flow/console/json_artifacts.py": "e908d47f34bc040e83b257b953c55a7f3cec9b2b74a4519369d85c3a12e6cb7a",
+ "packages/flow/openadapt_flow/console/save_approvals.py": "1c180720a593e160720421a72cb5676a13f399a5e2bd3fd07ccc063b5bd8c00b",
+ "packages/flow/openadapt_flow/console/server.py": "d250a4e486053343eb92e38887fdb59c55c5c3cde64b69756e432b3b074f7367",
+ "packages/flow/openadapt_flow/console/standard_changes.py": "29f34f8fb06b4b412e825892fa340bea11f07e21c6560ae4936c0bab19972505",
+ "packages/flow/openadapt_flow/contracts/__init__.py": "cc4213ad8ee43060894281df685a4d2554b9e0869bcd267f0509b965d81d19cc",
+ "packages/flow/openadapt_flow/countersign/__init__.py": "727c18b4914e681256d727bf6a13285bd9b43c84430c7cbb610efd6721d7edba",
+ "packages/flow/openadapt_flow/countersign/cli.py": "bbb2f1b833297dab3d90fab4ee8bc60b71598b93d0da1dcd30baa6de6dfe8886",
+ "packages/flow/openadapt_flow/countersign/commitments.py": "2ec3967924a7142facbaee575d6c76c0241f9187e4ce2c4b497f479b5e432339",
+ "packages/flow/openadapt_flow/countersign/document.py": "3e4760c7ad0f6949b8cde441217d647c5caf7ea13f63c25bfeffee92c0c6e375",
+ "packages/flow/openadapt_flow/countersign/dossier.py": "1ea1151f03b55a6b8a73333b46079cf2cc31d338e6b413490636d2b3ef16033b",
+ "packages/flow/openadapt_flow/countersign/exceptions.py": "effb4425752f60d44e133ee7b2d704f25473bcb46e168fd17780f50320cf1ee7",
+ "packages/flow/openadapt_flow/countersign/render.py": "754b6858cb5a3de7db6489103c5225f8f5a62f7ec91af5027b68c0d0c9e7e5cc",
+ "packages/flow/openadapt_flow/countersign/tsa.py": "c3597122c33e80b3eb2cb129551e1cd50b6021f45cbad01c20869f13699f8200",
+ "packages/flow/openadapt_flow/countersign/vault.py": "71ea45df4993a00a384791c227328eab67a2e5d3d1d75896e7c841765d5ed1bc",
+ "packages/flow/openadapt_flow/crypto.py": "4428317caed40074c5210bdb1d54c67a3d29c7fa1fe4bb0da0fd1abcb48db526",
+ "packages/flow/openadapt_flow/decision/__init__.py": "32b2b08051ab45571c55af1d44f2b68fd4106eec9ceb078d6769c2d306403550",
+ "packages/flow/openadapt_flow/decision/calibration.py": "51b2adc7ee624d78120a12ebf02d6eb6b9408ce90642e064647fe678e5578051",
+ "packages/flow/openadapt_flow/decision/cli.py": "b0f453ad2616e4b0f99249e983967d1fa7b929e4692662b8adab47053cdf027d",
+ "packages/flow/openadapt_flow/decision/eligibility.py": "86e77ae372f8eef0c31eb9ff694e17cadc7f278155c76d46f0a40be0dc766cb8",
+ "packages/flow/openadapt_flow/decision/feature_model.py": "af7207d471e531377ea653448fd2487f1988a4e8c0b3c7c36d7983a369621077",
+ "packages/flow/openadapt_flow/decision/features.py": "cc5e21ecf0ca93982645791724fd41afcb9e77ed4c526cfa2ea7d3c6cee3931d",
+ "packages/flow/openadapt_flow/decision/labels.py": "924fa2fa32cdde259a2900d0c8af3c3f54b07c30bcbbb9f4af7289663a2889c2",
+ "packages/flow/openadapt_flow/decision/minimize.py": "9c0695866985ecda25a0c96d251d3358d15ab7ee57e66a3b4528e66f4df65ace",
+ "packages/flow/openadapt_flow/decision/provider.py": "3e14c3b013533925a62e67bdd9b82ddf99f969a2552914db1630498ee7f4bcbf",
+ "packages/flow/openadapt_flow/decision/review.py": "47822513196daa1cb3e827e3cb846763f41165738c3576c2df946f6135676098",
+ "packages/flow/openadapt_flow/decision/rules.py": "59a33e0bec5f19fc35621652c96c79ee6d6cc719854ff402853c9cf9c143b31c",
+ "packages/flow/openadapt_flow/decision/synthetic.py": "2ee2fc309a5342a5a3e050a47054b6b1730e21d8d20592956f7bc83f8e7389c6",
+ "packages/flow/openadapt_flow/decision/triage.py": "201235c57ce21e631c4e2f5990628f40ce3bae95e239f0bba29ce7738d95f96b",
+ "packages/flow/openadapt_flow/decision_delivery.py": "e3fd372d84ecb8a13fd811e115255362fae2f96e5b073e59d1d7f123c2bd85a8",
+ "packages/flow/openadapt_flow/demo_driver.py": "84976fda59fe901ab8b0e787bfccf46153f2794367e9655b6583a2ce485fff82",
+ "packages/flow/openadapt_flow/demo_proof.py": "dd9d11d97e4ed264593ecd33052910bea4784934ac575a5365d5cd4c8099f110",
+ "packages/flow/openadapt_flow/deployment.py": "f2e39de0c5bbfad89d6fe1f6f83c801ee5ffe8cb192ff40a03ba4d14690f3263",
+ "packages/flow/openadapt_flow/desktop_record.py": "a162df0e593b9f437bca86aa723be013836dd5e0c93acd5fcff7876ba16e3110",
+ "packages/flow/openadapt_flow/ed25519ph.py": "c8bb9e5d64adc44715e27c06f437e7801f6cac56aca1f15d8a577e629c649282",
+ "packages/flow/openadapt_flow/eligibility/__init__.py": "c4b10f081ff9c6d3ec3a3017d8a12aa7eb67b41488ae931000a8f84f08d9c54c",
+ "packages/flow/openadapt_flow/eligibility/artifact.py": "686eae18906a58b42fb6219fe6c4fa7b98638192db8169f0098601403ab274b9",
+ "packages/flow/openadapt_flow/eligibility/client.py": "9ddd6ca4512b64b8ad7ce7fad6c31d037209f3a19e9c52c605e9eb508c0f63e6",
+ "packages/flow/openadapt_flow/eligibility/waterfall.py": "15e15b5c8efed40cdeba907b74a279c217434ccf62a378f2ed4a05feba0d44ec",
+ "packages/flow/openadapt_flow/emit/__init__.py": "f9d028ad70f3eda13321fdab9d23845016781cb7360160d71eab82a1752419cb",
+ "packages/flow/openadapt_flow/emit/l1_artifact.py": "8e590b6013d1aedb6b722745d616bc394451c703642a1b7b0159359d94a4a868",
+ "packages/flow/openadapt_flow/emit/mcp_tool.py": "7852e44e2451103612a282b8fe3224a631c4b7261203418636949f82e80b4ba7",
+ "packages/flow/openadapt_flow/emit/skill.py": "43bd4116c93a662ef628a07a81c0ee2777351b6eb790ddc58b91151df672267e",
+ "packages/flow/openadapt_flow/ensure_record.py": "d009dbce1ea5e1802fd2ff1c4ab5e93ce9aa4cfec489f17af463220d13bdd1b5",
+ "packages/flow/openadapt_flow/execute/__init__.py": "769684783844a34810850275aba3647c303acc2cd6eced1d8c350c4a2e774d54",
+ "packages/flow/openadapt_flow/execute/app.py": "fde39916331f18c8ec84948cebce74b2e1c31d3c06cdaadcdb8225eda4df92d5",
+ "packages/flow/openadapt_flow/execute/dispatch.py": "9cea78d3955ca6ef30e7ebe74b8ad752e6bafcba0289f2db4a746342ba1bf2f9",
+ "packages/flow/openadapt_flow/execute/keys.py": "f43c622ef1df57efb3ed52db6aafc9d98d78100f2e25fff50dcc8b75489f9750",
+ "packages/flow/openadapt_flow/execute/models.py": "bfbac12c75f4fc52c0f9bf89652e876828f208c13a7827dab8bc741b112a5e6a",
+ "packages/flow/openadapt_flow/execute/registry.py": "d687121bec318dd4b56faa1db195a181501fde92263f7b851fb33607de903642",
+ "packages/flow/openadapt_flow/execute/service.py": "1453344697293a8b76ef7a5788930408b19e60981e8770e8680c852dd307af88",
+ "packages/flow/openadapt_flow/execution_profiles.py": "53b27ddb96edba887a6e8c1af231975f25bafc23b55dea191fbcd08db4956de5",
+ "packages/flow/openadapt_flow/failure_signals.py": "63090631a784bf6626859f3a2f7c95551b019d1baac79573255fb41c98f7d8c9",
+ "packages/flow/openadapt_flow/fault_gate.py": "e4db640d84d1310557d7bfc82e4a0849323a11a2757035ceb70dda354bb9a046",
+ "packages/flow/openadapt_flow/fleet/__init__.py": "3196cac4fbcf1ac5974955e8d9f4dbd0295b516ad5b758e1f67e4f6f545a95b7",
+ "packages/flow/openadapt_flow/fleet/_lock.py": "b877076335ab50d6b240e3b6b0f131d0c699ba706e4af738858320c3fbfe45a1",
+ "packages/flow/openadapt_flow/fleet/canary.py": "275a8acf693d566f17858a2656df9d1b6315becc6c9153149046902bede9c1db",
+ "packages/flow/openadapt_flow/fleet/export.py": "f3c4385716ceb71c0f2e93e4552a32aa22fc31561d0497f9b4c5f13f09c64937",
+ "packages/flow/openadapt_flow/fleet/feed.py": "f229589e292195b387f9c756fbd549eacede2cbaaac2a43d782ae89fc69a7a34",
+ "packages/flow/openadapt_flow/fleet/fingerprint.py": "f641b80642a5bdabf97e44b7f9796ab413c8c5e1ec64355c333ecf91ccda6e00",
+ "packages/flow/openadapt_flow/fleet/hub.py": "5605dd4b5cc620f400bf101c8a94b3fd386dcdbea91329ce9fd2dac087e12f8a",
+ "packages/flow/openadapt_flow/fleet/intake.py": "c6390b6814eff7f0dc424711a6502145baf13bc7ba32031de827f1458184b267",
+ "packages/flow/openadapt_flow/fleet/optin.py": "c6a02feef8c31dfda435fa7b5c9ae2313775979cf68ba0643fe1f284142d3eb5",
+ "packages/flow/openadapt_flow/fleet/patch.py": "50fbd5f28c25c5af1a74ab79534bfc45d80335bf50971d88937d6f48a8047caa",
+ "packages/flow/openadapt_flow/fleet/policy.py": "d9a6dfc09ace5a6446f421728f636d77ac40c4e8e3068685d54cf12a52091729",
+ "packages/flow/openadapt_flow/fleet/signing.py": "9761c1e080a04ddcbb0f54f75ca37fd74a1801399be32218e527ef1c5b71bc89",
+ "packages/flow/openadapt_flow/fleet/simulator.py": "5c6ef1603f7bb500e3845d85edb8c971c5515db45feecf934003cf0be0d75fdd",
+ "packages/flow/openadapt_flow/fleet/status.py": "2be462c6f00fda3b783e7825c12a5a031346b11e34c10c6465de75fa79c650a5",
+ "packages/flow/openadapt_flow/generate/__init__.py": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
+ "packages/flow/openadapt_flow/generate/demo_analysis.py": "5d8b08a6b73c91a6a0fcdeda965f1086288fa728e0a47a11b373f2fa004cb74a",
+ "packages/flow/openadapt_flow/generate/ensure_contract.py": "b225841620cf86040065890a7585d2b0481529059546cd2f8bb087624d1edea9",
+ "packages/flow/openadapt_flow/generate/fhir_tables.py": "efe58cb353bb8e660c69773f4b057410165b74adf782d1a49e39e676a7a904ca",
+ "packages/flow/openadapt_flow/generate/sql_store.py": "f0fdc8a8ab7941a6e4ac8fd45195c2d652ab54fe73bc423a685c4cfcc088f474",
+ "packages/flow/openadapt_flow/generate/verify_contract.py": "5366153fd16a5c1e617295ac2a2c7e6e248892d83ce654f1c5841daca2b5c040",
+ "packages/flow/openadapt_flow/generate/zero_touch.py": "e5f8d39fd4ea2df9cc0e53993d6872280fd1a753f7631fa7adde864038acabf9",
+ "packages/flow/openadapt_flow/guard.py": "9a002384f9564d7bf379fbe855cabbb4484ff2c18a7ba5412502c818f11213cc",
+ "packages/flow/openadapt_flow/halt_cleanup.py": "c1e0e58b170519c683faf97593fb36e91523392f17a1726223d90b47738c3cae",
+ "packages/flow/openadapt_flow/hosted.py": "30e7d7517f638b89fad598f1cbf6c314024ebc7e43c86918fcc9d6d57e2555cd",
+ "packages/flow/openadapt_flow/identity_signals.py": "46e1392fe0fdc7473bc28bb25562f31a6dcc6c90f95d7900de255bc750bf7287",
+ "packages/flow/openadapt_flow/image_hash.py": "4dea419ca5617104d6072ebddf8141e8f9809227aaf833969e390eb3d5c7d73e",
+ "packages/flow/openadapt_flow/intake/__init__.py": "76815b0b2ecd679c7b076f28f1bb48c66a6be007f208fe8a6ab2746477b3ddc0",
+ "packages/flow/openadapt_flow/intake/cli.py": "332e14ae4367185c4cb51f3f704c4de63cfb277e22689972bfae7ad841971465",
+ "packages/flow/openadapt_flow/intake/document.py": "b71b232d18d509e336d9d950063b14c6dd703383319a25b845e08fa5731b6f32",
+ "packages/flow/openadapt_flow/intake/extract.py": "61a1db7580d8fcd47943337ece067980527a541520929a62e0de321c23fd6f37",
+ "packages/flow/openadapt_flow/integrations/__init__.py": "f963112195eca4e46543778de92d5e5ad6e3afffccd999fb94377f4c75199606",
+ "packages/flow/openadapt_flow/integrations/agents/__init__.py": "280e431a4b07bb961e3ff7ddd8f2e8225faaad139fe00d091eda18ddc77b2bdd",
+ "packages/flow/openadapt_flow/integrations/agents/claude_sdk.py": "c2b4fe00a75c8ea95652a29b438269608c2f5f3cfd7cdbe80538b3bc87570120",
+ "packages/flow/openadapt_flow/integrations/agents/crewai.py": "a93a5a2222c20e77e89161c3587cc9e90769739465e1045f2666e80da91b7718",
+ "packages/flow/openadapt_flow/integrations/agents/langgraph.py": "ffe07ab4063cf8d053d89d63586fe114babec53e75274f2b406179de845c90b4",
+ "packages/flow/openadapt_flow/integrations/agents/openai_agents.py": "0a5d6e04f3bbe6e568c9eda5b63f76f86343c686f6ab103e209b6d410605ffe8",
+ "packages/flow/openadapt_flow/integrations/agents/skills.py": "862d688e35a13ae69b6402c3feed6cf18ad98c637771f64ad5f4a9aa74e558f6",
+ "packages/flow/openadapt_flow/interactive_recorder.py": "69cb3d8a3c448e5e0749a17fda751ed3ada89093da7289df43c40fba008f495d",
+ "packages/flow/openadapt_flow/interchange/__init__.py": "b40b98268f7317e7539f123a6fca9b507d6492280d6f679525673493dbe24718",
+ "packages/flow/openadapt_flow/interchange/__main__.py": "8eba812ea2fcab0984b05def3fcc596cc4e523756ea3d8daecd23eb4a5c2cd1b",
+ "packages/flow/openadapt_flow/interchange/conformance.py": "50d7192c78d9b1fffad09fa37dc9abe7b33e84d66a395af955fa852912a99adb",
+ "packages/flow/openadapt_flow/interchange/l1.py": "438d2b59a856017cdc2f0256e6efd7e605c68ce54ecf9825282a34f09b24c7e3",
+ "packages/flow/openadapt_flow/interchange/model.py": "eedfe5e24508b82b24fabc05edf003fe3fc3c89e414d0436d6ca4c0d682c7444",
+ "packages/flow/openadapt_flow/interop/__init__.py": "fe8f034e12327da65230f887cd17fef5a21b8ec350a77d22fa0693f728f11d03",
+ "packages/flow/openadapt_flow/interop/business_decision.py": "264c35835b5d7e5693d140a0b6fc6515c719b73d42aba57bbb685f1dd1140743",
+ "packages/flow/openadapt_flow/interop/business_decision_cloud.py": "85b3a01a0642f28bdf2ec704b8b39bb8f81b5e16ab716791b56ea25990a890f2",
+ "packages/flow/openadapt_flow/interop/business_decision_supervisor.py": "d39d6bf9cfd1d4c84804b5565a99f0ac9560ac15e2838deee4c81426503b521b",
+ "packages/flow/openadapt_flow/interop/decision_relay_transport.py": "31a2f2ecea1d39f108747dbb81b123d2d7d1b0421fe75b97c6abac1d94652a51",
+ "packages/flow/openadapt_flow/interop/types.py": "1f2a45fcf456d31cf15534ab6d1417fd3c52612c3ab948bdb14f5a0b6f814945",
+ "packages/flow/openadapt_flow/ir.py": "509e9ef8666ec65496b4b7afdd0b2bc8af4ba0663e64a4079ce1813950bf028e",
+ "packages/flow/openadapt_flow/jit/__init__.py": "351ae6f83405a8dedb9585ea031ad068416a8595504edb21b39e623a67a1f489",
+ "packages/flow/openadapt_flow/jit/adapters.py": "c7af4267e8a1704e1390dee295a2ec3696ae9c932e506a2785023ac88a71c879",
+ "packages/flow/openadapt_flow/jit/authority.py": "421e369b815c16578f5aa54158065c8c0700105124a32b6e8a0aa0020ed1de60",
+ "packages/flow/openadapt_flow/jit/cli.py": "36374e4032c91969af3d39d56bfd3788cd3997f0c2e7aed4be09e240c92e223a",
+ "packages/flow/openadapt_flow/jit/compile_agent.py": "55a56073827e3a2ec2d0fb13beabd6a727edf304721e8b4ee974c5debe90e09e",
+ "packages/flow/openadapt_flow/jit/keys.py": "8d4b0674a351a69011e590ca9bbe5e09ccfd3c55868ff03db7584bbc6e2d530d",
+ "packages/flow/openadapt_flow/jit/lifecycle.py": "395ea2b8261a1b3b26bb9a7faded23780c482efdf55871ea47e1f931743e794f",
+ "packages/flow/openadapt_flow/jit/lift.py": "75a87c70262f626532568ad414e5ecbbcdddb43c8b5c5c605f637030640c4f07",
+ "packages/flow/openadapt_flow/jit/recorded.py": "3dac2027d3bc1d0e7028dc39f85e7c072c115656ef556d3e21e003f9cdb2a8aa",
+ "packages/flow/openadapt_flow/jit/signature.py": "b7f68b753c10c89fe57ef6912baf2e857637a5cdde5c23dfeb105f27c43c67e1",
+ "packages/flow/openadapt_flow/judgment_cases.py": "021f312ad721f06c6ee0f99cd2061d32c82eea7bfe6f87c4b182e36a4f445db9",
+ "packages/flow/openadapt_flow/learn.py": "9972f0c1edd58180aafa44793ae1152b3d53fd0fe74604cb9efb2fe3836f4e8a",
+ "packages/flow/openadapt_flow/learning/__init__.py": "fb5b8f2f0b59009c55662f56ed7957e94859feeace15c2e3c671998447cb9de6",
+ "packages/flow/openadapt_flow/learning/branch_teach.py": "60b03c5a0f0f28bc21ae4bd21377735a89bf166e17519e7cc949ffc2260cc171",
+ "packages/flow/openadapt_flow/learning/clustering.py": "50173d350b1c936e2f667db1612dae7721df7a81b40c07eef11abf10c9c0f1c4",
+ "packages/flow/openadapt_flow/learning/gate.py": "f34fd9f3ec74d7a5cb7f111be658db9debd032ceaa12d9254e2adc25f0becbf5",
+ "packages/flow/openadapt_flow/learning/halt_loop.py": "c39cc99409dd9b1631086f3d4f09b7997d3f6bda17861871169599f982d2e76f",
+ "packages/flow/openadapt_flow/learning/induce.py": "57a7018ddc2399c4810cc4f1b371ccf7ef128b1779c731f5e13df13f7ab873a5",
+ "packages/flow/openadapt_flow/learning/interpreter.py": "606d336216a899b11651c2e4eb341748d8cc91a10508bd33a63c7d50a44318aa",
+ "packages/flow/openadapt_flow/learning/library.py": "ec7f5ac69c5a75c081a1c5c0089c3e0f77c8fcc630b5ab7e2aeae0cb38221740",
+ "packages/flow/openadapt_flow/learning/loop.py": "f3e5c1127b4fa21f3e112516670edce15daf05322c554642b8057bf268adb7cb",
+ "packages/flow/openadapt_flow/learning/teach.py": "bb64ee5a7bbd14cb872a3f82fb2de4601d5b0d7f7e1a45c1e205f6d23dfcbde5",
+ "packages/flow/openadapt_flow/learning/trace.py": "323bc17cfa3fc3876ac030abda028c73e8af02d5e30b2cbe9c9b9faa4639c524",
+ "packages/flow/openadapt_flow/lookup_capabilities.py": "6f8068a05f005e0eac994d14d0ca3e6b1ce7a4e532471bf4b8d9dc15c0fe1b4a",
+ "packages/flow/openadapt_flow/mockloan/__init__.py": "06beb30be301dde52a522064ed192864a4c2bc1f167ebb5800c173eaa72f4735",
+ "packages/flow/openadapt_flow/mockloan/fault_server.py": "0f6f6e4ca4622c5674dca6e49b9dc67360f34b9071ba1346727683aed16682ca",
+ "packages/flow/openadapt_flow/mockloan/server.py": "6d81bda0dd715a71e54306c92d739b49ca3b3a75fac65ee7a70a3d18027ecaa7",
+ "packages/flow/openadapt_flow/mockmed/__init__.py": "223bb05087540a7e0e90f72b83a5dd3634318b95dc0a6874cbc82fd38ce5ee9b",
+ "packages/flow/openadapt_flow/mockmed/chart_pages.py": "38db2fb4d34d14d8745c7c9b31a6c729a4e0afc545333c164296fde5044bf395",
+ "packages/flow/openadapt_flow/mockmed/fault_server.py": "acdd45ef82111d50e1ebbd242d55ad14094f0a0c457c43049855be5efa8ecb70",
+ "packages/flow/openadapt_flow/mockmed/server.py": "9fbeaf2b0c873dcdce478b4f54990b954844c057a0760ab763705e6aa3f202ab",
+ "packages/flow/openadapt_flow/narration.py": "9e23870f1f9c34aa9f3d4ed65706129e6c77e9cdd3ade8f2d0940383e2fcae8b",
+ "packages/flow/openadapt_flow/network_capture.py": "4b3a27d297cf109dfe375c78621f4438c02694408ea57414a6f5237b739d7df2",
+ "packages/flow/openadapt_flow/network_scope.py": "c64d2288c98fde49c437a0a44b53af4a4b1884a8130b99bee098c2046e249033",
+ "packages/flow/openadapt_flow/no_outbound.py": "220f5ee084a4c7948f331cf08b064bf7291bd5a45c575d234fd43697121c5081",
+ "packages/flow/openadapt_flow/no_outbound_allow.py": "b60aa14551bd39ed333389290ae4a9069863b370532e1016d74441a8dde5dd2a",
+ "packages/flow/openadapt_flow/offline_seal.py": "cc7b0a2dd8d946e6cae740af7d7fb250253a58276c11de4f8a9122b91819d54b",
+ "packages/flow/openadapt_flow/onprem_reboot.py": "5897eda697e7111ef3ad944c7e397b64ed39abdb225085f9eea0f47b6630879e",
+ "packages/flow/openadapt_flow/onprem_service.py": "efa4da8f836f2e88d88e3353324ce810066c945cb62cd21e6bde5d8d0aa06aed",
+ "packages/flow/openadapt_flow/operator_profile.py": "88e013511d1a7fcb7b8e46841c6d7291433a631cb3baec349da42e7a300c5934",
+ "packages/flow/openadapt_flow/pf_firewall.py": "adff9c485d303b5b07efa910c45d39762e12285c843f8cd782ffecac5631e0de",
+ "packages/flow/openadapt_flow/plain_outcome.py": "1a74681faaf317377af006d37557e114f0ba7f5bb561a33331565da0addb4de2",
+ "packages/flow/openadapt_flow/policy.py": "730c8a74c8c1d2e65454407665b62517a48eecb7bcebc9bfb7b6ca3f8fb25079",
+ "packages/flow/openadapt_flow/policy_packs.py": "8df13eaf8e7e4ac7492c2f8c25063ce387833174f3c82dfec3f8c68de4bbaaf7",
+ "packages/flow/openadapt_flow/privacy.py": "d999942cfc463c8d0501a5c5c5ed987c1312a7ec16be9f97b7c527f23b8ae0c1",
+ "packages/flow/openadapt_flow/private_file.py": "eae5ffdae6a76c57bc999278baae8ad0bbabfe87813818777e825beddc22f135",
+ "packages/flow/openadapt_flow/production_qualification.py": "c5c9911c7fcaa12bbd513fe737c4c17a3bd64522b98100880c1a05fddfff3aef",
+ "packages/flow/openadapt_flow/provenance.py": "0865fd3f0362eb6a7b4ced98070b5e399b91e1530288b9a002bc933c86d90879",
+ "packages/flow/openadapt_flow/qualification.py": "ca86f0249c0a9c6abc92c67a8df03d4a94dbb90055b8bad7b4de4dd6625c6ee8",
+ "packages/flow/openadapt_flow/qualification_admission.py": "73a43db18fd383fde7c5e11823ace50046e0784e662b56c76b82289f61616cf0",
+ "packages/flow/openadapt_flow/qualification_admission_v2.py": "10d8241a38b24767953e6b98986c838773a02399652924a53e53c7ec7c7c5e56",
+ "packages/flow/openadapt_flow/qualification_admission_v4.py": "5a11934e42fdea85c7ff792ab6d33754b974a719783154e8e6144e9a90db1292",
+ "packages/flow/openadapt_flow/qualification_campaign_authority.py": "cea191889f3b3f8da5c078e0cb020e7e0ebe9c4100035f5f1bb2b17ace75c3d7",
+ "packages/flow/openadapt_flow/qualification_campaign_permit.py": "1468882d9627f0355673873cd493c2709ab7cec2506dac3b1efa32d1c16f0637",
+ "packages/flow/openadapt_flow/qualification_dev_signer.py": "db70cdacae8235acc73f13a3281e667a7a5e502c246151854db4dd921caf8643",
+ "packages/flow/openadapt_flow/qualification_drills.py": "6fecf639ee1db59b8f15f857f01765d2e5b4dd116da44f664aef0350fc715173",
+ "packages/flow/openadapt_flow/qualification_environment.py": "842f5dd827750f55d9e1046613a804fa6b27c2a41981d4d7fbd6b04d9acc8131",
+ "packages/flow/openadapt_flow/qualification_faults.py": "b4e437aae822c648fca54f8a57b722ca9c940d56f6a906a52292877ba16cc9ff",
+ "packages/flow/openadapt_flow/qualification_identity_evidence.py": "7b94bde4ec7e2d1eb9522bd456aec407ef7d1063f5cc7518a21b40be1464bdb4",
+ "packages/flow/openadapt_flow/qualification_oracle_gate.py": "75a6c16a7a314ac92b05a457302076e5b79478fc737907e1dd1854a1a77c2243",
+ "packages/flow/openadapt_flow/qualification_proposal.py": "1c13d44a189dd798244dbd69186aa78856d304e0b21213d5262450bb9c3861a6",
+ "packages/flow/openadapt_flow/qualification_web_session.py": "3766e5b5f03a92f91a5f51988b1764542b74aeaf634d72e18c9a9b1b6ffc4fdd",
+ "packages/flow/openadapt_flow/qualified_business_decisions.py": "9b56b3d0923440b589e6ff010dda1cab88c893aa01e92861e796e6cae2c83c34",
+ "packages/flow/openadapt_flow/qualify/__init__.py": "a3d7b8e30c06fb77be32b75996ce1f3ea8f96264e74edef2646f122ebbbdc1f6",
+ "packages/flow/openadapt_flow/qualify/campaign.py": "3634f6bb501b83c09325dffa63463b52b85eb6684518c8c47c1179157a8ccc62",
+ "packages/flow/openadapt_flow/qualify/config.py": "04d6e12d00141f1c0c4a6825956ad6d7cd4c5fc108d3d7732118fe2d6acce086",
+ "packages/flow/openadapt_flow/qualify/environment.py": "be85934985a000c6dfef8d1f35f3d790c1c4974a14bea893d58386e533ec45da",
+ "packages/flow/openadapt_flow/qualify/faults.py": "4a78131403af4aff905bdfaf1056c332f890acee1b991283f3c7e2424a9539a5",
+ "packages/flow/openadapt_flow/qualify/keys.py": "fb2e94913ad0db0fcc697943faaeef3f3391a83fe045af703d249b9344afc556",
+ "packages/flow/openadapt_flow/qualify/result.py": "018ccf0d1c6fbc6c91621bd76b3124d5cf09cc4f92edd4f67f2bbff3a1f81b09",
+ "packages/flow/openadapt_flow/qualify/session.py": "b8f367480033e63af4706398ce062c08b56ff02cbf99a844f78c3c3d9fcee920",
+ "packages/flow/openadapt_flow/readback_ladder.py": "7706e14c0531e31677ccaffeefc5e78734ba2434b1ba43360d7144ce44d08ea2",
+ "packages/flow/openadapt_flow/receipt.py": "b90c51a048182475d49db793b00afe5396ac03933042d2ca74b5661375957755",
+ "packages/flow/openadapt_flow/receipt_log.py": "c6b31acf2139ac803389a8dd0d7a1769e2039ff9a51069e0fd02e2e8c8520562",
+ "packages/flow/openadapt_flow/record_check_binding.py": "ff608c3361e92f9f10c863c1ad17a06fd737657b978d6b966e223fa75c1f9b06",
+ "packages/flow/openadapt_flow/record_check_identity.py": "2538298c5343919a80fd5bfe3eb6db0143faaf833f05a1f132c38ab1145c4864",
+ "packages/flow/openadapt_flow/record_check_proof.py": "26104f4de1283d01dd6646768ed50ef624bb143293cb30c62e6427efec9a2111",
+ "packages/flow/openadapt_flow/record_check_synthesis.py": "c71614f451dc2e50332bbf45c4463ba4cb6570fc25fef7491c42e21f38648fdf",
+ "packages/flow/openadapt_flow/record_sor.py": "101a1235c46891da5d0a07bad2c1ba72c4960b7685af772961e4b1e7a629ee34",
+ "packages/flow/openadapt_flow/recorder.py": "ed1e659886a6d9d9e3975754133e7bfe9b07cfced75b8c312598eba332d605a9",
+ "packages/flow/openadapt_flow/records/__init__.py": "5d05312df045601b1b65183587135e6f7ba908cc3d880b18a4b74487a8d06a45",
+ "packages/flow/openadapt_flow/records/export.py": "644bbae324cf146e24f2c97e8ba1c959ebfacfd33b58056e6819909b9dfd4abf",
+ "packages/flow/openadapt_flow/records/read.py": "ac88614c9cd3524cb29ba8c8c44725e4dd6ab24afc8aca9479d875ee2aa0ee29",
+ "packages/flow/openadapt_flow/records/review.py": "de530c3d3617e40d0c0254c9f04d6b70ee453877a130cfb4dfc27348704e1945",
+ "packages/flow/openadapt_flow/records/run.py": "a9ec68f5ca19b2396aea6e9d9e0198cdb5e63b63fbc0fe2854773e9a7888c6b2",
+ "packages/flow/openadapt_flow/records/schema.py": "3d9d3b4fc1fcb3b4835e6dced9ef49ce08e5c2e61448aa4e1859e56f09ae7b67",
+ "packages/flow/openadapt_flow/registry.py": "6203135d2768776f95a8a5d46765aa76cc2e16904b46b06ba83852d18416d215",
+ "packages/flow/openadapt_flow/registry_attest.py": "8a8375762ac6bc2a2f717359c1002d220295997f01c012b5c42b7dcd09709676",
+ "packages/flow/openadapt_flow/release_admission.py": "5afdf674f30073b10ed5b4ee06fd3818db26e74cc935c649548256cb60160f7a",
+ "packages/flow/openadapt_flow/remote_frame_contract.py": "745c8e9a6731ea89b722092183f760527d9e6f329a5a7ef61152870114e77406",
+ "packages/flow/openadapt_flow/repair/__init__.py": "db1e673372764eb9ba76be658980a94b9747a0d716b5ec1a8d5f74d69ca909ee",
+ "packages/flow/openadapt_flow/repair/agent_teach.py": "ec9995ba2d3ccaee0ee623e77cd30f0d30a565235befcfbb003fb81d4b7f2920",
+ "packages/flow/openadapt_flow/repair/auto_repair.py": "dd4270718c906eef6d89939d5bfdc5ae63d842ab78bdc55f45b5afd425507c79",
+ "packages/flow/openadapt_flow/repair/campaign.py": "520e08184f5abe0bb53a4e08eb2d314e89ad3cc0636069573ca26bdfa82f20db",
+ "packages/flow/openadapt_flow/repair/candidate.py": "84c8a1da1d052c33ef4ade3e441644f108abbe0fea9834413bdddcbd450f7d5f",
+ "packages/flow/openadapt_flow/repair/cli.py": "b600b9920a3dc6e993f96c38d4914fc44458a9b9bcdfee807f58660a41b342dc",
+ "packages/flow/openadapt_flow/repair/cloud_review.py": "eae37867caa636115ae63adb6018987c322bfceb78a25c4178f4287bd13bc6d9",
+ "packages/flow/openadapt_flow/repair/dialog_fixture.py": "7969fe9c3e4373e32873a237867e182f8c2933397e2c47614216c5ced59a4e9f",
+ "packages/flow/openadapt_flow/repair/dialog_identity.py": "77e828471626051c74e502c29bce3ec2356926b38b6ddd83489b7bdc3fff3dd8",
+ "packages/flow/openadapt_flow/repair/element_identity.py": "337dc232e727b7388221c042e0eb2ddd9b7b11b3de73b1c3e88c6f80f23c16ed",
+ "packages/flow/openadapt_flow/repair/hold.py": "9b34c9d1bb9fb12d4077d18bf19e9e389ca98ae0e2ea8faecc40e2da267d11ec",
+ "packages/flow/openadapt_flow/repair/invariants.py": "c645ffc37b7135018e0783955b77a067e719e99765d70ccfc26812b3e0336d45",
+ "packages/flow/openadapt_flow/repair/lifecycle.py": "98758330dd9cfbf8b53d39071848b6319f2ae3b328a914be84ae44873abd64df",
+ "packages/flow/openadapt_flow/repair/preflight_queue.py": "9ca1d23b744218745a660fd3b57233f41366c72c9603673347326854cca49b5d",
+ "packages/flow/openadapt_flow/repair/readmission.py": "39a35fcc0a2c804b2465054aa0a8803a6b934d2abb8427fc7f79bd5c59629630",
+ "packages/flow/openadapt_flow/repair/registration.py": "0d2166fae57ee43aec1361645f73b9472cf709c5ba63749f51cca6bd3f84ed24",
+ "packages/flow/openadapt_flow/repair/relabel.py": "a1b870b14175f073153fbf9b80733d7fd34ac766921a2924e292f4e86a96921f",
+ "packages/flow/openadapt_flow/repair/self_repair.py": "771ad3af601bf3385865b1335202194dbd8c300c3fac3d3e5cc82ecd7895f62f",
+ "packages/flow/openadapt_flow/repair/standard_change.py": "b67523f9d78a4a544a90fb79694e321a90601e9885ade8f302f09d39d96ff741",
+ "packages/flow/openadapt_flow/report.py": "288b62601328e4630f2db0f1a7af48b3fcf9db36340c370c51628dfe889ca373",
+ "packages/flow/openadapt_flow/report_redaction.py": "fb5f25259dbe76c42e2e541749a9db941c43f536b0c59b92221791afd915b6a2",
+ "packages/flow/openadapt_flow/reports/__init__.py": "51b2ae3769609912e56518619972b551128a0ae9bd2af0e7661ed32629ce16bc",
+ "packages/flow/openadapt_flow/reports/parse.py": "5732213e6b7290ad8339bd9559d2e25394fe631c0ee289a5bf34d32991f79817",
+ "packages/flow/openadapt_flow/reward/__init__.py": "a16f606b5333fa2a0732ba0a3ae643125e6831f8c923fd17940194fab25eff76",
+ "packages/flow/openadapt_flow/reward/bundle.py": "46e2a272f7592534e6f27945eeda2a1fdad27da6a309d035913eb1ba5e1bfa1b",
+ "packages/flow/openadapt_flow/reward/calibration.py": "5d54500f75cbd442e5194cde11674099bf3428d72611d8e8aea2a49e1c0a8a61",
+ "packages/flow/openadapt_flow/reward/callables.py": "a5736681e02b8862da15a81c95be78112d2d61741177f3895ae05941e5c4b913",
+ "packages/flow/openadapt_flow/reward/models.py": "343c3bfb3158e05325f364c063b1198c47c8725a39151779c42d3a7242d600ac",
+ "packages/flow/openadapt_flow/reward/oracles.py": "55c5e0c667f0777e0599a2330355a655dd9c77da0dc4b65282f56d30d01515c2",
+ "packages/flow/openadapt_flow/reward/seed.py": "1024757f781c9dd06d969138a098651aa57c6a9fbab11b07831e22f47911687f",
+ "packages/flow/openadapt_flow/reward/serve.py": "c8bf963939d991c1ad55ca7ac4ba50d3d632f70693793b92a2fc07fbb003e5da",
+ "packages/flow/openadapt_flow/reward/worker.py": "9986fb2fd3280056fed914170d7bf5ed6a5ad45d51a30ab2be87e9c8963e520a",
+ "packages/flow/openadapt_flow/risk.py": "f63459a5a55b24b1890edfee22e575d1ec6e1cbdb5f4a430ad27d009902472ec",
+ "packages/flow/openadapt_flow/rl_env/__init__.py": "2fe82b5386d41a7907880a929b9c025db5a14620a555322e0a81f16dc0f5f243",
+ "packages/flow/openadapt_flow/rl_env/agents.py": "8b36ed11d8bb28a1cc443695925142a3a4ec4f6971d2637c6c60d89e4df19825",
+ "packages/flow/openadapt_flow/rl_env/desktop.py": "75262271ae87ced93ce898a16498492a66985ed80f891800962b8021f2066948",
+ "packages/flow/openadapt_flow/rl_env/environment.py": "532db6c47d41d5007c0300801930577ea56de3a6335707dedd1db1195edbebbf",
+ "packages/flow/openadapt_flow/rl_env/parallel.py": "13095c72ed367279dccb6360f945ee1b38d13f57c6b464e840913c263fa5e874",
+ "packages/flow/openadapt_flow/rl_env/reward.py": "59796f51df0cf0f85bf896c03edd4f5457d3af4a78359d6691d6d1ab14ae14f6",
+ "packages/flow/openadapt_flow/rl_env/server.py": "469f84e5a0adfbd5e08f20a39d81a142afad67408135f3482dab23758bee5013",
+ "packages/flow/openadapt_flow/rl_env/tasks.py": "cc075797af232227ed5fcf434d5c8f0da3e1f42705cc1648eaacd29907202582",
+ "packages/flow/openadapt_flow/rl_env/typed.py": "b468b29f6c2ba64b23b7f9641b804637245c65ae1f9146360b87ce6b6b43521a",
+ "packages/flow/openadapt_flow/rl_env/validate.py": "fda4f484e1bbd8d6cd05df6f89c1f56a734513448f07079357387300603f8603",
+ "packages/flow/openadapt_flow/rl_env/validate_desktop.py": "2419d37924fe9b502f718fa49681a5b69a4d871a820c27d03fd2e7c7eb9238bd",
+ "packages/flow/openadapt_flow/rl_env/windows_guest.py": "106ba1189718296ef594f15207815191feee4e07225533b49daab187bafe9200",
+ "packages/flow/openadapt_flow/rollback.py": "1ed498b261add28c5faabb9bd75d8a3c1f114bbd69931bcfa46d0e4fb18aac98",
+ "packages/flow/openadapt_flow/rollback_durable.py": "88302d9158fce87884be891cca59db21a4b2ae303fee93dad3f45fe37cdb4677",
+ "packages/flow/openadapt_flow/rollback_qualify.py": "81d47df7b8f669d029833772365f6ef507aaa95f8a7bdfcb0c2cd1765352ef85",
+ "packages/flow/openadapt_flow/rollback_state.py": "a59a85a4101d5188c400e34d716859c7031db12b0d861a5649a6c2c7943131ec",
+ "packages/flow/openadapt_flow/run_authorization.py": "eef848a71340e8951d80f421872d82ffc79098025fe9e9d4d3d2aecb50d93464",
+ "packages/flow/openadapt_flow/run_gate.py": "2297a7c84efe4b10788808d2e0fdd189d6be3a5a20dfb33be338365fad7306cf",
+ "packages/flow/openadapt_flow/runner/__init__.py": "1111900db86ee0f61faa093996a6e64a1405c9052bb74f186afa1a84a60ffcc0",
+ "packages/flow/openadapt_flow/runner/business_decision_service.py": "97bab36f3c9dbc9974129a34a5c636dba08e7fbf3c56fc522ed507feae216bd4",
+ "packages/flow/openadapt_flow/runner/commands.py": "92a62d244b406c405cdfd51c3189a835878f0e334fc74e16e98a1acfbca47ba3",
+ "packages/flow/openadapt_flow/runner/config.py": "ba84ed0b0638ee12de51f40fe3fa4da13c14effafbbba7bceab256e56664fc2d",
+ "packages/flow/openadapt_flow/runner/dispatch_envelope.py": "4a867de3740e46b67ecf90b74120f53ad038d7c0aae9b17c6bcefef998ec674d",
+ "packages/flow/openadapt_flow/runner/evidence.py": "4f884203b69f3368b56e7bd0a31df123a28f5c7b464fa73a69b1da742fd7fe76",
+ "packages/flow/openadapt_flow/runner/flow_release_receipt.py": "1e80b5d956de0debc12e5a14f4595256eb13caba16d387e8193ad1737be4ae18",
+ "packages/flow/openadapt_flow/runner/hosted_adapter.py": "0e2f0e5e96a609dac3e78e516ceb8e6a0050f6406a8a6e4e74f93381781e3eb2",
+ "packages/flow/openadapt_flow/runner/inputs.py": "711464bd021afbde06b9c4d132ea782c3b6a321ea48bcb24c3f565f8609f8a9d",
+ "packages/flow/openadapt_flow/runner/lease.py": "9ba80da689f4eeec85d44a860a27851e2408e3772b135bd01e4c4a0996d77c60",
+ "packages/flow/openadapt_flow/runner/outbox.py": "19454f29bb30bd8707f452a00e6fcb3511a1fce1b70ee2401d5d40d2e11e496e",
+ "packages/flow/openadapt_flow/runner/product_release.py": "072ad1a818fd1ccd7bfbe2995ee90825111890dfb4c1bd9b72275350107adab3",
+ "packages/flow/openadapt_flow/runner/protocol.py": "02ab8b7ce4a936d8533cf99a58f68fb5281b2afce2f17b99dbba27b0eeaf7e82",
+ "packages/flow/openadapt_flow/runner/verify.py": "473bab048ac39adfd9020816e81ea969c05856993e4029e17ce9bc9ba237d92c",
+ "packages/flow/openadapt_flow/runtime/__init__.py": "fa78a3356ae6470aaab3c3093c57502ac8aef9b1ecb03ec2f4ccbc2a0c0b9f0b",
+ "packages/flow/openadapt_flow/runtime/actuators/__init__.py": "597b6f56b00bb79c7f3a4452f602d1746aa0acc99bebc1683ce71ceece5af59d",
+ "packages/flow/openadapt_flow/runtime/actuators/api.py": "05fb4e35a9cbb2c85874bdc3d5df1aeaf4f5ba1e011ec0e4ae8b02aaaab78a13",
+ "packages/flow/openadapt_flow/runtime/actuators/form_eval.py": "39ade168ee3029b501cc4eecc6f33d6b23a3b48c51b3f3f9bb3c9391422f495a",
+ "packages/flow/openadapt_flow/runtime/actuators/web_form.py": "5f69d401eefaec75f1a8042f5178462ac1cbb468cc787c2549c7ffd956cfee6f",
+ "packages/flow/openadapt_flow/runtime/admitted_composition.py": "cbe722002872533c37797183d6efd3b42a5e65f95759e0e8d28a5dbc1794ec07",
+ "packages/flow/openadapt_flow/runtime/authorization.py": "18876e85bbdede3aa6bd98068cff49170a908f10d2374a755e7b0986d039f461",
+ "packages/flow/openadapt_flow/runtime/composition.py": "888011575a90153a22a474e0316f8eb41d76e2424a020f235557da80deb6e9e6",
+ "packages/flow/openadapt_flow/runtime/control_overlay.py": "b141f20afa76036f7ab20ae19d97293f7dc0ee20b0aea2c7d23061dca4bb3aa1",
+ "packages/flow/openadapt_flow/runtime/durable/__init__.py": "32d5846e0775819d84e903485f1c32a14774d2ee3d4f3322335182afd68f8826",
+ "packages/flow/openadapt_flow/runtime/durable/approval.py": "2b3e5eb95ae02d11dfe75d3970cbb65f8b04cf8c7f066ed8b8aa1bba3da034ba",
+ "packages/flow/openadapt_flow/runtime/durable/attended.py": "061f871aa82088506da046d2705ada74fe7a246772df8d20e56518c41d674441",
+ "packages/flow/openadapt_flow/runtime/durable/attended_service.py": "d621f4785ec37afa9baf1ab18622745cae498eda0f91d903a7e3b8ffd54f2426",
+ "packages/flow/openadapt_flow/runtime/durable/attended_state.py": "6ee0b25ef54e88338b3e580283fa8fdcf820fd016451a822969498d8803c8d96",
+ "packages/flow/openadapt_flow/runtime/durable/authority.py": "57f2312f27e7bafe09513807e76298d29876aec32e03f74d82bededbcb600dd8",
+ "packages/flow/openadapt_flow/runtime/durable/business_decision.py": "dff9bb63163561045318f2416420e9d96c1c69fc6f1f31eaa00e50fc41083e63",
+ "packages/flow/openadapt_flow/runtime/durable/checkpoint.py": "c00e83092e95e632a1773185498d409f9d31a0e71762f66f63ef24d185661e2b",
+ "packages/flow/openadapt_flow/runtime/durable/continuation.py": "5eb5319b3b5a1a52c73d6472418aeefbf961fff41743412a9c82afde9df9b542",
+ "packages/flow/openadapt_flow/runtime/durable/controller.py": "f6644d8c4c657e7d847cca846f6d89722fe8ffc2a19ee427cebab6ce9b60ec21",
+ "packages/flow/openadapt_flow/runtime/durable/program_checkpoint.py": "1945df32ff1d418c5eac7f9f02fe29297da315d6e07e395cb706312ab1d2cf53",
+ "packages/flow/openadapt_flow/runtime/durable/resume.py": "1d1f3939714fc7f2b74aa3ee1cafb56db182db1c25d8589d07ba5f4ff483f1b3",
+ "packages/flow/openadapt_flow/runtime/effects/__init__.py": "26ee73ae1d836050ff796e5211f649d89a416ba171a9aa7449ff8079795cfd6d",
+ "packages/flow/openadapt_flow/runtime/effects/_common.py": "fe80ff93215a0f8126e0aab4a39c1eb4cf67a6352efb7ce33d76a0be0fe9a878",
+ "packages/flow/openadapt_flow/runtime/effects/adapter.py": "6b44cda61a78ce3934db28a6b2ce1ccadac5a52a99f8bbc225346f602116b5a4",
+ "packages/flow/openadapt_flow/runtime/effects/auth.py": "af0c2be6ab49f998aaf404800a0f5c8a3a35f30f08dda609cafa8b49ea622f91",
+ "packages/flow/openadapt_flow/runtime/effects/compensation.py": "d162cf54bd6b7cd8759486a8876efd072e29146d81a0c14d9e76770a61783293",
+ "packages/flow/openadapt_flow/runtime/effects/db_snapshot.py": "8bf04887ad611146c26dfdf094ce47552b0b158ed6eb0220ffe1fb455c69928e",
+ "packages/flow/openadapt_flow/runtime/effects/deferred_report.py": "f0e94087724acedad688e46c6a6375b1e6c24aa42abeafb10682eee71d9b9526",
+ "packages/flow/openadapt_flow/runtime/effects/desktop_readback.py": "6ac9ab08c1a4f385c34475fc90f9368a8730fa9b8e59b22c2d8b067dad46be61",
+ "packages/flow/openadapt_flow/runtime/effects/desktop_readback_sessions.py": "85cf7364d4aaa4fdc6673610c4ff387e602a349ff5082acda446f048a82fbf92",
+ "packages/flow/openadapt_flow/runtime/effects/document_arrival.py": "1f62bb1c46f0f9521610a152fe68340a96014bc4a8d293d6681ef5099acc1307",
+ "packages/flow/openadapt_flow/runtime/effects/document_hash.py": "5c64f1ffc187cd03114d61dff3518080e59b817f8b1c3424dbc4b57db30e1f04",
+ "packages/flow/openadapt_flow/runtime/effects/effect.py": "9fe46e7533979621a7c3c08c35a7665e4846e59424cfc69c8cb62d7724c0a814",
+ "packages/flow/openadapt_flow/runtime/effects/email_delivery.py": "bca21113e2c8fc3f3820fd1c0e27c16f2c5db920ccdd05275477bd08884b6ce2",
+ "packages/flow/openadapt_flow/runtime/effects/fhir.py": "20590b70e9dfde931f560695d49490ff10318f87439877657e793c1df89ec9c7",
+ "packages/flow/openadapt_flow/runtime/effects/file_arrival.py": "8a5dcb94534e9f3ef40fa820cc18ae73e45f626137f0de856941c3adcfc235e5",
+ "packages/flow/openadapt_flow/runtime/effects/frame.py": "e984cee555c61e01e5e2c6c2033d4513859d4afc5927fcc72ae876cc9a545fe2",
+ "packages/flow/openadapt_flow/runtime/effects/fresh_session.py": "0603645b9f18b5d7a7fd6eec50387b7f1a6aa07d44dd36993afc89a78353dee7",
+ "packages/flow/openadapt_flow/runtime/effects/graphql.py": "cebae9844af5046963fdaba3abaed3ed1f9b1084dedd1a8948ac454b64990e26",
+ "packages/flow/openadapt_flow/runtime/effects/late_write.py": "a158374ccba1861df4ee23bc1330b57d141df64cf5c5b83c0b9410a5c570e577",
+ "packages/flow/openadapt_flow/runtime/effects/learned.py": "e1a2de2f30f12adb12db2888b6be5a5a993ab73ea3c7b86ddfb3bc46e191c833",
+ "packages/flow/openadapt_flow/runtime/effects/onscreen.py": "a9767dfca331d425e7f9b60a147305087cfc53499754ea4cc866c06307dd6a17",
+ "packages/flow/openadapt_flow/runtime/effects/readback_values.py": "783239fefb4bcbbe76d195de4a94eb4cd246f8e9e6f4117aa8c78dbf78ec0b5d",
+ "packages/flow/openadapt_flow/runtime/effects/rest.py": "6e1d80a9cad6c50bed7d42241db2aaa8e9e929ba37cd89d2335e07c7ae7f3add",
+ "packages/flow/openadapt_flow/runtime/effects/sealed.py": "d763c49a9e4382c4160e33e0f8e6de2e1c86b59ea9cccd9b41a7328264c6f141",
+ "packages/flow/openadapt_flow/runtime/effects/smart_auth.py": "57dc86cbd4249d528148d6c47a0bb5eec56d9c2e854ede8e0a97a7dbe8cda15d",
+ "packages/flow/openadapt_flow/runtime/effects/sql.py": "42210633b40a3dcc0f9ec6742c10ddb6656db2a1e2c90b9c92281488ab4ad330",
+ "packages/flow/openadapt_flow/runtime/effects/surfaces.py": "5841fc1d7e97dd481964e354df5185136aa8759cd90c94d5ef2e71a21cec423d",
+ "packages/flow/openadapt_flow/runtime/effects/ui_readback.py": "94a7291c95e672d8611949a4d923a26061d5b938a74d706159644b23ce7eb476",
+ "packages/flow/openadapt_flow/runtime/effects/versions.py": "970e6ed27c5246ffe082cf1e68a9e86a3e677152c19247ebcefe286c33fa55c0",
+ "packages/flow/openadapt_flow/runtime/grounder.py": "75e90667e536b4fd10612a29fe19b183da72bf8ef08f8939c59e1425b1339e4f",
+ "packages/flow/openadapt_flow/runtime/heal.py": "edda48b9a0e0d38ff4b639d2a3f1d986d3b7b24671e1c20f064366ce96021f44",
+ "packages/flow/openadapt_flow/runtime/healing/__init__.py": "7f2b58eb0e8d53394d9764066378e228f4dcbd8fd48b143b3497c11167b6ad80",
+ "packages/flow/openadapt_flow/runtime/healing/governance.py": "f3a755d46bbd7eedbe6b0ebc962cc2073714551eee34c7f5f2faf002623d3222",
+ "packages/flow/openadapt_flow/runtime/healing/patch.py": "2a918bfbe9523c7946085581465bc6fae5735ba9d9e46e2a0a04e4a841fdadb7",
+ "packages/flow/openadapt_flow/runtime/healing/perturbation.py": "18159ae5a273b33b90ee677164e44fe794bff4c8cfa96a9d3d0f9f8d12166f18",
+ "packages/flow/openadapt_flow/runtime/healing/pipeline.py": "d31fe159c6a9d029d0f9c7ec6d9b71cd006a51e71945bd4bd493b405075beef6",
+ "packages/flow/openadapt_flow/runtime/hover_evidence.py": "bafe2cb6ff8ee205a510cca79bf1324a316d0ebc5728e5b9e8581290fcdd0790",
+ "packages/flow/openadapt_flow/runtime/identity.py": "5da03135b8dc171882cfe6f40d3256baaf9729d8cb210e1463af9fdb7fed6b0f",
+ "packages/flow/openadapt_flow/runtime/identity_census.py": "690cd1dc5083b53d18ef5d8d7d768dde12b0c4a87dafe769f7883eff3f903be3",
+ "packages/flow/openadapt_flow/runtime/identity_looks.py": "3a80471cb4b3c71f5d1a6e0be455ad7bff3d05c19a3be278233672b5c4674eaf",
+ "packages/flow/openadapt_flow/runtime/identity_template.py": "9d9303cb49a194f5530d4daf7ade24fc9839efe01fe0a5bc44456aa7e9024b8f",
+ "packages/flow/openadapt_flow/runtime/identity_vlm.py": "be1151e8bdb3cafe428b5dd25579d6c5d7ef7b47c18ff3f9687d56f94a229428",
+ "packages/flow/openadapt_flow/runtime/known_ids.py": "42e719c1f2618431a5a722b50e6d832873f059534e22922fe57f6454c543ead1",
+ "packages/flow/openadapt_flow/runtime/layout_drift.py": "b385273433c782841482c331ceb3e1819d5a9362a1acdbc168d1da395f9ad56a",
+ "packages/flow/openadapt_flow/runtime/list_guard.py": "9471aa4b414fd795a156726758ffbb12998a8d7b40766c005c7475a29db495dd",
+ "packages/flow/openadapt_flow/runtime/list_source.py": "603aa2ba02841f9ab8f7c71911d7288302edac3acbca87bb54046111cc8b158d",
+ "packages/flow/openadapt_flow/runtime/local_grounder.py": "97820b33e69270f07c84873a224a93d5e5cf78c80ee6e0e8fb8e1be4992ee83d",
+ "packages/flow/openadapt_flow/runtime/process_v1.py": "ee6259ec2ec31cba34511db6a628b7d52a9c8ef5977a1e18ee3961fd82df60bb",
+ "packages/flow/openadapt_flow/runtime/program_predicates.py": "7d3f387a3ef0c2eb7119f46567904b65e52dd4ec6ea91857aeebcdeeb87d5a79",
+ "packages/flow/openadapt_flow/runtime/readback_pipeline.py": "bc00ae9d8d37a561646f31b18ff6acc94e6a1f8802a56f7514dd63e6c9ceb304",
+ "packages/flow/openadapt_flow/runtime/remote_vlm.py": "cc00a062f99e2f4abe608346fef912da5f2eaed9d90fc2d6a4c4f17debf7fd97",
+ "packages/flow/openadapt_flow/runtime/render_scale.py": "81cf507214e432ac9279bb09398dc20ac187c1d749913afc8586af49accd5638",
+ "packages/flow/openadapt_flow/runtime/replayer.py": "a457dc1866e16189e7de86992a52890ac819da4bfe59b18a7205bc8611aa1749",
+ "packages/flow/openadapt_flow/runtime/resolver.py": "e080e0c4640fe4371d3e57cd1a7a0e69f07576abf3ae31cf0f98037251152b66",
+ "packages/flow/openadapt_flow/runtime/speed.py": "3ea92c67afa3766fb0e1aacc34b3d2bcc5fcc1d397a23904cc20d10adab3d088",
+ "packages/flow/openadapt_flow/runtime/step_timing.py": "8d0f0f851eeb4c4c331b52c9376e6527a3e40134f2500204804cc1a9ce269ef8",
+ "packages/flow/openadapt_flow/runtime/surfaces.py": "34e5142a4138cfae191a404950c04d8efe48b7526e8a4dce3b05953f4191cb28",
+ "packages/flow/openadapt_flow/runtime/target_param.py": "43de5d0653b793d90066c6b386c4e64bef87a70a903623480a380a2f87ae7bf3",
+ "packages/flow/openadapt_flow/runtime/variant_router.py": "f48e93dbb1b6a0d8b36c6279df734cc7f4b99b939e7a8be6d9a9c5679105b413",
+ "packages/flow/openadapt_flow/runtime/variant_stamp.py": "9bba7d2fa3b81008040cbfdae52311b6c79ac24bb85e3799e3e136c08491809b",
+ "packages/flow/openadapt_flow/runtime/worklist_pool.py": "f58ee9837fe7ce459dd1b774523283739df408224d1998291b9385aa38c80845",
+ "packages/flow/openadapt_flow/runtime_validation.py": "a5a220f570c5ee5769ac2f21d8d140bb69373d4de2ccc0ebfd08540122883f0e",
+ "packages/flow/openadapt_flow/safe_errors.py": "2e04e744a32e4a5621d22c229b1257f6e38c26543ad449485eb87cafe9479da1",
+ "packages/flow/openadapt_flow/sanitized_artifact.py": "4464041bae067c9330ce797d0c659c9638db00df4f6a88bbc9ac6aaf0bce2ae6",
+ "packages/flow/openadapt_flow/scaffold_verifier.py": "8df9652aded917e9660ffc0d779fecfe09d1f98b7e77cae10e211dca13eb9357",
+ "packages/flow/openadapt_flow/seal_anchor.py": "e54b0fba6ec9d390ecb3d81bf2f5049a20b7c9b36fe8dec7dc8b741cd660347a",
+ "packages/flow/openadapt_flow/seal_batch.py": "c93b91fb0401d7fb3810b304c1e99a5817b82c346927c83c96cfd77892d31415",
+ "packages/flow/openadapt_flow/seal_keys.py": "63c80bad5675fd97808fe0093fd1a01b0c9919c3545fd11b30197feb86ad7e71",
+ "packages/flow/openadapt_flow/seal_timestamp.py": "9d39f36b4dd56bdc5f7a0ceb526e9208a790f648e7108a5684fd24670e4f6f66",
+ "packages/flow/openadapt_flow/sealed_set.py": "8000dc6e370011b85574d75496a299ed3c12626477038fc8341612091e805fcd",
+ "packages/flow/openadapt_flow/section_capture.py": "cbb98dd22dc57ad01b887180f9dc47d4af616a5f556eb225d91eddae005d07fa",
+ "packages/flow/openadapt_flow/sections.py": "4001315490d7a921f2ab7d08b47f248ba26facb4dcbc858d79a357cb91fb7c6a",
+ "packages/flow/openadapt_flow/services/__init__.py": "f38b556ba34b1fc674267a2c386edf9beb542d5a98c8e266b70f61ec6a617ba4",
+ "packages/flow/openadapt_flow/services/vlm_service/__init__.py": "da71deb7edc5ea6c30c250faf4cb39b4a76b532801debe6f64598b5d2ed8978e",
+ "packages/flow/openadapt_flow/services/vlm_service/__main__.py": "3844e4479038b670ef897697c71c05bb8e9f92136425ff899137501b3fc60966",
+ "packages/flow/openadapt_flow/services/vlm_service/app.py": "808094e2285b70965cc7f84a2c6037749ef29304318e1986c3dbbf7e4a1ec9c0",
+ "packages/flow/openadapt_flow/services/vlm_service/backends.py": "771df17902dc1c31e44517880706468f0c3dd13ee8dedc161ca60f159e1d9255",
+ "packages/flow/openadapt_flow/services/vlm_service/batching.py": "545ceb328637acbbaf343566059bcd23ba61ae9b385c6d32b14844a08c074971",
+ "packages/flow/openadapt_flow/services/vlm_service/config.py": "0bf363d7be1419ed1dd1597230a2be87d880473e5d19df4a9b8ef5e2f33a1bee",
+ "packages/flow/openadapt_flow/services/vlm_service/prompts.py": "f3af38485a7f61ad96fdaf066387c4809cf34b60cb96147ac186caa828cff1c3",
+ "packages/flow/openadapt_flow/services/vlm_service/schemas.py": "ca2de9068dcdfc45ca2b33a73fe5b51edaef0c27299b901ec5b340aa0143462f",
+ "packages/flow/openadapt_flow/shadow.py": "9e4c276ff4f189bf429dff7053ef9160fcff161b0b82746fed232a197a566cee",
+ "packages/flow/openadapt_flow/shadow_report.py": "ea79a2129bc99189171c418931fdb57fee55fe8a638977cc88dd21733167e428",
+ "packages/flow/openadapt_flow/skills.py": "9f99447dd927226fcf5122497b1b607b5a098b911ceb00d44f7bdbf0e22fb051",
+ "packages/flow/openadapt_flow/ssh_sig.py": "095ab479ed182611a416b442a25bbb86c811f1cc671b08e99e631ae8ef157d88",
+ "packages/flow/openadapt_flow/submit_binding.py": "985fe6d313ef281d3360e104cd12c65f72838e1940daebfb6ea40851d4641369",
+ "packages/flow/openadapt_flow/surface_bindings.py": "6b5f02db23ce8ec01bce2eecad6f822d743445547f62a0fe9c6286d50f36d762",
+ "packages/flow/openadapt_flow/surface_selection.py": "150481be4c3509a07e69a5e2a9ec2ebc8d8f48578d16c14f1633feb5a5b613fd",
+ "packages/flow/openadapt_flow/teach_authorization.py": "b7de7d85e79266b27efabf13d60e442e0f54b6d0e2e9c1ad9feb11cf4a195e81",
+ "packages/flow/openadapt_flow/teach_authorization_fixture.py": "1b392eb547257871ace4b0576964ff5e726c3665ac3b8274833d0e08a3400f6d",
+ "packages/flow/openadapt_flow/teach_scope.py": "0befa9f4692b27980123622507c5de76cf22ce65415e4a078634c1d84531d475",
+ "packages/flow/openadapt_flow/terminal_verification_v2.py": "3bc44d80abc3679cebdeec123b34bcc5656cd2624b1c8943bb22352c0efc3261",
+ "packages/flow/openadapt_flow/transaction.py": "2d1da876951335d06301757d01607d588dac9146e51e55ca212f120542dde179",
+ "packages/flow/openadapt_flow/traversal.py": "4bec0fcd5877649e71f7273a17a2073d56c83af6cb7fcd595d0eb9bd7f7a387b",
+ "packages/flow/openadapt_flow/tutorial.py": "51a21f2bd8aa99ba1d97a3f0a3e8f2cefc856e3c52d8294449b9eabab576c6d8",
+ "packages/flow/openadapt_flow/undo_proposal.py": "e09883af1fd9741ed876c75a3209ef16bae42b99790c4ca0506aac559f5ae7e9",
+ "packages/flow/openadapt_flow/validation/__init__.py": "d7f94f2027a19347364cf9491a94f9e6d8c497cd4a67e555e9d200d406e35e0f",
+ "packages/flow/openadapt_flow/validation/behavioral_generalization.py": "1540c508721eb77fcf1ae5f4b8dc19d88c59e65ec93a71e4ddb88e86878bda3e",
+ "packages/flow/openadapt_flow/validation/dense_surface.py": "c851d7d90704c59eb2bae9bf1c589df44956190989961ef001a60ac7434211f6",
+ "packages/flow/openadapt_flow/validation/governed_run.py": "d7fefab39d409381c338b015b9b44f4c757f6bcff693699eef78d73f1f2a9659",
+ "packages/flow/openadapt_flow/validation/hardening/__init__.py": "f54bdcaf0e0e1c8706e1262d983b7d57dba12e7c3912c50aaec148cc4a6a352a",
+ "packages/flow/openadapt_flow/validation/hardening/__main__.py": "6a2637d07c62e55e6d46dbd277e7c5d499426044120e949532010efe988aeb75",
+ "packages/flow/openadapt_flow/validation/hardening/corpus.py": "927d3f60d1971b82175c6a40a4b45116ba1339e8bb644da5750981e3770e068f",
+ "packages/flow/openadapt_flow/validation/hardening/fixtures.py": "44e85d3c03f03bd46c017a15e46ebff0fee483aed0d76045120e3c43e631318b",
+ "packages/flow/openadapt_flow/validation/hardening/harness.py": "f214c456ded5c2b27eec1fbe1810c5c7d0467960459baecb04c810df4f978e18",
+ "packages/flow/openadapt_flow/validation/hardening/perturbations.py": "fe634c8e6878766beea377bd0c62a6ea681d7ff883ff2896c98941a6f3112583",
+ "packages/flow/openadapt_flow/validation/identity_ladder.py": "4fcb0e3313de20fa3a148d2917aa2b3517d4438561aa140b244b931dc5081880",
+ "packages/flow/openadapt_flow/validation/identity_looks_dense.py": "ae482b821207e4dc5e6ea825f2d4bedf3cd8528dbbf516e732edbaaca6fb57ef",
+ "packages/flow/openadapt_flow/validation/identity_rates.py": "d0648e8e94b96677366ac5372453de797f6221a8aa5c799fe2327674d90c851c",
+ "packages/flow/openadapt_flow/validation/known_ids_dense.py": "9dfcc761b649e83f781e3390077b1c7eea60b4bd16c92e2dae9dd02173192835",
+ "packages/flow/openadapt_flow/validation/pixel_identity_aligned.py": "dff6c6f9d7ae1788f906c42b2cf443e34f93baf3d26d645413b2c84b54933053",
+ "packages/flow/openadapt_flow/validation/pixel_identity_probe.py": "66095f52fe8de431a3ab0cf68ba02202bb459b46927e98d7ae6bcf4c68d7ef49",
+ "packages/flow/openadapt_flow/validation/structural_action.py": "1cb3117f7c2efc9bd6d6a6358d5be167cbbf6b2050df6c133b90f441b75e6118",
+ "packages/flow/openadapt_flow/validation/vlm_identity_probe.py": "f3641e289f0a02e80fcb31ff76c34c0ed150c647fa9954252425db2b7659b713",
+ "packages/flow/openadapt_flow/variants.py": "3f434bf5caa78dadc908085a3b9a3586177928660be0ed8854301edcd6f2a2ec",
+ "packages/flow/openadapt_flow/verification.py": "0bb9f564b4d3dccce7fbebad64abaae1cbd4bd600ffa1b58ec18d9025df52ff2",
+ "packages/flow/openadapt_flow/verifier.py": "b18c244e18e1e0a69c4ab333a80805542987e9ab68e70decfd3357dd3d05c3ef",
+ "packages/flow/openadapt_flow/verify.py": "26b3e327a1dec09f8c9a968133f090dababb58cf6178be3e89b11101bc9478f7",
+ "packages/flow/openadapt_flow/verify_run.py": "95ee80146238aed7c1c0c12b023e61264c1491c34e0320d8a7e3aee200e50bea",
+ "packages/flow/openadapt_flow/vision/__init__.py": "488c92f581189c81f2ba1e98ddb267119a0407b2c1497822ffa9596c02cd0147",
+ "packages/flow/openadapt_flow/vision/hashing.py": "60d5b56a991100310163007d6778d6bec8521826c3f586f6b88e6e1a76f1d70e",
+ "packages/flow/openadapt_flow/vision/imgops.py": "9cd252bcb3a8bab46795098bc29cd5cf988d77c96abd9687ba93b9252e3f53c9",
+ "packages/flow/openadapt_flow/vision/match.py": "b4d34620ef7aa9f68e922659554c02f51e2c20f9469febd88457d158163d213e",
+ "packages/flow/openadapt_flow/vision/ocr.py": "e42d4f2b84790ae16b80e2bb5c8c8108b2582a6a3ded8407686e8957d954eded",
+ "packages/flow/openadapt_flow/vision/ocr_backends.py": "3b38a83eeeb4a9191ad729c1f8e15ecb239ff7d061239b2fd1c3b65c98e35b26",
+ "packages/flow/openadapt_flow/vision/settle.py": "d81049501c6dc41a4713ddc3d4d8fbc506f4e2320ff7e5ca6a4a769e6a7a18f6",
+ "packages/flow/openadapt_flow/visualize/__init__.py": "8d791c4ae4fff8a56e5860fdd95c42e441ae462eb029cdc268d771eb0ade4c96",
+ "packages/flow/openadapt_flow/visualize/admitted_composition.py": "9758fb49a8d3e587204e3df921a42cf823921cb25f8c66e08cfec748337be8d7",
+ "packages/flow/openadapt_flow/visualize/builder.py": "53749366b83db4a49596cecd41859213ef38bb62f8fd98ed41c3b53dd7ea5211",
+ "packages/flow/openadapt_flow/visualize/composition.py": "52d42000d0747af577a6f4e2af0b4326c22790c3cf7fc2e6ebd05b83baef91d0",
+ "packages/flow/openadapt_flow/visualize/projection.py": "8993aa3c33779eac81490f055e31143f09120d047cadd43e94e226b6dadba9ae",
+ "packages/flow/openadapt_flow/visualize/render.py": "87887e31698e1ffbda8984f5212de5e2743fcd6fd637f5b20643cc8fc5a2c65a",
+ "packages/flow/openadapt_flow/visualize/spec.py": "68db48c9d4ffba499b9901a2016d2e95bf7f78f89af17d521ed47da16381e6d0",
+ "packages/flow/openadapt_flow/volatility.py": "117c9df0dcbeff9669f78b27455c5bc1ada762798c9a64393c30fdab5c29dfa1",
+ "packages/flow/openadapt_flow/wire_check.py": "f3ee4c8c5313b02428129128478c1fd30152f11fa5f77e5592debbceeea2fca7",
+ "packages/flow/openadapt_flow/write_ledger.py": "627a4e924ded7571280e57d2f54b81bd705a4d33fe8667ef1e7ab337c5db47e7",
+ "packages/flow/openadapt_flow/write_receipt.py": "a46af4d09ef42b9f48db8b0905d6bf787002b8e48dc3493b40ad4b22a1d0ad03",
+ "packages/flow/pyproject.toml": "7e05357e58b1a1b56fd7896b2aa0ff4b132f2616a9c934940daf156d8a6ca373",
+ "packages/flow/uv.lock": "005f88098f5acc2ae30f09b6f4a645e3fd8dc39db95750e3d70e9f18d7db50c0",
+ "packages/types/openadapt_types/__init__.py": "8cc924b5be7b9b926263a1bdb9b4d9120af85c805fb2762c877b3a28632e2351",
+ "packages/types/openadapt_types/_compat.py": "b4889a9291687aec404b5b6a83d98c4090f98f9d1aabf270798df0252d998147",
+ "packages/types/openadapt_types/action.py": "0ec10f7e6a840c09a48492abbf501d3ebe807fd06671657ae4f4c62137fba61e",
+ "packages/types/openadapt_types/approval.py": "27ed4f73dcb7c71dca80acd51e8b1087b55c6105c8c1e12c9796e94c98a0f0b9",
+ "packages/types/openadapt_types/authentication.py": "5a9d88de3de6f659e41ad3817abfc40902b3f3bbdcb6d55906a0fc1d83ffd3f1",
+ "packages/types/openadapt_types/authoring.py": "658383bed9a542b0e7ecc9dd451bc7de3e0771646e9da826acbcf5d2e69231b8",
+ "packages/types/openadapt_types/benchmark.py": "23640632a9c95cee35cd664d75aa8aa8ca5585259ead7221aaaff610f469d321",
+ "packages/types/openadapt_types/business_decision.py": "05932e2d37641390e2693520673bf926d5ceba388f8d702d9213582f66b0a3c6",
+ "packages/types/openadapt_types/check_level.py": "c999b800924fbeaf872b829607b453b63be8d5d4207d79733f641d6eac6c4ad0",
+ "packages/types/openadapt_types/clinic_job.py": "4719877cb2a1dee680d74d66a1d2f182bab8f86fbb7d81c3e82baf1bdab79d07",
+ "packages/types/openadapt_types/computer_state.py": "c2063f22364e9012ee852ff36f8a2a13f5015655a0b0d634fcd5755f813dbfa7",
+ "packages/types/openadapt_types/control_overlay.py": "3aa01f89b43e12478c9e2ff1a9e61689397370691d15247ded9dcd5b05242790",
+ "packages/types/openadapt_types/control_overlay_tracking.py": "af8d934f0572c5f4e9c63ba720d4a1d0e73c8cdf3f7b87cc4562c01a8a551755",
+ "packages/types/openadapt_types/episode.py": "5ace88d9e278d099c0e7939cc19e99bf18cbbb80d6ea7d606e3950c027baa8a9",
+ "packages/types/openadapt_types/execute.py": "a577cdd2d2c4e5db235acdb38ee92d15521fcba60267b8835d3bf68d228d346f",
+ "packages/types/openadapt_types/execute_client.py": "ed73a52a1f364646263b25132a2cd60db68deec2b33dfae2b92230402afccb57",
+ "packages/types/openadapt_types/execute_openapi.py": "4600dd2c8995e909c797e2022c22d7745e522123d28627d61e3dab9e7bf405c9",
+ "packages/types/openadapt_types/execution_requirements.py": "58a3fdb2a43b06af0f27b01abd812ccef6b226b6cfa5307f0b6ceff5f197fba2",
+ "packages/types/openadapt_types/failure.py": "26efb6e04d17c10cae8bbd688249ee44bcd7844a62be6736de984a6e881fa0bf",
+ "packages/types/openadapt_types/human_decision.py": "0bb39a3575f511e10d01d92858b340982adee2f0fc20d2409441dbc0b2c55c4f",
+ "packages/types/openadapt_types/oracle.py": "47a3060d5a49529d4f6506fc3116a0bf902e8b30431456154604ce8371195cde",
+ "packages/types/openadapt_types/parsing.py": "aae2ceaeead749c3b67619a271b87ecf2388496d37d5bf524834a884ff87a720",
+ "packages/types/openadapt_types/plain_results.py": "a1fc8b54434af25314e179fbd2670c60f9e52a2a08a4757c8b16d281cbc68951",
+ "packages/types/openadapt_types/process_capability.py": "8fa70ad62c586534884a73290710c9706291160d63397cb5543de1f2646114d9",
+ "packages/types/openadapt_types/production_lifecycle.py": "046f30559dac66e4105ad830a274cfb31e0374f95a7a8b0adc1b7dff2aba9449",
+ "packages/types/openadapt_types/reward.py": "9a5f8d012a8d81f75ed2ac75fc356d4db713edc604ea3bc67070e7f32fec93b5",
+ "packages/types/openadapt_types/runner_capability.py": "26fd3c1d96a5558c70886cf203c999d524b9bf927cde23d90735c90be9e2b427",
+ "packages/types/openadapt_types/schemas/__init__.py": "965365ce3faee699154d06428c2dd83414c18632ca3ba39516ef513523b8d618",
+ "packages/types/openadapt_types/seal.py": "bf4ac2e28b561b3ed80b3e1da2bb5cb0eb005a0cdc151dcf805fd02157bf5143",
+ "packages/types/openadapt_types/vocabulary/__init__.py": "b5f060d92bea3c0d8b1c15468c1564c3cf5ee864ee4bddf2393debca8f269bb4",
+ "packages/types/openadapt_types/vocabulary/__main__.py": "0d132037f99fe1d1588a9233ed179df7de0dcbf2d36ffb0fec294c98bd1d7acf",
+ "packages/types/openadapt_types/vocabulary/lint.py": "ee2a8c6279aa3c737fa2f49e09092c7f652dedaef513e59baf63dd19ba661060",
+ "packages/types/pyproject.toml": "4904ddc18342be5bf7da91f315d1bed91e60b35dc55d1aa3bdfb149af13415c6"
+ }
+}
diff --git a/packages/flow/tests/fixtures/bundle_compatibility/README.md b/packages/flow/tests/fixtures/bundle_compatibility/README.md
new file mode 100644
index 0000000000..59490be47f
--- /dev/null
+++ b/packages/flow/tests/fixtures/bundle_compatibility/README.md
@@ -0,0 +1,29 @@
+# Frozen bundle compatibility fixtures
+
+These synthetic linear and program bundles were emitted by the actual Flow
+2.2.0, 2.5.0 and 2.6.0 serializers at the source commits recorded in each
+provenance file. Each producing release loaded and verified its own output
+before the bytes were frozen. The current serializer does not generate the
+expected bundles or digests.
+
+`canonical.json` contains the producing release's manifest-free canonical
+payload and sealed asset hashes. Its SHA-256 is the original manifest content
+digest. This is content-integrity evidence, not a claim of cryptographic signing.
+No signing credential or private data is used.
+
+The generator refuses another package version or source tree, checks pinned
+source hashes, and writes only a new output directory. Run it in the exact
+historical release's locked environment, then freeze provenance and every output
+hash before running the current loader. The tests copy fixtures to temporary
+storage, verify original seals, reject tampering and replay one exact button
+click in an owned synthetic headless Chromium page.
+
+Changes to a fixture require new release provenance. Do not regenerate a golden
+with the current runtime to make a compatibility test pass.
+
+Flow 2.2.0's original lockfile failed uv 0.13.7's freshness check. Its fixture
+run used `uv sync --frozen` with that unchanged lockfile; it did not resolve or
+update dependencies. The 2.5.0 and 2.6.0 runs passed `uv sync --locked`. Each
+provenance file pins the producing source, project metadata, lockfile, Python
+and Pydantic version. These runs reproduce the pinned release source serializers;
+they do not claim to reproduce the original release build environment.
diff --git a/packages/flow/tests/fixtures/bundle_compatibility/generate_release_fixture.py b/packages/flow/tests/fixtures/bundle_compatibility/generate_release_fixture.py
new file mode 100644
index 0000000000..f72a7839f3
--- /dev/null
+++ b/packages/flow/tests/fixtures/bundle_compatibility/generate_release_fixture.py
@@ -0,0 +1,146 @@
+"""Run only in the exact historical release checkout, before current-loader tests."""
+
+from __future__ import annotations
+
+import argparse
+import hashlib
+import importlib.metadata
+import json
+import sys
+from pathlib import Path
+
+from PIL import Image, ImageDraw
+
+import openadapt_flow
+from openadapt_flow import bundle_validation as bundles
+from openadapt_flow.ir import (
+ ActionKind,
+ Anchor,
+ BundleManifest,
+ BundleProvenance,
+ ProgramGraph,
+ State,
+ StateKind,
+ Step,
+ StructuralLocator,
+ Transition,
+ Workflow,
+)
+
+FIXED_TIME = "2026-01-02T03:04:05+00:00"
+
+
+def sha(path: Path) -> str:
+ return hashlib.sha256(path.read_bytes()).hexdigest()
+
+
+def main() -> None:
+ parser = argparse.ArgumentParser(description=__doc__)
+ parser.add_argument("--source-root", type=Path, required=True)
+ parser.add_argument("--source-manifest", type=Path, required=True)
+ parser.add_argument("--output", type=Path, required=True)
+ args = parser.parse_args()
+ source = args.source_root.resolve()
+ expected = json.loads(args.source_manifest.read_text())
+ assert openadapt_flow.__version__ == expected["release"]
+ assert (
+ Path(openadapt_flow.__file__).resolve().is_relative_to(source / "packages/flow")
+ )
+ for relative, digest in expected["source_hashes"].items():
+ assert sha(source / relative) == digest, relative
+ args.output.mkdir(parents=True, exist_ok=False)
+ summaries = []
+ for shape in ("linear", "program"):
+ bundle = args.output / shape
+ (bundle / "templates").mkdir(parents=True)
+ image = Image.new("RGB", (80, 40), "#f0f0f0")
+ draw = ImageDraw.Draw(image)
+ draw.rectangle((0, 0, 79, 39), outline="#555555")
+ draw.text((25, 12), "Apply", fill="black")
+ image.save(bundle / "templates/button.png")
+ step = Step(
+ id="apply",
+ intent="apply synthetic change",
+ action=ActionKind.CLICK,
+ anchor=Anchor(
+ template="templates/button.png",
+ region=(40, 50, 80, 40),
+ click_point=(80, 70),
+ ocr_text="Apply",
+ structural=StructuralLocator(selector="#apply"),
+ ),
+ )
+ values = {
+ "name": "release-compatibility",
+ "created_at": FIXED_TIME,
+ "viewport": (320, 200),
+ "manifest": BundleManifest(
+ provenance=BundleProvenance(created_at=FIXED_TIME)
+ ),
+ }
+ if shape == "linear":
+ workflow = Workflow(steps=[step], **values)
+ else:
+ workflow = Workflow(
+ program=ProgramGraph(
+ entry="apply",
+ states={
+ "apply": State(
+ id="apply",
+ kind=StateKind.ACTION,
+ step=step,
+ transitions=[Transition(target="done")],
+ ),
+ "done": State(
+ id="done", kind=StateKind.TERMINAL, outcome="success"
+ ),
+ },
+ ),
+ **values,
+ )
+ workflow.save(bundle)
+ canonical = json.dumps(
+ {
+ "workflow": bundles._workflow_content(workflow),
+ "files": dict(sorted(workflow.manifest.file_hashes.items())),
+ },
+ sort_keys=True,
+ separators=(",", ":"),
+ ensure_ascii=False,
+ ).encode()
+ digest = hashlib.sha256(canonical).hexdigest()
+ assert digest == workflow.manifest.content_digest
+ # Validate with the producing release, not with the implementation under test.
+ loaded = Workflow.load(bundle)
+ bundles.verify_integrity(loaded, bundle, loaded.manifest)
+ assert loaded.manifest.content_digest == digest
+ (bundle / "canonical.json").write_bytes(canonical)
+ summary = {
+ "shape": shape,
+ "content_digest": digest,
+ "files": {
+ path.relative_to(bundle).as_posix(): sha(path)
+ for path in sorted(bundle.rglob("*"))
+ if path.is_file()
+ },
+ }
+ summaries.append(summary)
+ (args.output / "provenance.json").write_text(
+ json.dumps(
+ {
+ **expected,
+ "generator_sha256": sha(Path(__file__)),
+ "python": sys.version.split()[0],
+ "pydantic": importlib.metadata.version("pydantic"),
+ "original_release_load_verified": True,
+ "bundles": summaries,
+ },
+ indent=2,
+ sort_keys=True,
+ )
+ + "\n"
+ )
+
+
+if __name__ == "__main__":
+ main()
diff --git a/packages/flow/tests/test_artifact_reads.py b/packages/flow/tests/test_artifact_reads.py
index ab6f10facc..737c199117 100644
--- a/packages/flow/tests/test_artifact_reads.py
+++ b/packages/flow/tests/test_artifact_reads.py
@@ -20,6 +20,7 @@
from __future__ import annotations
import ast
+import hashlib
import json
import os
from pathlib import Path
@@ -838,11 +839,21 @@ def test_push_in_strict_mode_seals_the_review_copy_of_a_plain_recording(
def _bundle_with_a_bad_action(source: Path, out: Path, *, key=None) -> Path:
- """A copy of ``source`` whose first action is the private marker."""
+ """A sealed copy whose first action is invalid but integrity-consistent."""
+ from openadapt_flow import bundle_validation
+
opened = sealed_set.open_set(source, KEY)
files = {rel: opened.read_bytes(rel) for rel in opened.files("")}
doc = json.loads(files["workflow.json"])
doc["steps"][0]["action"] = _MARKER
+ stored = doc["manifest"]
+ digest = hashlib.sha256(
+ bundle_validation.source_canonical_payload(doc, stored["file_hashes"])
+ ).hexdigest()
+ stored["content_digest"] = digest
+ sidecar = json.loads(files["manifest.json"])
+ sidecar["content_digest"] = digest
+ files["manifest.json"] = json.dumps(sidecar, indent=2, sort_keys=True).encode()
files["workflow.json"] = json.dumps(doc).encode()
if key is None:
for rel, data in files.items():
diff --git a/packages/flow/tests/test_bundle_original_format.py b/packages/flow/tests/test_bundle_original_format.py
new file mode 100644
index 0000000000..59d868a919
--- /dev/null
+++ b/packages/flow/tests/test_bundle_original_format.py
@@ -0,0 +1,302 @@
+"""Original-format verification is independent of current model serialization."""
+
+from __future__ import annotations
+
+import copy
+import json
+
+import pytest
+from PIL import Image
+
+from openadapt_flow import bundle_validation as bundles
+from openadapt_flow.ir import ActionKind, Anchor, Step, Workflow
+
+
+def saved_bundle(tmp_path):
+ bundle = tmp_path / "bundle"
+ (bundle / "templates").mkdir(parents=True)
+ Image.new("RGB", (20, 20), "white").save(bundle / "templates/button.png")
+ workflow = Workflow(
+ name="original",
+ steps=[
+ Step(
+ id="click",
+ intent="select",
+ action=ActionKind.CLICK,
+ anchor=Anchor(
+ template="templates/button.png",
+ region=(0, 0, 20, 20),
+ click_point=(10, 10),
+ ),
+ )
+ ],
+ )
+ workflow.save(bundle)
+ return bundle
+
+
+@pytest.mark.parametrize("version", [0, -1, 3, True, False, "2", 2.0, None])
+def test_unknown_or_malformed_schema_refuses_before_parsing(tmp_path, version):
+ (tmp_path / "workflow.json").write_text(
+ json.dumps({"schema_version": version, "name": "bad"})
+ )
+ with pytest.raises(bundles.BundleSchemaError):
+ Workflow.load(tmp_path)
+
+
+def test_upgrade_is_explicit_deterministic_and_does_not_mutate_source(monkeypatch):
+ original = {"name": "legacy", "steps": [], "nested": {"schema_version": 77}}
+ snapshot = copy.deepcopy(original)
+ upgraded = bundles.migrate_bundle_dict(original)
+ assert original == snapshot and upgraded["schema_version"] == 2
+ assert upgraded["nested"]["schema_version"] == 77
+ assert bundles.migrate_bundle_dict(original) == upgraded
+ assert bundles.migrate_bundle_dict(upgraded) == upgraded
+ monkeypatch.setattr(bundles, "_BUNDLE_UPGRADERS", {})
+ with pytest.raises(bundles.BundleSchemaError, match="no upgrader"):
+ bundles.migrate_bundle_dict(original)
+
+
+def test_original_seal_is_checked_before_current_model_construction(
+ tmp_path, monkeypatch
+):
+ bundle = saved_bundle(tmp_path)
+ raw = json.loads((bundle / "workflow.json").read_bytes())
+ raw["name"] = "changed"
+ (bundle / "workflow.json").write_text(json.dumps(raw))
+
+ def forbidden(*args, **kwargs):
+ raise AssertionError(
+ "current Workflow constructed before original seal refusal"
+ )
+
+ monkeypatch.setattr(Workflow, "model_validate", forbidden)
+ with pytest.raises(bundles.BundleIntegrityError, match="before migration"):
+ Workflow.load(bundle)
+
+
+def test_future_serializer_default_does_not_invalidate_original_seal(
+ tmp_path, monkeypatch
+):
+ bundle = saved_bundle(tmp_path)
+ original_bytes = (bundle / "workflow.json").read_bytes()
+ expected = json.loads(original_bytes)["manifest"]["content_digest"]
+ current = bundles._workflow_content
+
+ def future_serializer(workflow):
+ return {**current(workflow), "future_empty_default": None}
+
+ monkeypatch.setattr(bundles, "_workflow_content", future_serializer)
+ loaded = Workflow.load(bundle)
+ assert loaded.manifest.content_digest == expected
+ bundles.verify_integrity(loaded, bundle, loaded.manifest)
+ assert (bundle / "workflow.json").read_bytes() == original_bytes
+ loaded.name = "later mutation"
+ with pytest.raises(bundles.BundleIntegrityError):
+ bundles.verify_integrity(loaded, bundle, loaded.manifest)
+
+
+def test_source_projection_omits_only_the_format_owners():
+ shadow = {
+ "frame_path": [],
+ "form_identity": None,
+ "new_records": [],
+ "identity_field": "id",
+ }
+ raw = {
+ "schema_version": 2,
+ "name": "owned",
+ "steps": [
+ {
+ "anchor": {"form_identity": None, "structural": {"frame_path": []}},
+ "api_binding": {
+ "body_template": {"nested": shadow},
+ "effects": [
+ {
+ "new_records": [],
+ "identity_field": "id",
+ "forbid_collateral_change": False,
+ }
+ ],
+ },
+ }
+ ],
+ }
+ before = copy.deepcopy(raw)
+ content = json.loads(bundles.source_canonical_payload(raw, {}))["workflow"]
+ assert raw == before
+ step = content["steps"][0]
+ assert step["anchor"] == {"structural": {}}
+ assert step["api_binding"]["effects"] == [{}]
+ assert step["api_binding"]["body_template"]["nested"] == shadow
+
+
+def test_decision_revalidation_uses_its_owned_predicate_projection():
+ raw = {
+ "schema_version": 2,
+ "name": "decision",
+ "program": {
+ "states": {
+ "choose": {
+ "decision": {
+ "revalidation": [
+ {
+ "anchor": {
+ "form_identity": None,
+ "structural": {"frame_path": []},
+ }
+ }
+ ]
+ }
+ }
+ }
+ },
+ }
+ content = json.loads(bundles.source_canonical_payload(raw, {}))["workflow"]
+ predicate = content["program"]["states"]["choose"]["decision"]["revalidation"][0]
+ assert predicate["anchor"] == {"structural": {}}
+
+
+@pytest.mark.parametrize(
+ "mutation",
+ ["name", "point", "hashes", "empty_digest", "digest", "schema", "encrypted"],
+)
+def test_loaded_integrity_catches_model_and_manifest_mutation(tmp_path, mutation):
+ bundle = saved_bundle(tmp_path)
+ loaded = Workflow.load(bundle)
+ if mutation == "name":
+ loaded.name = "changed"
+ elif mutation == "point":
+ loaded.steps[0].anchor.click_point = (11, 10)
+ elif mutation == "hashes":
+ loaded.manifest.file_hashes = {}
+ elif mutation == "empty_digest":
+ loaded.manifest.content_digest = ""
+ elif mutation == "digest":
+ loaded.manifest.content_digest = "0" * 64
+ elif mutation == "schema":
+ loaded.manifest.schema_version = 3
+ else:
+ loaded.manifest.encrypted = not loaded.manifest.encrypted
+ with pytest.raises(bundles.BundleIntegrityError):
+ bundles.verify_integrity(loaded, bundle, loaded.manifest)
+
+
+def test_loaded_asset_tamper_refuses(tmp_path):
+ bundle = saved_bundle(tmp_path)
+ loaded = Workflow.load(bundle)
+ (bundle / "templates/button.png").write_bytes(b"changed synthetic asset")
+ with pytest.raises(bundles.BundleIntegrityError):
+ bundles.verify_integrity(loaded, bundle, loaded.manifest)
+
+
+def test_loaded_serialization_requires_explicit_reseal(tmp_path):
+ bundle = saved_bundle(tmp_path)
+ loaded = Workflow.load(bundle)
+ original = (bundle / "workflow.json").read_bytes()
+ loaded.name = "approved new content"
+ with pytest.raises(bundles.BundleIntegrityError, match="explicit resealing"):
+ loaded.save(bundle, seal_manifest=False)
+ assert (bundle / "workflow.json").read_bytes() == original
+ loaded.save(bundle)
+ bundles.verify_integrity(loaded, bundle, loaded.manifest)
+ assert Workflow.load(bundle).name == loaded.name
+
+
+def test_unknown_manifest_version_refuses(tmp_path):
+ bundle = saved_bundle(tmp_path)
+ raw = json.loads((bundle / "workflow.json").read_bytes())
+ raw["manifest"]["schema_version"] = 3
+ (bundle / "workflow.json").write_text(json.dumps(raw))
+ with pytest.raises(bundles.BundleSchemaError):
+ Workflow.load(bundle)
+
+
+def test_unknown_unsealed_extension_cannot_hide_in_current_model_defaults(tmp_path):
+ bundle = saved_bundle(tmp_path)
+ raw = json.loads((bundle / "workflow.json").read_bytes())
+ raw["future_behavior"] = "changed"
+ (bundle / "workflow.json").write_text(json.dumps(raw))
+ with pytest.raises(bundles.BundleIntegrityError, match="before migration"):
+ Workflow.load(bundle)
+
+
+def test_unverified_load_cannot_launder_a_broken_original_seal(tmp_path):
+ bundle = saved_bundle(tmp_path)
+ raw = json.loads((bundle / "workflow.json").read_bytes())
+ raw["name"] = "tampered before unchecked load"
+ (bundle / "workflow.json").write_text(json.dumps(raw))
+ loaded = Workflow.load(bundle, verify_integrity=False)
+ with pytest.raises(bundles.BundleIntegrityError):
+ bundles.verify_integrity(loaded, bundle, loaded.manifest)
+ with pytest.raises(bundles.BundleIntegrityError):
+ bundles.content_identity_digest(loaded, loaded.manifest.file_hashes)
+
+
+def test_loaded_identity_refuses_replaced_asset_hashes_or_missing_manifest(tmp_path):
+ bundle = saved_bundle(tmp_path)
+ loaded = Workflow.load(bundle)
+ with pytest.raises(bundles.BundleIntegrityError):
+ bundles.content_identity_digest(loaded, {})
+ loaded.manifest = None
+ with pytest.raises(bundles.BundleIntegrityError):
+ bundles.content_identity_digest(loaded, {})
+
+
+@pytest.mark.parametrize("consumer", ["pipeline", "summary", "composition"])
+def test_digest_consumers_retain_verified_original_identity(
+ tmp_path, monkeypatch, consumer
+):
+ bundle = saved_bundle(tmp_path)
+ expected = json.loads((bundle / "workflow.json").read_bytes())["manifest"][
+ "content_digest"
+ ]
+ current = bundles._workflow_content
+ monkeypatch.setattr(
+ bundles,
+ "_workflow_content",
+ lambda workflow: {
+ **current(workflow),
+ "future_empty_default": None,
+ },
+ )
+ if consumer == "pipeline":
+ from openadapt_flow.admit_pipeline import _bundle_digest
+
+ actual = _bundle_digest(bundle)
+ elif consumer == "summary":
+ from openadapt_flow.authorization_summary import bundle_digest
+
+ actual = bundle_digest(bundle)
+ else:
+ from openadapt_flow.admitted_composition import live_bundle_content_digest
+
+ actual = live_bundle_content_digest(Workflow.load(bundle), bundle)
+ assert actual == expected
+
+
+def test_governed_identity_retains_original_seal_and_refuses_later_mutation(
+ tmp_path, monkeypatch
+):
+ from openadapt_flow.run_gate import build_runtime_authorization
+ from tests.test_run_gate import _KEY, _good_workflow, _run, _seal
+
+ _, bundle = _seal(_good_workflow(), tmp_path)
+ current = bundles._workflow_content
+ monkeypatch.setattr(
+ bundles,
+ "_workflow_content",
+ lambda workflow: {
+ **current(workflow),
+ "future_empty_default": None,
+ },
+ )
+ loaded = Workflow.load(bundle, key=_KEY)
+ report = _run(loaded, bundle)
+ assert report.passed, report.render()
+ authorization = build_runtime_authorization(loaded, report)
+ assert authorization.validate_workflow(loaded) is None
+ loaded.name = "later unauthorized change"
+ assert authorization.validate_workflow(loaded) is not None
+ with pytest.raises(ValueError, match="workflow changed"):
+ build_runtime_authorization(loaded, report)
diff --git a/packages/flow/tests/test_bundle_release_compatibility.py b/packages/flow/tests/test_bundle_release_compatibility.py
new file mode 100644
index 0000000000..1e85ef2050
--- /dev/null
+++ b/packages/flow/tests/test_bundle_release_compatibility.py
@@ -0,0 +1,120 @@
+"""Frozen release-produced bundles load, retain their seal, and drive a real browser."""
+
+from __future__ import annotations
+
+import hashlib
+import json
+import shutil
+from pathlib import Path
+
+import pytest
+
+from openadapt_flow import bundle_validation as bundles
+from openadapt_flow.ir import Workflow
+
+FIXTURES = Path(__file__).parent / "fixtures/bundle_compatibility"
+RELEASES = {
+ "2.2.0": "98c437f12b04f11e44fbc864e051252e480a848e",
+ "2.5.0": "5a3bf49a0bf2d662430386295a1c34036c064d58",
+ "2.6.0": "1c832365d11e9dbe2a166485b13f7b8effd6d8d0",
+}
+CASES = [(release, shape) for release in RELEASES for shape in ("linear", "program")]
+
+
+def hashes(directory):
+ return {
+ path.relative_to(directory).as_posix(): hashlib.sha256(
+ path.read_bytes()
+ ).hexdigest()
+ for path in directory.rglob("*")
+ if path.is_file()
+ }
+
+
+@pytest.fixture(params=CASES, ids=["-".join(case) for case in CASES])
+def frozen_bundle(request, tmp_path):
+ release, shape = request.param
+ provenance = json.loads((FIXTURES / release / "provenance.json").read_bytes())
+ assert provenance["commit"] == RELEASES[release]
+ assert provenance["release"] == release
+ assert provenance["original_release_load_verified"] is True
+ expected = next(item for item in provenance["bundles"] if item["shape"] == shape)
+ source = FIXTURES / release / shape
+ assert hashes(source) == expected["files"]
+ bundle = tmp_path / "bundle"
+ shutil.copytree(source, bundle)
+ return bundle, expected
+
+
+def test_frozen_bundle_original_seal_loads_without_rewriting(frozen_bundle):
+ bundle, expected = frozen_bundle
+ before = hashes(bundle)
+ canonical = (bundle / "canonical.json").read_bytes()
+ assert hashlib.sha256(canonical).hexdigest() == expected["content_digest"]
+ workflow = Workflow.load(bundle)
+ assert workflow.manifest.content_digest == expected["content_digest"]
+ bundles.verify_integrity(workflow, bundle, workflow.manifest)
+ assert hashes(bundle) == before
+
+
+@pytest.mark.parametrize("attack", ["workflow", "version", "asset"])
+def test_frozen_bundle_tampering_refuses(frozen_bundle, attack):
+ bundle, _ = frozen_bundle
+ if attack == "asset":
+ (bundle / "templates/button.png").write_bytes(b"different synthetic pixels")
+ else:
+ raw = json.loads((bundle / "workflow.json").read_bytes())
+ if attack == "workflow":
+ raw["name"] = "changed after sealing"
+ else:
+ raw["schema_version"] = 1
+ (bundle / "workflow.json").write_text(json.dumps(raw))
+ with pytest.raises(bundles.BundleIntegrityError):
+ Workflow.load(bundle)
+
+
+@pytest.fixture(scope="module")
+def chromium():
+ from playwright.sync_api import sync_playwright
+
+ with sync_playwright() as playwright:
+ browser = playwright.chromium.launch(headless=True)
+ try:
+ yield browser
+ finally:
+ browser.close()
+
+
+def test_frozen_bundle_replays_one_exact_input_in_real_chromium(
+ frozen_bundle, chromium, tmp_path
+):
+ from openadapt_flow.backends.playwright_backend import (
+ PlaywrightBackend,
+ prepare_ws_guard,
+ )
+ from openadapt_flow.runtime import Replayer
+
+ bundle, expected = frozen_bundle
+ before = hashes(bundle)
+ context = chromium.new_context(viewport={"width": 320, "height": 200})
+ try:
+ prepare_ws_guard(context)
+ page = context.new_page()
+ page.set_content("""
+
+""")
+ workflow = Workflow.load(bundle)
+ report = Replayer(PlaywrightBackend(page)).run(
+ workflow, bundle_dir=bundle, run_dir=tmp_path / "run"
+ )
+ assert report.success, [
+ (result.step_id, result.error) for result in report.results
+ ]
+ assert page.locator("#count").inner_text() == "1"
+ assert len(report.results) == 1
+ assert report.results[0].resolution.rung == "structural"
+ assert workflow.manifest.content_digest == expected["content_digest"]
+ assert hashes(bundle) == before
+ finally:
+ context.close()
diff --git a/packages/flow/tests/test_compiler.py b/packages/flow/tests/test_compiler.py
index 9820671032..821777e2a3 100644
--- a/packages/flow/tests/test_compiler.py
+++ b/packages/flow/tests/test_compiler.py
@@ -871,11 +871,20 @@ def test_corner_click_clamped_no_change(self, compiled) -> None:
assert step.expect == []
def test_bundle_roundtrip(self, compiled) -> None:
+ from openadapt_flow import bundle_validation
+
wf, bundle = compiled["workflow"], compiled["bundle"]
loaded = Workflow.load(bundle)
- assert loaded == wf
+ # A loaded workflow intentionally carries private original-seal state;
+ # compare the public model and validate that persisted seal separately.
+ assert loaded.model_dump(mode="json") == wf.model_dump(mode="json")
+ bundle_validation.verify_integrity(loaded, bundle, loaded.manifest)
+ loaded.save(bundle)
+ reloaded = Workflow.load(bundle)
+ assert reloaded.model_dump(mode="json") == wf.model_dump(mode="json")
+ bundle_validation.verify_integrity(reloaded, bundle, reloaded.manifest)
# every referenced template exists in the bundle
- for step in loaded.steps:
+ for step in reloaded.steps:
if step.anchor:
assert (bundle / step.anchor.template).exists()
diff --git a/scripts/ci/gitleaks_metadata.py b/scripts/ci/gitleaks_metadata.py
new file mode 100644
index 0000000000..0dc9fa4f75
--- /dev/null
+++ b/scripts/ci/gitleaks_metadata.py
@@ -0,0 +1,133 @@
+"""Print a strict projection of Gitleaks' four-field metadata report."""
+
+from __future__ import annotations
+
+import argparse
+import base64
+import binascii
+import json
+import re
+import sys
+from pathlib import Path, PurePosixPath
+from typing import TextIO
+
+_RULE_ID = re.compile(r"[A-Za-z0-9_.-]{1,128}\Z")
+_COMMIT = re.compile(r"(?:[0-9a-f]{40}|[0-9a-f]{64})\Z")
+
+
+class InvalidReport(ValueError):
+ """Raised when report metadata cannot be safely projected."""
+
+
+def _decode_field(value: str) -> str:
+ try:
+ decoded = base64.b64decode(value, validate=True)
+ return decoded.decode("utf-8", errors="strict")
+ except (binascii.Error, UnicodeError, ValueError) as exc:
+ raise InvalidReport from exc
+
+
+def _safe_path(value: str) -> str:
+ if not value or len(value) > 512:
+ raise InvalidReport
+ if "\\" in value or any(
+ ord(char) < 32 or 127 <= ord(char) <= 159 for char in value
+ ):
+ raise InvalidReport
+ path = PurePosixPath(value)
+ if (
+ path.is_absolute()
+ or not path.parts
+ or value != path.as_posix()
+ or any(part in {"", ".", ".."} for part in path.parts)
+ ):
+ raise InvalidReport
+ return value
+
+
+def project_report(report: str) -> list[dict[str, str | int]]:
+ """Decode four-field TSV containing only Gitleaks metadata fields."""
+ if not isinstance(report, str):
+ raise InvalidReport
+ if not report:
+ return []
+
+ projected: list[dict[str, str | int]] = []
+ for record in report.splitlines():
+ fields = record.split("\t")
+ if len(fields) != 4:
+ raise InvalidReport
+ rule_id, file_path, line_text, commit = (
+ _decode_field(fields[0]),
+ _decode_field(fields[1]),
+ fields[2],
+ _decode_field(fields[3]),
+ )
+ if not _RULE_ID.fullmatch(rule_id):
+ raise InvalidReport
+ file_path = _safe_path(file_path)
+ if not line_text.isascii() or not line_text.isdecimal():
+ raise InvalidReport
+ line = int(line_text)
+ if line < 1:
+ raise InvalidReport
+ if not _COMMIT.fullmatch(commit):
+ raise InvalidReport
+ projected.append(
+ {
+ "RuleID": rule_id,
+ "File": file_path,
+ "StartLine": line,
+ "Commit": commit,
+ }
+ )
+ return projected
+
+
+def read_projection(report_path: Path) -> list[dict[str, str | int]]:
+ try:
+ return project_report(report_path.read_text(encoding="utf-8"))
+ except (OSError, UnicodeError, InvalidReport) as exc:
+ raise InvalidReport from exc
+
+
+def report_scan_result(
+ report_path: Path, scanner_exit_code: int, output: TextIO = sys.stdout
+) -> int:
+ """Emit safe metadata and preserve scanner failure semantics."""
+ try:
+ findings = read_projection(report_path)
+ except InvalidReport:
+ print(
+ "Gitleaks metadata report missing or invalid; scan remains blocked.",
+ file=output,
+ )
+ return scanner_exit_code or 2
+
+ print(f"Gitleaks findings: {len(findings)}", file=output)
+ for finding in findings:
+ # JSON escaping prevents repository-controlled metadata from becoming
+ # GitHub Actions workflow commands or additional log lines.
+ print(
+ "Gitleaks metadata: "
+ + json.dumps(finding, ensure_ascii=True, separators=(",", ":")),
+ file=output,
+ )
+
+ if findings and scanner_exit_code == 0:
+ return 1
+ return scanner_exit_code
+
+
+def main() -> int:
+ parser = argparse.ArgumentParser(description=__doc__)
+ parser.add_argument("report_path", type=Path)
+ parser.add_argument("scanner_exit_code", type=int)
+ args = parser.parse_args()
+ if args.scanner_exit_code < 0 or args.scanner_exit_code > 255:
+ parser.error("scanner exit code must be between 0 and 255")
+ return report_scan_result(args.report_path, args.scanner_exit_code)
+
+
+if __name__ == "__main__":
+ raise SystemExit(main())
diff --git a/tests/test_gitleaks_metadata.py b/tests/test_gitleaks_metadata.py
new file mode 100644
index 0000000000..aa75bcb202
--- /dev/null
+++ b/tests/test_gitleaks_metadata.py
@@ -0,0 +1,160 @@
+"""Synthetic controls for Gitleaks' metadata-only report projection."""
+
+from __future__ import annotations
+
+import base64
+import importlib.util
+import io
+from pathlib import Path
+
+import pytest
+
+WORKFLOW = Path(__file__).resolve().parents[1] / ".github/workflows/secret-scan.yml"
+PARSER = Path(__file__).resolve().parents[1] / "scripts/ci/gitleaks_metadata.py"
+PARSER_SPEC = importlib.util.spec_from_file_location("gitleaks_metadata", PARSER)
+if PARSER_SPEC is None or PARSER_SPEC.loader is None:
+ raise RuntimeError("could not load the Gitleaks metadata parser")
+PARSER_MODULE = importlib.util.module_from_spec(PARSER_SPEC)
+PARSER_SPEC.loader.exec_module(PARSER_MODULE)
+
+InvalidReport = PARSER_MODULE.InvalidReport
+project_report = PARSER_MODULE.project_report
+report_scan_result = PARSER_MODULE.report_scan_result
+
+
+def _encode(value: str) -> str:
+ return base64.b64encode(value.encode("utf-8")).decode("ascii")
+
+
+def _record(
+ *,
+ rule_id: str = "synthetic-api-key",
+ file_path: str = "tests/fixtures/history.py",
+ line: int = 17,
+ commit: str = "a" * 40,
+) -> str:
+ return f"{_encode(rule_id)}\t{_encode(file_path)}\t{line}\t{_encode(commit)}\n"
+
+
+def test_projection_contains_only_the_allowlisted_metadata() -> None:
+ result = project_report(_record())
+
+ assert result == [
+ {
+ "RuleID": "synthetic-api-key",
+ "File": "tests/fixtures/history.py",
+ "StartLine": 17,
+ "Commit": "a" * 40,
+ }
+ ]
+
+
+def test_report_output_never_emits_non_allowlisted_fields(tmp_path: Path) -> None:
+ report_path = tmp_path / "synthetic-report.tsv"
+ report_path.write_text(_record(), encoding="utf-8")
+ output = io.StringIO()
+
+ result = report_scan_result(report_path, 1, output)
+
+ assert result == 1
+ assert "synthetic-api-key" in output.getvalue()
+ assert "tests/fixtures/history.py" in output.getvalue()
+ assert "a" * 40 in output.getvalue()
+ assert "SYNTHETIC_MATCH_SENTINEL_NOT_A_SECRET" not in output.getvalue()
+ assert "SYNTHETIC_SECRET_SENTINEL_NOT_A_SECRET" not in output.getvalue()
+ assert "synthetic@example.invalid" not in output.getvalue()
+ assert "synthetic commit message" not in output.getvalue()
+ assert "synthetic-fingerprint" not in output.getvalue()
+
+
+@pytest.mark.parametrize(
+ "record",
+ [
+ _record(rule_id="bad\n::error::synthetic"),
+ _record(file_path="../outside.txt"),
+ _record(file_path="/absolute/path.txt"),
+ _record(file_path="."),
+ _record(file_path="dir\\file.txt"),
+ _record(file_path="line\nbreak.txt"),
+ _record(line=0),
+ _record(commit="not-a-commit"),
+ "%%%\t%%%\t17\t%%%\n",
+ "one\ttwo\tthree\n",
+ "one\ttwo\t3\tfour\textra\n",
+ _record() + "not-a-record\n",
+ ],
+)
+def test_unsafe_or_ambiguous_metadata_fails_closed(record: str) -> None:
+ with pytest.raises(InvalidReport):
+ project_report(record)
+
+
+def test_missing_or_invalid_report_stays_failed_and_does_not_echo_values(
+ tmp_path: Path,
+) -> None:
+ missing_path = tmp_path / "missing.tsv"
+ output = io.StringIO()
+
+ result = report_scan_result(missing_path, 1, output)
+
+ assert result == 1
+ assert "remains blocked" in output.getvalue()
+ assert str(missing_path) not in output.getvalue()
+
+
+def test_malformed_report_error_is_generic(tmp_path: Path) -> None:
+ report_path = tmp_path / "synthetic-report.tsv"
+ report_path.write_text("not-a-record", encoding="utf-8")
+ output = io.StringIO()
+
+ result = report_scan_result(report_path, 0, output)
+
+ assert result == 2
+ assert output.getvalue() == (
+ "Gitleaks metadata report missing or invalid; scan remains blocked.\n"
+ )
+
+
+def test_findings_with_zero_scanner_status_are_still_failed(tmp_path: Path) -> None:
+ report_path = tmp_path / "synthetic-report.tsv"
+ report_path.write_text(_record(), encoding="utf-8")
+
+ assert report_scan_result(report_path, 0, io.StringIO()) == 1
+
+
+def test_empty_report_preserves_success(tmp_path: Path) -> None:
+ report_path = tmp_path / "synthetic-report.tsv"
+ report_path.write_text("", encoding="utf-8")
+
+ assert report_scan_result(report_path, 0, io.StringIO()) == 0
+
+
+def test_scanner_failure_is_preserved_without_findings(tmp_path: Path) -> None:
+ report_path = tmp_path / "synthetic-report.tsv"
+ report_path.write_text("", encoding="utf-8")
+
+ assert report_scan_result(report_path, 2, io.StringIO()) == 2
+
+
+def test_workflow_retains_full_history_scan_and_uses_only_metadata_template() -> None:
+ workflow = WORKFLOW.read_text(encoding="utf-8")
+
+ assert "fetch-depth: 0" in workflow
+ assert "gitleaks git ." in workflow
+ assert "--config .gitleaks.toml" in workflow
+ assert "--log-opts=HEAD" in workflow
+ assert "--redact=100" in workflow
+ assert "--report-format=template" in workflow
+ assert '--report-template "$template_path"' in workflow
+ assert "{{end -}}" in workflow
+ assert "{{.RuleID | b64enc}}" not in workflow
+ assert "{{.File | b64enc}}" not in workflow
+ assert (
+ '{{printf "%s\\t%s\\t%d\\t%s\\n" (.RuleID | b64enc) '
+ "(.File | b64enc) .StartLine (.Commit | b64enc)}}" in workflow
+ )
+ assert "--report-format=json" not in workflow
+ assert '--report-path "$report_path"' in workflow
+ assert ">/dev/null 2>&1" in workflow
+ assert "python3 scripts/ci/gitleaks_metadata.py" in workflow
+ assert "actions/upload-artifact" not in workflow