From eb0f2c138391623aee69ef06025ce2fb0a9ecba5 Mon Sep 17 00:00:00 2001 From: Richard Abrich Date: Thu, 27 Aug 2026 13:31:29 -0400 Subject: [PATCH 1/7] feat(hosted): sign complete terminal outcomes --- openadapt_flow/runner/hosted_adapter.py | 117 ++- openadapt_flow/runtime/durable/authority.py | 6 +- openadapt_flow/terminal_verification_v2.py | 805 ++++++++++++++---- ...inal_verification_v2_terminal_vectors.json | 1 + tests/test_durable_authority_v13.py | 19 + tests/test_hosted_runner_adapter.py | 80 +- tests/test_terminal_verification_v2.py | 660 +++++++++++++- 7 files changed, 1487 insertions(+), 201 deletions(-) create mode 100644 tests/fixtures/terminal_verification_v2_terminal_vectors.json diff --git a/openadapt_flow/runner/hosted_adapter.py b/openadapt_flow/runner/hosted_adapter.py index 9ee003fb..7fd50a0c 100644 --- a/openadapt_flow/runner/hosted_adapter.py +++ b/openadapt_flow/runner/hosted_adapter.py @@ -235,6 +235,9 @@ class HostedDispatch(_Closed): run_id: str = Field(pattern=_UUID) workflow_id: str = Field(pattern=_UUID) workflow_version_id: str = Field(pattern=_UUID) + execution_authority_id: str = Field(pattern=_UUID) + execution_authority_sha256: str = Field(pattern=_HEX64) + execution_authority_signer_sha256: str = Field(pattern=_HEX64) idempotency_key: str = Field(pattern=_IDEMPOTENCY) lease_token: str = Field(pattern=_LEASE_TOKEN, repr=False) lease_expires_at: str @@ -306,14 +309,22 @@ class HostedTerminalEvent(_Closed): ) @model_validator(mode="after") - def _verified_requires_exact_proof(self) -> "HostedTerminalEvent": + def _terminal_outcome_requires_exact_proof(self) -> "HostedTerminalEvent": has_proof = self.terminal_verification_artifact_bytes_base64 is not None if has_proof != (self.terminal_verification_artifact_sha256 is not None): raise ValueError("terminal verification binding is incomplete") - if self.outcome == "VERIFIED" and not has_proof: - raise ValueError("VERIFIED requires exact terminal verification") - if self.outcome != "VERIFIED" and has_proof: - raise ValueError("non-VERIFIED callback cannot carry a success proof") + if self.outcome in {"VERIFIED", "HALTED_BEFORE_EFFECT"} and not has_proof: + raise ValueError(f"{self.outcome} requires exact terminal verification") + if ( + self.outcome + not in { + "VERIFIED", + "HALTED_BEFORE_EFFECT", + "RECONCILIATION_REQUIRED", + } + and has_proof + ): + raise ValueError("terminal callback outcome cannot carry a v2 proof") if has_proof: assert self.terminal_verification_artifact_bytes_base64 is not None assert self.terminal_verification_artifact_sha256 is not None @@ -339,6 +350,8 @@ def _verified_requires_exact_proof(self) -> "HostedTerminalEvent": or proof.payload.run_report_object_sha256 != self.report_sha256 ): raise ValueError("terminal verification names a different run report") + if proof.payload.run_receipt.transaction_outcome != self.outcome: + raise ValueError("terminal verification names a different outcome") return self @@ -355,14 +368,24 @@ class HostedRunResult(_Closed): @model_validator(mode="after") def _closed_terminal(self) -> "HostedRunResult": - if (self.outcome is TransactionOutcome.VERIFIED) != ( - self.terminal_verification is not None + if ( + self.outcome + in { + TransactionOutcome.VERIFIED, + TransactionOutcome.HALTED_BEFORE_EFFECT, + } + and self.terminal_verification is None ): - raise ValueError("only a terminally verified result can be VERIFIED") - if self.uncertain_delivery and self.outcome not in { - TransactionOutcome.RECONCILIATION_REQUIRED, + raise ValueError("closed terminal outcome requires a signed v2 proof") + if self.terminal_verification is not None and self.outcome not in { TransactionOutcome.VERIFIED, + TransactionOutcome.HALTED_BEFORE_EFFECT, + TransactionOutcome.RECONCILIATION_REQUIRED, }: + raise ValueError("terminal outcome cannot carry a signed v2 proof") + if self.uncertain_delivery != ( + self.outcome is TransactionOutcome.RECONCILIATION_REQUIRED + ): raise ValueError("uncertain delivery has an invalid terminal outcome") if self.terminal_verification is not None and ( self.terminal_verification.payload.run_id != self.run_id @@ -370,8 +393,12 @@ def _closed_terminal(self) -> "HostedRunResult": != self.report_sha256 or self.terminal_verification.payload.run_report_object_sha256 != self.report_sha256 + or self.terminal_verification.payload.run_receipt.transaction_outcome + != self.outcome.value ): - raise ValueError("terminal verification names a different run report") + raise ValueError( + "terminal verification names a different run report or outcome" + ) return self @@ -1171,8 +1198,13 @@ def _produce_terminal_verification( ): raise ValueError("run report differs from retained governed inputs") - chain = DurableAuthority(run_dir, store).production_delivery_permit_chain() - first = chain.entries[0] + prepared = prepare_production_terminal_evidence(report) + chain = DurableAuthority(run_dir, store).production_delivery_permit_chain( + allow_empty=( + prepared.transaction_outcome is TransactionOutcome.HALTED_BEFORE_EFFECT + ) + ) + first = chain.entries[0] if chain.entries else None expected = qualification.expected runtime = expected.runtime_build_identity flow_run_id_sha256 = hashlib.sha256(dispatch.run_id.encode("utf-8")).hexdigest() @@ -1182,9 +1214,13 @@ def _produce_terminal_verification( runner_session_id_sha256 = hashlib.sha256( dispatch.runner_session_id.encode("utf-8") ).hexdigest() - if ( + if first is not None and ( first.run_id != dispatch.run_id or first.flow_run_id_sha256 != flow_run_id_sha256 + or first.execution_authority_id != dispatch.execution_authority_id + or first.execution_authority_sha256 != dispatch.execution_authority_sha256 + or first.authority_signer_sha256 + != dispatch.execution_authority_signer_sha256 or first.admission_artifact_sha256 != qualification.qualification_admission_sha256 or first.evidence_identity_sha256 @@ -1199,7 +1235,6 @@ def _produce_terminal_verification( ): raise ValueError("retained delivery chain differs from admitted live state") - prepared = prepare_production_terminal_evidence(report) now = datetime.now(timezone.utc).replace(microsecond=0) now_text = now.isoformat().replace("+00:00", "Z") context = ProductionTerminalVerificationContext( @@ -1228,9 +1263,11 @@ def _produce_terminal_verification( qualification_signer_registry_revision=( qualification.qualification_signer_registry.revision ), - execution_authority_id=first.execution_authority_id, - execution_authority_sha256=first.execution_authority_sha256, - execution_authority_signer_sha256=first.authority_signer_sha256, + execution_authority_id=dispatch.execution_authority_id, + execution_authority_sha256=dispatch.execution_authority_sha256, + execution_authority_signer_sha256=( + dispatch.execution_authority_signer_sha256 + ), permit_chain=chain, run_report_object_version="sha256:" + prepared.report_sha256, verified_at=now_text, @@ -1248,7 +1285,7 @@ def _produce_terminal_verification( raise ValueError("terminal report changed during proof production") envelope_bytes = canonical_json(built.envelope) payload = built.envelope.payload - final = chain.entries[-1] + final = chain.entries[-1] if chain.entries else None live_expected = ProductionTerminalVerificationExpected( run_id=dispatch.run_id, flow_run_id_sha256=flow_run_id_sha256, @@ -1277,13 +1314,19 @@ def _produce_terminal_verification( qualification_signer_registry_revision=( qualification.qualification_signer_registry.revision ), - execution_authority_id=first.execution_authority_id, - execution_authority_sha256=first.execution_authority_sha256, - execution_authority_signer_sha256=first.authority_signer_sha256, + execution_authority_id=dispatch.execution_authority_id, + execution_authority_sha256=dispatch.execution_authority_sha256, + execution_authority_signer_sha256=( + dispatch.execution_authority_signer_sha256 + ), permit_chain_sha256=chain.permit_chain_sha256, permit_count=len(chain.entries), - final_authority_sequence=final.authority_sequence, - final_runtime_delivery_sequence=final.runtime_delivery_sequence, + final_authority_sequence=( + final.authority_sequence if final is not None else 0 + ), + final_runtime_delivery_sequence=( + final.runtime_delivery_sequence if final is not None else 0 + ), authenticated_runner_id_sha256=runner_id_sha256, authenticated_session_id_sha256=runner_session_id_sha256, acknowledged_one_use_claim_ids=tuple( @@ -1624,8 +1667,12 @@ def execute( proof: ProductionTerminalVerificationEnvelope | None = None if execution.terminal_verification is not None: raise ValueError("managed child supplied an untrusted terminal proof") - if outcome is TransactionOutcome.VERIFIED: - if execution.returncode != 0: + if outcome in { + TransactionOutcome.VERIFIED, + TransactionOutcome.HALTED_BEFORE_EFFECT, + TransactionOutcome.RECONCILIATION_REQUIRED, + }: + if outcome is TransactionOutcome.VERIFIED and execution.returncode != 0: raise ValueError("managed child exited unsuccessfully") terminal_config = load_runner_config(runner_config, protected=True) if self._protected_runner_origin(terminal_config) != configured_origin: @@ -1653,11 +1700,20 @@ def execute( verified_params=params, dispatch_binding_sha256=verified.payload.dispatch_binding_sha256, ) + if proof.payload.run_receipt.transaction_outcome != outcome.value: + raise ValueError("terminal proof outcome differs from the report") except Exception: # noqa: BLE001 - post-delivery terminalization fails closed outcome = TransactionOutcome.RECONCILIATION_REQUIRED proof = None - if outcome is not TransactionOutcome.VERIFIED: - proof = None + if ( + outcome + in { + TransactionOutcome.VERIFIED, + TransactionOutcome.HALTED_BEFORE_EFFECT, + } + and proof is None + ): + outcome = TransactionOutcome.RECONCILIATION_REQUIRED self._ledger.record_outcome(reservation_key, outcome, run_id=parsed.run_id) if report is None: events = tuple( @@ -1681,10 +1737,7 @@ def execute( ), ) ) - uncertain = outcome is TransactionOutcome.RECONCILIATION_REQUIRED or any( - result.delivery_uncertainty is not None - for result in (report.results if report is not None else ()) - ) + uncertain = outcome is TransactionOutcome.RECONCILIATION_REQUIRED return HostedRunResult( dispatch_id=parsed.dispatch_id, run_id=parsed.run_id, diff --git a/openadapt_flow/runtime/durable/authority.py b/openadapt_flow/runtime/durable/authority.py index dde650d8..08113081 100644 --- a/openadapt_flow/runtime/durable/authority.py +++ b/openadapt_flow/runtime/durable/authority.py @@ -2418,7 +2418,9 @@ def acknowledge_remote_delivery( self._emit_synthetic_delivery_marker(marker_payload) return entry - def production_delivery_permit_chain(self) -> ProductionDeliveryPermitChain: + def production_delivery_permit_chain( + self, *, allow_empty: bool = False + ) -> ProductionDeliveryPermitChain: """Rebuild the exact acknowledged chain from protected retained bytes.""" with self._transaction() as connection: @@ -2433,6 +2435,8 @@ def production_delivery_permit_chain(self) -> ProductionDeliveryPermitChain: (self.path_key,), ).fetchall() if not rows: + if allow_empty: + return ProductionDeliveryPermitChain.build(()) raise DurableAuthorityBusy( "the production delivery permit chain is unavailable" ) diff --git a/openadapt_flow/terminal_verification_v2.py b/openadapt_flow/terminal_verification_v2.py index 925df798..93a13750 100644 --- a/openadapt_flow/terminal_verification_v2.py +++ b/openadapt_flow/terminal_verification_v2.py @@ -1,9 +1,9 @@ """Production terminal-verification v2 contracts and producer. -Flow builds one success-only artifact after it revalidates a complete VERIFIED -report, run receipt, signed permit chain, and class-separated evidence. The -acceptor must reconstruct every value from immutable storage before it admits -the result as Production success. +Flow builds one signed terminal artifact after it revalidates a complete +VERIFIED, HALTED_BEFORE_EFFECT, or RECONCILIATION_REQUIRED report. The +acceptor reconstructs every value from immutable storage. Only a VERIFIED +artifact can authorize a Production success or a billable result. """ from __future__ import annotations @@ -32,13 +32,31 @@ model_validator, ) -from openadapt_flow.ir import PostconditionContractEvidence, RunReport +from openadapt_flow.ir import ( + EffectVerificationEvidence, + PostconditionContractEvidence, + RunReport, +) from openadapt_flow.qualification_admission_v2 import ( MAX_PERMIT_SNAPSHOT_AGE, ClosedSignedModel, canonical_json, ) -from openadapt_flow.receipt import ReceiptError, RunReceipt, build_receipt +from openadapt_flow.receipt import ( + ReceiptError, + RunReceipt, + _hour_utc, + _over_halt_count, + _receipt_builder_version, + build_receipt, +) +from openadapt_flow.transaction import ( + TransactionOutcome, + _attempt_state, + _effect_absence_proven, + _is_consequential_result, + classify_transaction_outcome, +) SCHEMA: Final[Literal["openadapt.production-terminal-verification/v2"]] = ( "openadapt.production-terminal-verification/v2" @@ -104,6 +122,7 @@ class PreparedProductionTerminalEvidence: execution_outcome: "ProductionExecutionOutcome" run_receipt: "ProductionRunReceipt" run_receipt_sha256: str + transaction_outcome: TransactionOutcome report: RunReport = dataclass_field(repr=False) @@ -130,10 +149,10 @@ def evidence_runner_signer_sha256(public_key: bytes) -> str: class TerminalContractCounts(ClosedSignedModel): - authorization: StrictInt = Field(ge=1, le=JS_MAX_SAFE_INTEGER) - identity: StrictInt = Field(ge=1, le=JS_MAX_SAFE_INTEGER) - postcondition: StrictInt = Field(ge=1, le=JS_MAX_SAFE_INTEGER) - effect: StrictInt = Field(ge=1, le=JS_MAX_SAFE_INTEGER) + authorization: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) + identity: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) + postcondition: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) + effect: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) class ProductionExecutionOutcome(ClosedSignedModel): @@ -142,11 +161,16 @@ class ProductionExecutionOutcome(ClosedSignedModel): version: Literal["openadapt.execution-outcome/v1"] = ( "openadapt.execution-outcome/v1" ) - outcome: Literal["VERIFIED"] = "VERIFIED" + outcome: Literal[ + "VERIFIED", + "HALTED", + "FAILED", + "ROLLED_BACK", + ] = "VERIFIED" profile: Literal["standard", "regulated"] - production_eligible: Literal[True] = True + production_eligible: StrictBool = True qualification_evidence_only: Literal[False] = False - execution_completed: Literal[True] = True + execution_completed: StrictBool = True required_contracts: TerminalContractCounts passed_contracts: TerminalContractCounts workflow_contract_sha256: str = Field(pattern=_SHA256_RE) @@ -164,27 +188,33 @@ class ProductionExecutionOutcome(ClosedSignedModel): "model", ], ..., - ] = Field(min_length=4, max_length=7) + ] = Field(min_length=1, max_length=7) model_calls: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) external_network_calls: Literal["none", "observed"] - compensation_actions: Literal[0] = 0 + compensation_actions: StrictInt = Field(default=0, ge=0, le=JS_MAX_SAFE_INTEGER) @model_validator(mode="after") - def _complete_verified_outcome(self) -> "ProductionExecutionOutcome": - if self.passed_contracts != self.required_contracts: - raise ValueError( - "terminal VERIFIED outcome lacks complete contract coverage" - ) + def _complete_terminal_outcome(self) -> "ProductionExecutionOutcome": + required = self.required_contracts.model_dump(mode="python") + passed = self.passed_contracts.model_dump(mode="python") + if any(passed[key] > required[key] for key in required): + raise ValueError("terminal passed contract counts exceed required counts") if self.required_contracts.authorization != 1: - raise ValueError("terminal VERIFIED outcome requires one authorization") + raise ValueError("terminal outcome requires one authorization") + if self.passed_contracts.authorization != 1: + raise ValueError("terminal outcome requires one passed authorization") if len(self.postcondition_evidence) != self.required_contracts.postcondition: raise ValueError("terminal postcondition evidence cardinality is invalid") + if ( + sum(item.verdict == "passed" for item in self.postcondition_evidence) + != self.passed_contracts.postcondition + ): + raise ValueError("terminal postcondition evidence count is invalid") if any( - item.verdict != "passed" - or item.workflow_contract_sha256 != self.workflow_contract_sha256 + item.workflow_contract_sha256 != self.workflow_contract_sha256 for item in self.postcondition_evidence ): - raise ValueError("terminal postcondition evidence is not fully verified") + raise ValueError("terminal postcondition evidence binding is invalid") keys = tuple( (item.result_index, item.contract_kind, item.contract_index) for item in self.postcondition_evidence @@ -202,20 +232,47 @@ def _complete_verified_outcome(self) -> "ProductionExecutionOutcome": self.evidence_classes ) != len(set(self.evidence_classes)): raise ValueError("terminal evidence classes must be unique and ordered") - required_classes = {"authorization", "identity", "postcondition"} - if not required_classes.issubset(self.evidence_classes): - raise ValueError( - "terminal VERIFIED outcome lacks required evidence classes" - ) + if "authorization" not in self.evidence_classes: + raise ValueError("terminal outcome lacks authorization evidence") + if (self.passed_contracts.identity > 0) != ( + "identity" in self.evidence_classes + ): + raise ValueError("terminal identity evidence class is invalid") + if (self.passed_contracts.postcondition > 0) != ( + "postcondition" in self.evidence_classes + ): + raise ValueError("terminal postcondition evidence class is invalid") effect_classes = { item for item in self.evidence_classes if item.startswith("effect_tier_") } - if len(effect_classes) != 1: - raise ValueError("terminal VERIFIED outcome requires one effect tier") + if (self.passed_contracts.effect > 0) != bool(effect_classes) or len( + effect_classes + ) > 1: + raise ValueError("terminal effect evidence classes are invalid") if (self.model_calls > 0) != ("model" in self.evidence_classes): raise ValueError("terminal model evidence does not match its call count") if self.model_calls > 0 and self.external_network_calls != "observed": raise ValueError("terminal model calls require observed network evidence") + if (self.compensation_actions > 0) != (self.outcome == "ROLLED_BACK"): + raise ValueError("terminal compensation evidence is invalid") + if self.outcome == "VERIFIED": + if self.passed_contracts != self.required_contracts: + raise ValueError( + "terminal VERIFIED outcome lacks complete contract coverage" + ) + if not self.production_eligible or not self.execution_completed: + raise ValueError("terminal VERIFIED outcome is not production complete") + required_classes = {"authorization", "identity", "postcondition"} + if not required_classes.issubset(self.evidence_classes): + raise ValueError( + "terminal VERIFIED outcome lacks required evidence classes" + ) + if len(effect_classes) != 1: + raise ValueError("terminal VERIFIED outcome requires one effect tier") + elif self.production_eligible: + raise ValueError("only a VERIFIED terminal outcome is production eligible") + elif self.outcome == "HALTED" and self.execution_completed: + raise ValueError("terminal HALTED outcome cannot claim completed execution") return self def artifact_sha256(self) -> str: @@ -225,20 +282,25 @@ def artifact_sha256(self) -> str: class ProductionRunReceipt(ClosedSignedModel): - """Cross-language integer projection of every current RunReceipt field.""" + """Cross-language integer projection of one terminal report.""" schema_version: Literal["openadapt.production-run-receipt/v1"] = ( "openadapt.production-run-receipt/v1" ) - source_schema_version: Literal["openadapt.run-receipt/v2"] = ( - "openadapt.run-receipt/v2" - ) - outcome: Literal["VERIFIED"] - transaction_outcome: Literal["VERIFIED"] + source_schema_version: Literal[ + "openadapt.run-receipt/v2", + "openadapt.run-report/v1", + ] + outcome: Literal["VERIFIED", "HALTED", "FAILED", "ROLLED_BACK"] + transaction_outcome: Literal[ + "VERIFIED", + "HALTED_BEFORE_EFFECT", + "RECONCILIATION_REQUIRED", + ] profile: Literal["standard", "regulated"] - production_eligible: Literal[True] + production_eligible: StrictBool steps_total: StrictInt = Field(ge=1, le=JS_MAX_SAFE_INTEGER) - steps_ok: StrictInt = Field(ge=1, le=JS_MAX_SAFE_INTEGER) + steps_ok: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) heals: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) model_calls: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) est_cost_microusd: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) @@ -266,8 +328,9 @@ class ProductionRunReceipt(ClosedSignedModel): "model", ], ..., - ] = Field(min_length=4, max_length=7) + ] = Field(min_length=1, max_length=7) effect_tier_reached: Literal[ + "none", "independent_system", "independent_session", "persisted_state_reacquisition", @@ -275,14 +338,14 @@ class ProductionRunReceipt(ClosedSignedModel): authorization_required: StrictInt = Field(ge=1, le=JS_MAX_SAFE_INTEGER) authorization_confirmed: StrictInt = Field(ge=1, le=JS_MAX_SAFE_INTEGER) identity_required: StrictInt = Field(ge=1, le=JS_MAX_SAFE_INTEGER) - identity_confirmed: StrictInt = Field(ge=1, le=JS_MAX_SAFE_INTEGER) + identity_confirmed: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) postconditions_required: StrictInt = Field(ge=1, le=JS_MAX_SAFE_INTEGER) - postconditions_confirmed: StrictInt = Field(ge=1, le=JS_MAX_SAFE_INTEGER) - effects_required: StrictInt = Field(ge=1, le=JS_MAX_SAFE_INTEGER) - effects_confirmed: StrictInt = Field(ge=1, le=JS_MAX_SAFE_INTEGER) - identity_armed: StrictInt = Field(ge=1, le=JS_MAX_SAFE_INTEGER) - identity_applicable: StrictInt = Field(ge=1, le=JS_MAX_SAFE_INTEGER) - over_halt_count: Literal[0] + postconditions_confirmed: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) + effects_required: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) + effects_confirmed: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) + identity_armed: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) + identity_applicable: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) + over_halt_count: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) substrate: Literal["web", "windows", "macos", "linux", "rdp", "citrix"] provenance: Literal["production"] receipt_builder_version: str = Field( @@ -310,14 +373,14 @@ def _closed_receipt(self) -> "ProductionRunReceipt": ), ("effect", self.effects_required, self.effects_confirmed), ): - if required != confirmed: - raise ValueError(f"production receipt lacks complete {label} coverage") + if confirmed > required: + raise ValueError(f"terminal receipt exceeds required {label} coverage") if self.authorization_required != 1: - raise ValueError("production receipt requires one authorization") - if self.steps_ok != self.steps_total: - raise ValueError("production receipt requires all steps to succeed") - if self.identity_armed != self.identity_applicable: - raise ValueError("production receipt requires complete identity arming") + raise ValueError("terminal receipt requires one authorization") + if self.authorization_confirmed != 1: + raise ValueError("terminal receipt requires one passed authorization") + if self.steps_ok > self.steps_total: + raise ValueError("terminal receipt successful step count is invalid") if self.evidence_classes != tuple(sorted(self.evidence_classes)) or len( self.evidence_classes ) != len(set(self.evidence_classes)): @@ -327,6 +390,67 @@ def _closed_receipt(self) -> "ProductionRunReceipt": for value in self.rung_histogram.values() ): raise ValueError("production receipt rung counts are invalid") + effect_classes = { + item for item in self.evidence_classes if item.startswith("effect_tier_") + } + expected_effect_tier = { + "effect_tier_1": "independent_system", + "effect_tier_2": "independent_session", + "effect_tier_3": "persisted_state_reacquisition", + } + if self.effects_confirmed == 0: + if effect_classes or self.effect_tier_reached != "none": + raise ValueError("terminal receipt effect evidence is inconsistent") + elif ( + len(effect_classes) != 1 + or self.effect_tier_reached + != (expected_effect_tier[next(iter(effect_classes))]) + ): + raise ValueError("terminal receipt effect tier is inconsistent") + if self.transaction_outcome == "VERIFIED": + if ( + self.outcome != "VERIFIED" + or not self.production_eligible + or self.source_schema_version != "openadapt.run-receipt/v2" + or self.steps_ok != self.steps_total + or self.identity_armed != self.identity_applicable + or self.over_halt_count != 0 + or self.effect_tier_reached == "none" + ): + raise ValueError("VERIFIED terminal receipt is incomplete") + for label, required, confirmed in ( + ( + "authorization", + self.authorization_required, + self.authorization_confirmed, + ), + ("identity", self.identity_required, self.identity_confirmed), + ( + "postcondition", + self.postconditions_required, + self.postconditions_confirmed, + ), + ("effect", self.effects_required, self.effects_confirmed), + ): + if required != confirmed: + raise ValueError( + f"VERIFIED terminal receipt lacks complete {label} coverage" + ) + elif self.production_eligible: + raise ValueError( + "non-VERIFIED terminal receipt cannot be production eligible" + ) + elif self.source_schema_version != "openadapt.run-report/v1": + raise ValueError( + "non-VERIFIED terminal receipt must derive from its report" + ) + elif self.transaction_outcome == "HALTED_BEFORE_EFFECT": + if ( + self.outcome != "HALTED" + or self.effects_confirmed != 0 + or self.effect_tier_reached != "none" + ): + raise ValueError("HALTED terminal receipt does not prove no effect") return self @@ -347,6 +471,7 @@ def project_production_run_receipt(receipt: RunReceipt) -> ProductionRunReceipt: # instead of a static cast; a value outside the production subset raises. return ProductionRunReceipt.model_validate( { + "source_schema_version": "openadapt.run-receipt/v2", "outcome": receipt.outcome, "transaction_outcome": receipt.transaction_outcome, "profile": receipt.profile, @@ -383,10 +508,128 @@ def project_production_run_receipt(receipt: RunReceipt) -> ProductionRunReceipt: ) +def project_production_terminal_run_receipt( + report: RunReport, + *, + transaction_outcome: TransactionOutcome, +) -> ProductionRunReceipt: + """Project a non-success terminal report without creating a success receipt.""" + + if transaction_outcome not in { + TransactionOutcome.HALTED_BEFORE_EFFECT, + TransactionOutcome.RECONCILIATION_REQUIRED, + }: + raise ProductionTerminalVerificationError( + "non-success terminal receipt has an invalid transaction outcome" + ) + envelope = report.outcome_envelope + if ( + envelope is None + or report.execution_outcome not in {"HALTED", "FAILED", "ROLLED_BACK"} + or report.execution_profile not in {"standard", "regulated"} + or report.production_eligible + or report.execution_completed is True + and report.execution_outcome == "HALTED" + or report.transaction_outcome != transaction_outcome.value + or report.transaction_billable is not False + or report.bundle_content_digest is None + ): + raise ProductionTerminalVerificationError( + "terminal report lacks its closed non-success transaction contract" + ) + if not report.results: + raise ProductionTerminalVerificationError( + "terminal report contains no retained step result" + ) + report_bytes = canonical_json(report.model_dump(mode="json")) + report_sha256 = hashlib.sha256(report_bytes).hexdigest() + try: + micros = Decimal(str(round(float(report.est_model_cost_usd), 6))) * Decimal( + 1_000_000 + ) + except (InvalidOperation, TypeError, ValueError) as exc: + raise ProductionTerminalVerificationError( + "terminal report cost is not an exact integer microusd value" + ) from exc + if micros != micros.to_integral_value(): + raise ProductionTerminalVerificationError( + "terminal report cost is not an exact integer microusd value" + ) + required = envelope.required_contracts + passed = envelope.passed_contracts + confirmed_tiers = [ + int(item.verification_tier) + for result in report.results + for item in result.effect_evidence + if item.final_verdict == "confirmed" + and item.observed_effect == "present" + and item.verification_tier is not None + ] + if int(passed.effect) > 0 and len(confirmed_tiers) != int(passed.effect): + raise ProductionTerminalVerificationError( + "terminal report lacks exact confirmed effect tiers" + ) + effect_tier_reached = ( + { + 1: "independent_system", + 2: "independent_session", + 3: "persisted_state_reacquisition", + }.get(max(confirmed_tiers)) + if confirmed_tiers + else "none" + ) + if effect_tier_reached is None: + raise ProductionTerminalVerificationError( + "terminal report effect tier is outside the production range" + ) + try: + return ProductionRunReceipt.model_validate( + { + "source_schema_version": "openadapt.run-report/v1", + "outcome": report.execution_outcome, + "transaction_outcome": transaction_outcome.value, + "profile": report.execution_profile, + "production_eligible": False, + "steps_total": len(report.results), + "steps_ok": sum(1 for result in report.results if result.ok), + "heals": int(report.heal_count), + "model_calls": int(report.model_calls), + "est_cost_microusd": int(micros), + "duration_ms": int(round(float(report.total_ms))), + "rung_histogram": dict(report.rung_counts), + "evidence_classes": tuple(sorted(envelope.evidence_classes)), + "effect_tier_reached": effect_tier_reached, + "authorization_required": int(required.authorization), + "authorization_confirmed": int(passed.authorization), + "identity_required": int(required.identity), + "identity_confirmed": int(passed.identity), + "postconditions_required": int(required.postcondition), + "postconditions_confirmed": int(passed.postcondition), + "effects_required": int(required.effect), + "effects_confirmed": int(passed.effect), + "identity_armed": int(report.identity_armed_steps), + "identity_applicable": int(report.identity_applicable_steps), + "over_halt_count": _over_halt_count(report), + "substrate": report.execution_target_kind, + "provenance": "production", + "receipt_builder_version": _receipt_builder_version(), + "external_network_calls": envelope.external_network_calls, + "bundle_digest": report.bundle_content_digest, + "source_receipt_digest": report_sha256, + "source_receipt_sha256": report_sha256, + "generated_at": _hour_utc(report.started_at), + } + ) + except (TypeError, ValueError) as exc: + raise ProductionTerminalVerificationError( + "terminal report cannot produce a closed non-success receipt" + ) from exc + + def prepare_production_terminal_evidence( report: RunReport, ) -> PreparedProductionTerminalEvidence: - """Revalidate the exact report and build the only terminal-safe projections. + """Revalidate the exact report and build its terminal-safe projections. The returned report bytes are the bytes that the runner must store as the immutable report object. The production proof later binds the storage @@ -404,12 +647,42 @@ def prepare_production_terminal_evidence( envelope is None or validated.run_id_sha256 is None or validated.bundle_content_digest is None + or validated.workflow_contract_sha256 is None ): raise ProductionTerminalVerificationError( "terminal report lacks its run or bundle binding" ) + transaction_outcome = classify_transaction_outcome(validated) + if transaction_outcome not in { + TransactionOutcome.VERIFIED, + TransactionOutcome.HALTED_BEFORE_EFFECT, + TransactionOutcome.RECONCILIATION_REQUIRED, + }: + raise ProductionTerminalVerificationError( + "terminal report does not have an admitted terminal transaction outcome" + ) + if ( + validated.transaction_outcome != transaction_outcome.value + or validated.transaction_billable is not transaction_outcome.is_billable + ): + raise ProductionTerminalVerificationError( + "terminal report transaction fields differ from its retained evidence" + ) + if transaction_outcome is TransactionOutcome.HALTED_BEFORE_EFFECT and any( + _is_consequential_result(result) and not _effect_absence_proven(result) + for result in validated.results + ): + raise ProductionTerminalVerificationError( + "terminal HALTED report lacks exact effect-absence evidence" + ) try: - receipt = project_production_run_receipt(build_receipt(validated)) + if transaction_outcome is TransactionOutcome.VERIFIED: + receipt = project_production_run_receipt(build_receipt(validated)) + else: + receipt = project_production_terminal_run_receipt( + validated, + transaction_outcome=transaction_outcome, + ) outcome = ProductionExecutionOutcome.model_validate( { "version": envelope.version, @@ -435,7 +708,7 @@ def prepare_production_terminal_evidence( ) except (ReceiptError, ValueError) as exc: raise ProductionTerminalVerificationError( - "terminal report is not a complete production VERIFIED outcome" + "terminal report is not a complete production terminal outcome" ) from exc report_bytes = canonical_json(validated.model_dump(mode="json")) report_sha256 = hashlib.sha256(report_bytes).hexdigest() @@ -448,6 +721,7 @@ def prepare_production_terminal_evidence( execution_outcome=outcome, run_receipt=receipt, run_receipt_sha256=receipt_sha256, + transaction_outcome=transaction_outcome, report=validated, ) @@ -538,7 +812,7 @@ class ProductionIdentitySignal(ClosedSignedModel): class ProductionIdentityResult(ClosedSignedModel): result_index: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) - status: Literal["verified"] + status: Literal["verified", "mismatch", "abstain", "unreadable"] mode: Literal["context", "param", "structured", "pixel", "vlm", "signal_quorum"] signals: tuple[ProductionIdentitySignal, ...] = Field(max_length=32) @@ -559,17 +833,17 @@ class ProductionIdentityEvidenceManifest(ClosedSignedModel): ) identity_contract_sha256: str = Field(pattern=_SHA256_RE) workflow_contract_sha256: str = Field(pattern=_SHA256_RE) - required: StrictInt = Field(ge=1, le=JS_MAX_SAFE_INTEGER) - confirmed: StrictInt = Field(ge=1, le=JS_MAX_SAFE_INTEGER) - results: tuple[ProductionIdentityResult, ...] = Field( - min_length=1, max_length=10_000 - ) + required: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) + confirmed: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) + results: tuple[ProductionIdentityResult, ...] = Field(max_length=10_000) manifest_sha256: str = Field(pattern=_SHA256_RE) @model_validator(mode="after") def _digest(self) -> "ProductionIdentityEvidenceManifest": - if self.required != self.confirmed or len(self.results) != self.required: - raise ValueError("production identity evidence coverage is incomplete") + if self.confirmed > self.required or len(self.results) > self.required: + raise ValueError("production identity evidence coverage is invalid") + if sum(item.status == "verified" for item in self.results) != self.confirmed: + raise ValueError("production identity confirmed count is invalid") indices = tuple(item.result_index for item in self.results) if indices != tuple(sorted(indices)) or len(indices) != len(set(indices)): raise ValueError("production identity evidence results are invalid") @@ -586,23 +860,22 @@ class ProductionPostconditionEvidenceManifest(ClosedSignedModel): "openadapt.production-postcondition-evidence/v1" ) workflow_contract_sha256: str = Field(pattern=_SHA256_RE) - required: StrictInt = Field(ge=1, le=JS_MAX_SAFE_INTEGER) - confirmed: StrictInt = Field(ge=1, le=JS_MAX_SAFE_INTEGER) - records: tuple[PostconditionContractEvidence, ...] = Field( - min_length=1, max_length=10_000 - ) + required: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) + confirmed: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) + records: tuple[PostconditionContractEvidence, ...] = Field(max_length=10_000) manifest_sha256: str = Field(pattern=_SHA256_RE) @model_validator(mode="after") def _digest(self) -> "ProductionPostconditionEvidenceManifest": - if self.required != self.confirmed or len(self.records) != self.required: - raise ValueError("production postcondition evidence coverage is incomplete") + if self.confirmed > self.required or len(self.records) != self.required: + raise ValueError("production postcondition evidence coverage is invalid") if any( - item.verdict != "passed" - or item.workflow_contract_sha256 != self.workflow_contract_sha256 + item.workflow_contract_sha256 != self.workflow_contract_sha256 for item in self.records ): raise ValueError("production postcondition evidence is invalid") + if sum(item.verdict == "passed" for item in self.records) != self.confirmed: + raise ValueError("production postcondition confirmed count is invalid") expected = _evidence_manifest_sha256( b"openadapt-production-postcondition-evidence-v1\0", self ) @@ -624,23 +897,98 @@ class ProductionEffectEvidence(ClosedSignedModel): reconciliation_actions: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) +class ProductionTerminalEffectState(ClosedSignedModel): + """Remote-safe state for one effect contract on a non-success terminal.""" + + record_kind: Literal["terminal_effect_state"] = "terminal_effect_state" + result_index: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) + effect_contract_hash: str = Field(pattern=r"^sha256:[a-f0-9]{64}$") + attempt_state: Literal[ + "not_actuated", + "delivered", + "actuated_api", + "delivery_uncertain", + ] + observed_effect: Literal["present", "absent", "conflicting", "unknown"] + effect_verified: StrictBool + verification_performed: StrictBool + verifier_identity: str | None = Field( + default=None, pattern=r"^sha256:[a-f0-9]{64}$" + ) + verification_tier: StrictInt | None = Field(default=None, ge=1, le=3) + final_verdict: Literal["confirmed", "refuted", "indeterminate"] | None + resolved_delivery_uncertainty: StrictBool + absence_basis: Literal["not_actuated", "verifier_refuted", "none"] + reconciliation_completed: StrictBool + reconciliation_actions: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) + + @model_validator(mode="after") + def _closed_terminal_effect_state(self) -> "ProductionTerminalEffectState": + if self.verification_performed != (self.final_verdict is not None): + raise ValueError("terminal effect verification fields are inconsistent") + if self.verification_performed != (self.verification_tier is not None): + raise ValueError("terminal effect verification tier is inconsistent") + if self.verification_performed != (self.verifier_identity is not None): + raise ValueError("terminal effect verifier identity is inconsistent") + if self.effect_verified != ( + self.final_verdict == "confirmed" and self.observed_effect == "present" + ): + raise ValueError("terminal effect verified state is inconsistent") + if self.absence_basis == "not_actuated": + if ( + self.attempt_state != "not_actuated" + or self.observed_effect != "absent" + or self.verification_performed + or self.resolved_delivery_uncertainty + ): + raise ValueError("terminal non-actuation evidence is invalid") + elif self.absence_basis == "verifier_refuted": + if ( + self.attempt_state == "not_actuated" + or self.observed_effect != "absent" + or self.final_verdict != "refuted" + or not self.verification_performed + ): + raise ValueError("terminal verifier absence evidence is invalid") + elif self.attempt_state == "not_actuated" or ( + self.final_verdict == "refuted" and self.observed_effect == "absent" + ): + raise ValueError("terminal absence evidence must name its basis") + if self.reconciliation_completed != (self.reconciliation_actions > 0): + raise ValueError("terminal effect reconciliation fields are inconsistent") + return self + + class ProductionEffectEvidenceManifest(ClosedSignedModel): schema_version: Literal["openadapt.production-effect-evidence/v1"] = ( "openadapt.production-effect-evidence/v1" ) effect_contract_sha256: str = Field(pattern=_SHA256_RE) workflow_contract_sha256: str = Field(pattern=_SHA256_RE) - required: StrictInt = Field(ge=1, le=JS_MAX_SAFE_INTEGER) - confirmed: StrictInt = Field(ge=1, le=JS_MAX_SAFE_INTEGER) - records: tuple[ProductionEffectEvidence, ...] = Field( - min_length=1, max_length=10_000 + required: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) + confirmed: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) + records: tuple[ProductionEffectEvidence | ProductionTerminalEffectState, ...] = ( + Field(max_length=10_000) ) manifest_sha256: str = Field(pattern=_SHA256_RE) @model_validator(mode="after") def _digest(self) -> "ProductionEffectEvidenceManifest": - if self.required != self.confirmed or len(self.records) != self.required: - raise ValueError("production effect evidence coverage is incomplete") + if self.confirmed > self.required or len(self.records) != self.required: + raise ValueError("production effect evidence coverage is invalid") + if all(isinstance(item, ProductionEffectEvidence) for item in self.records): + if self.required != self.confirmed: + raise ValueError("production effect success coverage is incomplete") + elif ( + sum( + isinstance(item, ProductionTerminalEffectState) + and item.final_verdict == "confirmed" + and item.observed_effect == "present" + for item in self.records + ) + != self.confirmed + ): + raise ValueError("production effect confirmed count is invalid") keys = tuple( (item.result_index, item.effect_contract_hash) for item in self.records ) @@ -1196,9 +1544,7 @@ class ProductionDeliveryPermitChain(ClosedSignedModel): schema_version: Literal["openadapt.production-delivery-permit-chain/v2"] = ( PERMIT_CHAIN_SCHEMA ) - entries: tuple[ProductionDeliveryPermit, ...] = Field( - min_length=1, max_length=10_000 - ) + entries: tuple[ProductionDeliveryPermit, ...] = Field(max_length=10_000) permit_chain_sha256: str = Field(pattern=_SHA256_RE) @model_validator(mode="after") @@ -1208,6 +1554,19 @@ def _closed_chain(self) -> "ProductionDeliveryPermitChain": # in-memory mutation cannot enter a trusted chain with a stale digest. for item in self.entries: ProductionDeliveryPermit.model_validate(item.model_dump(mode="json")) + expected = hashlib.sha256( + PERMIT_CHAIN_DOMAIN + + canonical_json( + { + "schema_version": self.schema_version, + "entries": [item.model_dump(mode="json") for item in self.entries], + } + ) + ).hexdigest() + if self.permit_chain_sha256 != expected: + raise ValueError("delivery permit chain digest is invalid") + if not self.entries: + return self authority = self.entries[0].execution_authority_id authority_digest = self.entries[0].execution_authority_sha256 admission_digest = self.entries[0].admission_artifact_sha256 @@ -1281,17 +1640,6 @@ def _closed_chain(self) -> "ProductionDeliveryPermitChain": for previous, current in zip(event_times, event_times[1:]) ): raise ValueError("delivery permit chronology is invalid") - expected = hashlib.sha256( - PERMIT_CHAIN_DOMAIN - + canonical_json( - { - "schema_version": self.schema_version, - "entries": [item.model_dump(mode="json") for item in self.entries], - } - ) - ).hexdigest() - if self.permit_chain_sha256 != expected: - raise ValueError("delivery permit chain digest is invalid") return self @classmethod @@ -1410,25 +1758,109 @@ def build_production_evidence_manifests( confirmed=outcome.passed_contracts.postcondition, records=outcome.postcondition_evidence, ) - effect_records: list[ProductionEffectEvidence] = [] + effect_records: list[ProductionEffectEvidence | ProductionTerminalEffectState] = [] for result_index, result in enumerate(report.results): if result.skipped or result.exception_handled: continue - for item in result.effect_evidence: + if prepared.transaction_outcome is TransactionOutcome.VERIFIED: + for effect_item in result.effect_evidence: + effect_records.append( + ProductionEffectEvidence.model_validate( + { + "result_index": result_index, + "effect_contract_hash": effect_item.effect_contract_hash, + "verifier_identity": effect_item.verifier_identity, + "verification_tier": effect_item.verification_tier, + "final_verdict": effect_item.final_verdict, + "observed_effect": effect_item.observed_effect, + "reconciliation_completed": ( + effect_item.reconciliation_completed + ), + "reconciliation_actions": ( + effect_item.reconciliation_actions + ), + } + ) + ) + continue + if not _is_consequential_result(result): + continue + evidence_by_hash: dict[str, list[EffectVerificationEvidence]] = {} + for effect_item in result.effect_evidence: + evidence_by_hash.setdefault(effect_item.effect_contract_hash, []).append( + effect_item + ) + effect_hashes = tuple(sorted(set(result.effect_contract_hashes))) + if len(effect_hashes) != len(result.effect_contract_hashes): + raise ProductionTerminalVerificationError( + "terminal effect contract hashes are duplicated" + ) + attempt_state = _attempt_state(result) + uncertainty_resolved = bool( + result.delivery_uncertainty is not None + and result.delivery_uncertainty.resolved_by_contract + ) + for effect_hash in effect_hashes: + matches = evidence_by_hash.pop(effect_hash, []) + if len(matches) > 1: + raise ProductionTerminalVerificationError( + "terminal effect evidence is duplicated" + ) + terminal_item: EffectVerificationEvidence | None = ( + matches[0] if matches else None + ) + if terminal_item is None: + observed_effect = ( + "absent" if attempt_state == "not_actuated" else "unknown" + ) + final_verdict = None + verification_tier = None + verifier_identity = None + reconciliation_completed = False + reconciliation_actions = 0 + absence_basis = ( + "not_actuated" if attempt_state == "not_actuated" else "none" + ) + else: + observed_effect = terminal_item.observed_effect + final_verdict = terminal_item.final_verdict + verification_tier = terminal_item.verification_tier + verifier_identity = terminal_item.verifier_identity + reconciliation_completed = terminal_item.reconciliation_completed + reconciliation_actions = terminal_item.reconciliation_actions + absence_basis = ( + "verifier_refuted" + if terminal_item.final_verdict == "refuted" + and terminal_item.observed_effect == "absent" + else "none" + ) effect_records.append( - ProductionEffectEvidence.model_validate( + ProductionTerminalEffectState.model_validate( { "result_index": result_index, - "effect_contract_hash": item.effect_contract_hash, - "verifier_identity": item.verifier_identity, - "verification_tier": item.verification_tier, - "final_verdict": item.final_verdict, - "observed_effect": item.observed_effect, - "reconciliation_completed": item.reconciliation_completed, - "reconciliation_actions": item.reconciliation_actions, + "effect_contract_hash": effect_hash, + "attempt_state": attempt_state, + "observed_effect": observed_effect, + "effect_verified": bool( + terminal_item is not None + and terminal_item.final_verdict == "confirmed" + and terminal_item.observed_effect == "present" + ), + "verification_performed": terminal_item is not None, + "verifier_identity": verifier_identity, + "verification_tier": verification_tier, + "final_verdict": final_verdict, + "resolved_delivery_uncertainty": uncertainty_resolved, + "absence_basis": absence_basis, + "reconciliation_completed": reconciliation_completed, + "reconciliation_actions": reconciliation_actions, } ) ) + if evidence_by_hash: + raise ProductionTerminalVerificationError( + "terminal effect evidence lacks a declared contract" + ) effect_records.sort(key=lambda item: (item.result_index, item.effect_contract_hash)) effect = build_evidence_manifest( ProductionEffectEvidenceManifest, @@ -1482,7 +1914,7 @@ class ProductionTerminalVerificationPayload(ClosedSignedModel): execution_authority_sha256: str = Field(pattern=_SHA256_RE) execution_authority_signer_sha256: str = Field(pattern=_SHA256_RE) permit_chain: ProductionDeliveryPermitChain - permit_count: StrictInt = Field(ge=1, le=JS_MAX_SAFE_INTEGER) + permit_count: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) final_authority_sequence: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) final_runtime_delivery_sequence: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) workflow_contract_sha256: str = Field(pattern=_SHA256_RE) @@ -1498,7 +1930,7 @@ class ProductionTerminalVerificationPayload(ClosedSignedModel): issued_at: str @model_validator(mode="after") - def _closed_terminal_success(self) -> "ProductionTerminalVerificationPayload": + def _closed_terminal_outcome(self) -> "ProductionTerminalVerificationPayload": if hashlib.sha256(self.run_id.encode("utf-8")).hexdigest() != ( self.flow_run_id_sha256 ): @@ -1508,49 +1940,63 @@ def _closed_terminal_success(self) -> "ProductionTerminalVerificationPayload": if self.workflow_version_id != self.bundle_version_id: raise ValueError("terminal workflow and bundle versions must match") chain = self.permit_chain - final = chain.entries[-1] - if ( - self.execution_authority_id, - self.execution_authority_sha256, - self.execution_authority_signer_sha256, - self.admission_artifact_sha256, - ) != ( - final.execution_authority_id, - final.execution_authority_sha256, - final.authority_signer_sha256, - final.admission_artifact_sha256, - ): - raise ValueError("terminal authority does not match its permit chain") - if ( - self.run_id != final.run_id - or self.flow_run_id_sha256 != final.flow_run_id_sha256 - ): - raise ValueError("terminal run identity does not match its permit chain") - if ( - self.evidence_identity_sha256, - self.environment_digest, - self.qualification_signer_registry_sha256, - self.qualification_signer_registry_revision, - ) != ( - final.evidence_identity_sha256, - final.environment_digest, - final.qualification_signer_registry_sha256, - final.qualification_signer_registry_revision, - ): - raise ValueError("terminal qualification state does not match its permits") - if ( - self.permit_count, - self.final_authority_sequence, - self.final_runtime_delivery_sequence, - ) != ( - len(chain.entries), - final.authority_sequence, - final.runtime_delivery_sequence, - ): - raise ValueError("terminal permit counts do not match the permit chain") receipt = self.run_receipt outcome = self.execution_outcome manifests = self.evidence_manifests + if chain.entries: + final = chain.entries[-1] + if ( + self.execution_authority_id, + self.execution_authority_sha256, + self.execution_authority_signer_sha256, + self.admission_artifact_sha256, + ) != ( + final.execution_authority_id, + final.execution_authority_sha256, + final.authority_signer_sha256, + final.admission_artifact_sha256, + ): + raise ValueError("terminal authority does not match its permit chain") + if ( + self.run_id != final.run_id + or self.flow_run_id_sha256 != final.flow_run_id_sha256 + ): + raise ValueError( + "terminal run identity does not match its permit chain" + ) + if ( + self.evidence_identity_sha256, + self.environment_digest, + self.qualification_signer_registry_sha256, + self.qualification_signer_registry_revision, + ) != ( + final.evidence_identity_sha256, + final.environment_digest, + final.qualification_signer_registry_sha256, + final.qualification_signer_registry_revision, + ): + raise ValueError( + "terminal qualification state does not match its permits" + ) + if ( + self.permit_count, + self.final_authority_sequence, + self.final_runtime_delivery_sequence, + ) != ( + len(chain.entries), + final.authority_sequence, + final.runtime_delivery_sequence, + ): + raise ValueError("terminal permit counts do not match the permit chain") + elif ( + receipt.transaction_outcome != "HALTED_BEFORE_EFFECT" + or self.permit_count != 0 + or self.final_authority_sequence != 0 + or self.final_runtime_delivery_sequence != 0 + ): + raise ValueError( + "only a HALTED_BEFORE_EFFECT terminal may use an empty permit chain" + ) if ( self.workflow_contract_sha256 != outcome.workflow_contract_sha256 or self.execution_outcome_sha256 != outcome.artifact_sha256() @@ -1622,17 +2068,56 @@ def _closed_terminal_success(self) -> "ProductionTerminalVerificationPayload": raise ValueError( "terminal run receipt does not match its execution outcome" ) + transaction_outcome = receipt.transaction_outcome + if transaction_outcome == "VERIFIED": + if ( + outcome.outcome != "VERIFIED" + or not outcome.production_eligible + or not outcome.execution_completed + or not chain.entries + ): + raise ValueError("terminal VERIFIED proof is incomplete") + elif transaction_outcome == "HALTED_BEFORE_EFFECT": + if ( + outcome.outcome != "HALTED" + or outcome.production_eligible + or outcome.execution_completed + or receipt.production_eligible + or any( + not isinstance(item, ProductionTerminalEffectState) + or item.absence_basis not in {"not_actuated", "verifier_refuted"} + for item in manifests.effect.records + ) + ): + raise ValueError("terminal HALTED proof lacks exact effect absence") + elif ( + transaction_outcome != "RECONCILIATION_REQUIRED" + or outcome.outcome == "VERIFIED" + or outcome.production_eligible + or receipt.production_eligible + or not chain.entries + ): + raise ValueError("terminal reconciliation proof is invalid") + if transaction_outcome != "VERIFIED" and ( + receipt.source_receipt_digest != self.run_report_sha256 + or receipt.source_receipt_sha256 != self.run_report_sha256 + ): + raise ValueError("terminal non-success receipt does not bind its report") verified = _parse_utc(self.verified_at, field="terminal verified_at") issued = _parse_utc(self.issued_at, field="terminal issued_at") if not verified <= issued <= verified + timedelta(minutes=5): raise ValueError("terminal proof issue time is invalid") - final_delivered = _parse_utc(final.delivered_at, field="permit delivered_at") - registry_expires = _parse_utc( - final.qualification_signer_registry_expires_at, - field="permit registry expires_at", - ) - if not final_delivered <= verified < registry_expires: - raise ValueError("terminal verification is outside permit chronology") + if chain.entries: + final = chain.entries[-1] + final_delivered = _parse_utc( + final.delivered_at, field="permit delivered_at" + ) + registry_expires = _parse_utc( + final.qualification_signer_registry_expires_at, + field="permit registry expires_at", + ) + if not final_delivered <= verified < registry_expires: + raise ValueError("terminal verification is outside permit chronology") if self.run_report_object_sha256 != self.run_report_sha256: raise ValueError( "terminal report object must contain the exact revalidated report bytes" @@ -1734,14 +2219,12 @@ class ProductionTerminalVerificationExpected(ClosedSignedModel): execution_authority_sha256: str = Field(pattern=_SHA256_RE) execution_authority_signer_sha256: str = Field(pattern=_SHA256_RE) permit_chain_sha256: str = Field(pattern=_SHA256_RE) - permit_count: StrictInt = Field(ge=1, le=JS_MAX_SAFE_INTEGER) + permit_count: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) final_authority_sequence: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) final_runtime_delivery_sequence: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) authenticated_runner_id_sha256: str = Field(pattern=_SHA256_RE) authenticated_session_id_sha256: str = Field(pattern=_SHA256_RE) - acknowledged_one_use_claim_ids: tuple[str, ...] = Field( - min_length=1, max_length=10_000 - ) + acknowledged_one_use_claim_ids: tuple[str, ...] = Field(max_length=10_000) workflow_contract_sha256: str = Field(pattern=_SHA256_RE) execution_outcome_sha256: str = Field(pattern=_SHA256_RE) run_receipt_sha256: str = Field(pattern=_SHA256_RE) @@ -1885,7 +2368,7 @@ def build_production_terminal_verification( execution_authority_sha256=context.execution_authority_sha256, permit_chain=context.permit_chain, ) - final = context.permit_chain.entries[-1] + final = context.permit_chain.entries[-1] if context.permit_chain.entries else None payload = ProductionTerminalVerificationPayload( run_id=context.run_id, flow_run_id_sha256=prepared.flow_run_id_sha256, @@ -1919,8 +2402,10 @@ def build_production_terminal_verification( execution_authority_signer_sha256=(context.execution_authority_signer_sha256), permit_chain=context.permit_chain, permit_count=len(context.permit_chain.entries), - final_authority_sequence=final.authority_sequence, - final_runtime_delivery_sequence=final.runtime_delivery_sequence, + final_authority_sequence=(final.authority_sequence if final is not None else 0), + final_runtime_delivery_sequence=( + final.runtime_delivery_sequence if final is not None else 0 + ), workflow_contract_sha256=(prepared.execution_outcome.workflow_contract_sha256), execution_outcome=prepared.execution_outcome, execution_outcome_sha256=prepared.execution_outcome.artifact_sha256(), diff --git a/tests/fixtures/terminal_verification_v2_terminal_vectors.json b/tests/fixtures/terminal_verification_v2_terminal_vectors.json new file mode 100644 index 00000000..5764f76e --- /dev/null +++ b/tests/fixtures/terminal_verification_v2_terminal_vectors.json @@ -0,0 +1 @@ +{"key_id":"evidence-runner-ed25519-56475aa75463474c","private_key_base64":"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=","public_key_base64":"A6EHv/POEL4dcN0Y50vAmWfk1jCbpQ1fHdyGZBJVMbg=","schema_version":"openadapt.production-terminal-cross-language-vectors/v2","signature_domain_base64":"b3BlbmFkYXB0LXByb2R1Y3Rpb24tdGVybWluYWwtdmVyaWZpY2F0aW9uLXYyAA==","signer_sha256":"56475aa75463474c0285df5dbf2bcab73da651358839e9b77481b2eab107708c","vectors":[{"callback":{"artifact_bytes_source":"envelope_canonical_base64","outcome":"HALTED_BEFORE_EFFECT","report_sha256":"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb","run_id":"00000000-0000-4000-8000-000000000001","schema_version":"openadapt.hosted-runner-terminal/v1","started":true,"uncertain_delivery":false},"effect_state":{"absence_basis":"not_actuated","attempt_state":"not_actuated","effect_contract_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","effect_verified":false,"final_verdict":null,"observed_effect":"absent","reconciliation_actions":0,"reconciliation_completed":false,"record_kind":"terminal_effect_state","resolved_delivery_uncertainty":false,"result_index":0,"verification_performed":false,"verification_tier":null,"verifier_identity":null},"envelope_canonical_base64":"eyJwYXlsb2FkIjp7ImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA2IiwiYWRtaXNzaW9uX3BvbGljeV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYWRtaXR0ZWRfcnVudGltZV9idWlsZF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiYnVuZGxlX2FydGlmYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJidW5kbGVfY29udGVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYnVuZGxlX3ZlcnNpb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDQiLCJlZmZlY3RfY29udHJhY3Rfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImVudmlyb25tZW50X2NvbnRyYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJlbnZpcm9ubWVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXZpZGVuY2VfaWRlbnRpdHlfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImV2aWRlbmNlX21hbmlmZXN0cyI6eyJhdXRob3JpemF0aW9uIjp7ImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA2IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOCIsImV4ZWN1dGlvbl9hdXRob3JpdHlfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImdvdmVybmVkX2F1dGhvcml6YXRpb25faWRfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsIm1hbmlmZXN0X3NoYTI1NiI6IjMyY2QzNjEzYmVlOWJjNjkwNjkzYTM5NWQ5OTMzNTQ3ZjllZWI5ZjZmYWE1ZGJkYmIxNGExMDYyOThiZTQ2NWMiLCJwZXJtaXRfY2hhaW5fc2hhMjU2IjoiODJkYWI1NDI4ZTI1MmQxOGE1OWIwMTc3NzM5ZTAwY2FhZGI3NjJkY2Y1OWY0MDM2ZGVhNGQ3N2MzYzMyMDNjYiIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tYXV0aG9yaXphdGlvbi1ldmlkZW5jZS92MSJ9LCJlZmZlY3QiOnsiY29uZmlybWVkIjowLCJlZmZlY3RfY29udHJhY3Rfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsIm1hbmlmZXN0X3NoYTI1NiI6ImViYjU4MzYxNzhlZGZhYzYyOWJkOWJjYTkwZWNkMDE5NTkwOTQ5NjZhMGRkNjNiYWVhN2E2MmY2ZTNiMDRmZjgiLCJyZWNvcmRzIjpbeyJhYnNlbmNlX2Jhc2lzIjoibm90X2FjdHVhdGVkIiwiYXR0ZW1wdF9zdGF0ZSI6Im5vdF9hY3R1YXRlZCIsImVmZmVjdF9jb250cmFjdF9oYXNoIjoic2hhMjU2OmFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJlZmZlY3RfdmVyaWZpZWQiOmZhbHNlLCJmaW5hbF92ZXJkaWN0IjpudWxsLCJvYnNlcnZlZF9lZmZlY3QiOiJhYnNlbnQiLCJyZWNvbmNpbGlhdGlvbl9hY3Rpb25zIjowLCJyZWNvbmNpbGlhdGlvbl9jb21wbGV0ZWQiOmZhbHNlLCJyZWNvcmRfa2luZCI6InRlcm1pbmFsX2VmZmVjdF9zdGF0ZSIsInJlc29sdmVkX2RlbGl2ZXJ5X3VuY2VydGFpbnR5IjpmYWxzZSwicmVzdWx0X2luZGV4IjowLCJ2ZXJpZmljYXRpb25fcGVyZm9ybWVkIjpmYWxzZSwidmVyaWZpY2F0aW9uX3RpZXIiOm51bGwsInZlcmlmaWVyX2lkZW50aXR5IjpudWxsfV0sInJlcXVpcmVkIjoxLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWVmZmVjdC1ldmlkZW5jZS92MSIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifSwiaWRlbnRpdHkiOnsiY29uZmlybWVkIjoxLCJpZGVudGl0eV9jb250cmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwibWFuaWZlc3Rfc2hhMjU2IjoiMTM1Yzg2M2VkYzdmYWIxOGNhMjliNDkyOTNmYzI1YTFjOWJkNGRlMGU5ZWQyOGQ0Y2VjNmU4ZDBhNjc5MTIyOSIsInJlcXVpcmVkIjoxLCJyZXN1bHRzIjpbeyJtb2RlIjoic3RydWN0dXJlZCIsInJlc3VsdF9pbmRleCI6MCwic2lnbmFscyI6W10sInN0YXR1cyI6InZlcmlmaWVkIn1dLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWlkZW50aXR5LWV2aWRlbmNlL3YxIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSJ9LCJwb2xpY3kiOnsiYWRtaXNzaW9uX3BvbGljeV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZWZmZWN0X2NvbnRyYWN0X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJlbnZpcm9ubWVudF9jb250cmFjdF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwiZW52aXJvbm1lbnRfZGlnZXN0IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImdvdmVybmVkX3BvbGljeV9jb250cmFjdF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwiZ292ZXJuZWRfcnVudGltZV9pbnB1dHNfZGlnZXN0IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsImlkZW50aXR5X2NvbnRyYWN0X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJtYW5pZmVzdF9zaGEyNTYiOiI0Zjk4OGQwMTViY2Q3Y2Q3ZTA1YmEwNjYzZDg5ZjBhOTY4ZjBkOGFjZTk5YjA5MGViYWJlZTUyYTFjNTUwNDIxIiwibWluaW11bV9lZmZlY3RfdGllciI6MSwicnVudGltZV9lbnZpcm9ubWVudF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1wb2xpY3ktZXZpZGVuY2UvdjEifSwicG9zdGNvbmRpdGlvbiI6eyJjb25maXJtZWQiOjAsIm1hbmlmZXN0X3NoYTI1NiI6IjNlYTRjNjRhMzBiMGNmMTdiY2EwNGYzMjYwZTBhNDcxOGIyN2Y1MWUxZmRjMmJiODhhMTgyNjMwYTM0ZGQ1ZmYiLCJyZWNvcmRzIjpbeyJhY3Rpb25fa2luZCI6ImNsaWNrIiwiYWN0dWF0aW9uX3BhdGgiOiJndWkiLCJjb250cmFjdF9pbmRleCI6MCwiY29udHJhY3Rfa2luZCI6ImV4cGxpY2l0X3ByZWRpY2F0ZSIsImNvbnRyYWN0X3NoYTI1NiI6IjBhZGUwYjUyMGJjMDA3ODkxY2FjY2EwMDE3MTU3ODQ0MmEyYTc0Y2VmMTVmZjY0ZGRlNDVkZjA3YWZiNjRhZWIiLCJyZXN1bHRfaW5kZXgiOjAsInN0ZXBfY29udHJhY3Rfc2hhMjU2IjoiMWE1OTUzNmE0ODhiMWM0NmFhY2YwYmEzNzkzMGI4NDA2MmMxNDI3NTVmYTkzOTE1MmVmNWUyOGM0MDk0NzFlZCIsInN0ZXBfaW5kZXgiOjAsInZlcmRpY3QiOiJ1bnZlcmlmaWFibGUiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIn1dLCJyZXF1aXJlZCI6MSwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1wb3N0Y29uZGl0aW9uLWV2aWRlbmNlL3YxIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSJ9fSwiZXZpZGVuY2VfcnVubmVyX3NpZ25lcl9zaGEyNTYiOiI1NjQ3NWFhNzU0NjM0NzRjMDI4NWRmNWRiZjJiY2FiNzNkYTY1MTM1ODgzOWU5Yjc3NDgxYjJlYWIxMDc3MDhjIiwiZXhlY3V0aW9uX2F1dGhvcml0eV9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOCIsImV4ZWN1dGlvbl9hdXRob3JpdHlfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImV4ZWN1dGlvbl9hdXRob3JpdHlfc2lnbmVyX3NoYTI1NiI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJleGVjdXRpb25fb3V0Y29tZSI6eyJjb21wZW5zYXRpb25fYWN0aW9ucyI6MCwiZXZpZGVuY2VfY2xhc3NlcyI6WyJhdXRob3JpemF0aW9uIiwiaWRlbnRpdHkiXSwiZXhlY3V0aW9uX2NvbXBsZXRlZCI6ZmFsc2UsImV4dGVybmFsX25ldHdvcmtfY2FsbHMiOiJub25lIiwibW9kZWxfY2FsbHMiOjAsIm91dGNvbWUiOiJIQUxURUQiLCJwYXNzZWRfY29udHJhY3RzIjp7ImF1dGhvcml6YXRpb24iOjEsImVmZmVjdCI6MCwiaWRlbnRpdHkiOjEsInBvc3Rjb25kaXRpb24iOjB9LCJwb3N0Y29uZGl0aW9uX2V2aWRlbmNlIjpbeyJhY3Rpb25fa2luZCI6ImNsaWNrIiwiYWN0dWF0aW9uX3BhdGgiOiJndWkiLCJjb250cmFjdF9pbmRleCI6MCwiY29udHJhY3Rfa2luZCI6ImV4cGxpY2l0X3ByZWRpY2F0ZSIsImNvbnRyYWN0X3NoYTI1NiI6IjBhZGUwYjUyMGJjMDA3ODkxY2FjY2EwMDE3MTU3ODQ0MmEyYTc0Y2VmMTVmZjY0ZGRlNDVkZjA3YWZiNjRhZWIiLCJyZXN1bHRfaW5kZXgiOjAsInN0ZXBfY29udHJhY3Rfc2hhMjU2IjoiMWE1OTUzNmE0ODhiMWM0NmFhY2YwYmEzNzkzMGI4NDA2MmMxNDI3NTVmYTkzOTE1MmVmNWUyOGM0MDk0NzFlZCIsInN0ZXBfaW5kZXgiOjAsInZlcmRpY3QiOiJ1bnZlcmlmaWFibGUiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIn1dLCJwcm9kdWN0aW9uX2VsaWdpYmxlIjpmYWxzZSwicHJvZmlsZSI6InN0YW5kYXJkIiwicXVhbGlmaWNhdGlvbl9ldmlkZW5jZV9vbmx5IjpmYWxzZSwicmVxdWlyZWRfY29udHJhY3RzIjp7ImF1dGhvcml6YXRpb24iOjEsImVmZmVjdCI6MSwiaWRlbnRpdHkiOjEsInBvc3Rjb25kaXRpb24iOjF9LCJ2ZXJzaW9uIjoib3BlbmFkYXB0LmV4ZWN1dGlvbi1vdXRjb21lL3YxIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSJ9LCJleGVjdXRpb25fb3V0Y29tZV9zaGEyNTYiOiJmZTM4OWJhYjBlYjQ0NDdjZWMxOTk4Mjc0ZjcyN2NhNTcwMDQ5ZmVmZDU1N2RiNzk5MDQ3Njk5ZjJmNzhmMTQyIiwiZXhlY3V0aW9uX3B1cnBvc2UiOiJwcm9kdWN0aW9uIiwiZmluYWxfYXV0aG9yaXR5X3NlcXVlbmNlIjowLCJmaW5hbF9ydW50aW1lX2RlbGl2ZXJ5X3NlcXVlbmNlIjowLCJmbG93X3J1bl9pZF9zaGEyNTYiOiIxMWU1OTRmNDgxOTU4YzEwZTMwMTVkMGJmMDQ0N2EyMmYwNjhhOGE2NDdmNDc1ZGYxNWNlMmM3YWI0YjhmM2YxIiwiaWRlbnRpdHlfY29udHJhY3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsImlzc3VlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDNaIiwicGVybWl0X2NoYWluIjp7ImVudHJpZXMiOltdLCJwZXJtaXRfY2hhaW5fc2hhMjU2IjoiODJkYWI1NDI4ZTI1MmQxOGE1OWIwMTc3NzM5ZTAwY2FhZGI3NjJkY2Y1OWY0MDM2ZGVhNGQ3N2MzYzMyMDNjYiIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcGVybWl0LWNoYWluL3YyIn0sInBlcm1pdF9jb3VudCI6MCwicXVhbGlmaWNhdGlvbl9zaWduZXJfcmVnaXN0cnlfcmV2aXNpb24iOjcsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJydW5faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDEiLCJydW5fcmVjZWlwdCI6eyJhdXRob3JpemF0aW9uX2NvbmZpcm1lZCI6MSwiYXV0aG9yaXphdGlvbl9yZXF1aXJlZCI6MSwiYnVuZGxlX2RpZ2VzdCI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJkdXJhdGlvbl9tcyI6MTAwLCJlZmZlY3RfdGllcl9yZWFjaGVkIjoibm9uZSIsImVmZmVjdHNfY29uZmlybWVkIjowLCJlZmZlY3RzX3JlcXVpcmVkIjoxLCJlc3RfY29zdF9taWNyb3VzZCI6MCwiZXZpZGVuY2VfY2xhc3NlcyI6WyJhdXRob3JpemF0aW9uIiwiaWRlbnRpdHkiXSwiZXh0ZXJuYWxfbmV0d29ya19jYWxscyI6Im5vbmUiLCJnZW5lcmF0ZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAwWiIsImhlYWxzIjowLCJpZGVudGl0eV9hcHBsaWNhYmxlIjoxLCJpZGVudGl0eV9hcm1lZCI6MSwiaWRlbnRpdHlfY29uZmlybWVkIjoxLCJpZGVudGl0eV9yZXF1aXJlZCI6MSwibW9kZWxfY2FsbHMiOjAsIm91dGNvbWUiOiJIQUxURUQiLCJvdmVyX2hhbHRfY291bnQiOjAsInBvc3Rjb25kaXRpb25zX2NvbmZpcm1lZCI6MCwicG9zdGNvbmRpdGlvbnNfcmVxdWlyZWQiOjEsInByb2R1Y3Rpb25fZWxpZ2libGUiOmZhbHNlLCJwcm9maWxlIjoic3RhbmRhcmQiLCJwcm92ZW5hbmNlIjoicHJvZHVjdGlvbiIsInJlY2VpcHRfYnVpbGRlcl92ZXJzaW9uIjoiMS4yLjMiLCJydW5nX2hpc3RvZ3JhbSI6e30sInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tcnVuLXJlY2VpcHQvdjEiLCJzb3VyY2VfcmVjZWlwdF9kaWdlc3QiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwic291cmNlX3JlY2VpcHRfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsInNvdXJjZV9zY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5ydW4tcmVwb3J0L3YxIiwic3RlcHNfb2siOjAsInN0ZXBzX3RvdGFsIjoxLCJzdWJzdHJhdGUiOiJ3ZWIiLCJ0cmFuc2FjdGlvbl9vdXRjb21lIjoiSEFMVEVEX0JFRk9SRV9FRkZFQ1QifSwicnVuX3JlY2VpcHRfc2hhMjU2IjoiYWI1MGEwMDZhODg4YjNmOTBlMWU3MWVmMjA5MjFhZjcxN2IyZjQxYTM2NzZlNjA1ZmJkYjgyMGNiNmI1M2NjNCIsInJ1bl9yZXBvcnRfb2JqZWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJydW5fcmVwb3J0X29iamVjdF92ZXJzaW9uIjoidmVyc2lvbjpoYWx0ZWQ6MSIsInJ1bl9yZXBvcnRfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsInJ1bnRpbWVfZW52aXJvbm1lbnRfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsInJ1bnRpbWVfc3Vic3RyYXRlIjoid2ViIiwicnVudGltZV92YWxpZGF0aW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA1Iiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi10ZXJtaW5hbC12ZXJpZmljYXRpb24vdjIiLCJ0ZW5hbnRfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDIiLCJ0ZXJtaW5hbF9zZXF1ZW5jZSI6MSwidmVyaWZpZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAyWiIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJ3b3JrZmxvd19pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwMyIsIndvcmtmbG93X3ZlcnNpb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDQifSwic2lnbmF0dXJlIjoiNUptaHdlQXN0OGZ0eUwtbjd4a1JLNTE0cEJCbkU1TzlobUZ3RjRDbmtKOEtpVHBKeExFQWs2ZHNzTUhfTkVSM2QzbVFOeENBQkNHckRkY29tSkE5Q1EiLCJzaWduZXIiOnsiYWxnb3JpdGhtIjoiZWQyNTUxOSIsImtleV9pZCI6ImV2aWRlbmNlLXJ1bm5lci1lZDI1NTE5LTU2NDc1YWE3NTQ2MzQ3NGMiLCJwdWJsaWNfa2V5IjoiQTZFSHYvUE9FTDRkY04wWTUwdkFtV2ZrMWpDYnBRMWZIZHlHWkJKVk1iZz0ifX0=","name":"halted-before-effect-zero-permit","payload_canonical_sha256":"26f4073246b4998650636bd3f1cef10835c7f51d91ccfa1d0854bc67015e6792","signature":"5JmhweAst8ftyL-n7xkRK514pBBnE5O9hmFwF4CnkJ8KiTpJxLEAk6dssMH_NER3d3mQNxCABCGrDdcomJA9CQ","terminal_verification_artifact_sha256":"43f6fc7809d789aa42785b7f76ce2dd751b2c3251c8fc74ec1f7bfe3a70b6577"},{"callback":{"artifact_bytes_source":"envelope_canonical_base64","outcome":"RECONCILIATION_REQUIRED","report_sha256":"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb","run_id":"00000000-0000-4000-8000-000000000001","schema_version":"openadapt.hosted-runner-terminal/v1","started":true,"uncertain_delivery":true},"effect_state":{"absence_basis":"none","attempt_state":"delivery_uncertain","effect_contract_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","effect_verified":false,"final_verdict":null,"observed_effect":"unknown","reconciliation_actions":0,"reconciliation_completed":false,"record_kind":"terminal_effect_state","resolved_delivery_uncertainty":false,"result_index":0,"verification_performed":false,"verification_tier":null,"verifier_identity":null},"envelope_canonical_base64":"eyJwYXlsb2FkIjp7ImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA2IiwiYWRtaXNzaW9uX3BvbGljeV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYWRtaXR0ZWRfcnVudGltZV9idWlsZF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiYnVuZGxlX2FydGlmYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJidW5kbGVfY29udGVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYnVuZGxlX3ZlcnNpb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDQiLCJlZmZlY3RfY29udHJhY3Rfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImVudmlyb25tZW50X2NvbnRyYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJlbnZpcm9ubWVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXZpZGVuY2VfaWRlbnRpdHlfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImV2aWRlbmNlX21hbmlmZXN0cyI6eyJhdXRob3JpemF0aW9uIjp7ImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA2IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOCIsImV4ZWN1dGlvbl9hdXRob3JpdHlfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImdvdmVybmVkX2F1dGhvcml6YXRpb25faWRfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsIm1hbmlmZXN0X3NoYTI1NiI6ImYwY2ExOWE2YjNlYWJlNTk0ZGJjOTA2ODljMmY3NGNiZTVlODJkNGQ5NDdkYjI5YTVkMDdiMTY0MWU4OTYxY2YiLCJwZXJtaXRfY2hhaW5fc2hhMjU2IjoiNTA0OGZlOTQ1ODgyZDI4MDI2MDA4ZDdlOTEzN2FkMDE2ZmRkMDFhZWFmNTg4NDgxZmI1YmQwZjI0MmE1MDA0MyIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tYXV0aG9yaXphdGlvbi1ldmlkZW5jZS92MSJ9LCJlZmZlY3QiOnsiY29uZmlybWVkIjowLCJlZmZlY3RfY29udHJhY3Rfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsIm1hbmlmZXN0X3NoYTI1NiI6ImFmMTUwOWNjMmU5ZmExZjViOGI4MTVlN2IxZjYwNDYxOWIyYTM1ZWMwZGU1ZTBkMzRiYmZhNjdjYzkxZGJiYzciLCJyZWNvcmRzIjpbeyJhYnNlbmNlX2Jhc2lzIjoibm9uZSIsImF0dGVtcHRfc3RhdGUiOiJkZWxpdmVyeV91bmNlcnRhaW4iLCJlZmZlY3RfY29udHJhY3RfaGFzaCI6InNoYTI1NjphYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZWZmZWN0X3ZlcmlmaWVkIjpmYWxzZSwiZmluYWxfdmVyZGljdCI6bnVsbCwib2JzZXJ2ZWRfZWZmZWN0IjoidW5rbm93biIsInJlY29uY2lsaWF0aW9uX2FjdGlvbnMiOjAsInJlY29uY2lsaWF0aW9uX2NvbXBsZXRlZCI6ZmFsc2UsInJlY29yZF9raW5kIjoidGVybWluYWxfZWZmZWN0X3N0YXRlIiwicmVzb2x2ZWRfZGVsaXZlcnlfdW5jZXJ0YWludHkiOmZhbHNlLCJyZXN1bHRfaW5kZXgiOjAsInZlcmlmaWNhdGlvbl9wZXJmb3JtZWQiOmZhbHNlLCJ2ZXJpZmljYXRpb25fdGllciI6bnVsbCwidmVyaWZpZXJfaWRlbnRpdHkiOm51bGx9XSwicmVxdWlyZWQiOjEsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZWZmZWN0LWV2aWRlbmNlL3YxIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSJ9LCJpZGVudGl0eSI6eyJjb25maXJtZWQiOjEsImlkZW50aXR5X2NvbnRyYWN0X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJtYW5pZmVzdF9zaGEyNTYiOiIxMzVjODYzZWRjN2ZhYjE4Y2EyOWI0OTI5M2ZjMjVhMWM5YmQ0ZGUwZTllZDI4ZDRjZWM2ZThkMGE2NzkxMjI5IiwicmVxdWlyZWQiOjEsInJlc3VsdHMiOlt7Im1vZGUiOiJzdHJ1Y3R1cmVkIiwicmVzdWx0X2luZGV4IjowLCJzaWduYWxzIjpbXSwic3RhdHVzIjoidmVyaWZpZWQifV0sInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24taWRlbnRpdHktZXZpZGVuY2UvdjEiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIn0sInBvbGljeSI6eyJhZG1pc3Npb25fcG9saWN5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJlZmZlY3RfY29udHJhY3Rfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImVudmlyb25tZW50X2NvbnRyYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJlbnZpcm9ubWVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZ292ZXJuZWRfcG9saWN5X2NvbnRyYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJnb3Zlcm5lZF9ydW50aW1lX2lucHV0c19kaWdlc3QiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiaWRlbnRpdHlfY29udHJhY3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsIm1hbmlmZXN0X3NoYTI1NiI6IjRmOTg4ZDAxNWJjZDdjZDdlMDViYTA2NjNkODlmMGE5NjhmMGQ4YWNlOTliMDkwZWJhYmVlNTJhMWM1NTA0MjEiLCJtaW5pbXVtX2VmZmVjdF90aWVyIjoxLCJydW50aW1lX2Vudmlyb25tZW50X3NoYTI1NiI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLXBvbGljeS1ldmlkZW5jZS92MSJ9LCJwb3N0Y29uZGl0aW9uIjp7ImNvbmZpcm1lZCI6MCwibWFuaWZlc3Rfc2hhMjU2IjoiM2VhNGM2NGEzMGIwY2YxN2JjYTA0ZjMyNjBlMGE0NzE4YjI3ZjUxZTFmZGMyYmI4OGExODI2MzBhMzRkZDVmZiIsInJlY29yZHMiOlt7ImFjdGlvbl9raW5kIjoiY2xpY2siLCJhY3R1YXRpb25fcGF0aCI6Imd1aSIsImNvbnRyYWN0X2luZGV4IjowLCJjb250cmFjdF9raW5kIjoiZXhwbGljaXRfcHJlZGljYXRlIiwiY29udHJhY3Rfc2hhMjU2IjoiMGFkZTBiNTIwYmMwMDc4OTFjYWNjYTAwMTcxNTc4NDQyYTJhNzRjZWYxNWZmNjRkZGU0NWRmMDdhZmI2NGFlYiIsInJlc3VsdF9pbmRleCI6MCwic3RlcF9jb250cmFjdF9zaGEyNTYiOiIxYTU5NTM2YTQ4OGIxYzQ2YWFjZjBiYTM3OTMwYjg0MDYyYzE0Mjc1NWZhOTM5MTUyZWY1ZTI4YzQwOTQ3MWVkIiwic3RlcF9pbmRleCI6MCwidmVyZGljdCI6InVudmVyaWZpYWJsZSIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifV0sInJlcXVpcmVkIjoxLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLXBvc3Rjb25kaXRpb24tZXZpZGVuY2UvdjEiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIn19LCJldmlkZW5jZV9ydW5uZXJfc2lnbmVyX3NoYTI1NiI6IjU2NDc1YWE3NTQ2MzQ3NGMwMjg1ZGY1ZGJmMmJjYWI3M2RhNjUxMzU4ODM5ZTliNzc0ODFiMmVhYjEwNzcwOGMiLCJleGVjdXRpb25fYXV0aG9yaXR5X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA4IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaWduZXJfc2hhMjU2IjoiMjRmNmVkNmFjYmZlMTAwOWMwMzBkN2NhNTY3YzMzY2E0ODMwOTExNDk4MjM2YjU1NjFhNmM4MmFiZWM1ZGUyOCIsImV4ZWN1dGlvbl9vdXRjb21lIjp7ImNvbXBlbnNhdGlvbl9hY3Rpb25zIjowLCJldmlkZW5jZV9jbGFzc2VzIjpbImF1dGhvcml6YXRpb24iLCJpZGVudGl0eSJdLCJleGVjdXRpb25fY29tcGxldGVkIjpmYWxzZSwiZXh0ZXJuYWxfbmV0d29ya19jYWxscyI6Im5vbmUiLCJtb2RlbF9jYWxscyI6MCwib3V0Y29tZSI6IkhBTFRFRCIsInBhc3NlZF9jb250cmFjdHMiOnsiYXV0aG9yaXphdGlvbiI6MSwiZWZmZWN0IjowLCJpZGVudGl0eSI6MSwicG9zdGNvbmRpdGlvbiI6MH0sInBvc3Rjb25kaXRpb25fZXZpZGVuY2UiOlt7ImFjdGlvbl9raW5kIjoiY2xpY2siLCJhY3R1YXRpb25fcGF0aCI6Imd1aSIsImNvbnRyYWN0X2luZGV4IjowLCJjb250cmFjdF9raW5kIjoiZXhwbGljaXRfcHJlZGljYXRlIiwiY29udHJhY3Rfc2hhMjU2IjoiMGFkZTBiNTIwYmMwMDc4OTFjYWNjYTAwMTcxNTc4NDQyYTJhNzRjZWYxNWZmNjRkZGU0NWRmMDdhZmI2NGFlYiIsInJlc3VsdF9pbmRleCI6MCwic3RlcF9jb250cmFjdF9zaGEyNTYiOiIxYTU5NTM2YTQ4OGIxYzQ2YWFjZjBiYTM3OTMwYjg0MDYyYzE0Mjc1NWZhOTM5MTUyZWY1ZTI4YzQwOTQ3MWVkIiwic3RlcF9pbmRleCI6MCwidmVyZGljdCI6InVudmVyaWZpYWJsZSIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifV0sInByb2R1Y3Rpb25fZWxpZ2libGUiOmZhbHNlLCJwcm9maWxlIjoic3RhbmRhcmQiLCJxdWFsaWZpY2F0aW9uX2V2aWRlbmNlX29ubHkiOmZhbHNlLCJyZXF1aXJlZF9jb250cmFjdHMiOnsiYXV0aG9yaXphdGlvbiI6MSwiZWZmZWN0IjoxLCJpZGVudGl0eSI6MSwicG9zdGNvbmRpdGlvbiI6MX0sInZlcnNpb24iOiJvcGVuYWRhcHQuZXhlY3V0aW9uLW91dGNvbWUvdjEiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIn0sImV4ZWN1dGlvbl9vdXRjb21lX3NoYTI1NiI6ImZlMzg5YmFiMGViNDQ0N2NlYzE5OTgyNzRmNzI3Y2E1NzAwNDlmZWZkNTU3ZGI3OTkwNDc2OTlmMmY3OGYxNDIiLCJleGVjdXRpb25fcHVycG9zZSI6InByb2R1Y3Rpb24iLCJmaW5hbF9hdXRob3JpdHlfc2VxdWVuY2UiOjAsImZpbmFsX3J1bnRpbWVfZGVsaXZlcnlfc2VxdWVuY2UiOjksImZsb3dfcnVuX2lkX3NoYTI1NiI6IjExZTU5NGY0ODE5NThjMTBlMzAxNWQwYmYwNDQ3YTIyZjA2OGE4YTY0N2Y0NzVkZjE1Y2UyYzdhYjRiOGYzZjEiLCJpZGVudGl0eV9jb250cmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiaXNzdWVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowM1oiLCJwZXJtaXRfY2hhaW4iOnsiZW50cmllcyI6W3siZGVsaXZlcnlfcmVjZWlwdF9hcnRpZmFjdCI6eyJwYXlsb2FkIjp7ImF1dGhlbnRpY2F0ZWRfcnVubmVyX2lkX3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJhdXRoZW50aWNhdGVkX3Nlc3Npb25faWRfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsImRlbGl2ZXJlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDFaIiwiZXhlY3V0aW9uX2F1dGhvcml0eV9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOCIsIm9uZV91c2VfY2xhaW1faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMTAiLCJwZXJtaXRfYXJ0aWZhY3Rfc2hhMjU2IjoiOTcyYTgyYWY0NTZkYTU0MmJhYzc4NDYwMTg4OTY2ODg5MWQ4YjdjY2QyNDI5MDQ4MTZiMzI5MmUxNTdlNTI4OSIsInBlcm1pdF9pZCI6InBlcm1pdDoxIiwicnVudGltZV9kZWxpdmVyeV9zZXF1ZW5jZSI6OSwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1yZWNlaXB0LXBheWxvYWQvdjIifSwicGF5bG9hZF9zaGEyNTYiOiI4YThmNmQ4ODc1MGNiYjZiM2JkNjYyMDkzYWQyOWUyYmMyMGM2YWI2OTkxZDcwZTU4ODY5MWM4YjNhYjY2MmI5Iiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1yZWNlaXB0LWFydGlmYWN0L3YyIiwic2lnbmF0dXJlIjoiQU9LcUNnUzFzMFhhLWl5RTk2Vi15bFB6UWN2MnV2T3N1eWdIenZ1MlJ5VjdGTHNIRl9MVmZxeXg0dTJwdW1sRWwwWWs1WXU3MEpWVWtzWnBhVXBERHciLCJzaWduZXIiOnsiYWxnb3JpdGhtIjoiZWQyNTUxOSIsImtleV9pZCI6ImRlbGl2ZXJ5LWF1dGhvcml0eS1lZDI1NTE5LTI0ZjZlZDZhY2JmZTEwMDkiLCJwdWJsaWNfa2V5IjoiS2F5NjRVRzh5dkN5TGhxVTAwMEx4elllVW0wTC9oTElsNVM4a3lLV2JkYz0ifX0sImRlbGl2ZXJ5X3JlY2VpcHRfYXJ0aWZhY3Rfc2hhMjU2IjoiYzAwYTFiYTcwMTVmM2NiZTA1YTc2YWVhYmZmNjE5ZDc5M2U3Mzc1YTMxMGUxOTVmY2JiZDJkMjk0OGYyYjIxNCIsInBlcm1pdF9hcnRpZmFjdCI6eyJwYXlsb2FkIjp7ImFjdGlvbl9yZXF1ZXN0X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJhZG1pc3Npb25fYXJ0aWZhY3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsImF1dGhvcml0eV9zZXF1ZW5jZSI6MCwiZW52aXJvbm1lbnRfZGlnZXN0IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImV2aWRlbmNlX2lkZW50aXR5X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJleGVjdXRpb25fYXV0aG9yaXR5X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA4IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZmxvd19ydW5faWRfc2hhMjU2IjoiMTFlNTk0ZjQ4MTk1OGMxMGUzMDE1ZDBiZjA0NDdhMjJmMDY4YThhNjQ3ZjQ3NWRmMTVjZTJjN2FiNGI4ZjNmMSIsImlucHV0X2VkZ2Vfc2VxdWVuY2UiOjEsImlzc3VlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDBaIiwicGVybWl0X2lkIjoicGVybWl0OjEiLCJxdWFsaWZpY2F0aW9uX3NpZ25lcl9yZWdpc3RyeV9jaGVja2VkX2F0IjoiMjAyNi0wOC0xOFQxMTo1OTozMFoiLCJxdWFsaWZpY2F0aW9uX3NpZ25lcl9yZWdpc3RyeV9leHBpcmVzX2F0IjoiMjAyNi0wOC0yMFQxMTowMDowMFoiLCJxdWFsaWZpY2F0aW9uX3NpZ25lcl9yZWdpc3RyeV9yZXZpc2lvbiI6NywicXVhbGlmaWNhdGlvbl9zaWduZXJfcmVnaXN0cnlfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsInJ1bl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwMSIsInJ1bl9yZXF1ZXN0X3NoYTI1NiI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXBlcm1pdC1wYXlsb2FkL3YyIn0sInBheWxvYWRfc2hhMjU2IjoiYzg3ZjU3NTFhYTliMjc5Y2NlMjNhYTE3OGFmZjk1NmUxOWY2OTBmY2QyZjlmNzBlMGQ5OTk3ODJhNjkwZDZiOCIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcGVybWl0LWFydGlmYWN0L3YyIiwic2lnbmF0dXJlIjoiMEJ5SGdxRHhRWnJuZ0xJRi02dFpPcTlsWGFtY0FRQzBkb1VUbmVLTlBlUy1TeW9PYlF5T2tBdVBGSzVQWWNOek9iWnhnc2dBTGRXYUlfc2FVQ3BsQmciLCJzaWduZXIiOnsiYWxnb3JpdGhtIjoiZWQyNTUxOSIsImtleV9pZCI6ImRlbGl2ZXJ5LWF1dGhvcml0eS1lZDI1NTE5LTI0ZjZlZDZhY2JmZTEwMDkiLCJwdWJsaWNfa2V5IjoiS2F5NjRVRzh5dkN5TGhxVTAwMEx4elllVW0wTC9oTElsNVM4a3lLV2JkYz0ifX0sInBlcm1pdF9hcnRpZmFjdF9zaGEyNTYiOiI5NzJhODJhZjQ1NmRhNTQyYmFjNzg0NjAxODg5NjY4ODkxZDhiN2NjZDI0MjkwNDgxNmIzMjkyZTE1N2U1Mjg5Iiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1wZXJtaXQtY2hhaW4tZW50cnkvdjIifV0sInBlcm1pdF9jaGFpbl9zaGEyNTYiOiI1MDQ4ZmU5NDU4ODJkMjgwMjYwMDhkN2U5MTM3YWQwMTZmZGQwMWFlYWY1ODg0ODFmYjViZDBmMjQyYTUwMDQzIiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1wZXJtaXQtY2hhaW4vdjIifSwicGVybWl0X2NvdW50IjoxLCJxdWFsaWZpY2F0aW9uX3NpZ25lcl9yZWdpc3RyeV9yZXZpc2lvbiI6NywicXVhbGlmaWNhdGlvbl9zaWduZXJfcmVnaXN0cnlfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsInJ1bl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwMSIsInJ1bl9yZWNlaXB0Ijp7ImF1dGhvcml6YXRpb25fY29uZmlybWVkIjoxLCJhdXRob3JpemF0aW9uX3JlcXVpcmVkIjoxLCJidW5kbGVfZGlnZXN0IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImR1cmF0aW9uX21zIjoxMDAsImVmZmVjdF90aWVyX3JlYWNoZWQiOiJub25lIiwiZWZmZWN0c19jb25maXJtZWQiOjAsImVmZmVjdHNfcmVxdWlyZWQiOjEsImVzdF9jb3N0X21pY3JvdXNkIjowLCJldmlkZW5jZV9jbGFzc2VzIjpbImF1dGhvcml6YXRpb24iLCJpZGVudGl0eSJdLCJleHRlcm5hbF9uZXR3b3JrX2NhbGxzIjoibm9uZSIsImdlbmVyYXRlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDBaIiwiaGVhbHMiOjAsImlkZW50aXR5X2FwcGxpY2FibGUiOjEsImlkZW50aXR5X2FybWVkIjoxLCJpZGVudGl0eV9jb25maXJtZWQiOjEsImlkZW50aXR5X3JlcXVpcmVkIjoxLCJtb2RlbF9jYWxscyI6MCwib3V0Y29tZSI6IkhBTFRFRCIsIm92ZXJfaGFsdF9jb3VudCI6MCwicG9zdGNvbmRpdGlvbnNfY29uZmlybWVkIjowLCJwb3N0Y29uZGl0aW9uc19yZXF1aXJlZCI6MSwicHJvZHVjdGlvbl9lbGlnaWJsZSI6ZmFsc2UsInByb2ZpbGUiOiJzdGFuZGFyZCIsInByb3ZlbmFuY2UiOiJwcm9kdWN0aW9uIiwicmVjZWlwdF9idWlsZGVyX3ZlcnNpb24iOiIxLjIuMyIsInJ1bmdfaGlzdG9ncmFtIjp7fSwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1ydW4tcmVjZWlwdC92MSIsInNvdXJjZV9yZWNlaXB0X2RpZ2VzdCI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJzb3VyY2VfcmVjZWlwdF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwic291cmNlX3NjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnJ1bi1yZXBvcnQvdjEiLCJzdGVwc19vayI6MCwic3RlcHNfdG90YWwiOjEsInN1YnN0cmF0ZSI6IndlYiIsInRyYW5zYWN0aW9uX291dGNvbWUiOiJSRUNPTkNJTElBVElPTl9SRVFVSVJFRCJ9LCJydW5fcmVjZWlwdF9zaGEyNTYiOiIxOGViMmM0ZjQxNTNkYWIwNTNiZjAyN2MyNmY2OGFmYTA2MTMxN2UzYzJlN2Q1YTYwZWU1OGMzZWU2YjNkN2M2IiwicnVuX3JlcG9ydF9vYmplY3Rfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsInJ1bl9yZXBvcnRfb2JqZWN0X3ZlcnNpb24iOiJ2ZXJzaW9uOnJlY29uY2lsaWF0aW9uOjEiLCJydW5fcmVwb3J0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJydW50aW1lX2Vudmlyb25tZW50X3NoYTI1NiI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJydW50aW1lX3N1YnN0cmF0ZSI6IndlYiIsInJ1bnRpbWVfdmFsaWRhdGlvbl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwNSIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tdGVybWluYWwtdmVyaWZpY2F0aW9uL3YyIiwidGVuYW50X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAyIiwidGVybWluYWxfc2VxdWVuY2UiOjEsInZlcmlmaWVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMloiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwid29ya2Zsb3dfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDMiLCJ3b3JrZmxvd192ZXJzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA0In0sInNpZ25hdHVyZSI6Imd2ZHZuSlNPUzRWazg3M2k4eDBDMmE5MUE0Qm9WOFFvc05xdmMwaUVHMkJOOXpHOUlwamk5dXI1a0VpME5xdW5HVDdLVFZFczhfLUk2VG1TN21ERUJBIiwic2lnbmVyIjp7ImFsZ29yaXRobSI6ImVkMjU1MTkiLCJrZXlfaWQiOiJldmlkZW5jZS1ydW5uZXItZWQyNTUxOS01NjQ3NWFhNzU0NjM0NzRjIiwicHVibGljX2tleSI6IkE2RUh2L1BPRUw0ZGNOMFk1MHZBbVdmazFqQ2JwUTFmSGR5R1pCSlZNYmc9In19","name":"reconciliation-required-nonempty-permit","payload_canonical_sha256":"ef33d988e8895b431f8d06b134cac38fa0b6628b75c0fbe155e30ebb786bd8bf","signature":"gvdvnJSOS4Vk873i8x0C2a91A4BoV8QosNqvc0iEG2BN9zG9Ipji9ur5kEi0NqunGT7KTVEs8_-I6TmS7mDEBA","terminal_verification_artifact_sha256":"d4959d87ddb589221ddcddc6094bf42948c9357b51769239834815036fc36cad"}]} diff --git a/tests/test_durable_authority_v13.py b/tests/test_durable_authority_v13.py index f484327e..0db17584 100644 --- a/tests/test_durable_authority_v13.py +++ b/tests/test_durable_authority_v13.py @@ -524,6 +524,8 @@ def test_v2_permit_remains_pending_until_signed_receipt_commits_edge( authority.before_initial_delivery(manifest) with pytest.raises(DurableAuthorityBusy, match="remains uncertain"): authority.production_delivery_permit_chain() + with pytest.raises(DurableAuthorityBusy, match="remains uncertain"): + authority.production_delivery_permit_chain(allow_empty=True) entry = authority.acknowledge_remote_delivery(manifest, permit) @@ -535,6 +537,23 @@ def test_v2_permit_remains_pending_until_signed_receipt_commits_edge( assert entry.runtime_delivery_sequence == 0 +def test_pre_actuation_terminal_can_retain_an_empty_delivery_chain( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch +) -> None: + manifest, authority = _remote_initial_authority( + tmp_path, + monkeypatch, + _issued_permit_transport("unused", "4" * 64), + ) + + chain = authority.production_delivery_permit_chain(allow_empty=True) + + assert chain.entries == () + assert authority.validate(manifest).delivery_sequence == 0 + with pytest.raises(DurableAuthorityBusy, match="unavailable"): + authority.production_delivery_permit_chain() + + def test_remote_permit_refuses_a_different_hosted_dispatch_session( tmp_path: Path, monkeypatch: pytest.MonkeyPatch ) -> None: diff --git a/tests/test_hosted_runner_adapter.py b/tests/test_hosted_runner_adapter.py index 1f8b6e08..1debe264 100644 --- a/tests/test_hosted_runner_adapter.py +++ b/tests/test_hosted_runner_adapter.py @@ -58,6 +58,7 @@ ProductionDeliveryPermitChain, ProductionDeliveryPermitPayload, ProductionDeliveryReceiptPayload, + delivery_authority_signer_sha256, evidence_runner_signer_sha256, sign_production_delivery_permit, sign_production_delivery_receipt, @@ -66,7 +67,12 @@ from openadapt_flow.transaction import TransactionOutcome from tests.test_run_receipt import _report as _production_report from tests.test_runner_client_lib import dispatch_payload -from tests.test_terminal_verification_v2 import _payload, _private_key +from tests.test_terminal_verification_v2 import ( + _halted_payload, + _payload, + _private_key, + _reconciliation_payload, +) pytest_plugins = ("tests.test_runner_client_lib",) @@ -182,6 +188,11 @@ def _hosted_dispatch(workflow) -> HostedDispatch: artifact_bytes_base64=b64encode(artifact_raw).decode("ascii"), artifact_sha256=hashlib.sha256(artifact_raw).hexdigest(), ) + authority_key = Ed25519PrivateKey.from_private_bytes(bytes(range(32, 64))) + authority_public_key = authority_key.public_key().public_bytes( + serialization.Encoding.Raw, + serialization.PublicFormat.Raw, + ) return HostedDispatch( schema_version="openadapt.hosted-runner/v1", dispatch_id="11111111-1111-4111-8111-111111111111", @@ -192,6 +203,11 @@ def _hosted_dispatch(workflow) -> HostedDispatch: run_id=payload.run_id, workflow_id=workflow_id, workflow_version_id=version_id, + execution_authority_id="00000000-0000-4000-8000-000000000008", + execution_authority_sha256="1" * 64, + execution_authority_signer_sha256=delivery_authority_signer_sha256( + authority_public_key + ), idempotency_key="hosted-dispatch-0001", lease_token="oal_" + "a" * 64, lease_expires_at="2099-01-01T00:00:00Z", @@ -618,7 +634,7 @@ class Authority: def __init__(self, _run_dir, _store): pass - def production_delivery_permit_chain(self): + def production_delivery_permit_chain(self, **_kwargs): return chain fixed_now = datetime(2026, 8, 26, 12, 0, 2, tzinfo=timezone.utc) @@ -1211,6 +1227,66 @@ def test_recovery_callback_retains_exact_terminal_v2_envelope(tmp_path, sealed) ) +@pytest.mark.parametrize( + ("outcome", "payload_factory", "uncertain_delivery"), + [ + ( + TransactionOutcome.HALTED_BEFORE_EFFECT, + _halted_payload, + False, + ), + ( + TransactionOutcome.RECONCILIATION_REQUIRED, + _reconciliation_payload, + True, + ), + ], +) +def test_recovery_callback_retains_signed_non_success_terminal_v2( + tmp_path, + sealed, + outcome, + payload_factory, + uncertain_delivery, +) -> None: + workflow, _ = sealed + dispatch = _hosted_dispatch(workflow) + adapter = HostedRunnerAdapter(tmp_path / "ledger.sqlite") + proof = sign_production_terminal_verification(payload_factory(), _private_key()) + binding = adapter.recovery_binding(dispatch).model_copy( + update={"run_id": proof.payload.run_id} + ) + result = HostedRunResult( + dispatch_id=dispatch.dispatch_id, + run_id=binding.run_id, + outcome=outcome, + evidence_batch=(), + terminal_verification=proof, + started=True, + uncertain_delivery=uncertain_delivery, + report_sha256=proof.payload.run_report_sha256, + ) + + callback = adapter.callback_request(binding, result) + terminal = HostedTerminalEvent.model_validate(callback.events[-1]) + + assert terminal.outcome == outcome.value + assert terminal.uncertain_delivery is uncertain_delivery + assert terminal.terminal_verification_artifact_bytes_base64 is not None + assert terminal.terminal_verification_artifact_sha256 == proof.artifact_sha256() + + +def test_safe_halt_callback_requires_signed_terminal_proof() -> None: + with pytest.raises(ValueError, match="requires exact terminal verification"): + HostedTerminalEvent( + run_id=_halted_payload().run_id, + outcome="HALTED_BEFORE_EFFECT", + report_sha256="b" * 64, + started=True, + uncertain_delivery=False, + ) + + def test_callback_refuses_terminal_proof_for_a_different_run(tmp_path, sealed) -> None: workflow, _ = sealed dispatch = _hosted_dispatch(workflow) diff --git a/tests/test_terminal_verification_v2.py b/tests/test_terminal_verification_v2.py index 66b65fd1..e96245df 100644 --- a/tests/test_terminal_verification_v2.py +++ b/tests/test_terminal_verification_v2.py @@ -12,14 +12,21 @@ from pydantic import ValidationError from openadapt_flow.ir import ( + ActionDeliveryUncertainty, ActionKind, + EffectVerificationEvidence, + ExecutionOutcomeEnvelope, + IdentityCheck, + OutcomeContractCounts, PostconditionContractEvidence, + RunReport, postcondition_contract_sha256, postcondition_step_contract_sha256, ) from openadapt_flow.qualification_admission_v2 import canonical_json from openadapt_flow.receipt import RunReceipt from openadapt_flow.terminal_verification_v2 import ( + SIGNATURE_DOMAIN, ProductionAuthorizationEvidenceManifest, ProductionDeliveryPermit, ProductionDeliveryPermitChain, @@ -35,11 +42,15 @@ ProductionPolicyEvidenceManifest, ProductionPostconditionEvidenceManifest, ProductionRunReceipt, + ProductionTerminalEffectState, + ProductionTerminalVerificationContext, + ProductionTerminalVerificationEnvelope, ProductionTerminalVerificationError, ProductionTerminalVerificationExpected, ProductionTerminalVerificationPayload, TerminalContractCounts, build_evidence_manifest, + build_production_terminal_verification, evidence_runner_signer_sha256, project_production_run_receipt, rebuild_production_delivery_permit_chain_from_artifacts, @@ -48,6 +59,7 @@ sign_production_terminal_verification, verify_production_terminal_verification, ) +from tests.test_run_receipt import _report as _production_report SHA_A = "a" * 64 SHA_B = "b" * 64 @@ -137,6 +149,220 @@ def _outcome() -> ProductionExecutionOutcome: ) +def _terminal_postcondition( + verdict: str, +) -> PostconditionContractEvidence: + return _postcondition().model_copy(update={"verdict": verdict}) + + +def _halted_outcome() -> ProductionExecutionOutcome: + return ProductionExecutionOutcome( + outcome="HALTED", + profile="standard", + production_eligible=False, + execution_completed=False, + required_contracts=TerminalContractCounts( + authorization=1, + identity=1, + postcondition=1, + effect=1, + ), + passed_contracts=TerminalContractCounts( + authorization=1, + identity=1, + postcondition=0, + effect=0, + ), + workflow_contract_sha256=SHA_A, + postcondition_evidence=(_terminal_postcondition("unverifiable"),), + evidence_classes=("authorization", "identity"), + model_calls=0, + external_network_calls="none", + ) + + +def _halted_receipt() -> ProductionRunReceipt: + return ProductionRunReceipt( + source_schema_version="openadapt.run-report/v1", + outcome="HALTED", + transaction_outcome="HALTED_BEFORE_EFFECT", + profile="standard", + production_eligible=False, + steps_total=1, + steps_ok=0, + heals=0, + model_calls=0, + est_cost_microusd=0, + duration_ms=100, + rung_histogram={}, + evidence_classes=("authorization", "identity"), + effect_tier_reached="none", + authorization_required=1, + authorization_confirmed=1, + identity_required=1, + identity_confirmed=1, + postconditions_required=1, + postconditions_confirmed=0, + effects_required=1, + effects_confirmed=0, + identity_armed=1, + identity_applicable=1, + over_halt_count=0, + substrate="web", + provenance="production", + receipt_builder_version="1.2.3", + external_network_calls="none", + bundle_digest=SHA_A, + source_receipt_digest=SHA_B, + source_receipt_sha256=SHA_B, + generated_at="2026-08-18T12:00:00Z", + ) + + +def _reconciliation_outcome() -> ProductionExecutionOutcome: + return ProductionExecutionOutcome( + outcome="HALTED", + profile="standard", + production_eligible=False, + execution_completed=False, + required_contracts=TerminalContractCounts( + authorization=1, + identity=1, + postcondition=1, + effect=1, + ), + passed_contracts=TerminalContractCounts( + authorization=1, + identity=1, + postcondition=0, + effect=0, + ), + workflow_contract_sha256=SHA_A, + postcondition_evidence=(_terminal_postcondition("unverifiable"),), + evidence_classes=("authorization", "identity"), + model_calls=0, + external_network_calls="none", + ) + + +def _reconciliation_receipt() -> ProductionRunReceipt: + return _halted_receipt().model_copy( + update={ + "transaction_outcome": "RECONCILIATION_REQUIRED", + "evidence_classes": ("authorization", "identity"), + "identity_confirmed": 1, + } + ) + + +def _actual_non_success_report( + transaction_outcome: str, +) -> RunReport: + base = _production_report() + assert base.outcome_envelope is not None + base_result = base.results[0] + postcondition = base.outcome_envelope.postcondition_evidence[0].model_copy( + update={"verdict": "unverifiable"} + ) + if transaction_outcome == "HALTED_BEFORE_EFFECT": + identity = IdentityCheck( + status="verified", + mode="structured", + coverage=1.0, + ) + result = base_result.model_copy( + update={ + "risk": "irreversible", + "ok": False, + "identity": identity, + "postconditions_ok": None, + "effect_verified": False, + "effect_evidence": [], + "delivery_attempted": False, + "safety_halt": True, + } + ) + passed = OutcomeContractCounts( + authorization=1, + identity=1, + postcondition=0, + effect=0, + ) + evidence_classes = ["authorization", "identity"] + else: + uncertainty = ActionDeliveryUncertainty( + operation="guarded_coordinate_click", + native=False, + observed_at="2026-07-27T15:34:57+00:00", + cause_type="ConnectionResetError", + verification_attempted=True, + postconditions_confirmed=False, + effects_confirmed=False, + resolved_by_contract=False, + ) + effect = EffectVerificationEvidence( + effect_contract_hash=base_result.effect_contract_hashes[0], + substrate="rest", + verifier_identity="sha256:" + SHA_B, + verification_tier=1, + initial_verdict="indeterminate", + final_verdict="indeterminate", + observed_effect="unknown", + ) + result = base_result.model_copy( + update={ + "risk": "irreversible", + "ok": False, + "postconditions_ok": False, + "effect_verified": False, + "effect_evidence": [effect], + "delivery_attempted": True, + "delivery_uncertainty": uncertainty, + "safety_halt": True, + } + ) + passed = OutcomeContractCounts( + authorization=1, + identity=1, + postcondition=0, + effect=0, + ) + evidence_classes = ["authorization", "identity"] + envelope = ExecutionOutcomeEnvelope( + outcome="HALTED", + profile="standard", + production_eligible=False, + execution_completed=False, + required_contracts=OutcomeContractCounts( + authorization=1, + identity=1, + postcondition=1, + effect=1, + ), + passed_contracts=passed, + workflow_contract_sha256=base.workflow_contract_sha256, + postcondition_evidence=[postcondition], + evidence_classes=evidence_classes, + model_calls=0, + external_network_calls="observed", + ) + return RunReport.model_validate( + base.model_dump(mode="json") + | { + "run_id_sha256": hashlib.sha256(IDS["run_id"].encode()).hexdigest(), + "execution_outcome": "HALTED", + "transaction_outcome": transaction_outcome, + "transaction_billable": False, + "transaction_platform_fault": False, + "production_eligible": False, + "execution_completed": False, + "outcome_envelope": envelope.model_dump(mode="json"), + "success": False, + "results": [result.model_dump(mode="json")], + } + ) + + def _receipt() -> ProductionRunReceipt: unsigned = { "schema_version": "openadapt.run-receipt/v2", @@ -319,6 +545,208 @@ def _manifests( ) +def _halted_manifests( + chain: ProductionDeliveryPermitChain, +) -> ProductionEvidenceManifests: + success = _manifests(_permit_chain()) + authorization = build_evidence_manifest( + ProductionAuthorizationEvidenceManifest, + governed_authorization_id_sha256=SHA_A, + admission_id=IDS["admission_id"], + admission_artifact_sha256=SHA_D, + execution_authority_id=IDS["execution_authority_id"], + execution_authority_sha256=SHA_A, + permit_chain_sha256=chain.permit_chain_sha256, + ) + identity = build_evidence_manifest( + ProductionIdentityEvidenceManifest, + identity_contract_sha256=SHA_D, + workflow_contract_sha256=SHA_A, + required=1, + confirmed=1, + results=( + ProductionIdentityResult( + result_index=0, + status="verified", + mode="structured", + signals=(), + ), + ), + ) + postcondition = build_evidence_manifest( + ProductionPostconditionEvidenceManifest, + workflow_contract_sha256=SHA_A, + required=1, + confirmed=0, + records=(_terminal_postcondition("unverifiable"),), + ) + effect = build_evidence_manifest( + ProductionEffectEvidenceManifest, + effect_contract_sha256=SHA_E, + workflow_contract_sha256=SHA_A, + required=1, + confirmed=0, + records=( + ProductionTerminalEffectState( + result_index=0, + effect_contract_hash="sha256:" + SHA_A, + attempt_state="not_actuated", + observed_effect="absent", + effect_verified=False, + verification_performed=False, + verifier_identity=None, + verification_tier=None, + final_verdict=None, + resolved_delivery_uncertainty=False, + absence_basis="not_actuated", + reconciliation_completed=False, + reconciliation_actions=0, + ), + ), + ) + return ProductionEvidenceManifests( + policy=success.policy, + authorization=authorization, + identity=identity, + postcondition=postcondition, + effect=effect, + ) + + +def _reconciliation_manifests( + chain: ProductionDeliveryPermitChain, +) -> ProductionEvidenceManifests: + halted = _halted_manifests(chain) + identity = build_evidence_manifest( + ProductionIdentityEvidenceManifest, + identity_contract_sha256=SHA_D, + workflow_contract_sha256=SHA_A, + required=1, + confirmed=1, + results=( + ProductionIdentityResult( + result_index=0, + status="verified", + mode="structured", + signals=(), + ), + ), + ) + effect = build_evidence_manifest( + ProductionEffectEvidenceManifest, + effect_contract_sha256=SHA_E, + workflow_contract_sha256=SHA_A, + required=1, + confirmed=0, + records=( + ProductionTerminalEffectState( + result_index=0, + effect_contract_hash="sha256:" + SHA_A, + attempt_state="delivery_uncertain", + observed_effect="unknown", + effect_verified=False, + verification_performed=False, + verifier_identity=None, + verification_tier=None, + final_verdict=None, + resolved_delivery_uncertainty=False, + absence_basis="none", + reconciliation_completed=False, + reconciliation_actions=0, + ), + ), + ) + return halted.model_copy(update={"identity": identity, "effect": effect}) + + +def _halted_payload() -> ProductionTerminalVerificationPayload: + receipt = _halted_receipt() + outcome = _halted_outcome() + chain = ProductionDeliveryPermitChain.build(()) + return ProductionTerminalVerificationPayload( + **IDS, + flow_run_id_sha256=hashlib.sha256(IDS["run_id"].encode("utf-8")).hexdigest(), + bundle_artifact_sha256=SHA_B, + bundle_content_digest=SHA_A, + environment_digest=SHA_A, + environment_contract_sha256=SHA_B, + runtime_environment_sha256=SHA_C, + identity_contract_sha256=SHA_D, + effect_contract_sha256=SHA_E, + runtime_substrate="web", + admission_artifact_sha256=SHA_D, + admission_policy_sha256=SHA_A, + evidence_identity_sha256=SHA_E, + admitted_runtime_build_sha256=SHA_C, + evidence_runner_signer_sha256=evidence_runner_signer_sha256(_public_key()), + qualification_signer_registry_sha256=SHA_E, + qualification_signer_registry_revision=7, + execution_authority_sha256=SHA_A, + execution_authority_signer_sha256=SHA_C, + permit_chain=chain, + permit_count=0, + final_authority_sequence=0, + final_runtime_delivery_sequence=0, + workflow_contract_sha256=SHA_A, + execution_outcome=outcome, + execution_outcome_sha256=outcome.artifact_sha256(), + run_receipt=receipt, + run_receipt_sha256=hashlib.sha256( + canonical_json(receipt.model_dump(mode="json")) + ).hexdigest(), + run_report_sha256=SHA_B, + run_report_object_version="version:halted:1", + run_report_object_sha256=SHA_B, + evidence_manifests=_halted_manifests(chain), + verified_at="2026-08-18T12:00:02Z", + issued_at="2026-08-18T12:00:03Z", + ) + + +def _reconciliation_payload() -> ProductionTerminalVerificationPayload: + chain = _permit_chain() + receipt = _reconciliation_receipt() + outcome = _reconciliation_outcome() + return ProductionTerminalVerificationPayload( + **IDS, + flow_run_id_sha256=hashlib.sha256(IDS["run_id"].encode("utf-8")).hexdigest(), + bundle_artifact_sha256=SHA_B, + bundle_content_digest=SHA_A, + environment_digest=SHA_A, + environment_contract_sha256=SHA_B, + runtime_environment_sha256=SHA_C, + identity_contract_sha256=SHA_D, + effect_contract_sha256=SHA_E, + runtime_substrate="web", + admission_artifact_sha256=SHA_D, + admission_policy_sha256=SHA_A, + evidence_identity_sha256=SHA_E, + admitted_runtime_build_sha256=SHA_C, + evidence_runner_signer_sha256=evidence_runner_signer_sha256(_public_key()), + qualification_signer_registry_sha256=SHA_E, + qualification_signer_registry_revision=7, + execution_authority_sha256=SHA_A, + execution_authority_signer_sha256=chain.entries[0].authority_signer_sha256, + permit_chain=chain, + permit_count=1, + final_authority_sequence=0, + final_runtime_delivery_sequence=9, + workflow_contract_sha256=SHA_A, + execution_outcome=outcome, + execution_outcome_sha256=outcome.artifact_sha256(), + run_receipt=receipt, + run_receipt_sha256=hashlib.sha256( + canonical_json(receipt.model_dump(mode="json")) + ).hexdigest(), + run_report_sha256=SHA_B, + run_report_object_version="version:reconciliation:1", + run_report_object_sha256=SHA_B, + evidence_manifests=_reconciliation_manifests(chain), + verified_at="2026-08-18T12:00:02Z", + issued_at="2026-08-18T12:00:03Z", + ) + + def _payload() -> ProductionTerminalVerificationPayload: receipt = _receipt() chain = _permit_chain() @@ -365,6 +793,16 @@ def _payload() -> ProductionTerminalVerificationPayload: def _expected( payload: ProductionTerminalVerificationPayload, ) -> ProductionTerminalVerificationExpected: + if payload.permit_chain.entries: + authenticated_runner_id_sha256 = payload.permit_chain.entries[ + 0 + ].authenticated_runner_id_sha256 + authenticated_session_id_sha256 = payload.permit_chain.entries[ + 0 + ].authenticated_session_id_sha256 + else: + authenticated_runner_id_sha256 = SHA_B + authenticated_session_id_sha256 = SHA_C return ProductionTerminalVerificationExpected( run_id=payload.run_id, flow_run_id_sha256=payload.flow_run_id_sha256, @@ -396,12 +834,8 @@ def _expected( permit_count=payload.permit_count, final_authority_sequence=payload.final_authority_sequence, final_runtime_delivery_sequence=payload.final_runtime_delivery_sequence, - authenticated_runner_id_sha256=( - payload.permit_chain.entries[0].authenticated_runner_id_sha256 - ), - authenticated_session_id_sha256=( - payload.permit_chain.entries[0].authenticated_session_id_sha256 - ), + authenticated_runner_id_sha256=authenticated_runner_id_sha256, + authenticated_session_id_sha256=authenticated_session_id_sha256, acknowledged_one_use_claim_ids=tuple( entry.one_use_claim_id for entry in payload.permit_chain.entries ), @@ -430,6 +864,173 @@ def test_terminal_v2_signs_and_verifies_exact_production_success() -> None: ) +def test_terminal_v2_signs_and_verifies_zero_permit_safe_halt() -> None: + payload = _halted_payload() + envelope = sign_production_terminal_verification(payload, _private_key()) + + digest = verify_production_terminal_verification( + envelope, + expected=_expected(payload), + now=NOW, + ) + + assert digest == envelope.artifact_sha256() + assert payload.execution_outcome.outcome == "HALTED" + assert payload.run_receipt.transaction_outcome == "HALTED_BEFORE_EFFECT" + assert payload.permit_count == 0 + assert payload.permit_chain.entries == () + assert all( + isinstance(record, ProductionTerminalEffectState) + and record.absence_basis in {"not_actuated", "verifier_refuted"} + for record in payload.evidence_manifests.effect.records + ) + + +def test_terminal_v2_refuses_zero_permit_verified_claim() -> None: + data = _halted_payload().model_dump(mode="json") + data["run_receipt"]["transaction_outcome"] = "VERIFIED" + + with pytest.raises(ValidationError): + ProductionTerminalVerificationPayload.model_validate(data) + + +def test_terminal_v2_refuses_safe_halt_without_effect_absence() -> None: + data = _halted_payload().model_dump(mode="json") + effect = data["evidence_manifests"]["effect"] + record = effect["records"][0] + record.update( + { + "attempt_state": "delivery_uncertain", + "observed_effect": "unknown", + "absence_basis": "none", + } + ) + unsigned = {key: value for key, value in effect.items() if key != "manifest_sha256"} + effect["manifest_sha256"] = hashlib.sha256( + b"openadapt-production-effect-evidence-v1\0" + canonical_json(unsigned) + ).hexdigest() + + with pytest.raises(ValidationError, match="effect absence"): + ProductionTerminalVerificationPayload.model_validate(data) + + +def test_terminal_effect_state_requires_exact_verifier_and_verdict_binding() -> None: + record = _halted_payload().evidence_manifests.effect.records[0] + assert isinstance(record, ProductionTerminalEffectState) + data = record.model_dump(mode="json") + + with pytest.raises(ValidationError, match="verified state"): + ProductionTerminalEffectState.model_validate(data | {"effect_verified": True}) + with pytest.raises(ValidationError, match="verifier identity"): + ProductionTerminalEffectState.model_validate( + data + | { + "attempt_state": "delivered", + "verification_performed": True, + "verification_tier": 1, + "final_verdict": "refuted", + "absence_basis": "verifier_refuted", + } + ) + + refuted = ProductionTerminalEffectState.model_validate( + data + | { + "attempt_state": "delivered", + "verification_performed": True, + "verifier_identity": "sha256:" + SHA_B, + "verification_tier": 1, + "final_verdict": "refuted", + "absence_basis": "verifier_refuted", + } + ) + assert refuted.effect_verified is False + + +def test_terminal_v2_signs_and_verifies_reconciliation_proof() -> None: + payload = _reconciliation_payload() + envelope = sign_production_terminal_verification(payload, _private_key()) + + digest = verify_production_terminal_verification( + envelope, + expected=_expected(payload), + now=NOW, + ) + + assert digest == envelope.artifact_sha256() + assert payload.run_receipt.transaction_outcome == "RECONCILIATION_REQUIRED" + assert payload.permit_count == 1 + record = payload.evidence_manifests.effect.records[0] + assert isinstance(record, ProductionTerminalEffectState) + assert record.attempt_state == "delivery_uncertain" + assert record.observed_effect == "unknown" + + +@pytest.mark.parametrize( + "transaction_outcome", + ["HALTED_BEFORE_EFFECT", "RECONCILIATION_REQUIRED"], +) +def test_terminal_v2_builds_non_success_proof_from_exact_run_report( + transaction_outcome: str, +) -> None: + report = _actual_non_success_report(transaction_outcome) + chain = ( + ProductionDeliveryPermitChain.build(()) + if transaction_outcome == "HALTED_BEFORE_EFFECT" + else _permit_chain() + ) + context = ProductionTerminalVerificationContext( + run_id=IDS["run_id"], + tenant_id=IDS["tenant_id"], + workflow_id=IDS["workflow_id"], + workflow_version_id=IDS["workflow_version_id"], + bundle_version_id=IDS["bundle_version_id"], + bundle_artifact_sha256=SHA_B, + environment_digest=SHA_A, + environment_contract_sha256=SHA_B, + runtime_environment_sha256=SHA_C, + identity_contract_sha256=SHA_D, + effect_contract_sha256=SHA_E, + runtime_validation_id=IDS["runtime_validation_id"], + runtime_substrate="web", + admission_id=IDS["admission_id"], + admission_artifact_sha256=SHA_D, + admission_policy_sha256=SHA_A, + evidence_identity_sha256=SHA_E, + admitted_runtime_build_sha256=SHA_C, + evidence_runner_signer_sha256=evidence_runner_signer_sha256(_public_key()), + qualification_signer_registry_sha256=SHA_E, + qualification_signer_registry_revision=7, + execution_authority_id=IDS["execution_authority_id"], + execution_authority_sha256=SHA_A, + execution_authority_signer_sha256=( + chain.entries[0].authority_signer_sha256 if chain.entries else SHA_C + ), + permit_chain=chain, + run_report_object_version="version:terminal-report:1", + verified_at="2026-08-18T12:00:02Z", + issued_at="2026-08-18T12:00:03Z", + ) + + built = build_production_terminal_verification( + report, + context=context, + private_key=_private_key(), + ) + payload = built.envelope.payload + + assert payload.run_receipt.transaction_outcome == transaction_outcome + assert payload.run_report_sha256 == hashlib.sha256(built.report_bytes).hexdigest() + assert ( + verify_production_terminal_verification( + built.envelope, + expected=_expected(payload), + now=NOW, + ) + == built.envelope.artifact_sha256() + ) + + @pytest.mark.parametrize( ("field", "value", "message"), [ @@ -697,6 +1298,53 @@ def test_delivery_cross_language_vector_is_exact() -> None: assert rebuilt == chain +def test_non_success_terminal_cross_language_vectors_are_exact() -> None: + fixture = json.loads( + Path("tests/fixtures/terminal_verification_v2_terminal_vectors.json").read_text( + encoding="utf-8" + ) + ) + assert b64decode(fixture["signature_domain_base64"], validate=True) == ( + SIGNATURE_DOMAIN + ) + key = Ed25519PrivateKey.from_private_bytes( + b64decode(fixture["private_key_base64"], validate=True) + ) + payloads = { + "halted-before-effect-zero-permit": _halted_payload(), + "reconciliation-required-nonempty-permit": _reconciliation_payload(), + } + + for vector in fixture["vectors"]: + raw = b64decode(vector["envelope_canonical_base64"], validate=True) + envelope = ProductionTerminalVerificationEnvelope.model_validate_json(raw) + payload = payloads[vector["name"]] + expected = sign_production_terminal_verification(payload, key) + + assert canonical_json(envelope) == raw + assert envelope == expected + assert ( + hashlib.sha256(payload.canonical_bytes()).hexdigest() + == (vector["payload_canonical_sha256"]) + ) + assert envelope.signature == vector["signature"] + assert ( + envelope.artifact_sha256() + == (vector["terminal_verification_artifact_sha256"]) + ) + assert ( + envelope.payload.evidence_manifests.effect.records[0].model_dump( + mode="json" + ) + == vector["effect_state"] + ) + callback = vector["callback"] + assert callback["run_id"] == payload.run_id + assert callback["outcome"] == payload.run_receipt.transaction_outcome + assert callback["report_sha256"] == payload.run_report_sha256 + assert callback["artifact_bytes_source"] == "envelope_canonical_base64" + + def test_delivery_artifact_rebuild_rejects_noncanonical_stored_bytes() -> None: entry = _permit_chain().entries[0] with pytest.raises( From d37dd1e7d2563c6672e7b143234546ff8654394c Mon Sep 17 00:00:00 2001 From: Richard Abrich Date: Thu, 27 Aug 2026 14:16:34 -0400 Subject: [PATCH 2/7] fix(hosted): sign unresolved delivery reconciliation --- openadapt_flow/runner/evidence.py | 20 +- openadapt_flow/runner/hosted_adapter.py | 160 ++++--- openadapt_flow/runtime/durable/authority.py | 31 +- openadapt_flow/terminal_verification_v2.py | 422 +++++++++++++++--- public-artifacts.json | 4 + ...nerate_terminal_verification_v2_vectors.py | 102 +++++ ...inal_verification_v2_terminal_vectors.json | 75 +++- tests/test_durable_authority_v13.py | 16 + tests/test_hosted_runner_adapter.py | 133 ++++-- tests/test_run_receipt.py | 4 + tests/test_terminal_verification_v2.py | 120 ++++- 11 files changed, 919 insertions(+), 168 deletions(-) create mode 100644 scripts/generate_terminal_verification_v2_vectors.py diff --git a/openadapt_flow/runner/evidence.py b/openadapt_flow/runner/evidence.py index adf93849..e8ce0867 100644 --- a/openadapt_flow/runner/evidence.py +++ b/openadapt_flow/runner/evidence.py @@ -207,6 +207,7 @@ def report_events( authorization_id: str, consequential_steps: int, effect_covered_consequential_steps: int, + terminal_outcome: str | None = None, start_seq: int = 1, ) -> list[dict[str, Any]]: """The ordered evidence stream for a completed local run. @@ -241,10 +242,27 @@ def report_events( for result in report.results if result.identity is not None and result.identity.status == "verified" ) + if terminal_outcome is None: + status = summary_status(report) + elif terminal_outcome == "VERIFIED": + status = "confirmed" + elif terminal_outcome == "HALTED_BEFORE_EFFECT": + status = "halted-needs-attention" + elif terminal_outcome in { + "RECONCILIATION_REQUIRED", + "FAILED_PLATFORM", + "CANCELED", + "REJECTED_POLICY", + "COMPLETED_UNVERIFIED", + "ROLLED_BACK", + }: + status = "failed" + else: + raise ValueError("terminal outcome cannot classify the evidence summary") body = _summary_body( bundle_digest=bundle_digest, authorization_id=authorization_id, - status=summary_status(report), + status=status, steps_total=len(report.results), consequential_steps=consequential_steps, effect_covered_consequential_steps=effect_covered_consequential_steps, diff --git a/openadapt_flow/runner/hosted_adapter.py b/openadapt_flow/runner/hosted_adapter.py index 7fd50a0c..7fa80f08 100644 --- a/openadapt_flow/runner/hosted_adapter.py +++ b/openadapt_flow/runner/hosted_adapter.py @@ -313,8 +313,18 @@ def _terminal_outcome_requires_exact_proof(self) -> "HostedTerminalEvent": has_proof = self.terminal_verification_artifact_bytes_base64 is not None if has_proof != (self.terminal_verification_artifact_sha256 is not None): raise ValueError("terminal verification binding is incomplete") - if self.outcome in {"VERIFIED", "HALTED_BEFORE_EFFECT"} and not has_proof: + if ( + self.outcome + in { + "VERIFIED", + "HALTED_BEFORE_EFFECT", + "RECONCILIATION_REQUIRED", + } + and not has_proof + ): raise ValueError(f"{self.outcome} requires exact terminal verification") + if self.uncertain_delivery != (self.outcome == "RECONCILIATION_REQUIRED"): + raise ValueError("terminal uncertainty conflicts with its outcome") if ( self.outcome not in { @@ -373,6 +383,7 @@ def _closed_terminal(self) -> "HostedRunResult": in { TransactionOutcome.VERIFIED, TransactionOutcome.HALTED_BEFORE_EFFECT, + TransactionOutcome.RECONCILIATION_REQUIRED, } and self.terminal_verification is None ): @@ -427,6 +438,34 @@ class CallbackRequest(_Closed): workflow_admission_sha256: str = Field(pattern=_HEX64) events: tuple[dict[str, Any], ...] = Field(min_length=1, max_length=10_001) + @model_validator(mode="after") + def _atomic_terminal_batch(self) -> "CallbackRequest": + terminal_indices = tuple( + index + for index, event in enumerate(self.events) + if event.get("schema_version") == "openadapt.hosted-runner-terminal/v1" + ) + if terminal_indices != (len(self.events) - 1,): + raise ValueError("callback must end in exactly one terminal event") + terminal = HostedTerminalEvent.model_validate(self.events[-1]) + summaries = tuple( + event for event in self.events[:-1] if event.get("kind") == "run_summary" + ) + if len(summaries) != 1: + raise ValueError("callback must contain exactly one run summary") + if any(event.get("run_id") != terminal.run_id for event in self.events[:-1]): + raise ValueError("callback evidence names a different run") + summary = summaries[0].get("run_summary") + if not isinstance(summary, dict): + raise ValueError("callback run summary is invalid") + expected_status = { + "VERIFIED": "confirmed", + "HALTED_BEFORE_EFFECT": "halted-needs-attention", + }.get(terminal.outcome, "failed") + if summary.get("status") != expected_status: + raise ValueError("callback run summary conflicts with terminal outcome") + return self + class CallbackResponse(_Closed): schema_version: Literal["openadapt.hosted-runner-callback-result/v1"] @@ -1199,12 +1238,24 @@ def _produce_terminal_verification( raise ValueError("run report differs from retained governed inputs") prepared = prepare_production_terminal_evidence(report) + now = datetime.now(timezone.utc).replace(microsecond=0) + now_text = now.isoformat().replace("+00:00", "Z") chain = DurableAuthority(run_dir, store).production_delivery_permit_chain( allow_empty=( prepared.transaction_outcome is TransactionOutcome.HALTED_BEFORE_EFFECT - ) + ), + allow_pending=( + prepared.transaction_outcome + is TransactionOutcome.RECONCILIATION_REQUIRED + ), + receipt_absence_observed_at=( + now_text + if prepared.transaction_outcome + is TransactionOutcome.RECONCILIATION_REQUIRED + else None + ), ) - first = chain.entries[0] if chain.entries else None + first = chain.entries[0] if chain.entries else chain.pending expected = qualification.expected runtime = expected.runtime_build_identity flow_run_id_sha256 = hashlib.sha256(dispatch.run_id.encode("utf-8")).hexdigest() @@ -1230,13 +1281,14 @@ def _produce_terminal_verification( != qualification.qualification_signer_registry_sha256 or first.qualification_signer_registry_revision != qualification.qualification_signer_registry.revision - or first.authenticated_runner_id_sha256 != runner_id_sha256 - or first.authenticated_session_id_sha256 != runner_session_id_sha256 ): raise ValueError("retained delivery chain differs from admitted live state") - - now = datetime.now(timezone.utc).replace(microsecond=0) - now_text = now.isoformat().replace("+00:00", "Z") + if chain.entries and ( + chain.entries[0].authenticated_runner_id_sha256 != runner_id_sha256 + or chain.entries[0].authenticated_session_id_sha256 + != runner_session_id_sha256 + ): + raise ValueError("retained delivery chain differs from admitted live state") context = ProductionTerminalVerificationContext( run_id=dispatch.run_id, tenant_id=dispatch.tenant_id, @@ -1286,6 +1338,7 @@ def _produce_terminal_verification( envelope_bytes = canonical_json(built.envelope) payload = built.envelope.payload final = chain.entries[-1] if chain.entries else None + final_authority = chain.pending or final live_expected = ProductionTerminalVerificationExpected( run_id=dispatch.run_id, flow_run_id_sha256=flow_run_id_sha256, @@ -1320,9 +1373,16 @@ def _produce_terminal_verification( dispatch.execution_authority_signer_sha256 ), permit_chain_sha256=chain.permit_chain_sha256, - permit_count=len(chain.entries), + permit_count=len(chain.entries) + (1 if chain.pending is not None else 0), + acknowledged_permit_count=len(chain.entries), + pending_permit_count=(1 if chain.pending is not None else 0), + pending_permit_artifact_sha256=( + chain.pending.permit_artifact_sha256 + if chain.pending is not None + else None + ), final_authority_sequence=( - final.authority_sequence if final is not None else 0 + final_authority.authority_sequence if final_authority is not None else 0 ), final_runtime_delivery_sequence=( final.runtime_delivery_sequence if final is not None else 0 @@ -1445,9 +1505,9 @@ def reconciliation_required( *, code: str = "runner_result_lost", ) -> HostedRunResult: - """Close a crash window without re-entering the execution path.""" + """Refuse an unsigned callback without re-entering the execution path.""" - parsed = HostedRecoveryBinding.model_validate(binding) + HostedRecoveryBinding.model_validate(binding) if ( not code or len(code) > 64 @@ -1457,21 +1517,7 @@ def reconciliation_required( ) ): raise ValueError("reconciliation code is invalid") - return HostedRunResult( - dispatch_id=parsed.dispatch_id, - run_id=parsed.run_id, - outcome=TransactionOutcome.RECONCILIATION_REQUIRED, - evidence_batch=tuple( - failure_events( - run_id=parsed.run_id, - bundle_digest=parsed.bundle_content_digest, - authorization_id=parsed.authorization_id, - ) - ), - started=True, - uncertain_delivery=True, - report_sha256="0" * 64, - ) + raise RuntimeError("managed run requires signed terminal reconciliation") def execute( self, @@ -1622,45 +1668,20 @@ def execute( # Once this call starts, the child can reach a real input edge. Any # lost or malformed result is uncertain and can never be retried. execution = self._runner(argv, run_dir, child_env) - except Exception: + except Exception as exc: outcome = TransactionOutcome.RECONCILIATION_REQUIRED self._ledger.record_outcome(reservation_key, outcome, run_id=parsed.run_id) - return HostedRunResult( - dispatch_id=parsed.dispatch_id, - run_id=parsed.run_id, - outcome=outcome, - evidence_batch=tuple( - failure_events( - run_id=parsed.run_id, - bundle_digest=parsed.payload.bundle.content_digest, - authorization_id=parsed.payload.authorization.authorization_id, - ) - ), - started=True, - uncertain_delivery=True, - report_sha256="0" * 64, - ) + raise RuntimeError( + "managed run requires signed terminal reconciliation" + ) from exc if execution.report_bytes is None: outcome = TransactionOutcome.RECONCILIATION_REQUIRED self._ledger.record_outcome(reservation_key, outcome, run_id=parsed.run_id) - return HostedRunResult( - dispatch_id=parsed.dispatch_id, - run_id=parsed.run_id, - outcome=outcome, - evidence_batch=tuple( - failure_events( - run_id=parsed.run_id, - bundle_digest=parsed.payload.bundle.content_digest, - authorization_id=parsed.payload.authorization.authorization_id, - ) - ), - started=True, - uncertain_delivery=True, - report_sha256="0" * 64, - ) + raise RuntimeError("managed run requires signed terminal reconciliation") report: RunReport | None = None report_digest = hashlib.sha256(execution.report_bytes).hexdigest() + terminalization_error: Exception | None try: report = RunReport.model_validate_json(execution.report_bytes) outcome = classify_transaction_outcome(report) @@ -1702,19 +1723,23 @@ def execute( ) if proof.payload.run_receipt.transaction_outcome != outcome.value: raise ValueError("terminal proof outcome differs from the report") - except Exception: # noqa: BLE001 - post-delivery terminalization fails closed + except Exception as exc: # noqa: BLE001 - terminalization fails closed outcome = TransactionOutcome.RECONCILIATION_REQUIRED proof = None - if ( - outcome - in { - TransactionOutcome.VERIFIED, - TransactionOutcome.HALTED_BEFORE_EFFECT, - } - and proof is None - ): + terminalization_error = exc + else: + terminalization_error = None + if proof is None and outcome in { + TransactionOutcome.VERIFIED, + TransactionOutcome.HALTED_BEFORE_EFFECT, + TransactionOutcome.RECONCILIATION_REQUIRED, + }: outcome = TransactionOutcome.RECONCILIATION_REQUIRED self._ledger.record_outcome(reservation_key, outcome, run_id=parsed.run_id) + if outcome is TransactionOutcome.RECONCILIATION_REQUIRED and proof is None: + raise RuntimeError( + "managed run requires signed terminal reconciliation" + ) from terminalization_error if report is None: events = tuple( failure_events( @@ -1735,6 +1760,7 @@ def execute( effect_covered_consequential_steps=( verified.effect_covered_consequential_steps ), + terminal_outcome=outcome.value, ) ) uncertain = outcome is TransactionOutcome.RECONCILIATION_REQUIRED diff --git a/openadapt_flow/runtime/durable/authority.py b/openadapt_flow/runtime/durable/authority.py index 08113081..03e3fe64 100644 --- a/openadapt_flow/runtime/durable/authority.py +++ b/openadapt_flow/runtime/durable/authority.py @@ -48,6 +48,7 @@ ProductionDeliveryPermitArtifact, ProductionDeliveryPermitChain, ProductionDeliveryReceiptArtifact, + ProductionPendingDeliveryPermit, ) AUTHORITY_DB_ENV = "OPENADAPT_DURABLE_AUTHORITY_DB" @@ -2419,12 +2420,17 @@ def acknowledge_remote_delivery( return entry def production_delivery_permit_chain( - self, *, allow_empty: bool = False + self, + *, + allow_empty: bool = False, + allow_pending: bool = False, + receipt_absence_observed_at: str | None = None, ) -> ProductionDeliveryPermitChain: - """Rebuild the exact acknowledged chain from protected retained bytes.""" + """Rebuild the exact retained chain without resolving uncertain delivery.""" with self._transaction() as connection: - if self._pending_remote_delivery(connection) is not None: + pending = self._pending_remote_delivery(connection) + if pending is not None and not allow_pending: raise DurableAuthorityBusy( "production delivery remains uncertain without a receipt" ) @@ -2434,7 +2440,11 @@ def production_delivery_permit_chain( "ORDER BY runtime_delivery_sequence", (self.path_key,), ).fetchall() - if not rows: + if pending is not None and receipt_absence_observed_at is None: + raise DurableAuthorityBusy( + "pending production delivery requires an exact absence observation" + ) + if not rows and pending is None: if allow_empty: return ProductionDeliveryPermitChain.build(()) raise DurableAuthorityBusy( @@ -2450,7 +2460,18 @@ def production_delivery_permit_chain( for row in rows ) try: - return ProductionDeliveryPermitChain.build(entries) + pending_entry = ( + ProductionPendingDeliveryPermit.build( + pending.permit_artifact, + receipt_absence_observed_at=receipt_absence_observed_at, + ) + if pending is not None and receipt_absence_observed_at is not None + else None + ) + return ProductionDeliveryPermitChain.build( + entries, + pending=pending_entry, + ) except ValueError as exc: raise DurableAuthorityBusy( "the retained production delivery permit chain is invalid" diff --git a/openadapt_flow/terminal_verification_v2.py b/openadapt_flow/terminal_verification_v2.py index 93a13750..ec6d86c2 100644 --- a/openadapt_flow/terminal_verification_v2.py +++ b/openadapt_flow/terminal_verification_v2.py @@ -87,6 +87,9 @@ PERMIT_CHAIN_ENTRY_SCHEMA: Final[ Literal["openadapt.production-delivery-permit-chain-entry/v2"] ] = "openadapt.production-delivery-permit-chain-entry/v2" +PENDING_PERMIT_SCHEMA: Final[ + Literal["openadapt.production-delivery-pending-permit/v2"] +] = "openadapt.production-delivery-pending-permit/v2" EXECUTION_AUTHORITY_DOMAIN: Final[bytes] = ( b"openadapt.production-execution-authority.v2\0" ) @@ -1540,11 +1543,135 @@ def one_use_claim_id(self) -> str: return self._receipt.one_use_claim_id +class ProductionPendingDeliveryPermit(ClosedSignedModel): + """One final signed permit whose delivery receipt is unresolved.""" + + schema_version: Literal["openadapt.production-delivery-pending-permit/v2"] = ( + PENDING_PERMIT_SCHEMA + ) + permit_artifact: ProductionDeliveryPermitArtifact + permit_artifact_sha256: str = Field(pattern=_SHA256_RE) + delivery_state: Literal["UNRESOLVED"] = "UNRESOLVED" + delivery_receipt_artifact: Literal[None] = None + delivery_receipt_artifact_sha256: Literal[None] = None + receipt_absence_observed_at: str + actuation_replay_authorized: Literal[False] = False + + @model_validator(mode="after") + def _closed_pending_edge(self) -> "ProductionPendingDeliveryPermit": + permit = ProductionDeliveryPermitArtifact.model_validate( + self.permit_artifact.model_dump(mode="json") + ) + if self.permit_artifact_sha256 != permit.artifact_sha256(): + raise ValueError("pending delivery permit artifact digest is invalid") + issued = _parse_utc(permit.payload.issued_at, field="permit issued_at") + absence = _parse_utc( + self.receipt_absence_observed_at, + field="pending receipt absence observed_at", + ) + registry_expires = _parse_utc( + permit.payload.qualification_signer_registry_expires_at, + field="permit registry expires_at", + ) + if not issued <= absence < registry_expires: + raise ValueError("pending delivery permit chronology is invalid") + return self + + @classmethod + def build( + cls, + permit_artifact: ProductionDeliveryPermitArtifact, + *, + receipt_absence_observed_at: str, + ) -> "ProductionPendingDeliveryPermit": + return cls( + permit_artifact=permit_artifact, + permit_artifact_sha256=permit_artifact.artifact_sha256(), + receipt_absence_observed_at=receipt_absence_observed_at, + ) + + @property + def _permit(self) -> ProductionDeliveryPermitPayload: + return self.permit_artifact.payload + + @property + def execution_authority_id(self) -> str: + return self._permit.execution_authority_id + + @property + def execution_authority_sha256(self) -> str: + return self._permit.execution_authority_sha256 + + @property + def permit_id(self) -> str: + return self._permit.permit_id + + @property + def run_id(self) -> str: + return self._permit.run_id + + @property + def flow_run_id_sha256(self) -> str: + return self._permit.flow_run_id_sha256 + + @property + def run_request_sha256(self) -> str: + return self._permit.run_request_sha256 + + @property + def action_request_sha256(self) -> str: + return self._permit.action_request_sha256 + + @property + def admission_artifact_sha256(self) -> str: + return self._permit.admission_artifact_sha256 + + @property + def evidence_identity_sha256(self) -> str: + return self._permit.evidence_identity_sha256 + + @property + def environment_digest(self) -> str: + return self._permit.environment_digest + + @property + def qualification_signer_registry_sha256(self) -> str: + return self._permit.qualification_signer_registry_sha256 + + @property + def qualification_signer_registry_revision(self) -> int: + return self._permit.qualification_signer_registry_revision + + @property + def qualification_signer_registry_expires_at(self) -> str: + return self._permit.qualification_signer_registry_expires_at + + @property + def input_edge_sequence(self) -> int: + return self._permit.input_edge_sequence + + @property + def authority_sequence(self) -> int: + return self._permit.authority_sequence + + @property + def issued_at(self) -> str: + return self._permit.issued_at + + @property + def authority_signer_sha256(self) -> str: + return self.permit_artifact.signer.signer_sha256() + + class ProductionDeliveryPermitChain(ClosedSignedModel): schema_version: Literal["openadapt.production-delivery-permit-chain/v2"] = ( PERMIT_CHAIN_SCHEMA ) entries: tuple[ProductionDeliveryPermit, ...] = Field(max_length=10_000) + pending: ProductionPendingDeliveryPermit | None = Field( + default=None, + exclude_if=lambda value: value is None, + ) permit_chain_sha256: str = Field(pattern=_SHA256_RE) @model_validator(mode="after") @@ -1554,35 +1681,39 @@ def _closed_chain(self) -> "ProductionDeliveryPermitChain": # in-memory mutation cannot enter a trusted chain with a stale digest. for item in self.entries: ProductionDeliveryPermit.model_validate(item.model_dump(mode="json")) - expected = hashlib.sha256( - PERMIT_CHAIN_DOMAIN - + canonical_json( - { - "schema_version": self.schema_version, - "entries": [item.model_dump(mode="json") for item in self.entries], - } + if self.pending is not None: + ProductionPendingDeliveryPermit.model_validate( + self.pending.model_dump(mode="json") ) + digest_payload: dict[str, Any] = { + "schema_version": self.schema_version, + "entries": [item.model_dump(mode="json") for item in self.entries], + } + if self.pending is not None: + digest_payload["pending"] = self.pending.model_dump(mode="json") + expected = hashlib.sha256( + PERMIT_CHAIN_DOMAIN + canonical_json(digest_payload) ).hexdigest() if self.permit_chain_sha256 != expected: raise ValueError("delivery permit chain digest is invalid") - if not self.entries: + all_permits: tuple[ + ProductionDeliveryPermit | ProductionPendingDeliveryPermit, ... + ] = (*self.entries, *((self.pending,) if self.pending else ())) + if not all_permits: return self - authority = self.entries[0].execution_authority_id - authority_digest = self.entries[0].execution_authority_sha256 - admission_digest = self.entries[0].admission_artifact_sha256 - evidence_identity_digest = self.entries[0].evidence_identity_sha256 - environment_digest = self.entries[0].environment_digest - registry_digest = self.entries[0].qualification_signer_registry_sha256 - registry_revision = self.entries[0].qualification_signer_registry_revision - registry_expiry = self.entries[0].qualification_signer_registry_expires_at - run_request_digest = self.entries[0].run_request_sha256 - run_id = self.entries[0].run_id - flow_run_id_sha256 = self.entries[0].flow_run_id_sha256 - authority_signer_sha256 = self.entries[0].authority_signer_sha256 - authenticated_runner_id_sha256 = self.entries[0].authenticated_runner_id_sha256 - authenticated_session_id_sha256 = self.entries[ - 0 - ].authenticated_session_id_sha256 + first = all_permits[0] + authority = first.execution_authority_id + authority_digest = first.execution_authority_sha256 + admission_digest = first.admission_artifact_sha256 + evidence_identity_digest = first.evidence_identity_sha256 + environment_digest = first.environment_digest + registry_digest = first.qualification_signer_registry_sha256 + registry_revision = first.qualification_signer_registry_revision + registry_expiry = first.qualification_signer_registry_expires_at + run_request_digest = first.run_request_sha256 + run_id = first.run_id + flow_run_id_sha256 = first.flow_run_id_sha256 + authority_signer_sha256 = first.authority_signer_sha256 if any( item.execution_authority_id != authority or item.execution_authority_sha256 != authority_digest @@ -1596,33 +1727,49 @@ def _closed_chain(self) -> "ProductionDeliveryPermitChain": or item.qualification_signer_registry_expires_at != registry_expiry or item.run_request_sha256 != run_request_digest or item.authority_signer_sha256 != authority_signer_sha256 - or item.authenticated_runner_id_sha256 != authenticated_runner_id_sha256 - or item.authenticated_session_id_sha256 != authenticated_session_id_sha256 - for item in self.entries + for item in all_permits ): raise ValueError("delivery permit chain changes its production authority") - input_sequences = tuple(item.input_edge_sequence for item in self.entries) - authority_sequences = tuple(item.authority_sequence for item in self.entries) + if self.entries: + authenticated_runner_id_sha256 = self.entries[ + 0 + ].authenticated_runner_id_sha256 + authenticated_session_id_sha256 = self.entries[ + 0 + ].authenticated_session_id_sha256 + if any( + item.authenticated_runner_id_sha256 != authenticated_runner_id_sha256 + or item.authenticated_session_id_sha256 + != authenticated_session_id_sha256 + for item in self.entries + ): + raise ValueError( + "delivery permit chain changes its authenticated runner" + ) + input_sequences = tuple(item.input_edge_sequence for item in all_permits) + authority_sequences = tuple(item.authority_sequence for item in all_permits) delivery_sequences = tuple( item.runtime_delivery_sequence for item in self.entries ) - exact = tuple(range(1, len(self.entries) + 1)) + exact = tuple(range(1, len(all_permits) + 1)) if input_sequences != exact: raise ValueError( "delivery input-edge sequence must be exact and contiguous" ) if authority_sequences != tuple( - range(authority_sequences[0], authority_sequences[0] + len(self.entries)) + range(authority_sequences[0], authority_sequences[0] + len(all_permits)) ): raise ValueError("delivery authority sequence must be contiguous") - if delivery_sequences != tuple( - range(delivery_sequences[0], delivery_sequences[0] + len(self.entries)) + if delivery_sequences and delivery_sequences != tuple( + range( + delivery_sequences[0], delivery_sequences[0] + len(delivery_sequences) + ) ): raise ValueError("runtime delivery sequence must be contiguous") - permit_ids = tuple(item.permit_id for item in self.entries) + permit_ids = tuple(item.permit_id for item in all_permits) if len(permit_ids) != len(set(permit_ids)): raise ValueError("delivery permit chain repeats a permit") - action_requests = tuple(item.action_request_sha256 for item in self.entries) + action_requests = tuple(item.action_request_sha256 for item in all_permits) if len(action_requests) != len(set(action_requests)): raise ValueError("delivery permit chain repeats an action request") claim_ids = tuple(item.one_use_claim_id for item in self.entries) @@ -1640,20 +1787,36 @@ def _closed_chain(self) -> "ProductionDeliveryPermitChain": for previous, current in zip(event_times, event_times[1:]) ): raise ValueError("delivery permit chronology is invalid") + if self.pending is not None and self.entries: + final_delivered = _parse_utc( + self.entries[-1].delivered_at, + field="permit delivered_at", + ) + pending_issued = _parse_utc( + self.pending.issued_at, + field="pending permit issued_at", + ) + if final_delivered > pending_issued: + raise ValueError("pending delivery permit chronology is invalid") return self @classmethod def build( - cls, entries: tuple[ProductionDeliveryPermit, ...] + cls, + entries: tuple[ProductionDeliveryPermit, ...], + *, + pending: ProductionPendingDeliveryPermit | None = None, ) -> "ProductionDeliveryPermitChain": - payload = { + payload: dict[str, Any] = { "schema_version": PERMIT_CHAIN_SCHEMA, "entries": [item.model_dump(mode="json") for item in entries], } + if pending is not None: + payload["pending"] = pending.model_dump(mode="json") digest = hashlib.sha256( PERMIT_CHAIN_DOMAIN + canonical_json(payload) ).hexdigest() - return cls(entries=entries, permit_chain_sha256=digest) + return cls(entries=entries, pending=pending, permit_chain_sha256=digest) def build_production_evidence_manifests( @@ -1915,6 +2078,8 @@ class ProductionTerminalVerificationPayload(ClosedSignedModel): execution_authority_signer_sha256: str = Field(pattern=_SHA256_RE) permit_chain: ProductionDeliveryPermitChain permit_count: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) + acknowledged_permit_count: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) + pending_permit_count: StrictInt = Field(ge=0, le=1) final_authority_sequence: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) final_runtime_delivery_sequence: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) workflow_contract_sha256: str = Field(pattern=_SHA256_RE) @@ -1943,8 +2108,8 @@ def _closed_terminal_outcome(self) -> "ProductionTerminalVerificationPayload": receipt = self.run_receipt outcome = self.execution_outcome manifests = self.evidence_manifests - if chain.entries: - final = chain.entries[-1] + final = chain.pending or (chain.entries[-1] if chain.entries else None) + if final is not None: if ( self.execution_authority_id, self.execution_authority_sha256, @@ -1978,19 +2143,28 @@ def _closed_terminal_outcome(self) -> "ProductionTerminalVerificationPayload": raise ValueError( "terminal qualification state does not match its permits" ) + expected_final_delivery_sequence = ( + chain.entries[-1].runtime_delivery_sequence if chain.entries else 0 + ) if ( self.permit_count, + self.acknowledged_permit_count, + self.pending_permit_count, self.final_authority_sequence, self.final_runtime_delivery_sequence, ) != ( + len(chain.entries) + (1 if chain.pending is not None else 0), len(chain.entries), + 1 if chain.pending is not None else 0, final.authority_sequence, - final.runtime_delivery_sequence, + expected_final_delivery_sequence, ): raise ValueError("terminal permit counts do not match the permit chain") elif ( receipt.transaction_outcome != "HALTED_BEFORE_EFFECT" or self.permit_count != 0 + or self.acknowledged_permit_count != 0 + or self.pending_permit_count != 0 or self.final_authority_sequence != 0 or self.final_runtime_delivery_sequence != 0 ): @@ -2074,7 +2248,8 @@ def _closed_terminal_outcome(self) -> "ProductionTerminalVerificationPayload": outcome.outcome != "VERIFIED" or not outcome.production_eligible or not outcome.execution_completed - or not chain.entries + or self.acknowledged_permit_count < 1 + or self.pending_permit_count != 0 ): raise ValueError("terminal VERIFIED proof is incomplete") elif transaction_outcome == "HALTED_BEFORE_EFFECT": @@ -2083,6 +2258,7 @@ def _closed_terminal_outcome(self) -> "ProductionTerminalVerificationPayload": or outcome.production_eligible or outcome.execution_completed or receipt.production_eligible + or self.permit_count != 0 or any( not isinstance(item, ProductionTerminalEffectState) or item.absence_basis not in {"not_actuated", "verifier_refuted"} @@ -2090,13 +2266,46 @@ def _closed_terminal_outcome(self) -> "ProductionTerminalVerificationPayload": ) ): raise ValueError("terminal HALTED proof lacks exact effect absence") - elif ( - transaction_outcome != "RECONCILIATION_REQUIRED" - or outcome.outcome == "VERIFIED" - or outcome.production_eligible - or receipt.production_eligible - or not chain.entries - ): + elif transaction_outcome == "RECONCILIATION_REQUIRED": + if ( + outcome.outcome == "VERIFIED" + or outcome.production_eligible + or receipt.production_eligible + or self.permit_count < 1 + ): + raise ValueError("terminal reconciliation proof is invalid") + if chain.pending is not None: + uncertain_records = tuple( + item + for item in manifests.effect.records + if isinstance(item, ProductionTerminalEffectState) + and item.attempt_state == "delivery_uncertain" + ) + if not uncertain_records or any( + item.observed_effect not in {"conflicting", "unknown"} + or item.resolved_delivery_uncertainty + or item.absence_basis != "none" + for item in uncertain_records + ): + raise ValueError( + "terminal pending delivery lacks unresolved effect evidence" + ) + elif not any( + isinstance(item, ProductionTerminalEffectState) + and ( + item.final_verdict == "indeterminate" + or item.observed_effect in {"conflicting", "unknown"} + or ( + item.attempt_state == "delivery_uncertain" + and not item.resolved_delivery_uncertainty + ) + ) + for item in manifests.effect.records + ): + raise ValueError( + "terminal reconciliation proof lacks inconclusive effect evidence" + ) + else: raise ValueError("terminal reconciliation proof is invalid") if transaction_outcome != "VERIFIED" and ( receipt.source_receipt_digest != self.run_report_sha256 @@ -2107,7 +2316,24 @@ def _closed_terminal_outcome(self) -> "ProductionTerminalVerificationPayload": issued = _parse_utc(self.issued_at, field="terminal issued_at") if not verified <= issued <= verified + timedelta(minutes=5): raise ValueError("terminal proof issue time is invalid") - if chain.entries: + if chain.pending is not None: + pending_issued = _parse_utc( + chain.pending.issued_at, + field="pending permit issued_at", + ) + absence_observed = _parse_utc( + chain.pending.receipt_absence_observed_at, + field="pending receipt absence observed_at", + ) + registry_expires = _parse_utc( + chain.pending.qualification_signer_registry_expires_at, + field="pending permit registry expires_at", + ) + if not pending_issued <= absence_observed <= verified < registry_expires: + raise ValueError( + "terminal verification is outside pending permit chronology" + ) + elif chain.entries: final = chain.entries[-1] final_delivered = _parse_utc( final.delivered_at, field="permit delivered_at" @@ -2220,6 +2446,12 @@ class ProductionTerminalVerificationExpected(ClosedSignedModel): execution_authority_signer_sha256: str = Field(pattern=_SHA256_RE) permit_chain_sha256: str = Field(pattern=_SHA256_RE) permit_count: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) + acknowledged_permit_count: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) + pending_permit_count: StrictInt = Field(ge=0, le=1) + pending_permit_artifact_sha256: str | None = Field( + default=None, + pattern=_SHA256_RE, + ) final_authority_sequence: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) final_runtime_delivery_sequence: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) authenticated_runner_id_sha256: str = Field(pattern=_SHA256_RE) @@ -2235,10 +2467,21 @@ class ProductionTerminalVerificationExpected(ClosedSignedModel): @model_validator(mode="after") def _closed_delivery_state(self) -> "ProductionTerminalVerificationExpected": - if len(self.acknowledged_one_use_claim_ids) != self.permit_count: + if self.permit_count != ( + self.acknowledged_permit_count + self.pending_permit_count + ): + raise ValueError("live delivery permit counts are inconsistent") + if len(self.acknowledged_one_use_claim_ids) != self.acknowledged_permit_count: raise ValueError("live delivery claim count does not match permit count") - if len(set(self.acknowledged_one_use_claim_ids)) != self.permit_count: + if ( + len(set(self.acknowledged_one_use_claim_ids)) + != self.acknowledged_permit_count + ): raise ValueError("live delivery claims are not globally one-use") + if (self.pending_permit_artifact_sha256 is not None) != ( + self.pending_permit_count == 1 + ): + raise ValueError("live pending delivery binding is inconsistent") for claim_id in self.acknowledged_one_use_claim_ids: if _UUID_RE.fullmatch(claim_id) is None: raise ValueError("live delivery claim id is invalid") @@ -2308,6 +2551,7 @@ class BuiltProductionTerminalVerification: "authenticated_runner_id_sha256", "authenticated_session_id_sha256", "acknowledged_one_use_claim_ids", + "pending_permit_artifact_sha256", } ) @@ -2401,8 +2645,19 @@ def build_production_terminal_verification( execution_authority_sha256=context.execution_authority_sha256, execution_authority_signer_sha256=(context.execution_authority_signer_sha256), permit_chain=context.permit_chain, - permit_count=len(context.permit_chain.entries), - final_authority_sequence=(final.authority_sequence if final is not None else 0), + permit_count=( + len(context.permit_chain.entries) + + (1 if context.permit_chain.pending is not None else 0) + ), + acknowledged_permit_count=len(context.permit_chain.entries), + pending_permit_count=(1 if context.permit_chain.pending is not None else 0), + final_authority_sequence=( + context.permit_chain.pending.authority_sequence + if context.permit_chain.pending is not None + else final.authority_sequence + if final is not None + else 0 + ), final_runtime_delivery_sequence=( final.runtime_delivery_sequence if final is not None else 0 ), @@ -2487,6 +2742,13 @@ def verify_production_terminal_verification( raise ProductionTerminalVerificationError( "production terminal one-use claims do not match live state" ) + pending_permit_artifact_sha256 = ( + chain.pending.permit_artifact_sha256 if chain.pending is not None else None + ) + if pending_permit_artifact_sha256 != expected.pending_permit_artifact_sha256: + raise ProductionTerminalVerificationError( + "production terminal pending permit does not match live state" + ) current = (now or datetime.now(timezone.utc)).astimezone(timezone.utc) if _parse_utc(payload.issued_at, field="terminal issued_at") > current + timedelta( minutes=5 @@ -2499,6 +2761,8 @@ def verify_production_terminal_verification( def rebuild_production_delivery_permit_chain( permits: tuple[ProductionDeliveryPermit, ...], + *, + pending: ProductionPendingDeliveryPermit | None = None, ) -> ProductionDeliveryPermitChain: """Rebuild the permit chain from independently retained permit records. @@ -2508,15 +2772,33 @@ def rebuild_production_delivery_permit_chain( rebuilds the chain, and passes the rebuilt digest as the expected value. """ - return ProductionDeliveryPermitChain.build(permits) + if not permits and pending is None: + raise ProductionTerminalVerificationError( + "retained production delivery artifact count is invalid" + ) + if len(permits) + (1 if pending is not None else 0) > 10_000: + raise ProductionTerminalVerificationError( + "retained production delivery artifact count is invalid" + ) + return ProductionDeliveryPermitChain.build(permits, pending=pending) def rebuild_production_delivery_permit_chain_from_artifacts( artifacts: tuple[tuple[bytes, bytes], ...], + *, + pending_permit_artifact: bytes | None = None, + receipt_absence_observed_at: str | None = None, ) -> ProductionDeliveryPermitChain: """Rebuild a chain from exact retained permit and receipt envelope bytes.""" - if not artifacts or len(artifacts) > 10_000: + has_pending = pending_permit_artifact is not None + if has_pending != (receipt_absence_observed_at is not None): + raise ProductionTerminalVerificationError( + "retained pending delivery binding is incomplete" + ) + if (not artifacts and not has_pending) or len(artifacts) + ( + 1 if has_pending else 0 + ) > 10_000: raise ProductionTerminalVerificationError( "retained production delivery artifact count is invalid" ) @@ -2550,7 +2832,33 @@ def rebuild_production_delivery_permit_chain_from_artifacts( "retained production delivery artifact is not canonical" ) entries.append(ProductionDeliveryPermit.build(permit, receipt)) - return ProductionDeliveryPermitChain.build(tuple(entries)) + pending: ProductionPendingDeliveryPermit | None = None + if pending_permit_artifact is not None: + if ( + len(pending_permit_artifact) == 0 + or len(pending_permit_artifact) > MAX_DELIVERY_ARTIFACT_BYTES + ): + raise ProductionTerminalVerificationError( + "retained pending delivery artifact size is invalid" + ) + try: + permit = ProductionDeliveryPermitArtifact.model_validate_json( + pending_permit_artifact + ) + except ValueError as exc: + raise ProductionTerminalVerificationError( + "retained pending delivery artifact is invalid" + ) from exc + if permit.canonical_bytes() != pending_permit_artifact: + raise ProductionTerminalVerificationError( + "retained pending delivery artifact is not canonical" + ) + assert receipt_absence_observed_at is not None + pending = ProductionPendingDeliveryPermit.build( + permit, + receipt_absence_observed_at=receipt_absence_observed_at, + ) + return ProductionDeliveryPermitChain.build(tuple(entries), pending=pending) def verify_production_terminal_verification_from_report( diff --git a/public-artifacts.json b/public-artifacts.json index 5fa48130..a5abef09 100644 --- a/public-artifacts.json +++ b/public-artifacts.json @@ -5783,6 +5783,10 @@ "path": "tests/fixtures/terminal_verification_v2_delivery_vector.json", "sha256": "20a1ae7f1878315c100c58894ec14bbc6af4848a6c206c467ca82cff025325f0" }, + { + "path": "tests/fixtures/terminal_verification_v2_terminal_vectors.json", + "sha256": "82d609a0c29593c91ec42b9416a64d6432fad47e3898bbfb926e76f7598f91df" + }, { "path": "tests/fixtures/theme-region-stable-overhalt-v1.16.1.json", "sha256": "4bf055e6c11f837ed6daa4a5b89ab28dd431a7eccd2ce3044758ba260eed52cd" diff --git a/scripts/generate_terminal_verification_v2_vectors.py b/scripts/generate_terminal_verification_v2_vectors.py new file mode 100644 index 00000000..2b7ea7f3 --- /dev/null +++ b/scripts/generate_terminal_verification_v2_vectors.py @@ -0,0 +1,102 @@ +#!/usr/bin/env python3 +"""Regenerate the deterministic non-success terminal-v2 test vectors.""" + +from __future__ import annotations + +import argparse +import hashlib +import json +from base64 import b64encode +from pathlib import Path + +from cryptography.hazmat.primitives import serialization + +from openadapt_flow.qualification_admission_v2 import canonical_json +from openadapt_flow.terminal_verification_v2 import ( + SIGNATURE_DOMAIN, + evidence_runner_key_id, + evidence_runner_signer_sha256, + sign_production_terminal_verification, +) +from tests.test_terminal_verification_v2 import ( + _halted_payload, + _private_key, + _reconciliation_payload, +) + +DEFAULT_OUTPUT = Path("tests/fixtures/terminal_verification_v2_terminal_vectors.json") + + +def _vector(name: str, *, uncertain_delivery: bool) -> dict[str, object]: + payload = ( + _halted_payload() + if name == "halted-before-effect-zero-permit" + else _reconciliation_payload() + ) + envelope = sign_production_terminal_verification(payload, _private_key()) + raw = canonical_json(envelope) + effect_state = payload.evidence_manifests.effect.records[0] + return { + "callback": { + "artifact_bytes_source": "envelope_canonical_base64", + "outcome": payload.run_receipt.transaction_outcome, + "report_sha256": payload.run_report_sha256, + "run_id": payload.run_id, + "schema_version": "openadapt.hosted-runner-terminal/v1", + "started": True, + "uncertain_delivery": uncertain_delivery, + }, + "effect_state": effect_state.model_dump(mode="json"), + "envelope_canonical_base64": b64encode(raw).decode("ascii"), + "name": name, + "payload_canonical_sha256": hashlib.sha256( + payload.canonical_bytes() + ).hexdigest(), + "signature": envelope.signature, + "terminal_verification_artifact_sha256": envelope.artifact_sha256(), + } + + +def build_fixture() -> dict[str, object]: + private_key = _private_key() + private_bytes = private_key.private_bytes( + encoding=serialization.Encoding.Raw, + format=serialization.PrivateFormat.Raw, + encryption_algorithm=serialization.NoEncryption(), + ) + public_bytes = private_key.public_key().public_bytes( + encoding=serialization.Encoding.Raw, + format=serialization.PublicFormat.Raw, + ) + return { + "key_id": evidence_runner_key_id(public_bytes), + "private_key_base64": b64encode(private_bytes).decode("ascii"), + "public_key_base64": b64encode(public_bytes).decode("ascii"), + "schema_version": "openadapt.production-terminal-cross-language-vectors/v2", + "signature_domain_base64": b64encode(SIGNATURE_DOMAIN).decode("ascii"), + "signer_sha256": evidence_runner_signer_sha256(public_bytes), + "vectors": [ + _vector( + "halted-before-effect-zero-permit", + uncertain_delivery=False, + ), + _vector( + "reconciliation-required-pending-permit", + uncertain_delivery=True, + ), + ], + } + + +def main() -> None: + parser = argparse.ArgumentParser() + parser.add_argument("--output", type=Path, default=DEFAULT_OUTPUT) + args = parser.parse_args() + args.output.write_text( + json.dumps(build_fixture(), indent=2, sort_keys=True) + "\n", + encoding="utf-8", + ) + + +if __name__ == "__main__": + main() diff --git a/tests/fixtures/terminal_verification_v2_terminal_vectors.json b/tests/fixtures/terminal_verification_v2_terminal_vectors.json index 5764f76e..5d7ceabc 100644 --- a/tests/fixtures/terminal_verification_v2_terminal_vectors.json +++ b/tests/fixtures/terminal_verification_v2_terminal_vectors.json @@ -1 +1,74 @@ -{"key_id":"evidence-runner-ed25519-56475aa75463474c","private_key_base64":"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=","public_key_base64":"A6EHv/POEL4dcN0Y50vAmWfk1jCbpQ1fHdyGZBJVMbg=","schema_version":"openadapt.production-terminal-cross-language-vectors/v2","signature_domain_base64":"b3BlbmFkYXB0LXByb2R1Y3Rpb24tdGVybWluYWwtdmVyaWZpY2F0aW9uLXYyAA==","signer_sha256":"56475aa75463474c0285df5dbf2bcab73da651358839e9b77481b2eab107708c","vectors":[{"callback":{"artifact_bytes_source":"envelope_canonical_base64","outcome":"HALTED_BEFORE_EFFECT","report_sha256":"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb","run_id":"00000000-0000-4000-8000-000000000001","schema_version":"openadapt.hosted-runner-terminal/v1","started":true,"uncertain_delivery":false},"effect_state":{"absence_basis":"not_actuated","attempt_state":"not_actuated","effect_contract_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","effect_verified":false,"final_verdict":null,"observed_effect":"absent","reconciliation_actions":0,"reconciliation_completed":false,"record_kind":"terminal_effect_state","resolved_delivery_uncertainty":false,"result_index":0,"verification_performed":false,"verification_tier":null,"verifier_identity":null},"envelope_canonical_base64":"eyJwYXlsb2FkIjp7ImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA2IiwiYWRtaXNzaW9uX3BvbGljeV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYWRtaXR0ZWRfcnVudGltZV9idWlsZF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiYnVuZGxlX2FydGlmYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJidW5kbGVfY29udGVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYnVuZGxlX3ZlcnNpb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDQiLCJlZmZlY3RfY29udHJhY3Rfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImVudmlyb25tZW50X2NvbnRyYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJlbnZpcm9ubWVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXZpZGVuY2VfaWRlbnRpdHlfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImV2aWRlbmNlX21hbmlmZXN0cyI6eyJhdXRob3JpemF0aW9uIjp7ImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA2IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOCIsImV4ZWN1dGlvbl9hdXRob3JpdHlfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImdvdmVybmVkX2F1dGhvcml6YXRpb25faWRfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsIm1hbmlmZXN0X3NoYTI1NiI6IjMyY2QzNjEzYmVlOWJjNjkwNjkzYTM5NWQ5OTMzNTQ3ZjllZWI5ZjZmYWE1ZGJkYmIxNGExMDYyOThiZTQ2NWMiLCJwZXJtaXRfY2hhaW5fc2hhMjU2IjoiODJkYWI1NDI4ZTI1MmQxOGE1OWIwMTc3NzM5ZTAwY2FhZGI3NjJkY2Y1OWY0MDM2ZGVhNGQ3N2MzYzMyMDNjYiIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tYXV0aG9yaXphdGlvbi1ldmlkZW5jZS92MSJ9LCJlZmZlY3QiOnsiY29uZmlybWVkIjowLCJlZmZlY3RfY29udHJhY3Rfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsIm1hbmlmZXN0X3NoYTI1NiI6ImViYjU4MzYxNzhlZGZhYzYyOWJkOWJjYTkwZWNkMDE5NTkwOTQ5NjZhMGRkNjNiYWVhN2E2MmY2ZTNiMDRmZjgiLCJyZWNvcmRzIjpbeyJhYnNlbmNlX2Jhc2lzIjoibm90X2FjdHVhdGVkIiwiYXR0ZW1wdF9zdGF0ZSI6Im5vdF9hY3R1YXRlZCIsImVmZmVjdF9jb250cmFjdF9oYXNoIjoic2hhMjU2OmFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJlZmZlY3RfdmVyaWZpZWQiOmZhbHNlLCJmaW5hbF92ZXJkaWN0IjpudWxsLCJvYnNlcnZlZF9lZmZlY3QiOiJhYnNlbnQiLCJyZWNvbmNpbGlhdGlvbl9hY3Rpb25zIjowLCJyZWNvbmNpbGlhdGlvbl9jb21wbGV0ZWQiOmZhbHNlLCJyZWNvcmRfa2luZCI6InRlcm1pbmFsX2VmZmVjdF9zdGF0ZSIsInJlc29sdmVkX2RlbGl2ZXJ5X3VuY2VydGFpbnR5IjpmYWxzZSwicmVzdWx0X2luZGV4IjowLCJ2ZXJpZmljYXRpb25fcGVyZm9ybWVkIjpmYWxzZSwidmVyaWZpY2F0aW9uX3RpZXIiOm51bGwsInZlcmlmaWVyX2lkZW50aXR5IjpudWxsfV0sInJlcXVpcmVkIjoxLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWVmZmVjdC1ldmlkZW5jZS92MSIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifSwiaWRlbnRpdHkiOnsiY29uZmlybWVkIjoxLCJpZGVudGl0eV9jb250cmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwibWFuaWZlc3Rfc2hhMjU2IjoiMTM1Yzg2M2VkYzdmYWIxOGNhMjliNDkyOTNmYzI1YTFjOWJkNGRlMGU5ZWQyOGQ0Y2VjNmU4ZDBhNjc5MTIyOSIsInJlcXVpcmVkIjoxLCJyZXN1bHRzIjpbeyJtb2RlIjoic3RydWN0dXJlZCIsInJlc3VsdF9pbmRleCI6MCwic2lnbmFscyI6W10sInN0YXR1cyI6InZlcmlmaWVkIn1dLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWlkZW50aXR5LWV2aWRlbmNlL3YxIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSJ9LCJwb2xpY3kiOnsiYWRtaXNzaW9uX3BvbGljeV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZWZmZWN0X2NvbnRyYWN0X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJlbnZpcm9ubWVudF9jb250cmFjdF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwiZW52aXJvbm1lbnRfZGlnZXN0IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImdvdmVybmVkX3BvbGljeV9jb250cmFjdF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwiZ292ZXJuZWRfcnVudGltZV9pbnB1dHNfZGlnZXN0IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsImlkZW50aXR5X2NvbnRyYWN0X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJtYW5pZmVzdF9zaGEyNTYiOiI0Zjk4OGQwMTViY2Q3Y2Q3ZTA1YmEwNjYzZDg5ZjBhOTY4ZjBkOGFjZTk5YjA5MGViYWJlZTUyYTFjNTUwNDIxIiwibWluaW11bV9lZmZlY3RfdGllciI6MSwicnVudGltZV9lbnZpcm9ubWVudF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1wb2xpY3ktZXZpZGVuY2UvdjEifSwicG9zdGNvbmRpdGlvbiI6eyJjb25maXJtZWQiOjAsIm1hbmlmZXN0X3NoYTI1NiI6IjNlYTRjNjRhMzBiMGNmMTdiY2EwNGYzMjYwZTBhNDcxOGIyN2Y1MWUxZmRjMmJiODhhMTgyNjMwYTM0ZGQ1ZmYiLCJyZWNvcmRzIjpbeyJhY3Rpb25fa2luZCI6ImNsaWNrIiwiYWN0dWF0aW9uX3BhdGgiOiJndWkiLCJjb250cmFjdF9pbmRleCI6MCwiY29udHJhY3Rfa2luZCI6ImV4cGxpY2l0X3ByZWRpY2F0ZSIsImNvbnRyYWN0X3NoYTI1NiI6IjBhZGUwYjUyMGJjMDA3ODkxY2FjY2EwMDE3MTU3ODQ0MmEyYTc0Y2VmMTVmZjY0ZGRlNDVkZjA3YWZiNjRhZWIiLCJyZXN1bHRfaW5kZXgiOjAsInN0ZXBfY29udHJhY3Rfc2hhMjU2IjoiMWE1OTUzNmE0ODhiMWM0NmFhY2YwYmEzNzkzMGI4NDA2MmMxNDI3NTVmYTkzOTE1MmVmNWUyOGM0MDk0NzFlZCIsInN0ZXBfaW5kZXgiOjAsInZlcmRpY3QiOiJ1bnZlcmlmaWFibGUiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIn1dLCJyZXF1aXJlZCI6MSwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1wb3N0Y29uZGl0aW9uLWV2aWRlbmNlL3YxIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSJ9fSwiZXZpZGVuY2VfcnVubmVyX3NpZ25lcl9zaGEyNTYiOiI1NjQ3NWFhNzU0NjM0NzRjMDI4NWRmNWRiZjJiY2FiNzNkYTY1MTM1ODgzOWU5Yjc3NDgxYjJlYWIxMDc3MDhjIiwiZXhlY3V0aW9uX2F1dGhvcml0eV9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOCIsImV4ZWN1dGlvbl9hdXRob3JpdHlfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImV4ZWN1dGlvbl9hdXRob3JpdHlfc2lnbmVyX3NoYTI1NiI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJleGVjdXRpb25fb3V0Y29tZSI6eyJjb21wZW5zYXRpb25fYWN0aW9ucyI6MCwiZXZpZGVuY2VfY2xhc3NlcyI6WyJhdXRob3JpemF0aW9uIiwiaWRlbnRpdHkiXSwiZXhlY3V0aW9uX2NvbXBsZXRlZCI6ZmFsc2UsImV4dGVybmFsX25ldHdvcmtfY2FsbHMiOiJub25lIiwibW9kZWxfY2FsbHMiOjAsIm91dGNvbWUiOiJIQUxURUQiLCJwYXNzZWRfY29udHJhY3RzIjp7ImF1dGhvcml6YXRpb24iOjEsImVmZmVjdCI6MCwiaWRlbnRpdHkiOjEsInBvc3Rjb25kaXRpb24iOjB9LCJwb3N0Y29uZGl0aW9uX2V2aWRlbmNlIjpbeyJhY3Rpb25fa2luZCI6ImNsaWNrIiwiYWN0dWF0aW9uX3BhdGgiOiJndWkiLCJjb250cmFjdF9pbmRleCI6MCwiY29udHJhY3Rfa2luZCI6ImV4cGxpY2l0X3ByZWRpY2F0ZSIsImNvbnRyYWN0X3NoYTI1NiI6IjBhZGUwYjUyMGJjMDA3ODkxY2FjY2EwMDE3MTU3ODQ0MmEyYTc0Y2VmMTVmZjY0ZGRlNDVkZjA3YWZiNjRhZWIiLCJyZXN1bHRfaW5kZXgiOjAsInN0ZXBfY29udHJhY3Rfc2hhMjU2IjoiMWE1OTUzNmE0ODhiMWM0NmFhY2YwYmEzNzkzMGI4NDA2MmMxNDI3NTVmYTkzOTE1MmVmNWUyOGM0MDk0NzFlZCIsInN0ZXBfaW5kZXgiOjAsInZlcmRpY3QiOiJ1bnZlcmlmaWFibGUiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIn1dLCJwcm9kdWN0aW9uX2VsaWdpYmxlIjpmYWxzZSwicHJvZmlsZSI6InN0YW5kYXJkIiwicXVhbGlmaWNhdGlvbl9ldmlkZW5jZV9vbmx5IjpmYWxzZSwicmVxdWlyZWRfY29udHJhY3RzIjp7ImF1dGhvcml6YXRpb24iOjEsImVmZmVjdCI6MSwiaWRlbnRpdHkiOjEsInBvc3Rjb25kaXRpb24iOjF9LCJ2ZXJzaW9uIjoib3BlbmFkYXB0LmV4ZWN1dGlvbi1vdXRjb21lL3YxIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSJ9LCJleGVjdXRpb25fb3V0Y29tZV9zaGEyNTYiOiJmZTM4OWJhYjBlYjQ0NDdjZWMxOTk4Mjc0ZjcyN2NhNTcwMDQ5ZmVmZDU1N2RiNzk5MDQ3Njk5ZjJmNzhmMTQyIiwiZXhlY3V0aW9uX3B1cnBvc2UiOiJwcm9kdWN0aW9uIiwiZmluYWxfYXV0aG9yaXR5X3NlcXVlbmNlIjowLCJmaW5hbF9ydW50aW1lX2RlbGl2ZXJ5X3NlcXVlbmNlIjowLCJmbG93X3J1bl9pZF9zaGEyNTYiOiIxMWU1OTRmNDgxOTU4YzEwZTMwMTVkMGJmMDQ0N2EyMmYwNjhhOGE2NDdmNDc1ZGYxNWNlMmM3YWI0YjhmM2YxIiwiaWRlbnRpdHlfY29udHJhY3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsImlzc3VlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDNaIiwicGVybWl0X2NoYWluIjp7ImVudHJpZXMiOltdLCJwZXJtaXRfY2hhaW5fc2hhMjU2IjoiODJkYWI1NDI4ZTI1MmQxOGE1OWIwMTc3NzM5ZTAwY2FhZGI3NjJkY2Y1OWY0MDM2ZGVhNGQ3N2MzYzMyMDNjYiIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcGVybWl0LWNoYWluL3YyIn0sInBlcm1pdF9jb3VudCI6MCwicXVhbGlmaWNhdGlvbl9zaWduZXJfcmVnaXN0cnlfcmV2aXNpb24iOjcsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJydW5faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDEiLCJydW5fcmVjZWlwdCI6eyJhdXRob3JpemF0aW9uX2NvbmZpcm1lZCI6MSwiYXV0aG9yaXphdGlvbl9yZXF1aXJlZCI6MSwiYnVuZGxlX2RpZ2VzdCI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJkdXJhdGlvbl9tcyI6MTAwLCJlZmZlY3RfdGllcl9yZWFjaGVkIjoibm9uZSIsImVmZmVjdHNfY29uZmlybWVkIjowLCJlZmZlY3RzX3JlcXVpcmVkIjoxLCJlc3RfY29zdF9taWNyb3VzZCI6MCwiZXZpZGVuY2VfY2xhc3NlcyI6WyJhdXRob3JpemF0aW9uIiwiaWRlbnRpdHkiXSwiZXh0ZXJuYWxfbmV0d29ya19jYWxscyI6Im5vbmUiLCJnZW5lcmF0ZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAwWiIsImhlYWxzIjowLCJpZGVudGl0eV9hcHBsaWNhYmxlIjoxLCJpZGVudGl0eV9hcm1lZCI6MSwiaWRlbnRpdHlfY29uZmlybWVkIjoxLCJpZGVudGl0eV9yZXF1aXJlZCI6MSwibW9kZWxfY2FsbHMiOjAsIm91dGNvbWUiOiJIQUxURUQiLCJvdmVyX2hhbHRfY291bnQiOjAsInBvc3Rjb25kaXRpb25zX2NvbmZpcm1lZCI6MCwicG9zdGNvbmRpdGlvbnNfcmVxdWlyZWQiOjEsInByb2R1Y3Rpb25fZWxpZ2libGUiOmZhbHNlLCJwcm9maWxlIjoic3RhbmRhcmQiLCJwcm92ZW5hbmNlIjoicHJvZHVjdGlvbiIsInJlY2VpcHRfYnVpbGRlcl92ZXJzaW9uIjoiMS4yLjMiLCJydW5nX2hpc3RvZ3JhbSI6e30sInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tcnVuLXJlY2VpcHQvdjEiLCJzb3VyY2VfcmVjZWlwdF9kaWdlc3QiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwic291cmNlX3JlY2VpcHRfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsInNvdXJjZV9zY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5ydW4tcmVwb3J0L3YxIiwic3RlcHNfb2siOjAsInN0ZXBzX3RvdGFsIjoxLCJzdWJzdHJhdGUiOiJ3ZWIiLCJ0cmFuc2FjdGlvbl9vdXRjb21lIjoiSEFMVEVEX0JFRk9SRV9FRkZFQ1QifSwicnVuX3JlY2VpcHRfc2hhMjU2IjoiYWI1MGEwMDZhODg4YjNmOTBlMWU3MWVmMjA5MjFhZjcxN2IyZjQxYTM2NzZlNjA1ZmJkYjgyMGNiNmI1M2NjNCIsInJ1bl9yZXBvcnRfb2JqZWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJydW5fcmVwb3J0X29iamVjdF92ZXJzaW9uIjoidmVyc2lvbjpoYWx0ZWQ6MSIsInJ1bl9yZXBvcnRfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsInJ1bnRpbWVfZW52aXJvbm1lbnRfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsInJ1bnRpbWVfc3Vic3RyYXRlIjoid2ViIiwicnVudGltZV92YWxpZGF0aW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA1Iiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi10ZXJtaW5hbC12ZXJpZmljYXRpb24vdjIiLCJ0ZW5hbnRfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDIiLCJ0ZXJtaW5hbF9zZXF1ZW5jZSI6MSwidmVyaWZpZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAyWiIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJ3b3JrZmxvd19pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwMyIsIndvcmtmbG93X3ZlcnNpb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDQifSwic2lnbmF0dXJlIjoiNUptaHdlQXN0OGZ0eUwtbjd4a1JLNTE0cEJCbkU1TzlobUZ3RjRDbmtKOEtpVHBKeExFQWs2ZHNzTUhfTkVSM2QzbVFOeENBQkNHckRkY29tSkE5Q1EiLCJzaWduZXIiOnsiYWxnb3JpdGhtIjoiZWQyNTUxOSIsImtleV9pZCI6ImV2aWRlbmNlLXJ1bm5lci1lZDI1NTE5LTU2NDc1YWE3NTQ2MzQ3NGMiLCJwdWJsaWNfa2V5IjoiQTZFSHYvUE9FTDRkY04wWTUwdkFtV2ZrMWpDYnBRMWZIZHlHWkJKVk1iZz0ifX0=","name":"halted-before-effect-zero-permit","payload_canonical_sha256":"26f4073246b4998650636bd3f1cef10835c7f51d91ccfa1d0854bc67015e6792","signature":"5JmhweAst8ftyL-n7xkRK514pBBnE5O9hmFwF4CnkJ8KiTpJxLEAk6dssMH_NER3d3mQNxCABCGrDdcomJA9CQ","terminal_verification_artifact_sha256":"43f6fc7809d789aa42785b7f76ce2dd751b2c3251c8fc74ec1f7bfe3a70b6577"},{"callback":{"artifact_bytes_source":"envelope_canonical_base64","outcome":"RECONCILIATION_REQUIRED","report_sha256":"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb","run_id":"00000000-0000-4000-8000-000000000001","schema_version":"openadapt.hosted-runner-terminal/v1","started":true,"uncertain_delivery":true},"effect_state":{"absence_basis":"none","attempt_state":"delivery_uncertain","effect_contract_hash":"sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","effect_verified":false,"final_verdict":null,"observed_effect":"unknown","reconciliation_actions":0,"reconciliation_completed":false,"record_kind":"terminal_effect_state","resolved_delivery_uncertainty":false,"result_index":0,"verification_performed":false,"verification_tier":null,"verifier_identity":null},"envelope_canonical_base64":"eyJwYXlsb2FkIjp7ImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA2IiwiYWRtaXNzaW9uX3BvbGljeV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYWRtaXR0ZWRfcnVudGltZV9idWlsZF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiYnVuZGxlX2FydGlmYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJidW5kbGVfY29udGVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYnVuZGxlX3ZlcnNpb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDQiLCJlZmZlY3RfY29udHJhY3Rfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImVudmlyb25tZW50X2NvbnRyYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJlbnZpcm9ubWVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXZpZGVuY2VfaWRlbnRpdHlfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImV2aWRlbmNlX21hbmlmZXN0cyI6eyJhdXRob3JpemF0aW9uIjp7ImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA2IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOCIsImV4ZWN1dGlvbl9hdXRob3JpdHlfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImdvdmVybmVkX2F1dGhvcml6YXRpb25faWRfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsIm1hbmlmZXN0X3NoYTI1NiI6ImYwY2ExOWE2YjNlYWJlNTk0ZGJjOTA2ODljMmY3NGNiZTVlODJkNGQ5NDdkYjI5YTVkMDdiMTY0MWU4OTYxY2YiLCJwZXJtaXRfY2hhaW5fc2hhMjU2IjoiNTA0OGZlOTQ1ODgyZDI4MDI2MDA4ZDdlOTEzN2FkMDE2ZmRkMDFhZWFmNTg4NDgxZmI1YmQwZjI0MmE1MDA0MyIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tYXV0aG9yaXphdGlvbi1ldmlkZW5jZS92MSJ9LCJlZmZlY3QiOnsiY29uZmlybWVkIjowLCJlZmZlY3RfY29udHJhY3Rfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsIm1hbmlmZXN0X3NoYTI1NiI6ImFmMTUwOWNjMmU5ZmExZjViOGI4MTVlN2IxZjYwNDYxOWIyYTM1ZWMwZGU1ZTBkMzRiYmZhNjdjYzkxZGJiYzciLCJyZWNvcmRzIjpbeyJhYnNlbmNlX2Jhc2lzIjoibm9uZSIsImF0dGVtcHRfc3RhdGUiOiJkZWxpdmVyeV91bmNlcnRhaW4iLCJlZmZlY3RfY29udHJhY3RfaGFzaCI6InNoYTI1NjphYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZWZmZWN0X3ZlcmlmaWVkIjpmYWxzZSwiZmluYWxfdmVyZGljdCI6bnVsbCwib2JzZXJ2ZWRfZWZmZWN0IjoidW5rbm93biIsInJlY29uY2lsaWF0aW9uX2FjdGlvbnMiOjAsInJlY29uY2lsaWF0aW9uX2NvbXBsZXRlZCI6ZmFsc2UsInJlY29yZF9raW5kIjoidGVybWluYWxfZWZmZWN0X3N0YXRlIiwicmVzb2x2ZWRfZGVsaXZlcnlfdW5jZXJ0YWludHkiOmZhbHNlLCJyZXN1bHRfaW5kZXgiOjAsInZlcmlmaWNhdGlvbl9wZXJmb3JtZWQiOmZhbHNlLCJ2ZXJpZmljYXRpb25fdGllciI6bnVsbCwidmVyaWZpZXJfaWRlbnRpdHkiOm51bGx9XSwicmVxdWlyZWQiOjEsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZWZmZWN0LWV2aWRlbmNlL3YxIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSJ9LCJpZGVudGl0eSI6eyJjb25maXJtZWQiOjEsImlkZW50aXR5X2NvbnRyYWN0X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJtYW5pZmVzdF9zaGEyNTYiOiIxMzVjODYzZWRjN2ZhYjE4Y2EyOWI0OTI5M2ZjMjVhMWM5YmQ0ZGUwZTllZDI4ZDRjZWM2ZThkMGE2NzkxMjI5IiwicmVxdWlyZWQiOjEsInJlc3VsdHMiOlt7Im1vZGUiOiJzdHJ1Y3R1cmVkIiwicmVzdWx0X2luZGV4IjowLCJzaWduYWxzIjpbXSwic3RhdHVzIjoidmVyaWZpZWQifV0sInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24taWRlbnRpdHktZXZpZGVuY2UvdjEiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIn0sInBvbGljeSI6eyJhZG1pc3Npb25fcG9saWN5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJlZmZlY3RfY29udHJhY3Rfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImVudmlyb25tZW50X2NvbnRyYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJlbnZpcm9ubWVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZ292ZXJuZWRfcG9saWN5X2NvbnRyYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJnb3Zlcm5lZF9ydW50aW1lX2lucHV0c19kaWdlc3QiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiaWRlbnRpdHlfY29udHJhY3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsIm1hbmlmZXN0X3NoYTI1NiI6IjRmOTg4ZDAxNWJjZDdjZDdlMDViYTA2NjNkODlmMGE5NjhmMGQ4YWNlOTliMDkwZWJhYmVlNTJhMWM1NTA0MjEiLCJtaW5pbXVtX2VmZmVjdF90aWVyIjoxLCJydW50aW1lX2Vudmlyb25tZW50X3NoYTI1NiI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLXBvbGljeS1ldmlkZW5jZS92MSJ9LCJwb3N0Y29uZGl0aW9uIjp7ImNvbmZpcm1lZCI6MCwibWFuaWZlc3Rfc2hhMjU2IjoiM2VhNGM2NGEzMGIwY2YxN2JjYTA0ZjMyNjBlMGE0NzE4YjI3ZjUxZTFmZGMyYmI4OGExODI2MzBhMzRkZDVmZiIsInJlY29yZHMiOlt7ImFjdGlvbl9raW5kIjoiY2xpY2siLCJhY3R1YXRpb25fcGF0aCI6Imd1aSIsImNvbnRyYWN0X2luZGV4IjowLCJjb250cmFjdF9raW5kIjoiZXhwbGljaXRfcHJlZGljYXRlIiwiY29udHJhY3Rfc2hhMjU2IjoiMGFkZTBiNTIwYmMwMDc4OTFjYWNjYTAwMTcxNTc4NDQyYTJhNzRjZWYxNWZmNjRkZGU0NWRmMDdhZmI2NGFlYiIsInJlc3VsdF9pbmRleCI6MCwic3RlcF9jb250cmFjdF9zaGEyNTYiOiIxYTU5NTM2YTQ4OGIxYzQ2YWFjZjBiYTM3OTMwYjg0MDYyYzE0Mjc1NWZhOTM5MTUyZWY1ZTI4YzQwOTQ3MWVkIiwic3RlcF9pbmRleCI6MCwidmVyZGljdCI6InVudmVyaWZpYWJsZSIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifV0sInJlcXVpcmVkIjoxLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLXBvc3Rjb25kaXRpb24tZXZpZGVuY2UvdjEiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIn19LCJldmlkZW5jZV9ydW5uZXJfc2lnbmVyX3NoYTI1NiI6IjU2NDc1YWE3NTQ2MzQ3NGMwMjg1ZGY1ZGJmMmJjYWI3M2RhNjUxMzU4ODM5ZTliNzc0ODFiMmVhYjEwNzcwOGMiLCJleGVjdXRpb25fYXV0aG9yaXR5X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA4IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaWduZXJfc2hhMjU2IjoiMjRmNmVkNmFjYmZlMTAwOWMwMzBkN2NhNTY3YzMzY2E0ODMwOTExNDk4MjM2YjU1NjFhNmM4MmFiZWM1ZGUyOCIsImV4ZWN1dGlvbl9vdXRjb21lIjp7ImNvbXBlbnNhdGlvbl9hY3Rpb25zIjowLCJldmlkZW5jZV9jbGFzc2VzIjpbImF1dGhvcml6YXRpb24iLCJpZGVudGl0eSJdLCJleGVjdXRpb25fY29tcGxldGVkIjpmYWxzZSwiZXh0ZXJuYWxfbmV0d29ya19jYWxscyI6Im5vbmUiLCJtb2RlbF9jYWxscyI6MCwib3V0Y29tZSI6IkhBTFRFRCIsInBhc3NlZF9jb250cmFjdHMiOnsiYXV0aG9yaXphdGlvbiI6MSwiZWZmZWN0IjowLCJpZGVudGl0eSI6MSwicG9zdGNvbmRpdGlvbiI6MH0sInBvc3Rjb25kaXRpb25fZXZpZGVuY2UiOlt7ImFjdGlvbl9raW5kIjoiY2xpY2siLCJhY3R1YXRpb25fcGF0aCI6Imd1aSIsImNvbnRyYWN0X2luZGV4IjowLCJjb250cmFjdF9raW5kIjoiZXhwbGljaXRfcHJlZGljYXRlIiwiY29udHJhY3Rfc2hhMjU2IjoiMGFkZTBiNTIwYmMwMDc4OTFjYWNjYTAwMTcxNTc4NDQyYTJhNzRjZWYxNWZmNjRkZGU0NWRmMDdhZmI2NGFlYiIsInJlc3VsdF9pbmRleCI6MCwic3RlcF9jb250cmFjdF9zaGEyNTYiOiIxYTU5NTM2YTQ4OGIxYzQ2YWFjZjBiYTM3OTMwYjg0MDYyYzE0Mjc1NWZhOTM5MTUyZWY1ZTI4YzQwOTQ3MWVkIiwic3RlcF9pbmRleCI6MCwidmVyZGljdCI6InVudmVyaWZpYWJsZSIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifV0sInByb2R1Y3Rpb25fZWxpZ2libGUiOmZhbHNlLCJwcm9maWxlIjoic3RhbmRhcmQiLCJxdWFsaWZpY2F0aW9uX2V2aWRlbmNlX29ubHkiOmZhbHNlLCJyZXF1aXJlZF9jb250cmFjdHMiOnsiYXV0aG9yaXphdGlvbiI6MSwiZWZmZWN0IjoxLCJpZGVudGl0eSI6MSwicG9zdGNvbmRpdGlvbiI6MX0sInZlcnNpb24iOiJvcGVuYWRhcHQuZXhlY3V0aW9uLW91dGNvbWUvdjEiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIn0sImV4ZWN1dGlvbl9vdXRjb21lX3NoYTI1NiI6ImZlMzg5YmFiMGViNDQ0N2NlYzE5OTgyNzRmNzI3Y2E1NzAwNDlmZWZkNTU3ZGI3OTkwNDc2OTlmMmY3OGYxNDIiLCJleGVjdXRpb25fcHVycG9zZSI6InByb2R1Y3Rpb24iLCJmaW5hbF9hdXRob3JpdHlfc2VxdWVuY2UiOjAsImZpbmFsX3J1bnRpbWVfZGVsaXZlcnlfc2VxdWVuY2UiOjksImZsb3dfcnVuX2lkX3NoYTI1NiI6IjExZTU5NGY0ODE5NThjMTBlMzAxNWQwYmYwNDQ3YTIyZjA2OGE4YTY0N2Y0NzVkZjE1Y2UyYzdhYjRiOGYzZjEiLCJpZGVudGl0eV9jb250cmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiaXNzdWVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowM1oiLCJwZXJtaXRfY2hhaW4iOnsiZW50cmllcyI6W3siZGVsaXZlcnlfcmVjZWlwdF9hcnRpZmFjdCI6eyJwYXlsb2FkIjp7ImF1dGhlbnRpY2F0ZWRfcnVubmVyX2lkX3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJhdXRoZW50aWNhdGVkX3Nlc3Npb25faWRfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsImRlbGl2ZXJlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDFaIiwiZXhlY3V0aW9uX2F1dGhvcml0eV9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOCIsIm9uZV91c2VfY2xhaW1faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMTAiLCJwZXJtaXRfYXJ0aWZhY3Rfc2hhMjU2IjoiOTcyYTgyYWY0NTZkYTU0MmJhYzc4NDYwMTg4OTY2ODg5MWQ4YjdjY2QyNDI5MDQ4MTZiMzI5MmUxNTdlNTI4OSIsInBlcm1pdF9pZCI6InBlcm1pdDoxIiwicnVudGltZV9kZWxpdmVyeV9zZXF1ZW5jZSI6OSwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1yZWNlaXB0LXBheWxvYWQvdjIifSwicGF5bG9hZF9zaGEyNTYiOiI4YThmNmQ4ODc1MGNiYjZiM2JkNjYyMDkzYWQyOWUyYmMyMGM2YWI2OTkxZDcwZTU4ODY5MWM4YjNhYjY2MmI5Iiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1yZWNlaXB0LWFydGlmYWN0L3YyIiwic2lnbmF0dXJlIjoiQU9LcUNnUzFzMFhhLWl5RTk2Vi15bFB6UWN2MnV2T3N1eWdIenZ1MlJ5VjdGTHNIRl9MVmZxeXg0dTJwdW1sRWwwWWs1WXU3MEpWVWtzWnBhVXBERHciLCJzaWduZXIiOnsiYWxnb3JpdGhtIjoiZWQyNTUxOSIsImtleV9pZCI6ImRlbGl2ZXJ5LWF1dGhvcml0eS1lZDI1NTE5LTI0ZjZlZDZhY2JmZTEwMDkiLCJwdWJsaWNfa2V5IjoiS2F5NjRVRzh5dkN5TGhxVTAwMEx4elllVW0wTC9oTElsNVM4a3lLV2JkYz0ifX0sImRlbGl2ZXJ5X3JlY2VpcHRfYXJ0aWZhY3Rfc2hhMjU2IjoiYzAwYTFiYTcwMTVmM2NiZTA1YTc2YWVhYmZmNjE5ZDc5M2U3Mzc1YTMxMGUxOTVmY2JiZDJkMjk0OGYyYjIxNCIsInBlcm1pdF9hcnRpZmFjdCI6eyJwYXlsb2FkIjp7ImFjdGlvbl9yZXF1ZXN0X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJhZG1pc3Npb25fYXJ0aWZhY3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsImF1dGhvcml0eV9zZXF1ZW5jZSI6MCwiZW52aXJvbm1lbnRfZGlnZXN0IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImV2aWRlbmNlX2lkZW50aXR5X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJleGVjdXRpb25fYXV0aG9yaXR5X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA4IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZmxvd19ydW5faWRfc2hhMjU2IjoiMTFlNTk0ZjQ4MTk1OGMxMGUzMDE1ZDBiZjA0NDdhMjJmMDY4YThhNjQ3ZjQ3NWRmMTVjZTJjN2FiNGI4ZjNmMSIsImlucHV0X2VkZ2Vfc2VxdWVuY2UiOjEsImlzc3VlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDBaIiwicGVybWl0X2lkIjoicGVybWl0OjEiLCJxdWFsaWZpY2F0aW9uX3NpZ25lcl9yZWdpc3RyeV9jaGVja2VkX2F0IjoiMjAyNi0wOC0xOFQxMTo1OTozMFoiLCJxdWFsaWZpY2F0aW9uX3NpZ25lcl9yZWdpc3RyeV9leHBpcmVzX2F0IjoiMjAyNi0wOC0yMFQxMTowMDowMFoiLCJxdWFsaWZpY2F0aW9uX3NpZ25lcl9yZWdpc3RyeV9yZXZpc2lvbiI6NywicXVhbGlmaWNhdGlvbl9zaWduZXJfcmVnaXN0cnlfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsInJ1bl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwMSIsInJ1bl9yZXF1ZXN0X3NoYTI1NiI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXBlcm1pdC1wYXlsb2FkL3YyIn0sInBheWxvYWRfc2hhMjU2IjoiYzg3ZjU3NTFhYTliMjc5Y2NlMjNhYTE3OGFmZjk1NmUxOWY2OTBmY2QyZjlmNzBlMGQ5OTk3ODJhNjkwZDZiOCIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcGVybWl0LWFydGlmYWN0L3YyIiwic2lnbmF0dXJlIjoiMEJ5SGdxRHhRWnJuZ0xJRi02dFpPcTlsWGFtY0FRQzBkb1VUbmVLTlBlUy1TeW9PYlF5T2tBdVBGSzVQWWNOek9iWnhnc2dBTGRXYUlfc2FVQ3BsQmciLCJzaWduZXIiOnsiYWxnb3JpdGhtIjoiZWQyNTUxOSIsImtleV9pZCI6ImRlbGl2ZXJ5LWF1dGhvcml0eS1lZDI1NTE5LTI0ZjZlZDZhY2JmZTEwMDkiLCJwdWJsaWNfa2V5IjoiS2F5NjRVRzh5dkN5TGhxVTAwMEx4elllVW0wTC9oTElsNVM4a3lLV2JkYz0ifX0sInBlcm1pdF9hcnRpZmFjdF9zaGEyNTYiOiI5NzJhODJhZjQ1NmRhNTQyYmFjNzg0NjAxODg5NjY4ODkxZDhiN2NjZDI0MjkwNDgxNmIzMjkyZTE1N2U1Mjg5Iiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1wZXJtaXQtY2hhaW4tZW50cnkvdjIifV0sInBlcm1pdF9jaGFpbl9zaGEyNTYiOiI1MDQ4ZmU5NDU4ODJkMjgwMjYwMDhkN2U5MTM3YWQwMTZmZGQwMWFlYWY1ODg0ODFmYjViZDBmMjQyYTUwMDQzIiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1wZXJtaXQtY2hhaW4vdjIifSwicGVybWl0X2NvdW50IjoxLCJxdWFsaWZpY2F0aW9uX3NpZ25lcl9yZWdpc3RyeV9yZXZpc2lvbiI6NywicXVhbGlmaWNhdGlvbl9zaWduZXJfcmVnaXN0cnlfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsInJ1bl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwMSIsInJ1bl9yZWNlaXB0Ijp7ImF1dGhvcml6YXRpb25fY29uZmlybWVkIjoxLCJhdXRob3JpemF0aW9uX3JlcXVpcmVkIjoxLCJidW5kbGVfZGlnZXN0IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImR1cmF0aW9uX21zIjoxMDAsImVmZmVjdF90aWVyX3JlYWNoZWQiOiJub25lIiwiZWZmZWN0c19jb25maXJtZWQiOjAsImVmZmVjdHNfcmVxdWlyZWQiOjEsImVzdF9jb3N0X21pY3JvdXNkIjowLCJldmlkZW5jZV9jbGFzc2VzIjpbImF1dGhvcml6YXRpb24iLCJpZGVudGl0eSJdLCJleHRlcm5hbF9uZXR3b3JrX2NhbGxzIjoibm9uZSIsImdlbmVyYXRlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDBaIiwiaGVhbHMiOjAsImlkZW50aXR5X2FwcGxpY2FibGUiOjEsImlkZW50aXR5X2FybWVkIjoxLCJpZGVudGl0eV9jb25maXJtZWQiOjEsImlkZW50aXR5X3JlcXVpcmVkIjoxLCJtb2RlbF9jYWxscyI6MCwib3V0Y29tZSI6IkhBTFRFRCIsIm92ZXJfaGFsdF9jb3VudCI6MCwicG9zdGNvbmRpdGlvbnNfY29uZmlybWVkIjowLCJwb3N0Y29uZGl0aW9uc19yZXF1aXJlZCI6MSwicHJvZHVjdGlvbl9lbGlnaWJsZSI6ZmFsc2UsInByb2ZpbGUiOiJzdGFuZGFyZCIsInByb3ZlbmFuY2UiOiJwcm9kdWN0aW9uIiwicmVjZWlwdF9idWlsZGVyX3ZlcnNpb24iOiIxLjIuMyIsInJ1bmdfaGlzdG9ncmFtIjp7fSwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1ydW4tcmVjZWlwdC92MSIsInNvdXJjZV9yZWNlaXB0X2RpZ2VzdCI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJzb3VyY2VfcmVjZWlwdF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwic291cmNlX3NjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnJ1bi1yZXBvcnQvdjEiLCJzdGVwc19vayI6MCwic3RlcHNfdG90YWwiOjEsInN1YnN0cmF0ZSI6IndlYiIsInRyYW5zYWN0aW9uX291dGNvbWUiOiJSRUNPTkNJTElBVElPTl9SRVFVSVJFRCJ9LCJydW5fcmVjZWlwdF9zaGEyNTYiOiIxOGViMmM0ZjQxNTNkYWIwNTNiZjAyN2MyNmY2OGFmYTA2MTMxN2UzYzJlN2Q1YTYwZWU1OGMzZWU2YjNkN2M2IiwicnVuX3JlcG9ydF9vYmplY3Rfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsInJ1bl9yZXBvcnRfb2JqZWN0X3ZlcnNpb24iOiJ2ZXJzaW9uOnJlY29uY2lsaWF0aW9uOjEiLCJydW5fcmVwb3J0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJydW50aW1lX2Vudmlyb25tZW50X3NoYTI1NiI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJydW50aW1lX3N1YnN0cmF0ZSI6IndlYiIsInJ1bnRpbWVfdmFsaWRhdGlvbl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwNSIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tdGVybWluYWwtdmVyaWZpY2F0aW9uL3YyIiwidGVuYW50X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAyIiwidGVybWluYWxfc2VxdWVuY2UiOjEsInZlcmlmaWVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMloiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwid29ya2Zsb3dfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDMiLCJ3b3JrZmxvd192ZXJzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA0In0sInNpZ25hdHVyZSI6Imd2ZHZuSlNPUzRWazg3M2k4eDBDMmE5MUE0Qm9WOFFvc05xdmMwaUVHMkJOOXpHOUlwamk5dXI1a0VpME5xdW5HVDdLVFZFczhfLUk2VG1TN21ERUJBIiwic2lnbmVyIjp7ImFsZ29yaXRobSI6ImVkMjU1MTkiLCJrZXlfaWQiOiJldmlkZW5jZS1ydW5uZXItZWQyNTUxOS01NjQ3NWFhNzU0NjM0NzRjIiwicHVibGljX2tleSI6IkE2RUh2L1BPRUw0ZGNOMFk1MHZBbVdmazFqQ2JwUTFmSGR5R1pCSlZNYmc9In19","name":"reconciliation-required-nonempty-permit","payload_canonical_sha256":"ef33d988e8895b431f8d06b134cac38fa0b6628b75c0fbe155e30ebb786bd8bf","signature":"gvdvnJSOS4Vk873i8x0C2a91A4BoV8QosNqvc0iEG2BN9zG9Ipji9ur5kEi0NqunGT7KTVEs8_-I6TmS7mDEBA","terminal_verification_artifact_sha256":"d4959d87ddb589221ddcddc6094bf42948c9357b51769239834815036fc36cad"}]} +{ + "key_id": "evidence-runner-ed25519-56475aa75463474c", + "private_key_base64": "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=", + "public_key_base64": "A6EHv/POEL4dcN0Y50vAmWfk1jCbpQ1fHdyGZBJVMbg=", + "schema_version": "openadapt.production-terminal-cross-language-vectors/v2", + "signature_domain_base64": "b3BlbmFkYXB0LXByb2R1Y3Rpb24tdGVybWluYWwtdmVyaWZpY2F0aW9uLXYyAA==", + "signer_sha256": "56475aa75463474c0285df5dbf2bcab73da651358839e9b77481b2eab107708c", + "vectors": [ + { + "callback": { + "artifact_bytes_source": "envelope_canonical_base64", + "outcome": "HALTED_BEFORE_EFFECT", + "report_sha256": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "run_id": "00000000-0000-4000-8000-000000000001", + "schema_version": "openadapt.hosted-runner-terminal/v1", + "started": true, + "uncertain_delivery": false + }, + "effect_state": { + "absence_basis": "not_actuated", + "attempt_state": "not_actuated", + "effect_contract_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "effect_verified": false, + "final_verdict": null, + "observed_effect": "absent", + "reconciliation_actions": 0, + "reconciliation_completed": false, + "record_kind": "terminal_effect_state", + "resolved_delivery_uncertainty": false, + "result_index": 0, + "verification_performed": false, + "verification_tier": null, + "verifier_identity": null + }, + "envelope_canonical_base64": "eyJwYXlsb2FkIjp7ImFja25vd2xlZGdlZF9wZXJtaXRfY291bnQiOjAsImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA2IiwiYWRtaXNzaW9uX3BvbGljeV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYWRtaXR0ZWRfcnVudGltZV9idWlsZF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiYnVuZGxlX2FydGlmYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJidW5kbGVfY29udGVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYnVuZGxlX3ZlcnNpb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDQiLCJlZmZlY3RfY29udHJhY3Rfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImVudmlyb25tZW50X2NvbnRyYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJlbnZpcm9ubWVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXZpZGVuY2VfaWRlbnRpdHlfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImV2aWRlbmNlX21hbmlmZXN0cyI6eyJhdXRob3JpemF0aW9uIjp7ImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA2IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOCIsImV4ZWN1dGlvbl9hdXRob3JpdHlfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImdvdmVybmVkX2F1dGhvcml6YXRpb25faWRfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsIm1hbmlmZXN0X3NoYTI1NiI6IjMyY2QzNjEzYmVlOWJjNjkwNjkzYTM5NWQ5OTMzNTQ3ZjllZWI5ZjZmYWE1ZGJkYmIxNGExMDYyOThiZTQ2NWMiLCJwZXJtaXRfY2hhaW5fc2hhMjU2IjoiODJkYWI1NDI4ZTI1MmQxOGE1OWIwMTc3NzM5ZTAwY2FhZGI3NjJkY2Y1OWY0MDM2ZGVhNGQ3N2MzYzMyMDNjYiIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tYXV0aG9yaXphdGlvbi1ldmlkZW5jZS92MSJ9LCJlZmZlY3QiOnsiY29uZmlybWVkIjowLCJlZmZlY3RfY29udHJhY3Rfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsIm1hbmlmZXN0X3NoYTI1NiI6ImViYjU4MzYxNzhlZGZhYzYyOWJkOWJjYTkwZWNkMDE5NTkwOTQ5NjZhMGRkNjNiYWVhN2E2MmY2ZTNiMDRmZjgiLCJyZWNvcmRzIjpbeyJhYnNlbmNlX2Jhc2lzIjoibm90X2FjdHVhdGVkIiwiYXR0ZW1wdF9zdGF0ZSI6Im5vdF9hY3R1YXRlZCIsImVmZmVjdF9jb250cmFjdF9oYXNoIjoic2hhMjU2OmFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJlZmZlY3RfdmVyaWZpZWQiOmZhbHNlLCJmaW5hbF92ZXJkaWN0IjpudWxsLCJvYnNlcnZlZF9lZmZlY3QiOiJhYnNlbnQiLCJyZWNvbmNpbGlhdGlvbl9hY3Rpb25zIjowLCJyZWNvbmNpbGlhdGlvbl9jb21wbGV0ZWQiOmZhbHNlLCJyZWNvcmRfa2luZCI6InRlcm1pbmFsX2VmZmVjdF9zdGF0ZSIsInJlc29sdmVkX2RlbGl2ZXJ5X3VuY2VydGFpbnR5IjpmYWxzZSwicmVzdWx0X2luZGV4IjowLCJ2ZXJpZmljYXRpb25fcGVyZm9ybWVkIjpmYWxzZSwidmVyaWZpY2F0aW9uX3RpZXIiOm51bGwsInZlcmlmaWVyX2lkZW50aXR5IjpudWxsfV0sInJlcXVpcmVkIjoxLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWVmZmVjdC1ldmlkZW5jZS92MSIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifSwiaWRlbnRpdHkiOnsiY29uZmlybWVkIjoxLCJpZGVudGl0eV9jb250cmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwibWFuaWZlc3Rfc2hhMjU2IjoiMTM1Yzg2M2VkYzdmYWIxOGNhMjliNDkyOTNmYzI1YTFjOWJkNGRlMGU5ZWQyOGQ0Y2VjNmU4ZDBhNjc5MTIyOSIsInJlcXVpcmVkIjoxLCJyZXN1bHRzIjpbeyJtb2RlIjoic3RydWN0dXJlZCIsInJlc3VsdF9pbmRleCI6MCwic2lnbmFscyI6W10sInN0YXR1cyI6InZlcmlmaWVkIn1dLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWlkZW50aXR5LWV2aWRlbmNlL3YxIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSJ9LCJwb2xpY3kiOnsiYWRtaXNzaW9uX3BvbGljeV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZWZmZWN0X2NvbnRyYWN0X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJlbnZpcm9ubWVudF9jb250cmFjdF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwiZW52aXJvbm1lbnRfZGlnZXN0IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImdvdmVybmVkX3BvbGljeV9jb250cmFjdF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwiZ292ZXJuZWRfcnVudGltZV9pbnB1dHNfZGlnZXN0IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsImlkZW50aXR5X2NvbnRyYWN0X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJtYW5pZmVzdF9zaGEyNTYiOiI0Zjk4OGQwMTViY2Q3Y2Q3ZTA1YmEwNjYzZDg5ZjBhOTY4ZjBkOGFjZTk5YjA5MGViYWJlZTUyYTFjNTUwNDIxIiwibWluaW11bV9lZmZlY3RfdGllciI6MSwicnVudGltZV9lbnZpcm9ubWVudF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1wb2xpY3ktZXZpZGVuY2UvdjEifSwicG9zdGNvbmRpdGlvbiI6eyJjb25maXJtZWQiOjAsIm1hbmlmZXN0X3NoYTI1NiI6IjNlYTRjNjRhMzBiMGNmMTdiY2EwNGYzMjYwZTBhNDcxOGIyN2Y1MWUxZmRjMmJiODhhMTgyNjMwYTM0ZGQ1ZmYiLCJyZWNvcmRzIjpbeyJhY3Rpb25fa2luZCI6ImNsaWNrIiwiYWN0dWF0aW9uX3BhdGgiOiJndWkiLCJjb250cmFjdF9pbmRleCI6MCwiY29udHJhY3Rfa2luZCI6ImV4cGxpY2l0X3ByZWRpY2F0ZSIsImNvbnRyYWN0X3NoYTI1NiI6IjBhZGUwYjUyMGJjMDA3ODkxY2FjY2EwMDE3MTU3ODQ0MmEyYTc0Y2VmMTVmZjY0ZGRlNDVkZjA3YWZiNjRhZWIiLCJyZXN1bHRfaW5kZXgiOjAsInN0ZXBfY29udHJhY3Rfc2hhMjU2IjoiMWE1OTUzNmE0ODhiMWM0NmFhY2YwYmEzNzkzMGI4NDA2MmMxNDI3NTVmYTkzOTE1MmVmNWUyOGM0MDk0NzFlZCIsInN0ZXBfaW5kZXgiOjAsInZlcmRpY3QiOiJ1bnZlcmlmaWFibGUiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIn1dLCJyZXF1aXJlZCI6MSwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1wb3N0Y29uZGl0aW9uLWV2aWRlbmNlL3YxIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSJ9fSwiZXZpZGVuY2VfcnVubmVyX3NpZ25lcl9zaGEyNTYiOiI1NjQ3NWFhNzU0NjM0NzRjMDI4NWRmNWRiZjJiY2FiNzNkYTY1MTM1ODgzOWU5Yjc3NDgxYjJlYWIxMDc3MDhjIiwiZXhlY3V0aW9uX2F1dGhvcml0eV9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOCIsImV4ZWN1dGlvbl9hdXRob3JpdHlfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImV4ZWN1dGlvbl9hdXRob3JpdHlfc2lnbmVyX3NoYTI1NiI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJleGVjdXRpb25fb3V0Y29tZSI6eyJjb21wZW5zYXRpb25fYWN0aW9ucyI6MCwiZXZpZGVuY2VfY2xhc3NlcyI6WyJhdXRob3JpemF0aW9uIiwiaWRlbnRpdHkiXSwiZXhlY3V0aW9uX2NvbXBsZXRlZCI6ZmFsc2UsImV4dGVybmFsX25ldHdvcmtfY2FsbHMiOiJub25lIiwibW9kZWxfY2FsbHMiOjAsIm91dGNvbWUiOiJIQUxURUQiLCJwYXNzZWRfY29udHJhY3RzIjp7ImF1dGhvcml6YXRpb24iOjEsImVmZmVjdCI6MCwiaWRlbnRpdHkiOjEsInBvc3Rjb25kaXRpb24iOjB9LCJwb3N0Y29uZGl0aW9uX2V2aWRlbmNlIjpbeyJhY3Rpb25fa2luZCI6ImNsaWNrIiwiYWN0dWF0aW9uX3BhdGgiOiJndWkiLCJjb250cmFjdF9pbmRleCI6MCwiY29udHJhY3Rfa2luZCI6ImV4cGxpY2l0X3ByZWRpY2F0ZSIsImNvbnRyYWN0X3NoYTI1NiI6IjBhZGUwYjUyMGJjMDA3ODkxY2FjY2EwMDE3MTU3ODQ0MmEyYTc0Y2VmMTVmZjY0ZGRlNDVkZjA3YWZiNjRhZWIiLCJyZXN1bHRfaW5kZXgiOjAsInN0ZXBfY29udHJhY3Rfc2hhMjU2IjoiMWE1OTUzNmE0ODhiMWM0NmFhY2YwYmEzNzkzMGI4NDA2MmMxNDI3NTVmYTkzOTE1MmVmNWUyOGM0MDk0NzFlZCIsInN0ZXBfaW5kZXgiOjAsInZlcmRpY3QiOiJ1bnZlcmlmaWFibGUiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIn1dLCJwcm9kdWN0aW9uX2VsaWdpYmxlIjpmYWxzZSwicHJvZmlsZSI6InN0YW5kYXJkIiwicXVhbGlmaWNhdGlvbl9ldmlkZW5jZV9vbmx5IjpmYWxzZSwicmVxdWlyZWRfY29udHJhY3RzIjp7ImF1dGhvcml6YXRpb24iOjEsImVmZmVjdCI6MSwiaWRlbnRpdHkiOjEsInBvc3Rjb25kaXRpb24iOjF9LCJ2ZXJzaW9uIjoib3BlbmFkYXB0LmV4ZWN1dGlvbi1vdXRjb21lL3YxIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSJ9LCJleGVjdXRpb25fb3V0Y29tZV9zaGEyNTYiOiJmZTM4OWJhYjBlYjQ0NDdjZWMxOTk4Mjc0ZjcyN2NhNTcwMDQ5ZmVmZDU1N2RiNzk5MDQ3Njk5ZjJmNzhmMTQyIiwiZXhlY3V0aW9uX3B1cnBvc2UiOiJwcm9kdWN0aW9uIiwiZmluYWxfYXV0aG9yaXR5X3NlcXVlbmNlIjowLCJmaW5hbF9ydW50aW1lX2RlbGl2ZXJ5X3NlcXVlbmNlIjowLCJmbG93X3J1bl9pZF9zaGEyNTYiOiIxMWU1OTRmNDgxOTU4YzEwZTMwMTVkMGJmMDQ0N2EyMmYwNjhhOGE2NDdmNDc1ZGYxNWNlMmM3YWI0YjhmM2YxIiwiaWRlbnRpdHlfY29udHJhY3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsImlzc3VlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDNaIiwicGVuZGluZ19wZXJtaXRfY291bnQiOjAsInBlcm1pdF9jaGFpbiI6eyJlbnRyaWVzIjpbXSwicGVybWl0X2NoYWluX3NoYTI1NiI6IjgyZGFiNTQyOGUyNTJkMThhNTliMDE3NzczOWUwMGNhYWRiNzYyZGNmNTlmNDAzNmRlYTRkNzdjM2MzMjAzY2IiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXBlcm1pdC1jaGFpbi92MiJ9LCJwZXJtaXRfY291bnQiOjAsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X3JldmlzaW9uIjo3LCJxdWFsaWZpY2F0aW9uX3NpZ25lcl9yZWdpc3RyeV9zaGEyNTYiOiJlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlIiwicnVuX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAxIiwicnVuX3JlY2VpcHQiOnsiYXV0aG9yaXphdGlvbl9jb25maXJtZWQiOjEsImF1dGhvcml6YXRpb25fcmVxdWlyZWQiOjEsImJ1bmRsZV9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZHVyYXRpb25fbXMiOjEwMCwiZWZmZWN0X3RpZXJfcmVhY2hlZCI6Im5vbmUiLCJlZmZlY3RzX2NvbmZpcm1lZCI6MCwiZWZmZWN0c19yZXF1aXJlZCI6MSwiZXN0X2Nvc3RfbWljcm91c2QiOjAsImV2aWRlbmNlX2NsYXNzZXMiOlsiYXV0aG9yaXphdGlvbiIsImlkZW50aXR5Il0sImV4dGVybmFsX25ldHdvcmtfY2FsbHMiOiJub25lIiwiZ2VuZXJhdGVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMFoiLCJoZWFscyI6MCwiaWRlbnRpdHlfYXBwbGljYWJsZSI6MSwiaWRlbnRpdHlfYXJtZWQiOjEsImlkZW50aXR5X2NvbmZpcm1lZCI6MSwiaWRlbnRpdHlfcmVxdWlyZWQiOjEsIm1vZGVsX2NhbGxzIjowLCJvdXRjb21lIjoiSEFMVEVEIiwib3Zlcl9oYWx0X2NvdW50IjowLCJwb3N0Y29uZGl0aW9uc19jb25maXJtZWQiOjAsInBvc3Rjb25kaXRpb25zX3JlcXVpcmVkIjoxLCJwcm9kdWN0aW9uX2VsaWdpYmxlIjpmYWxzZSwicHJvZmlsZSI6InN0YW5kYXJkIiwicHJvdmVuYW5jZSI6InByb2R1Y3Rpb24iLCJyZWNlaXB0X2J1aWxkZXJfdmVyc2lvbiI6IjEuMi4zIiwicnVuZ19oaXN0b2dyYW0iOnt9LCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLXJ1bi1yZWNlaXB0L3YxIiwic291cmNlX3JlY2VpcHRfZGlnZXN0IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsInNvdXJjZV9yZWNlaXB0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJzb3VyY2Vfc2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucnVuLXJlcG9ydC92MSIsInN0ZXBzX29rIjowLCJzdGVwc190b3RhbCI6MSwic3Vic3RyYXRlIjoid2ViIiwidHJhbnNhY3Rpb25fb3V0Y29tZSI6IkhBTFRFRF9CRUZPUkVfRUZGRUNUIn0sInJ1bl9yZWNlaXB0X3NoYTI1NiI6ImFiNTBhMDA2YTg4OGIzZjkwZTFlNzFlZjIwOTIxYWY3MTdiMmY0MWEzNjc2ZTYwNWZiZGI4MjBjYjZiNTNjYzQiLCJydW5fcmVwb3J0X29iamVjdF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwicnVuX3JlcG9ydF9vYmplY3RfdmVyc2lvbiI6InZlcnNpb246aGFsdGVkOjEiLCJydW5fcmVwb3J0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJydW50aW1lX2Vudmlyb25tZW50X3NoYTI1NiI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJydW50aW1lX3N1YnN0cmF0ZSI6IndlYiIsInJ1bnRpbWVfdmFsaWRhdGlvbl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwNSIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tdGVybWluYWwtdmVyaWZpY2F0aW9uL3YyIiwidGVuYW50X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAyIiwidGVybWluYWxfc2VxdWVuY2UiOjEsInZlcmlmaWVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMloiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwid29ya2Zsb3dfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDMiLCJ3b3JrZmxvd192ZXJzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA0In0sInNpZ25hdHVyZSI6IktHQzRqQllpN01ReVlkbFV5TnJ5bGowcmwxaUVNbUFFeHQwUmlxWjV2bGh0Y1lWQzVJOEY1RDZ2V0NkRVlnb09takZNOU5UNjZmVW95ODVsYlFOQkRnIiwic2lnbmVyIjp7ImFsZ29yaXRobSI6ImVkMjU1MTkiLCJrZXlfaWQiOiJldmlkZW5jZS1ydW5uZXItZWQyNTUxOS01NjQ3NWFhNzU0NjM0NzRjIiwicHVibGljX2tleSI6IkE2RUh2L1BPRUw0ZGNOMFk1MHZBbVdmazFqQ2JwUTFmSGR5R1pCSlZNYmc9In19", + "name": "halted-before-effect-zero-permit", + "payload_canonical_sha256": "a2909800fffc776ac70a5f6beb77b7c9941a91e7e2930eb20d9042210dc66001", + "signature": "KGC4jBYi7MQyYdlUyNrylj0rl1iEMmAExt0RiqZ5vlhtcYVC5I8F5D6vWCdEYgoOmjFM9NT66fUoy85lbQNBDg", + "terminal_verification_artifact_sha256": "ef25997f54fdd08ba6cd49533bf23735c35bbac86d195cff19a0df087f82e4d8" + }, + { + "callback": { + "artifact_bytes_source": "envelope_canonical_base64", + "outcome": "RECONCILIATION_REQUIRED", + "report_sha256": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "run_id": "00000000-0000-4000-8000-000000000001", + "schema_version": "openadapt.hosted-runner-terminal/v1", + "started": true, + "uncertain_delivery": true + }, + "effect_state": { + "absence_basis": "none", + "attempt_state": "delivery_uncertain", + "effect_contract_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "effect_verified": false, + "final_verdict": null, + "observed_effect": "unknown", + "reconciliation_actions": 0, + "reconciliation_completed": false, + "record_kind": "terminal_effect_state", + "resolved_delivery_uncertainty": false, + "result_index": 0, + "verification_performed": false, + "verification_tier": null, + "verifier_identity": null + }, + "envelope_canonical_base64": "eyJwYXlsb2FkIjp7ImFja25vd2xlZGdlZF9wZXJtaXRfY291bnQiOjAsImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA2IiwiYWRtaXNzaW9uX3BvbGljeV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYWRtaXR0ZWRfcnVudGltZV9idWlsZF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiYnVuZGxlX2FydGlmYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJidW5kbGVfY29udGVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYnVuZGxlX3ZlcnNpb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDQiLCJlZmZlY3RfY29udHJhY3Rfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImVudmlyb25tZW50X2NvbnRyYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJlbnZpcm9ubWVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXZpZGVuY2VfaWRlbnRpdHlfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImV2aWRlbmNlX21hbmlmZXN0cyI6eyJhdXRob3JpemF0aW9uIjp7ImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA2IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOCIsImV4ZWN1dGlvbl9hdXRob3JpdHlfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImdvdmVybmVkX2F1dGhvcml6YXRpb25faWRfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsIm1hbmlmZXN0X3NoYTI1NiI6IjE1YzBlNzZkYzJlMzIxYTM4NGU1M2VjMTVmZjUzZTc1NTU3YjdjZGU3MWM1YWQyYmEyYjkzZmYyZTk1ODM1YTUiLCJwZXJtaXRfY2hhaW5fc2hhMjU2IjoiNTliMzk5NzFlMzA1MTA5YzU0Mjk5NDVhNWZhYjQ2NjBiMDlmNDFlN2FjM2ZmZDkyZTM1MDZhZjAwMzM3ZGE5NSIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tYXV0aG9yaXphdGlvbi1ldmlkZW5jZS92MSJ9LCJlZmZlY3QiOnsiY29uZmlybWVkIjowLCJlZmZlY3RfY29udHJhY3Rfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsIm1hbmlmZXN0X3NoYTI1NiI6ImFmMTUwOWNjMmU5ZmExZjViOGI4MTVlN2IxZjYwNDYxOWIyYTM1ZWMwZGU1ZTBkMzRiYmZhNjdjYzkxZGJiYzciLCJyZWNvcmRzIjpbeyJhYnNlbmNlX2Jhc2lzIjoibm9uZSIsImF0dGVtcHRfc3RhdGUiOiJkZWxpdmVyeV91bmNlcnRhaW4iLCJlZmZlY3RfY29udHJhY3RfaGFzaCI6InNoYTI1NjphYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZWZmZWN0X3ZlcmlmaWVkIjpmYWxzZSwiZmluYWxfdmVyZGljdCI6bnVsbCwib2JzZXJ2ZWRfZWZmZWN0IjoidW5rbm93biIsInJlY29uY2lsaWF0aW9uX2FjdGlvbnMiOjAsInJlY29uY2lsaWF0aW9uX2NvbXBsZXRlZCI6ZmFsc2UsInJlY29yZF9raW5kIjoidGVybWluYWxfZWZmZWN0X3N0YXRlIiwicmVzb2x2ZWRfZGVsaXZlcnlfdW5jZXJ0YWludHkiOmZhbHNlLCJyZXN1bHRfaW5kZXgiOjAsInZlcmlmaWNhdGlvbl9wZXJmb3JtZWQiOmZhbHNlLCJ2ZXJpZmljYXRpb25fdGllciI6bnVsbCwidmVyaWZpZXJfaWRlbnRpdHkiOm51bGx9XSwicmVxdWlyZWQiOjEsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZWZmZWN0LWV2aWRlbmNlL3YxIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSJ9LCJpZGVudGl0eSI6eyJjb25maXJtZWQiOjEsImlkZW50aXR5X2NvbnRyYWN0X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJtYW5pZmVzdF9zaGEyNTYiOiIxMzVjODYzZWRjN2ZhYjE4Y2EyOWI0OTI5M2ZjMjVhMWM5YmQ0ZGUwZTllZDI4ZDRjZWM2ZThkMGE2NzkxMjI5IiwicmVxdWlyZWQiOjEsInJlc3VsdHMiOlt7Im1vZGUiOiJzdHJ1Y3R1cmVkIiwicmVzdWx0X2luZGV4IjowLCJzaWduYWxzIjpbXSwic3RhdHVzIjoidmVyaWZpZWQifV0sInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24taWRlbnRpdHktZXZpZGVuY2UvdjEiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIn0sInBvbGljeSI6eyJhZG1pc3Npb25fcG9saWN5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJlZmZlY3RfY29udHJhY3Rfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImVudmlyb25tZW50X2NvbnRyYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJlbnZpcm9ubWVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZ292ZXJuZWRfcG9saWN5X2NvbnRyYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJnb3Zlcm5lZF9ydW50aW1lX2lucHV0c19kaWdlc3QiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiaWRlbnRpdHlfY29udHJhY3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsIm1hbmlmZXN0X3NoYTI1NiI6IjRmOTg4ZDAxNWJjZDdjZDdlMDViYTA2NjNkODlmMGE5NjhmMGQ4YWNlOTliMDkwZWJhYmVlNTJhMWM1NTA0MjEiLCJtaW5pbXVtX2VmZmVjdF90aWVyIjoxLCJydW50aW1lX2Vudmlyb25tZW50X3NoYTI1NiI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLXBvbGljeS1ldmlkZW5jZS92MSJ9LCJwb3N0Y29uZGl0aW9uIjp7ImNvbmZpcm1lZCI6MCwibWFuaWZlc3Rfc2hhMjU2IjoiM2VhNGM2NGEzMGIwY2YxN2JjYTA0ZjMyNjBlMGE0NzE4YjI3ZjUxZTFmZGMyYmI4OGExODI2MzBhMzRkZDVmZiIsInJlY29yZHMiOlt7ImFjdGlvbl9raW5kIjoiY2xpY2siLCJhY3R1YXRpb25fcGF0aCI6Imd1aSIsImNvbnRyYWN0X2luZGV4IjowLCJjb250cmFjdF9raW5kIjoiZXhwbGljaXRfcHJlZGljYXRlIiwiY29udHJhY3Rfc2hhMjU2IjoiMGFkZTBiNTIwYmMwMDc4OTFjYWNjYTAwMTcxNTc4NDQyYTJhNzRjZWYxNWZmNjRkZGU0NWRmMDdhZmI2NGFlYiIsInJlc3VsdF9pbmRleCI6MCwic3RlcF9jb250cmFjdF9zaGEyNTYiOiIxYTU5NTM2YTQ4OGIxYzQ2YWFjZjBiYTM3OTMwYjg0MDYyYzE0Mjc1NWZhOTM5MTUyZWY1ZTI4YzQwOTQ3MWVkIiwic3RlcF9pbmRleCI6MCwidmVyZGljdCI6InVudmVyaWZpYWJsZSIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifV0sInJlcXVpcmVkIjoxLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLXBvc3Rjb25kaXRpb24tZXZpZGVuY2UvdjEiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIn19LCJldmlkZW5jZV9ydW5uZXJfc2lnbmVyX3NoYTI1NiI6IjU2NDc1YWE3NTQ2MzQ3NGMwMjg1ZGY1ZGJmMmJjYWI3M2RhNjUxMzU4ODM5ZTliNzc0ODFiMmVhYjEwNzcwOGMiLCJleGVjdXRpb25fYXV0aG9yaXR5X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA4IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaWduZXJfc2hhMjU2IjoiMjRmNmVkNmFjYmZlMTAwOWMwMzBkN2NhNTY3YzMzY2E0ODMwOTExNDk4MjM2YjU1NjFhNmM4MmFiZWM1ZGUyOCIsImV4ZWN1dGlvbl9vdXRjb21lIjp7ImNvbXBlbnNhdGlvbl9hY3Rpb25zIjowLCJldmlkZW5jZV9jbGFzc2VzIjpbImF1dGhvcml6YXRpb24iLCJpZGVudGl0eSJdLCJleGVjdXRpb25fY29tcGxldGVkIjpmYWxzZSwiZXh0ZXJuYWxfbmV0d29ya19jYWxscyI6Im5vbmUiLCJtb2RlbF9jYWxscyI6MCwib3V0Y29tZSI6IkhBTFRFRCIsInBhc3NlZF9jb250cmFjdHMiOnsiYXV0aG9yaXphdGlvbiI6MSwiZWZmZWN0IjowLCJpZGVudGl0eSI6MSwicG9zdGNvbmRpdGlvbiI6MH0sInBvc3Rjb25kaXRpb25fZXZpZGVuY2UiOlt7ImFjdGlvbl9raW5kIjoiY2xpY2siLCJhY3R1YXRpb25fcGF0aCI6Imd1aSIsImNvbnRyYWN0X2luZGV4IjowLCJjb250cmFjdF9raW5kIjoiZXhwbGljaXRfcHJlZGljYXRlIiwiY29udHJhY3Rfc2hhMjU2IjoiMGFkZTBiNTIwYmMwMDc4OTFjYWNjYTAwMTcxNTc4NDQyYTJhNzRjZWYxNWZmNjRkZGU0NWRmMDdhZmI2NGFlYiIsInJlc3VsdF9pbmRleCI6MCwic3RlcF9jb250cmFjdF9zaGEyNTYiOiIxYTU5NTM2YTQ4OGIxYzQ2YWFjZjBiYTM3OTMwYjg0MDYyYzE0Mjc1NWZhOTM5MTUyZWY1ZTI4YzQwOTQ3MWVkIiwic3RlcF9pbmRleCI6MCwidmVyZGljdCI6InVudmVyaWZpYWJsZSIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifV0sInByb2R1Y3Rpb25fZWxpZ2libGUiOmZhbHNlLCJwcm9maWxlIjoic3RhbmRhcmQiLCJxdWFsaWZpY2F0aW9uX2V2aWRlbmNlX29ubHkiOmZhbHNlLCJyZXF1aXJlZF9jb250cmFjdHMiOnsiYXV0aG9yaXphdGlvbiI6MSwiZWZmZWN0IjoxLCJpZGVudGl0eSI6MSwicG9zdGNvbmRpdGlvbiI6MX0sInZlcnNpb24iOiJvcGVuYWRhcHQuZXhlY3V0aW9uLW91dGNvbWUvdjEiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIn0sImV4ZWN1dGlvbl9vdXRjb21lX3NoYTI1NiI6ImZlMzg5YmFiMGViNDQ0N2NlYzE5OTgyNzRmNzI3Y2E1NzAwNDlmZWZkNTU3ZGI3OTkwNDc2OTlmMmY3OGYxNDIiLCJleGVjdXRpb25fcHVycG9zZSI6InByb2R1Y3Rpb24iLCJmaW5hbF9hdXRob3JpdHlfc2VxdWVuY2UiOjAsImZpbmFsX3J1bnRpbWVfZGVsaXZlcnlfc2VxdWVuY2UiOjAsImZsb3dfcnVuX2lkX3NoYTI1NiI6IjExZTU5NGY0ODE5NThjMTBlMzAxNWQwYmYwNDQ3YTIyZjA2OGE4YTY0N2Y0NzVkZjE1Y2UyYzdhYjRiOGYzZjEiLCJpZGVudGl0eV9jb250cmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiaXNzdWVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowM1oiLCJwZW5kaW5nX3Blcm1pdF9jb3VudCI6MSwicGVybWl0X2NoYWluIjp7ImVudHJpZXMiOltdLCJwZW5kaW5nIjp7ImFjdHVhdGlvbl9yZXBsYXlfYXV0aG9yaXplZCI6ZmFsc2UsImRlbGl2ZXJ5X3JlY2VpcHRfYXJ0aWZhY3QiOm51bGwsImRlbGl2ZXJ5X3JlY2VpcHRfYXJ0aWZhY3Rfc2hhMjU2IjpudWxsLCJkZWxpdmVyeV9zdGF0ZSI6IlVOUkVTT0xWRUQiLCJwZXJtaXRfYXJ0aWZhY3QiOnsicGF5bG9hZCI6eyJhY3Rpb25fcmVxdWVzdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2FydGlmYWN0X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJhdXRob3JpdHlfc2VxdWVuY2UiOjAsImVudmlyb25tZW50X2RpZ2VzdCI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJldmlkZW5jZV9pZGVudGl0eV9zaGEyNTYiOiJlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlIiwiZXhlY3V0aW9uX2F1dGhvcml0eV9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOCIsImV4ZWN1dGlvbl9hdXRob3JpdHlfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImZsb3dfcnVuX2lkX3NoYTI1NiI6IjExZTU5NGY0ODE5NThjMTBlMzAxNWQwYmYwNDQ3YTIyZjA2OGE4YTY0N2Y0NzVkZjE1Y2UyYzdhYjRiOGYzZjEiLCJpbnB1dF9lZGdlX3NlcXVlbmNlIjoxLCJpc3N1ZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAwWiIsInBlcm1pdF9pZCI6InBlcm1pdDoxIiwicXVhbGlmaWNhdGlvbl9zaWduZXJfcmVnaXN0cnlfY2hlY2tlZF9hdCI6IjIwMjYtMDgtMThUMTE6NTk6MzBaIiwicXVhbGlmaWNhdGlvbl9zaWduZXJfcmVnaXN0cnlfZXhwaXJlc19hdCI6IjIwMjYtMDgtMjBUMTE6MDA6MDBaIiwicXVhbGlmaWNhdGlvbl9zaWduZXJfcmVnaXN0cnlfcmV2aXNpb24iOjcsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJydW5faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDEiLCJydW5fcmVxdWVzdF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1wZXJtaXQtcGF5bG9hZC92MiJ9LCJwYXlsb2FkX3NoYTI1NiI6ImM4N2Y1NzUxYWE5YjI3OWNjZTIzYWExNzhhZmY5NTZlMTlmNjkwZmNkMmY5ZjcwZTBkOTk5NzgyYTY5MGQ2YjgiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXBlcm1pdC1hcnRpZmFjdC92MiIsInNpZ25hdHVyZSI6IjBCeUhncUR4UVpybmdMSUYtNnRaT3E5bFhhbWNBUUMwZG9VVG5lS05QZVMtU3lvT2JReU9rQXVQRks1UFljTnpPYlp4Z3NnQUxkV2FJX3NhVUNwbEJnIiwic2lnbmVyIjp7ImFsZ29yaXRobSI6ImVkMjU1MTkiLCJrZXlfaWQiOiJkZWxpdmVyeS1hdXRob3JpdHktZWQyNTUxOS0yNGY2ZWQ2YWNiZmUxMDA5IiwicHVibGljX2tleSI6IktheTY0VUc4eXZDeUxocVUwMDBMeHpZZVVtMEwvaExJbDVTOGt5S1diZGM9In19LCJwZXJtaXRfYXJ0aWZhY3Rfc2hhMjU2IjoiOTcyYTgyYWY0NTZkYTU0MmJhYzc4NDYwMTg4OTY2ODg5MWQ4YjdjY2QyNDI5MDQ4MTZiMzI5MmUxNTdlNTI4OSIsInJlY2VpcHRfYWJzZW5jZV9vYnNlcnZlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDJaIiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1wZW5kaW5nLXBlcm1pdC92MiJ9LCJwZXJtaXRfY2hhaW5fc2hhMjU2IjoiNTliMzk5NzFlMzA1MTA5YzU0Mjk5NDVhNWZhYjQ2NjBiMDlmNDFlN2FjM2ZmZDkyZTM1MDZhZjAwMzM3ZGE5NSIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcGVybWl0LWNoYWluL3YyIn0sInBlcm1pdF9jb3VudCI6MSwicXVhbGlmaWNhdGlvbl9zaWduZXJfcmVnaXN0cnlfcmV2aXNpb24iOjcsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJydW5faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDEiLCJydW5fcmVjZWlwdCI6eyJhdXRob3JpemF0aW9uX2NvbmZpcm1lZCI6MSwiYXV0aG9yaXphdGlvbl9yZXF1aXJlZCI6MSwiYnVuZGxlX2RpZ2VzdCI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJkdXJhdGlvbl9tcyI6MTAwLCJlZmZlY3RfdGllcl9yZWFjaGVkIjoibm9uZSIsImVmZmVjdHNfY29uZmlybWVkIjowLCJlZmZlY3RzX3JlcXVpcmVkIjoxLCJlc3RfY29zdF9taWNyb3VzZCI6MCwiZXZpZGVuY2VfY2xhc3NlcyI6WyJhdXRob3JpemF0aW9uIiwiaWRlbnRpdHkiXSwiZXh0ZXJuYWxfbmV0d29ya19jYWxscyI6Im5vbmUiLCJnZW5lcmF0ZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAwWiIsImhlYWxzIjowLCJpZGVudGl0eV9hcHBsaWNhYmxlIjoxLCJpZGVudGl0eV9hcm1lZCI6MSwiaWRlbnRpdHlfY29uZmlybWVkIjoxLCJpZGVudGl0eV9yZXF1aXJlZCI6MSwibW9kZWxfY2FsbHMiOjAsIm91dGNvbWUiOiJIQUxURUQiLCJvdmVyX2hhbHRfY291bnQiOjAsInBvc3Rjb25kaXRpb25zX2NvbmZpcm1lZCI6MCwicG9zdGNvbmRpdGlvbnNfcmVxdWlyZWQiOjEsInByb2R1Y3Rpb25fZWxpZ2libGUiOmZhbHNlLCJwcm9maWxlIjoic3RhbmRhcmQiLCJwcm92ZW5hbmNlIjoicHJvZHVjdGlvbiIsInJlY2VpcHRfYnVpbGRlcl92ZXJzaW9uIjoiMS4yLjMiLCJydW5nX2hpc3RvZ3JhbSI6e30sInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tcnVuLXJlY2VpcHQvdjEiLCJzb3VyY2VfcmVjZWlwdF9kaWdlc3QiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwic291cmNlX3JlY2VpcHRfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsInNvdXJjZV9zY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5ydW4tcmVwb3J0L3YxIiwic3RlcHNfb2siOjAsInN0ZXBzX3RvdGFsIjoxLCJzdWJzdHJhdGUiOiJ3ZWIiLCJ0cmFuc2FjdGlvbl9vdXRjb21lIjoiUkVDT05DSUxJQVRJT05fUkVRVUlSRUQifSwicnVuX3JlY2VpcHRfc2hhMjU2IjoiMThlYjJjNGY0MTUzZGFiMDUzYmYwMjdjMjZmNjhhZmEwNjEzMTdlM2MyZTdkNWE2MGVlNThjM2VlNmIzZDdjNiIsInJ1bl9yZXBvcnRfb2JqZWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJydW5fcmVwb3J0X29iamVjdF92ZXJzaW9uIjoidmVyc2lvbjpyZWNvbmNpbGlhdGlvbjoxIiwicnVuX3JlcG9ydF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwicnVudGltZV9lbnZpcm9ubWVudF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwicnVudGltZV9zdWJzdHJhdGUiOiJ3ZWIiLCJydW50aW1lX3ZhbGlkYXRpb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDUiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLXRlcm1pbmFsLXZlcmlmaWNhdGlvbi92MiIsInRlbmFudF9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwMiIsInRlcm1pbmFsX3NlcXVlbmNlIjoxLCJ2ZXJpZmllZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDJaIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsIndvcmtmbG93X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAzIiwid29ya2Zsb3dfdmVyc2lvbl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwNCJ9LCJzaWduYXR1cmUiOiJkRUdXZ0NDTGZGTm1QNnV5X0JuZ1dZUHJnel9ScmpYeFVULUpkSEwzaTNEclZSTnJ6OWJsWlpzbTBRQXo2cWVHTy1UZkhHT2FLMTVTdUc2ZlIwRGpCdyIsInNpZ25lciI6eyJhbGdvcml0aG0iOiJlZDI1NTE5Iiwia2V5X2lkIjoiZXZpZGVuY2UtcnVubmVyLWVkMjU1MTktNTY0NzVhYTc1NDYzNDc0YyIsInB1YmxpY19rZXkiOiJBNkVIdi9QT0VMNGRjTjBZNTB2QW1XZmsxakNicFExZkhkeUdaQkpWTWJnPSJ9fQ==", + "name": "reconciliation-required-pending-permit", + "payload_canonical_sha256": "2f2af3926539d2bde7a12888bddbdc26aa3193818b82a01743a100d5181581b0", + "signature": "dEGWgCCLfFNmP6uy_BngWYPrgz_RrjXxUT-JdHL3i3DrVRNrz9blZZsm0QAz6qeGO-TfHGOaK15SuG6fR0DjBw", + "terminal_verification_artifact_sha256": "2abcc6c65e0288a235b901169415d59632c8eaacf9b1aac087b1bb0d55ced624" + } + ] +} diff --git a/tests/test_durable_authority_v13.py b/tests/test_durable_authority_v13.py index 0db17584..6fdaaad9 100644 --- a/tests/test_durable_authority_v13.py +++ b/tests/test_durable_authority_v13.py @@ -527,6 +527,22 @@ def test_v2_permit_remains_pending_until_signed_receipt_commits_edge( with pytest.raises(DurableAuthorityBusy, match="remains uncertain"): authority.production_delivery_permit_chain(allow_empty=True) + pending_chain = authority.production_delivery_permit_chain( + allow_pending=True, + receipt_absence_observed_at="2026-08-20T00:00:30Z", + ) + assert pending_chain.entries == () + assert pending_chain.pending is not None + assert pending_chain.pending.permit_artifact == permit.permit_artifact + assert pending_chain.pending.delivery_state == "UNRESOLVED" + assert pending_chain.pending.delivery_receipt_artifact is None + assert pending_chain.pending.delivery_receipt_artifact_sha256 is None + assert pending_chain.pending.actuation_replay_authorized is False + assert pending_chain.pending.receipt_absence_observed_at == ("2026-08-20T00:00:30Z") + assert authority.validate(manifest).delivery_sequence == 0 + with pytest.raises(DurableAuthorityBusy, match="lacks an acknowledgment"): + authority.before_initial_delivery(manifest) + entry = authority.acknowledge_remote_delivery(manifest, permit) assert authority.validate(manifest).delivery_sequence == 1 diff --git a/tests/test_hosted_runner_adapter.py b/tests/test_hosted_runner_adapter.py index 1debe264..11de044f 100644 --- a/tests/test_hosted_runner_adapter.py +++ b/tests/test_hosted_runner_adapter.py @@ -12,6 +12,7 @@ import pytest from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey +from pydantic import ValidationError import openadapt_flow.runner.hosted_adapter as hosted from openadapt_flow.__main__ import _replay_params @@ -751,16 +752,13 @@ def verify_release(*_args): dispatch.delivery_authority_token, ) - first = adapter.execute( - dispatch, - runner_config=tmp_path / "runner.toml", - run_dir=tmp_path / "run", - authority=authority, - ) - - assert first.outcome is TransactionOutcome.RECONCILIATION_REQUIRED - assert first.started is True - assert first.terminal_verification is None + with pytest.raises(RuntimeError, match="signed terminal reconciliation"): + adapter.execute( + dispatch, + runner_config=tmp_path / "runner.toml", + run_dir=tmp_path / "run", + authority=authority, + ) assert calls == 1 assert release_checks == 2 @@ -818,25 +816,20 @@ def runner(argv, _run_dir, child_env): dispatch.managed_delivery_authority_url, dispatch.delivery_authority_token, ) - first = adapter.execute( - dispatch, - runner_config=tmp_path / "runner.toml", - run_dir=tmp_path / "run", - authority=authority, - ) - second = adapter.execute( - dispatch, - runner_config=tmp_path / "runner.toml", - run_dir=tmp_path / "run-again", - authority=authority, - ) - - assert first.outcome is TransactionOutcome.RECONCILIATION_REQUIRED - assert first.started is True - assert first.uncertain_delivery is True - assert second.outcome is TransactionOutcome.RECONCILIATION_REQUIRED - assert second.started is True - assert second.uncertain_delivery is True + with pytest.raises(RuntimeError, match="signed terminal reconciliation"): + adapter.execute( + dispatch, + runner_config=tmp_path / "runner.toml", + run_dir=tmp_path / "run", + authority=authority, + ) + with pytest.raises(RuntimeError, match="signed terminal reconciliation"): + adapter.execute( + dispatch, + runner_config=tmp_path / "runner.toml", + run_dir=tmp_path / "run-again", + authority=authority, + ) assert calls == 1 assert seen_child_env[REMOTE_DISPATCH_SESSION_ID_ENV] == ( dispatch.dispatch_session_id @@ -1201,7 +1194,18 @@ def test_recovery_callback_retains_exact_terminal_v2_envelope(tmp_path, sealed) dispatch_id=dispatch.dispatch_id, run_id=binding.run_id, outcome=TransactionOutcome.VERIFIED, - evidence_batch=(), + evidence_batch=tuple( + hosted.report_events( + _production_report(), + run_id=binding.run_id, + workflow_id=proof.payload.workflow_id, + bundle_digest=proof.payload.bundle_content_digest, + authorization_id="test-authorization", + consequential_steps=1, + effect_covered_consequential_steps=1, + terminal_outcome=TransactionOutcome.VERIFIED.value, + ) + ), terminal_verification=proof, started=True, uncertain_delivery=False, @@ -1260,7 +1264,18 @@ def test_recovery_callback_retains_signed_non_success_terminal_v2( dispatch_id=dispatch.dispatch_id, run_id=binding.run_id, outcome=outcome, - evidence_batch=(), + evidence_batch=tuple( + hosted.report_events( + _production_report(), + run_id=binding.run_id, + workflow_id=proof.payload.workflow_id, + bundle_digest=proof.payload.bundle_content_digest, + authorization_id="test-authorization", + consequential_steps=1, + effect_covered_consequential_steps=1, + terminal_outcome=outcome.value, + ) + ), terminal_verification=proof, started=True, uncertain_delivery=uncertain_delivery, @@ -1287,6 +1302,62 @@ def test_safe_halt_callback_requires_signed_terminal_proof() -> None: ) +def test_terminal_callback_refuses_conflicting_uncertainty_state() -> None: + proof = sign_production_terminal_verification( + _reconciliation_payload(), _private_key() + ) + with pytest.raises(ValueError, match="uncertainty conflicts"): + HostedTerminalEvent( + run_id=proof.payload.run_id, + outcome="RECONCILIATION_REQUIRED", + report_sha256=proof.payload.run_report_sha256, + started=True, + uncertain_delivery=False, + terminal_verification_artifact_bytes_base64=b64encode( + hosted.canonical_json(proof) + ).decode("ascii"), + terminal_verification_artifact_sha256=proof.artifact_sha256(), + ) + + +def test_callback_rejects_confirmed_summary_for_reconciliation() -> None: + proof = sign_production_terminal_verification( + _reconciliation_payload(), _private_key() + ) + terminal = HostedTerminalEvent( + run_id=proof.payload.run_id, + outcome="RECONCILIATION_REQUIRED", + report_sha256=proof.payload.run_report_sha256, + started=True, + uncertain_delivery=True, + terminal_verification_artifact_bytes_base64=b64encode( + hosted.canonical_json(proof) + ).decode("ascii"), + terminal_verification_artifact_sha256=proof.artifact_sha256(), + ) + summary = hosted.report_events( + _production_report(), + run_id=proof.payload.run_id, + workflow_id=proof.payload.workflow_id, + bundle_digest=proof.payload.bundle_content_digest, + authorization_id="test-authorization", + consequential_steps=1, + effect_covered_consequential_steps=1, + terminal_outcome="VERIFIED", + )[-1] + + with pytest.raises(ValidationError, match="conflicts with terminal outcome"): + CallbackRequest( + dispatch_id="11111111-1111-4111-8111-111111111111", + runner_session_id="22222222-2222-4222-8222-222222222222", + idempotency_key="callback-test-key", + lease_token="oal_" + "a" * 64, + product_release_admission_sha256="b" * 64, + workflow_admission_sha256="c" * 64, + events=(summary, terminal.model_dump(mode="json")), + ) + + def test_callback_refuses_terminal_proof_for_a_different_run(tmp_path, sealed) -> None: workflow, _ = sealed dispatch = _hosted_dispatch(workflow) diff --git a/tests/test_run_receipt.py b/tests/test_run_receipt.py index 7e6ba54b..b99390ca 100644 --- a/tests/test_run_receipt.py +++ b/tests/test_run_receipt.py @@ -241,6 +241,8 @@ def _terminal_payload_from_report() -> tuple[ execution_authority_signer_sha256=(chain.entries[0].authority_signer_sha256), permit_chain=chain, permit_count=1, + acknowledged_permit_count=1, + pending_permit_count=0, final_authority_sequence=0, final_runtime_delivery_sequence=9, workflow_contract_sha256=prepared.execution_outcome.workflow_contract_sha256, @@ -270,6 +272,7 @@ def _terminal_expected( "authenticated_runner_id_sha256", "authenticated_session_id_sha256", "acknowledged_one_use_claim_ids", + "pending_permit_artifact_sha256", } } values["permit_chain_sha256"] = payload.permit_chain.permit_chain_sha256 @@ -282,6 +285,7 @@ def _terminal_expected( values["acknowledged_one_use_claim_ids"] = tuple( entry.one_use_claim_id for entry in payload.permit_chain.entries ) + values["pending_permit_artifact_sha256"] = None return ProductionTerminalVerificationExpected.model_validate(values) diff --git a/tests/test_terminal_verification_v2.py b/tests/test_terminal_verification_v2.py index e96245df..08107dbb 100644 --- a/tests/test_terminal_verification_v2.py +++ b/tests/test_terminal_verification_v2.py @@ -39,6 +39,7 @@ ProductionExecutionOutcome, ProductionIdentityEvidenceManifest, ProductionIdentityResult, + ProductionPendingDeliveryPermit, ProductionPolicyEvidenceManifest, ProductionPostconditionEvidenceManifest, ProductionRunReceipt, @@ -469,6 +470,15 @@ def _permit_chain() -> ProductionDeliveryPermitChain: return ProductionDeliveryPermitChain.build((_permit_entry(),)) +def _pending_permit_chain() -> ProductionDeliveryPermitChain: + permit = _permit_entry().permit_artifact + pending = ProductionPendingDeliveryPermit.build( + permit, + receipt_absence_observed_at="2026-08-18T12:00:02Z", + ) + return ProductionDeliveryPermitChain.build((), pending=pending) + + def _manifests( chain: ProductionDeliveryPermitChain, ) -> ProductionEvidenceManifests: @@ -685,6 +695,8 @@ def _halted_payload() -> ProductionTerminalVerificationPayload: execution_authority_signer_sha256=SHA_C, permit_chain=chain, permit_count=0, + acknowledged_permit_count=0, + pending_permit_count=0, final_authority_sequence=0, final_runtime_delivery_sequence=0, workflow_contract_sha256=SHA_A, @@ -704,7 +716,7 @@ def _halted_payload() -> ProductionTerminalVerificationPayload: def _reconciliation_payload() -> ProductionTerminalVerificationPayload: - chain = _permit_chain() + chain = _pending_permit_chain() receipt = _reconciliation_receipt() outcome = _reconciliation_outcome() return ProductionTerminalVerificationPayload( @@ -726,11 +738,13 @@ def _reconciliation_payload() -> ProductionTerminalVerificationPayload: qualification_signer_registry_sha256=SHA_E, qualification_signer_registry_revision=7, execution_authority_sha256=SHA_A, - execution_authority_signer_sha256=chain.entries[0].authority_signer_sha256, + execution_authority_signer_sha256=chain.pending.authority_signer_sha256, permit_chain=chain, permit_count=1, + acknowledged_permit_count=0, + pending_permit_count=1, final_authority_sequence=0, - final_runtime_delivery_sequence=9, + final_runtime_delivery_sequence=0, workflow_contract_sha256=SHA_A, execution_outcome=outcome, execution_outcome_sha256=outcome.artifact_sha256(), @@ -772,6 +786,8 @@ def _payload() -> ProductionTerminalVerificationPayload: execution_authority_signer_sha256=(chain.entries[0].authority_signer_sha256), permit_chain=chain, permit_count=1, + acknowledged_permit_count=1, + pending_permit_count=0, final_authority_sequence=0, final_runtime_delivery_sequence=9, workflow_contract_sha256=SHA_A, @@ -832,6 +848,13 @@ def _expected( execution_authority_signer_sha256=(payload.execution_authority_signer_sha256), permit_chain_sha256=payload.permit_chain.permit_chain_sha256, permit_count=payload.permit_count, + acknowledged_permit_count=payload.acknowledged_permit_count, + pending_permit_count=payload.pending_permit_count, + pending_permit_artifact_sha256=( + payload.permit_chain.pending.permit_artifact_sha256 + if payload.permit_chain.pending is not None + else None + ), final_authority_sequence=payload.final_authority_sequence, final_runtime_delivery_sequence=payload.final_runtime_delivery_sequence, authenticated_runner_id_sha256=authenticated_runner_id_sha256, @@ -960,12 +983,93 @@ def test_terminal_v2_signs_and_verifies_reconciliation_proof() -> None: assert digest == envelope.artifact_sha256() assert payload.run_receipt.transaction_outcome == "RECONCILIATION_REQUIRED" assert payload.permit_count == 1 + assert payload.acknowledged_permit_count == 0 + assert payload.pending_permit_count == 1 + assert payload.final_runtime_delivery_sequence == 0 + assert payload.permit_chain.pending is not None + assert payload.permit_chain.pending.delivery_state == "UNRESOLVED" + assert payload.permit_chain.pending.delivery_receipt_artifact is None + assert payload.permit_chain.pending.actuation_replay_authorized is False record = payload.evidence_manifests.effect.records[0] assert isinstance(record, ProductionTerminalEffectState) assert record.attempt_state == "delivery_uncertain" assert record.observed_effect == "unknown" +def test_pending_delivery_chain_rebuilds_from_exact_retained_permit() -> None: + chain = _pending_permit_chain() + assert chain.pending is not None + + rebuilt = rebuild_production_delivery_permit_chain_from_artifacts( + (), + pending_permit_artifact=chain.pending.permit_artifact.canonical_bytes(), + receipt_absence_observed_at=chain.pending.receipt_absence_observed_at, + ) + + assert rebuilt == chain + with pytest.raises( + ProductionTerminalVerificationError, + match="pending delivery binding is incomplete", + ): + rebuild_production_delivery_permit_chain_from_artifacts( + (), + pending_permit_artifact=chain.pending.permit_artifact.canonical_bytes(), + ) + + +def test_pending_reconciliation_refuses_effect_absence_or_replay() -> None: + payload = _reconciliation_payload() + assert payload.permit_chain.pending is not None + pending = payload.permit_chain.pending.model_dump(mode="json") + + pending["actuation_replay_authorized"] = True + with pytest.raises(ValidationError): + ProductionPendingDeliveryPermit.model_validate(pending) + + data = payload.model_dump(mode="json") + effect = data["evidence_manifests"]["effect"] + effect["records"][0]["observed_effect"] = "absent" + effect["records"][0]["absence_basis"] = "not_actuated" + with pytest.raises(ValidationError): + ProductionTerminalVerificationPayload.model_validate(data) + + +def test_terminal_acceptor_rechecks_pending_permit_digest() -> None: + payload = _reconciliation_payload() + envelope = sign_production_terminal_verification(payload, _private_key()) + expected = _expected(payload).model_copy( + update={"pending_permit_artifact_sha256": SHA_A} + ) + + with pytest.raises( + ProductionTerminalVerificationError, + match="pending permit", + ): + verify_production_terminal_verification( + envelope, + expected=expected, + now=NOW, + ) + + +def test_verified_terminal_refuses_a_pending_permit() -> None: + success = _payload() + pending_chain = _pending_permit_chain() + data = success.model_dump(mode="json") + data.update( + { + "permit_chain": pending_chain.model_dump(mode="json"), + "acknowledged_permit_count": 0, + "pending_permit_count": 1, + "final_runtime_delivery_sequence": 0, + "evidence_manifests": _manifests(pending_chain).model_dump(mode="json"), + } + ) + + with pytest.raises(ValidationError, match="VERIFIED proof is incomplete"): + ProductionTerminalVerificationPayload.model_validate(data) + + @pytest.mark.parametrize( "transaction_outcome", ["HALTED_BEFORE_EFFECT", "RECONCILIATION_REQUIRED"], @@ -977,7 +1081,7 @@ def test_terminal_v2_builds_non_success_proof_from_exact_run_report( chain = ( ProductionDeliveryPermitChain.build(()) if transaction_outcome == "HALTED_BEFORE_EFFECT" - else _permit_chain() + else _pending_permit_chain() ) context = ProductionTerminalVerificationContext( run_id=IDS["run_id"], @@ -1004,7 +1108,11 @@ def test_terminal_v2_builds_non_success_proof_from_exact_run_report( execution_authority_id=IDS["execution_authority_id"], execution_authority_sha256=SHA_A, execution_authority_signer_sha256=( - chain.entries[0].authority_signer_sha256 if chain.entries else SHA_C + chain.pending.authority_signer_sha256 + if chain.pending is not None + else chain.entries[0].authority_signer_sha256 + if chain.entries + else SHA_C ), permit_chain=chain, run_report_object_version="version:terminal-report:1", @@ -1312,7 +1420,7 @@ def test_non_success_terminal_cross_language_vectors_are_exact() -> None: ) payloads = { "halted-before-effect-zero-permit": _halted_payload(), - "reconciliation-required-nonempty-permit": _reconciliation_payload(), + "reconciliation-required-pending-permit": _reconciliation_payload(), } for vector in fixture["vectors"]: From 3084231c255a9a940fb17537f2da3a575fde42ec Mon Sep 17 00:00:00 2001 From: Richard Abrich Date: Thu, 27 Aug 2026 15:45:12 -0400 Subject: [PATCH 3/7] fix(hosted): fence managed result-loss terminalization --- openadapt_flow/ir.py | 165 +++ openadapt_flow/runner/__init__.py | 4 + openadapt_flow/runner/hosted_adapter.py | 1302 +++++++++++++++-- openadapt_flow/terminal_verification_v2.py | 479 +++++- openadapt_flow/transaction.py | 8 + public-artifacts.json | 2 +- ...nerate_terminal_verification_v2_vectors.py | 90 +- ...inal_verification_v2_terminal_vectors.json | 175 +++ tests/test_hosted_runner_adapter.py | 654 ++++++++- tests/test_terminal_verification_v2.py | 419 +++++- 10 files changed, 3192 insertions(+), 106 deletions(-) diff --git a/openadapt_flow/ir.py b/openadapt_flow/ir.py index b6a8ffb2..6f337eb1 100644 --- a/openadapt_flow/ir.py +++ b/openadapt_flow/ir.py @@ -3371,6 +3371,145 @@ class EffectJournalEntry(BaseModel): collateral_reconciliation_actions: int = Field(default=0, ge=0) +MANAGED_RESULT_LOSS_DOMAIN: Final[bytes] = b"OpenAdapt managed result loss v1\0" +MANAGED_RESULT_LOSS_IDEMPOTENCY_DOMAIN: Final[bytes] = ( + b"OpenAdapt managed result loss idempotency v1\0" +) + + +def managed_result_loss_idempotency_sha256(idempotency_key: str) -> str: + """Bind a retained hosted idempotency key without exposing the key.""" + + if not isinstance(idempotency_key, str) or not idempotency_key: + raise ValueError("managed result loss idempotency key is invalid") + return hashlib.sha256( + MANAGED_RESULT_LOSS_IDEMPOTENCY_DOMAIN + idempotency_key.encode("utf-8") + ).hexdigest() + + +class ManagedResultLossEvidence(BaseModel): + """Sealed PHI-free evidence that a managed child result was lost. + + This record does not describe the business effect. It binds the outer + runner's exact retained dispatch and unresolved permit state, and it makes + every prohibited inference explicit. The signed terminal proof can then + require reconciliation without claiming that delivery did not occur. + """ + + model_config = ConfigDict(extra="forbid", frozen=True) + + schema_version: Literal["openadapt.managed-result-loss/v1"] = ( + "openadapt.managed-result-loss/v1" + ) + report_provenance: Literal["outer_runner_recovery"] = "outer_runner_recovery" + loss_code: Literal[ + "runner_exception", + "report_missing", + "recovered_after_restart", + ] + child_started_at: str = Field( + pattern=r"^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$" + ) + child_start_evidence_sha256: str = Field(pattern=r"^[a-f0-9]{64}$") + run_store_identity_sha256: str = Field(pattern=r"^[a-f0-9]{64}$") + observed_at: str = Field( + pattern=r"^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$" + ) + run_id: str = Field( + pattern=( + r"^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-" + r"[89ab][0-9a-f]{3}-[0-9a-f]{12}$" + ) + ) + flow_run_id_sha256: str = Field(pattern=r"^[a-f0-9]{64}$") + dispatch_id: str = Field( + pattern=( + r"^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-" + r"[89ab][0-9a-f]{3}-[0-9a-f]{12}$" + ) + ) + dispatch_session_id: str = Field( + pattern=( + r"^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-" + r"[89ab][0-9a-f]{3}-[0-9a-f]{12}$" + ) + ) + managed_dispatch_binding_sha256: str = Field(pattern=r"^sha256:[a-f0-9]{64}$") + idempotency_key_sha256: str = Field(pattern=r"^[a-f0-9]{64}$") + authenticated_runner_id_sha256: str = Field(pattern=r"^[a-f0-9]{64}$") + authenticated_session_id_sha256: str = Field(pattern=r"^[a-f0-9]{64}$") + execution_authority_id: str = Field( + pattern=( + r"^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-" + r"[89ab][0-9a-f]{3}-[0-9a-f]{12}$" + ) + ) + execution_authority_sha256: str = Field(pattern=r"^[a-f0-9]{64}$") + execution_authority_signer_sha256: str = Field(pattern=r"^[a-f0-9]{64}$") + delivery_result_loss_closure_artifact_sha256: str = Field(pattern=r"^[a-f0-9]{64}$") + pending_permit_artifact_sha256: Optional[str] = Field( + default=None, + pattern=r"^[a-f0-9]{64}$", + ) + run_request_sha256: str = Field(pattern=r"^[a-f0-9]{64}$") + pending_action_request_sha256: Optional[str] = Field( + default=None, + pattern=r"^[a-f0-9]{64}$", + ) + delivery_state: Literal["CLOSED_UNRESOLVED_RESULT_LOSS"] = ( + "CLOSED_UNRESOLVED_RESULT_LOSS" + ) + child_started: Literal[True] = True + child_report_retained: Literal[False] = False + effect_absence_claimed: Literal[False] = False + not_received_claimed: Literal[False] = False + blind_retry_authorized: Literal[False] = False + actuation_replay_authorized: Literal[False] = False + evidence_sha256: str = Field(pattern=r"^[a-f0-9]{64}$") + + def _digest_payload(self) -> dict[str, Any]: + payload = self.model_dump(mode="json") + payload.pop("evidence_sha256", None) + return payload + + def computed_sha256(self) -> str: + encoded = json.dumps( + self._digest_payload(), + sort_keys=True, + separators=(",", ":"), + ensure_ascii=False, + ).encode("utf-8") + return hashlib.sha256(MANAGED_RESULT_LOSS_DOMAIN + encoded).hexdigest() + + @model_validator(mode="after") + def _closed_result_loss(self) -> "ManagedResultLossEvidence": + if hashlib.sha256(self.run_id.encode("utf-8")).hexdigest() != ( + self.flow_run_id_sha256 + ): + raise ValueError("managed result loss run identity digest is invalid") + if self.evidence_sha256 != self.computed_sha256(): + raise ValueError("managed result loss evidence digest is invalid") + if (self.pending_permit_artifact_sha256 is None) != ( + self.pending_action_request_sha256 is None + ): + raise ValueError("managed result loss pending binding is incomplete") + child_started = datetime.fromisoformat(self.child_started_at[:-1] + "+00:00") + observed = datetime.fromisoformat(self.observed_at[:-1] + "+00:00") + if child_started > observed: + raise ValueError("managed result loss chronology is invalid") + return self + + @classmethod + def create(cls, **values: Any) -> "ManagedResultLossEvidence": + candidate = cls.model_construct(**values, evidence_sha256="0" * 64) + return cls.model_validate( + { + **candidate._digest_payload(), + "evidence_sha256": candidate.computed_sha256(), + } + ) + + class RunReport(BaseModel): workflow_name: str started_at: str @@ -3466,6 +3605,14 @@ class RunReport(BaseModel): "delta). PHI-free; the substrate the reconciliation model reads." ), ) + managed_result_loss: Optional[ManagedResultLossEvidence] = Field( + default=None, + exclude_if=lambda value: value is None, + description=( + "Sealed outer-runner evidence that the managed child result was " + "lost after execution started. It authorizes reconciliation only." + ), + ) idempotency_key: Optional[str] = Field( default=None, description=( @@ -3721,6 +3868,24 @@ def _validate_outcome_envelope_binding(self) -> "RunReport": ) envelope = self.outcome_envelope + if self.managed_result_loss is not None: + if ( + self.execution_outcome != "HALTED" + or self.production_eligible + or self.execution_completed is not False + or self.success + or self.transaction_outcome != "RECONCILIATION_REQUIRED" + or self.transaction_billable is not False + or self.transaction_platform_fault is not False + or len(self.results) != 1 + or self.results[0].step_id != "" + or self.results[0].ok + or self.results[0].delivery_attempted is not None + or self.results[0].effect_contract_hashes + or self.results[0].effect_evidence + or self.results[0].effect_verified is not None + ): + raise ValueError("managed result loss report contract is invalid") if envelope is None: return self if self.execution_outcome != envelope.outcome: diff --git a/openadapt_flow/runner/__init__.py b/openadapt_flow/runner/__init__.py index 3d975663..adf17415 100644 --- a/openadapt_flow/runner/__init__.py +++ b/openadapt_flow/runner/__init__.py @@ -59,6 +59,8 @@ HostedRunnerTransport, HostedRunResult, PollRequest, + ProductionDeliveryResultLossClosureRequest, + ProductionDeliveryResultLossClosureResult, RegisterCapabilities, RegisterRequest, RegisterResponse, @@ -110,6 +112,8 @@ "Refusal", "RefusalCode", "PollRequest", + "ProductionDeliveryResultLossClosureRequest", + "ProductionDeliveryResultLossClosureResult", "RUNNER_RENEWAL_HEADER", "RegisterCapabilities", "RegisterRequest", diff --git a/openadapt_flow/runner/hosted_adapter.py b/openadapt_flow/runner/hosted_adapter.py index 7fa80f08..107b70b6 100644 --- a/openadapt_flow/runner/hosted_adapter.py +++ b/openadapt_flow/runner/hosted_adapter.py @@ -12,6 +12,7 @@ import json import os import re +import secrets import stat import subprocess from base64 import b64decode, b64encode @@ -25,7 +26,15 @@ from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey from pydantic import BaseModel, ConfigDict, Field, model_validator -from openadapt_flow.ir import RunReport, Workflow +from openadapt_flow.bundle_validation import compute_parameter_schema_digest +from openadapt_flow.execution_profiles import stamp_execution_outcome +from openadapt_flow.ir import ( + ManagedResultLossEvidence, + RunReport, + StepResult, + Workflow, + managed_result_loss_idempotency_sha256, +) from openadapt_flow.private_file import ( PrivateFileAclError, windows_descriptor_has_private_acl, @@ -35,6 +44,7 @@ ProductionQualificationGuard, _read_private_json, ) +from openadapt_flow.qualification import workflow_contract_sha256 from openadapt_flow.qualification_admission_v2 import ( QualificationAdmissionEnvelope, QualificationAdmissionExpected, @@ -72,12 +82,16 @@ ) from openadapt_flow.runtime.durable.checkpoint import CheckpointStore from openadapt_flow.terminal_verification_v2 import ( + RESULT_LOSS_CLOSURE_REQUEST_DOMAIN, + ProductionDeliveryPermitChain, + ProductionDeliveryResultLossClosureArtifact, ProductionTerminalVerificationContext, ProductionTerminalVerificationEnvelope, ProductionTerminalVerificationExpected, build_production_terminal_verification, evidence_runner_signer_sha256, prepare_production_terminal_evidence, + verify_production_delivery_result_loss_closure_binding, verify_production_terminal_verification_from_report, ) from openadapt_flow.transaction import ( @@ -95,6 +109,12 @@ _SAFE_ID = r"^[A-Za-z0-9][A-Za-z0-9._:@/+\-]{0,199}$" _UTC_SECONDS = re.compile(r"^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$") _MAX_ARTIFACT_BYTES = 2 * 1024 * 1024 +_MAX_RESULT_LOSS_CHAIN_BYTES = 1024 * 1024 +_MAX_RESULT_LOSS_SNAPSHOT_BYTES = 3 * 1024 * 1024 +_CHILD_START_DOMAIN = b"OpenAdapt managed child start v1\0" +_RUN_STORE_IDENTITY_DOMAIN = b"OpenAdapt managed run store identity v1\0" +_RESULT_LOSS_SNAPSHOT_DOMAIN = b"OpenAdapt managed result loss snapshot v1\0" +_MAX_TERMINAL_STATE_BYTES = 2 * (4 * ((_MAX_ARTIFACT_BYTES + 2) // 3)) + 4096 # The current runner credential is never part of a request model. Desktop may # project it into this header only for POST /api/runners/register on the exact @@ -283,6 +303,197 @@ class HostedRecoveryBinding(_Closed): authorization_id: str = Field(min_length=1, max_length=128) +class ManagedChildStartEvidence(_Closed): + """Durable outer-runner boundary written before managed child entry.""" + + schema_version: Literal["openadapt.managed-child-start/v1"] = ( + "openadapt.managed-child-start/v1" + ) + started_at: str + dispatch_id: str = Field(pattern=_UUID) + dispatch_session_id: str = Field(pattern=_UUID) + run_id: str = Field(pattern=_UUID) + managed_dispatch_binding_sha256: str = Field(pattern=r"^sha256:[a-f0-9]{64}$") + authenticated_runner_id_sha256: str = Field(pattern=_HEX64) + authenticated_session_id_sha256: str = Field(pattern=_HEX64) + execution_authority_id: str = Field(pattern=_UUID) + execution_authority_sha256: str = Field(pattern=_HEX64) + execution_authority_signer_sha256: str = Field(pattern=_HEX64) + run_store_identity_sha256: str = Field(pattern=_HEX64) + marker_sha256: str = Field(pattern=_HEX64) + + def computed_sha256(self) -> str: + payload = self.model_dump(mode="json") + payload.pop("marker_sha256", None) + return hashlib.sha256(_CHILD_START_DOMAIN + canonical_json(payload)).hexdigest() + + @model_validator(mode="after") + def _closed_marker(self) -> "ManagedChildStartEvidence": + _utc_seconds(self.started_at, label="managed child start") + if self.marker_sha256 != self.computed_sha256(): + raise ValueError("managed child start digest is invalid") + return self + + @classmethod + def create(cls, **values: Any) -> "ManagedChildStartEvidence": + candidate = cls.model_construct(**values, marker_sha256="0" * 64) + payload = candidate.model_dump(mode="json") + payload["marker_sha256"] = candidate.computed_sha256() + return cls.model_validate(payload) + + +class ProductionDeliveryResultLossClosureRequest(_Closed): + """Credential-free request for one monotonic hosted result-loss fence.""" + + schema_version: Literal[ + "openadapt.production-delivery-result-loss-closure-request/v2" + ] = "openadapt.production-delivery-result-loss-closure-request/v2" + child_start_evidence: ManagedChildStartEvidence + expected_closure_sequence: Literal[0] = 0 + result_loss_observed_at: str + + @model_validator(mode="after") + def _closed_request(self) -> "ProductionDeliveryResultLossClosureRequest": + observed = _utc_seconds( + self.result_loss_observed_at, + label="result loss observation", + ) + started = _utc_seconds( + self.child_start_evidence.started_at, + label="managed child start", + ) + if started > observed: + raise ValueError("result-loss closure request chronology is invalid") + return self + + def canonical_bytes(self) -> bytes: + return canonical_json(self) + + def request_sha256(self) -> str: + return hashlib.sha256( + RESULT_LOSS_CLOSURE_REQUEST_DOMAIN + self.canonical_bytes() + ).hexdigest() + + +class ProductionDeliveryResultLossClosureResult(_Closed): + """Exact Cloud authority closure and its atomically frozen permit chain.""" + + schema_version: Literal[ + "openadapt.production-delivery-result-loss-closure-result/v2" + ] = "openadapt.production-delivery-result-loss-closure-result/v2" + status: Literal["closed"] = "closed" + closure_artifact_bytes_base64: str = Field(max_length=2_796_204) + closure_artifact_sha256: str = Field(pattern=_HEX64) + permit_chain_bytes_base64: str = Field(max_length=2_796_204) + permit_chain_sha256: str = Field(pattern=_HEX64) + + @staticmethod + def _decode_canonical( + value: str, + *, + label: str, + maximum_bytes: int = _MAX_ARTIFACT_BYTES, + ) -> bytes: + try: + raw = b64decode(value, validate=True) + except (TypeError, ValueError) as exc: + raise ValueError(f"{label} is not canonical base64") from exc + if ( + not raw + or len(raw) > maximum_bytes + or b64encode(raw).decode("ascii") != value + ): + raise ValueError(f"{label} is not canonical base64") + return raw + + def artifacts( + self, + ) -> tuple[ + ProductionDeliveryResultLossClosureArtifact, + ProductionDeliveryPermitChain, + ]: + closure_raw = self._decode_canonical( + self.closure_artifact_bytes_base64, + label="result-loss closure artifact", + ) + chain_raw = self._decode_canonical( + self.permit_chain_bytes_base64, + label="result-loss closure permit chain", + maximum_bytes=_MAX_RESULT_LOSS_CHAIN_BYTES, + ) + try: + closure = ProductionDeliveryResultLossClosureArtifact.model_validate_json( + closure_raw + ) + chain = ProductionDeliveryPermitChain.model_validate_json(chain_raw) + except ValueError as exc: + raise ValueError("result-loss closure response is invalid") from exc + if ( + canonical_json(closure) != closure_raw + or canonical_json(chain) != chain_raw + or hashlib.sha256(closure_raw).hexdigest() != self.closure_artifact_sha256 + or closure.artifact_sha256() != self.closure_artifact_sha256 + or chain.permit_chain_sha256 != self.permit_chain_sha256 + or closure.payload.permit_chain_sha256 != self.permit_chain_sha256 + ): + raise ValueError("result-loss closure response binding is invalid") + return closure, chain + + @model_validator(mode="after") + def _closed_result(self) -> "ProductionDeliveryResultLossClosureResult": + self.artifacts() + return self + + +class ManagedResultLossSnapshot(_Closed): + """One local CAS record for the loss evidence and exact permit-chain view.""" + + schema_version: Literal["openadapt.managed-result-loss-snapshot/v1"] = ( + "openadapt.managed-result-loss-snapshot/v1" + ) + evidence: ManagedResultLossEvidence + permit_chain: ProductionDeliveryPermitChain + closure_artifact: ProductionDeliveryResultLossClosureArtifact + snapshot_sha256: str = Field(pattern=_HEX64) + + def computed_sha256(self) -> str: + payload = self.model_dump(mode="json") + payload.pop("snapshot_sha256", None) + return hashlib.sha256( + _RESULT_LOSS_SNAPSHOT_DOMAIN + canonical_json(payload) + ).hexdigest() + + @model_validator(mode="after") + def _closed_snapshot(self) -> "ManagedResultLossSnapshot": + if ( + self.snapshot_sha256 != self.computed_sha256() + or self.evidence.delivery_result_loss_closure_artifact_sha256 + != self.closure_artifact.artifact_sha256() + or self.closure_artifact.payload.permit_chain_sha256 + != self.permit_chain.permit_chain_sha256 + ): + raise ValueError("managed result loss snapshot is invalid") + return self + + @classmethod + def create( + cls, + *, + evidence: ManagedResultLossEvidence, + permit_chain: ProductionDeliveryPermitChain, + closure_artifact: ProductionDeliveryResultLossClosureArtifact, + ) -> "ManagedResultLossSnapshot": + candidate = cls.model_construct( + evidence=evidence, + permit_chain=permit_chain, + closure_artifact=closure_artifact, + snapshot_sha256="0" * 64, + ) + payload = candidate.model_dump(mode="json") + payload["snapshot_sha256"] = candidate.computed_sha256() + return cls.model_validate(payload) + + class HostedTerminalEvent(_Closed): schema_version: Literal["openadapt.hosted-runner-terminal/v1"] = ( "openadapt.hosted-runner-terminal/v1" @@ -323,8 +534,6 @@ def _terminal_outcome_requires_exact_proof(self) -> "HostedTerminalEvent": and not has_proof ): raise ValueError(f"{self.outcome} requires exact terminal verification") - if self.uncertain_delivery != (self.outcome == "RECONCILIATION_REQUIRED"): - raise ValueError("terminal uncertainty conflicts with its outcome") if ( self.outcome not in { @@ -362,6 +571,11 @@ def _terminal_outcome_requires_exact_proof(self) -> "HostedTerminalEvent": raise ValueError("terminal verification names a different run report") if proof.payload.run_receipt.transaction_outcome != self.outcome: raise ValueError("terminal verification names a different outcome") + expected_uncertainty = proof.payload.pending_permit_count == 1 + else: + expected_uncertainty = False + if self.uncertain_delivery != expected_uncertainty: + raise ValueError("terminal uncertainty conflicts with its signed proof") return self @@ -394,10 +608,12 @@ def _closed_terminal(self) -> "HostedRunResult": TransactionOutcome.RECONCILIATION_REQUIRED, }: raise ValueError("terminal outcome cannot carry a signed v2 proof") - if self.uncertain_delivery != ( - self.outcome is TransactionOutcome.RECONCILIATION_REQUIRED - ): - raise ValueError("uncertain delivery has an invalid terminal outcome") + expected_uncertainty = bool( + self.terminal_verification is not None + and self.terminal_verification.payload.pending_permit_count == 1 + ) + if self.uncertain_delivery != expected_uncertainty: + raise ValueError("uncertain delivery conflicts with its signed proof") if self.terminal_verification is not None and ( self.terminal_verification.payload.run_id != self.run_id or self.terminal_verification.payload.run_report_sha256 @@ -483,6 +699,13 @@ def register(self, request: RegisterRequest) -> RegisterResponse: ... def poll(self, request: PollRequest) -> HostedDispatch | None: ... + def close_result_loss( + self, + run_id: str, + lease_token: str, + request: ProductionDeliveryResultLossClosureRequest, + ) -> ProductionDeliveryResultLossClosureResult: ... + def callback(self, run_id: str, request: CallbackRequest) -> CallbackResponse: ... @@ -1018,6 +1241,515 @@ def _write_private_bytes(path: Path, raw: bytes) -> Path: os.close(descriptor) return path + @staticmethod + def _write_private_bytes_atomic_exclusive(path: Path, raw: bytes) -> Path: + """Publish complete owner-only bytes once, without an overwrite window.""" + + temporary = path.with_name( + f".{path.name}.{os.getpid()}.{secrets.token_hex(8)}.tmp" + ) + try: + HostedRunnerAdapter._write_private_bytes(temporary, raw) + try: + os.link(temporary, path) + except FileExistsError: + raise + try: + directory = os.open(path.parent, os.O_RDONLY) + except OSError: + directory = None + if directory is not None: + try: + os.fsync(directory) + finally: + os.close(directory) + finally: + try: + temporary.unlink() + except FileNotFoundError: + pass + return path + + @staticmethod + def _run_store_identity_sha256(run_dir: Path) -> str: + resolved = Path(run_dir).resolve(strict=True) + value = resolved.lstat() + payload = { + "canonical_run_dir": str(resolved), + "device": int(value.st_dev), + "inode": int(value.st_ino), + } + return hashlib.sha256( + _RUN_STORE_IDENTITY_DOMAIN + canonical_json(payload) + ).hexdigest() + + def _write_child_start_evidence( + self, + *, + dispatch: HostedDispatch, + run_dir: Path, + dispatch_binding_sha256: str, + ) -> ManagedChildStartEvidence: + now = datetime.now(timezone.utc).replace(microsecond=0) + marker = ManagedChildStartEvidence.create( + started_at=now.isoformat().replace("+00:00", "Z"), + dispatch_id=dispatch.dispatch_id, + dispatch_session_id=dispatch.dispatch_session_id, + run_id=dispatch.run_id, + managed_dispatch_binding_sha256=dispatch_binding_sha256, + authenticated_runner_id_sha256=hashlib.sha256( + dispatch.runner_id.encode("utf-8") + ).hexdigest(), + authenticated_session_id_sha256=hashlib.sha256( + dispatch.runner_session_id.encode("utf-8") + ).hexdigest(), + execution_authority_id=dispatch.execution_authority_id, + execution_authority_sha256=dispatch.execution_authority_sha256, + execution_authority_signer_sha256=( + dispatch.execution_authority_signer_sha256 + ), + run_store_identity_sha256=self._run_store_identity_sha256(run_dir), + ) + self._write_private_bytes_atomic_exclusive( + run_dir / "managed-child-started.json", canonical_json(marker) + ) + return marker + + def _read_child_start_evidence( + self, + *, + dispatch: HostedDispatch, + run_dir: Path, + dispatch_binding_sha256: str, + ) -> ManagedChildStartEvidence: + raw = self._read_private_bytes( + run_dir / "managed-child-started.json", + maximum_bytes=64 * 1024, + label="managed child start evidence", + ) + try: + marker = ManagedChildStartEvidence.model_validate_json(raw) + except ValueError as exc: + raise ValueError("managed child start evidence is invalid") from exc + expected = ( + dispatch.dispatch_id, + dispatch.dispatch_session_id, + dispatch.run_id, + dispatch_binding_sha256, + hashlib.sha256(dispatch.runner_id.encode("utf-8")).hexdigest(), + hashlib.sha256(dispatch.runner_session_id.encode("utf-8")).hexdigest(), + dispatch.execution_authority_id, + dispatch.execution_authority_sha256, + dispatch.execution_authority_signer_sha256, + self._run_store_identity_sha256(run_dir), + ) + actual = ( + marker.dispatch_id, + marker.dispatch_session_id, + marker.run_id, + marker.managed_dispatch_binding_sha256, + marker.authenticated_runner_id_sha256, + marker.authenticated_session_id_sha256, + marker.execution_authority_id, + marker.execution_authority_sha256, + marker.execution_authority_signer_sha256, + marker.run_store_identity_sha256, + ) + if canonical_json(marker) != raw or actual != expected: + raise ValueError("managed child start evidence changed") + return marker + + @staticmethod + def _managed_result_loss_report( + *, + dispatch: HostedDispatch, + workflow: Workflow, + manifest: object, + marker: ManagedChildStartEvidence, + evidence: ManagedResultLossEvidence, + verified_params: dict[str, RuntimeParamScalar], + runtime_substrate: Literal["web", "windows", "macos", "linux", "rdp", "citrix"], + ) -> RunReport: + authorization = getattr(manifest, "governed_authorization", None) + if ( + workflow.manifest is None + or authorization is None + or authorization.execution_profile + not in { + "standard", + "regulated", + } + ): + raise ValueError("managed result loss lacks retained authorization") + qualification_case_id_sha256 = ( + hashlib.sha256( + authorization.qualification_case_id.encode("utf-8") + ).hexdigest() + if authorization.qualification_case_id is not None + else None + ) + report = RunReport( + workflow_name=workflow.name, + started_at=marker.started_at, + execution_profile=authorization.execution_profile, + execution_outcome="HALTED", + production_eligible=False, + execution_completed=False, + transaction_outcome="RECONCILIATION_REQUIRED", + transaction_billable=False, + transaction_platform_fault=False, + managed_result_loss=evidence, + execution_target_kind=runtime_substrate, + recorded_surface=workflow.surface, + bundle_content_digest=workflow.manifest.content_digest, + workflow_contract_sha256=workflow_contract_sha256(workflow), + source_recording_sha256=workflow.manifest.provenance.source_recording_sha256, + parameter_schema_sha256=compute_parameter_schema_digest(workflow), + governed_authorization_id=authorization.authorization_id, + governed_approval_source=authorization.approval_source, + governed_authorization_created_at=authorization.created_at, + governed_policy_name=authorization.admitted_policy_name, + governed_policy_contract_sha256=( + authorization.admitted_policy_contract_sha256 + ), + governed_minimum_effect_tier=authorization.minimum_effect_tier, + governed_qualified_effect_requirements=list( + authorization.qualified_effect_requirements + ), + governed_runtime_inputs_digest=authorization.runtime_inputs_digest, + run_id_sha256=evidence.flow_run_id_sha256, + governed_qualification_project_id=authorization.qualification_project_id, + governed_qualification_project_revision=( + authorization.qualification_project_revision + ), + governed_qualification_project_contract_sha256=( + authorization.qualification_project_contract_sha256 + ), + governed_qualification_campaign_id_sha256=( + authorization.qualification_campaign_id_sha256 + ), + governed_qualification_case_id_sha256=qualification_case_id_sha256, + governed_qualification_case_input_sha256=( + authorization.qualification_case_input_sha256 + ), + governed_qualification_run_id_sha256=( + authorization.qualification_run_id_sha256 + ), + governed_qualification_case_kind=authorization.qualification_case_kind, + governed_qualification_case_action_paths=dict( + authorization.qualification_case_action_paths + ), + governed_qualification_fault_driver_id=( + authorization.qualification_fault_driver_id + ), + governed_qualification_fault_driver_contract_sha256=( + authorization.qualification_fault_driver_contract_sha256 + ), + governed_qualification_fault_driver_key_id=( + authorization.qualification_fault_driver_key_id + ), + governed_qualification_fault_step_id_sha256=( + authorization.qualification_fault_step_id_sha256 + ), + governed_authorized_effect_contracts={ + approval.step_id: list(approval.effect_contract_hashes) + for approval in authorization.unverified_write_approvals + }, + required_identity_step_ids=list(authorization.required_identity_step_ids), + approved_unverified_effect_step_ids=[ + approval.step_id + for approval in authorization.unverified_write_approvals + ], + params=verified_params, + results=[ + StepResult( + step_id="", + intent="retain managed child result loss", + ok=False, + safety_halt=True, + failure_category="safety_halt", + delivery_attempted=None, + ) + ], + success=False, + model_calls=int(getattr(manifest, "model_calls", 0)), + # The exact Cloud authority interaction proves that network I/O + # occurred even though the child report is unavailable. + external_network_calls="observed", + ) + stamp_execution_outcome( + report, + workflow, + authorization.execution_profile, + ) + if ( + report.execution_outcome != "HALTED" + or report.transaction_outcome != "RECONCILIATION_REQUIRED" + ): + raise ValueError("managed result loss classification changed") + return RunReport.model_validate_json(report.model_dump_json()) + + def _produce_managed_result_loss( + self, + *, + dispatch: HostedDispatch, + workflow: Workflow, + run_dir: Path, + qualification: ProductionQualificationAuthority, + private_key: Ed25519PrivateKey, + verified_params: dict[str, RuntimeParamScalar], + dispatch_binding_sha256: str, + closure_authority: HostedRunnerTransport, + loss_code: Literal[ + "runner_exception", + "report_missing", + "recovered_after_restart", + ], + ) -> tuple[ProductionTerminalVerificationEnvelope, str, RunReport]: + """Seal one result-loss report without resolving or replaying delivery.""" + + store = CheckpointStore(run_dir) + manifest = store.read_manifest() + if manifest is None: + raise ValueError("managed result loss lacks a retained run manifest") + marker = self._read_child_start_evidence( + dispatch=dispatch, + run_dir=run_dir, + dispatch_binding_sha256=dispatch_binding_sha256, + ) + + def snapshot_from_closure( + *, + request: ProductionDeliveryResultLossClosureRequest, + retained_loss_code: Literal[ + "runner_exception", + "report_missing", + "recovered_after_restart", + ], + closure_artifact: ProductionDeliveryResultLossClosureArtifact, + retained_chain: ProductionDeliveryPermitChain, + ) -> ManagedResultLossSnapshot: + chain = ProductionDeliveryPermitChain.model_validate( + retained_chain.model_dump(mode="json") + ) + if not chain.entries and chain.pending is None: + raise ValueError("managed result loss closure returned no permit") + closure_artifact = ( + ProductionDeliveryResultLossClosureArtifact.model_validate( + closure_artifact.model_dump(mode="json") + ) + ) + closure = closure_artifact.payload + if ( + closure.closure_request_sha256 != request.request_sha256() + or closure.result_loss_observed_at != request.result_loss_observed_at + or request.child_start_evidence != marker + ): + raise ValueError("managed result loss closure changed its request") + first = chain.entries[0] if chain.entries else chain.pending + assert first is not None + pending = chain.pending + evidence = ManagedResultLossEvidence.create( + loss_code=retained_loss_code, + child_started_at=marker.started_at, + child_start_evidence_sha256=marker.marker_sha256, + run_store_identity_sha256=marker.run_store_identity_sha256, + observed_at=request.result_loss_observed_at, + run_id=dispatch.run_id, + flow_run_id_sha256=hashlib.sha256( + dispatch.run_id.encode("utf-8") + ).hexdigest(), + dispatch_id=dispatch.dispatch_id, + dispatch_session_id=dispatch.dispatch_session_id, + managed_dispatch_binding_sha256=dispatch_binding_sha256, + idempotency_key_sha256=managed_result_loss_idempotency_sha256( + dispatch.idempotency_key + ), + authenticated_runner_id_sha256=hashlib.sha256( + dispatch.runner_id.encode("utf-8") + ).hexdigest(), + authenticated_session_id_sha256=hashlib.sha256( + dispatch.runner_session_id.encode("utf-8") + ).hexdigest(), + execution_authority_id=dispatch.execution_authority_id, + execution_authority_sha256=dispatch.execution_authority_sha256, + execution_authority_signer_sha256=( + dispatch.execution_authority_signer_sha256 + ), + delivery_result_loss_closure_artifact_sha256=( + closure_artifact.artifact_sha256() + ), + pending_permit_artifact_sha256=( + pending.permit_artifact_sha256 if pending is not None else None + ), + run_request_sha256=first.run_request_sha256, + pending_action_request_sha256=( + pending.action_request_sha256 if pending is not None else None + ), + ) + verify_production_delivery_result_loss_closure_binding( + closure_artifact, + permit_chain=chain, + result_loss=evidence, + tenant_id=dispatch.tenant_id, + terminal_verified_at=closure.closed_at, + ) + return ManagedResultLossSnapshot.create( + evidence=evidence, + permit_chain=chain, + closure_artifact=closure_artifact, + ) + + request_path = run_dir / "managed-result-loss-closure-request.json" + + def read_retained_request() -> ProductionDeliveryResultLossClosureRequest: + raw = self._read_private_bytes( + request_path, + maximum_bytes=64 * 1024, + label="managed result loss closure request", + ) + try: + retained = ( + ProductionDeliveryResultLossClosureRequest.model_validate_json(raw) + ) + except ValueError as exc: + raise ValueError( + "managed result loss closure request is invalid" + ) from exc + if ( + canonical_json(retained) != raw + or retained.child_start_evidence != marker + ): + raise ValueError("managed result loss closure request changed") + return retained + + try: + request_path.lstat() + except FileNotFoundError: + observed_at = ( + datetime.now(timezone.utc) + .replace(microsecond=0) + .isoformat() + .replace("+00:00", "Z") + ) + request = ProductionDeliveryResultLossClosureRequest( + child_start_evidence=marker, + result_loss_observed_at=observed_at, + ) + try: + self._write_private_bytes_atomic_exclusive( + request_path, + request.canonical_bytes(), + ) + except FileExistsError: + request = read_retained_request() + else: + request = read_retained_request() + + evidence_path = run_dir / "managed-result-loss.json" + + def read_retained_snapshot() -> ManagedResultLossSnapshot: + retained_bytes = self._read_private_bytes( + evidence_path, + maximum_bytes=_MAX_RESULT_LOSS_SNAPSHOT_BYTES, + label="managed result loss snapshot", + ) + try: + retained = ManagedResultLossSnapshot.model_validate_json(retained_bytes) + except ValueError as exc: + raise ValueError("managed result loss snapshot is invalid") from exc + if canonical_json(retained) != retained_bytes: + raise ValueError("managed result loss snapshot is not canonical") + expected_retained = snapshot_from_closure( + request=request, + retained_loss_code=retained.evidence.loss_code, + closure_artifact=retained.closure_artifact, + retained_chain=retained.permit_chain, + ) + if retained != expected_retained: + raise ValueError("managed result loss snapshot changed") + return retained + + try: + evidence_path.lstat() + except FileNotFoundError: + raw_result = closure_authority.close_result_loss( + dispatch.run_id, + dispatch.lease_token, + request, + ) + result = ProductionDeliveryResultLossClosureResult.model_validate( + raw_result + ) + closure_artifact, permit_chain = result.artifacts() + snapshot = snapshot_from_closure( + request=request, + retained_loss_code=loss_code, + closure_artifact=closure_artifact, + retained_chain=permit_chain, + ) + try: + self._write_private_bytes_atomic_exclusive( + evidence_path, canonical_json(snapshot) + ) + except FileExistsError: + snapshot = read_retained_snapshot() + else: + snapshot = read_retained_snapshot() + evidence = snapshot.evidence + observed_at = evidence.observed_at + expected = qualification.expected + report = self._managed_result_loss_report( + dispatch=dispatch, + workflow=workflow, + manifest=manifest, + marker=marker, + evidence=evidence, + verified_params=verified_params, + runtime_substrate=expected.runtime_build_identity.substrate, + ) + proof, digest = self._produce_terminal_verification( + dispatch=dispatch, + report=report, + run_dir=run_dir, + qualification=qualification, + private_key=private_key, + verified_params=verified_params, + dispatch_binding_sha256=dispatch_binding_sha256, + result_loss_observed_at=observed_at, + retained_permit_chain=snapshot.permit_chain, + retained_result_loss_closure=snapshot.closure_artifact, + ) + return proof, digest, report + + def _revalidate_terminal_authority( + self, + *, + dispatch: HostedDispatch, + runner_config: Path, + configured_origin: str, + initial_qualification: ProductionQualificationAuthority, + initial_deployment_bytes: bytes, + ) -> tuple[Ed25519PrivateKey, ProductionQualificationAuthority]: + """Revalidate all live signing authority after managed execution.""" + + terminal_config = load_runner_config(runner_config, protected=True) + if self._protected_runner_origin(terminal_config) != configured_origin: + raise ValueError("protected runner origin changed during execution") + self._verify_product_release(dispatch, terminal_config) + terminal_key = self._load_evidence_private_key(terminal_config) + terminal_qualification, terminal_deployment = self._verify_workflow_admission( + dispatch, + terminal_config, + evidence_private_key=terminal_key, + ) + if ( + terminal_qualification != initial_qualification + or terminal_deployment != initial_deployment_bytes + ): + raise ValueError("production admission changed during execution") + return terminal_key, terminal_qualification + def _resolve_params( self, dispatch: HostedDispatch, @@ -1126,6 +1858,11 @@ def _produce_terminal_verification( private_key: Ed25519PrivateKey, verified_params: dict[str, RuntimeParamScalar], dispatch_binding_sha256: str, + result_loss_observed_at: str | None = None, + retained_permit_chain: ProductionDeliveryPermitChain | None = None, + retained_result_loss_closure: ( + ProductionDeliveryResultLossClosureArtifact | None + ) = None, ) -> tuple[ProductionTerminalVerificationEnvelope, str]: """Build, retain, reread, and verify one exact terminal-v2 proof.""" @@ -1239,22 +1976,45 @@ def _produce_terminal_verification( prepared = prepare_production_terminal_evidence(report) now = datetime.now(timezone.utc).replace(microsecond=0) + if retained_result_loss_closure is not None: + closure_time = _utc_seconds( + retained_result_loss_closure.payload.closed_at, + label="managed result loss authority closure", + ) + now = max(now, closure_time) now_text = now.isoformat().replace("+00:00", "Z") - chain = DurableAuthority(run_dir, store).production_delivery_permit_chain( - allow_empty=( - prepared.transaction_outcome is TransactionOutcome.HALTED_BEFORE_EFFECT - ), - allow_pending=( - prepared.transaction_outcome - is TransactionOutcome.RECONCILIATION_REQUIRED - ), - receipt_absence_observed_at=( - now_text - if prepared.transaction_outcome - is TransactionOutcome.RECONCILIATION_REQUIRED - else None - ), + chain = ( + ProductionDeliveryPermitChain.model_validate( + retained_permit_chain.model_dump(mode="json") + ) + if retained_permit_chain is not None + else DurableAuthority(run_dir, store).production_delivery_permit_chain( + allow_empty=( + prepared.transaction_outcome + is TransactionOutcome.HALTED_BEFORE_EFFECT + ), + allow_pending=( + prepared.transaction_outcome + is TransactionOutcome.RECONCILIATION_REQUIRED + ), + receipt_absence_observed_at=( + now_text + if prepared.transaction_outcome + is TransactionOutcome.RECONCILIATION_REQUIRED + else None + ), + ) ) + if retained_permit_chain is not None and report.managed_result_loss is None: + raise ValueError("only managed result loss can use a retained permit chain") + if (report.managed_result_loss is not None) != all( + ( + result_loss_observed_at is not None, + retained_permit_chain is not None, + retained_result_loss_closure is not None, + ) + ): + raise ValueError("managed result loss observation binding is incomplete") first = chain.entries[0] if chain.entries else chain.pending expected = qualification.expected runtime = expected.runtime_build_identity @@ -1289,6 +2049,43 @@ def _produce_terminal_verification( != runner_session_id_sha256 ): raise ValueError("retained delivery chain differs from admitted live state") + if report.managed_result_loss is not None: + loss = report.managed_result_loss + pending = chain.pending + first_permit = chain.entries[0] if chain.entries else pending + pending_digest = ( + pending.permit_artifact_sha256 if pending is not None else None + ) + if ( + first_permit is None + or loss.observed_at != result_loss_observed_at + or loss.pending_permit_artifact_sha256 != pending_digest + or loss.run_request_sha256 != first_permit.run_request_sha256 + or loss.pending_action_request_sha256 + != (pending.action_request_sha256 if pending is not None else None) + or loss.dispatch_id != dispatch.dispatch_id + or loss.dispatch_session_id != dispatch.dispatch_session_id + or loss.managed_dispatch_binding_sha256 + != dispatch.payload.dispatch_binding_sha256 + or loss.idempotency_key_sha256 + != managed_result_loss_idempotency_sha256(dispatch.idempotency_key) + or loss.authenticated_runner_id_sha256 != runner_id_sha256 + or loss.authenticated_session_id_sha256 != runner_session_id_sha256 + or loss.execution_authority_id != dispatch.execution_authority_id + or loss.execution_authority_sha256 + != dispatch.execution_authority_sha256 + or loss.execution_authority_signer_sha256 + != dispatch.execution_authority_signer_sha256 + ): + raise ValueError("managed result loss differs from retained live state") + assert retained_result_loss_closure is not None + verify_production_delivery_result_loss_closure_binding( + retained_result_loss_closure, + permit_chain=chain, + result_loss=loss, + tenant_id=dispatch.tenant_id, + terminal_verified_at=now_text, + ) context = ProductionTerminalVerificationContext( run_id=dispatch.run_id, tenant_id=dispatch.tenant_id, @@ -1321,6 +2118,7 @@ def _produce_terminal_verification( dispatch.execution_authority_signer_sha256 ), permit_chain=chain, + delivery_result_loss_closure=retained_result_loss_closure, run_report_object_version="sha256:" + prepared.report_sha256, verified_at=now_text, issued_at=now_text, @@ -1336,6 +2134,8 @@ def _produce_terminal_verification( ): raise ValueError("terminal report changed during proof production") envelope_bytes = canonical_json(built.envelope) + if len(envelope_bytes) > _MAX_ARTIFACT_BYTES: + raise ValueError("terminal verification exceeds the callback size limit") payload = built.envelope.payload final = chain.entries[-1] if chain.entries else None final_authority = chain.pending or final @@ -1399,6 +2199,8 @@ def _produce_terminal_verification( run_report_object_version=context.run_report_object_version, run_report_object_sha256=built.report_sha256, evidence_manifests=payload.evidence_manifests, + managed_result_loss=payload.managed_result_loss, + delivery_result_loss_closure=payload.delivery_result_loss_closure, ) artifact_sha256 = verify_production_terminal_verification_from_report( built.envelope, @@ -1409,50 +2211,145 @@ def _produce_terminal_verification( if artifact_sha256 != hashlib.sha256(envelope_bytes).hexdigest(): raise ValueError("terminal verification artifact digest changed") - # Final-named evidence exists only after the complete in-memory proof - # passes. If storage or the required reread fails, remove only files - # created by this call so no failed terminalization leaves success - # artifacts behind. + # One exact CAS object owns the terminal state. Once it exists, a late + # child result or a concurrent terminalizer can only return the same + # bytes; it can never replace reconciliation with another outcome. report_path = run_dir / "production-terminal-report.json" envelope_path = run_dir / "production-terminal-verification.json" - written: list[Path] = [] + state_path = run_dir / "production-terminal-state.json" + state_bytes = canonical_json( + { + "schema_version": "openadapt.production-terminal-state/v1", + "report_bytes_base64": b64encode(built.report_bytes).decode("ascii"), + "report_sha256": built.report_sha256, + "terminal_verification_bytes_base64": b64encode(envelope_bytes).decode( + "ascii" + ), + "terminal_verification_sha256": artifact_sha256, + } + ) try: - self._write_private_bytes(report_path, built.report_bytes) - written.append(report_path) - self._write_private_bytes(envelope_path, envelope_bytes) - written.append(envelope_path) - stored_report = self._read_private_bytes( - report_path, - maximum_bytes=_MAX_ARTIFACT_BYTES, - label="production terminal report", - ) - stored_envelope = self._read_private_bytes( - envelope_path, - maximum_bytes=_MAX_ARTIFACT_BYTES, - label="production terminal verification", - ) - if stored_report != built.report_bytes or stored_envelope != envelope_bytes: - raise ValueError("stored terminal evidence changed after write") - reread = ProductionTerminalVerificationEnvelope.model_validate_json( - stored_envelope + self._write_private_bytes_atomic_exclusive(state_path, state_bytes) + except FileExistsError: + retained_state = self._read_private_bytes( + state_path, + maximum_bytes=_MAX_TERMINAL_STATE_BYTES, + label="production terminal state", ) - if canonical_json(reread) != stored_envelope: - raise ValueError("stored terminal verification is not canonical") - reread_sha256 = verify_production_terminal_verification_from_report( - reread, - report_bytes=stored_report, - expected=live_expected, - now=now, - ) - if reread_sha256 != artifact_sha256: - raise ValueError("stored terminal verification digest changed") - except Exception: - for path in reversed(written): + if retained_state != state_bytes: try: - path.unlink() - except OSError: - pass - raise + retained_value = json.loads(retained_state.decode("utf-8")) + except (UnicodeDecodeError, json.JSONDecodeError) as exc: + raise ValueError("retained terminal state is invalid") from exc + expected_state_keys = { + "schema_version", + "report_bytes_base64", + "report_sha256", + "terminal_verification_bytes_base64", + "terminal_verification_sha256", + } + if ( + not isinstance(retained_value, dict) + or set(retained_value) != expected_state_keys + or retained_value["schema_version"] + != "openadapt.production-terminal-state/v1" + or not all( + isinstance(retained_value[field], str) + for field in expected_state_keys - {"schema_version"} + ) + or canonical_json(retained_value) != retained_state + ): + raise ValueError("retained terminal state is invalid") + try: + retained_report = b64decode( + retained_value["report_bytes_base64"], validate=True + ) + retained_envelope = b64decode( + retained_value["terminal_verification_bytes_base64"], + validate=True, + ) + except (TypeError, ValueError) as exc: + raise ValueError("retained terminal state is invalid") from exc + if ( + len(retained_report) > _MAX_ARTIFACT_BYTES + or len(retained_envelope) > _MAX_ARTIFACT_BYTES + or retained_report != built.report_bytes + or hashlib.sha256(retained_report).hexdigest() + != retained_value["report_sha256"] + or hashlib.sha256(retained_envelope).hexdigest() + != retained_value["terminal_verification_sha256"] + ): + raise ValueError("a different terminal outcome is already sealed") + try: + retained_proof = ( + ProductionTerminalVerificationEnvelope.model_validate_json( + retained_envelope + ) + ) + except ValueError as exc: + raise ValueError("retained terminal state is invalid") from exc + retained_sha256 = verify_production_terminal_verification_from_report( + retained_proof, + report_bytes=retained_report, + expected=live_expected, + now=now, + ) + if ( + canonical_json(retained_proof) != retained_envelope + or retained_sha256 != retained_value["terminal_verification_sha256"] + ): + raise ValueError("retained terminal state is invalid") + state_bytes = retained_state + envelope_bytes = retained_envelope + artifact_sha256 = retained_sha256 + for path, raw, label in ( + (report_path, built.report_bytes, "production terminal report"), + (envelope_path, envelope_bytes, "production terminal verification"), + ): + try: + self._write_private_bytes_atomic_exclusive(path, raw) + except FileExistsError: + retained = self._read_private_bytes( + path, + maximum_bytes=_MAX_ARTIFACT_BYTES, + label=label, + ) + if retained != raw: + raise ValueError("a different terminal artifact is already sealed") + stored_report = self._read_private_bytes( + report_path, + maximum_bytes=_MAX_ARTIFACT_BYTES, + label="production terminal report", + ) + stored_envelope = self._read_private_bytes( + envelope_path, + maximum_bytes=_MAX_ARTIFACT_BYTES, + label="production terminal verification", + ) + if stored_report != built.report_bytes or stored_envelope != envelope_bytes: + raise ValueError("stored terminal evidence changed after write") + reread = ProductionTerminalVerificationEnvelope.model_validate_json( + stored_envelope + ) + if canonical_json(reread) != stored_envelope: + raise ValueError("stored terminal verification is not canonical") + reread_sha256 = verify_production_terminal_verification_from_report( + reread, + report_bytes=stored_report, + expected=live_expected, + now=now, + ) + if reread_sha256 != artifact_sha256: + raise ValueError("stored terminal verification digest changed") + if ( + self._read_private_bytes( + state_path, + maximum_bytes=_MAX_TERMINAL_STATE_BYTES, + label="production terminal state", + ) + != state_bytes + ): + raise ValueError("stored terminal state changed") return reread, built.report_sha256 @staticmethod @@ -1519,6 +2416,113 @@ def reconciliation_required( raise ValueError("reconciliation code is invalid") raise RuntimeError("managed run requires signed terminal reconciliation") + def recover_uncertain_run( + self, + dispatch: HostedDispatch | Mapping[str, object], + *, + runner_config: Path, + run_dir: Path, + closure_authority: HostedRunnerTransport, + ) -> HostedRunResult: + """Return or create the one signed terminal for a lost managed result. + + This path never invokes the managed child. It accepts only the exact + original dispatch, protected run store, live admissions, child-start + marker, and unresolved terminal permit. + """ + + parsed = HostedDispatch.model_validate(dispatch) + config = load_runner_config(runner_config, protected=True) + self._protected_runner_origin(config) + self._verify_product_release(parsed, config) + key = self._load_evidence_private_key(config) + qualification, deployment_bytes = self._verify_workflow_admission( + parsed, + config, + evidence_private_key=key, + ) + params = self._resolve_params(parsed, config) + run_dir = Path(run_dir) + run_stat = run_dir.lstat() + if ( + not stat.S_ISDIR(run_stat.st_mode) + or stat.S_ISLNK(run_stat.st_mode) + or ( + os.name != "nt" + and ( + run_stat.st_uid != os.geteuid() + or stat.S_IMODE(run_stat.st_mode) != 0o700 + ) + ) + ): + raise ValueError("hosted recovery run directory is not protected") + profile_path = run_dir / "deployment.yaml" + if ( + self._read_private_bytes( + profile_path, + maximum_bytes=1024 * 1024, + label="staged hosted deployment profile", + ) + != deployment_bytes + ): + raise ValueError("staged hosted deployment profile changed") + staged_profiles = dict(config.profiles) + staged_profiles[parsed.payload.deployment_profile_id] = profile_path + verified = verify_dispatch( + parsed.payload, + replace(config, profiles=staged_profiles), + resolved_params=params, + ) + if isinstance(verified, Refusal): + raise ValueError("hosted recovery dispatch no longer verifies") + self._read_child_start_evidence( + dispatch=parsed, + run_dir=run_dir, + dispatch_binding_sha256=verified.payload.dispatch_binding_sha256, + ) + reservation_key = f"{parsed.tenant_id}:{parsed.idempotency_key}" + reservation = self._ledger.lookup(reservation_key) + if reservation is None or reservation.get("run_id") != parsed.run_id: + raise ValueError("hosted recovery lacks the original reservation") + + proof, report_digest, report = self._produce_managed_result_loss( + dispatch=parsed, + workflow=verified.workflow, + run_dir=run_dir, + qualification=qualification, + private_key=key, + verified_params=params, + dispatch_binding_sha256=verified.payload.dispatch_binding_sha256, + closure_authority=closure_authority, + loss_code="recovered_after_restart", + ) + outcome = TransactionOutcome.RECONCILIATION_REQUIRED + self._ledger.record_outcome(reservation_key, outcome, run_id=parsed.run_id) + events = tuple( + report_events( + report, + run_id=parsed.run_id, + workflow_id=parsed.workflow_id, + bundle_digest=parsed.payload.bundle.content_digest, + authorization_id=parsed.payload.authorization.authorization_id, + consequential_steps=verified.consequential_steps, + effect_covered_consequential_steps=( + verified.effect_covered_consequential_steps + ), + terminal_outcome=outcome.value, + ) + ) + return HostedRunResult( + dispatch_id=parsed.dispatch_id, + run_id=parsed.run_id, + outcome=outcome, + evidence_batch=events, + terminal_verification=proof, + started=True, + uncertain_delivery=proof.payload.pending_permit_count == 1, + report_sha256=report_digest, + ) + def execute( self, dispatch: HostedDispatch | Mapping[str, object], @@ -1526,10 +2530,12 @@ def execute( runner_config: Path, run_dir: Path, authority: DeliveryAuthority, + closure_authority: HostedRunnerTransport | None = None, ) -> Union[HostedRunResult, HostedDispatchRefusal]: parsed: HostedDispatch | None = None try: parsed = HostedDispatch.model_validate(dispatch) + assert parsed is not None expiry = _utc_seconds(parsed.lease_expires_at, label="hosted lease expiry") if datetime.now(timezone.utc) >= expiry: raise ValueError("hosted lease expired before execution") @@ -1600,6 +2606,7 @@ def execute( f"prestart_{type(exc).__name__}", ) + assert parsed is not None reservation_key = f"{parsed.tenant_id}:{parsed.idempotency_key}" try: self._ledger.reserve(reservation_key, run_id=parsed.run_id) @@ -1664,26 +2671,165 @@ def execute( report_sha256="0" * 64, ) + try: + self._write_child_start_evidence( + dispatch=parsed, + run_dir=run_dir, + dispatch_binding_sha256=verified.payload.dispatch_binding_sha256, + ) + except Exception: + outcome = TransactionOutcome.FAILED_PLATFORM + self._ledger.record_outcome(reservation_key, outcome, run_id=parsed.run_id) + events = tuple( + failure_events( + run_id=parsed.run_id, + bundle_digest=parsed.payload.bundle.content_digest, + authorization_id=parsed.payload.authorization.authorization_id, + ) + ) + return HostedRunResult( + dispatch_id=parsed.dispatch_id, + run_id=parsed.run_id, + outcome=outcome, + evidence_batch=events, + started=False, + uncertain_delivery=False, + report_sha256="0" * 64, + ) + try: # Once this call starts, the child can reach a real input edge. Any # lost or malformed result is uncertain and can never be retried. execution = self._runner(argv, run_dir, child_env) - except Exception as exc: + except Exception: outcome = TransactionOutcome.RECONCILIATION_REQUIRED + try: + if closure_authority is None: + raise ValueError("hosted result-loss closure authority is absent") + terminal_key, terminal_qualification = ( + self._revalidate_terminal_authority( + dispatch=parsed, + runner_config=runner_config, + configured_origin=configured_origin, + initial_qualification=qualification, + initial_deployment_bytes=deployment_bytes, + ) + ) + exception_loss_proof, report_digest, exception_loss_report = ( + self._produce_managed_result_loss( + dispatch=parsed, + workflow=verified.workflow, + run_dir=run_dir, + qualification=terminal_qualification, + private_key=terminal_key, + verified_params=params, + dispatch_binding_sha256=verified.payload.dispatch_binding_sha256, + closure_authority=closure_authority, + loss_code="runner_exception", + ) + ) + except Exception as terminal_exc: + self._ledger.record_outcome( + reservation_key, outcome, run_id=parsed.run_id + ) + raise RuntimeError( + "managed run requires signed terminal reconciliation" + ) from terminal_exc self._ledger.record_outcome(reservation_key, outcome, run_id=parsed.run_id) - raise RuntimeError( - "managed run requires signed terminal reconciliation" - ) from exc + events = tuple( + report_events( + exception_loss_report, + run_id=parsed.run_id, + workflow_id=parsed.workflow_id, + bundle_digest=parsed.payload.bundle.content_digest, + authorization_id=parsed.payload.authorization.authorization_id, + consequential_steps=verified.consequential_steps, + effect_covered_consequential_steps=( + verified.effect_covered_consequential_steps + ), + terminal_outcome=outcome.value, + ) + ) + return HostedRunResult( + dispatch_id=parsed.dispatch_id, + run_id=parsed.run_id, + outcome=outcome, + evidence_batch=events, + terminal_verification=exception_loss_proof, + started=True, + uncertain_delivery=( + exception_loss_proof.payload.pending_permit_count == 1 + ), + report_sha256=report_digest, + ) if execution.report_bytes is None: outcome = TransactionOutcome.RECONCILIATION_REQUIRED + try: + if closure_authority is None: + raise ValueError("hosted result-loss closure authority is absent") + terminal_key, terminal_qualification = ( + self._revalidate_terminal_authority( + dispatch=parsed, + runner_config=runner_config, + configured_origin=configured_origin, + initial_qualification=qualification, + initial_deployment_bytes=deployment_bytes, + ) + ) + missing_loss_proof, report_digest, missing_loss_report = ( + self._produce_managed_result_loss( + dispatch=parsed, + workflow=verified.workflow, + run_dir=run_dir, + qualification=terminal_qualification, + private_key=terminal_key, + verified_params=params, + dispatch_binding_sha256=verified.payload.dispatch_binding_sha256, + closure_authority=closure_authority, + loss_code="report_missing", + ) + ) + except Exception as terminal_exc: + self._ledger.record_outcome( + reservation_key, outcome, run_id=parsed.run_id + ) + raise RuntimeError( + "managed run requires signed terminal reconciliation" + ) from terminal_exc self._ledger.record_outcome(reservation_key, outcome, run_id=parsed.run_id) - raise RuntimeError("managed run requires signed terminal reconciliation") + events = tuple( + report_events( + missing_loss_report, + run_id=parsed.run_id, + workflow_id=parsed.workflow_id, + bundle_digest=parsed.payload.bundle.content_digest, + authorization_id=parsed.payload.authorization.authorization_id, + consequential_steps=verified.consequential_steps, + effect_covered_consequential_steps=( + verified.effect_covered_consequential_steps + ), + terminal_outcome=outcome.value, + ) + ) + return HostedRunResult( + dispatch_id=parsed.dispatch_id, + run_id=parsed.run_id, + outcome=outcome, + evidence_batch=events, + terminal_verification=missing_loss_proof, + started=True, + uncertain_delivery=( + missing_loss_proof.payload.pending_permit_count == 1 + ), + report_sha256=report_digest, + ) report: RunReport | None = None report_digest = hashlib.sha256(execution.report_bytes).hexdigest() terminalization_error: Exception | None try: report = RunReport.model_validate_json(execution.report_bytes) + assert report is not None outcome = classify_transaction_outcome(report) proof: ProductionTerminalVerificationEnvelope | None = None if execution.terminal_verification is not None: @@ -1695,28 +2841,20 @@ def execute( }: if outcome is TransactionOutcome.VERIFIED and execution.returncode != 0: raise ValueError("managed child exited unsuccessfully") - terminal_config = load_runner_config(runner_config, protected=True) - if self._protected_runner_origin(terminal_config) != configured_origin: - raise ValueError("protected runner origin changed during execution") - self._verify_product_release(parsed, terminal_config) - terminal_key = self._load_evidence_private_key(terminal_config) - terminal_qualification, terminal_deployment = ( - self._verify_workflow_admission( - parsed, - terminal_config, - evidence_private_key=terminal_key, + terminal_key, terminal_qualification = ( + self._revalidate_terminal_authority( + dispatch=parsed, + runner_config=runner_config, + configured_origin=configured_origin, + initial_qualification=qualification, + initial_deployment_bytes=deployment_bytes, ) ) - if ( - terminal_qualification != qualification - or terminal_deployment != deployment_bytes - ): - raise ValueError("production admission changed during execution") proof, report_digest = self._produce_terminal_verification( dispatch=parsed, report=report, run_dir=run_dir, - qualification=qualification, + qualification=terminal_qualification, private_key=terminal_key, verified_params=params, dispatch_binding_sha256=verified.payload.dispatch_binding_sha256, @@ -1763,7 +2901,7 @@ def execute( terminal_outcome=outcome.value, ) ) - uncertain = outcome is TransactionOutcome.RECONCILIATION_REQUIRED + uncertain = bool(proof is not None and proof.payload.pending_permit_count == 1) return HostedRunResult( dispatch_id=parsed.dispatch_id, run_id=parsed.run_id, diff --git a/openadapt_flow/terminal_verification_v2.py b/openadapt_flow/terminal_verification_v2.py index ec6d86c2..6d531024 100644 --- a/openadapt_flow/terminal_verification_v2.py +++ b/openadapt_flow/terminal_verification_v2.py @@ -34,6 +34,7 @@ from openadapt_flow.ir import ( EffectVerificationEvidence, + ManagedResultLossEvidence, PostconditionContractEvidence, RunReport, ) @@ -96,6 +97,18 @@ EXECUTION_AUTHORITY_SCHEMA: Final[ Literal["openadapt.production-execution-authority/v2"] ] = "openadapt.production-execution-authority/v2" +RESULT_LOSS_CLOSURE_REQUEST_DOMAIN: Final[bytes] = ( + b"openadapt.production-delivery-result-loss-closure-request.v2\0" +) +RESULT_LOSS_CLOSURE_PAYLOAD_DOMAIN: Final[bytes] = ( + b"openadapt.production-delivery-result-loss-closure-payload.v2\0" +) +RESULT_LOSS_CLOSURE_PAYLOAD_SCHEMA: Final[ + Literal["openadapt.production-delivery-result-loss-closure-payload/v2"] +] = "openadapt.production-delivery-result-loss-closure-payload/v2" +RESULT_LOSS_CLOSURE_ARTIFACT_SCHEMA: Final[ + Literal["openadapt.production-delivery-result-loss-closure-artifact/v2"] +] = "openadapt.production-delivery-result-loss-closure-artifact/v2" _SHA256_RE = re.compile(r"^[a-f0-9]{64}$") _UUID_RE = re.compile( @@ -178,7 +191,7 @@ class ProductionExecutionOutcome(ClosedSignedModel): passed_contracts: TerminalContractCounts workflow_contract_sha256: str = Field(pattern=_SHA256_RE) postcondition_evidence: tuple[PostconditionContractEvidence, ...] = Field( - min_length=1, max_length=10_000 + max_length=10_000 ) evidence_classes: tuple[ Literal[ @@ -195,9 +208,15 @@ class ProductionExecutionOutcome(ClosedSignedModel): model_calls: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) external_network_calls: Literal["none", "observed"] compensation_actions: StrictInt = Field(default=0, ge=0, le=JS_MAX_SAFE_INTEGER) + managed_result_loss_evidence_sha256: str | None = Field( + default=None, + pattern=_SHA256_RE, + exclude_if=lambda value: value is None, + ) @model_validator(mode="after") def _complete_terminal_outcome(self) -> "ProductionExecutionOutcome": + result_loss = self.managed_result_loss_evidence_sha256 is not None required = self.required_contracts.model_dump(mode="python") passed = self.passed_contracts.model_dump(mode="python") if any(passed[key] > required[key] for key in required): @@ -206,6 +225,8 @@ def _complete_terminal_outcome(self) -> "ProductionExecutionOutcome": raise ValueError("terminal outcome requires one authorization") if self.passed_contracts.authorization != 1: raise ValueError("terminal outcome requires one passed authorization") + if not result_loss and not self.postcondition_evidence: + raise ValueError("ordinary terminal outcome requires a postcondition") if len(self.postcondition_evidence) != self.required_contracts.postcondition: raise ValueError("terminal postcondition evidence cardinality is invalid") if ( @@ -276,6 +297,22 @@ def _complete_terminal_outcome(self) -> "ProductionExecutionOutcome": raise ValueError("only a VERIFIED terminal outcome is production eligible") elif self.outcome == "HALTED" and self.execution_completed: raise ValueError("terminal HALTED outcome cannot claim completed execution") + if result_loss and ( + self.outcome != "HALTED" + or self.production_eligible + or self.execution_completed + or self.required_contracts + != TerminalContractCounts( + authorization=1, + identity=0, + postcondition=0, + effect=0, + ) + or self.passed_contracts != self.required_contracts + or self.postcondition_evidence + or self.evidence_classes != ("authorization",) + ): + raise ValueError("managed result loss execution outcome is invalid") return self def artifact_sha256(self) -> str: @@ -340,9 +377,9 @@ class ProductionRunReceipt(ClosedSignedModel): ] authorization_required: StrictInt = Field(ge=1, le=JS_MAX_SAFE_INTEGER) authorization_confirmed: StrictInt = Field(ge=1, le=JS_MAX_SAFE_INTEGER) - identity_required: StrictInt = Field(ge=1, le=JS_MAX_SAFE_INTEGER) + identity_required: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) identity_confirmed: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) - postconditions_required: StrictInt = Field(ge=1, le=JS_MAX_SAFE_INTEGER) + postconditions_required: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) postconditions_confirmed: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) effects_required: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) effects_confirmed: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) @@ -359,9 +396,15 @@ class ProductionRunReceipt(ClosedSignedModel): source_receipt_digest: str = Field(pattern=_SHA256_RE) source_receipt_sha256: str = Field(pattern=_SHA256_RE) generated_at: str = Field(pattern=r"^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:00:00Z$") + managed_result_loss_evidence_sha256: str | None = Field( + default=None, + pattern=_SHA256_RE, + exclude_if=lambda value: value is None, + ) @model_validator(mode="after") def _closed_receipt(self) -> "ProductionRunReceipt": + result_loss = self.managed_result_loss_evidence_sha256 is not None for label, required, confirmed in ( ( "authorization", @@ -382,6 +425,12 @@ def _closed_receipt(self) -> "ProductionRunReceipt": raise ValueError("terminal receipt requires one authorization") if self.authorization_confirmed != 1: raise ValueError("terminal receipt requires one passed authorization") + if not result_loss and ( + self.identity_required < 1 or self.postconditions_required < 1 + ): + raise ValueError( + "ordinary terminal receipt requires identity and postcondition contracts" + ) if self.steps_ok > self.steps_total: raise ValueError("terminal receipt successful step count is invalid") if self.evidence_classes != tuple(sorted(self.evidence_classes)) or len( @@ -454,6 +503,23 @@ def _closed_receipt(self) -> "ProductionRunReceipt": or self.effect_tier_reached != "none" ): raise ValueError("HALTED terminal receipt does not prove no effect") + if result_loss and ( + self.transaction_outcome != "RECONCILIATION_REQUIRED" + or self.outcome != "HALTED" + or self.production_eligible + or self.source_schema_version != "openadapt.run-report/v1" + or self.steps_total != 1 + or self.steps_ok != 0 + or self.identity_required != 0 + or self.identity_confirmed != 0 + or self.postconditions_required != 0 + or self.postconditions_confirmed != 0 + or self.effects_required != 0 + or self.effects_confirmed != 0 + or self.evidence_classes != ("authorization",) + or self.effect_tier_reached != "none" + ): + raise ValueError("managed result loss receipt is invalid") return self @@ -621,6 +687,11 @@ def project_production_terminal_run_receipt( "source_receipt_digest": report_sha256, "source_receipt_sha256": report_sha256, "generated_at": _hour_utc(report.started_at), + "managed_result_loss_evidence_sha256": ( + report.managed_result_loss.evidence_sha256 + if report.managed_result_loss is not None + else None + ), } ) except (TypeError, ValueError) as exc: @@ -707,6 +778,11 @@ def prepare_production_terminal_evidence( "model_calls": envelope.model_calls, "external_network_calls": envelope.external_network_calls, "compensation_actions": envelope.compensation_actions, + "managed_result_loss_evidence_sha256": ( + validated.managed_result_loss.evidence_sha256 + if validated.managed_result_loss is not None + else None + ), } ) except (ReceiptError, ValueError) as exc: @@ -1309,6 +1385,149 @@ def artifact_sha256(self) -> str: return hashlib.sha256(self.canonical_bytes()).hexdigest() +class ProductionDeliveryResultLossClosurePayload(ClosedSignedModel): + """Cloud authority fence for one managed child result loss.""" + + schema_version: Literal[ + "openadapt.production-delivery-result-loss-closure-payload/v2" + ] = RESULT_LOSS_CLOSURE_PAYLOAD_SCHEMA + closure_id: str = Field(pattern=_UUID_RE) + closure_sequence: Literal[1] = 1 + closure_request_sha256: str = Field(pattern=_SHA256_RE) + closed_at: str + result_loss_observed_at: str + receipt_absence_observed_at: str | None = None + tenant_id: str = Field(pattern=_UUID_RE) + run_id: str = Field(pattern=_UUID_RE) + flow_run_id_sha256: str = Field(pattern=_SHA256_RE) + dispatch_id: str = Field(pattern=_UUID_RE) + dispatch_session_id: str = Field(pattern=_UUID_RE) + managed_dispatch_binding_sha256: str = Field(pattern=r"^sha256:[a-f0-9]{64}$") + idempotency_key_sha256: str = Field(pattern=_SHA256_RE) + authenticated_runner_id_sha256: str = Field(pattern=_SHA256_RE) + authenticated_session_id_sha256: str = Field(pattern=_SHA256_RE) + execution_authority_id: str = Field(pattern=_UUID_RE) + execution_authority_sha256: str = Field(pattern=_SHA256_RE) + execution_authority_signer_sha256: str = Field(pattern=_SHA256_RE) + child_started_at: str + child_start_evidence_sha256: str = Field(pattern=_SHA256_RE) + run_store_identity_sha256: str = Field(pattern=_SHA256_RE) + permit_chain_sha256: str = Field(pattern=_SHA256_RE) + permit_count: StrictInt = Field(ge=1, le=JS_MAX_SAFE_INTEGER) + acknowledged_permit_count: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) + pending_permit_count: StrictInt = Field(ge=0, le=1) + pending_permit_artifact_sha256: str | None = Field( + default=None, + pattern=_SHA256_RE, + ) + run_request_sha256: str = Field(pattern=_SHA256_RE) + pending_action_request_sha256: str | None = Field( + default=None, + pattern=_SHA256_RE, + ) + final_input_edge_sequence: StrictInt = Field(ge=1, le=JS_MAX_SAFE_INTEGER) + final_authority_sequence: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) + final_runtime_delivery_sequence: StrictInt = Field(ge=0, le=JS_MAX_SAFE_INTEGER) + delivery_state: Literal["CLOSED_UNRESOLVED_RESULT_LOSS"] = ( + "CLOSED_UNRESOLVED_RESULT_LOSS" + ) + effect_absence_claimed: Literal[False] = False + not_received_claimed: Literal[False] = False + blind_retry_authorized: Literal[False] = False + actuation_replay_authorized: Literal[False] = False + new_permit_authorized: Literal[False] = False + delivery_acknowledgment_authorized: Literal[False] = False + terminal_callback_required: Literal[True] = True + + @model_validator(mode="after") + def _closed_result_loss_fence(self) -> "ProductionDeliveryResultLossClosurePayload": + if hashlib.sha256(self.run_id.encode("utf-8")).hexdigest() != ( + self.flow_run_id_sha256 + ): + raise ValueError("result-loss closure run identity digest is invalid") + if self.permit_count != ( + self.acknowledged_permit_count + self.pending_permit_count + ): + raise ValueError("result-loss closure permit counts are inconsistent") + has_pending = self.pending_permit_count == 1 + if has_pending != (self.pending_permit_artifact_sha256 is not None): + raise ValueError("result-loss closure pending permit binding is incomplete") + if has_pending != (self.pending_action_request_sha256 is not None): + raise ValueError("result-loss closure pending action binding is incomplete") + if has_pending != (self.receipt_absence_observed_at is not None): + raise ValueError( + "result-loss closure receipt-absence binding is incomplete" + ) + child_started = _parse_utc( + self.child_started_at, + field="result-loss closure child_started_at", + ) + observed = _parse_utc( + self.result_loss_observed_at, + field="result-loss closure result_loss_observed_at", + ) + closed = _parse_utc(self.closed_at, field="result-loss closure closed_at") + if not child_started <= observed <= closed: + raise ValueError("result-loss closure chronology is invalid") + if self.receipt_absence_observed_at is not None: + absence = _parse_utc( + self.receipt_absence_observed_at, + field="result-loss closure receipt_absence_observed_at", + ) + if absence != observed: + raise ValueError( + "result-loss closure receipt absence differs from observation" + ) + return self + + def canonical_bytes(self) -> bytes: + return canonical_json(self) + + def payload_sha256(self) -> str: + return hashlib.sha256( + RESULT_LOSS_CLOSURE_PAYLOAD_DOMAIN + self.canonical_bytes() + ).hexdigest() + + +class ProductionDeliveryResultLossClosureArtifact(ClosedSignedModel): + schema_version: Literal[ + "openadapt.production-delivery-result-loss-closure-artifact/v2" + ] = RESULT_LOSS_CLOSURE_ARTIFACT_SCHEMA + payload: ProductionDeliveryResultLossClosurePayload + payload_sha256: str = Field(pattern=_SHA256_RE) + signer: DeliveryAuthoritySigner + signature: str = Field(min_length=86, max_length=86) + + @field_validator("signature") + @classmethod + def _canonical_signature(cls, value: str) -> str: + _decode_ed25519_signature(value, field="delivery result-loss closure") + return value + + @model_validator(mode="after") + def _verify_artifact(self) -> "ProductionDeliveryResultLossClosureArtifact": + payload = ProductionDeliveryResultLossClosurePayload.model_validate( + self.payload.model_dump(mode="json") + ) + if self.payload_sha256 != payload.payload_sha256(): + raise ValueError("delivery result-loss closure payload digest is invalid") + if self.signer.signer_sha256() != payload.execution_authority_signer_sha256: + raise ValueError("delivery result-loss closure signer is invalid") + _verify_authority_signature( + self.signer, + self.signature, + RESULT_LOSS_CLOSURE_PAYLOAD_DOMAIN + payload.canonical_bytes(), + field="delivery result-loss closure", + ) + return self + + def canonical_bytes(self) -> bytes: + return canonical_json(self) + + def artifact_sha256(self) -> str: + return hashlib.sha256(self.canonical_bytes()).hexdigest() + + def _decode_ed25519_signature(value: str, *, field: str) -> bytes: try: decoded = urlsafe_b64decode(value + "==") @@ -1382,6 +1601,26 @@ def sign_production_delivery_receipt( ) +def sign_production_delivery_result_loss_closure( + payload: ProductionDeliveryResultLossClosurePayload, + private_key: Ed25519PrivateKey, +) -> ProductionDeliveryResultLossClosureArtifact: + """Sign one monotonic result-loss closure with the delivery authority.""" + + payload = ProductionDeliveryResultLossClosurePayload.model_validate( + payload.model_dump(mode="json") + ) + signature = private_key.sign( + RESULT_LOSS_CLOSURE_PAYLOAD_DOMAIN + payload.canonical_bytes() + ) + return ProductionDeliveryResultLossClosureArtifact( + payload=payload, + payload_sha256=payload.payload_sha256(), + signer=_authority_signer(private_key), + signature=urlsafe_b64encode(signature).decode("ascii").rstrip("="), + ) + + class ProductionDeliveryPermit(ClosedSignedModel): """One acknowledged input edge in the terminal permit chain.""" @@ -1819,6 +2058,153 @@ def build( return cls(entries=entries, pending=pending, permit_chain_sha256=digest) +def verify_production_delivery_result_loss_closure_binding( + artifact: ProductionDeliveryResultLossClosureArtifact, + *, + permit_chain: ProductionDeliveryPermitChain, + result_loss: ManagedResultLossEvidence, + tenant_id: str, + terminal_verified_at: str, +) -> str: + """Verify one signed authority fence against the exact terminal snapshot.""" + + artifact = ProductionDeliveryResultLossClosureArtifact.model_validate( + artifact.model_dump(mode="json") + ) + permit_chain = ProductionDeliveryPermitChain.model_validate( + permit_chain.model_dump(mode="json") + ) + if not permit_chain.entries and permit_chain.pending is None: + raise ValueError("result-loss closure requires at least one permit") + payload = artifact.payload + all_permits: tuple[ + ProductionDeliveryPermit | ProductionPendingDeliveryPermit, ... + ] = ( + *permit_chain.entries, + *((permit_chain.pending,) if permit_chain.pending is not None else ()), + ) + first = all_permits[0] + final = all_permits[-1] + final_acknowledged = permit_chain.entries[-1] if permit_chain.entries else None + pending = permit_chain.pending + expected_pending_digest = ( + pending.permit_artifact_sha256 if pending is not None else None + ) + expected_pending_action = pending.action_request_sha256 if pending else None + expected_receipt_absence = ( + pending.receipt_absence_observed_at if pending is not None else None + ) + if ( + payload.tenant_id, + payload.run_id, + payload.flow_run_id_sha256, + payload.dispatch_id, + payload.dispatch_session_id, + payload.managed_dispatch_binding_sha256, + payload.idempotency_key_sha256, + payload.authenticated_runner_id_sha256, + payload.authenticated_session_id_sha256, + payload.execution_authority_id, + payload.execution_authority_sha256, + payload.execution_authority_signer_sha256, + payload.child_started_at, + payload.child_start_evidence_sha256, + payload.run_store_identity_sha256, + ) != ( + tenant_id, + result_loss.run_id, + result_loss.flow_run_id_sha256, + result_loss.dispatch_id, + result_loss.dispatch_session_id, + result_loss.managed_dispatch_binding_sha256, + result_loss.idempotency_key_sha256, + result_loss.authenticated_runner_id_sha256, + result_loss.authenticated_session_id_sha256, + result_loss.execution_authority_id, + result_loss.execution_authority_sha256, + result_loss.execution_authority_signer_sha256, + result_loss.child_started_at, + result_loss.child_start_evidence_sha256, + result_loss.run_store_identity_sha256, + ): + raise ValueError("result-loss closure identity binding is invalid") + if ( + payload.permit_chain_sha256, + payload.permit_count, + payload.acknowledged_permit_count, + payload.pending_permit_count, + payload.pending_permit_artifact_sha256, + payload.run_request_sha256, + payload.pending_action_request_sha256, + payload.final_input_edge_sequence, + payload.final_authority_sequence, + payload.final_runtime_delivery_sequence, + payload.receipt_absence_observed_at, + ) != ( + permit_chain.permit_chain_sha256, + len(all_permits), + len(permit_chain.entries), + 1 if pending is not None else 0, + expected_pending_digest, + first.run_request_sha256, + expected_pending_action, + final.input_edge_sequence, + final.authority_sequence, + final_acknowledged.runtime_delivery_sequence + if final_acknowledged is not None + else 0, + expected_receipt_absence, + ): + raise ValueError("result-loss closure delivery snapshot is invalid") + if ( + result_loss.delivery_result_loss_closure_artifact_sha256 + != artifact.artifact_sha256() + or result_loss.observed_at != payload.result_loss_observed_at + or result_loss.pending_permit_artifact_sha256 != expected_pending_digest + or result_loss.run_request_sha256 != first.run_request_sha256 + or result_loss.pending_action_request_sha256 != expected_pending_action + ): + raise ValueError("result-loss evidence differs from its authority closure") + child_started = _parse_utc( + result_loss.child_started_at, + field="managed child started_at", + ) + first_issued = _parse_utc(first.issued_at, field="first permit issued_at") + observed = _parse_utc( + result_loss.observed_at, + field="managed result loss observed_at", + ) + closed = _parse_utc(payload.closed_at, field="result-loss closure closed_at") + terminal_verified = _parse_utc( + terminal_verified_at, + field="terminal verified_at", + ) + registry_expires = _parse_utc( + first.qualification_signer_registry_expires_at, + field="result-loss closure registry expires_at", + ) + if not child_started <= first_issued <= observed <= closed <= terminal_verified: + raise ValueError("result-loss closure chronology is invalid") + if not terminal_verified < registry_expires: + raise ValueError("result-loss closure signer registry is expired") + if any( + _parse_utc(item.issued_at, field="permit issued_at") > closed + or _parse_utc(item.delivered_at, field="permit delivered_at") > closed + for item in permit_chain.entries + ): + raise ValueError("result-loss closure excludes an acknowledged permit") + if ( + pending is not None + and _parse_utc( + pending.issued_at, + field="pending permit issued_at", + ) + > observed + ): + raise ValueError("result-loss closure pending permit chronology is invalid") + return artifact.artifact_sha256() + + def build_production_evidence_manifests( prepared: PreparedProductionTerminalEvidence, *, @@ -2091,6 +2477,16 @@ class ProductionTerminalVerificationPayload(ClosedSignedModel): run_report_object_version: str = Field(pattern=_ID_RE) run_report_object_sha256: str = Field(pattern=_SHA256_RE) evidence_manifests: ProductionEvidenceManifests + managed_result_loss: ManagedResultLossEvidence | None = Field( + default=None, + exclude_if=lambda value: value is None, + ) + delivery_result_loss_closure: ProductionDeliveryResultLossClosureArtifact | None = ( + Field( + default=None, + exclude_if=lambda value: value is None, + ) + ) verified_at: str issued_at: str @@ -2243,6 +2639,55 @@ def _closed_terminal_outcome(self) -> "ProductionTerminalVerificationPayload": "terminal run receipt does not match its execution outcome" ) transaction_outcome = receipt.transaction_outcome + result_loss = self.managed_result_loss + result_loss_closure = self.delivery_result_loss_closure + if (result_loss is not None) != ( + receipt.managed_result_loss_evidence_sha256 is not None + ): + raise ValueError("managed result loss receipt binding is incomplete") + if (result_loss is not None) != (result_loss_closure is not None): + raise ValueError("managed result loss authority closure is incomplete") + if result_loss is not None: + pending = chain.pending + if ( + transaction_outcome != "RECONCILIATION_REQUIRED" + or self.permit_count < 1 + or result_loss.evidence_sha256 + != receipt.managed_result_loss_evidence_sha256 + or result_loss.evidence_sha256 + != outcome.managed_result_loss_evidence_sha256 + or result_loss.run_id != self.run_id + or result_loss.flow_run_id_sha256 != self.flow_run_id_sha256 + or result_loss.execution_authority_id != self.execution_authority_id + or result_loss.execution_authority_sha256 + != self.execution_authority_sha256 + or result_loss.execution_authority_signer_sha256 + != self.execution_authority_signer_sha256 + or result_loss.pending_permit_artifact_sha256 + != (pending.permit_artifact_sha256 if pending is not None else None) + or result_loss.run_request_sha256 + != (chain.pending or chain.entries[0]).run_request_sha256 + or result_loss.pending_action_request_sha256 + != (pending.action_request_sha256 if pending is not None else None) + or manifests.identity.required != 0 + or manifests.identity.confirmed != 0 + or manifests.identity.results + or manifests.postcondition.required != 0 + or manifests.postcondition.confirmed != 0 + or manifests.postcondition.records + or manifests.effect.required != 0 + or manifests.effect.confirmed != 0 + or manifests.effect.records + ): + raise ValueError("managed result loss terminal binding is invalid") + assert result_loss_closure is not None + verify_production_delivery_result_loss_closure_binding( + result_loss_closure, + permit_chain=chain, + result_loss=result_loss, + tenant_id=self.tenant_id, + terminal_verified_at=self.verified_at, + ) if transaction_outcome == "VERIFIED": if ( outcome.outcome != "VERIFIED" @@ -2274,7 +2719,9 @@ def _closed_terminal_outcome(self) -> "ProductionTerminalVerificationPayload": or self.permit_count < 1 ): raise ValueError("terminal reconciliation proof is invalid") - if chain.pending is not None: + if result_loss is not None: + pass + elif chain.pending is not None: uncertain_records = tuple( item for item in manifests.effect.records @@ -2464,6 +2911,16 @@ class ProductionTerminalVerificationExpected(ClosedSignedModel): run_report_object_version: str = Field(pattern=_ID_RE) run_report_object_sha256: str = Field(pattern=_SHA256_RE) evidence_manifests: ProductionEvidenceManifests + managed_result_loss: ManagedResultLossEvidence | None = Field( + default=None, + exclude_if=lambda value: value is None, + ) + delivery_result_loss_closure: ProductionDeliveryResultLossClosureArtifact | None = ( + Field( + default=None, + exclude_if=lambda value: value is None, + ) + ) @model_validator(mode="after") def _closed_delivery_state(self) -> "ProductionTerminalVerificationExpected": @@ -2482,6 +2939,12 @@ def _closed_delivery_state(self) -> "ProductionTerminalVerificationExpected": self.pending_permit_count == 1 ): raise ValueError("live pending delivery binding is inconsistent") + if (self.managed_result_loss is not None) != ( + self.delivery_result_loss_closure is not None + ): + raise ValueError("live managed result loss closure is incomplete") + if self.managed_result_loss is not None and self.permit_count < 1: + raise ValueError("live managed result loss lacks a retained permit") for claim_id in self.acknowledged_one_use_claim_ids: if _UUID_RE.fullmatch(claim_id) is None: raise ValueError("live delivery claim id is invalid") @@ -2518,6 +2981,12 @@ class ProductionTerminalVerificationContext(ClosedSignedModel): execution_authority_sha256: str = Field(pattern=_SHA256_RE) execution_authority_signer_sha256: str = Field(pattern=_SHA256_RE) permit_chain: ProductionDeliveryPermitChain + delivery_result_loss_closure: ProductionDeliveryResultLossClosureArtifact | None = ( + Field( + default=None, + exclude_if=lambda value: value is None, + ) + ) run_report_object_version: str = Field(pattern=_ID_RE) verified_at: str issued_at: str @@ -2670,6 +3139,8 @@ def build_production_terminal_verification( run_report_object_version=context.run_report_object_version, run_report_object_sha256=prepared.report_sha256, evidence_manifests=manifests, + managed_result_loss=prepared.report.managed_result_loss, + delivery_result_loss_closure=context.delivery_result_loss_closure, verified_at=context.verified_at, issued_at=context.issued_at, ) diff --git a/openadapt_flow/transaction.py b/openadapt_flow/transaction.py index 9ce2de2b..c55b2ace 100644 --- a/openadapt_flow/transaction.py +++ b/openadapt_flow/transaction.py @@ -323,6 +323,14 @@ def classify_transaction_outcome(report: RunReport) -> TransactionOutcome: stopped (policy rejection, cancellation, governed halt, platform fault). """ + if report.managed_result_loss is not None: + # The outer hosted runner fenced the exact delivery chain but lost the + # managed child's terminal result. A delivery acknowledgment can win + # before that fence, so this is neither effect absence nor a platform + # failure. The signed loss record exists only to force reconciliation + # and prohibit retry. + return TransactionOutcome.RECONCILIATION_REQUIRED + coarse = report.execution_outcome if coarse == "VERIFIED": return TransactionOutcome.VERIFIED diff --git a/public-artifacts.json b/public-artifacts.json index a5abef09..8eb6f4c5 100644 --- a/public-artifacts.json +++ b/public-artifacts.json @@ -5785,7 +5785,7 @@ }, { "path": "tests/fixtures/terminal_verification_v2_terminal_vectors.json", - "sha256": "82d609a0c29593c91ec42b9416a64d6432fad47e3898bbfb926e76f7598f91df" + "sha256": "314c902ca5420d312626d521cec05652848f503e76226cb7168ed2384c759376" }, { "path": "tests/fixtures/theme-region-stable-overhalt-v1.16.1.json", diff --git a/scripts/generate_terminal_verification_v2_vectors.py b/scripts/generate_terminal_verification_v2_vectors.py index 2b7ea7f3..e02cb3c2 100644 --- a/scripts/generate_terminal_verification_v2_vectors.py +++ b/scripts/generate_terminal_verification_v2_vectors.py @@ -13,29 +13,43 @@ from openadapt_flow.qualification_admission_v2 import canonical_json from openadapt_flow.terminal_verification_v2 import ( + RESULT_LOSS_CLOSURE_PAYLOAD_DOMAIN, + RESULT_LOSS_CLOSURE_REQUEST_DOMAIN, SIGNATURE_DOMAIN, evidence_runner_key_id, evidence_runner_signer_sha256, sign_production_terminal_verification, ) from tests.test_terminal_verification_v2 import ( + _acknowledged_reconciliation_payload, _halted_payload, + _managed_result_loss_acknowledged_payload, + _managed_result_loss_payload, + _payload, _private_key, _reconciliation_payload, + _result_loss_request, ) DEFAULT_OUTPUT = Path("tests/fixtures/terminal_verification_v2_terminal_vectors.json") def _vector(name: str, *, uncertain_delivery: bool) -> dict[str, object]: - payload = ( - _halted_payload() - if name == "halted-before-effect-zero-permit" - else _reconciliation_payload() - ) + payload = { + "verified-complete": _payload, + "halted-before-effect-zero-permit": _halted_payload, + "reconciliation-required-pending-permit": _reconciliation_payload, + "reconciliation-required-acknowledged-inconclusive": ( + _acknowledged_reconciliation_payload + ), + "reconciliation-required-managed-result-loss": _managed_result_loss_payload, + "reconciliation-required-managed-result-loss-acknowledged": ( + _managed_result_loss_acknowledged_payload + ), + }[name]() envelope = sign_production_terminal_verification(payload, _private_key()) raw = canonical_json(envelope) - effect_state = payload.evidence_manifests.effect.records[0] + effect_records = payload.evidence_manifests.effect.records return { "callback": { "artifact_bytes_source": "envelope_canonical_base64", @@ -46,7 +60,9 @@ def _vector(name: str, *, uncertain_delivery: bool) -> dict[str, object]: "started": True, "uncertain_delivery": uncertain_delivery, }, - "effect_state": effect_state.model_dump(mode="json"), + "effect_state": ( + effect_records[0].model_dump(mode="json") if effect_records else None + ), "envelope_canonical_base64": b64encode(raw).decode("ascii"), "name": name, "payload_canonical_sha256": hashlib.sha256( @@ -54,6 +70,11 @@ def _vector(name: str, *, uncertain_delivery: bool) -> dict[str, object]: ).hexdigest(), "signature": envelope.signature, "terminal_verification_artifact_sha256": envelope.artifact_sha256(), + "managed_result_loss": ( + payload.managed_result_loss.model_dump(mode="json") + if payload.managed_result_loss is not None + else None + ), } @@ -68,6 +89,22 @@ def build_fixture() -> dict[str, object]: encoding=serialization.Encoding.Raw, format=serialization.PublicFormat.Raw, ) + managed = _managed_result_loss_payload() + request = _result_loss_request() + closure = managed.delivery_result_loss_closure + assert closure is not None + closure_raw = canonical_json(closure) + chain_raw = canonical_json(managed.permit_chain) + closure_result = { + "schema_version": ( + "openadapt.production-delivery-result-loss-closure-result/v2" + ), + "status": "closed", + "closure_artifact_bytes_base64": b64encode(closure_raw).decode("ascii"), + "closure_artifact_sha256": closure.artifact_sha256(), + "permit_chain_bytes_base64": b64encode(chain_raw).decode("ascii"), + "permit_chain_sha256": managed.permit_chain.permit_chain_sha256, + } return { "key_id": evidence_runner_key_id(public_bytes), "private_key_base64": b64encode(private_bytes).decode("ascii"), @@ -75,7 +112,34 @@ def build_fixture() -> dict[str, object]: "schema_version": "openadapt.production-terminal-cross-language-vectors/v2", "signature_domain_base64": b64encode(SIGNATURE_DOMAIN).decode("ascii"), "signer_sha256": evidence_runner_signer_sha256(public_bytes), + "managed_result_loss_closure_vector": { + "http_method": "POST", + "http_route": "/api/internal/managed-delivery-result-loss-closure", + "authorization_credential_source": "hosted_dispatch.lease_token", + "request_digest_domain_base64": b64encode( + RESULT_LOSS_CLOSURE_REQUEST_DOMAIN + ).decode("ascii"), + "request_canonical_base64": b64encode(request.canonical_bytes()).decode( + "ascii" + ), + "request_sha256": request.request_sha256(), + "payload_signature_domain_base64": b64encode( + RESULT_LOSS_CLOSURE_PAYLOAD_DOMAIN + ).decode("ascii"), + "closure_payload_sha256": closure.payload_sha256, + "closure_artifact_canonical_base64": b64encode(closure_raw).decode("ascii"), + "closure_artifact_sha256": closure.artifact_sha256(), + "permit_chain_canonical_base64": b64encode(chain_raw).decode("ascii"), + "permit_chain_sha256": managed.permit_chain.permit_chain_sha256, + "result_canonical_base64": b64encode(canonical_json(closure_result)).decode( + "ascii" + ), + }, "vectors": [ + _vector( + "verified-complete", + uncertain_delivery=False, + ), _vector( "halted-before-effect-zero-permit", uncertain_delivery=False, @@ -84,6 +148,18 @@ def build_fixture() -> dict[str, object]: "reconciliation-required-pending-permit", uncertain_delivery=True, ), + _vector( + "reconciliation-required-acknowledged-inconclusive", + uncertain_delivery=False, + ), + _vector( + "reconciliation-required-managed-result-loss", + uncertain_delivery=True, + ), + _vector( + "reconciliation-required-managed-result-loss-acknowledged", + uncertain_delivery=False, + ), ], } diff --git a/tests/fixtures/terminal_verification_v2_terminal_vectors.json b/tests/fixtures/terminal_verification_v2_terminal_vectors.json index 5d7ceabc..e175c30f 100644 --- a/tests/fixtures/terminal_verification_v2_terminal_vectors.json +++ b/tests/fixtures/terminal_verification_v2_terminal_vectors.json @@ -1,11 +1,53 @@ { "key_id": "evidence-runner-ed25519-56475aa75463474c", + "managed_result_loss_closure_vector": { + "authorization_credential_source": "hosted_dispatch.lease_token", + "closure_artifact_canonical_base64": "eyJwYXlsb2FkIjp7ImFja25vd2xlZGdlZF9wZXJtaXRfY291bnQiOjAsImFjdHVhdGlvbl9yZXBsYXlfYXV0aG9yaXplZCI6ZmFsc2UsImF1dGhlbnRpY2F0ZWRfcnVubmVyX2lkX3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJhdXRoZW50aWNhdGVkX3Nlc3Npb25faWRfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsImJsaW5kX3JldHJ5X2F1dGhvcml6ZWQiOmZhbHNlLCJjaGlsZF9zdGFydF9ldmlkZW5jZV9zaGEyNTYiOiI2NWE2YmVkOTIzZTQ1YTZhYTBjNjI0MzA0NWUwMzY0YzkwYWNlMDY0OGZlY2I1YjBiYjJlYmQ5NDAyNzkzYzc3IiwiY2hpbGRfc3RhcnRlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDBaIiwiY2xvc2VkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMloiLCJjbG9zdXJlX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDExIiwiY2xvc3VyZV9yZXF1ZXN0X3NoYTI1NiI6ImJhZjQxN2FlNDhlZWM0MDY1ODRlZjUyODZhYWExYjFhYzJlNmUwM2Q4YTI5YTRmYjRiMGM1MzI3MDRiZTU5YzYiLCJjbG9zdXJlX3NlcXVlbmNlIjoxLCJkZWxpdmVyeV9hY2tub3dsZWRnbWVudF9hdXRob3JpemVkIjpmYWxzZSwiZGVsaXZlcnlfc3RhdGUiOiJDTE9TRURfVU5SRVNPTFZFRF9SRVNVTFRfTE9TUyIsImRpc3BhdGNoX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA5IiwiZGlzcGF0Y2hfc2Vzc2lvbl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAxMCIsImVmZmVjdF9hYnNlbmNlX2NsYWltZWQiOmZhbHNlLCJleGVjdXRpb25fYXV0aG9yaXR5X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA4IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaWduZXJfc2hhMjU2IjoiMjRmNmVkNmFjYmZlMTAwOWMwMzBkN2NhNTY3YzMzY2E0ODMwOTExNDk4MjM2YjU1NjFhNmM4MmFiZWM1ZGUyOCIsImZpbmFsX2F1dGhvcml0eV9zZXF1ZW5jZSI6MCwiZmluYWxfaW5wdXRfZWRnZV9zZXF1ZW5jZSI6MSwiZmluYWxfcnVudGltZV9kZWxpdmVyeV9zZXF1ZW5jZSI6MCwiZmxvd19ydW5faWRfc2hhMjU2IjoiMTFlNTk0ZjQ4MTk1OGMxMGUzMDE1ZDBiZjA0NDdhMjJmMDY4YThhNjQ3ZjQ3NWRmMTVjZTJjN2FiNGI4ZjNmMSIsImlkZW1wb3RlbmN5X2tleV9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwibWFuYWdlZF9kaXNwYXRjaF9iaW5kaW5nX3NoYTI1NiI6InNoYTI1NjpjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwibmV3X3Blcm1pdF9hdXRob3JpemVkIjpmYWxzZSwibm90X3JlY2VpdmVkX2NsYWltZWQiOmZhbHNlLCJwZW5kaW5nX2FjdGlvbl9yZXF1ZXN0X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJwZW5kaW5nX3Blcm1pdF9hcnRpZmFjdF9zaGEyNTYiOiI5NzJhODJhZjQ1NmRhNTQyYmFjNzg0NjAxODg5NjY4ODkxZDhiN2NjZDI0MjkwNDgxNmIzMjkyZTE1N2U1Mjg5IiwicGVuZGluZ19wZXJtaXRfY291bnQiOjEsInBlcm1pdF9jaGFpbl9zaGEyNTYiOiI1OWIzOTk3MWUzMDUxMDljNTQyOTk0NWE1ZmFiNDY2MGIwOWY0MWU3YWMzZmZkOTJlMzUwNmFmMDAzMzdkYTk1IiwicGVybWl0X2NvdW50IjoxLCJyZWNlaXB0X2Fic2VuY2Vfb2JzZXJ2ZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAyWiIsInJlc3VsdF9sb3NzX29ic2VydmVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMloiLCJydW5faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDEiLCJydW5fcmVxdWVzdF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwicnVuX3N0b3JlX2lkZW50aXR5X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXJlc3VsdC1sb3NzLWNsb3N1cmUtcGF5bG9hZC92MiIsInRlbmFudF9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwMiIsInRlcm1pbmFsX2NhbGxiYWNrX3JlcXVpcmVkIjp0cnVlfSwicGF5bG9hZF9zaGEyNTYiOiI4ZGI1OGY2YTA1ZjRlZjFmODI3NzY2MDBkNWUyYTEzMDY0NWEzZTEyYjUwZmVlNjgxMDg4NzRlZmYwOGY3ZWJmIiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1yZXN1bHQtbG9zcy1jbG9zdXJlLWFydGlmYWN0L3YyIiwic2lnbmF0dXJlIjoiYWpDYXd4d1kxWWlBVTF3cDNrdXBZR2t6bmw3MlZBVHBsSFdnWTF1WDU3akVPRmpfNHMyX3ZYUGxVRUF5VW1wTmhwNHhvcVRYQlA4YzhPZTJKTGUzRHciLCJzaWduZXIiOnsiYWxnb3JpdGhtIjoiZWQyNTUxOSIsImtleV9pZCI6ImRlbGl2ZXJ5LWF1dGhvcml0eS1lZDI1NTE5LTI0ZjZlZDZhY2JmZTEwMDkiLCJwdWJsaWNfa2V5IjoiS2F5NjRVRzh5dkN5TGhxVTAwMEx4elllVW0wTC9oTElsNVM4a3lLV2JkYz0ifX0=", + "closure_artifact_sha256": "cec357acdb74f4e02dd1c3209a8ec880915c9830136e07260f3c1f631f8d52e8", + "closure_payload_sha256": "8db58f6a05f4ef1f82776600d5e2a130645a3e12b50fee68108874eff08f7ebf", + "http_method": "POST", + "http_route": "/api/internal/managed-delivery-result-loss-closure", + "payload_signature_domain_base64": "b3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcmVzdWx0LWxvc3MtY2xvc3VyZS1wYXlsb2FkLnYyAA==", + "permit_chain_canonical_base64": "eyJlbnRyaWVzIjpbXSwicGVuZGluZyI6eyJhY3R1YXRpb25fcmVwbGF5X2F1dGhvcml6ZWQiOmZhbHNlLCJkZWxpdmVyeV9yZWNlaXB0X2FydGlmYWN0IjpudWxsLCJkZWxpdmVyeV9yZWNlaXB0X2FydGlmYWN0X3NoYTI1NiI6bnVsbCwiZGVsaXZlcnlfc3RhdGUiOiJVTlJFU09MVkVEIiwicGVybWl0X2FydGlmYWN0Ijp7InBheWxvYWQiOnsiYWN0aW9uX3JlcXVlc3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYXV0aG9yaXR5X3NlcXVlbmNlIjowLCJlbnZpcm9ubWVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXZpZGVuY2VfaWRlbnRpdHlfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImV4ZWN1dGlvbl9hdXRob3JpdHlfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDgiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJmbG93X3J1bl9pZF9zaGEyNTYiOiIxMWU1OTRmNDgxOTU4YzEwZTMwMTVkMGJmMDQ0N2EyMmYwNjhhOGE2NDdmNDc1ZGYxNWNlMmM3YWI0YjhmM2YxIiwiaW5wdXRfZWRnZV9zZXF1ZW5jZSI6MSwiaXNzdWVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMFoiLCJwZXJtaXRfaWQiOiJwZXJtaXQ6MSIsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X2NoZWNrZWRfYXQiOiIyMDI2LTA4LTE4VDExOjU5OjMwWiIsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X2V4cGlyZXNfYXQiOiIyMDI2LTA4LTIwVDExOjAwOjAwWiIsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X3JldmlzaW9uIjo3LCJxdWFsaWZpY2F0aW9uX3NpZ25lcl9yZWdpc3RyeV9zaGEyNTYiOiJlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlIiwicnVuX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAxIiwicnVuX3JlcXVlc3Rfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcGVybWl0LXBheWxvYWQvdjIifSwicGF5bG9hZF9zaGEyNTYiOiJjODdmNTc1MWFhOWIyNzljY2UyM2FhMTc4YWZmOTU2ZTE5ZjY5MGZjZDJmOWY3MGUwZDk5OTc4MmE2OTBkNmI4Iiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1wZXJtaXQtYXJ0aWZhY3QvdjIiLCJzaWduYXR1cmUiOiIwQnlIZ3FEeFFacm5nTElGLTZ0Wk9xOWxYYW1jQVFDMGRvVVRuZUtOUGVTLVN5b09iUXlPa0F1UEZLNVBZY056T2JaeGdzZ0FMZFdhSV9zYVVDcGxCZyIsInNpZ25lciI6eyJhbGdvcml0aG0iOiJlZDI1NTE5Iiwia2V5X2lkIjoiZGVsaXZlcnktYXV0aG9yaXR5LWVkMjU1MTktMjRmNmVkNmFjYmZlMTAwOSIsInB1YmxpY19rZXkiOiJLYXk2NFVHOHl2Q3lMaHFVMDAwTHh6WWVVbTBML2hMSWw1UzhreUtXYmRjPSJ9fSwicGVybWl0X2FydGlmYWN0X3NoYTI1NiI6Ijk3MmE4MmFmNDU2ZGE1NDJiYWM3ODQ2MDE4ODk2Njg4OTFkOGI3Y2NkMjQyOTA0ODE2YjMyOTJlMTU3ZTUyODkiLCJyZWNlaXB0X2Fic2VuY2Vfb2JzZXJ2ZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAyWiIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcGVuZGluZy1wZXJtaXQvdjIifSwicGVybWl0X2NoYWluX3NoYTI1NiI6IjU5YjM5OTcxZTMwNTEwOWM1NDI5OTQ1YTVmYWI0NjYwYjA5ZjQxZTdhYzNmZmQ5MmUzNTA2YWYwMDMzN2RhOTUiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXBlcm1pdC1jaGFpbi92MiJ9", + "permit_chain_sha256": "59b39971e305109c5429945a5fab4660b09f41e7ac3ffd92e3506af00337da95", + "request_canonical_base64": "eyJjaGlsZF9zdGFydF9ldmlkZW5jZSI6eyJhdXRoZW50aWNhdGVkX3J1bm5lcl9pZF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYXV0aGVudGljYXRlZF9zZXNzaW9uX2lkX3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJkaXNwYXRjaF9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOSIsImRpc3BhdGNoX3Nlc3Npb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMTAiLCJleGVjdXRpb25fYXV0aG9yaXR5X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA4IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaWduZXJfc2hhMjU2IjoiMjRmNmVkNmFjYmZlMTAwOWMwMzBkN2NhNTY3YzMzY2E0ODMwOTExNDk4MjM2YjU1NjFhNmM4MmFiZWM1ZGUyOCIsIm1hbmFnZWRfZGlzcGF0Y2hfYmluZGluZ19zaGEyNTYiOiJzaGEyNTY6Y2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsIm1hcmtlcl9zaGEyNTYiOiI2NWE2YmVkOTIzZTQ1YTZhYTBjNjI0MzA0NWUwMzY0YzkwYWNlMDY0OGZlY2I1YjBiYjJlYmQ5NDAyNzkzYzc3IiwicnVuX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAxIiwicnVuX3N0b3JlX2lkZW50aXR5X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5tYW5hZ2VkLWNoaWxkLXN0YXJ0L3YxIiwic3RhcnRlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDBaIn0sImV4cGVjdGVkX2Nsb3N1cmVfc2VxdWVuY2UiOjAsInJlc3VsdF9sb3NzX29ic2VydmVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMloiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXJlc3VsdC1sb3NzLWNsb3N1cmUtcmVxdWVzdC92MiJ9", + "request_digest_domain_base64": "b3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcmVzdWx0LWxvc3MtY2xvc3VyZS1yZXF1ZXN0LnYyAA==", + "request_sha256": "baf417ae48eec406584ef5286aaa1b1ac2e6e03d8a29a4fb4b0c532704be59c6", + "result_canonical_base64": "eyJjbG9zdXJlX2FydGlmYWN0X2J5dGVzX2Jhc2U2NCI6ImV5SndZWGxzYjJGa0lqcDdJbUZqYTI1dmQyeGxaR2RsWkY5d1pYSnRhWFJmWTI5MWJuUWlPakFzSW1GamRIVmhkR2x2Ymw5eVpYQnNZWGxmWVhWMGFHOXlhWHBsWkNJNlptRnNjMlVzSW1GMWRHaGxiblJwWTJGMFpXUmZjblZ1Ym1WeVgybGtYM05vWVRJMU5pSTZJbUZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0VpTENKaGRYUm9aVzUwYVdOaGRHVmtYM05sYzNOcGIyNWZhV1JmYzJoaE1qVTJJam9pWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWWlJc0ltSnNhVzVrWDNKbGRISjVYMkYxZEdodmNtbDZaV1FpT21aaGJITmxMQ0pqYUdsc1pGOXpkR0Z5ZEY5bGRtbGtaVzVqWlY5emFHRXlOVFlpT2lJMk5XRTJZbVZrT1RJelpUUTFZVFpoWVRCak5qSTBNekEwTldVd016WTBZemt3WVdObE1EWTBPR1psWTJJMVlqQmlZakpsWW1RNU5EQXlOemt6WXpjM0lpd2lZMmhwYkdSZmMzUmhjblJsWkY5aGRDSTZJakl3TWpZdE1EZ3RNVGhVTVRJNk1EQTZNREJhSWl3aVkyeHZjMlZrWDJGMElqb2lNakF5Tmkwd09DMHhPRlF4TWpvd01Eb3dNbG9pTENKamJHOXpkWEpsWDJsa0lqb2lNREF3TURBd01EQXRNREF3TUMwME1EQXdMVGd3TURBdE1EQXdNREF3TURBd01ERXhJaXdpWTJ4dmMzVnlaVjl5WlhGMVpYTjBYM05vWVRJMU5pSTZJbUpoWmpReE4yRmxORGhsWldNME1EWTFPRFJsWmpVeU9EWmhZV0V4WWpGaFl6SmxObVV3TTJRNFlUSTVZVFJtWWpSaU1HTTFNekkzTURSaVpUVTVZellpTENKamJHOXpkWEpsWDNObGNYVmxibU5sSWpveExDSmtaV3hwZG1WeWVWOWhZMnR1YjNkc1pXUm5iV1Z1ZEY5aGRYUm9iM0pwZW1Wa0lqcG1ZV3h6WlN3aVpHVnNhWFpsY25sZmMzUmhkR1VpT2lKRFRFOVRSVVJmVlU1U1JWTlBURlpGUkY5U1JWTlZURlJmVEU5VFV5SXNJbVJwYzNCaGRHTm9YMmxrSWpvaU1EQXdNREF3TURBdE1EQXdNQzAwTURBd0xUZ3dNREF0TURBd01EQXdNREF3TURBNUlpd2laR2x6Y0dGMFkyaGZjMlZ6YzJsdmJsOXBaQ0k2SWpBd01EQXdNREF3TFRBd01EQXROREF3TUMwNE1EQXdMVEF3TURBd01EQXdNREF4TUNJc0ltVm1abVZqZEY5aFluTmxibU5sWDJOc1lXbHRaV1FpT21aaGJITmxMQ0psZUdWamRYUnBiMjVmWVhWMGFHOXlhWFI1WDJsa0lqb2lNREF3TURBd01EQXRNREF3TUMwME1EQXdMVGd3TURBdE1EQXdNREF3TURBd01EQTRJaXdpWlhobFkzVjBhVzl1WDJGMWRHaHZjbWwwZVY5emFHRXlOVFlpT2lKaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaElpd2laWGhsWTNWMGFXOXVYMkYxZEdodmNtbDBlVjl6YVdkdVpYSmZjMmhoTWpVMklqb2lNalJtTm1Wa05tRmpZbVpsTVRBd09XTXdNekJrTjJOaE5UWTNZek16WTJFME9ETXdPVEV4TkRrNE1qTTJZalUxTmpGaE5tTTRNbUZpWldNMVpHVXlPQ0lzSW1acGJtRnNYMkYxZEdodmNtbDBlVjl6WlhGMVpXNWpaU0k2TUN3aVptbHVZV3hmYVc1d2RYUmZaV1JuWlY5elpYRjFaVzVqWlNJNk1Td2labWx1WVd4ZmNuVnVkR2x0WlY5a1pXeHBkbVZ5ZVY5elpYRjFaVzVqWlNJNk1Dd2labXh2ZDE5eWRXNWZhV1JmYzJoaE1qVTJJam9pTVRGbE5UazBaalE0TVRrMU9HTXhNR1V6TURFMVpEQmlaakEwTkRkaE1qSm1NRFk0WVRoaE5qUTNaalEzTldSbU1UVmpaVEpqTjJGaU5HSTRaak5tTVNJc0ltbGtaVzF3YjNSbGJtTjVYMnRsZVY5emFHRXlOVFlpT2lKa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa0lpd2liV0Z1WVdkbFpGOWthWE53WVhSamFGOWlhVzVrYVc1blgzTm9ZVEkxTmlJNkluTm9ZVEkxTmpwalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOaklpd2libVYzWDNCbGNtMXBkRjloZFhSb2IzSnBlbVZrSWpwbVlXeHpaU3dpYm05MFgzSmxZMlZwZG1Wa1gyTnNZV2x0WldRaU9tWmhiSE5sTENKd1pXNWthVzVuWDJGamRHbHZibDl5WlhGMVpYTjBYM05vWVRJMU5pSTZJbVJrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1FpTENKd1pXNWthVzVuWDNCbGNtMXBkRjloY25ScFptRmpkRjl6YUdFeU5UWWlPaUk1TnpKaE9ESmhaalExTm1SaE5UUXlZbUZqTnpnME5qQXhPRGc1TmpZNE9Ea3haRGhpTjJOalpESTBNamt3TkRneE5tSXpNamt5WlRFMU4yVTFNamc1SWl3aWNHVnVaR2x1WjE5d1pYSnRhWFJmWTI5MWJuUWlPakVzSW5CbGNtMXBkRjlqYUdGcGJsOXphR0V5TlRZaU9pSTFPV0l6T1RrM01XVXpNRFV4TURsak5UUXlPVGswTldFMVptRmlORFkyTUdJd09XWTBNV1UzWVdNelptWmtPVEpsTXpVd05tRm1NREF6TXpka1lUazFJaXdpY0dWeWJXbDBYMk52ZFc1MElqb3hMQ0p5WldObGFYQjBYMkZpYzJWdVkyVmZiMkp6WlhKMlpXUmZZWFFpT2lJeU1ESTJMVEE0TFRFNFZERXlPakF3T2pBeVdpSXNJbkpsYzNWc2RGOXNiM056WDI5aWMyVnlkbVZrWDJGMElqb2lNakF5Tmkwd09DMHhPRlF4TWpvd01Eb3dNbG9pTENKeWRXNWZhV1FpT2lJd01EQXdNREF3TUMwd01EQXdMVFF3TURBdE9EQXdNQzB3TURBd01EQXdNREF3TURFaUxDSnlkVzVmY21WeGRXVnpkRjl6YUdFeU5UWWlPaUpqWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qSWl3aWNuVnVYM04wYjNKbFgybGtaVzUwYVhSNVgzTm9ZVEkxTmlJNkltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSWlMQ0p6WTJobGJXRmZkbVZ5YzJsdmJpSTZJbTl3Wlc1aFpHRndkQzV3Y205a2RXTjBhVzl1TFdSbGJHbDJaWEo1TFhKbGMzVnNkQzFzYjNOekxXTnNiM04xY21VdGNHRjViRzloWkM5Mk1pSXNJblJsYm1GdWRGOXBaQ0k2SWpBd01EQXdNREF3TFRBd01EQXROREF3TUMwNE1EQXdMVEF3TURBd01EQXdNREF3TWlJc0luUmxjbTFwYm1Gc1gyTmhiR3hpWVdOclgzSmxjWFZwY21Wa0lqcDBjblZsZlN3aWNHRjViRzloWkY5emFHRXlOVFlpT2lJNFpHSTFPR1kyWVRBMVpqUmxaakZtT0RJM056WTJNREJrTldVeVlURXpNRFkwTldFelpURXlZalV3Wm1WbE5qZ3hNRGc0TnpSbFptWXdPR1kzWldKbUlpd2ljMk5vWlcxaFgzWmxjbk5wYjI0aU9pSnZjR1Z1WVdSaGNIUXVjSEp2WkhWamRHbHZiaTFrWld4cGRtVnllUzF5WlhOMWJIUXRiRzl6Y3kxamJHOXpkWEpsTFdGeWRHbG1ZV04wTDNZeUlpd2ljMmxuYm1GMGRYSmxJam9pWVdwRFlYZDRkMWt4V1dsQlZURjNjRE5yZFhCWlIydDZibXczTWxaQlZIQnNTRmRuV1RGMVdEVTNha1ZQUm1wZk5ITXlYM1pZVUd4VlJVRjVWVzF3VG1od05IaHZjVlJZUWxBNFl6aFBaVEpLVEdVelJIY2lMQ0p6YVdkdVpYSWlPbnNpWVd4bmIzSnBkR2h0SWpvaVpXUXlOVFV4T1NJc0ltdGxlVjlwWkNJNkltUmxiR2wyWlhKNUxXRjFkR2h2Y21sMGVTMWxaREkxTlRFNUxUSTBaalpsWkRaaFkySm1aVEV3TURraUxDSndkV0pzYVdOZmEyVjVJam9pUzJGNU5qUlZSemg1ZGtONVRHaHhWVEF3TUV4NGVsbGxWVzB3VEM5b1RFbHNOVk00YTNsTFYySmtZejBpZlgwPSIsImNsb3N1cmVfYXJ0aWZhY3Rfc2hhMjU2IjoiY2VjMzU3YWNkYjc0ZjRlMDJkZDFjMzIwOWE4ZWM4ODA5MTVjOTgzMDEzNmUwNzI2MGYzYzFmNjMxZjhkNTJlOCIsInBlcm1pdF9jaGFpbl9ieXRlc19iYXNlNjQiOiJleUpsYm5SeWFXVnpJanBiWFN3aWNHVnVaR2x1WnlJNmV5SmhZM1IxWVhScGIyNWZjbVZ3YkdGNVgyRjFkR2h2Y21sNlpXUWlPbVpoYkhObExDSmtaV3hwZG1WeWVWOXlaV05sYVhCMFgyRnlkR2xtWVdOMElqcHVkV3hzTENKa1pXeHBkbVZ5ZVY5eVpXTmxhWEIwWDJGeWRHbG1ZV04wWDNOb1lUSTFOaUk2Ym5Wc2JDd2laR1ZzYVhabGNubGZjM1JoZEdVaU9pSlZUbEpGVTA5TVZrVkVJaXdpY0dWeWJXbDBYMkZ5ZEdsbVlXTjBJanA3SW5CaGVXeHZZV1FpT25zaVlXTjBhVzl1WDNKbGNYVmxjM1JmYzJoaE1qVTJJam9pWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkNJc0ltRmtiV2x6YzJsdmJsOWhjblJwWm1GamRGOXphR0V5TlRZaU9pSmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtJaXdpWVhWMGFHOXlhWFI1WDNObGNYVmxibU5sSWpvd0xDSmxiblpwY205dWJXVnVkRjlrYVdkbGMzUWlPaUpoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoSWl3aVpYWnBaR1Z1WTJWZmFXUmxiblJwZEhsZmMyaGhNalUySWpvaVpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbFpTSXNJbVY0WldOMWRHbHZibDloZFhSb2IzSnBkSGxmYVdRaU9pSXdNREF3TURBd01DMHdNREF3TFRRd01EQXRPREF3TUMwd01EQXdNREF3TURBd01EZ2lMQ0psZUdWamRYUnBiMjVmWVhWMGFHOXlhWFI1WDNOb1lUSTFOaUk2SW1GaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdFaUxDSm1iRzkzWDNKMWJsOXBaRjl6YUdFeU5UWWlPaUl4TVdVMU9UUm1ORGd4T1RVNFl6RXdaVE13TVRWa01HSm1NRFEwTjJFeU1tWXdOamhoT0dFMk5EZG1ORGMxWkdZeE5XTmxNbU0zWVdJMFlqaG1NMll4SWl3aWFXNXdkWFJmWldSblpWOXpaWEYxWlc1alpTSTZNU3dpYVhOemRXVmtYMkYwSWpvaU1qQXlOaTB3T0MweE9GUXhNam93TURvd01Gb2lMQ0p3WlhKdGFYUmZhV1FpT2lKd1pYSnRhWFE2TVNJc0luRjFZV3hwWm1sallYUnBiMjVmYzJsbmJtVnlYM0psWjJsemRISjVYMk5vWldOclpXUmZZWFFpT2lJeU1ESTJMVEE0TFRFNFZERXhPalU1T2pNd1dpSXNJbkYxWVd4cFptbGpZWFJwYjI1ZmMybG5ibVZ5WDNKbFoybHpkSEo1WDJWNGNHbHlaWE5mWVhRaU9pSXlNREkyTFRBNExUSXdWREV4T2pBd09qQXdXaUlzSW5GMVlXeHBabWxqWVhScGIyNWZjMmxuYm1WeVgzSmxaMmx6ZEhKNVgzSmxkbWx6YVc5dUlqbzNMQ0p4ZFdGc2FXWnBZMkYwYVc5dVgzTnBaMjVsY2w5eVpXZHBjM1J5ZVY5emFHRXlOVFlpT2lKbFpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbElpd2ljblZ1WDJsa0lqb2lNREF3TURBd01EQXRNREF3TUMwME1EQXdMVGd3TURBdE1EQXdNREF3TURBd01EQXhJaXdpY25WdVgzSmxjWFZsYzNSZmMyaGhNalUySWpvaVkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOall5SXNJbk5qYUdWdFlWOTJaWEp6YVc5dUlqb2liM0JsYm1Ga1lYQjBMbkJ5YjJSMVkzUnBiMjR0WkdWc2FYWmxjbmt0Y0dWeWJXbDBMWEJoZVd4dllXUXZkaklpZlN3aWNHRjViRzloWkY5emFHRXlOVFlpT2lKak9EZG1OVGMxTVdGaE9XSXlOemxqWTJVeU0yRmhNVGM0WVdabU9UVTJaVEU1WmpZNU1HWmpaREptT1dZM01HVXdaRGs1T1RjNE1tRTJPVEJrTm1JNElpd2ljMk5vWlcxaFgzWmxjbk5wYjI0aU9pSnZjR1Z1WVdSaGNIUXVjSEp2WkhWamRHbHZiaTFrWld4cGRtVnllUzF3WlhKdGFYUXRZWEowYVdaaFkzUXZkaklpTENKemFXZHVZWFIxY21VaU9pSXdRbmxJWjNGRWVGRmFjbTVuVEVsR0xUWjBXazl4T1d4WVlXMWpRVkZETUdSdlZWUnVaVXRPVUdWVExWTjViMDlpVVhsUGEwRjFVRVpMTlZCWlkwNTZUMkphZUdkelowRk1aRmRoU1Y5ellWVkRjR3hDWnlJc0luTnBaMjVsY2lJNmV5SmhiR2R2Y21sMGFHMGlPaUpsWkRJMU5URTVJaXdpYTJWNVgybGtJam9pWkdWc2FYWmxjbmt0WVhWMGFHOXlhWFI1TFdWa01qVTFNVGt0TWpSbU5tVmtObUZqWW1abE1UQXdPU0lzSW5CMVlteHBZMTlyWlhraU9pSkxZWGsyTkZWSE9IbDJRM2xNYUhGVk1EQXdUSGg2V1dWVmJUQk1MMmhNU1d3MVV6aHJlVXRYWW1SalBTSjlmU3dpY0dWeWJXbDBYMkZ5ZEdsbVlXTjBYM05vWVRJMU5pSTZJamszTW1FNE1tRm1ORFUyWkdFMU5ESmlZV00zT0RRMk1ERTRPRGsyTmpnNE9URmtPR0kzWTJOa01qUXlPVEEwT0RFMllqTXlPVEpsTVRVM1pUVXlPRGtpTENKeVpXTmxhWEIwWDJGaWMyVnVZMlZmYjJKelpYSjJaV1JmWVhRaU9pSXlNREkyTFRBNExURTRWREV5T2pBd09qQXlXaUlzSW5OamFHVnRZVjkyWlhKemFXOXVJam9pYjNCbGJtRmtZWEIwTG5CeWIyUjFZM1JwYjI0dFpHVnNhWFpsY25rdGNHVnVaR2x1Wnkxd1pYSnRhWFF2ZGpJaWZTd2ljR1Z5YldsMFgyTm9ZV2x1WDNOb1lUSTFOaUk2SWpVNVlqTTVPVGN4WlRNd05URXdPV00xTkRJNU9UUTFZVFZtWVdJME5qWXdZakE1WmpReFpUZGhZek5tWm1RNU1tVXpOVEEyWVdZd01ETXpOMlJoT1RVaUxDSnpZMmhsYldGZmRtVnljMmx2YmlJNkltOXdaVzVoWkdGd2RDNXdjbTlrZFdOMGFXOXVMV1JsYkdsMlpYSjVMWEJsY20xcGRDMWphR0ZwYmk5Mk1pSjkiLCJwZXJtaXRfY2hhaW5fc2hhMjU2IjoiNTliMzk5NzFlMzA1MTA5YzU0Mjk5NDVhNWZhYjQ2NjBiMDlmNDFlN2FjM2ZmZDkyZTM1MDZhZjAwMzM3ZGE5NSIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcmVzdWx0LWxvc3MtY2xvc3VyZS1yZXN1bHQvdjIiLCJzdGF0dXMiOiJjbG9zZWQifQ==" + }, "private_key_base64": "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=", "public_key_base64": "A6EHv/POEL4dcN0Y50vAmWfk1jCbpQ1fHdyGZBJVMbg=", "schema_version": "openadapt.production-terminal-cross-language-vectors/v2", "signature_domain_base64": "b3BlbmFkYXB0LXByb2R1Y3Rpb24tdGVybWluYWwtdmVyaWZpY2F0aW9uLXYyAA==", "signer_sha256": "56475aa75463474c0285df5dbf2bcab73da651358839e9b77481b2eab107708c", "vectors": [ + { + "callback": { + "artifact_bytes_source": "envelope_canonical_base64", + "outcome": "VERIFIED", + "report_sha256": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "run_id": "00000000-0000-4000-8000-000000000001", + "schema_version": "openadapt.hosted-runner-terminal/v1", + "started": true, + "uncertain_delivery": false + }, + "effect_state": { + "effect_contract_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "final_verdict": "confirmed", + "observed_effect": "present", + "reconciliation_actions": 0, + "reconciliation_completed": false, + "result_index": 0, + "verification_tier": 1, + "verifier_identity": "sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" + }, + "envelope_canonical_base64": "eyJwYXlsb2FkIjp7ImFja25vd2xlZGdlZF9wZXJtaXRfY291bnQiOjEsImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA2IiwiYWRtaXNzaW9uX3BvbGljeV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYWRtaXR0ZWRfcnVudGltZV9idWlsZF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiYnVuZGxlX2FydGlmYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJidW5kbGVfY29udGVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYnVuZGxlX3ZlcnNpb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDQiLCJlZmZlY3RfY29udHJhY3Rfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImVudmlyb25tZW50X2NvbnRyYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJlbnZpcm9ubWVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXZpZGVuY2VfaWRlbnRpdHlfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImV2aWRlbmNlX21hbmlmZXN0cyI6eyJhdXRob3JpemF0aW9uIjp7ImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA2IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOCIsImV4ZWN1dGlvbl9hdXRob3JpdHlfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImdvdmVybmVkX2F1dGhvcml6YXRpb25faWRfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsIm1hbmlmZXN0X3NoYTI1NiI6ImYwY2ExOWE2YjNlYWJlNTk0ZGJjOTA2ODljMmY3NGNiZTVlODJkNGQ5NDdkYjI5YTVkMDdiMTY0MWU4OTYxY2YiLCJwZXJtaXRfY2hhaW5fc2hhMjU2IjoiNTA0OGZlOTQ1ODgyZDI4MDI2MDA4ZDdlOTEzN2FkMDE2ZmRkMDFhZWFmNTg4NDgxZmI1YmQwZjI0MmE1MDA0MyIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tYXV0aG9yaXphdGlvbi1ldmlkZW5jZS92MSJ9LCJlZmZlY3QiOnsiY29uZmlybWVkIjoxLCJlZmZlY3RfY29udHJhY3Rfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsIm1hbmlmZXN0X3NoYTI1NiI6ImEzOThlNGJmMDUyZmIwMzBiOTdlNDM1ZTI4M2E2ZjY2MzJkOWE1ZDUxMjU0YTYwZDY4OWUwNWEwZGY2ZjAxMDYiLCJyZWNvcmRzIjpbeyJlZmZlY3RfY29udHJhY3RfaGFzaCI6InNoYTI1NjphYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZmluYWxfdmVyZGljdCI6ImNvbmZpcm1lZCIsIm9ic2VydmVkX2VmZmVjdCI6InByZXNlbnQiLCJyZWNvbmNpbGlhdGlvbl9hY3Rpb25zIjowLCJyZWNvbmNpbGlhdGlvbl9jb21wbGV0ZWQiOmZhbHNlLCJyZXN1bHRfaW5kZXgiOjAsInZlcmlmaWNhdGlvbl90aWVyIjoxLCJ2ZXJpZmllcl9pZGVudGl0eSI6InNoYTI1NjpiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIn1dLCJyZXF1aXJlZCI6MSwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1lZmZlY3QtZXZpZGVuY2UvdjEiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIn0sImlkZW50aXR5Ijp7ImNvbmZpcm1lZCI6MSwiaWRlbnRpdHlfY29udHJhY3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsIm1hbmlmZXN0X3NoYTI1NiI6IjEzNWM4NjNlZGM3ZmFiMThjYTI5YjQ5MjkzZmMyNWExYzliZDRkZTBlOWVkMjhkNGNlYzZlOGQwYTY3OTEyMjkiLCJyZXF1aXJlZCI6MSwicmVzdWx0cyI6W3sibW9kZSI6InN0cnVjdHVyZWQiLCJyZXN1bHRfaW5kZXgiOjAsInNpZ25hbHMiOltdLCJzdGF0dXMiOiJ2ZXJpZmllZCJ9XSwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1pZGVudGl0eS1ldmlkZW5jZS92MSIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifSwicG9saWN5Ijp7ImFkbWlzc2lvbl9wb2xpY3lfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImVmZmVjdF9jb250cmFjdF9zaGEyNTYiOiJlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlIiwiZW52aXJvbm1lbnRfY29udHJhY3Rfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsImVudmlyb25tZW50X2RpZ2VzdCI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJnb3Zlcm5lZF9wb2xpY3lfY29udHJhY3Rfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsImdvdmVybmVkX3J1bnRpbWVfaW5wdXRzX2RpZ2VzdCI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJpZGVudGl0eV9jb250cmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwibWFuaWZlc3Rfc2hhMjU2IjoiNGY5ODhkMDE1YmNkN2NkN2UwNWJhMDY2M2Q4OWYwYTk2OGYwZDhhY2U5OWIwOTBlYmFiZWU1MmExYzU1MDQyMSIsIm1pbmltdW1fZWZmZWN0X3RpZXIiOjEsInJ1bnRpbWVfZW52aXJvbm1lbnRfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tcG9saWN5LWV2aWRlbmNlL3YxIn0sInBvc3Rjb25kaXRpb24iOnsiY29uZmlybWVkIjoxLCJtYW5pZmVzdF9zaGEyNTYiOiJmNjg1YWUyOWYzMjQyMzdiMzcxOWNiMmVkMTZkNmYzMjVmYjg4Yjk4Y2E0NmQ1MjNjY2I1MDJiYWFjOGQ5YjU5IiwicmVjb3JkcyI6W3siYWN0aW9uX2tpbmQiOiJjbGljayIsImFjdHVhdGlvbl9wYXRoIjoiZ3VpIiwiY29udHJhY3RfaW5kZXgiOjAsImNvbnRyYWN0X2tpbmQiOiJleHBsaWNpdF9wcmVkaWNhdGUiLCJjb250cmFjdF9zaGEyNTYiOiIwYWRlMGI1MjBiYzAwNzg5MWNhY2NhMDAxNzE1Nzg0NDJhMmE3NGNlZjE1ZmY2NGRkZTQ1ZGYwN2FmYjY0YWViIiwicmVzdWx0X2luZGV4IjowLCJzdGVwX2NvbnRyYWN0X3NoYTI1NiI6IjFhNTk1MzZhNDg4YjFjNDZhYWNmMGJhMzc5MzBiODQwNjJjMTQyNzU1ZmE5MzkxNTJlZjVlMjhjNDA5NDcxZWQiLCJzdGVwX2luZGV4IjowLCJ2ZXJkaWN0IjoicGFzc2VkIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSJ9XSwicmVxdWlyZWQiOjEsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tcG9zdGNvbmRpdGlvbi1ldmlkZW5jZS92MSIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifX0sImV2aWRlbmNlX3J1bm5lcl9zaWduZXJfc2hhMjU2IjoiNTY0NzVhYTc1NDYzNDc0YzAyODVkZjVkYmYyYmNhYjczZGE2NTEzNTg4MzllOWI3NzQ4MWIyZWFiMTA3NzA4YyIsImV4ZWN1dGlvbl9hdXRob3JpdHlfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDgiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NpZ25lcl9zaGEyNTYiOiIyNGY2ZWQ2YWNiZmUxMDA5YzAzMGQ3Y2E1NjdjMzNjYTQ4MzA5MTE0OTgyMzZiNTU2MWE2YzgyYWJlYzVkZTI4IiwiZXhlY3V0aW9uX291dGNvbWUiOnsiY29tcGVuc2F0aW9uX2FjdGlvbnMiOjAsImV2aWRlbmNlX2NsYXNzZXMiOlsiYXV0aG9yaXphdGlvbiIsImVmZmVjdF90aWVyXzEiLCJpZGVudGl0eSIsInBvc3Rjb25kaXRpb24iXSwiZXhlY3V0aW9uX2NvbXBsZXRlZCI6dHJ1ZSwiZXh0ZXJuYWxfbmV0d29ya19jYWxscyI6Im5vbmUiLCJtb2RlbF9jYWxscyI6MCwib3V0Y29tZSI6IlZFUklGSUVEIiwicGFzc2VkX2NvbnRyYWN0cyI6eyJhdXRob3JpemF0aW9uIjoxLCJlZmZlY3QiOjEsImlkZW50aXR5IjoxLCJwb3N0Y29uZGl0aW9uIjoxfSwicG9zdGNvbmRpdGlvbl9ldmlkZW5jZSI6W3siYWN0aW9uX2tpbmQiOiJjbGljayIsImFjdHVhdGlvbl9wYXRoIjoiZ3VpIiwiY29udHJhY3RfaW5kZXgiOjAsImNvbnRyYWN0X2tpbmQiOiJleHBsaWNpdF9wcmVkaWNhdGUiLCJjb250cmFjdF9zaGEyNTYiOiIwYWRlMGI1MjBiYzAwNzg5MWNhY2NhMDAxNzE1Nzg0NDJhMmE3NGNlZjE1ZmY2NGRkZTQ1ZGYwN2FmYjY0YWViIiwicmVzdWx0X2luZGV4IjowLCJzdGVwX2NvbnRyYWN0X3NoYTI1NiI6IjFhNTk1MzZhNDg4YjFjNDZhYWNmMGJhMzc5MzBiODQwNjJjMTQyNzU1ZmE5MzkxNTJlZjVlMjhjNDA5NDcxZWQiLCJzdGVwX2luZGV4IjowLCJ2ZXJkaWN0IjoicGFzc2VkIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSJ9XSwicHJvZHVjdGlvbl9lbGlnaWJsZSI6dHJ1ZSwicHJvZmlsZSI6InN0YW5kYXJkIiwicXVhbGlmaWNhdGlvbl9ldmlkZW5jZV9vbmx5IjpmYWxzZSwicmVxdWlyZWRfY29udHJhY3RzIjp7ImF1dGhvcml6YXRpb24iOjEsImVmZmVjdCI6MSwiaWRlbnRpdHkiOjEsInBvc3Rjb25kaXRpb24iOjF9LCJ2ZXJzaW9uIjoib3BlbmFkYXB0LmV4ZWN1dGlvbi1vdXRjb21lL3YxIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSJ9LCJleGVjdXRpb25fb3V0Y29tZV9zaGEyNTYiOiJlZjVlNWYwMzgwYmMwOWRkMjc5YjE5OTQ3Y2RhYzUyZTEzOWZmODNjYTI3NzFjZDA0NDg0MGFjNzM5MzZmMWI0IiwiZXhlY3V0aW9uX3B1cnBvc2UiOiJwcm9kdWN0aW9uIiwiZmluYWxfYXV0aG9yaXR5X3NlcXVlbmNlIjowLCJmaW5hbF9ydW50aW1lX2RlbGl2ZXJ5X3NlcXVlbmNlIjo5LCJmbG93X3J1bl9pZF9zaGEyNTYiOiIxMWU1OTRmNDgxOTU4YzEwZTMwMTVkMGJmMDQ0N2EyMmYwNjhhOGE2NDdmNDc1ZGYxNWNlMmM3YWI0YjhmM2YxIiwiaWRlbnRpdHlfY29udHJhY3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsImlzc3VlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDNaIiwicGVuZGluZ19wZXJtaXRfY291bnQiOjAsInBlcm1pdF9jaGFpbiI6eyJlbnRyaWVzIjpbeyJkZWxpdmVyeV9yZWNlaXB0X2FydGlmYWN0Ijp7InBheWxvYWQiOnsiYXV0aGVudGljYXRlZF9ydW5uZXJfaWRfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsImF1dGhlbnRpY2F0ZWRfc2Vzc2lvbl9pZF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiZGVsaXZlcmVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMVoiLCJleGVjdXRpb25fYXV0aG9yaXR5X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA4Iiwib25lX3VzZV9jbGFpbV9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAxMCIsInBlcm1pdF9hcnRpZmFjdF9zaGEyNTYiOiI5NzJhODJhZjQ1NmRhNTQyYmFjNzg0NjAxODg5NjY4ODkxZDhiN2NjZDI0MjkwNDgxNmIzMjkyZTE1N2U1Mjg5IiwicGVybWl0X2lkIjoicGVybWl0OjEiLCJydW50aW1lX2RlbGl2ZXJ5X3NlcXVlbmNlIjo5LCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXJlY2VpcHQtcGF5bG9hZC92MiJ9LCJwYXlsb2FkX3NoYTI1NiI6IjhhOGY2ZDg4NzUwY2JiNmIzYmQ2NjIwOTNhZDI5ZTJiYzIwYzZhYjY5OTFkNzBlNTg4NjkxYzhiM2FiNjYyYjkiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXJlY2VpcHQtYXJ0aWZhY3QvdjIiLCJzaWduYXR1cmUiOiJBT0txQ2dTMXMwWGEtaXlFOTZWLXlsUHpRY3YydXZPc3V5Z0h6dnUyUnlWN0ZMc0hGX0xWZnF5eDR1MnB1bWxFbDBZazVZdTcwSlZVa3NacGFVcEREdyIsInNpZ25lciI6eyJhbGdvcml0aG0iOiJlZDI1NTE5Iiwia2V5X2lkIjoiZGVsaXZlcnktYXV0aG9yaXR5LWVkMjU1MTktMjRmNmVkNmFjYmZlMTAwOSIsInB1YmxpY19rZXkiOiJLYXk2NFVHOHl2Q3lMaHFVMDAwTHh6WWVVbTBML2hMSWw1UzhreUtXYmRjPSJ9fSwiZGVsaXZlcnlfcmVjZWlwdF9hcnRpZmFjdF9zaGEyNTYiOiJjMDBhMWJhNzAxNWYzY2JlMDVhNzZhZWFiZmY2MTlkNzkzZTczNzVhMzEwZTE5NWZjYmJkMmQyOTQ4ZjJiMjE0IiwicGVybWl0X2FydGlmYWN0Ijp7InBheWxvYWQiOnsiYWN0aW9uX3JlcXVlc3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYXV0aG9yaXR5X3NlcXVlbmNlIjowLCJlbnZpcm9ubWVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXZpZGVuY2VfaWRlbnRpdHlfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImV4ZWN1dGlvbl9hdXRob3JpdHlfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDgiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJmbG93X3J1bl9pZF9zaGEyNTYiOiIxMWU1OTRmNDgxOTU4YzEwZTMwMTVkMGJmMDQ0N2EyMmYwNjhhOGE2NDdmNDc1ZGYxNWNlMmM3YWI0YjhmM2YxIiwiaW5wdXRfZWRnZV9zZXF1ZW5jZSI6MSwiaXNzdWVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMFoiLCJwZXJtaXRfaWQiOiJwZXJtaXQ6MSIsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X2NoZWNrZWRfYXQiOiIyMDI2LTA4LTE4VDExOjU5OjMwWiIsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X2V4cGlyZXNfYXQiOiIyMDI2LTA4LTIwVDExOjAwOjAwWiIsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X3JldmlzaW9uIjo3LCJxdWFsaWZpY2F0aW9uX3NpZ25lcl9yZWdpc3RyeV9zaGEyNTYiOiJlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlIiwicnVuX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAxIiwicnVuX3JlcXVlc3Rfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcGVybWl0LXBheWxvYWQvdjIifSwicGF5bG9hZF9zaGEyNTYiOiJjODdmNTc1MWFhOWIyNzljY2UyM2FhMTc4YWZmOTU2ZTE5ZjY5MGZjZDJmOWY3MGUwZDk5OTc4MmE2OTBkNmI4Iiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1wZXJtaXQtYXJ0aWZhY3QvdjIiLCJzaWduYXR1cmUiOiIwQnlIZ3FEeFFacm5nTElGLTZ0Wk9xOWxYYW1jQVFDMGRvVVRuZUtOUGVTLVN5b09iUXlPa0F1UEZLNVBZY056T2JaeGdzZ0FMZFdhSV9zYVVDcGxCZyIsInNpZ25lciI6eyJhbGdvcml0aG0iOiJlZDI1NTE5Iiwia2V5X2lkIjoiZGVsaXZlcnktYXV0aG9yaXR5LWVkMjU1MTktMjRmNmVkNmFjYmZlMTAwOSIsInB1YmxpY19rZXkiOiJLYXk2NFVHOHl2Q3lMaHFVMDAwTHh6WWVVbTBML2hMSWw1UzhreUtXYmRjPSJ9fSwicGVybWl0X2FydGlmYWN0X3NoYTI1NiI6Ijk3MmE4MmFmNDU2ZGE1NDJiYWM3ODQ2MDE4ODk2Njg4OTFkOGI3Y2NkMjQyOTA0ODE2YjMyOTJlMTU3ZTUyODkiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXBlcm1pdC1jaGFpbi1lbnRyeS92MiJ9XSwicGVybWl0X2NoYWluX3NoYTI1NiI6IjUwNDhmZTk0NTg4MmQyODAyNjAwOGQ3ZTkxMzdhZDAxNmZkZDAxYWVhZjU4ODQ4MWZiNWJkMGYyNDJhNTAwNDMiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXBlcm1pdC1jaGFpbi92MiJ9LCJwZXJtaXRfY291bnQiOjEsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X3JldmlzaW9uIjo3LCJxdWFsaWZpY2F0aW9uX3NpZ25lcl9yZWdpc3RyeV9zaGEyNTYiOiJlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlIiwicnVuX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAxIiwicnVuX3JlY2VpcHQiOnsiYXV0aG9yaXphdGlvbl9jb25maXJtZWQiOjEsImF1dGhvcml6YXRpb25fcmVxdWlyZWQiOjEsImJ1bmRsZV9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZHVyYXRpb25fbXMiOjEwMCwiZWZmZWN0X3RpZXJfcmVhY2hlZCI6ImluZGVwZW5kZW50X3N5c3RlbSIsImVmZmVjdHNfY29uZmlybWVkIjoxLCJlZmZlY3RzX3JlcXVpcmVkIjoxLCJlc3RfY29zdF9taWNyb3VzZCI6MCwiZXZpZGVuY2VfY2xhc3NlcyI6WyJhdXRob3JpemF0aW9uIiwiZWZmZWN0X3RpZXJfMSIsImlkZW50aXR5IiwicG9zdGNvbmRpdGlvbiJdLCJleHRlcm5hbF9uZXR3b3JrX2NhbGxzIjoibm9uZSIsImdlbmVyYXRlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDBaIiwiaGVhbHMiOjAsImlkZW50aXR5X2FwcGxpY2FibGUiOjEsImlkZW50aXR5X2FybWVkIjoxLCJpZGVudGl0eV9jb25maXJtZWQiOjEsImlkZW50aXR5X3JlcXVpcmVkIjoxLCJtb2RlbF9jYWxscyI6MCwib3V0Y29tZSI6IlZFUklGSUVEIiwib3Zlcl9oYWx0X2NvdW50IjowLCJwb3N0Y29uZGl0aW9uc19jb25maXJtZWQiOjEsInBvc3Rjb25kaXRpb25zX3JlcXVpcmVkIjoxLCJwcm9kdWN0aW9uX2VsaWdpYmxlIjp0cnVlLCJwcm9maWxlIjoic3RhbmRhcmQiLCJwcm92ZW5hbmNlIjoicHJvZHVjdGlvbiIsInJlY2VpcHRfYnVpbGRlcl92ZXJzaW9uIjoiMS4yLjMiLCJydW5nX2hpc3RvZ3JhbSI6eyJzdHJ1Y3R1cmFsIjoxfSwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1ydW4tcmVjZWlwdC92MSIsInNvdXJjZV9yZWNlaXB0X2RpZ2VzdCI6IjI2N2NmMDU1ZjIzYmVmYmM5NzE1NzVlMDljMTBhY2Y0ODlmNDdlNzMwOWNiYWM0YjA4YjZiMDkzZjM2NGQ1OTYiLCJzb3VyY2VfcmVjZWlwdF9zaGEyNTYiOiI4ZDkwNDJjOTlmOWU0NjBlNGI0YWExY2VlZjYzMTJiMzFlOTVlODVkZTU4ZDg5Yjc0MGU2NDEzMTgxNDQ3MGNiIiwic291cmNlX3NjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnJ1bi1yZWNlaXB0L3YyIiwic3RlcHNfb2siOjEsInN0ZXBzX3RvdGFsIjoxLCJzdWJzdHJhdGUiOiJ3ZWIiLCJ0cmFuc2FjdGlvbl9vdXRjb21lIjoiVkVSSUZJRUQifSwicnVuX3JlY2VpcHRfc2hhMjU2IjoiNjM5YzMxMzY5YjM1MDQ1NGU1ZjE0MWFhODI2OWVmYjk1Njk4NmM2MGU5NzA5YWNjNmViMDllMmZiNmYwZDgzZSIsInJ1bl9yZXBvcnRfb2JqZWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJydW5fcmVwb3J0X29iamVjdF92ZXJzaW9uIjoidmVyc2lvbjoxIiwicnVuX3JlcG9ydF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwicnVudGltZV9lbnZpcm9ubWVudF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwicnVudGltZV9zdWJzdHJhdGUiOiJ3ZWIiLCJydW50aW1lX3ZhbGlkYXRpb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDUiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLXRlcm1pbmFsLXZlcmlmaWNhdGlvbi92MiIsInRlbmFudF9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwMiIsInRlcm1pbmFsX3NlcXVlbmNlIjoxLCJ2ZXJpZmllZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDJaIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsIndvcmtmbG93X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAzIiwid29ya2Zsb3dfdmVyc2lvbl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwNCJ9LCJzaWduYXR1cmUiOiJkVlBRN2ZhLTJSaF93Y040Sjd0TzBsSXQ0bTZmdnNEZXZjYjN1WE5zRDEwZTlmUGpOLWlsSjg0WGdiMVdvZ1ROd3NSLTJFdTY2UnZzSGVRcWFfcHJDZyIsInNpZ25lciI6eyJhbGdvcml0aG0iOiJlZDI1NTE5Iiwia2V5X2lkIjoiZXZpZGVuY2UtcnVubmVyLWVkMjU1MTktNTY0NzVhYTc1NDYzNDc0YyIsInB1YmxpY19rZXkiOiJBNkVIdi9QT0VMNGRjTjBZNTB2QW1XZmsxakNicFExZkhkeUdaQkpWTWJnPSJ9fQ==", + "managed_result_loss": null, + "name": "verified-complete", + "payload_canonical_sha256": "ba885e032122ee1e9c616c048d32845cbbf0b27fb67141fefc0bd45cd12b2d2f", + "signature": "dVPQ7fa-2Rh_wcN4J7tO0lIt4m6fvsDevcb3uXNsD10e9fPjN-ilJ84Xgb1WogTNwsR-2Eu66RvsHeQqa_prCg", + "terminal_verification_artifact_sha256": "23ff9e0a8f6c5e1a4fc124e08ab41e42e456bda4d32cb65c24db40e8ec7b8bcc" + }, { "callback": { "artifact_bytes_source": "envelope_canonical_base64", @@ -33,6 +75,7 @@ "verifier_identity": null }, "envelope_canonical_base64": "eyJwYXlsb2FkIjp7ImFja25vd2xlZGdlZF9wZXJtaXRfY291bnQiOjAsImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA2IiwiYWRtaXNzaW9uX3BvbGljeV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYWRtaXR0ZWRfcnVudGltZV9idWlsZF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiYnVuZGxlX2FydGlmYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJidW5kbGVfY29udGVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYnVuZGxlX3ZlcnNpb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDQiLCJlZmZlY3RfY29udHJhY3Rfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImVudmlyb25tZW50X2NvbnRyYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJlbnZpcm9ubWVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXZpZGVuY2VfaWRlbnRpdHlfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImV2aWRlbmNlX21hbmlmZXN0cyI6eyJhdXRob3JpemF0aW9uIjp7ImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA2IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOCIsImV4ZWN1dGlvbl9hdXRob3JpdHlfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImdvdmVybmVkX2F1dGhvcml6YXRpb25faWRfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsIm1hbmlmZXN0X3NoYTI1NiI6IjMyY2QzNjEzYmVlOWJjNjkwNjkzYTM5NWQ5OTMzNTQ3ZjllZWI5ZjZmYWE1ZGJkYmIxNGExMDYyOThiZTQ2NWMiLCJwZXJtaXRfY2hhaW5fc2hhMjU2IjoiODJkYWI1NDI4ZTI1MmQxOGE1OWIwMTc3NzM5ZTAwY2FhZGI3NjJkY2Y1OWY0MDM2ZGVhNGQ3N2MzYzMyMDNjYiIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tYXV0aG9yaXphdGlvbi1ldmlkZW5jZS92MSJ9LCJlZmZlY3QiOnsiY29uZmlybWVkIjowLCJlZmZlY3RfY29udHJhY3Rfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsIm1hbmlmZXN0X3NoYTI1NiI6ImViYjU4MzYxNzhlZGZhYzYyOWJkOWJjYTkwZWNkMDE5NTkwOTQ5NjZhMGRkNjNiYWVhN2E2MmY2ZTNiMDRmZjgiLCJyZWNvcmRzIjpbeyJhYnNlbmNlX2Jhc2lzIjoibm90X2FjdHVhdGVkIiwiYXR0ZW1wdF9zdGF0ZSI6Im5vdF9hY3R1YXRlZCIsImVmZmVjdF9jb250cmFjdF9oYXNoIjoic2hhMjU2OmFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJlZmZlY3RfdmVyaWZpZWQiOmZhbHNlLCJmaW5hbF92ZXJkaWN0IjpudWxsLCJvYnNlcnZlZF9lZmZlY3QiOiJhYnNlbnQiLCJyZWNvbmNpbGlhdGlvbl9hY3Rpb25zIjowLCJyZWNvbmNpbGlhdGlvbl9jb21wbGV0ZWQiOmZhbHNlLCJyZWNvcmRfa2luZCI6InRlcm1pbmFsX2VmZmVjdF9zdGF0ZSIsInJlc29sdmVkX2RlbGl2ZXJ5X3VuY2VydGFpbnR5IjpmYWxzZSwicmVzdWx0X2luZGV4IjowLCJ2ZXJpZmljYXRpb25fcGVyZm9ybWVkIjpmYWxzZSwidmVyaWZpY2F0aW9uX3RpZXIiOm51bGwsInZlcmlmaWVyX2lkZW50aXR5IjpudWxsfV0sInJlcXVpcmVkIjoxLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWVmZmVjdC1ldmlkZW5jZS92MSIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifSwiaWRlbnRpdHkiOnsiY29uZmlybWVkIjoxLCJpZGVudGl0eV9jb250cmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwibWFuaWZlc3Rfc2hhMjU2IjoiMTM1Yzg2M2VkYzdmYWIxOGNhMjliNDkyOTNmYzI1YTFjOWJkNGRlMGU5ZWQyOGQ0Y2VjNmU4ZDBhNjc5MTIyOSIsInJlcXVpcmVkIjoxLCJyZXN1bHRzIjpbeyJtb2RlIjoic3RydWN0dXJlZCIsInJlc3VsdF9pbmRleCI6MCwic2lnbmFscyI6W10sInN0YXR1cyI6InZlcmlmaWVkIn1dLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWlkZW50aXR5LWV2aWRlbmNlL3YxIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSJ9LCJwb2xpY3kiOnsiYWRtaXNzaW9uX3BvbGljeV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZWZmZWN0X2NvbnRyYWN0X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJlbnZpcm9ubWVudF9jb250cmFjdF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwiZW52aXJvbm1lbnRfZGlnZXN0IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImdvdmVybmVkX3BvbGljeV9jb250cmFjdF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwiZ292ZXJuZWRfcnVudGltZV9pbnB1dHNfZGlnZXN0IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsImlkZW50aXR5X2NvbnRyYWN0X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJtYW5pZmVzdF9zaGEyNTYiOiI0Zjk4OGQwMTViY2Q3Y2Q3ZTA1YmEwNjYzZDg5ZjBhOTY4ZjBkOGFjZTk5YjA5MGViYWJlZTUyYTFjNTUwNDIxIiwibWluaW11bV9lZmZlY3RfdGllciI6MSwicnVudGltZV9lbnZpcm9ubWVudF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1wb2xpY3ktZXZpZGVuY2UvdjEifSwicG9zdGNvbmRpdGlvbiI6eyJjb25maXJtZWQiOjAsIm1hbmlmZXN0X3NoYTI1NiI6IjNlYTRjNjRhMzBiMGNmMTdiY2EwNGYzMjYwZTBhNDcxOGIyN2Y1MWUxZmRjMmJiODhhMTgyNjMwYTM0ZGQ1ZmYiLCJyZWNvcmRzIjpbeyJhY3Rpb25fa2luZCI6ImNsaWNrIiwiYWN0dWF0aW9uX3BhdGgiOiJndWkiLCJjb250cmFjdF9pbmRleCI6MCwiY29udHJhY3Rfa2luZCI6ImV4cGxpY2l0X3ByZWRpY2F0ZSIsImNvbnRyYWN0X3NoYTI1NiI6IjBhZGUwYjUyMGJjMDA3ODkxY2FjY2EwMDE3MTU3ODQ0MmEyYTc0Y2VmMTVmZjY0ZGRlNDVkZjA3YWZiNjRhZWIiLCJyZXN1bHRfaW5kZXgiOjAsInN0ZXBfY29udHJhY3Rfc2hhMjU2IjoiMWE1OTUzNmE0ODhiMWM0NmFhY2YwYmEzNzkzMGI4NDA2MmMxNDI3NTVmYTkzOTE1MmVmNWUyOGM0MDk0NzFlZCIsInN0ZXBfaW5kZXgiOjAsInZlcmRpY3QiOiJ1bnZlcmlmaWFibGUiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIn1dLCJyZXF1aXJlZCI6MSwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1wb3N0Y29uZGl0aW9uLWV2aWRlbmNlL3YxIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSJ9fSwiZXZpZGVuY2VfcnVubmVyX3NpZ25lcl9zaGEyNTYiOiI1NjQ3NWFhNzU0NjM0NzRjMDI4NWRmNWRiZjJiY2FiNzNkYTY1MTM1ODgzOWU5Yjc3NDgxYjJlYWIxMDc3MDhjIiwiZXhlY3V0aW9uX2F1dGhvcml0eV9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOCIsImV4ZWN1dGlvbl9hdXRob3JpdHlfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImV4ZWN1dGlvbl9hdXRob3JpdHlfc2lnbmVyX3NoYTI1NiI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJleGVjdXRpb25fb3V0Y29tZSI6eyJjb21wZW5zYXRpb25fYWN0aW9ucyI6MCwiZXZpZGVuY2VfY2xhc3NlcyI6WyJhdXRob3JpemF0aW9uIiwiaWRlbnRpdHkiXSwiZXhlY3V0aW9uX2NvbXBsZXRlZCI6ZmFsc2UsImV4dGVybmFsX25ldHdvcmtfY2FsbHMiOiJub25lIiwibW9kZWxfY2FsbHMiOjAsIm91dGNvbWUiOiJIQUxURUQiLCJwYXNzZWRfY29udHJhY3RzIjp7ImF1dGhvcml6YXRpb24iOjEsImVmZmVjdCI6MCwiaWRlbnRpdHkiOjEsInBvc3Rjb25kaXRpb24iOjB9LCJwb3N0Y29uZGl0aW9uX2V2aWRlbmNlIjpbeyJhY3Rpb25fa2luZCI6ImNsaWNrIiwiYWN0dWF0aW9uX3BhdGgiOiJndWkiLCJjb250cmFjdF9pbmRleCI6MCwiY29udHJhY3Rfa2luZCI6ImV4cGxpY2l0X3ByZWRpY2F0ZSIsImNvbnRyYWN0X3NoYTI1NiI6IjBhZGUwYjUyMGJjMDA3ODkxY2FjY2EwMDE3MTU3ODQ0MmEyYTc0Y2VmMTVmZjY0ZGRlNDVkZjA3YWZiNjRhZWIiLCJyZXN1bHRfaW5kZXgiOjAsInN0ZXBfY29udHJhY3Rfc2hhMjU2IjoiMWE1OTUzNmE0ODhiMWM0NmFhY2YwYmEzNzkzMGI4NDA2MmMxNDI3NTVmYTkzOTE1MmVmNWUyOGM0MDk0NzFlZCIsInN0ZXBfaW5kZXgiOjAsInZlcmRpY3QiOiJ1bnZlcmlmaWFibGUiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIn1dLCJwcm9kdWN0aW9uX2VsaWdpYmxlIjpmYWxzZSwicHJvZmlsZSI6InN0YW5kYXJkIiwicXVhbGlmaWNhdGlvbl9ldmlkZW5jZV9vbmx5IjpmYWxzZSwicmVxdWlyZWRfY29udHJhY3RzIjp7ImF1dGhvcml6YXRpb24iOjEsImVmZmVjdCI6MSwiaWRlbnRpdHkiOjEsInBvc3Rjb25kaXRpb24iOjF9LCJ2ZXJzaW9uIjoib3BlbmFkYXB0LmV4ZWN1dGlvbi1vdXRjb21lL3YxIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSJ9LCJleGVjdXRpb25fb3V0Y29tZV9zaGEyNTYiOiJmZTM4OWJhYjBlYjQ0NDdjZWMxOTk4Mjc0ZjcyN2NhNTcwMDQ5ZmVmZDU1N2RiNzk5MDQ3Njk5ZjJmNzhmMTQyIiwiZXhlY3V0aW9uX3B1cnBvc2UiOiJwcm9kdWN0aW9uIiwiZmluYWxfYXV0aG9yaXR5X3NlcXVlbmNlIjowLCJmaW5hbF9ydW50aW1lX2RlbGl2ZXJ5X3NlcXVlbmNlIjowLCJmbG93X3J1bl9pZF9zaGEyNTYiOiIxMWU1OTRmNDgxOTU4YzEwZTMwMTVkMGJmMDQ0N2EyMmYwNjhhOGE2NDdmNDc1ZGYxNWNlMmM3YWI0YjhmM2YxIiwiaWRlbnRpdHlfY29udHJhY3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsImlzc3VlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDNaIiwicGVuZGluZ19wZXJtaXRfY291bnQiOjAsInBlcm1pdF9jaGFpbiI6eyJlbnRyaWVzIjpbXSwicGVybWl0X2NoYWluX3NoYTI1NiI6IjgyZGFiNTQyOGUyNTJkMThhNTliMDE3NzczOWUwMGNhYWRiNzYyZGNmNTlmNDAzNmRlYTRkNzdjM2MzMjAzY2IiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXBlcm1pdC1jaGFpbi92MiJ9LCJwZXJtaXRfY291bnQiOjAsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X3JldmlzaW9uIjo3LCJxdWFsaWZpY2F0aW9uX3NpZ25lcl9yZWdpc3RyeV9zaGEyNTYiOiJlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlIiwicnVuX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAxIiwicnVuX3JlY2VpcHQiOnsiYXV0aG9yaXphdGlvbl9jb25maXJtZWQiOjEsImF1dGhvcml6YXRpb25fcmVxdWlyZWQiOjEsImJ1bmRsZV9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZHVyYXRpb25fbXMiOjEwMCwiZWZmZWN0X3RpZXJfcmVhY2hlZCI6Im5vbmUiLCJlZmZlY3RzX2NvbmZpcm1lZCI6MCwiZWZmZWN0c19yZXF1aXJlZCI6MSwiZXN0X2Nvc3RfbWljcm91c2QiOjAsImV2aWRlbmNlX2NsYXNzZXMiOlsiYXV0aG9yaXphdGlvbiIsImlkZW50aXR5Il0sImV4dGVybmFsX25ldHdvcmtfY2FsbHMiOiJub25lIiwiZ2VuZXJhdGVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMFoiLCJoZWFscyI6MCwiaWRlbnRpdHlfYXBwbGljYWJsZSI6MSwiaWRlbnRpdHlfYXJtZWQiOjEsImlkZW50aXR5X2NvbmZpcm1lZCI6MSwiaWRlbnRpdHlfcmVxdWlyZWQiOjEsIm1vZGVsX2NhbGxzIjowLCJvdXRjb21lIjoiSEFMVEVEIiwib3Zlcl9oYWx0X2NvdW50IjowLCJwb3N0Y29uZGl0aW9uc19jb25maXJtZWQiOjAsInBvc3Rjb25kaXRpb25zX3JlcXVpcmVkIjoxLCJwcm9kdWN0aW9uX2VsaWdpYmxlIjpmYWxzZSwicHJvZmlsZSI6InN0YW5kYXJkIiwicHJvdmVuYW5jZSI6InByb2R1Y3Rpb24iLCJyZWNlaXB0X2J1aWxkZXJfdmVyc2lvbiI6IjEuMi4zIiwicnVuZ19oaXN0b2dyYW0iOnt9LCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLXJ1bi1yZWNlaXB0L3YxIiwic291cmNlX3JlY2VpcHRfZGlnZXN0IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsInNvdXJjZV9yZWNlaXB0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJzb3VyY2Vfc2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucnVuLXJlcG9ydC92MSIsInN0ZXBzX29rIjowLCJzdGVwc190b3RhbCI6MSwic3Vic3RyYXRlIjoid2ViIiwidHJhbnNhY3Rpb25fb3V0Y29tZSI6IkhBTFRFRF9CRUZPUkVfRUZGRUNUIn0sInJ1bl9yZWNlaXB0X3NoYTI1NiI6ImFiNTBhMDA2YTg4OGIzZjkwZTFlNzFlZjIwOTIxYWY3MTdiMmY0MWEzNjc2ZTYwNWZiZGI4MjBjYjZiNTNjYzQiLCJydW5fcmVwb3J0X29iamVjdF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwicnVuX3JlcG9ydF9vYmplY3RfdmVyc2lvbiI6InZlcnNpb246aGFsdGVkOjEiLCJydW5fcmVwb3J0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJydW50aW1lX2Vudmlyb25tZW50X3NoYTI1NiI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJydW50aW1lX3N1YnN0cmF0ZSI6IndlYiIsInJ1bnRpbWVfdmFsaWRhdGlvbl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwNSIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tdGVybWluYWwtdmVyaWZpY2F0aW9uL3YyIiwidGVuYW50X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAyIiwidGVybWluYWxfc2VxdWVuY2UiOjEsInZlcmlmaWVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMloiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwid29ya2Zsb3dfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDMiLCJ3b3JrZmxvd192ZXJzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA0In0sInNpZ25hdHVyZSI6IktHQzRqQllpN01ReVlkbFV5TnJ5bGowcmwxaUVNbUFFeHQwUmlxWjV2bGh0Y1lWQzVJOEY1RDZ2V0NkRVlnb09takZNOU5UNjZmVW95ODVsYlFOQkRnIiwic2lnbmVyIjp7ImFsZ29yaXRobSI6ImVkMjU1MTkiLCJrZXlfaWQiOiJldmlkZW5jZS1ydW5uZXItZWQyNTUxOS01NjQ3NWFhNzU0NjM0NzRjIiwicHVibGljX2tleSI6IkE2RUh2L1BPRUw0ZGNOMFk1MHZBbVdmazFqQ2JwUTFmSGR5R1pCSlZNYmc9In19", + "managed_result_loss": null, "name": "halted-before-effect-zero-permit", "payload_canonical_sha256": "a2909800fffc776ac70a5f6beb77b7c9941a91e7e2930eb20d9042210dc66001", "signature": "KGC4jBYi7MQyYdlUyNrylj0rl1iEMmAExt0RiqZ5vlhtcYVC5I8F5D6vWCdEYgoOmjFM9NT66fUoy85lbQNBDg", @@ -65,10 +108,142 @@ "verifier_identity": null }, "envelope_canonical_base64": "eyJwYXlsb2FkIjp7ImFja25vd2xlZGdlZF9wZXJtaXRfY291bnQiOjAsImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA2IiwiYWRtaXNzaW9uX3BvbGljeV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYWRtaXR0ZWRfcnVudGltZV9idWlsZF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiYnVuZGxlX2FydGlmYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJidW5kbGVfY29udGVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYnVuZGxlX3ZlcnNpb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDQiLCJlZmZlY3RfY29udHJhY3Rfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImVudmlyb25tZW50X2NvbnRyYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJlbnZpcm9ubWVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXZpZGVuY2VfaWRlbnRpdHlfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImV2aWRlbmNlX21hbmlmZXN0cyI6eyJhdXRob3JpemF0aW9uIjp7ImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA2IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOCIsImV4ZWN1dGlvbl9hdXRob3JpdHlfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImdvdmVybmVkX2F1dGhvcml6YXRpb25faWRfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsIm1hbmlmZXN0X3NoYTI1NiI6IjE1YzBlNzZkYzJlMzIxYTM4NGU1M2VjMTVmZjUzZTc1NTU3YjdjZGU3MWM1YWQyYmEyYjkzZmYyZTk1ODM1YTUiLCJwZXJtaXRfY2hhaW5fc2hhMjU2IjoiNTliMzk5NzFlMzA1MTA5YzU0Mjk5NDVhNWZhYjQ2NjBiMDlmNDFlN2FjM2ZmZDkyZTM1MDZhZjAwMzM3ZGE5NSIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tYXV0aG9yaXphdGlvbi1ldmlkZW5jZS92MSJ9LCJlZmZlY3QiOnsiY29uZmlybWVkIjowLCJlZmZlY3RfY29udHJhY3Rfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsIm1hbmlmZXN0X3NoYTI1NiI6ImFmMTUwOWNjMmU5ZmExZjViOGI4MTVlN2IxZjYwNDYxOWIyYTM1ZWMwZGU1ZTBkMzRiYmZhNjdjYzkxZGJiYzciLCJyZWNvcmRzIjpbeyJhYnNlbmNlX2Jhc2lzIjoibm9uZSIsImF0dGVtcHRfc3RhdGUiOiJkZWxpdmVyeV91bmNlcnRhaW4iLCJlZmZlY3RfY29udHJhY3RfaGFzaCI6InNoYTI1NjphYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZWZmZWN0X3ZlcmlmaWVkIjpmYWxzZSwiZmluYWxfdmVyZGljdCI6bnVsbCwib2JzZXJ2ZWRfZWZmZWN0IjoidW5rbm93biIsInJlY29uY2lsaWF0aW9uX2FjdGlvbnMiOjAsInJlY29uY2lsaWF0aW9uX2NvbXBsZXRlZCI6ZmFsc2UsInJlY29yZF9raW5kIjoidGVybWluYWxfZWZmZWN0X3N0YXRlIiwicmVzb2x2ZWRfZGVsaXZlcnlfdW5jZXJ0YWludHkiOmZhbHNlLCJyZXN1bHRfaW5kZXgiOjAsInZlcmlmaWNhdGlvbl9wZXJmb3JtZWQiOmZhbHNlLCJ2ZXJpZmljYXRpb25fdGllciI6bnVsbCwidmVyaWZpZXJfaWRlbnRpdHkiOm51bGx9XSwicmVxdWlyZWQiOjEsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZWZmZWN0LWV2aWRlbmNlL3YxIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSJ9LCJpZGVudGl0eSI6eyJjb25maXJtZWQiOjEsImlkZW50aXR5X2NvbnRyYWN0X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJtYW5pZmVzdF9zaGEyNTYiOiIxMzVjODYzZWRjN2ZhYjE4Y2EyOWI0OTI5M2ZjMjVhMWM5YmQ0ZGUwZTllZDI4ZDRjZWM2ZThkMGE2NzkxMjI5IiwicmVxdWlyZWQiOjEsInJlc3VsdHMiOlt7Im1vZGUiOiJzdHJ1Y3R1cmVkIiwicmVzdWx0X2luZGV4IjowLCJzaWduYWxzIjpbXSwic3RhdHVzIjoidmVyaWZpZWQifV0sInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24taWRlbnRpdHktZXZpZGVuY2UvdjEiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIn0sInBvbGljeSI6eyJhZG1pc3Npb25fcG9saWN5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJlZmZlY3RfY29udHJhY3Rfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImVudmlyb25tZW50X2NvbnRyYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJlbnZpcm9ubWVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZ292ZXJuZWRfcG9saWN5X2NvbnRyYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJnb3Zlcm5lZF9ydW50aW1lX2lucHV0c19kaWdlc3QiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiaWRlbnRpdHlfY29udHJhY3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsIm1hbmlmZXN0X3NoYTI1NiI6IjRmOTg4ZDAxNWJjZDdjZDdlMDViYTA2NjNkODlmMGE5NjhmMGQ4YWNlOTliMDkwZWJhYmVlNTJhMWM1NTA0MjEiLCJtaW5pbXVtX2VmZmVjdF90aWVyIjoxLCJydW50aW1lX2Vudmlyb25tZW50X3NoYTI1NiI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLXBvbGljeS1ldmlkZW5jZS92MSJ9LCJwb3N0Y29uZGl0aW9uIjp7ImNvbmZpcm1lZCI6MCwibWFuaWZlc3Rfc2hhMjU2IjoiM2VhNGM2NGEzMGIwY2YxN2JjYTA0ZjMyNjBlMGE0NzE4YjI3ZjUxZTFmZGMyYmI4OGExODI2MzBhMzRkZDVmZiIsInJlY29yZHMiOlt7ImFjdGlvbl9raW5kIjoiY2xpY2siLCJhY3R1YXRpb25fcGF0aCI6Imd1aSIsImNvbnRyYWN0X2luZGV4IjowLCJjb250cmFjdF9raW5kIjoiZXhwbGljaXRfcHJlZGljYXRlIiwiY29udHJhY3Rfc2hhMjU2IjoiMGFkZTBiNTIwYmMwMDc4OTFjYWNjYTAwMTcxNTc4NDQyYTJhNzRjZWYxNWZmNjRkZGU0NWRmMDdhZmI2NGFlYiIsInJlc3VsdF9pbmRleCI6MCwic3RlcF9jb250cmFjdF9zaGEyNTYiOiIxYTU5NTM2YTQ4OGIxYzQ2YWFjZjBiYTM3OTMwYjg0MDYyYzE0Mjc1NWZhOTM5MTUyZWY1ZTI4YzQwOTQ3MWVkIiwic3RlcF9pbmRleCI6MCwidmVyZGljdCI6InVudmVyaWZpYWJsZSIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifV0sInJlcXVpcmVkIjoxLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLXBvc3Rjb25kaXRpb24tZXZpZGVuY2UvdjEiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIn19LCJldmlkZW5jZV9ydW5uZXJfc2lnbmVyX3NoYTI1NiI6IjU2NDc1YWE3NTQ2MzQ3NGMwMjg1ZGY1ZGJmMmJjYWI3M2RhNjUxMzU4ODM5ZTliNzc0ODFiMmVhYjEwNzcwOGMiLCJleGVjdXRpb25fYXV0aG9yaXR5X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA4IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaWduZXJfc2hhMjU2IjoiMjRmNmVkNmFjYmZlMTAwOWMwMzBkN2NhNTY3YzMzY2E0ODMwOTExNDk4MjM2YjU1NjFhNmM4MmFiZWM1ZGUyOCIsImV4ZWN1dGlvbl9vdXRjb21lIjp7ImNvbXBlbnNhdGlvbl9hY3Rpb25zIjowLCJldmlkZW5jZV9jbGFzc2VzIjpbImF1dGhvcml6YXRpb24iLCJpZGVudGl0eSJdLCJleGVjdXRpb25fY29tcGxldGVkIjpmYWxzZSwiZXh0ZXJuYWxfbmV0d29ya19jYWxscyI6Im5vbmUiLCJtb2RlbF9jYWxscyI6MCwib3V0Y29tZSI6IkhBTFRFRCIsInBhc3NlZF9jb250cmFjdHMiOnsiYXV0aG9yaXphdGlvbiI6MSwiZWZmZWN0IjowLCJpZGVudGl0eSI6MSwicG9zdGNvbmRpdGlvbiI6MH0sInBvc3Rjb25kaXRpb25fZXZpZGVuY2UiOlt7ImFjdGlvbl9raW5kIjoiY2xpY2siLCJhY3R1YXRpb25fcGF0aCI6Imd1aSIsImNvbnRyYWN0X2luZGV4IjowLCJjb250cmFjdF9raW5kIjoiZXhwbGljaXRfcHJlZGljYXRlIiwiY29udHJhY3Rfc2hhMjU2IjoiMGFkZTBiNTIwYmMwMDc4OTFjYWNjYTAwMTcxNTc4NDQyYTJhNzRjZWYxNWZmNjRkZGU0NWRmMDdhZmI2NGFlYiIsInJlc3VsdF9pbmRleCI6MCwic3RlcF9jb250cmFjdF9zaGEyNTYiOiIxYTU5NTM2YTQ4OGIxYzQ2YWFjZjBiYTM3OTMwYjg0MDYyYzE0Mjc1NWZhOTM5MTUyZWY1ZTI4YzQwOTQ3MWVkIiwic3RlcF9pbmRleCI6MCwidmVyZGljdCI6InVudmVyaWZpYWJsZSIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifV0sInByb2R1Y3Rpb25fZWxpZ2libGUiOmZhbHNlLCJwcm9maWxlIjoic3RhbmRhcmQiLCJxdWFsaWZpY2F0aW9uX2V2aWRlbmNlX29ubHkiOmZhbHNlLCJyZXF1aXJlZF9jb250cmFjdHMiOnsiYXV0aG9yaXphdGlvbiI6MSwiZWZmZWN0IjoxLCJpZGVudGl0eSI6MSwicG9zdGNvbmRpdGlvbiI6MX0sInZlcnNpb24iOiJvcGVuYWRhcHQuZXhlY3V0aW9uLW91dGNvbWUvdjEiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIn0sImV4ZWN1dGlvbl9vdXRjb21lX3NoYTI1NiI6ImZlMzg5YmFiMGViNDQ0N2NlYzE5OTgyNzRmNzI3Y2E1NzAwNDlmZWZkNTU3ZGI3OTkwNDc2OTlmMmY3OGYxNDIiLCJleGVjdXRpb25fcHVycG9zZSI6InByb2R1Y3Rpb24iLCJmaW5hbF9hdXRob3JpdHlfc2VxdWVuY2UiOjAsImZpbmFsX3J1bnRpbWVfZGVsaXZlcnlfc2VxdWVuY2UiOjAsImZsb3dfcnVuX2lkX3NoYTI1NiI6IjExZTU5NGY0ODE5NThjMTBlMzAxNWQwYmYwNDQ3YTIyZjA2OGE4YTY0N2Y0NzVkZjE1Y2UyYzdhYjRiOGYzZjEiLCJpZGVudGl0eV9jb250cmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiaXNzdWVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowM1oiLCJwZW5kaW5nX3Blcm1pdF9jb3VudCI6MSwicGVybWl0X2NoYWluIjp7ImVudHJpZXMiOltdLCJwZW5kaW5nIjp7ImFjdHVhdGlvbl9yZXBsYXlfYXV0aG9yaXplZCI6ZmFsc2UsImRlbGl2ZXJ5X3JlY2VpcHRfYXJ0aWZhY3QiOm51bGwsImRlbGl2ZXJ5X3JlY2VpcHRfYXJ0aWZhY3Rfc2hhMjU2IjpudWxsLCJkZWxpdmVyeV9zdGF0ZSI6IlVOUkVTT0xWRUQiLCJwZXJtaXRfYXJ0aWZhY3QiOnsicGF5bG9hZCI6eyJhY3Rpb25fcmVxdWVzdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2FydGlmYWN0X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJhdXRob3JpdHlfc2VxdWVuY2UiOjAsImVudmlyb25tZW50X2RpZ2VzdCI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJldmlkZW5jZV9pZGVudGl0eV9zaGEyNTYiOiJlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlIiwiZXhlY3V0aW9uX2F1dGhvcml0eV9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOCIsImV4ZWN1dGlvbl9hdXRob3JpdHlfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImZsb3dfcnVuX2lkX3NoYTI1NiI6IjExZTU5NGY0ODE5NThjMTBlMzAxNWQwYmYwNDQ3YTIyZjA2OGE4YTY0N2Y0NzVkZjE1Y2UyYzdhYjRiOGYzZjEiLCJpbnB1dF9lZGdlX3NlcXVlbmNlIjoxLCJpc3N1ZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAwWiIsInBlcm1pdF9pZCI6InBlcm1pdDoxIiwicXVhbGlmaWNhdGlvbl9zaWduZXJfcmVnaXN0cnlfY2hlY2tlZF9hdCI6IjIwMjYtMDgtMThUMTE6NTk6MzBaIiwicXVhbGlmaWNhdGlvbl9zaWduZXJfcmVnaXN0cnlfZXhwaXJlc19hdCI6IjIwMjYtMDgtMjBUMTE6MDA6MDBaIiwicXVhbGlmaWNhdGlvbl9zaWduZXJfcmVnaXN0cnlfcmV2aXNpb24iOjcsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJydW5faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDEiLCJydW5fcmVxdWVzdF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1wZXJtaXQtcGF5bG9hZC92MiJ9LCJwYXlsb2FkX3NoYTI1NiI6ImM4N2Y1NzUxYWE5YjI3OWNjZTIzYWExNzhhZmY5NTZlMTlmNjkwZmNkMmY5ZjcwZTBkOTk5NzgyYTY5MGQ2YjgiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXBlcm1pdC1hcnRpZmFjdC92MiIsInNpZ25hdHVyZSI6IjBCeUhncUR4UVpybmdMSUYtNnRaT3E5bFhhbWNBUUMwZG9VVG5lS05QZVMtU3lvT2JReU9rQXVQRks1UFljTnpPYlp4Z3NnQUxkV2FJX3NhVUNwbEJnIiwic2lnbmVyIjp7ImFsZ29yaXRobSI6ImVkMjU1MTkiLCJrZXlfaWQiOiJkZWxpdmVyeS1hdXRob3JpdHktZWQyNTUxOS0yNGY2ZWQ2YWNiZmUxMDA5IiwicHVibGljX2tleSI6IktheTY0VUc4eXZDeUxocVUwMDBMeHpZZVVtMEwvaExJbDVTOGt5S1diZGM9In19LCJwZXJtaXRfYXJ0aWZhY3Rfc2hhMjU2IjoiOTcyYTgyYWY0NTZkYTU0MmJhYzc4NDYwMTg4OTY2ODg5MWQ4YjdjY2QyNDI5MDQ4MTZiMzI5MmUxNTdlNTI4OSIsInJlY2VpcHRfYWJzZW5jZV9vYnNlcnZlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDJaIiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1wZW5kaW5nLXBlcm1pdC92MiJ9LCJwZXJtaXRfY2hhaW5fc2hhMjU2IjoiNTliMzk5NzFlMzA1MTA5YzU0Mjk5NDVhNWZhYjQ2NjBiMDlmNDFlN2FjM2ZmZDkyZTM1MDZhZjAwMzM3ZGE5NSIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcGVybWl0LWNoYWluL3YyIn0sInBlcm1pdF9jb3VudCI6MSwicXVhbGlmaWNhdGlvbl9zaWduZXJfcmVnaXN0cnlfcmV2aXNpb24iOjcsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJydW5faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDEiLCJydW5fcmVjZWlwdCI6eyJhdXRob3JpemF0aW9uX2NvbmZpcm1lZCI6MSwiYXV0aG9yaXphdGlvbl9yZXF1aXJlZCI6MSwiYnVuZGxlX2RpZ2VzdCI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJkdXJhdGlvbl9tcyI6MTAwLCJlZmZlY3RfdGllcl9yZWFjaGVkIjoibm9uZSIsImVmZmVjdHNfY29uZmlybWVkIjowLCJlZmZlY3RzX3JlcXVpcmVkIjoxLCJlc3RfY29zdF9taWNyb3VzZCI6MCwiZXZpZGVuY2VfY2xhc3NlcyI6WyJhdXRob3JpemF0aW9uIiwiaWRlbnRpdHkiXSwiZXh0ZXJuYWxfbmV0d29ya19jYWxscyI6Im5vbmUiLCJnZW5lcmF0ZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAwWiIsImhlYWxzIjowLCJpZGVudGl0eV9hcHBsaWNhYmxlIjoxLCJpZGVudGl0eV9hcm1lZCI6MSwiaWRlbnRpdHlfY29uZmlybWVkIjoxLCJpZGVudGl0eV9yZXF1aXJlZCI6MSwibW9kZWxfY2FsbHMiOjAsIm91dGNvbWUiOiJIQUxURUQiLCJvdmVyX2hhbHRfY291bnQiOjAsInBvc3Rjb25kaXRpb25zX2NvbmZpcm1lZCI6MCwicG9zdGNvbmRpdGlvbnNfcmVxdWlyZWQiOjEsInByb2R1Y3Rpb25fZWxpZ2libGUiOmZhbHNlLCJwcm9maWxlIjoic3RhbmRhcmQiLCJwcm92ZW5hbmNlIjoicHJvZHVjdGlvbiIsInJlY2VpcHRfYnVpbGRlcl92ZXJzaW9uIjoiMS4yLjMiLCJydW5nX2hpc3RvZ3JhbSI6e30sInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tcnVuLXJlY2VpcHQvdjEiLCJzb3VyY2VfcmVjZWlwdF9kaWdlc3QiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwic291cmNlX3JlY2VpcHRfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsInNvdXJjZV9zY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5ydW4tcmVwb3J0L3YxIiwic3RlcHNfb2siOjAsInN0ZXBzX3RvdGFsIjoxLCJzdWJzdHJhdGUiOiJ3ZWIiLCJ0cmFuc2FjdGlvbl9vdXRjb21lIjoiUkVDT05DSUxJQVRJT05fUkVRVUlSRUQifSwicnVuX3JlY2VpcHRfc2hhMjU2IjoiMThlYjJjNGY0MTUzZGFiMDUzYmYwMjdjMjZmNjhhZmEwNjEzMTdlM2MyZTdkNWE2MGVlNThjM2VlNmIzZDdjNiIsInJ1bl9yZXBvcnRfb2JqZWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJydW5fcmVwb3J0X29iamVjdF92ZXJzaW9uIjoidmVyc2lvbjpyZWNvbmNpbGlhdGlvbjoxIiwicnVuX3JlcG9ydF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwicnVudGltZV9lbnZpcm9ubWVudF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwicnVudGltZV9zdWJzdHJhdGUiOiJ3ZWIiLCJydW50aW1lX3ZhbGlkYXRpb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDUiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLXRlcm1pbmFsLXZlcmlmaWNhdGlvbi92MiIsInRlbmFudF9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwMiIsInRlcm1pbmFsX3NlcXVlbmNlIjoxLCJ2ZXJpZmllZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDJaIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsIndvcmtmbG93X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAzIiwid29ya2Zsb3dfdmVyc2lvbl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwNCJ9LCJzaWduYXR1cmUiOiJkRUdXZ0NDTGZGTm1QNnV5X0JuZ1dZUHJnel9ScmpYeFVULUpkSEwzaTNEclZSTnJ6OWJsWlpzbTBRQXo2cWVHTy1UZkhHT2FLMTVTdUc2ZlIwRGpCdyIsInNpZ25lciI6eyJhbGdvcml0aG0iOiJlZDI1NTE5Iiwia2V5X2lkIjoiZXZpZGVuY2UtcnVubmVyLWVkMjU1MTktNTY0NzVhYTc1NDYzNDc0YyIsInB1YmxpY19rZXkiOiJBNkVIdi9QT0VMNGRjTjBZNTB2QW1XZmsxakNicFExZkhkeUdaQkpWTWJnPSJ9fQ==", + "managed_result_loss": null, "name": "reconciliation-required-pending-permit", "payload_canonical_sha256": "2f2af3926539d2bde7a12888bddbdc26aa3193818b82a01743a100d5181581b0", "signature": "dEGWgCCLfFNmP6uy_BngWYPrgz_RrjXxUT-JdHL3i3DrVRNrz9blZZsm0QAz6qeGO-TfHGOaK15SuG6fR0DjBw", "terminal_verification_artifact_sha256": "2abcc6c65e0288a235b901169415d59632c8eaacf9b1aac087b1bb0d55ced624" + }, + { + "callback": { + "artifact_bytes_source": "envelope_canonical_base64", + "outcome": "RECONCILIATION_REQUIRED", + "report_sha256": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "run_id": "00000000-0000-4000-8000-000000000001", + "schema_version": "openadapt.hosted-runner-terminal/v1", + "started": true, + "uncertain_delivery": false + }, + "effect_state": { + "absence_basis": "none", + "attempt_state": "delivery_uncertain", + "effect_contract_hash": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "effect_verified": false, + "final_verdict": null, + "observed_effect": "unknown", + "reconciliation_actions": 0, + "reconciliation_completed": false, + "record_kind": "terminal_effect_state", + "resolved_delivery_uncertainty": false, + "result_index": 0, + "verification_performed": false, + "verification_tier": null, + "verifier_identity": null + }, + "envelope_canonical_base64": "eyJwYXlsb2FkIjp7ImFja25vd2xlZGdlZF9wZXJtaXRfY291bnQiOjEsImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA2IiwiYWRtaXNzaW9uX3BvbGljeV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYWRtaXR0ZWRfcnVudGltZV9idWlsZF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiYnVuZGxlX2FydGlmYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJidW5kbGVfY29udGVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYnVuZGxlX3ZlcnNpb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDQiLCJlZmZlY3RfY29udHJhY3Rfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImVudmlyb25tZW50X2NvbnRyYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJlbnZpcm9ubWVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXZpZGVuY2VfaWRlbnRpdHlfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImV2aWRlbmNlX21hbmlmZXN0cyI6eyJhdXRob3JpemF0aW9uIjp7ImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA2IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOCIsImV4ZWN1dGlvbl9hdXRob3JpdHlfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImdvdmVybmVkX2F1dGhvcml6YXRpb25faWRfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsIm1hbmlmZXN0X3NoYTI1NiI6ImYwY2ExOWE2YjNlYWJlNTk0ZGJjOTA2ODljMmY3NGNiZTVlODJkNGQ5NDdkYjI5YTVkMDdiMTY0MWU4OTYxY2YiLCJwZXJtaXRfY2hhaW5fc2hhMjU2IjoiNTA0OGZlOTQ1ODgyZDI4MDI2MDA4ZDdlOTEzN2FkMDE2ZmRkMDFhZWFmNTg4NDgxZmI1YmQwZjI0MmE1MDA0MyIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tYXV0aG9yaXphdGlvbi1ldmlkZW5jZS92MSJ9LCJlZmZlY3QiOnsiY29uZmlybWVkIjowLCJlZmZlY3RfY29udHJhY3Rfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsIm1hbmlmZXN0X3NoYTI1NiI6ImFmMTUwOWNjMmU5ZmExZjViOGI4MTVlN2IxZjYwNDYxOWIyYTM1ZWMwZGU1ZTBkMzRiYmZhNjdjYzkxZGJiYzciLCJyZWNvcmRzIjpbeyJhYnNlbmNlX2Jhc2lzIjoibm9uZSIsImF0dGVtcHRfc3RhdGUiOiJkZWxpdmVyeV91bmNlcnRhaW4iLCJlZmZlY3RfY29udHJhY3RfaGFzaCI6InNoYTI1NjphYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZWZmZWN0X3ZlcmlmaWVkIjpmYWxzZSwiZmluYWxfdmVyZGljdCI6bnVsbCwib2JzZXJ2ZWRfZWZmZWN0IjoidW5rbm93biIsInJlY29uY2lsaWF0aW9uX2FjdGlvbnMiOjAsInJlY29uY2lsaWF0aW9uX2NvbXBsZXRlZCI6ZmFsc2UsInJlY29yZF9raW5kIjoidGVybWluYWxfZWZmZWN0X3N0YXRlIiwicmVzb2x2ZWRfZGVsaXZlcnlfdW5jZXJ0YWludHkiOmZhbHNlLCJyZXN1bHRfaW5kZXgiOjAsInZlcmlmaWNhdGlvbl9wZXJmb3JtZWQiOmZhbHNlLCJ2ZXJpZmljYXRpb25fdGllciI6bnVsbCwidmVyaWZpZXJfaWRlbnRpdHkiOm51bGx9XSwicmVxdWlyZWQiOjEsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZWZmZWN0LWV2aWRlbmNlL3YxIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSJ9LCJpZGVudGl0eSI6eyJjb25maXJtZWQiOjEsImlkZW50aXR5X2NvbnRyYWN0X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJtYW5pZmVzdF9zaGEyNTYiOiIxMzVjODYzZWRjN2ZhYjE4Y2EyOWI0OTI5M2ZjMjVhMWM5YmQ0ZGUwZTllZDI4ZDRjZWM2ZThkMGE2NzkxMjI5IiwicmVxdWlyZWQiOjEsInJlc3VsdHMiOlt7Im1vZGUiOiJzdHJ1Y3R1cmVkIiwicmVzdWx0X2luZGV4IjowLCJzaWduYWxzIjpbXSwic3RhdHVzIjoidmVyaWZpZWQifV0sInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24taWRlbnRpdHktZXZpZGVuY2UvdjEiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIn0sInBvbGljeSI6eyJhZG1pc3Npb25fcG9saWN5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJlZmZlY3RfY29udHJhY3Rfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImVudmlyb25tZW50X2NvbnRyYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJlbnZpcm9ubWVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZ292ZXJuZWRfcG9saWN5X2NvbnRyYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJnb3Zlcm5lZF9ydW50aW1lX2lucHV0c19kaWdlc3QiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiaWRlbnRpdHlfY29udHJhY3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsIm1hbmlmZXN0X3NoYTI1NiI6IjRmOTg4ZDAxNWJjZDdjZDdlMDViYTA2NjNkODlmMGE5NjhmMGQ4YWNlOTliMDkwZWJhYmVlNTJhMWM1NTA0MjEiLCJtaW5pbXVtX2VmZmVjdF90aWVyIjoxLCJydW50aW1lX2Vudmlyb25tZW50X3NoYTI1NiI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLXBvbGljeS1ldmlkZW5jZS92MSJ9LCJwb3N0Y29uZGl0aW9uIjp7ImNvbmZpcm1lZCI6MCwibWFuaWZlc3Rfc2hhMjU2IjoiM2VhNGM2NGEzMGIwY2YxN2JjYTA0ZjMyNjBlMGE0NzE4YjI3ZjUxZTFmZGMyYmI4OGExODI2MzBhMzRkZDVmZiIsInJlY29yZHMiOlt7ImFjdGlvbl9raW5kIjoiY2xpY2siLCJhY3R1YXRpb25fcGF0aCI6Imd1aSIsImNvbnRyYWN0X2luZGV4IjowLCJjb250cmFjdF9raW5kIjoiZXhwbGljaXRfcHJlZGljYXRlIiwiY29udHJhY3Rfc2hhMjU2IjoiMGFkZTBiNTIwYmMwMDc4OTFjYWNjYTAwMTcxNTc4NDQyYTJhNzRjZWYxNWZmNjRkZGU0NWRmMDdhZmI2NGFlYiIsInJlc3VsdF9pbmRleCI6MCwic3RlcF9jb250cmFjdF9zaGEyNTYiOiIxYTU5NTM2YTQ4OGIxYzQ2YWFjZjBiYTM3OTMwYjg0MDYyYzE0Mjc1NWZhOTM5MTUyZWY1ZTI4YzQwOTQ3MWVkIiwic3RlcF9pbmRleCI6MCwidmVyZGljdCI6InVudmVyaWZpYWJsZSIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifV0sInJlcXVpcmVkIjoxLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLXBvc3Rjb25kaXRpb24tZXZpZGVuY2UvdjEiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIn19LCJldmlkZW5jZV9ydW5uZXJfc2lnbmVyX3NoYTI1NiI6IjU2NDc1YWE3NTQ2MzQ3NGMwMjg1ZGY1ZGJmMmJjYWI3M2RhNjUxMzU4ODM5ZTliNzc0ODFiMmVhYjEwNzcwOGMiLCJleGVjdXRpb25fYXV0aG9yaXR5X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA4IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaWduZXJfc2hhMjU2IjoiMjRmNmVkNmFjYmZlMTAwOWMwMzBkN2NhNTY3YzMzY2E0ODMwOTExNDk4MjM2YjU1NjFhNmM4MmFiZWM1ZGUyOCIsImV4ZWN1dGlvbl9vdXRjb21lIjp7ImNvbXBlbnNhdGlvbl9hY3Rpb25zIjowLCJldmlkZW5jZV9jbGFzc2VzIjpbImF1dGhvcml6YXRpb24iLCJpZGVudGl0eSJdLCJleGVjdXRpb25fY29tcGxldGVkIjpmYWxzZSwiZXh0ZXJuYWxfbmV0d29ya19jYWxscyI6Im5vbmUiLCJtb2RlbF9jYWxscyI6MCwib3V0Y29tZSI6IkhBTFRFRCIsInBhc3NlZF9jb250cmFjdHMiOnsiYXV0aG9yaXphdGlvbiI6MSwiZWZmZWN0IjowLCJpZGVudGl0eSI6MSwicG9zdGNvbmRpdGlvbiI6MH0sInBvc3Rjb25kaXRpb25fZXZpZGVuY2UiOlt7ImFjdGlvbl9raW5kIjoiY2xpY2siLCJhY3R1YXRpb25fcGF0aCI6Imd1aSIsImNvbnRyYWN0X2luZGV4IjowLCJjb250cmFjdF9raW5kIjoiZXhwbGljaXRfcHJlZGljYXRlIiwiY29udHJhY3Rfc2hhMjU2IjoiMGFkZTBiNTIwYmMwMDc4OTFjYWNjYTAwMTcxNTc4NDQyYTJhNzRjZWYxNWZmNjRkZGU0NWRmMDdhZmI2NGFlYiIsInJlc3VsdF9pbmRleCI6MCwic3RlcF9jb250cmFjdF9zaGEyNTYiOiIxYTU5NTM2YTQ4OGIxYzQ2YWFjZjBiYTM3OTMwYjg0MDYyYzE0Mjc1NWZhOTM5MTUyZWY1ZTI4YzQwOTQ3MWVkIiwic3RlcF9pbmRleCI6MCwidmVyZGljdCI6InVudmVyaWZpYWJsZSIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifV0sInByb2R1Y3Rpb25fZWxpZ2libGUiOmZhbHNlLCJwcm9maWxlIjoic3RhbmRhcmQiLCJxdWFsaWZpY2F0aW9uX2V2aWRlbmNlX29ubHkiOmZhbHNlLCJyZXF1aXJlZF9jb250cmFjdHMiOnsiYXV0aG9yaXphdGlvbiI6MSwiZWZmZWN0IjoxLCJpZGVudGl0eSI6MSwicG9zdGNvbmRpdGlvbiI6MX0sInZlcnNpb24iOiJvcGVuYWRhcHQuZXhlY3V0aW9uLW91dGNvbWUvdjEiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIn0sImV4ZWN1dGlvbl9vdXRjb21lX3NoYTI1NiI6ImZlMzg5YmFiMGViNDQ0N2NlYzE5OTgyNzRmNzI3Y2E1NzAwNDlmZWZkNTU3ZGI3OTkwNDc2OTlmMmY3OGYxNDIiLCJleGVjdXRpb25fcHVycG9zZSI6InByb2R1Y3Rpb24iLCJmaW5hbF9hdXRob3JpdHlfc2VxdWVuY2UiOjAsImZpbmFsX3J1bnRpbWVfZGVsaXZlcnlfc2VxdWVuY2UiOjksImZsb3dfcnVuX2lkX3NoYTI1NiI6IjExZTU5NGY0ODE5NThjMTBlMzAxNWQwYmYwNDQ3YTIyZjA2OGE4YTY0N2Y0NzVkZjE1Y2UyYzdhYjRiOGYzZjEiLCJpZGVudGl0eV9jb250cmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiaXNzdWVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowM1oiLCJwZW5kaW5nX3Blcm1pdF9jb3VudCI6MCwicGVybWl0X2NoYWluIjp7ImVudHJpZXMiOlt7ImRlbGl2ZXJ5X3JlY2VpcHRfYXJ0aWZhY3QiOnsicGF5bG9hZCI6eyJhdXRoZW50aWNhdGVkX3J1bm5lcl9pZF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwiYXV0aGVudGljYXRlZF9zZXNzaW9uX2lkX3NoYTI1NiI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJkZWxpdmVyZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAxWiIsImV4ZWN1dGlvbl9hdXRob3JpdHlfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDgiLCJvbmVfdXNlX2NsYWltX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDEwIiwicGVybWl0X2FydGlmYWN0X3NoYTI1NiI6Ijk3MmE4MmFmNDU2ZGE1NDJiYWM3ODQ2MDE4ODk2Njg4OTFkOGI3Y2NkMjQyOTA0ODE2YjMyOTJlMTU3ZTUyODkiLCJwZXJtaXRfaWQiOiJwZXJtaXQ6MSIsInJ1bnRpbWVfZGVsaXZlcnlfc2VxdWVuY2UiOjksInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcmVjZWlwdC1wYXlsb2FkL3YyIn0sInBheWxvYWRfc2hhMjU2IjoiOGE4ZjZkODg3NTBjYmI2YjNiZDY2MjA5M2FkMjllMmJjMjBjNmFiNjk5MWQ3MGU1ODg2OTFjOGIzYWI2NjJiOSIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcmVjZWlwdC1hcnRpZmFjdC92MiIsInNpZ25hdHVyZSI6IkFPS3FDZ1MxczBYYS1peUU5NlYteWxQelFjdjJ1dk9zdXlnSHp2dTJSeVY3RkxzSEZfTFZmcXl4NHUycHVtbEVsMFlrNVl1NzBKVlVrc1pwYVVwRER3Iiwic2lnbmVyIjp7ImFsZ29yaXRobSI6ImVkMjU1MTkiLCJrZXlfaWQiOiJkZWxpdmVyeS1hdXRob3JpdHktZWQyNTUxOS0yNGY2ZWQ2YWNiZmUxMDA5IiwicHVibGljX2tleSI6IktheTY0VUc4eXZDeUxocVUwMDBMeHpZZVVtMEwvaExJbDVTOGt5S1diZGM9In19LCJkZWxpdmVyeV9yZWNlaXB0X2FydGlmYWN0X3NoYTI1NiI6ImMwMGExYmE3MDE1ZjNjYmUwNWE3NmFlYWJmZjYxOWQ3OTNlNzM3NWEzMTBlMTk1ZmNiYmQyZDI5NDhmMmIyMTQiLCJwZXJtaXRfYXJ0aWZhY3QiOnsicGF5bG9hZCI6eyJhY3Rpb25fcmVxdWVzdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2FydGlmYWN0X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJhdXRob3JpdHlfc2VxdWVuY2UiOjAsImVudmlyb25tZW50X2RpZ2VzdCI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJldmlkZW5jZV9pZGVudGl0eV9zaGEyNTYiOiJlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlIiwiZXhlY3V0aW9uX2F1dGhvcml0eV9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOCIsImV4ZWN1dGlvbl9hdXRob3JpdHlfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImZsb3dfcnVuX2lkX3NoYTI1NiI6IjExZTU5NGY0ODE5NThjMTBlMzAxNWQwYmYwNDQ3YTIyZjA2OGE4YTY0N2Y0NzVkZjE1Y2UyYzdhYjRiOGYzZjEiLCJpbnB1dF9lZGdlX3NlcXVlbmNlIjoxLCJpc3N1ZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAwWiIsInBlcm1pdF9pZCI6InBlcm1pdDoxIiwicXVhbGlmaWNhdGlvbl9zaWduZXJfcmVnaXN0cnlfY2hlY2tlZF9hdCI6IjIwMjYtMDgtMThUMTE6NTk6MzBaIiwicXVhbGlmaWNhdGlvbl9zaWduZXJfcmVnaXN0cnlfZXhwaXJlc19hdCI6IjIwMjYtMDgtMjBUMTE6MDA6MDBaIiwicXVhbGlmaWNhdGlvbl9zaWduZXJfcmVnaXN0cnlfcmV2aXNpb24iOjcsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJydW5faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDEiLCJydW5fcmVxdWVzdF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1wZXJtaXQtcGF5bG9hZC92MiJ9LCJwYXlsb2FkX3NoYTI1NiI6ImM4N2Y1NzUxYWE5YjI3OWNjZTIzYWExNzhhZmY5NTZlMTlmNjkwZmNkMmY5ZjcwZTBkOTk5NzgyYTY5MGQ2YjgiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXBlcm1pdC1hcnRpZmFjdC92MiIsInNpZ25hdHVyZSI6IjBCeUhncUR4UVpybmdMSUYtNnRaT3E5bFhhbWNBUUMwZG9VVG5lS05QZVMtU3lvT2JReU9rQXVQRks1UFljTnpPYlp4Z3NnQUxkV2FJX3NhVUNwbEJnIiwic2lnbmVyIjp7ImFsZ29yaXRobSI6ImVkMjU1MTkiLCJrZXlfaWQiOiJkZWxpdmVyeS1hdXRob3JpdHktZWQyNTUxOS0yNGY2ZWQ2YWNiZmUxMDA5IiwicHVibGljX2tleSI6IktheTY0VUc4eXZDeUxocVUwMDBMeHpZZVVtMEwvaExJbDVTOGt5S1diZGM9In19LCJwZXJtaXRfYXJ0aWZhY3Rfc2hhMjU2IjoiOTcyYTgyYWY0NTZkYTU0MmJhYzc4NDYwMTg4OTY2ODg5MWQ4YjdjY2QyNDI5MDQ4MTZiMzI5MmUxNTdlNTI4OSIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcGVybWl0LWNoYWluLWVudHJ5L3YyIn1dLCJwZXJtaXRfY2hhaW5fc2hhMjU2IjoiNTA0OGZlOTQ1ODgyZDI4MDI2MDA4ZDdlOTEzN2FkMDE2ZmRkMDFhZWFmNTg4NDgxZmI1YmQwZjI0MmE1MDA0MyIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcGVybWl0LWNoYWluL3YyIn0sInBlcm1pdF9jb3VudCI6MSwicXVhbGlmaWNhdGlvbl9zaWduZXJfcmVnaXN0cnlfcmV2aXNpb24iOjcsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJydW5faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDEiLCJydW5fcmVjZWlwdCI6eyJhdXRob3JpemF0aW9uX2NvbmZpcm1lZCI6MSwiYXV0aG9yaXphdGlvbl9yZXF1aXJlZCI6MSwiYnVuZGxlX2RpZ2VzdCI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJkdXJhdGlvbl9tcyI6MTAwLCJlZmZlY3RfdGllcl9yZWFjaGVkIjoibm9uZSIsImVmZmVjdHNfY29uZmlybWVkIjowLCJlZmZlY3RzX3JlcXVpcmVkIjoxLCJlc3RfY29zdF9taWNyb3VzZCI6MCwiZXZpZGVuY2VfY2xhc3NlcyI6WyJhdXRob3JpemF0aW9uIiwiaWRlbnRpdHkiXSwiZXh0ZXJuYWxfbmV0d29ya19jYWxscyI6Im5vbmUiLCJnZW5lcmF0ZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAwWiIsImhlYWxzIjowLCJpZGVudGl0eV9hcHBsaWNhYmxlIjoxLCJpZGVudGl0eV9hcm1lZCI6MSwiaWRlbnRpdHlfY29uZmlybWVkIjoxLCJpZGVudGl0eV9yZXF1aXJlZCI6MSwibW9kZWxfY2FsbHMiOjAsIm91dGNvbWUiOiJIQUxURUQiLCJvdmVyX2hhbHRfY291bnQiOjAsInBvc3Rjb25kaXRpb25zX2NvbmZpcm1lZCI6MCwicG9zdGNvbmRpdGlvbnNfcmVxdWlyZWQiOjEsInByb2R1Y3Rpb25fZWxpZ2libGUiOmZhbHNlLCJwcm9maWxlIjoic3RhbmRhcmQiLCJwcm92ZW5hbmNlIjoicHJvZHVjdGlvbiIsInJlY2VpcHRfYnVpbGRlcl92ZXJzaW9uIjoiMS4yLjMiLCJydW5nX2hpc3RvZ3JhbSI6e30sInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tcnVuLXJlY2VpcHQvdjEiLCJzb3VyY2VfcmVjZWlwdF9kaWdlc3QiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwic291cmNlX3JlY2VpcHRfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsInNvdXJjZV9zY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5ydW4tcmVwb3J0L3YxIiwic3RlcHNfb2siOjAsInN0ZXBzX3RvdGFsIjoxLCJzdWJzdHJhdGUiOiJ3ZWIiLCJ0cmFuc2FjdGlvbl9vdXRjb21lIjoiUkVDT05DSUxJQVRJT05fUkVRVUlSRUQifSwicnVuX3JlY2VpcHRfc2hhMjU2IjoiMThlYjJjNGY0MTUzZGFiMDUzYmYwMjdjMjZmNjhhZmEwNjEzMTdlM2MyZTdkNWE2MGVlNThjM2VlNmIzZDdjNiIsInJ1bl9yZXBvcnRfb2JqZWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJydW5fcmVwb3J0X29iamVjdF92ZXJzaW9uIjoidmVyc2lvbjpyZWNvbmNpbGlhdGlvbjphY2tub3dsZWRnZWQ6MSIsInJ1bl9yZXBvcnRfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsInJ1bnRpbWVfZW52aXJvbm1lbnRfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsInJ1bnRpbWVfc3Vic3RyYXRlIjoid2ViIiwicnVudGltZV92YWxpZGF0aW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA1Iiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi10ZXJtaW5hbC12ZXJpZmljYXRpb24vdjIiLCJ0ZW5hbnRfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDIiLCJ0ZXJtaW5hbF9zZXF1ZW5jZSI6MSwidmVyaWZpZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAyWiIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJ3b3JrZmxvd19pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwMyIsIndvcmtmbG93X3ZlcnNpb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDQifSwic2lnbmF0dXJlIjoiQjVjRnVWbl81dkhLWFRES1FjYWtTakJ1NFRxd2lMblFrRG50MXU2VERhM1dJTTk5bXRQTTVfdW9WdmJka056NnhtbDZYdDljWHpITW1IbkYyZkh3Q1EiLCJzaWduZXIiOnsiYWxnb3JpdGhtIjoiZWQyNTUxOSIsImtleV9pZCI6ImV2aWRlbmNlLXJ1bm5lci1lZDI1NTE5LTU2NDc1YWE3NTQ2MzQ3NGMiLCJwdWJsaWNfa2V5IjoiQTZFSHYvUE9FTDRkY04wWTUwdkFtV2ZrMWpDYnBRMWZIZHlHWkJKVk1iZz0ifX0=", + "managed_result_loss": null, + "name": "reconciliation-required-acknowledged-inconclusive", + "payload_canonical_sha256": "fb4579f7c07f9cd2a46ed8af3a040fc7e06883401be7e10466ef9bed4324ca68", + "signature": "B5cFuVn_5vHKXTDKQcakSjBu4TqwiLnQkDnt1u6TDa3WIM99mtPM5_uoVvbdkNz6xml6Xt9cXzHMmHnF2fHwCQ", + "terminal_verification_artifact_sha256": "90cf0455a33f17c0462915a89dee93a3fb8a81f6a59cedbef1de2d709277cade" + }, + { + "callback": { + "artifact_bytes_source": "envelope_canonical_base64", + "outcome": "RECONCILIATION_REQUIRED", + "report_sha256": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "run_id": "00000000-0000-4000-8000-000000000001", + "schema_version": "openadapt.hosted-runner-terminal/v1", + "started": true, + "uncertain_delivery": true + }, + "effect_state": null, + "envelope_canonical_base64": "eyJwYXlsb2FkIjp7ImFja25vd2xlZGdlZF9wZXJtaXRfY291bnQiOjAsImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA2IiwiYWRtaXNzaW9uX3BvbGljeV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYWRtaXR0ZWRfcnVudGltZV9idWlsZF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiYnVuZGxlX2FydGlmYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJidW5kbGVfY29udGVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYnVuZGxlX3ZlcnNpb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDQiLCJkZWxpdmVyeV9yZXN1bHRfbG9zc19jbG9zdXJlIjp7InBheWxvYWQiOnsiYWNrbm93bGVkZ2VkX3Blcm1pdF9jb3VudCI6MCwiYWN0dWF0aW9uX3JlcGxheV9hdXRob3JpemVkIjpmYWxzZSwiYXV0aGVudGljYXRlZF9ydW5uZXJfaWRfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImF1dGhlbnRpY2F0ZWRfc2Vzc2lvbl9pZF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwiYmxpbmRfcmV0cnlfYXV0aG9yaXplZCI6ZmFsc2UsImNoaWxkX3N0YXJ0X2V2aWRlbmNlX3NoYTI1NiI6IjY1YTZiZWQ5MjNlNDVhNmFhMGM2MjQzMDQ1ZTAzNjRjOTBhY2UwNjQ4ZmVjYjViMGJiMmViZDk0MDI3OTNjNzciLCJjaGlsZF9zdGFydGVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMFoiLCJjbG9zZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAyWiIsImNsb3N1cmVfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMTEiLCJjbG9zdXJlX3JlcXVlc3Rfc2hhMjU2IjoiYmFmNDE3YWU0OGVlYzQwNjU4NGVmNTI4NmFhYTFiMWFjMmU2ZTAzZDhhMjlhNGZiNGIwYzUzMjcwNGJlNTljNiIsImNsb3N1cmVfc2VxdWVuY2UiOjEsImRlbGl2ZXJ5X2Fja25vd2xlZGdtZW50X2F1dGhvcml6ZWQiOmZhbHNlLCJkZWxpdmVyeV9zdGF0ZSI6IkNMT1NFRF9VTlJFU09MVkVEX1JFU1VMVF9MT1NTIiwiZGlzcGF0Y2hfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDkiLCJkaXNwYXRjaF9zZXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDEwIiwiZWZmZWN0X2Fic2VuY2VfY2xhaW1lZCI6ZmFsc2UsImV4ZWN1dGlvbl9hdXRob3JpdHlfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDgiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NpZ25lcl9zaGEyNTYiOiIyNGY2ZWQ2YWNiZmUxMDA5YzAzMGQ3Y2E1NjdjMzNjYTQ4MzA5MTE0OTgyMzZiNTU2MWE2YzgyYWJlYzVkZTI4IiwiZmluYWxfYXV0aG9yaXR5X3NlcXVlbmNlIjowLCJmaW5hbF9pbnB1dF9lZGdlX3NlcXVlbmNlIjoxLCJmaW5hbF9ydW50aW1lX2RlbGl2ZXJ5X3NlcXVlbmNlIjowLCJmbG93X3J1bl9pZF9zaGEyNTYiOiIxMWU1OTRmNDgxOTU4YzEwZTMwMTVkMGJmMDQ0N2EyMmYwNjhhOGE2NDdmNDc1ZGYxNWNlMmM3YWI0YjhmM2YxIiwiaWRlbXBvdGVuY3lfa2V5X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJtYW5hZ2VkX2Rpc3BhdGNoX2JpbmRpbmdfc2hhMjU2Ijoic2hhMjU2OmNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJuZXdfcGVybWl0X2F1dGhvcml6ZWQiOmZhbHNlLCJub3RfcmVjZWl2ZWRfY2xhaW1lZCI6ZmFsc2UsInBlbmRpbmdfYWN0aW9uX3JlcXVlc3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsInBlbmRpbmdfcGVybWl0X2FydGlmYWN0X3NoYTI1NiI6Ijk3MmE4MmFmNDU2ZGE1NDJiYWM3ODQ2MDE4ODk2Njg4OTFkOGI3Y2NkMjQyOTA0ODE2YjMyOTJlMTU3ZTUyODkiLCJwZW5kaW5nX3Blcm1pdF9jb3VudCI6MSwicGVybWl0X2NoYWluX3NoYTI1NiI6IjU5YjM5OTcxZTMwNTEwOWM1NDI5OTQ1YTVmYWI0NjYwYjA5ZjQxZTdhYzNmZmQ5MmUzNTA2YWYwMDMzN2RhOTUiLCJwZXJtaXRfY291bnQiOjEsInJlY2VpcHRfYWJzZW5jZV9vYnNlcnZlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDJaIiwicmVzdWx0X2xvc3Nfb2JzZXJ2ZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAyWiIsInJ1bl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwMSIsInJ1bl9yZXF1ZXN0X3NoYTI1NiI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJydW5fc3RvcmVfaWRlbnRpdHlfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcmVzdWx0LWxvc3MtY2xvc3VyZS1wYXlsb2FkL3YyIiwidGVuYW50X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAyIiwidGVybWluYWxfY2FsbGJhY2tfcmVxdWlyZWQiOnRydWV9LCJwYXlsb2FkX3NoYTI1NiI6IjhkYjU4ZjZhMDVmNGVmMWY4Mjc3NjYwMGQ1ZTJhMTMwNjQ1YTNlMTJiNTBmZWU2ODEwODg3NGVmZjA4ZjdlYmYiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXJlc3VsdC1sb3NzLWNsb3N1cmUtYXJ0aWZhY3QvdjIiLCJzaWduYXR1cmUiOiJhakNhd3h3WTFZaUFVMXdwM2t1cFlHa3pubDcyVkFUcGxIV2dZMXVYNTdqRU9Gal80czJfdlhQbFVFQXlVbXBOaHA0eG9xVFhCUDhjOE9lMkpMZTNEdyIsInNpZ25lciI6eyJhbGdvcml0aG0iOiJlZDI1NTE5Iiwia2V5X2lkIjoiZGVsaXZlcnktYXV0aG9yaXR5LWVkMjU1MTktMjRmNmVkNmFjYmZlMTAwOSIsInB1YmxpY19rZXkiOiJLYXk2NFVHOHl2Q3lMaHFVMDAwTHh6WWVVbTBML2hMSWw1UzhreUtXYmRjPSJ9fSwiZWZmZWN0X2NvbnRyYWN0X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJlbnZpcm9ubWVudF9jb250cmFjdF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwiZW52aXJvbm1lbnRfZGlnZXN0IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImV2aWRlbmNlX2lkZW50aXR5X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJldmlkZW5jZV9tYW5pZmVzdHMiOnsiYXV0aG9yaXphdGlvbiI6eyJhZG1pc3Npb25fYXJ0aWZhY3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsImFkbWlzc2lvbl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwNiIsImV4ZWN1dGlvbl9hdXRob3JpdHlfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDgiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJnb3Zlcm5lZF9hdXRob3JpemF0aW9uX2lkX3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJtYW5pZmVzdF9zaGEyNTYiOiIxNWMwZTc2ZGMyZTMyMWEzODRlNTNlYzE1ZmY1M2U3NTU1N2I3Y2RlNzFjNWFkMmJhMmI5M2ZmMmU5NTgzNWE1IiwicGVybWl0X2NoYWluX3NoYTI1NiI6IjU5YjM5OTcxZTMwNTEwOWM1NDI5OTQ1YTVmYWI0NjYwYjA5ZjQxZTdhYzNmZmQ5MmUzNTA2YWYwMDMzN2RhOTUiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWF1dGhvcml6YXRpb24tZXZpZGVuY2UvdjEifSwiZWZmZWN0Ijp7ImNvbmZpcm1lZCI6MCwiZWZmZWN0X2NvbnRyYWN0X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJtYW5pZmVzdF9zaGEyNTYiOiI3ZTEyZGNhNWM0NGNmOTk4YTQ2OTM2MmI4NjJlODE2YTdkMmM4NTQxNjNmNjNlOGRlNjFmYjc5ZTk1YmE4MDA3IiwicmVjb3JkcyI6W10sInJlcXVpcmVkIjowLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWVmZmVjdC1ldmlkZW5jZS92MSIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifSwiaWRlbnRpdHkiOnsiY29uZmlybWVkIjowLCJpZGVudGl0eV9jb250cmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwibWFuaWZlc3Rfc2hhMjU2IjoiZDNhN2VhYzM0MjdkNzZmNmJjMzYwMzA3Mzg2MDkxMTlmMDdlMGQ5MWE2ZDM1OGFiY2U1YjZmMGQ2ZGY3ODY0NSIsInJlcXVpcmVkIjowLCJyZXN1bHRzIjpbXSwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1pZGVudGl0eS1ldmlkZW5jZS92MSIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifSwicG9saWN5Ijp7ImFkbWlzc2lvbl9wb2xpY3lfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImVmZmVjdF9jb250cmFjdF9zaGEyNTYiOiJlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlIiwiZW52aXJvbm1lbnRfY29udHJhY3Rfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsImVudmlyb25tZW50X2RpZ2VzdCI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJnb3Zlcm5lZF9wb2xpY3lfY29udHJhY3Rfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsImdvdmVybmVkX3J1bnRpbWVfaW5wdXRzX2RpZ2VzdCI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJpZGVudGl0eV9jb250cmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwibWFuaWZlc3Rfc2hhMjU2IjoiNGY5ODhkMDE1YmNkN2NkN2UwNWJhMDY2M2Q4OWYwYTk2OGYwZDhhY2U5OWIwOTBlYmFiZWU1MmExYzU1MDQyMSIsIm1pbmltdW1fZWZmZWN0X3RpZXIiOjEsInJ1bnRpbWVfZW52aXJvbm1lbnRfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tcG9saWN5LWV2aWRlbmNlL3YxIn0sInBvc3Rjb25kaXRpb24iOnsiY29uZmlybWVkIjowLCJtYW5pZmVzdF9zaGEyNTYiOiI1MmYwOWQ1ZDYzOWIxYzM4M2YzNzc5NjNlNDg3Y2I4OWQ4OTQxNzg1N2U0NGRhN2UzZjIzZTU1YmU3NTFlN2Y0IiwicmVjb3JkcyI6W10sInJlcXVpcmVkIjowLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLXBvc3Rjb25kaXRpb24tZXZpZGVuY2UvdjEiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIn19LCJldmlkZW5jZV9ydW5uZXJfc2lnbmVyX3NoYTI1NiI6IjU2NDc1YWE3NTQ2MzQ3NGMwMjg1ZGY1ZGJmMmJjYWI3M2RhNjUxMzU4ODM5ZTliNzc0ODFiMmVhYjEwNzcwOGMiLCJleGVjdXRpb25fYXV0aG9yaXR5X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA4IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaWduZXJfc2hhMjU2IjoiMjRmNmVkNmFjYmZlMTAwOWMwMzBkN2NhNTY3YzMzY2E0ODMwOTExNDk4MjM2YjU1NjFhNmM4MmFiZWM1ZGUyOCIsImV4ZWN1dGlvbl9vdXRjb21lIjp7ImNvbXBlbnNhdGlvbl9hY3Rpb25zIjowLCJldmlkZW5jZV9jbGFzc2VzIjpbImF1dGhvcml6YXRpb24iXSwiZXhlY3V0aW9uX2NvbXBsZXRlZCI6ZmFsc2UsImV4dGVybmFsX25ldHdvcmtfY2FsbHMiOiJub25lIiwibWFuYWdlZF9yZXN1bHRfbG9zc19ldmlkZW5jZV9zaGEyNTYiOiIzODEzMTljMWQ3NjJhMjNjMjExNmEyZWUwNzQxNzZjMDZmOWM4NDIwYjk1MTM4ZWFkYjliNjdkYTZhM2I0NDQ3IiwibW9kZWxfY2FsbHMiOjAsIm91dGNvbWUiOiJIQUxURUQiLCJwYXNzZWRfY29udHJhY3RzIjp7ImF1dGhvcml6YXRpb24iOjEsImVmZmVjdCI6MCwiaWRlbnRpdHkiOjAsInBvc3Rjb25kaXRpb24iOjB9LCJwb3N0Y29uZGl0aW9uX2V2aWRlbmNlIjpbXSwicHJvZHVjdGlvbl9lbGlnaWJsZSI6ZmFsc2UsInByb2ZpbGUiOiJzdGFuZGFyZCIsInF1YWxpZmljYXRpb25fZXZpZGVuY2Vfb25seSI6ZmFsc2UsInJlcXVpcmVkX2NvbnRyYWN0cyI6eyJhdXRob3JpemF0aW9uIjoxLCJlZmZlY3QiOjAsImlkZW50aXR5IjowLCJwb3N0Y29uZGl0aW9uIjowfSwidmVyc2lvbiI6Im9wZW5hZGFwdC5leGVjdXRpb24tb3V0Y29tZS92MSIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifSwiZXhlY3V0aW9uX291dGNvbWVfc2hhMjU2IjoiNzBjZjZmODE3NzJiMGJlNGIxZDcwNjdhMDVhYjRjMjkzMzY5MjM2ZDAyOWFhMWJlOGQ3OWQ2YzdjNzMxM2VmNSIsImV4ZWN1dGlvbl9wdXJwb3NlIjoicHJvZHVjdGlvbiIsImZpbmFsX2F1dGhvcml0eV9zZXF1ZW5jZSI6MCwiZmluYWxfcnVudGltZV9kZWxpdmVyeV9zZXF1ZW5jZSI6MCwiZmxvd19ydW5faWRfc2hhMjU2IjoiMTFlNTk0ZjQ4MTk1OGMxMGUzMDE1ZDBiZjA0NDdhMjJmMDY4YThhNjQ3ZjQ3NWRmMTVjZTJjN2FiNGI4ZjNmMSIsImlkZW50aXR5X2NvbnRyYWN0X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJpc3N1ZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAzWiIsIm1hbmFnZWRfcmVzdWx0X2xvc3MiOnsiYWN0dWF0aW9uX3JlcGxheV9hdXRob3JpemVkIjpmYWxzZSwiYXV0aGVudGljYXRlZF9ydW5uZXJfaWRfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImF1dGhlbnRpY2F0ZWRfc2Vzc2lvbl9pZF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwiYmxpbmRfcmV0cnlfYXV0aG9yaXplZCI6ZmFsc2UsImNoaWxkX3JlcG9ydF9yZXRhaW5lZCI6ZmFsc2UsImNoaWxkX3N0YXJ0X2V2aWRlbmNlX3NoYTI1NiI6IjY1YTZiZWQ5MjNlNDVhNmFhMGM2MjQzMDQ1ZTAzNjRjOTBhY2UwNjQ4ZmVjYjViMGJiMmViZDk0MDI3OTNjNzciLCJjaGlsZF9zdGFydGVkIjp0cnVlLCJjaGlsZF9zdGFydGVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMFoiLCJkZWxpdmVyeV9yZXN1bHRfbG9zc19jbG9zdXJlX2FydGlmYWN0X3NoYTI1NiI6ImNlYzM1N2FjZGI3NGY0ZTAyZGQxYzMyMDlhOGVjODgwOTE1Yzk4MzAxMzZlMDcyNjBmM2MxZjYzMWY4ZDUyZTgiLCJkZWxpdmVyeV9zdGF0ZSI6IkNMT1NFRF9VTlJFU09MVkVEX1JFU1VMVF9MT1NTIiwiZGlzcGF0Y2hfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDkiLCJkaXNwYXRjaF9zZXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDEwIiwiZWZmZWN0X2Fic2VuY2VfY2xhaW1lZCI6ZmFsc2UsImV2aWRlbmNlX3NoYTI1NiI6IjM4MTMxOWMxZDc2MmEyM2MyMTE2YTJlZTA3NDE3NmMwNmY5Yzg0MjBiOTUxMzhlYWRiOWI2N2RhNmEzYjQ0NDciLCJleGVjdXRpb25fYXV0aG9yaXR5X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA4IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaWduZXJfc2hhMjU2IjoiMjRmNmVkNmFjYmZlMTAwOWMwMzBkN2NhNTY3YzMzY2E0ODMwOTExNDk4MjM2YjU1NjFhNmM4MmFiZWM1ZGUyOCIsImZsb3dfcnVuX2lkX3NoYTI1NiI6IjExZTU5NGY0ODE5NThjMTBlMzAxNWQwYmYwNDQ3YTIyZjA2OGE4YTY0N2Y0NzVkZjE1Y2UyYzdhYjRiOGYzZjEiLCJpZGVtcG90ZW5jeV9rZXlfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsImxvc3NfY29kZSI6InJlcG9ydF9taXNzaW5nIiwibWFuYWdlZF9kaXNwYXRjaF9iaW5kaW5nX3NoYTI1NiI6InNoYTI1NjpjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwibm90X3JlY2VpdmVkX2NsYWltZWQiOmZhbHNlLCJvYnNlcnZlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDJaIiwicGVuZGluZ19hY3Rpb25fcmVxdWVzdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwicGVuZGluZ19wZXJtaXRfYXJ0aWZhY3Rfc2hhMjU2IjoiOTcyYTgyYWY0NTZkYTU0MmJhYzc4NDYwMTg4OTY2ODg5MWQ4YjdjY2QyNDI5MDQ4MTZiMzI5MmUxNTdlNTI4OSIsInJlcG9ydF9wcm92ZW5hbmNlIjoib3V0ZXJfcnVubmVyX3JlY292ZXJ5IiwicnVuX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAxIiwicnVuX3JlcXVlc3Rfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsInJ1bl9zdG9yZV9pZGVudGl0eV9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQubWFuYWdlZC1yZXN1bHQtbG9zcy92MSJ9LCJwZW5kaW5nX3Blcm1pdF9jb3VudCI6MSwicGVybWl0X2NoYWluIjp7ImVudHJpZXMiOltdLCJwZW5kaW5nIjp7ImFjdHVhdGlvbl9yZXBsYXlfYXV0aG9yaXplZCI6ZmFsc2UsImRlbGl2ZXJ5X3JlY2VpcHRfYXJ0aWZhY3QiOm51bGwsImRlbGl2ZXJ5X3JlY2VpcHRfYXJ0aWZhY3Rfc2hhMjU2IjpudWxsLCJkZWxpdmVyeV9zdGF0ZSI6IlVOUkVTT0xWRUQiLCJwZXJtaXRfYXJ0aWZhY3QiOnsicGF5bG9hZCI6eyJhY3Rpb25fcmVxdWVzdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2FydGlmYWN0X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJhdXRob3JpdHlfc2VxdWVuY2UiOjAsImVudmlyb25tZW50X2RpZ2VzdCI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJldmlkZW5jZV9pZGVudGl0eV9zaGEyNTYiOiJlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlIiwiZXhlY3V0aW9uX2F1dGhvcml0eV9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOCIsImV4ZWN1dGlvbl9hdXRob3JpdHlfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImZsb3dfcnVuX2lkX3NoYTI1NiI6IjExZTU5NGY0ODE5NThjMTBlMzAxNWQwYmYwNDQ3YTIyZjA2OGE4YTY0N2Y0NzVkZjE1Y2UyYzdhYjRiOGYzZjEiLCJpbnB1dF9lZGdlX3NlcXVlbmNlIjoxLCJpc3N1ZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAwWiIsInBlcm1pdF9pZCI6InBlcm1pdDoxIiwicXVhbGlmaWNhdGlvbl9zaWduZXJfcmVnaXN0cnlfY2hlY2tlZF9hdCI6IjIwMjYtMDgtMThUMTE6NTk6MzBaIiwicXVhbGlmaWNhdGlvbl9zaWduZXJfcmVnaXN0cnlfZXhwaXJlc19hdCI6IjIwMjYtMDgtMjBUMTE6MDA6MDBaIiwicXVhbGlmaWNhdGlvbl9zaWduZXJfcmVnaXN0cnlfcmV2aXNpb24iOjcsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJydW5faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDEiLCJydW5fcmVxdWVzdF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1wZXJtaXQtcGF5bG9hZC92MiJ9LCJwYXlsb2FkX3NoYTI1NiI6ImM4N2Y1NzUxYWE5YjI3OWNjZTIzYWExNzhhZmY5NTZlMTlmNjkwZmNkMmY5ZjcwZTBkOTk5NzgyYTY5MGQ2YjgiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXBlcm1pdC1hcnRpZmFjdC92MiIsInNpZ25hdHVyZSI6IjBCeUhncUR4UVpybmdMSUYtNnRaT3E5bFhhbWNBUUMwZG9VVG5lS05QZVMtU3lvT2JReU9rQXVQRks1UFljTnpPYlp4Z3NnQUxkV2FJX3NhVUNwbEJnIiwic2lnbmVyIjp7ImFsZ29yaXRobSI6ImVkMjU1MTkiLCJrZXlfaWQiOiJkZWxpdmVyeS1hdXRob3JpdHktZWQyNTUxOS0yNGY2ZWQ2YWNiZmUxMDA5IiwicHVibGljX2tleSI6IktheTY0VUc4eXZDeUxocVUwMDBMeHpZZVVtMEwvaExJbDVTOGt5S1diZGM9In19LCJwZXJtaXRfYXJ0aWZhY3Rfc2hhMjU2IjoiOTcyYTgyYWY0NTZkYTU0MmJhYzc4NDYwMTg4OTY2ODg5MWQ4YjdjY2QyNDI5MDQ4MTZiMzI5MmUxNTdlNTI4OSIsInJlY2VpcHRfYWJzZW5jZV9vYnNlcnZlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDJaIiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1wZW5kaW5nLXBlcm1pdC92MiJ9LCJwZXJtaXRfY2hhaW5fc2hhMjU2IjoiNTliMzk5NzFlMzA1MTA5YzU0Mjk5NDVhNWZhYjQ2NjBiMDlmNDFlN2FjM2ZmZDkyZTM1MDZhZjAwMzM3ZGE5NSIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcGVybWl0LWNoYWluL3YyIn0sInBlcm1pdF9jb3VudCI6MSwicXVhbGlmaWNhdGlvbl9zaWduZXJfcmVnaXN0cnlfcmV2aXNpb24iOjcsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJydW5faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDEiLCJydW5fcmVjZWlwdCI6eyJhdXRob3JpemF0aW9uX2NvbmZpcm1lZCI6MSwiYXV0aG9yaXphdGlvbl9yZXF1aXJlZCI6MSwiYnVuZGxlX2RpZ2VzdCI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJkdXJhdGlvbl9tcyI6MCwiZWZmZWN0X3RpZXJfcmVhY2hlZCI6Im5vbmUiLCJlZmZlY3RzX2NvbmZpcm1lZCI6MCwiZWZmZWN0c19yZXF1aXJlZCI6MCwiZXN0X2Nvc3RfbWljcm91c2QiOjAsImV2aWRlbmNlX2NsYXNzZXMiOlsiYXV0aG9yaXphdGlvbiJdLCJleHRlcm5hbF9uZXR3b3JrX2NhbGxzIjoibm9uZSIsImdlbmVyYXRlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDBaIiwiaGVhbHMiOjAsImlkZW50aXR5X2FwcGxpY2FibGUiOjAsImlkZW50aXR5X2FybWVkIjowLCJpZGVudGl0eV9jb25maXJtZWQiOjAsImlkZW50aXR5X3JlcXVpcmVkIjowLCJtYW5hZ2VkX3Jlc3VsdF9sb3NzX2V2aWRlbmNlX3NoYTI1NiI6IjM4MTMxOWMxZDc2MmEyM2MyMTE2YTJlZTA3NDE3NmMwNmY5Yzg0MjBiOTUxMzhlYWRiOWI2N2RhNmEzYjQ0NDciLCJtb2RlbF9jYWxscyI6MCwib3V0Y29tZSI6IkhBTFRFRCIsIm92ZXJfaGFsdF9jb3VudCI6MCwicG9zdGNvbmRpdGlvbnNfY29uZmlybWVkIjowLCJwb3N0Y29uZGl0aW9uc19yZXF1aXJlZCI6MCwicHJvZHVjdGlvbl9lbGlnaWJsZSI6ZmFsc2UsInByb2ZpbGUiOiJzdGFuZGFyZCIsInByb3ZlbmFuY2UiOiJwcm9kdWN0aW9uIiwicmVjZWlwdF9idWlsZGVyX3ZlcnNpb24iOiIxLjIuMyIsInJ1bmdfaGlzdG9ncmFtIjp7fSwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1ydW4tcmVjZWlwdC92MSIsInNvdXJjZV9yZWNlaXB0X2RpZ2VzdCI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJzb3VyY2VfcmVjZWlwdF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwic291cmNlX3NjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnJ1bi1yZXBvcnQvdjEiLCJzdGVwc19vayI6MCwic3RlcHNfdG90YWwiOjEsInN1YnN0cmF0ZSI6IndlYiIsInRyYW5zYWN0aW9uX291dGNvbWUiOiJSRUNPTkNJTElBVElPTl9SRVFVSVJFRCJ9LCJydW5fcmVjZWlwdF9zaGEyNTYiOiJhN2RhZmIxNWFiODE4MzhmNGIzNGRhZDA4MTI2OTJhN2E1ZjE5ZTAwNzkzNWUwZDc2NTIwNDFiOGU3MDUwYWUyIiwicnVuX3JlcG9ydF9vYmplY3Rfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsInJ1bl9yZXBvcnRfb2JqZWN0X3ZlcnNpb24iOiJ2ZXJzaW9uOm1hbmFnZWQtcmVzdWx0LWxvc3M6MSIsInJ1bl9yZXBvcnRfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsInJ1bnRpbWVfZW52aXJvbm1lbnRfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsInJ1bnRpbWVfc3Vic3RyYXRlIjoid2ViIiwicnVudGltZV92YWxpZGF0aW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA1Iiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi10ZXJtaW5hbC12ZXJpZmljYXRpb24vdjIiLCJ0ZW5hbnRfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDIiLCJ0ZXJtaW5hbF9zZXF1ZW5jZSI6MSwidmVyaWZpZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAyWiIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJ3b3JrZmxvd19pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwMyIsIndvcmtmbG93X3ZlcnNpb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDQifSwic2lnbmF0dXJlIjoiVzRUMmpQelZ3azFoM2NuR1JoVkZ5aTgwalZyanZkandRR04tTVpyeFQ2R2pVejljbDV4UXloajd2LURabkxFTkFzcGlnLTBGeEV1WVJHeU9tWkdDQVEiLCJzaWduZXIiOnsiYWxnb3JpdGhtIjoiZWQyNTUxOSIsImtleV9pZCI6ImV2aWRlbmNlLXJ1bm5lci1lZDI1NTE5LTU2NDc1YWE3NTQ2MzQ3NGMiLCJwdWJsaWNfa2V5IjoiQTZFSHYvUE9FTDRkY04wWTUwdkFtV2ZrMWpDYnBRMWZIZHlHWkJKVk1iZz0ifX0=", + "managed_result_loss": { + "actuation_replay_authorized": false, + "authenticated_runner_id_sha256": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "authenticated_session_id_sha256": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "blind_retry_authorized": false, + "child_report_retained": false, + "child_start_evidence_sha256": "65a6bed923e45a6aa0c6243045e0364c90ace0648fecb5b0bb2ebd9402793c77", + "child_started": true, + "child_started_at": "2026-08-18T12:00:00Z", + "delivery_result_loss_closure_artifact_sha256": "cec357acdb74f4e02dd1c3209a8ec880915c9830136e07260f3c1f631f8d52e8", + "delivery_state": "CLOSED_UNRESOLVED_RESULT_LOSS", + "dispatch_id": "00000000-0000-4000-8000-000000000009", + "dispatch_session_id": "00000000-0000-4000-8000-000000000010", + "effect_absence_claimed": false, + "evidence_sha256": "381319c1d762a23c2116a2ee074176c06f9c8420b95138eadb9b67da6a3b4447", + "execution_authority_id": "00000000-0000-4000-8000-000000000008", + "execution_authority_sha256": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "execution_authority_signer_sha256": "24f6ed6acbfe1009c030d7ca567c33ca4830911498236b5561a6c82abec5de28", + "flow_run_id_sha256": "11e594f481958c10e3015d0bf0447a22f068a8a647f475df15ce2c7ab4b8f3f1", + "idempotency_key_sha256": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "loss_code": "report_missing", + "managed_dispatch_binding_sha256": "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "not_received_claimed": false, + "observed_at": "2026-08-18T12:00:02Z", + "pending_action_request_sha256": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "pending_permit_artifact_sha256": "972a82af456da542bac784601889668891d8b7ccd242904816b3292e157e5289", + "report_provenance": "outer_runner_recovery", + "run_id": "00000000-0000-4000-8000-000000000001", + "run_request_sha256": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "run_store_identity_sha256": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "schema_version": "openadapt.managed-result-loss/v1" + }, + "name": "reconciliation-required-managed-result-loss", + "payload_canonical_sha256": "1480dcd4830987d01d27a66647e8b38af02a605d93ca604c5cbc50c10a7a1852", + "signature": "W4T2jPzVwk1h3cnGRhVFyi80jVrjvdjwQGN-MZrxT6GjUz9cl5xQyhj7v-DZnLENAspig-0FxEuYRGyOmZGCAQ", + "terminal_verification_artifact_sha256": "fa3eb5109494d421cefff1557211b19614fbf4be654c188832c8130c3308899e" + }, + { + "callback": { + "artifact_bytes_source": "envelope_canonical_base64", + "outcome": "RECONCILIATION_REQUIRED", + "report_sha256": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "run_id": "00000000-0000-4000-8000-000000000001", + "schema_version": "openadapt.hosted-runner-terminal/v1", + "started": true, + "uncertain_delivery": false + }, + "effect_state": null, + "envelope_canonical_base64": "eyJwYXlsb2FkIjp7ImFja25vd2xlZGdlZF9wZXJtaXRfY291bnQiOjEsImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA2IiwiYWRtaXNzaW9uX3BvbGljeV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYWRtaXR0ZWRfcnVudGltZV9idWlsZF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiYnVuZGxlX2FydGlmYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJidW5kbGVfY29udGVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYnVuZGxlX3ZlcnNpb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDQiLCJkZWxpdmVyeV9yZXN1bHRfbG9zc19jbG9zdXJlIjp7InBheWxvYWQiOnsiYWNrbm93bGVkZ2VkX3Blcm1pdF9jb3VudCI6MSwiYWN0dWF0aW9uX3JlcGxheV9hdXRob3JpemVkIjpmYWxzZSwiYXV0aGVudGljYXRlZF9ydW5uZXJfaWRfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImF1dGhlbnRpY2F0ZWRfc2Vzc2lvbl9pZF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwiYmxpbmRfcmV0cnlfYXV0aG9yaXplZCI6ZmFsc2UsImNoaWxkX3N0YXJ0X2V2aWRlbmNlX3NoYTI1NiI6IjY1YTZiZWQ5MjNlNDVhNmFhMGM2MjQzMDQ1ZTAzNjRjOTBhY2UwNjQ4ZmVjYjViMGJiMmViZDk0MDI3OTNjNzciLCJjaGlsZF9zdGFydGVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMFoiLCJjbG9zZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAyWiIsImNsb3N1cmVfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMTEiLCJjbG9zdXJlX3JlcXVlc3Rfc2hhMjU2IjoiYmFmNDE3YWU0OGVlYzQwNjU4NGVmNTI4NmFhYTFiMWFjMmU2ZTAzZDhhMjlhNGZiNGIwYzUzMjcwNGJlNTljNiIsImNsb3N1cmVfc2VxdWVuY2UiOjEsImRlbGl2ZXJ5X2Fja25vd2xlZGdtZW50X2F1dGhvcml6ZWQiOmZhbHNlLCJkZWxpdmVyeV9zdGF0ZSI6IkNMT1NFRF9VTlJFU09MVkVEX1JFU1VMVF9MT1NTIiwiZGlzcGF0Y2hfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDkiLCJkaXNwYXRjaF9zZXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDEwIiwiZWZmZWN0X2Fic2VuY2VfY2xhaW1lZCI6ZmFsc2UsImV4ZWN1dGlvbl9hdXRob3JpdHlfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDgiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NpZ25lcl9zaGEyNTYiOiIyNGY2ZWQ2YWNiZmUxMDA5YzAzMGQ3Y2E1NjdjMzNjYTQ4MzA5MTE0OTgyMzZiNTU2MWE2YzgyYWJlYzVkZTI4IiwiZmluYWxfYXV0aG9yaXR5X3NlcXVlbmNlIjowLCJmaW5hbF9pbnB1dF9lZGdlX3NlcXVlbmNlIjoxLCJmaW5hbF9ydW50aW1lX2RlbGl2ZXJ5X3NlcXVlbmNlIjo5LCJmbG93X3J1bl9pZF9zaGEyNTYiOiIxMWU1OTRmNDgxOTU4YzEwZTMwMTVkMGJmMDQ0N2EyMmYwNjhhOGE2NDdmNDc1ZGYxNWNlMmM3YWI0YjhmM2YxIiwiaWRlbXBvdGVuY3lfa2V5X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJtYW5hZ2VkX2Rpc3BhdGNoX2JpbmRpbmdfc2hhMjU2Ijoic2hhMjU2OmNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJuZXdfcGVybWl0X2F1dGhvcml6ZWQiOmZhbHNlLCJub3RfcmVjZWl2ZWRfY2xhaW1lZCI6ZmFsc2UsInBlbmRpbmdfYWN0aW9uX3JlcXVlc3Rfc2hhMjU2IjpudWxsLCJwZW5kaW5nX3Blcm1pdF9hcnRpZmFjdF9zaGEyNTYiOm51bGwsInBlbmRpbmdfcGVybWl0X2NvdW50IjowLCJwZXJtaXRfY2hhaW5fc2hhMjU2IjoiNTA0OGZlOTQ1ODgyZDI4MDI2MDA4ZDdlOTEzN2FkMDE2ZmRkMDFhZWFmNTg4NDgxZmI1YmQwZjI0MmE1MDA0MyIsInBlcm1pdF9jb3VudCI6MSwicmVjZWlwdF9hYnNlbmNlX29ic2VydmVkX2F0IjpudWxsLCJyZXN1bHRfbG9zc19vYnNlcnZlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDJaIiwicnVuX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAxIiwicnVuX3JlcXVlc3Rfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsInJ1bl9zdG9yZV9pZGVudGl0eV9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1yZXN1bHQtbG9zcy1jbG9zdXJlLXBheWxvYWQvdjIiLCJ0ZW5hbnRfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDIiLCJ0ZXJtaW5hbF9jYWxsYmFja19yZXF1aXJlZCI6dHJ1ZX0sInBheWxvYWRfc2hhMjU2IjoiMTE5YjBkODA2Njk0ZWQyMTYwNGQwOTE3MTMyMmQ1MjFiYzBhYTEyYjFlYTc5ZmIzNDkyNTA0YWMzZWZjNjRlYSIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcmVzdWx0LWxvc3MtY2xvc3VyZS1hcnRpZmFjdC92MiIsInNpZ25hdHVyZSI6InZsUmhUdHFSdm9kYnNObWZ5MmFSU3pndU0tYmZkZDRUWkFyeHBvbGRHd0NSeWtDZWRVLUZhanhkdHlyTDd5TmNpQnZpdWNvTnBpUFUyQXBNdG9abEJnIiwic2lnbmVyIjp7ImFsZ29yaXRobSI6ImVkMjU1MTkiLCJrZXlfaWQiOiJkZWxpdmVyeS1hdXRob3JpdHktZWQyNTUxOS0yNGY2ZWQ2YWNiZmUxMDA5IiwicHVibGljX2tleSI6IktheTY0VUc4eXZDeUxocVUwMDBMeHpZZVVtMEwvaExJbDVTOGt5S1diZGM9In19LCJlZmZlY3RfY29udHJhY3Rfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImVudmlyb25tZW50X2NvbnRyYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJlbnZpcm9ubWVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXZpZGVuY2VfaWRlbnRpdHlfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImV2aWRlbmNlX21hbmlmZXN0cyI6eyJhdXRob3JpemF0aW9uIjp7ImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA2IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOCIsImV4ZWN1dGlvbl9hdXRob3JpdHlfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImdvdmVybmVkX2F1dGhvcml6YXRpb25faWRfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsIm1hbmlmZXN0X3NoYTI1NiI6ImYwY2ExOWE2YjNlYWJlNTk0ZGJjOTA2ODljMmY3NGNiZTVlODJkNGQ5NDdkYjI5YTVkMDdiMTY0MWU4OTYxY2YiLCJwZXJtaXRfY2hhaW5fc2hhMjU2IjoiNTA0OGZlOTQ1ODgyZDI4MDI2MDA4ZDdlOTEzN2FkMDE2ZmRkMDFhZWFmNTg4NDgxZmI1YmQwZjI0MmE1MDA0MyIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tYXV0aG9yaXphdGlvbi1ldmlkZW5jZS92MSJ9LCJlZmZlY3QiOnsiY29uZmlybWVkIjowLCJlZmZlY3RfY29udHJhY3Rfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsIm1hbmlmZXN0X3NoYTI1NiI6IjdlMTJkY2E1YzQ0Y2Y5OThhNDY5MzYyYjg2MmU4MTZhN2QyYzg1NDE2M2Y2M2U4ZGU2MWZiNzllOTViYTgwMDciLCJyZWNvcmRzIjpbXSwicmVxdWlyZWQiOjAsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZWZmZWN0LWV2aWRlbmNlL3YxIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSJ9LCJpZGVudGl0eSI6eyJjb25maXJtZWQiOjAsImlkZW50aXR5X2NvbnRyYWN0X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJtYW5pZmVzdF9zaGEyNTYiOiJkM2E3ZWFjMzQyN2Q3NmY2YmMzNjAzMDczODYwOTExOWYwN2UwZDkxYTZkMzU4YWJjZTViNmYwZDZkZjc4NjQ1IiwicmVxdWlyZWQiOjAsInJlc3VsdHMiOltdLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWlkZW50aXR5LWV2aWRlbmNlL3YxIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSJ9LCJwb2xpY3kiOnsiYWRtaXNzaW9uX3BvbGljeV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZWZmZWN0X2NvbnRyYWN0X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJlbnZpcm9ubWVudF9jb250cmFjdF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwiZW52aXJvbm1lbnRfZGlnZXN0IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImdvdmVybmVkX3BvbGljeV9jb250cmFjdF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwiZ292ZXJuZWRfcnVudGltZV9pbnB1dHNfZGlnZXN0IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsImlkZW50aXR5X2NvbnRyYWN0X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJtYW5pZmVzdF9zaGEyNTYiOiI0Zjk4OGQwMTViY2Q3Y2Q3ZTA1YmEwNjYzZDg5ZjBhOTY4ZjBkOGFjZTk5YjA5MGViYWJlZTUyYTFjNTUwNDIxIiwibWluaW11bV9lZmZlY3RfdGllciI6MSwicnVudGltZV9lbnZpcm9ubWVudF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1wb2xpY3ktZXZpZGVuY2UvdjEifSwicG9zdGNvbmRpdGlvbiI6eyJjb25maXJtZWQiOjAsIm1hbmlmZXN0X3NoYTI1NiI6IjUyZjA5ZDVkNjM5YjFjMzgzZjM3Nzk2M2U0ODdjYjg5ZDg5NDE3ODU3ZTQ0ZGE3ZTNmMjNlNTViZTc1MWU3ZjQiLCJyZWNvcmRzIjpbXSwicmVxdWlyZWQiOjAsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tcG9zdGNvbmRpdGlvbi1ldmlkZW5jZS92MSIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifX0sImV2aWRlbmNlX3J1bm5lcl9zaWduZXJfc2hhMjU2IjoiNTY0NzVhYTc1NDYzNDc0YzAyODVkZjVkYmYyYmNhYjczZGE2NTEzNTg4MzllOWI3NzQ4MWIyZWFiMTA3NzA4YyIsImV4ZWN1dGlvbl9hdXRob3JpdHlfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDgiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NpZ25lcl9zaGEyNTYiOiIyNGY2ZWQ2YWNiZmUxMDA5YzAzMGQ3Y2E1NjdjMzNjYTQ4MzA5MTE0OTgyMzZiNTU2MWE2YzgyYWJlYzVkZTI4IiwiZXhlY3V0aW9uX291dGNvbWUiOnsiY29tcGVuc2F0aW9uX2FjdGlvbnMiOjAsImV2aWRlbmNlX2NsYXNzZXMiOlsiYXV0aG9yaXphdGlvbiJdLCJleGVjdXRpb25fY29tcGxldGVkIjpmYWxzZSwiZXh0ZXJuYWxfbmV0d29ya19jYWxscyI6Im5vbmUiLCJtYW5hZ2VkX3Jlc3VsdF9sb3NzX2V2aWRlbmNlX3NoYTI1NiI6IjcxNDUyYjExODgzYWJjZDYzZDhjNzYxMzNkNDI2MDEyMjhmYWExYWZlY2Q4Mjc5YjVlY2NlODY2MThkNGViMjMiLCJtb2RlbF9jYWxscyI6MCwib3V0Y29tZSI6IkhBTFRFRCIsInBhc3NlZF9jb250cmFjdHMiOnsiYXV0aG9yaXphdGlvbiI6MSwiZWZmZWN0IjowLCJpZGVudGl0eSI6MCwicG9zdGNvbmRpdGlvbiI6MH0sInBvc3Rjb25kaXRpb25fZXZpZGVuY2UiOltdLCJwcm9kdWN0aW9uX2VsaWdpYmxlIjpmYWxzZSwicHJvZmlsZSI6InN0YW5kYXJkIiwicXVhbGlmaWNhdGlvbl9ldmlkZW5jZV9vbmx5IjpmYWxzZSwicmVxdWlyZWRfY29udHJhY3RzIjp7ImF1dGhvcml6YXRpb24iOjEsImVmZmVjdCI6MCwiaWRlbnRpdHkiOjAsInBvc3Rjb25kaXRpb24iOjB9LCJ2ZXJzaW9uIjoib3BlbmFkYXB0LmV4ZWN1dGlvbi1vdXRjb21lL3YxIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSJ9LCJleGVjdXRpb25fb3V0Y29tZV9zaGEyNTYiOiI0ODlhYmU5MzQ0OGNjYzc5NWZhZWY0NGJjZTcwMTE1MzQwODM2ZDVjNDc1ZDIwZGIzZmNmOWY2NTY2NTJmYzRkIiwiZXhlY3V0aW9uX3B1cnBvc2UiOiJwcm9kdWN0aW9uIiwiZmluYWxfYXV0aG9yaXR5X3NlcXVlbmNlIjowLCJmaW5hbF9ydW50aW1lX2RlbGl2ZXJ5X3NlcXVlbmNlIjo5LCJmbG93X3J1bl9pZF9zaGEyNTYiOiIxMWU1OTRmNDgxOTU4YzEwZTMwMTVkMGJmMDQ0N2EyMmYwNjhhOGE2NDdmNDc1ZGYxNWNlMmM3YWI0YjhmM2YxIiwiaWRlbnRpdHlfY29udHJhY3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsImlzc3VlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDNaIiwibWFuYWdlZF9yZXN1bHRfbG9zcyI6eyJhY3R1YXRpb25fcmVwbGF5X2F1dGhvcml6ZWQiOmZhbHNlLCJhdXRoZW50aWNhdGVkX3J1bm5lcl9pZF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYXV0aGVudGljYXRlZF9zZXNzaW9uX2lkX3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJibGluZF9yZXRyeV9hdXRob3JpemVkIjpmYWxzZSwiY2hpbGRfcmVwb3J0X3JldGFpbmVkIjpmYWxzZSwiY2hpbGRfc3RhcnRfZXZpZGVuY2Vfc2hhMjU2IjoiNjVhNmJlZDkyM2U0NWE2YWEwYzYyNDMwNDVlMDM2NGM5MGFjZTA2NDhmZWNiNWIwYmIyZWJkOTQwMjc5M2M3NyIsImNoaWxkX3N0YXJ0ZWQiOnRydWUsImNoaWxkX3N0YXJ0ZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAwWiIsImRlbGl2ZXJ5X3Jlc3VsdF9sb3NzX2Nsb3N1cmVfYXJ0aWZhY3Rfc2hhMjU2IjoiOTBkZjhiZDFmMjg5MWIyMDM2NjNhNjNmNDI1MTUwNzQ0NWRiZTgzODM2MGEyMTllNDNhZjlhMWJjZTBhODBhMSIsImRlbGl2ZXJ5X3N0YXRlIjoiQ0xPU0VEX1VOUkVTT0xWRURfUkVTVUxUX0xPU1MiLCJkaXNwYXRjaF9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOSIsImRpc3BhdGNoX3Nlc3Npb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMTAiLCJlZmZlY3RfYWJzZW5jZV9jbGFpbWVkIjpmYWxzZSwiZXZpZGVuY2Vfc2hhMjU2IjoiNzE0NTJiMTE4ODNhYmNkNjNkOGM3NjEzM2Q0MjYwMTIyOGZhYTFhZmVjZDgyNzliNWVjY2U4NjYxOGQ0ZWIyMyIsImV4ZWN1dGlvbl9hdXRob3JpdHlfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDgiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NpZ25lcl9zaGEyNTYiOiIyNGY2ZWQ2YWNiZmUxMDA5YzAzMGQ3Y2E1NjdjMzNjYTQ4MzA5MTE0OTgyMzZiNTU2MWE2YzgyYWJlYzVkZTI4IiwiZmxvd19ydW5faWRfc2hhMjU2IjoiMTFlNTk0ZjQ4MTk1OGMxMGUzMDE1ZDBiZjA0NDdhMjJmMDY4YThhNjQ3ZjQ3NWRmMTVjZTJjN2FiNGI4ZjNmMSIsImlkZW1wb3RlbmN5X2tleV9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwibG9zc19jb2RlIjoicmVwb3J0X21pc3NpbmciLCJtYW5hZ2VkX2Rpc3BhdGNoX2JpbmRpbmdfc2hhMjU2Ijoic2hhMjU2OmNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJub3RfcmVjZWl2ZWRfY2xhaW1lZCI6ZmFsc2UsIm9ic2VydmVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMloiLCJwZW5kaW5nX2FjdGlvbl9yZXF1ZXN0X3NoYTI1NiI6bnVsbCwicGVuZGluZ19wZXJtaXRfYXJ0aWZhY3Rfc2hhMjU2IjpudWxsLCJyZXBvcnRfcHJvdmVuYW5jZSI6Im91dGVyX3J1bm5lcl9yZWNvdmVyeSIsInJ1bl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwMSIsInJ1bl9yZXF1ZXN0X3NoYTI1NiI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJydW5fc3RvcmVfaWRlbnRpdHlfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0Lm1hbmFnZWQtcmVzdWx0LWxvc3MvdjEifSwicGVuZGluZ19wZXJtaXRfY291bnQiOjAsInBlcm1pdF9jaGFpbiI6eyJlbnRyaWVzIjpbeyJkZWxpdmVyeV9yZWNlaXB0X2FydGlmYWN0Ijp7InBheWxvYWQiOnsiYXV0aGVudGljYXRlZF9ydW5uZXJfaWRfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsImF1dGhlbnRpY2F0ZWRfc2Vzc2lvbl9pZF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiZGVsaXZlcmVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMVoiLCJleGVjdXRpb25fYXV0aG9yaXR5X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA4Iiwib25lX3VzZV9jbGFpbV9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAxMCIsInBlcm1pdF9hcnRpZmFjdF9zaGEyNTYiOiI5NzJhODJhZjQ1NmRhNTQyYmFjNzg0NjAxODg5NjY4ODkxZDhiN2NjZDI0MjkwNDgxNmIzMjkyZTE1N2U1Mjg5IiwicGVybWl0X2lkIjoicGVybWl0OjEiLCJydW50aW1lX2RlbGl2ZXJ5X3NlcXVlbmNlIjo5LCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXJlY2VpcHQtcGF5bG9hZC92MiJ9LCJwYXlsb2FkX3NoYTI1NiI6IjhhOGY2ZDg4NzUwY2JiNmIzYmQ2NjIwOTNhZDI5ZTJiYzIwYzZhYjY5OTFkNzBlNTg4NjkxYzhiM2FiNjYyYjkiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXJlY2VpcHQtYXJ0aWZhY3QvdjIiLCJzaWduYXR1cmUiOiJBT0txQ2dTMXMwWGEtaXlFOTZWLXlsUHpRY3YydXZPc3V5Z0h6dnUyUnlWN0ZMc0hGX0xWZnF5eDR1MnB1bWxFbDBZazVZdTcwSlZVa3NacGFVcEREdyIsInNpZ25lciI6eyJhbGdvcml0aG0iOiJlZDI1NTE5Iiwia2V5X2lkIjoiZGVsaXZlcnktYXV0aG9yaXR5LWVkMjU1MTktMjRmNmVkNmFjYmZlMTAwOSIsInB1YmxpY19rZXkiOiJLYXk2NFVHOHl2Q3lMaHFVMDAwTHh6WWVVbTBML2hMSWw1UzhreUtXYmRjPSJ9fSwiZGVsaXZlcnlfcmVjZWlwdF9hcnRpZmFjdF9zaGEyNTYiOiJjMDBhMWJhNzAxNWYzY2JlMDVhNzZhZWFiZmY2MTlkNzkzZTczNzVhMzEwZTE5NWZjYmJkMmQyOTQ4ZjJiMjE0IiwicGVybWl0X2FydGlmYWN0Ijp7InBheWxvYWQiOnsiYWN0aW9uX3JlcXVlc3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYXV0aG9yaXR5X3NlcXVlbmNlIjowLCJlbnZpcm9ubWVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXZpZGVuY2VfaWRlbnRpdHlfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImV4ZWN1dGlvbl9hdXRob3JpdHlfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDgiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJmbG93X3J1bl9pZF9zaGEyNTYiOiIxMWU1OTRmNDgxOTU4YzEwZTMwMTVkMGJmMDQ0N2EyMmYwNjhhOGE2NDdmNDc1ZGYxNWNlMmM3YWI0YjhmM2YxIiwiaW5wdXRfZWRnZV9zZXF1ZW5jZSI6MSwiaXNzdWVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMFoiLCJwZXJtaXRfaWQiOiJwZXJtaXQ6MSIsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X2NoZWNrZWRfYXQiOiIyMDI2LTA4LTE4VDExOjU5OjMwWiIsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X2V4cGlyZXNfYXQiOiIyMDI2LTA4LTIwVDExOjAwOjAwWiIsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X3JldmlzaW9uIjo3LCJxdWFsaWZpY2F0aW9uX3NpZ25lcl9yZWdpc3RyeV9zaGEyNTYiOiJlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlIiwicnVuX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAxIiwicnVuX3JlcXVlc3Rfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcGVybWl0LXBheWxvYWQvdjIifSwicGF5bG9hZF9zaGEyNTYiOiJjODdmNTc1MWFhOWIyNzljY2UyM2FhMTc4YWZmOTU2ZTE5ZjY5MGZjZDJmOWY3MGUwZDk5OTc4MmE2OTBkNmI4Iiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1wZXJtaXQtYXJ0aWZhY3QvdjIiLCJzaWduYXR1cmUiOiIwQnlIZ3FEeFFacm5nTElGLTZ0Wk9xOWxYYW1jQVFDMGRvVVRuZUtOUGVTLVN5b09iUXlPa0F1UEZLNVBZY056T2JaeGdzZ0FMZFdhSV9zYVVDcGxCZyIsInNpZ25lciI6eyJhbGdvcml0aG0iOiJlZDI1NTE5Iiwia2V5X2lkIjoiZGVsaXZlcnktYXV0aG9yaXR5LWVkMjU1MTktMjRmNmVkNmFjYmZlMTAwOSIsInB1YmxpY19rZXkiOiJLYXk2NFVHOHl2Q3lMaHFVMDAwTHh6WWVVbTBML2hMSWw1UzhreUtXYmRjPSJ9fSwicGVybWl0X2FydGlmYWN0X3NoYTI1NiI6Ijk3MmE4MmFmNDU2ZGE1NDJiYWM3ODQ2MDE4ODk2Njg4OTFkOGI3Y2NkMjQyOTA0ODE2YjMyOTJlMTU3ZTUyODkiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXBlcm1pdC1jaGFpbi1lbnRyeS92MiJ9XSwicGVybWl0X2NoYWluX3NoYTI1NiI6IjUwNDhmZTk0NTg4MmQyODAyNjAwOGQ3ZTkxMzdhZDAxNmZkZDAxYWVhZjU4ODQ4MWZiNWJkMGYyNDJhNTAwNDMiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXBlcm1pdC1jaGFpbi92MiJ9LCJwZXJtaXRfY291bnQiOjEsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X3JldmlzaW9uIjo3LCJxdWFsaWZpY2F0aW9uX3NpZ25lcl9yZWdpc3RyeV9zaGEyNTYiOiJlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlIiwicnVuX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAxIiwicnVuX3JlY2VpcHQiOnsiYXV0aG9yaXphdGlvbl9jb25maXJtZWQiOjEsImF1dGhvcml6YXRpb25fcmVxdWlyZWQiOjEsImJ1bmRsZV9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZHVyYXRpb25fbXMiOjAsImVmZmVjdF90aWVyX3JlYWNoZWQiOiJub25lIiwiZWZmZWN0c19jb25maXJtZWQiOjAsImVmZmVjdHNfcmVxdWlyZWQiOjAsImVzdF9jb3N0X21pY3JvdXNkIjowLCJldmlkZW5jZV9jbGFzc2VzIjpbImF1dGhvcml6YXRpb24iXSwiZXh0ZXJuYWxfbmV0d29ya19jYWxscyI6Im5vbmUiLCJnZW5lcmF0ZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAwWiIsImhlYWxzIjowLCJpZGVudGl0eV9hcHBsaWNhYmxlIjowLCJpZGVudGl0eV9hcm1lZCI6MCwiaWRlbnRpdHlfY29uZmlybWVkIjowLCJpZGVudGl0eV9yZXF1aXJlZCI6MCwibWFuYWdlZF9yZXN1bHRfbG9zc19ldmlkZW5jZV9zaGEyNTYiOiI3MTQ1MmIxMTg4M2FiY2Q2M2Q4Yzc2MTMzZDQyNjAxMjI4ZmFhMWFmZWNkODI3OWI1ZWNjZTg2NjE4ZDRlYjIzIiwibW9kZWxfY2FsbHMiOjAsIm91dGNvbWUiOiJIQUxURUQiLCJvdmVyX2hhbHRfY291bnQiOjAsInBvc3Rjb25kaXRpb25zX2NvbmZpcm1lZCI6MCwicG9zdGNvbmRpdGlvbnNfcmVxdWlyZWQiOjAsInByb2R1Y3Rpb25fZWxpZ2libGUiOmZhbHNlLCJwcm9maWxlIjoic3RhbmRhcmQiLCJwcm92ZW5hbmNlIjoicHJvZHVjdGlvbiIsInJlY2VpcHRfYnVpbGRlcl92ZXJzaW9uIjoiMS4yLjMiLCJydW5nX2hpc3RvZ3JhbSI6e30sInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tcnVuLXJlY2VpcHQvdjEiLCJzb3VyY2VfcmVjZWlwdF9kaWdlc3QiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwic291cmNlX3JlY2VpcHRfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsInNvdXJjZV9zY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5ydW4tcmVwb3J0L3YxIiwic3RlcHNfb2siOjAsInN0ZXBzX3RvdGFsIjoxLCJzdWJzdHJhdGUiOiJ3ZWIiLCJ0cmFuc2FjdGlvbl9vdXRjb21lIjoiUkVDT05DSUxJQVRJT05fUkVRVUlSRUQifSwicnVuX3JlY2VpcHRfc2hhMjU2IjoiNDhiZDFkNmRjOTVkYmNhOTlhMTM4ZDE2ZjIzMmNkNjkxMDI1ZThhNGUxM2E0OGFlYTA4ZTI4NmRkMjA2NzlhNSIsInJ1bl9yZXBvcnRfb2JqZWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJydW5fcmVwb3J0X29iamVjdF92ZXJzaW9uIjoidmVyc2lvbjptYW5hZ2VkLXJlc3VsdC1sb3NzOjEiLCJydW5fcmVwb3J0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJydW50aW1lX2Vudmlyb25tZW50X3NoYTI1NiI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJydW50aW1lX3N1YnN0cmF0ZSI6IndlYiIsInJ1bnRpbWVfdmFsaWRhdGlvbl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwNSIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tdGVybWluYWwtdmVyaWZpY2F0aW9uL3YyIiwidGVuYW50X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAyIiwidGVybWluYWxfc2VxdWVuY2UiOjEsInZlcmlmaWVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMloiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwid29ya2Zsb3dfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDMiLCJ3b3JrZmxvd192ZXJzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA0In0sInNpZ25hdHVyZSI6ImM2OFVFYUdXejVfb2tRMDN2cGZjWGJOS1poWEE1Y2FfV3dpaTBPeGdhVGI3RzJXc1FFZGVjZGI0Z0tqVDIzck5FRGtBRTFaQzRBb1ZpTUdXcFRlaERRIiwic2lnbmVyIjp7ImFsZ29yaXRobSI6ImVkMjU1MTkiLCJrZXlfaWQiOiJldmlkZW5jZS1ydW5uZXItZWQyNTUxOS01NjQ3NWFhNzU0NjM0NzRjIiwicHVibGljX2tleSI6IkE2RUh2L1BPRUw0ZGNOMFk1MHZBbVdmazFqQ2JwUTFmSGR5R1pCSlZNYmc9In19", + "managed_result_loss": { + "actuation_replay_authorized": false, + "authenticated_runner_id_sha256": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "authenticated_session_id_sha256": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "blind_retry_authorized": false, + "child_report_retained": false, + "child_start_evidence_sha256": "65a6bed923e45a6aa0c6243045e0364c90ace0648fecb5b0bb2ebd9402793c77", + "child_started": true, + "child_started_at": "2026-08-18T12:00:00Z", + "delivery_result_loss_closure_artifact_sha256": "90df8bd1f2891b203663a63f4251507445dbe838360a219e43af9a1bce0a80a1", + "delivery_state": "CLOSED_UNRESOLVED_RESULT_LOSS", + "dispatch_id": "00000000-0000-4000-8000-000000000009", + "dispatch_session_id": "00000000-0000-4000-8000-000000000010", + "effect_absence_claimed": false, + "evidence_sha256": "71452b11883abcd63d8c76133d42601228faa1afecd8279b5ecce86618d4eb23", + "execution_authority_id": "00000000-0000-4000-8000-000000000008", + "execution_authority_sha256": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "execution_authority_signer_sha256": "24f6ed6acbfe1009c030d7ca567c33ca4830911498236b5561a6c82abec5de28", + "flow_run_id_sha256": "11e594f481958c10e3015d0bf0447a22f068a8a647f475df15ce2c7ab4b8f3f1", + "idempotency_key_sha256": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", + "loss_code": "report_missing", + "managed_dispatch_binding_sha256": "sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "not_received_claimed": false, + "observed_at": "2026-08-18T12:00:02Z", + "pending_action_request_sha256": null, + "pending_permit_artifact_sha256": null, + "report_provenance": "outer_runner_recovery", + "run_id": "00000000-0000-4000-8000-000000000001", + "run_request_sha256": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "run_store_identity_sha256": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "schema_version": "openadapt.managed-result-loss/v1" + }, + "name": "reconciliation-required-managed-result-loss-acknowledged", + "payload_canonical_sha256": "f636736f6796ba6246fdd2d6c0668642928ad5990342e801b882b2c22013eae3", + "signature": "c68UEaGWz5_okQ03vpfcXbNKZhXA5ca_Wwii0OxgaTb7G2WsQEdecdb4gKjT23rNEDkAE1ZC4AoViMGWpTehDQ", + "terminal_verification_artifact_sha256": "b78ff44e81d4be51fbb28132c871aab660616a8ec5eba0dcde24e6298c0cd87f" } ] } diff --git a/tests/test_hosted_runner_adapter.py b/tests/test_hosted_runner_adapter.py index 11de044f..1dae494f 100644 --- a/tests/test_hosted_runner_adapter.py +++ b/tests/test_hosted_runner_adapter.py @@ -4,6 +4,7 @@ import json import os from base64 import b64decode, b64encode, urlsafe_b64encode +from concurrent.futures import ThreadPoolExecutor from dataclasses import replace from datetime import datetime, timezone from pathlib import Path @@ -59,17 +60,24 @@ ProductionDeliveryPermitChain, ProductionDeliveryPermitPayload, ProductionDeliveryReceiptPayload, + ProductionDeliveryResultLossClosurePayload, + ProductionPendingDeliveryPermit, delivery_authority_signer_sha256, evidence_runner_signer_sha256, sign_production_delivery_permit, sign_production_delivery_receipt, + sign_production_delivery_result_loss_closure, sign_production_terminal_verification, ) from openadapt_flow.transaction import TransactionOutcome from tests.test_run_receipt import _report as _production_report from tests.test_runner_client_lib import dispatch_payload from tests.test_terminal_verification_v2 import ( + IDS, + _acknowledged_reconciliation_payload, _halted_payload, + _managed_result_loss_acknowledged_payload, + _managed_result_loss_payload, _payload, _private_key, _reconciliation_payload, @@ -500,6 +508,78 @@ def _terminal_delivery_chain( ) +def _result_loss_closure_result( + dispatch: HostedDispatch, + marker: hosted.ManagedChildStartEvidence, + request: hosted.ProductionDeliveryResultLossClosureRequest, + chain: ProductionDeliveryPermitChain, +) -> hosted.ProductionDeliveryResultLossClosureResult: + all_permits = (*chain.entries, *((chain.pending,) if chain.pending else ())) + assert all_permits + first = all_permits[0] + final = all_permits[-1] + pending = chain.pending + acknowledged = chain.entries[-1] if chain.entries else None + payload = ProductionDeliveryResultLossClosurePayload( + closure_id="00000000-0000-4000-8000-000000000011", + closure_request_sha256=request.request_sha256(), + closed_at=request.result_loss_observed_at, + result_loss_observed_at=request.result_loss_observed_at, + receipt_absence_observed_at=( + pending.receipt_absence_observed_at if pending is not None else None + ), + tenant_id=dispatch.tenant_id, + run_id=dispatch.run_id, + flow_run_id_sha256=hashlib.sha256(dispatch.run_id.encode("utf-8")).hexdigest(), + dispatch_id=dispatch.dispatch_id, + dispatch_session_id=dispatch.dispatch_session_id, + managed_dispatch_binding_sha256=dispatch.payload.dispatch_binding_sha256, + idempotency_key_sha256=hosted.managed_result_loss_idempotency_sha256( + dispatch.idempotency_key + ), + authenticated_runner_id_sha256=hashlib.sha256( + dispatch.runner_id.encode("utf-8") + ).hexdigest(), + authenticated_session_id_sha256=hashlib.sha256( + dispatch.runner_session_id.encode("utf-8") + ).hexdigest(), + execution_authority_id=dispatch.execution_authority_id, + execution_authority_sha256=dispatch.execution_authority_sha256, + execution_authority_signer_sha256=(dispatch.execution_authority_signer_sha256), + child_started_at=marker.started_at, + child_start_evidence_sha256=marker.marker_sha256, + run_store_identity_sha256=marker.run_store_identity_sha256, + permit_chain_sha256=chain.permit_chain_sha256, + permit_count=len(all_permits), + acknowledged_permit_count=len(chain.entries), + pending_permit_count=1 if pending else 0, + pending_permit_artifact_sha256=( + pending.permit_artifact_sha256 if pending else None + ), + run_request_sha256=first.run_request_sha256, + pending_action_request_sha256=( + pending.action_request_sha256 if pending else None + ), + final_input_edge_sequence=final.input_edge_sequence, + final_authority_sequence=final.authority_sequence, + final_runtime_delivery_sequence=( + acknowledged.runtime_delivery_sequence if acknowledged else 0 + ), + ) + artifact = sign_production_delivery_result_loss_closure( + payload, + Ed25519PrivateKey.from_private_bytes(bytes(range(32, 64))), + ) + artifact_raw = hosted.canonical_json(artifact) + chain_raw = hosted.canonical_json(chain) + return hosted.ProductionDeliveryResultLossClosureResult( + closure_artifact_bytes_base64=b64encode(artifact_raw).decode("ascii"), + closure_artifact_sha256=artifact.artifact_sha256(), + permit_chain_bytes_base64=b64encode(chain_raw).decode("ascii"), + permit_chain_sha256=chain.permit_chain_sha256, + ) + + def test_outer_adapter_builds_stores_rereads_and_verifies_terminal_v2( monkeypatch, tmp_path, sealed ) -> None: @@ -687,8 +767,11 @@ def fail_proof_reread(path, *, maximum_bytes, label): verified_params=verified_params, dispatch_binding_sha256=binding, ) - assert not (storage_failure_dir / "production-terminal-report.json").exists() - assert not (storage_failure_dir / "production-terminal-verification.json").exists() + # The one-use terminal CAS remains authoritative after a component reread + # fault. Removing it would let a late result replace a sealed outcome. + assert (storage_failure_dir / "production-terminal-state.json").is_file() + assert (storage_failure_dir / "production-terminal-report.json").is_file() + assert (storage_failure_dir / "production-terminal-verification.json").is_file() monkeypatch.setattr(adapter, "_read_private_bytes", original_read) proof, report_sha256 = adapter._produce_terminal_verification( @@ -714,6 +797,82 @@ def fail_proof_reread(path, *, maximum_bytes, label): assert "2026-07-01" in report_path.read_text(encoding="utf-8") assert "2026-07-01" not in proof_path.read_text(encoding="utf-8") + replayed_proof, replayed_report_sha256 = adapter._produce_terminal_verification( + dispatch=dispatch, + report=report, + run_dir=run_dir, + qualification=qualification, + private_key=private_key, + verified_params=verified_params, + dispatch_binding_sha256=binding, + ) + assert hosted.canonical_json(replayed_proof) == hosted.canonical_json(proof) + assert replayed_report_sha256 == report_sha256 + + late_report = report.model_copy(update={"total_ms": report.total_ms + 1}) + with pytest.raises(ValueError, match="different terminal outcome"): + adapter._produce_terminal_verification( + dispatch=dispatch, + report=late_report, + run_dir=run_dir, + qualification=qualification, + private_key=private_key, + verified_params=verified_params, + dispatch_binding_sha256=binding, + ) + assert proof_path.read_bytes() == hosted.canonical_json(proof) + + race_dir = tmp_path / "terminal-race" + race_dir.mkdir(mode=0o700) + + def terminalize_once(_index): + return adapter._produce_terminal_verification( + dispatch=dispatch, + report=report, + run_dir=race_dir, + qualification=qualification, + private_key=private_key, + verified_params=verified_params, + dispatch_binding_sha256=binding, + ) + + with ThreadPoolExecutor(max_workers=4) as pool: + raced = list(pool.map(terminalize_once, range(4))) + assert {hosted.canonical_json(item[0]) for item in raced} == { + hosted.canonical_json(proof) + } + assert {item[1] for item in raced} == {report_sha256} + + advancing_race_dir = tmp_path / "advancing-terminal-race" + advancing_race_dir.mkdir(mode=0o700) + + class AdvancingDatetime(datetime): + calls = 0 + + @classmethod + def now(cls, tz=None): + cls.calls += 1 + value = fixed_now.replace(second=2 + cls.calls) + return value if tz is not None else value.replace(tzinfo=None) + + monkeypatch.setattr(hosted, "datetime", AdvancingDatetime) + + def advancing_terminalize_once(_index): + return adapter._produce_terminal_verification( + dispatch=dispatch, + report=report, + run_dir=advancing_race_dir, + qualification=qualification, + private_key=private_key, + verified_params=verified_params, + dispatch_binding_sha256=binding, + ) + + with ThreadPoolExecutor(max_workers=4) as pool: + advancing_raced = list(pool.map(advancing_terminalize_once, range(4))) + assert len({hosted.canonical_json(item[0]) for item in advancing_raced}) == 1 + assert {item[1] for item in advancing_raced} == {report_sha256} + def test_terminal_admission_is_revalidated_after_child_execution( monkeypatch, tmp_path, config, sealed @@ -847,6 +1006,453 @@ def runner(argv, _run_dir, child_env): } +@pytest.mark.parametrize( + ("execution", "expected_loss_code"), + [ + (RuntimeError("child exit result lost"), "runner_exception"), + (OSError("child transport result lost"), "runner_exception"), + ( + ManagedExecution(returncode=1, report_bytes=None), + "report_missing", + ), + ], + ids=("runtime-exception", "transport-exception", "missing-report"), +) +def test_expected_result_loss_returns_one_signed_reconciliation_without_retry( + monkeypatch, + tmp_path, + config, + sealed, + execution, + expected_loss_code, +) -> None: + workflow, _ = sealed + calls = 0 + + def runner(_argv, _run_dir, _child_env): + nonlocal calls + calls += 1 + if isinstance(execution, Exception): + raise execution + return execution + + adapter, dispatch = _prepared_adapter( + monkeypatch, tmp_path, config, workflow, runner + ) + payload = dispatch.payload.model_copy( + update={ + "run_id": IDS["run_id"], + "workflow_id": IDS["workflow_id"], + } + ) + payload = payload.model_copy( + update={ + "dispatch_binding_sha256": dispatch_binding_sha256( + IDS["run_id"], payload.authorization + ) + } + ) + dispatch = HostedDispatch.model_validate( + { + **dispatch.model_dump(mode="json"), + "run_id": IDS["run_id"], + "workflow_id": IDS["workflow_id"], + "payload": payload.model_dump(mode="json"), + } + ) + proof = sign_production_terminal_verification( + _managed_result_loss_payload(), _private_key() + ) + report = _production_report() + seen_loss_codes: list[str] = [] + + def produce_loss(**kwargs): + seen_loss_codes.append(kwargs["loss_code"]) + return proof, proof.payload.run_report_sha256, report + + monkeypatch.setattr(adapter, "_produce_managed_result_loss", produce_loss) + authority = DeliveryAuthority( + dispatch.managed_delivery_authority_url, + dispatch.delivery_authority_token, + ) + + result = adapter.execute( + dispatch, + runner_config=tmp_path / "runner.toml", + run_dir=tmp_path / "run", + authority=authority, + closure_authority=SimpleNamespace(), + ) + callback = adapter.callback_request(dispatch, result) + + assert calls == 1 + assert seen_loss_codes == [expected_loss_code] + assert result.outcome is TransactionOutcome.RECONCILIATION_REQUIRED + assert result.uncertain_delivery is True + assert result.terminal_verification == proof + assert ( + len( + [ + event + for event in callback.events + if event.get("schema_version") == "openadapt.hosted-runner-terminal/v1" + ] + ) + == 1 + ) + assert callback.events[-1]["outcome"] == "RECONCILIATION_REQUIRED" + assert callback.events[-1]["uncertain_delivery"] is True + with pytest.raises(RuntimeError, match="signed terminal reconciliation"): + adapter.execute( + dispatch, + runner_config=tmp_path / "runner.toml", + run_dir=tmp_path / "run-again", + authority=authority, + ) + assert calls == 1 + + +def test_managed_result_loss_report_is_outer_recovery_only(tmp_path, sealed) -> None: + workflow, _ = sealed + dispatch = _hosted_dispatch(workflow) + adapter = HostedRunnerAdapter(tmp_path / "ledger.sqlite") + run_dir = tmp_path / "run" + run_dir.mkdir(mode=0o700) + marker = hosted.ManagedChildStartEvidence.create( + started_at="2026-08-26T12:00:00Z", + dispatch_id=dispatch.dispatch_id, + dispatch_session_id=dispatch.dispatch_session_id, + run_id=dispatch.run_id, + managed_dispatch_binding_sha256=dispatch.payload.dispatch_binding_sha256, + authenticated_runner_id_sha256=hashlib.sha256( + dispatch.runner_id.encode("utf-8") + ).hexdigest(), + authenticated_session_id_sha256=hashlib.sha256( + dispatch.runner_session_id.encode("utf-8") + ).hexdigest(), + execution_authority_id=dispatch.execution_authority_id, + execution_authority_sha256=dispatch.execution_authority_sha256, + execution_authority_signer_sha256=(dispatch.execution_authority_signer_sha256), + run_store_identity_sha256=adapter._run_store_identity_sha256(run_dir), + ) + loss = hosted.ManagedResultLossEvidence.create( + loss_code="report_missing", + child_started_at=marker.started_at, + child_start_evidence_sha256=marker.marker_sha256, + run_store_identity_sha256=marker.run_store_identity_sha256, + observed_at="2026-08-26T12:00:02Z", + run_id=dispatch.run_id, + flow_run_id_sha256=hashlib.sha256(dispatch.run_id.encode("utf-8")).hexdigest(), + dispatch_id=dispatch.dispatch_id, + dispatch_session_id=dispatch.dispatch_session_id, + managed_dispatch_binding_sha256=dispatch.payload.dispatch_binding_sha256, + idempotency_key_sha256=hosted.managed_result_loss_idempotency_sha256( + dispatch.idempotency_key + ), + authenticated_runner_id_sha256=marker.authenticated_runner_id_sha256, + authenticated_session_id_sha256=(marker.authenticated_session_id_sha256), + execution_authority_id=dispatch.execution_authority_id, + execution_authority_sha256=dispatch.execution_authority_sha256, + execution_authority_signer_sha256=(dispatch.execution_authority_signer_sha256), + delivery_result_loss_closure_artifact_sha256="d" * 64, + pending_permit_artifact_sha256="a" * 64, + run_request_sha256="b" * 64, + pending_action_request_sha256="c" * 64, + ) + manifest = SimpleNamespace( + governed_authorization=dispatch.payload.authorization.model_copy( + update={"execution_profile": "standard"} + ), + model_calls=0, + ) + + report = adapter._managed_result_loss_report( + dispatch=dispatch, + workflow=workflow, + manifest=manifest, + marker=marker, + evidence=loss, + verified_params=dict(dispatch.payload.params.values), + runtime_substrate="web", + ) + + assert report.managed_result_loss is not None + assert report.managed_result_loss.report_provenance == "outer_runner_recovery" + assert report.execution_outcome == "HALTED" + assert report.transaction_outcome == "RECONCILIATION_REQUIRED" + assert report.transaction_billable is False + assert report.effect_journal == [] + assert report.outcome_envelope is not None + assert report.outcome_envelope.required_contracts.model_dump() == { + "authorization": 1, + "identity": 0, + "postcondition": 0, + "effect": 0, + } + invalid = report.model_dump(mode="json") + invalid["success"] = True + with pytest.raises(ValueError, match="managed result loss report contract"): + hosted.RunReport.model_validate(invalid) + + +def test_concurrent_managed_result_loss_terminalizers_reuse_one_exact_record( + monkeypatch, tmp_path, sealed +) -> None: + workflow, _ = sealed + dispatch = _hosted_dispatch(workflow) + adapter = HostedRunnerAdapter(tmp_path / "ledger.sqlite") + run_dir = tmp_path / "run" + run_dir.mkdir(mode=0o700) + binding = dispatch.payload.dispatch_binding_sha256 + marker = hosted.ManagedChildStartEvidence.create( + started_at="2026-08-26T11:59:59Z", + dispatch_id=dispatch.dispatch_id, + dispatch_session_id=dispatch.dispatch_session_id, + run_id=dispatch.run_id, + managed_dispatch_binding_sha256=binding, + authenticated_runner_id_sha256=hashlib.sha256( + dispatch.runner_id.encode("utf-8") + ).hexdigest(), + authenticated_session_id_sha256=hashlib.sha256( + dispatch.runner_session_id.encode("utf-8") + ).hexdigest(), + execution_authority_id=dispatch.execution_authority_id, + execution_authority_sha256=dispatch.execution_authority_sha256, + execution_authority_signer_sha256=(dispatch.execution_authority_signer_sha256), + run_store_identity_sha256=adapter._run_store_identity_sha256(run_dir), + ) + adapter._write_private_bytes_atomic_exclusive( + run_dir / "managed-child-started.json", hosted.canonical_json(marker) + ) + acknowledged = _terminal_delivery_chain( + dispatch, + admission_sha256="d" * 64, + evidence_identity_sha256="e" * 64, + environment_digest="a" * 64, + registry_sha256="e" * 64, + ) + assert acknowledged.entries + permit = acknowledged.entries[0].permit_artifact + + class Store: + def __init__(self, _run_dir): + pass + + def read_manifest(self): + return SimpleNamespace() + + class ClosureAuthority: + requests: list[hosted.ProductionDeliveryResultLossClosureRequest] = [] + + def close_result_loss(self, run_id, lease_token, request): + assert run_id == dispatch.run_id + assert lease_token == dispatch.lease_token + assert "oal_" not in request.canonical_bytes().decode("utf-8") + self.requests.append(request) + pending = ProductionPendingDeliveryPermit.build( + permit, + receipt_absence_observed_at=request.result_loss_observed_at, + ) + chain = ProductionDeliveryPermitChain.build((), pending=pending) + return _result_loss_closure_result(dispatch, marker, request, chain) + + closure_authority = ClosureAuthority() + + class RacingDatetime(datetime): + calls = 0 + + @classmethod + def now(cls, tz=None): + cls.calls += 1 + second = 1 + cls.calls + value = datetime(2026, 8, 26, 12, 0, second, tzinfo=timezone.utc) + return value if tz is not None else value.replace(tzinfo=None) + + monkeypatch.setattr(hosted, "CheckpointStore", Store) + monkeypatch.setattr(hosted, "datetime", RacingDatetime) + monkeypatch.setattr( + adapter, + "_managed_result_loss_report", + lambda **kwargs: kwargs["evidence"], + ) + monkeypatch.setattr( + adapter, + "_produce_terminal_verification", + lambda **kwargs: ( + kwargs["report"], + kwargs["report"].evidence_sha256, + ), + ) + qualification = SimpleNamespace( + expected=SimpleNamespace( + runtime_build_identity=SimpleNamespace(substrate="web") + ) + ) + + def terminalize(loss_code, closer=closure_authority): + return adapter._produce_managed_result_loss( + dispatch=dispatch, + workflow=workflow, + run_dir=run_dir, + qualification=qualification, + private_key=object(), + verified_params=dict(dispatch.payload.params.values), + dispatch_binding_sha256=binding, + closure_authority=closer, + loss_code=loss_code, + ) + + with ThreadPoolExecutor(max_workers=3) as pool: + results = list( + pool.map( + terminalize, + ("runner_exception", "report_missing", "recovered_after_restart"), + ) + ) + + retained = (run_dir / "managed-result-loss.json").read_bytes() + snapshot = hosted.ManagedResultLossSnapshot.model_validate_json(retained) + evidence_bytes = hosted.canonical_json(snapshot.evidence) + assert hosted.canonical_json(snapshot) == retained + assert {hosted.canonical_json(item[0]) for item in results} == {evidence_bytes} + assert {hosted.canonical_json(item[2]) for item in results} == {evidence_bytes} + assert {item[1] for item in results} == {snapshot.evidence.evidence_sha256} + assert closure_authority.requests + assert len({item.request_sha256() for item in closure_authority.requests}) == 1 + + class RefuseClosureReplay: + def close_result_loss(self, *_args, **_kwargs): + raise AssertionError("retained result loss requested a second closure") + + replayed = terminalize("recovered_after_restart", RefuseClosureReplay()) + assert hosted.canonical_json(replayed[0]) == evidence_bytes + assert hosted.canonical_json(replayed[2]) == evidence_bytes + if os.name != "nt": + assert (run_dir / "managed-result-loss.json").stat().st_mode & 0o777 == 0o600 + + +@pytest.mark.parametrize("pending", [True, False], ids=("pending", "ack-won")) +def test_result_loss_closure_response_binds_exact_request_and_chain( + tmp_path, sealed, pending +) -> None: + workflow, _ = sealed + dispatch = _hosted_dispatch(workflow) + adapter = HostedRunnerAdapter(tmp_path / "ledger.sqlite") + run_dir = tmp_path / "run" + run_dir.mkdir(mode=0o700) + marker = hosted.ManagedChildStartEvidence.create( + started_at="2026-08-26T11:59:59Z", + dispatch_id=dispatch.dispatch_id, + dispatch_session_id=dispatch.dispatch_session_id, + run_id=dispatch.run_id, + managed_dispatch_binding_sha256=dispatch.payload.dispatch_binding_sha256, + authenticated_runner_id_sha256=hashlib.sha256( + dispatch.runner_id.encode("utf-8") + ).hexdigest(), + authenticated_session_id_sha256=hashlib.sha256( + dispatch.runner_session_id.encode("utf-8") + ).hexdigest(), + execution_authority_id=dispatch.execution_authority_id, + execution_authority_sha256=dispatch.execution_authority_sha256, + execution_authority_signer_sha256=(dispatch.execution_authority_signer_sha256), + run_store_identity_sha256=adapter._run_store_identity_sha256(run_dir), + ) + request = hosted.ProductionDeliveryResultLossClosureRequest( + child_start_evidence=marker, + result_loss_observed_at="2026-08-26T12:00:02Z", + ) + acknowledged = _terminal_delivery_chain( + dispatch, + admission_sha256="d" * 64, + evidence_identity_sha256="e" * 64, + environment_digest="a" * 64, + registry_sha256="e" * 64, + ) + if pending: + permit = acknowledged.entries[0].permit_artifact + chain = ProductionDeliveryPermitChain.build( + (), + pending=ProductionPendingDeliveryPermit.build( + permit, + receipt_absence_observed_at=request.result_loss_observed_at, + ), + ) + else: + chain = acknowledged + + result = _result_loss_closure_result(dispatch, marker, request, chain) + artifact, retained_chain = result.artifacts() + + assert retained_chain == chain + assert artifact.payload.closure_request_sha256 == request.request_sha256() + assert artifact.payload.pending_permit_count == (1 if pending else 0) + assert dispatch.lease_token not in request.canonical_bytes().decode("utf-8") + assert dispatch.delivery_authority_token not in request.canonical_bytes().decode( + "utf-8" + ) + invalid = result.model_dump(mode="json") + invalid["permit_chain_sha256"] = "f" * 64 + with pytest.raises(ValueError, match="closure response"): + hosted.ProductionDeliveryResultLossClosureResult.model_validate(invalid) + + +def test_unavailable_result_loss_fence_never_returns_a_callback_or_retries( + monkeypatch, tmp_path, config, sealed +) -> None: + workflow, _ = sealed + calls = 0 + + def runner(_argv, _run_dir, _child_env): + nonlocal calls + calls += 1 + raise RuntimeError("child result lost") + + adapter, dispatch = _prepared_adapter( + monkeypatch, tmp_path, config, workflow, runner + ) + monkeypatch.setattr( + adapter, + "_revalidate_terminal_authority", + lambda **_kwargs: (object(), object()), + ) + + def refuse_unsigned_result_loss(**_kwargs): + raise ValueError("hosted result-loss closure is unavailable") + + monkeypatch.setattr( + adapter, + "_produce_managed_result_loss", + refuse_unsigned_result_loss, + ) + authority = DeliveryAuthority( + dispatch.managed_delivery_authority_url, + dispatch.delivery_authority_token, + ) + with pytest.raises(RuntimeError, match="signed terminal reconciliation"): + adapter.execute( + dispatch, + runner_config=tmp_path / "runner.toml", + run_dir=tmp_path / "run", + authority=authority, + closure_authority=SimpleNamespace(), + ) + + reservation = adapter._ledger.lookup( + f"{dispatch.tenant_id}:{dispatch.idempotency_key}" + ) + assert reservation is not None + assert reservation["outcome"] == "RECONCILIATION_REQUIRED" + with pytest.raises(RuntimeError, match="signed terminal reconciliation"): + adapter.execute( + dispatch, + runner_config=tmp_path / "runner.toml", + run_dir=tmp_path / "run-again", + authority=authority, + closure_authority=SimpleNamespace(), + ) + assert calls == 1 + + def test_params_reference_resolves_only_from_protected_local_root( monkeypatch, tmp_path, config, sealed ) -> None: @@ -1302,17 +1908,24 @@ def test_safe_halt_callback_requires_signed_terminal_proof() -> None: ) -def test_terminal_callback_refuses_conflicting_uncertainty_state() -> None: - proof = sign_production_terminal_verification( - _reconciliation_payload(), _private_key() - ) +@pytest.mark.parametrize( + ("payload_factory", "uncertain_delivery"), + [ + (_reconciliation_payload, False), + (_acknowledged_reconciliation_payload, True), + ], +) +def test_terminal_callback_refuses_conflicting_uncertainty_state( + payload_factory, uncertain_delivery +) -> None: + proof = sign_production_terminal_verification(payload_factory(), _private_key()) with pytest.raises(ValueError, match="uncertainty conflicts"): HostedTerminalEvent( run_id=proof.payload.run_id, outcome="RECONCILIATION_REQUIRED", report_sha256=proof.payload.run_report_sha256, started=True, - uncertain_delivery=False, + uncertain_delivery=uncertain_delivery, terminal_verification_artifact_bytes_base64=b64encode( hosted.canonical_json(proof) ).decode("ascii"), @@ -1320,6 +1933,33 @@ def test_terminal_callback_refuses_conflicting_uncertainty_state() -> None: ) +@pytest.mark.parametrize( + ("payload_factory", "uncertain_delivery"), + [ + (_reconciliation_payload, True), + (_acknowledged_reconciliation_payload, False), + (_managed_result_loss_payload, True), + (_managed_result_loss_acknowledged_payload, False), + ], +) +def test_terminal_callback_derives_uncertainty_from_pending_permit_count( + payload_factory, uncertain_delivery +) -> None: + proof = sign_production_terminal_verification(payload_factory(), _private_key()) + terminal = HostedTerminalEvent( + run_id=proof.payload.run_id, + outcome="RECONCILIATION_REQUIRED", + report_sha256=proof.payload.run_report_sha256, + started=True, + uncertain_delivery=uncertain_delivery, + terminal_verification_artifact_bytes_base64=b64encode( + hosted.canonical_json(proof) + ).decode("ascii"), + terminal_verification_artifact_sha256=proof.artifact_sha256(), + ) + assert terminal.uncertain_delivery is uncertain_delivery + + def test_callback_rejects_confirmed_summary_for_reconciliation() -> None: proof = sign_production_terminal_verification( _reconciliation_payload(), _private_key() diff --git a/tests/test_terminal_verification_v2.py b/tests/test_terminal_verification_v2.py index 08107dbb..ed8195ff 100644 --- a/tests/test_terminal_verification_v2.py +++ b/tests/test_terminal_verification_v2.py @@ -17,6 +17,7 @@ EffectVerificationEvidence, ExecutionOutcomeEnvelope, IdentityCheck, + ManagedResultLossEvidence, OutcomeContractCounts, PostconditionContractEvidence, RunReport, @@ -25,13 +26,22 @@ ) from openadapt_flow.qualification_admission_v2 import canonical_json from openadapt_flow.receipt import RunReceipt +from openadapt_flow.runner.hosted_adapter import ( + ManagedChildStartEvidence, + ProductionDeliveryResultLossClosureRequest, + ProductionDeliveryResultLossClosureResult, +) from openadapt_flow.terminal_verification_v2 import ( + RESULT_LOSS_CLOSURE_PAYLOAD_DOMAIN, + RESULT_LOSS_CLOSURE_REQUEST_DOMAIN, SIGNATURE_DOMAIN, ProductionAuthorizationEvidenceManifest, ProductionDeliveryPermit, ProductionDeliveryPermitChain, ProductionDeliveryPermitPayload, ProductionDeliveryReceiptPayload, + ProductionDeliveryResultLossClosureArtifact, + ProductionDeliveryResultLossClosurePayload, ProductionEffectEvidence, ProductionEffectEvidenceManifest, ProductionEvidenceManifests, @@ -57,6 +67,7 @@ rebuild_production_delivery_permit_chain_from_artifacts, sign_production_delivery_permit, sign_production_delivery_receipt, + sign_production_delivery_result_loss_closure, sign_production_terminal_verification, verify_production_terminal_verification, ) @@ -761,6 +772,288 @@ def _reconciliation_payload() -> ProductionTerminalVerificationPayload: ) +def _acknowledged_reconciliation_payload() -> ProductionTerminalVerificationPayload: + pending_payload = _reconciliation_payload() + chain = _permit_chain() + assert chain.entries + payload = pending_payload.model_dump(mode="json") + payload.update( + { + "permit_chain": chain.model_dump(mode="json"), + "permit_count": 1, + "acknowledged_permit_count": 1, + "pending_permit_count": 0, + "final_authority_sequence": chain.entries[-1].authority_sequence, + "final_runtime_delivery_sequence": ( + chain.entries[-1].runtime_delivery_sequence + ), + "execution_authority_signer_sha256": ( + chain.entries[-1].authority_signer_sha256 + ), + "evidence_manifests": _reconciliation_manifests(chain).model_dump( + mode="json" + ), + "run_report_object_version": "version:reconciliation:acknowledged:1", + } + ) + return ProductionTerminalVerificationPayload.model_validate(payload) + + +def _result_loss_request() -> ProductionDeliveryResultLossClosureRequest: + marker = ManagedChildStartEvidence.create( + started_at="2026-08-18T12:00:00Z", + dispatch_id="00000000-0000-4000-8000-000000000009", + dispatch_session_id="00000000-0000-4000-8000-000000000010", + run_id=IDS["run_id"], + managed_dispatch_binding_sha256="sha256:" + SHA_C, + authenticated_runner_id_sha256=SHA_A, + authenticated_session_id_sha256=SHA_B, + execution_authority_id=IDS["execution_authority_id"], + execution_authority_sha256=SHA_A, + execution_authority_signer_sha256=(_permit_entry().authority_signer_sha256), + run_store_identity_sha256=SHA_B, + ) + return ProductionDeliveryResultLossClosureRequest( + child_start_evidence=marker, + result_loss_observed_at="2026-08-18T12:00:02Z", + ) + + +def _result_loss_closure( + chain: ProductionDeliveryPermitChain, +) -> ProductionDeliveryResultLossClosureArtifact: + request = _result_loss_request() + all_permits = (*chain.entries, *((chain.pending,) if chain.pending else ())) + assert all_permits + first = all_permits[0] + final = all_permits[-1] + pending = chain.pending + acknowledged = chain.entries[-1] if chain.entries else None + return sign_production_delivery_result_loss_closure( + ProductionDeliveryResultLossClosurePayload( + closure_id="00000000-0000-4000-8000-000000000011", + closure_request_sha256=request.request_sha256(), + closed_at="2026-08-18T12:00:02Z", + result_loss_observed_at="2026-08-18T12:00:02Z", + receipt_absence_observed_at=( + pending.receipt_absence_observed_at if pending else None + ), + tenant_id=IDS["tenant_id"], + run_id=IDS["run_id"], + flow_run_id_sha256=hashlib.sha256( + IDS["run_id"].encode("utf-8") + ).hexdigest(), + dispatch_id="00000000-0000-4000-8000-000000000009", + dispatch_session_id="00000000-0000-4000-8000-000000000010", + managed_dispatch_binding_sha256="sha256:" + SHA_C, + idempotency_key_sha256=SHA_D, + authenticated_runner_id_sha256=SHA_A, + authenticated_session_id_sha256=SHA_B, + execution_authority_id=IDS["execution_authority_id"], + execution_authority_sha256=SHA_A, + execution_authority_signer_sha256=final.authority_signer_sha256, + child_started_at="2026-08-18T12:00:00Z", + child_start_evidence_sha256=(request.child_start_evidence.marker_sha256), + run_store_identity_sha256=SHA_B, + permit_chain_sha256=chain.permit_chain_sha256, + permit_count=len(all_permits), + acknowledged_permit_count=len(chain.entries), + pending_permit_count=1 if pending else 0, + pending_permit_artifact_sha256=( + pending.permit_artifact_sha256 if pending else None + ), + run_request_sha256=first.run_request_sha256, + pending_action_request_sha256=( + pending.action_request_sha256 if pending else None + ), + final_input_edge_sequence=final.input_edge_sequence, + final_authority_sequence=final.authority_sequence, + final_runtime_delivery_sequence=( + acknowledged.runtime_delivery_sequence if acknowledged else 0 + ), + ), + _authority_key(), + ) + + +def _managed_result_loss_payload( + chain: ProductionDeliveryPermitChain | None = None, +) -> ProductionTerminalVerificationPayload: + chain = chain or _pending_permit_chain() + all_permits = (*chain.entries, *((chain.pending,) if chain.pending else ())) + assert all_permits + first = all_permits[0] + final = all_permits[-1] + pending = chain.pending + acknowledged = chain.entries[-1] if chain.entries else None + request = _result_loss_request() + closure = _result_loss_closure(chain) + loss = ManagedResultLossEvidence.create( + loss_code="report_missing", + child_started_at="2026-08-18T12:00:00Z", + child_start_evidence_sha256=request.child_start_evidence.marker_sha256, + run_store_identity_sha256=SHA_B, + observed_at=request.result_loss_observed_at, + run_id=IDS["run_id"], + flow_run_id_sha256=hashlib.sha256(IDS["run_id"].encode("utf-8")).hexdigest(), + dispatch_id="00000000-0000-4000-8000-000000000009", + dispatch_session_id="00000000-0000-4000-8000-000000000010", + managed_dispatch_binding_sha256="sha256:" + SHA_C, + idempotency_key_sha256=SHA_D, + authenticated_runner_id_sha256=SHA_A, + authenticated_session_id_sha256=SHA_B, + execution_authority_id=IDS["execution_authority_id"], + execution_authority_sha256=SHA_A, + execution_authority_signer_sha256=final.authority_signer_sha256, + delivery_result_loss_closure_artifact_sha256=closure.artifact_sha256(), + pending_permit_artifact_sha256=( + pending.permit_artifact_sha256 if pending else None + ), + run_request_sha256=first.run_request_sha256, + pending_action_request_sha256=( + pending.action_request_sha256 if pending else None + ), + ) + outcome = ProductionExecutionOutcome( + outcome="HALTED", + profile="standard", + production_eligible=False, + execution_completed=False, + required_contracts=TerminalContractCounts( + authorization=1, + identity=0, + postcondition=0, + effect=0, + ), + passed_contracts=TerminalContractCounts( + authorization=1, + identity=0, + postcondition=0, + effect=0, + ), + workflow_contract_sha256=SHA_A, + postcondition_evidence=(), + evidence_classes=("authorization",), + model_calls=0, + external_network_calls="none", + managed_result_loss_evidence_sha256=loss.evidence_sha256, + ) + receipt = ProductionRunReceipt( + source_schema_version="openadapt.run-report/v1", + outcome="HALTED", + transaction_outcome="RECONCILIATION_REQUIRED", + profile="standard", + production_eligible=False, + steps_total=1, + steps_ok=0, + heals=0, + model_calls=0, + est_cost_microusd=0, + duration_ms=0, + rung_histogram={}, + evidence_classes=("authorization",), + effect_tier_reached="none", + authorization_required=1, + authorization_confirmed=1, + identity_required=0, + identity_confirmed=0, + postconditions_required=0, + postconditions_confirmed=0, + effects_required=0, + effects_confirmed=0, + identity_armed=0, + identity_applicable=0, + over_halt_count=0, + substrate="web", + provenance="production", + receipt_builder_version="1.2.3", + external_network_calls="none", + bundle_digest=SHA_A, + source_receipt_digest=SHA_B, + source_receipt_sha256=SHA_B, + generated_at="2026-08-18T12:00:00Z", + managed_result_loss_evidence_sha256=loss.evidence_sha256, + ) + base = _halted_manifests(chain) + manifests = base.model_copy( + update={ + "identity": build_evidence_manifest( + ProductionIdentityEvidenceManifest, + identity_contract_sha256=SHA_D, + workflow_contract_sha256=SHA_A, + required=0, + confirmed=0, + results=(), + ), + "postcondition": build_evidence_manifest( + ProductionPostconditionEvidenceManifest, + workflow_contract_sha256=SHA_A, + required=0, + confirmed=0, + records=(), + ), + "effect": build_evidence_manifest( + ProductionEffectEvidenceManifest, + effect_contract_sha256=SHA_E, + workflow_contract_sha256=SHA_A, + required=0, + confirmed=0, + records=(), + ), + } + ) + return ProductionTerminalVerificationPayload( + **IDS, + flow_run_id_sha256=loss.flow_run_id_sha256, + bundle_artifact_sha256=SHA_B, + bundle_content_digest=SHA_A, + environment_digest=SHA_A, + environment_contract_sha256=SHA_B, + runtime_environment_sha256=SHA_C, + identity_contract_sha256=SHA_D, + effect_contract_sha256=SHA_E, + runtime_substrate="web", + admission_artifact_sha256=SHA_D, + admission_policy_sha256=SHA_A, + evidence_identity_sha256=SHA_E, + admitted_runtime_build_sha256=SHA_C, + evidence_runner_signer_sha256=evidence_runner_signer_sha256(_public_key()), + qualification_signer_registry_sha256=SHA_E, + qualification_signer_registry_revision=7, + execution_authority_sha256=SHA_A, + execution_authority_signer_sha256=final.authority_signer_sha256, + permit_chain=chain, + permit_count=len(all_permits), + acknowledged_permit_count=len(chain.entries), + pending_permit_count=1 if pending else 0, + final_authority_sequence=final.authority_sequence, + final_runtime_delivery_sequence=( + acknowledged.runtime_delivery_sequence if acknowledged else 0 + ), + workflow_contract_sha256=SHA_A, + execution_outcome=outcome, + execution_outcome_sha256=outcome.artifact_sha256(), + run_receipt=receipt, + run_receipt_sha256=hashlib.sha256( + canonical_json(receipt.model_dump(mode="json")) + ).hexdigest(), + run_report_sha256=SHA_B, + run_report_object_version="version:managed-result-loss:1", + run_report_object_sha256=SHA_B, + evidence_manifests=manifests, + managed_result_loss=loss, + delivery_result_loss_closure=closure, + verified_at="2026-08-18T12:00:02Z", + issued_at="2026-08-18T12:00:03Z", + ) + + +def _managed_result_loss_acknowledged_payload() -> ( + ProductionTerminalVerificationPayload +): + return _managed_result_loss_payload(_permit_chain()) + + def _payload() -> ProductionTerminalVerificationPayload: receipt = _receipt() chain = _permit_chain() @@ -869,6 +1162,8 @@ def _expected( run_report_object_version=payload.run_report_object_version, run_report_object_sha256=payload.run_report_object_sha256, evidence_manifests=payload.evidence_manifests, + managed_result_loss=payload.managed_result_loss, + delivery_result_loss_closure=payload.delivery_result_loss_closure, ) @@ -996,6 +1291,65 @@ def test_terminal_v2_signs_and_verifies_reconciliation_proof() -> None: assert record.observed_effect == "unknown" +def test_terminal_v2_signs_managed_result_loss_without_effect_absence() -> None: + payload = _managed_result_loss_payload() + envelope = sign_production_terminal_verification(payload, _private_key()) + loss = payload.managed_result_loss + + assert loss is not None + assert payload.run_receipt.transaction_outcome == "RECONCILIATION_REQUIRED" + assert payload.pending_permit_count == 1 + assert payload.evidence_manifests.effect.required == 0 + assert payload.evidence_manifests.effect.records == () + assert loss.delivery_state == "CLOSED_UNRESOLVED_RESULT_LOSS" + assert loss.child_report_retained is False + assert loss.effect_absence_claimed is False + assert loss.not_received_claimed is False + assert loss.blind_retry_authorized is False + assert loss.actuation_replay_authorized is False + assert envelope.payload.managed_result_loss == loss + + +def test_terminal_v2_signs_ack_won_managed_result_loss_without_uncertainty() -> None: + payload = _managed_result_loss_acknowledged_payload() + envelope = sign_production_terminal_verification(payload, _private_key()) + + digest = verify_production_terminal_verification( + envelope, + expected=_expected(payload), + now=NOW, + ) + + assert digest == envelope.artifact_sha256() + assert payload.acknowledged_permit_count == 1 + assert payload.pending_permit_count == 0 + assert payload.permit_chain.pending is None + assert payload.managed_result_loss is not None + assert payload.managed_result_loss.pending_permit_artifact_sha256 is None + assert payload.managed_result_loss.pending_action_request_sha256 is None + assert payload.evidence_manifests.effect.records == () + + +@pytest.mark.parametrize( + "field", + [ + "child_report_retained", + "effect_absence_claimed", + "not_received_claimed", + "blind_retry_authorized", + "actuation_replay_authorized", + ], +) +def test_managed_result_loss_refuses_a_positive_prohibited_claim(field: str) -> None: + loss = _managed_result_loss_payload().managed_result_loss + assert loss is not None + raw = loss.model_dump(mode="json") + raw[field] = True + + with pytest.raises(ValidationError): + ManagedResultLossEvidence.model_validate(raw) + + def test_pending_delivery_chain_rebuilds_from_exact_retained_permit() -> None: chain = _pending_permit_chain() assert chain.pending is not None @@ -1419,8 +1773,16 @@ def test_non_success_terminal_cross_language_vectors_are_exact() -> None: b64decode(fixture["private_key_base64"], validate=True) ) payloads = { + "verified-complete": _payload(), "halted-before-effect-zero-permit": _halted_payload(), "reconciliation-required-pending-permit": _reconciliation_payload(), + "reconciliation-required-acknowledged-inconclusive": ( + _acknowledged_reconciliation_payload() + ), + "reconciliation-required-managed-result-loss": (_managed_result_loss_payload()), + "reconciliation-required-managed-result-loss-acknowledged": ( + _managed_result_loss_acknowledged_payload() + ), } for vector in fixture["vectors"]: @@ -1440,12 +1802,15 @@ def test_non_success_terminal_cross_language_vectors_are_exact() -> None: envelope.artifact_sha256() == (vector["terminal_verification_artifact_sha256"]) ) + effect_records = envelope.payload.evidence_manifests.effect.records assert ( - envelope.payload.evidence_manifests.effect.records[0].model_dump( - mode="json" - ) - == vector["effect_state"] - ) + effect_records[0].model_dump(mode="json") if effect_records else None + ) == vector["effect_state"] + assert ( + envelope.payload.managed_result_loss.model_dump(mode="json") + if envelope.payload.managed_result_loss is not None + else None + ) == vector["managed_result_loss"] callback = vector["callback"] assert callback["run_id"] == payload.run_id assert callback["outcome"] == payload.run_receipt.transaction_outcome @@ -1453,6 +1818,50 @@ def test_non_success_terminal_cross_language_vectors_are_exact() -> None: assert callback["artifact_bytes_source"] == "envelope_canonical_base64" +def test_managed_result_loss_closure_cross_language_vector_is_exact() -> None: + fixture = json.loads( + Path("tests/fixtures/terminal_verification_v2_terminal_vectors.json").read_text( + encoding="utf-8" + ) + ) + vector = fixture["managed_result_loss_closure_vector"] + request_raw = b64decode(vector["request_canonical_base64"], validate=True) + closure_raw = b64decode( + vector["closure_artifact_canonical_base64"], validate=True + ) + chain_raw = b64decode(vector["permit_chain_canonical_base64"], validate=True) + result_raw = b64decode(vector["result_canonical_base64"], validate=True) + request = ProductionDeliveryResultLossClosureRequest.model_validate_json( + request_raw + ) + closure = ProductionDeliveryResultLossClosureArtifact.model_validate_json( + closure_raw + ) + chain = ProductionDeliveryPermitChain.model_validate_json(chain_raw) + result = ProductionDeliveryResultLossClosureResult.model_validate_json(result_raw) + + assert vector["http_method"] == "POST" + assert vector["http_route"] == ( + "/api/internal/managed-delivery-result-loss-closure" + ) + assert vector["authorization_credential_source"] == "hosted_dispatch.lease_token" + assert b64decode(vector["request_digest_domain_base64"], validate=True) == ( + RESULT_LOSS_CLOSURE_REQUEST_DOMAIN + ) + assert b64decode(vector["payload_signature_domain_base64"], validate=True) == ( + RESULT_LOSS_CLOSURE_PAYLOAD_DOMAIN + ) + assert request.canonical_bytes() == request_raw + assert request.request_sha256() == vector["request_sha256"] + assert closure.canonical_bytes() == closure_raw + assert closure.payload_sha256 == vector["closure_payload_sha256"] + assert closure.artifact_sha256() == vector["closure_artifact_sha256"] + assert canonical_json(chain) == chain_raw + assert chain.permit_chain_sha256 == vector["permit_chain_sha256"] + assert canonical_json(result) == result_raw + assert result.artifacts() == (closure, chain) + + def test_delivery_artifact_rebuild_rejects_noncanonical_stored_bytes() -> None: entry = _permit_chain().entries[0] with pytest.raises( From 01dae9c9055d4e9990074515402be9878cca7d9b Mon Sep 17 00:00:00 2001 From: Richard Abrich Date: Thu, 27 Aug 2026 15:51:50 -0400 Subject: [PATCH 4/7] fix(hosted): bind result-loss delivery identity --- openadapt_flow/terminal_verification_v2.py | 14 +++++ public-artifacts.json | 2 +- ...inal_verification_v2_terminal_vectors.json | 48 +++++++-------- tests/test_terminal_verification_v2.py | 59 +++++++++++++++++-- 4 files changed, 92 insertions(+), 31 deletions(-) diff --git a/openadapt_flow/terminal_verification_v2.py b/openadapt_flow/terminal_verification_v2.py index 6d531024..abaa2dbf 100644 --- a/openadapt_flow/terminal_verification_v2.py +++ b/openadapt_flow/terminal_verification_v2.py @@ -2128,6 +2128,20 @@ def verify_production_delivery_result_loss_closure_binding( result_loss.run_store_identity_sha256, ): raise ValueError("result-loss closure identity binding is invalid") + if permit_chain.entries and any( + ( + item.authenticated_runner_id_sha256, + item.authenticated_session_id_sha256, + ) + != ( + payload.authenticated_runner_id_sha256, + payload.authenticated_session_id_sha256, + ) + for item in permit_chain.entries + ): + raise ValueError( + "result-loss closure authenticated delivery identity is invalid" + ) if ( payload.permit_chain_sha256, payload.permit_count, diff --git a/public-artifacts.json b/public-artifacts.json index 8eb6f4c5..644b4080 100644 --- a/public-artifacts.json +++ b/public-artifacts.json @@ -5785,7 +5785,7 @@ }, { "path": "tests/fixtures/terminal_verification_v2_terminal_vectors.json", - "sha256": "314c902ca5420d312626d521cec05652848f503e76226cb7168ed2384c759376" + "sha256": "0e94c1b106ca06ef6978c5923770b6b4ae32661deb68ce81078fede9a611dd5f" }, { "path": "tests/fixtures/theme-region-stable-overhalt-v1.16.1.json", diff --git a/tests/fixtures/terminal_verification_v2_terminal_vectors.json b/tests/fixtures/terminal_verification_v2_terminal_vectors.json index e175c30f..5b65c8fb 100644 --- a/tests/fixtures/terminal_verification_v2_terminal_vectors.json +++ b/tests/fixtures/terminal_verification_v2_terminal_vectors.json @@ -2,18 +2,18 @@ "key_id": "evidence-runner-ed25519-56475aa75463474c", "managed_result_loss_closure_vector": { "authorization_credential_source": "hosted_dispatch.lease_token", - "closure_artifact_canonical_base64": "eyJwYXlsb2FkIjp7ImFja25vd2xlZGdlZF9wZXJtaXRfY291bnQiOjAsImFjdHVhdGlvbl9yZXBsYXlfYXV0aG9yaXplZCI6ZmFsc2UsImF1dGhlbnRpY2F0ZWRfcnVubmVyX2lkX3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJhdXRoZW50aWNhdGVkX3Nlc3Npb25faWRfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsImJsaW5kX3JldHJ5X2F1dGhvcml6ZWQiOmZhbHNlLCJjaGlsZF9zdGFydF9ldmlkZW5jZV9zaGEyNTYiOiI2NWE2YmVkOTIzZTQ1YTZhYTBjNjI0MzA0NWUwMzY0YzkwYWNlMDY0OGZlY2I1YjBiYjJlYmQ5NDAyNzkzYzc3IiwiY2hpbGRfc3RhcnRlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDBaIiwiY2xvc2VkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMloiLCJjbG9zdXJlX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDExIiwiY2xvc3VyZV9yZXF1ZXN0X3NoYTI1NiI6ImJhZjQxN2FlNDhlZWM0MDY1ODRlZjUyODZhYWExYjFhYzJlNmUwM2Q4YTI5YTRmYjRiMGM1MzI3MDRiZTU5YzYiLCJjbG9zdXJlX3NlcXVlbmNlIjoxLCJkZWxpdmVyeV9hY2tub3dsZWRnbWVudF9hdXRob3JpemVkIjpmYWxzZSwiZGVsaXZlcnlfc3RhdGUiOiJDTE9TRURfVU5SRVNPTFZFRF9SRVNVTFRfTE9TUyIsImRpc3BhdGNoX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA5IiwiZGlzcGF0Y2hfc2Vzc2lvbl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAxMCIsImVmZmVjdF9hYnNlbmNlX2NsYWltZWQiOmZhbHNlLCJleGVjdXRpb25fYXV0aG9yaXR5X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA4IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaWduZXJfc2hhMjU2IjoiMjRmNmVkNmFjYmZlMTAwOWMwMzBkN2NhNTY3YzMzY2E0ODMwOTExNDk4MjM2YjU1NjFhNmM4MmFiZWM1ZGUyOCIsImZpbmFsX2F1dGhvcml0eV9zZXF1ZW5jZSI6MCwiZmluYWxfaW5wdXRfZWRnZV9zZXF1ZW5jZSI6MSwiZmluYWxfcnVudGltZV9kZWxpdmVyeV9zZXF1ZW5jZSI6MCwiZmxvd19ydW5faWRfc2hhMjU2IjoiMTFlNTk0ZjQ4MTk1OGMxMGUzMDE1ZDBiZjA0NDdhMjJmMDY4YThhNjQ3ZjQ3NWRmMTVjZTJjN2FiNGI4ZjNmMSIsImlkZW1wb3RlbmN5X2tleV9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwibWFuYWdlZF9kaXNwYXRjaF9iaW5kaW5nX3NoYTI1NiI6InNoYTI1NjpjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwibmV3X3Blcm1pdF9hdXRob3JpemVkIjpmYWxzZSwibm90X3JlY2VpdmVkX2NsYWltZWQiOmZhbHNlLCJwZW5kaW5nX2FjdGlvbl9yZXF1ZXN0X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJwZW5kaW5nX3Blcm1pdF9hcnRpZmFjdF9zaGEyNTYiOiI5NzJhODJhZjQ1NmRhNTQyYmFjNzg0NjAxODg5NjY4ODkxZDhiN2NjZDI0MjkwNDgxNmIzMjkyZTE1N2U1Mjg5IiwicGVuZGluZ19wZXJtaXRfY291bnQiOjEsInBlcm1pdF9jaGFpbl9zaGEyNTYiOiI1OWIzOTk3MWUzMDUxMDljNTQyOTk0NWE1ZmFiNDY2MGIwOWY0MWU3YWMzZmZkOTJlMzUwNmFmMDAzMzdkYTk1IiwicGVybWl0X2NvdW50IjoxLCJyZWNlaXB0X2Fic2VuY2Vfb2JzZXJ2ZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAyWiIsInJlc3VsdF9sb3NzX29ic2VydmVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMloiLCJydW5faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDEiLCJydW5fcmVxdWVzdF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwicnVuX3N0b3JlX2lkZW50aXR5X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXJlc3VsdC1sb3NzLWNsb3N1cmUtcGF5bG9hZC92MiIsInRlbmFudF9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwMiIsInRlcm1pbmFsX2NhbGxiYWNrX3JlcXVpcmVkIjp0cnVlfSwicGF5bG9hZF9zaGEyNTYiOiI4ZGI1OGY2YTA1ZjRlZjFmODI3NzY2MDBkNWUyYTEzMDY0NWEzZTEyYjUwZmVlNjgxMDg4NzRlZmYwOGY3ZWJmIiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1yZXN1bHQtbG9zcy1jbG9zdXJlLWFydGlmYWN0L3YyIiwic2lnbmF0dXJlIjoiYWpDYXd4d1kxWWlBVTF3cDNrdXBZR2t6bmw3MlZBVHBsSFdnWTF1WDU3akVPRmpfNHMyX3ZYUGxVRUF5VW1wTmhwNHhvcVRYQlA4YzhPZTJKTGUzRHciLCJzaWduZXIiOnsiYWxnb3JpdGhtIjoiZWQyNTUxOSIsImtleV9pZCI6ImRlbGl2ZXJ5LWF1dGhvcml0eS1lZDI1NTE5LTI0ZjZlZDZhY2JmZTEwMDkiLCJwdWJsaWNfa2V5IjoiS2F5NjRVRzh5dkN5TGhxVTAwMEx4elllVW0wTC9oTElsNVM4a3lLV2JkYz0ifX0=", - "closure_artifact_sha256": "cec357acdb74f4e02dd1c3209a8ec880915c9830136e07260f3c1f631f8d52e8", - "closure_payload_sha256": "8db58f6a05f4ef1f82776600d5e2a130645a3e12b50fee68108874eff08f7ebf", + "closure_artifact_canonical_base64": "eyJwYXlsb2FkIjp7ImFja25vd2xlZGdlZF9wZXJtaXRfY291bnQiOjAsImFjdHVhdGlvbl9yZXBsYXlfYXV0aG9yaXplZCI6ZmFsc2UsImF1dGhlbnRpY2F0ZWRfcnVubmVyX2lkX3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJhdXRoZW50aWNhdGVkX3Nlc3Npb25faWRfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsImJsaW5kX3JldHJ5X2F1dGhvcml6ZWQiOmZhbHNlLCJjaGlsZF9zdGFydF9ldmlkZW5jZV9zaGEyNTYiOiJlYzY5MDc5MTg4NmFlMmNlMDBjNGU1MTE1NGMzZjEyMGVhNDQxOWVkMjY1MWUwNzNkYjU3MjQ5MThhM2IwOGM2IiwiY2hpbGRfc3RhcnRlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDBaIiwiY2xvc2VkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMloiLCJjbG9zdXJlX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDExIiwiY2xvc3VyZV9yZXF1ZXN0X3NoYTI1NiI6ImQ5MzBhYjFhYmMyYjJhMDRiODQ4Yjk1NWZmZGZmZmExZmJlMDY1NWE1NTMyNWUwNDg5YWUxMWVkODQyMDIyNjAiLCJjbG9zdXJlX3NlcXVlbmNlIjoxLCJkZWxpdmVyeV9hY2tub3dsZWRnbWVudF9hdXRob3JpemVkIjpmYWxzZSwiZGVsaXZlcnlfc3RhdGUiOiJDTE9TRURfVU5SRVNPTFZFRF9SRVNVTFRfTE9TUyIsImRpc3BhdGNoX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA5IiwiZGlzcGF0Y2hfc2Vzc2lvbl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAxMCIsImVmZmVjdF9hYnNlbmNlX2NsYWltZWQiOmZhbHNlLCJleGVjdXRpb25fYXV0aG9yaXR5X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA4IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaWduZXJfc2hhMjU2IjoiMjRmNmVkNmFjYmZlMTAwOWMwMzBkN2NhNTY3YzMzY2E0ODMwOTExNDk4MjM2YjU1NjFhNmM4MmFiZWM1ZGUyOCIsImZpbmFsX2F1dGhvcml0eV9zZXF1ZW5jZSI6MCwiZmluYWxfaW5wdXRfZWRnZV9zZXF1ZW5jZSI6MSwiZmluYWxfcnVudGltZV9kZWxpdmVyeV9zZXF1ZW5jZSI6MCwiZmxvd19ydW5faWRfc2hhMjU2IjoiMTFlNTk0ZjQ4MTk1OGMxMGUzMDE1ZDBiZjA0NDdhMjJmMDY4YThhNjQ3ZjQ3NWRmMTVjZTJjN2FiNGI4ZjNmMSIsImlkZW1wb3RlbmN5X2tleV9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwibWFuYWdlZF9kaXNwYXRjaF9iaW5kaW5nX3NoYTI1NiI6InNoYTI1NjpjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwibmV3X3Blcm1pdF9hdXRob3JpemVkIjpmYWxzZSwibm90X3JlY2VpdmVkX2NsYWltZWQiOmZhbHNlLCJwZW5kaW5nX2FjdGlvbl9yZXF1ZXN0X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJwZW5kaW5nX3Blcm1pdF9hcnRpZmFjdF9zaGEyNTYiOiI5NzJhODJhZjQ1NmRhNTQyYmFjNzg0NjAxODg5NjY4ODkxZDhiN2NjZDI0MjkwNDgxNmIzMjkyZTE1N2U1Mjg5IiwicGVuZGluZ19wZXJtaXRfY291bnQiOjEsInBlcm1pdF9jaGFpbl9zaGEyNTYiOiI1OWIzOTk3MWUzMDUxMDljNTQyOTk0NWE1ZmFiNDY2MGIwOWY0MWU3YWMzZmZkOTJlMzUwNmFmMDAzMzdkYTk1IiwicGVybWl0X2NvdW50IjoxLCJyZWNlaXB0X2Fic2VuY2Vfb2JzZXJ2ZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAyWiIsInJlc3VsdF9sb3NzX29ic2VydmVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMloiLCJydW5faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDEiLCJydW5fcmVxdWVzdF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwicnVuX3N0b3JlX2lkZW50aXR5X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXJlc3VsdC1sb3NzLWNsb3N1cmUtcGF5bG9hZC92MiIsInRlbmFudF9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwMiIsInRlcm1pbmFsX2NhbGxiYWNrX3JlcXVpcmVkIjp0cnVlfSwicGF5bG9hZF9zaGEyNTYiOiJhODkxYWM0Y2JhNWZkZmMxN2QwM2MxZjgwMmEyZGY4YzExZmJmMGI2MmU0ZjA0YmU2N2YxYTVjNmU2OGQwYTUzIiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1yZXN1bHQtbG9zcy1jbG9zdXJlLWFydGlmYWN0L3YyIiwic2lnbmF0dXJlIjoiZ2JzdDNuNUkzMEFBdXc2ajE3UkRFLUFlUWV5cXNKa1J1TWxyR0I3SklDTzhTbkx4ZUJIWkszNDVUYjdZY2NpVWY1SExfQjhWTnRKWkRUUndGaTNVRFEiLCJzaWduZXIiOnsiYWxnb3JpdGhtIjoiZWQyNTUxOSIsImtleV9pZCI6ImRlbGl2ZXJ5LWF1dGhvcml0eS1lZDI1NTE5LTI0ZjZlZDZhY2JmZTEwMDkiLCJwdWJsaWNfa2V5IjoiS2F5NjRVRzh5dkN5TGhxVTAwMEx4elllVW0wTC9oTElsNVM4a3lLV2JkYz0ifX0=", + "closure_artifact_sha256": "65d0d82d577a5323022b2afce1a26a216a52d21ef982e0540c266f3063fbc797", + "closure_payload_sha256": "a891ac4cba5fdfc17d03c1f802a2df8c11fbf0b62e4f04be67f1a5c6e68d0a53", "http_method": "POST", "http_route": "/api/internal/managed-delivery-result-loss-closure", "payload_signature_domain_base64": "b3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcmVzdWx0LWxvc3MtY2xvc3VyZS1wYXlsb2FkLnYyAA==", "permit_chain_canonical_base64": "eyJlbnRyaWVzIjpbXSwicGVuZGluZyI6eyJhY3R1YXRpb25fcmVwbGF5X2F1dGhvcml6ZWQiOmZhbHNlLCJkZWxpdmVyeV9yZWNlaXB0X2FydGlmYWN0IjpudWxsLCJkZWxpdmVyeV9yZWNlaXB0X2FydGlmYWN0X3NoYTI1NiI6bnVsbCwiZGVsaXZlcnlfc3RhdGUiOiJVTlJFU09MVkVEIiwicGVybWl0X2FydGlmYWN0Ijp7InBheWxvYWQiOnsiYWN0aW9uX3JlcXVlc3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYXV0aG9yaXR5X3NlcXVlbmNlIjowLCJlbnZpcm9ubWVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXZpZGVuY2VfaWRlbnRpdHlfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImV4ZWN1dGlvbl9hdXRob3JpdHlfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDgiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJmbG93X3J1bl9pZF9zaGEyNTYiOiIxMWU1OTRmNDgxOTU4YzEwZTMwMTVkMGJmMDQ0N2EyMmYwNjhhOGE2NDdmNDc1ZGYxNWNlMmM3YWI0YjhmM2YxIiwiaW5wdXRfZWRnZV9zZXF1ZW5jZSI6MSwiaXNzdWVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMFoiLCJwZXJtaXRfaWQiOiJwZXJtaXQ6MSIsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X2NoZWNrZWRfYXQiOiIyMDI2LTA4LTE4VDExOjU5OjMwWiIsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X2V4cGlyZXNfYXQiOiIyMDI2LTA4LTIwVDExOjAwOjAwWiIsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X3JldmlzaW9uIjo3LCJxdWFsaWZpY2F0aW9uX3NpZ25lcl9yZWdpc3RyeV9zaGEyNTYiOiJlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlIiwicnVuX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAxIiwicnVuX3JlcXVlc3Rfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcGVybWl0LXBheWxvYWQvdjIifSwicGF5bG9hZF9zaGEyNTYiOiJjODdmNTc1MWFhOWIyNzljY2UyM2FhMTc4YWZmOTU2ZTE5ZjY5MGZjZDJmOWY3MGUwZDk5OTc4MmE2OTBkNmI4Iiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1wZXJtaXQtYXJ0aWZhY3QvdjIiLCJzaWduYXR1cmUiOiIwQnlIZ3FEeFFacm5nTElGLTZ0Wk9xOWxYYW1jQVFDMGRvVVRuZUtOUGVTLVN5b09iUXlPa0F1UEZLNVBZY056T2JaeGdzZ0FMZFdhSV9zYVVDcGxCZyIsInNpZ25lciI6eyJhbGdvcml0aG0iOiJlZDI1NTE5Iiwia2V5X2lkIjoiZGVsaXZlcnktYXV0aG9yaXR5LWVkMjU1MTktMjRmNmVkNmFjYmZlMTAwOSIsInB1YmxpY19rZXkiOiJLYXk2NFVHOHl2Q3lMaHFVMDAwTHh6WWVVbTBML2hMSWw1UzhreUtXYmRjPSJ9fSwicGVybWl0X2FydGlmYWN0X3NoYTI1NiI6Ijk3MmE4MmFmNDU2ZGE1NDJiYWM3ODQ2MDE4ODk2Njg4OTFkOGI3Y2NkMjQyOTA0ODE2YjMyOTJlMTU3ZTUyODkiLCJyZWNlaXB0X2Fic2VuY2Vfb2JzZXJ2ZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAyWiIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcGVuZGluZy1wZXJtaXQvdjIifSwicGVybWl0X2NoYWluX3NoYTI1NiI6IjU5YjM5OTcxZTMwNTEwOWM1NDI5OTQ1YTVmYWI0NjYwYjA5ZjQxZTdhYzNmZmQ5MmUzNTA2YWYwMDMzN2RhOTUiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXBlcm1pdC1jaGFpbi92MiJ9", "permit_chain_sha256": "59b39971e305109c5429945a5fab4660b09f41e7ac3ffd92e3506af00337da95", - "request_canonical_base64": "eyJjaGlsZF9zdGFydF9ldmlkZW5jZSI6eyJhdXRoZW50aWNhdGVkX3J1bm5lcl9pZF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYXV0aGVudGljYXRlZF9zZXNzaW9uX2lkX3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJkaXNwYXRjaF9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOSIsImRpc3BhdGNoX3Nlc3Npb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMTAiLCJleGVjdXRpb25fYXV0aG9yaXR5X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA4IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaWduZXJfc2hhMjU2IjoiMjRmNmVkNmFjYmZlMTAwOWMwMzBkN2NhNTY3YzMzY2E0ODMwOTExNDk4MjM2YjU1NjFhNmM4MmFiZWM1ZGUyOCIsIm1hbmFnZWRfZGlzcGF0Y2hfYmluZGluZ19zaGEyNTYiOiJzaGEyNTY6Y2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsIm1hcmtlcl9zaGEyNTYiOiI2NWE2YmVkOTIzZTQ1YTZhYTBjNjI0MzA0NWUwMzY0YzkwYWNlMDY0OGZlY2I1YjBiYjJlYmQ5NDAyNzkzYzc3IiwicnVuX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAxIiwicnVuX3N0b3JlX2lkZW50aXR5X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5tYW5hZ2VkLWNoaWxkLXN0YXJ0L3YxIiwic3RhcnRlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDBaIn0sImV4cGVjdGVkX2Nsb3N1cmVfc2VxdWVuY2UiOjAsInJlc3VsdF9sb3NzX29ic2VydmVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMloiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXJlc3VsdC1sb3NzLWNsb3N1cmUtcmVxdWVzdC92MiJ9", + "request_canonical_base64": "eyJjaGlsZF9zdGFydF9ldmlkZW5jZSI6eyJhdXRoZW50aWNhdGVkX3J1bm5lcl9pZF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwiYXV0aGVudGljYXRlZF9zZXNzaW9uX2lkX3NoYTI1NiI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJkaXNwYXRjaF9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOSIsImRpc3BhdGNoX3Nlc3Npb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMTAiLCJleGVjdXRpb25fYXV0aG9yaXR5X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA4IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaWduZXJfc2hhMjU2IjoiMjRmNmVkNmFjYmZlMTAwOWMwMzBkN2NhNTY3YzMzY2E0ODMwOTExNDk4MjM2YjU1NjFhNmM4MmFiZWM1ZGUyOCIsIm1hbmFnZWRfZGlzcGF0Y2hfYmluZGluZ19zaGEyNTYiOiJzaGEyNTY6Y2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsIm1hcmtlcl9zaGEyNTYiOiJlYzY5MDc5MTg4NmFlMmNlMDBjNGU1MTE1NGMzZjEyMGVhNDQxOWVkMjY1MWUwNzNkYjU3MjQ5MThhM2IwOGM2IiwicnVuX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAxIiwicnVuX3N0b3JlX2lkZW50aXR5X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5tYW5hZ2VkLWNoaWxkLXN0YXJ0L3YxIiwic3RhcnRlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDBaIn0sImV4cGVjdGVkX2Nsb3N1cmVfc2VxdWVuY2UiOjAsInJlc3VsdF9sb3NzX29ic2VydmVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMloiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXJlc3VsdC1sb3NzLWNsb3N1cmUtcmVxdWVzdC92MiJ9", "request_digest_domain_base64": "b3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcmVzdWx0LWxvc3MtY2xvc3VyZS1yZXF1ZXN0LnYyAA==", - "request_sha256": "baf417ae48eec406584ef5286aaa1b1ac2e6e03d8a29a4fb4b0c532704be59c6", - "result_canonical_base64": "eyJjbG9zdXJlX2FydGlmYWN0X2J5dGVzX2Jhc2U2NCI6ImV5SndZWGxzYjJGa0lqcDdJbUZqYTI1dmQyeGxaR2RsWkY5d1pYSnRhWFJmWTI5MWJuUWlPakFzSW1GamRIVmhkR2x2Ymw5eVpYQnNZWGxmWVhWMGFHOXlhWHBsWkNJNlptRnNjMlVzSW1GMWRHaGxiblJwWTJGMFpXUmZjblZ1Ym1WeVgybGtYM05vWVRJMU5pSTZJbUZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0VpTENKaGRYUm9aVzUwYVdOaGRHVmtYM05sYzNOcGIyNWZhV1JmYzJoaE1qVTJJam9pWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWWlJc0ltSnNhVzVrWDNKbGRISjVYMkYxZEdodmNtbDZaV1FpT21aaGJITmxMQ0pqYUdsc1pGOXpkR0Z5ZEY5bGRtbGtaVzVqWlY5emFHRXlOVFlpT2lJMk5XRTJZbVZrT1RJelpUUTFZVFpoWVRCak5qSTBNekEwTldVd016WTBZemt3WVdObE1EWTBPR1psWTJJMVlqQmlZakpsWW1RNU5EQXlOemt6WXpjM0lpd2lZMmhwYkdSZmMzUmhjblJsWkY5aGRDSTZJakl3TWpZdE1EZ3RNVGhVTVRJNk1EQTZNREJhSWl3aVkyeHZjMlZrWDJGMElqb2lNakF5Tmkwd09DMHhPRlF4TWpvd01Eb3dNbG9pTENKamJHOXpkWEpsWDJsa0lqb2lNREF3TURBd01EQXRNREF3TUMwME1EQXdMVGd3TURBdE1EQXdNREF3TURBd01ERXhJaXdpWTJ4dmMzVnlaVjl5WlhGMVpYTjBYM05vWVRJMU5pSTZJbUpoWmpReE4yRmxORGhsWldNME1EWTFPRFJsWmpVeU9EWmhZV0V4WWpGaFl6SmxObVV3TTJRNFlUSTVZVFJtWWpSaU1HTTFNekkzTURSaVpUVTVZellpTENKamJHOXpkWEpsWDNObGNYVmxibU5sSWpveExDSmtaV3hwZG1WeWVWOWhZMnR1YjNkc1pXUm5iV1Z1ZEY5aGRYUm9iM0pwZW1Wa0lqcG1ZV3h6WlN3aVpHVnNhWFpsY25sZmMzUmhkR1VpT2lKRFRFOVRSVVJmVlU1U1JWTlBURlpGUkY5U1JWTlZURlJmVEU5VFV5SXNJbVJwYzNCaGRHTm9YMmxrSWpvaU1EQXdNREF3TURBdE1EQXdNQzAwTURBd0xUZ3dNREF0TURBd01EQXdNREF3TURBNUlpd2laR2x6Y0dGMFkyaGZjMlZ6YzJsdmJsOXBaQ0k2SWpBd01EQXdNREF3TFRBd01EQXROREF3TUMwNE1EQXdMVEF3TURBd01EQXdNREF4TUNJc0ltVm1abVZqZEY5aFluTmxibU5sWDJOc1lXbHRaV1FpT21aaGJITmxMQ0psZUdWamRYUnBiMjVmWVhWMGFHOXlhWFI1WDJsa0lqb2lNREF3TURBd01EQXRNREF3TUMwME1EQXdMVGd3TURBdE1EQXdNREF3TURBd01EQTRJaXdpWlhobFkzVjBhVzl1WDJGMWRHaHZjbWwwZVY5emFHRXlOVFlpT2lKaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaElpd2laWGhsWTNWMGFXOXVYMkYxZEdodmNtbDBlVjl6YVdkdVpYSmZjMmhoTWpVMklqb2lNalJtTm1Wa05tRmpZbVpsTVRBd09XTXdNekJrTjJOaE5UWTNZek16WTJFME9ETXdPVEV4TkRrNE1qTTJZalUxTmpGaE5tTTRNbUZpWldNMVpHVXlPQ0lzSW1acGJtRnNYMkYxZEdodmNtbDBlVjl6WlhGMVpXNWpaU0k2TUN3aVptbHVZV3hmYVc1d2RYUmZaV1JuWlY5elpYRjFaVzVqWlNJNk1Td2labWx1WVd4ZmNuVnVkR2x0WlY5a1pXeHBkbVZ5ZVY5elpYRjFaVzVqWlNJNk1Dd2labXh2ZDE5eWRXNWZhV1JmYzJoaE1qVTJJam9pTVRGbE5UazBaalE0TVRrMU9HTXhNR1V6TURFMVpEQmlaakEwTkRkaE1qSm1NRFk0WVRoaE5qUTNaalEzTldSbU1UVmpaVEpqTjJGaU5HSTRaak5tTVNJc0ltbGtaVzF3YjNSbGJtTjVYMnRsZVY5emFHRXlOVFlpT2lKa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa0lpd2liV0Z1WVdkbFpGOWthWE53WVhSamFGOWlhVzVrYVc1blgzTm9ZVEkxTmlJNkluTm9ZVEkxTmpwalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOaklpd2libVYzWDNCbGNtMXBkRjloZFhSb2IzSnBlbVZrSWpwbVlXeHpaU3dpYm05MFgzSmxZMlZwZG1Wa1gyTnNZV2x0WldRaU9tWmhiSE5sTENKd1pXNWthVzVuWDJGamRHbHZibDl5WlhGMVpYTjBYM05vWVRJMU5pSTZJbVJrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1FpTENKd1pXNWthVzVuWDNCbGNtMXBkRjloY25ScFptRmpkRjl6YUdFeU5UWWlPaUk1TnpKaE9ESmhaalExTm1SaE5UUXlZbUZqTnpnME5qQXhPRGc1TmpZNE9Ea3haRGhpTjJOalpESTBNamt3TkRneE5tSXpNamt5WlRFMU4yVTFNamc1SWl3aWNHVnVaR2x1WjE5d1pYSnRhWFJmWTI5MWJuUWlPakVzSW5CbGNtMXBkRjlqYUdGcGJsOXphR0V5TlRZaU9pSTFPV0l6T1RrM01XVXpNRFV4TURsak5UUXlPVGswTldFMVptRmlORFkyTUdJd09XWTBNV1UzWVdNelptWmtPVEpsTXpVd05tRm1NREF6TXpka1lUazFJaXdpY0dWeWJXbDBYMk52ZFc1MElqb3hMQ0p5WldObGFYQjBYMkZpYzJWdVkyVmZiMkp6WlhKMlpXUmZZWFFpT2lJeU1ESTJMVEE0TFRFNFZERXlPakF3T2pBeVdpSXNJbkpsYzNWc2RGOXNiM056WDI5aWMyVnlkbVZrWDJGMElqb2lNakF5Tmkwd09DMHhPRlF4TWpvd01Eb3dNbG9pTENKeWRXNWZhV1FpT2lJd01EQXdNREF3TUMwd01EQXdMVFF3TURBdE9EQXdNQzB3TURBd01EQXdNREF3TURFaUxDSnlkVzVmY21WeGRXVnpkRjl6YUdFeU5UWWlPaUpqWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qSWl3aWNuVnVYM04wYjNKbFgybGtaVzUwYVhSNVgzTm9ZVEkxTmlJNkltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSWlMQ0p6WTJobGJXRmZkbVZ5YzJsdmJpSTZJbTl3Wlc1aFpHRndkQzV3Y205a2RXTjBhVzl1TFdSbGJHbDJaWEo1TFhKbGMzVnNkQzFzYjNOekxXTnNiM04xY21VdGNHRjViRzloWkM5Mk1pSXNJblJsYm1GdWRGOXBaQ0k2SWpBd01EQXdNREF3TFRBd01EQXROREF3TUMwNE1EQXdMVEF3TURBd01EQXdNREF3TWlJc0luUmxjbTFwYm1Gc1gyTmhiR3hpWVdOclgzSmxjWFZwY21Wa0lqcDBjblZsZlN3aWNHRjViRzloWkY5emFHRXlOVFlpT2lJNFpHSTFPR1kyWVRBMVpqUmxaakZtT0RJM056WTJNREJrTldVeVlURXpNRFkwTldFelpURXlZalV3Wm1WbE5qZ3hNRGc0TnpSbFptWXdPR1kzWldKbUlpd2ljMk5vWlcxaFgzWmxjbk5wYjI0aU9pSnZjR1Z1WVdSaGNIUXVjSEp2WkhWamRHbHZiaTFrWld4cGRtVnllUzF5WlhOMWJIUXRiRzl6Y3kxamJHOXpkWEpsTFdGeWRHbG1ZV04wTDNZeUlpd2ljMmxuYm1GMGRYSmxJam9pWVdwRFlYZDRkMWt4V1dsQlZURjNjRE5yZFhCWlIydDZibXczTWxaQlZIQnNTRmRuV1RGMVdEVTNha1ZQUm1wZk5ITXlYM1pZVUd4VlJVRjVWVzF3VG1od05IaHZjVlJZUWxBNFl6aFBaVEpLVEdVelJIY2lMQ0p6YVdkdVpYSWlPbnNpWVd4bmIzSnBkR2h0SWpvaVpXUXlOVFV4T1NJc0ltdGxlVjlwWkNJNkltUmxiR2wyWlhKNUxXRjFkR2h2Y21sMGVTMWxaREkxTlRFNUxUSTBaalpsWkRaaFkySm1aVEV3TURraUxDSndkV0pzYVdOZmEyVjVJam9pUzJGNU5qUlZSemg1ZGtONVRHaHhWVEF3TUV4NGVsbGxWVzB3VEM5b1RFbHNOVk00YTNsTFYySmtZejBpZlgwPSIsImNsb3N1cmVfYXJ0aWZhY3Rfc2hhMjU2IjoiY2VjMzU3YWNkYjc0ZjRlMDJkZDFjMzIwOWE4ZWM4ODA5MTVjOTgzMDEzNmUwNzI2MGYzYzFmNjMxZjhkNTJlOCIsInBlcm1pdF9jaGFpbl9ieXRlc19iYXNlNjQiOiJleUpsYm5SeWFXVnpJanBiWFN3aWNHVnVaR2x1WnlJNmV5SmhZM1IxWVhScGIyNWZjbVZ3YkdGNVgyRjFkR2h2Y21sNlpXUWlPbVpoYkhObExDSmtaV3hwZG1WeWVWOXlaV05sYVhCMFgyRnlkR2xtWVdOMElqcHVkV3hzTENKa1pXeHBkbVZ5ZVY5eVpXTmxhWEIwWDJGeWRHbG1ZV04wWDNOb1lUSTFOaUk2Ym5Wc2JDd2laR1ZzYVhabGNubGZjM1JoZEdVaU9pSlZUbEpGVTA5TVZrVkVJaXdpY0dWeWJXbDBYMkZ5ZEdsbVlXTjBJanA3SW5CaGVXeHZZV1FpT25zaVlXTjBhVzl1WDNKbGNYVmxjM1JmYzJoaE1qVTJJam9pWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkNJc0ltRmtiV2x6YzJsdmJsOWhjblJwWm1GamRGOXphR0V5TlRZaU9pSmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtJaXdpWVhWMGFHOXlhWFI1WDNObGNYVmxibU5sSWpvd0xDSmxiblpwY205dWJXVnVkRjlrYVdkbGMzUWlPaUpoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoSWl3aVpYWnBaR1Z1WTJWZmFXUmxiblJwZEhsZmMyaGhNalUySWpvaVpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbFpTSXNJbVY0WldOMWRHbHZibDloZFhSb2IzSnBkSGxmYVdRaU9pSXdNREF3TURBd01DMHdNREF3TFRRd01EQXRPREF3TUMwd01EQXdNREF3TURBd01EZ2lMQ0psZUdWamRYUnBiMjVmWVhWMGFHOXlhWFI1WDNOb1lUSTFOaUk2SW1GaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdFaUxDSm1iRzkzWDNKMWJsOXBaRjl6YUdFeU5UWWlPaUl4TVdVMU9UUm1ORGd4T1RVNFl6RXdaVE13TVRWa01HSm1NRFEwTjJFeU1tWXdOamhoT0dFMk5EZG1ORGMxWkdZeE5XTmxNbU0zWVdJMFlqaG1NMll4SWl3aWFXNXdkWFJmWldSblpWOXpaWEYxWlc1alpTSTZNU3dpYVhOemRXVmtYMkYwSWpvaU1qQXlOaTB3T0MweE9GUXhNam93TURvd01Gb2lMQ0p3WlhKdGFYUmZhV1FpT2lKd1pYSnRhWFE2TVNJc0luRjFZV3hwWm1sallYUnBiMjVmYzJsbmJtVnlYM0psWjJsemRISjVYMk5vWldOclpXUmZZWFFpT2lJeU1ESTJMVEE0TFRFNFZERXhPalU1T2pNd1dpSXNJbkYxWVd4cFptbGpZWFJwYjI1ZmMybG5ibVZ5WDNKbFoybHpkSEo1WDJWNGNHbHlaWE5mWVhRaU9pSXlNREkyTFRBNExUSXdWREV4T2pBd09qQXdXaUlzSW5GMVlXeHBabWxqWVhScGIyNWZjMmxuYm1WeVgzSmxaMmx6ZEhKNVgzSmxkbWx6YVc5dUlqbzNMQ0p4ZFdGc2FXWnBZMkYwYVc5dVgzTnBaMjVsY2w5eVpXZHBjM1J5ZVY5emFHRXlOVFlpT2lKbFpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbElpd2ljblZ1WDJsa0lqb2lNREF3TURBd01EQXRNREF3TUMwME1EQXdMVGd3TURBdE1EQXdNREF3TURBd01EQXhJaXdpY25WdVgzSmxjWFZsYzNSZmMyaGhNalUySWpvaVkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOall5SXNJbk5qYUdWdFlWOTJaWEp6YVc5dUlqb2liM0JsYm1Ga1lYQjBMbkJ5YjJSMVkzUnBiMjR0WkdWc2FYWmxjbmt0Y0dWeWJXbDBMWEJoZVd4dllXUXZkaklpZlN3aWNHRjViRzloWkY5emFHRXlOVFlpT2lKak9EZG1OVGMxTVdGaE9XSXlOemxqWTJVeU0yRmhNVGM0WVdabU9UVTJaVEU1WmpZNU1HWmpaREptT1dZM01HVXdaRGs1T1RjNE1tRTJPVEJrTm1JNElpd2ljMk5vWlcxaFgzWmxjbk5wYjI0aU9pSnZjR1Z1WVdSaGNIUXVjSEp2WkhWamRHbHZiaTFrWld4cGRtVnllUzF3WlhKdGFYUXRZWEowYVdaaFkzUXZkaklpTENKemFXZHVZWFIxY21VaU9pSXdRbmxJWjNGRWVGRmFjbTVuVEVsR0xUWjBXazl4T1d4WVlXMWpRVkZETUdSdlZWUnVaVXRPVUdWVExWTjViMDlpVVhsUGEwRjFVRVpMTlZCWlkwNTZUMkphZUdkelowRk1aRmRoU1Y5ellWVkRjR3hDWnlJc0luTnBaMjVsY2lJNmV5SmhiR2R2Y21sMGFHMGlPaUpsWkRJMU5URTVJaXdpYTJWNVgybGtJam9pWkdWc2FYWmxjbmt0WVhWMGFHOXlhWFI1TFdWa01qVTFNVGt0TWpSbU5tVmtObUZqWW1abE1UQXdPU0lzSW5CMVlteHBZMTlyWlhraU9pSkxZWGsyTkZWSE9IbDJRM2xNYUhGVk1EQXdUSGg2V1dWVmJUQk1MMmhNU1d3MVV6aHJlVXRYWW1SalBTSjlmU3dpY0dWeWJXbDBYMkZ5ZEdsbVlXTjBYM05vWVRJMU5pSTZJamszTW1FNE1tRm1ORFUyWkdFMU5ESmlZV00zT0RRMk1ERTRPRGsyTmpnNE9URmtPR0kzWTJOa01qUXlPVEEwT0RFMllqTXlPVEpsTVRVM1pUVXlPRGtpTENKeVpXTmxhWEIwWDJGaWMyVnVZMlZmYjJKelpYSjJaV1JmWVhRaU9pSXlNREkyTFRBNExURTRWREV5T2pBd09qQXlXaUlzSW5OamFHVnRZVjkyWlhKemFXOXVJam9pYjNCbGJtRmtZWEIwTG5CeWIyUjFZM1JwYjI0dFpHVnNhWFpsY25rdGNHVnVaR2x1Wnkxd1pYSnRhWFF2ZGpJaWZTd2ljR1Z5YldsMFgyTm9ZV2x1WDNOb1lUSTFOaUk2SWpVNVlqTTVPVGN4WlRNd05URXdPV00xTkRJNU9UUTFZVFZtWVdJME5qWXdZakE1WmpReFpUZGhZek5tWm1RNU1tVXpOVEEyWVdZd01ETXpOMlJoT1RVaUxDSnpZMmhsYldGZmRtVnljMmx2YmlJNkltOXdaVzVoWkdGd2RDNXdjbTlrZFdOMGFXOXVMV1JsYkdsMlpYSjVMWEJsY20xcGRDMWphR0ZwYmk5Mk1pSjkiLCJwZXJtaXRfY2hhaW5fc2hhMjU2IjoiNTliMzk5NzFlMzA1MTA5YzU0Mjk5NDVhNWZhYjQ2NjBiMDlmNDFlN2FjM2ZmZDkyZTM1MDZhZjAwMzM3ZGE5NSIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcmVzdWx0LWxvc3MtY2xvc3VyZS1yZXN1bHQvdjIiLCJzdGF0dXMiOiJjbG9zZWQifQ==" + "request_sha256": "d930ab1abc2b2a04b848b955ffdfffa1fbe0655a55325e0489ae11ed84202260", + "result_canonical_base64": "eyJjbG9zdXJlX2FydGlmYWN0X2J5dGVzX2Jhc2U2NCI6ImV5SndZWGxzYjJGa0lqcDdJbUZqYTI1dmQyeGxaR2RsWkY5d1pYSnRhWFJmWTI5MWJuUWlPakFzSW1GamRIVmhkR2x2Ymw5eVpYQnNZWGxmWVhWMGFHOXlhWHBsWkNJNlptRnNjMlVzSW1GMWRHaGxiblJwWTJGMFpXUmZjblZ1Ym1WeVgybGtYM05vWVRJMU5pSTZJbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUlpTENKaGRYUm9aVzUwYVdOaGRHVmtYM05sYzNOcGIyNWZhV1JmYzJoaE1qVTJJam9pWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWXlJc0ltSnNhVzVrWDNKbGRISjVYMkYxZEdodmNtbDZaV1FpT21aaGJITmxMQ0pqYUdsc1pGOXpkR0Z5ZEY5bGRtbGtaVzVqWlY5emFHRXlOVFlpT2lKbFl6WTVNRGM1TVRnNE5tRmxNbU5sTURCak5HVTFNVEUxTkdNelpqRXlNR1ZoTkRReE9XVmtNalkxTVdVd056TmtZalUzTWpRNU1UaGhNMkl3T0dNMklpd2lZMmhwYkdSZmMzUmhjblJsWkY5aGRDSTZJakl3TWpZdE1EZ3RNVGhVTVRJNk1EQTZNREJhSWl3aVkyeHZjMlZrWDJGMElqb2lNakF5Tmkwd09DMHhPRlF4TWpvd01Eb3dNbG9pTENKamJHOXpkWEpsWDJsa0lqb2lNREF3TURBd01EQXRNREF3TUMwME1EQXdMVGd3TURBdE1EQXdNREF3TURBd01ERXhJaXdpWTJ4dmMzVnlaVjl5WlhGMVpYTjBYM05vWVRJMU5pSTZJbVE1TXpCaFlqRmhZbU15WWpKaE1EUmlPRFE0WWprMU5XWm1aR1ptWm1FeFptSmxNRFkxTldFMU5UTXlOV1V3TkRnNVlXVXhNV1ZrT0RReU1ESXlOakFpTENKamJHOXpkWEpsWDNObGNYVmxibU5sSWpveExDSmtaV3hwZG1WeWVWOWhZMnR1YjNkc1pXUm5iV1Z1ZEY5aGRYUm9iM0pwZW1Wa0lqcG1ZV3h6WlN3aVpHVnNhWFpsY25sZmMzUmhkR1VpT2lKRFRFOVRSVVJmVlU1U1JWTlBURlpGUkY5U1JWTlZURlJmVEU5VFV5SXNJbVJwYzNCaGRHTm9YMmxrSWpvaU1EQXdNREF3TURBdE1EQXdNQzAwTURBd0xUZ3dNREF0TURBd01EQXdNREF3TURBNUlpd2laR2x6Y0dGMFkyaGZjMlZ6YzJsdmJsOXBaQ0k2SWpBd01EQXdNREF3TFRBd01EQXROREF3TUMwNE1EQXdMVEF3TURBd01EQXdNREF4TUNJc0ltVm1abVZqZEY5aFluTmxibU5sWDJOc1lXbHRaV1FpT21aaGJITmxMQ0psZUdWamRYUnBiMjVmWVhWMGFHOXlhWFI1WDJsa0lqb2lNREF3TURBd01EQXRNREF3TUMwME1EQXdMVGd3TURBdE1EQXdNREF3TURBd01EQTRJaXdpWlhobFkzVjBhVzl1WDJGMWRHaHZjbWwwZVY5emFHRXlOVFlpT2lKaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaElpd2laWGhsWTNWMGFXOXVYMkYxZEdodmNtbDBlVjl6YVdkdVpYSmZjMmhoTWpVMklqb2lNalJtTm1Wa05tRmpZbVpsTVRBd09XTXdNekJrTjJOaE5UWTNZek16WTJFME9ETXdPVEV4TkRrNE1qTTJZalUxTmpGaE5tTTRNbUZpWldNMVpHVXlPQ0lzSW1acGJtRnNYMkYxZEdodmNtbDBlVjl6WlhGMVpXNWpaU0k2TUN3aVptbHVZV3hmYVc1d2RYUmZaV1JuWlY5elpYRjFaVzVqWlNJNk1Td2labWx1WVd4ZmNuVnVkR2x0WlY5a1pXeHBkbVZ5ZVY5elpYRjFaVzVqWlNJNk1Dd2labXh2ZDE5eWRXNWZhV1JmYzJoaE1qVTJJam9pTVRGbE5UazBaalE0TVRrMU9HTXhNR1V6TURFMVpEQmlaakEwTkRkaE1qSm1NRFk0WVRoaE5qUTNaalEzTldSbU1UVmpaVEpqTjJGaU5HSTRaak5tTVNJc0ltbGtaVzF3YjNSbGJtTjVYMnRsZVY5emFHRXlOVFlpT2lKa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa0lpd2liV0Z1WVdkbFpGOWthWE53WVhSamFGOWlhVzVrYVc1blgzTm9ZVEkxTmlJNkluTm9ZVEkxTmpwalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOaklpd2libVYzWDNCbGNtMXBkRjloZFhSb2IzSnBlbVZrSWpwbVlXeHpaU3dpYm05MFgzSmxZMlZwZG1Wa1gyTnNZV2x0WldRaU9tWmhiSE5sTENKd1pXNWthVzVuWDJGamRHbHZibDl5WlhGMVpYTjBYM05vWVRJMU5pSTZJbVJrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1FpTENKd1pXNWthVzVuWDNCbGNtMXBkRjloY25ScFptRmpkRjl6YUdFeU5UWWlPaUk1TnpKaE9ESmhaalExTm1SaE5UUXlZbUZqTnpnME5qQXhPRGc1TmpZNE9Ea3haRGhpTjJOalpESTBNamt3TkRneE5tSXpNamt5WlRFMU4yVTFNamc1SWl3aWNHVnVaR2x1WjE5d1pYSnRhWFJmWTI5MWJuUWlPakVzSW5CbGNtMXBkRjlqYUdGcGJsOXphR0V5TlRZaU9pSTFPV0l6T1RrM01XVXpNRFV4TURsak5UUXlPVGswTldFMVptRmlORFkyTUdJd09XWTBNV1UzWVdNelptWmtPVEpsTXpVd05tRm1NREF6TXpka1lUazFJaXdpY0dWeWJXbDBYMk52ZFc1MElqb3hMQ0p5WldObGFYQjBYMkZpYzJWdVkyVmZiMkp6WlhKMlpXUmZZWFFpT2lJeU1ESTJMVEE0TFRFNFZERXlPakF3T2pBeVdpSXNJbkpsYzNWc2RGOXNiM056WDI5aWMyVnlkbVZrWDJGMElqb2lNakF5Tmkwd09DMHhPRlF4TWpvd01Eb3dNbG9pTENKeWRXNWZhV1FpT2lJd01EQXdNREF3TUMwd01EQXdMVFF3TURBdE9EQXdNQzB3TURBd01EQXdNREF3TURFaUxDSnlkVzVmY21WeGRXVnpkRjl6YUdFeU5UWWlPaUpqWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qSWl3aWNuVnVYM04wYjNKbFgybGtaVzUwYVhSNVgzTm9ZVEkxTmlJNkltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSWlMQ0p6WTJobGJXRmZkbVZ5YzJsdmJpSTZJbTl3Wlc1aFpHRndkQzV3Y205a2RXTjBhVzl1TFdSbGJHbDJaWEo1TFhKbGMzVnNkQzFzYjNOekxXTnNiM04xY21VdGNHRjViRzloWkM5Mk1pSXNJblJsYm1GdWRGOXBaQ0k2SWpBd01EQXdNREF3TFRBd01EQXROREF3TUMwNE1EQXdMVEF3TURBd01EQXdNREF3TWlJc0luUmxjbTFwYm1Gc1gyTmhiR3hpWVdOclgzSmxjWFZwY21Wa0lqcDBjblZsZlN3aWNHRjViRzloWkY5emFHRXlOVFlpT2lKaE9Ea3hZV00wWTJKaE5XWmtabU14TjJRd00yTXhaamd3TW1FeVpHWTRZekV4Wm1KbU1HSTJNbVUwWmpBMFltVTJOMll4WVRWak5tVTJPR1F3WVRVeklpd2ljMk5vWlcxaFgzWmxjbk5wYjI0aU9pSnZjR1Z1WVdSaGNIUXVjSEp2WkhWamRHbHZiaTFrWld4cGRtVnllUzF5WlhOMWJIUXRiRzl6Y3kxamJHOXpkWEpsTFdGeWRHbG1ZV04wTDNZeUlpd2ljMmxuYm1GMGRYSmxJam9pWjJKemRETnVOVWt6TUVGQmRYYzJhakUzVWtSRkxVRmxVV1Y1Y1hOS2ExSjFUV3h5UjBJM1NrbERUemhUYmt4NFpVSklXa3N6TkRWVVlqZFpZMk5wVldZMVNFeGZRamhXVG5SS1drUlVVbmRHYVROVlJGRWlMQ0p6YVdkdVpYSWlPbnNpWVd4bmIzSnBkR2h0SWpvaVpXUXlOVFV4T1NJc0ltdGxlVjlwWkNJNkltUmxiR2wyWlhKNUxXRjFkR2h2Y21sMGVTMWxaREkxTlRFNUxUSTBaalpsWkRaaFkySm1aVEV3TURraUxDSndkV0pzYVdOZmEyVjVJam9pUzJGNU5qUlZSemg1ZGtONVRHaHhWVEF3TUV4NGVsbGxWVzB3VEM5b1RFbHNOVk00YTNsTFYySmtZejBpZlgwPSIsImNsb3N1cmVfYXJ0aWZhY3Rfc2hhMjU2IjoiNjVkMGQ4MmQ1NzdhNTMyMzAyMmIyYWZjZTFhMjZhMjE2YTUyZDIxZWY5ODJlMDU0MGMyNjZmMzA2M2ZiYzc5NyIsInBlcm1pdF9jaGFpbl9ieXRlc19iYXNlNjQiOiJleUpsYm5SeWFXVnpJanBiWFN3aWNHVnVaR2x1WnlJNmV5SmhZM1IxWVhScGIyNWZjbVZ3YkdGNVgyRjFkR2h2Y21sNlpXUWlPbVpoYkhObExDSmtaV3hwZG1WeWVWOXlaV05sYVhCMFgyRnlkR2xtWVdOMElqcHVkV3hzTENKa1pXeHBkbVZ5ZVY5eVpXTmxhWEIwWDJGeWRHbG1ZV04wWDNOb1lUSTFOaUk2Ym5Wc2JDd2laR1ZzYVhabGNubGZjM1JoZEdVaU9pSlZUbEpGVTA5TVZrVkVJaXdpY0dWeWJXbDBYMkZ5ZEdsbVlXTjBJanA3SW5CaGVXeHZZV1FpT25zaVlXTjBhVzl1WDNKbGNYVmxjM1JmYzJoaE1qVTJJam9pWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkNJc0ltRmtiV2x6YzJsdmJsOWhjblJwWm1GamRGOXphR0V5TlRZaU9pSmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtJaXdpWVhWMGFHOXlhWFI1WDNObGNYVmxibU5sSWpvd0xDSmxiblpwY205dWJXVnVkRjlrYVdkbGMzUWlPaUpoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoSWl3aVpYWnBaR1Z1WTJWZmFXUmxiblJwZEhsZmMyaGhNalUySWpvaVpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbFpTSXNJbVY0WldOMWRHbHZibDloZFhSb2IzSnBkSGxmYVdRaU9pSXdNREF3TURBd01DMHdNREF3TFRRd01EQXRPREF3TUMwd01EQXdNREF3TURBd01EZ2lMQ0psZUdWamRYUnBiMjVmWVhWMGFHOXlhWFI1WDNOb1lUSTFOaUk2SW1GaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdFaUxDSm1iRzkzWDNKMWJsOXBaRjl6YUdFeU5UWWlPaUl4TVdVMU9UUm1ORGd4T1RVNFl6RXdaVE13TVRWa01HSm1NRFEwTjJFeU1tWXdOamhoT0dFMk5EZG1ORGMxWkdZeE5XTmxNbU0zWVdJMFlqaG1NMll4SWl3aWFXNXdkWFJmWldSblpWOXpaWEYxWlc1alpTSTZNU3dpYVhOemRXVmtYMkYwSWpvaU1qQXlOaTB3T0MweE9GUXhNam93TURvd01Gb2lMQ0p3WlhKdGFYUmZhV1FpT2lKd1pYSnRhWFE2TVNJc0luRjFZV3hwWm1sallYUnBiMjVmYzJsbmJtVnlYM0psWjJsemRISjVYMk5vWldOclpXUmZZWFFpT2lJeU1ESTJMVEE0TFRFNFZERXhPalU1T2pNd1dpSXNJbkYxWVd4cFptbGpZWFJwYjI1ZmMybG5ibVZ5WDNKbFoybHpkSEo1WDJWNGNHbHlaWE5mWVhRaU9pSXlNREkyTFRBNExUSXdWREV4T2pBd09qQXdXaUlzSW5GMVlXeHBabWxqWVhScGIyNWZjMmxuYm1WeVgzSmxaMmx6ZEhKNVgzSmxkbWx6YVc5dUlqbzNMQ0p4ZFdGc2FXWnBZMkYwYVc5dVgzTnBaMjVsY2w5eVpXZHBjM1J5ZVY5emFHRXlOVFlpT2lKbFpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbElpd2ljblZ1WDJsa0lqb2lNREF3TURBd01EQXRNREF3TUMwME1EQXdMVGd3TURBdE1EQXdNREF3TURBd01EQXhJaXdpY25WdVgzSmxjWFZsYzNSZmMyaGhNalUySWpvaVkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOall5SXNJbk5qYUdWdFlWOTJaWEp6YVc5dUlqb2liM0JsYm1Ga1lYQjBMbkJ5YjJSMVkzUnBiMjR0WkdWc2FYWmxjbmt0Y0dWeWJXbDBMWEJoZVd4dllXUXZkaklpZlN3aWNHRjViRzloWkY5emFHRXlOVFlpT2lKak9EZG1OVGMxTVdGaE9XSXlOemxqWTJVeU0yRmhNVGM0WVdabU9UVTJaVEU1WmpZNU1HWmpaREptT1dZM01HVXdaRGs1T1RjNE1tRTJPVEJrTm1JNElpd2ljMk5vWlcxaFgzWmxjbk5wYjI0aU9pSnZjR1Z1WVdSaGNIUXVjSEp2WkhWamRHbHZiaTFrWld4cGRtVnllUzF3WlhKdGFYUXRZWEowYVdaaFkzUXZkaklpTENKemFXZHVZWFIxY21VaU9pSXdRbmxJWjNGRWVGRmFjbTVuVEVsR0xUWjBXazl4T1d4WVlXMWpRVkZETUdSdlZWUnVaVXRPVUdWVExWTjViMDlpVVhsUGEwRjFVRVpMTlZCWlkwNTZUMkphZUdkelowRk1aRmRoU1Y5ellWVkRjR3hDWnlJc0luTnBaMjVsY2lJNmV5SmhiR2R2Y21sMGFHMGlPaUpsWkRJMU5URTVJaXdpYTJWNVgybGtJam9pWkdWc2FYWmxjbmt0WVhWMGFHOXlhWFI1TFdWa01qVTFNVGt0TWpSbU5tVmtObUZqWW1abE1UQXdPU0lzSW5CMVlteHBZMTlyWlhraU9pSkxZWGsyTkZWSE9IbDJRM2xNYUhGVk1EQXdUSGg2V1dWVmJUQk1MMmhNU1d3MVV6aHJlVXRYWW1SalBTSjlmU3dpY0dWeWJXbDBYMkZ5ZEdsbVlXTjBYM05vWVRJMU5pSTZJamszTW1FNE1tRm1ORFUyWkdFMU5ESmlZV00zT0RRMk1ERTRPRGsyTmpnNE9URmtPR0kzWTJOa01qUXlPVEEwT0RFMllqTXlPVEpsTVRVM1pUVXlPRGtpTENKeVpXTmxhWEIwWDJGaWMyVnVZMlZmYjJKelpYSjJaV1JmWVhRaU9pSXlNREkyTFRBNExURTRWREV5T2pBd09qQXlXaUlzSW5OamFHVnRZVjkyWlhKemFXOXVJam9pYjNCbGJtRmtZWEIwTG5CeWIyUjFZM1JwYjI0dFpHVnNhWFpsY25rdGNHVnVaR2x1Wnkxd1pYSnRhWFF2ZGpJaWZTd2ljR1Z5YldsMFgyTm9ZV2x1WDNOb1lUSTFOaUk2SWpVNVlqTTVPVGN4WlRNd05URXdPV00xTkRJNU9UUTFZVFZtWVdJME5qWXdZakE1WmpReFpUZGhZek5tWm1RNU1tVXpOVEEyWVdZd01ETXpOMlJoT1RVaUxDSnpZMmhsYldGZmRtVnljMmx2YmlJNkltOXdaVzVoWkdGd2RDNXdjbTlrZFdOMGFXOXVMV1JsYkdsMlpYSjVMWEJsY20xcGRDMWphR0ZwYmk5Mk1pSjkiLCJwZXJtaXRfY2hhaW5fc2hhMjU2IjoiNTliMzk5NzFlMzA1MTA5YzU0Mjk5NDVhNWZhYjQ2NjBiMDlmNDFlN2FjM2ZmZDkyZTM1MDZhZjAwMzM3ZGE5NSIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcmVzdWx0LWxvc3MtY2xvc3VyZS1yZXN1bHQvdjIiLCJzdGF0dXMiOiJjbG9zZWQifQ==" }, "private_key_base64": "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=", "public_key_base64": "A6EHv/POEL4dcN0Y50vAmWfk1jCbpQ1fHdyGZBJVMbg=", @@ -158,22 +158,22 @@ "uncertain_delivery": true }, "effect_state": null, - "envelope_canonical_base64": "eyJwYXlsb2FkIjp7ImFja25vd2xlZGdlZF9wZXJtaXRfY291bnQiOjAsImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA2IiwiYWRtaXNzaW9uX3BvbGljeV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYWRtaXR0ZWRfcnVudGltZV9idWlsZF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiYnVuZGxlX2FydGlmYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJidW5kbGVfY29udGVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYnVuZGxlX3ZlcnNpb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDQiLCJkZWxpdmVyeV9yZXN1bHRfbG9zc19jbG9zdXJlIjp7InBheWxvYWQiOnsiYWNrbm93bGVkZ2VkX3Blcm1pdF9jb3VudCI6MCwiYWN0dWF0aW9uX3JlcGxheV9hdXRob3JpemVkIjpmYWxzZSwiYXV0aGVudGljYXRlZF9ydW5uZXJfaWRfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImF1dGhlbnRpY2F0ZWRfc2Vzc2lvbl9pZF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwiYmxpbmRfcmV0cnlfYXV0aG9yaXplZCI6ZmFsc2UsImNoaWxkX3N0YXJ0X2V2aWRlbmNlX3NoYTI1NiI6IjY1YTZiZWQ5MjNlNDVhNmFhMGM2MjQzMDQ1ZTAzNjRjOTBhY2UwNjQ4ZmVjYjViMGJiMmViZDk0MDI3OTNjNzciLCJjaGlsZF9zdGFydGVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMFoiLCJjbG9zZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAyWiIsImNsb3N1cmVfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMTEiLCJjbG9zdXJlX3JlcXVlc3Rfc2hhMjU2IjoiYmFmNDE3YWU0OGVlYzQwNjU4NGVmNTI4NmFhYTFiMWFjMmU2ZTAzZDhhMjlhNGZiNGIwYzUzMjcwNGJlNTljNiIsImNsb3N1cmVfc2VxdWVuY2UiOjEsImRlbGl2ZXJ5X2Fja25vd2xlZGdtZW50X2F1dGhvcml6ZWQiOmZhbHNlLCJkZWxpdmVyeV9zdGF0ZSI6IkNMT1NFRF9VTlJFU09MVkVEX1JFU1VMVF9MT1NTIiwiZGlzcGF0Y2hfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDkiLCJkaXNwYXRjaF9zZXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDEwIiwiZWZmZWN0X2Fic2VuY2VfY2xhaW1lZCI6ZmFsc2UsImV4ZWN1dGlvbl9hdXRob3JpdHlfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDgiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NpZ25lcl9zaGEyNTYiOiIyNGY2ZWQ2YWNiZmUxMDA5YzAzMGQ3Y2E1NjdjMzNjYTQ4MzA5MTE0OTgyMzZiNTU2MWE2YzgyYWJlYzVkZTI4IiwiZmluYWxfYXV0aG9yaXR5X3NlcXVlbmNlIjowLCJmaW5hbF9pbnB1dF9lZGdlX3NlcXVlbmNlIjoxLCJmaW5hbF9ydW50aW1lX2RlbGl2ZXJ5X3NlcXVlbmNlIjowLCJmbG93X3J1bl9pZF9zaGEyNTYiOiIxMWU1OTRmNDgxOTU4YzEwZTMwMTVkMGJmMDQ0N2EyMmYwNjhhOGE2NDdmNDc1ZGYxNWNlMmM3YWI0YjhmM2YxIiwiaWRlbXBvdGVuY3lfa2V5X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJtYW5hZ2VkX2Rpc3BhdGNoX2JpbmRpbmdfc2hhMjU2Ijoic2hhMjU2OmNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJuZXdfcGVybWl0X2F1dGhvcml6ZWQiOmZhbHNlLCJub3RfcmVjZWl2ZWRfY2xhaW1lZCI6ZmFsc2UsInBlbmRpbmdfYWN0aW9uX3JlcXVlc3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsInBlbmRpbmdfcGVybWl0X2FydGlmYWN0X3NoYTI1NiI6Ijk3MmE4MmFmNDU2ZGE1NDJiYWM3ODQ2MDE4ODk2Njg4OTFkOGI3Y2NkMjQyOTA0ODE2YjMyOTJlMTU3ZTUyODkiLCJwZW5kaW5nX3Blcm1pdF9jb3VudCI6MSwicGVybWl0X2NoYWluX3NoYTI1NiI6IjU5YjM5OTcxZTMwNTEwOWM1NDI5OTQ1YTVmYWI0NjYwYjA5ZjQxZTdhYzNmZmQ5MmUzNTA2YWYwMDMzN2RhOTUiLCJwZXJtaXRfY291bnQiOjEsInJlY2VpcHRfYWJzZW5jZV9vYnNlcnZlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDJaIiwicmVzdWx0X2xvc3Nfb2JzZXJ2ZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAyWiIsInJ1bl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwMSIsInJ1bl9yZXF1ZXN0X3NoYTI1NiI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJydW5fc3RvcmVfaWRlbnRpdHlfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcmVzdWx0LWxvc3MtY2xvc3VyZS1wYXlsb2FkL3YyIiwidGVuYW50X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAyIiwidGVybWluYWxfY2FsbGJhY2tfcmVxdWlyZWQiOnRydWV9LCJwYXlsb2FkX3NoYTI1NiI6IjhkYjU4ZjZhMDVmNGVmMWY4Mjc3NjYwMGQ1ZTJhMTMwNjQ1YTNlMTJiNTBmZWU2ODEwODg3NGVmZjA4ZjdlYmYiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXJlc3VsdC1sb3NzLWNsb3N1cmUtYXJ0aWZhY3QvdjIiLCJzaWduYXR1cmUiOiJhakNhd3h3WTFZaUFVMXdwM2t1cFlHa3pubDcyVkFUcGxIV2dZMXVYNTdqRU9Gal80czJfdlhQbFVFQXlVbXBOaHA0eG9xVFhCUDhjOE9lMkpMZTNEdyIsInNpZ25lciI6eyJhbGdvcml0aG0iOiJlZDI1NTE5Iiwia2V5X2lkIjoiZGVsaXZlcnktYXV0aG9yaXR5LWVkMjU1MTktMjRmNmVkNmFjYmZlMTAwOSIsInB1YmxpY19rZXkiOiJLYXk2NFVHOHl2Q3lMaHFVMDAwTHh6WWVVbTBML2hMSWw1UzhreUtXYmRjPSJ9fSwiZWZmZWN0X2NvbnRyYWN0X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJlbnZpcm9ubWVudF9jb250cmFjdF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwiZW52aXJvbm1lbnRfZGlnZXN0IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImV2aWRlbmNlX2lkZW50aXR5X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJldmlkZW5jZV9tYW5pZmVzdHMiOnsiYXV0aG9yaXphdGlvbiI6eyJhZG1pc3Npb25fYXJ0aWZhY3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsImFkbWlzc2lvbl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwNiIsImV4ZWN1dGlvbl9hdXRob3JpdHlfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDgiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJnb3Zlcm5lZF9hdXRob3JpemF0aW9uX2lkX3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJtYW5pZmVzdF9zaGEyNTYiOiIxNWMwZTc2ZGMyZTMyMWEzODRlNTNlYzE1ZmY1M2U3NTU1N2I3Y2RlNzFjNWFkMmJhMmI5M2ZmMmU5NTgzNWE1IiwicGVybWl0X2NoYWluX3NoYTI1NiI6IjU5YjM5OTcxZTMwNTEwOWM1NDI5OTQ1YTVmYWI0NjYwYjA5ZjQxZTdhYzNmZmQ5MmUzNTA2YWYwMDMzN2RhOTUiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWF1dGhvcml6YXRpb24tZXZpZGVuY2UvdjEifSwiZWZmZWN0Ijp7ImNvbmZpcm1lZCI6MCwiZWZmZWN0X2NvbnRyYWN0X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJtYW5pZmVzdF9zaGEyNTYiOiI3ZTEyZGNhNWM0NGNmOTk4YTQ2OTM2MmI4NjJlODE2YTdkMmM4NTQxNjNmNjNlOGRlNjFmYjc5ZTk1YmE4MDA3IiwicmVjb3JkcyI6W10sInJlcXVpcmVkIjowLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWVmZmVjdC1ldmlkZW5jZS92MSIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifSwiaWRlbnRpdHkiOnsiY29uZmlybWVkIjowLCJpZGVudGl0eV9jb250cmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwibWFuaWZlc3Rfc2hhMjU2IjoiZDNhN2VhYzM0MjdkNzZmNmJjMzYwMzA3Mzg2MDkxMTlmMDdlMGQ5MWE2ZDM1OGFiY2U1YjZmMGQ2ZGY3ODY0NSIsInJlcXVpcmVkIjowLCJyZXN1bHRzIjpbXSwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1pZGVudGl0eS1ldmlkZW5jZS92MSIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifSwicG9saWN5Ijp7ImFkbWlzc2lvbl9wb2xpY3lfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImVmZmVjdF9jb250cmFjdF9zaGEyNTYiOiJlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlIiwiZW52aXJvbm1lbnRfY29udHJhY3Rfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsImVudmlyb25tZW50X2RpZ2VzdCI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJnb3Zlcm5lZF9wb2xpY3lfY29udHJhY3Rfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsImdvdmVybmVkX3J1bnRpbWVfaW5wdXRzX2RpZ2VzdCI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJpZGVudGl0eV9jb250cmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwibWFuaWZlc3Rfc2hhMjU2IjoiNGY5ODhkMDE1YmNkN2NkN2UwNWJhMDY2M2Q4OWYwYTk2OGYwZDhhY2U5OWIwOTBlYmFiZWU1MmExYzU1MDQyMSIsIm1pbmltdW1fZWZmZWN0X3RpZXIiOjEsInJ1bnRpbWVfZW52aXJvbm1lbnRfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tcG9saWN5LWV2aWRlbmNlL3YxIn0sInBvc3Rjb25kaXRpb24iOnsiY29uZmlybWVkIjowLCJtYW5pZmVzdF9zaGEyNTYiOiI1MmYwOWQ1ZDYzOWIxYzM4M2YzNzc5NjNlNDg3Y2I4OWQ4OTQxNzg1N2U0NGRhN2UzZjIzZTU1YmU3NTFlN2Y0IiwicmVjb3JkcyI6W10sInJlcXVpcmVkIjowLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLXBvc3Rjb25kaXRpb24tZXZpZGVuY2UvdjEiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIn19LCJldmlkZW5jZV9ydW5uZXJfc2lnbmVyX3NoYTI1NiI6IjU2NDc1YWE3NTQ2MzQ3NGMwMjg1ZGY1ZGJmMmJjYWI3M2RhNjUxMzU4ODM5ZTliNzc0ODFiMmVhYjEwNzcwOGMiLCJleGVjdXRpb25fYXV0aG9yaXR5X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA4IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaWduZXJfc2hhMjU2IjoiMjRmNmVkNmFjYmZlMTAwOWMwMzBkN2NhNTY3YzMzY2E0ODMwOTExNDk4MjM2YjU1NjFhNmM4MmFiZWM1ZGUyOCIsImV4ZWN1dGlvbl9vdXRjb21lIjp7ImNvbXBlbnNhdGlvbl9hY3Rpb25zIjowLCJldmlkZW5jZV9jbGFzc2VzIjpbImF1dGhvcml6YXRpb24iXSwiZXhlY3V0aW9uX2NvbXBsZXRlZCI6ZmFsc2UsImV4dGVybmFsX25ldHdvcmtfY2FsbHMiOiJub25lIiwibWFuYWdlZF9yZXN1bHRfbG9zc19ldmlkZW5jZV9zaGEyNTYiOiIzODEzMTljMWQ3NjJhMjNjMjExNmEyZWUwNzQxNzZjMDZmOWM4NDIwYjk1MTM4ZWFkYjliNjdkYTZhM2I0NDQ3IiwibW9kZWxfY2FsbHMiOjAsIm91dGNvbWUiOiJIQUxURUQiLCJwYXNzZWRfY29udHJhY3RzIjp7ImF1dGhvcml6YXRpb24iOjEsImVmZmVjdCI6MCwiaWRlbnRpdHkiOjAsInBvc3Rjb25kaXRpb24iOjB9LCJwb3N0Y29uZGl0aW9uX2V2aWRlbmNlIjpbXSwicHJvZHVjdGlvbl9lbGlnaWJsZSI6ZmFsc2UsInByb2ZpbGUiOiJzdGFuZGFyZCIsInF1YWxpZmljYXRpb25fZXZpZGVuY2Vfb25seSI6ZmFsc2UsInJlcXVpcmVkX2NvbnRyYWN0cyI6eyJhdXRob3JpemF0aW9uIjoxLCJlZmZlY3QiOjAsImlkZW50aXR5IjowLCJwb3N0Y29uZGl0aW9uIjowfSwidmVyc2lvbiI6Im9wZW5hZGFwdC5leGVjdXRpb24tb3V0Y29tZS92MSIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifSwiZXhlY3V0aW9uX291dGNvbWVfc2hhMjU2IjoiNzBjZjZmODE3NzJiMGJlNGIxZDcwNjdhMDVhYjRjMjkzMzY5MjM2ZDAyOWFhMWJlOGQ3OWQ2YzdjNzMxM2VmNSIsImV4ZWN1dGlvbl9wdXJwb3NlIjoicHJvZHVjdGlvbiIsImZpbmFsX2F1dGhvcml0eV9zZXF1ZW5jZSI6MCwiZmluYWxfcnVudGltZV9kZWxpdmVyeV9zZXF1ZW5jZSI6MCwiZmxvd19ydW5faWRfc2hhMjU2IjoiMTFlNTk0ZjQ4MTk1OGMxMGUzMDE1ZDBiZjA0NDdhMjJmMDY4YThhNjQ3ZjQ3NWRmMTVjZTJjN2FiNGI4ZjNmMSIsImlkZW50aXR5X2NvbnRyYWN0X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJpc3N1ZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAzWiIsIm1hbmFnZWRfcmVzdWx0X2xvc3MiOnsiYWN0dWF0aW9uX3JlcGxheV9hdXRob3JpemVkIjpmYWxzZSwiYXV0aGVudGljYXRlZF9ydW5uZXJfaWRfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImF1dGhlbnRpY2F0ZWRfc2Vzc2lvbl9pZF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwiYmxpbmRfcmV0cnlfYXV0aG9yaXplZCI6ZmFsc2UsImNoaWxkX3JlcG9ydF9yZXRhaW5lZCI6ZmFsc2UsImNoaWxkX3N0YXJ0X2V2aWRlbmNlX3NoYTI1NiI6IjY1YTZiZWQ5MjNlNDVhNmFhMGM2MjQzMDQ1ZTAzNjRjOTBhY2UwNjQ4ZmVjYjViMGJiMmViZDk0MDI3OTNjNzciLCJjaGlsZF9zdGFydGVkIjp0cnVlLCJjaGlsZF9zdGFydGVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMFoiLCJkZWxpdmVyeV9yZXN1bHRfbG9zc19jbG9zdXJlX2FydGlmYWN0X3NoYTI1NiI6ImNlYzM1N2FjZGI3NGY0ZTAyZGQxYzMyMDlhOGVjODgwOTE1Yzk4MzAxMzZlMDcyNjBmM2MxZjYzMWY4ZDUyZTgiLCJkZWxpdmVyeV9zdGF0ZSI6IkNMT1NFRF9VTlJFU09MVkVEX1JFU1VMVF9MT1NTIiwiZGlzcGF0Y2hfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDkiLCJkaXNwYXRjaF9zZXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDEwIiwiZWZmZWN0X2Fic2VuY2VfY2xhaW1lZCI6ZmFsc2UsImV2aWRlbmNlX3NoYTI1NiI6IjM4MTMxOWMxZDc2MmEyM2MyMTE2YTJlZTA3NDE3NmMwNmY5Yzg0MjBiOTUxMzhlYWRiOWI2N2RhNmEzYjQ0NDciLCJleGVjdXRpb25fYXV0aG9yaXR5X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA4IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaWduZXJfc2hhMjU2IjoiMjRmNmVkNmFjYmZlMTAwOWMwMzBkN2NhNTY3YzMzY2E0ODMwOTExNDk4MjM2YjU1NjFhNmM4MmFiZWM1ZGUyOCIsImZsb3dfcnVuX2lkX3NoYTI1NiI6IjExZTU5NGY0ODE5NThjMTBlMzAxNWQwYmYwNDQ3YTIyZjA2OGE4YTY0N2Y0NzVkZjE1Y2UyYzdhYjRiOGYzZjEiLCJpZGVtcG90ZW5jeV9rZXlfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsImxvc3NfY29kZSI6InJlcG9ydF9taXNzaW5nIiwibWFuYWdlZF9kaXNwYXRjaF9iaW5kaW5nX3NoYTI1NiI6InNoYTI1NjpjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwibm90X3JlY2VpdmVkX2NsYWltZWQiOmZhbHNlLCJvYnNlcnZlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDJaIiwicGVuZGluZ19hY3Rpb25fcmVxdWVzdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwicGVuZGluZ19wZXJtaXRfYXJ0aWZhY3Rfc2hhMjU2IjoiOTcyYTgyYWY0NTZkYTU0MmJhYzc4NDYwMTg4OTY2ODg5MWQ4YjdjY2QyNDI5MDQ4MTZiMzI5MmUxNTdlNTI4OSIsInJlcG9ydF9wcm92ZW5hbmNlIjoib3V0ZXJfcnVubmVyX3JlY292ZXJ5IiwicnVuX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAxIiwicnVuX3JlcXVlc3Rfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsInJ1bl9zdG9yZV9pZGVudGl0eV9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQubWFuYWdlZC1yZXN1bHQtbG9zcy92MSJ9LCJwZW5kaW5nX3Blcm1pdF9jb3VudCI6MSwicGVybWl0X2NoYWluIjp7ImVudHJpZXMiOltdLCJwZW5kaW5nIjp7ImFjdHVhdGlvbl9yZXBsYXlfYXV0aG9yaXplZCI6ZmFsc2UsImRlbGl2ZXJ5X3JlY2VpcHRfYXJ0aWZhY3QiOm51bGwsImRlbGl2ZXJ5X3JlY2VpcHRfYXJ0aWZhY3Rfc2hhMjU2IjpudWxsLCJkZWxpdmVyeV9zdGF0ZSI6IlVOUkVTT0xWRUQiLCJwZXJtaXRfYXJ0aWZhY3QiOnsicGF5bG9hZCI6eyJhY3Rpb25fcmVxdWVzdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2FydGlmYWN0X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJhdXRob3JpdHlfc2VxdWVuY2UiOjAsImVudmlyb25tZW50X2RpZ2VzdCI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJldmlkZW5jZV9pZGVudGl0eV9zaGEyNTYiOiJlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlIiwiZXhlY3V0aW9uX2F1dGhvcml0eV9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOCIsImV4ZWN1dGlvbl9hdXRob3JpdHlfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImZsb3dfcnVuX2lkX3NoYTI1NiI6IjExZTU5NGY0ODE5NThjMTBlMzAxNWQwYmYwNDQ3YTIyZjA2OGE4YTY0N2Y0NzVkZjE1Y2UyYzdhYjRiOGYzZjEiLCJpbnB1dF9lZGdlX3NlcXVlbmNlIjoxLCJpc3N1ZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAwWiIsInBlcm1pdF9pZCI6InBlcm1pdDoxIiwicXVhbGlmaWNhdGlvbl9zaWduZXJfcmVnaXN0cnlfY2hlY2tlZF9hdCI6IjIwMjYtMDgtMThUMTE6NTk6MzBaIiwicXVhbGlmaWNhdGlvbl9zaWduZXJfcmVnaXN0cnlfZXhwaXJlc19hdCI6IjIwMjYtMDgtMjBUMTE6MDA6MDBaIiwicXVhbGlmaWNhdGlvbl9zaWduZXJfcmVnaXN0cnlfcmV2aXNpb24iOjcsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJydW5faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDEiLCJydW5fcmVxdWVzdF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1wZXJtaXQtcGF5bG9hZC92MiJ9LCJwYXlsb2FkX3NoYTI1NiI6ImM4N2Y1NzUxYWE5YjI3OWNjZTIzYWExNzhhZmY5NTZlMTlmNjkwZmNkMmY5ZjcwZTBkOTk5NzgyYTY5MGQ2YjgiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXBlcm1pdC1hcnRpZmFjdC92MiIsInNpZ25hdHVyZSI6IjBCeUhncUR4UVpybmdMSUYtNnRaT3E5bFhhbWNBUUMwZG9VVG5lS05QZVMtU3lvT2JReU9rQXVQRks1UFljTnpPYlp4Z3NnQUxkV2FJX3NhVUNwbEJnIiwic2lnbmVyIjp7ImFsZ29yaXRobSI6ImVkMjU1MTkiLCJrZXlfaWQiOiJkZWxpdmVyeS1hdXRob3JpdHktZWQyNTUxOS0yNGY2ZWQ2YWNiZmUxMDA5IiwicHVibGljX2tleSI6IktheTY0VUc4eXZDeUxocVUwMDBMeHpZZVVtMEwvaExJbDVTOGt5S1diZGM9In19LCJwZXJtaXRfYXJ0aWZhY3Rfc2hhMjU2IjoiOTcyYTgyYWY0NTZkYTU0MmJhYzc4NDYwMTg4OTY2ODg5MWQ4YjdjY2QyNDI5MDQ4MTZiMzI5MmUxNTdlNTI4OSIsInJlY2VpcHRfYWJzZW5jZV9vYnNlcnZlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDJaIiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1wZW5kaW5nLXBlcm1pdC92MiJ9LCJwZXJtaXRfY2hhaW5fc2hhMjU2IjoiNTliMzk5NzFlMzA1MTA5YzU0Mjk5NDVhNWZhYjQ2NjBiMDlmNDFlN2FjM2ZmZDkyZTM1MDZhZjAwMzM3ZGE5NSIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcGVybWl0LWNoYWluL3YyIn0sInBlcm1pdF9jb3VudCI6MSwicXVhbGlmaWNhdGlvbl9zaWduZXJfcmVnaXN0cnlfcmV2aXNpb24iOjcsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJydW5faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDEiLCJydW5fcmVjZWlwdCI6eyJhdXRob3JpemF0aW9uX2NvbmZpcm1lZCI6MSwiYXV0aG9yaXphdGlvbl9yZXF1aXJlZCI6MSwiYnVuZGxlX2RpZ2VzdCI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJkdXJhdGlvbl9tcyI6MCwiZWZmZWN0X3RpZXJfcmVhY2hlZCI6Im5vbmUiLCJlZmZlY3RzX2NvbmZpcm1lZCI6MCwiZWZmZWN0c19yZXF1aXJlZCI6MCwiZXN0X2Nvc3RfbWljcm91c2QiOjAsImV2aWRlbmNlX2NsYXNzZXMiOlsiYXV0aG9yaXphdGlvbiJdLCJleHRlcm5hbF9uZXR3b3JrX2NhbGxzIjoibm9uZSIsImdlbmVyYXRlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDBaIiwiaGVhbHMiOjAsImlkZW50aXR5X2FwcGxpY2FibGUiOjAsImlkZW50aXR5X2FybWVkIjowLCJpZGVudGl0eV9jb25maXJtZWQiOjAsImlkZW50aXR5X3JlcXVpcmVkIjowLCJtYW5hZ2VkX3Jlc3VsdF9sb3NzX2V2aWRlbmNlX3NoYTI1NiI6IjM4MTMxOWMxZDc2MmEyM2MyMTE2YTJlZTA3NDE3NmMwNmY5Yzg0MjBiOTUxMzhlYWRiOWI2N2RhNmEzYjQ0NDciLCJtb2RlbF9jYWxscyI6MCwib3V0Y29tZSI6IkhBTFRFRCIsIm92ZXJfaGFsdF9jb3VudCI6MCwicG9zdGNvbmRpdGlvbnNfY29uZmlybWVkIjowLCJwb3N0Y29uZGl0aW9uc19yZXF1aXJlZCI6MCwicHJvZHVjdGlvbl9lbGlnaWJsZSI6ZmFsc2UsInByb2ZpbGUiOiJzdGFuZGFyZCIsInByb3ZlbmFuY2UiOiJwcm9kdWN0aW9uIiwicmVjZWlwdF9idWlsZGVyX3ZlcnNpb24iOiIxLjIuMyIsInJ1bmdfaGlzdG9ncmFtIjp7fSwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1ydW4tcmVjZWlwdC92MSIsInNvdXJjZV9yZWNlaXB0X2RpZ2VzdCI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJzb3VyY2VfcmVjZWlwdF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwic291cmNlX3NjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnJ1bi1yZXBvcnQvdjEiLCJzdGVwc19vayI6MCwic3RlcHNfdG90YWwiOjEsInN1YnN0cmF0ZSI6IndlYiIsInRyYW5zYWN0aW9uX291dGNvbWUiOiJSRUNPTkNJTElBVElPTl9SRVFVSVJFRCJ9LCJydW5fcmVjZWlwdF9zaGEyNTYiOiJhN2RhZmIxNWFiODE4MzhmNGIzNGRhZDA4MTI2OTJhN2E1ZjE5ZTAwNzkzNWUwZDc2NTIwNDFiOGU3MDUwYWUyIiwicnVuX3JlcG9ydF9vYmplY3Rfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsInJ1bl9yZXBvcnRfb2JqZWN0X3ZlcnNpb24iOiJ2ZXJzaW9uOm1hbmFnZWQtcmVzdWx0LWxvc3M6MSIsInJ1bl9yZXBvcnRfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsInJ1bnRpbWVfZW52aXJvbm1lbnRfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsInJ1bnRpbWVfc3Vic3RyYXRlIjoid2ViIiwicnVudGltZV92YWxpZGF0aW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA1Iiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi10ZXJtaW5hbC12ZXJpZmljYXRpb24vdjIiLCJ0ZW5hbnRfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDIiLCJ0ZXJtaW5hbF9zZXF1ZW5jZSI6MSwidmVyaWZpZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAyWiIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJ3b3JrZmxvd19pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwMyIsIndvcmtmbG93X3ZlcnNpb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDQifSwic2lnbmF0dXJlIjoiVzRUMmpQelZ3azFoM2NuR1JoVkZ5aTgwalZyanZkandRR04tTVpyeFQ2R2pVejljbDV4UXloajd2LURabkxFTkFzcGlnLTBGeEV1WVJHeU9tWkdDQVEiLCJzaWduZXIiOnsiYWxnb3JpdGhtIjoiZWQyNTUxOSIsImtleV9pZCI6ImV2aWRlbmNlLXJ1bm5lci1lZDI1NTE5LTU2NDc1YWE3NTQ2MzQ3NGMiLCJwdWJsaWNfa2V5IjoiQTZFSHYvUE9FTDRkY04wWTUwdkFtV2ZrMWpDYnBRMWZIZHlHWkJKVk1iZz0ifX0=", + "envelope_canonical_base64": "eyJwYXlsb2FkIjp7ImFja25vd2xlZGdlZF9wZXJtaXRfY291bnQiOjAsImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA2IiwiYWRtaXNzaW9uX3BvbGljeV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYWRtaXR0ZWRfcnVudGltZV9idWlsZF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiYnVuZGxlX2FydGlmYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJidW5kbGVfY29udGVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYnVuZGxlX3ZlcnNpb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDQiLCJkZWxpdmVyeV9yZXN1bHRfbG9zc19jbG9zdXJlIjp7InBheWxvYWQiOnsiYWNrbm93bGVkZ2VkX3Blcm1pdF9jb3VudCI6MCwiYWN0dWF0aW9uX3JlcGxheV9hdXRob3JpemVkIjpmYWxzZSwiYXV0aGVudGljYXRlZF9ydW5uZXJfaWRfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsImF1dGhlbnRpY2F0ZWRfc2Vzc2lvbl9pZF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiYmxpbmRfcmV0cnlfYXV0aG9yaXplZCI6ZmFsc2UsImNoaWxkX3N0YXJ0X2V2aWRlbmNlX3NoYTI1NiI6ImVjNjkwNzkxODg2YWUyY2UwMGM0ZTUxMTU0YzNmMTIwZWE0NDE5ZWQyNjUxZTA3M2RiNTcyNDkxOGEzYjA4YzYiLCJjaGlsZF9zdGFydGVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMFoiLCJjbG9zZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAyWiIsImNsb3N1cmVfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMTEiLCJjbG9zdXJlX3JlcXVlc3Rfc2hhMjU2IjoiZDkzMGFiMWFiYzJiMmEwNGI4NDhiOTU1ZmZkZmZmYTFmYmUwNjU1YTU1MzI1ZTA0ODlhZTExZWQ4NDIwMjI2MCIsImNsb3N1cmVfc2VxdWVuY2UiOjEsImRlbGl2ZXJ5X2Fja25vd2xlZGdtZW50X2F1dGhvcml6ZWQiOmZhbHNlLCJkZWxpdmVyeV9zdGF0ZSI6IkNMT1NFRF9VTlJFU09MVkVEX1JFU1VMVF9MT1NTIiwiZGlzcGF0Y2hfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDkiLCJkaXNwYXRjaF9zZXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDEwIiwiZWZmZWN0X2Fic2VuY2VfY2xhaW1lZCI6ZmFsc2UsImV4ZWN1dGlvbl9hdXRob3JpdHlfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDgiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NpZ25lcl9zaGEyNTYiOiIyNGY2ZWQ2YWNiZmUxMDA5YzAzMGQ3Y2E1NjdjMzNjYTQ4MzA5MTE0OTgyMzZiNTU2MWE2YzgyYWJlYzVkZTI4IiwiZmluYWxfYXV0aG9yaXR5X3NlcXVlbmNlIjowLCJmaW5hbF9pbnB1dF9lZGdlX3NlcXVlbmNlIjoxLCJmaW5hbF9ydW50aW1lX2RlbGl2ZXJ5X3NlcXVlbmNlIjowLCJmbG93X3J1bl9pZF9zaGEyNTYiOiIxMWU1OTRmNDgxOTU4YzEwZTMwMTVkMGJmMDQ0N2EyMmYwNjhhOGE2NDdmNDc1ZGYxNWNlMmM3YWI0YjhmM2YxIiwiaWRlbXBvdGVuY3lfa2V5X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJtYW5hZ2VkX2Rpc3BhdGNoX2JpbmRpbmdfc2hhMjU2Ijoic2hhMjU2OmNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJuZXdfcGVybWl0X2F1dGhvcml6ZWQiOmZhbHNlLCJub3RfcmVjZWl2ZWRfY2xhaW1lZCI6ZmFsc2UsInBlbmRpbmdfYWN0aW9uX3JlcXVlc3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsInBlbmRpbmdfcGVybWl0X2FydGlmYWN0X3NoYTI1NiI6Ijk3MmE4MmFmNDU2ZGE1NDJiYWM3ODQ2MDE4ODk2Njg4OTFkOGI3Y2NkMjQyOTA0ODE2YjMyOTJlMTU3ZTUyODkiLCJwZW5kaW5nX3Blcm1pdF9jb3VudCI6MSwicGVybWl0X2NoYWluX3NoYTI1NiI6IjU5YjM5OTcxZTMwNTEwOWM1NDI5OTQ1YTVmYWI0NjYwYjA5ZjQxZTdhYzNmZmQ5MmUzNTA2YWYwMDMzN2RhOTUiLCJwZXJtaXRfY291bnQiOjEsInJlY2VpcHRfYWJzZW5jZV9vYnNlcnZlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDJaIiwicmVzdWx0X2xvc3Nfb2JzZXJ2ZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAyWiIsInJ1bl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwMSIsInJ1bl9yZXF1ZXN0X3NoYTI1NiI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJydW5fc3RvcmVfaWRlbnRpdHlfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcmVzdWx0LWxvc3MtY2xvc3VyZS1wYXlsb2FkL3YyIiwidGVuYW50X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAyIiwidGVybWluYWxfY2FsbGJhY2tfcmVxdWlyZWQiOnRydWV9LCJwYXlsb2FkX3NoYTI1NiI6ImE4OTFhYzRjYmE1ZmRmYzE3ZDAzYzFmODAyYTJkZjhjMTFmYmYwYjYyZTRmMDRiZTY3ZjFhNWM2ZTY4ZDBhNTMiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXJlc3VsdC1sb3NzLWNsb3N1cmUtYXJ0aWZhY3QvdjIiLCJzaWduYXR1cmUiOiJnYnN0M241STMwQUF1dzZqMTdSREUtQWVRZXlxc0prUnVNbHJHQjdKSUNPOFNuTHhlQkhaSzM0NVRiN1ljY2lVZjVITF9COFZOdEpaRFRSd0ZpM1VEUSIsInNpZ25lciI6eyJhbGdvcml0aG0iOiJlZDI1NTE5Iiwia2V5X2lkIjoiZGVsaXZlcnktYXV0aG9yaXR5LWVkMjU1MTktMjRmNmVkNmFjYmZlMTAwOSIsInB1YmxpY19rZXkiOiJLYXk2NFVHOHl2Q3lMaHFVMDAwTHh6WWVVbTBML2hMSWw1UzhreUtXYmRjPSJ9fSwiZWZmZWN0X2NvbnRyYWN0X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJlbnZpcm9ubWVudF9jb250cmFjdF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwiZW52aXJvbm1lbnRfZGlnZXN0IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImV2aWRlbmNlX2lkZW50aXR5X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJldmlkZW5jZV9tYW5pZmVzdHMiOnsiYXV0aG9yaXphdGlvbiI6eyJhZG1pc3Npb25fYXJ0aWZhY3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsImFkbWlzc2lvbl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwNiIsImV4ZWN1dGlvbl9hdXRob3JpdHlfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDgiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJnb3Zlcm5lZF9hdXRob3JpemF0aW9uX2lkX3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJtYW5pZmVzdF9zaGEyNTYiOiIxNWMwZTc2ZGMyZTMyMWEzODRlNTNlYzE1ZmY1M2U3NTU1N2I3Y2RlNzFjNWFkMmJhMmI5M2ZmMmU5NTgzNWE1IiwicGVybWl0X2NoYWluX3NoYTI1NiI6IjU5YjM5OTcxZTMwNTEwOWM1NDI5OTQ1YTVmYWI0NjYwYjA5ZjQxZTdhYzNmZmQ5MmUzNTA2YWYwMDMzN2RhOTUiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWF1dGhvcml6YXRpb24tZXZpZGVuY2UvdjEifSwiZWZmZWN0Ijp7ImNvbmZpcm1lZCI6MCwiZWZmZWN0X2NvbnRyYWN0X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJtYW5pZmVzdF9zaGEyNTYiOiI3ZTEyZGNhNWM0NGNmOTk4YTQ2OTM2MmI4NjJlODE2YTdkMmM4NTQxNjNmNjNlOGRlNjFmYjc5ZTk1YmE4MDA3IiwicmVjb3JkcyI6W10sInJlcXVpcmVkIjowLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWVmZmVjdC1ldmlkZW5jZS92MSIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifSwiaWRlbnRpdHkiOnsiY29uZmlybWVkIjowLCJpZGVudGl0eV9jb250cmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwibWFuaWZlc3Rfc2hhMjU2IjoiZDNhN2VhYzM0MjdkNzZmNmJjMzYwMzA3Mzg2MDkxMTlmMDdlMGQ5MWE2ZDM1OGFiY2U1YjZmMGQ2ZGY3ODY0NSIsInJlcXVpcmVkIjowLCJyZXN1bHRzIjpbXSwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1pZGVudGl0eS1ldmlkZW5jZS92MSIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifSwicG9saWN5Ijp7ImFkbWlzc2lvbl9wb2xpY3lfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImVmZmVjdF9jb250cmFjdF9zaGEyNTYiOiJlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlIiwiZW52aXJvbm1lbnRfY29udHJhY3Rfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsImVudmlyb25tZW50X2RpZ2VzdCI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJnb3Zlcm5lZF9wb2xpY3lfY29udHJhY3Rfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsImdvdmVybmVkX3J1bnRpbWVfaW5wdXRzX2RpZ2VzdCI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJpZGVudGl0eV9jb250cmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwibWFuaWZlc3Rfc2hhMjU2IjoiNGY5ODhkMDE1YmNkN2NkN2UwNWJhMDY2M2Q4OWYwYTk2OGYwZDhhY2U5OWIwOTBlYmFiZWU1MmExYzU1MDQyMSIsIm1pbmltdW1fZWZmZWN0X3RpZXIiOjEsInJ1bnRpbWVfZW52aXJvbm1lbnRfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tcG9saWN5LWV2aWRlbmNlL3YxIn0sInBvc3Rjb25kaXRpb24iOnsiY29uZmlybWVkIjowLCJtYW5pZmVzdF9zaGEyNTYiOiI1MmYwOWQ1ZDYzOWIxYzM4M2YzNzc5NjNlNDg3Y2I4OWQ4OTQxNzg1N2U0NGRhN2UzZjIzZTU1YmU3NTFlN2Y0IiwicmVjb3JkcyI6W10sInJlcXVpcmVkIjowLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLXBvc3Rjb25kaXRpb24tZXZpZGVuY2UvdjEiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIn19LCJldmlkZW5jZV9ydW5uZXJfc2lnbmVyX3NoYTI1NiI6IjU2NDc1YWE3NTQ2MzQ3NGMwMjg1ZGY1ZGJmMmJjYWI3M2RhNjUxMzU4ODM5ZTliNzc0ODFiMmVhYjEwNzcwOGMiLCJleGVjdXRpb25fYXV0aG9yaXR5X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA4IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaWduZXJfc2hhMjU2IjoiMjRmNmVkNmFjYmZlMTAwOWMwMzBkN2NhNTY3YzMzY2E0ODMwOTExNDk4MjM2YjU1NjFhNmM4MmFiZWM1ZGUyOCIsImV4ZWN1dGlvbl9vdXRjb21lIjp7ImNvbXBlbnNhdGlvbl9hY3Rpb25zIjowLCJldmlkZW5jZV9jbGFzc2VzIjpbImF1dGhvcml6YXRpb24iXSwiZXhlY3V0aW9uX2NvbXBsZXRlZCI6ZmFsc2UsImV4dGVybmFsX25ldHdvcmtfY2FsbHMiOiJub25lIiwibWFuYWdlZF9yZXN1bHRfbG9zc19ldmlkZW5jZV9zaGEyNTYiOiIyY2QwNzY0OTBjYTVlNWU4ZDlkMGJkMTQ2ZDU1OWMwNmVkNDEzYTY3ZDY5NDgxYTFhZmNjMzU0NDY0ZWNkYjA3IiwibW9kZWxfY2FsbHMiOjAsIm91dGNvbWUiOiJIQUxURUQiLCJwYXNzZWRfY29udHJhY3RzIjp7ImF1dGhvcml6YXRpb24iOjEsImVmZmVjdCI6MCwiaWRlbnRpdHkiOjAsInBvc3Rjb25kaXRpb24iOjB9LCJwb3N0Y29uZGl0aW9uX2V2aWRlbmNlIjpbXSwicHJvZHVjdGlvbl9lbGlnaWJsZSI6ZmFsc2UsInByb2ZpbGUiOiJzdGFuZGFyZCIsInF1YWxpZmljYXRpb25fZXZpZGVuY2Vfb25seSI6ZmFsc2UsInJlcXVpcmVkX2NvbnRyYWN0cyI6eyJhdXRob3JpemF0aW9uIjoxLCJlZmZlY3QiOjAsImlkZW50aXR5IjowLCJwb3N0Y29uZGl0aW9uIjowfSwidmVyc2lvbiI6Im9wZW5hZGFwdC5leGVjdXRpb24tb3V0Y29tZS92MSIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifSwiZXhlY3V0aW9uX291dGNvbWVfc2hhMjU2IjoiMzQ0OTYyZDJkZTM2ZWNiZDI5NWIxZTViZjhhZmIwNmE3ZjQ2NWQ2NTRlODFjZGZiNTIxNmZiYjYxMWYxZGE4YiIsImV4ZWN1dGlvbl9wdXJwb3NlIjoicHJvZHVjdGlvbiIsImZpbmFsX2F1dGhvcml0eV9zZXF1ZW5jZSI6MCwiZmluYWxfcnVudGltZV9kZWxpdmVyeV9zZXF1ZW5jZSI6MCwiZmxvd19ydW5faWRfc2hhMjU2IjoiMTFlNTk0ZjQ4MTk1OGMxMGUzMDE1ZDBiZjA0NDdhMjJmMDY4YThhNjQ3ZjQ3NWRmMTVjZTJjN2FiNGI4ZjNmMSIsImlkZW50aXR5X2NvbnRyYWN0X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJpc3N1ZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAzWiIsIm1hbmFnZWRfcmVzdWx0X2xvc3MiOnsiYWN0dWF0aW9uX3JlcGxheV9hdXRob3JpemVkIjpmYWxzZSwiYXV0aGVudGljYXRlZF9ydW5uZXJfaWRfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsImF1dGhlbnRpY2F0ZWRfc2Vzc2lvbl9pZF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiYmxpbmRfcmV0cnlfYXV0aG9yaXplZCI6ZmFsc2UsImNoaWxkX3JlcG9ydF9yZXRhaW5lZCI6ZmFsc2UsImNoaWxkX3N0YXJ0X2V2aWRlbmNlX3NoYTI1NiI6ImVjNjkwNzkxODg2YWUyY2UwMGM0ZTUxMTU0YzNmMTIwZWE0NDE5ZWQyNjUxZTA3M2RiNTcyNDkxOGEzYjA4YzYiLCJjaGlsZF9zdGFydGVkIjp0cnVlLCJjaGlsZF9zdGFydGVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMFoiLCJkZWxpdmVyeV9yZXN1bHRfbG9zc19jbG9zdXJlX2FydGlmYWN0X3NoYTI1NiI6IjY1ZDBkODJkNTc3YTUzMjMwMjJiMmFmY2UxYTI2YTIxNmE1MmQyMWVmOTgyZTA1NDBjMjY2ZjMwNjNmYmM3OTciLCJkZWxpdmVyeV9zdGF0ZSI6IkNMT1NFRF9VTlJFU09MVkVEX1JFU1VMVF9MT1NTIiwiZGlzcGF0Y2hfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDkiLCJkaXNwYXRjaF9zZXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDEwIiwiZWZmZWN0X2Fic2VuY2VfY2xhaW1lZCI6ZmFsc2UsImV2aWRlbmNlX3NoYTI1NiI6IjJjZDA3NjQ5MGNhNWU1ZThkOWQwYmQxNDZkNTU5YzA2ZWQ0MTNhNjdkNjk0ODFhMWFmY2MzNTQ0NjRlY2RiMDciLCJleGVjdXRpb25fYXV0aG9yaXR5X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA4IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaWduZXJfc2hhMjU2IjoiMjRmNmVkNmFjYmZlMTAwOWMwMzBkN2NhNTY3YzMzY2E0ODMwOTExNDk4MjM2YjU1NjFhNmM4MmFiZWM1ZGUyOCIsImZsb3dfcnVuX2lkX3NoYTI1NiI6IjExZTU5NGY0ODE5NThjMTBlMzAxNWQwYmYwNDQ3YTIyZjA2OGE4YTY0N2Y0NzVkZjE1Y2UyYzdhYjRiOGYzZjEiLCJpZGVtcG90ZW5jeV9rZXlfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsImxvc3NfY29kZSI6InJlcG9ydF9taXNzaW5nIiwibWFuYWdlZF9kaXNwYXRjaF9iaW5kaW5nX3NoYTI1NiI6InNoYTI1NjpjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwibm90X3JlY2VpdmVkX2NsYWltZWQiOmZhbHNlLCJvYnNlcnZlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDJaIiwicGVuZGluZ19hY3Rpb25fcmVxdWVzdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwicGVuZGluZ19wZXJtaXRfYXJ0aWZhY3Rfc2hhMjU2IjoiOTcyYTgyYWY0NTZkYTU0MmJhYzc4NDYwMTg4OTY2ODg5MWQ4YjdjY2QyNDI5MDQ4MTZiMzI5MmUxNTdlNTI4OSIsInJlcG9ydF9wcm92ZW5hbmNlIjoib3V0ZXJfcnVubmVyX3JlY292ZXJ5IiwicnVuX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAxIiwicnVuX3JlcXVlc3Rfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsInJ1bl9zdG9yZV9pZGVudGl0eV9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQubWFuYWdlZC1yZXN1bHQtbG9zcy92MSJ9LCJwZW5kaW5nX3Blcm1pdF9jb3VudCI6MSwicGVybWl0X2NoYWluIjp7ImVudHJpZXMiOltdLCJwZW5kaW5nIjp7ImFjdHVhdGlvbl9yZXBsYXlfYXV0aG9yaXplZCI6ZmFsc2UsImRlbGl2ZXJ5X3JlY2VpcHRfYXJ0aWZhY3QiOm51bGwsImRlbGl2ZXJ5X3JlY2VpcHRfYXJ0aWZhY3Rfc2hhMjU2IjpudWxsLCJkZWxpdmVyeV9zdGF0ZSI6IlVOUkVTT0xWRUQiLCJwZXJtaXRfYXJ0aWZhY3QiOnsicGF5bG9hZCI6eyJhY3Rpb25fcmVxdWVzdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2FydGlmYWN0X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJhdXRob3JpdHlfc2VxdWVuY2UiOjAsImVudmlyb25tZW50X2RpZ2VzdCI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJldmlkZW5jZV9pZGVudGl0eV9zaGEyNTYiOiJlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlIiwiZXhlY3V0aW9uX2F1dGhvcml0eV9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOCIsImV4ZWN1dGlvbl9hdXRob3JpdHlfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImZsb3dfcnVuX2lkX3NoYTI1NiI6IjExZTU5NGY0ODE5NThjMTBlMzAxNWQwYmYwNDQ3YTIyZjA2OGE4YTY0N2Y0NzVkZjE1Y2UyYzdhYjRiOGYzZjEiLCJpbnB1dF9lZGdlX3NlcXVlbmNlIjoxLCJpc3N1ZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAwWiIsInBlcm1pdF9pZCI6InBlcm1pdDoxIiwicXVhbGlmaWNhdGlvbl9zaWduZXJfcmVnaXN0cnlfY2hlY2tlZF9hdCI6IjIwMjYtMDgtMThUMTE6NTk6MzBaIiwicXVhbGlmaWNhdGlvbl9zaWduZXJfcmVnaXN0cnlfZXhwaXJlc19hdCI6IjIwMjYtMDgtMjBUMTE6MDA6MDBaIiwicXVhbGlmaWNhdGlvbl9zaWduZXJfcmVnaXN0cnlfcmV2aXNpb24iOjcsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJydW5faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDEiLCJydW5fcmVxdWVzdF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1wZXJtaXQtcGF5bG9hZC92MiJ9LCJwYXlsb2FkX3NoYTI1NiI6ImM4N2Y1NzUxYWE5YjI3OWNjZTIzYWExNzhhZmY5NTZlMTlmNjkwZmNkMmY5ZjcwZTBkOTk5NzgyYTY5MGQ2YjgiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXBlcm1pdC1hcnRpZmFjdC92MiIsInNpZ25hdHVyZSI6IjBCeUhncUR4UVpybmdMSUYtNnRaT3E5bFhhbWNBUUMwZG9VVG5lS05QZVMtU3lvT2JReU9rQXVQRks1UFljTnpPYlp4Z3NnQUxkV2FJX3NhVUNwbEJnIiwic2lnbmVyIjp7ImFsZ29yaXRobSI6ImVkMjU1MTkiLCJrZXlfaWQiOiJkZWxpdmVyeS1hdXRob3JpdHktZWQyNTUxOS0yNGY2ZWQ2YWNiZmUxMDA5IiwicHVibGljX2tleSI6IktheTY0VUc4eXZDeUxocVUwMDBMeHpZZVVtMEwvaExJbDVTOGt5S1diZGM9In19LCJwZXJtaXRfYXJ0aWZhY3Rfc2hhMjU2IjoiOTcyYTgyYWY0NTZkYTU0MmJhYzc4NDYwMTg4OTY2ODg5MWQ4YjdjY2QyNDI5MDQ4MTZiMzI5MmUxNTdlNTI4OSIsInJlY2VpcHRfYWJzZW5jZV9vYnNlcnZlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDJaIiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1wZW5kaW5nLXBlcm1pdC92MiJ9LCJwZXJtaXRfY2hhaW5fc2hhMjU2IjoiNTliMzk5NzFlMzA1MTA5YzU0Mjk5NDVhNWZhYjQ2NjBiMDlmNDFlN2FjM2ZmZDkyZTM1MDZhZjAwMzM3ZGE5NSIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcGVybWl0LWNoYWluL3YyIn0sInBlcm1pdF9jb3VudCI6MSwicXVhbGlmaWNhdGlvbl9zaWduZXJfcmVnaXN0cnlfcmV2aXNpb24iOjcsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJydW5faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDEiLCJydW5fcmVjZWlwdCI6eyJhdXRob3JpemF0aW9uX2NvbmZpcm1lZCI6MSwiYXV0aG9yaXphdGlvbl9yZXF1aXJlZCI6MSwiYnVuZGxlX2RpZ2VzdCI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJkdXJhdGlvbl9tcyI6MCwiZWZmZWN0X3RpZXJfcmVhY2hlZCI6Im5vbmUiLCJlZmZlY3RzX2NvbmZpcm1lZCI6MCwiZWZmZWN0c19yZXF1aXJlZCI6MCwiZXN0X2Nvc3RfbWljcm91c2QiOjAsImV2aWRlbmNlX2NsYXNzZXMiOlsiYXV0aG9yaXphdGlvbiJdLCJleHRlcm5hbF9uZXR3b3JrX2NhbGxzIjoibm9uZSIsImdlbmVyYXRlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDBaIiwiaGVhbHMiOjAsImlkZW50aXR5X2FwcGxpY2FibGUiOjAsImlkZW50aXR5X2FybWVkIjowLCJpZGVudGl0eV9jb25maXJtZWQiOjAsImlkZW50aXR5X3JlcXVpcmVkIjowLCJtYW5hZ2VkX3Jlc3VsdF9sb3NzX2V2aWRlbmNlX3NoYTI1NiI6IjJjZDA3NjQ5MGNhNWU1ZThkOWQwYmQxNDZkNTU5YzA2ZWQ0MTNhNjdkNjk0ODFhMWFmY2MzNTQ0NjRlY2RiMDciLCJtb2RlbF9jYWxscyI6MCwib3V0Y29tZSI6IkhBTFRFRCIsIm92ZXJfaGFsdF9jb3VudCI6MCwicG9zdGNvbmRpdGlvbnNfY29uZmlybWVkIjowLCJwb3N0Y29uZGl0aW9uc19yZXF1aXJlZCI6MCwicHJvZHVjdGlvbl9lbGlnaWJsZSI6ZmFsc2UsInByb2ZpbGUiOiJzdGFuZGFyZCIsInByb3ZlbmFuY2UiOiJwcm9kdWN0aW9uIiwicmVjZWlwdF9idWlsZGVyX3ZlcnNpb24iOiIxLjIuMyIsInJ1bmdfaGlzdG9ncmFtIjp7fSwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1ydW4tcmVjZWlwdC92MSIsInNvdXJjZV9yZWNlaXB0X2RpZ2VzdCI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJzb3VyY2VfcmVjZWlwdF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwic291cmNlX3NjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnJ1bi1yZXBvcnQvdjEiLCJzdGVwc19vayI6MCwic3RlcHNfdG90YWwiOjEsInN1YnN0cmF0ZSI6IndlYiIsInRyYW5zYWN0aW9uX291dGNvbWUiOiJSRUNPTkNJTElBVElPTl9SRVFVSVJFRCJ9LCJydW5fcmVjZWlwdF9zaGEyNTYiOiIwOTU1YjBlNzllMDlmYjFlMzRiZGI5OGE4ZDEzMGE4YzEyNjNiZTg2Y2E5ZDU0ODYyZDdkMzRhYmZmNGNkOWI0IiwicnVuX3JlcG9ydF9vYmplY3Rfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsInJ1bl9yZXBvcnRfb2JqZWN0X3ZlcnNpb24iOiJ2ZXJzaW9uOm1hbmFnZWQtcmVzdWx0LWxvc3M6MSIsInJ1bl9yZXBvcnRfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsInJ1bnRpbWVfZW52aXJvbm1lbnRfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsInJ1bnRpbWVfc3Vic3RyYXRlIjoid2ViIiwicnVudGltZV92YWxpZGF0aW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA1Iiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi10ZXJtaW5hbC12ZXJpZmljYXRpb24vdjIiLCJ0ZW5hbnRfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDIiLCJ0ZXJtaW5hbF9zZXF1ZW5jZSI6MSwidmVyaWZpZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAyWiIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJ3b3JrZmxvd19pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwMyIsIndvcmtmbG93X3ZlcnNpb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDQifSwic2lnbmF0dXJlIjoidUd0S1hWY2pxS0tyTEhPMm44dGhmYUdsbDk5bHpFeHF0MlcyUHpSZlQyOG9udXpzNjk5VGxtMDVkSzlCVTlCZC16WDM3NEJDcjBtVktIeHJ2WnRsQlEiLCJzaWduZXIiOnsiYWxnb3JpdGhtIjoiZWQyNTUxOSIsImtleV9pZCI6ImV2aWRlbmNlLXJ1bm5lci1lZDI1NTE5LTU2NDc1YWE3NTQ2MzQ3NGMiLCJwdWJsaWNfa2V5IjoiQTZFSHYvUE9FTDRkY04wWTUwdkFtV2ZrMWpDYnBRMWZIZHlHWkJKVk1iZz0ifX0=", "managed_result_loss": { "actuation_replay_authorized": false, - "authenticated_runner_id_sha256": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "authenticated_session_id_sha256": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "authenticated_runner_id_sha256": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "authenticated_session_id_sha256": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "blind_retry_authorized": false, "child_report_retained": false, - "child_start_evidence_sha256": "65a6bed923e45a6aa0c6243045e0364c90ace0648fecb5b0bb2ebd9402793c77", + "child_start_evidence_sha256": "ec690791886ae2ce00c4e51154c3f120ea4419ed2651e073db5724918a3b08c6", "child_started": true, "child_started_at": "2026-08-18T12:00:00Z", - "delivery_result_loss_closure_artifact_sha256": "cec357acdb74f4e02dd1c3209a8ec880915c9830136e07260f3c1f631f8d52e8", + "delivery_result_loss_closure_artifact_sha256": "65d0d82d577a5323022b2afce1a26a216a52d21ef982e0540c266f3063fbc797", "delivery_state": "CLOSED_UNRESOLVED_RESULT_LOSS", "dispatch_id": "00000000-0000-4000-8000-000000000009", "dispatch_session_id": "00000000-0000-4000-8000-000000000010", "effect_absence_claimed": false, - "evidence_sha256": "381319c1d762a23c2116a2ee074176c06f9c8420b95138eadb9b67da6a3b4447", + "evidence_sha256": "2cd076490ca5e5e8d9d0bd146d559c06ed413a67d69481a1afcc354464ecdb07", "execution_authority_id": "00000000-0000-4000-8000-000000000008", "execution_authority_sha256": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "execution_authority_signer_sha256": "24f6ed6acbfe1009c030d7ca567c33ca4830911498236b5561a6c82abec5de28", @@ -192,9 +192,9 @@ "schema_version": "openadapt.managed-result-loss/v1" }, "name": "reconciliation-required-managed-result-loss", - "payload_canonical_sha256": "1480dcd4830987d01d27a66647e8b38af02a605d93ca604c5cbc50c10a7a1852", - "signature": "W4T2jPzVwk1h3cnGRhVFyi80jVrjvdjwQGN-MZrxT6GjUz9cl5xQyhj7v-DZnLENAspig-0FxEuYRGyOmZGCAQ", - "terminal_verification_artifact_sha256": "fa3eb5109494d421cefff1557211b19614fbf4be654c188832c8130c3308899e" + "payload_canonical_sha256": "955bae00518f0d07965a05727654e108b618818fd6933f6de2ed8c3d425f27fd", + "signature": "uGtKXVcjqKKrLHO2n8thfaGll99lzExqt2W2PzRfT28onuzs699Tlm05dK9BU9Bd-zX374BCr0mVKHxrvZtlBQ", + "terminal_verification_artifact_sha256": "c2a7ef78aebeb55c585386b7b78e16ac3c84f8d19656d0dd1cb76b65141b8d47" }, { "callback": { @@ -207,22 +207,22 @@ "uncertain_delivery": false }, "effect_state": null, - "envelope_canonical_base64": "eyJwYXlsb2FkIjp7ImFja25vd2xlZGdlZF9wZXJtaXRfY291bnQiOjEsImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA2IiwiYWRtaXNzaW9uX3BvbGljeV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYWRtaXR0ZWRfcnVudGltZV9idWlsZF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiYnVuZGxlX2FydGlmYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJidW5kbGVfY29udGVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYnVuZGxlX3ZlcnNpb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDQiLCJkZWxpdmVyeV9yZXN1bHRfbG9zc19jbG9zdXJlIjp7InBheWxvYWQiOnsiYWNrbm93bGVkZ2VkX3Blcm1pdF9jb3VudCI6MSwiYWN0dWF0aW9uX3JlcGxheV9hdXRob3JpemVkIjpmYWxzZSwiYXV0aGVudGljYXRlZF9ydW5uZXJfaWRfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImF1dGhlbnRpY2F0ZWRfc2Vzc2lvbl9pZF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwiYmxpbmRfcmV0cnlfYXV0aG9yaXplZCI6ZmFsc2UsImNoaWxkX3N0YXJ0X2V2aWRlbmNlX3NoYTI1NiI6IjY1YTZiZWQ5MjNlNDVhNmFhMGM2MjQzMDQ1ZTAzNjRjOTBhY2UwNjQ4ZmVjYjViMGJiMmViZDk0MDI3OTNjNzciLCJjaGlsZF9zdGFydGVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMFoiLCJjbG9zZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAyWiIsImNsb3N1cmVfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMTEiLCJjbG9zdXJlX3JlcXVlc3Rfc2hhMjU2IjoiYmFmNDE3YWU0OGVlYzQwNjU4NGVmNTI4NmFhYTFiMWFjMmU2ZTAzZDhhMjlhNGZiNGIwYzUzMjcwNGJlNTljNiIsImNsb3N1cmVfc2VxdWVuY2UiOjEsImRlbGl2ZXJ5X2Fja25vd2xlZGdtZW50X2F1dGhvcml6ZWQiOmZhbHNlLCJkZWxpdmVyeV9zdGF0ZSI6IkNMT1NFRF9VTlJFU09MVkVEX1JFU1VMVF9MT1NTIiwiZGlzcGF0Y2hfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDkiLCJkaXNwYXRjaF9zZXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDEwIiwiZWZmZWN0X2Fic2VuY2VfY2xhaW1lZCI6ZmFsc2UsImV4ZWN1dGlvbl9hdXRob3JpdHlfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDgiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NpZ25lcl9zaGEyNTYiOiIyNGY2ZWQ2YWNiZmUxMDA5YzAzMGQ3Y2E1NjdjMzNjYTQ4MzA5MTE0OTgyMzZiNTU2MWE2YzgyYWJlYzVkZTI4IiwiZmluYWxfYXV0aG9yaXR5X3NlcXVlbmNlIjowLCJmaW5hbF9pbnB1dF9lZGdlX3NlcXVlbmNlIjoxLCJmaW5hbF9ydW50aW1lX2RlbGl2ZXJ5X3NlcXVlbmNlIjo5LCJmbG93X3J1bl9pZF9zaGEyNTYiOiIxMWU1OTRmNDgxOTU4YzEwZTMwMTVkMGJmMDQ0N2EyMmYwNjhhOGE2NDdmNDc1ZGYxNWNlMmM3YWI0YjhmM2YxIiwiaWRlbXBvdGVuY3lfa2V5X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJtYW5hZ2VkX2Rpc3BhdGNoX2JpbmRpbmdfc2hhMjU2Ijoic2hhMjU2OmNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJuZXdfcGVybWl0X2F1dGhvcml6ZWQiOmZhbHNlLCJub3RfcmVjZWl2ZWRfY2xhaW1lZCI6ZmFsc2UsInBlbmRpbmdfYWN0aW9uX3JlcXVlc3Rfc2hhMjU2IjpudWxsLCJwZW5kaW5nX3Blcm1pdF9hcnRpZmFjdF9zaGEyNTYiOm51bGwsInBlbmRpbmdfcGVybWl0X2NvdW50IjowLCJwZXJtaXRfY2hhaW5fc2hhMjU2IjoiNTA0OGZlOTQ1ODgyZDI4MDI2MDA4ZDdlOTEzN2FkMDE2ZmRkMDFhZWFmNTg4NDgxZmI1YmQwZjI0MmE1MDA0MyIsInBlcm1pdF9jb3VudCI6MSwicmVjZWlwdF9hYnNlbmNlX29ic2VydmVkX2F0IjpudWxsLCJyZXN1bHRfbG9zc19vYnNlcnZlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDJaIiwicnVuX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAxIiwicnVuX3JlcXVlc3Rfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsInJ1bl9zdG9yZV9pZGVudGl0eV9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1yZXN1bHQtbG9zcy1jbG9zdXJlLXBheWxvYWQvdjIiLCJ0ZW5hbnRfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDIiLCJ0ZXJtaW5hbF9jYWxsYmFja19yZXF1aXJlZCI6dHJ1ZX0sInBheWxvYWRfc2hhMjU2IjoiMTE5YjBkODA2Njk0ZWQyMTYwNGQwOTE3MTMyMmQ1MjFiYzBhYTEyYjFlYTc5ZmIzNDkyNTA0YWMzZWZjNjRlYSIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcmVzdWx0LWxvc3MtY2xvc3VyZS1hcnRpZmFjdC92MiIsInNpZ25hdHVyZSI6InZsUmhUdHFSdm9kYnNObWZ5MmFSU3pndU0tYmZkZDRUWkFyeHBvbGRHd0NSeWtDZWRVLUZhanhkdHlyTDd5TmNpQnZpdWNvTnBpUFUyQXBNdG9abEJnIiwic2lnbmVyIjp7ImFsZ29yaXRobSI6ImVkMjU1MTkiLCJrZXlfaWQiOiJkZWxpdmVyeS1hdXRob3JpdHktZWQyNTUxOS0yNGY2ZWQ2YWNiZmUxMDA5IiwicHVibGljX2tleSI6IktheTY0VUc4eXZDeUxocVUwMDBMeHpZZVVtMEwvaExJbDVTOGt5S1diZGM9In19LCJlZmZlY3RfY29udHJhY3Rfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImVudmlyb25tZW50X2NvbnRyYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJlbnZpcm9ubWVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXZpZGVuY2VfaWRlbnRpdHlfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImV2aWRlbmNlX21hbmlmZXN0cyI6eyJhdXRob3JpemF0aW9uIjp7ImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA2IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOCIsImV4ZWN1dGlvbl9hdXRob3JpdHlfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImdvdmVybmVkX2F1dGhvcml6YXRpb25faWRfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsIm1hbmlmZXN0X3NoYTI1NiI6ImYwY2ExOWE2YjNlYWJlNTk0ZGJjOTA2ODljMmY3NGNiZTVlODJkNGQ5NDdkYjI5YTVkMDdiMTY0MWU4OTYxY2YiLCJwZXJtaXRfY2hhaW5fc2hhMjU2IjoiNTA0OGZlOTQ1ODgyZDI4MDI2MDA4ZDdlOTEzN2FkMDE2ZmRkMDFhZWFmNTg4NDgxZmI1YmQwZjI0MmE1MDA0MyIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tYXV0aG9yaXphdGlvbi1ldmlkZW5jZS92MSJ9LCJlZmZlY3QiOnsiY29uZmlybWVkIjowLCJlZmZlY3RfY29udHJhY3Rfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsIm1hbmlmZXN0X3NoYTI1NiI6IjdlMTJkY2E1YzQ0Y2Y5OThhNDY5MzYyYjg2MmU4MTZhN2QyYzg1NDE2M2Y2M2U4ZGU2MWZiNzllOTViYTgwMDciLCJyZWNvcmRzIjpbXSwicmVxdWlyZWQiOjAsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZWZmZWN0LWV2aWRlbmNlL3YxIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSJ9LCJpZGVudGl0eSI6eyJjb25maXJtZWQiOjAsImlkZW50aXR5X2NvbnRyYWN0X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJtYW5pZmVzdF9zaGEyNTYiOiJkM2E3ZWFjMzQyN2Q3NmY2YmMzNjAzMDczODYwOTExOWYwN2UwZDkxYTZkMzU4YWJjZTViNmYwZDZkZjc4NjQ1IiwicmVxdWlyZWQiOjAsInJlc3VsdHMiOltdLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWlkZW50aXR5LWV2aWRlbmNlL3YxIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSJ9LCJwb2xpY3kiOnsiYWRtaXNzaW9uX3BvbGljeV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZWZmZWN0X2NvbnRyYWN0X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJlbnZpcm9ubWVudF9jb250cmFjdF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwiZW52aXJvbm1lbnRfZGlnZXN0IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImdvdmVybmVkX3BvbGljeV9jb250cmFjdF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwiZ292ZXJuZWRfcnVudGltZV9pbnB1dHNfZGlnZXN0IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsImlkZW50aXR5X2NvbnRyYWN0X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJtYW5pZmVzdF9zaGEyNTYiOiI0Zjk4OGQwMTViY2Q3Y2Q3ZTA1YmEwNjYzZDg5ZjBhOTY4ZjBkOGFjZTk5YjA5MGViYWJlZTUyYTFjNTUwNDIxIiwibWluaW11bV9lZmZlY3RfdGllciI6MSwicnVudGltZV9lbnZpcm9ubWVudF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1wb2xpY3ktZXZpZGVuY2UvdjEifSwicG9zdGNvbmRpdGlvbiI6eyJjb25maXJtZWQiOjAsIm1hbmlmZXN0X3NoYTI1NiI6IjUyZjA5ZDVkNjM5YjFjMzgzZjM3Nzk2M2U0ODdjYjg5ZDg5NDE3ODU3ZTQ0ZGE3ZTNmMjNlNTViZTc1MWU3ZjQiLCJyZWNvcmRzIjpbXSwicmVxdWlyZWQiOjAsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tcG9zdGNvbmRpdGlvbi1ldmlkZW5jZS92MSIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifX0sImV2aWRlbmNlX3J1bm5lcl9zaWduZXJfc2hhMjU2IjoiNTY0NzVhYTc1NDYzNDc0YzAyODVkZjVkYmYyYmNhYjczZGE2NTEzNTg4MzllOWI3NzQ4MWIyZWFiMTA3NzA4YyIsImV4ZWN1dGlvbl9hdXRob3JpdHlfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDgiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NpZ25lcl9zaGEyNTYiOiIyNGY2ZWQ2YWNiZmUxMDA5YzAzMGQ3Y2E1NjdjMzNjYTQ4MzA5MTE0OTgyMzZiNTU2MWE2YzgyYWJlYzVkZTI4IiwiZXhlY3V0aW9uX291dGNvbWUiOnsiY29tcGVuc2F0aW9uX2FjdGlvbnMiOjAsImV2aWRlbmNlX2NsYXNzZXMiOlsiYXV0aG9yaXphdGlvbiJdLCJleGVjdXRpb25fY29tcGxldGVkIjpmYWxzZSwiZXh0ZXJuYWxfbmV0d29ya19jYWxscyI6Im5vbmUiLCJtYW5hZ2VkX3Jlc3VsdF9sb3NzX2V2aWRlbmNlX3NoYTI1NiI6IjcxNDUyYjExODgzYWJjZDYzZDhjNzYxMzNkNDI2MDEyMjhmYWExYWZlY2Q4Mjc5YjVlY2NlODY2MThkNGViMjMiLCJtb2RlbF9jYWxscyI6MCwib3V0Y29tZSI6IkhBTFRFRCIsInBhc3NlZF9jb250cmFjdHMiOnsiYXV0aG9yaXphdGlvbiI6MSwiZWZmZWN0IjowLCJpZGVudGl0eSI6MCwicG9zdGNvbmRpdGlvbiI6MH0sInBvc3Rjb25kaXRpb25fZXZpZGVuY2UiOltdLCJwcm9kdWN0aW9uX2VsaWdpYmxlIjpmYWxzZSwicHJvZmlsZSI6InN0YW5kYXJkIiwicXVhbGlmaWNhdGlvbl9ldmlkZW5jZV9vbmx5IjpmYWxzZSwicmVxdWlyZWRfY29udHJhY3RzIjp7ImF1dGhvcml6YXRpb24iOjEsImVmZmVjdCI6MCwiaWRlbnRpdHkiOjAsInBvc3Rjb25kaXRpb24iOjB9LCJ2ZXJzaW9uIjoib3BlbmFkYXB0LmV4ZWN1dGlvbi1vdXRjb21lL3YxIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSJ9LCJleGVjdXRpb25fb3V0Y29tZV9zaGEyNTYiOiI0ODlhYmU5MzQ0OGNjYzc5NWZhZWY0NGJjZTcwMTE1MzQwODM2ZDVjNDc1ZDIwZGIzZmNmOWY2NTY2NTJmYzRkIiwiZXhlY3V0aW9uX3B1cnBvc2UiOiJwcm9kdWN0aW9uIiwiZmluYWxfYXV0aG9yaXR5X3NlcXVlbmNlIjowLCJmaW5hbF9ydW50aW1lX2RlbGl2ZXJ5X3NlcXVlbmNlIjo5LCJmbG93X3J1bl9pZF9zaGEyNTYiOiIxMWU1OTRmNDgxOTU4YzEwZTMwMTVkMGJmMDQ0N2EyMmYwNjhhOGE2NDdmNDc1ZGYxNWNlMmM3YWI0YjhmM2YxIiwiaWRlbnRpdHlfY29udHJhY3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsImlzc3VlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDNaIiwibWFuYWdlZF9yZXN1bHRfbG9zcyI6eyJhY3R1YXRpb25fcmVwbGF5X2F1dGhvcml6ZWQiOmZhbHNlLCJhdXRoZW50aWNhdGVkX3J1bm5lcl9pZF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYXV0aGVudGljYXRlZF9zZXNzaW9uX2lkX3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJibGluZF9yZXRyeV9hdXRob3JpemVkIjpmYWxzZSwiY2hpbGRfcmVwb3J0X3JldGFpbmVkIjpmYWxzZSwiY2hpbGRfc3RhcnRfZXZpZGVuY2Vfc2hhMjU2IjoiNjVhNmJlZDkyM2U0NWE2YWEwYzYyNDMwNDVlMDM2NGM5MGFjZTA2NDhmZWNiNWIwYmIyZWJkOTQwMjc5M2M3NyIsImNoaWxkX3N0YXJ0ZWQiOnRydWUsImNoaWxkX3N0YXJ0ZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAwWiIsImRlbGl2ZXJ5X3Jlc3VsdF9sb3NzX2Nsb3N1cmVfYXJ0aWZhY3Rfc2hhMjU2IjoiOTBkZjhiZDFmMjg5MWIyMDM2NjNhNjNmNDI1MTUwNzQ0NWRiZTgzODM2MGEyMTllNDNhZjlhMWJjZTBhODBhMSIsImRlbGl2ZXJ5X3N0YXRlIjoiQ0xPU0VEX1VOUkVTT0xWRURfUkVTVUxUX0xPU1MiLCJkaXNwYXRjaF9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOSIsImRpc3BhdGNoX3Nlc3Npb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMTAiLCJlZmZlY3RfYWJzZW5jZV9jbGFpbWVkIjpmYWxzZSwiZXZpZGVuY2Vfc2hhMjU2IjoiNzE0NTJiMTE4ODNhYmNkNjNkOGM3NjEzM2Q0MjYwMTIyOGZhYTFhZmVjZDgyNzliNWVjY2U4NjYxOGQ0ZWIyMyIsImV4ZWN1dGlvbl9hdXRob3JpdHlfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDgiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NpZ25lcl9zaGEyNTYiOiIyNGY2ZWQ2YWNiZmUxMDA5YzAzMGQ3Y2E1NjdjMzNjYTQ4MzA5MTE0OTgyMzZiNTU2MWE2YzgyYWJlYzVkZTI4IiwiZmxvd19ydW5faWRfc2hhMjU2IjoiMTFlNTk0ZjQ4MTk1OGMxMGUzMDE1ZDBiZjA0NDdhMjJmMDY4YThhNjQ3ZjQ3NWRmMTVjZTJjN2FiNGI4ZjNmMSIsImlkZW1wb3RlbmN5X2tleV9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwibG9zc19jb2RlIjoicmVwb3J0X21pc3NpbmciLCJtYW5hZ2VkX2Rpc3BhdGNoX2JpbmRpbmdfc2hhMjU2Ijoic2hhMjU2OmNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJub3RfcmVjZWl2ZWRfY2xhaW1lZCI6ZmFsc2UsIm9ic2VydmVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMloiLCJwZW5kaW5nX2FjdGlvbl9yZXF1ZXN0X3NoYTI1NiI6bnVsbCwicGVuZGluZ19wZXJtaXRfYXJ0aWZhY3Rfc2hhMjU2IjpudWxsLCJyZXBvcnRfcHJvdmVuYW5jZSI6Im91dGVyX3J1bm5lcl9yZWNvdmVyeSIsInJ1bl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwMSIsInJ1bl9yZXF1ZXN0X3NoYTI1NiI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJydW5fc3RvcmVfaWRlbnRpdHlfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0Lm1hbmFnZWQtcmVzdWx0LWxvc3MvdjEifSwicGVuZGluZ19wZXJtaXRfY291bnQiOjAsInBlcm1pdF9jaGFpbiI6eyJlbnRyaWVzIjpbeyJkZWxpdmVyeV9yZWNlaXB0X2FydGlmYWN0Ijp7InBheWxvYWQiOnsiYXV0aGVudGljYXRlZF9ydW5uZXJfaWRfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsImF1dGhlbnRpY2F0ZWRfc2Vzc2lvbl9pZF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiZGVsaXZlcmVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMVoiLCJleGVjdXRpb25fYXV0aG9yaXR5X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA4Iiwib25lX3VzZV9jbGFpbV9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAxMCIsInBlcm1pdF9hcnRpZmFjdF9zaGEyNTYiOiI5NzJhODJhZjQ1NmRhNTQyYmFjNzg0NjAxODg5NjY4ODkxZDhiN2NjZDI0MjkwNDgxNmIzMjkyZTE1N2U1Mjg5IiwicGVybWl0X2lkIjoicGVybWl0OjEiLCJydW50aW1lX2RlbGl2ZXJ5X3NlcXVlbmNlIjo5LCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXJlY2VpcHQtcGF5bG9hZC92MiJ9LCJwYXlsb2FkX3NoYTI1NiI6IjhhOGY2ZDg4NzUwY2JiNmIzYmQ2NjIwOTNhZDI5ZTJiYzIwYzZhYjY5OTFkNzBlNTg4NjkxYzhiM2FiNjYyYjkiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXJlY2VpcHQtYXJ0aWZhY3QvdjIiLCJzaWduYXR1cmUiOiJBT0txQ2dTMXMwWGEtaXlFOTZWLXlsUHpRY3YydXZPc3V5Z0h6dnUyUnlWN0ZMc0hGX0xWZnF5eDR1MnB1bWxFbDBZazVZdTcwSlZVa3NacGFVcEREdyIsInNpZ25lciI6eyJhbGdvcml0aG0iOiJlZDI1NTE5Iiwia2V5X2lkIjoiZGVsaXZlcnktYXV0aG9yaXR5LWVkMjU1MTktMjRmNmVkNmFjYmZlMTAwOSIsInB1YmxpY19rZXkiOiJLYXk2NFVHOHl2Q3lMaHFVMDAwTHh6WWVVbTBML2hMSWw1UzhreUtXYmRjPSJ9fSwiZGVsaXZlcnlfcmVjZWlwdF9hcnRpZmFjdF9zaGEyNTYiOiJjMDBhMWJhNzAxNWYzY2JlMDVhNzZhZWFiZmY2MTlkNzkzZTczNzVhMzEwZTE5NWZjYmJkMmQyOTQ4ZjJiMjE0IiwicGVybWl0X2FydGlmYWN0Ijp7InBheWxvYWQiOnsiYWN0aW9uX3JlcXVlc3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYXV0aG9yaXR5X3NlcXVlbmNlIjowLCJlbnZpcm9ubWVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXZpZGVuY2VfaWRlbnRpdHlfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImV4ZWN1dGlvbl9hdXRob3JpdHlfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDgiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJmbG93X3J1bl9pZF9zaGEyNTYiOiIxMWU1OTRmNDgxOTU4YzEwZTMwMTVkMGJmMDQ0N2EyMmYwNjhhOGE2NDdmNDc1ZGYxNWNlMmM3YWI0YjhmM2YxIiwiaW5wdXRfZWRnZV9zZXF1ZW5jZSI6MSwiaXNzdWVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMFoiLCJwZXJtaXRfaWQiOiJwZXJtaXQ6MSIsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X2NoZWNrZWRfYXQiOiIyMDI2LTA4LTE4VDExOjU5OjMwWiIsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X2V4cGlyZXNfYXQiOiIyMDI2LTA4LTIwVDExOjAwOjAwWiIsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X3JldmlzaW9uIjo3LCJxdWFsaWZpY2F0aW9uX3NpZ25lcl9yZWdpc3RyeV9zaGEyNTYiOiJlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlIiwicnVuX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAxIiwicnVuX3JlcXVlc3Rfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcGVybWl0LXBheWxvYWQvdjIifSwicGF5bG9hZF9zaGEyNTYiOiJjODdmNTc1MWFhOWIyNzljY2UyM2FhMTc4YWZmOTU2ZTE5ZjY5MGZjZDJmOWY3MGUwZDk5OTc4MmE2OTBkNmI4Iiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1wZXJtaXQtYXJ0aWZhY3QvdjIiLCJzaWduYXR1cmUiOiIwQnlIZ3FEeFFacm5nTElGLTZ0Wk9xOWxYYW1jQVFDMGRvVVRuZUtOUGVTLVN5b09iUXlPa0F1UEZLNVBZY056T2JaeGdzZ0FMZFdhSV9zYVVDcGxCZyIsInNpZ25lciI6eyJhbGdvcml0aG0iOiJlZDI1NTE5Iiwia2V5X2lkIjoiZGVsaXZlcnktYXV0aG9yaXR5LWVkMjU1MTktMjRmNmVkNmFjYmZlMTAwOSIsInB1YmxpY19rZXkiOiJLYXk2NFVHOHl2Q3lMaHFVMDAwTHh6WWVVbTBML2hMSWw1UzhreUtXYmRjPSJ9fSwicGVybWl0X2FydGlmYWN0X3NoYTI1NiI6Ijk3MmE4MmFmNDU2ZGE1NDJiYWM3ODQ2MDE4ODk2Njg4OTFkOGI3Y2NkMjQyOTA0ODE2YjMyOTJlMTU3ZTUyODkiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXBlcm1pdC1jaGFpbi1lbnRyeS92MiJ9XSwicGVybWl0X2NoYWluX3NoYTI1NiI6IjUwNDhmZTk0NTg4MmQyODAyNjAwOGQ3ZTkxMzdhZDAxNmZkZDAxYWVhZjU4ODQ4MWZiNWJkMGYyNDJhNTAwNDMiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXBlcm1pdC1jaGFpbi92MiJ9LCJwZXJtaXRfY291bnQiOjEsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X3JldmlzaW9uIjo3LCJxdWFsaWZpY2F0aW9uX3NpZ25lcl9yZWdpc3RyeV9zaGEyNTYiOiJlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlIiwicnVuX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAxIiwicnVuX3JlY2VpcHQiOnsiYXV0aG9yaXphdGlvbl9jb25maXJtZWQiOjEsImF1dGhvcml6YXRpb25fcmVxdWlyZWQiOjEsImJ1bmRsZV9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZHVyYXRpb25fbXMiOjAsImVmZmVjdF90aWVyX3JlYWNoZWQiOiJub25lIiwiZWZmZWN0c19jb25maXJtZWQiOjAsImVmZmVjdHNfcmVxdWlyZWQiOjAsImVzdF9jb3N0X21pY3JvdXNkIjowLCJldmlkZW5jZV9jbGFzc2VzIjpbImF1dGhvcml6YXRpb24iXSwiZXh0ZXJuYWxfbmV0d29ya19jYWxscyI6Im5vbmUiLCJnZW5lcmF0ZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAwWiIsImhlYWxzIjowLCJpZGVudGl0eV9hcHBsaWNhYmxlIjowLCJpZGVudGl0eV9hcm1lZCI6MCwiaWRlbnRpdHlfY29uZmlybWVkIjowLCJpZGVudGl0eV9yZXF1aXJlZCI6MCwibWFuYWdlZF9yZXN1bHRfbG9zc19ldmlkZW5jZV9zaGEyNTYiOiI3MTQ1MmIxMTg4M2FiY2Q2M2Q4Yzc2MTMzZDQyNjAxMjI4ZmFhMWFmZWNkODI3OWI1ZWNjZTg2NjE4ZDRlYjIzIiwibW9kZWxfY2FsbHMiOjAsIm91dGNvbWUiOiJIQUxURUQiLCJvdmVyX2hhbHRfY291bnQiOjAsInBvc3Rjb25kaXRpb25zX2NvbmZpcm1lZCI6MCwicG9zdGNvbmRpdGlvbnNfcmVxdWlyZWQiOjAsInByb2R1Y3Rpb25fZWxpZ2libGUiOmZhbHNlLCJwcm9maWxlIjoic3RhbmRhcmQiLCJwcm92ZW5hbmNlIjoicHJvZHVjdGlvbiIsInJlY2VpcHRfYnVpbGRlcl92ZXJzaW9uIjoiMS4yLjMiLCJydW5nX2hpc3RvZ3JhbSI6e30sInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tcnVuLXJlY2VpcHQvdjEiLCJzb3VyY2VfcmVjZWlwdF9kaWdlc3QiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwic291cmNlX3JlY2VpcHRfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsInNvdXJjZV9zY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5ydW4tcmVwb3J0L3YxIiwic3RlcHNfb2siOjAsInN0ZXBzX3RvdGFsIjoxLCJzdWJzdHJhdGUiOiJ3ZWIiLCJ0cmFuc2FjdGlvbl9vdXRjb21lIjoiUkVDT05DSUxJQVRJT05fUkVRVUlSRUQifSwicnVuX3JlY2VpcHRfc2hhMjU2IjoiNDhiZDFkNmRjOTVkYmNhOTlhMTM4ZDE2ZjIzMmNkNjkxMDI1ZThhNGUxM2E0OGFlYTA4ZTI4NmRkMjA2NzlhNSIsInJ1bl9yZXBvcnRfb2JqZWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJydW5fcmVwb3J0X29iamVjdF92ZXJzaW9uIjoidmVyc2lvbjptYW5hZ2VkLXJlc3VsdC1sb3NzOjEiLCJydW5fcmVwb3J0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJydW50aW1lX2Vudmlyb25tZW50X3NoYTI1NiI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJydW50aW1lX3N1YnN0cmF0ZSI6IndlYiIsInJ1bnRpbWVfdmFsaWRhdGlvbl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwNSIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tdGVybWluYWwtdmVyaWZpY2F0aW9uL3YyIiwidGVuYW50X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAyIiwidGVybWluYWxfc2VxdWVuY2UiOjEsInZlcmlmaWVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMloiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwid29ya2Zsb3dfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDMiLCJ3b3JrZmxvd192ZXJzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA0In0sInNpZ25hdHVyZSI6ImM2OFVFYUdXejVfb2tRMDN2cGZjWGJOS1poWEE1Y2FfV3dpaTBPeGdhVGI3RzJXc1FFZGVjZGI0Z0tqVDIzck5FRGtBRTFaQzRBb1ZpTUdXcFRlaERRIiwic2lnbmVyIjp7ImFsZ29yaXRobSI6ImVkMjU1MTkiLCJrZXlfaWQiOiJldmlkZW5jZS1ydW5uZXItZWQyNTUxOS01NjQ3NWFhNzU0NjM0NzRjIiwicHVibGljX2tleSI6IkE2RUh2L1BPRUw0ZGNOMFk1MHZBbVdmazFqQ2JwUTFmSGR5R1pCSlZNYmc9In19", + "envelope_canonical_base64": "eyJwYXlsb2FkIjp7ImFja25vd2xlZGdlZF9wZXJtaXRfY291bnQiOjEsImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA2IiwiYWRtaXNzaW9uX3BvbGljeV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYWRtaXR0ZWRfcnVudGltZV9idWlsZF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiYnVuZGxlX2FydGlmYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJidW5kbGVfY29udGVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYnVuZGxlX3ZlcnNpb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDQiLCJkZWxpdmVyeV9yZXN1bHRfbG9zc19jbG9zdXJlIjp7InBheWxvYWQiOnsiYWNrbm93bGVkZ2VkX3Blcm1pdF9jb3VudCI6MSwiYWN0dWF0aW9uX3JlcGxheV9hdXRob3JpemVkIjpmYWxzZSwiYXV0aGVudGljYXRlZF9ydW5uZXJfaWRfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsImF1dGhlbnRpY2F0ZWRfc2Vzc2lvbl9pZF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiYmxpbmRfcmV0cnlfYXV0aG9yaXplZCI6ZmFsc2UsImNoaWxkX3N0YXJ0X2V2aWRlbmNlX3NoYTI1NiI6ImVjNjkwNzkxODg2YWUyY2UwMGM0ZTUxMTU0YzNmMTIwZWE0NDE5ZWQyNjUxZTA3M2RiNTcyNDkxOGEzYjA4YzYiLCJjaGlsZF9zdGFydGVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMFoiLCJjbG9zZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAyWiIsImNsb3N1cmVfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMTEiLCJjbG9zdXJlX3JlcXVlc3Rfc2hhMjU2IjoiZDkzMGFiMWFiYzJiMmEwNGI4NDhiOTU1ZmZkZmZmYTFmYmUwNjU1YTU1MzI1ZTA0ODlhZTExZWQ4NDIwMjI2MCIsImNsb3N1cmVfc2VxdWVuY2UiOjEsImRlbGl2ZXJ5X2Fja25vd2xlZGdtZW50X2F1dGhvcml6ZWQiOmZhbHNlLCJkZWxpdmVyeV9zdGF0ZSI6IkNMT1NFRF9VTlJFU09MVkVEX1JFU1VMVF9MT1NTIiwiZGlzcGF0Y2hfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDkiLCJkaXNwYXRjaF9zZXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDEwIiwiZWZmZWN0X2Fic2VuY2VfY2xhaW1lZCI6ZmFsc2UsImV4ZWN1dGlvbl9hdXRob3JpdHlfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDgiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NpZ25lcl9zaGEyNTYiOiIyNGY2ZWQ2YWNiZmUxMDA5YzAzMGQ3Y2E1NjdjMzNjYTQ4MzA5MTE0OTgyMzZiNTU2MWE2YzgyYWJlYzVkZTI4IiwiZmluYWxfYXV0aG9yaXR5X3NlcXVlbmNlIjowLCJmaW5hbF9pbnB1dF9lZGdlX3NlcXVlbmNlIjoxLCJmaW5hbF9ydW50aW1lX2RlbGl2ZXJ5X3NlcXVlbmNlIjo5LCJmbG93X3J1bl9pZF9zaGEyNTYiOiIxMWU1OTRmNDgxOTU4YzEwZTMwMTVkMGJmMDQ0N2EyMmYwNjhhOGE2NDdmNDc1ZGYxNWNlMmM3YWI0YjhmM2YxIiwiaWRlbXBvdGVuY3lfa2V5X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJtYW5hZ2VkX2Rpc3BhdGNoX2JpbmRpbmdfc2hhMjU2Ijoic2hhMjU2OmNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJuZXdfcGVybWl0X2F1dGhvcml6ZWQiOmZhbHNlLCJub3RfcmVjZWl2ZWRfY2xhaW1lZCI6ZmFsc2UsInBlbmRpbmdfYWN0aW9uX3JlcXVlc3Rfc2hhMjU2IjpudWxsLCJwZW5kaW5nX3Blcm1pdF9hcnRpZmFjdF9zaGEyNTYiOm51bGwsInBlbmRpbmdfcGVybWl0X2NvdW50IjowLCJwZXJtaXRfY2hhaW5fc2hhMjU2IjoiNTA0OGZlOTQ1ODgyZDI4MDI2MDA4ZDdlOTEzN2FkMDE2ZmRkMDFhZWFmNTg4NDgxZmI1YmQwZjI0MmE1MDA0MyIsInBlcm1pdF9jb3VudCI6MSwicmVjZWlwdF9hYnNlbmNlX29ic2VydmVkX2F0IjpudWxsLCJyZXN1bHRfbG9zc19vYnNlcnZlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDJaIiwicnVuX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAxIiwicnVuX3JlcXVlc3Rfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsInJ1bl9zdG9yZV9pZGVudGl0eV9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1yZXN1bHQtbG9zcy1jbG9zdXJlLXBheWxvYWQvdjIiLCJ0ZW5hbnRfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDIiLCJ0ZXJtaW5hbF9jYWxsYmFja19yZXF1aXJlZCI6dHJ1ZX0sInBheWxvYWRfc2hhMjU2IjoiNmI3NWY4YjQ1YTdkM2U5Y2ZlODU2NGZmZTMyZjI5YzJiNTk3YzI4MTM2YTk3YTRmNTQ1M2ZlMmFmZDE3MjhhYSIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcmVzdWx0LWxvc3MtY2xvc3VyZS1hcnRpZmFjdC92MiIsInNpZ25hdHVyZSI6Imt6dVIycXJjR1Q0cG82LXl6ZFlEZ2gzd2FZamI5V3BRR1VfQm5RTEhUSWJkZDV4QmxyVVNsNkg0Y2VWQzMzcjFCd2JGdFJQYVB2bzA1cGd4Z0U0d0F3Iiwic2lnbmVyIjp7ImFsZ29yaXRobSI6ImVkMjU1MTkiLCJrZXlfaWQiOiJkZWxpdmVyeS1hdXRob3JpdHktZWQyNTUxOS0yNGY2ZWQ2YWNiZmUxMDA5IiwicHVibGljX2tleSI6IktheTY0VUc4eXZDeUxocVUwMDBMeHpZZVVtMEwvaExJbDVTOGt5S1diZGM9In19LCJlZmZlY3RfY29udHJhY3Rfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImVudmlyb25tZW50X2NvbnRyYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJlbnZpcm9ubWVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXZpZGVuY2VfaWRlbnRpdHlfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImV2aWRlbmNlX21hbmlmZXN0cyI6eyJhdXRob3JpemF0aW9uIjp7ImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA2IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOCIsImV4ZWN1dGlvbl9hdXRob3JpdHlfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImdvdmVybmVkX2F1dGhvcml6YXRpb25faWRfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsIm1hbmlmZXN0X3NoYTI1NiI6ImYwY2ExOWE2YjNlYWJlNTk0ZGJjOTA2ODljMmY3NGNiZTVlODJkNGQ5NDdkYjI5YTVkMDdiMTY0MWU4OTYxY2YiLCJwZXJtaXRfY2hhaW5fc2hhMjU2IjoiNTA0OGZlOTQ1ODgyZDI4MDI2MDA4ZDdlOTEzN2FkMDE2ZmRkMDFhZWFmNTg4NDgxZmI1YmQwZjI0MmE1MDA0MyIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tYXV0aG9yaXphdGlvbi1ldmlkZW5jZS92MSJ9LCJlZmZlY3QiOnsiY29uZmlybWVkIjowLCJlZmZlY3RfY29udHJhY3Rfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsIm1hbmlmZXN0X3NoYTI1NiI6IjdlMTJkY2E1YzQ0Y2Y5OThhNDY5MzYyYjg2MmU4MTZhN2QyYzg1NDE2M2Y2M2U4ZGU2MWZiNzllOTViYTgwMDciLCJyZWNvcmRzIjpbXSwicmVxdWlyZWQiOjAsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZWZmZWN0LWV2aWRlbmNlL3YxIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSJ9LCJpZGVudGl0eSI6eyJjb25maXJtZWQiOjAsImlkZW50aXR5X2NvbnRyYWN0X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJtYW5pZmVzdF9zaGEyNTYiOiJkM2E3ZWFjMzQyN2Q3NmY2YmMzNjAzMDczODYwOTExOWYwN2UwZDkxYTZkMzU4YWJjZTViNmYwZDZkZjc4NjQ1IiwicmVxdWlyZWQiOjAsInJlc3VsdHMiOltdLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWlkZW50aXR5LWV2aWRlbmNlL3YxIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSJ9LCJwb2xpY3kiOnsiYWRtaXNzaW9uX3BvbGljeV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZWZmZWN0X2NvbnRyYWN0X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJlbnZpcm9ubWVudF9jb250cmFjdF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwiZW52aXJvbm1lbnRfZGlnZXN0IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImdvdmVybmVkX3BvbGljeV9jb250cmFjdF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwiZ292ZXJuZWRfcnVudGltZV9pbnB1dHNfZGlnZXN0IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsImlkZW50aXR5X2NvbnRyYWN0X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJtYW5pZmVzdF9zaGEyNTYiOiI0Zjk4OGQwMTViY2Q3Y2Q3ZTA1YmEwNjYzZDg5ZjBhOTY4ZjBkOGFjZTk5YjA5MGViYWJlZTUyYTFjNTUwNDIxIiwibWluaW11bV9lZmZlY3RfdGllciI6MSwicnVudGltZV9lbnZpcm9ubWVudF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1wb2xpY3ktZXZpZGVuY2UvdjEifSwicG9zdGNvbmRpdGlvbiI6eyJjb25maXJtZWQiOjAsIm1hbmlmZXN0X3NoYTI1NiI6IjUyZjA5ZDVkNjM5YjFjMzgzZjM3Nzk2M2U0ODdjYjg5ZDg5NDE3ODU3ZTQ0ZGE3ZTNmMjNlNTViZTc1MWU3ZjQiLCJyZWNvcmRzIjpbXSwicmVxdWlyZWQiOjAsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tcG9zdGNvbmRpdGlvbi1ldmlkZW5jZS92MSIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifX0sImV2aWRlbmNlX3J1bm5lcl9zaWduZXJfc2hhMjU2IjoiNTY0NzVhYTc1NDYzNDc0YzAyODVkZjVkYmYyYmNhYjczZGE2NTEzNTg4MzllOWI3NzQ4MWIyZWFiMTA3NzA4YyIsImV4ZWN1dGlvbl9hdXRob3JpdHlfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDgiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NpZ25lcl9zaGEyNTYiOiIyNGY2ZWQ2YWNiZmUxMDA5YzAzMGQ3Y2E1NjdjMzNjYTQ4MzA5MTE0OTgyMzZiNTU2MWE2YzgyYWJlYzVkZTI4IiwiZXhlY3V0aW9uX291dGNvbWUiOnsiY29tcGVuc2F0aW9uX2FjdGlvbnMiOjAsImV2aWRlbmNlX2NsYXNzZXMiOlsiYXV0aG9yaXphdGlvbiJdLCJleGVjdXRpb25fY29tcGxldGVkIjpmYWxzZSwiZXh0ZXJuYWxfbmV0d29ya19jYWxscyI6Im5vbmUiLCJtYW5hZ2VkX3Jlc3VsdF9sb3NzX2V2aWRlbmNlX3NoYTI1NiI6ImYyMmYyNzA0NGVmMzE1ZTkzOWFiYWRmNmI2NzI1ZmNmMmI5MmYyYTI4MDM5NDA3NTgwZTBmMmY3ZTIzMDU0OTQiLCJtb2RlbF9jYWxscyI6MCwib3V0Y29tZSI6IkhBTFRFRCIsInBhc3NlZF9jb250cmFjdHMiOnsiYXV0aG9yaXphdGlvbiI6MSwiZWZmZWN0IjowLCJpZGVudGl0eSI6MCwicG9zdGNvbmRpdGlvbiI6MH0sInBvc3Rjb25kaXRpb25fZXZpZGVuY2UiOltdLCJwcm9kdWN0aW9uX2VsaWdpYmxlIjpmYWxzZSwicHJvZmlsZSI6InN0YW5kYXJkIiwicXVhbGlmaWNhdGlvbl9ldmlkZW5jZV9vbmx5IjpmYWxzZSwicmVxdWlyZWRfY29udHJhY3RzIjp7ImF1dGhvcml6YXRpb24iOjEsImVmZmVjdCI6MCwiaWRlbnRpdHkiOjAsInBvc3Rjb25kaXRpb24iOjB9LCJ2ZXJzaW9uIjoib3BlbmFkYXB0LmV4ZWN1dGlvbi1vdXRjb21lL3YxIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSJ9LCJleGVjdXRpb25fb3V0Y29tZV9zaGEyNTYiOiJhOTUxNjFlYjFmOGZjMzBmYjk0ZGNiNzdjZDIzYzc2MjdlM2NhY2EzODBhZmEzNGU0MTE3YzI2NGNmYzhiMmYzIiwiZXhlY3V0aW9uX3B1cnBvc2UiOiJwcm9kdWN0aW9uIiwiZmluYWxfYXV0aG9yaXR5X3NlcXVlbmNlIjowLCJmaW5hbF9ydW50aW1lX2RlbGl2ZXJ5X3NlcXVlbmNlIjo5LCJmbG93X3J1bl9pZF9zaGEyNTYiOiIxMWU1OTRmNDgxOTU4YzEwZTMwMTVkMGJmMDQ0N2EyMmYwNjhhOGE2NDdmNDc1ZGYxNWNlMmM3YWI0YjhmM2YxIiwiaWRlbnRpdHlfY29udHJhY3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsImlzc3VlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDNaIiwibWFuYWdlZF9yZXN1bHRfbG9zcyI6eyJhY3R1YXRpb25fcmVwbGF5X2F1dGhvcml6ZWQiOmZhbHNlLCJhdXRoZW50aWNhdGVkX3J1bm5lcl9pZF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwiYXV0aGVudGljYXRlZF9zZXNzaW9uX2lkX3NoYTI1NiI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJibGluZF9yZXRyeV9hdXRob3JpemVkIjpmYWxzZSwiY2hpbGRfcmVwb3J0X3JldGFpbmVkIjpmYWxzZSwiY2hpbGRfc3RhcnRfZXZpZGVuY2Vfc2hhMjU2IjoiZWM2OTA3OTE4ODZhZTJjZTAwYzRlNTExNTRjM2YxMjBlYTQ0MTllZDI2NTFlMDczZGI1NzI0OTE4YTNiMDhjNiIsImNoaWxkX3N0YXJ0ZWQiOnRydWUsImNoaWxkX3N0YXJ0ZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAwWiIsImRlbGl2ZXJ5X3Jlc3VsdF9sb3NzX2Nsb3N1cmVfYXJ0aWZhY3Rfc2hhMjU2IjoiYjJkOTJmMzI0OGY0ZGE2MWVkYjAyN2NmNTlkYTUzOTVmZmM0MThlYWQ2ZDQ4NWMyOWRmNmMzNWJjMjFhOTMwZCIsImRlbGl2ZXJ5X3N0YXRlIjoiQ0xPU0VEX1VOUkVTT0xWRURfUkVTVUxUX0xPU1MiLCJkaXNwYXRjaF9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOSIsImRpc3BhdGNoX3Nlc3Npb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMTAiLCJlZmZlY3RfYWJzZW5jZV9jbGFpbWVkIjpmYWxzZSwiZXZpZGVuY2Vfc2hhMjU2IjoiZjIyZjI3MDQ0ZWYzMTVlOTM5YWJhZGY2YjY3MjVmY2YyYjkyZjJhMjgwMzk0MDc1ODBlMGYyZjdlMjMwNTQ5NCIsImV4ZWN1dGlvbl9hdXRob3JpdHlfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDgiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NpZ25lcl9zaGEyNTYiOiIyNGY2ZWQ2YWNiZmUxMDA5YzAzMGQ3Y2E1NjdjMzNjYTQ4MzA5MTE0OTgyMzZiNTU2MWE2YzgyYWJlYzVkZTI4IiwiZmxvd19ydW5faWRfc2hhMjU2IjoiMTFlNTk0ZjQ4MTk1OGMxMGUzMDE1ZDBiZjA0NDdhMjJmMDY4YThhNjQ3ZjQ3NWRmMTVjZTJjN2FiNGI4ZjNmMSIsImlkZW1wb3RlbmN5X2tleV9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwibG9zc19jb2RlIjoicmVwb3J0X21pc3NpbmciLCJtYW5hZ2VkX2Rpc3BhdGNoX2JpbmRpbmdfc2hhMjU2Ijoic2hhMjU2OmNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJub3RfcmVjZWl2ZWRfY2xhaW1lZCI6ZmFsc2UsIm9ic2VydmVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMloiLCJwZW5kaW5nX2FjdGlvbl9yZXF1ZXN0X3NoYTI1NiI6bnVsbCwicGVuZGluZ19wZXJtaXRfYXJ0aWZhY3Rfc2hhMjU2IjpudWxsLCJyZXBvcnRfcHJvdmVuYW5jZSI6Im91dGVyX3J1bm5lcl9yZWNvdmVyeSIsInJ1bl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwMSIsInJ1bl9yZXF1ZXN0X3NoYTI1NiI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJydW5fc3RvcmVfaWRlbnRpdHlfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0Lm1hbmFnZWQtcmVzdWx0LWxvc3MvdjEifSwicGVuZGluZ19wZXJtaXRfY291bnQiOjAsInBlcm1pdF9jaGFpbiI6eyJlbnRyaWVzIjpbeyJkZWxpdmVyeV9yZWNlaXB0X2FydGlmYWN0Ijp7InBheWxvYWQiOnsiYXV0aGVudGljYXRlZF9ydW5uZXJfaWRfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsImF1dGhlbnRpY2F0ZWRfc2Vzc2lvbl9pZF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiZGVsaXZlcmVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMVoiLCJleGVjdXRpb25fYXV0aG9yaXR5X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA4Iiwib25lX3VzZV9jbGFpbV9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAxMCIsInBlcm1pdF9hcnRpZmFjdF9zaGEyNTYiOiI5NzJhODJhZjQ1NmRhNTQyYmFjNzg0NjAxODg5NjY4ODkxZDhiN2NjZDI0MjkwNDgxNmIzMjkyZTE1N2U1Mjg5IiwicGVybWl0X2lkIjoicGVybWl0OjEiLCJydW50aW1lX2RlbGl2ZXJ5X3NlcXVlbmNlIjo5LCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXJlY2VpcHQtcGF5bG9hZC92MiJ9LCJwYXlsb2FkX3NoYTI1NiI6IjhhOGY2ZDg4NzUwY2JiNmIzYmQ2NjIwOTNhZDI5ZTJiYzIwYzZhYjY5OTFkNzBlNTg4NjkxYzhiM2FiNjYyYjkiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXJlY2VpcHQtYXJ0aWZhY3QvdjIiLCJzaWduYXR1cmUiOiJBT0txQ2dTMXMwWGEtaXlFOTZWLXlsUHpRY3YydXZPc3V5Z0h6dnUyUnlWN0ZMc0hGX0xWZnF5eDR1MnB1bWxFbDBZazVZdTcwSlZVa3NacGFVcEREdyIsInNpZ25lciI6eyJhbGdvcml0aG0iOiJlZDI1NTE5Iiwia2V5X2lkIjoiZGVsaXZlcnktYXV0aG9yaXR5LWVkMjU1MTktMjRmNmVkNmFjYmZlMTAwOSIsInB1YmxpY19rZXkiOiJLYXk2NFVHOHl2Q3lMaHFVMDAwTHh6WWVVbTBML2hMSWw1UzhreUtXYmRjPSJ9fSwiZGVsaXZlcnlfcmVjZWlwdF9hcnRpZmFjdF9zaGEyNTYiOiJjMDBhMWJhNzAxNWYzY2JlMDVhNzZhZWFiZmY2MTlkNzkzZTczNzVhMzEwZTE5NWZjYmJkMmQyOTQ4ZjJiMjE0IiwicGVybWl0X2FydGlmYWN0Ijp7InBheWxvYWQiOnsiYWN0aW9uX3JlcXVlc3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYXV0aG9yaXR5X3NlcXVlbmNlIjowLCJlbnZpcm9ubWVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXZpZGVuY2VfaWRlbnRpdHlfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImV4ZWN1dGlvbl9hdXRob3JpdHlfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDgiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJmbG93X3J1bl9pZF9zaGEyNTYiOiIxMWU1OTRmNDgxOTU4YzEwZTMwMTVkMGJmMDQ0N2EyMmYwNjhhOGE2NDdmNDc1ZGYxNWNlMmM3YWI0YjhmM2YxIiwiaW5wdXRfZWRnZV9zZXF1ZW5jZSI6MSwiaXNzdWVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMFoiLCJwZXJtaXRfaWQiOiJwZXJtaXQ6MSIsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X2NoZWNrZWRfYXQiOiIyMDI2LTA4LTE4VDExOjU5OjMwWiIsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X2V4cGlyZXNfYXQiOiIyMDI2LTA4LTIwVDExOjAwOjAwWiIsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X3JldmlzaW9uIjo3LCJxdWFsaWZpY2F0aW9uX3NpZ25lcl9yZWdpc3RyeV9zaGEyNTYiOiJlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlIiwicnVuX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAxIiwicnVuX3JlcXVlc3Rfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcGVybWl0LXBheWxvYWQvdjIifSwicGF5bG9hZF9zaGEyNTYiOiJjODdmNTc1MWFhOWIyNzljY2UyM2FhMTc4YWZmOTU2ZTE5ZjY5MGZjZDJmOWY3MGUwZDk5OTc4MmE2OTBkNmI4Iiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1wZXJtaXQtYXJ0aWZhY3QvdjIiLCJzaWduYXR1cmUiOiIwQnlIZ3FEeFFacm5nTElGLTZ0Wk9xOWxYYW1jQVFDMGRvVVRuZUtOUGVTLVN5b09iUXlPa0F1UEZLNVBZY056T2JaeGdzZ0FMZFdhSV9zYVVDcGxCZyIsInNpZ25lciI6eyJhbGdvcml0aG0iOiJlZDI1NTE5Iiwia2V5X2lkIjoiZGVsaXZlcnktYXV0aG9yaXR5LWVkMjU1MTktMjRmNmVkNmFjYmZlMTAwOSIsInB1YmxpY19rZXkiOiJLYXk2NFVHOHl2Q3lMaHFVMDAwTHh6WWVVbTBML2hMSWw1UzhreUtXYmRjPSJ9fSwicGVybWl0X2FydGlmYWN0X3NoYTI1NiI6Ijk3MmE4MmFmNDU2ZGE1NDJiYWM3ODQ2MDE4ODk2Njg4OTFkOGI3Y2NkMjQyOTA0ODE2YjMyOTJlMTU3ZTUyODkiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXBlcm1pdC1jaGFpbi1lbnRyeS92MiJ9XSwicGVybWl0X2NoYWluX3NoYTI1NiI6IjUwNDhmZTk0NTg4MmQyODAyNjAwOGQ3ZTkxMzdhZDAxNmZkZDAxYWVhZjU4ODQ4MWZiNWJkMGYyNDJhNTAwNDMiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXBlcm1pdC1jaGFpbi92MiJ9LCJwZXJtaXRfY291bnQiOjEsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X3JldmlzaW9uIjo3LCJxdWFsaWZpY2F0aW9uX3NpZ25lcl9yZWdpc3RyeV9zaGEyNTYiOiJlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlIiwicnVuX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAxIiwicnVuX3JlY2VpcHQiOnsiYXV0aG9yaXphdGlvbl9jb25maXJtZWQiOjEsImF1dGhvcml6YXRpb25fcmVxdWlyZWQiOjEsImJ1bmRsZV9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZHVyYXRpb25fbXMiOjAsImVmZmVjdF90aWVyX3JlYWNoZWQiOiJub25lIiwiZWZmZWN0c19jb25maXJtZWQiOjAsImVmZmVjdHNfcmVxdWlyZWQiOjAsImVzdF9jb3N0X21pY3JvdXNkIjowLCJldmlkZW5jZV9jbGFzc2VzIjpbImF1dGhvcml6YXRpb24iXSwiZXh0ZXJuYWxfbmV0d29ya19jYWxscyI6Im5vbmUiLCJnZW5lcmF0ZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAwWiIsImhlYWxzIjowLCJpZGVudGl0eV9hcHBsaWNhYmxlIjowLCJpZGVudGl0eV9hcm1lZCI6MCwiaWRlbnRpdHlfY29uZmlybWVkIjowLCJpZGVudGl0eV9yZXF1aXJlZCI6MCwibWFuYWdlZF9yZXN1bHRfbG9zc19ldmlkZW5jZV9zaGEyNTYiOiJmMjJmMjcwNDRlZjMxNWU5MzlhYmFkZjZiNjcyNWZjZjJiOTJmMmEyODAzOTQwNzU4MGUwZjJmN2UyMzA1NDk0IiwibW9kZWxfY2FsbHMiOjAsIm91dGNvbWUiOiJIQUxURUQiLCJvdmVyX2hhbHRfY291bnQiOjAsInBvc3Rjb25kaXRpb25zX2NvbmZpcm1lZCI6MCwicG9zdGNvbmRpdGlvbnNfcmVxdWlyZWQiOjAsInByb2R1Y3Rpb25fZWxpZ2libGUiOmZhbHNlLCJwcm9maWxlIjoic3RhbmRhcmQiLCJwcm92ZW5hbmNlIjoicHJvZHVjdGlvbiIsInJlY2VpcHRfYnVpbGRlcl92ZXJzaW9uIjoiMS4yLjMiLCJydW5nX2hpc3RvZ3JhbSI6e30sInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tcnVuLXJlY2VpcHQvdjEiLCJzb3VyY2VfcmVjZWlwdF9kaWdlc3QiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwic291cmNlX3JlY2VpcHRfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsInNvdXJjZV9zY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5ydW4tcmVwb3J0L3YxIiwic3RlcHNfb2siOjAsInN0ZXBzX3RvdGFsIjoxLCJzdWJzdHJhdGUiOiJ3ZWIiLCJ0cmFuc2FjdGlvbl9vdXRjb21lIjoiUkVDT05DSUxJQVRJT05fUkVRVUlSRUQifSwicnVuX3JlY2VpcHRfc2hhMjU2IjoiMzI5NzEzZDkwZTA1YjBmNTVlNmFhNTM2NWJmZThiMzA2NGY1ZTQ3OTBlMWNkYmRjOThlMzYyM2Y4N2NlYzVjYyIsInJ1bl9yZXBvcnRfb2JqZWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJydW5fcmVwb3J0X29iamVjdF92ZXJzaW9uIjoidmVyc2lvbjptYW5hZ2VkLXJlc3VsdC1sb3NzOjEiLCJydW5fcmVwb3J0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJydW50aW1lX2Vudmlyb25tZW50X3NoYTI1NiI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJydW50aW1lX3N1YnN0cmF0ZSI6IndlYiIsInJ1bnRpbWVfdmFsaWRhdGlvbl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwNSIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tdGVybWluYWwtdmVyaWZpY2F0aW9uL3YyIiwidGVuYW50X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAyIiwidGVybWluYWxfc2VxdWVuY2UiOjEsInZlcmlmaWVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMloiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwid29ya2Zsb3dfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDMiLCJ3b3JrZmxvd192ZXJzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA0In0sInNpZ25hdHVyZSI6IlgwcWtfTkJXVFVKVk1LQ2NFaFJHcWNJeDRjOTdYd1U2Szg4T0plbHdxc2FpWGVtTV9nRlJ4MHlNYjdPcjhfZUlSNmpMNDNDSVNPMEc0Ums3SWVYNUN3Iiwic2lnbmVyIjp7ImFsZ29yaXRobSI6ImVkMjU1MTkiLCJrZXlfaWQiOiJldmlkZW5jZS1ydW5uZXItZWQyNTUxOS01NjQ3NWFhNzU0NjM0NzRjIiwicHVibGljX2tleSI6IkE2RUh2L1BPRUw0ZGNOMFk1MHZBbVdmazFqQ2JwUTFmSGR5R1pCSlZNYmc9In19", "managed_result_loss": { "actuation_replay_authorized": false, - "authenticated_runner_id_sha256": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "authenticated_session_id_sha256": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "authenticated_runner_id_sha256": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "authenticated_session_id_sha256": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "blind_retry_authorized": false, "child_report_retained": false, - "child_start_evidence_sha256": "65a6bed923e45a6aa0c6243045e0364c90ace0648fecb5b0bb2ebd9402793c77", + "child_start_evidence_sha256": "ec690791886ae2ce00c4e51154c3f120ea4419ed2651e073db5724918a3b08c6", "child_started": true, "child_started_at": "2026-08-18T12:00:00Z", - "delivery_result_loss_closure_artifact_sha256": "90df8bd1f2891b203663a63f4251507445dbe838360a219e43af9a1bce0a80a1", + "delivery_result_loss_closure_artifact_sha256": "b2d92f3248f4da61edb027cf59da5395ffc418ead6d485c29df6c35bc21a930d", "delivery_state": "CLOSED_UNRESOLVED_RESULT_LOSS", "dispatch_id": "00000000-0000-4000-8000-000000000009", "dispatch_session_id": "00000000-0000-4000-8000-000000000010", "effect_absence_claimed": false, - "evidence_sha256": "71452b11883abcd63d8c76133d42601228faa1afecd8279b5ecce86618d4eb23", + "evidence_sha256": "f22f27044ef315e939abadf6b6725fcf2b92f2a28039407580e0f2f7e2305494", "execution_authority_id": "00000000-0000-4000-8000-000000000008", "execution_authority_sha256": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "execution_authority_signer_sha256": "24f6ed6acbfe1009c030d7ca567c33ca4830911498236b5561a6c82abec5de28", @@ -241,9 +241,9 @@ "schema_version": "openadapt.managed-result-loss/v1" }, "name": "reconciliation-required-managed-result-loss-acknowledged", - "payload_canonical_sha256": "f636736f6796ba6246fdd2d6c0668642928ad5990342e801b882b2c22013eae3", - "signature": "c68UEaGWz5_okQ03vpfcXbNKZhXA5ca_Wwii0OxgaTb7G2WsQEdecdb4gKjT23rNEDkAE1ZC4AoViMGWpTehDQ", - "terminal_verification_artifact_sha256": "b78ff44e81d4be51fbb28132c871aab660616a8ec5eba0dcde24e6298c0cd87f" + "payload_canonical_sha256": "c024765711724b2645dbe23c250d301079e9045cc45f54eba72bacab3a22233b", + "signature": "X0qk_NBWTUJVMKCcEhRGqcIx4c97XwU6K88OJelwqsaiXemM_gFRx0yMb7Or8_eIR6jL43CISO0G4Rk7IeX5Cw", + "terminal_verification_artifact_sha256": "1707d4b13e8549cb7b12edae186866006b0211933830384d9fca6e1fc0b54756" } ] } diff --git a/tests/test_terminal_verification_v2.py b/tests/test_terminal_verification_v2.py index ed8195ff..92cc246f 100644 --- a/tests/test_terminal_verification_v2.py +++ b/tests/test_terminal_verification_v2.py @@ -69,6 +69,7 @@ sign_production_delivery_receipt, sign_production_delivery_result_loss_closure, sign_production_terminal_verification, + verify_production_delivery_result_loss_closure_binding, verify_production_terminal_verification, ) from tests.test_run_receipt import _report as _production_report @@ -806,8 +807,8 @@ def _result_loss_request() -> ProductionDeliveryResultLossClosureRequest: dispatch_session_id="00000000-0000-4000-8000-000000000010", run_id=IDS["run_id"], managed_dispatch_binding_sha256="sha256:" + SHA_C, - authenticated_runner_id_sha256=SHA_A, - authenticated_session_id_sha256=SHA_B, + authenticated_runner_id_sha256=SHA_B, + authenticated_session_id_sha256=SHA_C, execution_authority_id=IDS["execution_authority_id"], execution_authority_sha256=SHA_A, execution_authority_signer_sha256=(_permit_entry().authority_signer_sha256), @@ -847,8 +848,12 @@ def _result_loss_closure( dispatch_session_id="00000000-0000-4000-8000-000000000010", managed_dispatch_binding_sha256="sha256:" + SHA_C, idempotency_key_sha256=SHA_D, - authenticated_runner_id_sha256=SHA_A, - authenticated_session_id_sha256=SHA_B, + authenticated_runner_id_sha256=( + request.child_start_evidence.authenticated_runner_id_sha256 + ), + authenticated_session_id_sha256=( + request.child_start_evidence.authenticated_session_id_sha256 + ), execution_authority_id=IDS["execution_authority_id"], execution_authority_sha256=SHA_A, execution_authority_signer_sha256=final.authority_signer_sha256, @@ -900,8 +905,12 @@ def _managed_result_loss_payload( dispatch_session_id="00000000-0000-4000-8000-000000000010", managed_dispatch_binding_sha256="sha256:" + SHA_C, idempotency_key_sha256=SHA_D, - authenticated_runner_id_sha256=SHA_A, - authenticated_session_id_sha256=SHA_B, + authenticated_runner_id_sha256=( + request.child_start_evidence.authenticated_runner_id_sha256 + ), + authenticated_session_id_sha256=( + request.child_start_evidence.authenticated_session_id_sha256 + ), execution_authority_id=IDS["execution_authority_id"], execution_authority_sha256=SHA_A, execution_authority_signer_sha256=final.authority_signer_sha256, @@ -1330,6 +1339,44 @@ def test_terminal_v2_signs_ack_won_managed_result_loss_without_uncertainty() -> assert payload.evidence_manifests.effect.records == () +@pytest.mark.parametrize( + "identity_field", + ["authenticated_runner_id_sha256", "authenticated_session_id_sha256"], +) +def test_ack_won_result_loss_closure_rejects_receipt_identity_mismatch( + identity_field: str, +) -> None: + payload = _managed_result_loss_acknowledged_payload() + closure = payload.delivery_result_loss_closure + loss = payload.managed_result_loss + assert closure is not None + assert loss is not None + mismatched_payload = closure.payload.model_copy(update={identity_field: SHA_E}) + mismatched_closure = sign_production_delivery_result_loss_closure( + mismatched_payload, + _authority_key(), + ) + loss_values = loss.model_dump(mode="json") + loss_values.pop("evidence_sha256") + loss_values[identity_field] = SHA_E + loss_values["delivery_result_loss_closure_artifact_sha256"] = ( + mismatched_closure.artifact_sha256() + ) + mismatched_loss = ManagedResultLossEvidence.create(**loss_values) + + with pytest.raises( + ValueError, + match="authenticated delivery identity", + ): + verify_production_delivery_result_loss_closure_binding( + mismatched_closure, + permit_chain=payload.permit_chain, + result_loss=mismatched_loss, + tenant_id=payload.tenant_id, + terminal_verified_at=payload.verified_at, + ) + + @pytest.mark.parametrize( "field", [ From b7a20ed020df956c30c6febe4625122f7a465f22 Mon Sep 17 00:00:00 2001 From: Richard Abrich Date: Thu, 27 Aug 2026 16:05:32 -0400 Subject: [PATCH 5/7] fix(hosted): fence every managed result loss --- openadapt_flow/ir.py | 1 + openadapt_flow/runner/hosted_adapter.py | 173 ++++++++++++---- openadapt_flow/terminal_verification_v2.py | 2 + public-artifacts.json | 2 +- ...nerate_terminal_verification_v2_vectors.py | 84 ++++---- ...inal_verification_v2_terminal_vectors.json | 31 ++- tests/test_hosted_runner_adapter.py | 193 +++++++++++++++++- tests/test_terminal_verification_v2.py | 105 ++++++---- 8 files changed, 464 insertions(+), 127 deletions(-) diff --git a/openadapt_flow/ir.py b/openadapt_flow/ir.py index 6f337eb1..d5b6d126 100644 --- a/openadapt_flow/ir.py +++ b/openadapt_flow/ir.py @@ -3405,6 +3405,7 @@ class ManagedResultLossEvidence(BaseModel): loss_code: Literal[ "runner_exception", "report_missing", + "report_invalid", "recovered_after_restart", ] child_started_at: str = Field( diff --git a/openadapt_flow/runner/hosted_adapter.py b/openadapt_flow/runner/hosted_adapter.py index 107b70b6..9a0b7e42 100644 --- a/openadapt_flow/runner/hosted_adapter.py +++ b/openadapt_flow/runner/hosted_adapter.py @@ -115,6 +115,12 @@ _RUN_STORE_IDENTITY_DOMAIN = b"OpenAdapt managed run store identity v1\0" _RESULT_LOSS_SNAPSHOT_DOMAIN = b"OpenAdapt managed result loss snapshot v1\0" _MAX_TERMINAL_STATE_BYTES = 2 * (4 * ((_MAX_ARTIFACT_BYTES + 2) // 3)) + 4096 +ManagedResultLossCode = Literal[ + "runner_exception", + "report_missing", + "report_invalid", + "recovered_after_restart", +] # The current runner credential is never part of a request model. Desktop may # project it into this header only for POST /api/runners/register on the exact @@ -1489,29 +1495,17 @@ def _managed_result_loss_report( raise ValueError("managed result loss classification changed") return RunReport.model_validate_json(report.model_dump_json()) - def _produce_managed_result_loss( + def _retain_managed_result_loss_closure( self, *, dispatch: HostedDispatch, - workflow: Workflow, run_dir: Path, - qualification: ProductionQualificationAuthority, - private_key: Ed25519PrivateKey, - verified_params: dict[str, RuntimeParamScalar], dispatch_binding_sha256: str, closure_authority: HostedRunnerTransport, - loss_code: Literal[ - "runner_exception", - "report_missing", - "recovered_after_restart", - ], - ) -> tuple[ProductionTerminalVerificationEnvelope, str, RunReport]: - """Seal one result-loss report without resolving or replaying delivery.""" + loss_code: ManagedResultLossCode, + ) -> ManagedResultLossSnapshot: + """Fence delivery authority before any fallible terminal proof work.""" - store = CheckpointStore(run_dir) - manifest = store.read_manifest() - if manifest is None: - raise ValueError("managed result loss lacks a retained run manifest") marker = self._read_child_start_evidence( dispatch=dispatch, run_dir=run_dir, @@ -1521,11 +1515,7 @@ def _produce_managed_result_loss( def snapshot_from_closure( *, request: ProductionDeliveryResultLossClosureRequest, - retained_loss_code: Literal[ - "runner_exception", - "report_missing", - "recovered_after_restart", - ], + retained_loss_code: ManagedResultLossCode, closure_artifact: ProductionDeliveryResultLossClosureArtifact, retained_chain: ProductionDeliveryPermitChain, ) -> ManagedResultLossSnapshot: @@ -1696,6 +1686,43 @@ def read_retained_snapshot() -> ManagedResultLossSnapshot: snapshot = read_retained_snapshot() else: snapshot = read_retained_snapshot() + return snapshot + + def _produce_managed_result_loss( + self, + *, + dispatch: HostedDispatch, + workflow: Workflow, + run_dir: Path, + qualification: ProductionQualificationAuthority, + private_key: Ed25519PrivateKey, + verified_params: dict[str, RuntimeParamScalar], + dispatch_binding_sha256: str, + loss_code: ManagedResultLossCode, + closure_authority: HostedRunnerTransport | None = None, + snapshot: ManagedResultLossSnapshot | None = None, + ) -> tuple[ProductionTerminalVerificationEnvelope, str, RunReport]: + """Sign one result-loss terminal after Cloud has fenced delivery.""" + + if snapshot is None: + if closure_authority is None: + raise ValueError("hosted result-loss closure authority is absent") + snapshot = self._retain_managed_result_loss_closure( + dispatch=dispatch, + run_dir=run_dir, + dispatch_binding_sha256=dispatch_binding_sha256, + closure_authority=closure_authority, + loss_code=loss_code, + ) + store = CheckpointStore(run_dir) + manifest = store.read_manifest() + if manifest is None: + raise ValueError("managed result loss lacks a retained run manifest") + marker = self._read_child_start_evidence( + dispatch=dispatch, + run_dir=run_dir, + dispatch_binding_sha256=dispatch_binding_sha256, + ) evidence = snapshot.evidence observed_at = evidence.observed_at expected = qualification.expected @@ -2432,16 +2459,6 @@ def recover_uncertain_run( """ parsed = HostedDispatch.model_validate(dispatch) - config = load_runner_config(runner_config, protected=True) - self._protected_runner_origin(config) - self._verify_product_release(parsed, config) - key = self._load_evidence_private_key(config) - qualification, deployment_bytes = self._verify_workflow_admission( - parsed, - config, - evidence_private_key=key, - ) - params = self._resolve_params(parsed, config) run_dir = Path(run_dir) run_stat = run_dir.lstat() if ( @@ -2456,6 +2473,33 @@ def recover_uncertain_run( ) ): raise ValueError("hosted recovery run directory is not protected") + self._read_child_start_evidence( + dispatch=parsed, + run_dir=run_dir, + dispatch_binding_sha256=parsed.payload.dispatch_binding_sha256, + ) + reservation_key = f"{parsed.tenant_id}:{parsed.idempotency_key}" + reservation = self._ledger.lookup(reservation_key) + if reservation is None or reservation.get("run_id") != parsed.run_id: + raise ValueError("hosted recovery lacks the original reservation") + loss_snapshot = self._retain_managed_result_loss_closure( + dispatch=parsed, + run_dir=run_dir, + dispatch_binding_sha256=parsed.payload.dispatch_binding_sha256, + closure_authority=closure_authority, + loss_code="recovered_after_restart", + ) + + config = load_runner_config(runner_config, protected=True) + self._protected_runner_origin(config) + self._verify_product_release(parsed, config) + key = self._load_evidence_private_key(config) + qualification, deployment_bytes = self._verify_workflow_admission( + parsed, + config, + evidence_private_key=key, + ) + params = self._resolve_params(parsed, config) profile_path = run_dir / "deployment.yaml" if ( self._read_private_bytes( @@ -2475,15 +2519,10 @@ def recover_uncertain_run( ) if isinstance(verified, Refusal): raise ValueError("hosted recovery dispatch no longer verifies") - self._read_child_start_evidence( - dispatch=parsed, - run_dir=run_dir, - dispatch_binding_sha256=verified.payload.dispatch_binding_sha256, - ) - reservation_key = f"{parsed.tenant_id}:{parsed.idempotency_key}" - reservation = self._ledger.lookup(reservation_key) - if reservation is None or reservation.get("run_id") != parsed.run_id: - raise ValueError("hosted recovery lacks the original reservation") + if verified.payload.dispatch_binding_sha256 != ( + parsed.payload.dispatch_binding_sha256 + ): + raise ValueError("hosted recovery dispatch binding changed") proof, report_digest, report = self._produce_managed_result_loss( dispatch=parsed, @@ -2493,8 +2532,8 @@ def recover_uncertain_run( private_key=key, verified_params=params, dispatch_binding_sha256=verified.payload.dispatch_binding_sha256, - closure_authority=closure_authority, loss_code="recovered_after_restart", + snapshot=loss_snapshot, ) outcome = TransactionOutcome.RECONCILIATION_REQUIRED self._ledger.record_outcome(reservation_key, outcome, run_id=parsed.run_id) @@ -2706,6 +2745,13 @@ def execute( try: if closure_authority is None: raise ValueError("hosted result-loss closure authority is absent") + loss_snapshot = self._retain_managed_result_loss_closure( + dispatch=parsed, + run_dir=run_dir, + dispatch_binding_sha256=verified.payload.dispatch_binding_sha256, + closure_authority=closure_authority, + loss_code="runner_exception", + ) terminal_key, terminal_qualification = ( self._revalidate_terminal_authority( dispatch=parsed, @@ -2724,8 +2770,8 @@ def execute( private_key=terminal_key, verified_params=params, dispatch_binding_sha256=verified.payload.dispatch_binding_sha256, - closure_authority=closure_authority, loss_code="runner_exception", + snapshot=loss_snapshot, ) ) except Exception as terminal_exc: @@ -2768,6 +2814,13 @@ def execute( try: if closure_authority is None: raise ValueError("hosted result-loss closure authority is absent") + loss_snapshot = self._retain_managed_result_loss_closure( + dispatch=parsed, + run_dir=run_dir, + dispatch_binding_sha256=verified.payload.dispatch_binding_sha256, + closure_authority=closure_authority, + loss_code="report_missing", + ) terminal_key, terminal_qualification = ( self._revalidate_terminal_authority( dispatch=parsed, @@ -2786,8 +2839,8 @@ def execute( private_key=terminal_key, verified_params=params, dispatch_binding_sha256=verified.payload.dispatch_binding_sha256, - closure_authority=closure_authority, loss_code="report_missing", + snapshot=loss_snapshot, ) ) except Exception as terminal_exc: @@ -2865,6 +2918,40 @@ def execute( outcome = TransactionOutcome.RECONCILIATION_REQUIRED proof = None terminalization_error = exc + try: + if closure_authority is None: + raise ValueError("hosted result-loss closure authority is absent") + loss_snapshot = self._retain_managed_result_loss_closure( + dispatch=parsed, + run_dir=run_dir, + dispatch_binding_sha256=verified.payload.dispatch_binding_sha256, + closure_authority=closure_authority, + loss_code="report_invalid", + ) + terminal_key, terminal_qualification = ( + self._revalidate_terminal_authority( + dispatch=parsed, + runner_config=runner_config, + configured_origin=configured_origin, + initial_qualification=qualification, + initial_deployment_bytes=deployment_bytes, + ) + ) + proof, report_digest, report = self._produce_managed_result_loss( + dispatch=parsed, + workflow=verified.workflow, + run_dir=run_dir, + qualification=terminal_qualification, + private_key=terminal_key, + verified_params=params, + dispatch_binding_sha256=verified.payload.dispatch_binding_sha256, + loss_code="report_invalid", + snapshot=loss_snapshot, + ) + except Exception as loss_exc: # noqa: BLE001 - remains fenced/reconciling + terminalization_error = loss_exc + else: + terminalization_error = None else: terminalization_error = None if proof is None and outcome in { diff --git a/openadapt_flow/terminal_verification_v2.py b/openadapt_flow/terminal_verification_v2.py index abaa2dbf..34bf6fa7 100644 --- a/openadapt_flow/terminal_verification_v2.py +++ b/openadapt_flow/terminal_verification_v2.py @@ -2683,6 +2683,8 @@ def _closed_terminal_outcome(self) -> "ProductionTerminalVerificationPayload": != (chain.pending or chain.entries[0]).run_request_sha256 or result_loss.pending_action_request_sha256 != (pending.action_request_sha256 if pending is not None else None) + or outcome.external_network_calls != "observed" + or receipt.external_network_calls != "observed" or manifests.identity.required != 0 or manifests.identity.confirmed != 0 or manifests.identity.results diff --git a/public-artifacts.json b/public-artifacts.json index 644b4080..2e55d127 100644 --- a/public-artifacts.json +++ b/public-artifacts.json @@ -5785,7 +5785,7 @@ }, { "path": "tests/fixtures/terminal_verification_v2_terminal_vectors.json", - "sha256": "0e94c1b106ca06ef6978c5923770b6b4ae32661deb68ce81078fede9a611dd5f" + "sha256": "2c2af93f1cd5d7b62ede33e59475aa61126cdc9c568949e1a8722b0d899bee3f" }, { "path": "tests/fixtures/theme-region-stable-overhalt-v1.16.1.json", diff --git a/scripts/generate_terminal_verification_v2_vectors.py b/scripts/generate_terminal_verification_v2_vectors.py index e02cb3c2..b42e75c4 100644 --- a/scripts/generate_terminal_verification_v2_vectors.py +++ b/scripts/generate_terminal_verification_v2_vectors.py @@ -78,23 +78,12 @@ def _vector(name: str, *, uncertain_delivery: bool) -> dict[str, object]: } -def build_fixture() -> dict[str, object]: - private_key = _private_key() - private_bytes = private_key.private_bytes( - encoding=serialization.Encoding.Raw, - format=serialization.PrivateFormat.Raw, - encryption_algorithm=serialization.NoEncryption(), - ) - public_bytes = private_key.public_key().public_bytes( - encoding=serialization.Encoding.Raw, - format=serialization.PublicFormat.Raw, - ) - managed = _managed_result_loss_payload() +def _result_loss_closure_vector(payload) -> dict[str, object]: request = _result_loss_request() - closure = managed.delivery_result_loss_closure + closure = payload.delivery_result_loss_closure assert closure is not None closure_raw = canonical_json(closure) - chain_raw = canonical_json(managed.permit_chain) + chain_raw = canonical_json(payload.permit_chain) closure_result = { "schema_version": ( "openadapt.production-delivery-result-loss-closure-result/v2" @@ -103,8 +92,46 @@ def build_fixture() -> dict[str, object]: "closure_artifact_bytes_base64": b64encode(closure_raw).decode("ascii"), "closure_artifact_sha256": closure.artifact_sha256(), "permit_chain_bytes_base64": b64encode(chain_raw).decode("ascii"), - "permit_chain_sha256": managed.permit_chain.permit_chain_sha256, + "permit_chain_sha256": payload.permit_chain.permit_chain_sha256, } + return { + "http_method": "POST", + "http_route": "/api/internal/managed-delivery-result-loss-closure", + "authorization_credential_source": "hosted_dispatch.lease_token", + "request_digest_domain_base64": b64encode( + RESULT_LOSS_CLOSURE_REQUEST_DOMAIN + ).decode("ascii"), + "request_canonical_base64": b64encode(request.canonical_bytes()).decode( + "ascii" + ), + "request_sha256": request.request_sha256(), + "payload_signature_domain_base64": b64encode( + RESULT_LOSS_CLOSURE_PAYLOAD_DOMAIN + ).decode("ascii"), + "closure_payload_sha256": closure.payload_sha256, + "closure_artifact_canonical_base64": b64encode(closure_raw).decode("ascii"), + "closure_artifact_sha256": closure.artifact_sha256(), + "permit_chain_canonical_base64": b64encode(chain_raw).decode("ascii"), + "permit_chain_sha256": payload.permit_chain.permit_chain_sha256, + "result_canonical_base64": b64encode(canonical_json(closure_result)).decode( + "ascii" + ), + } + + +def build_fixture() -> dict[str, object]: + private_key = _private_key() + private_bytes = private_key.private_bytes( + encoding=serialization.Encoding.Raw, + format=serialization.PrivateFormat.Raw, + encryption_algorithm=serialization.NoEncryption(), + ) + public_bytes = private_key.public_key().public_bytes( + encoding=serialization.Encoding.Raw, + format=serialization.PublicFormat.Raw, + ) + managed = _managed_result_loss_payload() + managed_acknowledged = _managed_result_loss_acknowledged_payload() return { "key_id": evidence_runner_key_id(public_bytes), "private_key_base64": b64encode(private_bytes).decode("ascii"), @@ -112,29 +139,10 @@ def build_fixture() -> dict[str, object]: "schema_version": "openadapt.production-terminal-cross-language-vectors/v2", "signature_domain_base64": b64encode(SIGNATURE_DOMAIN).decode("ascii"), "signer_sha256": evidence_runner_signer_sha256(public_bytes), - "managed_result_loss_closure_vector": { - "http_method": "POST", - "http_route": "/api/internal/managed-delivery-result-loss-closure", - "authorization_credential_source": "hosted_dispatch.lease_token", - "request_digest_domain_base64": b64encode( - RESULT_LOSS_CLOSURE_REQUEST_DOMAIN - ).decode("ascii"), - "request_canonical_base64": b64encode(request.canonical_bytes()).decode( - "ascii" - ), - "request_sha256": request.request_sha256(), - "payload_signature_domain_base64": b64encode( - RESULT_LOSS_CLOSURE_PAYLOAD_DOMAIN - ).decode("ascii"), - "closure_payload_sha256": closure.payload_sha256, - "closure_artifact_canonical_base64": b64encode(closure_raw).decode("ascii"), - "closure_artifact_sha256": closure.artifact_sha256(), - "permit_chain_canonical_base64": b64encode(chain_raw).decode("ascii"), - "permit_chain_sha256": managed.permit_chain.permit_chain_sha256, - "result_canonical_base64": b64encode(canonical_json(closure_result)).decode( - "ascii" - ), - }, + "managed_result_loss_closure_vector": _result_loss_closure_vector(managed), + "managed_result_loss_acknowledged_closure_vector": ( + _result_loss_closure_vector(managed_acknowledged) + ), "vectors": [ _vector( "verified-complete", diff --git a/tests/fixtures/terminal_verification_v2_terminal_vectors.json b/tests/fixtures/terminal_verification_v2_terminal_vectors.json index 5b65c8fb..5c7d9548 100644 --- a/tests/fixtures/terminal_verification_v2_terminal_vectors.json +++ b/tests/fixtures/terminal_verification_v2_terminal_vectors.json @@ -1,5 +1,20 @@ { "key_id": "evidence-runner-ed25519-56475aa75463474c", + "managed_result_loss_acknowledged_closure_vector": { + "authorization_credential_source": "hosted_dispatch.lease_token", + "closure_artifact_canonical_base64": "eyJwYXlsb2FkIjp7ImFja25vd2xlZGdlZF9wZXJtaXRfY291bnQiOjEsImFjdHVhdGlvbl9yZXBsYXlfYXV0aG9yaXplZCI6ZmFsc2UsImF1dGhlbnRpY2F0ZWRfcnVubmVyX2lkX3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJhdXRoZW50aWNhdGVkX3Nlc3Npb25faWRfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsImJsaW5kX3JldHJ5X2F1dGhvcml6ZWQiOmZhbHNlLCJjaGlsZF9zdGFydF9ldmlkZW5jZV9zaGEyNTYiOiJlYzY5MDc5MTg4NmFlMmNlMDBjNGU1MTE1NGMzZjEyMGVhNDQxOWVkMjY1MWUwNzNkYjU3MjQ5MThhM2IwOGM2IiwiY2hpbGRfc3RhcnRlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDBaIiwiY2xvc2VkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMloiLCJjbG9zdXJlX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDExIiwiY2xvc3VyZV9yZXF1ZXN0X3NoYTI1NiI6ImQ5MzBhYjFhYmMyYjJhMDRiODQ4Yjk1NWZmZGZmZmExZmJlMDY1NWE1NTMyNWUwNDg5YWUxMWVkODQyMDIyNjAiLCJjbG9zdXJlX3NlcXVlbmNlIjoxLCJkZWxpdmVyeV9hY2tub3dsZWRnbWVudF9hdXRob3JpemVkIjpmYWxzZSwiZGVsaXZlcnlfc3RhdGUiOiJDTE9TRURfVU5SRVNPTFZFRF9SRVNVTFRfTE9TUyIsImRpc3BhdGNoX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA5IiwiZGlzcGF0Y2hfc2Vzc2lvbl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAxMCIsImVmZmVjdF9hYnNlbmNlX2NsYWltZWQiOmZhbHNlLCJleGVjdXRpb25fYXV0aG9yaXR5X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA4IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaWduZXJfc2hhMjU2IjoiMjRmNmVkNmFjYmZlMTAwOWMwMzBkN2NhNTY3YzMzY2E0ODMwOTExNDk4MjM2YjU1NjFhNmM4MmFiZWM1ZGUyOCIsImZpbmFsX2F1dGhvcml0eV9zZXF1ZW5jZSI6MCwiZmluYWxfaW5wdXRfZWRnZV9zZXF1ZW5jZSI6MSwiZmluYWxfcnVudGltZV9kZWxpdmVyeV9zZXF1ZW5jZSI6OSwiZmxvd19ydW5faWRfc2hhMjU2IjoiMTFlNTk0ZjQ4MTk1OGMxMGUzMDE1ZDBiZjA0NDdhMjJmMDY4YThhNjQ3ZjQ3NWRmMTVjZTJjN2FiNGI4ZjNmMSIsImlkZW1wb3RlbmN5X2tleV9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwibWFuYWdlZF9kaXNwYXRjaF9iaW5kaW5nX3NoYTI1NiI6InNoYTI1NjpjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwibmV3X3Blcm1pdF9hdXRob3JpemVkIjpmYWxzZSwibm90X3JlY2VpdmVkX2NsYWltZWQiOmZhbHNlLCJwZW5kaW5nX2FjdGlvbl9yZXF1ZXN0X3NoYTI1NiI6bnVsbCwicGVuZGluZ19wZXJtaXRfYXJ0aWZhY3Rfc2hhMjU2IjpudWxsLCJwZW5kaW5nX3Blcm1pdF9jb3VudCI6MCwicGVybWl0X2NoYWluX3NoYTI1NiI6IjUwNDhmZTk0NTg4MmQyODAyNjAwOGQ3ZTkxMzdhZDAxNmZkZDAxYWVhZjU4ODQ4MWZiNWJkMGYyNDJhNTAwNDMiLCJwZXJtaXRfY291bnQiOjEsInJlY2VpcHRfYWJzZW5jZV9vYnNlcnZlZF9hdCI6bnVsbCwicmVzdWx0X2xvc3Nfb2JzZXJ2ZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAyWiIsInJ1bl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwMSIsInJ1bl9yZXF1ZXN0X3NoYTI1NiI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJydW5fc3RvcmVfaWRlbnRpdHlfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcmVzdWx0LWxvc3MtY2xvc3VyZS1wYXlsb2FkL3YyIiwidGVuYW50X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAyIiwidGVybWluYWxfY2FsbGJhY2tfcmVxdWlyZWQiOnRydWV9LCJwYXlsb2FkX3NoYTI1NiI6IjZiNzVmOGI0NWE3ZDNlOWNmZTg1NjRmZmUzMmYyOWMyYjU5N2MyODEzNmE5N2E0ZjU0NTNmZTJhZmQxNzI4YWEiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXJlc3VsdC1sb3NzLWNsb3N1cmUtYXJ0aWZhY3QvdjIiLCJzaWduYXR1cmUiOiJrenVSMnFyY0dUNHBvNi15emRZRGdoM3dhWWpiOVdwUUdVX0JuUUxIVEliZGQ1eEJsclVTbDZINGNlVkMzM3IxQndiRnRSUGFQdm8wNXBneGdFNHdBdyIsInNpZ25lciI6eyJhbGdvcml0aG0iOiJlZDI1NTE5Iiwia2V5X2lkIjoiZGVsaXZlcnktYXV0aG9yaXR5LWVkMjU1MTktMjRmNmVkNmFjYmZlMTAwOSIsInB1YmxpY19rZXkiOiJLYXk2NFVHOHl2Q3lMaHFVMDAwTHh6WWVVbTBML2hMSWw1UzhreUtXYmRjPSJ9fQ==", + "closure_artifact_sha256": "b2d92f3248f4da61edb027cf59da5395ffc418ead6d485c29df6c35bc21a930d", + "closure_payload_sha256": "6b75f8b45a7d3e9cfe8564ffe32f29c2b597c28136a97a4f5453fe2afd1728aa", + "http_method": "POST", + "http_route": "/api/internal/managed-delivery-result-loss-closure", + "payload_signature_domain_base64": "b3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcmVzdWx0LWxvc3MtY2xvc3VyZS1wYXlsb2FkLnYyAA==", + "permit_chain_canonical_base64": "eyJlbnRyaWVzIjpbeyJkZWxpdmVyeV9yZWNlaXB0X2FydGlmYWN0Ijp7InBheWxvYWQiOnsiYXV0aGVudGljYXRlZF9ydW5uZXJfaWRfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsImF1dGhlbnRpY2F0ZWRfc2Vzc2lvbl9pZF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiZGVsaXZlcmVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMVoiLCJleGVjdXRpb25fYXV0aG9yaXR5X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA4Iiwib25lX3VzZV9jbGFpbV9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAxMCIsInBlcm1pdF9hcnRpZmFjdF9zaGEyNTYiOiI5NzJhODJhZjQ1NmRhNTQyYmFjNzg0NjAxODg5NjY4ODkxZDhiN2NjZDI0MjkwNDgxNmIzMjkyZTE1N2U1Mjg5IiwicGVybWl0X2lkIjoicGVybWl0OjEiLCJydW50aW1lX2RlbGl2ZXJ5X3NlcXVlbmNlIjo5LCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXJlY2VpcHQtcGF5bG9hZC92MiJ9LCJwYXlsb2FkX3NoYTI1NiI6IjhhOGY2ZDg4NzUwY2JiNmIzYmQ2NjIwOTNhZDI5ZTJiYzIwYzZhYjY5OTFkNzBlNTg4NjkxYzhiM2FiNjYyYjkiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXJlY2VpcHQtYXJ0aWZhY3QvdjIiLCJzaWduYXR1cmUiOiJBT0txQ2dTMXMwWGEtaXlFOTZWLXlsUHpRY3YydXZPc3V5Z0h6dnUyUnlWN0ZMc0hGX0xWZnF5eDR1MnB1bWxFbDBZazVZdTcwSlZVa3NacGFVcEREdyIsInNpZ25lciI6eyJhbGdvcml0aG0iOiJlZDI1NTE5Iiwia2V5X2lkIjoiZGVsaXZlcnktYXV0aG9yaXR5LWVkMjU1MTktMjRmNmVkNmFjYmZlMTAwOSIsInB1YmxpY19rZXkiOiJLYXk2NFVHOHl2Q3lMaHFVMDAwTHh6WWVVbTBML2hMSWw1UzhreUtXYmRjPSJ9fSwiZGVsaXZlcnlfcmVjZWlwdF9hcnRpZmFjdF9zaGEyNTYiOiJjMDBhMWJhNzAxNWYzY2JlMDVhNzZhZWFiZmY2MTlkNzkzZTczNzVhMzEwZTE5NWZjYmJkMmQyOTQ4ZjJiMjE0IiwicGVybWl0X2FydGlmYWN0Ijp7InBheWxvYWQiOnsiYWN0aW9uX3JlcXVlc3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYXV0aG9yaXR5X3NlcXVlbmNlIjowLCJlbnZpcm9ubWVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXZpZGVuY2VfaWRlbnRpdHlfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImV4ZWN1dGlvbl9hdXRob3JpdHlfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDgiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJmbG93X3J1bl9pZF9zaGEyNTYiOiIxMWU1OTRmNDgxOTU4YzEwZTMwMTVkMGJmMDQ0N2EyMmYwNjhhOGE2NDdmNDc1ZGYxNWNlMmM3YWI0YjhmM2YxIiwiaW5wdXRfZWRnZV9zZXF1ZW5jZSI6MSwiaXNzdWVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMFoiLCJwZXJtaXRfaWQiOiJwZXJtaXQ6MSIsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X2NoZWNrZWRfYXQiOiIyMDI2LTA4LTE4VDExOjU5OjMwWiIsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X2V4cGlyZXNfYXQiOiIyMDI2LTA4LTIwVDExOjAwOjAwWiIsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X3JldmlzaW9uIjo3LCJxdWFsaWZpY2F0aW9uX3NpZ25lcl9yZWdpc3RyeV9zaGEyNTYiOiJlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlIiwicnVuX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAxIiwicnVuX3JlcXVlc3Rfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcGVybWl0LXBheWxvYWQvdjIifSwicGF5bG9hZF9zaGEyNTYiOiJjODdmNTc1MWFhOWIyNzljY2UyM2FhMTc4YWZmOTU2ZTE5ZjY5MGZjZDJmOWY3MGUwZDk5OTc4MmE2OTBkNmI4Iiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1wZXJtaXQtYXJ0aWZhY3QvdjIiLCJzaWduYXR1cmUiOiIwQnlIZ3FEeFFacm5nTElGLTZ0Wk9xOWxYYW1jQVFDMGRvVVRuZUtOUGVTLVN5b09iUXlPa0F1UEZLNVBZY056T2JaeGdzZ0FMZFdhSV9zYVVDcGxCZyIsInNpZ25lciI6eyJhbGdvcml0aG0iOiJlZDI1NTE5Iiwia2V5X2lkIjoiZGVsaXZlcnktYXV0aG9yaXR5LWVkMjU1MTktMjRmNmVkNmFjYmZlMTAwOSIsInB1YmxpY19rZXkiOiJLYXk2NFVHOHl2Q3lMaHFVMDAwTHh6WWVVbTBML2hMSWw1UzhreUtXYmRjPSJ9fSwicGVybWl0X2FydGlmYWN0X3NoYTI1NiI6Ijk3MmE4MmFmNDU2ZGE1NDJiYWM3ODQ2MDE4ODk2Njg4OTFkOGI3Y2NkMjQyOTA0ODE2YjMyOTJlMTU3ZTUyODkiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXBlcm1pdC1jaGFpbi1lbnRyeS92MiJ9XSwicGVybWl0X2NoYWluX3NoYTI1NiI6IjUwNDhmZTk0NTg4MmQyODAyNjAwOGQ3ZTkxMzdhZDAxNmZkZDAxYWVhZjU4ODQ4MWZiNWJkMGYyNDJhNTAwNDMiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXBlcm1pdC1jaGFpbi92MiJ9", + "permit_chain_sha256": "5048fe945882d28026008d7e9137ad016fdd01aeaf588481fb5bd0f242a50043", + "request_canonical_base64": "eyJjaGlsZF9zdGFydF9ldmlkZW5jZSI6eyJhdXRoZW50aWNhdGVkX3J1bm5lcl9pZF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwiYXV0aGVudGljYXRlZF9zZXNzaW9uX2lkX3NoYTI1NiI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJkaXNwYXRjaF9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOSIsImRpc3BhdGNoX3Nlc3Npb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMTAiLCJleGVjdXRpb25fYXV0aG9yaXR5X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA4IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaWduZXJfc2hhMjU2IjoiMjRmNmVkNmFjYmZlMTAwOWMwMzBkN2NhNTY3YzMzY2E0ODMwOTExNDk4MjM2YjU1NjFhNmM4MmFiZWM1ZGUyOCIsIm1hbmFnZWRfZGlzcGF0Y2hfYmluZGluZ19zaGEyNTYiOiJzaGEyNTY6Y2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsIm1hcmtlcl9zaGEyNTYiOiJlYzY5MDc5MTg4NmFlMmNlMDBjNGU1MTE1NGMzZjEyMGVhNDQxOWVkMjY1MWUwNzNkYjU3MjQ5MThhM2IwOGM2IiwicnVuX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAxIiwicnVuX3N0b3JlX2lkZW50aXR5X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5tYW5hZ2VkLWNoaWxkLXN0YXJ0L3YxIiwic3RhcnRlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDBaIn0sImV4cGVjdGVkX2Nsb3N1cmVfc2VxdWVuY2UiOjAsInJlc3VsdF9sb3NzX29ic2VydmVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMloiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXJlc3VsdC1sb3NzLWNsb3N1cmUtcmVxdWVzdC92MiJ9", + "request_digest_domain_base64": "b3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcmVzdWx0LWxvc3MtY2xvc3VyZS1yZXF1ZXN0LnYyAA==", + "request_sha256": "d930ab1abc2b2a04b848b955ffdfffa1fbe0655a55325e0489ae11ed84202260", + "result_canonical_base64": "eyJjbG9zdXJlX2FydGlmYWN0X2J5dGVzX2Jhc2U2NCI6ImV5SndZWGxzYjJGa0lqcDdJbUZqYTI1dmQyeGxaR2RsWkY5d1pYSnRhWFJmWTI5MWJuUWlPakVzSW1GamRIVmhkR2x2Ymw5eVpYQnNZWGxmWVhWMGFHOXlhWHBsWkNJNlptRnNjMlVzSW1GMWRHaGxiblJwWTJGMFpXUmZjblZ1Ym1WeVgybGtYM05vWVRJMU5pSTZJbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUlpTENKaGRYUm9aVzUwYVdOaGRHVmtYM05sYzNOcGIyNWZhV1JmYzJoaE1qVTJJam9pWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWXlJc0ltSnNhVzVrWDNKbGRISjVYMkYxZEdodmNtbDZaV1FpT21aaGJITmxMQ0pqYUdsc1pGOXpkR0Z5ZEY5bGRtbGtaVzVqWlY5emFHRXlOVFlpT2lKbFl6WTVNRGM1TVRnNE5tRmxNbU5sTURCak5HVTFNVEUxTkdNelpqRXlNR1ZoTkRReE9XVmtNalkxTVdVd056TmtZalUzTWpRNU1UaGhNMkl3T0dNMklpd2lZMmhwYkdSZmMzUmhjblJsWkY5aGRDSTZJakl3TWpZdE1EZ3RNVGhVTVRJNk1EQTZNREJhSWl3aVkyeHZjMlZrWDJGMElqb2lNakF5Tmkwd09DMHhPRlF4TWpvd01Eb3dNbG9pTENKamJHOXpkWEpsWDJsa0lqb2lNREF3TURBd01EQXRNREF3TUMwME1EQXdMVGd3TURBdE1EQXdNREF3TURBd01ERXhJaXdpWTJ4dmMzVnlaVjl5WlhGMVpYTjBYM05vWVRJMU5pSTZJbVE1TXpCaFlqRmhZbU15WWpKaE1EUmlPRFE0WWprMU5XWm1aR1ptWm1FeFptSmxNRFkxTldFMU5UTXlOV1V3TkRnNVlXVXhNV1ZrT0RReU1ESXlOakFpTENKamJHOXpkWEpsWDNObGNYVmxibU5sSWpveExDSmtaV3hwZG1WeWVWOWhZMnR1YjNkc1pXUm5iV1Z1ZEY5aGRYUm9iM0pwZW1Wa0lqcG1ZV3h6WlN3aVpHVnNhWFpsY25sZmMzUmhkR1VpT2lKRFRFOVRSVVJmVlU1U1JWTlBURlpGUkY5U1JWTlZURlJmVEU5VFV5SXNJbVJwYzNCaGRHTm9YMmxrSWpvaU1EQXdNREF3TURBdE1EQXdNQzAwTURBd0xUZ3dNREF0TURBd01EQXdNREF3TURBNUlpd2laR2x6Y0dGMFkyaGZjMlZ6YzJsdmJsOXBaQ0k2SWpBd01EQXdNREF3TFRBd01EQXROREF3TUMwNE1EQXdMVEF3TURBd01EQXdNREF4TUNJc0ltVm1abVZqZEY5aFluTmxibU5sWDJOc1lXbHRaV1FpT21aaGJITmxMQ0psZUdWamRYUnBiMjVmWVhWMGFHOXlhWFI1WDJsa0lqb2lNREF3TURBd01EQXRNREF3TUMwME1EQXdMVGd3TURBdE1EQXdNREF3TURBd01EQTRJaXdpWlhobFkzVjBhVzl1WDJGMWRHaHZjbWwwZVY5emFHRXlOVFlpT2lKaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaElpd2laWGhsWTNWMGFXOXVYMkYxZEdodmNtbDBlVjl6YVdkdVpYSmZjMmhoTWpVMklqb2lNalJtTm1Wa05tRmpZbVpsTVRBd09XTXdNekJrTjJOaE5UWTNZek16WTJFME9ETXdPVEV4TkRrNE1qTTJZalUxTmpGaE5tTTRNbUZpWldNMVpHVXlPQ0lzSW1acGJtRnNYMkYxZEdodmNtbDBlVjl6WlhGMVpXNWpaU0k2TUN3aVptbHVZV3hmYVc1d2RYUmZaV1JuWlY5elpYRjFaVzVqWlNJNk1Td2labWx1WVd4ZmNuVnVkR2x0WlY5a1pXeHBkbVZ5ZVY5elpYRjFaVzVqWlNJNk9Td2labXh2ZDE5eWRXNWZhV1JmYzJoaE1qVTJJam9pTVRGbE5UazBaalE0TVRrMU9HTXhNR1V6TURFMVpEQmlaakEwTkRkaE1qSm1NRFk0WVRoaE5qUTNaalEzTldSbU1UVmpaVEpqTjJGaU5HSTRaak5tTVNJc0ltbGtaVzF3YjNSbGJtTjVYMnRsZVY5emFHRXlOVFlpT2lKa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa0lpd2liV0Z1WVdkbFpGOWthWE53WVhSamFGOWlhVzVrYVc1blgzTm9ZVEkxTmlJNkluTm9ZVEkxTmpwalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOaklpd2libVYzWDNCbGNtMXBkRjloZFhSb2IzSnBlbVZrSWpwbVlXeHpaU3dpYm05MFgzSmxZMlZwZG1Wa1gyTnNZV2x0WldRaU9tWmhiSE5sTENKd1pXNWthVzVuWDJGamRHbHZibDl5WlhGMVpYTjBYM05vWVRJMU5pSTZiblZzYkN3aWNHVnVaR2x1WjE5d1pYSnRhWFJmWVhKMGFXWmhZM1JmYzJoaE1qVTJJanB1ZFd4c0xDSndaVzVrYVc1blgzQmxjbTFwZEY5amIzVnVkQ0k2TUN3aWNHVnliV2wwWDJOb1lXbHVYM05vWVRJMU5pSTZJalV3TkRobVpUazBOVGc0TW1ReU9EQXlOakF3T0dRM1pUa3hNemRoWkRBeE5tWmtaREF4WVdWaFpqVTRPRFE0TVdaaU5XSmtNR1l5TkRKaE5UQXdORE1pTENKd1pYSnRhWFJmWTI5MWJuUWlPakVzSW5KbFkyVnBjSFJmWVdKelpXNWpaVjl2WW5ObGNuWmxaRjloZENJNmJuVnNiQ3dpY21WemRXeDBYMnh2YzNOZmIySnpaWEoyWldSZllYUWlPaUl5TURJMkxUQTRMVEU0VkRFeU9qQXdPakF5V2lJc0luSjFibDlwWkNJNklqQXdNREF3TURBd0xUQXdNREF0TkRBd01DMDRNREF3TFRBd01EQXdNREF3TURBd01TSXNJbkoxYmw5eVpYRjFaWE4wWDNOb1lUSTFOaUk2SW1OalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJNaUxDSnlkVzVmYzNSdmNtVmZhV1JsYm5ScGRIbGZjMmhoTWpVMklqb2lZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZaUlzSW5OamFHVnRZVjkyWlhKemFXOXVJam9pYjNCbGJtRmtZWEIwTG5CeWIyUjFZM1JwYjI0dFpHVnNhWFpsY25rdGNtVnpkV3gwTFd4dmMzTXRZMnh2YzNWeVpTMXdZWGxzYjJGa0wzWXlJaXdpZEdWdVlXNTBYMmxrSWpvaU1EQXdNREF3TURBdE1EQXdNQzAwTURBd0xUZ3dNREF0TURBd01EQXdNREF3TURBeUlpd2lkR1Z5YldsdVlXeGZZMkZzYkdKaFkydGZjbVZ4ZFdseVpXUWlPblJ5ZFdWOUxDSndZWGxzYjJGa1gzTm9ZVEkxTmlJNklqWmlOelZtT0dJME5XRTNaRE5sT1dObVpUZzFOalJtWm1Vek1tWXlPV015WWpVNU4yTXlPREV6Tm1FNU4yRTBaalUwTlRObVpUSmhabVF4TnpJNFlXRWlMQ0p6WTJobGJXRmZkbVZ5YzJsdmJpSTZJbTl3Wlc1aFpHRndkQzV3Y205a2RXTjBhVzl1TFdSbGJHbDJaWEo1TFhKbGMzVnNkQzFzYjNOekxXTnNiM04xY21VdFlYSjBhV1poWTNRdmRqSWlMQ0p6YVdkdVlYUjFjbVVpT2lKcmVuVlNNbkZ5WTBkVU5IQnZOaTE1ZW1SWlJHZG9NM2RoV1dwaU9WZHdVVWRWWDBKdVVVeElWRWxpWkdRMWVFSnNjbFZUYkRaSU5HTmxWa016TTNJeFFuZGlSblJTVUdGUWRtOHdOWEJuZUdkRk5IZEJkeUlzSW5OcFoyNWxjaUk2ZXlKaGJHZHZjbWwwYUcwaU9pSmxaREkxTlRFNUlpd2lhMlY1WDJsa0lqb2laR1ZzYVhabGNua3RZWFYwYUc5eWFYUjVMV1ZrTWpVMU1Ua3RNalJtTm1Wa05tRmpZbVpsTVRBd09TSXNJbkIxWW14cFkxOXJaWGtpT2lKTFlYazJORlZIT0hsMlEzbE1hSEZWTURBd1RIaDZXV1ZWYlRCTUwyaE1TV3cxVXpocmVVdFhZbVJqUFNKOWZRPT0iLCJjbG9zdXJlX2FydGlmYWN0X3NoYTI1NiI6ImIyZDkyZjMyNDhmNGRhNjFlZGIwMjdjZjU5ZGE1Mzk1ZmZjNDE4ZWFkNmQ0ODVjMjlkZjZjMzViYzIxYTkzMGQiLCJwZXJtaXRfY2hhaW5fYnl0ZXNfYmFzZTY0IjoiZXlKbGJuUnlhV1Z6SWpwYmV5SmtaV3hwZG1WeWVWOXlaV05sYVhCMFgyRnlkR2xtWVdOMElqcDdJbkJoZVd4dllXUWlPbnNpWVhWMGFHVnVkR2xqWVhSbFpGOXlkVzV1WlhKZmFXUmZjMmhoTWpVMklqb2lZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZbUppWW1KaVltSmlZaUlzSW1GMWRHaGxiblJwWTJGMFpXUmZjMlZ6YzJsdmJsOXBaRjl6YUdFeU5UWWlPaUpqWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qSWl3aVpHVnNhWFpsY21Wa1gyRjBJam9pTWpBeU5pMHdPQzB4T0ZReE1qb3dNRG93TVZvaUxDSmxlR1ZqZFhScGIyNWZZWFYwYUc5eWFYUjVYMmxrSWpvaU1EQXdNREF3TURBdE1EQXdNQzAwTURBd0xUZ3dNREF0TURBd01EQXdNREF3TURBNElpd2liMjVsWDNWelpWOWpiR0ZwYlY5cFpDSTZJakF3TURBd01EQXdMVEF3TURBdE5EQXdNQzA0TURBd0xUQXdNREF3TURBd01EQXhNQ0lzSW5CbGNtMXBkRjloY25ScFptRmpkRjl6YUdFeU5UWWlPaUk1TnpKaE9ESmhaalExTm1SaE5UUXlZbUZqTnpnME5qQXhPRGc1TmpZNE9Ea3haRGhpTjJOalpESTBNamt3TkRneE5tSXpNamt5WlRFMU4yVTFNamc1SWl3aWNHVnliV2wwWDJsa0lqb2ljR1Z5YldsME9qRWlMQ0p5ZFc1MGFXMWxYMlJsYkdsMlpYSjVYM05sY1hWbGJtTmxJam81TENKelkyaGxiV0ZmZG1WeWMybHZiaUk2SW05d1pXNWhaR0Z3ZEM1d2NtOWtkV04wYVc5dUxXUmxiR2wyWlhKNUxYSmxZMlZwY0hRdGNHRjViRzloWkM5Mk1pSjlMQ0p3WVhsc2IyRmtYM05vWVRJMU5pSTZJamhoT0dZMlpEZzROelV3WTJKaU5tSXpZbVEyTmpJd09UTmhaREk1WlRKaVl6SXdZelpoWWpZNU9URmtOekJsTlRnNE5qa3hZemhpTTJGaU5qWXlZamtpTENKelkyaGxiV0ZmZG1WeWMybHZiaUk2SW05d1pXNWhaR0Z3ZEM1d2NtOWtkV04wYVc5dUxXUmxiR2wyWlhKNUxYSmxZMlZwY0hRdFlYSjBhV1poWTNRdmRqSWlMQ0p6YVdkdVlYUjFjbVVpT2lKQlQwdHhRMmRUTVhNd1dHRXRhWGxGT1RaV0xYbHNVSHBSWTNZeWRYWlBjM1Y1WjBoNmRuVXlVbmxXTjBaTWMwaEdYMHhXWm5GNWVEUjFNbkIxYld4RmJEQlphelZaZFRjd1NsWlZhM05hY0dGVmNFUkVkeUlzSW5OcFoyNWxjaUk2ZXlKaGJHZHZjbWwwYUcwaU9pSmxaREkxTlRFNUlpd2lhMlY1WDJsa0lqb2laR1ZzYVhabGNua3RZWFYwYUc5eWFYUjVMV1ZrTWpVMU1Ua3RNalJtTm1Wa05tRmpZbVpsTVRBd09TSXNJbkIxWW14cFkxOXJaWGtpT2lKTFlYazJORlZIT0hsMlEzbE1hSEZWTURBd1RIaDZXV1ZWYlRCTUwyaE1TV3cxVXpocmVVdFhZbVJqUFNKOWZTd2laR1ZzYVhabGNubGZjbVZqWldsd2RGOWhjblJwWm1GamRGOXphR0V5TlRZaU9pSmpNREJoTVdKaE56QXhOV1l6WTJKbE1EVmhOelpoWldGaVptWTJNVGxrTnprelpUY3pOelZoTXpFd1pURTVOV1pqWW1Ka01tUXlPVFE0WmpKaU1qRTBJaXdpY0dWeWJXbDBYMkZ5ZEdsbVlXTjBJanA3SW5CaGVXeHZZV1FpT25zaVlXTjBhVzl1WDNKbGNYVmxjM1JmYzJoaE1qVTJJam9pWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkNJc0ltRmtiV2x6YzJsdmJsOWhjblJwWm1GamRGOXphR0V5TlRZaU9pSmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtaR1JrWkdSa1pHUmtJaXdpWVhWMGFHOXlhWFI1WDNObGNYVmxibU5sSWpvd0xDSmxiblpwY205dWJXVnVkRjlrYVdkbGMzUWlPaUpoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoSWl3aVpYWnBaR1Z1WTJWZmFXUmxiblJwZEhsZmMyaGhNalUySWpvaVpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbFpTSXNJbVY0WldOMWRHbHZibDloZFhSb2IzSnBkSGxmYVdRaU9pSXdNREF3TURBd01DMHdNREF3TFRRd01EQXRPREF3TUMwd01EQXdNREF3TURBd01EZ2lMQ0psZUdWamRYUnBiMjVmWVhWMGFHOXlhWFI1WDNOb1lUSTFOaUk2SW1GaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdGaFlXRmhZV0ZoWVdFaUxDSm1iRzkzWDNKMWJsOXBaRjl6YUdFeU5UWWlPaUl4TVdVMU9UUm1ORGd4T1RVNFl6RXdaVE13TVRWa01HSm1NRFEwTjJFeU1tWXdOamhoT0dFMk5EZG1ORGMxWkdZeE5XTmxNbU0zWVdJMFlqaG1NMll4SWl3aWFXNXdkWFJmWldSblpWOXpaWEYxWlc1alpTSTZNU3dpYVhOemRXVmtYMkYwSWpvaU1qQXlOaTB3T0MweE9GUXhNam93TURvd01Gb2lMQ0p3WlhKdGFYUmZhV1FpT2lKd1pYSnRhWFE2TVNJc0luRjFZV3hwWm1sallYUnBiMjVmYzJsbmJtVnlYM0psWjJsemRISjVYMk5vWldOclpXUmZZWFFpT2lJeU1ESTJMVEE0TFRFNFZERXhPalU1T2pNd1dpSXNJbkYxWVd4cFptbGpZWFJwYjI1ZmMybG5ibVZ5WDNKbFoybHpkSEo1WDJWNGNHbHlaWE5mWVhRaU9pSXlNREkyTFRBNExUSXdWREV4T2pBd09qQXdXaUlzSW5GMVlXeHBabWxqWVhScGIyNWZjMmxuYm1WeVgzSmxaMmx6ZEhKNVgzSmxkbWx6YVc5dUlqbzNMQ0p4ZFdGc2FXWnBZMkYwYVc5dVgzTnBaMjVsY2w5eVpXZHBjM1J5ZVY5emFHRXlOVFlpT2lKbFpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbFpXVmxaV1ZsWldWbElpd2ljblZ1WDJsa0lqb2lNREF3TURBd01EQXRNREF3TUMwME1EQXdMVGd3TURBdE1EQXdNREF3TURBd01EQXhJaXdpY25WdVgzSmxjWFZsYzNSZmMyaGhNalUySWpvaVkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOalkyTmpZMk5qWTJOall5SXNJbk5qYUdWdFlWOTJaWEp6YVc5dUlqb2liM0JsYm1Ga1lYQjBMbkJ5YjJSMVkzUnBiMjR0WkdWc2FYWmxjbmt0Y0dWeWJXbDBMWEJoZVd4dllXUXZkaklpZlN3aWNHRjViRzloWkY5emFHRXlOVFlpT2lKak9EZG1OVGMxTVdGaE9XSXlOemxqWTJVeU0yRmhNVGM0WVdabU9UVTJaVEU1WmpZNU1HWmpaREptT1dZM01HVXdaRGs1T1RjNE1tRTJPVEJrTm1JNElpd2ljMk5vWlcxaFgzWmxjbk5wYjI0aU9pSnZjR1Z1WVdSaGNIUXVjSEp2WkhWamRHbHZiaTFrWld4cGRtVnllUzF3WlhKdGFYUXRZWEowYVdaaFkzUXZkaklpTENKemFXZHVZWFIxY21VaU9pSXdRbmxJWjNGRWVGRmFjbTVuVEVsR0xUWjBXazl4T1d4WVlXMWpRVkZETUdSdlZWUnVaVXRPVUdWVExWTjViMDlpVVhsUGEwRjFVRVpMTlZCWlkwNTZUMkphZUdkelowRk1aRmRoU1Y5ellWVkRjR3hDWnlJc0luTnBaMjVsY2lJNmV5SmhiR2R2Y21sMGFHMGlPaUpsWkRJMU5URTVJaXdpYTJWNVgybGtJam9pWkdWc2FYWmxjbmt0WVhWMGFHOXlhWFI1TFdWa01qVTFNVGt0TWpSbU5tVmtObUZqWW1abE1UQXdPU0lzSW5CMVlteHBZMTlyWlhraU9pSkxZWGsyTkZWSE9IbDJRM2xNYUhGVk1EQXdUSGg2V1dWVmJUQk1MMmhNU1d3MVV6aHJlVXRYWW1SalBTSjlmU3dpY0dWeWJXbDBYMkZ5ZEdsbVlXTjBYM05vWVRJMU5pSTZJamszTW1FNE1tRm1ORFUyWkdFMU5ESmlZV00zT0RRMk1ERTRPRGsyTmpnNE9URmtPR0kzWTJOa01qUXlPVEEwT0RFMllqTXlPVEpsTVRVM1pUVXlPRGtpTENKelkyaGxiV0ZmZG1WeWMybHZiaUk2SW05d1pXNWhaR0Z3ZEM1d2NtOWtkV04wYVc5dUxXUmxiR2wyWlhKNUxYQmxjbTFwZEMxamFHRnBiaTFsYm5SeWVTOTJNaUo5WFN3aWNHVnliV2wwWDJOb1lXbHVYM05vWVRJMU5pSTZJalV3TkRobVpUazBOVGc0TW1ReU9EQXlOakF3T0dRM1pUa3hNemRoWkRBeE5tWmtaREF4WVdWaFpqVTRPRFE0TVdaaU5XSmtNR1l5TkRKaE5UQXdORE1pTENKelkyaGxiV0ZmZG1WeWMybHZiaUk2SW05d1pXNWhaR0Z3ZEM1d2NtOWtkV04wYVc5dUxXUmxiR2wyWlhKNUxYQmxjbTFwZEMxamFHRnBiaTkyTWlKOSIsInBlcm1pdF9jaGFpbl9zaGEyNTYiOiI1MDQ4ZmU5NDU4ODJkMjgwMjYwMDhkN2U5MTM3YWQwMTZmZGQwMWFlYWY1ODg0ODFmYjViZDBmMjQyYTUwMDQzIiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1yZXN1bHQtbG9zcy1jbG9zdXJlLXJlc3VsdC92MiIsInN0YXR1cyI6ImNsb3NlZCJ9" + }, "managed_result_loss_closure_vector": { "authorization_credential_source": "hosted_dispatch.lease_token", "closure_artifact_canonical_base64": "eyJwYXlsb2FkIjp7ImFja25vd2xlZGdlZF9wZXJtaXRfY291bnQiOjAsImFjdHVhdGlvbl9yZXBsYXlfYXV0aG9yaXplZCI6ZmFsc2UsImF1dGhlbnRpY2F0ZWRfcnVubmVyX2lkX3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJhdXRoZW50aWNhdGVkX3Nlc3Npb25faWRfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsImJsaW5kX3JldHJ5X2F1dGhvcml6ZWQiOmZhbHNlLCJjaGlsZF9zdGFydF9ldmlkZW5jZV9zaGEyNTYiOiJlYzY5MDc5MTg4NmFlMmNlMDBjNGU1MTE1NGMzZjEyMGVhNDQxOWVkMjY1MWUwNzNkYjU3MjQ5MThhM2IwOGM2IiwiY2hpbGRfc3RhcnRlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDBaIiwiY2xvc2VkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMloiLCJjbG9zdXJlX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDExIiwiY2xvc3VyZV9yZXF1ZXN0X3NoYTI1NiI6ImQ5MzBhYjFhYmMyYjJhMDRiODQ4Yjk1NWZmZGZmZmExZmJlMDY1NWE1NTMyNWUwNDg5YWUxMWVkODQyMDIyNjAiLCJjbG9zdXJlX3NlcXVlbmNlIjoxLCJkZWxpdmVyeV9hY2tub3dsZWRnbWVudF9hdXRob3JpemVkIjpmYWxzZSwiZGVsaXZlcnlfc3RhdGUiOiJDTE9TRURfVU5SRVNPTFZFRF9SRVNVTFRfTE9TUyIsImRpc3BhdGNoX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA5IiwiZGlzcGF0Y2hfc2Vzc2lvbl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAxMCIsImVmZmVjdF9hYnNlbmNlX2NsYWltZWQiOmZhbHNlLCJleGVjdXRpb25fYXV0aG9yaXR5X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA4IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaWduZXJfc2hhMjU2IjoiMjRmNmVkNmFjYmZlMTAwOWMwMzBkN2NhNTY3YzMzY2E0ODMwOTExNDk4MjM2YjU1NjFhNmM4MmFiZWM1ZGUyOCIsImZpbmFsX2F1dGhvcml0eV9zZXF1ZW5jZSI6MCwiZmluYWxfaW5wdXRfZWRnZV9zZXF1ZW5jZSI6MSwiZmluYWxfcnVudGltZV9kZWxpdmVyeV9zZXF1ZW5jZSI6MCwiZmxvd19ydW5faWRfc2hhMjU2IjoiMTFlNTk0ZjQ4MTk1OGMxMGUzMDE1ZDBiZjA0NDdhMjJmMDY4YThhNjQ3ZjQ3NWRmMTVjZTJjN2FiNGI4ZjNmMSIsImlkZW1wb3RlbmN5X2tleV9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwibWFuYWdlZF9kaXNwYXRjaF9iaW5kaW5nX3NoYTI1NiI6InNoYTI1NjpjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwibmV3X3Blcm1pdF9hdXRob3JpemVkIjpmYWxzZSwibm90X3JlY2VpdmVkX2NsYWltZWQiOmZhbHNlLCJwZW5kaW5nX2FjdGlvbl9yZXF1ZXN0X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJwZW5kaW5nX3Blcm1pdF9hcnRpZmFjdF9zaGEyNTYiOiI5NzJhODJhZjQ1NmRhNTQyYmFjNzg0NjAxODg5NjY4ODkxZDhiN2NjZDI0MjkwNDgxNmIzMjkyZTE1N2U1Mjg5IiwicGVuZGluZ19wZXJtaXRfY291bnQiOjEsInBlcm1pdF9jaGFpbl9zaGEyNTYiOiI1OWIzOTk3MWUzMDUxMDljNTQyOTk0NWE1ZmFiNDY2MGIwOWY0MWU3YWMzZmZkOTJlMzUwNmFmMDAzMzdkYTk1IiwicGVybWl0X2NvdW50IjoxLCJyZWNlaXB0X2Fic2VuY2Vfb2JzZXJ2ZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAyWiIsInJlc3VsdF9sb3NzX29ic2VydmVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMloiLCJydW5faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDEiLCJydW5fcmVxdWVzdF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwicnVuX3N0b3JlX2lkZW50aXR5X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXJlc3VsdC1sb3NzLWNsb3N1cmUtcGF5bG9hZC92MiIsInRlbmFudF9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwMiIsInRlcm1pbmFsX2NhbGxiYWNrX3JlcXVpcmVkIjp0cnVlfSwicGF5bG9hZF9zaGEyNTYiOiJhODkxYWM0Y2JhNWZkZmMxN2QwM2MxZjgwMmEyZGY4YzExZmJmMGI2MmU0ZjA0YmU2N2YxYTVjNmU2OGQwYTUzIiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1yZXN1bHQtbG9zcy1jbG9zdXJlLWFydGlmYWN0L3YyIiwic2lnbmF0dXJlIjoiZ2JzdDNuNUkzMEFBdXc2ajE3UkRFLUFlUWV5cXNKa1J1TWxyR0I3SklDTzhTbkx4ZUJIWkszNDVUYjdZY2NpVWY1SExfQjhWTnRKWkRUUndGaTNVRFEiLCJzaWduZXIiOnsiYWxnb3JpdGhtIjoiZWQyNTUxOSIsImtleV9pZCI6ImRlbGl2ZXJ5LWF1dGhvcml0eS1lZDI1NTE5LTI0ZjZlZDZhY2JmZTEwMDkiLCJwdWJsaWNfa2V5IjoiS2F5NjRVRzh5dkN5TGhxVTAwMEx4elllVW0wTC9oTElsNVM4a3lLV2JkYz0ifX0=", @@ -158,7 +173,7 @@ "uncertain_delivery": true }, "effect_state": null, - "envelope_canonical_base64": "eyJwYXlsb2FkIjp7ImFja25vd2xlZGdlZF9wZXJtaXRfY291bnQiOjAsImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA2IiwiYWRtaXNzaW9uX3BvbGljeV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYWRtaXR0ZWRfcnVudGltZV9idWlsZF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiYnVuZGxlX2FydGlmYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJidW5kbGVfY29udGVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYnVuZGxlX3ZlcnNpb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDQiLCJkZWxpdmVyeV9yZXN1bHRfbG9zc19jbG9zdXJlIjp7InBheWxvYWQiOnsiYWNrbm93bGVkZ2VkX3Blcm1pdF9jb3VudCI6MCwiYWN0dWF0aW9uX3JlcGxheV9hdXRob3JpemVkIjpmYWxzZSwiYXV0aGVudGljYXRlZF9ydW5uZXJfaWRfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsImF1dGhlbnRpY2F0ZWRfc2Vzc2lvbl9pZF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiYmxpbmRfcmV0cnlfYXV0aG9yaXplZCI6ZmFsc2UsImNoaWxkX3N0YXJ0X2V2aWRlbmNlX3NoYTI1NiI6ImVjNjkwNzkxODg2YWUyY2UwMGM0ZTUxMTU0YzNmMTIwZWE0NDE5ZWQyNjUxZTA3M2RiNTcyNDkxOGEzYjA4YzYiLCJjaGlsZF9zdGFydGVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMFoiLCJjbG9zZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAyWiIsImNsb3N1cmVfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMTEiLCJjbG9zdXJlX3JlcXVlc3Rfc2hhMjU2IjoiZDkzMGFiMWFiYzJiMmEwNGI4NDhiOTU1ZmZkZmZmYTFmYmUwNjU1YTU1MzI1ZTA0ODlhZTExZWQ4NDIwMjI2MCIsImNsb3N1cmVfc2VxdWVuY2UiOjEsImRlbGl2ZXJ5X2Fja25vd2xlZGdtZW50X2F1dGhvcml6ZWQiOmZhbHNlLCJkZWxpdmVyeV9zdGF0ZSI6IkNMT1NFRF9VTlJFU09MVkVEX1JFU1VMVF9MT1NTIiwiZGlzcGF0Y2hfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDkiLCJkaXNwYXRjaF9zZXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDEwIiwiZWZmZWN0X2Fic2VuY2VfY2xhaW1lZCI6ZmFsc2UsImV4ZWN1dGlvbl9hdXRob3JpdHlfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDgiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NpZ25lcl9zaGEyNTYiOiIyNGY2ZWQ2YWNiZmUxMDA5YzAzMGQ3Y2E1NjdjMzNjYTQ4MzA5MTE0OTgyMzZiNTU2MWE2YzgyYWJlYzVkZTI4IiwiZmluYWxfYXV0aG9yaXR5X3NlcXVlbmNlIjowLCJmaW5hbF9pbnB1dF9lZGdlX3NlcXVlbmNlIjoxLCJmaW5hbF9ydW50aW1lX2RlbGl2ZXJ5X3NlcXVlbmNlIjowLCJmbG93X3J1bl9pZF9zaGEyNTYiOiIxMWU1OTRmNDgxOTU4YzEwZTMwMTVkMGJmMDQ0N2EyMmYwNjhhOGE2NDdmNDc1ZGYxNWNlMmM3YWI0YjhmM2YxIiwiaWRlbXBvdGVuY3lfa2V5X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJtYW5hZ2VkX2Rpc3BhdGNoX2JpbmRpbmdfc2hhMjU2Ijoic2hhMjU2OmNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJuZXdfcGVybWl0X2F1dGhvcml6ZWQiOmZhbHNlLCJub3RfcmVjZWl2ZWRfY2xhaW1lZCI6ZmFsc2UsInBlbmRpbmdfYWN0aW9uX3JlcXVlc3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsInBlbmRpbmdfcGVybWl0X2FydGlmYWN0X3NoYTI1NiI6Ijk3MmE4MmFmNDU2ZGE1NDJiYWM3ODQ2MDE4ODk2Njg4OTFkOGI3Y2NkMjQyOTA0ODE2YjMyOTJlMTU3ZTUyODkiLCJwZW5kaW5nX3Blcm1pdF9jb3VudCI6MSwicGVybWl0X2NoYWluX3NoYTI1NiI6IjU5YjM5OTcxZTMwNTEwOWM1NDI5OTQ1YTVmYWI0NjYwYjA5ZjQxZTdhYzNmZmQ5MmUzNTA2YWYwMDMzN2RhOTUiLCJwZXJtaXRfY291bnQiOjEsInJlY2VpcHRfYWJzZW5jZV9vYnNlcnZlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDJaIiwicmVzdWx0X2xvc3Nfb2JzZXJ2ZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAyWiIsInJ1bl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwMSIsInJ1bl9yZXF1ZXN0X3NoYTI1NiI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJydW5fc3RvcmVfaWRlbnRpdHlfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcmVzdWx0LWxvc3MtY2xvc3VyZS1wYXlsb2FkL3YyIiwidGVuYW50X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAyIiwidGVybWluYWxfY2FsbGJhY2tfcmVxdWlyZWQiOnRydWV9LCJwYXlsb2FkX3NoYTI1NiI6ImE4OTFhYzRjYmE1ZmRmYzE3ZDAzYzFmODAyYTJkZjhjMTFmYmYwYjYyZTRmMDRiZTY3ZjFhNWM2ZTY4ZDBhNTMiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXJlc3VsdC1sb3NzLWNsb3N1cmUtYXJ0aWZhY3QvdjIiLCJzaWduYXR1cmUiOiJnYnN0M241STMwQUF1dzZqMTdSREUtQWVRZXlxc0prUnVNbHJHQjdKSUNPOFNuTHhlQkhaSzM0NVRiN1ljY2lVZjVITF9COFZOdEpaRFRSd0ZpM1VEUSIsInNpZ25lciI6eyJhbGdvcml0aG0iOiJlZDI1NTE5Iiwia2V5X2lkIjoiZGVsaXZlcnktYXV0aG9yaXR5LWVkMjU1MTktMjRmNmVkNmFjYmZlMTAwOSIsInB1YmxpY19rZXkiOiJLYXk2NFVHOHl2Q3lMaHFVMDAwTHh6WWVVbTBML2hMSWw1UzhreUtXYmRjPSJ9fSwiZWZmZWN0X2NvbnRyYWN0X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJlbnZpcm9ubWVudF9jb250cmFjdF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwiZW52aXJvbm1lbnRfZGlnZXN0IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImV2aWRlbmNlX2lkZW50aXR5X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJldmlkZW5jZV9tYW5pZmVzdHMiOnsiYXV0aG9yaXphdGlvbiI6eyJhZG1pc3Npb25fYXJ0aWZhY3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsImFkbWlzc2lvbl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwNiIsImV4ZWN1dGlvbl9hdXRob3JpdHlfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDgiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJnb3Zlcm5lZF9hdXRob3JpemF0aW9uX2lkX3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJtYW5pZmVzdF9zaGEyNTYiOiIxNWMwZTc2ZGMyZTMyMWEzODRlNTNlYzE1ZmY1M2U3NTU1N2I3Y2RlNzFjNWFkMmJhMmI5M2ZmMmU5NTgzNWE1IiwicGVybWl0X2NoYWluX3NoYTI1NiI6IjU5YjM5OTcxZTMwNTEwOWM1NDI5OTQ1YTVmYWI0NjYwYjA5ZjQxZTdhYzNmZmQ5MmUzNTA2YWYwMDMzN2RhOTUiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWF1dGhvcml6YXRpb24tZXZpZGVuY2UvdjEifSwiZWZmZWN0Ijp7ImNvbmZpcm1lZCI6MCwiZWZmZWN0X2NvbnRyYWN0X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJtYW5pZmVzdF9zaGEyNTYiOiI3ZTEyZGNhNWM0NGNmOTk4YTQ2OTM2MmI4NjJlODE2YTdkMmM4NTQxNjNmNjNlOGRlNjFmYjc5ZTk1YmE4MDA3IiwicmVjb3JkcyI6W10sInJlcXVpcmVkIjowLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWVmZmVjdC1ldmlkZW5jZS92MSIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifSwiaWRlbnRpdHkiOnsiY29uZmlybWVkIjowLCJpZGVudGl0eV9jb250cmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwibWFuaWZlc3Rfc2hhMjU2IjoiZDNhN2VhYzM0MjdkNzZmNmJjMzYwMzA3Mzg2MDkxMTlmMDdlMGQ5MWE2ZDM1OGFiY2U1YjZmMGQ2ZGY3ODY0NSIsInJlcXVpcmVkIjowLCJyZXN1bHRzIjpbXSwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1pZGVudGl0eS1ldmlkZW5jZS92MSIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifSwicG9saWN5Ijp7ImFkbWlzc2lvbl9wb2xpY3lfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImVmZmVjdF9jb250cmFjdF9zaGEyNTYiOiJlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlIiwiZW52aXJvbm1lbnRfY29udHJhY3Rfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsImVudmlyb25tZW50X2RpZ2VzdCI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJnb3Zlcm5lZF9wb2xpY3lfY29udHJhY3Rfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsImdvdmVybmVkX3J1bnRpbWVfaW5wdXRzX2RpZ2VzdCI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJpZGVudGl0eV9jb250cmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwibWFuaWZlc3Rfc2hhMjU2IjoiNGY5ODhkMDE1YmNkN2NkN2UwNWJhMDY2M2Q4OWYwYTk2OGYwZDhhY2U5OWIwOTBlYmFiZWU1MmExYzU1MDQyMSIsIm1pbmltdW1fZWZmZWN0X3RpZXIiOjEsInJ1bnRpbWVfZW52aXJvbm1lbnRfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tcG9saWN5LWV2aWRlbmNlL3YxIn0sInBvc3Rjb25kaXRpb24iOnsiY29uZmlybWVkIjowLCJtYW5pZmVzdF9zaGEyNTYiOiI1MmYwOWQ1ZDYzOWIxYzM4M2YzNzc5NjNlNDg3Y2I4OWQ4OTQxNzg1N2U0NGRhN2UzZjIzZTU1YmU3NTFlN2Y0IiwicmVjb3JkcyI6W10sInJlcXVpcmVkIjowLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLXBvc3Rjb25kaXRpb24tZXZpZGVuY2UvdjEiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIn19LCJldmlkZW5jZV9ydW5uZXJfc2lnbmVyX3NoYTI1NiI6IjU2NDc1YWE3NTQ2MzQ3NGMwMjg1ZGY1ZGJmMmJjYWI3M2RhNjUxMzU4ODM5ZTliNzc0ODFiMmVhYjEwNzcwOGMiLCJleGVjdXRpb25fYXV0aG9yaXR5X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA4IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaWduZXJfc2hhMjU2IjoiMjRmNmVkNmFjYmZlMTAwOWMwMzBkN2NhNTY3YzMzY2E0ODMwOTExNDk4MjM2YjU1NjFhNmM4MmFiZWM1ZGUyOCIsImV4ZWN1dGlvbl9vdXRjb21lIjp7ImNvbXBlbnNhdGlvbl9hY3Rpb25zIjowLCJldmlkZW5jZV9jbGFzc2VzIjpbImF1dGhvcml6YXRpb24iXSwiZXhlY3V0aW9uX2NvbXBsZXRlZCI6ZmFsc2UsImV4dGVybmFsX25ldHdvcmtfY2FsbHMiOiJub25lIiwibWFuYWdlZF9yZXN1bHRfbG9zc19ldmlkZW5jZV9zaGEyNTYiOiIyY2QwNzY0OTBjYTVlNWU4ZDlkMGJkMTQ2ZDU1OWMwNmVkNDEzYTY3ZDY5NDgxYTFhZmNjMzU0NDY0ZWNkYjA3IiwibW9kZWxfY2FsbHMiOjAsIm91dGNvbWUiOiJIQUxURUQiLCJwYXNzZWRfY29udHJhY3RzIjp7ImF1dGhvcml6YXRpb24iOjEsImVmZmVjdCI6MCwiaWRlbnRpdHkiOjAsInBvc3Rjb25kaXRpb24iOjB9LCJwb3N0Y29uZGl0aW9uX2V2aWRlbmNlIjpbXSwicHJvZHVjdGlvbl9lbGlnaWJsZSI6ZmFsc2UsInByb2ZpbGUiOiJzdGFuZGFyZCIsInF1YWxpZmljYXRpb25fZXZpZGVuY2Vfb25seSI6ZmFsc2UsInJlcXVpcmVkX2NvbnRyYWN0cyI6eyJhdXRob3JpemF0aW9uIjoxLCJlZmZlY3QiOjAsImlkZW50aXR5IjowLCJwb3N0Y29uZGl0aW9uIjowfSwidmVyc2lvbiI6Im9wZW5hZGFwdC5leGVjdXRpb24tb3V0Y29tZS92MSIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifSwiZXhlY3V0aW9uX291dGNvbWVfc2hhMjU2IjoiMzQ0OTYyZDJkZTM2ZWNiZDI5NWIxZTViZjhhZmIwNmE3ZjQ2NWQ2NTRlODFjZGZiNTIxNmZiYjYxMWYxZGE4YiIsImV4ZWN1dGlvbl9wdXJwb3NlIjoicHJvZHVjdGlvbiIsImZpbmFsX2F1dGhvcml0eV9zZXF1ZW5jZSI6MCwiZmluYWxfcnVudGltZV9kZWxpdmVyeV9zZXF1ZW5jZSI6MCwiZmxvd19ydW5faWRfc2hhMjU2IjoiMTFlNTk0ZjQ4MTk1OGMxMGUzMDE1ZDBiZjA0NDdhMjJmMDY4YThhNjQ3ZjQ3NWRmMTVjZTJjN2FiNGI4ZjNmMSIsImlkZW50aXR5X2NvbnRyYWN0X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJpc3N1ZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAzWiIsIm1hbmFnZWRfcmVzdWx0X2xvc3MiOnsiYWN0dWF0aW9uX3JlcGxheV9hdXRob3JpemVkIjpmYWxzZSwiYXV0aGVudGljYXRlZF9ydW5uZXJfaWRfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsImF1dGhlbnRpY2F0ZWRfc2Vzc2lvbl9pZF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiYmxpbmRfcmV0cnlfYXV0aG9yaXplZCI6ZmFsc2UsImNoaWxkX3JlcG9ydF9yZXRhaW5lZCI6ZmFsc2UsImNoaWxkX3N0YXJ0X2V2aWRlbmNlX3NoYTI1NiI6ImVjNjkwNzkxODg2YWUyY2UwMGM0ZTUxMTU0YzNmMTIwZWE0NDE5ZWQyNjUxZTA3M2RiNTcyNDkxOGEzYjA4YzYiLCJjaGlsZF9zdGFydGVkIjp0cnVlLCJjaGlsZF9zdGFydGVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMFoiLCJkZWxpdmVyeV9yZXN1bHRfbG9zc19jbG9zdXJlX2FydGlmYWN0X3NoYTI1NiI6IjY1ZDBkODJkNTc3YTUzMjMwMjJiMmFmY2UxYTI2YTIxNmE1MmQyMWVmOTgyZTA1NDBjMjY2ZjMwNjNmYmM3OTciLCJkZWxpdmVyeV9zdGF0ZSI6IkNMT1NFRF9VTlJFU09MVkVEX1JFU1VMVF9MT1NTIiwiZGlzcGF0Y2hfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDkiLCJkaXNwYXRjaF9zZXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDEwIiwiZWZmZWN0X2Fic2VuY2VfY2xhaW1lZCI6ZmFsc2UsImV2aWRlbmNlX3NoYTI1NiI6IjJjZDA3NjQ5MGNhNWU1ZThkOWQwYmQxNDZkNTU5YzA2ZWQ0MTNhNjdkNjk0ODFhMWFmY2MzNTQ0NjRlY2RiMDciLCJleGVjdXRpb25fYXV0aG9yaXR5X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA4IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaWduZXJfc2hhMjU2IjoiMjRmNmVkNmFjYmZlMTAwOWMwMzBkN2NhNTY3YzMzY2E0ODMwOTExNDk4MjM2YjU1NjFhNmM4MmFiZWM1ZGUyOCIsImZsb3dfcnVuX2lkX3NoYTI1NiI6IjExZTU5NGY0ODE5NThjMTBlMzAxNWQwYmYwNDQ3YTIyZjA2OGE4YTY0N2Y0NzVkZjE1Y2UyYzdhYjRiOGYzZjEiLCJpZGVtcG90ZW5jeV9rZXlfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsImxvc3NfY29kZSI6InJlcG9ydF9taXNzaW5nIiwibWFuYWdlZF9kaXNwYXRjaF9iaW5kaW5nX3NoYTI1NiI6InNoYTI1NjpjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwibm90X3JlY2VpdmVkX2NsYWltZWQiOmZhbHNlLCJvYnNlcnZlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDJaIiwicGVuZGluZ19hY3Rpb25fcmVxdWVzdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwicGVuZGluZ19wZXJtaXRfYXJ0aWZhY3Rfc2hhMjU2IjoiOTcyYTgyYWY0NTZkYTU0MmJhYzc4NDYwMTg4OTY2ODg5MWQ4YjdjY2QyNDI5MDQ4MTZiMzI5MmUxNTdlNTI4OSIsInJlcG9ydF9wcm92ZW5hbmNlIjoib3V0ZXJfcnVubmVyX3JlY292ZXJ5IiwicnVuX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAxIiwicnVuX3JlcXVlc3Rfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsInJ1bl9zdG9yZV9pZGVudGl0eV9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQubWFuYWdlZC1yZXN1bHQtbG9zcy92MSJ9LCJwZW5kaW5nX3Blcm1pdF9jb3VudCI6MSwicGVybWl0X2NoYWluIjp7ImVudHJpZXMiOltdLCJwZW5kaW5nIjp7ImFjdHVhdGlvbl9yZXBsYXlfYXV0aG9yaXplZCI6ZmFsc2UsImRlbGl2ZXJ5X3JlY2VpcHRfYXJ0aWZhY3QiOm51bGwsImRlbGl2ZXJ5X3JlY2VpcHRfYXJ0aWZhY3Rfc2hhMjU2IjpudWxsLCJkZWxpdmVyeV9zdGF0ZSI6IlVOUkVTT0xWRUQiLCJwZXJtaXRfYXJ0aWZhY3QiOnsicGF5bG9hZCI6eyJhY3Rpb25fcmVxdWVzdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2FydGlmYWN0X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJhdXRob3JpdHlfc2VxdWVuY2UiOjAsImVudmlyb25tZW50X2RpZ2VzdCI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJldmlkZW5jZV9pZGVudGl0eV9zaGEyNTYiOiJlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlIiwiZXhlY3V0aW9uX2F1dGhvcml0eV9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOCIsImV4ZWN1dGlvbl9hdXRob3JpdHlfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImZsb3dfcnVuX2lkX3NoYTI1NiI6IjExZTU5NGY0ODE5NThjMTBlMzAxNWQwYmYwNDQ3YTIyZjA2OGE4YTY0N2Y0NzVkZjE1Y2UyYzdhYjRiOGYzZjEiLCJpbnB1dF9lZGdlX3NlcXVlbmNlIjoxLCJpc3N1ZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAwWiIsInBlcm1pdF9pZCI6InBlcm1pdDoxIiwicXVhbGlmaWNhdGlvbl9zaWduZXJfcmVnaXN0cnlfY2hlY2tlZF9hdCI6IjIwMjYtMDgtMThUMTE6NTk6MzBaIiwicXVhbGlmaWNhdGlvbl9zaWduZXJfcmVnaXN0cnlfZXhwaXJlc19hdCI6IjIwMjYtMDgtMjBUMTE6MDA6MDBaIiwicXVhbGlmaWNhdGlvbl9zaWduZXJfcmVnaXN0cnlfcmV2aXNpb24iOjcsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJydW5faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDEiLCJydW5fcmVxdWVzdF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1wZXJtaXQtcGF5bG9hZC92MiJ9LCJwYXlsb2FkX3NoYTI1NiI6ImM4N2Y1NzUxYWE5YjI3OWNjZTIzYWExNzhhZmY5NTZlMTlmNjkwZmNkMmY5ZjcwZTBkOTk5NzgyYTY5MGQ2YjgiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXBlcm1pdC1hcnRpZmFjdC92MiIsInNpZ25hdHVyZSI6IjBCeUhncUR4UVpybmdMSUYtNnRaT3E5bFhhbWNBUUMwZG9VVG5lS05QZVMtU3lvT2JReU9rQXVQRks1UFljTnpPYlp4Z3NnQUxkV2FJX3NhVUNwbEJnIiwic2lnbmVyIjp7ImFsZ29yaXRobSI6ImVkMjU1MTkiLCJrZXlfaWQiOiJkZWxpdmVyeS1hdXRob3JpdHktZWQyNTUxOS0yNGY2ZWQ2YWNiZmUxMDA5IiwicHVibGljX2tleSI6IktheTY0VUc4eXZDeUxocVUwMDBMeHpZZVVtMEwvaExJbDVTOGt5S1diZGM9In19LCJwZXJtaXRfYXJ0aWZhY3Rfc2hhMjU2IjoiOTcyYTgyYWY0NTZkYTU0MmJhYzc4NDYwMTg4OTY2ODg5MWQ4YjdjY2QyNDI5MDQ4MTZiMzI5MmUxNTdlNTI4OSIsInJlY2VpcHRfYWJzZW5jZV9vYnNlcnZlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDJaIiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1wZW5kaW5nLXBlcm1pdC92MiJ9LCJwZXJtaXRfY2hhaW5fc2hhMjU2IjoiNTliMzk5NzFlMzA1MTA5YzU0Mjk5NDVhNWZhYjQ2NjBiMDlmNDFlN2FjM2ZmZDkyZTM1MDZhZjAwMzM3ZGE5NSIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcGVybWl0LWNoYWluL3YyIn0sInBlcm1pdF9jb3VudCI6MSwicXVhbGlmaWNhdGlvbl9zaWduZXJfcmVnaXN0cnlfcmV2aXNpb24iOjcsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJydW5faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDEiLCJydW5fcmVjZWlwdCI6eyJhdXRob3JpemF0aW9uX2NvbmZpcm1lZCI6MSwiYXV0aG9yaXphdGlvbl9yZXF1aXJlZCI6MSwiYnVuZGxlX2RpZ2VzdCI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJkdXJhdGlvbl9tcyI6MCwiZWZmZWN0X3RpZXJfcmVhY2hlZCI6Im5vbmUiLCJlZmZlY3RzX2NvbmZpcm1lZCI6MCwiZWZmZWN0c19yZXF1aXJlZCI6MCwiZXN0X2Nvc3RfbWljcm91c2QiOjAsImV2aWRlbmNlX2NsYXNzZXMiOlsiYXV0aG9yaXphdGlvbiJdLCJleHRlcm5hbF9uZXR3b3JrX2NhbGxzIjoibm9uZSIsImdlbmVyYXRlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDBaIiwiaGVhbHMiOjAsImlkZW50aXR5X2FwcGxpY2FibGUiOjAsImlkZW50aXR5X2FybWVkIjowLCJpZGVudGl0eV9jb25maXJtZWQiOjAsImlkZW50aXR5X3JlcXVpcmVkIjowLCJtYW5hZ2VkX3Jlc3VsdF9sb3NzX2V2aWRlbmNlX3NoYTI1NiI6IjJjZDA3NjQ5MGNhNWU1ZThkOWQwYmQxNDZkNTU5YzA2ZWQ0MTNhNjdkNjk0ODFhMWFmY2MzNTQ0NjRlY2RiMDciLCJtb2RlbF9jYWxscyI6MCwib3V0Y29tZSI6IkhBTFRFRCIsIm92ZXJfaGFsdF9jb3VudCI6MCwicG9zdGNvbmRpdGlvbnNfY29uZmlybWVkIjowLCJwb3N0Y29uZGl0aW9uc19yZXF1aXJlZCI6MCwicHJvZHVjdGlvbl9lbGlnaWJsZSI6ZmFsc2UsInByb2ZpbGUiOiJzdGFuZGFyZCIsInByb3ZlbmFuY2UiOiJwcm9kdWN0aW9uIiwicmVjZWlwdF9idWlsZGVyX3ZlcnNpb24iOiIxLjIuMyIsInJ1bmdfaGlzdG9ncmFtIjp7fSwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1ydW4tcmVjZWlwdC92MSIsInNvdXJjZV9yZWNlaXB0X2RpZ2VzdCI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJzb3VyY2VfcmVjZWlwdF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwic291cmNlX3NjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnJ1bi1yZXBvcnQvdjEiLCJzdGVwc19vayI6MCwic3RlcHNfdG90YWwiOjEsInN1YnN0cmF0ZSI6IndlYiIsInRyYW5zYWN0aW9uX291dGNvbWUiOiJSRUNPTkNJTElBVElPTl9SRVFVSVJFRCJ9LCJydW5fcmVjZWlwdF9zaGEyNTYiOiIwOTU1YjBlNzllMDlmYjFlMzRiZGI5OGE4ZDEzMGE4YzEyNjNiZTg2Y2E5ZDU0ODYyZDdkMzRhYmZmNGNkOWI0IiwicnVuX3JlcG9ydF9vYmplY3Rfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsInJ1bl9yZXBvcnRfb2JqZWN0X3ZlcnNpb24iOiJ2ZXJzaW9uOm1hbmFnZWQtcmVzdWx0LWxvc3M6MSIsInJ1bl9yZXBvcnRfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsInJ1bnRpbWVfZW52aXJvbm1lbnRfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsInJ1bnRpbWVfc3Vic3RyYXRlIjoid2ViIiwicnVudGltZV92YWxpZGF0aW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA1Iiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi10ZXJtaW5hbC12ZXJpZmljYXRpb24vdjIiLCJ0ZW5hbnRfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDIiLCJ0ZXJtaW5hbF9zZXF1ZW5jZSI6MSwidmVyaWZpZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAyWiIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJ3b3JrZmxvd19pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwMyIsIndvcmtmbG93X3ZlcnNpb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDQifSwic2lnbmF0dXJlIjoidUd0S1hWY2pxS0tyTEhPMm44dGhmYUdsbDk5bHpFeHF0MlcyUHpSZlQyOG9udXpzNjk5VGxtMDVkSzlCVTlCZC16WDM3NEJDcjBtVktIeHJ2WnRsQlEiLCJzaWduZXIiOnsiYWxnb3JpdGhtIjoiZWQyNTUxOSIsImtleV9pZCI6ImV2aWRlbmNlLXJ1bm5lci1lZDI1NTE5LTU2NDc1YWE3NTQ2MzQ3NGMiLCJwdWJsaWNfa2V5IjoiQTZFSHYvUE9FTDRkY04wWTUwdkFtV2ZrMWpDYnBRMWZIZHlHWkJKVk1iZz0ifX0=", + "envelope_canonical_base64": "eyJwYXlsb2FkIjp7ImFja25vd2xlZGdlZF9wZXJtaXRfY291bnQiOjAsImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA2IiwiYWRtaXNzaW9uX3BvbGljeV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYWRtaXR0ZWRfcnVudGltZV9idWlsZF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiYnVuZGxlX2FydGlmYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJidW5kbGVfY29udGVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYnVuZGxlX3ZlcnNpb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDQiLCJkZWxpdmVyeV9yZXN1bHRfbG9zc19jbG9zdXJlIjp7InBheWxvYWQiOnsiYWNrbm93bGVkZ2VkX3Blcm1pdF9jb3VudCI6MCwiYWN0dWF0aW9uX3JlcGxheV9hdXRob3JpemVkIjpmYWxzZSwiYXV0aGVudGljYXRlZF9ydW5uZXJfaWRfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsImF1dGhlbnRpY2F0ZWRfc2Vzc2lvbl9pZF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiYmxpbmRfcmV0cnlfYXV0aG9yaXplZCI6ZmFsc2UsImNoaWxkX3N0YXJ0X2V2aWRlbmNlX3NoYTI1NiI6ImVjNjkwNzkxODg2YWUyY2UwMGM0ZTUxMTU0YzNmMTIwZWE0NDE5ZWQyNjUxZTA3M2RiNTcyNDkxOGEzYjA4YzYiLCJjaGlsZF9zdGFydGVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMFoiLCJjbG9zZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAyWiIsImNsb3N1cmVfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMTEiLCJjbG9zdXJlX3JlcXVlc3Rfc2hhMjU2IjoiZDkzMGFiMWFiYzJiMmEwNGI4NDhiOTU1ZmZkZmZmYTFmYmUwNjU1YTU1MzI1ZTA0ODlhZTExZWQ4NDIwMjI2MCIsImNsb3N1cmVfc2VxdWVuY2UiOjEsImRlbGl2ZXJ5X2Fja25vd2xlZGdtZW50X2F1dGhvcml6ZWQiOmZhbHNlLCJkZWxpdmVyeV9zdGF0ZSI6IkNMT1NFRF9VTlJFU09MVkVEX1JFU1VMVF9MT1NTIiwiZGlzcGF0Y2hfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDkiLCJkaXNwYXRjaF9zZXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDEwIiwiZWZmZWN0X2Fic2VuY2VfY2xhaW1lZCI6ZmFsc2UsImV4ZWN1dGlvbl9hdXRob3JpdHlfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDgiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NpZ25lcl9zaGEyNTYiOiIyNGY2ZWQ2YWNiZmUxMDA5YzAzMGQ3Y2E1NjdjMzNjYTQ4MzA5MTE0OTgyMzZiNTU2MWE2YzgyYWJlYzVkZTI4IiwiZmluYWxfYXV0aG9yaXR5X3NlcXVlbmNlIjowLCJmaW5hbF9pbnB1dF9lZGdlX3NlcXVlbmNlIjoxLCJmaW5hbF9ydW50aW1lX2RlbGl2ZXJ5X3NlcXVlbmNlIjowLCJmbG93X3J1bl9pZF9zaGEyNTYiOiIxMWU1OTRmNDgxOTU4YzEwZTMwMTVkMGJmMDQ0N2EyMmYwNjhhOGE2NDdmNDc1ZGYxNWNlMmM3YWI0YjhmM2YxIiwiaWRlbXBvdGVuY3lfa2V5X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJtYW5hZ2VkX2Rpc3BhdGNoX2JpbmRpbmdfc2hhMjU2Ijoic2hhMjU2OmNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJuZXdfcGVybWl0X2F1dGhvcml6ZWQiOmZhbHNlLCJub3RfcmVjZWl2ZWRfY2xhaW1lZCI6ZmFsc2UsInBlbmRpbmdfYWN0aW9uX3JlcXVlc3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsInBlbmRpbmdfcGVybWl0X2FydGlmYWN0X3NoYTI1NiI6Ijk3MmE4MmFmNDU2ZGE1NDJiYWM3ODQ2MDE4ODk2Njg4OTFkOGI3Y2NkMjQyOTA0ODE2YjMyOTJlMTU3ZTUyODkiLCJwZW5kaW5nX3Blcm1pdF9jb3VudCI6MSwicGVybWl0X2NoYWluX3NoYTI1NiI6IjU5YjM5OTcxZTMwNTEwOWM1NDI5OTQ1YTVmYWI0NjYwYjA5ZjQxZTdhYzNmZmQ5MmUzNTA2YWYwMDMzN2RhOTUiLCJwZXJtaXRfY291bnQiOjEsInJlY2VpcHRfYWJzZW5jZV9vYnNlcnZlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDJaIiwicmVzdWx0X2xvc3Nfb2JzZXJ2ZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAyWiIsInJ1bl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwMSIsInJ1bl9yZXF1ZXN0X3NoYTI1NiI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJydW5fc3RvcmVfaWRlbnRpdHlfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcmVzdWx0LWxvc3MtY2xvc3VyZS1wYXlsb2FkL3YyIiwidGVuYW50X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAyIiwidGVybWluYWxfY2FsbGJhY2tfcmVxdWlyZWQiOnRydWV9LCJwYXlsb2FkX3NoYTI1NiI6ImE4OTFhYzRjYmE1ZmRmYzE3ZDAzYzFmODAyYTJkZjhjMTFmYmYwYjYyZTRmMDRiZTY3ZjFhNWM2ZTY4ZDBhNTMiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXJlc3VsdC1sb3NzLWNsb3N1cmUtYXJ0aWZhY3QvdjIiLCJzaWduYXR1cmUiOiJnYnN0M241STMwQUF1dzZqMTdSREUtQWVRZXlxc0prUnVNbHJHQjdKSUNPOFNuTHhlQkhaSzM0NVRiN1ljY2lVZjVITF9COFZOdEpaRFRSd0ZpM1VEUSIsInNpZ25lciI6eyJhbGdvcml0aG0iOiJlZDI1NTE5Iiwia2V5X2lkIjoiZGVsaXZlcnktYXV0aG9yaXR5LWVkMjU1MTktMjRmNmVkNmFjYmZlMTAwOSIsInB1YmxpY19rZXkiOiJLYXk2NFVHOHl2Q3lMaHFVMDAwTHh6WWVVbTBML2hMSWw1UzhreUtXYmRjPSJ9fSwiZWZmZWN0X2NvbnRyYWN0X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJlbnZpcm9ubWVudF9jb250cmFjdF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwiZW52aXJvbm1lbnRfZGlnZXN0IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImV2aWRlbmNlX2lkZW50aXR5X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJldmlkZW5jZV9tYW5pZmVzdHMiOnsiYXV0aG9yaXphdGlvbiI6eyJhZG1pc3Npb25fYXJ0aWZhY3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsImFkbWlzc2lvbl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwNiIsImV4ZWN1dGlvbl9hdXRob3JpdHlfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDgiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJnb3Zlcm5lZF9hdXRob3JpemF0aW9uX2lkX3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJtYW5pZmVzdF9zaGEyNTYiOiIxNWMwZTc2ZGMyZTMyMWEzODRlNTNlYzE1ZmY1M2U3NTU1N2I3Y2RlNzFjNWFkMmJhMmI5M2ZmMmU5NTgzNWE1IiwicGVybWl0X2NoYWluX3NoYTI1NiI6IjU5YjM5OTcxZTMwNTEwOWM1NDI5OTQ1YTVmYWI0NjYwYjA5ZjQxZTdhYzNmZmQ5MmUzNTA2YWYwMDMzN2RhOTUiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWF1dGhvcml6YXRpb24tZXZpZGVuY2UvdjEifSwiZWZmZWN0Ijp7ImNvbmZpcm1lZCI6MCwiZWZmZWN0X2NvbnRyYWN0X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJtYW5pZmVzdF9zaGEyNTYiOiI3ZTEyZGNhNWM0NGNmOTk4YTQ2OTM2MmI4NjJlODE2YTdkMmM4NTQxNjNmNjNlOGRlNjFmYjc5ZTk1YmE4MDA3IiwicmVjb3JkcyI6W10sInJlcXVpcmVkIjowLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWVmZmVjdC1ldmlkZW5jZS92MSIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifSwiaWRlbnRpdHkiOnsiY29uZmlybWVkIjowLCJpZGVudGl0eV9jb250cmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwibWFuaWZlc3Rfc2hhMjU2IjoiZDNhN2VhYzM0MjdkNzZmNmJjMzYwMzA3Mzg2MDkxMTlmMDdlMGQ5MWE2ZDM1OGFiY2U1YjZmMGQ2ZGY3ODY0NSIsInJlcXVpcmVkIjowLCJyZXN1bHRzIjpbXSwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1pZGVudGl0eS1ldmlkZW5jZS92MSIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifSwicG9saWN5Ijp7ImFkbWlzc2lvbl9wb2xpY3lfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImVmZmVjdF9jb250cmFjdF9zaGEyNTYiOiJlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlIiwiZW52aXJvbm1lbnRfY29udHJhY3Rfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsImVudmlyb25tZW50X2RpZ2VzdCI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJnb3Zlcm5lZF9wb2xpY3lfY29udHJhY3Rfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsImdvdmVybmVkX3J1bnRpbWVfaW5wdXRzX2RpZ2VzdCI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJpZGVudGl0eV9jb250cmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwibWFuaWZlc3Rfc2hhMjU2IjoiNGY5ODhkMDE1YmNkN2NkN2UwNWJhMDY2M2Q4OWYwYTk2OGYwZDhhY2U5OWIwOTBlYmFiZWU1MmExYzU1MDQyMSIsIm1pbmltdW1fZWZmZWN0X3RpZXIiOjEsInJ1bnRpbWVfZW52aXJvbm1lbnRfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tcG9saWN5LWV2aWRlbmNlL3YxIn0sInBvc3Rjb25kaXRpb24iOnsiY29uZmlybWVkIjowLCJtYW5pZmVzdF9zaGEyNTYiOiI1MmYwOWQ1ZDYzOWIxYzM4M2YzNzc5NjNlNDg3Y2I4OWQ4OTQxNzg1N2U0NGRhN2UzZjIzZTU1YmU3NTFlN2Y0IiwicmVjb3JkcyI6W10sInJlcXVpcmVkIjowLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLXBvc3Rjb25kaXRpb24tZXZpZGVuY2UvdjEiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIn19LCJldmlkZW5jZV9ydW5uZXJfc2lnbmVyX3NoYTI1NiI6IjU2NDc1YWE3NTQ2MzQ3NGMwMjg1ZGY1ZGJmMmJjYWI3M2RhNjUxMzU4ODM5ZTliNzc0ODFiMmVhYjEwNzcwOGMiLCJleGVjdXRpb25fYXV0aG9yaXR5X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA4IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaWduZXJfc2hhMjU2IjoiMjRmNmVkNmFjYmZlMTAwOWMwMzBkN2NhNTY3YzMzY2E0ODMwOTExNDk4MjM2YjU1NjFhNmM4MmFiZWM1ZGUyOCIsImV4ZWN1dGlvbl9vdXRjb21lIjp7ImNvbXBlbnNhdGlvbl9hY3Rpb25zIjowLCJldmlkZW5jZV9jbGFzc2VzIjpbImF1dGhvcml6YXRpb24iXSwiZXhlY3V0aW9uX2NvbXBsZXRlZCI6ZmFsc2UsImV4dGVybmFsX25ldHdvcmtfY2FsbHMiOiJvYnNlcnZlZCIsIm1hbmFnZWRfcmVzdWx0X2xvc3NfZXZpZGVuY2Vfc2hhMjU2IjoiMmNkMDc2NDkwY2E1ZTVlOGQ5ZDBiZDE0NmQ1NTljMDZlZDQxM2E2N2Q2OTQ4MWExYWZjYzM1NDQ2NGVjZGIwNyIsIm1vZGVsX2NhbGxzIjowLCJvdXRjb21lIjoiSEFMVEVEIiwicGFzc2VkX2NvbnRyYWN0cyI6eyJhdXRob3JpemF0aW9uIjoxLCJlZmZlY3QiOjAsImlkZW50aXR5IjowLCJwb3N0Y29uZGl0aW9uIjowfSwicG9zdGNvbmRpdGlvbl9ldmlkZW5jZSI6W10sInByb2R1Y3Rpb25fZWxpZ2libGUiOmZhbHNlLCJwcm9maWxlIjoic3RhbmRhcmQiLCJxdWFsaWZpY2F0aW9uX2V2aWRlbmNlX29ubHkiOmZhbHNlLCJyZXF1aXJlZF9jb250cmFjdHMiOnsiYXV0aG9yaXphdGlvbiI6MSwiZWZmZWN0IjowLCJpZGVudGl0eSI6MCwicG9zdGNvbmRpdGlvbiI6MH0sInZlcnNpb24iOiJvcGVuYWRhcHQuZXhlY3V0aW9uLW91dGNvbWUvdjEiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIn0sImV4ZWN1dGlvbl9vdXRjb21lX3NoYTI1NiI6IjRmNzdkMTRkNjdjZjQ1OTRmMjE2MjNhZWUxMTUzMTg4Mzk1ODYyNjVmZjFkY2FiNzI3N2Q3NmZlMTU5NDIyMDMiLCJleGVjdXRpb25fcHVycG9zZSI6InByb2R1Y3Rpb24iLCJmaW5hbF9hdXRob3JpdHlfc2VxdWVuY2UiOjAsImZpbmFsX3J1bnRpbWVfZGVsaXZlcnlfc2VxdWVuY2UiOjAsImZsb3dfcnVuX2lkX3NoYTI1NiI6IjExZTU5NGY0ODE5NThjMTBlMzAxNWQwYmYwNDQ3YTIyZjA2OGE4YTY0N2Y0NzVkZjE1Y2UyYzdhYjRiOGYzZjEiLCJpZGVudGl0eV9jb250cmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiaXNzdWVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowM1oiLCJtYW5hZ2VkX3Jlc3VsdF9sb3NzIjp7ImFjdHVhdGlvbl9yZXBsYXlfYXV0aG9yaXplZCI6ZmFsc2UsImF1dGhlbnRpY2F0ZWRfcnVubmVyX2lkX3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJhdXRoZW50aWNhdGVkX3Nlc3Npb25faWRfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsImJsaW5kX3JldHJ5X2F1dGhvcml6ZWQiOmZhbHNlLCJjaGlsZF9yZXBvcnRfcmV0YWluZWQiOmZhbHNlLCJjaGlsZF9zdGFydF9ldmlkZW5jZV9zaGEyNTYiOiJlYzY5MDc5MTg4NmFlMmNlMDBjNGU1MTE1NGMzZjEyMGVhNDQxOWVkMjY1MWUwNzNkYjU3MjQ5MThhM2IwOGM2IiwiY2hpbGRfc3RhcnRlZCI6dHJ1ZSwiY2hpbGRfc3RhcnRlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDBaIiwiZGVsaXZlcnlfcmVzdWx0X2xvc3NfY2xvc3VyZV9hcnRpZmFjdF9zaGEyNTYiOiI2NWQwZDgyZDU3N2E1MzIzMDIyYjJhZmNlMWEyNmEyMTZhNTJkMjFlZjk4MmUwNTQwYzI2NmYzMDYzZmJjNzk3IiwiZGVsaXZlcnlfc3RhdGUiOiJDTE9TRURfVU5SRVNPTFZFRF9SRVNVTFRfTE9TUyIsImRpc3BhdGNoX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA5IiwiZGlzcGF0Y2hfc2Vzc2lvbl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAxMCIsImVmZmVjdF9hYnNlbmNlX2NsYWltZWQiOmZhbHNlLCJldmlkZW5jZV9zaGEyNTYiOiIyY2QwNzY0OTBjYTVlNWU4ZDlkMGJkMTQ2ZDU1OWMwNmVkNDEzYTY3ZDY5NDgxYTFhZmNjMzU0NDY0ZWNkYjA3IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOCIsImV4ZWN1dGlvbl9hdXRob3JpdHlfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImV4ZWN1dGlvbl9hdXRob3JpdHlfc2lnbmVyX3NoYTI1NiI6IjI0ZjZlZDZhY2JmZTEwMDljMDMwZDdjYTU2N2MzM2NhNDgzMDkxMTQ5ODIzNmI1NTYxYTZjODJhYmVjNWRlMjgiLCJmbG93X3J1bl9pZF9zaGEyNTYiOiIxMWU1OTRmNDgxOTU4YzEwZTMwMTVkMGJmMDQ0N2EyMmYwNjhhOGE2NDdmNDc1ZGYxNWNlMmM3YWI0YjhmM2YxIiwiaWRlbXBvdGVuY3lfa2V5X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJsb3NzX2NvZGUiOiJyZXBvcnRfbWlzc2luZyIsIm1hbmFnZWRfZGlzcGF0Y2hfYmluZGluZ19zaGEyNTYiOiJzaGEyNTY6Y2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsIm5vdF9yZWNlaXZlZF9jbGFpbWVkIjpmYWxzZSwib2JzZXJ2ZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAyWiIsInBlbmRpbmdfYWN0aW9uX3JlcXVlc3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsInBlbmRpbmdfcGVybWl0X2FydGlmYWN0X3NoYTI1NiI6Ijk3MmE4MmFmNDU2ZGE1NDJiYWM3ODQ2MDE4ODk2Njg4OTFkOGI3Y2NkMjQyOTA0ODE2YjMyOTJlMTU3ZTUyODkiLCJyZXBvcnRfcHJvdmVuYW5jZSI6Im91dGVyX3J1bm5lcl9yZWNvdmVyeSIsInJ1bl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwMSIsInJ1bl9yZXF1ZXN0X3NoYTI1NiI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJydW5fc3RvcmVfaWRlbnRpdHlfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0Lm1hbmFnZWQtcmVzdWx0LWxvc3MvdjEifSwicGVuZGluZ19wZXJtaXRfY291bnQiOjEsInBlcm1pdF9jaGFpbiI6eyJlbnRyaWVzIjpbXSwicGVuZGluZyI6eyJhY3R1YXRpb25fcmVwbGF5X2F1dGhvcml6ZWQiOmZhbHNlLCJkZWxpdmVyeV9yZWNlaXB0X2FydGlmYWN0IjpudWxsLCJkZWxpdmVyeV9yZWNlaXB0X2FydGlmYWN0X3NoYTI1NiI6bnVsbCwiZGVsaXZlcnlfc3RhdGUiOiJVTlJFU09MVkVEIiwicGVybWl0X2FydGlmYWN0Ijp7InBheWxvYWQiOnsiYWN0aW9uX3JlcXVlc3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYXV0aG9yaXR5X3NlcXVlbmNlIjowLCJlbnZpcm9ubWVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXZpZGVuY2VfaWRlbnRpdHlfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImV4ZWN1dGlvbl9hdXRob3JpdHlfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDgiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJmbG93X3J1bl9pZF9zaGEyNTYiOiIxMWU1OTRmNDgxOTU4YzEwZTMwMTVkMGJmMDQ0N2EyMmYwNjhhOGE2NDdmNDc1ZGYxNWNlMmM3YWI0YjhmM2YxIiwiaW5wdXRfZWRnZV9zZXF1ZW5jZSI6MSwiaXNzdWVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMFoiLCJwZXJtaXRfaWQiOiJwZXJtaXQ6MSIsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X2NoZWNrZWRfYXQiOiIyMDI2LTA4LTE4VDExOjU5OjMwWiIsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X2V4cGlyZXNfYXQiOiIyMDI2LTA4LTIwVDExOjAwOjAwWiIsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X3JldmlzaW9uIjo3LCJxdWFsaWZpY2F0aW9uX3NpZ25lcl9yZWdpc3RyeV9zaGEyNTYiOiJlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlIiwicnVuX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAxIiwicnVuX3JlcXVlc3Rfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcGVybWl0LXBheWxvYWQvdjIifSwicGF5bG9hZF9zaGEyNTYiOiJjODdmNTc1MWFhOWIyNzljY2UyM2FhMTc4YWZmOTU2ZTE5ZjY5MGZjZDJmOWY3MGUwZDk5OTc4MmE2OTBkNmI4Iiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1wZXJtaXQtYXJ0aWZhY3QvdjIiLCJzaWduYXR1cmUiOiIwQnlIZ3FEeFFacm5nTElGLTZ0Wk9xOWxYYW1jQVFDMGRvVVRuZUtOUGVTLVN5b09iUXlPa0F1UEZLNVBZY056T2JaeGdzZ0FMZFdhSV9zYVVDcGxCZyIsInNpZ25lciI6eyJhbGdvcml0aG0iOiJlZDI1NTE5Iiwia2V5X2lkIjoiZGVsaXZlcnktYXV0aG9yaXR5LWVkMjU1MTktMjRmNmVkNmFjYmZlMTAwOSIsInB1YmxpY19rZXkiOiJLYXk2NFVHOHl2Q3lMaHFVMDAwTHh6WWVVbTBML2hMSWw1UzhreUtXYmRjPSJ9fSwicGVybWl0X2FydGlmYWN0X3NoYTI1NiI6Ijk3MmE4MmFmNDU2ZGE1NDJiYWM3ODQ2MDE4ODk2Njg4OTFkOGI3Y2NkMjQyOTA0ODE2YjMyOTJlMTU3ZTUyODkiLCJyZWNlaXB0X2Fic2VuY2Vfb2JzZXJ2ZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAyWiIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcGVuZGluZy1wZXJtaXQvdjIifSwicGVybWl0X2NoYWluX3NoYTI1NiI6IjU5YjM5OTcxZTMwNTEwOWM1NDI5OTQ1YTVmYWI0NjYwYjA5ZjQxZTdhYzNmZmQ5MmUzNTA2YWYwMDMzN2RhOTUiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXBlcm1pdC1jaGFpbi92MiJ9LCJwZXJtaXRfY291bnQiOjEsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X3JldmlzaW9uIjo3LCJxdWFsaWZpY2F0aW9uX3NpZ25lcl9yZWdpc3RyeV9zaGEyNTYiOiJlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlIiwicnVuX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAxIiwicnVuX3JlY2VpcHQiOnsiYXV0aG9yaXphdGlvbl9jb25maXJtZWQiOjEsImF1dGhvcml6YXRpb25fcmVxdWlyZWQiOjEsImJ1bmRsZV9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZHVyYXRpb25fbXMiOjAsImVmZmVjdF90aWVyX3JlYWNoZWQiOiJub25lIiwiZWZmZWN0c19jb25maXJtZWQiOjAsImVmZmVjdHNfcmVxdWlyZWQiOjAsImVzdF9jb3N0X21pY3JvdXNkIjowLCJldmlkZW5jZV9jbGFzc2VzIjpbImF1dGhvcml6YXRpb24iXSwiZXh0ZXJuYWxfbmV0d29ya19jYWxscyI6Im9ic2VydmVkIiwiZ2VuZXJhdGVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMFoiLCJoZWFscyI6MCwiaWRlbnRpdHlfYXBwbGljYWJsZSI6MCwiaWRlbnRpdHlfYXJtZWQiOjAsImlkZW50aXR5X2NvbmZpcm1lZCI6MCwiaWRlbnRpdHlfcmVxdWlyZWQiOjAsIm1hbmFnZWRfcmVzdWx0X2xvc3NfZXZpZGVuY2Vfc2hhMjU2IjoiMmNkMDc2NDkwY2E1ZTVlOGQ5ZDBiZDE0NmQ1NTljMDZlZDQxM2E2N2Q2OTQ4MWExYWZjYzM1NDQ2NGVjZGIwNyIsIm1vZGVsX2NhbGxzIjowLCJvdXRjb21lIjoiSEFMVEVEIiwib3Zlcl9oYWx0X2NvdW50IjowLCJwb3N0Y29uZGl0aW9uc19jb25maXJtZWQiOjAsInBvc3Rjb25kaXRpb25zX3JlcXVpcmVkIjowLCJwcm9kdWN0aW9uX2VsaWdpYmxlIjpmYWxzZSwicHJvZmlsZSI6InN0YW5kYXJkIiwicHJvdmVuYW5jZSI6InByb2R1Y3Rpb24iLCJyZWNlaXB0X2J1aWxkZXJfdmVyc2lvbiI6IjEuMi4zIiwicnVuZ19oaXN0b2dyYW0iOnt9LCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLXJ1bi1yZWNlaXB0L3YxIiwic291cmNlX3JlY2VpcHRfZGlnZXN0IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsInNvdXJjZV9yZWNlaXB0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJzb3VyY2Vfc2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucnVuLXJlcG9ydC92MSIsInN0ZXBzX29rIjowLCJzdGVwc190b3RhbCI6MSwic3Vic3RyYXRlIjoid2ViIiwidHJhbnNhY3Rpb25fb3V0Y29tZSI6IlJFQ09OQ0lMSUFUSU9OX1JFUVVJUkVEIn0sInJ1bl9yZWNlaXB0X3NoYTI1NiI6IjMwMDllZTJlMGRlMmIzZmM0MDZkNDkxMWFhY2U1OTY0MjBhZWFhZDgyZjZhOGE1MmVlY2MyNjQ4MDAzZTI0NTkiLCJydW5fcmVwb3J0X29iamVjdF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwicnVuX3JlcG9ydF9vYmplY3RfdmVyc2lvbiI6InZlcnNpb246bWFuYWdlZC1yZXN1bHQtbG9zczoxIiwicnVuX3JlcG9ydF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwicnVudGltZV9lbnZpcm9ubWVudF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwicnVudGltZV9zdWJzdHJhdGUiOiJ3ZWIiLCJydW50aW1lX3ZhbGlkYXRpb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDUiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLXRlcm1pbmFsLXZlcmlmaWNhdGlvbi92MiIsInRlbmFudF9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwMiIsInRlcm1pbmFsX3NlcXVlbmNlIjoxLCJ2ZXJpZmllZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDJaIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsIndvcmtmbG93X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAzIiwid29ya2Zsb3dfdmVyc2lvbl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwNCJ9LCJzaWduYXR1cmUiOiJzVlhzVE5yZDdrTGZTdkFjU2Z6TUh1eWtBLThBbHdJUGMtRk5tYkRPVVdsb3BQaC11MGowR0xlX1JxWURQSThFd003MEp4LTJWa0JNdW9BeXhJaGdEZyIsInNpZ25lciI6eyJhbGdvcml0aG0iOiJlZDI1NTE5Iiwia2V5X2lkIjoiZXZpZGVuY2UtcnVubmVyLWVkMjU1MTktNTY0NzVhYTc1NDYzNDc0YyIsInB1YmxpY19rZXkiOiJBNkVIdi9QT0VMNGRjTjBZNTB2QW1XZmsxakNicFExZkhkeUdaQkpWTWJnPSJ9fQ==", "managed_result_loss": { "actuation_replay_authorized": false, "authenticated_runner_id_sha256": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", @@ -192,9 +207,9 @@ "schema_version": "openadapt.managed-result-loss/v1" }, "name": "reconciliation-required-managed-result-loss", - "payload_canonical_sha256": "955bae00518f0d07965a05727654e108b618818fd6933f6de2ed8c3d425f27fd", - "signature": "uGtKXVcjqKKrLHO2n8thfaGll99lzExqt2W2PzRfT28onuzs699Tlm05dK9BU9Bd-zX374BCr0mVKHxrvZtlBQ", - "terminal_verification_artifact_sha256": "c2a7ef78aebeb55c585386b7b78e16ac3c84f8d19656d0dd1cb76b65141b8d47" + "payload_canonical_sha256": "c1c4558b3240938ee687ebfc5e2702c3fafd3a34a10cadfad08c76465010da5a", + "signature": "sVXsTNrd7kLfSvAcSfzMHuykA-8AlwIPc-FNmbDOUWlopPh-u0j0GLe_RqYDPI8EwM70Jx-2VkBMuoAyxIhgDg", + "terminal_verification_artifact_sha256": "b61dbd7c53e609c28181a9f31b067eb8c829b37c14b2e99d6ff711fe9c64dcac" }, { "callback": { @@ -207,7 +222,7 @@ "uncertain_delivery": false }, "effect_state": null, - "envelope_canonical_base64": "eyJwYXlsb2FkIjp7ImFja25vd2xlZGdlZF9wZXJtaXRfY291bnQiOjEsImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA2IiwiYWRtaXNzaW9uX3BvbGljeV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYWRtaXR0ZWRfcnVudGltZV9idWlsZF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiYnVuZGxlX2FydGlmYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJidW5kbGVfY29udGVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYnVuZGxlX3ZlcnNpb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDQiLCJkZWxpdmVyeV9yZXN1bHRfbG9zc19jbG9zdXJlIjp7InBheWxvYWQiOnsiYWNrbm93bGVkZ2VkX3Blcm1pdF9jb3VudCI6MSwiYWN0dWF0aW9uX3JlcGxheV9hdXRob3JpemVkIjpmYWxzZSwiYXV0aGVudGljYXRlZF9ydW5uZXJfaWRfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsImF1dGhlbnRpY2F0ZWRfc2Vzc2lvbl9pZF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiYmxpbmRfcmV0cnlfYXV0aG9yaXplZCI6ZmFsc2UsImNoaWxkX3N0YXJ0X2V2aWRlbmNlX3NoYTI1NiI6ImVjNjkwNzkxODg2YWUyY2UwMGM0ZTUxMTU0YzNmMTIwZWE0NDE5ZWQyNjUxZTA3M2RiNTcyNDkxOGEzYjA4YzYiLCJjaGlsZF9zdGFydGVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMFoiLCJjbG9zZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAyWiIsImNsb3N1cmVfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMTEiLCJjbG9zdXJlX3JlcXVlc3Rfc2hhMjU2IjoiZDkzMGFiMWFiYzJiMmEwNGI4NDhiOTU1ZmZkZmZmYTFmYmUwNjU1YTU1MzI1ZTA0ODlhZTExZWQ4NDIwMjI2MCIsImNsb3N1cmVfc2VxdWVuY2UiOjEsImRlbGl2ZXJ5X2Fja25vd2xlZGdtZW50X2F1dGhvcml6ZWQiOmZhbHNlLCJkZWxpdmVyeV9zdGF0ZSI6IkNMT1NFRF9VTlJFU09MVkVEX1JFU1VMVF9MT1NTIiwiZGlzcGF0Y2hfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDkiLCJkaXNwYXRjaF9zZXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDEwIiwiZWZmZWN0X2Fic2VuY2VfY2xhaW1lZCI6ZmFsc2UsImV4ZWN1dGlvbl9hdXRob3JpdHlfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDgiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NpZ25lcl9zaGEyNTYiOiIyNGY2ZWQ2YWNiZmUxMDA5YzAzMGQ3Y2E1NjdjMzNjYTQ4MzA5MTE0OTgyMzZiNTU2MWE2YzgyYWJlYzVkZTI4IiwiZmluYWxfYXV0aG9yaXR5X3NlcXVlbmNlIjowLCJmaW5hbF9pbnB1dF9lZGdlX3NlcXVlbmNlIjoxLCJmaW5hbF9ydW50aW1lX2RlbGl2ZXJ5X3NlcXVlbmNlIjo5LCJmbG93X3J1bl9pZF9zaGEyNTYiOiIxMWU1OTRmNDgxOTU4YzEwZTMwMTVkMGJmMDQ0N2EyMmYwNjhhOGE2NDdmNDc1ZGYxNWNlMmM3YWI0YjhmM2YxIiwiaWRlbXBvdGVuY3lfa2V5X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJtYW5hZ2VkX2Rpc3BhdGNoX2JpbmRpbmdfc2hhMjU2Ijoic2hhMjU2OmNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJuZXdfcGVybWl0X2F1dGhvcml6ZWQiOmZhbHNlLCJub3RfcmVjZWl2ZWRfY2xhaW1lZCI6ZmFsc2UsInBlbmRpbmdfYWN0aW9uX3JlcXVlc3Rfc2hhMjU2IjpudWxsLCJwZW5kaW5nX3Blcm1pdF9hcnRpZmFjdF9zaGEyNTYiOm51bGwsInBlbmRpbmdfcGVybWl0X2NvdW50IjowLCJwZXJtaXRfY2hhaW5fc2hhMjU2IjoiNTA0OGZlOTQ1ODgyZDI4MDI2MDA4ZDdlOTEzN2FkMDE2ZmRkMDFhZWFmNTg4NDgxZmI1YmQwZjI0MmE1MDA0MyIsInBlcm1pdF9jb3VudCI6MSwicmVjZWlwdF9hYnNlbmNlX29ic2VydmVkX2F0IjpudWxsLCJyZXN1bHRfbG9zc19vYnNlcnZlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDJaIiwicnVuX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAxIiwicnVuX3JlcXVlc3Rfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsInJ1bl9zdG9yZV9pZGVudGl0eV9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1yZXN1bHQtbG9zcy1jbG9zdXJlLXBheWxvYWQvdjIiLCJ0ZW5hbnRfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDIiLCJ0ZXJtaW5hbF9jYWxsYmFja19yZXF1aXJlZCI6dHJ1ZX0sInBheWxvYWRfc2hhMjU2IjoiNmI3NWY4YjQ1YTdkM2U5Y2ZlODU2NGZmZTMyZjI5YzJiNTk3YzI4MTM2YTk3YTRmNTQ1M2ZlMmFmZDE3MjhhYSIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcmVzdWx0LWxvc3MtY2xvc3VyZS1hcnRpZmFjdC92MiIsInNpZ25hdHVyZSI6Imt6dVIycXJjR1Q0cG82LXl6ZFlEZ2gzd2FZamI5V3BRR1VfQm5RTEhUSWJkZDV4QmxyVVNsNkg0Y2VWQzMzcjFCd2JGdFJQYVB2bzA1cGd4Z0U0d0F3Iiwic2lnbmVyIjp7ImFsZ29yaXRobSI6ImVkMjU1MTkiLCJrZXlfaWQiOiJkZWxpdmVyeS1hdXRob3JpdHktZWQyNTUxOS0yNGY2ZWQ2YWNiZmUxMDA5IiwicHVibGljX2tleSI6IktheTY0VUc4eXZDeUxocVUwMDBMeHpZZVVtMEwvaExJbDVTOGt5S1diZGM9In19LCJlZmZlY3RfY29udHJhY3Rfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImVudmlyb25tZW50X2NvbnRyYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJlbnZpcm9ubWVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXZpZGVuY2VfaWRlbnRpdHlfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImV2aWRlbmNlX21hbmlmZXN0cyI6eyJhdXRob3JpemF0aW9uIjp7ImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA2IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOCIsImV4ZWN1dGlvbl9hdXRob3JpdHlfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImdvdmVybmVkX2F1dGhvcml6YXRpb25faWRfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsIm1hbmlmZXN0X3NoYTI1NiI6ImYwY2ExOWE2YjNlYWJlNTk0ZGJjOTA2ODljMmY3NGNiZTVlODJkNGQ5NDdkYjI5YTVkMDdiMTY0MWU4OTYxY2YiLCJwZXJtaXRfY2hhaW5fc2hhMjU2IjoiNTA0OGZlOTQ1ODgyZDI4MDI2MDA4ZDdlOTEzN2FkMDE2ZmRkMDFhZWFmNTg4NDgxZmI1YmQwZjI0MmE1MDA0MyIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tYXV0aG9yaXphdGlvbi1ldmlkZW5jZS92MSJ9LCJlZmZlY3QiOnsiY29uZmlybWVkIjowLCJlZmZlY3RfY29udHJhY3Rfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsIm1hbmlmZXN0X3NoYTI1NiI6IjdlMTJkY2E1YzQ0Y2Y5OThhNDY5MzYyYjg2MmU4MTZhN2QyYzg1NDE2M2Y2M2U4ZGU2MWZiNzllOTViYTgwMDciLCJyZWNvcmRzIjpbXSwicmVxdWlyZWQiOjAsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZWZmZWN0LWV2aWRlbmNlL3YxIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSJ9LCJpZGVudGl0eSI6eyJjb25maXJtZWQiOjAsImlkZW50aXR5X2NvbnRyYWN0X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJtYW5pZmVzdF9zaGEyNTYiOiJkM2E3ZWFjMzQyN2Q3NmY2YmMzNjAzMDczODYwOTExOWYwN2UwZDkxYTZkMzU4YWJjZTViNmYwZDZkZjc4NjQ1IiwicmVxdWlyZWQiOjAsInJlc3VsdHMiOltdLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWlkZW50aXR5LWV2aWRlbmNlL3YxIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSJ9LCJwb2xpY3kiOnsiYWRtaXNzaW9uX3BvbGljeV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZWZmZWN0X2NvbnRyYWN0X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJlbnZpcm9ubWVudF9jb250cmFjdF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwiZW52aXJvbm1lbnRfZGlnZXN0IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImdvdmVybmVkX3BvbGljeV9jb250cmFjdF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwiZ292ZXJuZWRfcnVudGltZV9pbnB1dHNfZGlnZXN0IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsImlkZW50aXR5X2NvbnRyYWN0X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJtYW5pZmVzdF9zaGEyNTYiOiI0Zjk4OGQwMTViY2Q3Y2Q3ZTA1YmEwNjYzZDg5ZjBhOTY4ZjBkOGFjZTk5YjA5MGViYWJlZTUyYTFjNTUwNDIxIiwibWluaW11bV9lZmZlY3RfdGllciI6MSwicnVudGltZV9lbnZpcm9ubWVudF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1wb2xpY3ktZXZpZGVuY2UvdjEifSwicG9zdGNvbmRpdGlvbiI6eyJjb25maXJtZWQiOjAsIm1hbmlmZXN0X3NoYTI1NiI6IjUyZjA5ZDVkNjM5YjFjMzgzZjM3Nzk2M2U0ODdjYjg5ZDg5NDE3ODU3ZTQ0ZGE3ZTNmMjNlNTViZTc1MWU3ZjQiLCJyZWNvcmRzIjpbXSwicmVxdWlyZWQiOjAsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tcG9zdGNvbmRpdGlvbi1ldmlkZW5jZS92MSIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifX0sImV2aWRlbmNlX3J1bm5lcl9zaWduZXJfc2hhMjU2IjoiNTY0NzVhYTc1NDYzNDc0YzAyODVkZjVkYmYyYmNhYjczZGE2NTEzNTg4MzllOWI3NzQ4MWIyZWFiMTA3NzA4YyIsImV4ZWN1dGlvbl9hdXRob3JpdHlfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDgiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NpZ25lcl9zaGEyNTYiOiIyNGY2ZWQ2YWNiZmUxMDA5YzAzMGQ3Y2E1NjdjMzNjYTQ4MzA5MTE0OTgyMzZiNTU2MWE2YzgyYWJlYzVkZTI4IiwiZXhlY3V0aW9uX291dGNvbWUiOnsiY29tcGVuc2F0aW9uX2FjdGlvbnMiOjAsImV2aWRlbmNlX2NsYXNzZXMiOlsiYXV0aG9yaXphdGlvbiJdLCJleGVjdXRpb25fY29tcGxldGVkIjpmYWxzZSwiZXh0ZXJuYWxfbmV0d29ya19jYWxscyI6Im5vbmUiLCJtYW5hZ2VkX3Jlc3VsdF9sb3NzX2V2aWRlbmNlX3NoYTI1NiI6ImYyMmYyNzA0NGVmMzE1ZTkzOWFiYWRmNmI2NzI1ZmNmMmI5MmYyYTI4MDM5NDA3NTgwZTBmMmY3ZTIzMDU0OTQiLCJtb2RlbF9jYWxscyI6MCwib3V0Y29tZSI6IkhBTFRFRCIsInBhc3NlZF9jb250cmFjdHMiOnsiYXV0aG9yaXphdGlvbiI6MSwiZWZmZWN0IjowLCJpZGVudGl0eSI6MCwicG9zdGNvbmRpdGlvbiI6MH0sInBvc3Rjb25kaXRpb25fZXZpZGVuY2UiOltdLCJwcm9kdWN0aW9uX2VsaWdpYmxlIjpmYWxzZSwicHJvZmlsZSI6InN0YW5kYXJkIiwicXVhbGlmaWNhdGlvbl9ldmlkZW5jZV9vbmx5IjpmYWxzZSwicmVxdWlyZWRfY29udHJhY3RzIjp7ImF1dGhvcml6YXRpb24iOjEsImVmZmVjdCI6MCwiaWRlbnRpdHkiOjAsInBvc3Rjb25kaXRpb24iOjB9LCJ2ZXJzaW9uIjoib3BlbmFkYXB0LmV4ZWN1dGlvbi1vdXRjb21lL3YxIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSJ9LCJleGVjdXRpb25fb3V0Y29tZV9zaGEyNTYiOiJhOTUxNjFlYjFmOGZjMzBmYjk0ZGNiNzdjZDIzYzc2MjdlM2NhY2EzODBhZmEzNGU0MTE3YzI2NGNmYzhiMmYzIiwiZXhlY3V0aW9uX3B1cnBvc2UiOiJwcm9kdWN0aW9uIiwiZmluYWxfYXV0aG9yaXR5X3NlcXVlbmNlIjowLCJmaW5hbF9ydW50aW1lX2RlbGl2ZXJ5X3NlcXVlbmNlIjo5LCJmbG93X3J1bl9pZF9zaGEyNTYiOiIxMWU1OTRmNDgxOTU4YzEwZTMwMTVkMGJmMDQ0N2EyMmYwNjhhOGE2NDdmNDc1ZGYxNWNlMmM3YWI0YjhmM2YxIiwiaWRlbnRpdHlfY29udHJhY3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsImlzc3VlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDNaIiwibWFuYWdlZF9yZXN1bHRfbG9zcyI6eyJhY3R1YXRpb25fcmVwbGF5X2F1dGhvcml6ZWQiOmZhbHNlLCJhdXRoZW50aWNhdGVkX3J1bm5lcl9pZF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwiYXV0aGVudGljYXRlZF9zZXNzaW9uX2lkX3NoYTI1NiI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJibGluZF9yZXRyeV9hdXRob3JpemVkIjpmYWxzZSwiY2hpbGRfcmVwb3J0X3JldGFpbmVkIjpmYWxzZSwiY2hpbGRfc3RhcnRfZXZpZGVuY2Vfc2hhMjU2IjoiZWM2OTA3OTE4ODZhZTJjZTAwYzRlNTExNTRjM2YxMjBlYTQ0MTllZDI2NTFlMDczZGI1NzI0OTE4YTNiMDhjNiIsImNoaWxkX3N0YXJ0ZWQiOnRydWUsImNoaWxkX3N0YXJ0ZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAwWiIsImRlbGl2ZXJ5X3Jlc3VsdF9sb3NzX2Nsb3N1cmVfYXJ0aWZhY3Rfc2hhMjU2IjoiYjJkOTJmMzI0OGY0ZGE2MWVkYjAyN2NmNTlkYTUzOTVmZmM0MThlYWQ2ZDQ4NWMyOWRmNmMzNWJjMjFhOTMwZCIsImRlbGl2ZXJ5X3N0YXRlIjoiQ0xPU0VEX1VOUkVTT0xWRURfUkVTVUxUX0xPU1MiLCJkaXNwYXRjaF9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOSIsImRpc3BhdGNoX3Nlc3Npb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMTAiLCJlZmZlY3RfYWJzZW5jZV9jbGFpbWVkIjpmYWxzZSwiZXZpZGVuY2Vfc2hhMjU2IjoiZjIyZjI3MDQ0ZWYzMTVlOTM5YWJhZGY2YjY3MjVmY2YyYjkyZjJhMjgwMzk0MDc1ODBlMGYyZjdlMjMwNTQ5NCIsImV4ZWN1dGlvbl9hdXRob3JpdHlfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDgiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NpZ25lcl9zaGEyNTYiOiIyNGY2ZWQ2YWNiZmUxMDA5YzAzMGQ3Y2E1NjdjMzNjYTQ4MzA5MTE0OTgyMzZiNTU2MWE2YzgyYWJlYzVkZTI4IiwiZmxvd19ydW5faWRfc2hhMjU2IjoiMTFlNTk0ZjQ4MTk1OGMxMGUzMDE1ZDBiZjA0NDdhMjJmMDY4YThhNjQ3ZjQ3NWRmMTVjZTJjN2FiNGI4ZjNmMSIsImlkZW1wb3RlbmN5X2tleV9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwibG9zc19jb2RlIjoicmVwb3J0X21pc3NpbmciLCJtYW5hZ2VkX2Rpc3BhdGNoX2JpbmRpbmdfc2hhMjU2Ijoic2hhMjU2OmNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJub3RfcmVjZWl2ZWRfY2xhaW1lZCI6ZmFsc2UsIm9ic2VydmVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMloiLCJwZW5kaW5nX2FjdGlvbl9yZXF1ZXN0X3NoYTI1NiI6bnVsbCwicGVuZGluZ19wZXJtaXRfYXJ0aWZhY3Rfc2hhMjU2IjpudWxsLCJyZXBvcnRfcHJvdmVuYW5jZSI6Im91dGVyX3J1bm5lcl9yZWNvdmVyeSIsInJ1bl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwMSIsInJ1bl9yZXF1ZXN0X3NoYTI1NiI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJydW5fc3RvcmVfaWRlbnRpdHlfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0Lm1hbmFnZWQtcmVzdWx0LWxvc3MvdjEifSwicGVuZGluZ19wZXJtaXRfY291bnQiOjAsInBlcm1pdF9jaGFpbiI6eyJlbnRyaWVzIjpbeyJkZWxpdmVyeV9yZWNlaXB0X2FydGlmYWN0Ijp7InBheWxvYWQiOnsiYXV0aGVudGljYXRlZF9ydW5uZXJfaWRfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsImF1dGhlbnRpY2F0ZWRfc2Vzc2lvbl9pZF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiZGVsaXZlcmVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMVoiLCJleGVjdXRpb25fYXV0aG9yaXR5X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA4Iiwib25lX3VzZV9jbGFpbV9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAxMCIsInBlcm1pdF9hcnRpZmFjdF9zaGEyNTYiOiI5NzJhODJhZjQ1NmRhNTQyYmFjNzg0NjAxODg5NjY4ODkxZDhiN2NjZDI0MjkwNDgxNmIzMjkyZTE1N2U1Mjg5IiwicGVybWl0X2lkIjoicGVybWl0OjEiLCJydW50aW1lX2RlbGl2ZXJ5X3NlcXVlbmNlIjo5LCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXJlY2VpcHQtcGF5bG9hZC92MiJ9LCJwYXlsb2FkX3NoYTI1NiI6IjhhOGY2ZDg4NzUwY2JiNmIzYmQ2NjIwOTNhZDI5ZTJiYzIwYzZhYjY5OTFkNzBlNTg4NjkxYzhiM2FiNjYyYjkiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXJlY2VpcHQtYXJ0aWZhY3QvdjIiLCJzaWduYXR1cmUiOiJBT0txQ2dTMXMwWGEtaXlFOTZWLXlsUHpRY3YydXZPc3V5Z0h6dnUyUnlWN0ZMc0hGX0xWZnF5eDR1MnB1bWxFbDBZazVZdTcwSlZVa3NacGFVcEREdyIsInNpZ25lciI6eyJhbGdvcml0aG0iOiJlZDI1NTE5Iiwia2V5X2lkIjoiZGVsaXZlcnktYXV0aG9yaXR5LWVkMjU1MTktMjRmNmVkNmFjYmZlMTAwOSIsInB1YmxpY19rZXkiOiJLYXk2NFVHOHl2Q3lMaHFVMDAwTHh6WWVVbTBML2hMSWw1UzhreUtXYmRjPSJ9fSwiZGVsaXZlcnlfcmVjZWlwdF9hcnRpZmFjdF9zaGEyNTYiOiJjMDBhMWJhNzAxNWYzY2JlMDVhNzZhZWFiZmY2MTlkNzkzZTczNzVhMzEwZTE5NWZjYmJkMmQyOTQ4ZjJiMjE0IiwicGVybWl0X2FydGlmYWN0Ijp7InBheWxvYWQiOnsiYWN0aW9uX3JlcXVlc3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYXV0aG9yaXR5X3NlcXVlbmNlIjowLCJlbnZpcm9ubWVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXZpZGVuY2VfaWRlbnRpdHlfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImV4ZWN1dGlvbl9hdXRob3JpdHlfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDgiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJmbG93X3J1bl9pZF9zaGEyNTYiOiIxMWU1OTRmNDgxOTU4YzEwZTMwMTVkMGJmMDQ0N2EyMmYwNjhhOGE2NDdmNDc1ZGYxNWNlMmM3YWI0YjhmM2YxIiwiaW5wdXRfZWRnZV9zZXF1ZW5jZSI6MSwiaXNzdWVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMFoiLCJwZXJtaXRfaWQiOiJwZXJtaXQ6MSIsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X2NoZWNrZWRfYXQiOiIyMDI2LTA4LTE4VDExOjU5OjMwWiIsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X2V4cGlyZXNfYXQiOiIyMDI2LTA4LTIwVDExOjAwOjAwWiIsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X3JldmlzaW9uIjo3LCJxdWFsaWZpY2F0aW9uX3NpZ25lcl9yZWdpc3RyeV9zaGEyNTYiOiJlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlIiwicnVuX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAxIiwicnVuX3JlcXVlc3Rfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcGVybWl0LXBheWxvYWQvdjIifSwicGF5bG9hZF9zaGEyNTYiOiJjODdmNTc1MWFhOWIyNzljY2UyM2FhMTc4YWZmOTU2ZTE5ZjY5MGZjZDJmOWY3MGUwZDk5OTc4MmE2OTBkNmI4Iiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1wZXJtaXQtYXJ0aWZhY3QvdjIiLCJzaWduYXR1cmUiOiIwQnlIZ3FEeFFacm5nTElGLTZ0Wk9xOWxYYW1jQVFDMGRvVVRuZUtOUGVTLVN5b09iUXlPa0F1UEZLNVBZY056T2JaeGdzZ0FMZFdhSV9zYVVDcGxCZyIsInNpZ25lciI6eyJhbGdvcml0aG0iOiJlZDI1NTE5Iiwia2V5X2lkIjoiZGVsaXZlcnktYXV0aG9yaXR5LWVkMjU1MTktMjRmNmVkNmFjYmZlMTAwOSIsInB1YmxpY19rZXkiOiJLYXk2NFVHOHl2Q3lMaHFVMDAwTHh6WWVVbTBML2hMSWw1UzhreUtXYmRjPSJ9fSwicGVybWl0X2FydGlmYWN0X3NoYTI1NiI6Ijk3MmE4MmFmNDU2ZGE1NDJiYWM3ODQ2MDE4ODk2Njg4OTFkOGI3Y2NkMjQyOTA0ODE2YjMyOTJlMTU3ZTUyODkiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXBlcm1pdC1jaGFpbi1lbnRyeS92MiJ9XSwicGVybWl0X2NoYWluX3NoYTI1NiI6IjUwNDhmZTk0NTg4MmQyODAyNjAwOGQ3ZTkxMzdhZDAxNmZkZDAxYWVhZjU4ODQ4MWZiNWJkMGYyNDJhNTAwNDMiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXBlcm1pdC1jaGFpbi92MiJ9LCJwZXJtaXRfY291bnQiOjEsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X3JldmlzaW9uIjo3LCJxdWFsaWZpY2F0aW9uX3NpZ25lcl9yZWdpc3RyeV9zaGEyNTYiOiJlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlIiwicnVuX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAxIiwicnVuX3JlY2VpcHQiOnsiYXV0aG9yaXphdGlvbl9jb25maXJtZWQiOjEsImF1dGhvcml6YXRpb25fcmVxdWlyZWQiOjEsImJ1bmRsZV9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZHVyYXRpb25fbXMiOjAsImVmZmVjdF90aWVyX3JlYWNoZWQiOiJub25lIiwiZWZmZWN0c19jb25maXJtZWQiOjAsImVmZmVjdHNfcmVxdWlyZWQiOjAsImVzdF9jb3N0X21pY3JvdXNkIjowLCJldmlkZW5jZV9jbGFzc2VzIjpbImF1dGhvcml6YXRpb24iXSwiZXh0ZXJuYWxfbmV0d29ya19jYWxscyI6Im5vbmUiLCJnZW5lcmF0ZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAwWiIsImhlYWxzIjowLCJpZGVudGl0eV9hcHBsaWNhYmxlIjowLCJpZGVudGl0eV9hcm1lZCI6MCwiaWRlbnRpdHlfY29uZmlybWVkIjowLCJpZGVudGl0eV9yZXF1aXJlZCI6MCwibWFuYWdlZF9yZXN1bHRfbG9zc19ldmlkZW5jZV9zaGEyNTYiOiJmMjJmMjcwNDRlZjMxNWU5MzlhYmFkZjZiNjcyNWZjZjJiOTJmMmEyODAzOTQwNzU4MGUwZjJmN2UyMzA1NDk0IiwibW9kZWxfY2FsbHMiOjAsIm91dGNvbWUiOiJIQUxURUQiLCJvdmVyX2hhbHRfY291bnQiOjAsInBvc3Rjb25kaXRpb25zX2NvbmZpcm1lZCI6MCwicG9zdGNvbmRpdGlvbnNfcmVxdWlyZWQiOjAsInByb2R1Y3Rpb25fZWxpZ2libGUiOmZhbHNlLCJwcm9maWxlIjoic3RhbmRhcmQiLCJwcm92ZW5hbmNlIjoicHJvZHVjdGlvbiIsInJlY2VpcHRfYnVpbGRlcl92ZXJzaW9uIjoiMS4yLjMiLCJydW5nX2hpc3RvZ3JhbSI6e30sInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tcnVuLXJlY2VpcHQvdjEiLCJzb3VyY2VfcmVjZWlwdF9kaWdlc3QiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwic291cmNlX3JlY2VpcHRfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsInNvdXJjZV9zY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5ydW4tcmVwb3J0L3YxIiwic3RlcHNfb2siOjAsInN0ZXBzX3RvdGFsIjoxLCJzdWJzdHJhdGUiOiJ3ZWIiLCJ0cmFuc2FjdGlvbl9vdXRjb21lIjoiUkVDT05DSUxJQVRJT05fUkVRVUlSRUQifSwicnVuX3JlY2VpcHRfc2hhMjU2IjoiMzI5NzEzZDkwZTA1YjBmNTVlNmFhNTM2NWJmZThiMzA2NGY1ZTQ3OTBlMWNkYmRjOThlMzYyM2Y4N2NlYzVjYyIsInJ1bl9yZXBvcnRfb2JqZWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJydW5fcmVwb3J0X29iamVjdF92ZXJzaW9uIjoidmVyc2lvbjptYW5hZ2VkLXJlc3VsdC1sb3NzOjEiLCJydW5fcmVwb3J0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJydW50aW1lX2Vudmlyb25tZW50X3NoYTI1NiI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJydW50aW1lX3N1YnN0cmF0ZSI6IndlYiIsInJ1bnRpbWVfdmFsaWRhdGlvbl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwNSIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tdGVybWluYWwtdmVyaWZpY2F0aW9uL3YyIiwidGVuYW50X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAyIiwidGVybWluYWxfc2VxdWVuY2UiOjEsInZlcmlmaWVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMloiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwid29ya2Zsb3dfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDMiLCJ3b3JrZmxvd192ZXJzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA0In0sInNpZ25hdHVyZSI6IlgwcWtfTkJXVFVKVk1LQ2NFaFJHcWNJeDRjOTdYd1U2Szg4T0plbHdxc2FpWGVtTV9nRlJ4MHlNYjdPcjhfZUlSNmpMNDNDSVNPMEc0Ums3SWVYNUN3Iiwic2lnbmVyIjp7ImFsZ29yaXRobSI6ImVkMjU1MTkiLCJrZXlfaWQiOiJldmlkZW5jZS1ydW5uZXItZWQyNTUxOS01NjQ3NWFhNzU0NjM0NzRjIiwicHVibGljX2tleSI6IkE2RUh2L1BPRUw0ZGNOMFk1MHZBbVdmazFqQ2JwUTFmSGR5R1pCSlZNYmc9In19", + "envelope_canonical_base64": "eyJwYXlsb2FkIjp7ImFja25vd2xlZGdlZF9wZXJtaXRfY291bnQiOjEsImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA2IiwiYWRtaXNzaW9uX3BvbGljeV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYWRtaXR0ZWRfcnVudGltZV9idWlsZF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiYnVuZGxlX2FydGlmYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJidW5kbGVfY29udGVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYnVuZGxlX3ZlcnNpb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDQiLCJkZWxpdmVyeV9yZXN1bHRfbG9zc19jbG9zdXJlIjp7InBheWxvYWQiOnsiYWNrbm93bGVkZ2VkX3Blcm1pdF9jb3VudCI6MSwiYWN0dWF0aW9uX3JlcGxheV9hdXRob3JpemVkIjpmYWxzZSwiYXV0aGVudGljYXRlZF9ydW5uZXJfaWRfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsImF1dGhlbnRpY2F0ZWRfc2Vzc2lvbl9pZF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiYmxpbmRfcmV0cnlfYXV0aG9yaXplZCI6ZmFsc2UsImNoaWxkX3N0YXJ0X2V2aWRlbmNlX3NoYTI1NiI6ImVjNjkwNzkxODg2YWUyY2UwMGM0ZTUxMTU0YzNmMTIwZWE0NDE5ZWQyNjUxZTA3M2RiNTcyNDkxOGEzYjA4YzYiLCJjaGlsZF9zdGFydGVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMFoiLCJjbG9zZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAyWiIsImNsb3N1cmVfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMTEiLCJjbG9zdXJlX3JlcXVlc3Rfc2hhMjU2IjoiZDkzMGFiMWFiYzJiMmEwNGI4NDhiOTU1ZmZkZmZmYTFmYmUwNjU1YTU1MzI1ZTA0ODlhZTExZWQ4NDIwMjI2MCIsImNsb3N1cmVfc2VxdWVuY2UiOjEsImRlbGl2ZXJ5X2Fja25vd2xlZGdtZW50X2F1dGhvcml6ZWQiOmZhbHNlLCJkZWxpdmVyeV9zdGF0ZSI6IkNMT1NFRF9VTlJFU09MVkVEX1JFU1VMVF9MT1NTIiwiZGlzcGF0Y2hfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDkiLCJkaXNwYXRjaF9zZXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDEwIiwiZWZmZWN0X2Fic2VuY2VfY2xhaW1lZCI6ZmFsc2UsImV4ZWN1dGlvbl9hdXRob3JpdHlfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDgiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NpZ25lcl9zaGEyNTYiOiIyNGY2ZWQ2YWNiZmUxMDA5YzAzMGQ3Y2E1NjdjMzNjYTQ4MzA5MTE0OTgyMzZiNTU2MWE2YzgyYWJlYzVkZTI4IiwiZmluYWxfYXV0aG9yaXR5X3NlcXVlbmNlIjowLCJmaW5hbF9pbnB1dF9lZGdlX3NlcXVlbmNlIjoxLCJmaW5hbF9ydW50aW1lX2RlbGl2ZXJ5X3NlcXVlbmNlIjo5LCJmbG93X3J1bl9pZF9zaGEyNTYiOiIxMWU1OTRmNDgxOTU4YzEwZTMwMTVkMGJmMDQ0N2EyMmYwNjhhOGE2NDdmNDc1ZGYxNWNlMmM3YWI0YjhmM2YxIiwiaWRlbXBvdGVuY3lfa2V5X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJtYW5hZ2VkX2Rpc3BhdGNoX2JpbmRpbmdfc2hhMjU2Ijoic2hhMjU2OmNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJuZXdfcGVybWl0X2F1dGhvcml6ZWQiOmZhbHNlLCJub3RfcmVjZWl2ZWRfY2xhaW1lZCI6ZmFsc2UsInBlbmRpbmdfYWN0aW9uX3JlcXVlc3Rfc2hhMjU2IjpudWxsLCJwZW5kaW5nX3Blcm1pdF9hcnRpZmFjdF9zaGEyNTYiOm51bGwsInBlbmRpbmdfcGVybWl0X2NvdW50IjowLCJwZXJtaXRfY2hhaW5fc2hhMjU2IjoiNTA0OGZlOTQ1ODgyZDI4MDI2MDA4ZDdlOTEzN2FkMDE2ZmRkMDFhZWFmNTg4NDgxZmI1YmQwZjI0MmE1MDA0MyIsInBlcm1pdF9jb3VudCI6MSwicmVjZWlwdF9hYnNlbmNlX29ic2VydmVkX2F0IjpudWxsLCJyZXN1bHRfbG9zc19vYnNlcnZlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDJaIiwicnVuX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAxIiwicnVuX3JlcXVlc3Rfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsInJ1bl9zdG9yZV9pZGVudGl0eV9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1yZXN1bHQtbG9zcy1jbG9zdXJlLXBheWxvYWQvdjIiLCJ0ZW5hbnRfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDIiLCJ0ZXJtaW5hbF9jYWxsYmFja19yZXF1aXJlZCI6dHJ1ZX0sInBheWxvYWRfc2hhMjU2IjoiNmI3NWY4YjQ1YTdkM2U5Y2ZlODU2NGZmZTMyZjI5YzJiNTk3YzI4MTM2YTk3YTRmNTQ1M2ZlMmFmZDE3MjhhYSIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcmVzdWx0LWxvc3MtY2xvc3VyZS1hcnRpZmFjdC92MiIsInNpZ25hdHVyZSI6Imt6dVIycXJjR1Q0cG82LXl6ZFlEZ2gzd2FZamI5V3BRR1VfQm5RTEhUSWJkZDV4QmxyVVNsNkg0Y2VWQzMzcjFCd2JGdFJQYVB2bzA1cGd4Z0U0d0F3Iiwic2lnbmVyIjp7ImFsZ29yaXRobSI6ImVkMjU1MTkiLCJrZXlfaWQiOiJkZWxpdmVyeS1hdXRob3JpdHktZWQyNTUxOS0yNGY2ZWQ2YWNiZmUxMDA5IiwicHVibGljX2tleSI6IktheTY0VUc4eXZDeUxocVUwMDBMeHpZZVVtMEwvaExJbDVTOGt5S1diZGM9In19LCJlZmZlY3RfY29udHJhY3Rfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImVudmlyb25tZW50X2NvbnRyYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJlbnZpcm9ubWVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXZpZGVuY2VfaWRlbnRpdHlfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImV2aWRlbmNlX21hbmlmZXN0cyI6eyJhdXRob3JpemF0aW9uIjp7ImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA2IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOCIsImV4ZWN1dGlvbl9hdXRob3JpdHlfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImdvdmVybmVkX2F1dGhvcml6YXRpb25faWRfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsIm1hbmlmZXN0X3NoYTI1NiI6ImYwY2ExOWE2YjNlYWJlNTk0ZGJjOTA2ODljMmY3NGNiZTVlODJkNGQ5NDdkYjI5YTVkMDdiMTY0MWU4OTYxY2YiLCJwZXJtaXRfY2hhaW5fc2hhMjU2IjoiNTA0OGZlOTQ1ODgyZDI4MDI2MDA4ZDdlOTEzN2FkMDE2ZmRkMDFhZWFmNTg4NDgxZmI1YmQwZjI0MmE1MDA0MyIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tYXV0aG9yaXphdGlvbi1ldmlkZW5jZS92MSJ9LCJlZmZlY3QiOnsiY29uZmlybWVkIjowLCJlZmZlY3RfY29udHJhY3Rfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsIm1hbmlmZXN0X3NoYTI1NiI6IjdlMTJkY2E1YzQ0Y2Y5OThhNDY5MzYyYjg2MmU4MTZhN2QyYzg1NDE2M2Y2M2U4ZGU2MWZiNzllOTViYTgwMDciLCJyZWNvcmRzIjpbXSwicmVxdWlyZWQiOjAsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZWZmZWN0LWV2aWRlbmNlL3YxIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSJ9LCJpZGVudGl0eSI6eyJjb25maXJtZWQiOjAsImlkZW50aXR5X2NvbnRyYWN0X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJtYW5pZmVzdF9zaGEyNTYiOiJkM2E3ZWFjMzQyN2Q3NmY2YmMzNjAzMDczODYwOTExOWYwN2UwZDkxYTZkMzU4YWJjZTViNmYwZDZkZjc4NjQ1IiwicmVxdWlyZWQiOjAsInJlc3VsdHMiOltdLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWlkZW50aXR5LWV2aWRlbmNlL3YxIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSJ9LCJwb2xpY3kiOnsiYWRtaXNzaW9uX3BvbGljeV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZWZmZWN0X2NvbnRyYWN0X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJlbnZpcm9ubWVudF9jb250cmFjdF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwiZW52aXJvbm1lbnRfZGlnZXN0IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImdvdmVybmVkX3BvbGljeV9jb250cmFjdF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwiZ292ZXJuZWRfcnVudGltZV9pbnB1dHNfZGlnZXN0IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsImlkZW50aXR5X2NvbnRyYWN0X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJtYW5pZmVzdF9zaGEyNTYiOiI0Zjk4OGQwMTViY2Q3Y2Q3ZTA1YmEwNjYzZDg5ZjBhOTY4ZjBkOGFjZTk5YjA5MGViYWJlZTUyYTFjNTUwNDIxIiwibWluaW11bV9lZmZlY3RfdGllciI6MSwicnVudGltZV9lbnZpcm9ubWVudF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1wb2xpY3ktZXZpZGVuY2UvdjEifSwicG9zdGNvbmRpdGlvbiI6eyJjb25maXJtZWQiOjAsIm1hbmlmZXN0X3NoYTI1NiI6IjUyZjA5ZDVkNjM5YjFjMzgzZjM3Nzk2M2U0ODdjYjg5ZDg5NDE3ODU3ZTQ0ZGE3ZTNmMjNlNTViZTc1MWU3ZjQiLCJyZWNvcmRzIjpbXSwicmVxdWlyZWQiOjAsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tcG9zdGNvbmRpdGlvbi1ldmlkZW5jZS92MSIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifX0sImV2aWRlbmNlX3J1bm5lcl9zaWduZXJfc2hhMjU2IjoiNTY0NzVhYTc1NDYzNDc0YzAyODVkZjVkYmYyYmNhYjczZGE2NTEzNTg4MzllOWI3NzQ4MWIyZWFiMTA3NzA4YyIsImV4ZWN1dGlvbl9hdXRob3JpdHlfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDgiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NpZ25lcl9zaGEyNTYiOiIyNGY2ZWQ2YWNiZmUxMDA5YzAzMGQ3Y2E1NjdjMzNjYTQ4MzA5MTE0OTgyMzZiNTU2MWE2YzgyYWJlYzVkZTI4IiwiZXhlY3V0aW9uX291dGNvbWUiOnsiY29tcGVuc2F0aW9uX2FjdGlvbnMiOjAsImV2aWRlbmNlX2NsYXNzZXMiOlsiYXV0aG9yaXphdGlvbiJdLCJleGVjdXRpb25fY29tcGxldGVkIjpmYWxzZSwiZXh0ZXJuYWxfbmV0d29ya19jYWxscyI6Im9ic2VydmVkIiwibWFuYWdlZF9yZXN1bHRfbG9zc19ldmlkZW5jZV9zaGEyNTYiOiJmMjJmMjcwNDRlZjMxNWU5MzlhYmFkZjZiNjcyNWZjZjJiOTJmMmEyODAzOTQwNzU4MGUwZjJmN2UyMzA1NDk0IiwibW9kZWxfY2FsbHMiOjAsIm91dGNvbWUiOiJIQUxURUQiLCJwYXNzZWRfY29udHJhY3RzIjp7ImF1dGhvcml6YXRpb24iOjEsImVmZmVjdCI6MCwiaWRlbnRpdHkiOjAsInBvc3Rjb25kaXRpb24iOjB9LCJwb3N0Y29uZGl0aW9uX2V2aWRlbmNlIjpbXSwicHJvZHVjdGlvbl9lbGlnaWJsZSI6ZmFsc2UsInByb2ZpbGUiOiJzdGFuZGFyZCIsInF1YWxpZmljYXRpb25fZXZpZGVuY2Vfb25seSI6ZmFsc2UsInJlcXVpcmVkX2NvbnRyYWN0cyI6eyJhdXRob3JpemF0aW9uIjoxLCJlZmZlY3QiOjAsImlkZW50aXR5IjowLCJwb3N0Y29uZGl0aW9uIjowfSwidmVyc2lvbiI6Im9wZW5hZGFwdC5leGVjdXRpb24tb3V0Y29tZS92MSIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifSwiZXhlY3V0aW9uX291dGNvbWVfc2hhMjU2IjoiY2MzMGNiNGJlMzA1YmM1NzI1NzE1OGVjOThkMjUwYzA4MDgyMjAyOGI1ZTZiYTA5OTQ1N2ViYTQ3NTgxY2MzYyIsImV4ZWN1dGlvbl9wdXJwb3NlIjoicHJvZHVjdGlvbiIsImZpbmFsX2F1dGhvcml0eV9zZXF1ZW5jZSI6MCwiZmluYWxfcnVudGltZV9kZWxpdmVyeV9zZXF1ZW5jZSI6OSwiZmxvd19ydW5faWRfc2hhMjU2IjoiMTFlNTk0ZjQ4MTk1OGMxMGUzMDE1ZDBiZjA0NDdhMjJmMDY4YThhNjQ3ZjQ3NWRmMTVjZTJjN2FiNGI4ZjNmMSIsImlkZW50aXR5X2NvbnRyYWN0X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJpc3N1ZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAzWiIsIm1hbmFnZWRfcmVzdWx0X2xvc3MiOnsiYWN0dWF0aW9uX3JlcGxheV9hdXRob3JpemVkIjpmYWxzZSwiYXV0aGVudGljYXRlZF9ydW5uZXJfaWRfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsImF1dGhlbnRpY2F0ZWRfc2Vzc2lvbl9pZF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiYmxpbmRfcmV0cnlfYXV0aG9yaXplZCI6ZmFsc2UsImNoaWxkX3JlcG9ydF9yZXRhaW5lZCI6ZmFsc2UsImNoaWxkX3N0YXJ0X2V2aWRlbmNlX3NoYTI1NiI6ImVjNjkwNzkxODg2YWUyY2UwMGM0ZTUxMTU0YzNmMTIwZWE0NDE5ZWQyNjUxZTA3M2RiNTcyNDkxOGEzYjA4YzYiLCJjaGlsZF9zdGFydGVkIjp0cnVlLCJjaGlsZF9zdGFydGVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMFoiLCJkZWxpdmVyeV9yZXN1bHRfbG9zc19jbG9zdXJlX2FydGlmYWN0X3NoYTI1NiI6ImIyZDkyZjMyNDhmNGRhNjFlZGIwMjdjZjU5ZGE1Mzk1ZmZjNDE4ZWFkNmQ0ODVjMjlkZjZjMzViYzIxYTkzMGQiLCJkZWxpdmVyeV9zdGF0ZSI6IkNMT1NFRF9VTlJFU09MVkVEX1JFU1VMVF9MT1NTIiwiZGlzcGF0Y2hfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDkiLCJkaXNwYXRjaF9zZXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDEwIiwiZWZmZWN0X2Fic2VuY2VfY2xhaW1lZCI6ZmFsc2UsImV2aWRlbmNlX3NoYTI1NiI6ImYyMmYyNzA0NGVmMzE1ZTkzOWFiYWRmNmI2NzI1ZmNmMmI5MmYyYTI4MDM5NDA3NTgwZTBmMmY3ZTIzMDU0OTQiLCJleGVjdXRpb25fYXV0aG9yaXR5X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA4IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaWduZXJfc2hhMjU2IjoiMjRmNmVkNmFjYmZlMTAwOWMwMzBkN2NhNTY3YzMzY2E0ODMwOTExNDk4MjM2YjU1NjFhNmM4MmFiZWM1ZGUyOCIsImZsb3dfcnVuX2lkX3NoYTI1NiI6IjExZTU5NGY0ODE5NThjMTBlMzAxNWQwYmYwNDQ3YTIyZjA2OGE4YTY0N2Y0NzVkZjE1Y2UyYzdhYjRiOGYzZjEiLCJpZGVtcG90ZW5jeV9rZXlfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsImxvc3NfY29kZSI6InJlcG9ydF9taXNzaW5nIiwibWFuYWdlZF9kaXNwYXRjaF9iaW5kaW5nX3NoYTI1NiI6InNoYTI1NjpjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwibm90X3JlY2VpdmVkX2NsYWltZWQiOmZhbHNlLCJvYnNlcnZlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDJaIiwicGVuZGluZ19hY3Rpb25fcmVxdWVzdF9zaGEyNTYiOm51bGwsInBlbmRpbmdfcGVybWl0X2FydGlmYWN0X3NoYTI1NiI6bnVsbCwicmVwb3J0X3Byb3ZlbmFuY2UiOiJvdXRlcl9ydW5uZXJfcmVjb3ZlcnkiLCJydW5faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDEiLCJydW5fcmVxdWVzdF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwicnVuX3N0b3JlX2lkZW50aXR5X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5tYW5hZ2VkLXJlc3VsdC1sb3NzL3YxIn0sInBlbmRpbmdfcGVybWl0X2NvdW50IjowLCJwZXJtaXRfY2hhaW4iOnsiZW50cmllcyI6W3siZGVsaXZlcnlfcmVjZWlwdF9hcnRpZmFjdCI6eyJwYXlsb2FkIjp7ImF1dGhlbnRpY2F0ZWRfcnVubmVyX2lkX3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJhdXRoZW50aWNhdGVkX3Nlc3Npb25faWRfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsImRlbGl2ZXJlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDFaIiwiZXhlY3V0aW9uX2F1dGhvcml0eV9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOCIsIm9uZV91c2VfY2xhaW1faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMTAiLCJwZXJtaXRfYXJ0aWZhY3Rfc2hhMjU2IjoiOTcyYTgyYWY0NTZkYTU0MmJhYzc4NDYwMTg4OTY2ODg5MWQ4YjdjY2QyNDI5MDQ4MTZiMzI5MmUxNTdlNTI4OSIsInBlcm1pdF9pZCI6InBlcm1pdDoxIiwicnVudGltZV9kZWxpdmVyeV9zZXF1ZW5jZSI6OSwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1yZWNlaXB0LXBheWxvYWQvdjIifSwicGF5bG9hZF9zaGEyNTYiOiI4YThmNmQ4ODc1MGNiYjZiM2JkNjYyMDkzYWQyOWUyYmMyMGM2YWI2OTkxZDcwZTU4ODY5MWM4YjNhYjY2MmI5Iiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1yZWNlaXB0LWFydGlmYWN0L3YyIiwic2lnbmF0dXJlIjoiQU9LcUNnUzFzMFhhLWl5RTk2Vi15bFB6UWN2MnV2T3N1eWdIenZ1MlJ5VjdGTHNIRl9MVmZxeXg0dTJwdW1sRWwwWWs1WXU3MEpWVWtzWnBhVXBERHciLCJzaWduZXIiOnsiYWxnb3JpdGhtIjoiZWQyNTUxOSIsImtleV9pZCI6ImRlbGl2ZXJ5LWF1dGhvcml0eS1lZDI1NTE5LTI0ZjZlZDZhY2JmZTEwMDkiLCJwdWJsaWNfa2V5IjoiS2F5NjRVRzh5dkN5TGhxVTAwMEx4elllVW0wTC9oTElsNVM4a3lLV2JkYz0ifX0sImRlbGl2ZXJ5X3JlY2VpcHRfYXJ0aWZhY3Rfc2hhMjU2IjoiYzAwYTFiYTcwMTVmM2NiZTA1YTc2YWVhYmZmNjE5ZDc5M2U3Mzc1YTMxMGUxOTVmY2JiZDJkMjk0OGYyYjIxNCIsInBlcm1pdF9hcnRpZmFjdCI6eyJwYXlsb2FkIjp7ImFjdGlvbl9yZXF1ZXN0X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJhZG1pc3Npb25fYXJ0aWZhY3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsImF1dGhvcml0eV9zZXF1ZW5jZSI6MCwiZW52aXJvbm1lbnRfZGlnZXN0IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImV2aWRlbmNlX2lkZW50aXR5X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJleGVjdXRpb25fYXV0aG9yaXR5X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA4IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZmxvd19ydW5faWRfc2hhMjU2IjoiMTFlNTk0ZjQ4MTk1OGMxMGUzMDE1ZDBiZjA0NDdhMjJmMDY4YThhNjQ3ZjQ3NWRmMTVjZTJjN2FiNGI4ZjNmMSIsImlucHV0X2VkZ2Vfc2VxdWVuY2UiOjEsImlzc3VlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDBaIiwicGVybWl0X2lkIjoicGVybWl0OjEiLCJxdWFsaWZpY2F0aW9uX3NpZ25lcl9yZWdpc3RyeV9jaGVja2VkX2F0IjoiMjAyNi0wOC0xOFQxMTo1OTozMFoiLCJxdWFsaWZpY2F0aW9uX3NpZ25lcl9yZWdpc3RyeV9leHBpcmVzX2F0IjoiMjAyNi0wOC0yMFQxMTowMDowMFoiLCJxdWFsaWZpY2F0aW9uX3NpZ25lcl9yZWdpc3RyeV9yZXZpc2lvbiI6NywicXVhbGlmaWNhdGlvbl9zaWduZXJfcmVnaXN0cnlfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsInJ1bl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwMSIsInJ1bl9yZXF1ZXN0X3NoYTI1NiI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXBlcm1pdC1wYXlsb2FkL3YyIn0sInBheWxvYWRfc2hhMjU2IjoiYzg3ZjU3NTFhYTliMjc5Y2NlMjNhYTE3OGFmZjk1NmUxOWY2OTBmY2QyZjlmNzBlMGQ5OTk3ODJhNjkwZDZiOCIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcGVybWl0LWFydGlmYWN0L3YyIiwic2lnbmF0dXJlIjoiMEJ5SGdxRHhRWnJuZ0xJRi02dFpPcTlsWGFtY0FRQzBkb1VUbmVLTlBlUy1TeW9PYlF5T2tBdVBGSzVQWWNOek9iWnhnc2dBTGRXYUlfc2FVQ3BsQmciLCJzaWduZXIiOnsiYWxnb3JpdGhtIjoiZWQyNTUxOSIsImtleV9pZCI6ImRlbGl2ZXJ5LWF1dGhvcml0eS1lZDI1NTE5LTI0ZjZlZDZhY2JmZTEwMDkiLCJwdWJsaWNfa2V5IjoiS2F5NjRVRzh5dkN5TGhxVTAwMEx4elllVW0wTC9oTElsNVM4a3lLV2JkYz0ifX0sInBlcm1pdF9hcnRpZmFjdF9zaGEyNTYiOiI5NzJhODJhZjQ1NmRhNTQyYmFjNzg0NjAxODg5NjY4ODkxZDhiN2NjZDI0MjkwNDgxNmIzMjkyZTE1N2U1Mjg5Iiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1wZXJtaXQtY2hhaW4tZW50cnkvdjIifV0sInBlcm1pdF9jaGFpbl9zaGEyNTYiOiI1MDQ4ZmU5NDU4ODJkMjgwMjYwMDhkN2U5MTM3YWQwMTZmZGQwMWFlYWY1ODg0ODFmYjViZDBmMjQyYTUwMDQzIiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1wZXJtaXQtY2hhaW4vdjIifSwicGVybWl0X2NvdW50IjoxLCJxdWFsaWZpY2F0aW9uX3NpZ25lcl9yZWdpc3RyeV9yZXZpc2lvbiI6NywicXVhbGlmaWNhdGlvbl9zaWduZXJfcmVnaXN0cnlfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsInJ1bl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwMSIsInJ1bl9yZWNlaXB0Ijp7ImF1dGhvcml6YXRpb25fY29uZmlybWVkIjoxLCJhdXRob3JpemF0aW9uX3JlcXVpcmVkIjoxLCJidW5kbGVfZGlnZXN0IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImR1cmF0aW9uX21zIjowLCJlZmZlY3RfdGllcl9yZWFjaGVkIjoibm9uZSIsImVmZmVjdHNfY29uZmlybWVkIjowLCJlZmZlY3RzX3JlcXVpcmVkIjowLCJlc3RfY29zdF9taWNyb3VzZCI6MCwiZXZpZGVuY2VfY2xhc3NlcyI6WyJhdXRob3JpemF0aW9uIl0sImV4dGVybmFsX25ldHdvcmtfY2FsbHMiOiJvYnNlcnZlZCIsImdlbmVyYXRlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDBaIiwiaGVhbHMiOjAsImlkZW50aXR5X2FwcGxpY2FibGUiOjAsImlkZW50aXR5X2FybWVkIjowLCJpZGVudGl0eV9jb25maXJtZWQiOjAsImlkZW50aXR5X3JlcXVpcmVkIjowLCJtYW5hZ2VkX3Jlc3VsdF9sb3NzX2V2aWRlbmNlX3NoYTI1NiI6ImYyMmYyNzA0NGVmMzE1ZTkzOWFiYWRmNmI2NzI1ZmNmMmI5MmYyYTI4MDM5NDA3NTgwZTBmMmY3ZTIzMDU0OTQiLCJtb2RlbF9jYWxscyI6MCwib3V0Y29tZSI6IkhBTFRFRCIsIm92ZXJfaGFsdF9jb3VudCI6MCwicG9zdGNvbmRpdGlvbnNfY29uZmlybWVkIjowLCJwb3N0Y29uZGl0aW9uc19yZXF1aXJlZCI6MCwicHJvZHVjdGlvbl9lbGlnaWJsZSI6ZmFsc2UsInByb2ZpbGUiOiJzdGFuZGFyZCIsInByb3ZlbmFuY2UiOiJwcm9kdWN0aW9uIiwicmVjZWlwdF9idWlsZGVyX3ZlcnNpb24iOiIxLjIuMyIsInJ1bmdfaGlzdG9ncmFtIjp7fSwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1ydW4tcmVjZWlwdC92MSIsInNvdXJjZV9yZWNlaXB0X2RpZ2VzdCI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJzb3VyY2VfcmVjZWlwdF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwic291cmNlX3NjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnJ1bi1yZXBvcnQvdjEiLCJzdGVwc19vayI6MCwic3RlcHNfdG90YWwiOjEsInN1YnN0cmF0ZSI6IndlYiIsInRyYW5zYWN0aW9uX291dGNvbWUiOiJSRUNPTkNJTElBVElPTl9SRVFVSVJFRCJ9LCJydW5fcmVjZWlwdF9zaGEyNTYiOiJjOWRkNjNkNWY1MDEzNGU1NDZmNzJkMmQ4ZTcyMjJkMGEwNDM1ZWIwMmVkY2M4NWVjYTZjNzY5MjMwNWRjZTMwIiwicnVuX3JlcG9ydF9vYmplY3Rfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsInJ1bl9yZXBvcnRfb2JqZWN0X3ZlcnNpb24iOiJ2ZXJzaW9uOm1hbmFnZWQtcmVzdWx0LWxvc3M6MSIsInJ1bl9yZXBvcnRfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsInJ1bnRpbWVfZW52aXJvbm1lbnRfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsInJ1bnRpbWVfc3Vic3RyYXRlIjoid2ViIiwicnVudGltZV92YWxpZGF0aW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA1Iiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi10ZXJtaW5hbC12ZXJpZmljYXRpb24vdjIiLCJ0ZW5hbnRfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDIiLCJ0ZXJtaW5hbF9zZXF1ZW5jZSI6MSwidmVyaWZpZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAyWiIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJ3b3JrZmxvd19pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwMyIsIndvcmtmbG93X3ZlcnNpb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDQifSwic2lnbmF0dXJlIjoiU212VGw5N1MwNm9pb2NNMGNza0tIQ3ZnV1Q5T1dDN3V4NkN4WXljQ2hyMjFjY3B2Y3ExT3R3MUh5V1ZJMGhubTNDRExJcWgtVmN2cTh4TmdPTm40QkEiLCJzaWduZXIiOnsiYWxnb3JpdGhtIjoiZWQyNTUxOSIsImtleV9pZCI6ImV2aWRlbmNlLXJ1bm5lci1lZDI1NTE5LTU2NDc1YWE3NTQ2MzQ3NGMiLCJwdWJsaWNfa2V5IjoiQTZFSHYvUE9FTDRkY04wWTUwdkFtV2ZrMWpDYnBRMWZIZHlHWkJKVk1iZz0ifX0=", "managed_result_loss": { "actuation_replay_authorized": false, "authenticated_runner_id_sha256": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", @@ -241,9 +256,9 @@ "schema_version": "openadapt.managed-result-loss/v1" }, "name": "reconciliation-required-managed-result-loss-acknowledged", - "payload_canonical_sha256": "c024765711724b2645dbe23c250d301079e9045cc45f54eba72bacab3a22233b", - "signature": "X0qk_NBWTUJVMKCcEhRGqcIx4c97XwU6K88OJelwqsaiXemM_gFRx0yMb7Or8_eIR6jL43CISO0G4Rk7IeX5Cw", - "terminal_verification_artifact_sha256": "1707d4b13e8549cb7b12edae186866006b0211933830384d9fca6e1fc0b54756" + "payload_canonical_sha256": "5a09dfb147c5ba0cdab0038fb33e9ac497c5b95ccb2b85abd4fc5171f8ca22f1", + "signature": "SmvTl97S06oiocM0cskKHCvgWT9OWC7ux6CxYycChr21ccpvcq1Otw1HyWVI0hnm3CDLIqh-Vcvq8xNgONn4BA", + "terminal_verification_artifact_sha256": "eea2765e1d7f414e8299125eb3187b62c653f320ccaf08f45dc7bf572e2f5ae2" } ] } diff --git a/tests/test_hosted_runner_adapter.py b/tests/test_hosted_runner_adapter.py index 1dae494f..67f2574b 100644 --- a/tests/test_hosted_runner_adapter.py +++ b/tests/test_hosted_runner_adapter.py @@ -1015,8 +1015,17 @@ def runner(argv, _run_dir, child_env): ManagedExecution(returncode=1, report_bytes=None), "report_missing", ), + ( + ManagedExecution(returncode=1, report_bytes=b"{"), + "report_invalid", + ), ], - ids=("runtime-exception", "transport-exception", "missing-report"), + ids=( + "runtime-exception", + "transport-exception", + "missing-report", + "malformed-report", + ), ) def test_expected_result_loss_returns_one_signed_reconciliation_without_retry( monkeypatch, @@ -1065,11 +1074,21 @@ def runner(_argv, _run_dir, _child_env): ) report = _production_report() seen_loss_codes: list[str] = [] + seen_fence_codes: list[str] = [] + + def retain_loss_closure(**kwargs): + seen_fence_codes.append(kwargs["loss_code"]) + return object() def produce_loss(**kwargs): seen_loss_codes.append(kwargs["loss_code"]) return proof, proof.payload.run_report_sha256, report + monkeypatch.setattr( + adapter, + "_retain_managed_result_loss_closure", + retain_loss_closure, + ) monkeypatch.setattr(adapter, "_produce_managed_result_loss", produce_loss) authority = DeliveryAuthority( dispatch.managed_delivery_authority_url, @@ -1086,6 +1105,7 @@ def produce_loss(**kwargs): callback = adapter.callback_request(dispatch, result) assert calls == 1 + assert seen_fence_codes == [expected_loss_code] assert seen_loss_codes == [expected_loss_code] assert result.outcome is TransactionOutcome.RECONCILIATION_REQUIRED assert result.uncertain_delivery is True @@ -1112,6 +1132,177 @@ def produce_loss(**kwargs): assert calls == 1 +@pytest.mark.parametrize( + ("result_mode", "expected_loss_code"), + [ + ("runner-exception", "runner_exception"), + ("missing-report", "report_missing"), + ("malformed-report", "report_invalid"), + ("conflicting-child-proof", "report_invalid"), + ], +) +def test_result_loss_fences_before_terminal_trust_revalidation( + monkeypatch, + tmp_path, + config, + sealed, + result_mode, + expected_loss_code, +) -> None: + workflow, _ = sealed + + def runner(_argv, _run_dir, _child_env): + if result_mode == "runner-exception": + raise RuntimeError("child result lost") + if result_mode == "missing-report": + return ManagedExecution(returncode=1, report_bytes=None) + if result_mode == "malformed-report": + return ManagedExecution(returncode=1, report_bytes=b"{") + return ManagedExecution( + returncode=0, + report_bytes=_production_report().model_dump_json().encode("utf-8"), + terminal_verification=sign_production_terminal_verification( + _managed_result_loss_payload(), + _private_key(), + ), + ) + + adapter, dispatch = _prepared_adapter( + monkeypatch, + tmp_path, + config, + workflow, + runner, + ) + fence_codes: list[str] = [] + + def retain_fence(**kwargs): + fence_codes.append(kwargs["loss_code"]) + return object() + + monkeypatch.setattr( + adapter, + "_retain_managed_result_loss_closure", + retain_fence, + ) + monkeypatch.setattr( + adapter, + "_revalidate_terminal_authority", + lambda **_kwargs: (_ for _ in ()).throw(ValueError("authority revoked")), + ) + authority = DeliveryAuthority( + dispatch.managed_delivery_authority_url, + dispatch.delivery_authority_token, + ) + + with pytest.raises(RuntimeError, match="signed terminal reconciliation"): + adapter.execute( + dispatch, + runner_config=tmp_path / "runner.toml", + run_dir=tmp_path / "run", + authority=authority, + closure_authority=SimpleNamespace(), + ) + + assert fence_codes == [expected_loss_code] + reservation = adapter._ledger.lookup( + f"{dispatch.tenant_id}:{dispatch.idempotency_key}" + ) + assert reservation is not None + assert reservation["outcome"] == "RECONCILIATION_REQUIRED" + + +def test_result_loss_fences_before_missing_child_manifest_is_read( + monkeypatch, tmp_path, config, sealed +) -> None: + workflow, _ = sealed + + def runner(_argv, _run_dir, _child_env): + raise RuntimeError("child result lost") + + adapter, dispatch = _prepared_adapter( + monkeypatch, + tmp_path, + config, + workflow, + runner, + ) + fenced = object() + monkeypatch.setattr( + adapter, + "_retain_managed_result_loss_closure", + lambda **_kwargs: fenced, + ) + monkeypatch.setattr( + adapter, + "_revalidate_terminal_authority", + lambda **_kwargs: (object(), object()), + ) + authority = DeliveryAuthority( + dispatch.managed_delivery_authority_url, + dispatch.delivery_authority_token, + ) + + with pytest.raises(RuntimeError, match="signed terminal reconciliation") as error: + adapter.execute( + dispatch, + runner_config=tmp_path / "runner.toml", + run_dir=tmp_path / "run", + authority=authority, + closure_authority=SimpleNamespace(), + ) + + assert isinstance(error.value.__cause__, ValueError) + assert "retained run manifest" in str(error.value.__cause__) + + +def test_restart_recovery_fences_before_current_runner_trust_is_loaded( + monkeypatch, tmp_path, sealed +) -> None: + workflow, _ = sealed + dispatch = _hosted_dispatch(workflow) + adapter = HostedRunnerAdapter(tmp_path / "ledger.sqlite") + run_dir = tmp_path / "run" + run_dir.mkdir(mode=0o700) + adapter._write_child_start_evidence( + dispatch=dispatch, + run_dir=run_dir, + dispatch_binding_sha256=dispatch.payload.dispatch_binding_sha256, + ) + adapter._ledger.reserve( + f"{dispatch.tenant_id}:{dispatch.idempotency_key}", + run_id=dispatch.run_id, + ) + fence_codes: list[str] = [] + + def retain_fence(**kwargs): + fence_codes.append(kwargs["loss_code"]) + return object() + + monkeypatch.setattr( + adapter, + "_retain_managed_result_loss_closure", + retain_fence, + ) + monkeypatch.setattr( + hosted, + "load_runner_config", + lambda *_args, **_kwargs: (_ for _ in ()).throw( + ValueError("runner trust unavailable") + ), + ) + + with pytest.raises(ValueError, match="runner trust unavailable"): + adapter.recover_uncertain_run( + dispatch, + runner_config=tmp_path / "runner.toml", + run_dir=run_dir, + closure_authority=SimpleNamespace(), + ) + + assert fence_codes == ["recovered_after_restart"] + + def test_managed_result_loss_report_is_outer_recovery_only(tmp_path, sealed) -> None: workflow, _ = sealed dispatch = _hosted_dispatch(workflow) diff --git a/tests/test_terminal_verification_v2.py b/tests/test_terminal_verification_v2.py index 92cc246f..f5813809 100644 --- a/tests/test_terminal_verification_v2.py +++ b/tests/test_terminal_verification_v2.py @@ -944,7 +944,7 @@ def _managed_result_loss_payload( postcondition_evidence=(), evidence_classes=("authorization",), model_calls=0, - external_network_calls="none", + external_network_calls="observed", managed_result_loss_evidence_sha256=loss.evidence_sha256, ) receipt = ProductionRunReceipt( @@ -976,7 +976,7 @@ def _managed_result_loss_payload( substrate="web", provenance="production", receipt_builder_version="1.2.3", - external_network_calls="none", + external_network_calls="observed", bundle_digest=SHA_A, source_receipt_digest=SHA_B, source_receipt_sha256=SHA_B, @@ -1317,6 +1317,25 @@ def test_terminal_v2_signs_managed_result_loss_without_effect_absence() -> None: assert loss.blind_retry_authorized is False assert loss.actuation_replay_authorized is False assert envelope.payload.managed_result_loss == loss + assert payload.execution_outcome.external_network_calls == "observed" + assert payload.run_receipt.external_network_calls == "observed" + + +def test_managed_result_loss_requires_observed_closure_network_io() -> None: + raw = _managed_result_loss_payload().model_dump(mode="json") + outcome = ProductionExecutionOutcome.model_validate(raw["execution_outcome"]) + outcome = outcome.model_copy(update={"external_network_calls": "none"}) + receipt = ProductionRunReceipt.model_validate(raw["run_receipt"]) + receipt = receipt.model_copy(update={"external_network_calls": "none"}) + raw["execution_outcome"] = outcome.model_dump(mode="json") + raw["execution_outcome_sha256"] = outcome.artifact_sha256() + raw["run_receipt"] = receipt.model_dump(mode="json") + raw["run_receipt_sha256"] = hashlib.sha256( + canonical_json(receipt.model_dump(mode="json")) + ).hexdigest() + + with pytest.raises(ValueError, match="managed result loss terminal binding"): + ProductionTerminalVerificationPayload.model_validate(raw) def test_terminal_v2_signs_ack_won_managed_result_loss_without_uncertainty() -> None: @@ -1871,42 +1890,56 @@ def test_managed_result_loss_closure_cross_language_vector_is_exact() -> None: encoding="utf-8" ) ) - vector = fixture["managed_result_loss_closure_vector"] - request_raw = b64decode(vector["request_canonical_base64"], validate=True) - closure_raw = b64decode( - vector["closure_artifact_canonical_base64"], validate=True - ) - chain_raw = b64decode(vector["permit_chain_canonical_base64"], validate=True) - result_raw = b64decode(vector["result_canonical_base64"], validate=True) - request = ProductionDeliveryResultLossClosureRequest.model_validate_json( - request_raw - ) - closure = ProductionDeliveryResultLossClosureArtifact.model_validate_json( - closure_raw + names = ( + "managed_result_loss_closure_vector", + "managed_result_loss_acknowledged_closure_vector", ) - chain = ProductionDeliveryPermitChain.model_validate_json(chain_raw) - result = ProductionDeliveryResultLossClosureResult.model_validate_json(result_raw) + pending_counts: list[int] = [] + for name in names: + vector = fixture[name] + request_raw = b64decode(vector["request_canonical_base64"], validate=True) + closure_raw = b64decode( + vector["closure_artifact_canonical_base64"], validate=True + ) + chain_raw = b64decode( + vector["permit_chain_canonical_base64"], validate=True + ) + result_raw = b64decode(vector["result_canonical_base64"], validate=True) + request = ProductionDeliveryResultLossClosureRequest.model_validate_json( + request_raw + ) + closure = ProductionDeliveryResultLossClosureArtifact.model_validate_json( + closure_raw + ) + chain = ProductionDeliveryPermitChain.model_validate_json(chain_raw) + result = ProductionDeliveryResultLossClosureResult.model_validate_json( + result_raw + ) - assert vector["http_method"] == "POST" - assert vector["http_route"] == ( - "/api/internal/managed-delivery-result-loss-closure" - ) - assert vector["authorization_credential_source"] == "hosted_dispatch.lease_token" - assert b64decode(vector["request_digest_domain_base64"], validate=True) == ( - RESULT_LOSS_CLOSURE_REQUEST_DOMAIN - ) - assert b64decode(vector["payload_signature_domain_base64"], validate=True) == ( - RESULT_LOSS_CLOSURE_PAYLOAD_DOMAIN - ) - assert request.canonical_bytes() == request_raw - assert request.request_sha256() == vector["request_sha256"] - assert closure.canonical_bytes() == closure_raw - assert closure.payload_sha256 == vector["closure_payload_sha256"] - assert closure.artifact_sha256() == vector["closure_artifact_sha256"] - assert canonical_json(chain) == chain_raw - assert chain.permit_chain_sha256 == vector["permit_chain_sha256"] - assert canonical_json(result) == result_raw - assert result.artifacts() == (closure, chain) + assert vector["http_method"] == "POST" + assert vector["http_route"] == ( + "/api/internal/managed-delivery-result-loss-closure" + ) + assert vector["authorization_credential_source"] == ( + "hosted_dispatch.lease_token" + ) + assert b64decode(vector["request_digest_domain_base64"], validate=True) == ( + RESULT_LOSS_CLOSURE_REQUEST_DOMAIN + ) + assert b64decode( + vector["payload_signature_domain_base64"], validate=True + ) == (RESULT_LOSS_CLOSURE_PAYLOAD_DOMAIN) + assert request.canonical_bytes() == request_raw + assert request.request_sha256() == vector["request_sha256"] + assert closure.canonical_bytes() == closure_raw + assert closure.payload_sha256 == vector["closure_payload_sha256"] + assert closure.artifact_sha256() == vector["closure_artifact_sha256"] + assert canonical_json(chain) == chain_raw + assert chain.permit_chain_sha256 == vector["permit_chain_sha256"] + assert canonical_json(result) == result_raw + assert result.artifacts() == (closure, chain) + pending_counts.append(closure.payload.pending_permit_count) + assert pending_counts == [1, 0] def test_delivery_artifact_rebuild_rejects_noncanonical_stored_bytes() -> None: From 72fbf0e0c3e4519d023a9cf149bec86d980b0189 Mon Sep 17 00:00:00 2001 From: Richard Abrich Date: Thu, 27 Aug 2026 17:04:02 -0400 Subject: [PATCH 6/7] style: format terminal closure vector checks --- tests/test_terminal_verification_v2.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/tests/test_terminal_verification_v2.py b/tests/test_terminal_verification_v2.py index f5813809..dd9b23ed 100644 --- a/tests/test_terminal_verification_v2.py +++ b/tests/test_terminal_verification_v2.py @@ -1901,9 +1901,7 @@ def test_managed_result_loss_closure_cross_language_vector_is_exact() -> None: closure_raw = b64decode( vector["closure_artifact_canonical_base64"], validate=True ) - chain_raw = b64decode( - vector["permit_chain_canonical_base64"], validate=True - ) + chain_raw = b64decode(vector["permit_chain_canonical_base64"], validate=True) result_raw = b64decode(vector["result_canonical_base64"], validate=True) request = ProductionDeliveryResultLossClosureRequest.model_validate_json( request_raw @@ -1926,9 +1924,9 @@ def test_managed_result_loss_closure_cross_language_vector_is_exact() -> None: assert b64decode(vector["request_digest_domain_base64"], validate=True) == ( RESULT_LOSS_CLOSURE_REQUEST_DOMAIN ) - assert b64decode( - vector["payload_signature_domain_base64"], validate=True - ) == (RESULT_LOSS_CLOSURE_PAYLOAD_DOMAIN) + assert b64decode(vector["payload_signature_domain_base64"], validate=True) == ( + RESULT_LOSS_CLOSURE_PAYLOAD_DOMAIN + ) assert request.canonical_bytes() == request_raw assert request.request_sha256() == vector["request_sha256"] assert closure.canonical_bytes() == closure_raw From 5ad3cc7a52a4ba8f1b452ae71fe88ee82f96ab56 Mon Sep 17 00:00:00 2001 From: Richard Abrich Date: Fri, 28 Aug 2026 16:58:16 -0400 Subject: [PATCH 7/7] fix(vectors): emit valid terminal callback events --- public-artifacts.json | 2 +- ...nerate_terminal_verification_v2_vectors.py | 52 +++++++------------ ...inal_verification_v2_terminal_vectors.json | 18 ++++--- tests/test_terminal_verification_v2.py | 18 +++++-- 4 files changed, 44 insertions(+), 46 deletions(-) diff --git a/public-artifacts.json b/public-artifacts.json index 2e55d127..2d3c6ff8 100644 --- a/public-artifacts.json +++ b/public-artifacts.json @@ -5785,7 +5785,7 @@ }, { "path": "tests/fixtures/terminal_verification_v2_terminal_vectors.json", - "sha256": "2c2af93f1cd5d7b62ede33e59475aa61126cdc9c568949e1a8722b0d899bee3f" + "sha256": "6bd3a063c69d122ae5b94024c31cd445a202a061fccf5d2ad4f503d66c1fef18" }, { "path": "tests/fixtures/theme-region-stable-overhalt-v1.16.1.json", diff --git a/scripts/generate_terminal_verification_v2_vectors.py b/scripts/generate_terminal_verification_v2_vectors.py index b42e75c4..ba1da7bf 100644 --- a/scripts/generate_terminal_verification_v2_vectors.py +++ b/scripts/generate_terminal_verification_v2_vectors.py @@ -12,6 +12,7 @@ from cryptography.hazmat.primitives import serialization from openadapt_flow.qualification_admission_v2 import canonical_json +from openadapt_flow.runner.hosted_adapter import HostedTerminalEvent from openadapt_flow.terminal_verification_v2 import ( RESULT_LOSS_CLOSURE_PAYLOAD_DOMAIN, RESULT_LOSS_CLOSURE_REQUEST_DOMAIN, @@ -34,7 +35,7 @@ DEFAULT_OUTPUT = Path("tests/fixtures/terminal_verification_v2_terminal_vectors.json") -def _vector(name: str, *, uncertain_delivery: bool) -> dict[str, object]: +def _vector(name: str) -> dict[str, object]: payload = { "verified-complete": _payload, "halted-before-effect-zero-permit": _halted_payload, @@ -50,16 +51,17 @@ def _vector(name: str, *, uncertain_delivery: bool) -> dict[str, object]: envelope = sign_production_terminal_verification(payload, _private_key()) raw = canonical_json(envelope) effect_records = payload.evidence_manifests.effect.records + callback = HostedTerminalEvent( + run_id=payload.run_id, + outcome=payload.run_receipt.transaction_outcome, + report_sha256=payload.run_report_sha256, + started=True, + uncertain_delivery=payload.pending_permit_count == 1, + terminal_verification_artifact_bytes_base64=b64encode(raw).decode("ascii"), + terminal_verification_artifact_sha256=envelope.artifact_sha256(), + ) return { - "callback": { - "artifact_bytes_source": "envelope_canonical_base64", - "outcome": payload.run_receipt.transaction_outcome, - "report_sha256": payload.run_report_sha256, - "run_id": payload.run_id, - "schema_version": "openadapt.hosted-runner-terminal/v1", - "started": True, - "uncertain_delivery": uncertain_delivery, - }, + "callback": callback.model_dump(mode="json"), "effect_state": ( effect_records[0].model_dump(mode="json") if effect_records else None ), @@ -144,30 +146,12 @@ def build_fixture() -> dict[str, object]: _result_loss_closure_vector(managed_acknowledged) ), "vectors": [ - _vector( - "verified-complete", - uncertain_delivery=False, - ), - _vector( - "halted-before-effect-zero-permit", - uncertain_delivery=False, - ), - _vector( - "reconciliation-required-pending-permit", - uncertain_delivery=True, - ), - _vector( - "reconciliation-required-acknowledged-inconclusive", - uncertain_delivery=False, - ), - _vector( - "reconciliation-required-managed-result-loss", - uncertain_delivery=True, - ), - _vector( - "reconciliation-required-managed-result-loss-acknowledged", - uncertain_delivery=False, - ), + _vector("verified-complete"), + _vector("halted-before-effect-zero-permit"), + _vector("reconciliation-required-pending-permit"), + _vector("reconciliation-required-acknowledged-inconclusive"), + _vector("reconciliation-required-managed-result-loss"), + _vector("reconciliation-required-managed-result-loss-acknowledged"), ], } diff --git a/tests/fixtures/terminal_verification_v2_terminal_vectors.json b/tests/fixtures/terminal_verification_v2_terminal_vectors.json index 5c7d9548..b6e75a60 100644 --- a/tests/fixtures/terminal_verification_v2_terminal_vectors.json +++ b/tests/fixtures/terminal_verification_v2_terminal_vectors.json @@ -38,12 +38,13 @@ "vectors": [ { "callback": { - "artifact_bytes_source": "envelope_canonical_base64", "outcome": "VERIFIED", "report_sha256": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "run_id": "00000000-0000-4000-8000-000000000001", "schema_version": "openadapt.hosted-runner-terminal/v1", "started": true, + "terminal_verification_artifact_bytes_base64": "eyJwYXlsb2FkIjp7ImFja25vd2xlZGdlZF9wZXJtaXRfY291bnQiOjEsImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA2IiwiYWRtaXNzaW9uX3BvbGljeV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYWRtaXR0ZWRfcnVudGltZV9idWlsZF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiYnVuZGxlX2FydGlmYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJidW5kbGVfY29udGVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYnVuZGxlX3ZlcnNpb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDQiLCJlZmZlY3RfY29udHJhY3Rfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImVudmlyb25tZW50X2NvbnRyYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJlbnZpcm9ubWVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXZpZGVuY2VfaWRlbnRpdHlfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImV2aWRlbmNlX21hbmlmZXN0cyI6eyJhdXRob3JpemF0aW9uIjp7ImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA2IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOCIsImV4ZWN1dGlvbl9hdXRob3JpdHlfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImdvdmVybmVkX2F1dGhvcml6YXRpb25faWRfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsIm1hbmlmZXN0X3NoYTI1NiI6ImYwY2ExOWE2YjNlYWJlNTk0ZGJjOTA2ODljMmY3NGNiZTVlODJkNGQ5NDdkYjI5YTVkMDdiMTY0MWU4OTYxY2YiLCJwZXJtaXRfY2hhaW5fc2hhMjU2IjoiNTA0OGZlOTQ1ODgyZDI4MDI2MDA4ZDdlOTEzN2FkMDE2ZmRkMDFhZWFmNTg4NDgxZmI1YmQwZjI0MmE1MDA0MyIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tYXV0aG9yaXphdGlvbi1ldmlkZW5jZS92MSJ9LCJlZmZlY3QiOnsiY29uZmlybWVkIjoxLCJlZmZlY3RfY29udHJhY3Rfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsIm1hbmlmZXN0X3NoYTI1NiI6ImEzOThlNGJmMDUyZmIwMzBiOTdlNDM1ZTI4M2E2ZjY2MzJkOWE1ZDUxMjU0YTYwZDY4OWUwNWEwZGY2ZjAxMDYiLCJyZWNvcmRzIjpbeyJlZmZlY3RfY29udHJhY3RfaGFzaCI6InNoYTI1NjphYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZmluYWxfdmVyZGljdCI6ImNvbmZpcm1lZCIsIm9ic2VydmVkX2VmZmVjdCI6InByZXNlbnQiLCJyZWNvbmNpbGlhdGlvbl9hY3Rpb25zIjowLCJyZWNvbmNpbGlhdGlvbl9jb21wbGV0ZWQiOmZhbHNlLCJyZXN1bHRfaW5kZXgiOjAsInZlcmlmaWNhdGlvbl90aWVyIjoxLCJ2ZXJpZmllcl9pZGVudGl0eSI6InNoYTI1NjpiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIn1dLCJyZXF1aXJlZCI6MSwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1lZmZlY3QtZXZpZGVuY2UvdjEiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIn0sImlkZW50aXR5Ijp7ImNvbmZpcm1lZCI6MSwiaWRlbnRpdHlfY29udHJhY3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsIm1hbmlmZXN0X3NoYTI1NiI6IjEzNWM4NjNlZGM3ZmFiMThjYTI5YjQ5MjkzZmMyNWExYzliZDRkZTBlOWVkMjhkNGNlYzZlOGQwYTY3OTEyMjkiLCJyZXF1aXJlZCI6MSwicmVzdWx0cyI6W3sibW9kZSI6InN0cnVjdHVyZWQiLCJyZXN1bHRfaW5kZXgiOjAsInNpZ25hbHMiOltdLCJzdGF0dXMiOiJ2ZXJpZmllZCJ9XSwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1pZGVudGl0eS1ldmlkZW5jZS92MSIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifSwicG9saWN5Ijp7ImFkbWlzc2lvbl9wb2xpY3lfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImVmZmVjdF9jb250cmFjdF9zaGEyNTYiOiJlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlIiwiZW52aXJvbm1lbnRfY29udHJhY3Rfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsImVudmlyb25tZW50X2RpZ2VzdCI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJnb3Zlcm5lZF9wb2xpY3lfY29udHJhY3Rfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsImdvdmVybmVkX3J1bnRpbWVfaW5wdXRzX2RpZ2VzdCI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJpZGVudGl0eV9jb250cmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwibWFuaWZlc3Rfc2hhMjU2IjoiNGY5ODhkMDE1YmNkN2NkN2UwNWJhMDY2M2Q4OWYwYTk2OGYwZDhhY2U5OWIwOTBlYmFiZWU1MmExYzU1MDQyMSIsIm1pbmltdW1fZWZmZWN0X3RpZXIiOjEsInJ1bnRpbWVfZW52aXJvbm1lbnRfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tcG9saWN5LWV2aWRlbmNlL3YxIn0sInBvc3Rjb25kaXRpb24iOnsiY29uZmlybWVkIjoxLCJtYW5pZmVzdF9zaGEyNTYiOiJmNjg1YWUyOWYzMjQyMzdiMzcxOWNiMmVkMTZkNmYzMjVmYjg4Yjk4Y2E0NmQ1MjNjY2I1MDJiYWFjOGQ5YjU5IiwicmVjb3JkcyI6W3siYWN0aW9uX2tpbmQiOiJjbGljayIsImFjdHVhdGlvbl9wYXRoIjoiZ3VpIiwiY29udHJhY3RfaW5kZXgiOjAsImNvbnRyYWN0X2tpbmQiOiJleHBsaWNpdF9wcmVkaWNhdGUiLCJjb250cmFjdF9zaGEyNTYiOiIwYWRlMGI1MjBiYzAwNzg5MWNhY2NhMDAxNzE1Nzg0NDJhMmE3NGNlZjE1ZmY2NGRkZTQ1ZGYwN2FmYjY0YWViIiwicmVzdWx0X2luZGV4IjowLCJzdGVwX2NvbnRyYWN0X3NoYTI1NiI6IjFhNTk1MzZhNDg4YjFjNDZhYWNmMGJhMzc5MzBiODQwNjJjMTQyNzU1ZmE5MzkxNTJlZjVlMjhjNDA5NDcxZWQiLCJzdGVwX2luZGV4IjowLCJ2ZXJkaWN0IjoicGFzc2VkIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSJ9XSwicmVxdWlyZWQiOjEsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tcG9zdGNvbmRpdGlvbi1ldmlkZW5jZS92MSIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifX0sImV2aWRlbmNlX3J1bm5lcl9zaWduZXJfc2hhMjU2IjoiNTY0NzVhYTc1NDYzNDc0YzAyODVkZjVkYmYyYmNhYjczZGE2NTEzNTg4MzllOWI3NzQ4MWIyZWFiMTA3NzA4YyIsImV4ZWN1dGlvbl9hdXRob3JpdHlfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDgiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NpZ25lcl9zaGEyNTYiOiIyNGY2ZWQ2YWNiZmUxMDA5YzAzMGQ3Y2E1NjdjMzNjYTQ4MzA5MTE0OTgyMzZiNTU2MWE2YzgyYWJlYzVkZTI4IiwiZXhlY3V0aW9uX291dGNvbWUiOnsiY29tcGVuc2F0aW9uX2FjdGlvbnMiOjAsImV2aWRlbmNlX2NsYXNzZXMiOlsiYXV0aG9yaXphdGlvbiIsImVmZmVjdF90aWVyXzEiLCJpZGVudGl0eSIsInBvc3Rjb25kaXRpb24iXSwiZXhlY3V0aW9uX2NvbXBsZXRlZCI6dHJ1ZSwiZXh0ZXJuYWxfbmV0d29ya19jYWxscyI6Im5vbmUiLCJtb2RlbF9jYWxscyI6MCwib3V0Y29tZSI6IlZFUklGSUVEIiwicGFzc2VkX2NvbnRyYWN0cyI6eyJhdXRob3JpemF0aW9uIjoxLCJlZmZlY3QiOjEsImlkZW50aXR5IjoxLCJwb3N0Y29uZGl0aW9uIjoxfSwicG9zdGNvbmRpdGlvbl9ldmlkZW5jZSI6W3siYWN0aW9uX2tpbmQiOiJjbGljayIsImFjdHVhdGlvbl9wYXRoIjoiZ3VpIiwiY29udHJhY3RfaW5kZXgiOjAsImNvbnRyYWN0X2tpbmQiOiJleHBsaWNpdF9wcmVkaWNhdGUiLCJjb250cmFjdF9zaGEyNTYiOiIwYWRlMGI1MjBiYzAwNzg5MWNhY2NhMDAxNzE1Nzg0NDJhMmE3NGNlZjE1ZmY2NGRkZTQ1ZGYwN2FmYjY0YWViIiwicmVzdWx0X2luZGV4IjowLCJzdGVwX2NvbnRyYWN0X3NoYTI1NiI6IjFhNTk1MzZhNDg4YjFjNDZhYWNmMGJhMzc5MzBiODQwNjJjMTQyNzU1ZmE5MzkxNTJlZjVlMjhjNDA5NDcxZWQiLCJzdGVwX2luZGV4IjowLCJ2ZXJkaWN0IjoicGFzc2VkIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSJ9XSwicHJvZHVjdGlvbl9lbGlnaWJsZSI6dHJ1ZSwicHJvZmlsZSI6InN0YW5kYXJkIiwicXVhbGlmaWNhdGlvbl9ldmlkZW5jZV9vbmx5IjpmYWxzZSwicmVxdWlyZWRfY29udHJhY3RzIjp7ImF1dGhvcml6YXRpb24iOjEsImVmZmVjdCI6MSwiaWRlbnRpdHkiOjEsInBvc3Rjb25kaXRpb24iOjF9LCJ2ZXJzaW9uIjoib3BlbmFkYXB0LmV4ZWN1dGlvbi1vdXRjb21lL3YxIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSJ9LCJleGVjdXRpb25fb3V0Y29tZV9zaGEyNTYiOiJlZjVlNWYwMzgwYmMwOWRkMjc5YjE5OTQ3Y2RhYzUyZTEzOWZmODNjYTI3NzFjZDA0NDg0MGFjNzM5MzZmMWI0IiwiZXhlY3V0aW9uX3B1cnBvc2UiOiJwcm9kdWN0aW9uIiwiZmluYWxfYXV0aG9yaXR5X3NlcXVlbmNlIjowLCJmaW5hbF9ydW50aW1lX2RlbGl2ZXJ5X3NlcXVlbmNlIjo5LCJmbG93X3J1bl9pZF9zaGEyNTYiOiIxMWU1OTRmNDgxOTU4YzEwZTMwMTVkMGJmMDQ0N2EyMmYwNjhhOGE2NDdmNDc1ZGYxNWNlMmM3YWI0YjhmM2YxIiwiaWRlbnRpdHlfY29udHJhY3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsImlzc3VlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDNaIiwicGVuZGluZ19wZXJtaXRfY291bnQiOjAsInBlcm1pdF9jaGFpbiI6eyJlbnRyaWVzIjpbeyJkZWxpdmVyeV9yZWNlaXB0X2FydGlmYWN0Ijp7InBheWxvYWQiOnsiYXV0aGVudGljYXRlZF9ydW5uZXJfaWRfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsImF1dGhlbnRpY2F0ZWRfc2Vzc2lvbl9pZF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiZGVsaXZlcmVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMVoiLCJleGVjdXRpb25fYXV0aG9yaXR5X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA4Iiwib25lX3VzZV9jbGFpbV9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAxMCIsInBlcm1pdF9hcnRpZmFjdF9zaGEyNTYiOiI5NzJhODJhZjQ1NmRhNTQyYmFjNzg0NjAxODg5NjY4ODkxZDhiN2NjZDI0MjkwNDgxNmIzMjkyZTE1N2U1Mjg5IiwicGVybWl0X2lkIjoicGVybWl0OjEiLCJydW50aW1lX2RlbGl2ZXJ5X3NlcXVlbmNlIjo5LCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXJlY2VpcHQtcGF5bG9hZC92MiJ9LCJwYXlsb2FkX3NoYTI1NiI6IjhhOGY2ZDg4NzUwY2JiNmIzYmQ2NjIwOTNhZDI5ZTJiYzIwYzZhYjY5OTFkNzBlNTg4NjkxYzhiM2FiNjYyYjkiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXJlY2VpcHQtYXJ0aWZhY3QvdjIiLCJzaWduYXR1cmUiOiJBT0txQ2dTMXMwWGEtaXlFOTZWLXlsUHpRY3YydXZPc3V5Z0h6dnUyUnlWN0ZMc0hGX0xWZnF5eDR1MnB1bWxFbDBZazVZdTcwSlZVa3NacGFVcEREdyIsInNpZ25lciI6eyJhbGdvcml0aG0iOiJlZDI1NTE5Iiwia2V5X2lkIjoiZGVsaXZlcnktYXV0aG9yaXR5LWVkMjU1MTktMjRmNmVkNmFjYmZlMTAwOSIsInB1YmxpY19rZXkiOiJLYXk2NFVHOHl2Q3lMaHFVMDAwTHh6WWVVbTBML2hMSWw1UzhreUtXYmRjPSJ9fSwiZGVsaXZlcnlfcmVjZWlwdF9hcnRpZmFjdF9zaGEyNTYiOiJjMDBhMWJhNzAxNWYzY2JlMDVhNzZhZWFiZmY2MTlkNzkzZTczNzVhMzEwZTE5NWZjYmJkMmQyOTQ4ZjJiMjE0IiwicGVybWl0X2FydGlmYWN0Ijp7InBheWxvYWQiOnsiYWN0aW9uX3JlcXVlc3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYXV0aG9yaXR5X3NlcXVlbmNlIjowLCJlbnZpcm9ubWVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXZpZGVuY2VfaWRlbnRpdHlfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImV4ZWN1dGlvbl9hdXRob3JpdHlfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDgiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJmbG93X3J1bl9pZF9zaGEyNTYiOiIxMWU1OTRmNDgxOTU4YzEwZTMwMTVkMGJmMDQ0N2EyMmYwNjhhOGE2NDdmNDc1ZGYxNWNlMmM3YWI0YjhmM2YxIiwiaW5wdXRfZWRnZV9zZXF1ZW5jZSI6MSwiaXNzdWVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMFoiLCJwZXJtaXRfaWQiOiJwZXJtaXQ6MSIsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X2NoZWNrZWRfYXQiOiIyMDI2LTA4LTE4VDExOjU5OjMwWiIsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X2V4cGlyZXNfYXQiOiIyMDI2LTA4LTIwVDExOjAwOjAwWiIsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X3JldmlzaW9uIjo3LCJxdWFsaWZpY2F0aW9uX3NpZ25lcl9yZWdpc3RyeV9zaGEyNTYiOiJlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlIiwicnVuX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAxIiwicnVuX3JlcXVlc3Rfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcGVybWl0LXBheWxvYWQvdjIifSwicGF5bG9hZF9zaGEyNTYiOiJjODdmNTc1MWFhOWIyNzljY2UyM2FhMTc4YWZmOTU2ZTE5ZjY5MGZjZDJmOWY3MGUwZDk5OTc4MmE2OTBkNmI4Iiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1wZXJtaXQtYXJ0aWZhY3QvdjIiLCJzaWduYXR1cmUiOiIwQnlIZ3FEeFFacm5nTElGLTZ0Wk9xOWxYYW1jQVFDMGRvVVRuZUtOUGVTLVN5b09iUXlPa0F1UEZLNVBZY056T2JaeGdzZ0FMZFdhSV9zYVVDcGxCZyIsInNpZ25lciI6eyJhbGdvcml0aG0iOiJlZDI1NTE5Iiwia2V5X2lkIjoiZGVsaXZlcnktYXV0aG9yaXR5LWVkMjU1MTktMjRmNmVkNmFjYmZlMTAwOSIsInB1YmxpY19rZXkiOiJLYXk2NFVHOHl2Q3lMaHFVMDAwTHh6WWVVbTBML2hMSWw1UzhreUtXYmRjPSJ9fSwicGVybWl0X2FydGlmYWN0X3NoYTI1NiI6Ijk3MmE4MmFmNDU2ZGE1NDJiYWM3ODQ2MDE4ODk2Njg4OTFkOGI3Y2NkMjQyOTA0ODE2YjMyOTJlMTU3ZTUyODkiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXBlcm1pdC1jaGFpbi1lbnRyeS92MiJ9XSwicGVybWl0X2NoYWluX3NoYTI1NiI6IjUwNDhmZTk0NTg4MmQyODAyNjAwOGQ3ZTkxMzdhZDAxNmZkZDAxYWVhZjU4ODQ4MWZiNWJkMGYyNDJhNTAwNDMiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXBlcm1pdC1jaGFpbi92MiJ9LCJwZXJtaXRfY291bnQiOjEsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X3JldmlzaW9uIjo3LCJxdWFsaWZpY2F0aW9uX3NpZ25lcl9yZWdpc3RyeV9zaGEyNTYiOiJlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlIiwicnVuX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAxIiwicnVuX3JlY2VpcHQiOnsiYXV0aG9yaXphdGlvbl9jb25maXJtZWQiOjEsImF1dGhvcml6YXRpb25fcmVxdWlyZWQiOjEsImJ1bmRsZV9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZHVyYXRpb25fbXMiOjEwMCwiZWZmZWN0X3RpZXJfcmVhY2hlZCI6ImluZGVwZW5kZW50X3N5c3RlbSIsImVmZmVjdHNfY29uZmlybWVkIjoxLCJlZmZlY3RzX3JlcXVpcmVkIjoxLCJlc3RfY29zdF9taWNyb3VzZCI6MCwiZXZpZGVuY2VfY2xhc3NlcyI6WyJhdXRob3JpemF0aW9uIiwiZWZmZWN0X3RpZXJfMSIsImlkZW50aXR5IiwicG9zdGNvbmRpdGlvbiJdLCJleHRlcm5hbF9uZXR3b3JrX2NhbGxzIjoibm9uZSIsImdlbmVyYXRlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDBaIiwiaGVhbHMiOjAsImlkZW50aXR5X2FwcGxpY2FibGUiOjEsImlkZW50aXR5X2FybWVkIjoxLCJpZGVudGl0eV9jb25maXJtZWQiOjEsImlkZW50aXR5X3JlcXVpcmVkIjoxLCJtb2RlbF9jYWxscyI6MCwib3V0Y29tZSI6IlZFUklGSUVEIiwib3Zlcl9oYWx0X2NvdW50IjowLCJwb3N0Y29uZGl0aW9uc19jb25maXJtZWQiOjEsInBvc3Rjb25kaXRpb25zX3JlcXVpcmVkIjoxLCJwcm9kdWN0aW9uX2VsaWdpYmxlIjp0cnVlLCJwcm9maWxlIjoic3RhbmRhcmQiLCJwcm92ZW5hbmNlIjoicHJvZHVjdGlvbiIsInJlY2VpcHRfYnVpbGRlcl92ZXJzaW9uIjoiMS4yLjMiLCJydW5nX2hpc3RvZ3JhbSI6eyJzdHJ1Y3R1cmFsIjoxfSwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1ydW4tcmVjZWlwdC92MSIsInNvdXJjZV9yZWNlaXB0X2RpZ2VzdCI6IjI2N2NmMDU1ZjIzYmVmYmM5NzE1NzVlMDljMTBhY2Y0ODlmNDdlNzMwOWNiYWM0YjA4YjZiMDkzZjM2NGQ1OTYiLCJzb3VyY2VfcmVjZWlwdF9zaGEyNTYiOiI4ZDkwNDJjOTlmOWU0NjBlNGI0YWExY2VlZjYzMTJiMzFlOTVlODVkZTU4ZDg5Yjc0MGU2NDEzMTgxNDQ3MGNiIiwic291cmNlX3NjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnJ1bi1yZWNlaXB0L3YyIiwic3RlcHNfb2siOjEsInN0ZXBzX3RvdGFsIjoxLCJzdWJzdHJhdGUiOiJ3ZWIiLCJ0cmFuc2FjdGlvbl9vdXRjb21lIjoiVkVSSUZJRUQifSwicnVuX3JlY2VpcHRfc2hhMjU2IjoiNjM5YzMxMzY5YjM1MDQ1NGU1ZjE0MWFhODI2OWVmYjk1Njk4NmM2MGU5NzA5YWNjNmViMDllMmZiNmYwZDgzZSIsInJ1bl9yZXBvcnRfb2JqZWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJydW5fcmVwb3J0X29iamVjdF92ZXJzaW9uIjoidmVyc2lvbjoxIiwicnVuX3JlcG9ydF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwicnVudGltZV9lbnZpcm9ubWVudF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwicnVudGltZV9zdWJzdHJhdGUiOiJ3ZWIiLCJydW50aW1lX3ZhbGlkYXRpb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDUiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLXRlcm1pbmFsLXZlcmlmaWNhdGlvbi92MiIsInRlbmFudF9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwMiIsInRlcm1pbmFsX3NlcXVlbmNlIjoxLCJ2ZXJpZmllZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDJaIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsIndvcmtmbG93X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAzIiwid29ya2Zsb3dfdmVyc2lvbl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwNCJ9LCJzaWduYXR1cmUiOiJkVlBRN2ZhLTJSaF93Y040Sjd0TzBsSXQ0bTZmdnNEZXZjYjN1WE5zRDEwZTlmUGpOLWlsSjg0WGdiMVdvZ1ROd3NSLTJFdTY2UnZzSGVRcWFfcHJDZyIsInNpZ25lciI6eyJhbGdvcml0aG0iOiJlZDI1NTE5Iiwia2V5X2lkIjoiZXZpZGVuY2UtcnVubmVyLWVkMjU1MTktNTY0NzVhYTc1NDYzNDc0YyIsInB1YmxpY19rZXkiOiJBNkVIdi9QT0VMNGRjTjBZNTB2QW1XZmsxakNicFExZkhkeUdaQkpWTWJnPSJ9fQ==", + "terminal_verification_artifact_sha256": "23ff9e0a8f6c5e1a4fc124e08ab41e42e456bda4d32cb65c24db40e8ec7b8bcc", "uncertain_delivery": false }, "effect_state": { @@ -65,12 +66,13 @@ }, { "callback": { - "artifact_bytes_source": "envelope_canonical_base64", "outcome": "HALTED_BEFORE_EFFECT", "report_sha256": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "run_id": "00000000-0000-4000-8000-000000000001", "schema_version": "openadapt.hosted-runner-terminal/v1", "started": true, + "terminal_verification_artifact_bytes_base64": "eyJwYXlsb2FkIjp7ImFja25vd2xlZGdlZF9wZXJtaXRfY291bnQiOjAsImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA2IiwiYWRtaXNzaW9uX3BvbGljeV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYWRtaXR0ZWRfcnVudGltZV9idWlsZF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiYnVuZGxlX2FydGlmYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJidW5kbGVfY29udGVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYnVuZGxlX3ZlcnNpb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDQiLCJlZmZlY3RfY29udHJhY3Rfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImVudmlyb25tZW50X2NvbnRyYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJlbnZpcm9ubWVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXZpZGVuY2VfaWRlbnRpdHlfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImV2aWRlbmNlX21hbmlmZXN0cyI6eyJhdXRob3JpemF0aW9uIjp7ImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA2IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOCIsImV4ZWN1dGlvbl9hdXRob3JpdHlfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImdvdmVybmVkX2F1dGhvcml6YXRpb25faWRfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsIm1hbmlmZXN0X3NoYTI1NiI6IjMyY2QzNjEzYmVlOWJjNjkwNjkzYTM5NWQ5OTMzNTQ3ZjllZWI5ZjZmYWE1ZGJkYmIxNGExMDYyOThiZTQ2NWMiLCJwZXJtaXRfY2hhaW5fc2hhMjU2IjoiODJkYWI1NDI4ZTI1MmQxOGE1OWIwMTc3NzM5ZTAwY2FhZGI3NjJkY2Y1OWY0MDM2ZGVhNGQ3N2MzYzMyMDNjYiIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tYXV0aG9yaXphdGlvbi1ldmlkZW5jZS92MSJ9LCJlZmZlY3QiOnsiY29uZmlybWVkIjowLCJlZmZlY3RfY29udHJhY3Rfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsIm1hbmlmZXN0X3NoYTI1NiI6ImViYjU4MzYxNzhlZGZhYzYyOWJkOWJjYTkwZWNkMDE5NTkwOTQ5NjZhMGRkNjNiYWVhN2E2MmY2ZTNiMDRmZjgiLCJyZWNvcmRzIjpbeyJhYnNlbmNlX2Jhc2lzIjoibm90X2FjdHVhdGVkIiwiYXR0ZW1wdF9zdGF0ZSI6Im5vdF9hY3R1YXRlZCIsImVmZmVjdF9jb250cmFjdF9oYXNoIjoic2hhMjU2OmFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJlZmZlY3RfdmVyaWZpZWQiOmZhbHNlLCJmaW5hbF92ZXJkaWN0IjpudWxsLCJvYnNlcnZlZF9lZmZlY3QiOiJhYnNlbnQiLCJyZWNvbmNpbGlhdGlvbl9hY3Rpb25zIjowLCJyZWNvbmNpbGlhdGlvbl9jb21wbGV0ZWQiOmZhbHNlLCJyZWNvcmRfa2luZCI6InRlcm1pbmFsX2VmZmVjdF9zdGF0ZSIsInJlc29sdmVkX2RlbGl2ZXJ5X3VuY2VydGFpbnR5IjpmYWxzZSwicmVzdWx0X2luZGV4IjowLCJ2ZXJpZmljYXRpb25fcGVyZm9ybWVkIjpmYWxzZSwidmVyaWZpY2F0aW9uX3RpZXIiOm51bGwsInZlcmlmaWVyX2lkZW50aXR5IjpudWxsfV0sInJlcXVpcmVkIjoxLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWVmZmVjdC1ldmlkZW5jZS92MSIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifSwiaWRlbnRpdHkiOnsiY29uZmlybWVkIjoxLCJpZGVudGl0eV9jb250cmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwibWFuaWZlc3Rfc2hhMjU2IjoiMTM1Yzg2M2VkYzdmYWIxOGNhMjliNDkyOTNmYzI1YTFjOWJkNGRlMGU5ZWQyOGQ0Y2VjNmU4ZDBhNjc5MTIyOSIsInJlcXVpcmVkIjoxLCJyZXN1bHRzIjpbeyJtb2RlIjoic3RydWN0dXJlZCIsInJlc3VsdF9pbmRleCI6MCwic2lnbmFscyI6W10sInN0YXR1cyI6InZlcmlmaWVkIn1dLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWlkZW50aXR5LWV2aWRlbmNlL3YxIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSJ9LCJwb2xpY3kiOnsiYWRtaXNzaW9uX3BvbGljeV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZWZmZWN0X2NvbnRyYWN0X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJlbnZpcm9ubWVudF9jb250cmFjdF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwiZW52aXJvbm1lbnRfZGlnZXN0IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImdvdmVybmVkX3BvbGljeV9jb250cmFjdF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwiZ292ZXJuZWRfcnVudGltZV9pbnB1dHNfZGlnZXN0IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsImlkZW50aXR5X2NvbnRyYWN0X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJtYW5pZmVzdF9zaGEyNTYiOiI0Zjk4OGQwMTViY2Q3Y2Q3ZTA1YmEwNjYzZDg5ZjBhOTY4ZjBkOGFjZTk5YjA5MGViYWJlZTUyYTFjNTUwNDIxIiwibWluaW11bV9lZmZlY3RfdGllciI6MSwicnVudGltZV9lbnZpcm9ubWVudF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1wb2xpY3ktZXZpZGVuY2UvdjEifSwicG9zdGNvbmRpdGlvbiI6eyJjb25maXJtZWQiOjAsIm1hbmlmZXN0X3NoYTI1NiI6IjNlYTRjNjRhMzBiMGNmMTdiY2EwNGYzMjYwZTBhNDcxOGIyN2Y1MWUxZmRjMmJiODhhMTgyNjMwYTM0ZGQ1ZmYiLCJyZWNvcmRzIjpbeyJhY3Rpb25fa2luZCI6ImNsaWNrIiwiYWN0dWF0aW9uX3BhdGgiOiJndWkiLCJjb250cmFjdF9pbmRleCI6MCwiY29udHJhY3Rfa2luZCI6ImV4cGxpY2l0X3ByZWRpY2F0ZSIsImNvbnRyYWN0X3NoYTI1NiI6IjBhZGUwYjUyMGJjMDA3ODkxY2FjY2EwMDE3MTU3ODQ0MmEyYTc0Y2VmMTVmZjY0ZGRlNDVkZjA3YWZiNjRhZWIiLCJyZXN1bHRfaW5kZXgiOjAsInN0ZXBfY29udHJhY3Rfc2hhMjU2IjoiMWE1OTUzNmE0ODhiMWM0NmFhY2YwYmEzNzkzMGI4NDA2MmMxNDI3NTVmYTkzOTE1MmVmNWUyOGM0MDk0NzFlZCIsInN0ZXBfaW5kZXgiOjAsInZlcmRpY3QiOiJ1bnZlcmlmaWFibGUiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIn1dLCJyZXF1aXJlZCI6MSwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1wb3N0Y29uZGl0aW9uLWV2aWRlbmNlL3YxIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSJ9fSwiZXZpZGVuY2VfcnVubmVyX3NpZ25lcl9zaGEyNTYiOiI1NjQ3NWFhNzU0NjM0NzRjMDI4NWRmNWRiZjJiY2FiNzNkYTY1MTM1ODgzOWU5Yjc3NDgxYjJlYWIxMDc3MDhjIiwiZXhlY3V0aW9uX2F1dGhvcml0eV9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOCIsImV4ZWN1dGlvbl9hdXRob3JpdHlfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImV4ZWN1dGlvbl9hdXRob3JpdHlfc2lnbmVyX3NoYTI1NiI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJleGVjdXRpb25fb3V0Y29tZSI6eyJjb21wZW5zYXRpb25fYWN0aW9ucyI6MCwiZXZpZGVuY2VfY2xhc3NlcyI6WyJhdXRob3JpemF0aW9uIiwiaWRlbnRpdHkiXSwiZXhlY3V0aW9uX2NvbXBsZXRlZCI6ZmFsc2UsImV4dGVybmFsX25ldHdvcmtfY2FsbHMiOiJub25lIiwibW9kZWxfY2FsbHMiOjAsIm91dGNvbWUiOiJIQUxURUQiLCJwYXNzZWRfY29udHJhY3RzIjp7ImF1dGhvcml6YXRpb24iOjEsImVmZmVjdCI6MCwiaWRlbnRpdHkiOjEsInBvc3Rjb25kaXRpb24iOjB9LCJwb3N0Y29uZGl0aW9uX2V2aWRlbmNlIjpbeyJhY3Rpb25fa2luZCI6ImNsaWNrIiwiYWN0dWF0aW9uX3BhdGgiOiJndWkiLCJjb250cmFjdF9pbmRleCI6MCwiY29udHJhY3Rfa2luZCI6ImV4cGxpY2l0X3ByZWRpY2F0ZSIsImNvbnRyYWN0X3NoYTI1NiI6IjBhZGUwYjUyMGJjMDA3ODkxY2FjY2EwMDE3MTU3ODQ0MmEyYTc0Y2VmMTVmZjY0ZGRlNDVkZjA3YWZiNjRhZWIiLCJyZXN1bHRfaW5kZXgiOjAsInN0ZXBfY29udHJhY3Rfc2hhMjU2IjoiMWE1OTUzNmE0ODhiMWM0NmFhY2YwYmEzNzkzMGI4NDA2MmMxNDI3NTVmYTkzOTE1MmVmNWUyOGM0MDk0NzFlZCIsInN0ZXBfaW5kZXgiOjAsInZlcmRpY3QiOiJ1bnZlcmlmaWFibGUiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIn1dLCJwcm9kdWN0aW9uX2VsaWdpYmxlIjpmYWxzZSwicHJvZmlsZSI6InN0YW5kYXJkIiwicXVhbGlmaWNhdGlvbl9ldmlkZW5jZV9vbmx5IjpmYWxzZSwicmVxdWlyZWRfY29udHJhY3RzIjp7ImF1dGhvcml6YXRpb24iOjEsImVmZmVjdCI6MSwiaWRlbnRpdHkiOjEsInBvc3Rjb25kaXRpb24iOjF9LCJ2ZXJzaW9uIjoib3BlbmFkYXB0LmV4ZWN1dGlvbi1vdXRjb21lL3YxIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSJ9LCJleGVjdXRpb25fb3V0Y29tZV9zaGEyNTYiOiJmZTM4OWJhYjBlYjQ0NDdjZWMxOTk4Mjc0ZjcyN2NhNTcwMDQ5ZmVmZDU1N2RiNzk5MDQ3Njk5ZjJmNzhmMTQyIiwiZXhlY3V0aW9uX3B1cnBvc2UiOiJwcm9kdWN0aW9uIiwiZmluYWxfYXV0aG9yaXR5X3NlcXVlbmNlIjowLCJmaW5hbF9ydW50aW1lX2RlbGl2ZXJ5X3NlcXVlbmNlIjowLCJmbG93X3J1bl9pZF9zaGEyNTYiOiIxMWU1OTRmNDgxOTU4YzEwZTMwMTVkMGJmMDQ0N2EyMmYwNjhhOGE2NDdmNDc1ZGYxNWNlMmM3YWI0YjhmM2YxIiwiaWRlbnRpdHlfY29udHJhY3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsImlzc3VlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDNaIiwicGVuZGluZ19wZXJtaXRfY291bnQiOjAsInBlcm1pdF9jaGFpbiI6eyJlbnRyaWVzIjpbXSwicGVybWl0X2NoYWluX3NoYTI1NiI6IjgyZGFiNTQyOGUyNTJkMThhNTliMDE3NzczOWUwMGNhYWRiNzYyZGNmNTlmNDAzNmRlYTRkNzdjM2MzMjAzY2IiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXBlcm1pdC1jaGFpbi92MiJ9LCJwZXJtaXRfY291bnQiOjAsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X3JldmlzaW9uIjo3LCJxdWFsaWZpY2F0aW9uX3NpZ25lcl9yZWdpc3RyeV9zaGEyNTYiOiJlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlIiwicnVuX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAxIiwicnVuX3JlY2VpcHQiOnsiYXV0aG9yaXphdGlvbl9jb25maXJtZWQiOjEsImF1dGhvcml6YXRpb25fcmVxdWlyZWQiOjEsImJ1bmRsZV9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZHVyYXRpb25fbXMiOjEwMCwiZWZmZWN0X3RpZXJfcmVhY2hlZCI6Im5vbmUiLCJlZmZlY3RzX2NvbmZpcm1lZCI6MCwiZWZmZWN0c19yZXF1aXJlZCI6MSwiZXN0X2Nvc3RfbWljcm91c2QiOjAsImV2aWRlbmNlX2NsYXNzZXMiOlsiYXV0aG9yaXphdGlvbiIsImlkZW50aXR5Il0sImV4dGVybmFsX25ldHdvcmtfY2FsbHMiOiJub25lIiwiZ2VuZXJhdGVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMFoiLCJoZWFscyI6MCwiaWRlbnRpdHlfYXBwbGljYWJsZSI6MSwiaWRlbnRpdHlfYXJtZWQiOjEsImlkZW50aXR5X2NvbmZpcm1lZCI6MSwiaWRlbnRpdHlfcmVxdWlyZWQiOjEsIm1vZGVsX2NhbGxzIjowLCJvdXRjb21lIjoiSEFMVEVEIiwib3Zlcl9oYWx0X2NvdW50IjowLCJwb3N0Y29uZGl0aW9uc19jb25maXJtZWQiOjAsInBvc3Rjb25kaXRpb25zX3JlcXVpcmVkIjoxLCJwcm9kdWN0aW9uX2VsaWdpYmxlIjpmYWxzZSwicHJvZmlsZSI6InN0YW5kYXJkIiwicHJvdmVuYW5jZSI6InByb2R1Y3Rpb24iLCJyZWNlaXB0X2J1aWxkZXJfdmVyc2lvbiI6IjEuMi4zIiwicnVuZ19oaXN0b2dyYW0iOnt9LCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLXJ1bi1yZWNlaXB0L3YxIiwic291cmNlX3JlY2VpcHRfZGlnZXN0IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsInNvdXJjZV9yZWNlaXB0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJzb3VyY2Vfc2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucnVuLXJlcG9ydC92MSIsInN0ZXBzX29rIjowLCJzdGVwc190b3RhbCI6MSwic3Vic3RyYXRlIjoid2ViIiwidHJhbnNhY3Rpb25fb3V0Y29tZSI6IkhBTFRFRF9CRUZPUkVfRUZGRUNUIn0sInJ1bl9yZWNlaXB0X3NoYTI1NiI6ImFiNTBhMDA2YTg4OGIzZjkwZTFlNzFlZjIwOTIxYWY3MTdiMmY0MWEzNjc2ZTYwNWZiZGI4MjBjYjZiNTNjYzQiLCJydW5fcmVwb3J0X29iamVjdF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwicnVuX3JlcG9ydF9vYmplY3RfdmVyc2lvbiI6InZlcnNpb246aGFsdGVkOjEiLCJydW5fcmVwb3J0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJydW50aW1lX2Vudmlyb25tZW50X3NoYTI1NiI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJydW50aW1lX3N1YnN0cmF0ZSI6IndlYiIsInJ1bnRpbWVfdmFsaWRhdGlvbl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwNSIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tdGVybWluYWwtdmVyaWZpY2F0aW9uL3YyIiwidGVuYW50X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAyIiwidGVybWluYWxfc2VxdWVuY2UiOjEsInZlcmlmaWVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMloiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwid29ya2Zsb3dfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDMiLCJ3b3JrZmxvd192ZXJzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA0In0sInNpZ25hdHVyZSI6IktHQzRqQllpN01ReVlkbFV5TnJ5bGowcmwxaUVNbUFFeHQwUmlxWjV2bGh0Y1lWQzVJOEY1RDZ2V0NkRVlnb09takZNOU5UNjZmVW95ODVsYlFOQkRnIiwic2lnbmVyIjp7ImFsZ29yaXRobSI6ImVkMjU1MTkiLCJrZXlfaWQiOiJldmlkZW5jZS1ydW5uZXItZWQyNTUxOS01NjQ3NWFhNzU0NjM0NzRjIiwicHVibGljX2tleSI6IkE2RUh2L1BPRUw0ZGNOMFk1MHZBbVdmazFqQ2JwUTFmSGR5R1pCSlZNYmc9In19", + "terminal_verification_artifact_sha256": "ef25997f54fdd08ba6cd49533bf23735c35bbac86d195cff19a0df087f82e4d8", "uncertain_delivery": false }, "effect_state": { @@ -98,12 +100,13 @@ }, { "callback": { - "artifact_bytes_source": "envelope_canonical_base64", "outcome": "RECONCILIATION_REQUIRED", "report_sha256": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "run_id": "00000000-0000-4000-8000-000000000001", "schema_version": "openadapt.hosted-runner-terminal/v1", "started": true, + "terminal_verification_artifact_bytes_base64": "eyJwYXlsb2FkIjp7ImFja25vd2xlZGdlZF9wZXJtaXRfY291bnQiOjAsImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA2IiwiYWRtaXNzaW9uX3BvbGljeV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYWRtaXR0ZWRfcnVudGltZV9idWlsZF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiYnVuZGxlX2FydGlmYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJidW5kbGVfY29udGVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYnVuZGxlX3ZlcnNpb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDQiLCJlZmZlY3RfY29udHJhY3Rfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImVudmlyb25tZW50X2NvbnRyYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJlbnZpcm9ubWVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXZpZGVuY2VfaWRlbnRpdHlfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImV2aWRlbmNlX21hbmlmZXN0cyI6eyJhdXRob3JpemF0aW9uIjp7ImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA2IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOCIsImV4ZWN1dGlvbl9hdXRob3JpdHlfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImdvdmVybmVkX2F1dGhvcml6YXRpb25faWRfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsIm1hbmlmZXN0X3NoYTI1NiI6IjE1YzBlNzZkYzJlMzIxYTM4NGU1M2VjMTVmZjUzZTc1NTU3YjdjZGU3MWM1YWQyYmEyYjkzZmYyZTk1ODM1YTUiLCJwZXJtaXRfY2hhaW5fc2hhMjU2IjoiNTliMzk5NzFlMzA1MTA5YzU0Mjk5NDVhNWZhYjQ2NjBiMDlmNDFlN2FjM2ZmZDkyZTM1MDZhZjAwMzM3ZGE5NSIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tYXV0aG9yaXphdGlvbi1ldmlkZW5jZS92MSJ9LCJlZmZlY3QiOnsiY29uZmlybWVkIjowLCJlZmZlY3RfY29udHJhY3Rfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsIm1hbmlmZXN0X3NoYTI1NiI6ImFmMTUwOWNjMmU5ZmExZjViOGI4MTVlN2IxZjYwNDYxOWIyYTM1ZWMwZGU1ZTBkMzRiYmZhNjdjYzkxZGJiYzciLCJyZWNvcmRzIjpbeyJhYnNlbmNlX2Jhc2lzIjoibm9uZSIsImF0dGVtcHRfc3RhdGUiOiJkZWxpdmVyeV91bmNlcnRhaW4iLCJlZmZlY3RfY29udHJhY3RfaGFzaCI6InNoYTI1NjphYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZWZmZWN0X3ZlcmlmaWVkIjpmYWxzZSwiZmluYWxfdmVyZGljdCI6bnVsbCwib2JzZXJ2ZWRfZWZmZWN0IjoidW5rbm93biIsInJlY29uY2lsaWF0aW9uX2FjdGlvbnMiOjAsInJlY29uY2lsaWF0aW9uX2NvbXBsZXRlZCI6ZmFsc2UsInJlY29yZF9raW5kIjoidGVybWluYWxfZWZmZWN0X3N0YXRlIiwicmVzb2x2ZWRfZGVsaXZlcnlfdW5jZXJ0YWludHkiOmZhbHNlLCJyZXN1bHRfaW5kZXgiOjAsInZlcmlmaWNhdGlvbl9wZXJmb3JtZWQiOmZhbHNlLCJ2ZXJpZmljYXRpb25fdGllciI6bnVsbCwidmVyaWZpZXJfaWRlbnRpdHkiOm51bGx9XSwicmVxdWlyZWQiOjEsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZWZmZWN0LWV2aWRlbmNlL3YxIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSJ9LCJpZGVudGl0eSI6eyJjb25maXJtZWQiOjEsImlkZW50aXR5X2NvbnRyYWN0X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJtYW5pZmVzdF9zaGEyNTYiOiIxMzVjODYzZWRjN2ZhYjE4Y2EyOWI0OTI5M2ZjMjVhMWM5YmQ0ZGUwZTllZDI4ZDRjZWM2ZThkMGE2NzkxMjI5IiwicmVxdWlyZWQiOjEsInJlc3VsdHMiOlt7Im1vZGUiOiJzdHJ1Y3R1cmVkIiwicmVzdWx0X2luZGV4IjowLCJzaWduYWxzIjpbXSwic3RhdHVzIjoidmVyaWZpZWQifV0sInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24taWRlbnRpdHktZXZpZGVuY2UvdjEiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIn0sInBvbGljeSI6eyJhZG1pc3Npb25fcG9saWN5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJlZmZlY3RfY29udHJhY3Rfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImVudmlyb25tZW50X2NvbnRyYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJlbnZpcm9ubWVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZ292ZXJuZWRfcG9saWN5X2NvbnRyYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJnb3Zlcm5lZF9ydW50aW1lX2lucHV0c19kaWdlc3QiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiaWRlbnRpdHlfY29udHJhY3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsIm1hbmlmZXN0X3NoYTI1NiI6IjRmOTg4ZDAxNWJjZDdjZDdlMDViYTA2NjNkODlmMGE5NjhmMGQ4YWNlOTliMDkwZWJhYmVlNTJhMWM1NTA0MjEiLCJtaW5pbXVtX2VmZmVjdF90aWVyIjoxLCJydW50aW1lX2Vudmlyb25tZW50X3NoYTI1NiI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLXBvbGljeS1ldmlkZW5jZS92MSJ9LCJwb3N0Y29uZGl0aW9uIjp7ImNvbmZpcm1lZCI6MCwibWFuaWZlc3Rfc2hhMjU2IjoiM2VhNGM2NGEzMGIwY2YxN2JjYTA0ZjMyNjBlMGE0NzE4YjI3ZjUxZTFmZGMyYmI4OGExODI2MzBhMzRkZDVmZiIsInJlY29yZHMiOlt7ImFjdGlvbl9raW5kIjoiY2xpY2siLCJhY3R1YXRpb25fcGF0aCI6Imd1aSIsImNvbnRyYWN0X2luZGV4IjowLCJjb250cmFjdF9raW5kIjoiZXhwbGljaXRfcHJlZGljYXRlIiwiY29udHJhY3Rfc2hhMjU2IjoiMGFkZTBiNTIwYmMwMDc4OTFjYWNjYTAwMTcxNTc4NDQyYTJhNzRjZWYxNWZmNjRkZGU0NWRmMDdhZmI2NGFlYiIsInJlc3VsdF9pbmRleCI6MCwic3RlcF9jb250cmFjdF9zaGEyNTYiOiIxYTU5NTM2YTQ4OGIxYzQ2YWFjZjBiYTM3OTMwYjg0MDYyYzE0Mjc1NWZhOTM5MTUyZWY1ZTI4YzQwOTQ3MWVkIiwic3RlcF9pbmRleCI6MCwidmVyZGljdCI6InVudmVyaWZpYWJsZSIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifV0sInJlcXVpcmVkIjoxLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLXBvc3Rjb25kaXRpb24tZXZpZGVuY2UvdjEiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIn19LCJldmlkZW5jZV9ydW5uZXJfc2lnbmVyX3NoYTI1NiI6IjU2NDc1YWE3NTQ2MzQ3NGMwMjg1ZGY1ZGJmMmJjYWI3M2RhNjUxMzU4ODM5ZTliNzc0ODFiMmVhYjEwNzcwOGMiLCJleGVjdXRpb25fYXV0aG9yaXR5X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA4IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaWduZXJfc2hhMjU2IjoiMjRmNmVkNmFjYmZlMTAwOWMwMzBkN2NhNTY3YzMzY2E0ODMwOTExNDk4MjM2YjU1NjFhNmM4MmFiZWM1ZGUyOCIsImV4ZWN1dGlvbl9vdXRjb21lIjp7ImNvbXBlbnNhdGlvbl9hY3Rpb25zIjowLCJldmlkZW5jZV9jbGFzc2VzIjpbImF1dGhvcml6YXRpb24iLCJpZGVudGl0eSJdLCJleGVjdXRpb25fY29tcGxldGVkIjpmYWxzZSwiZXh0ZXJuYWxfbmV0d29ya19jYWxscyI6Im5vbmUiLCJtb2RlbF9jYWxscyI6MCwib3V0Y29tZSI6IkhBTFRFRCIsInBhc3NlZF9jb250cmFjdHMiOnsiYXV0aG9yaXphdGlvbiI6MSwiZWZmZWN0IjowLCJpZGVudGl0eSI6MSwicG9zdGNvbmRpdGlvbiI6MH0sInBvc3Rjb25kaXRpb25fZXZpZGVuY2UiOlt7ImFjdGlvbl9raW5kIjoiY2xpY2siLCJhY3R1YXRpb25fcGF0aCI6Imd1aSIsImNvbnRyYWN0X2luZGV4IjowLCJjb250cmFjdF9raW5kIjoiZXhwbGljaXRfcHJlZGljYXRlIiwiY29udHJhY3Rfc2hhMjU2IjoiMGFkZTBiNTIwYmMwMDc4OTFjYWNjYTAwMTcxNTc4NDQyYTJhNzRjZWYxNWZmNjRkZGU0NWRmMDdhZmI2NGFlYiIsInJlc3VsdF9pbmRleCI6MCwic3RlcF9jb250cmFjdF9zaGEyNTYiOiIxYTU5NTM2YTQ4OGIxYzQ2YWFjZjBiYTM3OTMwYjg0MDYyYzE0Mjc1NWZhOTM5MTUyZWY1ZTI4YzQwOTQ3MWVkIiwic3RlcF9pbmRleCI6MCwidmVyZGljdCI6InVudmVyaWZpYWJsZSIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifV0sInByb2R1Y3Rpb25fZWxpZ2libGUiOmZhbHNlLCJwcm9maWxlIjoic3RhbmRhcmQiLCJxdWFsaWZpY2F0aW9uX2V2aWRlbmNlX29ubHkiOmZhbHNlLCJyZXF1aXJlZF9jb250cmFjdHMiOnsiYXV0aG9yaXphdGlvbiI6MSwiZWZmZWN0IjoxLCJpZGVudGl0eSI6MSwicG9zdGNvbmRpdGlvbiI6MX0sInZlcnNpb24iOiJvcGVuYWRhcHQuZXhlY3V0aW9uLW91dGNvbWUvdjEiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIn0sImV4ZWN1dGlvbl9vdXRjb21lX3NoYTI1NiI6ImZlMzg5YmFiMGViNDQ0N2NlYzE5OTgyNzRmNzI3Y2E1NzAwNDlmZWZkNTU3ZGI3OTkwNDc2OTlmMmY3OGYxNDIiLCJleGVjdXRpb25fcHVycG9zZSI6InByb2R1Y3Rpb24iLCJmaW5hbF9hdXRob3JpdHlfc2VxdWVuY2UiOjAsImZpbmFsX3J1bnRpbWVfZGVsaXZlcnlfc2VxdWVuY2UiOjAsImZsb3dfcnVuX2lkX3NoYTI1NiI6IjExZTU5NGY0ODE5NThjMTBlMzAxNWQwYmYwNDQ3YTIyZjA2OGE4YTY0N2Y0NzVkZjE1Y2UyYzdhYjRiOGYzZjEiLCJpZGVudGl0eV9jb250cmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiaXNzdWVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowM1oiLCJwZW5kaW5nX3Blcm1pdF9jb3VudCI6MSwicGVybWl0X2NoYWluIjp7ImVudHJpZXMiOltdLCJwZW5kaW5nIjp7ImFjdHVhdGlvbl9yZXBsYXlfYXV0aG9yaXplZCI6ZmFsc2UsImRlbGl2ZXJ5X3JlY2VpcHRfYXJ0aWZhY3QiOm51bGwsImRlbGl2ZXJ5X3JlY2VpcHRfYXJ0aWZhY3Rfc2hhMjU2IjpudWxsLCJkZWxpdmVyeV9zdGF0ZSI6IlVOUkVTT0xWRUQiLCJwZXJtaXRfYXJ0aWZhY3QiOnsicGF5bG9hZCI6eyJhY3Rpb25fcmVxdWVzdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2FydGlmYWN0X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJhdXRob3JpdHlfc2VxdWVuY2UiOjAsImVudmlyb25tZW50X2RpZ2VzdCI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJldmlkZW5jZV9pZGVudGl0eV9zaGEyNTYiOiJlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlIiwiZXhlY3V0aW9uX2F1dGhvcml0eV9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOCIsImV4ZWN1dGlvbl9hdXRob3JpdHlfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImZsb3dfcnVuX2lkX3NoYTI1NiI6IjExZTU5NGY0ODE5NThjMTBlMzAxNWQwYmYwNDQ3YTIyZjA2OGE4YTY0N2Y0NzVkZjE1Y2UyYzdhYjRiOGYzZjEiLCJpbnB1dF9lZGdlX3NlcXVlbmNlIjoxLCJpc3N1ZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAwWiIsInBlcm1pdF9pZCI6InBlcm1pdDoxIiwicXVhbGlmaWNhdGlvbl9zaWduZXJfcmVnaXN0cnlfY2hlY2tlZF9hdCI6IjIwMjYtMDgtMThUMTE6NTk6MzBaIiwicXVhbGlmaWNhdGlvbl9zaWduZXJfcmVnaXN0cnlfZXhwaXJlc19hdCI6IjIwMjYtMDgtMjBUMTE6MDA6MDBaIiwicXVhbGlmaWNhdGlvbl9zaWduZXJfcmVnaXN0cnlfcmV2aXNpb24iOjcsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJydW5faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDEiLCJydW5fcmVxdWVzdF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1wZXJtaXQtcGF5bG9hZC92MiJ9LCJwYXlsb2FkX3NoYTI1NiI6ImM4N2Y1NzUxYWE5YjI3OWNjZTIzYWExNzhhZmY5NTZlMTlmNjkwZmNkMmY5ZjcwZTBkOTk5NzgyYTY5MGQ2YjgiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXBlcm1pdC1hcnRpZmFjdC92MiIsInNpZ25hdHVyZSI6IjBCeUhncUR4UVpybmdMSUYtNnRaT3E5bFhhbWNBUUMwZG9VVG5lS05QZVMtU3lvT2JReU9rQXVQRks1UFljTnpPYlp4Z3NnQUxkV2FJX3NhVUNwbEJnIiwic2lnbmVyIjp7ImFsZ29yaXRobSI6ImVkMjU1MTkiLCJrZXlfaWQiOiJkZWxpdmVyeS1hdXRob3JpdHktZWQyNTUxOS0yNGY2ZWQ2YWNiZmUxMDA5IiwicHVibGljX2tleSI6IktheTY0VUc4eXZDeUxocVUwMDBMeHpZZVVtMEwvaExJbDVTOGt5S1diZGM9In19LCJwZXJtaXRfYXJ0aWZhY3Rfc2hhMjU2IjoiOTcyYTgyYWY0NTZkYTU0MmJhYzc4NDYwMTg4OTY2ODg5MWQ4YjdjY2QyNDI5MDQ4MTZiMzI5MmUxNTdlNTI4OSIsInJlY2VpcHRfYWJzZW5jZV9vYnNlcnZlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDJaIiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1wZW5kaW5nLXBlcm1pdC92MiJ9LCJwZXJtaXRfY2hhaW5fc2hhMjU2IjoiNTliMzk5NzFlMzA1MTA5YzU0Mjk5NDVhNWZhYjQ2NjBiMDlmNDFlN2FjM2ZmZDkyZTM1MDZhZjAwMzM3ZGE5NSIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcGVybWl0LWNoYWluL3YyIn0sInBlcm1pdF9jb3VudCI6MSwicXVhbGlmaWNhdGlvbl9zaWduZXJfcmVnaXN0cnlfcmV2aXNpb24iOjcsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJydW5faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDEiLCJydW5fcmVjZWlwdCI6eyJhdXRob3JpemF0aW9uX2NvbmZpcm1lZCI6MSwiYXV0aG9yaXphdGlvbl9yZXF1aXJlZCI6MSwiYnVuZGxlX2RpZ2VzdCI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJkdXJhdGlvbl9tcyI6MTAwLCJlZmZlY3RfdGllcl9yZWFjaGVkIjoibm9uZSIsImVmZmVjdHNfY29uZmlybWVkIjowLCJlZmZlY3RzX3JlcXVpcmVkIjoxLCJlc3RfY29zdF9taWNyb3VzZCI6MCwiZXZpZGVuY2VfY2xhc3NlcyI6WyJhdXRob3JpemF0aW9uIiwiaWRlbnRpdHkiXSwiZXh0ZXJuYWxfbmV0d29ya19jYWxscyI6Im5vbmUiLCJnZW5lcmF0ZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAwWiIsImhlYWxzIjowLCJpZGVudGl0eV9hcHBsaWNhYmxlIjoxLCJpZGVudGl0eV9hcm1lZCI6MSwiaWRlbnRpdHlfY29uZmlybWVkIjoxLCJpZGVudGl0eV9yZXF1aXJlZCI6MSwibW9kZWxfY2FsbHMiOjAsIm91dGNvbWUiOiJIQUxURUQiLCJvdmVyX2hhbHRfY291bnQiOjAsInBvc3Rjb25kaXRpb25zX2NvbmZpcm1lZCI6MCwicG9zdGNvbmRpdGlvbnNfcmVxdWlyZWQiOjEsInByb2R1Y3Rpb25fZWxpZ2libGUiOmZhbHNlLCJwcm9maWxlIjoic3RhbmRhcmQiLCJwcm92ZW5hbmNlIjoicHJvZHVjdGlvbiIsInJlY2VpcHRfYnVpbGRlcl92ZXJzaW9uIjoiMS4yLjMiLCJydW5nX2hpc3RvZ3JhbSI6e30sInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tcnVuLXJlY2VpcHQvdjEiLCJzb3VyY2VfcmVjZWlwdF9kaWdlc3QiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwic291cmNlX3JlY2VpcHRfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsInNvdXJjZV9zY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5ydW4tcmVwb3J0L3YxIiwic3RlcHNfb2siOjAsInN0ZXBzX3RvdGFsIjoxLCJzdWJzdHJhdGUiOiJ3ZWIiLCJ0cmFuc2FjdGlvbl9vdXRjb21lIjoiUkVDT05DSUxJQVRJT05fUkVRVUlSRUQifSwicnVuX3JlY2VpcHRfc2hhMjU2IjoiMThlYjJjNGY0MTUzZGFiMDUzYmYwMjdjMjZmNjhhZmEwNjEzMTdlM2MyZTdkNWE2MGVlNThjM2VlNmIzZDdjNiIsInJ1bl9yZXBvcnRfb2JqZWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJydW5fcmVwb3J0X29iamVjdF92ZXJzaW9uIjoidmVyc2lvbjpyZWNvbmNpbGlhdGlvbjoxIiwicnVuX3JlcG9ydF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwicnVudGltZV9lbnZpcm9ubWVudF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwicnVudGltZV9zdWJzdHJhdGUiOiJ3ZWIiLCJydW50aW1lX3ZhbGlkYXRpb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDUiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLXRlcm1pbmFsLXZlcmlmaWNhdGlvbi92MiIsInRlbmFudF9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwMiIsInRlcm1pbmFsX3NlcXVlbmNlIjoxLCJ2ZXJpZmllZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDJaIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsIndvcmtmbG93X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAzIiwid29ya2Zsb3dfdmVyc2lvbl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwNCJ9LCJzaWduYXR1cmUiOiJkRUdXZ0NDTGZGTm1QNnV5X0JuZ1dZUHJnel9ScmpYeFVULUpkSEwzaTNEclZSTnJ6OWJsWlpzbTBRQXo2cWVHTy1UZkhHT2FLMTVTdUc2ZlIwRGpCdyIsInNpZ25lciI6eyJhbGdvcml0aG0iOiJlZDI1NTE5Iiwia2V5X2lkIjoiZXZpZGVuY2UtcnVubmVyLWVkMjU1MTktNTY0NzVhYTc1NDYzNDc0YyIsInB1YmxpY19rZXkiOiJBNkVIdi9QT0VMNGRjTjBZNTB2QW1XZmsxakNicFExZkhkeUdaQkpWTWJnPSJ9fQ==", + "terminal_verification_artifact_sha256": "2abcc6c65e0288a235b901169415d59632c8eaacf9b1aac087b1bb0d55ced624", "uncertain_delivery": true }, "effect_state": { @@ -131,12 +134,13 @@ }, { "callback": { - "artifact_bytes_source": "envelope_canonical_base64", "outcome": "RECONCILIATION_REQUIRED", "report_sha256": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "run_id": "00000000-0000-4000-8000-000000000001", "schema_version": "openadapt.hosted-runner-terminal/v1", "started": true, + "terminal_verification_artifact_bytes_base64": "eyJwYXlsb2FkIjp7ImFja25vd2xlZGdlZF9wZXJtaXRfY291bnQiOjEsImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA2IiwiYWRtaXNzaW9uX3BvbGljeV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYWRtaXR0ZWRfcnVudGltZV9idWlsZF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiYnVuZGxlX2FydGlmYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJidW5kbGVfY29udGVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYnVuZGxlX3ZlcnNpb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDQiLCJlZmZlY3RfY29udHJhY3Rfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImVudmlyb25tZW50X2NvbnRyYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJlbnZpcm9ubWVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXZpZGVuY2VfaWRlbnRpdHlfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImV2aWRlbmNlX21hbmlmZXN0cyI6eyJhdXRob3JpemF0aW9uIjp7ImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA2IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOCIsImV4ZWN1dGlvbl9hdXRob3JpdHlfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImdvdmVybmVkX2F1dGhvcml6YXRpb25faWRfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsIm1hbmlmZXN0X3NoYTI1NiI6ImYwY2ExOWE2YjNlYWJlNTk0ZGJjOTA2ODljMmY3NGNiZTVlODJkNGQ5NDdkYjI5YTVkMDdiMTY0MWU4OTYxY2YiLCJwZXJtaXRfY2hhaW5fc2hhMjU2IjoiNTA0OGZlOTQ1ODgyZDI4MDI2MDA4ZDdlOTEzN2FkMDE2ZmRkMDFhZWFmNTg4NDgxZmI1YmQwZjI0MmE1MDA0MyIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tYXV0aG9yaXphdGlvbi1ldmlkZW5jZS92MSJ9LCJlZmZlY3QiOnsiY29uZmlybWVkIjowLCJlZmZlY3RfY29udHJhY3Rfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsIm1hbmlmZXN0X3NoYTI1NiI6ImFmMTUwOWNjMmU5ZmExZjViOGI4MTVlN2IxZjYwNDYxOWIyYTM1ZWMwZGU1ZTBkMzRiYmZhNjdjYzkxZGJiYzciLCJyZWNvcmRzIjpbeyJhYnNlbmNlX2Jhc2lzIjoibm9uZSIsImF0dGVtcHRfc3RhdGUiOiJkZWxpdmVyeV91bmNlcnRhaW4iLCJlZmZlY3RfY29udHJhY3RfaGFzaCI6InNoYTI1NjphYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZWZmZWN0X3ZlcmlmaWVkIjpmYWxzZSwiZmluYWxfdmVyZGljdCI6bnVsbCwib2JzZXJ2ZWRfZWZmZWN0IjoidW5rbm93biIsInJlY29uY2lsaWF0aW9uX2FjdGlvbnMiOjAsInJlY29uY2lsaWF0aW9uX2NvbXBsZXRlZCI6ZmFsc2UsInJlY29yZF9raW5kIjoidGVybWluYWxfZWZmZWN0X3N0YXRlIiwicmVzb2x2ZWRfZGVsaXZlcnlfdW5jZXJ0YWludHkiOmZhbHNlLCJyZXN1bHRfaW5kZXgiOjAsInZlcmlmaWNhdGlvbl9wZXJmb3JtZWQiOmZhbHNlLCJ2ZXJpZmljYXRpb25fdGllciI6bnVsbCwidmVyaWZpZXJfaWRlbnRpdHkiOm51bGx9XSwicmVxdWlyZWQiOjEsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZWZmZWN0LWV2aWRlbmNlL3YxIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSJ9LCJpZGVudGl0eSI6eyJjb25maXJtZWQiOjEsImlkZW50aXR5X2NvbnRyYWN0X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJtYW5pZmVzdF9zaGEyNTYiOiIxMzVjODYzZWRjN2ZhYjE4Y2EyOWI0OTI5M2ZjMjVhMWM5YmQ0ZGUwZTllZDI4ZDRjZWM2ZThkMGE2NzkxMjI5IiwicmVxdWlyZWQiOjEsInJlc3VsdHMiOlt7Im1vZGUiOiJzdHJ1Y3R1cmVkIiwicmVzdWx0X2luZGV4IjowLCJzaWduYWxzIjpbXSwic3RhdHVzIjoidmVyaWZpZWQifV0sInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24taWRlbnRpdHktZXZpZGVuY2UvdjEiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIn0sInBvbGljeSI6eyJhZG1pc3Npb25fcG9saWN5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJlZmZlY3RfY29udHJhY3Rfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImVudmlyb25tZW50X2NvbnRyYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJlbnZpcm9ubWVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZ292ZXJuZWRfcG9saWN5X2NvbnRyYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJnb3Zlcm5lZF9ydW50aW1lX2lucHV0c19kaWdlc3QiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiaWRlbnRpdHlfY29udHJhY3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsIm1hbmlmZXN0X3NoYTI1NiI6IjRmOTg4ZDAxNWJjZDdjZDdlMDViYTA2NjNkODlmMGE5NjhmMGQ4YWNlOTliMDkwZWJhYmVlNTJhMWM1NTA0MjEiLCJtaW5pbXVtX2VmZmVjdF90aWVyIjoxLCJydW50aW1lX2Vudmlyb25tZW50X3NoYTI1NiI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLXBvbGljeS1ldmlkZW5jZS92MSJ9LCJwb3N0Y29uZGl0aW9uIjp7ImNvbmZpcm1lZCI6MCwibWFuaWZlc3Rfc2hhMjU2IjoiM2VhNGM2NGEzMGIwY2YxN2JjYTA0ZjMyNjBlMGE0NzE4YjI3ZjUxZTFmZGMyYmI4OGExODI2MzBhMzRkZDVmZiIsInJlY29yZHMiOlt7ImFjdGlvbl9raW5kIjoiY2xpY2siLCJhY3R1YXRpb25fcGF0aCI6Imd1aSIsImNvbnRyYWN0X2luZGV4IjowLCJjb250cmFjdF9raW5kIjoiZXhwbGljaXRfcHJlZGljYXRlIiwiY29udHJhY3Rfc2hhMjU2IjoiMGFkZTBiNTIwYmMwMDc4OTFjYWNjYTAwMTcxNTc4NDQyYTJhNzRjZWYxNWZmNjRkZGU0NWRmMDdhZmI2NGFlYiIsInJlc3VsdF9pbmRleCI6MCwic3RlcF9jb250cmFjdF9zaGEyNTYiOiIxYTU5NTM2YTQ4OGIxYzQ2YWFjZjBiYTM3OTMwYjg0MDYyYzE0Mjc1NWZhOTM5MTUyZWY1ZTI4YzQwOTQ3MWVkIiwic3RlcF9pbmRleCI6MCwidmVyZGljdCI6InVudmVyaWZpYWJsZSIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifV0sInJlcXVpcmVkIjoxLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLXBvc3Rjb25kaXRpb24tZXZpZGVuY2UvdjEiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIn19LCJldmlkZW5jZV9ydW5uZXJfc2lnbmVyX3NoYTI1NiI6IjU2NDc1YWE3NTQ2MzQ3NGMwMjg1ZGY1ZGJmMmJjYWI3M2RhNjUxMzU4ODM5ZTliNzc0ODFiMmVhYjEwNzcwOGMiLCJleGVjdXRpb25fYXV0aG9yaXR5X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA4IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaWduZXJfc2hhMjU2IjoiMjRmNmVkNmFjYmZlMTAwOWMwMzBkN2NhNTY3YzMzY2E0ODMwOTExNDk4MjM2YjU1NjFhNmM4MmFiZWM1ZGUyOCIsImV4ZWN1dGlvbl9vdXRjb21lIjp7ImNvbXBlbnNhdGlvbl9hY3Rpb25zIjowLCJldmlkZW5jZV9jbGFzc2VzIjpbImF1dGhvcml6YXRpb24iLCJpZGVudGl0eSJdLCJleGVjdXRpb25fY29tcGxldGVkIjpmYWxzZSwiZXh0ZXJuYWxfbmV0d29ya19jYWxscyI6Im5vbmUiLCJtb2RlbF9jYWxscyI6MCwib3V0Y29tZSI6IkhBTFRFRCIsInBhc3NlZF9jb250cmFjdHMiOnsiYXV0aG9yaXphdGlvbiI6MSwiZWZmZWN0IjowLCJpZGVudGl0eSI6MSwicG9zdGNvbmRpdGlvbiI6MH0sInBvc3Rjb25kaXRpb25fZXZpZGVuY2UiOlt7ImFjdGlvbl9raW5kIjoiY2xpY2siLCJhY3R1YXRpb25fcGF0aCI6Imd1aSIsImNvbnRyYWN0X2luZGV4IjowLCJjb250cmFjdF9raW5kIjoiZXhwbGljaXRfcHJlZGljYXRlIiwiY29udHJhY3Rfc2hhMjU2IjoiMGFkZTBiNTIwYmMwMDc4OTFjYWNjYTAwMTcxNTc4NDQyYTJhNzRjZWYxNWZmNjRkZGU0NWRmMDdhZmI2NGFlYiIsInJlc3VsdF9pbmRleCI6MCwic3RlcF9jb250cmFjdF9zaGEyNTYiOiIxYTU5NTM2YTQ4OGIxYzQ2YWFjZjBiYTM3OTMwYjg0MDYyYzE0Mjc1NWZhOTM5MTUyZWY1ZTI4YzQwOTQ3MWVkIiwic3RlcF9pbmRleCI6MCwidmVyZGljdCI6InVudmVyaWZpYWJsZSIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifV0sInByb2R1Y3Rpb25fZWxpZ2libGUiOmZhbHNlLCJwcm9maWxlIjoic3RhbmRhcmQiLCJxdWFsaWZpY2F0aW9uX2V2aWRlbmNlX29ubHkiOmZhbHNlLCJyZXF1aXJlZF9jb250cmFjdHMiOnsiYXV0aG9yaXphdGlvbiI6MSwiZWZmZWN0IjoxLCJpZGVudGl0eSI6MSwicG9zdGNvbmRpdGlvbiI6MX0sInZlcnNpb24iOiJvcGVuYWRhcHQuZXhlY3V0aW9uLW91dGNvbWUvdjEiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIn0sImV4ZWN1dGlvbl9vdXRjb21lX3NoYTI1NiI6ImZlMzg5YmFiMGViNDQ0N2NlYzE5OTgyNzRmNzI3Y2E1NzAwNDlmZWZkNTU3ZGI3OTkwNDc2OTlmMmY3OGYxNDIiLCJleGVjdXRpb25fcHVycG9zZSI6InByb2R1Y3Rpb24iLCJmaW5hbF9hdXRob3JpdHlfc2VxdWVuY2UiOjAsImZpbmFsX3J1bnRpbWVfZGVsaXZlcnlfc2VxdWVuY2UiOjksImZsb3dfcnVuX2lkX3NoYTI1NiI6IjExZTU5NGY0ODE5NThjMTBlMzAxNWQwYmYwNDQ3YTIyZjA2OGE4YTY0N2Y0NzVkZjE1Y2UyYzdhYjRiOGYzZjEiLCJpZGVudGl0eV9jb250cmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiaXNzdWVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowM1oiLCJwZW5kaW5nX3Blcm1pdF9jb3VudCI6MCwicGVybWl0X2NoYWluIjp7ImVudHJpZXMiOlt7ImRlbGl2ZXJ5X3JlY2VpcHRfYXJ0aWZhY3QiOnsicGF5bG9hZCI6eyJhdXRoZW50aWNhdGVkX3J1bm5lcl9pZF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwiYXV0aGVudGljYXRlZF9zZXNzaW9uX2lkX3NoYTI1NiI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJkZWxpdmVyZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAxWiIsImV4ZWN1dGlvbl9hdXRob3JpdHlfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDgiLCJvbmVfdXNlX2NsYWltX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDEwIiwicGVybWl0X2FydGlmYWN0X3NoYTI1NiI6Ijk3MmE4MmFmNDU2ZGE1NDJiYWM3ODQ2MDE4ODk2Njg4OTFkOGI3Y2NkMjQyOTA0ODE2YjMyOTJlMTU3ZTUyODkiLCJwZXJtaXRfaWQiOiJwZXJtaXQ6MSIsInJ1bnRpbWVfZGVsaXZlcnlfc2VxdWVuY2UiOjksInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcmVjZWlwdC1wYXlsb2FkL3YyIn0sInBheWxvYWRfc2hhMjU2IjoiOGE4ZjZkODg3NTBjYmI2YjNiZDY2MjA5M2FkMjllMmJjMjBjNmFiNjk5MWQ3MGU1ODg2OTFjOGIzYWI2NjJiOSIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcmVjZWlwdC1hcnRpZmFjdC92MiIsInNpZ25hdHVyZSI6IkFPS3FDZ1MxczBYYS1peUU5NlYteWxQelFjdjJ1dk9zdXlnSHp2dTJSeVY3RkxzSEZfTFZmcXl4NHUycHVtbEVsMFlrNVl1NzBKVlVrc1pwYVVwRER3Iiwic2lnbmVyIjp7ImFsZ29yaXRobSI6ImVkMjU1MTkiLCJrZXlfaWQiOiJkZWxpdmVyeS1hdXRob3JpdHktZWQyNTUxOS0yNGY2ZWQ2YWNiZmUxMDA5IiwicHVibGljX2tleSI6IktheTY0VUc4eXZDeUxocVUwMDBMeHpZZVVtMEwvaExJbDVTOGt5S1diZGM9In19LCJkZWxpdmVyeV9yZWNlaXB0X2FydGlmYWN0X3NoYTI1NiI6ImMwMGExYmE3MDE1ZjNjYmUwNWE3NmFlYWJmZjYxOWQ3OTNlNzM3NWEzMTBlMTk1ZmNiYmQyZDI5NDhmMmIyMTQiLCJwZXJtaXRfYXJ0aWZhY3QiOnsicGF5bG9hZCI6eyJhY3Rpb25fcmVxdWVzdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2FydGlmYWN0X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJhdXRob3JpdHlfc2VxdWVuY2UiOjAsImVudmlyb25tZW50X2RpZ2VzdCI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJldmlkZW5jZV9pZGVudGl0eV9zaGEyNTYiOiJlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlIiwiZXhlY3V0aW9uX2F1dGhvcml0eV9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOCIsImV4ZWN1dGlvbl9hdXRob3JpdHlfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImZsb3dfcnVuX2lkX3NoYTI1NiI6IjExZTU5NGY0ODE5NThjMTBlMzAxNWQwYmYwNDQ3YTIyZjA2OGE4YTY0N2Y0NzVkZjE1Y2UyYzdhYjRiOGYzZjEiLCJpbnB1dF9lZGdlX3NlcXVlbmNlIjoxLCJpc3N1ZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAwWiIsInBlcm1pdF9pZCI6InBlcm1pdDoxIiwicXVhbGlmaWNhdGlvbl9zaWduZXJfcmVnaXN0cnlfY2hlY2tlZF9hdCI6IjIwMjYtMDgtMThUMTE6NTk6MzBaIiwicXVhbGlmaWNhdGlvbl9zaWduZXJfcmVnaXN0cnlfZXhwaXJlc19hdCI6IjIwMjYtMDgtMjBUMTE6MDA6MDBaIiwicXVhbGlmaWNhdGlvbl9zaWduZXJfcmVnaXN0cnlfcmV2aXNpb24iOjcsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJydW5faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDEiLCJydW5fcmVxdWVzdF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1wZXJtaXQtcGF5bG9hZC92MiJ9LCJwYXlsb2FkX3NoYTI1NiI6ImM4N2Y1NzUxYWE5YjI3OWNjZTIzYWExNzhhZmY5NTZlMTlmNjkwZmNkMmY5ZjcwZTBkOTk5NzgyYTY5MGQ2YjgiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXBlcm1pdC1hcnRpZmFjdC92MiIsInNpZ25hdHVyZSI6IjBCeUhncUR4UVpybmdMSUYtNnRaT3E5bFhhbWNBUUMwZG9VVG5lS05QZVMtU3lvT2JReU9rQXVQRks1UFljTnpPYlp4Z3NnQUxkV2FJX3NhVUNwbEJnIiwic2lnbmVyIjp7ImFsZ29yaXRobSI6ImVkMjU1MTkiLCJrZXlfaWQiOiJkZWxpdmVyeS1hdXRob3JpdHktZWQyNTUxOS0yNGY2ZWQ2YWNiZmUxMDA5IiwicHVibGljX2tleSI6IktheTY0VUc4eXZDeUxocVUwMDBMeHpZZVVtMEwvaExJbDVTOGt5S1diZGM9In19LCJwZXJtaXRfYXJ0aWZhY3Rfc2hhMjU2IjoiOTcyYTgyYWY0NTZkYTU0MmJhYzc4NDYwMTg4OTY2ODg5MWQ4YjdjY2QyNDI5MDQ4MTZiMzI5MmUxNTdlNTI4OSIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcGVybWl0LWNoYWluLWVudHJ5L3YyIn1dLCJwZXJtaXRfY2hhaW5fc2hhMjU2IjoiNTA0OGZlOTQ1ODgyZDI4MDI2MDA4ZDdlOTEzN2FkMDE2ZmRkMDFhZWFmNTg4NDgxZmI1YmQwZjI0MmE1MDA0MyIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcGVybWl0LWNoYWluL3YyIn0sInBlcm1pdF9jb3VudCI6MSwicXVhbGlmaWNhdGlvbl9zaWduZXJfcmVnaXN0cnlfcmV2aXNpb24iOjcsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJydW5faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDEiLCJydW5fcmVjZWlwdCI6eyJhdXRob3JpemF0aW9uX2NvbmZpcm1lZCI6MSwiYXV0aG9yaXphdGlvbl9yZXF1aXJlZCI6MSwiYnVuZGxlX2RpZ2VzdCI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJkdXJhdGlvbl9tcyI6MTAwLCJlZmZlY3RfdGllcl9yZWFjaGVkIjoibm9uZSIsImVmZmVjdHNfY29uZmlybWVkIjowLCJlZmZlY3RzX3JlcXVpcmVkIjoxLCJlc3RfY29zdF9taWNyb3VzZCI6MCwiZXZpZGVuY2VfY2xhc3NlcyI6WyJhdXRob3JpemF0aW9uIiwiaWRlbnRpdHkiXSwiZXh0ZXJuYWxfbmV0d29ya19jYWxscyI6Im5vbmUiLCJnZW5lcmF0ZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAwWiIsImhlYWxzIjowLCJpZGVudGl0eV9hcHBsaWNhYmxlIjoxLCJpZGVudGl0eV9hcm1lZCI6MSwiaWRlbnRpdHlfY29uZmlybWVkIjoxLCJpZGVudGl0eV9yZXF1aXJlZCI6MSwibW9kZWxfY2FsbHMiOjAsIm91dGNvbWUiOiJIQUxURUQiLCJvdmVyX2hhbHRfY291bnQiOjAsInBvc3Rjb25kaXRpb25zX2NvbmZpcm1lZCI6MCwicG9zdGNvbmRpdGlvbnNfcmVxdWlyZWQiOjEsInByb2R1Y3Rpb25fZWxpZ2libGUiOmZhbHNlLCJwcm9maWxlIjoic3RhbmRhcmQiLCJwcm92ZW5hbmNlIjoicHJvZHVjdGlvbiIsInJlY2VpcHRfYnVpbGRlcl92ZXJzaW9uIjoiMS4yLjMiLCJydW5nX2hpc3RvZ3JhbSI6e30sInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tcnVuLXJlY2VpcHQvdjEiLCJzb3VyY2VfcmVjZWlwdF9kaWdlc3QiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwic291cmNlX3JlY2VpcHRfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsInNvdXJjZV9zY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5ydW4tcmVwb3J0L3YxIiwic3RlcHNfb2siOjAsInN0ZXBzX3RvdGFsIjoxLCJzdWJzdHJhdGUiOiJ3ZWIiLCJ0cmFuc2FjdGlvbl9vdXRjb21lIjoiUkVDT05DSUxJQVRJT05fUkVRVUlSRUQifSwicnVuX3JlY2VpcHRfc2hhMjU2IjoiMThlYjJjNGY0MTUzZGFiMDUzYmYwMjdjMjZmNjhhZmEwNjEzMTdlM2MyZTdkNWE2MGVlNThjM2VlNmIzZDdjNiIsInJ1bl9yZXBvcnRfb2JqZWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJydW5fcmVwb3J0X29iamVjdF92ZXJzaW9uIjoidmVyc2lvbjpyZWNvbmNpbGlhdGlvbjphY2tub3dsZWRnZWQ6MSIsInJ1bl9yZXBvcnRfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsInJ1bnRpbWVfZW52aXJvbm1lbnRfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsInJ1bnRpbWVfc3Vic3RyYXRlIjoid2ViIiwicnVudGltZV92YWxpZGF0aW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA1Iiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi10ZXJtaW5hbC12ZXJpZmljYXRpb24vdjIiLCJ0ZW5hbnRfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDIiLCJ0ZXJtaW5hbF9zZXF1ZW5jZSI6MSwidmVyaWZpZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAyWiIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJ3b3JrZmxvd19pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwMyIsIndvcmtmbG93X3ZlcnNpb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDQifSwic2lnbmF0dXJlIjoiQjVjRnVWbl81dkhLWFRES1FjYWtTakJ1NFRxd2lMblFrRG50MXU2VERhM1dJTTk5bXRQTTVfdW9WdmJka056NnhtbDZYdDljWHpITW1IbkYyZkh3Q1EiLCJzaWduZXIiOnsiYWxnb3JpdGhtIjoiZWQyNTUxOSIsImtleV9pZCI6ImV2aWRlbmNlLXJ1bm5lci1lZDI1NTE5LTU2NDc1YWE3NTQ2MzQ3NGMiLCJwdWJsaWNfa2V5IjoiQTZFSHYvUE9FTDRkY04wWTUwdkFtV2ZrMWpDYnBRMWZIZHlHWkJKVk1iZz0ifX0=", + "terminal_verification_artifact_sha256": "90cf0455a33f17c0462915a89dee93a3fb8a81f6a59cedbef1de2d709277cade", "uncertain_delivery": false }, "effect_state": { @@ -164,12 +168,13 @@ }, { "callback": { - "artifact_bytes_source": "envelope_canonical_base64", "outcome": "RECONCILIATION_REQUIRED", "report_sha256": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "run_id": "00000000-0000-4000-8000-000000000001", "schema_version": "openadapt.hosted-runner-terminal/v1", "started": true, + "terminal_verification_artifact_bytes_base64": "eyJwYXlsb2FkIjp7ImFja25vd2xlZGdlZF9wZXJtaXRfY291bnQiOjAsImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA2IiwiYWRtaXNzaW9uX3BvbGljeV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYWRtaXR0ZWRfcnVudGltZV9idWlsZF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiYnVuZGxlX2FydGlmYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJidW5kbGVfY29udGVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYnVuZGxlX3ZlcnNpb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDQiLCJkZWxpdmVyeV9yZXN1bHRfbG9zc19jbG9zdXJlIjp7InBheWxvYWQiOnsiYWNrbm93bGVkZ2VkX3Blcm1pdF9jb3VudCI6MCwiYWN0dWF0aW9uX3JlcGxheV9hdXRob3JpemVkIjpmYWxzZSwiYXV0aGVudGljYXRlZF9ydW5uZXJfaWRfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsImF1dGhlbnRpY2F0ZWRfc2Vzc2lvbl9pZF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiYmxpbmRfcmV0cnlfYXV0aG9yaXplZCI6ZmFsc2UsImNoaWxkX3N0YXJ0X2V2aWRlbmNlX3NoYTI1NiI6ImVjNjkwNzkxODg2YWUyY2UwMGM0ZTUxMTU0YzNmMTIwZWE0NDE5ZWQyNjUxZTA3M2RiNTcyNDkxOGEzYjA4YzYiLCJjaGlsZF9zdGFydGVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMFoiLCJjbG9zZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAyWiIsImNsb3N1cmVfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMTEiLCJjbG9zdXJlX3JlcXVlc3Rfc2hhMjU2IjoiZDkzMGFiMWFiYzJiMmEwNGI4NDhiOTU1ZmZkZmZmYTFmYmUwNjU1YTU1MzI1ZTA0ODlhZTExZWQ4NDIwMjI2MCIsImNsb3N1cmVfc2VxdWVuY2UiOjEsImRlbGl2ZXJ5X2Fja25vd2xlZGdtZW50X2F1dGhvcml6ZWQiOmZhbHNlLCJkZWxpdmVyeV9zdGF0ZSI6IkNMT1NFRF9VTlJFU09MVkVEX1JFU1VMVF9MT1NTIiwiZGlzcGF0Y2hfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDkiLCJkaXNwYXRjaF9zZXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDEwIiwiZWZmZWN0X2Fic2VuY2VfY2xhaW1lZCI6ZmFsc2UsImV4ZWN1dGlvbl9hdXRob3JpdHlfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDgiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NpZ25lcl9zaGEyNTYiOiIyNGY2ZWQ2YWNiZmUxMDA5YzAzMGQ3Y2E1NjdjMzNjYTQ4MzA5MTE0OTgyMzZiNTU2MWE2YzgyYWJlYzVkZTI4IiwiZmluYWxfYXV0aG9yaXR5X3NlcXVlbmNlIjowLCJmaW5hbF9pbnB1dF9lZGdlX3NlcXVlbmNlIjoxLCJmaW5hbF9ydW50aW1lX2RlbGl2ZXJ5X3NlcXVlbmNlIjowLCJmbG93X3J1bl9pZF9zaGEyNTYiOiIxMWU1OTRmNDgxOTU4YzEwZTMwMTVkMGJmMDQ0N2EyMmYwNjhhOGE2NDdmNDc1ZGYxNWNlMmM3YWI0YjhmM2YxIiwiaWRlbXBvdGVuY3lfa2V5X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJtYW5hZ2VkX2Rpc3BhdGNoX2JpbmRpbmdfc2hhMjU2Ijoic2hhMjU2OmNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJuZXdfcGVybWl0X2F1dGhvcml6ZWQiOmZhbHNlLCJub3RfcmVjZWl2ZWRfY2xhaW1lZCI6ZmFsc2UsInBlbmRpbmdfYWN0aW9uX3JlcXVlc3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsInBlbmRpbmdfcGVybWl0X2FydGlmYWN0X3NoYTI1NiI6Ijk3MmE4MmFmNDU2ZGE1NDJiYWM3ODQ2MDE4ODk2Njg4OTFkOGI3Y2NkMjQyOTA0ODE2YjMyOTJlMTU3ZTUyODkiLCJwZW5kaW5nX3Blcm1pdF9jb3VudCI6MSwicGVybWl0X2NoYWluX3NoYTI1NiI6IjU5YjM5OTcxZTMwNTEwOWM1NDI5OTQ1YTVmYWI0NjYwYjA5ZjQxZTdhYzNmZmQ5MmUzNTA2YWYwMDMzN2RhOTUiLCJwZXJtaXRfY291bnQiOjEsInJlY2VpcHRfYWJzZW5jZV9vYnNlcnZlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDJaIiwicmVzdWx0X2xvc3Nfb2JzZXJ2ZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAyWiIsInJ1bl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwMSIsInJ1bl9yZXF1ZXN0X3NoYTI1NiI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJydW5fc3RvcmVfaWRlbnRpdHlfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcmVzdWx0LWxvc3MtY2xvc3VyZS1wYXlsb2FkL3YyIiwidGVuYW50X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAyIiwidGVybWluYWxfY2FsbGJhY2tfcmVxdWlyZWQiOnRydWV9LCJwYXlsb2FkX3NoYTI1NiI6ImE4OTFhYzRjYmE1ZmRmYzE3ZDAzYzFmODAyYTJkZjhjMTFmYmYwYjYyZTRmMDRiZTY3ZjFhNWM2ZTY4ZDBhNTMiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXJlc3VsdC1sb3NzLWNsb3N1cmUtYXJ0aWZhY3QvdjIiLCJzaWduYXR1cmUiOiJnYnN0M241STMwQUF1dzZqMTdSREUtQWVRZXlxc0prUnVNbHJHQjdKSUNPOFNuTHhlQkhaSzM0NVRiN1ljY2lVZjVITF9COFZOdEpaRFRSd0ZpM1VEUSIsInNpZ25lciI6eyJhbGdvcml0aG0iOiJlZDI1NTE5Iiwia2V5X2lkIjoiZGVsaXZlcnktYXV0aG9yaXR5LWVkMjU1MTktMjRmNmVkNmFjYmZlMTAwOSIsInB1YmxpY19rZXkiOiJLYXk2NFVHOHl2Q3lMaHFVMDAwTHh6WWVVbTBML2hMSWw1UzhreUtXYmRjPSJ9fSwiZWZmZWN0X2NvbnRyYWN0X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJlbnZpcm9ubWVudF9jb250cmFjdF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwiZW52aXJvbm1lbnRfZGlnZXN0IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImV2aWRlbmNlX2lkZW50aXR5X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJldmlkZW5jZV9tYW5pZmVzdHMiOnsiYXV0aG9yaXphdGlvbiI6eyJhZG1pc3Npb25fYXJ0aWZhY3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsImFkbWlzc2lvbl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwNiIsImV4ZWN1dGlvbl9hdXRob3JpdHlfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDgiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJnb3Zlcm5lZF9hdXRob3JpemF0aW9uX2lkX3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJtYW5pZmVzdF9zaGEyNTYiOiIxNWMwZTc2ZGMyZTMyMWEzODRlNTNlYzE1ZmY1M2U3NTU1N2I3Y2RlNzFjNWFkMmJhMmI5M2ZmMmU5NTgzNWE1IiwicGVybWl0X2NoYWluX3NoYTI1NiI6IjU5YjM5OTcxZTMwNTEwOWM1NDI5OTQ1YTVmYWI0NjYwYjA5ZjQxZTdhYzNmZmQ5MmUzNTA2YWYwMDMzN2RhOTUiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWF1dGhvcml6YXRpb24tZXZpZGVuY2UvdjEifSwiZWZmZWN0Ijp7ImNvbmZpcm1lZCI6MCwiZWZmZWN0X2NvbnRyYWN0X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJtYW5pZmVzdF9zaGEyNTYiOiI3ZTEyZGNhNWM0NGNmOTk4YTQ2OTM2MmI4NjJlODE2YTdkMmM4NTQxNjNmNjNlOGRlNjFmYjc5ZTk1YmE4MDA3IiwicmVjb3JkcyI6W10sInJlcXVpcmVkIjowLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWVmZmVjdC1ldmlkZW5jZS92MSIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifSwiaWRlbnRpdHkiOnsiY29uZmlybWVkIjowLCJpZGVudGl0eV9jb250cmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwibWFuaWZlc3Rfc2hhMjU2IjoiZDNhN2VhYzM0MjdkNzZmNmJjMzYwMzA3Mzg2MDkxMTlmMDdlMGQ5MWE2ZDM1OGFiY2U1YjZmMGQ2ZGY3ODY0NSIsInJlcXVpcmVkIjowLCJyZXN1bHRzIjpbXSwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1pZGVudGl0eS1ldmlkZW5jZS92MSIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifSwicG9saWN5Ijp7ImFkbWlzc2lvbl9wb2xpY3lfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImVmZmVjdF9jb250cmFjdF9zaGEyNTYiOiJlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlIiwiZW52aXJvbm1lbnRfY29udHJhY3Rfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsImVudmlyb25tZW50X2RpZ2VzdCI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJnb3Zlcm5lZF9wb2xpY3lfY29udHJhY3Rfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsImdvdmVybmVkX3J1bnRpbWVfaW5wdXRzX2RpZ2VzdCI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJpZGVudGl0eV9jb250cmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwibWFuaWZlc3Rfc2hhMjU2IjoiNGY5ODhkMDE1YmNkN2NkN2UwNWJhMDY2M2Q4OWYwYTk2OGYwZDhhY2U5OWIwOTBlYmFiZWU1MmExYzU1MDQyMSIsIm1pbmltdW1fZWZmZWN0X3RpZXIiOjEsInJ1bnRpbWVfZW52aXJvbm1lbnRfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tcG9saWN5LWV2aWRlbmNlL3YxIn0sInBvc3Rjb25kaXRpb24iOnsiY29uZmlybWVkIjowLCJtYW5pZmVzdF9zaGEyNTYiOiI1MmYwOWQ1ZDYzOWIxYzM4M2YzNzc5NjNlNDg3Y2I4OWQ4OTQxNzg1N2U0NGRhN2UzZjIzZTU1YmU3NTFlN2Y0IiwicmVjb3JkcyI6W10sInJlcXVpcmVkIjowLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLXBvc3Rjb25kaXRpb24tZXZpZGVuY2UvdjEiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIn19LCJldmlkZW5jZV9ydW5uZXJfc2lnbmVyX3NoYTI1NiI6IjU2NDc1YWE3NTQ2MzQ3NGMwMjg1ZGY1ZGJmMmJjYWI3M2RhNjUxMzU4ODM5ZTliNzc0ODFiMmVhYjEwNzcwOGMiLCJleGVjdXRpb25fYXV0aG9yaXR5X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA4IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaWduZXJfc2hhMjU2IjoiMjRmNmVkNmFjYmZlMTAwOWMwMzBkN2NhNTY3YzMzY2E0ODMwOTExNDk4MjM2YjU1NjFhNmM4MmFiZWM1ZGUyOCIsImV4ZWN1dGlvbl9vdXRjb21lIjp7ImNvbXBlbnNhdGlvbl9hY3Rpb25zIjowLCJldmlkZW5jZV9jbGFzc2VzIjpbImF1dGhvcml6YXRpb24iXSwiZXhlY3V0aW9uX2NvbXBsZXRlZCI6ZmFsc2UsImV4dGVybmFsX25ldHdvcmtfY2FsbHMiOiJvYnNlcnZlZCIsIm1hbmFnZWRfcmVzdWx0X2xvc3NfZXZpZGVuY2Vfc2hhMjU2IjoiMmNkMDc2NDkwY2E1ZTVlOGQ5ZDBiZDE0NmQ1NTljMDZlZDQxM2E2N2Q2OTQ4MWExYWZjYzM1NDQ2NGVjZGIwNyIsIm1vZGVsX2NhbGxzIjowLCJvdXRjb21lIjoiSEFMVEVEIiwicGFzc2VkX2NvbnRyYWN0cyI6eyJhdXRob3JpemF0aW9uIjoxLCJlZmZlY3QiOjAsImlkZW50aXR5IjowLCJwb3N0Y29uZGl0aW9uIjowfSwicG9zdGNvbmRpdGlvbl9ldmlkZW5jZSI6W10sInByb2R1Y3Rpb25fZWxpZ2libGUiOmZhbHNlLCJwcm9maWxlIjoic3RhbmRhcmQiLCJxdWFsaWZpY2F0aW9uX2V2aWRlbmNlX29ubHkiOmZhbHNlLCJyZXF1aXJlZF9jb250cmFjdHMiOnsiYXV0aG9yaXphdGlvbiI6MSwiZWZmZWN0IjowLCJpZGVudGl0eSI6MCwicG9zdGNvbmRpdGlvbiI6MH0sInZlcnNpb24iOiJvcGVuYWRhcHQuZXhlY3V0aW9uLW91dGNvbWUvdjEiLCJ3b3JrZmxvd19jb250cmFjdF9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIn0sImV4ZWN1dGlvbl9vdXRjb21lX3NoYTI1NiI6IjRmNzdkMTRkNjdjZjQ1OTRmMjE2MjNhZWUxMTUzMTg4Mzk1ODYyNjVmZjFkY2FiNzI3N2Q3NmZlMTU5NDIyMDMiLCJleGVjdXRpb25fcHVycG9zZSI6InByb2R1Y3Rpb24iLCJmaW5hbF9hdXRob3JpdHlfc2VxdWVuY2UiOjAsImZpbmFsX3J1bnRpbWVfZGVsaXZlcnlfc2VxdWVuY2UiOjAsImZsb3dfcnVuX2lkX3NoYTI1NiI6IjExZTU5NGY0ODE5NThjMTBlMzAxNWQwYmYwNDQ3YTIyZjA2OGE4YTY0N2Y0NzVkZjE1Y2UyYzdhYjRiOGYzZjEiLCJpZGVudGl0eV9jb250cmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiaXNzdWVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowM1oiLCJtYW5hZ2VkX3Jlc3VsdF9sb3NzIjp7ImFjdHVhdGlvbl9yZXBsYXlfYXV0aG9yaXplZCI6ZmFsc2UsImF1dGhlbnRpY2F0ZWRfcnVubmVyX2lkX3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJhdXRoZW50aWNhdGVkX3Nlc3Npb25faWRfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsImJsaW5kX3JldHJ5X2F1dGhvcml6ZWQiOmZhbHNlLCJjaGlsZF9yZXBvcnRfcmV0YWluZWQiOmZhbHNlLCJjaGlsZF9zdGFydF9ldmlkZW5jZV9zaGEyNTYiOiJlYzY5MDc5MTg4NmFlMmNlMDBjNGU1MTE1NGMzZjEyMGVhNDQxOWVkMjY1MWUwNzNkYjU3MjQ5MThhM2IwOGM2IiwiY2hpbGRfc3RhcnRlZCI6dHJ1ZSwiY2hpbGRfc3RhcnRlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDBaIiwiZGVsaXZlcnlfcmVzdWx0X2xvc3NfY2xvc3VyZV9hcnRpZmFjdF9zaGEyNTYiOiI2NWQwZDgyZDU3N2E1MzIzMDIyYjJhZmNlMWEyNmEyMTZhNTJkMjFlZjk4MmUwNTQwYzI2NmYzMDYzZmJjNzk3IiwiZGVsaXZlcnlfc3RhdGUiOiJDTE9TRURfVU5SRVNPTFZFRF9SRVNVTFRfTE9TUyIsImRpc3BhdGNoX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA5IiwiZGlzcGF0Y2hfc2Vzc2lvbl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAxMCIsImVmZmVjdF9hYnNlbmNlX2NsYWltZWQiOmZhbHNlLCJldmlkZW5jZV9zaGEyNTYiOiIyY2QwNzY0OTBjYTVlNWU4ZDlkMGJkMTQ2ZDU1OWMwNmVkNDEzYTY3ZDY5NDgxYTFhZmNjMzU0NDY0ZWNkYjA3IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOCIsImV4ZWN1dGlvbl9hdXRob3JpdHlfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImV4ZWN1dGlvbl9hdXRob3JpdHlfc2lnbmVyX3NoYTI1NiI6IjI0ZjZlZDZhY2JmZTEwMDljMDMwZDdjYTU2N2MzM2NhNDgzMDkxMTQ5ODIzNmI1NTYxYTZjODJhYmVjNWRlMjgiLCJmbG93X3J1bl9pZF9zaGEyNTYiOiIxMWU1OTRmNDgxOTU4YzEwZTMwMTVkMGJmMDQ0N2EyMmYwNjhhOGE2NDdmNDc1ZGYxNWNlMmM3YWI0YjhmM2YxIiwiaWRlbXBvdGVuY3lfa2V5X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJsb3NzX2NvZGUiOiJyZXBvcnRfbWlzc2luZyIsIm1hbmFnZWRfZGlzcGF0Y2hfYmluZGluZ19zaGEyNTYiOiJzaGEyNTY6Y2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsIm5vdF9yZWNlaXZlZF9jbGFpbWVkIjpmYWxzZSwib2JzZXJ2ZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAyWiIsInBlbmRpbmdfYWN0aW9uX3JlcXVlc3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsInBlbmRpbmdfcGVybWl0X2FydGlmYWN0X3NoYTI1NiI6Ijk3MmE4MmFmNDU2ZGE1NDJiYWM3ODQ2MDE4ODk2Njg4OTFkOGI3Y2NkMjQyOTA0ODE2YjMyOTJlMTU3ZTUyODkiLCJyZXBvcnRfcHJvdmVuYW5jZSI6Im91dGVyX3J1bm5lcl9yZWNvdmVyeSIsInJ1bl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwMSIsInJ1bl9yZXF1ZXN0X3NoYTI1NiI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJydW5fc3RvcmVfaWRlbnRpdHlfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0Lm1hbmFnZWQtcmVzdWx0LWxvc3MvdjEifSwicGVuZGluZ19wZXJtaXRfY291bnQiOjEsInBlcm1pdF9jaGFpbiI6eyJlbnRyaWVzIjpbXSwicGVuZGluZyI6eyJhY3R1YXRpb25fcmVwbGF5X2F1dGhvcml6ZWQiOmZhbHNlLCJkZWxpdmVyeV9yZWNlaXB0X2FydGlmYWN0IjpudWxsLCJkZWxpdmVyeV9yZWNlaXB0X2FydGlmYWN0X3NoYTI1NiI6bnVsbCwiZGVsaXZlcnlfc3RhdGUiOiJVTlJFU09MVkVEIiwicGVybWl0X2FydGlmYWN0Ijp7InBheWxvYWQiOnsiYWN0aW9uX3JlcXVlc3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYXV0aG9yaXR5X3NlcXVlbmNlIjowLCJlbnZpcm9ubWVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXZpZGVuY2VfaWRlbnRpdHlfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImV4ZWN1dGlvbl9hdXRob3JpdHlfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDgiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJmbG93X3J1bl9pZF9zaGEyNTYiOiIxMWU1OTRmNDgxOTU4YzEwZTMwMTVkMGJmMDQ0N2EyMmYwNjhhOGE2NDdmNDc1ZGYxNWNlMmM3YWI0YjhmM2YxIiwiaW5wdXRfZWRnZV9zZXF1ZW5jZSI6MSwiaXNzdWVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMFoiLCJwZXJtaXRfaWQiOiJwZXJtaXQ6MSIsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X2NoZWNrZWRfYXQiOiIyMDI2LTA4LTE4VDExOjU5OjMwWiIsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X2V4cGlyZXNfYXQiOiIyMDI2LTA4LTIwVDExOjAwOjAwWiIsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X3JldmlzaW9uIjo3LCJxdWFsaWZpY2F0aW9uX3NpZ25lcl9yZWdpc3RyeV9zaGEyNTYiOiJlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlIiwicnVuX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAxIiwicnVuX3JlcXVlc3Rfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcGVybWl0LXBheWxvYWQvdjIifSwicGF5bG9hZF9zaGEyNTYiOiJjODdmNTc1MWFhOWIyNzljY2UyM2FhMTc4YWZmOTU2ZTE5ZjY5MGZjZDJmOWY3MGUwZDk5OTc4MmE2OTBkNmI4Iiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1wZXJtaXQtYXJ0aWZhY3QvdjIiLCJzaWduYXR1cmUiOiIwQnlIZ3FEeFFacm5nTElGLTZ0Wk9xOWxYYW1jQVFDMGRvVVRuZUtOUGVTLVN5b09iUXlPa0F1UEZLNVBZY056T2JaeGdzZ0FMZFdhSV9zYVVDcGxCZyIsInNpZ25lciI6eyJhbGdvcml0aG0iOiJlZDI1NTE5Iiwia2V5X2lkIjoiZGVsaXZlcnktYXV0aG9yaXR5LWVkMjU1MTktMjRmNmVkNmFjYmZlMTAwOSIsInB1YmxpY19rZXkiOiJLYXk2NFVHOHl2Q3lMaHFVMDAwTHh6WWVVbTBML2hMSWw1UzhreUtXYmRjPSJ9fSwicGVybWl0X2FydGlmYWN0X3NoYTI1NiI6Ijk3MmE4MmFmNDU2ZGE1NDJiYWM3ODQ2MDE4ODk2Njg4OTFkOGI3Y2NkMjQyOTA0ODE2YjMyOTJlMTU3ZTUyODkiLCJyZWNlaXB0X2Fic2VuY2Vfb2JzZXJ2ZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAyWiIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcGVuZGluZy1wZXJtaXQvdjIifSwicGVybWl0X2NoYWluX3NoYTI1NiI6IjU5YjM5OTcxZTMwNTEwOWM1NDI5OTQ1YTVmYWI0NjYwYjA5ZjQxZTdhYzNmZmQ5MmUzNTA2YWYwMDMzN2RhOTUiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXBlcm1pdC1jaGFpbi92MiJ9LCJwZXJtaXRfY291bnQiOjEsInF1YWxpZmljYXRpb25fc2lnbmVyX3JlZ2lzdHJ5X3JldmlzaW9uIjo3LCJxdWFsaWZpY2F0aW9uX3NpZ25lcl9yZWdpc3RyeV9zaGEyNTYiOiJlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlIiwicnVuX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAxIiwicnVuX3JlY2VpcHQiOnsiYXV0aG9yaXphdGlvbl9jb25maXJtZWQiOjEsImF1dGhvcml6YXRpb25fcmVxdWlyZWQiOjEsImJ1bmRsZV9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZHVyYXRpb25fbXMiOjAsImVmZmVjdF90aWVyX3JlYWNoZWQiOiJub25lIiwiZWZmZWN0c19jb25maXJtZWQiOjAsImVmZmVjdHNfcmVxdWlyZWQiOjAsImVzdF9jb3N0X21pY3JvdXNkIjowLCJldmlkZW5jZV9jbGFzc2VzIjpbImF1dGhvcml6YXRpb24iXSwiZXh0ZXJuYWxfbmV0d29ya19jYWxscyI6Im9ic2VydmVkIiwiZ2VuZXJhdGVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMFoiLCJoZWFscyI6MCwiaWRlbnRpdHlfYXBwbGljYWJsZSI6MCwiaWRlbnRpdHlfYXJtZWQiOjAsImlkZW50aXR5X2NvbmZpcm1lZCI6MCwiaWRlbnRpdHlfcmVxdWlyZWQiOjAsIm1hbmFnZWRfcmVzdWx0X2xvc3NfZXZpZGVuY2Vfc2hhMjU2IjoiMmNkMDc2NDkwY2E1ZTVlOGQ5ZDBiZDE0NmQ1NTljMDZlZDQxM2E2N2Q2OTQ4MWExYWZjYzM1NDQ2NGVjZGIwNyIsIm1vZGVsX2NhbGxzIjowLCJvdXRjb21lIjoiSEFMVEVEIiwib3Zlcl9oYWx0X2NvdW50IjowLCJwb3N0Y29uZGl0aW9uc19jb25maXJtZWQiOjAsInBvc3Rjb25kaXRpb25zX3JlcXVpcmVkIjowLCJwcm9kdWN0aW9uX2VsaWdpYmxlIjpmYWxzZSwicHJvZmlsZSI6InN0YW5kYXJkIiwicHJvdmVuYW5jZSI6InByb2R1Y3Rpb24iLCJyZWNlaXB0X2J1aWxkZXJfdmVyc2lvbiI6IjEuMi4zIiwicnVuZ19oaXN0b2dyYW0iOnt9LCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLXJ1bi1yZWNlaXB0L3YxIiwic291cmNlX3JlY2VpcHRfZGlnZXN0IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsInNvdXJjZV9yZWNlaXB0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJzb3VyY2Vfc2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucnVuLXJlcG9ydC92MSIsInN0ZXBzX29rIjowLCJzdGVwc190b3RhbCI6MSwic3Vic3RyYXRlIjoid2ViIiwidHJhbnNhY3Rpb25fb3V0Y29tZSI6IlJFQ09OQ0lMSUFUSU9OX1JFUVVJUkVEIn0sInJ1bl9yZWNlaXB0X3NoYTI1NiI6IjMwMDllZTJlMGRlMmIzZmM0MDZkNDkxMWFhY2U1OTY0MjBhZWFhZDgyZjZhOGE1MmVlY2MyNjQ4MDAzZTI0NTkiLCJydW5fcmVwb3J0X29iamVjdF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwicnVuX3JlcG9ydF9vYmplY3RfdmVyc2lvbiI6InZlcnNpb246bWFuYWdlZC1yZXN1bHQtbG9zczoxIiwicnVuX3JlcG9ydF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwicnVudGltZV9lbnZpcm9ubWVudF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwicnVudGltZV9zdWJzdHJhdGUiOiJ3ZWIiLCJydW50aW1lX3ZhbGlkYXRpb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDUiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLXRlcm1pbmFsLXZlcmlmaWNhdGlvbi92MiIsInRlbmFudF9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwMiIsInRlcm1pbmFsX3NlcXVlbmNlIjoxLCJ2ZXJpZmllZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDJaIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsIndvcmtmbG93X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAzIiwid29ya2Zsb3dfdmVyc2lvbl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwNCJ9LCJzaWduYXR1cmUiOiJzVlhzVE5yZDdrTGZTdkFjU2Z6TUh1eWtBLThBbHdJUGMtRk5tYkRPVVdsb3BQaC11MGowR0xlX1JxWURQSThFd003MEp4LTJWa0JNdW9BeXhJaGdEZyIsInNpZ25lciI6eyJhbGdvcml0aG0iOiJlZDI1NTE5Iiwia2V5X2lkIjoiZXZpZGVuY2UtcnVubmVyLWVkMjU1MTktNTY0NzVhYTc1NDYzNDc0YyIsInB1YmxpY19rZXkiOiJBNkVIdi9QT0VMNGRjTjBZNTB2QW1XZmsxakNicFExZkhkeUdaQkpWTWJnPSJ9fQ==", + "terminal_verification_artifact_sha256": "b61dbd7c53e609c28181a9f31b067eb8c829b37c14b2e99d6ff711fe9c64dcac", "uncertain_delivery": true }, "effect_state": null, @@ -213,12 +218,13 @@ }, { "callback": { - "artifact_bytes_source": "envelope_canonical_base64", "outcome": "RECONCILIATION_REQUIRED", "report_sha256": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "run_id": "00000000-0000-4000-8000-000000000001", "schema_version": "openadapt.hosted-runner-terminal/v1", "started": true, + "terminal_verification_artifact_bytes_base64": "eyJwYXlsb2FkIjp7ImFja25vd2xlZGdlZF9wZXJtaXRfY291bnQiOjEsImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA2IiwiYWRtaXNzaW9uX3BvbGljeV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYWRtaXR0ZWRfcnVudGltZV9idWlsZF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiYnVuZGxlX2FydGlmYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJidW5kbGVfY29udGVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiYnVuZGxlX3ZlcnNpb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDQiLCJkZWxpdmVyeV9yZXN1bHRfbG9zc19jbG9zdXJlIjp7InBheWxvYWQiOnsiYWNrbm93bGVkZ2VkX3Blcm1pdF9jb3VudCI6MSwiYWN0dWF0aW9uX3JlcGxheV9hdXRob3JpemVkIjpmYWxzZSwiYXV0aGVudGljYXRlZF9ydW5uZXJfaWRfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsImF1dGhlbnRpY2F0ZWRfc2Vzc2lvbl9pZF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiYmxpbmRfcmV0cnlfYXV0aG9yaXplZCI6ZmFsc2UsImNoaWxkX3N0YXJ0X2V2aWRlbmNlX3NoYTI1NiI6ImVjNjkwNzkxODg2YWUyY2UwMGM0ZTUxMTU0YzNmMTIwZWE0NDE5ZWQyNjUxZTA3M2RiNTcyNDkxOGEzYjA4YzYiLCJjaGlsZF9zdGFydGVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMFoiLCJjbG9zZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAyWiIsImNsb3N1cmVfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMTEiLCJjbG9zdXJlX3JlcXVlc3Rfc2hhMjU2IjoiZDkzMGFiMWFiYzJiMmEwNGI4NDhiOTU1ZmZkZmZmYTFmYmUwNjU1YTU1MzI1ZTA0ODlhZTExZWQ4NDIwMjI2MCIsImNsb3N1cmVfc2VxdWVuY2UiOjEsImRlbGl2ZXJ5X2Fja25vd2xlZGdtZW50X2F1dGhvcml6ZWQiOmZhbHNlLCJkZWxpdmVyeV9zdGF0ZSI6IkNMT1NFRF9VTlJFU09MVkVEX1JFU1VMVF9MT1NTIiwiZGlzcGF0Y2hfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDkiLCJkaXNwYXRjaF9zZXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDEwIiwiZWZmZWN0X2Fic2VuY2VfY2xhaW1lZCI6ZmFsc2UsImV4ZWN1dGlvbl9hdXRob3JpdHlfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDgiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NpZ25lcl9zaGEyNTYiOiIyNGY2ZWQ2YWNiZmUxMDA5YzAzMGQ3Y2E1NjdjMzNjYTQ4MzA5MTE0OTgyMzZiNTU2MWE2YzgyYWJlYzVkZTI4IiwiZmluYWxfYXV0aG9yaXR5X3NlcXVlbmNlIjowLCJmaW5hbF9pbnB1dF9lZGdlX3NlcXVlbmNlIjoxLCJmaW5hbF9ydW50aW1lX2RlbGl2ZXJ5X3NlcXVlbmNlIjo5LCJmbG93X3J1bl9pZF9zaGEyNTYiOiIxMWU1OTRmNDgxOTU4YzEwZTMwMTVkMGJmMDQ0N2EyMmYwNjhhOGE2NDdmNDc1ZGYxNWNlMmM3YWI0YjhmM2YxIiwiaWRlbXBvdGVuY3lfa2V5X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJtYW5hZ2VkX2Rpc3BhdGNoX2JpbmRpbmdfc2hhMjU2Ijoic2hhMjU2OmNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJuZXdfcGVybWl0X2F1dGhvcml6ZWQiOmZhbHNlLCJub3RfcmVjZWl2ZWRfY2xhaW1lZCI6ZmFsc2UsInBlbmRpbmdfYWN0aW9uX3JlcXVlc3Rfc2hhMjU2IjpudWxsLCJwZW5kaW5nX3Blcm1pdF9hcnRpZmFjdF9zaGEyNTYiOm51bGwsInBlbmRpbmdfcGVybWl0X2NvdW50IjowLCJwZXJtaXRfY2hhaW5fc2hhMjU2IjoiNTA0OGZlOTQ1ODgyZDI4MDI2MDA4ZDdlOTEzN2FkMDE2ZmRkMDFhZWFmNTg4NDgxZmI1YmQwZjI0MmE1MDA0MyIsInBlcm1pdF9jb3VudCI6MSwicmVjZWlwdF9hYnNlbmNlX29ic2VydmVkX2F0IjpudWxsLCJyZXN1bHRfbG9zc19vYnNlcnZlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDJaIiwicnVuX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAxIiwicnVuX3JlcXVlc3Rfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsInJ1bl9zdG9yZV9pZGVudGl0eV9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1yZXN1bHQtbG9zcy1jbG9zdXJlLXBheWxvYWQvdjIiLCJ0ZW5hbnRfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDIiLCJ0ZXJtaW5hbF9jYWxsYmFja19yZXF1aXJlZCI6dHJ1ZX0sInBheWxvYWRfc2hhMjU2IjoiNmI3NWY4YjQ1YTdkM2U5Y2ZlODU2NGZmZTMyZjI5YzJiNTk3YzI4MTM2YTk3YTRmNTQ1M2ZlMmFmZDE3MjhhYSIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcmVzdWx0LWxvc3MtY2xvc3VyZS1hcnRpZmFjdC92MiIsInNpZ25hdHVyZSI6Imt6dVIycXJjR1Q0cG82LXl6ZFlEZ2gzd2FZamI5V3BRR1VfQm5RTEhUSWJkZDV4QmxyVVNsNkg0Y2VWQzMzcjFCd2JGdFJQYVB2bzA1cGd4Z0U0d0F3Iiwic2lnbmVyIjp7ImFsZ29yaXRobSI6ImVkMjU1MTkiLCJrZXlfaWQiOiJkZWxpdmVyeS1hdXRob3JpdHktZWQyNTUxOS0yNGY2ZWQ2YWNiZmUxMDA5IiwicHVibGljX2tleSI6IktheTY0VUc4eXZDeUxocVUwMDBMeHpZZVVtMEwvaExJbDVTOGt5S1diZGM9In19LCJlZmZlY3RfY29udHJhY3Rfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImVudmlyb25tZW50X2NvbnRyYWN0X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJlbnZpcm9ubWVudF9kaWdlc3QiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXZpZGVuY2VfaWRlbnRpdHlfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsImV2aWRlbmNlX21hbmlmZXN0cyI6eyJhdXRob3JpemF0aW9uIjp7ImFkbWlzc2lvbl9hcnRpZmFjdF9zaGEyNTYiOiJkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkIiwiYWRtaXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA2IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOCIsImV4ZWN1dGlvbl9hdXRob3JpdHlfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImdvdmVybmVkX2F1dGhvcml6YXRpb25faWRfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsIm1hbmlmZXN0X3NoYTI1NiI6ImYwY2ExOWE2YjNlYWJlNTk0ZGJjOTA2ODljMmY3NGNiZTVlODJkNGQ5NDdkYjI5YTVkMDdiMTY0MWU4OTYxY2YiLCJwZXJtaXRfY2hhaW5fc2hhMjU2IjoiNTA0OGZlOTQ1ODgyZDI4MDI2MDA4ZDdlOTEzN2FkMDE2ZmRkMDFhZWFmNTg4NDgxZmI1YmQwZjI0MmE1MDA0MyIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tYXV0aG9yaXphdGlvbi1ldmlkZW5jZS92MSJ9LCJlZmZlY3QiOnsiY29uZmlybWVkIjowLCJlZmZlY3RfY29udHJhY3Rfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsIm1hbmlmZXN0X3NoYTI1NiI6IjdlMTJkY2E1YzQ0Y2Y5OThhNDY5MzYyYjg2MmU4MTZhN2QyYzg1NDE2M2Y2M2U4ZGU2MWZiNzllOTViYTgwMDciLCJyZWNvcmRzIjpbXSwicmVxdWlyZWQiOjAsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZWZmZWN0LWV2aWRlbmNlL3YxIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSJ9LCJpZGVudGl0eSI6eyJjb25maXJtZWQiOjAsImlkZW50aXR5X2NvbnRyYWN0X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJtYW5pZmVzdF9zaGEyNTYiOiJkM2E3ZWFjMzQyN2Q3NmY2YmMzNjAzMDczODYwOTExOWYwN2UwZDkxYTZkMzU4YWJjZTViNmYwZDZkZjc4NjQ1IiwicmVxdWlyZWQiOjAsInJlc3VsdHMiOltdLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWlkZW50aXR5LWV2aWRlbmNlL3YxIiwid29ya2Zsb3dfY29udHJhY3Rfc2hhMjU2IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSJ9LCJwb2xpY3kiOnsiYWRtaXNzaW9uX3BvbGljeV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZWZmZWN0X2NvbnRyYWN0X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJlbnZpcm9ubWVudF9jb250cmFjdF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwiZW52aXJvbm1lbnRfZGlnZXN0IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImdvdmVybmVkX3BvbGljeV9jb250cmFjdF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwiZ292ZXJuZWRfcnVudGltZV9pbnB1dHNfZGlnZXN0IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsImlkZW50aXR5X2NvbnRyYWN0X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJtYW5pZmVzdF9zaGEyNTYiOiI0Zjk4OGQwMTViY2Q3Y2Q3ZTA1YmEwNjYzZDg5ZjBhOTY4ZjBkOGFjZTk5YjA5MGViYWJlZTUyYTFjNTUwNDIxIiwibWluaW11bV9lZmZlY3RfdGllciI6MSwicnVudGltZV9lbnZpcm9ubWVudF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1wb2xpY3ktZXZpZGVuY2UvdjEifSwicG9zdGNvbmRpdGlvbiI6eyJjb25maXJtZWQiOjAsIm1hbmlmZXN0X3NoYTI1NiI6IjUyZjA5ZDVkNjM5YjFjMzgzZjM3Nzk2M2U0ODdjYjg5ZDg5NDE3ODU3ZTQ0ZGE3ZTNmMjNlNTViZTc1MWU3ZjQiLCJyZWNvcmRzIjpbXSwicmVxdWlyZWQiOjAsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tcG9zdGNvbmRpdGlvbi1ldmlkZW5jZS92MSIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifX0sImV2aWRlbmNlX3J1bm5lcl9zaWduZXJfc2hhMjU2IjoiNTY0NzVhYTc1NDYzNDc0YzAyODVkZjVkYmYyYmNhYjczZGE2NTEzNTg4MzllOWI3NzQ4MWIyZWFiMTA3NzA4YyIsImV4ZWN1dGlvbl9hdXRob3JpdHlfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDgiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJleGVjdXRpb25fYXV0aG9yaXR5X3NpZ25lcl9zaGEyNTYiOiIyNGY2ZWQ2YWNiZmUxMDA5YzAzMGQ3Y2E1NjdjMzNjYTQ4MzA5MTE0OTgyMzZiNTU2MWE2YzgyYWJlYzVkZTI4IiwiZXhlY3V0aW9uX291dGNvbWUiOnsiY29tcGVuc2F0aW9uX2FjdGlvbnMiOjAsImV2aWRlbmNlX2NsYXNzZXMiOlsiYXV0aG9yaXphdGlvbiJdLCJleGVjdXRpb25fY29tcGxldGVkIjpmYWxzZSwiZXh0ZXJuYWxfbmV0d29ya19jYWxscyI6Im9ic2VydmVkIiwibWFuYWdlZF9yZXN1bHRfbG9zc19ldmlkZW5jZV9zaGEyNTYiOiJmMjJmMjcwNDRlZjMxNWU5MzlhYmFkZjZiNjcyNWZjZjJiOTJmMmEyODAzOTQwNzU4MGUwZjJmN2UyMzA1NDk0IiwibW9kZWxfY2FsbHMiOjAsIm91dGNvbWUiOiJIQUxURUQiLCJwYXNzZWRfY29udHJhY3RzIjp7ImF1dGhvcml6YXRpb24iOjEsImVmZmVjdCI6MCwiaWRlbnRpdHkiOjAsInBvc3Rjb25kaXRpb24iOjB9LCJwb3N0Y29uZGl0aW9uX2V2aWRlbmNlIjpbXSwicHJvZHVjdGlvbl9lbGlnaWJsZSI6ZmFsc2UsInByb2ZpbGUiOiJzdGFuZGFyZCIsInF1YWxpZmljYXRpb25fZXZpZGVuY2Vfb25seSI6ZmFsc2UsInJlcXVpcmVkX2NvbnRyYWN0cyI6eyJhdXRob3JpemF0aW9uIjoxLCJlZmZlY3QiOjAsImlkZW50aXR5IjowLCJwb3N0Y29uZGl0aW9uIjowfSwidmVyc2lvbiI6Im9wZW5hZGFwdC5leGVjdXRpb24tb3V0Y29tZS92MSIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEifSwiZXhlY3V0aW9uX291dGNvbWVfc2hhMjU2IjoiY2MzMGNiNGJlMzA1YmM1NzI1NzE1OGVjOThkMjUwYzA4MDgyMjAyOGI1ZTZiYTA5OTQ1N2ViYTQ3NTgxY2MzYyIsImV4ZWN1dGlvbl9wdXJwb3NlIjoicHJvZHVjdGlvbiIsImZpbmFsX2F1dGhvcml0eV9zZXF1ZW5jZSI6MCwiZmluYWxfcnVudGltZV9kZWxpdmVyeV9zZXF1ZW5jZSI6OSwiZmxvd19ydW5faWRfc2hhMjU2IjoiMTFlNTk0ZjQ4MTk1OGMxMGUzMDE1ZDBiZjA0NDdhMjJmMDY4YThhNjQ3ZjQ3NWRmMTVjZTJjN2FiNGI4ZjNmMSIsImlkZW50aXR5X2NvbnRyYWN0X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJpc3N1ZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAzWiIsIm1hbmFnZWRfcmVzdWx0X2xvc3MiOnsiYWN0dWF0aW9uX3JlcGxheV9hdXRob3JpemVkIjpmYWxzZSwiYXV0aGVudGljYXRlZF9ydW5uZXJfaWRfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsImF1dGhlbnRpY2F0ZWRfc2Vzc2lvbl9pZF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwiYmxpbmRfcmV0cnlfYXV0aG9yaXplZCI6ZmFsc2UsImNoaWxkX3JlcG9ydF9yZXRhaW5lZCI6ZmFsc2UsImNoaWxkX3N0YXJ0X2V2aWRlbmNlX3NoYTI1NiI6ImVjNjkwNzkxODg2YWUyY2UwMGM0ZTUxMTU0YzNmMTIwZWE0NDE5ZWQyNjUxZTA3M2RiNTcyNDkxOGEzYjA4YzYiLCJjaGlsZF9zdGFydGVkIjp0cnVlLCJjaGlsZF9zdGFydGVkX2F0IjoiMjAyNi0wOC0xOFQxMjowMDowMFoiLCJkZWxpdmVyeV9yZXN1bHRfbG9zc19jbG9zdXJlX2FydGlmYWN0X3NoYTI1NiI6ImIyZDkyZjMyNDhmNGRhNjFlZGIwMjdjZjU5ZGE1Mzk1ZmZjNDE4ZWFkNmQ0ODVjMjlkZjZjMzViYzIxYTkzMGQiLCJkZWxpdmVyeV9zdGF0ZSI6IkNMT1NFRF9VTlJFU09MVkVEX1JFU1VMVF9MT1NTIiwiZGlzcGF0Y2hfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDkiLCJkaXNwYXRjaF9zZXNzaW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDEwIiwiZWZmZWN0X2Fic2VuY2VfY2xhaW1lZCI6ZmFsc2UsImV2aWRlbmNlX3NoYTI1NiI6ImYyMmYyNzA0NGVmMzE1ZTkzOWFiYWRmNmI2NzI1ZmNmMmI5MmYyYTI4MDM5NDA3NTgwZTBmMmY3ZTIzMDU0OTQiLCJleGVjdXRpb25fYXV0aG9yaXR5X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA4IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaWduZXJfc2hhMjU2IjoiMjRmNmVkNmFjYmZlMTAwOWMwMzBkN2NhNTY3YzMzY2E0ODMwOTExNDk4MjM2YjU1NjFhNmM4MmFiZWM1ZGUyOCIsImZsb3dfcnVuX2lkX3NoYTI1NiI6IjExZTU5NGY0ODE5NThjMTBlMzAxNWQwYmYwNDQ3YTIyZjA2OGE4YTY0N2Y0NzVkZjE1Y2UyYzdhYjRiOGYzZjEiLCJpZGVtcG90ZW5jeV9rZXlfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsImxvc3NfY29kZSI6InJlcG9ydF9taXNzaW5nIiwibWFuYWdlZF9kaXNwYXRjaF9iaW5kaW5nX3NoYTI1NiI6InNoYTI1NjpjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwibm90X3JlY2VpdmVkX2NsYWltZWQiOmZhbHNlLCJvYnNlcnZlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDJaIiwicGVuZGluZ19hY3Rpb25fcmVxdWVzdF9zaGEyNTYiOm51bGwsInBlbmRpbmdfcGVybWl0X2FydGlmYWN0X3NoYTI1NiI6bnVsbCwicmVwb3J0X3Byb3ZlbmFuY2UiOiJvdXRlcl9ydW5uZXJfcmVjb3ZlcnkiLCJydW5faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDEiLCJydW5fcmVxdWVzdF9zaGEyNTYiOiJjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjIiwicnVuX3N0b3JlX2lkZW50aXR5X3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5tYW5hZ2VkLXJlc3VsdC1sb3NzL3YxIn0sInBlbmRpbmdfcGVybWl0X2NvdW50IjowLCJwZXJtaXRfY2hhaW4iOnsiZW50cmllcyI6W3siZGVsaXZlcnlfcmVjZWlwdF9hcnRpZmFjdCI6eyJwYXlsb2FkIjp7ImF1dGhlbnRpY2F0ZWRfcnVubmVyX2lkX3NoYTI1NiI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJhdXRoZW50aWNhdGVkX3Nlc3Npb25faWRfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsImRlbGl2ZXJlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDFaIiwiZXhlY3V0aW9uX2F1dGhvcml0eV9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwOCIsIm9uZV91c2VfY2xhaW1faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMTAiLCJwZXJtaXRfYXJ0aWZhY3Rfc2hhMjU2IjoiOTcyYTgyYWY0NTZkYTU0MmJhYzc4NDYwMTg4OTY2ODg5MWQ4YjdjY2QyNDI5MDQ4MTZiMzI5MmUxNTdlNTI4OSIsInBlcm1pdF9pZCI6InBlcm1pdDoxIiwicnVudGltZV9kZWxpdmVyeV9zZXF1ZW5jZSI6OSwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1yZWNlaXB0LXBheWxvYWQvdjIifSwicGF5bG9hZF9zaGEyNTYiOiI4YThmNmQ4ODc1MGNiYjZiM2JkNjYyMDkzYWQyOWUyYmMyMGM2YWI2OTkxZDcwZTU4ODY5MWM4YjNhYjY2MmI5Iiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1yZWNlaXB0LWFydGlmYWN0L3YyIiwic2lnbmF0dXJlIjoiQU9LcUNnUzFzMFhhLWl5RTk2Vi15bFB6UWN2MnV2T3N1eWdIenZ1MlJ5VjdGTHNIRl9MVmZxeXg0dTJwdW1sRWwwWWs1WXU3MEpWVWtzWnBhVXBERHciLCJzaWduZXIiOnsiYWxnb3JpdGhtIjoiZWQyNTUxOSIsImtleV9pZCI6ImRlbGl2ZXJ5LWF1dGhvcml0eS1lZDI1NTE5LTI0ZjZlZDZhY2JmZTEwMDkiLCJwdWJsaWNfa2V5IjoiS2F5NjRVRzh5dkN5TGhxVTAwMEx4elllVW0wTC9oTElsNVM4a3lLV2JkYz0ifX0sImRlbGl2ZXJ5X3JlY2VpcHRfYXJ0aWZhY3Rfc2hhMjU2IjoiYzAwYTFiYTcwMTVmM2NiZTA1YTc2YWVhYmZmNjE5ZDc5M2U3Mzc1YTMxMGUxOTVmY2JiZDJkMjk0OGYyYjIxNCIsInBlcm1pdF9hcnRpZmFjdCI6eyJwYXlsb2FkIjp7ImFjdGlvbl9yZXF1ZXN0X3NoYTI1NiI6ImRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQiLCJhZG1pc3Npb25fYXJ0aWZhY3Rfc2hhMjU2IjoiZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZCIsImF1dGhvcml0eV9zZXF1ZW5jZSI6MCwiZW52aXJvbm1lbnRfZGlnZXN0IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImV2aWRlbmNlX2lkZW50aXR5X3NoYTI1NiI6ImVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWUiLCJleGVjdXRpb25fYXV0aG9yaXR5X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA4IiwiZXhlY3V0aW9uX2F1dGhvcml0eV9zaGEyNTYiOiJhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhIiwiZmxvd19ydW5faWRfc2hhMjU2IjoiMTFlNTk0ZjQ4MTk1OGMxMGUzMDE1ZDBiZjA0NDdhMjJmMDY4YThhNjQ3ZjQ3NWRmMTVjZTJjN2FiNGI4ZjNmMSIsImlucHV0X2VkZ2Vfc2VxdWVuY2UiOjEsImlzc3VlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDBaIiwicGVybWl0X2lkIjoicGVybWl0OjEiLCJxdWFsaWZpY2F0aW9uX3NpZ25lcl9yZWdpc3RyeV9jaGVja2VkX2F0IjoiMjAyNi0wOC0xOFQxMTo1OTozMFoiLCJxdWFsaWZpY2F0aW9uX3NpZ25lcl9yZWdpc3RyeV9leHBpcmVzX2F0IjoiMjAyNi0wOC0yMFQxMTowMDowMFoiLCJxdWFsaWZpY2F0aW9uX3NpZ25lcl9yZWdpc3RyeV9yZXZpc2lvbiI6NywicXVhbGlmaWNhdGlvbl9zaWduZXJfcmVnaXN0cnlfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsInJ1bl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwMSIsInJ1bl9yZXF1ZXN0X3NoYTI1NiI6ImNjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2MiLCJzY2hlbWFfdmVyc2lvbiI6Im9wZW5hZGFwdC5wcm9kdWN0aW9uLWRlbGl2ZXJ5LXBlcm1pdC1wYXlsb2FkL3YyIn0sInBheWxvYWRfc2hhMjU2IjoiYzg3ZjU3NTFhYTliMjc5Y2NlMjNhYTE3OGFmZjk1NmUxOWY2OTBmY2QyZjlmNzBlMGQ5OTk3ODJhNjkwZDZiOCIsInNjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnByb2R1Y3Rpb24tZGVsaXZlcnktcGVybWl0LWFydGlmYWN0L3YyIiwic2lnbmF0dXJlIjoiMEJ5SGdxRHhRWnJuZ0xJRi02dFpPcTlsWGFtY0FRQzBkb1VUbmVLTlBlUy1TeW9PYlF5T2tBdVBGSzVQWWNOek9iWnhnc2dBTGRXYUlfc2FVQ3BsQmciLCJzaWduZXIiOnsiYWxnb3JpdGhtIjoiZWQyNTUxOSIsImtleV9pZCI6ImRlbGl2ZXJ5LWF1dGhvcml0eS1lZDI1NTE5LTI0ZjZlZDZhY2JmZTEwMDkiLCJwdWJsaWNfa2V5IjoiS2F5NjRVRzh5dkN5TGhxVTAwMEx4elllVW0wTC9oTElsNVM4a3lLV2JkYz0ifX0sInBlcm1pdF9hcnRpZmFjdF9zaGEyNTYiOiI5NzJhODJhZjQ1NmRhNTQyYmFjNzg0NjAxODg5NjY4ODkxZDhiN2NjZDI0MjkwNDgxNmIzMjkyZTE1N2U1Mjg5Iiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1wZXJtaXQtY2hhaW4tZW50cnkvdjIifV0sInBlcm1pdF9jaGFpbl9zaGEyNTYiOiI1MDQ4ZmU5NDU4ODJkMjgwMjYwMDhkN2U5MTM3YWQwMTZmZGQwMWFlYWY1ODg0ODFmYjViZDBmMjQyYTUwMDQzIiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1kZWxpdmVyeS1wZXJtaXQtY2hhaW4vdjIifSwicGVybWl0X2NvdW50IjoxLCJxdWFsaWZpY2F0aW9uX3NpZ25lcl9yZWdpc3RyeV9yZXZpc2lvbiI6NywicXVhbGlmaWNhdGlvbl9zaWduZXJfcmVnaXN0cnlfc2hhMjU2IjoiZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZSIsInJ1bl9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwMSIsInJ1bl9yZWNlaXB0Ijp7ImF1dGhvcml6YXRpb25fY29uZmlybWVkIjoxLCJhdXRob3JpemF0aW9uX3JlcXVpcmVkIjoxLCJidW5kbGVfZGlnZXN0IjoiYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYSIsImR1cmF0aW9uX21zIjowLCJlZmZlY3RfdGllcl9yZWFjaGVkIjoibm9uZSIsImVmZmVjdHNfY29uZmlybWVkIjowLCJlZmZlY3RzX3JlcXVpcmVkIjowLCJlc3RfY29zdF9taWNyb3VzZCI6MCwiZXZpZGVuY2VfY2xhc3NlcyI6WyJhdXRob3JpemF0aW9uIl0sImV4dGVybmFsX25ldHdvcmtfY2FsbHMiOiJvYnNlcnZlZCIsImdlbmVyYXRlZF9hdCI6IjIwMjYtMDgtMThUMTI6MDA6MDBaIiwiaGVhbHMiOjAsImlkZW50aXR5X2FwcGxpY2FibGUiOjAsImlkZW50aXR5X2FybWVkIjowLCJpZGVudGl0eV9jb25maXJtZWQiOjAsImlkZW50aXR5X3JlcXVpcmVkIjowLCJtYW5hZ2VkX3Jlc3VsdF9sb3NzX2V2aWRlbmNlX3NoYTI1NiI6ImYyMmYyNzA0NGVmMzE1ZTkzOWFiYWRmNmI2NzI1ZmNmMmI5MmYyYTI4MDM5NDA3NTgwZTBmMmY3ZTIzMDU0OTQiLCJtb2RlbF9jYWxscyI6MCwib3V0Y29tZSI6IkhBTFRFRCIsIm92ZXJfaGFsdF9jb3VudCI6MCwicG9zdGNvbmRpdGlvbnNfY29uZmlybWVkIjowLCJwb3N0Y29uZGl0aW9uc19yZXF1aXJlZCI6MCwicHJvZHVjdGlvbl9lbGlnaWJsZSI6ZmFsc2UsInByb2ZpbGUiOiJzdGFuZGFyZCIsInByb3ZlbmFuY2UiOiJwcm9kdWN0aW9uIiwicmVjZWlwdF9idWlsZGVyX3ZlcnNpb24iOiIxLjIuMyIsInJ1bmdfaGlzdG9ncmFtIjp7fSwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi1ydW4tcmVjZWlwdC92MSIsInNvdXJjZV9yZWNlaXB0X2RpZ2VzdCI6ImJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIiLCJzb3VyY2VfcmVjZWlwdF9zaGEyNTYiOiJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiIiwic291cmNlX3NjaGVtYV92ZXJzaW9uIjoib3BlbmFkYXB0LnJ1bi1yZXBvcnQvdjEiLCJzdGVwc19vayI6MCwic3RlcHNfdG90YWwiOjEsInN1YnN0cmF0ZSI6IndlYiIsInRyYW5zYWN0aW9uX291dGNvbWUiOiJSRUNPTkNJTElBVElPTl9SRVFVSVJFRCJ9LCJydW5fcmVjZWlwdF9zaGEyNTYiOiJjOWRkNjNkNWY1MDEzNGU1NDZmNzJkMmQ4ZTcyMjJkMGEwNDM1ZWIwMmVkY2M4NWVjYTZjNzY5MjMwNWRjZTMwIiwicnVuX3JlcG9ydF9vYmplY3Rfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsInJ1bl9yZXBvcnRfb2JqZWN0X3ZlcnNpb24iOiJ2ZXJzaW9uOm1hbmFnZWQtcmVzdWx0LWxvc3M6MSIsInJ1bl9yZXBvcnRfc2hhMjU2IjoiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYiIsInJ1bnRpbWVfZW52aXJvbm1lbnRfc2hhMjU2IjoiY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjYyIsInJ1bnRpbWVfc3Vic3RyYXRlIjoid2ViIiwicnVudGltZV92YWxpZGF0aW9uX2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDA1Iiwic2NoZW1hX3ZlcnNpb24iOiJvcGVuYWRhcHQucHJvZHVjdGlvbi10ZXJtaW5hbC12ZXJpZmljYXRpb24vdjIiLCJ0ZW5hbnRfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDIiLCJ0ZXJtaW5hbF9zZXF1ZW5jZSI6MSwidmVyaWZpZWRfYXQiOiIyMDI2LTA4LTE4VDEyOjAwOjAyWiIsIndvcmtmbG93X2NvbnRyYWN0X3NoYTI1NiI6ImFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWEiLCJ3b3JrZmxvd19pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwMyIsIndvcmtmbG93X3ZlcnNpb25faWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDQifSwic2lnbmF0dXJlIjoiU212VGw5N1MwNm9pb2NNMGNza0tIQ3ZnV1Q5T1dDN3V4NkN4WXljQ2hyMjFjY3B2Y3ExT3R3MUh5V1ZJMGhubTNDRExJcWgtVmN2cTh4TmdPTm40QkEiLCJzaWduZXIiOnsiYWxnb3JpdGhtIjoiZWQyNTUxOSIsImtleV9pZCI6ImV2aWRlbmNlLXJ1bm5lci1lZDI1NTE5LTU2NDc1YWE3NTQ2MzQ3NGMiLCJwdWJsaWNfa2V5IjoiQTZFSHYvUE9FTDRkY04wWTUwdkFtV2ZrMWpDYnBRMWZIZHlHWkJKVk1iZz0ifX0=", + "terminal_verification_artifact_sha256": "eea2765e1d7f414e8299125eb3187b62c653f320ccaf08f45dc7bf572e2f5ae2", "uncertain_delivery": false }, "effect_state": null, diff --git a/tests/test_terminal_verification_v2.py b/tests/test_terminal_verification_v2.py index dd9b23ed..24582b6f 100644 --- a/tests/test_terminal_verification_v2.py +++ b/tests/test_terminal_verification_v2.py @@ -27,6 +27,7 @@ from openadapt_flow.qualification_admission_v2 import canonical_json from openadapt_flow.receipt import RunReceipt from openadapt_flow.runner.hosted_adapter import ( + HostedTerminalEvent, ManagedChildStartEvidence, ProductionDeliveryResultLossClosureRequest, ProductionDeliveryResultLossClosureResult, @@ -1877,11 +1878,18 @@ def test_non_success_terminal_cross_language_vectors_are_exact() -> None: if envelope.payload.managed_result_loss is not None else None ) == vector["managed_result_loss"] - callback = vector["callback"] - assert callback["run_id"] == payload.run_id - assert callback["outcome"] == payload.run_receipt.transaction_outcome - assert callback["report_sha256"] == payload.run_report_sha256 - assert callback["artifact_bytes_source"] == "envelope_canonical_base64" + callback = HostedTerminalEvent.model_validate(vector["callback"]) + assert callback.run_id == payload.run_id + assert callback.outcome == payload.run_receipt.transaction_outcome + assert callback.report_sha256 == payload.run_report_sha256 + assert callback.uncertain_delivery == (payload.pending_permit_count == 1) + assert ( + callback.terminal_verification_artifact_bytes_base64 + == (vector["envelope_canonical_base64"]) + ) + assert callback.terminal_verification_artifact_sha256 == ( + envelope.artifact_sha256() + ) def test_managed_result_loss_closure_cross_language_vector_is_exact() -> None: