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(""" + +0""") + 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