From 0c522565efc042faaaa30ee76a6570ecb02af262 Mon Sep 17 00:00:00 2001 From: James Ross Date: Wed, 21 Oct 2026 07:16:21 -0700 Subject: [PATCH] feat(provider): judge authored effect programs in the lowerer and verifier Echo's runtime was the only component that judged an authored effect program. The provider lowerer and verifier now each judge one themselves, sharing no code with the runtime or each other: - binding to the program's own Core, Target IR and exports; - the pinned lawpack, adapter, target profile and intrinsic catalog that authorize each effect; - each effect's runtime ABI, write class and failure contract through the intrinsic-scoped failure table, with one declared obstruction per arm; - node-for-node Core and Target IR correspondence; - the body's types, proven ranges (input constraints dominate, let caps carry, a require proves nothing) and declared budget under each component's own cost model. effect_publication::encode_effect_publication runs the lowerer's judgment before serializing and refuses unsafe programs with UnsupportedProgram; effect_publication::judge_effect_program exposes it. The verifier's effect_package::verify_effect_package also binds every identity the package claims, its operation, output and footprint contract to the program it carries. warp-core generates and pins a verdict corpus from its own fixture builders and asserts the runtime's verdict on each entry; the lowerer and verifier reach the same verdicts on the same bytes. The providers' cost models are stricter than the runtime's meter, so the captured node-atom read's 1 MiB step budget and the synthetic wire control's one-step budget are refused before installation; the wire control now declares 1,024 steps and the retained publication controls are re-emitted. Both components' Core type readers now accept an unsigned width named directly in a type table ({ kind: "U32" }), as Core and the runtime do. --- .ban-nondeterminism-allowlist | 1 + CHANGELOG.md | 13 + crates/echo-edict-provider-lowerer/README.md | 25 +- .../src/effect_publication.rs | 21 + .../src/executable_operation.rs | 1 + .../executable_operation/effect_program.rs | 966 +++++++++++++++++ .../executable_operation/source_functions.rs | 27 +- .../source_functions/effect_intent.rs | 264 +++++ .../tests/effect_program_judgment.rs | 176 ++++ .../fixtures/current-effect-wire/README.md | 4 + .../fixtures/current-effect-wire/bundle.hex | 2 +- .../tests/fixtures/effect-programs/README.md | 14 + .../effect-programs/ensure-node-control.hex | 1 + .../failure-mapping-duplicate.hex | 1 + .../failure-mapping-tag-spelled.hex | 1 + .../failure-mapping-unknown.hex | 1 + .../effect-programs/forged-node-order.hex | 1 + .../fixtures/effect-programs/over-budget.hex | 1 + .../effect-programs/read-captured-budget.hex | 1 + .../fixtures/effect-programs/read-control.hex | 1 + .../effect-programs/slice-other-operand.hex | 1 + .../fixtures/effect-programs/slice-proven.hex | 1 + .../effect-programs/slice-require-only.hex | 1 + .../effect-programs/slice-unproven.hex | 1 + .../undeclared-obstruction.hex | 1 + .../fixtures/effect-programs/verdicts.txt | 14 + .../wrong-intrinsic-input-type.hex | 1 + crates/echo-edict-provider-verifier/README.md | 4 + .../src/effect_package.rs | 131 +++ .../src/executable_operation.rs | 1 + .../executable_operation/effect_program.rs | 982 ++++++++++++++++++ .../executable_operation/source_functions.rs | 63 +- .../source_functions/effect_intent.rs | 276 +++++ .../source_functions/types.rs | 7 + .../echo-edict-provider-verifier/src/lib.rs | 1 + .../tests/effect_program_judgment.rs | 152 +++ .../current-effect-publication/package.hex | 2 +- .../tests/edict_effect_package_tests.rs | 4 + .../abi_conformance.rs | 2 +- .../proven_ranges.rs | 20 +- .../provider_corpus.rs | 384 +++++++ .../current-effect-publication/package.hex | 2 +- docs/topics/GeneratedRules.md | 18 + 43 files changed, 3540 insertions(+), 51 deletions(-) create mode 100644 crates/echo-edict-provider-lowerer/src/executable_operation/effect_program.rs create mode 100644 crates/echo-edict-provider-lowerer/src/executable_operation/source_functions/effect_intent.rs create mode 100644 crates/echo-edict-provider-lowerer/tests/effect_program_judgment.rs create mode 100644 crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/README.md create mode 100644 crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/ensure-node-control.hex create mode 100644 crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/failure-mapping-duplicate.hex create mode 100644 crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/failure-mapping-tag-spelled.hex create mode 100644 crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/failure-mapping-unknown.hex create mode 100644 crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/forged-node-order.hex create mode 100644 crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/over-budget.hex create mode 100644 crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/read-captured-budget.hex create mode 100644 crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/read-control.hex create mode 100644 crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/slice-other-operand.hex create mode 100644 crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/slice-proven.hex create mode 100644 crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/slice-require-only.hex create mode 100644 crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/slice-unproven.hex create mode 100644 crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/undeclared-obstruction.hex create mode 100644 crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/verdicts.txt create mode 100644 crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/wrong-intrinsic-input-type.hex create mode 100644 crates/echo-edict-provider-verifier/src/effect_package.rs create mode 100644 crates/echo-edict-provider-verifier/src/executable_operation/effect_program.rs create mode 100644 crates/echo-edict-provider-verifier/src/executable_operation/source_functions/effect_intent.rs create mode 100644 crates/echo-edict-provider-verifier/tests/effect_program_judgment.rs create mode 100644 crates/warp-core/tests/edict_effect_package_tests/provider_corpus.rs diff --git a/.ban-nondeterminism-allowlist b/.ban-nondeterminism-allowlist index a08c0312..c41b867f 100644 --- a/.ban-nondeterminism-allowlist +++ b/.ban-nondeterminism-allowlist @@ -51,3 +51,4 @@ time-instant crates/warp-core/benches/support/fixtures/think_append.rs benchmark hand-hashed-table crates/warp-core/src/snapshot.rs state-root membership accelerator in private mod membership, whose only operations are begin and insert (no iterator, slice accessor or lookup, enforced by the compiler); exact key equality, no seed; its contents, capacity, probe counts, generation and fallback cannot affect the state root, which is independent of scratch history (tested against the ordered reference). std-fs crates/warp-core/tests/edict_effect_admission_tests/installation.rs owned filesystem WAL fixture directory creation and cleanup only; paths never enter program, policy, installation or receipt identities. +std-fs crates/warp-core/tests/edict_effect_package_tests/provider_corpus.rs explicit ignored provider effect-corpus fixture regeneration only. diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e090e07..33f9fec0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -535,6 +535,19 @@ ### Added +- Echo's provider lowerer and verifier judge authored effect programs + themselves before publication and installation: artifact binding, adapter + authorization, each effect's intrinsic ABI and version-scoped failure + contract, declared obstructions, Core and Target IR correspondence, and + typing, proven ranges and budget under each component's own cost model. + `effect_publication::judge_effect_program` and + `encode_effect_publication` refuse unsafe programs with + `UnsupportedProgram`; `effect_package::verify_effect_package` also refuses a + package whose identities name another program. A retained corpus generated + by warp-core pins the verdict all three judgments reach. +- The lowerer's and verifier's Core type readers accept an unsigned width named + directly in a type table (`{ kind: "U32" }`), as Core and the runtime do. + - Runtime-owned installation retains exact policy and package evidence in the current WAL catalog and restores all program kinds through one fresh-host recovery path. Conflicts and failed WAL appends publish no registry entry. diff --git a/crates/echo-edict-provider-lowerer/README.md b/crates/echo-edict-provider-lowerer/README.md index b358031d..0ff9eac7 100644 --- a/crates/echo-edict-provider-lowerer/README.md +++ b/crates/echo-edict-provider-lowerer/README.md @@ -206,10 +206,11 @@ Those remain explicit Echo runtime crossings. ## Current effect proposal serialization The native Rust API `effect_publication::encode_effect_publication` serializes -untrusted proposals using the current `echo.operation-package/v1` and +proposals using the current `echo.operation-package/v1` and `echo.operation-program/v1` effect kind. It preserves the compiler bundle's -exact bytes, derives embedded Core/Target-IR/exports identities, carries explicit -limits and graph/footprint data, and requires a declared obstruction coordinate. +exact bytes, derives embedded Core/Target-IR/exports identities, and carries +explicit limits and graph/footprint data. The program's own exports declare +every obstruction it can return. Its requested `authority_profile_identity` is derived only from the configuration's required `authorityProfile` label, by the same label digest fixed operations use; no caller supplies it. @@ -217,10 +218,18 @@ It uses the current `steps`, `read_bytes`, and `write_bytes` budget fields and retains the actual lawpack inside the compiled bundle, without a duplicate outer lawpack identity. +Before serializing, publication runs the lowerer's own effect-program +judgment, also available as `effect_publication::judge_effect_program`, and +refuses an unsafe program with `UnsupportedProgram`. The judgment establishes +the program's binding to its own artifacts, the pinned lawpack, adapter, +profile and catalog that authorize each effect, each effect's intrinsic ABI and +failure contract, declared obstructions, Core and Target IR correspondence, and +the body's types, proven ranges and declared budget. It does not judge +graph-law semantics or grant authority. The verifier judges the same programs +independently in `effect_package::verify_effect_package`. + The witness uses synthetic crate-local inputs and the current runtime decoder as a separate native test oracle. Kernel dependencies and their trusted-host -features are dev dependencies only. The factory does not verify compiler -correspondence, graph-law semantics or authority. It is not yet called by the -public lowerer, and it does not change the frozen WIT interface or enable -installed effect execution. Producer integration and independent verification -remain unfinished. +features are dev dependencies only. The public lowerer's component interface +does not yet produce effect packages, and publication does not change the frozen +WIT interface or enable installed effect execution. diff --git a/crates/echo-edict-provider-lowerer/src/effect_publication.rs b/crates/echo-edict-provider-lowerer/src/effect_publication.rs index 7bfaa895..27d84614 100644 --- a/crates/echo-edict-provider-lowerer/src/effect_publication.rs +++ b/crates/echo-edict-provider-lowerer/src/effect_publication.rs @@ -26,6 +26,9 @@ pub enum EffectPublicationError { InvalidConfiguration, /// A required coordinate is missing or unbounded. InvalidCoordinate, + /// The compiled effect program is unsafe or does not match its own + /// artifacts, intrinsic contracts or declared budget. + UnsupportedProgram, } impl std::fmt::Display for EffectPublicationError { @@ -34,11 +37,27 @@ impl std::fmt::Display for EffectPublicationError { Self::InvalidArtifact => "invalid effect publication artifact envelope", Self::InvalidConfiguration => "invalid effect publication configuration or limits", Self::InvalidCoordinate => "missing or unbounded effect publication coordinate", + Self::UnsupportedProgram => { + "the compiled effect program is outside the checked profile" + } }) } } impl std::error::Error for EffectPublicationError {} +/// Judges compiler-produced effect-program bytes without serializing them. +/// +/// The lowerer establishes artifact binding, adapter authorization, each +/// effect's intrinsic ABI and failure contract, Core/Target IR +/// correspondence, typing, proven ranges and the declared budget itself. +/// # Errors +/// [`EffectPublicationError::UnsupportedProgram`] for any program outside +/// that judgment. +pub fn judge_effect_program(compiled_program: &[u8]) -> Result<(), EffectPublicationError> { + crate::executable_operation::effect_program::judge(compiled_program) + .map_err(|()| EffectPublicationError::UnsupportedProgram) +} + /// Serializes the single current operation-package and effect-program formats. /// /// This constructs an untrusted proposal. Callers must independently verify @@ -190,6 +209,8 @@ pub fn encode_effect_publication( } let reads = number(field(budget, "readBytes", C)?)?; let writes = number(field(budget, "writeBytes", C)?)?; + // The program is judged only once its envelope and configuration are. + judge_effect_program(input.compiler_program)?; let mut footprint = blake3::Hasher::new(); footprint.update(b"echo:operation-footprint-law:v1\0"); footprint.update(law); diff --git a/crates/echo-edict-provider-lowerer/src/executable_operation.rs b/crates/echo-edict-provider-lowerer/src/executable_operation.rs index 8bacc360..b037e726 100644 --- a/crates/echo-edict-provider-lowerer/src/executable_operation.rs +++ b/crates/echo-edict-provider-lowerer/src/executable_operation.rs @@ -3,6 +3,7 @@ //! Generic data-only lowering into Echo's bounded executable-operation profile. mod bounded_read; +pub(crate) mod effect_program; mod effect_resources; mod source_functions; diff --git a/crates/echo-edict-provider-lowerer/src/executable_operation/effect_program.rs b/crates/echo-edict-provider-lowerer/src/executable_operation/effect_program.rs new file mode 100644 index 00000000..4b8a9ca6 --- /dev/null +++ b/crates/echo-edict-provider-lowerer/src/executable_operation/effect_program.rs @@ -0,0 +1,966 @@ +// SPDX-License-Identifier: Apache-2.0 +// © James Ross Ω FLYING•ROBOTS +//! Lowerer-owned judgment of a compiler-produced authored effect program. +//! +//! The lowerer establishes, without consulting the runtime, that the program +//! is bound to its own artifacts, that each effect is authorized by its pinned +//! adapter and conforms to its intrinsic's runtime ABI, that every failure arm +//! names a declared obstruction through the version-scoped failure table, that +//! Core and Target IR agree node for node, and that the body is typed, proven +//! and within its declared budget. +use super::source_functions::{judge_effect_intent, EffectSite}; +use echo_edict_canonical::{ + decode_canonical_cbor_v1 as decode, digest_canonical_value_bytes_v1 as digest, + encode_canonical_cbor_v1 as encode, CanonicalValueV1 as Value, +}; +use std::collections::{BTreeMap, BTreeSet}; + +type Check = Result; + +const PROFILE_GRAPH_EFFECTS: &str = "continuum.profile.graph-effects/v1"; +const MAX_DEPTH: usize = 64; +const MAX_NODES: usize = 65_536; + +/// One failure of a read intrinsic: its catalog identifier, the runtime tag +/// Echo records, and its authority class. +struct FailureName { + catalog: &'static str, + runtime: &'static str, + authority: &'static str, +} + +const NODE_ATOM_READ_V1: [FailureName; 4] = [ + FailureName { + catalog: "atomMissing", + runtime: "echo.atom-missing/v1", + authority: "resourceFault", + }, + FailureName { + catalog: "atomRequired", + runtime: "echo.atom-required/v1", + authority: "integrityFault", + }, + FailureName { + catalog: "atomTypeMismatch", + runtime: "echo.atom-type-mismatch/v1", + authority: "integrityFault", + }, + FailureName { + catalog: "atomByteBoundExceeded", + runtime: "echo.atom-byte-bound-exceeded/v1", + authority: "integrityFault", + }, +]; + +/// The failure contract of each runtime intrinsic, keyed by its versioned +/// coordinate. An intrinsic outside this table is refused. +fn failures(intrinsic: &str) -> Option<&'static [FailureName]> { + match intrinsic { + "echo.dpo@1.node-atom-read" => Some(&NODE_ATOM_READ_V1), + "echo.dpo@1.ensure-node" + | "echo.dpo@1.create-node" + | "echo.dpo@1.replace-atom" + | "echo.dpo@1.ensure-edge" + | "echo.dpo@1.replace-edge" => Some(&[]), + _ => None, + } +} + +/// The effect kind, which is also the write class, of each intrinsic. +fn effect_kind(intrinsic: &str) -> Option<&'static str> { + Some(match intrinsic { + "echo.dpo@1.node-atom-read" => "read", + "echo.dpo@1.create-node" => "create", + "echo.dpo@1.ensure-node" | "echo.dpo@1.ensure-edge" => "ensure", + "echo.dpo@1.replace-atom" | "echo.dpo@1.replace-edge" => "replace", + _ => return None, + }) +} + +/// Judges compiler-produced effect-program bytes. +pub(crate) fn judge(compiled_program: &[u8]) -> Check<()> { + let bundle = decode(compiled_program).map_err(|_| ())?; + exact( + &bundle, + &[ + "schema", + "intent", + "core_artifact", + "target_ir_artifact", + "lawpack_exports_artifact", + "lowering_artifacts", + ], + )?; + equal_text( + &bundle, + "schema", + "echo.compiler-produced-effect-program/v1", + )?; + let intent_name = nonempty(get(&bundle, "intent")?)?; + let embedded = |key| decode(bytes(get(&bundle, key)?)?).map_err(|_| ()); + let module = embedded("core_artifact")?; + let target = embedded("target_ir_artifact")?; + let exports = embedded("lawpack_exports_artifact")?; + artifacts(&module, &target, &exports)?; + let intent = get(get(&module, "intents")?, intent_name)?; + let lowered = get(get(&target, "intents")?, intent_name)?; + binding(intent, lowered)?; + let sites = relation( + &module, + intent, + &target, + lowered, + &exports, + get(&bundle, "lowering_artifacts")?, + )?; + correspondence(intent, lowered)?; + judge_effect_intent(&module, &exports, intent, &sites) +} + +/// The three embedded artifacts and the Core pin the Target IR carries. +fn artifacts(module: &Value, target: &Value, exports: &Value) -> Check<()> { + exact( + target, + &[ + "domain", + "kind", + "intents", + "targetProfile", + "semanticClosure", + "sourceCoreCoordinate", + ], + )?; + equal_text(target, "domain", "echo.span-ir/v2")?; + equal_text(target, "kind", "orderedTargetIrArtifact")?; + exact( + exports, + &[ + "types", + "effects", + "constants", + "obstructions", + "pureFunctions", + "operationProfiles", + ], + )?; + list(get(exports, "types")?)?; + members(get(exports, "operationProfiles")?)?; + for key in ["effects", "constants", "obstructions", "pureFunctions"] { + list(get(exports, key)?)?; + } + let mut fields = vec![ + "apiVersion", + "coordinate", + "imports", + "types", + "intents", + "requiredCoreCapabilities", + ]; + if map_field(module, "functions").is_some() { + fields.push("functions"); + } + exact(module, &fields)?; + equal_text(module, "apiVersion", "edict.core/v1")?; + let coordinate = nonempty(get(module, "coordinate")?)?; + if members(get(module, "intents")?)?.is_empty() { + return Err(()); + } + list(get(module, "imports")?)?; + members(get(module, "types")?)?; + if let Some(functions) = map_field(module, "functions") { + if members(functions)?.is_empty() { + return Err(()); + } + } + for capability in list(get(module, "requiredCoreCapabilities")?)? { + string(capability)?; + } + equal_text(target, "sourceCoreCoordinate", coordinate)?; + let source = get(get(target, "semanticClosure")?, "sourceCore")?; + exact(source, &["id", "digest"])?; + equal_text(source, "id", coordinate)?; + pinned(source, identity("edict.core.module/v1", module)?) +} + +/// The selected intent and its lowered form agree on everything the runtime +/// executes besides the body's instructions. +fn binding(intent: &Value, lowered: &Value) -> Check<()> { + for key in ["inputConstraints", "coreEvaluationBudget"] { + if get(lowered, key)? != get(intent, key)? { + return Err(()); + } + } + equal_text( + lowered, + "operationProfile", + string(get(intent, "requiredOperationProfile")?)?, + )?; + if map_field(lowered, "basis") != map_field(intent, "basis") { + return Err(()); + } + let mut fields = vec![ + "input", + "output", + "requiredOperationProfile", + "inputConstraints", + "coreEvaluationBudget", + "body", + ]; + if map_field(intent, "basis").is_some() { + fields.push("basis"); + } + if map_field(intent, "optic").is_some() { + // Optic-scoped programs are outside the authored-effect route. + return Err(()); + } + exact(intent, &fields)?; + nonempty(get(intent, "input")?)?; + nonempty(get(intent, "output")?)?; + nonempty(get(intent, "requiredOperationProfile")?)?; + let budget = get(intent, "coreEvaluationBudget")?; + exact(budget, &["maxSteps", "maxAllocatedBytes", "maxOutputBytes"])?; + if number(get(budget, "maxSteps")?)? == 0 { + return Err(()); + } + let body = get(intent, "body")?; + exact(body, &["locals", "nodes", "result"])?; + if get(lowered, "result")? != get(body, "result")? { + return Err(()); + } + Ok(()) +} + +/// The pinned lawpack, adapter, target profile and intrinsic catalog that +/// authorize each effect node, and each effect's ABI and failure contract. +#[allow( + clippy::too_many_lines, + reason = "Each pin is checked where the next artifact relies on it." +)] +fn relation<'a>( + module: &'a Value, + intent: &'a Value, + target_artifact: &'a Value, + lowered: &'a Value, + exports: &'a Value, + lowering: &'a Value, +) -> Check> { + let steps = list(get(lowered, "steps")?)?; + if steps.is_empty() { + return if lowering == &Value::Null { + Ok(BTreeMap::new()) + } else { + Err(()) + }; + } + exact( + lowering, + &[ + "source_artifact", + "lawpack_artifact", + "adapter_artifact", + "target_profile_artifact", + "intrinsics_artifact", + ], + )?; + let embedded = |key| decode(bytes(get(lowering, key)?)?).map_err(|_| ()); + let source = embedded("source_artifact")?; + let source = std::str::from_utf8(bytes(&source)?).map_err(|_| ())?; + let lawpack = embedded("lawpack_artifact")?; + let adapter = embedded("adapter_artifact")?; + let profile = embedded("target_profile_artifact")?; + let catalog = embedded("intrinsics_artifact")?; + equal_text(&profile, "apiVersion", "edict.target-profile/v1")?; + let profile_coordinate = format!( + "{}@{}", + string(get(&profile, "id")?)?, + string(get(&profile, "version")?)? + ); + let profile_reference = get(target_artifact, "targetProfile")?; + equal_text(profile_reference, "id", &profile_coordinate)?; + pinned( + profile_reference, + identity("edict.target-profile/v1", &profile)?, + )?; + let core_abi = get(module, "apiVersion")?; + if !list(get(&profile, "acceptedCoreAbi")?)? + .iter() + .any(|value| value == core_abi) + { + return Err(()); + } + equal_text(&profile, "intrinsicNamespace", &profile_coordinate)?; + let catalog_reference = get(&profile, "intrinsics")?; + equal_text(catalog_reference, "id", "echo.dpo.intrinsics/v1")?; + pinned( + catalog_reference, + identity("echo.dpo.intrinsics/v1", &catalog)?, + )?; + exact(&catalog, &["apiVersion", "intrinsics"])?; + equal_text(&catalog, "apiVersion", "edict.target-profile.intrinsics/v1")?; + let catalog = get(&catalog, "intrinsics")?; + members(catalog)?; + equal_text(&lawpack, "apiVersion", "edict.lawpack/v1")?; + equal_text(&adapter, "apiVersion", "edict.lawpack-adapter/v1")?; + equal_text(&adapter, "class", "declarative")?; + let lawpack_coordinate = format!( + "{}@{}", + string(get(&lawpack, "id")?)?, + string(get(&lawpack, "version")?)? + ); + let lawpack_identity = identity("edict.lawpack/v1", &lawpack)?; + let [reference] = list(get(get(target_artifact, "semanticClosure")?, "lawpacks")?)? else { + return Err(()); + }; + equal_text(reference, "id", &lawpack_coordinate)?; + pinned(reference, lawpack_identity.clone())?; + let mut imports = list(get(module, "imports")?)? + .iter() + .filter(|entry| map_field(entry, "kind") == Some(&text("lawpack"))); + let import = imports.next().ok_or(())?; + if imports.next().is_some() || get(import, "ref")? != reference { + return Err(()); + } + pinned( + get(&lawpack, "exports")?, + identity("edict.lawpack-exports/v1", exports)?, + )?; + let mut matching = list(get(&lawpack, "targetAdapters")?)? + .iter() + .filter(|entry| map_field(entry, "acceptedTargetProfile") == Some(profile_reference)); + let entry = matching.next().ok_or(())?; + if matching.next().is_some() || get(&profile, "targetIr")? != get(entry, "acceptedTargetIr")? { + return Err(()); + } + equal_text( + get(entry, "acceptedTargetIr")?, + "id", + string(get(target_artifact, "domain")?)?, + )?; + pinned( + get(entry, "adapter")?, + identity("edict.lawpack-adapter/v1", &adapter)?, + )?; + let alias = alias( + source, + &lawpack_coordinate, + &lawpack_identity, + string(get(module, "coordinate")?)?, + )?; + imported_types(module, exports, &lawpack_coordinate)?; + let operation_profile = string(get(intent, "requiredOperationProfile")?)?; + let authorized = list(get( + unique_profile(&adapter, operation_profile)?, + "semanticEffects", + )?)?; + let implementations = get(&adapter, "effectImplementations")?; + let nodes = list(get(get(intent, "body")?, "nodes")?)?; + let lowered_steps = steps + .iter() + .map(|step| Ok((string(get(step, "id")?)?, step))) + .collect::>>()?; + let order = list(get(lowered, "executionOrder")?)?; + if order.len() != nodes.len() { + return Err(()); + } + let mut sites = BTreeMap::new(); + for (index, (node, id)) in nodes.iter().zip(order).enumerate() { + if string(get(node, "kind")?)? != "effect" { + continue; + } + let step = *lowered_steps.get(string(id)?).ok_or(())?; + let name = resolve(string(get(node, "effect")?)?, &alias, &lawpack_coordinate)?; + if !authorized.iter().any(|value| value == &text(&name)) { + return Err(()); + } + let implementation = get(implementations, &name)?; + let intrinsic_name = string(get(implementation, "targetIntrinsic")?)?; + if !intrinsic_name + .strip_prefix(profile_coordinate.as_str()) + .is_some_and(|suffix| suffix.starts_with('.') && suffix.len() > 1) + { + return Err(()); + } + equal_text(step, "targetIntrinsic", intrinsic_name)?; + let kind = effect_kind(intrinsic_name).ok_or(())?; + if kind != "read" && operation_profile != PROFILE_GRAPH_EFFECTS { + return Err(()); + } + let intrinsic = get(catalog, intrinsic_name)?; + let mut declarations = list(get(exports, "effects")?)? + .iter() + .filter(|effect| map_field(effect, "coordinate") == Some(&text(&name))); + let effect = declarations.next().ok_or(())?; + if declarations.next().is_some() { + return Err(()); + } + contract(intrinsic_name, kind, intrinsic, effect, implementation)?; + let output = string(get(effect, "outputType")?)?; + equal_text(get(node, "binding")?, "type", output)?; + arms( + node, + step, + effect, + implementation, + exports, + &alias, + &lawpack_coordinate, + )?; + sites.insert( + index, + EffectSite { + intrinsic: intrinsic_name.to_owned(), + input: string(get(effect, "inputType")?)?.to_owned(), + output: output.to_owned(), + }, + ); + } + if sites.len() != steps.len() { + return Err(()); + } + Ok(sites) +} + +/// The catalog entry, exported effect and adapter implementation agree with +/// each other and with the intrinsic's runtime ABI and failure table. +fn contract( + name: &str, + kind: &str, + intrinsic: &Value, + effect: &Value, + implementation: &Value, +) -> Check<()> { + exact( + intrinsic, + &[ + "intrinsicClass", + "argumentTypes", + "returnType", + "typeParameters", + "effectKind", + "writeClass", + "guardSupport", + "canParticipateInAtomicGuard", + "costTemplate", + "footprintTemplate", + "effectFailures", + ], + )?; + equal_text(intrinsic, "intrinsicClass", "effect")?; + equal_text(effect, "executionClass", "runtime")?; + let abi_input = format!("{name}.input"); + let [argument] = list(get(intrinsic, "argumentTypes")?)? else { + return Err(()); + }; + if string(argument)? != abi_input + || string(get(intrinsic, "returnType")?)? != format!("{name}.result") + { + return Err(()); + } + if !list(get(intrinsic, "typeParameters")?)?.is_empty() + || !list(get(effect, "typeParameters")?)?.is_empty() + { + return Err(()); + } + equal_text(intrinsic, "effectKind", kind)?; + equal_text(intrinsic, "writeClass", kind)?; + equal_text(implementation, "writeClass", kind)?; + let guard = boolean(get(intrinsic, "guardSupport")?)?; + boolean(get(intrinsic, "canParticipateInAtomicGuard")?)?; + if boolean(get(effect, "guardSupport")?)? && !guard { + return Err(()); + } + for key in ["costTemplate", "footprintTemplate"] { + nonempty(get(intrinsic, key)?)?; + } + let declared = failures(name).ok_or(())?; + let catalog_failures = members(get(intrinsic, "effectFailures")?)?; + let exported = get(effect, "effectFailures")?; + let mappings = members(get(implementation, "failureMappings")?)?; + if catalog_failures.len() != declared.len() + || mappings.len() != declared.len() + || members(exported)?.len() != declared.len() + { + return Err(()); + } + let mut mapped = BTreeSet::new(); + for (source, catalog_name) in mappings { + let catalog_name = string(catalog_name)?; + let failure = declared + .iter() + .find(|failure| failure.catalog == catalog_name) + .ok_or(())?; + if !mapped.insert(failure.runtime) { + return Err(()); + } + let actual = get(get(intrinsic, "effectFailures")?, catalog_name)?; + let expected = get(exported, string(source)?)?; + exact(actual, &["authorityClass", "payloadType"])?; + exact(expected, &["authorityClass", "payloadType"])?; + equal_text(actual, "authorityClass", failure.authority)?; + equal_text(expected, "authorityClass", failure.authority)?; + equal_text(actual, "payloadType", &abi_input)?; + equal_text(expected, "payloadType", string(get(effect, "inputType")?)?)?; + } + Ok(()) +} + +/// Every failure arm of an effect node names exactly one declared +/// obstruction with the failure's authority class, and Core and Target IR +/// carry the same arms under the catalog's failure names. +fn arms( + node: &Value, + step: &Value, + effect: &Value, + implementation: &Value, + exports: &Value, + alias: &str, + lawpack: &str, +) -> Check<()> { + let failures = get(effect, "effectFailures")?; + let mappings = members(get(implementation, "failureMappings")?)?; + let source_arms = get(node, "obstructionMap")?; + let target_arms = get(step, "obstructionArms")?; + if members(source_arms)?.len() != mappings.len() + || members(target_arms)?.len() != mappings.len() + { + return Err(()); + } + let declared_failures = list(get(step, "obstructionFailures")?)? + .iter() + .map(string) + .collect::>>()?; + if declared_failures.len() != mappings.len() { + return Err(()); + } + for (failure, catalog_name) in mappings { + let failure = string(failure)?; + let catalog_name = string(catalog_name)?; + let arm = get(source_arms, failure)?; + if Some(arm) != map_field(target_arms, catalog_name) + || !declared_failures.contains(catalog_name) + { + return Err(()); + } + exact(arm, &["binder", "value"])?; + equal_text( + get(arm, "binder")?, + "type", + string(get(get(failures, failure)?, "payloadType")?)?, + )?; + let reason = get(arm, "value")?; + let coordinate = resolve(string(get(reason, "callee")?)?, alias, lawpack)?; + let mut obstructions = list(get(exports, "obstructions")?)? + .iter() + .filter(|item| map_field(item, "coordinate") == Some(&text(&coordinate))); + let obstruction = obstructions.next().ok_or(())?; + if obstructions.next().is_some() { + return Err(()); + } + equal_text( + obstruction, + "authorityClass", + string(get(get(failures, failure)?, "authorityClass")?)?, + )?; + } + Ok(()) +} + +/// Core nodes and Target IR instructions correspond one for one, in the +/// lowered execution order, with identical kinds and contents. +fn correspondence(intent: &Value, lowered: &Value) -> Check<()> { + let mut fields = vec![ + "operationProfile", + "inputConstraints", + "coreEvaluationBudget", + "steps", + "requirements", + "result", + "executionOrder", + ]; + for key in ["basis", "pureBindings"] { + if map_field(lowered, key).is_some() { + fields.push(key); + } + } + exact(lowered, &fields)?; + let mut instructions = BTreeMap::new(); + for (collection, kind) in [ + ("steps", "effect"), + ("requirements", "require"), + ("pureBindings", "let"), + ] { + let Some(items) = map_field(lowered, collection) else { + continue; + }; + for item in list(items)? { + let id = nonempty(get(item, "id")?)?; + if instructions.insert(id, (kind, item)).is_some() { + return Err(()); + } + } + } + let nodes = list(get(get(intent, "body")?, "nodes")?)?; + let order = list(get(lowered, "executionOrder")?)?; + if nodes.len() != order.len() || nodes.len() != instructions.len() { + return Err(()); + } + for (node, id) in nodes.iter().zip(order) { + let (kind, instruction) = instructions.remove(string(id)?).ok_or(())?; + equal_text(node, "kind", kind)?; + let keys: &[&str] = match kind { + "let" => { + exact(instruction, &["id", "binding", "value"])?; + &["binding", "value"] + } + "require" => { + exact(instruction, &["id", "predicate", "onFailure"])?; + &["predicate", "onFailure"] + } + _ => { + exact( + instruction, + &[ + "id", + "binding", + "effect", + "input", + "targetIntrinsic", + "obstructionArms", + "obstructionFailures", + ], + )?; + &["binding", "effect", "input"] + } + }; + for key in keys { + if get(node, key)? != get(instruction, key)? { + return Err(()); + } + } + } + Ok(()) +} + +fn unique_profile<'a>(adapter: &'a Value, core: &str) -> Check<&'a Value> { + let mut selected = None; + for (_, profile) in members(get(adapter, "operationProfiles")?)? { + if string(get(profile, "core")?)? == core && selected.replace(profile).is_some() { + return Err(()); + } + } + selected.ok_or(()) +} + +fn resolve(name: &str, alias: &str, coordinate: &str) -> Check { + if name + .strip_prefix(coordinate) + .is_some_and(|rest| rest.starts_with('.') && rest.len() > 1) + { + return Ok(name.to_owned()); + } + let member = name + .strip_prefix(alias) + .and_then(|rest| rest.strip_prefix('.')) + .filter(|rest| !rest.is_empty()) + .ok_or(())?; + Ok(format!("{coordinate}.{member}")) +} + +/// The lawpack alias the source declares in its import preamble, with the +/// lawpack's exact digest. +fn alias(source: &str, coordinate: &str, identity: &Value, module: &str) -> Check { + let Value::Bytes(identity) = identity else { + return Err(()); + }; + let expected = format!("\"sha256:{}\"", lower_hex(identity)); + let mut lines = source + .lines() + .map(str::trim) + .filter(|line| !line.is_empty()); + if lines.next() != Some(format!("package {module};").as_str()) { + return Err(()); + } + let mut result = None; + for line in lines { + if !line.starts_with("use ") { + break; + } + let tokens = line.split_whitespace().collect::>(); + let ["use", "lawpack", name, "digest", value, "as", alias] = tokens.as_slice() else { + return Err(()); + }; + let alias = alias.strip_suffix(';').ok_or(())?; + if *name != coordinate + || *value != expected + || !identifier(alias) + || result.replace(alias.to_owned()).is_some() + { + return Err(()); + } + } + result.ok_or(()) +} + +/// Every Core type under the lawpack's namespace renders to exactly the +/// definition the pinned exports declare for it. +fn imported_types(module: &Value, exports: &Value, lawpack: &str) -> Check<()> { + let mut definitions = BTreeMap::new(); + let mut remaining = MAX_NODES; + for item in list(get(exports, "types")?)? { + spend(&mut remaining)?; + exact(item, &["coordinate", "definition"])?; + let name = nonempty(get(item, "coordinate")?)?; + let definition = nonempty(get(item, "definition")?)?; + if definitions.insert(name, definition).is_some() { + return Err(()); + } + } + let prefix = format!("{lawpack}."); + for (name, value) in members(get(module, "types")?)? { + spend(&mut remaining)?; + let name = string(name)?; + if !name.starts_with(&prefix) { + continue; + } + let mut expected = *definitions.get(name).ok_or(())?; + let mut seen = BTreeSet::new(); + while let Some(next) = definitions.get(expected) { + spend(&mut remaining)?; + if seen.len() >= MAX_DEPTH || !seen.insert(expected) { + return Err(()); + } + expected = next; + } + if render(name, value, &mut remaining)? != expected { + return Err(()); + } + } + Ok(()) +} + +fn render(name: &str, value: &Value, remaining: &mut usize) -> Check { + spend(remaining)?; + let kind = string(get(value, "kind")?)?; + match kind { + "Bool" | "Unit" | "I8" | "I16" | "I32" | "I64" | "U8" | "U16" | "U32" | "U64" => { + exact(value, &["kind"])?; + Ok(kind.to_owned()) + } + "Bytes" => { + let max = number(get(value, "max")?)?; + if let Some(min) = map_field(value, "min") { + exact(value, &["kind", "min", "max"])?; + let min = number(min)?; + if min > max { + return Err(()); + } + Ok(if min == max { + format!("Bytes") + } else { + format!("Bytes") + }) + } else { + exact(value, &["kind", "max"])?; + Ok(format!("Bytes")) + } + } + "String" => { + exact(value, &["kind", "max", "canonical"])?; + let max = number(get(value, "max")?)?; + let canonical = string(get(value, "canonical")?)?; + if !["raw-utf8", "unicode-scalar-nfc"].contains(&canonical) { + return Err(()); + } + Ok(format!("String")) + } + "Record" => { + exact(value, &["kind", "fields"])?; + let mut fields = BTreeMap::new(); + for (key, ty) in members(get(value, "fields")?)? { + let key = string(key)?; + if !identifier(key) || fields.insert(key, reference(ty, remaining)?).is_some() { + return Err(()); + } + } + let fields = fields + .into_iter() + .map(|(name, ty)| format!("{name}:{ty}")) + .collect::>() + .join(","); + Ok(format!("Record<{fields}>")) + } + "Nominal" => { + exact(value, &["kind", "contract", "representation"])?; + equal_text(value, "contract", name)?; + Ok(format!( + "Nominal<{}>", + reference(get(value, "representation")?, remaining)? + )) + } + "Option" | "CapabilityRef" => { + exact(value, &["kind", "item"])?; + Ok(format!( + "{kind}<{}>", + reference(get(value, "item")?, remaining)? + )) + } + "List" => { + exact(value, &["kind", "item", "max"])?; + let item = reference(get(value, "item")?, remaining)?; + Ok(format!("List<{item},max={}>", number(get(value, "max")?)?)) + } + "Map" => { + exact(value, &["kind", "key", "value", "max"])?; + let key = reference(get(value, "key")?, remaining)?; + let item = reference(get(value, "value")?, remaining)?; + Ok(format!( + "Map<{key},{item},max={}>", + number(get(value, "max")?)? + )) + } + "ExternalActionRequest" => { + exact(value, &["kind", "settlement"])?; + Ok(format!( + "edict.external-action.request/v1<{}>", + reference(get(value, "settlement")?, remaining)? + )) + } + _ => Err(()), + } +} + +fn reference<'a>(value: &'a Value, remaining: &mut usize) -> Check<&'a str> { + spend(remaining)?; + let value = string(value)?; + if value.is_empty() || value.len() > 1024 { + return Err(()); + } + let mut depth = 0usize; + for byte in value.bytes() { + match byte { + b'<' => { + depth += 1; + if depth > MAX_DEPTH { + return Err(()); + } + } + b'>' => depth = depth.checked_sub(1).ok_or(())?, + _ => {} + } + } + if depth != 0 { + return Err(()); + } + Ok(value) +} + +fn spend(remaining: &mut usize) -> Check<()> { + *remaining = remaining.checked_sub(1).ok_or(())?; + Ok(()) +} + +fn identifier(value: &str) -> bool { + !value.is_empty() + && value + .bytes() + .enumerate() + .all(|(i, c)| c == b'_' || c.is_ascii_alphabetic() || (i > 0 && c.is_ascii_digit())) +} + +fn lower_hex(bytes: &[u8]) -> String { + const DIGITS: &[u8; 16] = b"0123456789abcdef"; + let mut out = String::with_capacity(bytes.len() * 2); + for byte in bytes { + out.push(char::from(DIGITS[usize::from(byte >> 4)])); + out.push(char::from(DIGITS[usize::from(byte & 15)])); + } + out +} + +fn identity(domain: &str, value: &Value) -> Check { + digest(domain, value) + .map(|bytes| Value::Bytes(bytes.to_vec())) + .map_err(|_| ()) +} + +fn pinned(reference: &Value, expected: Value) -> Check<()> { + exact(reference, &["id", "digest"])?; + nonempty(get(reference, "id")?)?; + if get(reference, "digest")? != &Value::Array(vec![text("sha256"), expected]) { + return Err(()); + } + // A pin is canonical bytes, never a looser spelling of the same digest. + encode(reference).map(|_| ()).map_err(|_| ()) +} + +fn text(value: &str) -> Value { + Value::Text(value.to_owned()) +} +fn map_field<'a>(value: &'a Value, key: &str) -> Option<&'a Value> { + let Value::Map(fields) = value else { + return None; + }; + fields + .iter() + .find_map(|(k, v)| matches!(k, Value::Text(name) if name == key).then_some(v)) +} +fn get<'a>(value: &'a Value, key: &str) -> Check<&'a Value> { + map_field(value, key).ok_or(()) +} +fn members(value: &Value) -> Check<&[(Value, Value)]> { + match value { + Value::Map(fields) => Ok(fields), + _ => Err(()), + } +} +fn list(value: &Value) -> Check<&[Value]> { + match value { + Value::Array(items) => Ok(items), + _ => Err(()), + } +} +fn string(value: &Value) -> Check<&str> { + match value { + Value::Text(text) => Ok(text), + _ => Err(()), + } +} +fn nonempty(value: &Value) -> Check<&str> { + string(value).and_then(|text| if text.is_empty() { Err(()) } else { Ok(text) }) +} +fn bytes(value: &Value) -> Check<&[u8]> { + match value { + Value::Bytes(bytes) => Ok(bytes), + _ => Err(()), + } +} +fn number(value: &Value) -> Check { + match value { + Value::Integer(n) => u64::try_from(*n).map_err(|_| ()), + _ => Err(()), + } +} +fn boolean(value: &Value) -> Check { + match value { + Value::Bool(value) => Ok(*value), + _ => Err(()), + } +} +fn equal_text(value: &Value, key: &str, expected: &str) -> Check<()> { + if get(value, key)? == &text(expected) { + Ok(()) + } else { + Err(()) + } +} +fn exact(value: &Value, keys: &[&str]) -> Check<()> { + let fields = members(value)?; + if fields.len() != keys.len() + || fields + .iter() + .any(|(k, _)| !matches!(k, Value::Text(key) if keys.contains(&key.as_str()))) + { + return Err(()); + } + Ok(()) +} diff --git a/crates/echo-edict-provider-lowerer/src/executable_operation/source_functions.rs b/crates/echo-edict-provider-lowerer/src/executable_operation/source_functions.rs index 6252b189..a78812e2 100644 --- a/crates/echo-edict-provider-lowerer/src/executable_operation/source_functions.rs +++ b/crates/echo-edict-provider-lowerer/src/executable_operation/source_functions.rs @@ -2,10 +2,12 @@ // © James Ross Ω FLYING•ROBOTS //! Lowerer-owned forward type, totality, depth and deterministic cost judgment. //! Applies to the complete source-function module, including unused definitions. +mod effect_intent; mod order; mod unsigned_addition; use super::ProviderRefusalV1; use echo_edict_canonical::CanonicalValueV1 as Value; +pub(super) use effect_intent::{judge as judge_effect_intent, EffectSite}; use std::collections::{BTreeMap, BTreeSet}; type Check = Result; @@ -83,6 +85,18 @@ pub(super) fn validate(core: &Value, exports: &Value, read: bool) -> Result<(), }) } fn run(core: &Value, exports: &Value, read: bool) -> Check<()> { + let mut proof = judgment(core, exports)?; + if super::map_field(core, "functions").is_none() && !unsigned_addition::present(core)? { + return Ok(()); + } + for (_, intent) in members(get(core, "intents")?)? { + proof.intent(intent, read)?; + } + Ok(()) +} +/// Registers and checks every helper, imported and source-owned, so intent +/// bodies can call them. +fn judgment<'a>(core: &'a Value, exports: &'a Value) -> Check> { let mut functions = BTreeMap::new(); let imported_functions = super::map_field(exports, "pureFunctions") .map(list) @@ -172,13 +186,7 @@ fn run(core: &Value, exports: &Value, read: bool) -> Check<()> { for name in proof.functions.keys().cloned().collect::>() { proof.function(&name, 1)?; } - if super::map_field(core, "functions").is_none() && !unsigned_addition::present(core)? { - return Ok(()); - } - for (_, intent) in members(get(core, "intents")?)? { - proof.intent(intent, read)?; - } - Ok(()) + Ok(proof) } impl<'a> Judgment<'a> { /// An unsigned binding carries its proven cap to later evaluation in the @@ -276,6 +284,11 @@ impl<'a> Judgment<'a> { match string(get(definition, "kind")?)? { "Bool" => Ok(Ty::Bool), "Int" => self.ty(string(get(definition, "width")?)?, depth + 1), + // A table entry may also name an unsigned width directly, as Core does. + kind @ ("U8" | "U16" | "U32" | "U64") => { + exact(definition, &["kind"])?; + self.ty(kind, depth + 1) + } "Nominal" => { if string(get(definition, "contract")?)? != key { return Err(()); diff --git a/crates/echo-edict-provider-lowerer/src/executable_operation/source_functions/effect_intent.rs b/crates/echo-edict-provider-lowerer/src/executable_operation/source_functions/effect_intent.rs new file mode 100644 index 00000000..32bb42d7 --- /dev/null +++ b/crates/echo-edict-provider-lowerer/src/executable_operation/source_functions/effect_intent.rs @@ -0,0 +1,264 @@ +// SPDX-License-Identifier: Apache-2.0 +// © James Ross Ω FLYING•ROBOTS +//! Lowerer-owned typing, proof and cost judgment of an authored effect +//! program's body, independent of the runtime's own judgment. +//! +//! Proofs follow Edict: the intent's input constraints dominate the whole +//! body, an unsigned `let` carries its proven cap to later nodes, earlier +//! conjuncts of one `all` prove later ones, and a `require` proves nothing. +use super::{ + exact, get, includes, judgment, list, members, number, shape, string, Check, Cost, Judgment, + Ty, Value, +}; +use std::collections::BTreeMap; + +/// The largest atom an authored effect may read or write, in bytes. +const STORAGE_CEILING: u64 = 16 * 1024 * 1024; + +/// What the lowering relation established about one effect node. +pub(in crate::executable_operation) struct EffectSite { + pub(in crate::executable_operation) intrinsic: String, + pub(in crate::executable_operation) input: String, + pub(in crate::executable_operation) output: String, +} + +/// Judges the selected intent's body with the module's helpers. +pub(in crate::executable_operation) fn judge( + core: &Value, + exports: &Value, + intent: &Value, + sites: &BTreeMap, +) -> Check<()> { + judgment(core, exports)?.effect_intent(intent, sites) +} + +impl<'a> Judgment<'a> { + #[allow( + clippy::too_many_lines, + reason = "One ordered walk keeps scope, proof and cost in step with the body." + )] + fn effect_intent( + &mut self, + intent: &'a Value, + sites: &BTreeMap, + ) -> Check<()> { + self.proven.clear(); + self.bound.clear(); + let body = get(intent, "body")?; + exact(body, &["locals", "nodes", "result"])?; + let mut pending = BTreeMap::new(); + for declaration in list(get(body, "locals")?)? { + exact(declaration, &["id", "type", "alphaName"])?; + string(get(declaration, "alphaName")?)?; + self.ty(string(get(declaration, "type")?)?, 0)?; + if pending + .insert(string(get(declaration, "id")?)?, declaration) + .is_some() + { + return Err(()); + } + } + let input = pending.remove("arg.0").ok_or(())?; + if get(input, "type")? != get(intent, "input")? { + return Err(()); + } + let mut scope = BTreeMap::new(); + let ty = self.declaration(input, &mut scope)?; + let (copy, validation, _, _) = shape(&ty)?; + let mut cost = copy.plus(Cost { + steps: validation, + bytes: 0, + })?; + if let Some(basis) = super::super::map_field(intent, "basis") { + cost = cost.plus(self.expression(basis, &scope, true, 0)?.cost)?; + } + for constraint in list(get(intent, "inputConstraints")?)? { + cost = cost.plus( + self.predicate(get(constraint, "predicate")?, &scope, true, 0)? + .0, + )?; + self.proven.push(get(constraint, "predicate")?); + } + let nodes = list(get(body, "nodes")?)?; + if sites.keys().any(|index| *index >= nodes.len()) { + return Err(()); + } + for (index, node) in nodes.iter().enumerate() { + cost = cost.plus(Cost { steps: 1, bytes: 0 })?; + let mut claim = |local: &'a Value| -> Check<()> { + if pending.remove(string(get(local, "id")?)?) == Some(local) { + Ok(()) + } else { + Err(()) + } + }; + match string(get(node, "kind")?)? { + "let" => { + exact(node, &["kind", "binding", "value"])?; + if sites.contains_key(&index) { + return Err(()); + } + claim(get(node, "binding")?)?; + let fact = self.expression(get(node, "value")?, &scope, true, 0)?; + let ty = self.declaration(get(node, "binding")?, &mut scope)?; + if !includes(&ty, &fact.ty) { + return Err(()); + } + self.record_bound(get(node, "binding")?, get(node, "value")?, &ty)?; + cost = cost.plus(fact.cost)?.plus(Cost { + steps: shape(&ty)?.1, + bytes: 0, + })?; + } + "require" => { + exact(node, &["kind", "predicate", "onFailure"])?; + if sites.contains_key(&index) { + return Err(()); + } + // A require refuses later work; it is not a proof for it. + cost = + cost.plus(self.predicate(get(node, "predicate")?, &scope, true, 0)?.0)?; + let failure = get(node, "onFailure")?; + exact(failure, &["kind", "reason"])?; + if string(get(failure, "kind")?)? != "terminal" { + return Err(()); + } + let reason = get(failure, "reason")?; + exact(reason, &["reasonKind", "payload"])?; + if string(get(reason, "reasonKind")?)?.is_empty() { + return Err(()); + } + for (_, value) in members(get(reason, "payload")?)? { + cost = cost.plus(self.expression(value, &scope, true, 0)?.cost)?; + } + } + "effect" => { + exact( + node, + &["kind", "binding", "effect", "input", "obstructionMap"], + )?; + let site = sites.get(&index).ok_or(())?; + let fact = self.expression(get(node, "input")?, &scope, true, 0)?; + let expected = self.ty(&site.input, 0)?; + if !includes(&expected, &fact.ty) { + return Err(()); + } + let output = self.ty(&site.output, 0)?; + let charge = abi(&site.intrinsic, &expected, &output)?; + for (_, arm) in members(get(node, "obstructionMap")?)? { + exact(arm, &["binder", "value"])?; + claim(get(arm, "binder")?)?; + let reason = get(arm, "value")?; + exact(reason, &["kind", "callee", "args", "typeArgs"])?; + if string(get(reason, "kind")?)? != "call" + || !list(get(reason, "args")?)?.is_empty() + || !list(get(reason, "typeArgs")?)?.is_empty() + { + return Err(()); + } + } + claim(get(node, "binding")?)?; + let declared = self.declaration(get(node, "binding")?, &mut scope)?; + if declared != output { + return Err(()); + } + cost = cost + .plus(fact.cost)? + .plus(Cost { + steps: shape(&expected)?.1, + bytes: 0, + })? + .plus(charge)?; + } + _ => return Err(()), + } + } + if !pending.is_empty() { + return Err(()); + } + let result = self.expression(get(body, "result")?, &scope, true, 0)?; + let expected = self.ty(string(get(intent, "output")?)?, 0)?; + if !includes(&expected, &result.ty) { + return Err(()); + } + let (scratch, validations, output, _) = shape(&expected)?; + cost = cost.plus(result.cost)?.plus(scratch)?.plus(Cost { + steps: validations, + bytes: 0, + })?; + let budget = get(intent, "coreEvaluationBudget")?; + exact(budget, &["maxSteps", "maxAllocatedBytes", "maxOutputBytes"])?; + if cost.steps > number(get(budget, "maxSteps")?)? + || cost.bytes > number(get(budget, "maxAllocatedBytes")?)? + || output > number(get(budget, "maxOutputBytes")?)? + { + return Err(()); + } + Ok(()) + } +} + +/// Checks an effect's input and result against its intrinsic's runtime ABI +/// and returns the work the effect itself costs. +fn abi(intrinsic: &str, input: &Ty, output: &Ty) -> Check { + let Ty::Record(fields) = input.representation() else { + return Err(()); + }; + let id = |name: &str| fields.get(name).map(Ty::representation) == Some(&Ty::Bytes(32, 32)); + let atom = |name: &str| { + matches!( + fields.get(name).map(Ty::representation), + Some(Ty::Bytes(0, max)) if *max > 0 && *max <= STORAGE_CEILING + ) + }; + let unit = matches!(output.representation(), Ty::Record(fields) if fields.is_empty()); + let mutation = |names: &[&str]| -> Check { + let conforming = fields.len() == names.len() + && names.iter().all(|name| { + if *name == "atomBytes" { + atom(name) + } else { + id(name) + } + }); + if conforming && unit { + Ok(Cost { + steps: 1, + bytes: 64, + }) + } else { + Err(()) + } + }; + match intrinsic { + "echo.dpo@1.node-atom-read" => { + let Ty::Bytes(0, max) = output.representation() else { + return Err(()); + }; + if fields.len() != 3 + || !["nodeId", "typeId", "warpId"].iter().all(|name| id(name)) + || *max == 0 + || *max > STORAGE_CEILING + { + return Err(()); + } + Ok(Cost { + steps: max.checked_add(1).ok_or(())?, + bytes: max.checked_add(64).ok_or(())?, + }) + } + "echo.dpo@1.ensure-node" | "echo.dpo@1.create-node" => { + mutation(&["warpId", "nodeId", "nodeType", "atomType", "atomBytes"]) + } + "echo.dpo@1.replace-atom" => mutation(&[ + "warpId", + "nodeId", + "expectedAtomDigest", + "atomType", + "atomBytes", + ]), + "echo.dpo@1.ensure-edge" => mutation(&["warpId", "edgeId", "fromId", "toId", "edgeType"]), + "echo.dpo@1.replace-edge" => mutation(&["warpId", "edgeId", "expectedToId", "toId"]), + _ => Err(()), + } +} diff --git a/crates/echo-edict-provider-lowerer/tests/effect_program_judgment.rs b/crates/echo-edict-provider-lowerer/tests/effect_program_judgment.rs new file mode 100644 index 00000000..71215706 --- /dev/null +++ b/crates/echo-edict-provider-lowerer/tests/effect_program_judgment.rs @@ -0,0 +1,176 @@ +// SPDX-License-Identifier: Apache-2.0 +// © James Ross Ω FLYING•ROBOTS +#![allow(clippy::expect_used, clippy::panic)] +//! The lowerer judges authored effect programs itself, before publication, +//! and reaches the runtime's verdict on the shared retained corpus. +use echo_edict_canonical::{decode_canonical_cbor_v1 as decode, CanonicalValueV1 as V}; +use echo_edict_provider_lowerer::effect_publication::{ + encode_effect_publication, judge_effect_program, EffectPublicationError, EffectPublicationInput, +}; + +/// The retained corpus, embedded so the judgment reads no files. +macro_rules! retained { + ($($name:literal),* $(,)?) => { + &[$(( + $name, + include_str!(concat!("fixtures/effect-programs/", $name, ".hex")), + )),*] + }; +} +const RETAINED: &[(&str, &str)] = retained![ + "read-control", + "ensure-node-control", + "slice-proven", + "slice-unproven", + "slice-other-operand", + "slice-require-only", + "forged-node-order", + "wrong-intrinsic-input-type", + "undeclared-obstruction", + "failure-mapping-tag-spelled", + "failure-mapping-unknown", + "failure-mapping-duplicate", + "over-budget", + "read-captured-budget", +]; +const VERDICTS: &str = include_str!("fixtures/effect-programs/verdicts.txt"); + +fn get<'a>(value: &'a V, key: &str) -> &'a V { + let V::Map(fields) = value else { panic!("map") }; + &fields + .iter() + .find(|(k, _)| k == &V::Text(key.into())) + .unwrap_or_else(|| panic!("field {key}")) + .1 +} +fn bytes(value: &V) -> &[u8] { + let V::Bytes(bytes) = value else { + panic!("bytes") + }; + bytes +} +fn package(name: &str) -> V { + let hex = RETAINED + .iter() + .find_map(|(entry, hex)| (*entry == name).then_some(*hex)) + .expect(name); + decode(&hex::decode(hex.trim()).expect("hex")).expect("canonical package") +} +fn compiled_program(name: &str) -> Vec { + let program = decode(bytes(get(&package(name), "program"))).expect("program"); + bytes(get(&program, "compiled_program")).to_vec() +} +fn verdicts() -> Vec<(String, bool)> { + VERDICTS + .lines() + .map(|line| { + let (name, verdict) = line.split_once(' ').expect("entry"); + (name.to_owned(), verdict == "accept") + }) + .collect() +} + +#[test] +fn the_lowerer_reaches_every_retained_corpus_verdict() { + let verdicts = verdicts(); + assert_eq!( + verdicts + .iter() + .map(|(name, _)| name.as_str()) + .collect::>(), + RETAINED.iter().map(|(name, _)| *name).collect::>(), + "every verdict has its embedded package, in order" + ); + assert!(verdicts.iter().filter(|(_, accept)| *accept).count() >= 3); + assert!(verdicts.iter().filter(|(_, accept)| !*accept).count() >= 10); + for (name, accept) in verdicts { + let judged = judge_effect_program(&compiled_program(&name)); + if accept { + judged.unwrap_or_else(|e| panic!("{name}: lowerer refused an accepted program: {e}")); + } else { + assert_eq!( + judged, + Err(EffectPublicationError::UnsupportedProgram), + "{name}: lowerer accepted a refused program" + ); + } + } +} + +/// Publication runs the same judgment, so a refused program is never +/// serialized into a package. +#[test] +fn publication_refuses_what_the_judgment_refuses() { + for (name, accept) in verdicts() { + let program = compiled_program(&name); + let package = package(&name); + let program_value = decode(bytes(get(&package, "program"))).expect("program"); + let catalog = { + let bundle = decode(&program).expect("bundle"); + match get(&bundle, "lowering_artifacts") { + V::Null => echo_edict_canonical::encode_canonical_cbor_v1(&V::Map(vec![ + ( + V::Text("apiVersion".into()), + V::Text("edict.target-profile.intrinsics/v1".into()), + ), + (V::Text("intrinsics".into()), V::Map(vec![])), + ])) + .expect("empty catalog"), + lowering => bytes(get(lowering, "intrinsics_artifact")).to_vec(), + } + }; + let field = |key: &str| get(&program_value, key).clone(); + let configuration = echo_edict_canonical::encode_canonical_cbor_v1(&V::Map( + [ + ( + "apiVersion", + V::Text("echo.operation-lowering-configuration/v1".into()), + ), + ("programKind", V::Text("edict-effect-program/v1".into())), + ("identityLaw", V::Integer(1)), + ("intrinsicCatalog", V::Bytes(catalog)), + ("graphSchema", field("graph_schema")), + ("footprintLaw", field("footprint_law")), + ("maxInputBytes", field("max_input_bytes")), + ("maxResultBytes", field("max_result_bytes")), + ("maxAllocatedBytes", field("max_allocated_bytes")), + ( + "budgetCeiling", + V::Map(vec![ + (V::Text("steps".into()), V::Integer(1)), + (V::Text("readBytes".into()), V::Integer(0)), + (V::Text("writeBytes".into()), V::Integer(0)), + ]), + ), + ("authorityProfile", V::Text("app.effect-writer@1".into())), + ] + .into_iter() + .map(|(k, v)| (V::Text(k.into()), v)) + .collect(), + )) + .expect("configuration"); + let source = + echo_edict_canonical::encode_canonical_cbor_v1(&V::Bytes(b"package app;\n".to_vec())) + .expect("source"); + let published = encode_effect_publication(EffectPublicationInput { + compiler_program: &program, + application_schema_coordinate: "app.Exports", + source_artifact: &source, + source_domain: "edict.source/v1", + configuration: &configuration, + }); + if accept { + assert_ne!( + published, + Err(EffectPublicationError::UnsupportedProgram), + "{name}: publication refused an accepted program" + ); + } else { + assert_eq!( + published, + Err(EffectPublicationError::UnsupportedProgram), + "{name}: publication serialized a refused program" + ); + } + } +} diff --git a/crates/echo-edict-provider-lowerer/tests/fixtures/current-effect-wire/README.md b/crates/echo-edict-provider-lowerer/tests/fixtures/current-effect-wire/README.md index 701a9610..a746e3c3 100644 --- a/crates/echo-edict-provider-lowerer/tests/fixtures/current-effect-wire/README.md +++ b/crates/echo-edict-provider-lowerer/tests/fixtures/current-effect-wire/README.md @@ -16,6 +16,10 @@ Each `.hex` file contains the canonical bytes of one whole input artifact. Copies live in this crate so its source archive does not depend on another crate's test files. +The Core intent declares a step budget of 1,024. Publication judges the program +before serializing it, and the provider cost model needs more than one step for +even this constant result, so a smaller declared budget is refused. + The witness checks deterministic current-format serialization and the current runtime decoder's exact round trip. It does not establish compiler correctness, policy or profile authority, independent verifier acceptance, installed Action diff --git a/crates/echo-edict-provider-lowerer/tests/fixtures/current-effect-wire/bundle.hex b/crates/echo-edict-provider-lowerer/tests/fixtures/current-effect-wire/bundle.hex index ec195edc..375af14a 100644 --- a/crates/echo-edict-provider-lowerer/tests/fixtures/current-effect-wire/bundle.hex +++ b/crates/echo-edict-provider-lowerer/tests/fixtures/current-effect-wire/bundle.hex @@ -1 +1 @@ -a666696e74656e7468757064617465403166736368656d6178286563686f2e636f6d70696c65722d70726f64756365642d6566666563742d70726f6772616d2f76316d636f72655f6172746966616374590194a6657479706573a166526573756c74a1646b696e646355333267696d706f7274738067696e74656e7473a1687570646174654031a664626f6479a3656e6f64657380666c6f63616c7381a3626964656172672e3064747970656355333269616c7068614e616d6565246172673066726573756c74a2646b696e6465636f6e73746576616c7565a3646b696e6463696e746576616c7565182a6577696474686355333265696e70757463553332666f75747075746a6170702e526573756c7470696e707574436f6e73747261696e74738074636f72654576616c756174696f6e427564676574a3686d61785374657073016e6d61784f757470757442797465731a00010000716d6178416c6c6f636174656442797465731a01000000781872657175697265644f7065726174696f6e50726f66696c65781a636f6e74696e75756d2e70726f66696c652e746f74616c2f76316a61706956657273696f6e6d65646963742e636f72652f76316a636f6f7264696e6174656361707078187265717569726564436f72654361706162696c697469657380726c6f776572696e675f617274696661637473f6727461726765745f69725f6172746966616374590200a6646b696e64776f7264657265645461726765744972417274696661637466646f6d61696e6f6563686f2e7370616e2d69722f763267696e74656e7473a1687570646174654031a86573746570738066726573756c74a2646b696e6465636f6e73746576616c7565a3646b696e6463696e746576616c7565182a657769647468635533326c7075726542696e64696e6773806c726571756972656d656e7473806e657865637574696f6e4f726465728070696e707574436f6e73747261696e747380706f7065726174696f6e50726f66696c65781a636f6e74696e75756d2e70726f66696c652e746f74616c2f763174636f72654576616c756174696f6e427564676574a3686d61785374657073016e6d61784f757470757442797465731a00010000716d6178416c6c6f636174656442797465731a010000006d74617267657450726f66696c65a26269646a6563686f2e64706f4031666469676573748266736861323536582006060606060606060606060606060606060606060606060606060606060606066f73656d616e746963436c6f73757265a2686c61777061636b73806a736f75726365436f7265a262696463617070666469676573748266736861323536582017e17862979412ae3477593727e6d5ec05ee50fe255fc02acdfc5777b9ac744d74736f75726365436f7265436f6f7264696e6174656361707078186c61777061636b5f6578706f7274735f6172746966616374589ca66574797065738067656666656374738069636f6e7374616e7473806c6f62737472756374696f6e7381a36a636f6f7264696e6174656b6170702e5265667573616c6d7061796c6f6164536368656d61736170702e5265667573616c2e5061796c6f61646e617574686f72697479436c61737366646f6d61696e6d7075726546756e6374696f6e7380716f7065726174696f6e50726f66696c6573a0 +a666696e74656e7468757064617465403166736368656d6178286563686f2e636f6d70696c65722d70726f64756365642d6566666563742d70726f6772616d2f76316d636f72655f6172746966616374590196a6657479706573a166526573756c74a1646b696e646355333267696d706f7274738067696e74656e7473a1687570646174654031a664626f6479a3656e6f64657380666c6f63616c7381a3626964656172672e3064747970656355333269616c7068614e616d6565246172673066726573756c74a2646b696e6465636f6e73746576616c7565a3646b696e6463696e746576616c7565182a6577696474686355333265696e70757463553332666f75747075746a6170702e526573756c7470696e707574436f6e73747261696e74738074636f72654576616c756174696f6e427564676574a3686d617853746570731904006e6d61784f757470757442797465731a00010000716d6178416c6c6f636174656442797465731a01000000781872657175697265644f7065726174696f6e50726f66696c65781a636f6e74696e75756d2e70726f66696c652e746f74616c2f76316a61706956657273696f6e6d65646963742e636f72652f76316a636f6f7264696e6174656361707078187265717569726564436f72654361706162696c697469657380726c6f776572696e675f617274696661637473f6727461726765745f69725f6172746966616374590202a6646b696e64776f7264657265645461726765744972417274696661637466646f6d61696e6f6563686f2e7370616e2d69722f763267696e74656e7473a1687570646174654031a86573746570738066726573756c74a2646b696e6465636f6e73746576616c7565a3646b696e6463696e746576616c7565182a657769647468635533326c7075726542696e64696e6773806c726571756972656d656e7473806e657865637574696f6e4f726465728070696e707574436f6e73747261696e747380706f7065726174696f6e50726f66696c65781a636f6e74696e75756d2e70726f66696c652e746f74616c2f763174636f72654576616c756174696f6e427564676574a3686d617853746570731904006e6d61784f757470757442797465731a00010000716d6178416c6c6f636174656442797465731a010000006d74617267657450726f66696c65a26269646a6563686f2e64706f4031666469676573748266736861323536582006060606060606060606060606060606060606060606060606060606060606066f73656d616e746963436c6f73757265a2686c61777061636b73806a736f75726365436f7265a2626964636170706664696765737482667368613235365820e003c45d1967ce94fd454df03168536c81829a4247e2172412045f2a98528bd474736f75726365436f7265436f6f7264696e6174656361707078186c61777061636b5f6578706f7274735f6172746966616374589ca66574797065738067656666656374738069636f6e7374616e7473806c6f62737472756374696f6e7381a36a636f6f7264696e6174656b6170702e5265667573616c6d7061796c6f6164536368656d61736170702e5265667573616c2e5061796c6f61646e617574686f72697479436c61737366646f6d61696e6d7075726546756e6374696f6e7380716f7065726174696f6e50726f66696c6573a0 diff --git a/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/README.md b/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/README.md new file mode 100644 index 00000000..3058aded --- /dev/null +++ b/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/README.md @@ -0,0 +1,14 @@ + + + +# Authored effect-program verdict corpus + +Each `.hex` file holds the canonical bytes of one whole operation package carrying an authored effect program. `verdicts.txt` lists every entry, in order, with the verdict Echo's provider lowerer and verifier must each reach: `accept` or `refuse`. + +warp-core generates the corpus from its own effect-package fixture builders and asserts the runtime's verdict on every entry (`crates/warp-core/tests/edict_effect_package_tests/provider_corpus.rs`). The lowerer (`tests/effect_program_judgment.rs`) and the verifier (`crates/echo-edict-provider-verifier/tests/effect_program_judgment.rs`) judge the same bytes independently. Rebuild the files with that module's ignored `regenerate_the_retained_provider_corpus` test after changing an entry. + +The accepted entries are a node-atom read with its four failure arms, an `ensure-node` mutation, and a runtime prefix slice proven by an input constraint. Each refused entry is a well-formed package that reaches one specific check: an unproven slice, a slice guarded on another operand, a slice guarded only by a `require`, swapped execution order, a mutation input whose node id is not exactly 32 bytes, an obstruction missing from the exports, tag-spelled, unknown and duplicate failure mappings, and two step budgets too small for the program's worst case. + +The two budget entries are refused by the providers' static cost models. The runtime prepares them and meters the budget only when it executes, so the runtime test checks preparation for those two entries rather than refusal. + +These are synthetic, internally repinned packages built from the retained public node-atom-read capture. They are not evidence of a successful public compiler run. diff --git a/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/ensure-node-control.hex b/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/ensure-node-control.hex new file mode 100644 index 00000000..546043e0 --- /dev/null +++ b/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/ensure-node-control.hex @@ -0,0 +1 @@ +b166736368656d6178196563686f2e6f7065726174696f6e2d7061636b6167652f76316770726f6772616d592310ad646b696e647765646963742d6566666563742d70726f6772616d2f763166736368656d6178196563686f2e6f7065726174696f6e2d70726f6772616d2f76316b6f75747075745f747970656c4d75746174696f6e556e69746c67726170685f736368656d615876a26a656467655f7479706573a06a6e6f64655f7479706573a158200101010101010101010101010101010101010101010101010101010101010101a26a61646472657373696e67016a61746f6d5f747970657381582002020202020202020202020202020202020202020202020202020202020202026c6964656e746974795f6c6177016d666f6f747072696e745f6c617758f6a9696d61785f7265616473016a61746f6d5f747970657381582002020202020202020202020202020202020202020202020202020202020202026a6d61785f777269746573016f6d61785f72616e67655f6564676573006f726561645f6e6f64655f747970657381582001010101010101010101010101010101010101010101010101010101010101017072616e67655f656467655f7479706573807077726974655f656467655f7479706573807077726974655f6e6f64655f7479706573815820010101010101010101010101010101010101010101010101010101010101010172706f7274616c5f6f776e65725f7479706573806f6d61785f696e7075745f62797465731a0001000070636f6d70696c65645f70726f6772616d592013a666696e74656e746c7265706c61636552616e676566736368656d6178286563686f2e636f6d70696c65722d70726f64756365642d6566666563742d70726f6772616d2f76316d636f72655f61727469666163745904c0a6657479706573a565496e707574a2646b696e64665265636f7264666669656c6473a2676164647265737378186a656469742e7465787440312e4661637441646472657373686578706563746564766a656469742e7465787440312e4661637442797465736c4d75746174696f6e556e6974a2646b696e64665265636f7264666669656c6473a06d4d75746174696f6e496e707574a2646b696e64665265636f7264666669656c6473a5666e6f646549646f42797465733c65786163743d33323e667761727049646f42797465733c65786163743d33323e6861746f6d547970656f42797465733c65786163743d33323e686e6f6465547970656f42797465733c65786163743d33323e6961746f6d42797465736f42797465733c6d61783d313032343e766a656469742e7465787440312e466163744279746573a2636d61781a00100000646b696e6465427974657378186a656469742e7465787440312e4661637441646472657373a2646b696e64665265636f7264666669656c6473a3666e6f646549646f42797465733c65786163743d33323e667479706549646f42797465733c65786163743d33323e667761727049646f42797465733c65786163743d33323e67696d706f72747381a263726566a26269646c6a656469742e746578744031666469676573748266736861323536582046670d1111939331d51bce51951570230fe529196ed51ebef5c8de4a8a07d272646b696e64676c61777061636b67696e74656e7473a16c7265706c61636552616e6765a664626f6479a3656e6f64657381a5646b696e646665666665637465696e707574a263726566a3626964656172672e3064747970656d4d75746174696f6e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c666566666563746d746578742e72656164466163746762696e64696e67a3626964676c6f63616c2e3064747970656c4d75746174696f6e556e697469616c7068614e616d6567246c6f63616c306e6f62737472756374696f6e4d6170a0666c6f63616c7382a3626964656172672e3064747970656d4d75746174696f6e496e70757469616c7068614e616d65652461726730a3626964676c6f63616c2e3064747970656c4d75746174696f6e556e697469616c7068614e616d6567246c6f63616c3066726573756c74a263726566a3626964676c6f63616c2e3064747970656c4d75746174696f6e556e697469616c7068614e616d6567246c6f63616c30646b696e64656c6f63616c65696e7075746d4d75746174696f6e496e707574666f75747075746c4d75746174696f6e556e697470696e707574436f6e73747261696e74738074636f72654576616c756174696f6e427564676574a3686d617853746570731a001000006e6d61784f757470757442797465731a00800000716d6178416c6c6f636174656442797465731a01000000781872657175697265644f7065726174696f6e50726f66696c657822636f6e74696e75756d2e70726f66696c652e67726170682d656666656374732f76316a61706956657273696f6e6d65646963742e636f72652f76316a636f6f7264696e617465781a6a656469742e746578742e7265706c6163655f72616e6765403178187265717569726564436f72654361706162696c697469657380726c6f776572696e675f617274696661637473a56f736f757263655f61727469666163745902d55902d27061636b616765206a656469742e746578742e7265706c6163655f72616e676540313b0a757365206c61777061636b206a656469742e7465787440312064696765737420227368613235363a343636373064313131313933393333316435316263653531393531353730323330666535323931393665643531656265663563386465346138613037643237322220617320746578743b0a7479706520496e707574203d207b20616464726573733a20746578742e46616374416464726573732c2065787065637465643a20746578742e466163744279746573207d3b0a696e74656e74207265706c61636552616e676528696e7075743a20496e707574292072657475726e7320746578742e4661637442797465730a202070726f66696c6520746578742e7265706c61636552616e67650a2020626173697320696e7075742e616464726573732e6e6f646549640a2020627564676574203c3d20746578742e7265706c61636552616e67654275646765740a7b0a20206c65742061637475616c3a20746578742e466163744279746573203d20746578742e726561644661637428696e7075742e61646472657373290a20202020656c7365207b0a2020202020206d697373696e67286164647265737329203d3e20746578742e466163744d697373696e672c0a202020202020747970654d69736d61746368286164647265737329203d3e20746578742e466163744d616c666f726d65642c0a2020202020206e6f7441746f6d286164647265737329203d3e20746578742e466163744d616c666f726d65642c0a202020202020746f6f4c61726765286164647265737329203d3e20746578742e466163744d616c666f726d65642c0a202020207d3b0a2020726571756972652061637475616c203d3d20696e7075742e657870656374656420656c736520746578742e42617369734e6f7443616e6f6e6963616c3b0a202072657475726e2061637475616c3b0a7d0a70616461707465725f6172746966616374590313a565636c6173736b6465636c617261746976656762756467657473a1781f6a656469742e7465787440312e7265706c61636552616e6765427564676574a3686d617853746570731a001000006e6d61784f757470757442797465731a00800000716d6178416c6c6f636174656442797465731a010000006a61706956657273696f6e781865646963742e6c61777061636b2d616461707465722f7631716f7065726174696f6e50726f66696c6573a178196a656469742e7465787440312e7265706c61636552616e6765a464636f72657822636f6e74696e75756d2e70726f66696c652e67726170682d656666656374732f76316f73656d616e7469634566666563747381756a656469742e7465787440312e7265616446616374706275646765744f626c69676174696f6e781f6a656469742e7465787440312e7265706c61636552616e676542756467657473746172676574436f6e66696775726174696f6ea262696478286563686f2e6f7065726174696f6e2d6c6f776572696e672d636f6e66696775726174696f6e2f7631666469676573748266736861323536582056921f7058a4b68027c3e5415150b2c6ef4388b000c2ea649cd7a14d3f565f7e75656666656374496d706c656d656e746174696f6e73a1756a656469742e7465787440312e7265616446616374a66a7772697465436c61737366656e737572656e636f73744f626c69676174696f6e781f6a656469742e7465787440312e7265706c61636552616e67654275646765746f6661696c7572654d617070696e6773a06f746172676574496e7472696e736963766563686f2e64706f40312e656e737572652d6e6f646573666f6f747072696e744f626c69676174696f6e78226a656469742e7465787440312e7265706c61636552616e6765466f6f747072696e7473746172676574436f6e66696775726174696f6ea262696478286563686f2e6f7065726174696f6e2d6c6f776572696e672d636f6e66696775726174696f6e2f7631666469676573748266736861323536582056921f7058a4b68027c3e5415150b2c6ef4388b000c2ea649cd7a14d3f565f7e706c61777061636b5f6172746966616374590313aa6269646a6a656469742e74657874676578706f727473a2626964756a656469742e746578742e6578706f7274732f763166646967657374826673686132353658204fbbde0e4bf5d0467b916d263dba80188a9b735dc772b5a151b18d15c0f1e7096776657273696f6e6131687665726966696572a265636c6173736b6465636c617261746976656772756c65736574a2626964781c6a656469742e746578742e76657269666965722d72756c65732f76316664696765737482667368613235365820364fb4ff98ae64fcd8d793aae3d7cb133ff8a1ce661330cea47688b13a0a823f6a61706956657273696f6e7065646963742e6c61777061636b2f76316c646570656e64656e63696573806d636f6d7061746962696c697479a2626964781b6a656469742e746578742e636f6d7061746962696c6974792f763166646967657374826673686132353658202adf83f798205f52636ad64ca45178f33a8e1cc663874f8a6113484c945e30526e746172676574416461707465727381a36761646170746572a2626964781a6a656469742e746578742e6563686f2d616461707465722f76316664696765737482667368613235365820d6dd1b959db13e24dd6d1c3b539d9026acaaab4cb6fd76f9a51c902962a9d4877061636365707465645461726765744972a26269646f6563686f2e7370616e2d69722f76326664696765737482667368613235365820123e7f805dc5e831e88befec4cd49ec02c39858b6f3990da8a73b50c6086ae3975616363657074656454617267657450726f66696c65a26269646a6563686f2e64706f4031666469676573748266736861323536582098a018bef66bb611638edd2d06d25531f30de6c49651c5e684d73392527a2d316f6163636570746564436f7265416269816d65646963742e636f72652f76317818636f6e666f726d616e636546697874757265436f72707573a262696478206a656469742e746578742e5265706c61636552616e67652e6f7261636c6540316664696765737482667368613235365820b9b4707dd5e07897cbe7af36d88928401887e6af5d167d1a88a8d6181b4dbb0e73696e7472696e736963735f6172746966616374590195a26a61706956657273696f6e782265646963742e7461726765742d70726f66696c652e696e7472696e736963732f76316a696e7472696e73696373a1766563686f2e64706f40312e656e737572652d6e6f6465ab6a6566666563744b696e6466656e737572656a72657475726e54797065781d6563686f2e64706f40312e656e737572652d6e6f64652e726573756c746a7772697465436c61737366656e737572656c636f737454656d706c617465781f6a656469742e7465787440312e7265706c61636552616e67654275646765746c6775617264537570706f7274f56d617267756d656e74547970657381781c6563686f2e64706f40312e656e737572652d6e6f64652e696e7075746e6566666563744661696c75726573a06e696e7472696e736963436c617373666566666563746e74797065506172616d65746572738071666f6f747072696e7454656d706c61746578226a656469742e7465787440312e7265706c61636552616e6765466f6f747072696e74781b63616e5061727469636970617465496e41746f6d69634775617264f5777461726765745f70726f66696c655f61727469666163745906fbb81c626964686563686f2e64706f676c6f7765726572a2626964736563686f2e64706f2e6c6f77657265722f7631666469676573748266736861323536582044ca28eeeccc4ff522fd9ec7e4694124f4e04880171c8cce460eefcb9505b7976773616e64626f78a26269647765646963742e7761736d2d636f6d706f6e656e742f76316664696765737482667368613235365820095b4dd18f1a6a7276533f758665be319c5f476e7bdc70cc56d30b6b3e9f0a806776657273696f6e6131687461726765744972a26269646f6563686f2e7370616e2d69722f76326664696765737482667368613235365820123e7f805dc5e831e88befec4cd49ec02c39858b6f3990da8a73b50c6086ae39687665726966696572a2626964746563686f2e64706f2e76657269666965722f76316664696765737482667368613235365820ca96b190728de3d668072ec1bd37d24e5197e7bd9bd54f70966d8c566b9b67f2696675656c4d6f64656ca26269646d65646963742e6675656c2f76316664696765737482667368613235365820006c6ebc01a3c5d36d50bd390b69d47e42378be61074e3b5c96ecb9f5ee532076a61706956657273696f6e7765646963742e7461726765742d70726f66696c652f76316a696e7472696e73696373a2626964766563686f2e64706f2e696e7472696e736963732f7631666469676573748266736861323536582055a364ea3e31b10eb7ba65d9310fa1ece48a8f4a5c9e5705b990c1a2c3397f586b636f7374416c6765627261a2626964706563686f2e64706f2e636f73742f76316664696765737482667368613235365820486940acd1d4bc15cea40db29347619a07202d9c0f1e63c4016c26bccf0b52a86b6d756c7469546172676574f46d62756e646c6550726f66696c65a2626964726563686f2e64706f2e62756e646c652f76316664696765737482667368613235365820aa0438bcc6ef14ee6cb6d4976622f6080381d731459dcb7b9102595c9bed92c06d646961676e6f73746963416269a26269647465646963742e646961676e6f73746963732f7631666469676573748266736861323536582028fd72a98223153982ca084c29dbb1b2d430623967ab3b6db9d7fee668e614b96f6163636570746564436f7265416269816d65646963742e636f72652f76316f67756172644576616c756174696f6e70707265636f6d6d69742d61746f6d69636f72656164436f6e73697374656e6379746170706c69636174696f6e2d736e617073686f74706170706c69636174696f6e4d6f64656c6661746f6d696370666f6f747072696e74416c6765627261a2626964756563686f2e64706f2e666f6f747072696e742f76316664696765737482667368613235365820f47bb65867e78099ddcfd6ae7af83870df8823f974a496a111ed94e5d785c769716f7065726174696f6e50726f66696c6573a2626964781e6563686f2e64706f2e6f7065726174696f6e2d70726f66696c65732f7631666469676573748266736861323536582053256c51f6c817a77cc8694458bf9d3891abd15b9c94f79ca97d920d3c5f041672696e7472696e7369634e616d6573706163656a6563686f2e64706f4031736f62737472756374696f6e526f6c6c6261636b726e6f2d76697369626c652d65666665637473736f62737472756374696f6e5461786f6e6f6d79a262696478186563686f2e64706f2e6f62737472756374696f6e732f763166646967657374826673686132353658204f5a139d606053c3807f50710076ea9abeb0e611c12a530f5e5b4b31911c3e6474706f7374636f6e646974696f6e537570706f7274f57663616e6f6e6963616c456e636f64696e6752756c6573a26269647765646963742e63616e6f6e6963616c2d63626f722f76316664696765737482667368613235365820d1ea6d3de2a9762a438cbf4fac1d5ae2f357a4b27d13e0347e94ea655bf40f9d7664657465726d696e6973746963457865637574696f6ea26269647465646963742e64657465726d696e69736d2f76316664696765737482667368613235365820af4e6c774d5ea82db30e680be2ba7abc5ba04c6aead146139de32d8c5bb4981e7818636f6e666f726d616e636546697874757265436f72707573a2626964746563686f2e64706f2e66697874757265732f763166646967657374826673686132353658208fa81d37ae4eecb79252f310e7532fc9872bd7c17f2722da911fa74620f81b43781961636365707465644c61777061636b4164617074657241626981781865646963742e6c61777061636b2d616461707465722f7631781967656e657261746564417274696661637450726f66696c657381a262696478186563686f2e64706f2e726567697374726174696f6e2f76316664696765737482667368613235365820ff88be93c26cc533948d8a93601954dc391912d593ca1e96115c846cbf2c5b5d727461726765745f69725f6172746966616374590379a6646b696e64776f7264657265645461726765744972417274696661637466646f6d61696e6f6563686f2e7370616e2d69722f763267696e74656e7473a16c7265706c61636552616e6765a765737465707381a7626964686566666563742e3065696e707574a263726566a3626964656172672e3064747970656d4d75746174696f6e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c666566666563746d746578742e72656164466163746762696e64696e67a3626964676c6f63616c2e3064747970656c4d75746174696f6e556e697469616c7068614e616d6567246c6f63616c306f6f62737472756374696f6e41726d73a06f746172676574496e7472696e736963766563686f2e64706f40312e656e737572652d6e6f6465736f62737472756374696f6e4661696c757265738066726573756c74a263726566a3626964676c6f63616c2e3064747970656c4d75746174696f6e556e697469616c7068614e616d6567246c6f63616c30646b696e64656c6f63616c6c726571756972656d656e7473806e657865637574696f6e4f7264657281686566666563742e3070696e707574436f6e73747261696e747380706f7065726174696f6e50726f66696c657822636f6e74696e75756d2e70726f66696c652e67726170682d656666656374732f763174636f72654576616c756174696f6e427564676574a3686d617853746570731a001000006e6d61784f757470757442797465731a00800000716d6178416c6c6f636174656442797465731a010000006d74617267657450726f66696c65a26269646a6563686f2e64706f4031666469676573748266736861323536582098a018bef66bb611638edd2d06d25531f30de6c49651c5e684d73392527a2d316f73656d616e746963436c6f73757265a2686c61777061636b7381a26269646c6a656469742e746578744031666469676573748266736861323536582046670d1111939331d51bce51951570230fe529196ed51ebef5c8de4a8a07d2726a736f75726365436f7265a2626964781a6a656469742e746578742e7265706c6163655f72616e676540316664696765737482667368613235365820d684c0305c19d8cb690d4fff267a09c4a06a8adf1a81d0257cc5a66c85aac76374736f75726365436f7265436f6f7264696e617465781a6a656469742e746578742e7265706c6163655f72616e6765403178186c61777061636b5f6578706f7274735f6172746966616374590544a665747970657383a26a636f6f7264696e61746578186a656469742e7465787440312e46616374416464726573736a646566696e6974696f6e784c5265636f72643c6e6f646549643a42797465733c65786163743d33323e2c7479706549643a42797465733c65786163743d33323e2c7761727049643a42797465733c65786163743d33323e3ea26a636f6f7264696e617465766a656469742e7465787440312e4661637442797465736a646566696e6974696f6e7242797465733c6d61783d313034383537363ea26a636f6f7264696e617465781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6a646566696e6974696f6e7822537472696e673c6d61783d3235362c63616e6f6e6963616c3d7261772d757466383e676566666563747381aa69696e707574547970656d4d75746174696f6e496e7075746a636f6f7264696e617465756a656469742e7465787440312e72656164466163746a6f7574707574547970656c4d75746174696f6e556e69746c6775617264537570706f7274f56e636f73744f626c69676174696f6e781f6a656469742e7465787440312e7265706c61636552616e67654275646765746e6566666563744661696c75726573a06e6566666563744b696e6448696e7464726561646e657865637574696f6e436c6173736772756e74696d656e74797065506172616d65746572738073666f6f747072696e744f626c69676174696f6e78226a656469742e7465787440312e7265706c61636552616e6765466f6f747072696e7469636f6e7374616e7473806c6f62737472756374696f6e7383a36a636f6f7264696e617465781e6a656469742e7465787440312e42617369734e6f7443616e6f6e6963616c6d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736e646f6d61696e4d61707061626c65a36a636f6f7264696e61746578186a656469742e7465787440312e466163744d697373696e676d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736d7265736f757263654661756c74a36a636f6f7264696e617465781a6a656469742e7465787440312e466163744d616c666f726d65646d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736e696e746567726974794661756c746d7075726546756e6374696f6e7380716f7065726174696f6e50726f66696c6573a178196a656469742e7465787440312e7265706c61636552616e6765a26d6f7074696354656d706c617465a6696f707469634b696e64736166666563745265696e746567726174696f6e6c626f756e646172794b696e64666166666563746d626173697354656d706c617465781b6a656469742e7465787440312e65786163744865616442617369736d737570706f7274506f6c696379781e6a656469742e7465787440312e6261736973426f756e64537570706f72746f6c6f7373446973706f736974696f6e756a656469742e7465787440312e6c6f73736c657373736170657274757265526571756972656d656e74a26372656678226a656469742e7465787440312e7265706c61636552616e6765466f6f747072696e74646b696e64781b6162737472616374466f6f747072696e744f626c69676174696f6e6f65666665637450726564696361746578206a656469742e7465787440312e7265706c61636552616e676545666665637473706d61785f726573756c745f62797465731a00010000727461726765745f69725f6964656e7469747958203fb8c873345b66e29e182a2088083b3e10b2e1a3a30b076bd7914bf6552a6b33736d61785f616c6c6f63617465645f62797465731a01000000781a696e7472696e7369635f70726f66696c655f6964656e746974795820a0fc1b7a1e186598291754469fd6ea2220f676358284f7b84c7e2476901a3151781c696e7465727072657465725f70726f66696c655f6964656e746974795820eaa6f8ca4f395d291fdb70af1bd47b804ab82aa17fdbc01b8aaeeb747f7d218c6e6275646765745f6365696c696e67a3657374657073016a726561645f6279746573006b77726974655f6279746573007073656d616e7469635f636c6f73757265a66d636f72655f6964656e746974795820d684c0305c19d8cb690d4fff267a09c4a06a8adf1a81d0257cc5a66c85aac763727461726765745f69725f6964656e7469747958203fb8c873345b66e29e182a2088083b3e10b2e1a3a30b076bd7914bf6552a6b337565646963745f736f757263655f6964656e7469747958200101010101010101010101010101010101010101010101010101010101010101781a63616e6f6e6963616c5f6d65616e696e675f6964656e7469747958200303030303030303030303030303030303030303030303030303030303030303781b6170706c69636174696f6e5f736368656d615f6964656e7469747958204fbbde0e4bf5d0467b916d263dba80188a9b735dc772b5a151b18d15c0f1e709781d6170706c69636174696f6e5f736368656d615f636f6f7264696e6174656a6170702e536368656d61746f7065726174696f6e5f636f6f7264696e61746578276a656469742e746578742e7265706c6163655f72616e676540312e7265706c61636552616e676575696e7075745f736368656d615f6964656e746974795820d277705b5ab03fcb58590bad62fb8058e075c3b4c65efc21282bb531aa22b3ad76726573756c745f736368656d615f6964656e746974795820de5c0c4f0c640354c40bb4f9d4886cd820353a548caea4953269eba15fe902bc777461726765745f70726f66696c655f6964656e746974795820eaca21c05664241efd1e1c5b5636c7132fe8854f6bcaddb2fd4f014e1bd4a479781a617574686f726974795f70726f66696c655f6964656e7469747958200808080808080808080808080808080808080808080808080808080808080808781a696e7472696e7369635f70726f66696c655f6964656e746974795820a0fc1b7a1e186598291754469fd6ea2220f676358284f7b84c7e2476901a3151781b666f6f747072696e745f636f6e74726163745f6964656e746974795820362b20fb18488ce180f6c1096b5189994354604fd1b1b126a3ea4ef839e5232b781b6f62737472756374696f6e5f736368656d615f6964656e746974795820b1f96fdf3ec65e84d500702951393a931b4fdd843ad02723ea3725f90a671418781c696e7465727072657465725f70726f66696c655f6964656e746974795820eaa6f8ca4f395d291fdb70af1bd47b804ab82aa17fdbc01b8aaeeb747f7d218c781e726573756c745f696e746572707265746174696f6e5f6964656e74697479582042734d5e73435acc0fdd5a66b97e5bfd94278e64fce2b4890ec609f054dc969e78206576616c756174696f6e5f62617369735f736368656d615f6964656e74697479582020b6239db569aa86ae1c27596b374df90caa5ea41e8e005fd4fe00bfe5c3b38178216170706c69636174696f6e5f62617369735f736368656d615f6964656e7469747958208b294c69120a2e749c56266691b0974e7e0323c198fc42a467fd3790790f791078236f62737472756374696f6e5f696e746572707265746174696f6e5f6964656e746974795820924462071f3992b34c629f4788cc666bd14a87a0b9d0c398feba929ff4dd25f9 diff --git a/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/failure-mapping-duplicate.hex b/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/failure-mapping-duplicate.hex new file mode 100644 index 00000000..8e128e70 --- /dev/null +++ b/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/failure-mapping-duplicate.hex @@ -0,0 +1 @@ +b166736368656d6178196563686f2e6f7065726174696f6e2d7061636b6167652f76316770726f6772616d59304cad646b696e647765646963742d6566666563742d70726f6772616d2f763166736368656d6178196563686f2e6f7065726174696f6e2d70726f6772616d2f76316b6f75747075745f74797065766a656469742e7465787440312e4661637442797465736c67726170685f736368656d615876a26a656467655f7479706573a06a6e6f64655f7479706573a158200101010101010101010101010101010101010101010101010101010101010101a26a61646472657373696e67016a61746f6d5f747970657381582002020202020202020202020202020202020202020202020202020202020202026c6964656e746974795f6c6177016d666f6f747072696e745f6c617758f6a9696d61785f7265616473016a61746f6d5f747970657381582002020202020202020202020202020202020202020202020202020202020202026a6d61785f777269746573016f6d61785f72616e67655f6564676573006f726561645f6e6f64655f747970657381582001010101010101010101010101010101010101010101010101010101010101017072616e67655f656467655f7479706573807077726974655f656467655f7479706573807077726974655f6e6f64655f7479706573815820010101010101010101010101010101010101010101010101010101010101010172706f7274616c5f6f776e65725f7479706573806f6d61785f696e7075745f62797465731a0001000070636f6d70696c65645f70726f6772616d592d45a666696e74656e746c7265706c61636552616e676566736368656d6178286563686f2e636f6d70696c65722d70726f64756365642d6566666563742d70726f6772616d2f76316d636f72655f61727469666163745909caa6657479706573a365496e707574a2646b696e64665265636f7264666669656c6473a2676164647265737378186a656469742e7465787440312e4661637441646472657373686578706563746564766a656469742e7465787440312e466163744279746573766a656469742e7465787440312e466163744279746573a2636d61781a00100000646b696e6465427974657378186a656469742e7465787440312e4661637441646472657373a2646b696e64665265636f7264666669656c6473a3666e6f646549646f42797465733c65786163743d33323e667479706549646f42797465733c65786163743d33323e667761727049646f42797465733c65786163743d33323e67696d706f72747381a263726566a26269646c6a656469742e7465787440316664696765737482667368613235365820a1b7eb83c4b1f73ed65745f7dde6c110f2f6936aa4733743e932b836c525cce2646b696e64676c61777061636b67696e74656e7473a16c7265706c61636552616e6765a764626f6479a3656e6f64657382a5646b696e646665666665637465696e707574a36462617365a263726566a3626964656172672e30647479706578206a656469742e746578742e7265706c6163655f72616e676540312e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646761646472657373666566666563746d746578742e72656164466163746762696e64696e67a3626964676c6f63616c2e306474797065766a656469742e7465787440312e46616374427974657369616c7068614e616d6567246c6f63616c306e6f62737472756374696f6e4d6170a4676d697373696e67a26576616c7565a4646172677380646b696e646463616c6c6663616c6c656570746578742e466163744d697373696e67687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e30647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e30676e6f7441746f6da26576616c7565a4646172677380646b696e646463616c6c6663616c6c656572746578742e466163744d616c666f726d6564687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e31647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e3168746f6f4c61726765a26576616c7565a4646172677380646b696e646463616c6c6663616c6c656572746578742e466163744d616c666f726d6564687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e32647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e326c747970654d69736d61746368a26576616c7565a4646172677380646b696e646463616c6c6663616c6c656572746578742e466163744d616c666f726d6564687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e33647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e33a3646b696e646772657175697265696f6e4661696c757265a2646b696e64687465726d696e616c66726561736f6ea2677061796c6f6164a06a726561736f6e4b696e6476746578742e42617369734e6f7443616e6f6e6963616c69707265646963617465a4626f70623d3d646b696e6467636f6d70617265646c656674a263726566a3626964676c6f63616c2e306474797065766a656469742e7465787440312e46616374427974657369616c7068614e616d6567246c6f63616c30646b696e64656c6f63616c657269676874a36462617365a263726566a3626964656172672e30647479706578206a656469742e746578742e7265706c6163655f72616e676540312e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c64686578706563746564666c6f63616c7386a3626964656172672e30647479706578206a656469742e746578742e7265706c6163655f72616e676540312e496e70757469616c7068614e616d65652461726730a3626964676c6f63616c2e306474797065766a656469742e7465787440312e46616374427974657369616c7068614e616d6567246c6f63616c30a36269646d6f62737472756374696f6e2e30647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e30a36269646d6f62737472756374696f6e2e31647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e31a36269646d6f62737472756374696f6e2e32647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e32a36269646d6f62737472756374696f6e2e33647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e3366726573756c74a263726566a3626964676c6f63616c2e306474797065766a656469742e7465787440312e46616374427974657369616c7068614e616d6567246c6f63616c30646b696e64656c6f63616c656261736973a36462617365a36462617365a263726566a3626964656172672e30647479706578206a656469742e746578742e7265706c6163655f72616e676540312e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646761646472657373646b696e64656669656c64656669656c64666e6f6465496465696e70757478206a656469742e746578742e7265706c6163655f72616e676540312e496e707574666f7574707574766a656469742e7465787440312e46616374427974657370696e707574436f6e73747261696e74738074636f72654576616c756174696f6e427564676574a3686d617853746570731a004000006e6d61784f757470757442797465731a00800000716d6178416c6c6f636174656442797465731a01000000781872657175697265644f7065726174696f6e50726f66696c65781e636f6e74696e75756d2e70726f66696c652e726561642d6f6e6c792f76316a61706956657273696f6e6d65646963742e636f72652f76316a636f6f7264696e617465781a6a656469742e746578742e7265706c6163655f72616e6765403178187265717569726564436f72654361706162696c697469657380726c6f776572696e675f617274696661637473a56f736f757263655f61727469666163745902d55902d27061636b616765206a656469742e746578742e7265706c6163655f72616e676540313b0a757365206c61777061636b206a656469742e7465787440312064696765737420227368613235363a613162376562383363346231663733656436353734356637646465366331313066326636393336616134373333373433653933326238333663353235636365322220617320746578743b0a7479706520496e707574203d207b20616464726573733a20746578742e46616374416464726573732c2065787065637465643a20746578742e466163744279746573207d3b0a696e74656e74207265706c61636552616e676528696e7075743a20496e707574292072657475726e7320746578742e4661637442797465730a202070726f66696c6520746578742e7265706c61636552616e67650a2020626173697320696e7075742e616464726573732e6e6f646549640a2020627564676574203c3d20746578742e7265706c61636552616e67654275646765740a7b0a20206c65742061637475616c3a20746578742e466163744279746573203d20746578742e726561644661637428696e7075742e61646472657373290a20202020656c7365207b0a2020202020206d697373696e67286164647265737329203d3e20746578742e466163744d697373696e672c0a202020202020747970654d69736d61746368286164647265737329203d3e20746578742e466163744d616c666f726d65642c0a2020202020206e6f7441746f6d286164647265737329203d3e20746578742e466163744d616c666f726d65642c0a202020202020746f6f4c61726765286164647265737329203d3e20746578742e466163744d616c666f726d65642c0a202020207d3b0a2020726571756972652061637475616c203d3d20696e7075742e657870656374656420656c736520746578742e42617369734e6f7443616e6f6e6963616c3b0a202072657475726e2061637475616c3b0a7d0a70616461707465725f6172746966616374590376a565636c6173736b6465636c617261746976656762756467657473a1781f6a656469742e7465787440312e7265706c61636552616e6765427564676574a3686d617853746570731a001000006e6d61784f757470757442797465731a00800000716d6178416c6c6f636174656442797465731a010000006a61706956657273696f6e781865646963742e6c61777061636b2d616461707465722f7631716f7065726174696f6e50726f66696c6573a178196a656469742e7465787440312e7265706c61636552616e6765a464636f7265781e636f6e74696e75756d2e70726f66696c652e726561642d6f6e6c792f76316f73656d616e7469634566666563747381756a656469742e7465787440312e7265616446616374706275646765744f626c69676174696f6e781f6a656469742e7465787440312e7265706c61636552616e676542756467657473746172676574436f6e66696775726174696f6ea262696478286563686f2e6f7065726174696f6e2d6c6f776572696e672d636f6e66696775726174696f6e2f7631666469676573748266736861323536582056921f7058a4b68027c3e5415150b2c6ef4388b000c2ea649cd7a14d3f565f7e75656666656374496d706c656d656e746174696f6e73a1756a656469742e7465787440312e7265616446616374a66a7772697465436c61737364726561646e636f73744f626c69676174696f6e781f6a656469742e7465787440312e7265706c61636552616e67654275646765746f6661696c7572654d617070696e6773a4676d697373696e676b61746f6d4d697373696e67676e6f7441746f6d6b61746f6d4d697373696e6768746f6f4c617267657561746f6d42797465426f756e6445786365656465646c747970654d69736d617463687061746f6d547970654d69736d617463686f746172676574496e7472696e73696378196563686f2e64706f40312e6e6f64652d61746f6d2d7265616473666f6f747072696e744f626c69676174696f6e78226a656469742e7465787440312e7265706c61636552616e6765466f6f747072696e7473746172676574436f6e66696775726174696f6ea262696478286563686f2e6f7065726174696f6e2d6c6f776572696e672d636f6e66696775726174696f6e2f7631666469676573748266736861323536582056921f7058a4b68027c3e5415150b2c6ef4388b000c2ea649cd7a14d3f565f7e706c61777061636b5f6172746966616374590313aa6269646a6a656469742e74657874676578706f727473a2626964756a656469742e746578742e6578706f7274732f763166646967657374826673686132353658200c75bcc42fd23d9eafdc81f1d81754be32cde98170c5fc1fbaf2746ffef992846776657273696f6e6131687665726966696572a265636c6173736b6465636c617261746976656772756c65736574a2626964781c6a656469742e746578742e76657269666965722d72756c65732f76316664696765737482667368613235365820364fb4ff98ae64fcd8d793aae3d7cb133ff8a1ce661330cea47688b13a0a823f6a61706956657273696f6e7065646963742e6c61777061636b2f76316c646570656e64656e63696573806d636f6d7061746962696c697479a2626964781b6a656469742e746578742e636f6d7061746962696c6974792f763166646967657374826673686132353658202adf83f798205f52636ad64ca45178f33a8e1cc663874f8a6113484c945e30526e746172676574416461707465727381a36761646170746572a2626964781a6a656469742e746578742e6563686f2d616461707465722f7631666469676573748266736861323536582098e398c10674f6a993af79e50e21ed199254c54143799d6e789c57d9a8da8a7f7061636365707465645461726765744972a26269646f6563686f2e7370616e2d69722f76326664696765737482667368613235365820123e7f805dc5e831e88befec4cd49ec02c39858b6f3990da8a73b50c6086ae3975616363657074656454617267657450726f66696c65a26269646a6563686f2e64706f40316664696765737482667368613235365820e9ba4aab52c815b673aa4b03165ab32863de5052c342b938005d1c0013d5c8fc6f6163636570746564436f7265416269816d65646963742e636f72652f76317818636f6e666f726d616e636546697874757265436f72707573a262696478206a656469742e746578742e5265706c61636552616e67652e6f7261636c6540316664696765737482667368613235365820b9b4707dd5e07897cbe7af36d88928401887e6af5d167d1a88a8d6181b4dbb0e73696e7472696e736963735f617274696661637459030aa26a61706956657273696f6e782265646963742e7461726765742d70726f66696c652e696e7472696e736963732f76316a696e7472696e73696373a178196563686f2e64706f40312e6e6f64652d61746f6d2d72656164ab6a6566666563744b696e6464726561646a72657475726e5479706578206563686f2e64706f40312e6e6f64652d61746f6d2d726561642e726573756c746a7772697465436c61737364726561646c636f737454656d706c617465781f6a656469742e7465787440312e7265706c61636552616e67654275646765746c6775617264537570706f7274f56d617267756d656e74547970657381781f6563686f2e64706f40312e6e6f64652d61746f6d2d726561642e696e7075746e6566666563744661696c75726573a46b61746f6d4d697373696e67a26b7061796c6f616454797065781f6563686f2e64706f40312e6e6f64652d61746f6d2d726561642e696e7075746e617574686f72697479436c6173736d7265736f757263654661756c746c61746f6d5265717569726564a26b7061796c6f616454797065781f6563686f2e64706f40312e6e6f64652d61746f6d2d726561642e696e7075746e617574686f72697479436c6173736e696e746567726974794661756c747061746f6d547970654d69736d61746368a26b7061796c6f616454797065781f6563686f2e64706f40312e6e6f64652d61746f6d2d726561642e696e7075746e617574686f72697479436c6173736e696e746567726974794661756c747561746f6d42797465426f756e644578636565646564a26b7061796c6f616454797065781f6563686f2e64706f40312e6e6f64652d61746f6d2d726561642e696e7075746e617574686f72697479436c6173736e696e746567726974794661756c746e696e7472696e736963436c617373666566666563746e74797065506172616d65746572738071666f6f747072696e7454656d706c61746578226a656469742e7465787440312e7265706c61636552616e6765466f6f747072696e74781b63616e5061727469636970617465496e41746f6d69634775617264f5777461726765745f70726f66696c655f61727469666163745906fbb81c626964686563686f2e64706f676c6f7765726572a2626964736563686f2e64706f2e6c6f77657265722f7631666469676573748266736861323536582044ca28eeeccc4ff522fd9ec7e4694124f4e04880171c8cce460eefcb9505b7976773616e64626f78a26269647765646963742e7761736d2d636f6d706f6e656e742f76316664696765737482667368613235365820095b4dd18f1a6a7276533f758665be319c5f476e7bdc70cc56d30b6b3e9f0a806776657273696f6e6131687461726765744972a26269646f6563686f2e7370616e2d69722f76326664696765737482667368613235365820123e7f805dc5e831e88befec4cd49ec02c39858b6f3990da8a73b50c6086ae39687665726966696572a2626964746563686f2e64706f2e76657269666965722f76316664696765737482667368613235365820ca96b190728de3d668072ec1bd37d24e5197e7bd9bd54f70966d8c566b9b67f2696675656c4d6f64656ca26269646d65646963742e6675656c2f76316664696765737482667368613235365820006c6ebc01a3c5d36d50bd390b69d47e42378be61074e3b5c96ecb9f5ee532076a61706956657273696f6e7765646963742e7461726765742d70726f66696c652f76316a696e7472696e73696373a2626964766563686f2e64706f2e696e7472696e736963732f76316664696765737482667368613235365820865e4a94955f49bc97975acd2ff7670d4576296d68a72de1bcacbb3d5b8cfb666b636f7374416c6765627261a2626964706563686f2e64706f2e636f73742f76316664696765737482667368613235365820486940acd1d4bc15cea40db29347619a07202d9c0f1e63c4016c26bccf0b52a86b6d756c7469546172676574f46d62756e646c6550726f66696c65a2626964726563686f2e64706f2e62756e646c652f76316664696765737482667368613235365820aa0438bcc6ef14ee6cb6d4976622f6080381d731459dcb7b9102595c9bed92c06d646961676e6f73746963416269a26269647465646963742e646961676e6f73746963732f7631666469676573748266736861323536582028fd72a98223153982ca084c29dbb1b2d430623967ab3b6db9d7fee668e614b96f6163636570746564436f7265416269816d65646963742e636f72652f76316f67756172644576616c756174696f6e70707265636f6d6d69742d61746f6d69636f72656164436f6e73697374656e6379746170706c69636174696f6e2d736e617073686f74706170706c69636174696f6e4d6f64656c6661746f6d696370666f6f747072696e74416c6765627261a2626964756563686f2e64706f2e666f6f747072696e742f76316664696765737482667368613235365820f47bb65867e78099ddcfd6ae7af83870df8823f974a496a111ed94e5d785c769716f7065726174696f6e50726f66696c6573a2626964781e6563686f2e64706f2e6f7065726174696f6e2d70726f66696c65732f7631666469676573748266736861323536582053256c51f6c817a77cc8694458bf9d3891abd15b9c94f79ca97d920d3c5f041672696e7472696e7369634e616d6573706163656a6563686f2e64706f4031736f62737472756374696f6e526f6c6c6261636b726e6f2d76697369626c652d65666665637473736f62737472756374696f6e5461786f6e6f6d79a262696478186563686f2e64706f2e6f62737472756374696f6e732f763166646967657374826673686132353658204f5a139d606053c3807f50710076ea9abeb0e611c12a530f5e5b4b31911c3e6474706f7374636f6e646974696f6e537570706f7274f57663616e6f6e6963616c456e636f64696e6752756c6573a26269647765646963742e63616e6f6e6963616c2d63626f722f76316664696765737482667368613235365820d1ea6d3de2a9762a438cbf4fac1d5ae2f357a4b27d13e0347e94ea655bf40f9d7664657465726d696e6973746963457865637574696f6ea26269647465646963742e64657465726d696e69736d2f76316664696765737482667368613235365820af4e6c774d5ea82db30e680be2ba7abc5ba04c6aead146139de32d8c5bb4981e7818636f6e666f726d616e636546697874757265436f72707573a2626964746563686f2e64706f2e66697874757265732f763166646967657374826673686132353658208fa81d37ae4eecb79252f310e7532fc9872bd7c17f2722da911fa74620f81b43781961636365707465644c61777061636b4164617074657241626981781865646963742e6c61777061636b2d616461707465722f7631781967656e657261746564417274696661637450726f66696c657381a262696478186563686f2e64706f2e726567697374726174696f6e2f76316664696765737482667368613235365820ff88be93c26cc533948d8a93601954dc391912d593ca1e96115c846cbf2c5b5d727461726765745f69725f617274696661637459087aa6646b696e64776f7264657265645461726765744972417274696661637466646f6d61696e6f6563686f2e7370616e2d69722f763267696e74656e7473a16c7265706c61636552616e6765a8656261736973a36462617365a36462617365a263726566a3626964656172672e30647479706578206a656469742e746578742e7265706c6163655f72616e676540312e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646761646472657373646b696e64656669656c64656669656c64666e6f6465496465737465707381a7626964737265706c61636552616e67652e737465702e3065696e707574a36462617365a263726566a3626964656172672e30647479706578206a656469742e746578742e7265706c6163655f72616e676540312e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646761646472657373666566666563746d746578742e72656164466163746762696e64696e67a3626964676c6f63616c2e306474797065766a656469742e7465787440312e46616374427974657369616c7068614e616d6567246c6f63616c306f6f62737472756374696f6e41726d73a46b61746f6d4d697373696e67a26576616c7565a4646172677380646b696e646463616c6c6663616c6c656570746578742e466163744d697373696e67687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e30647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e306c61746f6d5265717569726564a26576616c7565a4646172677380646b696e646463616c6c6663616c6c656572746578742e466163744d616c666f726d6564687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e31647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e317061746f6d547970654d69736d61746368a26576616c7565a4646172677380646b696e646463616c6c6663616c6c656572746578742e466163744d616c666f726d6564687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e33647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e337561746f6d42797465426f756e644578636565646564a26576616c7565a4646172677380646b696e646463616c6c6663616c6c656572746578742e466163744d616c666f726d6564687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e32647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e326f746172676574496e7472696e73696378196563686f2e64706f40312e6e6f64652d61746f6d2d72656164736f62737472756374696f6e4661696c75726573847561746f6d42797465426f756e6445786365656465646b61746f6d4d697373696e676c61746f6d52657175697265647061746f6d547970654d69736d6174636866726573756c74a263726566a3626964676c6f63616c2e306474797065766a656469742e7465787440312e46616374427974657369616c7068614e616d6567246c6f63616c30646b696e64656c6f63616c6c726571756972656d656e747381a3626964767265706c61636552616e67652e726571756972652e30696f6e4661696c757265a2646b696e64687465726d696e616c66726561736f6ea2677061796c6f6164a06a726561736f6e4b696e6476746578742e42617369734e6f7443616e6f6e6963616c69707265646963617465a4626f70623d3d646b696e6467636f6d70617265646c656674a263726566a3626964676c6f63616c2e306474797065766a656469742e7465787440312e46616374427974657369616c7068614e616d6567246c6f63616c30646b696e64656c6f63616c657269676874a36462617365a263726566a3626964656172672e30647479706578206a656469742e746578742e7265706c6163655f72616e676540312e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646865787065637465646e657865637574696f6e4f7264657282737265706c61636552616e67652e737465702e30767265706c61636552616e67652e726571756972652e3070696e707574436f6e73747261696e747380706f7065726174696f6e50726f66696c65781e636f6e74696e75756d2e70726f66696c652e726561642d6f6e6c792f763174636f72654576616c756174696f6e427564676574a3686d617853746570731a004000006e6d61784f757470757442797465731a00800000716d6178416c6c6f636174656442797465731a010000006d74617267657450726f66696c65a26269646a6563686f2e64706f40316664696765737482667368613235365820e9ba4aab52c815b673aa4b03165ab32863de5052c342b938005d1c0013d5c8fc6f73656d616e746963436c6f73757265a2686c61777061636b7381a26269646c6a656469742e7465787440316664696765737482667368613235365820a1b7eb83c4b1f73ed65745f7dde6c110f2f6936aa4733743e932b836c525cce26a736f75726365436f7265a2626964781a6a656469742e746578742e7265706c6163655f72616e6765403166646967657374826673686132353658204c7d662173eaedb9d90a584cbcce54c75e23214294b6a9517b4cf1ca77e3ad4074736f75726365436f7265436f6f7264696e617465781a6a656469742e746578742e7265706c6163655f72616e6765403178186c61777061636b5f6578706f7274735f6172746966616374590693a665747970657383a26a636f6f7264696e61746578186a656469742e7465787440312e46616374416464726573736a646566696e6974696f6e784c5265636f72643c6e6f646549643a42797465733c65786163743d33323e2c7479706549643a42797465733c65786163743d33323e2c7761727049643a42797465733c65786163743d33323e3ea26a636f6f7264696e617465766a656469742e7465787440312e4661637442797465736a646566696e6974696f6e7242797465733c6d61783d313034383537363ea26a636f6f7264696e617465781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6a646566696e6974696f6e7822537472696e673c6d61783d3235362c63616e6f6e6963616c3d7261772d757466383e676566666563747381aa69696e7075745479706578186a656469742e7465787440312e46616374416464726573736a636f6f7264696e617465756a656469742e7465787440312e72656164466163746a6f757470757454797065766a656469742e7465787440312e4661637442797465736c6775617264537570706f7274f56e636f73744f626c69676174696f6e781f6a656469742e7465787440312e7265706c61636552616e67654275646765746e6566666563744661696c75726573a4676d697373696e67a26b7061796c6f61645479706578186a656469742e7465787440312e46616374416464726573736e617574686f72697479436c6173736d7265736f757263654661756c74676e6f7441746f6da26b7061796c6f61645479706578186a656469742e7465787440312e46616374416464726573736e617574686f72697479436c6173736e696e746567726974794661756c7468746f6f4c61726765a26b7061796c6f61645479706578186a656469742e7465787440312e46616374416464726573736e617574686f72697479436c6173736e696e746567726974794661756c746c747970654d69736d61746368a26b7061796c6f61645479706578186a656469742e7465787440312e46616374416464726573736e617574686f72697479436c6173736e696e746567726974794661756c746e6566666563744b696e6448696e7464726561646e657865637574696f6e436c6173736772756e74696d656e74797065506172616d65746572738073666f6f747072696e744f626c69676174696f6e78226a656469742e7465787440312e7265706c61636552616e6765466f6f747072696e7469636f6e7374616e7473806c6f62737472756374696f6e7383a36a636f6f7264696e617465781e6a656469742e7465787440312e42617369734e6f7443616e6f6e6963616c6d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736e646f6d61696e4d61707061626c65a36a636f6f7264696e61746578186a656469742e7465787440312e466163744d697373696e676d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736d7265736f757263654661756c74a36a636f6f7264696e617465781a6a656469742e7465787440312e466163744d616c666f726d65646d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736e696e746567726974794661756c746d7075726546756e6374696f6e7380716f7065726174696f6e50726f66696c6573a178196a656469742e7465787440312e7265706c61636552616e6765a26d6f7074696354656d706c617465a6696f707469634b696e64736166666563745265696e746567726174696f6e6c626f756e646172794b696e64666166666563746d626173697354656d706c617465781b6a656469742e7465787440312e65786163744865616442617369736d737570706f7274506f6c696379781e6a656469742e7465787440312e6261736973426f756e64537570706f72746f6c6f7373446973706f736974696f6e756a656469742e7465787440312e6c6f73736c657373736170657274757265526571756972656d656e74a26372656678226a656469742e7465787440312e7265706c61636552616e6765466f6f747072696e74646b696e64781b6162737472616374466f6f747072696e744f626c69676174696f6e6f65666665637450726564696361746578206a656469742e7465787440312e7265706c61636552616e676545666665637473706d61785f726573756c745f62797465731a00010000727461726765745f69725f6964656e7469747958201f8c2b0efa9ecae8080cf7f675f479cef1250d3221ff85dbc28a01c45974dc4b736d61785f616c6c6f63617465645f62797465731a01000000781a696e7472696e7369635f70726f66696c655f6964656e746974795820a0fc1b7a1e186598291754469fd6ea2220f676358284f7b84c7e2476901a3151781c696e7465727072657465725f70726f66696c655f6964656e746974795820eaa6f8ca4f395d291fdb70af1bd47b804ab82aa17fdbc01b8aaeeb747f7d218c6e6275646765745f6365696c696e67a3657374657073016a726561645f6279746573006b77726974655f6279746573007073656d616e7469635f636c6f73757265a66d636f72655f6964656e7469747958204c7d662173eaedb9d90a584cbcce54c75e23214294b6a9517b4cf1ca77e3ad40727461726765745f69725f6964656e7469747958201f8c2b0efa9ecae8080cf7f675f479cef1250d3221ff85dbc28a01c45974dc4b7565646963745f736f757263655f6964656e7469747958200101010101010101010101010101010101010101010101010101010101010101781a63616e6f6e6963616c5f6d65616e696e675f6964656e7469747958200303030303030303030303030303030303030303030303030303030303030303781b6170706c69636174696f6e5f736368656d615f6964656e7469747958200c75bcc42fd23d9eafdc81f1d81754be32cde98170c5fc1fbaf2746ffef99284781d6170706c69636174696f6e5f736368656d615f636f6f7264696e6174656a6170702e536368656d61746f7065726174696f6e5f636f6f7264696e61746578276a656469742e746578742e7265706c6163655f72616e676540312e7265706c61636552616e676575696e7075745f736368656d615f6964656e746974795820d277705b5ab03fcb58590bad62fb8058e075c3b4c65efc21282bb531aa22b3ad76726573756c745f736368656d615f6964656e746974795820de5c0c4f0c640354c40bb4f9d4886cd820353a548caea4953269eba15fe902bc777461726765745f70726f66696c655f6964656e746974795820eaca21c05664241efd1e1c5b5636c7132fe8854f6bcaddb2fd4f014e1bd4a479781a617574686f726974795f70726f66696c655f6964656e7469747958200808080808080808080808080808080808080808080808080808080808080808781a696e7472696e7369635f70726f66696c655f6964656e746974795820a0fc1b7a1e186598291754469fd6ea2220f676358284f7b84c7e2476901a3151781b666f6f747072696e745f636f6e74726163745f6964656e746974795820362b20fb18488ce180f6c1096b5189994354604fd1b1b126a3ea4ef839e5232b781b6f62737472756374696f6e5f736368656d615f6964656e746974795820b1f96fdf3ec65e84d500702951393a931b4fdd843ad02723ea3725f90a671418781c696e7465727072657465725f70726f66696c655f6964656e746974795820eaa6f8ca4f395d291fdb70af1bd47b804ab82aa17fdbc01b8aaeeb747f7d218c781e726573756c745f696e746572707265746174696f6e5f6964656e74697479582042734d5e73435acc0fdd5a66b97e5bfd94278e64fce2b4890ec609f054dc969e78206576616c756174696f6e5f62617369735f736368656d615f6964656e74697479582020b6239db569aa86ae1c27596b374df90caa5ea41e8e005fd4fe00bfe5c3b38178216170706c69636174696f6e5f62617369735f736368656d615f6964656e7469747958208b294c69120a2e749c56266691b0974e7e0323c198fc42a467fd3790790f791078236f62737472756374696f6e5f696e746572707265746174696f6e5f6964656e746974795820924462071f3992b34c629f4788cc666bd14a87a0b9d0c398feba929ff4dd25f9 diff --git a/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/failure-mapping-tag-spelled.hex b/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/failure-mapping-tag-spelled.hex new file mode 100644 index 00000000..6f2485d7 --- /dev/null +++ b/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/failure-mapping-tag-spelled.hex @@ -0,0 +1 @@ +b166736368656d6178196563686f2e6f7065726174696f6e2d7061636b6167652f76316770726f6772616d59309fad646b696e647765646963742d6566666563742d70726f6772616d2f763166736368656d6178196563686f2e6f7065726174696f6e2d70726f6772616d2f76316b6f75747075745f74797065766a656469742e7465787440312e4661637442797465736c67726170685f736368656d615876a26a656467655f7479706573a06a6e6f64655f7479706573a158200101010101010101010101010101010101010101010101010101010101010101a26a61646472657373696e67016a61746f6d5f747970657381582002020202020202020202020202020202020202020202020202020202020202026c6964656e746974795f6c6177016d666f6f747072696e745f6c617758f6a9696d61785f7265616473016a61746f6d5f747970657381582002020202020202020202020202020202020202020202020202020202020202026a6d61785f777269746573016f6d61785f72616e67655f6564676573006f726561645f6e6f64655f747970657381582001010101010101010101010101010101010101010101010101010101010101017072616e67655f656467655f7479706573807077726974655f656467655f7479706573807077726974655f6e6f64655f7479706573815820010101010101010101010101010101010101010101010101010101010101010172706f7274616c5f6f776e65725f7479706573806f6d61785f696e7075745f62797465731a0001000070636f6d70696c65645f70726f6772616d592d98a666696e74656e746c7265706c61636552616e676566736368656d6178286563686f2e636f6d70696c65722d70726f64756365642d6566666563742d70726f6772616d2f76316d636f72655f61727469666163745909caa6657479706573a365496e707574a2646b696e64665265636f7264666669656c6473a2676164647265737378186a656469742e7465787440312e4661637441646472657373686578706563746564766a656469742e7465787440312e466163744279746573766a656469742e7465787440312e466163744279746573a2636d61781a00100000646b696e6465427974657378186a656469742e7465787440312e4661637441646472657373a2646b696e64665265636f7264666669656c6473a3666e6f646549646f42797465733c65786163743d33323e667479706549646f42797465733c65786163743d33323e667761727049646f42797465733c65786163743d33323e67696d706f72747381a263726566a26269646c6a656469742e7465787440316664696765737482667368613235365820295e3c5398ce0af7fac80f961a56b060f986627eb4d2518e9c39e6f2f6781974646b696e64676c61777061636b67696e74656e7473a16c7265706c61636552616e6765a764626f6479a3656e6f64657382a5646b696e646665666665637465696e707574a36462617365a263726566a3626964656172672e30647479706578206a656469742e746578742e7265706c6163655f72616e676540312e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646761646472657373666566666563746d746578742e72656164466163746762696e64696e67a3626964676c6f63616c2e306474797065766a656469742e7465787440312e46616374427974657369616c7068614e616d6567246c6f63616c306e6f62737472756374696f6e4d6170a4676d697373696e67a26576616c7565a4646172677380646b696e646463616c6c6663616c6c656570746578742e466163744d697373696e67687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e30647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e30676e6f7441746f6da26576616c7565a4646172677380646b696e646463616c6c6663616c6c656572746578742e466163744d616c666f726d6564687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e31647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e3168746f6f4c61726765a26576616c7565a4646172677380646b696e646463616c6c6663616c6c656572746578742e466163744d616c666f726d6564687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e32647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e326c747970654d69736d61746368a26576616c7565a4646172677380646b696e646463616c6c6663616c6c656572746578742e466163744d616c666f726d6564687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e33647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e33a3646b696e646772657175697265696f6e4661696c757265a2646b696e64687465726d696e616c66726561736f6ea2677061796c6f6164a06a726561736f6e4b696e6476746578742e42617369734e6f7443616e6f6e6963616c69707265646963617465a4626f70623d3d646b696e6467636f6d70617265646c656674a263726566a3626964676c6f63616c2e306474797065766a656469742e7465787440312e46616374427974657369616c7068614e616d6567246c6f63616c30646b696e64656c6f63616c657269676874a36462617365a263726566a3626964656172672e30647479706578206a656469742e746578742e7265706c6163655f72616e676540312e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c64686578706563746564666c6f63616c7386a3626964656172672e30647479706578206a656469742e746578742e7265706c6163655f72616e676540312e496e70757469616c7068614e616d65652461726730a3626964676c6f63616c2e306474797065766a656469742e7465787440312e46616374427974657369616c7068614e616d6567246c6f63616c30a36269646d6f62737472756374696f6e2e30647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e30a36269646d6f62737472756374696f6e2e31647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e31a36269646d6f62737472756374696f6e2e32647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e32a36269646d6f62737472756374696f6e2e33647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e3366726573756c74a263726566a3626964676c6f63616c2e306474797065766a656469742e7465787440312e46616374427974657369616c7068614e616d6567246c6f63616c30646b696e64656c6f63616c656261736973a36462617365a36462617365a263726566a3626964656172672e30647479706578206a656469742e746578742e7265706c6163655f72616e676540312e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646761646472657373646b696e64656669656c64656669656c64666e6f6465496465696e70757478206a656469742e746578742e7265706c6163655f72616e676540312e496e707574666f7574707574766a656469742e7465787440312e46616374427974657370696e707574436f6e73747261696e74738074636f72654576616c756174696f6e427564676574a3686d617853746570731a004000006e6d61784f757470757442797465731a00800000716d6178416c6c6f636174656442797465731a01000000781872657175697265644f7065726174696f6e50726f66696c65781e636f6e74696e75756d2e70726f66696c652e726561642d6f6e6c792f76316a61706956657273696f6e6d65646963742e636f72652f76316a636f6f7264696e617465781a6a656469742e746578742e7265706c6163655f72616e6765403178187265717569726564436f72654361706162696c697469657380726c6f776572696e675f617274696661637473a56f736f757263655f61727469666163745902d55902d27061636b616765206a656469742e746578742e7265706c6163655f72616e676540313b0a757365206c61777061636b206a656469742e7465787440312064696765737420227368613235363a323935653363353339386365306166376661633830663936316135366230363066393836363237656234643235313865396333396536663266363738313937342220617320746578743b0a7479706520496e707574203d207b20616464726573733a20746578742e46616374416464726573732c2065787065637465643a20746578742e466163744279746573207d3b0a696e74656e74207265706c61636552616e676528696e7075743a20496e707574292072657475726e7320746578742e4661637442797465730a202070726f66696c6520746578742e7265706c61636552616e67650a2020626173697320696e7075742e616464726573732e6e6f646549640a2020627564676574203c3d20746578742e7265706c61636552616e67654275646765740a7b0a20206c65742061637475616c3a20746578742e466163744279746573203d20746578742e726561644661637428696e7075742e61646472657373290a20202020656c7365207b0a2020202020206d697373696e67286164647265737329203d3e20746578742e466163744d697373696e672c0a202020202020747970654d69736d61746368286164647265737329203d3e20746578742e466163744d616c666f726d65642c0a2020202020206e6f7441746f6d286164647265737329203d3e20746578742e466163744d616c666f726d65642c0a202020202020746f6f4c61726765286164647265737329203d3e20746578742e466163744d616c666f726d65642c0a202020207d3b0a2020726571756972652061637475616c203d3d20696e7075742e657870656374656420656c736520746578742e42617369734e6f7443616e6f6e6963616c3b0a202072657475726e2061637475616c3b0a7d0a70616461707465725f61727469666163745903a0a565636c6173736b6465636c617261746976656762756467657473a1781f6a656469742e7465787440312e7265706c61636552616e6765427564676574a3686d617853746570731a001000006e6d61784f757470757442797465731a00800000716d6178416c6c6f636174656442797465731a010000006a61706956657273696f6e781865646963742e6c61777061636b2d616461707465722f7631716f7065726174696f6e50726f66696c6573a178196a656469742e7465787440312e7265706c61636552616e6765a464636f7265781e636f6e74696e75756d2e70726f66696c652e726561642d6f6e6c792f76316f73656d616e7469634566666563747381756a656469742e7465787440312e7265616446616374706275646765744f626c69676174696f6e781f6a656469742e7465787440312e7265706c61636552616e676542756467657473746172676574436f6e66696775726174696f6ea262696478286563686f2e6f7065726174696f6e2d6c6f776572696e672d636f6e66696775726174696f6e2f7631666469676573748266736861323536582056921f7058a4b68027c3e5415150b2c6ef4388b000c2ea649cd7a14d3f565f7e75656666656374496d706c656d656e746174696f6e73a1756a656469742e7465787440312e7265616446616374a66a7772697465436c61737364726561646e636f73744f626c69676174696f6e781f6a656469742e7465787440312e7265706c61636552616e67654275646765746f6661696c7572654d617070696e6773a4676d697373696e67746563686f2e61746f6d2d6d697373696e672f7631676e6f7441746f6d756563686f2e61746f6d2d72657175697265642f763168746f6f4c6172676578206563686f2e61746f6d2d627974652d626f756e642d65786365656465642f76316c747970654d69736d61746368781a6563686f2e61746f6d2d747970652d6d69736d617463682f76316f746172676574496e7472696e73696378196563686f2e64706f40312e6e6f64652d61746f6d2d7265616473666f6f747072696e744f626c69676174696f6e78226a656469742e7465787440312e7265706c61636552616e6765466f6f747072696e7473746172676574436f6e66696775726174696f6ea262696478286563686f2e6f7065726174696f6e2d6c6f776572696e672d636f6e66696775726174696f6e2f7631666469676573748266736861323536582056921f7058a4b68027c3e5415150b2c6ef4388b000c2ea649cd7a14d3f565f7e706c61777061636b5f6172746966616374590313aa6269646a6a656469742e74657874676578706f727473a2626964756a656469742e746578742e6578706f7274732f763166646967657374826673686132353658200c75bcc42fd23d9eafdc81f1d81754be32cde98170c5fc1fbaf2746ffef992846776657273696f6e6131687665726966696572a265636c6173736b6465636c617261746976656772756c65736574a2626964781c6a656469742e746578742e76657269666965722d72756c65732f76316664696765737482667368613235365820364fb4ff98ae64fcd8d793aae3d7cb133ff8a1ce661330cea47688b13a0a823f6a61706956657273696f6e7065646963742e6c61777061636b2f76316c646570656e64656e63696573806d636f6d7061746962696c697479a2626964781b6a656469742e746578742e636f6d7061746962696c6974792f763166646967657374826673686132353658202adf83f798205f52636ad64ca45178f33a8e1cc663874f8a6113484c945e30526e746172676574416461707465727381a36761646170746572a2626964781a6a656469742e746578742e6563686f2d616461707465722f76316664696765737482667368613235365820c614e7a07ee71f99a29bb4273b3f954e7edb82bb3dc353165730f14aeda0dad27061636365707465645461726765744972a26269646f6563686f2e7370616e2d69722f76326664696765737482667368613235365820123e7f805dc5e831e88befec4cd49ec02c39858b6f3990da8a73b50c6086ae3975616363657074656454617267657450726f66696c65a26269646a6563686f2e64706f4031666469676573748266736861323536582058a539926636f4163e7ad468f327ac3bd837996964fbceb0b766eafef3199bc76f6163636570746564436f7265416269816d65646963742e636f72652f76317818636f6e666f726d616e636546697874757265436f72707573a262696478206a656469742e746578742e5265706c61636552616e67652e6f7261636c6540316664696765737482667368613235365820b9b4707dd5e07897cbe7af36d88928401887e6af5d167d1a88a8d6181b4dbb0e73696e7472696e736963735f6172746966616374590333a26a61706956657273696f6e782265646963742e7461726765742d70726f66696c652e696e7472696e736963732f76316a696e7472696e73696373a178196563686f2e64706f40312e6e6f64652d61746f6d2d72656164ab6a6566666563744b696e6464726561646a72657475726e5479706578206563686f2e64706f40312e6e6f64652d61746f6d2d726561642e726573756c746a7772697465436c61737364726561646c636f737454656d706c617465781f6a656469742e7465787440312e7265706c61636552616e67654275646765746c6775617264537570706f7274f56d617267756d656e74547970657381781f6563686f2e64706f40312e6e6f64652d61746f6d2d726561642e696e7075746e6566666563744661696c75726573a4746563686f2e61746f6d2d6d697373696e672f7631a26b7061796c6f616454797065781f6563686f2e64706f40312e6e6f64652d61746f6d2d726561642e696e7075746e617574686f72697479436c6173736d7265736f757263654661756c74756563686f2e61746f6d2d72657175697265642f7631a26b7061796c6f616454797065781f6563686f2e64706f40312e6e6f64652d61746f6d2d726561642e696e7075746e617574686f72697479436c6173736e696e746567726974794661756c74781a6563686f2e61746f6d2d747970652d6d69736d617463682f7631a26b7061796c6f616454797065781f6563686f2e64706f40312e6e6f64652d61746f6d2d726561642e696e7075746e617574686f72697479436c6173736e696e746567726974794661756c7478206563686f2e61746f6d2d627974652d626f756e642d65786365656465642f7631a26b7061796c6f616454797065781f6563686f2e64706f40312e6e6f64652d61746f6d2d726561642e696e7075746e617574686f72697479436c6173736e696e746567726974794661756c746e696e7472696e736963436c617373666566666563746e74797065506172616d65746572738071666f6f747072696e7454656d706c61746578226a656469742e7465787440312e7265706c61636552616e6765466f6f747072696e74781b63616e5061727469636970617465496e41746f6d69634775617264f5777461726765745f70726f66696c655f61727469666163745906fbb81c626964686563686f2e64706f676c6f7765726572a2626964736563686f2e64706f2e6c6f77657265722f7631666469676573748266736861323536582044ca28eeeccc4ff522fd9ec7e4694124f4e04880171c8cce460eefcb9505b7976773616e64626f78a26269647765646963742e7761736d2d636f6d706f6e656e742f76316664696765737482667368613235365820095b4dd18f1a6a7276533f758665be319c5f476e7bdc70cc56d30b6b3e9f0a806776657273696f6e6131687461726765744972a26269646f6563686f2e7370616e2d69722f76326664696765737482667368613235365820123e7f805dc5e831e88befec4cd49ec02c39858b6f3990da8a73b50c6086ae39687665726966696572a2626964746563686f2e64706f2e76657269666965722f76316664696765737482667368613235365820ca96b190728de3d668072ec1bd37d24e5197e7bd9bd54f70966d8c566b9b67f2696675656c4d6f64656ca26269646d65646963742e6675656c2f76316664696765737482667368613235365820006c6ebc01a3c5d36d50bd390b69d47e42378be61074e3b5c96ecb9f5ee532076a61706956657273696f6e7765646963742e7461726765742d70726f66696c652f76316a696e7472696e73696373a2626964766563686f2e64706f2e696e7472696e736963732f7631666469676573748266736861323536582024161c04f815a73a6d1aee9536143600a7514db726830fbacacc853f192ed71f6b636f7374416c6765627261a2626964706563686f2e64706f2e636f73742f76316664696765737482667368613235365820486940acd1d4bc15cea40db29347619a07202d9c0f1e63c4016c26bccf0b52a86b6d756c7469546172676574f46d62756e646c6550726f66696c65a2626964726563686f2e64706f2e62756e646c652f76316664696765737482667368613235365820aa0438bcc6ef14ee6cb6d4976622f6080381d731459dcb7b9102595c9bed92c06d646961676e6f73746963416269a26269647465646963742e646961676e6f73746963732f7631666469676573748266736861323536582028fd72a98223153982ca084c29dbb1b2d430623967ab3b6db9d7fee668e614b96f6163636570746564436f7265416269816d65646963742e636f72652f76316f67756172644576616c756174696f6e70707265636f6d6d69742d61746f6d69636f72656164436f6e73697374656e6379746170706c69636174696f6e2d736e617073686f74706170706c69636174696f6e4d6f64656c6661746f6d696370666f6f747072696e74416c6765627261a2626964756563686f2e64706f2e666f6f747072696e742f76316664696765737482667368613235365820f47bb65867e78099ddcfd6ae7af83870df8823f974a496a111ed94e5d785c769716f7065726174696f6e50726f66696c6573a2626964781e6563686f2e64706f2e6f7065726174696f6e2d70726f66696c65732f7631666469676573748266736861323536582053256c51f6c817a77cc8694458bf9d3891abd15b9c94f79ca97d920d3c5f041672696e7472696e7369634e616d6573706163656a6563686f2e64706f4031736f62737472756374696f6e526f6c6c6261636b726e6f2d76697369626c652d65666665637473736f62737472756374696f6e5461786f6e6f6d79a262696478186563686f2e64706f2e6f62737472756374696f6e732f763166646967657374826673686132353658204f5a139d606053c3807f50710076ea9abeb0e611c12a530f5e5b4b31911c3e6474706f7374636f6e646974696f6e537570706f7274f57663616e6f6e6963616c456e636f64696e6752756c6573a26269647765646963742e63616e6f6e6963616c2d63626f722f76316664696765737482667368613235365820d1ea6d3de2a9762a438cbf4fac1d5ae2f357a4b27d13e0347e94ea655bf40f9d7664657465726d696e6973746963457865637574696f6ea26269647465646963742e64657465726d696e69736d2f76316664696765737482667368613235365820af4e6c774d5ea82db30e680be2ba7abc5ba04c6aead146139de32d8c5bb4981e7818636f6e666f726d616e636546697874757265436f72707573a2626964746563686f2e64706f2e66697874757265732f763166646967657374826673686132353658208fa81d37ae4eecb79252f310e7532fc9872bd7c17f2722da911fa74620f81b43781961636365707465644c61777061636b4164617074657241626981781865646963742e6c61777061636b2d616461707465722f7631781967656e657261746564417274696661637450726f66696c657381a262696478186563686f2e64706f2e726567697374726174696f6e2f76316664696765737482667368613235365820ff88be93c26cc533948d8a93601954dc391912d593ca1e96115c846cbf2c5b5d727461726765745f69725f617274696661637459087aa6646b696e64776f7264657265645461726765744972417274696661637466646f6d61696e6f6563686f2e7370616e2d69722f763267696e74656e7473a16c7265706c61636552616e6765a8656261736973a36462617365a36462617365a263726566a3626964656172672e30647479706578206a656469742e746578742e7265706c6163655f72616e676540312e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646761646472657373646b696e64656669656c64656669656c64666e6f6465496465737465707381a7626964737265706c61636552616e67652e737465702e3065696e707574a36462617365a263726566a3626964656172672e30647479706578206a656469742e746578742e7265706c6163655f72616e676540312e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646761646472657373666566666563746d746578742e72656164466163746762696e64696e67a3626964676c6f63616c2e306474797065766a656469742e7465787440312e46616374427974657369616c7068614e616d6567246c6f63616c306f6f62737472756374696f6e41726d73a46b61746f6d4d697373696e67a26576616c7565a4646172677380646b696e646463616c6c6663616c6c656570746578742e466163744d697373696e67687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e30647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e306c61746f6d5265717569726564a26576616c7565a4646172677380646b696e646463616c6c6663616c6c656572746578742e466163744d616c666f726d6564687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e31647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e317061746f6d547970654d69736d61746368a26576616c7565a4646172677380646b696e646463616c6c6663616c6c656572746578742e466163744d616c666f726d6564687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e33647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e337561746f6d42797465426f756e644578636565646564a26576616c7565a4646172677380646b696e646463616c6c6663616c6c656572746578742e466163744d616c666f726d6564687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e32647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e326f746172676574496e7472696e73696378196563686f2e64706f40312e6e6f64652d61746f6d2d72656164736f62737472756374696f6e4661696c75726573847561746f6d42797465426f756e6445786365656465646b61746f6d4d697373696e676c61746f6d52657175697265647061746f6d547970654d69736d6174636866726573756c74a263726566a3626964676c6f63616c2e306474797065766a656469742e7465787440312e46616374427974657369616c7068614e616d6567246c6f63616c30646b696e64656c6f63616c6c726571756972656d656e747381a3626964767265706c61636552616e67652e726571756972652e30696f6e4661696c757265a2646b696e64687465726d696e616c66726561736f6ea2677061796c6f6164a06a726561736f6e4b696e6476746578742e42617369734e6f7443616e6f6e6963616c69707265646963617465a4626f70623d3d646b696e6467636f6d70617265646c656674a263726566a3626964676c6f63616c2e306474797065766a656469742e7465787440312e46616374427974657369616c7068614e616d6567246c6f63616c30646b696e64656c6f63616c657269676874a36462617365a263726566a3626964656172672e30647479706578206a656469742e746578742e7265706c6163655f72616e676540312e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646865787065637465646e657865637574696f6e4f7264657282737265706c61636552616e67652e737465702e30767265706c61636552616e67652e726571756972652e3070696e707574436f6e73747261696e747380706f7065726174696f6e50726f66696c65781e636f6e74696e75756d2e70726f66696c652e726561642d6f6e6c792f763174636f72654576616c756174696f6e427564676574a3686d617853746570731a004000006e6d61784f757470757442797465731a00800000716d6178416c6c6f636174656442797465731a010000006d74617267657450726f66696c65a26269646a6563686f2e64706f4031666469676573748266736861323536582058a539926636f4163e7ad468f327ac3bd837996964fbceb0b766eafef3199bc76f73656d616e746963436c6f73757265a2686c61777061636b7381a26269646c6a656469742e7465787440316664696765737482667368613235365820295e3c5398ce0af7fac80f961a56b060f986627eb4d2518e9c39e6f2f67819746a736f75726365436f7265a2626964781a6a656469742e746578742e7265706c6163655f72616e67654031666469676573748266736861323536582000a327ca4e12916319db135a4fa2b2aa47ed9719eca14be79b7fd365966a565374736f75726365436f7265436f6f7264696e617465781a6a656469742e746578742e7265706c6163655f72616e6765403178186c61777061636b5f6578706f7274735f6172746966616374590693a665747970657383a26a636f6f7264696e61746578186a656469742e7465787440312e46616374416464726573736a646566696e6974696f6e784c5265636f72643c6e6f646549643a42797465733c65786163743d33323e2c7479706549643a42797465733c65786163743d33323e2c7761727049643a42797465733c65786163743d33323e3ea26a636f6f7264696e617465766a656469742e7465787440312e4661637442797465736a646566696e6974696f6e7242797465733c6d61783d313034383537363ea26a636f6f7264696e617465781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6a646566696e6974696f6e7822537472696e673c6d61783d3235362c63616e6f6e6963616c3d7261772d757466383e676566666563747381aa69696e7075745479706578186a656469742e7465787440312e46616374416464726573736a636f6f7264696e617465756a656469742e7465787440312e72656164466163746a6f757470757454797065766a656469742e7465787440312e4661637442797465736c6775617264537570706f7274f56e636f73744f626c69676174696f6e781f6a656469742e7465787440312e7265706c61636552616e67654275646765746e6566666563744661696c75726573a4676d697373696e67a26b7061796c6f61645479706578186a656469742e7465787440312e46616374416464726573736e617574686f72697479436c6173736d7265736f757263654661756c74676e6f7441746f6da26b7061796c6f61645479706578186a656469742e7465787440312e46616374416464726573736e617574686f72697479436c6173736e696e746567726974794661756c7468746f6f4c61726765a26b7061796c6f61645479706578186a656469742e7465787440312e46616374416464726573736e617574686f72697479436c6173736e696e746567726974794661756c746c747970654d69736d61746368a26b7061796c6f61645479706578186a656469742e7465787440312e46616374416464726573736e617574686f72697479436c6173736e696e746567726974794661756c746e6566666563744b696e6448696e7464726561646e657865637574696f6e436c6173736772756e74696d656e74797065506172616d65746572738073666f6f747072696e744f626c69676174696f6e78226a656469742e7465787440312e7265706c61636552616e6765466f6f747072696e7469636f6e7374616e7473806c6f62737472756374696f6e7383a36a636f6f7264696e617465781e6a656469742e7465787440312e42617369734e6f7443616e6f6e6963616c6d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736e646f6d61696e4d61707061626c65a36a636f6f7264696e61746578186a656469742e7465787440312e466163744d697373696e676d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736d7265736f757263654661756c74a36a636f6f7264696e617465781a6a656469742e7465787440312e466163744d616c666f726d65646d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736e696e746567726974794661756c746d7075726546756e6374696f6e7380716f7065726174696f6e50726f66696c6573a178196a656469742e7465787440312e7265706c61636552616e6765a26d6f7074696354656d706c617465a6696f707469634b696e64736166666563745265696e746567726174696f6e6c626f756e646172794b696e64666166666563746d626173697354656d706c617465781b6a656469742e7465787440312e65786163744865616442617369736d737570706f7274506f6c696379781e6a656469742e7465787440312e6261736973426f756e64537570706f72746f6c6f7373446973706f736974696f6e756a656469742e7465787440312e6c6f73736c657373736170657274757265526571756972656d656e74a26372656678226a656469742e7465787440312e7265706c61636552616e6765466f6f747072696e74646b696e64781b6162737472616374466f6f747072696e744f626c69676174696f6e6f65666665637450726564696361746578206a656469742e7465787440312e7265706c61636552616e676545666665637473706d61785f726573756c745f62797465731a00010000727461726765745f69725f6964656e746974795820179dd9568cc095d45b94ac84b1178f2864882ba815cb8cb0f6733f2c4486aeec736d61785f616c6c6f63617465645f62797465731a01000000781a696e7472696e7369635f70726f66696c655f6964656e746974795820a0fc1b7a1e186598291754469fd6ea2220f676358284f7b84c7e2476901a3151781c696e7465727072657465725f70726f66696c655f6964656e746974795820eaa6f8ca4f395d291fdb70af1bd47b804ab82aa17fdbc01b8aaeeb747f7d218c6e6275646765745f6365696c696e67a3657374657073016a726561645f6279746573006b77726974655f6279746573007073656d616e7469635f636c6f73757265a66d636f72655f6964656e74697479582000a327ca4e12916319db135a4fa2b2aa47ed9719eca14be79b7fd365966a5653727461726765745f69725f6964656e746974795820179dd9568cc095d45b94ac84b1178f2864882ba815cb8cb0f6733f2c4486aeec7565646963745f736f757263655f6964656e7469747958200101010101010101010101010101010101010101010101010101010101010101781a63616e6f6e6963616c5f6d65616e696e675f6964656e7469747958200303030303030303030303030303030303030303030303030303030303030303781b6170706c69636174696f6e5f736368656d615f6964656e7469747958200c75bcc42fd23d9eafdc81f1d81754be32cde98170c5fc1fbaf2746ffef99284781d6170706c69636174696f6e5f736368656d615f636f6f7264696e6174656a6170702e536368656d61746f7065726174696f6e5f636f6f7264696e61746578276a656469742e746578742e7265706c6163655f72616e676540312e7265706c61636552616e676575696e7075745f736368656d615f6964656e746974795820d277705b5ab03fcb58590bad62fb8058e075c3b4c65efc21282bb531aa22b3ad76726573756c745f736368656d615f6964656e746974795820de5c0c4f0c640354c40bb4f9d4886cd820353a548caea4953269eba15fe902bc777461726765745f70726f66696c655f6964656e746974795820eaca21c05664241efd1e1c5b5636c7132fe8854f6bcaddb2fd4f014e1bd4a479781a617574686f726974795f70726f66696c655f6964656e7469747958200808080808080808080808080808080808080808080808080808080808080808781a696e7472696e7369635f70726f66696c655f6964656e746974795820a0fc1b7a1e186598291754469fd6ea2220f676358284f7b84c7e2476901a3151781b666f6f747072696e745f636f6e74726163745f6964656e746974795820362b20fb18488ce180f6c1096b5189994354604fd1b1b126a3ea4ef839e5232b781b6f62737472756374696f6e5f736368656d615f6964656e746974795820b1f96fdf3ec65e84d500702951393a931b4fdd843ad02723ea3725f90a671418781c696e7465727072657465725f70726f66696c655f6964656e746974795820eaa6f8ca4f395d291fdb70af1bd47b804ab82aa17fdbc01b8aaeeb747f7d218c781e726573756c745f696e746572707265746174696f6e5f6964656e74697479582042734d5e73435acc0fdd5a66b97e5bfd94278e64fce2b4890ec609f054dc969e78206576616c756174696f6e5f62617369735f736368656d615f6964656e74697479582020b6239db569aa86ae1c27596b374df90caa5ea41e8e005fd4fe00bfe5c3b38178216170706c69636174696f6e5f62617369735f736368656d615f6964656e7469747958208b294c69120a2e749c56266691b0974e7e0323c198fc42a467fd3790790f791078236f62737472756374696f6e5f696e746572707265746174696f6e5f6964656e746974795820924462071f3992b34c629f4788cc666bd14a87a0b9d0c398feba929ff4dd25f9 diff --git a/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/failure-mapping-unknown.hex b/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/failure-mapping-unknown.hex new file mode 100644 index 00000000..57939873 --- /dev/null +++ b/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/failure-mapping-unknown.hex @@ -0,0 +1 @@ +b166736368656d6178196563686f2e6f7065726174696f6e2d7061636b6167652f76316770726f6772616d59304bad646b696e647765646963742d6566666563742d70726f6772616d2f763166736368656d6178196563686f2e6f7065726174696f6e2d70726f6772616d2f76316b6f75747075745f74797065766a656469742e7465787440312e4661637442797465736c67726170685f736368656d615876a26a656467655f7479706573a06a6e6f64655f7479706573a158200101010101010101010101010101010101010101010101010101010101010101a26a61646472657373696e67016a61746f6d5f747970657381582002020202020202020202020202020202020202020202020202020202020202026c6964656e746974795f6c6177016d666f6f747072696e745f6c617758f6a9696d61785f7265616473016a61746f6d5f747970657381582002020202020202020202020202020202020202020202020202020202020202026a6d61785f777269746573016f6d61785f72616e67655f6564676573006f726561645f6e6f64655f747970657381582001010101010101010101010101010101010101010101010101010101010101017072616e67655f656467655f7479706573807077726974655f656467655f7479706573807077726974655f6e6f64655f7479706573815820010101010101010101010101010101010101010101010101010101010101010172706f7274616c5f6f776e65725f7479706573806f6d61785f696e7075745f62797465731a0001000070636f6d70696c65645f70726f6772616d592d44a666696e74656e746c7265706c61636552616e676566736368656d6178286563686f2e636f6d70696c65722d70726f64756365642d6566666563742d70726f6772616d2f76316d636f72655f61727469666163745909caa6657479706573a365496e707574a2646b696e64665265636f7264666669656c6473a2676164647265737378186a656469742e7465787440312e4661637441646472657373686578706563746564766a656469742e7465787440312e466163744279746573766a656469742e7465787440312e466163744279746573a2636d61781a00100000646b696e6465427974657378186a656469742e7465787440312e4661637441646472657373a2646b696e64665265636f7264666669656c6473a3666e6f646549646f42797465733c65786163743d33323e667479706549646f42797465733c65786163743d33323e667761727049646f42797465733c65786163743d33323e67696d706f72747381a263726566a26269646c6a656469742e746578744031666469676573748266736861323536582035a8017a70d9dc98ac1a788879b7acdeef3359ecca95dd336c98e0689b48d772646b696e64676c61777061636b67696e74656e7473a16c7265706c61636552616e6765a764626f6479a3656e6f64657382a5646b696e646665666665637465696e707574a36462617365a263726566a3626964656172672e30647479706578206a656469742e746578742e7265706c6163655f72616e676540312e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646761646472657373666566666563746d746578742e72656164466163746762696e64696e67a3626964676c6f63616c2e306474797065766a656469742e7465787440312e46616374427974657369616c7068614e616d6567246c6f63616c306e6f62737472756374696f6e4d6170a4676d697373696e67a26576616c7565a4646172677380646b696e646463616c6c6663616c6c656570746578742e466163744d697373696e67687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e30647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e30676e6f7441746f6da26576616c7565a4646172677380646b696e646463616c6c6663616c6c656572746578742e466163744d616c666f726d6564687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e31647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e3168746f6f4c61726765a26576616c7565a4646172677380646b696e646463616c6c6663616c6c656572746578742e466163744d616c666f726d6564687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e32647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e326c747970654d69736d61746368a26576616c7565a4646172677380646b696e646463616c6c6663616c6c656572746578742e466163744d616c666f726d6564687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e33647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e33a3646b696e646772657175697265696f6e4661696c757265a2646b696e64687465726d696e616c66726561736f6ea2677061796c6f6164a06a726561736f6e4b696e6476746578742e42617369734e6f7443616e6f6e6963616c69707265646963617465a4626f70623d3d646b696e6467636f6d70617265646c656674a263726566a3626964676c6f63616c2e306474797065766a656469742e7465787440312e46616374427974657369616c7068614e616d6567246c6f63616c30646b696e64656c6f63616c657269676874a36462617365a263726566a3626964656172672e30647479706578206a656469742e746578742e7265706c6163655f72616e676540312e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c64686578706563746564666c6f63616c7386a3626964656172672e30647479706578206a656469742e746578742e7265706c6163655f72616e676540312e496e70757469616c7068614e616d65652461726730a3626964676c6f63616c2e306474797065766a656469742e7465787440312e46616374427974657369616c7068614e616d6567246c6f63616c30a36269646d6f62737472756374696f6e2e30647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e30a36269646d6f62737472756374696f6e2e31647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e31a36269646d6f62737472756374696f6e2e32647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e32a36269646d6f62737472756374696f6e2e33647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e3366726573756c74a263726566a3626964676c6f63616c2e306474797065766a656469742e7465787440312e46616374427974657369616c7068614e616d6567246c6f63616c30646b696e64656c6f63616c656261736973a36462617365a36462617365a263726566a3626964656172672e30647479706578206a656469742e746578742e7265706c6163655f72616e676540312e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646761646472657373646b696e64656669656c64656669656c64666e6f6465496465696e70757478206a656469742e746578742e7265706c6163655f72616e676540312e496e707574666f7574707574766a656469742e7465787440312e46616374427974657370696e707574436f6e73747261696e74738074636f72654576616c756174696f6e427564676574a3686d617853746570731a004000006e6d61784f757470757442797465731a00800000716d6178416c6c6f636174656442797465731a01000000781872657175697265644f7065726174696f6e50726f66696c65781e636f6e74696e75756d2e70726f66696c652e726561642d6f6e6c792f76316a61706956657273696f6e6d65646963742e636f72652f76316a636f6f7264696e617465781a6a656469742e746578742e7265706c6163655f72616e6765403178187265717569726564436f72654361706162696c697469657380726c6f776572696e675f617274696661637473a56f736f757263655f61727469666163745902d55902d27061636b616765206a656469742e746578742e7265706c6163655f72616e676540313b0a757365206c61777061636b206a656469742e7465787440312064696765737420227368613235363a333561383031376137306439646339386163316137383838373962376163646565663333353965636361393564643333366339386530363839623438643737322220617320746578743b0a7479706520496e707574203d207b20616464726573733a20746578742e46616374416464726573732c2065787065637465643a20746578742e466163744279746573207d3b0a696e74656e74207265706c61636552616e676528696e7075743a20496e707574292072657475726e7320746578742e4661637442797465730a202070726f66696c6520746578742e7265706c61636552616e67650a2020626173697320696e7075742e616464726573732e6e6f646549640a2020627564676574203c3d20746578742e7265706c61636552616e67654275646765740a7b0a20206c65742061637475616c3a20746578742e466163744279746573203d20746578742e726561644661637428696e7075742e61646472657373290a20202020656c7365207b0a2020202020206d697373696e67286164647265737329203d3e20746578742e466163744d697373696e672c0a202020202020747970654d69736d61746368286164647265737329203d3e20746578742e466163744d616c666f726d65642c0a2020202020206e6f7441746f6d286164647265737329203d3e20746578742e466163744d616c666f726d65642c0a202020202020746f6f4c61726765286164647265737329203d3e20746578742e466163744d616c666f726d65642c0a202020207d3b0a2020726571756972652061637475616c203d3d20696e7075742e657870656374656420656c736520746578742e42617369734e6f7443616e6f6e6963616c3b0a202072657475726e2061637475616c3b0a7d0a70616461707465725f6172746966616374590376a565636c6173736b6465636c617261746976656762756467657473a1781f6a656469742e7465787440312e7265706c61636552616e6765427564676574a3686d617853746570731a001000006e6d61784f757470757442797465731a00800000716d6178416c6c6f636174656442797465731a010000006a61706956657273696f6e781865646963742e6c61777061636b2d616461707465722f7631716f7065726174696f6e50726f66696c6573a178196a656469742e7465787440312e7265706c61636552616e6765a464636f7265781e636f6e74696e75756d2e70726f66696c652e726561642d6f6e6c792f76316f73656d616e7469634566666563747381756a656469742e7465787440312e7265616446616374706275646765744f626c69676174696f6e781f6a656469742e7465787440312e7265706c61636552616e676542756467657473746172676574436f6e66696775726174696f6ea262696478286563686f2e6f7065726174696f6e2d6c6f776572696e672d636f6e66696775726174696f6e2f7631666469676573748266736861323536582056921f7058a4b68027c3e5415150b2c6ef4388b000c2ea649cd7a14d3f565f7e75656666656374496d706c656d656e746174696f6e73a1756a656469742e7465787440312e7265616446616374a66a7772697465436c61737364726561646e636f73744f626c69676174696f6e781f6a656469742e7465787440312e7265706c61636552616e67654275646765746f6661696c7572654d617070696e6773a4676d697373696e676a61746f6d416273656e74676e6f7441746f6d6c61746f6d526571756972656468746f6f4c617267657561746f6d42797465426f756e6445786365656465646c747970654d69736d617463687061746f6d547970654d69736d617463686f746172676574496e7472696e73696378196563686f2e64706f40312e6e6f64652d61746f6d2d7265616473666f6f747072696e744f626c69676174696f6e78226a656469742e7465787440312e7265706c61636552616e6765466f6f747072696e7473746172676574436f6e66696775726174696f6ea262696478286563686f2e6f7065726174696f6e2d6c6f776572696e672d636f6e66696775726174696f6e2f7631666469676573748266736861323536582056921f7058a4b68027c3e5415150b2c6ef4388b000c2ea649cd7a14d3f565f7e706c61777061636b5f6172746966616374590313aa6269646a6a656469742e74657874676578706f727473a2626964756a656469742e746578742e6578706f7274732f763166646967657374826673686132353658200c75bcc42fd23d9eafdc81f1d81754be32cde98170c5fc1fbaf2746ffef992846776657273696f6e6131687665726966696572a265636c6173736b6465636c617261746976656772756c65736574a2626964781c6a656469742e746578742e76657269666965722d72756c65732f76316664696765737482667368613235365820364fb4ff98ae64fcd8d793aae3d7cb133ff8a1ce661330cea47688b13a0a823f6a61706956657273696f6e7065646963742e6c61777061636b2f76316c646570656e64656e63696573806d636f6d7061746962696c697479a2626964781b6a656469742e746578742e636f6d7061746962696c6974792f763166646967657374826673686132353658202adf83f798205f52636ad64ca45178f33a8e1cc663874f8a6113484c945e30526e746172676574416461707465727381a36761646170746572a2626964781a6a656469742e746578742e6563686f2d616461707465722f76316664696765737482667368613235365820470ba3f5926138dbf6034cd71be761009c84e55bbe982f41215667289a7703097061636365707465645461726765744972a26269646f6563686f2e7370616e2d69722f76326664696765737482667368613235365820123e7f805dc5e831e88befec4cd49ec02c39858b6f3990da8a73b50c6086ae3975616363657074656454617267657450726f66696c65a26269646a6563686f2e64706f40316664696765737482667368613235365820033b457dfd63fe6b57f0756b78eb6d41c4b30994e84225d9a15afb2879c0841c6f6163636570746564436f7265416269816d65646963742e636f72652f76317818636f6e666f726d616e636546697874757265436f72707573a262696478206a656469742e746578742e5265706c61636552616e67652e6f7261636c6540316664696765737482667368613235365820b9b4707dd5e07897cbe7af36d88928401887e6af5d167d1a88a8d6181b4dbb0e73696e7472696e736963735f6172746966616374590309a26a61706956657273696f6e782265646963742e7461726765742d70726f66696c652e696e7472696e736963732f76316a696e7472696e73696373a178196563686f2e64706f40312e6e6f64652d61746f6d2d72656164ab6a6566666563744b696e6464726561646a72657475726e5479706578206563686f2e64706f40312e6e6f64652d61746f6d2d726561642e726573756c746a7772697465436c61737364726561646c636f737454656d706c617465781f6a656469742e7465787440312e7265706c61636552616e67654275646765746c6775617264537570706f7274f56d617267756d656e74547970657381781f6563686f2e64706f40312e6e6f64652d61746f6d2d726561642e696e7075746e6566666563744661696c75726573a46a61746f6d416273656e74a26b7061796c6f616454797065781f6563686f2e64706f40312e6e6f64652d61746f6d2d726561642e696e7075746e617574686f72697479436c6173736d7265736f757263654661756c746c61746f6d5265717569726564a26b7061796c6f616454797065781f6563686f2e64706f40312e6e6f64652d61746f6d2d726561642e696e7075746e617574686f72697479436c6173736e696e746567726974794661756c747061746f6d547970654d69736d61746368a26b7061796c6f616454797065781f6563686f2e64706f40312e6e6f64652d61746f6d2d726561642e696e7075746e617574686f72697479436c6173736e696e746567726974794661756c747561746f6d42797465426f756e644578636565646564a26b7061796c6f616454797065781f6563686f2e64706f40312e6e6f64652d61746f6d2d726561642e696e7075746e617574686f72697479436c6173736e696e746567726974794661756c746e696e7472696e736963436c617373666566666563746e74797065506172616d65746572738071666f6f747072696e7454656d706c61746578226a656469742e7465787440312e7265706c61636552616e6765466f6f747072696e74781b63616e5061727469636970617465496e41746f6d69634775617264f5777461726765745f70726f66696c655f61727469666163745906fbb81c626964686563686f2e64706f676c6f7765726572a2626964736563686f2e64706f2e6c6f77657265722f7631666469676573748266736861323536582044ca28eeeccc4ff522fd9ec7e4694124f4e04880171c8cce460eefcb9505b7976773616e64626f78a26269647765646963742e7761736d2d636f6d706f6e656e742f76316664696765737482667368613235365820095b4dd18f1a6a7276533f758665be319c5f476e7bdc70cc56d30b6b3e9f0a806776657273696f6e6131687461726765744972a26269646f6563686f2e7370616e2d69722f76326664696765737482667368613235365820123e7f805dc5e831e88befec4cd49ec02c39858b6f3990da8a73b50c6086ae39687665726966696572a2626964746563686f2e64706f2e76657269666965722f76316664696765737482667368613235365820ca96b190728de3d668072ec1bd37d24e5197e7bd9bd54f70966d8c566b9b67f2696675656c4d6f64656ca26269646d65646963742e6675656c2f76316664696765737482667368613235365820006c6ebc01a3c5d36d50bd390b69d47e42378be61074e3b5c96ecb9f5ee532076a61706956657273696f6e7765646963742e7461726765742d70726f66696c652f76316a696e7472696e73696373a2626964766563686f2e64706f2e696e7472696e736963732f763166646967657374826673686132353658204e5f2b4dc86ffc4d10d89e40354e3eec3438286f4fa3cd532379ca23dc33f4df6b636f7374416c6765627261a2626964706563686f2e64706f2e636f73742f76316664696765737482667368613235365820486940acd1d4bc15cea40db29347619a07202d9c0f1e63c4016c26bccf0b52a86b6d756c7469546172676574f46d62756e646c6550726f66696c65a2626964726563686f2e64706f2e62756e646c652f76316664696765737482667368613235365820aa0438bcc6ef14ee6cb6d4976622f6080381d731459dcb7b9102595c9bed92c06d646961676e6f73746963416269a26269647465646963742e646961676e6f73746963732f7631666469676573748266736861323536582028fd72a98223153982ca084c29dbb1b2d430623967ab3b6db9d7fee668e614b96f6163636570746564436f7265416269816d65646963742e636f72652f76316f67756172644576616c756174696f6e70707265636f6d6d69742d61746f6d69636f72656164436f6e73697374656e6379746170706c69636174696f6e2d736e617073686f74706170706c69636174696f6e4d6f64656c6661746f6d696370666f6f747072696e74416c6765627261a2626964756563686f2e64706f2e666f6f747072696e742f76316664696765737482667368613235365820f47bb65867e78099ddcfd6ae7af83870df8823f974a496a111ed94e5d785c769716f7065726174696f6e50726f66696c6573a2626964781e6563686f2e64706f2e6f7065726174696f6e2d70726f66696c65732f7631666469676573748266736861323536582053256c51f6c817a77cc8694458bf9d3891abd15b9c94f79ca97d920d3c5f041672696e7472696e7369634e616d6573706163656a6563686f2e64706f4031736f62737472756374696f6e526f6c6c6261636b726e6f2d76697369626c652d65666665637473736f62737472756374696f6e5461786f6e6f6d79a262696478186563686f2e64706f2e6f62737472756374696f6e732f763166646967657374826673686132353658204f5a139d606053c3807f50710076ea9abeb0e611c12a530f5e5b4b31911c3e6474706f7374636f6e646974696f6e537570706f7274f57663616e6f6e6963616c456e636f64696e6752756c6573a26269647765646963742e63616e6f6e6963616c2d63626f722f76316664696765737482667368613235365820d1ea6d3de2a9762a438cbf4fac1d5ae2f357a4b27d13e0347e94ea655bf40f9d7664657465726d696e6973746963457865637574696f6ea26269647465646963742e64657465726d696e69736d2f76316664696765737482667368613235365820af4e6c774d5ea82db30e680be2ba7abc5ba04c6aead146139de32d8c5bb4981e7818636f6e666f726d616e636546697874757265436f72707573a2626964746563686f2e64706f2e66697874757265732f763166646967657374826673686132353658208fa81d37ae4eecb79252f310e7532fc9872bd7c17f2722da911fa74620f81b43781961636365707465644c61777061636b4164617074657241626981781865646963742e6c61777061636b2d616461707465722f7631781967656e657261746564417274696661637450726f66696c657381a262696478186563686f2e64706f2e726567697374726174696f6e2f76316664696765737482667368613235365820ff88be93c26cc533948d8a93601954dc391912d593ca1e96115c846cbf2c5b5d727461726765745f69725f617274696661637459087aa6646b696e64776f7264657265645461726765744972417274696661637466646f6d61696e6f6563686f2e7370616e2d69722f763267696e74656e7473a16c7265706c61636552616e6765a8656261736973a36462617365a36462617365a263726566a3626964656172672e30647479706578206a656469742e746578742e7265706c6163655f72616e676540312e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646761646472657373646b696e64656669656c64656669656c64666e6f6465496465737465707381a7626964737265706c61636552616e67652e737465702e3065696e707574a36462617365a263726566a3626964656172672e30647479706578206a656469742e746578742e7265706c6163655f72616e676540312e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646761646472657373666566666563746d746578742e72656164466163746762696e64696e67a3626964676c6f63616c2e306474797065766a656469742e7465787440312e46616374427974657369616c7068614e616d6567246c6f63616c306f6f62737472756374696f6e41726d73a46b61746f6d4d697373696e67a26576616c7565a4646172677380646b696e646463616c6c6663616c6c656570746578742e466163744d697373696e67687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e30647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e306c61746f6d5265717569726564a26576616c7565a4646172677380646b696e646463616c6c6663616c6c656572746578742e466163744d616c666f726d6564687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e31647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e317061746f6d547970654d69736d61746368a26576616c7565a4646172677380646b696e646463616c6c6663616c6c656572746578742e466163744d616c666f726d6564687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e33647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e337561746f6d42797465426f756e644578636565646564a26576616c7565a4646172677380646b696e646463616c6c6663616c6c656572746578742e466163744d616c666f726d6564687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e32647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e326f746172676574496e7472696e73696378196563686f2e64706f40312e6e6f64652d61746f6d2d72656164736f62737472756374696f6e4661696c75726573847561746f6d42797465426f756e6445786365656465646b61746f6d4d697373696e676c61746f6d52657175697265647061746f6d547970654d69736d6174636866726573756c74a263726566a3626964676c6f63616c2e306474797065766a656469742e7465787440312e46616374427974657369616c7068614e616d6567246c6f63616c30646b696e64656c6f63616c6c726571756972656d656e747381a3626964767265706c61636552616e67652e726571756972652e30696f6e4661696c757265a2646b696e64687465726d696e616c66726561736f6ea2677061796c6f6164a06a726561736f6e4b696e6476746578742e42617369734e6f7443616e6f6e6963616c69707265646963617465a4626f70623d3d646b696e6467636f6d70617265646c656674a263726566a3626964676c6f63616c2e306474797065766a656469742e7465787440312e46616374427974657369616c7068614e616d6567246c6f63616c30646b696e64656c6f63616c657269676874a36462617365a263726566a3626964656172672e30647479706578206a656469742e746578742e7265706c6163655f72616e676540312e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646865787065637465646e657865637574696f6e4f7264657282737265706c61636552616e67652e737465702e30767265706c61636552616e67652e726571756972652e3070696e707574436f6e73747261696e747380706f7065726174696f6e50726f66696c65781e636f6e74696e75756d2e70726f66696c652e726561642d6f6e6c792f763174636f72654576616c756174696f6e427564676574a3686d617853746570731a004000006e6d61784f757470757442797465731a00800000716d6178416c6c6f636174656442797465731a010000006d74617267657450726f66696c65a26269646a6563686f2e64706f40316664696765737482667368613235365820033b457dfd63fe6b57f0756b78eb6d41c4b30994e84225d9a15afb2879c0841c6f73656d616e746963436c6f73757265a2686c61777061636b7381a26269646c6a656469742e746578744031666469676573748266736861323536582035a8017a70d9dc98ac1a788879b7acdeef3359ecca95dd336c98e0689b48d7726a736f75726365436f7265a2626964781a6a656469742e746578742e7265706c6163655f72616e676540316664696765737482667368613235365820088ccb1802f5bfe128cec995c5ac02c124b4a36559acb2d8b91798315471bc9974736f75726365436f7265436f6f7264696e617465781a6a656469742e746578742e7265706c6163655f72616e6765403178186c61777061636b5f6578706f7274735f6172746966616374590693a665747970657383a26a636f6f7264696e61746578186a656469742e7465787440312e46616374416464726573736a646566696e6974696f6e784c5265636f72643c6e6f646549643a42797465733c65786163743d33323e2c7479706549643a42797465733c65786163743d33323e2c7761727049643a42797465733c65786163743d33323e3ea26a636f6f7264696e617465766a656469742e7465787440312e4661637442797465736a646566696e6974696f6e7242797465733c6d61783d313034383537363ea26a636f6f7264696e617465781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6a646566696e6974696f6e7822537472696e673c6d61783d3235362c63616e6f6e6963616c3d7261772d757466383e676566666563747381aa69696e7075745479706578186a656469742e7465787440312e46616374416464726573736a636f6f7264696e617465756a656469742e7465787440312e72656164466163746a6f757470757454797065766a656469742e7465787440312e4661637442797465736c6775617264537570706f7274f56e636f73744f626c69676174696f6e781f6a656469742e7465787440312e7265706c61636552616e67654275646765746e6566666563744661696c75726573a4676d697373696e67a26b7061796c6f61645479706578186a656469742e7465787440312e46616374416464726573736e617574686f72697479436c6173736d7265736f757263654661756c74676e6f7441746f6da26b7061796c6f61645479706578186a656469742e7465787440312e46616374416464726573736e617574686f72697479436c6173736e696e746567726974794661756c7468746f6f4c61726765a26b7061796c6f61645479706578186a656469742e7465787440312e46616374416464726573736e617574686f72697479436c6173736e696e746567726974794661756c746c747970654d69736d61746368a26b7061796c6f61645479706578186a656469742e7465787440312e46616374416464726573736e617574686f72697479436c6173736e696e746567726974794661756c746e6566666563744b696e6448696e7464726561646e657865637574696f6e436c6173736772756e74696d656e74797065506172616d65746572738073666f6f747072696e744f626c69676174696f6e78226a656469742e7465787440312e7265706c61636552616e6765466f6f747072696e7469636f6e7374616e7473806c6f62737472756374696f6e7383a36a636f6f7264696e617465781e6a656469742e7465787440312e42617369734e6f7443616e6f6e6963616c6d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736e646f6d61696e4d61707061626c65a36a636f6f7264696e61746578186a656469742e7465787440312e466163744d697373696e676d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736d7265736f757263654661756c74a36a636f6f7264696e617465781a6a656469742e7465787440312e466163744d616c666f726d65646d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736e696e746567726974794661756c746d7075726546756e6374696f6e7380716f7065726174696f6e50726f66696c6573a178196a656469742e7465787440312e7265706c61636552616e6765a26d6f7074696354656d706c617465a6696f707469634b696e64736166666563745265696e746567726174696f6e6c626f756e646172794b696e64666166666563746d626173697354656d706c617465781b6a656469742e7465787440312e65786163744865616442617369736d737570706f7274506f6c696379781e6a656469742e7465787440312e6261736973426f756e64537570706f72746f6c6f7373446973706f736974696f6e756a656469742e7465787440312e6c6f73736c657373736170657274757265526571756972656d656e74a26372656678226a656469742e7465787440312e7265706c61636552616e6765466f6f747072696e74646b696e64781b6162737472616374466f6f747072696e744f626c69676174696f6e6f65666665637450726564696361746578206a656469742e7465787440312e7265706c61636552616e676545666665637473706d61785f726573756c745f62797465731a00010000727461726765745f69725f6964656e74697479582007c0717d957df5f54032be2b9b8efd423723b138e580fcf4c041c0366505aaaf736d61785f616c6c6f63617465645f62797465731a01000000781a696e7472696e7369635f70726f66696c655f6964656e746974795820a0fc1b7a1e186598291754469fd6ea2220f676358284f7b84c7e2476901a3151781c696e7465727072657465725f70726f66696c655f6964656e746974795820eaa6f8ca4f395d291fdb70af1bd47b804ab82aa17fdbc01b8aaeeb747f7d218c6e6275646765745f6365696c696e67a3657374657073016a726561645f6279746573006b77726974655f6279746573007073656d616e7469635f636c6f73757265a66d636f72655f6964656e746974795820088ccb1802f5bfe128cec995c5ac02c124b4a36559acb2d8b91798315471bc99727461726765745f69725f6964656e74697479582007c0717d957df5f54032be2b9b8efd423723b138e580fcf4c041c0366505aaaf7565646963745f736f757263655f6964656e7469747958200101010101010101010101010101010101010101010101010101010101010101781a63616e6f6e6963616c5f6d65616e696e675f6964656e7469747958200303030303030303030303030303030303030303030303030303030303030303781b6170706c69636174696f6e5f736368656d615f6964656e7469747958200c75bcc42fd23d9eafdc81f1d81754be32cde98170c5fc1fbaf2746ffef99284781d6170706c69636174696f6e5f736368656d615f636f6f7264696e6174656a6170702e536368656d61746f7065726174696f6e5f636f6f7264696e61746578276a656469742e746578742e7265706c6163655f72616e676540312e7265706c61636552616e676575696e7075745f736368656d615f6964656e746974795820d277705b5ab03fcb58590bad62fb8058e075c3b4c65efc21282bb531aa22b3ad76726573756c745f736368656d615f6964656e746974795820de5c0c4f0c640354c40bb4f9d4886cd820353a548caea4953269eba15fe902bc777461726765745f70726f66696c655f6964656e746974795820eaca21c05664241efd1e1c5b5636c7132fe8854f6bcaddb2fd4f014e1bd4a479781a617574686f726974795f70726f66696c655f6964656e7469747958200808080808080808080808080808080808080808080808080808080808080808781a696e7472696e7369635f70726f66696c655f6964656e746974795820a0fc1b7a1e186598291754469fd6ea2220f676358284f7b84c7e2476901a3151781b666f6f747072696e745f636f6e74726163745f6964656e746974795820362b20fb18488ce180f6c1096b5189994354604fd1b1b126a3ea4ef839e5232b781b6f62737472756374696f6e5f736368656d615f6964656e746974795820b1f96fdf3ec65e84d500702951393a931b4fdd843ad02723ea3725f90a671418781c696e7465727072657465725f70726f66696c655f6964656e746974795820eaa6f8ca4f395d291fdb70af1bd47b804ab82aa17fdbc01b8aaeeb747f7d218c781e726573756c745f696e746572707265746174696f6e5f6964656e74697479582042734d5e73435acc0fdd5a66b97e5bfd94278e64fce2b4890ec609f054dc969e78206576616c756174696f6e5f62617369735f736368656d615f6964656e74697479582020b6239db569aa86ae1c27596b374df90caa5ea41e8e005fd4fe00bfe5c3b38178216170706c69636174696f6e5f62617369735f736368656d615f6964656e7469747958208b294c69120a2e749c56266691b0974e7e0323c198fc42a467fd3790790f791078236f62737472756374696f6e5f696e746572707265746174696f6e5f6964656e746974795820924462071f3992b34c629f4788cc666bd14a87a0b9d0c398feba929ff4dd25f9 diff --git a/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/forged-node-order.hex b/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/forged-node-order.hex new file mode 100644 index 00000000..c4a4a10d --- /dev/null +++ b/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/forged-node-order.hex @@ -0,0 +1 @@ +b166736368656d6178196563686f2e6f7065726174696f6e2d7061636b6167652f76316770726f6772616d590fb1ad646b696e647765646963742d6566666563742d70726f6772616d2f763166736368656d6178196563686f2e6f7065726174696f6e2d70726f6772616d2f76316b6f75747075745f747970656a6170702e526573756c746c67726170685f736368656d615876a26a656467655f7479706573a06a6e6f64655f7479706573a158200101010101010101010101010101010101010101010101010101010101010101a26a61646472657373696e67016a61746f6d5f747970657381582002020202020202020202020202020202020202020202020202020202020202026c6964656e746974795f6c6177016d666f6f747072696e745f6c617758f6a9696d61785f7265616473016a61746f6d5f747970657381582002020202020202020202020202020202020202020202020202020202020202026a6d61785f777269746573016f6d61785f72616e67655f6564676573006f726561645f6e6f64655f747970657381582001010101010101010101010101010101010101010101010101010101010101017072616e67655f656467655f7479706573807077726974655f656467655f7479706573807077726974655f6e6f64655f7479706573815820010101010101010101010101010101010101010101010101010101010101010172706f7274616c5f6f776e65725f7479706573806f6d61785f696e7075745f62797465731a0001000070636f6d70696c65645f70726f6772616d590cb6a666696e74656e7468757064617465403166736368656d6178286563686f2e636f6d70696c65722d70726f64756365642d6566666563742d70726f6772616d2f76316d636f72655f61727469666163745905fba6657479706573a265496e707574a2646b696e64665265636f7264666669656c6473a36261746355363464746578746d42797465733c6d61783d36343e656f746865726d42797465733c6d61783d36343e66526573756c74a1646b696e6464426f6f6c67696d706f7274738067696e74656e7473a1687570646174654031a664626f6479a3656e6f64657382a3646b696e64636c65746576616c7565a4646172677381a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646474657874646b696e646463616c6c6663616c6c656571636f72652e62797465732e6c656e677468687479706541726773816d42797465733c6d61783d36343e6762696e64696e67a36269646a6c6f63616c2e73697a6564747970656355363469616c7068614e616d656a246c6f63616c73697a65a3646b696e64636c65746576616c7565a4646172677381a4646172677383a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646474657874a2646b696e6465636f6e73746576616c7565a3646b696e6463696e746576616c75650065776964746863553634a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c64626174646b696e646463616c6c6663616c6c656570636f72652e62797465732e736c696365687479706541726773816d42797465733c6d61783d36343e646b696e646463616c6c6663616c6c656571636f72652e62797465732e697355746638687479706541726773816d42797465733c6d61783d36343e6762696e64696e67a3626964686c6f63616c2e6f6b647479706564426f6f6c69616c7068614e616d6568246c6f63616c6f6b666c6f63616c7383a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730a36269646a6c6f63616c2e73697a6564747970656355363469616c7068614e616d656a246c6f63616c73697a65a3626964686c6f63616c2e6f6b647479706564426f6f6c69616c7068614e616d6568246c6f63616c6f6b66726573756c74a263726566a3626964686c6f63616c2e6f6b647479706564426f6f6c69616c7068614e616d6568246c6f63616c6f6b646b696e64656c6f63616c65696e707574696170702e496e707574666f75747075746a6170702e526573756c7470696e707574436f6e73747261696e747381a269707265646963617465a4626f70623c3d646b696e6467636f6d70617265646c656674a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c64626174657269676874a4646172677381a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646474657874646b696e646463616c6c6663616c6c656571636f72652e62797465732e6c656e677468687479706541726773816d42797465733c6d61783d36343e6a636f6f7264696e617465746170702e75706461746540312e77686572652e3074636f72654576616c756174696f6e427564676574a3686d617853746570731a000f42406e6d61784f757470757442797465731a00010000716d6178416c6c6f636174656442797465731a01000000781872657175697265644f7065726174696f6e50726f66696c65781a636f6e74696e75756d2e70726f66696c652e746f74616c2f76316a61706956657273696f6e6d65646963742e636f72652f76316a636f6f7264696e6174656361707078187265717569726564436f72654361706162696c697469657380726c6f776572696e675f617274696661637473f6727461726765745f69725f61727469666163745905d6a6646b696e64776f7264657265645461726765744972417274696661637466646f6d61696e6f6563686f2e7370616e2d69722f763267696e74656e7473a1687570646174654031a86573746570738066726573756c74a263726566a3626964686c6f63616c2e6f6b647479706564426f6f6c69616c7068614e616d6568246c6f63616c6f6b646b696e64656c6f63616c6c7075726542696e64696e677382a36269646962696e64696e672e306576616c7565a4646172677381a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646474657874646b696e646463616c6c6663616c6c656571636f72652e62797465732e6c656e677468687479706541726773816d42797465733c6d61783d36343e6762696e64696e67a36269646a6c6f63616c2e73697a6564747970656355363469616c7068614e616d656a246c6f63616c73697a65a36269646962696e64696e672e316576616c7565a4646172677381a4646172677383a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646474657874a2646b696e6465636f6e73746576616c7565a3646b696e6463696e746576616c75650065776964746863553634a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c64626174646b696e646463616c6c6663616c6c656570636f72652e62797465732e736c696365687479706541726773816d42797465733c6d61783d36343e646b696e646463616c6c6663616c6c656571636f72652e62797465732e697355746638687479706541726773816d42797465733c6d61783d36343e6762696e64696e67a3626964686c6f63616c2e6f6b647479706564426f6f6c69616c7068614e616d6568246c6f63616c6f6b6c726571756972656d656e7473806e657865637574696f6e4f72646572826962696e64696e672e316962696e64696e672e3070696e707574436f6e73747261696e747381a269707265646963617465a4626f70623c3d646b696e6467636f6d70617265646c656674a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c64626174657269676874a4646172677381a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646474657874646b696e646463616c6c6663616c6c656571636f72652e62797465732e6c656e677468687479706541726773816d42797465733c6d61783d36343e6a636f6f7264696e617465746170702e75706461746540312e77686572652e30706f7065726174696f6e50726f66696c65781a636f6e74696e75756d2e70726f66696c652e746f74616c2f763174636f72654576616c756174696f6e427564676574a3686d617853746570731a000f42406e6d61784f757470757442797465731a00010000716d6178416c6c6f636174656442797465731a010000006d74617267657450726f66696c65a26269646a6563686f2e64706f4031666469676573748266736861323536582006060606060606060606060606060606060606060606060606060606060606066f73656d616e746963436c6f73757265a2686c61777061636b73806a736f75726365436f7265a2626964636170706664696765737482667368613235365820559ab456aa78ea90f823a908dd6761ed1a7c1c233c138f2f6026e5d0df95a2af74736f75726365436f7265436f6f7264696e6174656361707078186c61777061636b5f6578706f7274735f6172746966616374584ca66574797065738067656666656374738069636f6e7374616e7473806c6f62737472756374696f6e73806d7075726546756e6374696f6e7380716f7065726174696f6e50726f66696c6573a0706d61785f726573756c745f62797465731a00010000727461726765745f69725f6964656e74697479582015a5c561571494e26c8709d3cbc842c21b80a83b8e9df68ad92797082fa58eb7736d61785f616c6c6f63617465645f62797465731a01000000781a696e7472696e7369635f70726f66696c655f6964656e746974795820a0fc1b7a1e186598291754469fd6ea2220f676358284f7b84c7e2476901a3151781c696e7465727072657465725f70726f66696c655f6964656e746974795820eaa6f8ca4f395d291fdb70af1bd47b804ab82aa17fdbc01b8aaeeb747f7d218c6e6275646765745f6365696c696e67a3657374657073016a726561645f6279746573006b77726974655f6279746573007073656d616e7469635f636c6f73757265a66d636f72655f6964656e746974795820559ab456aa78ea90f823a908dd6761ed1a7c1c233c138f2f6026e5d0df95a2af727461726765745f69725f6964656e74697479582015a5c561571494e26c8709d3cbc842c21b80a83b8e9df68ad92797082fa58eb77565646963745f736f757263655f6964656e7469747958200101010101010101010101010101010101010101010101010101010101010101781a63616e6f6e6963616c5f6d65616e696e675f6964656e7469747958200303030303030303030303030303030303030303030303030303030303030303781b6170706c69636174696f6e5f736368656d615f6964656e746974795820e2089c3b5730d3b54a8a645cbf77d76492a0f36e98e23d6ecab5e4fd7fa7c265781d6170706c69636174696f6e5f736368656d615f636f6f7264696e6174656a6170702e536368656d61746f7065726174696f6e5f636f6f7264696e6174656c6170702e757064617465403175696e7075745f736368656d615f6964656e746974795820d277705b5ab03fcb58590bad62fb8058e075c3b4c65efc21282bb531aa22b3ad76726573756c745f736368656d615f6964656e746974795820de5c0c4f0c640354c40bb4f9d4886cd820353a548caea4953269eba15fe902bc777461726765745f70726f66696c655f6964656e746974795820eaca21c05664241efd1e1c5b5636c7132fe8854f6bcaddb2fd4f014e1bd4a479781a617574686f726974795f70726f66696c655f6964656e7469747958200808080808080808080808080808080808080808080808080808080808080808781a696e7472696e7369635f70726f66696c655f6964656e746974795820a0fc1b7a1e186598291754469fd6ea2220f676358284f7b84c7e2476901a3151781b666f6f747072696e745f636f6e74726163745f6964656e746974795820362b20fb18488ce180f6c1096b5189994354604fd1b1b126a3ea4ef839e5232b781b6f62737472756374696f6e5f736368656d615f6964656e746974795820b1f96fdf3ec65e84d500702951393a931b4fdd843ad02723ea3725f90a671418781c696e7465727072657465725f70726f66696c655f6964656e746974795820eaa6f8ca4f395d291fdb70af1bd47b804ab82aa17fdbc01b8aaeeb747f7d218c781e726573756c745f696e746572707265746174696f6e5f6964656e74697479582042734d5e73435acc0fdd5a66b97e5bfd94278e64fce2b4890ec609f054dc969e78206576616c756174696f6e5f62617369735f736368656d615f6964656e74697479582020b6239db569aa86ae1c27596b374df90caa5ea41e8e005fd4fe00bfe5c3b38178216170706c69636174696f6e5f62617369735f736368656d615f6964656e7469747958208b294c69120a2e749c56266691b0974e7e0323c198fc42a467fd3790790f791078236f62737472756374696f6e5f696e746572707265746174696f6e5f6964656e746974795820924462071f3992b34c629f4788cc666bd14a87a0b9d0c398feba929ff4dd25f9 diff --git a/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/over-budget.hex b/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/over-budget.hex new file mode 100644 index 00000000..2ac085bc --- /dev/null +++ b/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/over-budget.hex @@ -0,0 +1 @@ +b166736368656d6178196563686f2e6f7065726174696f6e2d7061636b6167652f76316770726f6772616d590db6ad646b696e647765646963742d6566666563742d70726f6772616d2f763166736368656d6178196563686f2e6f7065726174696f6e2d70726f6772616d2f76316b6f75747075745f747970656a6170702e526573756c746c67726170685f736368656d615876a26a656467655f7479706573a06a6e6f64655f7479706573a158200101010101010101010101010101010101010101010101010101010101010101a26a61646472657373696e67016a61746f6d5f747970657381582002020202020202020202020202020202020202020202020202020202020202026c6964656e746974795f6c6177016d666f6f747072696e745f6c617758f6a9696d61785f7265616473016a61746f6d5f747970657381582002020202020202020202020202020202020202020202020202020202020202026a6d61785f777269746573016f6d61785f72616e67655f6564676573006f726561645f6e6f64655f747970657381582001010101010101010101010101010101010101010101010101010101010101017072616e67655f656467655f7479706573807077726974655f656467655f7479706573807077726974655f6e6f64655f7479706573815820010101010101010101010101010101010101010101010101010101010101010172706f7274616c5f6f776e65725f7479706573806f6d61785f696e7075745f62797465731a0001000070636f6d70696c65645f70726f6772616d590abba666696e74656e7468757064617465403166736368656d6178286563686f2e636f6d70696c65722d70726f64756365642d6566666563742d70726f6772616d2f76316d636f72655f61727469666163745904eea6657479706573a265496e707574a2646b696e64665265636f7264666669656c6473a36261746355363464746578746d42797465733c6d61783d36343e656f746865726d42797465733c6d61783d36343e66526573756c74a1646b696e6464426f6f6c67696d706f7274738067696e74656e7473a1687570646174654031a664626f6479a3656e6f64657381a3646b696e64636c65746576616c7565a4646172677381a4646172677383a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646474657874a2646b696e6465636f6e73746576616c7565a3646b696e6463696e746576616c75650065776964746863553634a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c64626174646b696e646463616c6c6663616c6c656570636f72652e62797465732e736c696365687479706541726773816d42797465733c6d61783d36343e646b696e646463616c6c6663616c6c656571636f72652e62797465732e697355746638687479706541726773816d42797465733c6d61783d36343e6762696e64696e67a3626964686c6f63616c2e6f6b647479706564426f6f6c69616c7068614e616d6568246c6f63616c6f6b666c6f63616c7382a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730a3626964686c6f63616c2e6f6b647479706564426f6f6c69616c7068614e616d6568246c6f63616c6f6b66726573756c74a263726566a3626964686c6f63616c2e6f6b647479706564426f6f6c69616c7068614e616d6568246c6f63616c6f6b646b696e64656c6f63616c65696e707574696170702e496e707574666f75747075746a6170702e526573756c7470696e707574436f6e73747261696e747381a269707265646963617465a4626f70623c3d646b696e6467636f6d70617265646c656674a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c64626174657269676874a4646172677381a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646474657874646b696e646463616c6c6663616c6c656571636f72652e62797465732e6c656e677468687479706541726773816d42797465733c6d61783d36343e6a636f6f7264696e617465746170702e75706461746540312e77686572652e3074636f72654576616c756174696f6e427564676574a3686d61785374657073016e6d61784f757470757442797465731a00010000716d6178416c6c6f636174656442797465731a01000000781872657175697265644f7065726174696f6e50726f66696c65781a636f6e74696e75756d2e70726f66696c652e746f74616c2f76316a61706956657273696f6e6d65646963742e636f72652f76316a636f6f7264696e6174656361707078187265717569726564436f72654361706162696c697469657380726c6f776572696e675f617274696661637473f6727461726765745f69725f61727469666163745904e8a6646b696e64776f7264657265645461726765744972417274696661637466646f6d61696e6f6563686f2e7370616e2d69722f763267696e74656e7473a1687570646174654031a86573746570738066726573756c74a263726566a3626964686c6f63616c2e6f6b647479706564426f6f6c69616c7068614e616d6568246c6f63616c6f6b646b696e64656c6f63616c6c7075726542696e64696e677381a36269646962696e64696e672e306576616c7565a4646172677381a4646172677383a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646474657874a2646b696e6465636f6e73746576616c7565a3646b696e6463696e746576616c75650065776964746863553634a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c64626174646b696e646463616c6c6663616c6c656570636f72652e62797465732e736c696365687479706541726773816d42797465733c6d61783d36343e646b696e646463616c6c6663616c6c656571636f72652e62797465732e697355746638687479706541726773816d42797465733c6d61783d36343e6762696e64696e67a3626964686c6f63616c2e6f6b647479706564426f6f6c69616c7068614e616d6568246c6f63616c6f6b6c726571756972656d656e7473806e657865637574696f6e4f72646572816962696e64696e672e3070696e707574436f6e73747261696e747381a269707265646963617465a4626f70623c3d646b696e6467636f6d70617265646c656674a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c64626174657269676874a4646172677381a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646474657874646b696e646463616c6c6663616c6c656571636f72652e62797465732e6c656e677468687479706541726773816d42797465733c6d61783d36343e6a636f6f7264696e617465746170702e75706461746540312e77686572652e30706f7065726174696f6e50726f66696c65781a636f6e74696e75756d2e70726f66696c652e746f74616c2f763174636f72654576616c756174696f6e427564676574a3686d61785374657073016e6d61784f757470757442797465731a00010000716d6178416c6c6f636174656442797465731a010000006d74617267657450726f66696c65a26269646a6563686f2e64706f4031666469676573748266736861323536582006060606060606060606060606060606060606060606060606060606060606066f73656d616e746963436c6f73757265a2686c61777061636b73806a736f75726365436f7265a2626964636170706664696765737482667368613235365820ff446a07d0fd35f5e3810173bb892a3edc734071e080517333cf6fe3eec8d05474736f75726365436f7265436f6f7264696e6174656361707078186c61777061636b5f6578706f7274735f6172746966616374584ca66574797065738067656666656374738069636f6e7374616e7473806c6f62737472756374696f6e73806d7075726546756e6374696f6e7380716f7065726174696f6e50726f66696c6573a0706d61785f726573756c745f62797465731a00010000727461726765745f69725f6964656e746974795820e3cb6e3a10ef06683006e01e549e50ba4e5c8bdee71ab73469a16849774def21736d61785f616c6c6f63617465645f62797465731a01000000781a696e7472696e7369635f70726f66696c655f6964656e746974795820a0fc1b7a1e186598291754469fd6ea2220f676358284f7b84c7e2476901a3151781c696e7465727072657465725f70726f66696c655f6964656e746974795820eaa6f8ca4f395d291fdb70af1bd47b804ab82aa17fdbc01b8aaeeb747f7d218c6e6275646765745f6365696c696e67a3657374657073016a726561645f6279746573006b77726974655f6279746573007073656d616e7469635f636c6f73757265a66d636f72655f6964656e746974795820ff446a07d0fd35f5e3810173bb892a3edc734071e080517333cf6fe3eec8d054727461726765745f69725f6964656e746974795820e3cb6e3a10ef06683006e01e549e50ba4e5c8bdee71ab73469a16849774def217565646963745f736f757263655f6964656e7469747958200101010101010101010101010101010101010101010101010101010101010101781a63616e6f6e6963616c5f6d65616e696e675f6964656e7469747958200303030303030303030303030303030303030303030303030303030303030303781b6170706c69636174696f6e5f736368656d615f6964656e746974795820e2089c3b5730d3b54a8a645cbf77d76492a0f36e98e23d6ecab5e4fd7fa7c265781d6170706c69636174696f6e5f736368656d615f636f6f7264696e6174656a6170702e536368656d61746f7065726174696f6e5f636f6f7264696e6174656c6170702e757064617465403175696e7075745f736368656d615f6964656e746974795820d277705b5ab03fcb58590bad62fb8058e075c3b4c65efc21282bb531aa22b3ad76726573756c745f736368656d615f6964656e746974795820de5c0c4f0c640354c40bb4f9d4886cd820353a548caea4953269eba15fe902bc777461726765745f70726f66696c655f6964656e746974795820eaca21c05664241efd1e1c5b5636c7132fe8854f6bcaddb2fd4f014e1bd4a479781a617574686f726974795f70726f66696c655f6964656e7469747958200808080808080808080808080808080808080808080808080808080808080808781a696e7472696e7369635f70726f66696c655f6964656e746974795820a0fc1b7a1e186598291754469fd6ea2220f676358284f7b84c7e2476901a3151781b666f6f747072696e745f636f6e74726163745f6964656e746974795820362b20fb18488ce180f6c1096b5189994354604fd1b1b126a3ea4ef839e5232b781b6f62737472756374696f6e5f736368656d615f6964656e746974795820b1f96fdf3ec65e84d500702951393a931b4fdd843ad02723ea3725f90a671418781c696e7465727072657465725f70726f66696c655f6964656e746974795820eaa6f8ca4f395d291fdb70af1bd47b804ab82aa17fdbc01b8aaeeb747f7d218c781e726573756c745f696e746572707265746174696f6e5f6964656e74697479582042734d5e73435acc0fdd5a66b97e5bfd94278e64fce2b4890ec609f054dc969e78206576616c756174696f6e5f62617369735f736368656d615f6964656e74697479582020b6239db569aa86ae1c27596b374df90caa5ea41e8e005fd4fe00bfe5c3b38178216170706c69636174696f6e5f62617369735f736368656d615f6964656e7469747958208b294c69120a2e749c56266691b0974e7e0323c198fc42a467fd3790790f791078236f62737472756374696f6e5f696e746572707265746174696f6e5f6964656e746974795820924462071f3992b34c629f4788cc666bd14a87a0b9d0c398feba929ff4dd25f9 diff --git a/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/read-captured-budget.hex b/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/read-captured-budget.hex new file mode 100644 index 00000000..68fe7213 --- /dev/null +++ b/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/read-captured-budget.hex @@ -0,0 +1 @@ +b166736368656d6178196563686f2e6f7065726174696f6e2d7061636b6167652f76316770726f6772616d59304dad646b696e647765646963742d6566666563742d70726f6772616d2f763166736368656d6178196563686f2e6f7065726174696f6e2d70726f6772616d2f76316b6f75747075745f74797065766a656469742e7465787440312e4661637442797465736c67726170685f736368656d615876a26a656467655f7479706573a06a6e6f64655f7479706573a158200101010101010101010101010101010101010101010101010101010101010101a26a61646472657373696e67016a61746f6d5f747970657381582002020202020202020202020202020202020202020202020202020202020202026c6964656e746974795f6c6177016d666f6f747072696e745f6c617758f6a9696d61785f7265616473016a61746f6d5f747970657381582002020202020202020202020202020202020202020202020202020202020202026a6d61785f777269746573016f6d61785f72616e67655f6564676573006f726561645f6e6f64655f747970657381582001010101010101010101010101010101010101010101010101010101010101017072616e67655f656467655f7479706573807077726974655f656467655f7479706573807077726974655f6e6f64655f7479706573815820010101010101010101010101010101010101010101010101010101010101010172706f7274616c5f6f776e65725f7479706573806f6d61785f696e7075745f62797465731a0001000070636f6d70696c65645f70726f6772616d592d46a666696e74656e746c7265706c61636552616e676566736368656d6178286563686f2e636f6d70696c65722d70726f64756365642d6566666563742d70726f6772616d2f76316d636f72655f61727469666163745909caa6657479706573a365496e707574a2646b696e64665265636f7264666669656c6473a2676164647265737378186a656469742e7465787440312e4661637441646472657373686578706563746564766a656469742e7465787440312e466163744279746573766a656469742e7465787440312e466163744279746573a2636d61781a00100000646b696e6465427974657378186a656469742e7465787440312e4661637441646472657373a2646b696e64665265636f7264666669656c6473a3666e6f646549646f42797465733c65786163743d33323e667479706549646f42797465733c65786163743d33323e667761727049646f42797465733c65786163743d33323e67696d706f72747381a263726566a26269646c6a656469742e74657874403166646967657374826673686132353658208d5c6edb069c707261b1547f74c339f859d420a4b778c197d2f7138d5ba29216646b696e64676c61777061636b67696e74656e7473a16c7265706c61636552616e6765a764626f6479a3656e6f64657382a5646b696e646665666665637465696e707574a36462617365a263726566a3626964656172672e30647479706578206a656469742e746578742e7265706c6163655f72616e676540312e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646761646472657373666566666563746d746578742e72656164466163746762696e64696e67a3626964676c6f63616c2e306474797065766a656469742e7465787440312e46616374427974657369616c7068614e616d6567246c6f63616c306e6f62737472756374696f6e4d6170a4676d697373696e67a26576616c7565a4646172677380646b696e646463616c6c6663616c6c656570746578742e466163744d697373696e67687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e30647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e30676e6f7441746f6da26576616c7565a4646172677380646b696e646463616c6c6663616c6c656572746578742e466163744d616c666f726d6564687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e31647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e3168746f6f4c61726765a26576616c7565a4646172677380646b696e646463616c6c6663616c6c656572746578742e466163744d616c666f726d6564687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e32647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e326c747970654d69736d61746368a26576616c7565a4646172677380646b696e646463616c6c6663616c6c656572746578742e466163744d616c666f726d6564687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e33647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e33a3646b696e646772657175697265696f6e4661696c757265a2646b696e64687465726d696e616c66726561736f6ea2677061796c6f6164a06a726561736f6e4b696e6476746578742e42617369734e6f7443616e6f6e6963616c69707265646963617465a4626f70623d3d646b696e6467636f6d70617265646c656674a263726566a3626964676c6f63616c2e306474797065766a656469742e7465787440312e46616374427974657369616c7068614e616d6567246c6f63616c30646b696e64656c6f63616c657269676874a36462617365a263726566a3626964656172672e30647479706578206a656469742e746578742e7265706c6163655f72616e676540312e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c64686578706563746564666c6f63616c7386a3626964656172672e30647479706578206a656469742e746578742e7265706c6163655f72616e676540312e496e70757469616c7068614e616d65652461726730a3626964676c6f63616c2e306474797065766a656469742e7465787440312e46616374427974657369616c7068614e616d6567246c6f63616c30a36269646d6f62737472756374696f6e2e30647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e30a36269646d6f62737472756374696f6e2e31647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e31a36269646d6f62737472756374696f6e2e32647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e32a36269646d6f62737472756374696f6e2e33647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e3366726573756c74a263726566a3626964676c6f63616c2e306474797065766a656469742e7465787440312e46616374427974657369616c7068614e616d6567246c6f63616c30646b696e64656c6f63616c656261736973a36462617365a36462617365a263726566a3626964656172672e30647479706578206a656469742e746578742e7265706c6163655f72616e676540312e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646761646472657373646b696e64656669656c64656669656c64666e6f6465496465696e70757478206a656469742e746578742e7265706c6163655f72616e676540312e496e707574666f7574707574766a656469742e7465787440312e46616374427974657370696e707574436f6e73747261696e74738074636f72654576616c756174696f6e427564676574a3686d617853746570731a001000006e6d61784f757470757442797465731a00800000716d6178416c6c6f636174656442797465731a01000000781872657175697265644f7065726174696f6e50726f66696c65781e636f6e74696e75756d2e70726f66696c652e726561642d6f6e6c792f76316a61706956657273696f6e6d65646963742e636f72652f76316a636f6f7264696e617465781a6a656469742e746578742e7265706c6163655f72616e6765403178187265717569726564436f72654361706162696c697469657380726c6f776572696e675f617274696661637473a56f736f757263655f61727469666163745902d55902d27061636b616765206a656469742e746578742e7265706c6163655f72616e676540313b0a757365206c61777061636b206a656469742e7465787440312064696765737420227368613235363a386435633665646230363963373037323631623135343766373463333339663835396434323061346237373863313937643266373133386435626132393231362220617320746578743b0a7479706520496e707574203d207b20616464726573733a20746578742e46616374416464726573732c2065787065637465643a20746578742e466163744279746573207d3b0a696e74656e74207265706c61636552616e676528696e7075743a20496e707574292072657475726e7320746578742e4661637442797465730a202070726f66696c6520746578742e7265706c61636552616e67650a2020626173697320696e7075742e616464726573732e6e6f646549640a2020627564676574203c3d20746578742e7265706c61636552616e67654275646765740a7b0a20206c65742061637475616c3a20746578742e466163744279746573203d20746578742e726561644661637428696e7075742e61646472657373290a20202020656c7365207b0a2020202020206d697373696e67286164647265737329203d3e20746578742e466163744d697373696e672c0a202020202020747970654d69736d61746368286164647265737329203d3e20746578742e466163744d616c666f726d65642c0a2020202020206e6f7441746f6d286164647265737329203d3e20746578742e466163744d616c666f726d65642c0a202020202020746f6f4c61726765286164647265737329203d3e20746578742e466163744d616c666f726d65642c0a202020207d3b0a2020726571756972652061637475616c203d3d20696e7075742e657870656374656420656c736520746578742e42617369734e6f7443616e6f6e6963616c3b0a202072657475726e2061637475616c3b0a7d0a70616461707465725f6172746966616374590377a565636c6173736b6465636c617261746976656762756467657473a1781f6a656469742e7465787440312e7265706c61636552616e6765427564676574a3686d617853746570731a001000006e6d61784f757470757442797465731a00800000716d6178416c6c6f636174656442797465731a010000006a61706956657273696f6e781865646963742e6c61777061636b2d616461707465722f7631716f7065726174696f6e50726f66696c6573a178196a656469742e7465787440312e7265706c61636552616e6765a464636f7265781e636f6e74696e75756d2e70726f66696c652e726561642d6f6e6c792f76316f73656d616e7469634566666563747381756a656469742e7465787440312e7265616446616374706275646765744f626c69676174696f6e781f6a656469742e7465787440312e7265706c61636552616e676542756467657473746172676574436f6e66696775726174696f6ea262696478286563686f2e6f7065726174696f6e2d6c6f776572696e672d636f6e66696775726174696f6e2f7631666469676573748266736861323536582056921f7058a4b68027c3e5415150b2c6ef4388b000c2ea649cd7a14d3f565f7e75656666656374496d706c656d656e746174696f6e73a1756a656469742e7465787440312e7265616446616374a66a7772697465436c61737364726561646e636f73744f626c69676174696f6e781f6a656469742e7465787440312e7265706c61636552616e67654275646765746f6661696c7572654d617070696e6773a4676d697373696e676b61746f6d4d697373696e67676e6f7441746f6d6c61746f6d526571756972656468746f6f4c617267657561746f6d42797465426f756e6445786365656465646c747970654d69736d617463687061746f6d547970654d69736d617463686f746172676574496e7472696e73696378196563686f2e64706f40312e6e6f64652d61746f6d2d7265616473666f6f747072696e744f626c69676174696f6e78226a656469742e7465787440312e7265706c61636552616e6765466f6f747072696e7473746172676574436f6e66696775726174696f6ea262696478286563686f2e6f7065726174696f6e2d6c6f776572696e672d636f6e66696775726174696f6e2f7631666469676573748266736861323536582056921f7058a4b68027c3e5415150b2c6ef4388b000c2ea649cd7a14d3f565f7e706c61777061636b5f6172746966616374590313aa6269646a6a656469742e74657874676578706f727473a2626964756a656469742e746578742e6578706f7274732f763166646967657374826673686132353658200c75bcc42fd23d9eafdc81f1d81754be32cde98170c5fc1fbaf2746ffef992846776657273696f6e6131687665726966696572a265636c6173736b6465636c617261746976656772756c65736574a2626964781c6a656469742e746578742e76657269666965722d72756c65732f76316664696765737482667368613235365820364fb4ff98ae64fcd8d793aae3d7cb133ff8a1ce661330cea47688b13a0a823f6a61706956657273696f6e7065646963742e6c61777061636b2f76316c646570656e64656e63696573806d636f6d7061746962696c697479a2626964781b6a656469742e746578742e636f6d7061746962696c6974792f763166646967657374826673686132353658202adf83f798205f52636ad64ca45178f33a8e1cc663874f8a6113484c945e30526e746172676574416461707465727381a36761646170746572a2626964781a6a656469742e746578742e6563686f2d616461707465722f763166646967657374826673686132353658207d09bca6885352b8e6198f2a7a1558b914395794e90469741b65618b4ab9bb887061636365707465645461726765744972a26269646f6563686f2e7370616e2d69722f76326664696765737482667368613235365820123e7f805dc5e831e88befec4cd49ec02c39858b6f3990da8a73b50c6086ae3975616363657074656454617267657450726f66696c65a26269646a6563686f2e64706f40316664696765737482667368613235365820e9ba4aab52c815b673aa4b03165ab32863de5052c342b938005d1c0013d5c8fc6f6163636570746564436f7265416269816d65646963742e636f72652f76317818636f6e666f726d616e636546697874757265436f72707573a262696478206a656469742e746578742e5265706c61636552616e67652e6f7261636c6540316664696765737482667368613235365820b9b4707dd5e07897cbe7af36d88928401887e6af5d167d1a88a8d6181b4dbb0e73696e7472696e736963735f617274696661637459030aa26a61706956657273696f6e782265646963742e7461726765742d70726f66696c652e696e7472696e736963732f76316a696e7472696e73696373a178196563686f2e64706f40312e6e6f64652d61746f6d2d72656164ab6a6566666563744b696e6464726561646a72657475726e5479706578206563686f2e64706f40312e6e6f64652d61746f6d2d726561642e726573756c746a7772697465436c61737364726561646c636f737454656d706c617465781f6a656469742e7465787440312e7265706c61636552616e67654275646765746c6775617264537570706f7274f56d617267756d656e74547970657381781f6563686f2e64706f40312e6e6f64652d61746f6d2d726561642e696e7075746e6566666563744661696c75726573a46b61746f6d4d697373696e67a26b7061796c6f616454797065781f6563686f2e64706f40312e6e6f64652d61746f6d2d726561642e696e7075746e617574686f72697479436c6173736d7265736f757263654661756c746c61746f6d5265717569726564a26b7061796c6f616454797065781f6563686f2e64706f40312e6e6f64652d61746f6d2d726561642e696e7075746e617574686f72697479436c6173736e696e746567726974794661756c747061746f6d547970654d69736d61746368a26b7061796c6f616454797065781f6563686f2e64706f40312e6e6f64652d61746f6d2d726561642e696e7075746e617574686f72697479436c6173736e696e746567726974794661756c747561746f6d42797465426f756e644578636565646564a26b7061796c6f616454797065781f6563686f2e64706f40312e6e6f64652d61746f6d2d726561642e696e7075746e617574686f72697479436c6173736e696e746567726974794661756c746e696e7472696e736963436c617373666566666563746e74797065506172616d65746572738071666f6f747072696e7454656d706c61746578226a656469742e7465787440312e7265706c61636552616e6765466f6f747072696e74781b63616e5061727469636970617465496e41746f6d69634775617264f5777461726765745f70726f66696c655f61727469666163745906fbb81c626964686563686f2e64706f676c6f7765726572a2626964736563686f2e64706f2e6c6f77657265722f7631666469676573748266736861323536582044ca28eeeccc4ff522fd9ec7e4694124f4e04880171c8cce460eefcb9505b7976773616e64626f78a26269647765646963742e7761736d2d636f6d706f6e656e742f76316664696765737482667368613235365820095b4dd18f1a6a7276533f758665be319c5f476e7bdc70cc56d30b6b3e9f0a806776657273696f6e6131687461726765744972a26269646f6563686f2e7370616e2d69722f76326664696765737482667368613235365820123e7f805dc5e831e88befec4cd49ec02c39858b6f3990da8a73b50c6086ae39687665726966696572a2626964746563686f2e64706f2e76657269666965722f76316664696765737482667368613235365820ca96b190728de3d668072ec1bd37d24e5197e7bd9bd54f70966d8c566b9b67f2696675656c4d6f64656ca26269646d65646963742e6675656c2f76316664696765737482667368613235365820006c6ebc01a3c5d36d50bd390b69d47e42378be61074e3b5c96ecb9f5ee532076a61706956657273696f6e7765646963742e7461726765742d70726f66696c652f76316a696e7472696e73696373a2626964766563686f2e64706f2e696e7472696e736963732f76316664696765737482667368613235365820865e4a94955f49bc97975acd2ff7670d4576296d68a72de1bcacbb3d5b8cfb666b636f7374416c6765627261a2626964706563686f2e64706f2e636f73742f76316664696765737482667368613235365820486940acd1d4bc15cea40db29347619a07202d9c0f1e63c4016c26bccf0b52a86b6d756c7469546172676574f46d62756e646c6550726f66696c65a2626964726563686f2e64706f2e62756e646c652f76316664696765737482667368613235365820aa0438bcc6ef14ee6cb6d4976622f6080381d731459dcb7b9102595c9bed92c06d646961676e6f73746963416269a26269647465646963742e646961676e6f73746963732f7631666469676573748266736861323536582028fd72a98223153982ca084c29dbb1b2d430623967ab3b6db9d7fee668e614b96f6163636570746564436f7265416269816d65646963742e636f72652f76316f67756172644576616c756174696f6e70707265636f6d6d69742d61746f6d69636f72656164436f6e73697374656e6379746170706c69636174696f6e2d736e617073686f74706170706c69636174696f6e4d6f64656c6661746f6d696370666f6f747072696e74416c6765627261a2626964756563686f2e64706f2e666f6f747072696e742f76316664696765737482667368613235365820f47bb65867e78099ddcfd6ae7af83870df8823f974a496a111ed94e5d785c769716f7065726174696f6e50726f66696c6573a2626964781e6563686f2e64706f2e6f7065726174696f6e2d70726f66696c65732f7631666469676573748266736861323536582053256c51f6c817a77cc8694458bf9d3891abd15b9c94f79ca97d920d3c5f041672696e7472696e7369634e616d6573706163656a6563686f2e64706f4031736f62737472756374696f6e526f6c6c6261636b726e6f2d76697369626c652d65666665637473736f62737472756374696f6e5461786f6e6f6d79a262696478186563686f2e64706f2e6f62737472756374696f6e732f763166646967657374826673686132353658204f5a139d606053c3807f50710076ea9abeb0e611c12a530f5e5b4b31911c3e6474706f7374636f6e646974696f6e537570706f7274f57663616e6f6e6963616c456e636f64696e6752756c6573a26269647765646963742e63616e6f6e6963616c2d63626f722f76316664696765737482667368613235365820d1ea6d3de2a9762a438cbf4fac1d5ae2f357a4b27d13e0347e94ea655bf40f9d7664657465726d696e6973746963457865637574696f6ea26269647465646963742e64657465726d696e69736d2f76316664696765737482667368613235365820af4e6c774d5ea82db30e680be2ba7abc5ba04c6aead146139de32d8c5bb4981e7818636f6e666f726d616e636546697874757265436f72707573a2626964746563686f2e64706f2e66697874757265732f763166646967657374826673686132353658208fa81d37ae4eecb79252f310e7532fc9872bd7c17f2722da911fa74620f81b43781961636365707465644c61777061636b4164617074657241626981781865646963742e6c61777061636b2d616461707465722f7631781967656e657261746564417274696661637450726f66696c657381a262696478186563686f2e64706f2e726567697374726174696f6e2f76316664696765737482667368613235365820ff88be93c26cc533948d8a93601954dc391912d593ca1e96115c846cbf2c5b5d727461726765745f69725f617274696661637459087aa6646b696e64776f7264657265645461726765744972417274696661637466646f6d61696e6f6563686f2e7370616e2d69722f763267696e74656e7473a16c7265706c61636552616e6765a8656261736973a36462617365a36462617365a263726566a3626964656172672e30647479706578206a656469742e746578742e7265706c6163655f72616e676540312e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646761646472657373646b696e64656669656c64656669656c64666e6f6465496465737465707381a7626964737265706c61636552616e67652e737465702e3065696e707574a36462617365a263726566a3626964656172672e30647479706578206a656469742e746578742e7265706c6163655f72616e676540312e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646761646472657373666566666563746d746578742e72656164466163746762696e64696e67a3626964676c6f63616c2e306474797065766a656469742e7465787440312e46616374427974657369616c7068614e616d6567246c6f63616c306f6f62737472756374696f6e41726d73a46b61746f6d4d697373696e67a26576616c7565a4646172677380646b696e646463616c6c6663616c6c656570746578742e466163744d697373696e67687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e30647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e306c61746f6d5265717569726564a26576616c7565a4646172677380646b696e646463616c6c6663616c6c656572746578742e466163744d616c666f726d6564687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e31647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e317061746f6d547970654d69736d61746368a26576616c7565a4646172677380646b696e646463616c6c6663616c6c656572746578742e466163744d616c666f726d6564687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e33647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e337561746f6d42797465426f756e644578636565646564a26576616c7565a4646172677380646b696e646463616c6c6663616c6c656572746578742e466163744d616c666f726d6564687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e32647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e326f746172676574496e7472696e73696378196563686f2e64706f40312e6e6f64652d61746f6d2d72656164736f62737472756374696f6e4661696c75726573847561746f6d42797465426f756e6445786365656465646b61746f6d4d697373696e676c61746f6d52657175697265647061746f6d547970654d69736d6174636866726573756c74a263726566a3626964676c6f63616c2e306474797065766a656469742e7465787440312e46616374427974657369616c7068614e616d6567246c6f63616c30646b696e64656c6f63616c6c726571756972656d656e747381a3626964767265706c61636552616e67652e726571756972652e30696f6e4661696c757265a2646b696e64687465726d696e616c66726561736f6ea2677061796c6f6164a06a726561736f6e4b696e6476746578742e42617369734e6f7443616e6f6e6963616c69707265646963617465a4626f70623d3d646b696e6467636f6d70617265646c656674a263726566a3626964676c6f63616c2e306474797065766a656469742e7465787440312e46616374427974657369616c7068614e616d6567246c6f63616c30646b696e64656c6f63616c657269676874a36462617365a263726566a3626964656172672e30647479706578206a656469742e746578742e7265706c6163655f72616e676540312e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646865787065637465646e657865637574696f6e4f7264657282737265706c61636552616e67652e737465702e30767265706c61636552616e67652e726571756972652e3070696e707574436f6e73747261696e747380706f7065726174696f6e50726f66696c65781e636f6e74696e75756d2e70726f66696c652e726561642d6f6e6c792f763174636f72654576616c756174696f6e427564676574a3686d617853746570731a001000006e6d61784f757470757442797465731a00800000716d6178416c6c6f636174656442797465731a010000006d74617267657450726f66696c65a26269646a6563686f2e64706f40316664696765737482667368613235365820e9ba4aab52c815b673aa4b03165ab32863de5052c342b938005d1c0013d5c8fc6f73656d616e746963436c6f73757265a2686c61777061636b7381a26269646c6a656469742e74657874403166646967657374826673686132353658208d5c6edb069c707261b1547f74c339f859d420a4b778c197d2f7138d5ba292166a736f75726365436f7265a2626964781a6a656469742e746578742e7265706c6163655f72616e67654031666469676573748266736861323536582095fe73809936807160634242ac87ca868e7c660382cad923c8c0cf7aff96aa3074736f75726365436f7265436f6f7264696e617465781a6a656469742e746578742e7265706c6163655f72616e6765403178186c61777061636b5f6578706f7274735f6172746966616374590693a665747970657383a26a636f6f7264696e61746578186a656469742e7465787440312e46616374416464726573736a646566696e6974696f6e784c5265636f72643c6e6f646549643a42797465733c65786163743d33323e2c7479706549643a42797465733c65786163743d33323e2c7761727049643a42797465733c65786163743d33323e3ea26a636f6f7264696e617465766a656469742e7465787440312e4661637442797465736a646566696e6974696f6e7242797465733c6d61783d313034383537363ea26a636f6f7264696e617465781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6a646566696e6974696f6e7822537472696e673c6d61783d3235362c63616e6f6e6963616c3d7261772d757466383e676566666563747381aa69696e7075745479706578186a656469742e7465787440312e46616374416464726573736a636f6f7264696e617465756a656469742e7465787440312e72656164466163746a6f757470757454797065766a656469742e7465787440312e4661637442797465736c6775617264537570706f7274f56e636f73744f626c69676174696f6e781f6a656469742e7465787440312e7265706c61636552616e67654275646765746e6566666563744661696c75726573a4676d697373696e67a26b7061796c6f61645479706578186a656469742e7465787440312e46616374416464726573736e617574686f72697479436c6173736d7265736f757263654661756c74676e6f7441746f6da26b7061796c6f61645479706578186a656469742e7465787440312e46616374416464726573736e617574686f72697479436c6173736e696e746567726974794661756c7468746f6f4c61726765a26b7061796c6f61645479706578186a656469742e7465787440312e46616374416464726573736e617574686f72697479436c6173736e696e746567726974794661756c746c747970654d69736d61746368a26b7061796c6f61645479706578186a656469742e7465787440312e46616374416464726573736e617574686f72697479436c6173736e696e746567726974794661756c746e6566666563744b696e6448696e7464726561646e657865637574696f6e436c6173736772756e74696d656e74797065506172616d65746572738073666f6f747072696e744f626c69676174696f6e78226a656469742e7465787440312e7265706c61636552616e6765466f6f747072696e7469636f6e7374616e7473806c6f62737472756374696f6e7383a36a636f6f7264696e617465781e6a656469742e7465787440312e42617369734e6f7443616e6f6e6963616c6d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736e646f6d61696e4d61707061626c65a36a636f6f7264696e61746578186a656469742e7465787440312e466163744d697373696e676d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736d7265736f757263654661756c74a36a636f6f7264696e617465781a6a656469742e7465787440312e466163744d616c666f726d65646d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736e696e746567726974794661756c746d7075726546756e6374696f6e7380716f7065726174696f6e50726f66696c6573a178196a656469742e7465787440312e7265706c61636552616e6765a26d6f7074696354656d706c617465a6696f707469634b696e64736166666563745265696e746567726174696f6e6c626f756e646172794b696e64666166666563746d626173697354656d706c617465781b6a656469742e7465787440312e65786163744865616442617369736d737570706f7274506f6c696379781e6a656469742e7465787440312e6261736973426f756e64537570706f72746f6c6f7373446973706f736974696f6e756a656469742e7465787440312e6c6f73736c657373736170657274757265526571756972656d656e74a26372656678226a656469742e7465787440312e7265706c61636552616e6765466f6f747072696e74646b696e64781b6162737472616374466f6f747072696e744f626c69676174696f6e6f65666665637450726564696361746578206a656469742e7465787440312e7265706c61636552616e676545666665637473706d61785f726573756c745f62797465731a00010000727461726765745f69725f6964656e746974795820640983db725b5d5e9c2a7ecf7de54fd6177c6d4c5fd1b58ca04da0ff0207db19736d61785f616c6c6f63617465645f62797465731a01000000781a696e7472696e7369635f70726f66696c655f6964656e746974795820a0fc1b7a1e186598291754469fd6ea2220f676358284f7b84c7e2476901a3151781c696e7465727072657465725f70726f66696c655f6964656e746974795820eaa6f8ca4f395d291fdb70af1bd47b804ab82aa17fdbc01b8aaeeb747f7d218c6e6275646765745f6365696c696e67a3657374657073016a726561645f6279746573006b77726974655f6279746573007073656d616e7469635f636c6f73757265a66d636f72655f6964656e74697479582095fe73809936807160634242ac87ca868e7c660382cad923c8c0cf7aff96aa30727461726765745f69725f6964656e746974795820640983db725b5d5e9c2a7ecf7de54fd6177c6d4c5fd1b58ca04da0ff0207db197565646963745f736f757263655f6964656e7469747958200101010101010101010101010101010101010101010101010101010101010101781a63616e6f6e6963616c5f6d65616e696e675f6964656e7469747958200303030303030303030303030303030303030303030303030303030303030303781b6170706c69636174696f6e5f736368656d615f6964656e7469747958200c75bcc42fd23d9eafdc81f1d81754be32cde98170c5fc1fbaf2746ffef99284781d6170706c69636174696f6e5f736368656d615f636f6f7264696e6174656a6170702e536368656d61746f7065726174696f6e5f636f6f7264696e61746578276a656469742e746578742e7265706c6163655f72616e676540312e7265706c61636552616e676575696e7075745f736368656d615f6964656e746974795820d277705b5ab03fcb58590bad62fb8058e075c3b4c65efc21282bb531aa22b3ad76726573756c745f736368656d615f6964656e746974795820de5c0c4f0c640354c40bb4f9d4886cd820353a548caea4953269eba15fe902bc777461726765745f70726f66696c655f6964656e746974795820eaca21c05664241efd1e1c5b5636c7132fe8854f6bcaddb2fd4f014e1bd4a479781a617574686f726974795f70726f66696c655f6964656e7469747958200808080808080808080808080808080808080808080808080808080808080808781a696e7472696e7369635f70726f66696c655f6964656e746974795820a0fc1b7a1e186598291754469fd6ea2220f676358284f7b84c7e2476901a3151781b666f6f747072696e745f636f6e74726163745f6964656e746974795820362b20fb18488ce180f6c1096b5189994354604fd1b1b126a3ea4ef839e5232b781b6f62737472756374696f6e5f736368656d615f6964656e746974795820b1f96fdf3ec65e84d500702951393a931b4fdd843ad02723ea3725f90a671418781c696e7465727072657465725f70726f66696c655f6964656e746974795820eaa6f8ca4f395d291fdb70af1bd47b804ab82aa17fdbc01b8aaeeb747f7d218c781e726573756c745f696e746572707265746174696f6e5f6964656e74697479582042734d5e73435acc0fdd5a66b97e5bfd94278e64fce2b4890ec609f054dc969e78206576616c756174696f6e5f62617369735f736368656d615f6964656e74697479582020b6239db569aa86ae1c27596b374df90caa5ea41e8e005fd4fe00bfe5c3b38178216170706c69636174696f6e5f62617369735f736368656d615f6964656e7469747958208b294c69120a2e749c56266691b0974e7e0323c198fc42a467fd3790790f791078236f62737472756374696f6e5f696e746572707265746174696f6e5f6964656e746974795820924462071f3992b34c629f4788cc666bd14a87a0b9d0c398feba929ff4dd25f9 diff --git a/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/read-control.hex b/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/read-control.hex new file mode 100644 index 00000000..be73bb09 --- /dev/null +++ b/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/read-control.hex @@ -0,0 +1 @@ +b166736368656d6178196563686f2e6f7065726174696f6e2d7061636b6167652f76316770726f6772616d59304dad646b696e647765646963742d6566666563742d70726f6772616d2f763166736368656d6178196563686f2e6f7065726174696f6e2d70726f6772616d2f76316b6f75747075745f74797065766a656469742e7465787440312e4661637442797465736c67726170685f736368656d615876a26a656467655f7479706573a06a6e6f64655f7479706573a158200101010101010101010101010101010101010101010101010101010101010101a26a61646472657373696e67016a61746f6d5f747970657381582002020202020202020202020202020202020202020202020202020202020202026c6964656e746974795f6c6177016d666f6f747072696e745f6c617758f6a9696d61785f7265616473016a61746f6d5f747970657381582002020202020202020202020202020202020202020202020202020202020202026a6d61785f777269746573016f6d61785f72616e67655f6564676573006f726561645f6e6f64655f747970657381582001010101010101010101010101010101010101010101010101010101010101017072616e67655f656467655f7479706573807077726974655f656467655f7479706573807077726974655f6e6f64655f7479706573815820010101010101010101010101010101010101010101010101010101010101010172706f7274616c5f6f776e65725f7479706573806f6d61785f696e7075745f62797465731a0001000070636f6d70696c65645f70726f6772616d592d46a666696e74656e746c7265706c61636552616e676566736368656d6178286563686f2e636f6d70696c65722d70726f64756365642d6566666563742d70726f6772616d2f76316d636f72655f61727469666163745909caa6657479706573a365496e707574a2646b696e64665265636f7264666669656c6473a2676164647265737378186a656469742e7465787440312e4661637441646472657373686578706563746564766a656469742e7465787440312e466163744279746573766a656469742e7465787440312e466163744279746573a2636d61781a00100000646b696e6465427974657378186a656469742e7465787440312e4661637441646472657373a2646b696e64665265636f7264666669656c6473a3666e6f646549646f42797465733c65786163743d33323e667479706549646f42797465733c65786163743d33323e667761727049646f42797465733c65786163743d33323e67696d706f72747381a263726566a26269646c6a656469742e74657874403166646967657374826673686132353658208d5c6edb069c707261b1547f74c339f859d420a4b778c197d2f7138d5ba29216646b696e64676c61777061636b67696e74656e7473a16c7265706c61636552616e6765a764626f6479a3656e6f64657382a5646b696e646665666665637465696e707574a36462617365a263726566a3626964656172672e30647479706578206a656469742e746578742e7265706c6163655f72616e676540312e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646761646472657373666566666563746d746578742e72656164466163746762696e64696e67a3626964676c6f63616c2e306474797065766a656469742e7465787440312e46616374427974657369616c7068614e616d6567246c6f63616c306e6f62737472756374696f6e4d6170a4676d697373696e67a26576616c7565a4646172677380646b696e646463616c6c6663616c6c656570746578742e466163744d697373696e67687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e30647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e30676e6f7441746f6da26576616c7565a4646172677380646b696e646463616c6c6663616c6c656572746578742e466163744d616c666f726d6564687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e31647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e3168746f6f4c61726765a26576616c7565a4646172677380646b696e646463616c6c6663616c6c656572746578742e466163744d616c666f726d6564687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e32647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e326c747970654d69736d61746368a26576616c7565a4646172677380646b696e646463616c6c6663616c6c656572746578742e466163744d616c666f726d6564687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e33647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e33a3646b696e646772657175697265696f6e4661696c757265a2646b696e64687465726d696e616c66726561736f6ea2677061796c6f6164a06a726561736f6e4b696e6476746578742e42617369734e6f7443616e6f6e6963616c69707265646963617465a4626f70623d3d646b696e6467636f6d70617265646c656674a263726566a3626964676c6f63616c2e306474797065766a656469742e7465787440312e46616374427974657369616c7068614e616d6567246c6f63616c30646b696e64656c6f63616c657269676874a36462617365a263726566a3626964656172672e30647479706578206a656469742e746578742e7265706c6163655f72616e676540312e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c64686578706563746564666c6f63616c7386a3626964656172672e30647479706578206a656469742e746578742e7265706c6163655f72616e676540312e496e70757469616c7068614e616d65652461726730a3626964676c6f63616c2e306474797065766a656469742e7465787440312e46616374427974657369616c7068614e616d6567246c6f63616c30a36269646d6f62737472756374696f6e2e30647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e30a36269646d6f62737472756374696f6e2e31647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e31a36269646d6f62737472756374696f6e2e32647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e32a36269646d6f62737472756374696f6e2e33647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e3366726573756c74a263726566a3626964676c6f63616c2e306474797065766a656469742e7465787440312e46616374427974657369616c7068614e616d6567246c6f63616c30646b696e64656c6f63616c656261736973a36462617365a36462617365a263726566a3626964656172672e30647479706578206a656469742e746578742e7265706c6163655f72616e676540312e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646761646472657373646b696e64656669656c64656669656c64666e6f6465496465696e70757478206a656469742e746578742e7265706c6163655f72616e676540312e496e707574666f7574707574766a656469742e7465787440312e46616374427974657370696e707574436f6e73747261696e74738074636f72654576616c756174696f6e427564676574a3686d617853746570731a004000006e6d61784f757470757442797465731a00800000716d6178416c6c6f636174656442797465731a01000000781872657175697265644f7065726174696f6e50726f66696c65781e636f6e74696e75756d2e70726f66696c652e726561642d6f6e6c792f76316a61706956657273696f6e6d65646963742e636f72652f76316a636f6f7264696e617465781a6a656469742e746578742e7265706c6163655f72616e6765403178187265717569726564436f72654361706162696c697469657380726c6f776572696e675f617274696661637473a56f736f757263655f61727469666163745902d55902d27061636b616765206a656469742e746578742e7265706c6163655f72616e676540313b0a757365206c61777061636b206a656469742e7465787440312064696765737420227368613235363a386435633665646230363963373037323631623135343766373463333339663835396434323061346237373863313937643266373133386435626132393231362220617320746578743b0a7479706520496e707574203d207b20616464726573733a20746578742e46616374416464726573732c2065787065637465643a20746578742e466163744279746573207d3b0a696e74656e74207265706c61636552616e676528696e7075743a20496e707574292072657475726e7320746578742e4661637442797465730a202070726f66696c6520746578742e7265706c61636552616e67650a2020626173697320696e7075742e616464726573732e6e6f646549640a2020627564676574203c3d20746578742e7265706c61636552616e67654275646765740a7b0a20206c65742061637475616c3a20746578742e466163744279746573203d20746578742e726561644661637428696e7075742e61646472657373290a20202020656c7365207b0a2020202020206d697373696e67286164647265737329203d3e20746578742e466163744d697373696e672c0a202020202020747970654d69736d61746368286164647265737329203d3e20746578742e466163744d616c666f726d65642c0a2020202020206e6f7441746f6d286164647265737329203d3e20746578742e466163744d616c666f726d65642c0a202020202020746f6f4c61726765286164647265737329203d3e20746578742e466163744d616c666f726d65642c0a202020207d3b0a2020726571756972652061637475616c203d3d20696e7075742e657870656374656420656c736520746578742e42617369734e6f7443616e6f6e6963616c3b0a202072657475726e2061637475616c3b0a7d0a70616461707465725f6172746966616374590377a565636c6173736b6465636c617261746976656762756467657473a1781f6a656469742e7465787440312e7265706c61636552616e6765427564676574a3686d617853746570731a001000006e6d61784f757470757442797465731a00800000716d6178416c6c6f636174656442797465731a010000006a61706956657273696f6e781865646963742e6c61777061636b2d616461707465722f7631716f7065726174696f6e50726f66696c6573a178196a656469742e7465787440312e7265706c61636552616e6765a464636f7265781e636f6e74696e75756d2e70726f66696c652e726561642d6f6e6c792f76316f73656d616e7469634566666563747381756a656469742e7465787440312e7265616446616374706275646765744f626c69676174696f6e781f6a656469742e7465787440312e7265706c61636552616e676542756467657473746172676574436f6e66696775726174696f6ea262696478286563686f2e6f7065726174696f6e2d6c6f776572696e672d636f6e66696775726174696f6e2f7631666469676573748266736861323536582056921f7058a4b68027c3e5415150b2c6ef4388b000c2ea649cd7a14d3f565f7e75656666656374496d706c656d656e746174696f6e73a1756a656469742e7465787440312e7265616446616374a66a7772697465436c61737364726561646e636f73744f626c69676174696f6e781f6a656469742e7465787440312e7265706c61636552616e67654275646765746f6661696c7572654d617070696e6773a4676d697373696e676b61746f6d4d697373696e67676e6f7441746f6d6c61746f6d526571756972656468746f6f4c617267657561746f6d42797465426f756e6445786365656465646c747970654d69736d617463687061746f6d547970654d69736d617463686f746172676574496e7472696e73696378196563686f2e64706f40312e6e6f64652d61746f6d2d7265616473666f6f747072696e744f626c69676174696f6e78226a656469742e7465787440312e7265706c61636552616e6765466f6f747072696e7473746172676574436f6e66696775726174696f6ea262696478286563686f2e6f7065726174696f6e2d6c6f776572696e672d636f6e66696775726174696f6e2f7631666469676573748266736861323536582056921f7058a4b68027c3e5415150b2c6ef4388b000c2ea649cd7a14d3f565f7e706c61777061636b5f6172746966616374590313aa6269646a6a656469742e74657874676578706f727473a2626964756a656469742e746578742e6578706f7274732f763166646967657374826673686132353658200c75bcc42fd23d9eafdc81f1d81754be32cde98170c5fc1fbaf2746ffef992846776657273696f6e6131687665726966696572a265636c6173736b6465636c617261746976656772756c65736574a2626964781c6a656469742e746578742e76657269666965722d72756c65732f76316664696765737482667368613235365820364fb4ff98ae64fcd8d793aae3d7cb133ff8a1ce661330cea47688b13a0a823f6a61706956657273696f6e7065646963742e6c61777061636b2f76316c646570656e64656e63696573806d636f6d7061746962696c697479a2626964781b6a656469742e746578742e636f6d7061746962696c6974792f763166646967657374826673686132353658202adf83f798205f52636ad64ca45178f33a8e1cc663874f8a6113484c945e30526e746172676574416461707465727381a36761646170746572a2626964781a6a656469742e746578742e6563686f2d616461707465722f763166646967657374826673686132353658207d09bca6885352b8e6198f2a7a1558b914395794e90469741b65618b4ab9bb887061636365707465645461726765744972a26269646f6563686f2e7370616e2d69722f76326664696765737482667368613235365820123e7f805dc5e831e88befec4cd49ec02c39858b6f3990da8a73b50c6086ae3975616363657074656454617267657450726f66696c65a26269646a6563686f2e64706f40316664696765737482667368613235365820e9ba4aab52c815b673aa4b03165ab32863de5052c342b938005d1c0013d5c8fc6f6163636570746564436f7265416269816d65646963742e636f72652f76317818636f6e666f726d616e636546697874757265436f72707573a262696478206a656469742e746578742e5265706c61636552616e67652e6f7261636c6540316664696765737482667368613235365820b9b4707dd5e07897cbe7af36d88928401887e6af5d167d1a88a8d6181b4dbb0e73696e7472696e736963735f617274696661637459030aa26a61706956657273696f6e782265646963742e7461726765742d70726f66696c652e696e7472696e736963732f76316a696e7472696e73696373a178196563686f2e64706f40312e6e6f64652d61746f6d2d72656164ab6a6566666563744b696e6464726561646a72657475726e5479706578206563686f2e64706f40312e6e6f64652d61746f6d2d726561642e726573756c746a7772697465436c61737364726561646c636f737454656d706c617465781f6a656469742e7465787440312e7265706c61636552616e67654275646765746c6775617264537570706f7274f56d617267756d656e74547970657381781f6563686f2e64706f40312e6e6f64652d61746f6d2d726561642e696e7075746e6566666563744661696c75726573a46b61746f6d4d697373696e67a26b7061796c6f616454797065781f6563686f2e64706f40312e6e6f64652d61746f6d2d726561642e696e7075746e617574686f72697479436c6173736d7265736f757263654661756c746c61746f6d5265717569726564a26b7061796c6f616454797065781f6563686f2e64706f40312e6e6f64652d61746f6d2d726561642e696e7075746e617574686f72697479436c6173736e696e746567726974794661756c747061746f6d547970654d69736d61746368a26b7061796c6f616454797065781f6563686f2e64706f40312e6e6f64652d61746f6d2d726561642e696e7075746e617574686f72697479436c6173736e696e746567726974794661756c747561746f6d42797465426f756e644578636565646564a26b7061796c6f616454797065781f6563686f2e64706f40312e6e6f64652d61746f6d2d726561642e696e7075746e617574686f72697479436c6173736e696e746567726974794661756c746e696e7472696e736963436c617373666566666563746e74797065506172616d65746572738071666f6f747072696e7454656d706c61746578226a656469742e7465787440312e7265706c61636552616e6765466f6f747072696e74781b63616e5061727469636970617465496e41746f6d69634775617264f5777461726765745f70726f66696c655f61727469666163745906fbb81c626964686563686f2e64706f676c6f7765726572a2626964736563686f2e64706f2e6c6f77657265722f7631666469676573748266736861323536582044ca28eeeccc4ff522fd9ec7e4694124f4e04880171c8cce460eefcb9505b7976773616e64626f78a26269647765646963742e7761736d2d636f6d706f6e656e742f76316664696765737482667368613235365820095b4dd18f1a6a7276533f758665be319c5f476e7bdc70cc56d30b6b3e9f0a806776657273696f6e6131687461726765744972a26269646f6563686f2e7370616e2d69722f76326664696765737482667368613235365820123e7f805dc5e831e88befec4cd49ec02c39858b6f3990da8a73b50c6086ae39687665726966696572a2626964746563686f2e64706f2e76657269666965722f76316664696765737482667368613235365820ca96b190728de3d668072ec1bd37d24e5197e7bd9bd54f70966d8c566b9b67f2696675656c4d6f64656ca26269646d65646963742e6675656c2f76316664696765737482667368613235365820006c6ebc01a3c5d36d50bd390b69d47e42378be61074e3b5c96ecb9f5ee532076a61706956657273696f6e7765646963742e7461726765742d70726f66696c652f76316a696e7472696e73696373a2626964766563686f2e64706f2e696e7472696e736963732f76316664696765737482667368613235365820865e4a94955f49bc97975acd2ff7670d4576296d68a72de1bcacbb3d5b8cfb666b636f7374416c6765627261a2626964706563686f2e64706f2e636f73742f76316664696765737482667368613235365820486940acd1d4bc15cea40db29347619a07202d9c0f1e63c4016c26bccf0b52a86b6d756c7469546172676574f46d62756e646c6550726f66696c65a2626964726563686f2e64706f2e62756e646c652f76316664696765737482667368613235365820aa0438bcc6ef14ee6cb6d4976622f6080381d731459dcb7b9102595c9bed92c06d646961676e6f73746963416269a26269647465646963742e646961676e6f73746963732f7631666469676573748266736861323536582028fd72a98223153982ca084c29dbb1b2d430623967ab3b6db9d7fee668e614b96f6163636570746564436f7265416269816d65646963742e636f72652f76316f67756172644576616c756174696f6e70707265636f6d6d69742d61746f6d69636f72656164436f6e73697374656e6379746170706c69636174696f6e2d736e617073686f74706170706c69636174696f6e4d6f64656c6661746f6d696370666f6f747072696e74416c6765627261a2626964756563686f2e64706f2e666f6f747072696e742f76316664696765737482667368613235365820f47bb65867e78099ddcfd6ae7af83870df8823f974a496a111ed94e5d785c769716f7065726174696f6e50726f66696c6573a2626964781e6563686f2e64706f2e6f7065726174696f6e2d70726f66696c65732f7631666469676573748266736861323536582053256c51f6c817a77cc8694458bf9d3891abd15b9c94f79ca97d920d3c5f041672696e7472696e7369634e616d6573706163656a6563686f2e64706f4031736f62737472756374696f6e526f6c6c6261636b726e6f2d76697369626c652d65666665637473736f62737472756374696f6e5461786f6e6f6d79a262696478186563686f2e64706f2e6f62737472756374696f6e732f763166646967657374826673686132353658204f5a139d606053c3807f50710076ea9abeb0e611c12a530f5e5b4b31911c3e6474706f7374636f6e646974696f6e537570706f7274f57663616e6f6e6963616c456e636f64696e6752756c6573a26269647765646963742e63616e6f6e6963616c2d63626f722f76316664696765737482667368613235365820d1ea6d3de2a9762a438cbf4fac1d5ae2f357a4b27d13e0347e94ea655bf40f9d7664657465726d696e6973746963457865637574696f6ea26269647465646963742e64657465726d696e69736d2f76316664696765737482667368613235365820af4e6c774d5ea82db30e680be2ba7abc5ba04c6aead146139de32d8c5bb4981e7818636f6e666f726d616e636546697874757265436f72707573a2626964746563686f2e64706f2e66697874757265732f763166646967657374826673686132353658208fa81d37ae4eecb79252f310e7532fc9872bd7c17f2722da911fa74620f81b43781961636365707465644c61777061636b4164617074657241626981781865646963742e6c61777061636b2d616461707465722f7631781967656e657261746564417274696661637450726f66696c657381a262696478186563686f2e64706f2e726567697374726174696f6e2f76316664696765737482667368613235365820ff88be93c26cc533948d8a93601954dc391912d593ca1e96115c846cbf2c5b5d727461726765745f69725f617274696661637459087aa6646b696e64776f7264657265645461726765744972417274696661637466646f6d61696e6f6563686f2e7370616e2d69722f763267696e74656e7473a16c7265706c61636552616e6765a8656261736973a36462617365a36462617365a263726566a3626964656172672e30647479706578206a656469742e746578742e7265706c6163655f72616e676540312e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646761646472657373646b696e64656669656c64656669656c64666e6f6465496465737465707381a7626964737265706c61636552616e67652e737465702e3065696e707574a36462617365a263726566a3626964656172672e30647479706578206a656469742e746578742e7265706c6163655f72616e676540312e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646761646472657373666566666563746d746578742e72656164466163746762696e64696e67a3626964676c6f63616c2e306474797065766a656469742e7465787440312e46616374427974657369616c7068614e616d6567246c6f63616c306f6f62737472756374696f6e41726d73a46b61746f6d4d697373696e67a26576616c7565a4646172677380646b696e646463616c6c6663616c6c656570746578742e466163744d697373696e67687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e30647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e306c61746f6d5265717569726564a26576616c7565a4646172677380646b696e646463616c6c6663616c6c656572746578742e466163744d616c666f726d6564687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e31647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e317061746f6d547970654d69736d61746368a26576616c7565a4646172677380646b696e646463616c6c6663616c6c656572746578742e466163744d616c666f726d6564687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e33647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e337561746f6d42797465426f756e644578636565646564a26576616c7565a4646172677380646b696e646463616c6c6663616c6c656572746578742e466163744d616c666f726d6564687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e32647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e326f746172676574496e7472696e73696378196563686f2e64706f40312e6e6f64652d61746f6d2d72656164736f62737472756374696f6e4661696c75726573847561746f6d42797465426f756e6445786365656465646b61746f6d4d697373696e676c61746f6d52657175697265647061746f6d547970654d69736d6174636866726573756c74a263726566a3626964676c6f63616c2e306474797065766a656469742e7465787440312e46616374427974657369616c7068614e616d6567246c6f63616c30646b696e64656c6f63616c6c726571756972656d656e747381a3626964767265706c61636552616e67652e726571756972652e30696f6e4661696c757265a2646b696e64687465726d696e616c66726561736f6ea2677061796c6f6164a06a726561736f6e4b696e6476746578742e42617369734e6f7443616e6f6e6963616c69707265646963617465a4626f70623d3d646b696e6467636f6d70617265646c656674a263726566a3626964676c6f63616c2e306474797065766a656469742e7465787440312e46616374427974657369616c7068614e616d6567246c6f63616c30646b696e64656c6f63616c657269676874a36462617365a263726566a3626964656172672e30647479706578206a656469742e746578742e7265706c6163655f72616e676540312e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646865787065637465646e657865637574696f6e4f7264657282737265706c61636552616e67652e737465702e30767265706c61636552616e67652e726571756972652e3070696e707574436f6e73747261696e747380706f7065726174696f6e50726f66696c65781e636f6e74696e75756d2e70726f66696c652e726561642d6f6e6c792f763174636f72654576616c756174696f6e427564676574a3686d617853746570731a004000006e6d61784f757470757442797465731a00800000716d6178416c6c6f636174656442797465731a010000006d74617267657450726f66696c65a26269646a6563686f2e64706f40316664696765737482667368613235365820e9ba4aab52c815b673aa4b03165ab32863de5052c342b938005d1c0013d5c8fc6f73656d616e746963436c6f73757265a2686c61777061636b7381a26269646c6a656469742e74657874403166646967657374826673686132353658208d5c6edb069c707261b1547f74c339f859d420a4b778c197d2f7138d5ba292166a736f75726365436f7265a2626964781a6a656469742e746578742e7265706c6163655f72616e676540316664696765737482667368613235365820aca638abdb6039281878f58ce14fa2b3cad9879d2166d7975de45610d14f242874736f75726365436f7265436f6f7264696e617465781a6a656469742e746578742e7265706c6163655f72616e6765403178186c61777061636b5f6578706f7274735f6172746966616374590693a665747970657383a26a636f6f7264696e61746578186a656469742e7465787440312e46616374416464726573736a646566696e6974696f6e784c5265636f72643c6e6f646549643a42797465733c65786163743d33323e2c7479706549643a42797465733c65786163743d33323e2c7761727049643a42797465733c65786163743d33323e3ea26a636f6f7264696e617465766a656469742e7465787440312e4661637442797465736a646566696e6974696f6e7242797465733c6d61783d313034383537363ea26a636f6f7264696e617465781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6a646566696e6974696f6e7822537472696e673c6d61783d3235362c63616e6f6e6963616c3d7261772d757466383e676566666563747381aa69696e7075745479706578186a656469742e7465787440312e46616374416464726573736a636f6f7264696e617465756a656469742e7465787440312e72656164466163746a6f757470757454797065766a656469742e7465787440312e4661637442797465736c6775617264537570706f7274f56e636f73744f626c69676174696f6e781f6a656469742e7465787440312e7265706c61636552616e67654275646765746e6566666563744661696c75726573a4676d697373696e67a26b7061796c6f61645479706578186a656469742e7465787440312e46616374416464726573736e617574686f72697479436c6173736d7265736f757263654661756c74676e6f7441746f6da26b7061796c6f61645479706578186a656469742e7465787440312e46616374416464726573736e617574686f72697479436c6173736e696e746567726974794661756c7468746f6f4c61726765a26b7061796c6f61645479706578186a656469742e7465787440312e46616374416464726573736e617574686f72697479436c6173736e696e746567726974794661756c746c747970654d69736d61746368a26b7061796c6f61645479706578186a656469742e7465787440312e46616374416464726573736e617574686f72697479436c6173736e696e746567726974794661756c746e6566666563744b696e6448696e7464726561646e657865637574696f6e436c6173736772756e74696d656e74797065506172616d65746572738073666f6f747072696e744f626c69676174696f6e78226a656469742e7465787440312e7265706c61636552616e6765466f6f747072696e7469636f6e7374616e7473806c6f62737472756374696f6e7383a36a636f6f7264696e617465781e6a656469742e7465787440312e42617369734e6f7443616e6f6e6963616c6d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736e646f6d61696e4d61707061626c65a36a636f6f7264696e61746578186a656469742e7465787440312e466163744d697373696e676d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736d7265736f757263654661756c74a36a636f6f7264696e617465781a6a656469742e7465787440312e466163744d616c666f726d65646d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736e696e746567726974794661756c746d7075726546756e6374696f6e7380716f7065726174696f6e50726f66696c6573a178196a656469742e7465787440312e7265706c61636552616e6765a26d6f7074696354656d706c617465a6696f707469634b696e64736166666563745265696e746567726174696f6e6c626f756e646172794b696e64666166666563746d626173697354656d706c617465781b6a656469742e7465787440312e65786163744865616442617369736d737570706f7274506f6c696379781e6a656469742e7465787440312e6261736973426f756e64537570706f72746f6c6f7373446973706f736974696f6e756a656469742e7465787440312e6c6f73736c657373736170657274757265526571756972656d656e74a26372656678226a656469742e7465787440312e7265706c61636552616e6765466f6f747072696e74646b696e64781b6162737472616374466f6f747072696e744f626c69676174696f6e6f65666665637450726564696361746578206a656469742e7465787440312e7265706c61636552616e676545666665637473706d61785f726573756c745f62797465731a00010000727461726765745f69725f6964656e7469747958201ddd64dc48d19b4c720f3afc36832a1f7f61c28499d586616aab1f2b292de440736d61785f616c6c6f63617465645f62797465731a01000000781a696e7472696e7369635f70726f66696c655f6964656e746974795820a0fc1b7a1e186598291754469fd6ea2220f676358284f7b84c7e2476901a3151781c696e7465727072657465725f70726f66696c655f6964656e746974795820eaa6f8ca4f395d291fdb70af1bd47b804ab82aa17fdbc01b8aaeeb747f7d218c6e6275646765745f6365696c696e67a3657374657073016a726561645f6279746573006b77726974655f6279746573007073656d616e7469635f636c6f73757265a66d636f72655f6964656e746974795820aca638abdb6039281878f58ce14fa2b3cad9879d2166d7975de45610d14f2428727461726765745f69725f6964656e7469747958201ddd64dc48d19b4c720f3afc36832a1f7f61c28499d586616aab1f2b292de4407565646963745f736f757263655f6964656e7469747958200101010101010101010101010101010101010101010101010101010101010101781a63616e6f6e6963616c5f6d65616e696e675f6964656e7469747958200303030303030303030303030303030303030303030303030303030303030303781b6170706c69636174696f6e5f736368656d615f6964656e7469747958200c75bcc42fd23d9eafdc81f1d81754be32cde98170c5fc1fbaf2746ffef99284781d6170706c69636174696f6e5f736368656d615f636f6f7264696e6174656a6170702e536368656d61746f7065726174696f6e5f636f6f7264696e61746578276a656469742e746578742e7265706c6163655f72616e676540312e7265706c61636552616e676575696e7075745f736368656d615f6964656e746974795820d277705b5ab03fcb58590bad62fb8058e075c3b4c65efc21282bb531aa22b3ad76726573756c745f736368656d615f6964656e746974795820de5c0c4f0c640354c40bb4f9d4886cd820353a548caea4953269eba15fe902bc777461726765745f70726f66696c655f6964656e746974795820eaca21c05664241efd1e1c5b5636c7132fe8854f6bcaddb2fd4f014e1bd4a479781a617574686f726974795f70726f66696c655f6964656e7469747958200808080808080808080808080808080808080808080808080808080808080808781a696e7472696e7369635f70726f66696c655f6964656e746974795820a0fc1b7a1e186598291754469fd6ea2220f676358284f7b84c7e2476901a3151781b666f6f747072696e745f636f6e74726163745f6964656e746974795820362b20fb18488ce180f6c1096b5189994354604fd1b1b126a3ea4ef839e5232b781b6f62737472756374696f6e5f736368656d615f6964656e746974795820b1f96fdf3ec65e84d500702951393a931b4fdd843ad02723ea3725f90a671418781c696e7465727072657465725f70726f66696c655f6964656e746974795820eaa6f8ca4f395d291fdb70af1bd47b804ab82aa17fdbc01b8aaeeb747f7d218c781e726573756c745f696e746572707265746174696f6e5f6964656e74697479582042734d5e73435acc0fdd5a66b97e5bfd94278e64fce2b4890ec609f054dc969e78206576616c756174696f6e5f62617369735f736368656d615f6964656e74697479582020b6239db569aa86ae1c27596b374df90caa5ea41e8e005fd4fe00bfe5c3b38178216170706c69636174696f6e5f62617369735f736368656d615f6964656e7469747958208b294c69120a2e749c56266691b0974e7e0323c198fc42a467fd3790790f791078236f62737472756374696f6e5f696e746572707265746174696f6e5f6964656e746974795820924462071f3992b34c629f4788cc666bd14a87a0b9d0c398feba929ff4dd25f9 diff --git a/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/slice-other-operand.hex b/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/slice-other-operand.hex new file mode 100644 index 00000000..4ef407d7 --- /dev/null +++ b/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/slice-other-operand.hex @@ -0,0 +1 @@ +b166736368656d6178196563686f2e6f7065726174696f6e2d7061636b6167652f76316770726f6772616d590dc0ad646b696e647765646963742d6566666563742d70726f6772616d2f763166736368656d6178196563686f2e6f7065726174696f6e2d70726f6772616d2f76316b6f75747075745f747970656a6170702e526573756c746c67726170685f736368656d615876a26a656467655f7479706573a06a6e6f64655f7479706573a158200101010101010101010101010101010101010101010101010101010101010101a26a61646472657373696e67016a61746f6d5f747970657381582002020202020202020202020202020202020202020202020202020202020202026c6964656e746974795f6c6177016d666f6f747072696e745f6c617758f6a9696d61785f7265616473016a61746f6d5f747970657381582002020202020202020202020202020202020202020202020202020202020202026a6d61785f777269746573016f6d61785f72616e67655f6564676573006f726561645f6e6f64655f747970657381582001010101010101010101010101010101010101010101010101010101010101017072616e67655f656467655f7479706573807077726974655f656467655f7479706573807077726974655f6e6f64655f7479706573815820010101010101010101010101010101010101010101010101010101010101010172706f7274616c5f6f776e65725f7479706573806f6d61785f696e7075745f62797465731a0001000070636f6d70696c65645f70726f6772616d590ac5a666696e74656e7468757064617465403166736368656d6178286563686f2e636f6d70696c65722d70726f64756365642d6566666563742d70726f6772616d2f76316d636f72655f61727469666163745904f3a6657479706573a265496e707574a2646b696e64665265636f7264666669656c6473a36261746355363464746578746d42797465733c6d61783d36343e656f746865726d42797465733c6d61783d36343e66526573756c74a1646b696e6464426f6f6c67696d706f7274738067696e74656e7473a1687570646174654031a664626f6479a3656e6f64657381a3646b696e64636c65746576616c7565a4646172677381a4646172677383a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646474657874a2646b696e6465636f6e73746576616c7565a3646b696e6463696e746576616c75650065776964746863553634a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c64626174646b696e646463616c6c6663616c6c656570636f72652e62797465732e736c696365687479706541726773816d42797465733c6d61783d36343e646b696e646463616c6c6663616c6c656571636f72652e62797465732e697355746638687479706541726773816d42797465733c6d61783d36343e6762696e64696e67a3626964686c6f63616c2e6f6b647479706564426f6f6c69616c7068614e616d6568246c6f63616c6f6b666c6f63616c7382a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730a3626964686c6f63616c2e6f6b647479706564426f6f6c69616c7068614e616d6568246c6f63616c6f6b66726573756c74a263726566a3626964686c6f63616c2e6f6b647479706564426f6f6c69616c7068614e616d6568246c6f63616c6f6b646b696e64656c6f63616c65696e707574696170702e496e707574666f75747075746a6170702e526573756c7470696e707574436f6e73747261696e747381a269707265646963617465a4626f70623c3d646b696e6467636f6d70617265646c656674a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c64626174657269676874a4646172677381a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c64656f74686572646b696e646463616c6c6663616c6c656571636f72652e62797465732e6c656e677468687479706541726773816d42797465733c6d61783d36343e6a636f6f7264696e617465746170702e75706461746540312e77686572652e3074636f72654576616c756174696f6e427564676574a3686d617853746570731a000f42406e6d61784f757470757442797465731a00010000716d6178416c6c6f636174656442797465731a01000000781872657175697265644f7065726174696f6e50726f66696c65781a636f6e74696e75756d2e70726f66696c652e746f74616c2f76316a61706956657273696f6e6d65646963742e636f72652f76316a636f6f7264696e6174656361707078187265717569726564436f72654361706162696c697469657380726c6f776572696e675f617274696661637473f6727461726765745f69725f61727469666163745904eda6646b696e64776f7264657265645461726765744972417274696661637466646f6d61696e6f6563686f2e7370616e2d69722f763267696e74656e7473a1687570646174654031a86573746570738066726573756c74a263726566a3626964686c6f63616c2e6f6b647479706564426f6f6c69616c7068614e616d6568246c6f63616c6f6b646b696e64656c6f63616c6c7075726542696e64696e677381a36269646962696e64696e672e306576616c7565a4646172677381a4646172677383a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646474657874a2646b696e6465636f6e73746576616c7565a3646b696e6463696e746576616c75650065776964746863553634a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c64626174646b696e646463616c6c6663616c6c656570636f72652e62797465732e736c696365687479706541726773816d42797465733c6d61783d36343e646b696e646463616c6c6663616c6c656571636f72652e62797465732e697355746638687479706541726773816d42797465733c6d61783d36343e6762696e64696e67a3626964686c6f63616c2e6f6b647479706564426f6f6c69616c7068614e616d6568246c6f63616c6f6b6c726571756972656d656e7473806e657865637574696f6e4f72646572816962696e64696e672e3070696e707574436f6e73747261696e747381a269707265646963617465a4626f70623c3d646b696e6467636f6d70617265646c656674a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c64626174657269676874a4646172677381a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c64656f74686572646b696e646463616c6c6663616c6c656571636f72652e62797465732e6c656e677468687479706541726773816d42797465733c6d61783d36343e6a636f6f7264696e617465746170702e75706461746540312e77686572652e30706f7065726174696f6e50726f66696c65781a636f6e74696e75756d2e70726f66696c652e746f74616c2f763174636f72654576616c756174696f6e427564676574a3686d617853746570731a000f42406e6d61784f757470757442797465731a00010000716d6178416c6c6f636174656442797465731a010000006d74617267657450726f66696c65a26269646a6563686f2e64706f4031666469676573748266736861323536582006060606060606060606060606060606060606060606060606060606060606066f73656d616e746963436c6f73757265a2686c61777061636b73806a736f75726365436f7265a2626964636170706664696765737482667368613235365820276d3675f325b929e5990ad261239afa5c6ce09cf43f18cbffb608fc9505ef6874736f75726365436f7265436f6f7264696e6174656361707078186c61777061636b5f6578706f7274735f6172746966616374584ca66574797065738067656666656374738069636f6e7374616e7473806c6f62737472756374696f6e73806d7075726546756e6374696f6e7380716f7065726174696f6e50726f66696c6573a0706d61785f726573756c745f62797465731a00010000727461726765745f69725f6964656e7469747958204ee63f1829d0e18aaf233e1c337ea9e8f2ecdd0ab6899716cc598a5974e34615736d61785f616c6c6f63617465645f62797465731a01000000781a696e7472696e7369635f70726f66696c655f6964656e746974795820a0fc1b7a1e186598291754469fd6ea2220f676358284f7b84c7e2476901a3151781c696e7465727072657465725f70726f66696c655f6964656e746974795820eaa6f8ca4f395d291fdb70af1bd47b804ab82aa17fdbc01b8aaeeb747f7d218c6e6275646765745f6365696c696e67a3657374657073016a726561645f6279746573006b77726974655f6279746573007073656d616e7469635f636c6f73757265a66d636f72655f6964656e746974795820276d3675f325b929e5990ad261239afa5c6ce09cf43f18cbffb608fc9505ef68727461726765745f69725f6964656e7469747958204ee63f1829d0e18aaf233e1c337ea9e8f2ecdd0ab6899716cc598a5974e346157565646963745f736f757263655f6964656e7469747958200101010101010101010101010101010101010101010101010101010101010101781a63616e6f6e6963616c5f6d65616e696e675f6964656e7469747958200303030303030303030303030303030303030303030303030303030303030303781b6170706c69636174696f6e5f736368656d615f6964656e746974795820e2089c3b5730d3b54a8a645cbf77d76492a0f36e98e23d6ecab5e4fd7fa7c265781d6170706c69636174696f6e5f736368656d615f636f6f7264696e6174656a6170702e536368656d61746f7065726174696f6e5f636f6f7264696e6174656c6170702e757064617465403175696e7075745f736368656d615f6964656e746974795820d277705b5ab03fcb58590bad62fb8058e075c3b4c65efc21282bb531aa22b3ad76726573756c745f736368656d615f6964656e746974795820de5c0c4f0c640354c40bb4f9d4886cd820353a548caea4953269eba15fe902bc777461726765745f70726f66696c655f6964656e746974795820eaca21c05664241efd1e1c5b5636c7132fe8854f6bcaddb2fd4f014e1bd4a479781a617574686f726974795f70726f66696c655f6964656e7469747958200808080808080808080808080808080808080808080808080808080808080808781a696e7472696e7369635f70726f66696c655f6964656e746974795820a0fc1b7a1e186598291754469fd6ea2220f676358284f7b84c7e2476901a3151781b666f6f747072696e745f636f6e74726163745f6964656e746974795820362b20fb18488ce180f6c1096b5189994354604fd1b1b126a3ea4ef839e5232b781b6f62737472756374696f6e5f736368656d615f6964656e746974795820b1f96fdf3ec65e84d500702951393a931b4fdd843ad02723ea3725f90a671418781c696e7465727072657465725f70726f66696c655f6964656e746974795820eaa6f8ca4f395d291fdb70af1bd47b804ab82aa17fdbc01b8aaeeb747f7d218c781e726573756c745f696e746572707265746174696f6e5f6964656e74697479582042734d5e73435acc0fdd5a66b97e5bfd94278e64fce2b4890ec609f054dc969e78206576616c756174696f6e5f62617369735f736368656d615f6964656e74697479582020b6239db569aa86ae1c27596b374df90caa5ea41e8e005fd4fe00bfe5c3b38178216170706c69636174696f6e5f62617369735f736368656d615f6964656e7469747958208b294c69120a2e749c56266691b0974e7e0323c198fc42a467fd3790790f791078236f62737472756374696f6e5f696e746572707265746174696f6e5f6964656e746974795820924462071f3992b34c629f4788cc666bd14a87a0b9d0c398feba929ff4dd25f9 diff --git a/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/slice-proven.hex b/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/slice-proven.hex new file mode 100644 index 00000000..f8f0a34f --- /dev/null +++ b/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/slice-proven.hex @@ -0,0 +1 @@ +b166736368656d6178196563686f2e6f7065726174696f6e2d7061636b6167652f76316770726f6772616d590dbead646b696e647765646963742d6566666563742d70726f6772616d2f763166736368656d6178196563686f2e6f7065726174696f6e2d70726f6772616d2f76316b6f75747075745f747970656a6170702e526573756c746c67726170685f736368656d615876a26a656467655f7479706573a06a6e6f64655f7479706573a158200101010101010101010101010101010101010101010101010101010101010101a26a61646472657373696e67016a61746f6d5f747970657381582002020202020202020202020202020202020202020202020202020202020202026c6964656e746974795f6c6177016d666f6f747072696e745f6c617758f6a9696d61785f7265616473016a61746f6d5f747970657381582002020202020202020202020202020202020202020202020202020202020202026a6d61785f777269746573016f6d61785f72616e67655f6564676573006f726561645f6e6f64655f747970657381582001010101010101010101010101010101010101010101010101010101010101017072616e67655f656467655f7479706573807077726974655f656467655f7479706573807077726974655f6e6f64655f7479706573815820010101010101010101010101010101010101010101010101010101010101010172706f7274616c5f6f776e65725f7479706573806f6d61785f696e7075745f62797465731a0001000070636f6d70696c65645f70726f6772616d590ac3a666696e74656e7468757064617465403166736368656d6178286563686f2e636f6d70696c65722d70726f64756365642d6566666563742d70726f6772616d2f76316d636f72655f61727469666163745904f2a6657479706573a265496e707574a2646b696e64665265636f7264666669656c6473a36261746355363464746578746d42797465733c6d61783d36343e656f746865726d42797465733c6d61783d36343e66526573756c74a1646b696e6464426f6f6c67696d706f7274738067696e74656e7473a1687570646174654031a664626f6479a3656e6f64657381a3646b696e64636c65746576616c7565a4646172677381a4646172677383a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646474657874a2646b696e6465636f6e73746576616c7565a3646b696e6463696e746576616c75650065776964746863553634a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c64626174646b696e646463616c6c6663616c6c656570636f72652e62797465732e736c696365687479706541726773816d42797465733c6d61783d36343e646b696e646463616c6c6663616c6c656571636f72652e62797465732e697355746638687479706541726773816d42797465733c6d61783d36343e6762696e64696e67a3626964686c6f63616c2e6f6b647479706564426f6f6c69616c7068614e616d6568246c6f63616c6f6b666c6f63616c7382a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730a3626964686c6f63616c2e6f6b647479706564426f6f6c69616c7068614e616d6568246c6f63616c6f6b66726573756c74a263726566a3626964686c6f63616c2e6f6b647479706564426f6f6c69616c7068614e616d6568246c6f63616c6f6b646b696e64656c6f63616c65696e707574696170702e496e707574666f75747075746a6170702e526573756c7470696e707574436f6e73747261696e747381a269707265646963617465a4626f70623c3d646b696e6467636f6d70617265646c656674a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c64626174657269676874a4646172677381a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646474657874646b696e646463616c6c6663616c6c656571636f72652e62797465732e6c656e677468687479706541726773816d42797465733c6d61783d36343e6a636f6f7264696e617465746170702e75706461746540312e77686572652e3074636f72654576616c756174696f6e427564676574a3686d617853746570731a000f42406e6d61784f757470757442797465731a00010000716d6178416c6c6f636174656442797465731a01000000781872657175697265644f7065726174696f6e50726f66696c65781a636f6e74696e75756d2e70726f66696c652e746f74616c2f76316a61706956657273696f6e6d65646963742e636f72652f76316a636f6f7264696e6174656361707078187265717569726564436f72654361706162696c697469657380726c6f776572696e675f617274696661637473f6727461726765745f69725f61727469666163745904eca6646b696e64776f7264657265645461726765744972417274696661637466646f6d61696e6f6563686f2e7370616e2d69722f763267696e74656e7473a1687570646174654031a86573746570738066726573756c74a263726566a3626964686c6f63616c2e6f6b647479706564426f6f6c69616c7068614e616d6568246c6f63616c6f6b646b696e64656c6f63616c6c7075726542696e64696e677381a36269646962696e64696e672e306576616c7565a4646172677381a4646172677383a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646474657874a2646b696e6465636f6e73746576616c7565a3646b696e6463696e746576616c75650065776964746863553634a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c64626174646b696e646463616c6c6663616c6c656570636f72652e62797465732e736c696365687479706541726773816d42797465733c6d61783d36343e646b696e646463616c6c6663616c6c656571636f72652e62797465732e697355746638687479706541726773816d42797465733c6d61783d36343e6762696e64696e67a3626964686c6f63616c2e6f6b647479706564426f6f6c69616c7068614e616d6568246c6f63616c6f6b6c726571756972656d656e7473806e657865637574696f6e4f72646572816962696e64696e672e3070696e707574436f6e73747261696e747381a269707265646963617465a4626f70623c3d646b696e6467636f6d70617265646c656674a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c64626174657269676874a4646172677381a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646474657874646b696e646463616c6c6663616c6c656571636f72652e62797465732e6c656e677468687479706541726773816d42797465733c6d61783d36343e6a636f6f7264696e617465746170702e75706461746540312e77686572652e30706f7065726174696f6e50726f66696c65781a636f6e74696e75756d2e70726f66696c652e746f74616c2f763174636f72654576616c756174696f6e427564676574a3686d617853746570731a000f42406e6d61784f757470757442797465731a00010000716d6178416c6c6f636174656442797465731a010000006d74617267657450726f66696c65a26269646a6563686f2e64706f4031666469676573748266736861323536582006060606060606060606060606060606060606060606060606060606060606066f73656d616e746963436c6f73757265a2686c61777061636b73806a736f75726365436f7265a2626964636170706664696765737482667368613235365820008f560a5d172892582934d69efac15fa57b10079039c710df29f836cfc3ddf574736f75726365436f7265436f6f7264696e6174656361707078186c61777061636b5f6578706f7274735f6172746966616374584ca66574797065738067656666656374738069636f6e7374616e7473806c6f62737472756374696f6e73806d7075726546756e6374696f6e7380716f7065726174696f6e50726f66696c6573a0706d61785f726573756c745f62797465731a00010000727461726765745f69725f6964656e7469747958209ca1e01c7eb7719b49a587bbd03a83b875314c0fc80c790dfcf0fbaea8905ae3736d61785f616c6c6f63617465645f62797465731a01000000781a696e7472696e7369635f70726f66696c655f6964656e746974795820a0fc1b7a1e186598291754469fd6ea2220f676358284f7b84c7e2476901a3151781c696e7465727072657465725f70726f66696c655f6964656e746974795820eaa6f8ca4f395d291fdb70af1bd47b804ab82aa17fdbc01b8aaeeb747f7d218c6e6275646765745f6365696c696e67a3657374657073016a726561645f6279746573006b77726974655f6279746573007073656d616e7469635f636c6f73757265a66d636f72655f6964656e746974795820008f560a5d172892582934d69efac15fa57b10079039c710df29f836cfc3ddf5727461726765745f69725f6964656e7469747958209ca1e01c7eb7719b49a587bbd03a83b875314c0fc80c790dfcf0fbaea8905ae37565646963745f736f757263655f6964656e7469747958200101010101010101010101010101010101010101010101010101010101010101781a63616e6f6e6963616c5f6d65616e696e675f6964656e7469747958200303030303030303030303030303030303030303030303030303030303030303781b6170706c69636174696f6e5f736368656d615f6964656e746974795820e2089c3b5730d3b54a8a645cbf77d76492a0f36e98e23d6ecab5e4fd7fa7c265781d6170706c69636174696f6e5f736368656d615f636f6f7264696e6174656a6170702e536368656d61746f7065726174696f6e5f636f6f7264696e6174656c6170702e757064617465403175696e7075745f736368656d615f6964656e746974795820d277705b5ab03fcb58590bad62fb8058e075c3b4c65efc21282bb531aa22b3ad76726573756c745f736368656d615f6964656e746974795820de5c0c4f0c640354c40bb4f9d4886cd820353a548caea4953269eba15fe902bc777461726765745f70726f66696c655f6964656e746974795820eaca21c05664241efd1e1c5b5636c7132fe8854f6bcaddb2fd4f014e1bd4a479781a617574686f726974795f70726f66696c655f6964656e7469747958200808080808080808080808080808080808080808080808080808080808080808781a696e7472696e7369635f70726f66696c655f6964656e746974795820a0fc1b7a1e186598291754469fd6ea2220f676358284f7b84c7e2476901a3151781b666f6f747072696e745f636f6e74726163745f6964656e746974795820362b20fb18488ce180f6c1096b5189994354604fd1b1b126a3ea4ef839e5232b781b6f62737472756374696f6e5f736368656d615f6964656e746974795820b1f96fdf3ec65e84d500702951393a931b4fdd843ad02723ea3725f90a671418781c696e7465727072657465725f70726f66696c655f6964656e746974795820eaa6f8ca4f395d291fdb70af1bd47b804ab82aa17fdbc01b8aaeeb747f7d218c781e726573756c745f696e746572707265746174696f6e5f6964656e74697479582042734d5e73435acc0fdd5a66b97e5bfd94278e64fce2b4890ec609f054dc969e78206576616c756174696f6e5f62617369735f736368656d615f6964656e74697479582020b6239db569aa86ae1c27596b374df90caa5ea41e8e005fd4fe00bfe5c3b38178216170706c69636174696f6e5f62617369735f736368656d615f6964656e7469747958208b294c69120a2e749c56266691b0974e7e0323c198fc42a467fd3790790f791078236f62737472756374696f6e5f696e746572707265746174696f6e5f6964656e746974795820924462071f3992b34c629f4788cc666bd14a87a0b9d0c398feba929ff4dd25f9 diff --git a/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/slice-require-only.hex b/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/slice-require-only.hex new file mode 100644 index 00000000..a8009e7c --- /dev/null +++ b/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/slice-require-only.hex @@ -0,0 +1 @@ +b166736368656d6178196563686f2e6f7065726174696f6e2d7061636b6167652f76316770726f6772616d590ed4ad646b696e647765646963742d6566666563742d70726f6772616d2f763166736368656d6178196563686f2e6f7065726174696f6e2d70726f6772616d2f76316b6f75747075745f747970656a6170702e526573756c746c67726170685f736368656d615876a26a656467655f7479706573a06a6e6f64655f7479706573a158200101010101010101010101010101010101010101010101010101010101010101a26a61646472657373696e67016a61746f6d5f747970657381582002020202020202020202020202020202020202020202020202020202020202026c6964656e746974795f6c6177016d666f6f747072696e745f6c617758f6a9696d61785f7265616473016a61746f6d5f747970657381582002020202020202020202020202020202020202020202020202020202020202026a6d61785f777269746573016f6d61785f72616e67655f6564676573006f726561645f6e6f64655f747970657381582001010101010101010101010101010101010101010101010101010101010101017072616e67655f656467655f7479706573807077726974655f656467655f7479706573807077726974655f6e6f64655f7479706573815820010101010101010101010101010101010101010101010101010101010101010172706f7274616c5f6f776e65725f7479706573806f6d61785f696e7075745f62797465731a0001000070636f6d70696c65645f70726f6772616d590bd9a666696e74656e7468757064617465403166736368656d6178286563686f2e636f6d70696c65722d70726f64756365642d6566666563742d70726f6772616d2f76316d636f72655f6172746966616374590578a6657479706573a265496e707574a2646b696e64665265636f7264666669656c6473a36261746355363464746578746d42797465733c6d61783d36343e656f746865726d42797465733c6d61783d36343e66526573756c74a1646b696e6464426f6f6c67696d706f7274738067696e74656e7473a1687570646174654031a664626f6479a3656e6f64657382a3646b696e646772657175697265696f6e4661696c757265a2646b696e64687465726d696e616c66726561736f6ea2677061796c6f6164a1626174a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646261746a726561736f6e4b696e646d6170702e4261644f666673657469707265646963617465a4626f70623c3d646b696e6467636f6d70617265646c656674a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c64626174657269676874a4646172677381a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646474657874646b696e646463616c6c6663616c6c656571636f72652e62797465732e6c656e677468687479706541726773816d42797465733c6d61783d36343ea3646b696e64636c65746576616c7565a4646172677381a4646172677383a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646474657874a2646b696e6465636f6e73746576616c7565a3646b696e6463696e746576616c75650065776964746863553634a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c64626174646b696e646463616c6c6663616c6c656570636f72652e62797465732e736c696365687479706541726773816d42797465733c6d61783d36343e646b696e646463616c6c6663616c6c656571636f72652e62797465732e697355746638687479706541726773816d42797465733c6d61783d36343e6762696e64696e67a3626964686c6f63616c2e6f6b647479706564426f6f6c69616c7068614e616d6568246c6f63616c6f6b666c6f63616c7382a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730a3626964686c6f63616c2e6f6b647479706564426f6f6c69616c7068614e616d6568246c6f63616c6f6b66726573756c74a263726566a3626964686c6f63616c2e6f6b647479706564426f6f6c69616c7068614e616d6568246c6f63616c6f6b646b696e64656c6f63616c65696e707574696170702e496e707574666f75747075746a6170702e526573756c7470696e707574436f6e73747261696e74738074636f72654576616c756174696f6e427564676574a3686d617853746570731a000f42406e6d61784f757470757442797465731a00010000716d6178416c6c6f636174656442797465731a01000000781872657175697265644f7065726174696f6e50726f66696c65781a636f6e74696e75756d2e70726f66696c652e746f74616c2f76316a61706956657273696f6e6d65646963742e636f72652f76316a636f6f7264696e6174656361707078187265717569726564436f72654361706162696c697469657380726c6f776572696e675f617274696661637473f6727461726765745f69725f617274696661637459057ca6646b696e64776f7264657265645461726765744972417274696661637466646f6d61696e6f6563686f2e7370616e2d69722f763267696e74656e7473a1687570646174654031a86573746570738066726573756c74a263726566a3626964686c6f63616c2e6f6b647479706564426f6f6c69616c7068614e616d6568246c6f63616c6f6b646b696e64656c6f63616c6c7075726542696e64696e677381a36269646962696e64696e672e316576616c7565a4646172677381a4646172677383a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646474657874a2646b696e6465636f6e73746576616c7565a3646b696e6463696e746576616c75650065776964746863553634a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c64626174646b696e646463616c6c6663616c6c656570636f72652e62797465732e736c696365687479706541726773816d42797465733c6d61783d36343e646b696e646463616c6c6663616c6c656571636f72652e62797465732e697355746638687479706541726773816d42797465733c6d61783d36343e6762696e64696e67a3626964686c6f63616c2e6f6b647479706564426f6f6c69616c7068614e616d6568246c6f63616c6f6b6c726571756972656d656e747381a362696469726571756972652e30696f6e4661696c757265a2646b696e64687465726d696e616c66726561736f6ea2677061796c6f6164a1626174a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646261746a726561736f6e4b696e646d6170702e4261644f666673657469707265646963617465a4626f70623c3d646b696e6467636f6d70617265646c656674a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c64626174657269676874a4646172677381a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646474657874646b696e646463616c6c6663616c6c656571636f72652e62797465732e6c656e677468687479706541726773816d42797465733c6d61783d36343e6e657865637574696f6e4f726465728269726571756972652e306962696e64696e672e3170696e707574436f6e73747261696e747380706f7065726174696f6e50726f66696c65781a636f6e74696e75756d2e70726f66696c652e746f74616c2f763174636f72654576616c756174696f6e427564676574a3686d617853746570731a000f42406e6d61784f757470757442797465731a00010000716d6178416c6c6f636174656442797465731a010000006d74617267657450726f66696c65a26269646a6563686f2e64706f4031666469676573748266736861323536582006060606060606060606060606060606060606060606060606060606060606066f73656d616e746963436c6f73757265a2686c61777061636b73806a736f75726365436f7265a262696463617070666469676573748266736861323536582050af7a30e995ddd04689fadced9615f4f95f859c27d5aa2560bfb15e8d910d5674736f75726365436f7265436f6f7264696e6174656361707078186c61777061636b5f6578706f7274735f6172746966616374584ca66574797065738067656666656374738069636f6e7374616e7473806c6f62737472756374696f6e73806d7075726546756e6374696f6e7380716f7065726174696f6e50726f66696c6573a0706d61785f726573756c745f62797465731a00010000727461726765745f69725f6964656e746974795820a46eca6f75ae25a5ac55dfde7f55a1f95b235d39ec50621c3b467be04f4869b8736d61785f616c6c6f63617465645f62797465731a01000000781a696e7472696e7369635f70726f66696c655f6964656e746974795820a0fc1b7a1e186598291754469fd6ea2220f676358284f7b84c7e2476901a3151781c696e7465727072657465725f70726f66696c655f6964656e746974795820eaa6f8ca4f395d291fdb70af1bd47b804ab82aa17fdbc01b8aaeeb747f7d218c6e6275646765745f6365696c696e67a3657374657073016a726561645f6279746573006b77726974655f6279746573007073656d616e7469635f636c6f73757265a66d636f72655f6964656e74697479582050af7a30e995ddd04689fadced9615f4f95f859c27d5aa2560bfb15e8d910d56727461726765745f69725f6964656e746974795820a46eca6f75ae25a5ac55dfde7f55a1f95b235d39ec50621c3b467be04f4869b87565646963745f736f757263655f6964656e7469747958200101010101010101010101010101010101010101010101010101010101010101781a63616e6f6e6963616c5f6d65616e696e675f6964656e7469747958200303030303030303030303030303030303030303030303030303030303030303781b6170706c69636174696f6e5f736368656d615f6964656e746974795820e2089c3b5730d3b54a8a645cbf77d76492a0f36e98e23d6ecab5e4fd7fa7c265781d6170706c69636174696f6e5f736368656d615f636f6f7264696e6174656a6170702e536368656d61746f7065726174696f6e5f636f6f7264696e6174656c6170702e757064617465403175696e7075745f736368656d615f6964656e746974795820d277705b5ab03fcb58590bad62fb8058e075c3b4c65efc21282bb531aa22b3ad76726573756c745f736368656d615f6964656e746974795820de5c0c4f0c640354c40bb4f9d4886cd820353a548caea4953269eba15fe902bc777461726765745f70726f66696c655f6964656e746974795820eaca21c05664241efd1e1c5b5636c7132fe8854f6bcaddb2fd4f014e1bd4a479781a617574686f726974795f70726f66696c655f6964656e7469747958200808080808080808080808080808080808080808080808080808080808080808781a696e7472696e7369635f70726f66696c655f6964656e746974795820a0fc1b7a1e186598291754469fd6ea2220f676358284f7b84c7e2476901a3151781b666f6f747072696e745f636f6e74726163745f6964656e746974795820362b20fb18488ce180f6c1096b5189994354604fd1b1b126a3ea4ef839e5232b781b6f62737472756374696f6e5f736368656d615f6964656e746974795820b1f96fdf3ec65e84d500702951393a931b4fdd843ad02723ea3725f90a671418781c696e7465727072657465725f70726f66696c655f6964656e746974795820eaa6f8ca4f395d291fdb70af1bd47b804ab82aa17fdbc01b8aaeeb747f7d218c781e726573756c745f696e746572707265746174696f6e5f6964656e74697479582042734d5e73435acc0fdd5a66b97e5bfd94278e64fce2b4890ec609f054dc969e78206576616c756174696f6e5f62617369735f736368656d615f6964656e74697479582020b6239db569aa86ae1c27596b374df90caa5ea41e8e005fd4fe00bfe5c3b38178216170706c69636174696f6e5f62617369735f736368656d615f6964656e7469747958208b294c69120a2e749c56266691b0974e7e0323c198fc42a467fd3790790f791078236f62737472756374696f6e5f696e746572707265746174696f6e5f6964656e746974795820924462071f3992b34c629f4788cc666bd14a87a0b9d0c398feba929ff4dd25f9 diff --git a/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/slice-unproven.hex b/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/slice-unproven.hex new file mode 100644 index 00000000..2132c8f7 --- /dev/null +++ b/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/slice-unproven.hex @@ -0,0 +1 @@ +b166736368656d6178196563686f2e6f7065726174696f6e2d7061636b6167652f76316770726f6772616d590b56ad646b696e647765646963742d6566666563742d70726f6772616d2f763166736368656d6178196563686f2e6f7065726174696f6e2d70726f6772616d2f76316b6f75747075745f747970656a6170702e526573756c746c67726170685f736368656d615876a26a656467655f7479706573a06a6e6f64655f7479706573a158200101010101010101010101010101010101010101010101010101010101010101a26a61646472657373696e67016a61746f6d5f747970657381582002020202020202020202020202020202020202020202020202020202020202026c6964656e746974795f6c6177016d666f6f747072696e745f6c617758f6a9696d61785f7265616473016a61746f6d5f747970657381582002020202020202020202020202020202020202020202020202020202020202026a6d61785f777269746573016f6d61785f72616e67655f6564676573006f726561645f6e6f64655f747970657381582001010101010101010101010101010101010101010101010101010101010101017072616e67655f656467655f7479706573807077726974655f656467655f7479706573807077726974655f6e6f64655f7479706573815820010101010101010101010101010101010101010101010101010101010101010172706f7274616c5f6f776e65725f7479706573806f6d61785f696e7075745f62797465731a0001000070636f6d70696c65645f70726f6772616d59085ba666696e74656e7468757064617465403166736368656d6178286563686f2e636f6d70696c65722d70726f64756365642d6566666563742d70726f6772616d2f76316d636f72655f61727469666163745903bea6657479706573a265496e707574a2646b696e64665265636f7264666669656c6473a36261746355363464746578746d42797465733c6d61783d36343e656f746865726d42797465733c6d61783d36343e66526573756c74a1646b696e6464426f6f6c67696d706f7274738067696e74656e7473a1687570646174654031a664626f6479a3656e6f64657381a3646b696e64636c65746576616c7565a4646172677381a4646172677383a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646474657874a2646b696e6465636f6e73746576616c7565a3646b696e6463696e746576616c75650065776964746863553634a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c64626174646b696e646463616c6c6663616c6c656570636f72652e62797465732e736c696365687479706541726773816d42797465733c6d61783d36343e646b696e646463616c6c6663616c6c656571636f72652e62797465732e697355746638687479706541726773816d42797465733c6d61783d36343e6762696e64696e67a3626964686c6f63616c2e6f6b647479706564426f6f6c69616c7068614e616d6568246c6f63616c6f6b666c6f63616c7382a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730a3626964686c6f63616c2e6f6b647479706564426f6f6c69616c7068614e616d6568246c6f63616c6f6b66726573756c74a263726566a3626964686c6f63616c2e6f6b647479706564426f6f6c69616c7068614e616d6568246c6f63616c6f6b646b696e64656c6f63616c65696e707574696170702e496e707574666f75747075746a6170702e526573756c7470696e707574436f6e73747261696e74738074636f72654576616c756174696f6e427564676574a3686d617853746570731a000f42406e6d61784f757470757442797465731a00010000716d6178416c6c6f636174656442797465731a01000000781872657175697265644f7065726174696f6e50726f66696c65781a636f6e74696e75756d2e70726f66696c652e746f74616c2f76316a61706956657273696f6e6d65646963742e636f72652f76316a636f6f7264696e6174656361707078187265717569726564436f72654361706162696c697469657380726c6f776572696e675f617274696661637473f6727461726765745f69725f61727469666163745903b8a6646b696e64776f7264657265645461726765744972417274696661637466646f6d61696e6f6563686f2e7370616e2d69722f763267696e74656e7473a1687570646174654031a86573746570738066726573756c74a263726566a3626964686c6f63616c2e6f6b647479706564426f6f6c69616c7068614e616d6568246c6f63616c6f6b646b696e64656c6f63616c6c7075726542696e64696e677381a36269646962696e64696e672e306576616c7565a4646172677381a4646172677383a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646474657874a2646b696e6465636f6e73746576616c7565a3646b696e6463696e746576616c75650065776964746863553634a36462617365a263726566a3626964656172672e306474797065696170702e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c64626174646b696e646463616c6c6663616c6c656570636f72652e62797465732e736c696365687479706541726773816d42797465733c6d61783d36343e646b696e646463616c6c6663616c6c656571636f72652e62797465732e697355746638687479706541726773816d42797465733c6d61783d36343e6762696e64696e67a3626964686c6f63616c2e6f6b647479706564426f6f6c69616c7068614e616d6568246c6f63616c6f6b6c726571756972656d656e7473806e657865637574696f6e4f72646572816962696e64696e672e3070696e707574436f6e73747261696e747380706f7065726174696f6e50726f66696c65781a636f6e74696e75756d2e70726f66696c652e746f74616c2f763174636f72654576616c756174696f6e427564676574a3686d617853746570731a000f42406e6d61784f757470757442797465731a00010000716d6178416c6c6f636174656442797465731a010000006d74617267657450726f66696c65a26269646a6563686f2e64706f4031666469676573748266736861323536582006060606060606060606060606060606060606060606060606060606060606066f73656d616e746963436c6f73757265a2686c61777061636b73806a736f75726365436f7265a26269646361707066646967657374826673686132353658204f07a42565b9d79ad680a02881edbe6c1d13a282ba6b1e942655385acbc80f1974736f75726365436f7265436f6f7264696e6174656361707078186c61777061636b5f6578706f7274735f6172746966616374584ca66574797065738067656666656374738069636f6e7374616e7473806c6f62737472756374696f6e73806d7075726546756e6374696f6e7380716f7065726174696f6e50726f66696c6573a0706d61785f726573756c745f62797465731a00010000727461726765745f69725f6964656e7469747958206e94501564a34d1684b6c888f7cacecec4d46fad36ac7b8db8fbf05e01ff194b736d61785f616c6c6f63617465645f62797465731a01000000781a696e7472696e7369635f70726f66696c655f6964656e746974795820a0fc1b7a1e186598291754469fd6ea2220f676358284f7b84c7e2476901a3151781c696e7465727072657465725f70726f66696c655f6964656e746974795820eaa6f8ca4f395d291fdb70af1bd47b804ab82aa17fdbc01b8aaeeb747f7d218c6e6275646765745f6365696c696e67a3657374657073016a726561645f6279746573006b77726974655f6279746573007073656d616e7469635f636c6f73757265a66d636f72655f6964656e7469747958204f07a42565b9d79ad680a02881edbe6c1d13a282ba6b1e942655385acbc80f19727461726765745f69725f6964656e7469747958206e94501564a34d1684b6c888f7cacecec4d46fad36ac7b8db8fbf05e01ff194b7565646963745f736f757263655f6964656e7469747958200101010101010101010101010101010101010101010101010101010101010101781a63616e6f6e6963616c5f6d65616e696e675f6964656e7469747958200303030303030303030303030303030303030303030303030303030303030303781b6170706c69636174696f6e5f736368656d615f6964656e746974795820e2089c3b5730d3b54a8a645cbf77d76492a0f36e98e23d6ecab5e4fd7fa7c265781d6170706c69636174696f6e5f736368656d615f636f6f7264696e6174656a6170702e536368656d61746f7065726174696f6e5f636f6f7264696e6174656c6170702e757064617465403175696e7075745f736368656d615f6964656e746974795820d277705b5ab03fcb58590bad62fb8058e075c3b4c65efc21282bb531aa22b3ad76726573756c745f736368656d615f6964656e746974795820de5c0c4f0c640354c40bb4f9d4886cd820353a548caea4953269eba15fe902bc777461726765745f70726f66696c655f6964656e746974795820eaca21c05664241efd1e1c5b5636c7132fe8854f6bcaddb2fd4f014e1bd4a479781a617574686f726974795f70726f66696c655f6964656e7469747958200808080808080808080808080808080808080808080808080808080808080808781a696e7472696e7369635f70726f66696c655f6964656e746974795820a0fc1b7a1e186598291754469fd6ea2220f676358284f7b84c7e2476901a3151781b666f6f747072696e745f636f6e74726163745f6964656e746974795820362b20fb18488ce180f6c1096b5189994354604fd1b1b126a3ea4ef839e5232b781b6f62737472756374696f6e5f736368656d615f6964656e746974795820b1f96fdf3ec65e84d500702951393a931b4fdd843ad02723ea3725f90a671418781c696e7465727072657465725f70726f66696c655f6964656e746974795820eaa6f8ca4f395d291fdb70af1bd47b804ab82aa17fdbc01b8aaeeb747f7d218c781e726573756c745f696e746572707265746174696f6e5f6964656e74697479582042734d5e73435acc0fdd5a66b97e5bfd94278e64fce2b4890ec609f054dc969e78206576616c756174696f6e5f62617369735f736368656d615f6964656e74697479582020b6239db569aa86ae1c27596b374df90caa5ea41e8e005fd4fe00bfe5c3b38178216170706c69636174696f6e5f62617369735f736368656d615f6964656e7469747958208b294c69120a2e749c56266691b0974e7e0323c198fc42a467fd3790790f791078236f62737472756374696f6e5f696e746572707265746174696f6e5f6964656e746974795820924462071f3992b34c629f4788cc666bd14a87a0b9d0c398feba929ff4dd25f9 diff --git a/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/undeclared-obstruction.hex b/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/undeclared-obstruction.hex new file mode 100644 index 00000000..44507916 --- /dev/null +++ b/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/undeclared-obstruction.hex @@ -0,0 +1 @@ +b166736368656d6178196563686f2e6f7065726174696f6e2d7061636b6167652f76316770726f6772616d592fd5ad646b696e647765646963742d6566666563742d70726f6772616d2f763166736368656d6178196563686f2e6f7065726174696f6e2d70726f6772616d2f76316b6f75747075745f74797065766a656469742e7465787440312e4661637442797465736c67726170685f736368656d615876a26a656467655f7479706573a06a6e6f64655f7479706573a158200101010101010101010101010101010101010101010101010101010101010101a26a61646472657373696e67016a61746f6d5f747970657381582002020202020202020202020202020202020202020202020202020202020202026c6964656e746974795f6c6177016d666f6f747072696e745f6c617758f6a9696d61785f7265616473016a61746f6d5f747970657381582002020202020202020202020202020202020202020202020202020202020202026a6d61785f777269746573016f6d61785f72616e67655f6564676573006f726561645f6e6f64655f747970657381582001010101010101010101010101010101010101010101010101010101010101017072616e67655f656467655f7479706573807077726974655f656467655f7479706573807077726974655f6e6f64655f7479706573815820010101010101010101010101010101010101010101010101010101010101010172706f7274616c5f6f776e65725f7479706573806f6d61785f696e7075745f62797465731a0001000070636f6d70696c65645f70726f6772616d592ccea666696e74656e746c7265706c61636552616e676566736368656d6178286563686f2e636f6d70696c65722d70726f64756365642d6566666563742d70726f6772616d2f76316d636f72655f61727469666163745909caa6657479706573a365496e707574a2646b696e64665265636f7264666669656c6473a2676164647265737378186a656469742e7465787440312e4661637441646472657373686578706563746564766a656469742e7465787440312e466163744279746573766a656469742e7465787440312e466163744279746573a2636d61781a00100000646b696e6465427974657378186a656469742e7465787440312e4661637441646472657373a2646b696e64665265636f7264666669656c6473a3666e6f646549646f42797465733c65786163743d33323e667479706549646f42797465733c65786163743d33323e667761727049646f42797465733c65786163743d33323e67696d706f72747381a263726566a26269646c6a656469742e74657874403166646967657374826673686132353658208d5c6edb069c707261b1547f74c339f859d420a4b778c197d2f7138d5ba29216646b696e64676c61777061636b67696e74656e7473a16c7265706c61636552616e6765a764626f6479a3656e6f64657382a5646b696e646665666665637465696e707574a36462617365a263726566a3626964656172672e30647479706578206a656469742e746578742e7265706c6163655f72616e676540312e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646761646472657373666566666563746d746578742e72656164466163746762696e64696e67a3626964676c6f63616c2e306474797065766a656469742e7465787440312e46616374427974657369616c7068614e616d6567246c6f63616c306e6f62737472756374696f6e4d6170a4676d697373696e67a26576616c7565a4646172677380646b696e646463616c6c6663616c6c656570746578742e466163744d697373696e67687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e30647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e30676e6f7441746f6da26576616c7565a4646172677380646b696e646463616c6c6663616c6c656572746578742e466163744d616c666f726d6564687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e31647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e3168746f6f4c61726765a26576616c7565a4646172677380646b696e646463616c6c6663616c6c656572746578742e466163744d616c666f726d6564687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e32647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e326c747970654d69736d61746368a26576616c7565a4646172677380646b696e646463616c6c6663616c6c656572746578742e466163744d616c666f726d6564687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e33647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e33a3646b696e646772657175697265696f6e4661696c757265a2646b696e64687465726d696e616c66726561736f6ea2677061796c6f6164a06a726561736f6e4b696e6476746578742e42617369734e6f7443616e6f6e6963616c69707265646963617465a4626f70623d3d646b696e6467636f6d70617265646c656674a263726566a3626964676c6f63616c2e306474797065766a656469742e7465787440312e46616374427974657369616c7068614e616d6567246c6f63616c30646b696e64656c6f63616c657269676874a36462617365a263726566a3626964656172672e30647479706578206a656469742e746578742e7265706c6163655f72616e676540312e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c64686578706563746564666c6f63616c7386a3626964656172672e30647479706578206a656469742e746578742e7265706c6163655f72616e676540312e496e70757469616c7068614e616d65652461726730a3626964676c6f63616c2e306474797065766a656469742e7465787440312e46616374427974657369616c7068614e616d6567246c6f63616c30a36269646d6f62737472756374696f6e2e30647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e30a36269646d6f62737472756374696f6e2e31647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e31a36269646d6f62737472756374696f6e2e32647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e32a36269646d6f62737472756374696f6e2e33647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e3366726573756c74a263726566a3626964676c6f63616c2e306474797065766a656469742e7465787440312e46616374427974657369616c7068614e616d6567246c6f63616c30646b696e64656c6f63616c656261736973a36462617365a36462617365a263726566a3626964656172672e30647479706578206a656469742e746578742e7265706c6163655f72616e676540312e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646761646472657373646b696e64656669656c64656669656c64666e6f6465496465696e70757478206a656469742e746578742e7265706c6163655f72616e676540312e496e707574666f7574707574766a656469742e7465787440312e46616374427974657370696e707574436f6e73747261696e74738074636f72654576616c756174696f6e427564676574a3686d617853746570731a004000006e6d61784f757470757442797465731a00800000716d6178416c6c6f636174656442797465731a01000000781872657175697265644f7065726174696f6e50726f66696c65781e636f6e74696e75756d2e70726f66696c652e726561642d6f6e6c792f76316a61706956657273696f6e6d65646963742e636f72652f76316a636f6f7264696e617465781a6a656469742e746578742e7265706c6163655f72616e6765403178187265717569726564436f72654361706162696c697469657380726c6f776572696e675f617274696661637473a56f736f757263655f61727469666163745902d55902d27061636b616765206a656469742e746578742e7265706c6163655f72616e676540313b0a757365206c61777061636b206a656469742e7465787440312064696765737420227368613235363a386435633665646230363963373037323631623135343766373463333339663835396434323061346237373863313937643266373133386435626132393231362220617320746578743b0a7479706520496e707574203d207b20616464726573733a20746578742e46616374416464726573732c2065787065637465643a20746578742e466163744279746573207d3b0a696e74656e74207265706c61636552616e676528696e7075743a20496e707574292072657475726e7320746578742e4661637442797465730a202070726f66696c6520746578742e7265706c61636552616e67650a2020626173697320696e7075742e616464726573732e6e6f646549640a2020627564676574203c3d20746578742e7265706c61636552616e67654275646765740a7b0a20206c65742061637475616c3a20746578742e466163744279746573203d20746578742e726561644661637428696e7075742e61646472657373290a20202020656c7365207b0a2020202020206d697373696e67286164647265737329203d3e20746578742e466163744d697373696e672c0a202020202020747970654d69736d61746368286164647265737329203d3e20746578742e466163744d616c666f726d65642c0a2020202020206e6f7441746f6d286164647265737329203d3e20746578742e466163744d616c666f726d65642c0a202020202020746f6f4c61726765286164647265737329203d3e20746578742e466163744d616c666f726d65642c0a202020207d3b0a2020726571756972652061637475616c203d3d20696e7075742e657870656374656420656c736520746578742e42617369734e6f7443616e6f6e6963616c3b0a202072657475726e2061637475616c3b0a7d0a70616461707465725f6172746966616374590377a565636c6173736b6465636c617261746976656762756467657473a1781f6a656469742e7465787440312e7265706c61636552616e6765427564676574a3686d617853746570731a001000006e6d61784f757470757442797465731a00800000716d6178416c6c6f636174656442797465731a010000006a61706956657273696f6e781865646963742e6c61777061636b2d616461707465722f7631716f7065726174696f6e50726f66696c6573a178196a656469742e7465787440312e7265706c61636552616e6765a464636f7265781e636f6e74696e75756d2e70726f66696c652e726561642d6f6e6c792f76316f73656d616e7469634566666563747381756a656469742e7465787440312e7265616446616374706275646765744f626c69676174696f6e781f6a656469742e7465787440312e7265706c61636552616e676542756467657473746172676574436f6e66696775726174696f6ea262696478286563686f2e6f7065726174696f6e2d6c6f776572696e672d636f6e66696775726174696f6e2f7631666469676573748266736861323536582056921f7058a4b68027c3e5415150b2c6ef4388b000c2ea649cd7a14d3f565f7e75656666656374496d706c656d656e746174696f6e73a1756a656469742e7465787440312e7265616446616374a66a7772697465436c61737364726561646e636f73744f626c69676174696f6e781f6a656469742e7465787440312e7265706c61636552616e67654275646765746f6661696c7572654d617070696e6773a4676d697373696e676b61746f6d4d697373696e67676e6f7441746f6d6c61746f6d526571756972656468746f6f4c617267657561746f6d42797465426f756e6445786365656465646c747970654d69736d617463687061746f6d547970654d69736d617463686f746172676574496e7472696e73696378196563686f2e64706f40312e6e6f64652d61746f6d2d7265616473666f6f747072696e744f626c69676174696f6e78226a656469742e7465787440312e7265706c61636552616e6765466f6f747072696e7473746172676574436f6e66696775726174696f6ea262696478286563686f2e6f7065726174696f6e2d6c6f776572696e672d636f6e66696775726174696f6e2f7631666469676573748266736861323536582056921f7058a4b68027c3e5415150b2c6ef4388b000c2ea649cd7a14d3f565f7e706c61777061636b5f6172746966616374590313aa6269646a6a656469742e74657874676578706f727473a2626964756a656469742e746578742e6578706f7274732f763166646967657374826673686132353658200c75bcc42fd23d9eafdc81f1d81754be32cde98170c5fc1fbaf2746ffef992846776657273696f6e6131687665726966696572a265636c6173736b6465636c617261746976656772756c65736574a2626964781c6a656469742e746578742e76657269666965722d72756c65732f76316664696765737482667368613235365820364fb4ff98ae64fcd8d793aae3d7cb133ff8a1ce661330cea47688b13a0a823f6a61706956657273696f6e7065646963742e6c61777061636b2f76316c646570656e64656e63696573806d636f6d7061746962696c697479a2626964781b6a656469742e746578742e636f6d7061746962696c6974792f763166646967657374826673686132353658202adf83f798205f52636ad64ca45178f33a8e1cc663874f8a6113484c945e30526e746172676574416461707465727381a36761646170746572a2626964781a6a656469742e746578742e6563686f2d616461707465722f763166646967657374826673686132353658207d09bca6885352b8e6198f2a7a1558b914395794e90469741b65618b4ab9bb887061636365707465645461726765744972a26269646f6563686f2e7370616e2d69722f76326664696765737482667368613235365820123e7f805dc5e831e88befec4cd49ec02c39858b6f3990da8a73b50c6086ae3975616363657074656454617267657450726f66696c65a26269646a6563686f2e64706f40316664696765737482667368613235365820e9ba4aab52c815b673aa4b03165ab32863de5052c342b938005d1c0013d5c8fc6f6163636570746564436f7265416269816d65646963742e636f72652f76317818636f6e666f726d616e636546697874757265436f72707573a262696478206a656469742e746578742e5265706c61636552616e67652e6f7261636c6540316664696765737482667368613235365820b9b4707dd5e07897cbe7af36d88928401887e6af5d167d1a88a8d6181b4dbb0e73696e7472696e736963735f617274696661637459030aa26a61706956657273696f6e782265646963742e7461726765742d70726f66696c652e696e7472696e736963732f76316a696e7472696e73696373a178196563686f2e64706f40312e6e6f64652d61746f6d2d72656164ab6a6566666563744b696e6464726561646a72657475726e5479706578206563686f2e64706f40312e6e6f64652d61746f6d2d726561642e726573756c746a7772697465436c61737364726561646c636f737454656d706c617465781f6a656469742e7465787440312e7265706c61636552616e67654275646765746c6775617264537570706f7274f56d617267756d656e74547970657381781f6563686f2e64706f40312e6e6f64652d61746f6d2d726561642e696e7075746e6566666563744661696c75726573a46b61746f6d4d697373696e67a26b7061796c6f616454797065781f6563686f2e64706f40312e6e6f64652d61746f6d2d726561642e696e7075746e617574686f72697479436c6173736d7265736f757263654661756c746c61746f6d5265717569726564a26b7061796c6f616454797065781f6563686f2e64706f40312e6e6f64652d61746f6d2d726561642e696e7075746e617574686f72697479436c6173736e696e746567726974794661756c747061746f6d547970654d69736d61746368a26b7061796c6f616454797065781f6563686f2e64706f40312e6e6f64652d61746f6d2d726561642e696e7075746e617574686f72697479436c6173736e696e746567726974794661756c747561746f6d42797465426f756e644578636565646564a26b7061796c6f616454797065781f6563686f2e64706f40312e6e6f64652d61746f6d2d726561642e696e7075746e617574686f72697479436c6173736e696e746567726974794661756c746e696e7472696e736963436c617373666566666563746e74797065506172616d65746572738071666f6f747072696e7454656d706c61746578226a656469742e7465787440312e7265706c61636552616e6765466f6f747072696e74781b63616e5061727469636970617465496e41746f6d69634775617264f5777461726765745f70726f66696c655f61727469666163745906fbb81c626964686563686f2e64706f676c6f7765726572a2626964736563686f2e64706f2e6c6f77657265722f7631666469676573748266736861323536582044ca28eeeccc4ff522fd9ec7e4694124f4e04880171c8cce460eefcb9505b7976773616e64626f78a26269647765646963742e7761736d2d636f6d706f6e656e742f76316664696765737482667368613235365820095b4dd18f1a6a7276533f758665be319c5f476e7bdc70cc56d30b6b3e9f0a806776657273696f6e6131687461726765744972a26269646f6563686f2e7370616e2d69722f76326664696765737482667368613235365820123e7f805dc5e831e88befec4cd49ec02c39858b6f3990da8a73b50c6086ae39687665726966696572a2626964746563686f2e64706f2e76657269666965722f76316664696765737482667368613235365820ca96b190728de3d668072ec1bd37d24e5197e7bd9bd54f70966d8c566b9b67f2696675656c4d6f64656ca26269646d65646963742e6675656c2f76316664696765737482667368613235365820006c6ebc01a3c5d36d50bd390b69d47e42378be61074e3b5c96ecb9f5ee532076a61706956657273696f6e7765646963742e7461726765742d70726f66696c652f76316a696e7472696e73696373a2626964766563686f2e64706f2e696e7472696e736963732f76316664696765737482667368613235365820865e4a94955f49bc97975acd2ff7670d4576296d68a72de1bcacbb3d5b8cfb666b636f7374416c6765627261a2626964706563686f2e64706f2e636f73742f76316664696765737482667368613235365820486940acd1d4bc15cea40db29347619a07202d9c0f1e63c4016c26bccf0b52a86b6d756c7469546172676574f46d62756e646c6550726f66696c65a2626964726563686f2e64706f2e62756e646c652f76316664696765737482667368613235365820aa0438bcc6ef14ee6cb6d4976622f6080381d731459dcb7b9102595c9bed92c06d646961676e6f73746963416269a26269647465646963742e646961676e6f73746963732f7631666469676573748266736861323536582028fd72a98223153982ca084c29dbb1b2d430623967ab3b6db9d7fee668e614b96f6163636570746564436f7265416269816d65646963742e636f72652f76316f67756172644576616c756174696f6e70707265636f6d6d69742d61746f6d69636f72656164436f6e73697374656e6379746170706c69636174696f6e2d736e617073686f74706170706c69636174696f6e4d6f64656c6661746f6d696370666f6f747072696e74416c6765627261a2626964756563686f2e64706f2e666f6f747072696e742f76316664696765737482667368613235365820f47bb65867e78099ddcfd6ae7af83870df8823f974a496a111ed94e5d785c769716f7065726174696f6e50726f66696c6573a2626964781e6563686f2e64706f2e6f7065726174696f6e2d70726f66696c65732f7631666469676573748266736861323536582053256c51f6c817a77cc8694458bf9d3891abd15b9c94f79ca97d920d3c5f041672696e7472696e7369634e616d6573706163656a6563686f2e64706f4031736f62737472756374696f6e526f6c6c6261636b726e6f2d76697369626c652d65666665637473736f62737472756374696f6e5461786f6e6f6d79a262696478186563686f2e64706f2e6f62737472756374696f6e732f763166646967657374826673686132353658204f5a139d606053c3807f50710076ea9abeb0e611c12a530f5e5b4b31911c3e6474706f7374636f6e646974696f6e537570706f7274f57663616e6f6e6963616c456e636f64696e6752756c6573a26269647765646963742e63616e6f6e6963616c2d63626f722f76316664696765737482667368613235365820d1ea6d3de2a9762a438cbf4fac1d5ae2f357a4b27d13e0347e94ea655bf40f9d7664657465726d696e6973746963457865637574696f6ea26269647465646963742e64657465726d696e69736d2f76316664696765737482667368613235365820af4e6c774d5ea82db30e680be2ba7abc5ba04c6aead146139de32d8c5bb4981e7818636f6e666f726d616e636546697874757265436f72707573a2626964746563686f2e64706f2e66697874757265732f763166646967657374826673686132353658208fa81d37ae4eecb79252f310e7532fc9872bd7c17f2722da911fa74620f81b43781961636365707465644c61777061636b4164617074657241626981781865646963742e6c61777061636b2d616461707465722f7631781967656e657261746564417274696661637450726f66696c657381a262696478186563686f2e64706f2e726567697374726174696f6e2f76316664696765737482667368613235365820ff88be93c26cc533948d8a93601954dc391912d593ca1e96115c846cbf2c5b5d727461726765745f69725f617274696661637459087aa6646b696e64776f7264657265645461726765744972417274696661637466646f6d61696e6f6563686f2e7370616e2d69722f763267696e74656e7473a16c7265706c61636552616e6765a8656261736973a36462617365a36462617365a263726566a3626964656172672e30647479706578206a656469742e746578742e7265706c6163655f72616e676540312e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646761646472657373646b696e64656669656c64656669656c64666e6f6465496465737465707381a7626964737265706c61636552616e67652e737465702e3065696e707574a36462617365a263726566a3626964656172672e30647479706578206a656469742e746578742e7265706c6163655f72616e676540312e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646761646472657373666566666563746d746578742e72656164466163746762696e64696e67a3626964676c6f63616c2e306474797065766a656469742e7465787440312e46616374427974657369616c7068614e616d6567246c6f63616c306f6f62737472756374696f6e41726d73a46b61746f6d4d697373696e67a26576616c7565a4646172677380646b696e646463616c6c6663616c6c656570746578742e466163744d697373696e67687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e30647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e306c61746f6d5265717569726564a26576616c7565a4646172677380646b696e646463616c6c6663616c6c656572746578742e466163744d616c666f726d6564687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e31647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e317061746f6d547970654d69736d61746368a26576616c7565a4646172677380646b696e646463616c6c6663616c6c656572746578742e466163744d616c666f726d6564687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e33647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e337561746f6d42797465426f756e644578636565646564a26576616c7565a4646172677380646b696e646463616c6c6663616c6c656572746578742e466163744d616c666f726d6564687479706541726773806662696e646572a36269646d6f62737472756374696f6e2e32647479706578186a656469742e7465787440312e466163744164647265737369616c7068614e616d656d246f62737472756374696f6e326f746172676574496e7472696e73696378196563686f2e64706f40312e6e6f64652d61746f6d2d72656164736f62737472756374696f6e4661696c75726573847561746f6d42797465426f756e6445786365656465646b61746f6d4d697373696e676c61746f6d52657175697265647061746f6d547970654d69736d6174636866726573756c74a263726566a3626964676c6f63616c2e306474797065766a656469742e7465787440312e46616374427974657369616c7068614e616d6567246c6f63616c30646b696e64656c6f63616c6c726571756972656d656e747381a3626964767265706c61636552616e67652e726571756972652e30696f6e4661696c757265a2646b696e64687465726d696e616c66726561736f6ea2677061796c6f6164a06a726561736f6e4b696e6476746578742e42617369734e6f7443616e6f6e6963616c69707265646963617465a4626f70623d3d646b696e6467636f6d70617265646c656674a263726566a3626964676c6f63616c2e306474797065766a656469742e7465787440312e46616374427974657369616c7068614e616d6567246c6f63616c30646b696e64656c6f63616c657269676874a36462617365a263726566a3626964656172672e30647479706578206a656469742e746578742e7265706c6163655f72616e676540312e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646865787065637465646e657865637574696f6e4f7264657282737265706c61636552616e67652e737465702e30767265706c61636552616e67652e726571756972652e3070696e707574436f6e73747261696e747380706f7065726174696f6e50726f66696c65781e636f6e74696e75756d2e70726f66696c652e726561642d6f6e6c792f763174636f72654576616c756174696f6e427564676574a3686d617853746570731a004000006e6d61784f757470757442797465731a00800000716d6178416c6c6f636174656442797465731a010000006d74617267657450726f66696c65a26269646a6563686f2e64706f40316664696765737482667368613235365820e9ba4aab52c815b673aa4b03165ab32863de5052c342b938005d1c0013d5c8fc6f73656d616e746963436c6f73757265a2686c61777061636b7381a26269646c6a656469742e74657874403166646967657374826673686132353658208d5c6edb069c707261b1547f74c339f859d420a4b778c197d2f7138d5ba292166a736f75726365436f7265a2626964781a6a656469742e746578742e7265706c6163655f72616e676540316664696765737482667368613235365820aca638abdb6039281878f58ce14fa2b3cad9879d2166d7975de45610d14f242874736f75726365436f7265436f6f7264696e617465781a6a656469742e746578742e7265706c6163655f72616e6765403178186c61777061636b5f6578706f7274735f617274696661637459061ba665747970657383a26a636f6f7264696e61746578186a656469742e7465787440312e46616374416464726573736a646566696e6974696f6e784c5265636f72643c6e6f646549643a42797465733c65786163743d33323e2c7479706549643a42797465733c65786163743d33323e2c7761727049643a42797465733c65786163743d33323e3ea26a636f6f7264696e617465766a656469742e7465787440312e4661637442797465736a646566696e6974696f6e7242797465733c6d61783d313034383537363ea26a636f6f7264696e617465781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6a646566696e6974696f6e7822537472696e673c6d61783d3235362c63616e6f6e6963616c3d7261772d757466383e676566666563747381aa69696e7075745479706578186a656469742e7465787440312e46616374416464726573736a636f6f7264696e617465756a656469742e7465787440312e72656164466163746a6f757470757454797065766a656469742e7465787440312e4661637442797465736c6775617264537570706f7274f56e636f73744f626c69676174696f6e781f6a656469742e7465787440312e7265706c61636552616e67654275646765746e6566666563744661696c75726573a4676d697373696e67a26b7061796c6f61645479706578186a656469742e7465787440312e46616374416464726573736e617574686f72697479436c6173736d7265736f757263654661756c74676e6f7441746f6da26b7061796c6f61645479706578186a656469742e7465787440312e46616374416464726573736e617574686f72697479436c6173736e696e746567726974794661756c7468746f6f4c61726765a26b7061796c6f61645479706578186a656469742e7465787440312e46616374416464726573736e617574686f72697479436c6173736e696e746567726974794661756c746c747970654d69736d61746368a26b7061796c6f61645479706578186a656469742e7465787440312e46616374416464726573736e617574686f72697479436c6173736e696e746567726974794661756c746e6566666563744b696e6448696e7464726561646e657865637574696f6e436c6173736772756e74696d656e74797065506172616d65746572738073666f6f747072696e744f626c69676174696f6e78226a656469742e7465787440312e7265706c61636552616e6765466f6f747072696e7469636f6e7374616e7473806c6f62737472756374696f6e7382a36a636f6f7264696e61746578186a656469742e7465787440312e466163744d697373696e676d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736d7265736f757263654661756c74a36a636f6f7264696e617465781a6a656469742e7465787440312e466163744d616c666f726d65646d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736e696e746567726974794661756c746d7075726546756e6374696f6e7380716f7065726174696f6e50726f66696c6573a178196a656469742e7465787440312e7265706c61636552616e6765a26d6f7074696354656d706c617465a6696f707469634b696e64736166666563745265696e746567726174696f6e6c626f756e646172794b696e64666166666563746d626173697354656d706c617465781b6a656469742e7465787440312e65786163744865616442617369736d737570706f7274506f6c696379781e6a656469742e7465787440312e6261736973426f756e64537570706f72746f6c6f7373446973706f736974696f6e756a656469742e7465787440312e6c6f73736c657373736170657274757265526571756972656d656e74a26372656678226a656469742e7465787440312e7265706c61636552616e6765466f6f747072696e74646b696e64781b6162737472616374466f6f747072696e744f626c69676174696f6e6f65666665637450726564696361746578206a656469742e7465787440312e7265706c61636552616e676545666665637473706d61785f726573756c745f62797465731a00010000727461726765745f69725f6964656e7469747958201ddd64dc48d19b4c720f3afc36832a1f7f61c28499d586616aab1f2b292de440736d61785f616c6c6f63617465645f62797465731a01000000781a696e7472696e7369635f70726f66696c655f6964656e746974795820a0fc1b7a1e186598291754469fd6ea2220f676358284f7b84c7e2476901a3151781c696e7465727072657465725f70726f66696c655f6964656e746974795820eaa6f8ca4f395d291fdb70af1bd47b804ab82aa17fdbc01b8aaeeb747f7d218c6e6275646765745f6365696c696e67a3657374657073016a726561645f6279746573006b77726974655f6279746573007073656d616e7469635f636c6f73757265a66d636f72655f6964656e746974795820aca638abdb6039281878f58ce14fa2b3cad9879d2166d7975de45610d14f2428727461726765745f69725f6964656e7469747958201ddd64dc48d19b4c720f3afc36832a1f7f61c28499d586616aab1f2b292de4407565646963745f736f757263655f6964656e7469747958200101010101010101010101010101010101010101010101010101010101010101781a63616e6f6e6963616c5f6d65616e696e675f6964656e7469747958200303030303030303030303030303030303030303030303030303030303030303781b6170706c69636174696f6e5f736368656d615f6964656e746974795820273c89f7a3e6d60e852610acc227e3f719db5dc188d26a8f5492d6ceccb62cc3781d6170706c69636174696f6e5f736368656d615f636f6f7264696e6174656a6170702e536368656d61746f7065726174696f6e5f636f6f7264696e61746578276a656469742e746578742e7265706c6163655f72616e676540312e7265706c61636552616e676575696e7075745f736368656d615f6964656e746974795820d277705b5ab03fcb58590bad62fb8058e075c3b4c65efc21282bb531aa22b3ad76726573756c745f736368656d615f6964656e746974795820de5c0c4f0c640354c40bb4f9d4886cd820353a548caea4953269eba15fe902bc777461726765745f70726f66696c655f6964656e746974795820eaca21c05664241efd1e1c5b5636c7132fe8854f6bcaddb2fd4f014e1bd4a479781a617574686f726974795f70726f66696c655f6964656e7469747958200808080808080808080808080808080808080808080808080808080808080808781a696e7472696e7369635f70726f66696c655f6964656e746974795820a0fc1b7a1e186598291754469fd6ea2220f676358284f7b84c7e2476901a3151781b666f6f747072696e745f636f6e74726163745f6964656e746974795820362b20fb18488ce180f6c1096b5189994354604fd1b1b126a3ea4ef839e5232b781b6f62737472756374696f6e5f736368656d615f6964656e746974795820b1f96fdf3ec65e84d500702951393a931b4fdd843ad02723ea3725f90a671418781c696e7465727072657465725f70726f66696c655f6964656e746974795820eaa6f8ca4f395d291fdb70af1bd47b804ab82aa17fdbc01b8aaeeb747f7d218c781e726573756c745f696e746572707265746174696f6e5f6964656e74697479582042734d5e73435acc0fdd5a66b97e5bfd94278e64fce2b4890ec609f054dc969e78206576616c756174696f6e5f62617369735f736368656d615f6964656e74697479582020b6239db569aa86ae1c27596b374df90caa5ea41e8e005fd4fe00bfe5c3b38178216170706c69636174696f6e5f62617369735f736368656d615f6964656e7469747958208b294c69120a2e749c56266691b0974e7e0323c198fc42a467fd3790790f791078236f62737472756374696f6e5f696e746572707265746174696f6e5f6964656e746974795820924462071f3992b34c629f4788cc666bd14a87a0b9d0c398feba929ff4dd25f9 diff --git a/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/verdicts.txt b/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/verdicts.txt new file mode 100644 index 00000000..cece7a1b --- /dev/null +++ b/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/verdicts.txt @@ -0,0 +1,14 @@ +read-control accept +ensure-node-control accept +slice-proven accept +slice-unproven refuse +slice-other-operand refuse +slice-require-only refuse +forged-node-order refuse +wrong-intrinsic-input-type refuse +undeclared-obstruction refuse +failure-mapping-tag-spelled refuse +failure-mapping-unknown refuse +failure-mapping-duplicate refuse +over-budget refuse +read-captured-budget refuse diff --git a/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/wrong-intrinsic-input-type.hex b/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/wrong-intrinsic-input-type.hex new file mode 100644 index 00000000..ad9e4ef7 --- /dev/null +++ b/crates/echo-edict-provider-lowerer/tests/fixtures/effect-programs/wrong-intrinsic-input-type.hex @@ -0,0 +1 @@ +b166736368656d6178196563686f2e6f7065726174696f6e2d7061636b6167652f76316770726f6772616d59230ead646b696e647765646963742d6566666563742d70726f6772616d2f763166736368656d6178196563686f2e6f7065726174696f6e2d70726f6772616d2f76316b6f75747075745f747970656c4d75746174696f6e556e69746c67726170685f736368656d615876a26a656467655f7479706573a06a6e6f64655f7479706573a158200101010101010101010101010101010101010101010101010101010101010101a26a61646472657373696e67016a61746f6d5f747970657381582002020202020202020202020202020202020202020202020202020202020202026c6964656e746974795f6c6177016d666f6f747072696e745f6c617758f6a9696d61785f7265616473016a61746f6d5f747970657381582002020202020202020202020202020202020202020202020202020202020202026a6d61785f777269746573016f6d61785f72616e67655f6564676573006f726561645f6e6f64655f747970657381582001010101010101010101010101010101010101010101010101010101010101017072616e67655f656467655f7479706573807077726974655f656467655f7479706573807077726974655f6e6f64655f7479706573815820010101010101010101010101010101010101010101010101010101010101010172706f7274616c5f6f776e65725f7479706573806f6d61785f696e7075745f62797465731a0001000070636f6d70696c65645f70726f6772616d592011a666696e74656e746c7265706c61636552616e676566736368656d6178286563686f2e636f6d70696c65722d70726f64756365642d6566666563742d70726f6772616d2f76316d636f72655f61727469666163745904bea6657479706573a565496e707574a2646b696e64665265636f7264666669656c6473a2676164647265737378186a656469742e7465787440312e4661637441646472657373686578706563746564766a656469742e7465787440312e4661637442797465736c4d75746174696f6e556e6974a2646b696e64665265636f7264666669656c6473a06d4d75746174696f6e496e707574a2646b696e64665265636f7264666669656c6473a5666e6f646549646d42797465733c6d61783d33323e667761727049646f42797465733c65786163743d33323e6861746f6d547970656f42797465733c65786163743d33323e686e6f6465547970656f42797465733c65786163743d33323e6961746f6d42797465736f42797465733c6d61783d313032343e766a656469742e7465787440312e466163744279746573a2636d61781a00100000646b696e6465427974657378186a656469742e7465787440312e4661637441646472657373a2646b696e64665265636f7264666669656c6473a3666e6f646549646f42797465733c65786163743d33323e667479706549646f42797465733c65786163743d33323e667761727049646f42797465733c65786163743d33323e67696d706f72747381a263726566a26269646c6a656469742e746578744031666469676573748266736861323536582046670d1111939331d51bce51951570230fe529196ed51ebef5c8de4a8a07d272646b696e64676c61777061636b67696e74656e7473a16c7265706c61636552616e6765a664626f6479a3656e6f64657381a5646b696e646665666665637465696e707574a263726566a3626964656172672e3064747970656d4d75746174696f6e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c666566666563746d746578742e72656164466163746762696e64696e67a3626964676c6f63616c2e3064747970656c4d75746174696f6e556e697469616c7068614e616d6567246c6f63616c306e6f62737472756374696f6e4d6170a0666c6f63616c7382a3626964656172672e3064747970656d4d75746174696f6e496e70757469616c7068614e616d65652461726730a3626964676c6f63616c2e3064747970656c4d75746174696f6e556e697469616c7068614e616d6567246c6f63616c3066726573756c74a263726566a3626964676c6f63616c2e3064747970656c4d75746174696f6e556e697469616c7068614e616d6567246c6f63616c30646b696e64656c6f63616c65696e7075746d4d75746174696f6e496e707574666f75747075746c4d75746174696f6e556e697470696e707574436f6e73747261696e74738074636f72654576616c756174696f6e427564676574a3686d617853746570731a001000006e6d61784f757470757442797465731a00800000716d6178416c6c6f636174656442797465731a01000000781872657175697265644f7065726174696f6e50726f66696c657822636f6e74696e75756d2e70726f66696c652e67726170682d656666656374732f76316a61706956657273696f6e6d65646963742e636f72652f76316a636f6f7264696e617465781a6a656469742e746578742e7265706c6163655f72616e6765403178187265717569726564436f72654361706162696c697469657380726c6f776572696e675f617274696661637473a56f736f757263655f61727469666163745902d55902d27061636b616765206a656469742e746578742e7265706c6163655f72616e676540313b0a757365206c61777061636b206a656469742e7465787440312064696765737420227368613235363a343636373064313131313933393333316435316263653531393531353730323330666535323931393665643531656265663563386465346138613037643237322220617320746578743b0a7479706520496e707574203d207b20616464726573733a20746578742e46616374416464726573732c2065787065637465643a20746578742e466163744279746573207d3b0a696e74656e74207265706c61636552616e676528696e7075743a20496e707574292072657475726e7320746578742e4661637442797465730a202070726f66696c6520746578742e7265706c61636552616e67650a2020626173697320696e7075742e616464726573732e6e6f646549640a2020627564676574203c3d20746578742e7265706c61636552616e67654275646765740a7b0a20206c65742061637475616c3a20746578742e466163744279746573203d20746578742e726561644661637428696e7075742e61646472657373290a20202020656c7365207b0a2020202020206d697373696e67286164647265737329203d3e20746578742e466163744d697373696e672c0a202020202020747970654d69736d61746368286164647265737329203d3e20746578742e466163744d616c666f726d65642c0a2020202020206e6f7441746f6d286164647265737329203d3e20746578742e466163744d616c666f726d65642c0a202020202020746f6f4c61726765286164647265737329203d3e20746578742e466163744d616c666f726d65642c0a202020207d3b0a2020726571756972652061637475616c203d3d20696e7075742e657870656374656420656c736520746578742e42617369734e6f7443616e6f6e6963616c3b0a202072657475726e2061637475616c3b0a7d0a70616461707465725f6172746966616374590313a565636c6173736b6465636c617261746976656762756467657473a1781f6a656469742e7465787440312e7265706c61636552616e6765427564676574a3686d617853746570731a001000006e6d61784f757470757442797465731a00800000716d6178416c6c6f636174656442797465731a010000006a61706956657273696f6e781865646963742e6c61777061636b2d616461707465722f7631716f7065726174696f6e50726f66696c6573a178196a656469742e7465787440312e7265706c61636552616e6765a464636f72657822636f6e74696e75756d2e70726f66696c652e67726170682d656666656374732f76316f73656d616e7469634566666563747381756a656469742e7465787440312e7265616446616374706275646765744f626c69676174696f6e781f6a656469742e7465787440312e7265706c61636552616e676542756467657473746172676574436f6e66696775726174696f6ea262696478286563686f2e6f7065726174696f6e2d6c6f776572696e672d636f6e66696775726174696f6e2f7631666469676573748266736861323536582056921f7058a4b68027c3e5415150b2c6ef4388b000c2ea649cd7a14d3f565f7e75656666656374496d706c656d656e746174696f6e73a1756a656469742e7465787440312e7265616446616374a66a7772697465436c61737366656e737572656e636f73744f626c69676174696f6e781f6a656469742e7465787440312e7265706c61636552616e67654275646765746f6661696c7572654d617070696e6773a06f746172676574496e7472696e736963766563686f2e64706f40312e656e737572652d6e6f646573666f6f747072696e744f626c69676174696f6e78226a656469742e7465787440312e7265706c61636552616e6765466f6f747072696e7473746172676574436f6e66696775726174696f6ea262696478286563686f2e6f7065726174696f6e2d6c6f776572696e672d636f6e66696775726174696f6e2f7631666469676573748266736861323536582056921f7058a4b68027c3e5415150b2c6ef4388b000c2ea649cd7a14d3f565f7e706c61777061636b5f6172746966616374590313aa6269646a6a656469742e74657874676578706f727473a2626964756a656469742e746578742e6578706f7274732f763166646967657374826673686132353658204fbbde0e4bf5d0467b916d263dba80188a9b735dc772b5a151b18d15c0f1e7096776657273696f6e6131687665726966696572a265636c6173736b6465636c617261746976656772756c65736574a2626964781c6a656469742e746578742e76657269666965722d72756c65732f76316664696765737482667368613235365820364fb4ff98ae64fcd8d793aae3d7cb133ff8a1ce661330cea47688b13a0a823f6a61706956657273696f6e7065646963742e6c61777061636b2f76316c646570656e64656e63696573806d636f6d7061746962696c697479a2626964781b6a656469742e746578742e636f6d7061746962696c6974792f763166646967657374826673686132353658202adf83f798205f52636ad64ca45178f33a8e1cc663874f8a6113484c945e30526e746172676574416461707465727381a36761646170746572a2626964781a6a656469742e746578742e6563686f2d616461707465722f76316664696765737482667368613235365820d6dd1b959db13e24dd6d1c3b539d9026acaaab4cb6fd76f9a51c902962a9d4877061636365707465645461726765744972a26269646f6563686f2e7370616e2d69722f76326664696765737482667368613235365820123e7f805dc5e831e88befec4cd49ec02c39858b6f3990da8a73b50c6086ae3975616363657074656454617267657450726f66696c65a26269646a6563686f2e64706f4031666469676573748266736861323536582098a018bef66bb611638edd2d06d25531f30de6c49651c5e684d73392527a2d316f6163636570746564436f7265416269816d65646963742e636f72652f76317818636f6e666f726d616e636546697874757265436f72707573a262696478206a656469742e746578742e5265706c61636552616e67652e6f7261636c6540316664696765737482667368613235365820b9b4707dd5e07897cbe7af36d88928401887e6af5d167d1a88a8d6181b4dbb0e73696e7472696e736963735f6172746966616374590195a26a61706956657273696f6e782265646963742e7461726765742d70726f66696c652e696e7472696e736963732f76316a696e7472696e73696373a1766563686f2e64706f40312e656e737572652d6e6f6465ab6a6566666563744b696e6466656e737572656a72657475726e54797065781d6563686f2e64706f40312e656e737572652d6e6f64652e726573756c746a7772697465436c61737366656e737572656c636f737454656d706c617465781f6a656469742e7465787440312e7265706c61636552616e67654275646765746c6775617264537570706f7274f56d617267756d656e74547970657381781c6563686f2e64706f40312e656e737572652d6e6f64652e696e7075746e6566666563744661696c75726573a06e696e7472696e736963436c617373666566666563746e74797065506172616d65746572738071666f6f747072696e7454656d706c61746578226a656469742e7465787440312e7265706c61636552616e6765466f6f747072696e74781b63616e5061727469636970617465496e41746f6d69634775617264f5777461726765745f70726f66696c655f61727469666163745906fbb81c626964686563686f2e64706f676c6f7765726572a2626964736563686f2e64706f2e6c6f77657265722f7631666469676573748266736861323536582044ca28eeeccc4ff522fd9ec7e4694124f4e04880171c8cce460eefcb9505b7976773616e64626f78a26269647765646963742e7761736d2d636f6d706f6e656e742f76316664696765737482667368613235365820095b4dd18f1a6a7276533f758665be319c5f476e7bdc70cc56d30b6b3e9f0a806776657273696f6e6131687461726765744972a26269646f6563686f2e7370616e2d69722f76326664696765737482667368613235365820123e7f805dc5e831e88befec4cd49ec02c39858b6f3990da8a73b50c6086ae39687665726966696572a2626964746563686f2e64706f2e76657269666965722f76316664696765737482667368613235365820ca96b190728de3d668072ec1bd37d24e5197e7bd9bd54f70966d8c566b9b67f2696675656c4d6f64656ca26269646d65646963742e6675656c2f76316664696765737482667368613235365820006c6ebc01a3c5d36d50bd390b69d47e42378be61074e3b5c96ecb9f5ee532076a61706956657273696f6e7765646963742e7461726765742d70726f66696c652f76316a696e7472696e73696373a2626964766563686f2e64706f2e696e7472696e736963732f7631666469676573748266736861323536582055a364ea3e31b10eb7ba65d9310fa1ece48a8f4a5c9e5705b990c1a2c3397f586b636f7374416c6765627261a2626964706563686f2e64706f2e636f73742f76316664696765737482667368613235365820486940acd1d4bc15cea40db29347619a07202d9c0f1e63c4016c26bccf0b52a86b6d756c7469546172676574f46d62756e646c6550726f66696c65a2626964726563686f2e64706f2e62756e646c652f76316664696765737482667368613235365820aa0438bcc6ef14ee6cb6d4976622f6080381d731459dcb7b9102595c9bed92c06d646961676e6f73746963416269a26269647465646963742e646961676e6f73746963732f7631666469676573748266736861323536582028fd72a98223153982ca084c29dbb1b2d430623967ab3b6db9d7fee668e614b96f6163636570746564436f7265416269816d65646963742e636f72652f76316f67756172644576616c756174696f6e70707265636f6d6d69742d61746f6d69636f72656164436f6e73697374656e6379746170706c69636174696f6e2d736e617073686f74706170706c69636174696f6e4d6f64656c6661746f6d696370666f6f747072696e74416c6765627261a2626964756563686f2e64706f2e666f6f747072696e742f76316664696765737482667368613235365820f47bb65867e78099ddcfd6ae7af83870df8823f974a496a111ed94e5d785c769716f7065726174696f6e50726f66696c6573a2626964781e6563686f2e64706f2e6f7065726174696f6e2d70726f66696c65732f7631666469676573748266736861323536582053256c51f6c817a77cc8694458bf9d3891abd15b9c94f79ca97d920d3c5f041672696e7472696e7369634e616d6573706163656a6563686f2e64706f4031736f62737472756374696f6e526f6c6c6261636b726e6f2d76697369626c652d65666665637473736f62737472756374696f6e5461786f6e6f6d79a262696478186563686f2e64706f2e6f62737472756374696f6e732f763166646967657374826673686132353658204f5a139d606053c3807f50710076ea9abeb0e611c12a530f5e5b4b31911c3e6474706f7374636f6e646974696f6e537570706f7274f57663616e6f6e6963616c456e636f64696e6752756c6573a26269647765646963742e63616e6f6e6963616c2d63626f722f76316664696765737482667368613235365820d1ea6d3de2a9762a438cbf4fac1d5ae2f357a4b27d13e0347e94ea655bf40f9d7664657465726d696e6973746963457865637574696f6ea26269647465646963742e64657465726d696e69736d2f76316664696765737482667368613235365820af4e6c774d5ea82db30e680be2ba7abc5ba04c6aead146139de32d8c5bb4981e7818636f6e666f726d616e636546697874757265436f72707573a2626964746563686f2e64706f2e66697874757265732f763166646967657374826673686132353658208fa81d37ae4eecb79252f310e7532fc9872bd7c17f2722da911fa74620f81b43781961636365707465644c61777061636b4164617074657241626981781865646963742e6c61777061636b2d616461707465722f7631781967656e657261746564417274696661637450726f66696c657381a262696478186563686f2e64706f2e726567697374726174696f6e2f76316664696765737482667368613235365820ff88be93c26cc533948d8a93601954dc391912d593ca1e96115c846cbf2c5b5d727461726765745f69725f6172746966616374590379a6646b696e64776f7264657265645461726765744972417274696661637466646f6d61696e6f6563686f2e7370616e2d69722f763267696e74656e7473a16c7265706c61636552616e6765a765737465707381a7626964686566666563742e3065696e707574a263726566a3626964656172672e3064747970656d4d75746174696f6e496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c666566666563746d746578742e72656164466163746762696e64696e67a3626964676c6f63616c2e3064747970656c4d75746174696f6e556e697469616c7068614e616d6567246c6f63616c306f6f62737472756374696f6e41726d73a06f746172676574496e7472696e736963766563686f2e64706f40312e656e737572652d6e6f6465736f62737472756374696f6e4661696c757265738066726573756c74a263726566a3626964676c6f63616c2e3064747970656c4d75746174696f6e556e697469616c7068614e616d6567246c6f63616c30646b696e64656c6f63616c6c726571756972656d656e7473806e657865637574696f6e4f7264657281686566666563742e3070696e707574436f6e73747261696e747380706f7065726174696f6e50726f66696c657822636f6e74696e75756d2e70726f66696c652e67726170682d656666656374732f763174636f72654576616c756174696f6e427564676574a3686d617853746570731a001000006e6d61784f757470757442797465731a00800000716d6178416c6c6f636174656442797465731a010000006d74617267657450726f66696c65a26269646a6563686f2e64706f4031666469676573748266736861323536582098a018bef66bb611638edd2d06d25531f30de6c49651c5e684d73392527a2d316f73656d616e746963436c6f73757265a2686c61777061636b7381a26269646c6a656469742e746578744031666469676573748266736861323536582046670d1111939331d51bce51951570230fe529196ed51ebef5c8de4a8a07d2726a736f75726365436f7265a2626964781a6a656469742e746578742e7265706c6163655f72616e676540316664696765737482667368613235365820417bae8a8fbdd95fd15c0209b1e2554cd5f3daa4ba1d44c3a9a59dd27976ae0074736f75726365436f7265436f6f7264696e617465781a6a656469742e746578742e7265706c6163655f72616e6765403178186c61777061636b5f6578706f7274735f6172746966616374590544a665747970657383a26a636f6f7264696e61746578186a656469742e7465787440312e46616374416464726573736a646566696e6974696f6e784c5265636f72643c6e6f646549643a42797465733c65786163743d33323e2c7479706549643a42797465733c65786163743d33323e2c7761727049643a42797465733c65786163743d33323e3ea26a636f6f7264696e617465766a656469742e7465787440312e4661637442797465736a646566696e6974696f6e7242797465733c6d61783d313034383537363ea26a636f6f7264696e617465781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6a646566696e6974696f6e7822537472696e673c6d61783d3235362c63616e6f6e6963616c3d7261772d757466383e676566666563747381aa69696e707574547970656d4d75746174696f6e496e7075746a636f6f7264696e617465756a656469742e7465787440312e72656164466163746a6f7574707574547970656c4d75746174696f6e556e69746c6775617264537570706f7274f56e636f73744f626c69676174696f6e781f6a656469742e7465787440312e7265706c61636552616e67654275646765746e6566666563744661696c75726573a06e6566666563744b696e6448696e7464726561646e657865637574696f6e436c6173736772756e74696d656e74797065506172616d65746572738073666f6f747072696e744f626c69676174696f6e78226a656469742e7465787440312e7265706c61636552616e6765466f6f747072696e7469636f6e7374616e7473806c6f62737472756374696f6e7383a36a636f6f7264696e617465781e6a656469742e7465787440312e42617369734e6f7443616e6f6e6963616c6d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736e646f6d61696e4d61707061626c65a36a636f6f7264696e61746578186a656469742e7465787440312e466163744d697373696e676d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736d7265736f757263654661756c74a36a636f6f7264696e617465781a6a656469742e7465787440312e466163744d616c666f726d65646d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736e696e746567726974794661756c746d7075726546756e6374696f6e7380716f7065726174696f6e50726f66696c6573a178196a656469742e7465787440312e7265706c61636552616e6765a26d6f7074696354656d706c617465a6696f707469634b696e64736166666563745265696e746567726174696f6e6c626f756e646172794b696e64666166666563746d626173697354656d706c617465781b6a656469742e7465787440312e65786163744865616442617369736d737570706f7274506f6c696379781e6a656469742e7465787440312e6261736973426f756e64537570706f72746f6c6f7373446973706f736974696f6e756a656469742e7465787440312e6c6f73736c657373736170657274757265526571756972656d656e74a26372656678226a656469742e7465787440312e7265706c61636552616e6765466f6f747072696e74646b696e64781b6162737472616374466f6f747072696e744f626c69676174696f6e6f65666665637450726564696361746578206a656469742e7465787440312e7265706c61636552616e676545666665637473706d61785f726573756c745f62797465731a00010000727461726765745f69725f6964656e7469747958200a56846160eaf6d3371acf694ce860491fd7542537a26236ad9444f68ae9793d736d61785f616c6c6f63617465645f62797465731a01000000781a696e7472696e7369635f70726f66696c655f6964656e746974795820a0fc1b7a1e186598291754469fd6ea2220f676358284f7b84c7e2476901a3151781c696e7465727072657465725f70726f66696c655f6964656e746974795820eaa6f8ca4f395d291fdb70af1bd47b804ab82aa17fdbc01b8aaeeb747f7d218c6e6275646765745f6365696c696e67a3657374657073016a726561645f6279746573006b77726974655f6279746573007073656d616e7469635f636c6f73757265a66d636f72655f6964656e746974795820417bae8a8fbdd95fd15c0209b1e2554cd5f3daa4ba1d44c3a9a59dd27976ae00727461726765745f69725f6964656e7469747958200a56846160eaf6d3371acf694ce860491fd7542537a26236ad9444f68ae9793d7565646963745f736f757263655f6964656e7469747958200101010101010101010101010101010101010101010101010101010101010101781a63616e6f6e6963616c5f6d65616e696e675f6964656e7469747958200303030303030303030303030303030303030303030303030303030303030303781b6170706c69636174696f6e5f736368656d615f6964656e7469747958204fbbde0e4bf5d0467b916d263dba80188a9b735dc772b5a151b18d15c0f1e709781d6170706c69636174696f6e5f736368656d615f636f6f7264696e6174656a6170702e536368656d61746f7065726174696f6e5f636f6f7264696e61746578276a656469742e746578742e7265706c6163655f72616e676540312e7265706c61636552616e676575696e7075745f736368656d615f6964656e746974795820d277705b5ab03fcb58590bad62fb8058e075c3b4c65efc21282bb531aa22b3ad76726573756c745f736368656d615f6964656e746974795820de5c0c4f0c640354c40bb4f9d4886cd820353a548caea4953269eba15fe902bc777461726765745f70726f66696c655f6964656e746974795820eaca21c05664241efd1e1c5b5636c7132fe8854f6bcaddb2fd4f014e1bd4a479781a617574686f726974795f70726f66696c655f6964656e7469747958200808080808080808080808080808080808080808080808080808080808080808781a696e7472696e7369635f70726f66696c655f6964656e746974795820a0fc1b7a1e186598291754469fd6ea2220f676358284f7b84c7e2476901a3151781b666f6f747072696e745f636f6e74726163745f6964656e746974795820362b20fb18488ce180f6c1096b5189994354604fd1b1b126a3ea4ef839e5232b781b6f62737472756374696f6e5f736368656d615f6964656e746974795820b1f96fdf3ec65e84d500702951393a931b4fdd843ad02723ea3725f90a671418781c696e7465727072657465725f70726f66696c655f6964656e746974795820eaa6f8ca4f395d291fdb70af1bd47b804ab82aa17fdbc01b8aaeeb747f7d218c781e726573756c745f696e746572707265746174696f6e5f6964656e74697479582042734d5e73435acc0fdd5a66b97e5bfd94278e64fce2b4890ec609f054dc969e78206576616c756174696f6e5f62617369735f736368656d615f6964656e74697479582020b6239db569aa86ae1c27596b374df90caa5ea41e8e005fd4fe00bfe5c3b38178216170706c69636174696f6e5f62617369735f736368656d615f6964656e7469747958208b294c69120a2e749c56266691b0974e7e0323c198fc42a467fd3790790f791078236f62737472756374696f6e5f696e746572707265746174696f6e5f6964656e746974795820924462071f3992b34c629f4788cc666bd14a87a0b9d0c398feba929ff4dd25f9 diff --git a/crates/echo-edict-provider-verifier/README.md b/crates/echo-edict-provider-verifier/README.md index 0b2c3f4d..1625638b 100644 --- a/crates/echo-edict-provider-verifier/README.md +++ b/crates/echo-edict-provider-verifier/README.md @@ -156,3 +156,7 @@ from the digest-locked package assembled by the next campaign goalpost, which binds the static inputs and verifier component together. Neither proposition has an Echo causal site or witnessed hologram, and neither grants Echo runtime installation, execution, or consequence authority. + +## Authored effect packages + +The native Rust API `effect_package::verify_effect_package` judges an authored effect package before installation, without trusting the lowerer that produced it or the runtime that will execute it. It judges the compiled effect program itself: its binding to its own Core, Target IR and exports; the pinned lawpack, adapter, target profile and intrinsic catalog that authorize each effect; each effect's intrinsic ABI and version-scoped failure contract; one declared obstruction per failure arm; Core and Target IR correspondence; and the body's types, proven ranges and declared budget under the verifier's own cost model. It then requires every identity the package claims, its operation, its output type and its footprint contract to name the program it carries. It refuses with `InvalidEnvelope`, `InvalidBinding` or `UnsupportedProgram`. It does not judge graph-law semantics or grant authority, and the verifier component's interface does not yet call it. diff --git a/crates/echo-edict-provider-verifier/src/effect_package.rs b/crates/echo-edict-provider-verifier/src/effect_package.rs new file mode 100644 index 00000000..6f6d32ee --- /dev/null +++ b/crates/echo-edict-provider-verifier/src/effect_package.rs @@ -0,0 +1,131 @@ +// SPDX-License-Identifier: Apache-2.0 +// © James Ross Ω FLYING•ROBOTS +//! Independent verification of an authored effect package before installation. +//! +//! The verifier judges the compiled effect program itself and requires every +//! identity the package claims to name that exact program. It does not trust +//! the lowerer that produced the package or the runtime that will execute it. +use echo_edict_canonical::{ + decode_canonical_cbor_v1 as decode, encode_canonical_cbor_v1 as encode, + CanonicalValueV1 as Value, +}; + +/// Why an authored effect package was refused. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum EffectPackageRefusal { + /// The bytes are not a canonical authored effect package. + InvalidEnvelope, + /// A package identity, operation or output does not name the program the + /// package carries. + InvalidBinding, + /// The compiled effect program is unsafe or does not match its own + /// artifacts, intrinsic contracts or declared budget. + UnsupportedProgram, +} + +impl std::fmt::Display for EffectPackageRefusal { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(match self { + Self::InvalidEnvelope => "not a canonical authored effect package", + Self::InvalidBinding => "the package does not name the program it carries", + Self::UnsupportedProgram => { + "the compiled effect program is outside the checked profile" + } + }) + } +} +impl std::error::Error for EffectPackageRefusal {} + +/// Verifies an authored effect package's program and its binding. +/// +/// # Errors +/// Refuses malformed envelopes, packages whose identities name another +/// program, and programs outside the verifier's own judgment. +pub fn verify_effect_package(package: &[u8]) -> Result<(), EffectPackageRefusal> { + use EffectPackageRefusal::{InvalidBinding as B, InvalidEnvelope as E}; + let package = canonical(package)?; + if text(get(&package, "schema", E)?, E)? != "echo.operation-package/v1" + || map_field(&package, "obstruction_coordinate").is_some() + { + return Err(E); + } + let program = canonical(bytes(get(&package, "program", E)?, E)?)?; + if text(get(&program, "schema", E)?, E)? != "echo.operation-program/v1" + || text(get(&program, "kind", E)?, E)? != "edict-effect-program/v1" + { + return Err(E); + } + let compiled = bytes(get(&program, "compiled_program", E)?, E)?; + let judged = crate::executable_operation::effect_program::judge(compiled) + .map_err(|()| EffectPackageRefusal::UnsupportedProgram)?; + let closure = get(&package, "semantic_closure", E)?; + for (value, expected) in [ + (get(closure, "core_identity", E)?, &judged.core_identity), + ( + get(closure, "target_ir_identity", E)?, + &judged.target_identity, + ), + ( + get(closure, "application_schema_identity", E)?, + &judged.exports_identity, + ), + ( + get(&program, "target_ir_identity", E)?, + &judged.target_identity, + ), + ] { + if value != expected { + return Err(B); + } + } + if text(get(&package, "operation_coordinate", E)?, E)? != judged.operation + || text(get(&program, "output_type", E)?, E)? != judged.output + { + return Err(B); + } + let mut footprint = blake3::Hasher::new(); + footprint.update(b"echo:operation-footprint-law:v1\0"); + footprint.update(bytes(get(&program, "footprint_law", E)?, E)?); + if bytes(get(&package, "footprint_contract_identity", E)?, E)? + != footprint.finalize().as_bytes() + { + return Err(B); + } + Ok(()) +} + +fn canonical(bytes: &[u8]) -> Result { + let value = decode(bytes).map_err(|_| EffectPackageRefusal::InvalidEnvelope)?; + // Only the exact canonical spelling of a package is verifiable. + if encode(&value).map_err(|_| EffectPackageRefusal::InvalidEnvelope)? != bytes { + return Err(EffectPackageRefusal::InvalidEnvelope); + } + Ok(value) +} +fn map_field<'a>(value: &'a Value, key: &str) -> Option<&'a Value> { + let Value::Map(fields) = value else { + return None; + }; + fields + .iter() + .find_map(|(k, v)| matches!(k, Value::Text(name) if name == key).then_some(v)) +} +fn get<'a>( + value: &'a Value, + key: &str, + refusal: EffectPackageRefusal, +) -> Result<&'a Value, EffectPackageRefusal> { + map_field(value, key).ok_or(refusal) +} +fn text(value: &Value, refusal: EffectPackageRefusal) -> Result<&str, EffectPackageRefusal> { + match value { + Value::Text(text) => Ok(text), + _ => Err(refusal), + } +} +fn bytes(value: &Value, refusal: EffectPackageRefusal) -> Result<&[u8], EffectPackageRefusal> { + match value { + Value::Bytes(bytes) => Ok(bytes), + _ => Err(refusal), + } +} diff --git a/crates/echo-edict-provider-verifier/src/executable_operation.rs b/crates/echo-edict-provider-verifier/src/executable_operation.rs index 38315b96..bd4b1e2d 100644 --- a/crates/echo-edict-provider-verifier/src/executable_operation.rs +++ b/crates/echo-edict-provider-verifier/src/executable_operation.rs @@ -3,6 +3,7 @@ //! Independent verification for generic bounded executable-operation packages. mod bounded_read; +pub(crate) mod effect_program; mod source_functions; use std::collections::BTreeSet; diff --git a/crates/echo-edict-provider-verifier/src/executable_operation/effect_program.rs b/crates/echo-edict-provider-verifier/src/executable_operation/effect_program.rs new file mode 100644 index 00000000..2c5d9fae --- /dev/null +++ b/crates/echo-edict-provider-verifier/src/executable_operation/effect_program.rs @@ -0,0 +1,982 @@ +// SPDX-License-Identifier: Apache-2.0 +// © James Ross Ω FLYING•ROBOTS +//! Verifier-owned judgment of a compiler-produced authored effect program. +//! +//! The verifier establishes, without consulting the lowerer or the runtime, +//! that the program is bound to its own artifacts, that each effect is +//! authorized by its pinned adapter and conforms to its intrinsic's runtime ABI, +//! that every failure arm names a declared obstruction through the +//! version-scoped failure table, that Core and Target IR agree node for node, +//! and that the body is typed, proven and within its declared budget. +use super::source_functions::{judge_effect_intent, EffectSite}; +use echo_edict_canonical::{ + decode_canonical_cbor_v1 as decode, digest_canonical_value_bytes_v1 as digest, + encode_canonical_cbor_v1 as encode, CanonicalValueV1 as Value, +}; +use std::collections::{BTreeMap, BTreeSet}; + +type Check = Result; + +const PROFILE_GRAPH_EFFECTS: &str = "continuum.profile.graph-effects/v1"; +const MAX_DEPTH: usize = 64; +const MAX_NODES: usize = 65_536; + +/// One failure of a read intrinsic: its catalog identifier, the runtime tag +/// Echo records, and its authority class. +struct FailureName { + catalog: &'static str, + runtime: &'static str, + authority: &'static str, +} + +const NODE_ATOM_READ_V1: [FailureName; 4] = [ + FailureName { + catalog: "atomMissing", + runtime: "echo.atom-missing/v1", + authority: "resourceFault", + }, + FailureName { + catalog: "atomRequired", + runtime: "echo.atom-required/v1", + authority: "integrityFault", + }, + FailureName { + catalog: "atomTypeMismatch", + runtime: "echo.atom-type-mismatch/v1", + authority: "integrityFault", + }, + FailureName { + catalog: "atomByteBoundExceeded", + runtime: "echo.atom-byte-bound-exceeded/v1", + authority: "integrityFault", + }, +]; + +/// The failure contract of each runtime intrinsic, keyed by its versioned +/// coordinate. An intrinsic outside this table is refused. +fn failures(intrinsic: &str) -> Option<&'static [FailureName]> { + match intrinsic { + "echo.dpo@1.node-atom-read" => Some(&NODE_ATOM_READ_V1), + "echo.dpo@1.ensure-node" + | "echo.dpo@1.create-node" + | "echo.dpo@1.replace-atom" + | "echo.dpo@1.ensure-edge" + | "echo.dpo@1.replace-edge" => Some(&[]), + _ => None, + } +} + +/// The effect kind, which is also the write class, of each intrinsic. +fn effect_kind(intrinsic: &str) -> Option<&'static str> { + Some(match intrinsic { + "echo.dpo@1.node-atom-read" => "read", + "echo.dpo@1.create-node" => "create", + "echo.dpo@1.ensure-node" | "echo.dpo@1.ensure-edge" => "ensure", + "echo.dpo@1.replace-atom" | "echo.dpo@1.replace-edge" => "replace", + _ => return None, + }) +} + +/// What the judged program binds a package to. +pub(crate) struct Judged { + pub(crate) core_identity: Value, + pub(crate) target_identity: Value, + pub(crate) exports_identity: Value, + pub(crate) operation: String, + pub(crate) output: String, +} + +/// Judges compiler-produced effect-program bytes. +pub(crate) fn judge(compiled_program: &[u8]) -> Check { + let bundle = decode(compiled_program).map_err(|_| ())?; + exact( + &bundle, + &[ + "schema", + "intent", + "core_artifact", + "target_ir_artifact", + "lawpack_exports_artifact", + "lowering_artifacts", + ], + )?; + equal_text( + &bundle, + "schema", + "echo.compiler-produced-effect-program/v1", + )?; + let intent_name = nonempty(get(&bundle, "intent")?)?; + let embedded = |key| decode(bytes(get(&bundle, key)?)?).map_err(|_| ()); + let module = embedded("core_artifact")?; + let target = embedded("target_ir_artifact")?; + let exports = embedded("lawpack_exports_artifact")?; + artifacts(&module, &target, &exports)?; + let intent = get(get(&module, "intents")?, intent_name)?; + let lowered = get(get(&target, "intents")?, intent_name)?; + binding(intent, lowered)?; + let sites = relation( + &module, + intent, + &target, + lowered, + &exports, + get(&bundle, "lowering_artifacts")?, + )?; + correspondence(intent, lowered)?; + judge_effect_intent(&module, &exports, intent, &sites)?; + Ok(Judged { + core_identity: identity("edict.core.module/v1", &module)?, + target_identity: identity("edict.target-ir.artifact/v1", &target)?, + exports_identity: identity("edict.lawpack-exports/v1", &exports)?, + operation: format!("{}.{intent_name}", string(get(&module, "coordinate")?)?), + output: string(get(intent, "output")?)?.to_owned(), + }) +} + +/// The three embedded artifacts and the Core pin the Target IR carries. +fn artifacts(module: &Value, target: &Value, exports: &Value) -> Check<()> { + exact( + target, + &[ + "domain", + "kind", + "intents", + "targetProfile", + "semanticClosure", + "sourceCoreCoordinate", + ], + )?; + equal_text(target, "domain", "echo.span-ir/v2")?; + equal_text(target, "kind", "orderedTargetIrArtifact")?; + exact( + exports, + &[ + "types", + "effects", + "constants", + "obstructions", + "pureFunctions", + "operationProfiles", + ], + )?; + list(get(exports, "types")?)?; + members(get(exports, "operationProfiles")?)?; + for key in ["effects", "constants", "obstructions", "pureFunctions"] { + list(get(exports, key)?)?; + } + let mut fields = vec![ + "apiVersion", + "coordinate", + "imports", + "types", + "intents", + "requiredCoreCapabilities", + ]; + if map_field(module, "functions").is_some() { + fields.push("functions"); + } + exact(module, &fields)?; + equal_text(module, "apiVersion", "edict.core/v1")?; + let coordinate = nonempty(get(module, "coordinate")?)?; + if members(get(module, "intents")?)?.is_empty() { + return Err(()); + } + list(get(module, "imports")?)?; + members(get(module, "types")?)?; + if let Some(functions) = map_field(module, "functions") { + if members(functions)?.is_empty() { + return Err(()); + } + } + for capability in list(get(module, "requiredCoreCapabilities")?)? { + string(capability)?; + } + equal_text(target, "sourceCoreCoordinate", coordinate)?; + let source = get(get(target, "semanticClosure")?, "sourceCore")?; + exact(source, &["id", "digest"])?; + equal_text(source, "id", coordinate)?; + pinned(source, identity("edict.core.module/v1", module)?) +} + +/// The selected intent and its lowered form agree on everything the runtime +/// executes besides the body's instructions. +fn binding(intent: &Value, lowered: &Value) -> Check<()> { + for key in ["inputConstraints", "coreEvaluationBudget"] { + if get(lowered, key)? != get(intent, key)? { + return Err(()); + } + } + equal_text( + lowered, + "operationProfile", + string(get(intent, "requiredOperationProfile")?)?, + )?; + if map_field(lowered, "basis") != map_field(intent, "basis") { + return Err(()); + } + let mut fields = vec![ + "input", + "output", + "requiredOperationProfile", + "inputConstraints", + "coreEvaluationBudget", + "body", + ]; + if map_field(intent, "basis").is_some() { + fields.push("basis"); + } + if map_field(intent, "optic").is_some() { + // Optic-scoped programs are outside the authored-effect route. + return Err(()); + } + exact(intent, &fields)?; + nonempty(get(intent, "input")?)?; + nonempty(get(intent, "output")?)?; + nonempty(get(intent, "requiredOperationProfile")?)?; + let budget = get(intent, "coreEvaluationBudget")?; + exact(budget, &["maxSteps", "maxAllocatedBytes", "maxOutputBytes"])?; + if number(get(budget, "maxSteps")?)? == 0 { + return Err(()); + } + let body = get(intent, "body")?; + exact(body, &["locals", "nodes", "result"])?; + if get(lowered, "result")? != get(body, "result")? { + return Err(()); + } + Ok(()) +} + +/// The pinned lawpack, adapter, target profile and intrinsic catalog that +/// authorize each effect node, and each effect's ABI and failure contract. +#[allow( + clippy::too_many_lines, + reason = "Each pin is checked where the next artifact relies on it." +)] +fn relation<'a>( + module: &'a Value, + intent: &'a Value, + target_artifact: &'a Value, + lowered: &'a Value, + exports: &'a Value, + lowering: &'a Value, +) -> Check> { + let steps = list(get(lowered, "steps")?)?; + if steps.is_empty() { + return if lowering == &Value::Null { + Ok(BTreeMap::new()) + } else { + Err(()) + }; + } + exact( + lowering, + &[ + "source_artifact", + "lawpack_artifact", + "adapter_artifact", + "target_profile_artifact", + "intrinsics_artifact", + ], + )?; + let embedded = |key| decode(bytes(get(lowering, key)?)?).map_err(|_| ()); + let source = embedded("source_artifact")?; + let source = std::str::from_utf8(bytes(&source)?).map_err(|_| ())?; + let lawpack = embedded("lawpack_artifact")?; + let adapter = embedded("adapter_artifact")?; + let profile = embedded("target_profile_artifact")?; + let catalog = embedded("intrinsics_artifact")?; + equal_text(&profile, "apiVersion", "edict.target-profile/v1")?; + let profile_coordinate = format!( + "{}@{}", + string(get(&profile, "id")?)?, + string(get(&profile, "version")?)? + ); + let profile_reference = get(target_artifact, "targetProfile")?; + equal_text(profile_reference, "id", &profile_coordinate)?; + pinned( + profile_reference, + identity("edict.target-profile/v1", &profile)?, + )?; + let core_abi = get(module, "apiVersion")?; + if !list(get(&profile, "acceptedCoreAbi")?)? + .iter() + .any(|value| value == core_abi) + { + return Err(()); + } + equal_text(&profile, "intrinsicNamespace", &profile_coordinate)?; + let catalog_reference = get(&profile, "intrinsics")?; + equal_text(catalog_reference, "id", "echo.dpo.intrinsics/v1")?; + pinned( + catalog_reference, + identity("echo.dpo.intrinsics/v1", &catalog)?, + )?; + exact(&catalog, &["apiVersion", "intrinsics"])?; + equal_text(&catalog, "apiVersion", "edict.target-profile.intrinsics/v1")?; + let catalog = get(&catalog, "intrinsics")?; + members(catalog)?; + equal_text(&lawpack, "apiVersion", "edict.lawpack/v1")?; + equal_text(&adapter, "apiVersion", "edict.lawpack-adapter/v1")?; + equal_text(&adapter, "class", "declarative")?; + let lawpack_coordinate = format!( + "{}@{}", + string(get(&lawpack, "id")?)?, + string(get(&lawpack, "version")?)? + ); + let lawpack_identity = identity("edict.lawpack/v1", &lawpack)?; + let [reference] = list(get(get(target_artifact, "semanticClosure")?, "lawpacks")?)? else { + return Err(()); + }; + equal_text(reference, "id", &lawpack_coordinate)?; + pinned(reference, lawpack_identity.clone())?; + let mut imports = list(get(module, "imports")?)? + .iter() + .filter(|entry| map_field(entry, "kind") == Some(&text("lawpack"))); + let import = imports.next().ok_or(())?; + if imports.next().is_some() || get(import, "ref")? != reference { + return Err(()); + } + pinned( + get(&lawpack, "exports")?, + identity("edict.lawpack-exports/v1", exports)?, + )?; + let mut matching = list(get(&lawpack, "targetAdapters")?)? + .iter() + .filter(|entry| map_field(entry, "acceptedTargetProfile") == Some(profile_reference)); + let entry = matching.next().ok_or(())?; + if matching.next().is_some() || get(&profile, "targetIr")? != get(entry, "acceptedTargetIr")? { + return Err(()); + } + equal_text( + get(entry, "acceptedTargetIr")?, + "id", + string(get(target_artifact, "domain")?)?, + )?; + pinned( + get(entry, "adapter")?, + identity("edict.lawpack-adapter/v1", &adapter)?, + )?; + let alias = alias( + source, + &lawpack_coordinate, + &lawpack_identity, + string(get(module, "coordinate")?)?, + )?; + imported_types(module, exports, &lawpack_coordinate)?; + let operation_profile = string(get(intent, "requiredOperationProfile")?)?; + let authorized = list(get( + unique_profile(&adapter, operation_profile)?, + "semanticEffects", + )?)?; + let implementations = get(&adapter, "effectImplementations")?; + let nodes = list(get(get(intent, "body")?, "nodes")?)?; + let lowered_steps = steps + .iter() + .map(|step| Ok((string(get(step, "id")?)?, step))) + .collect::>>()?; + let order = list(get(lowered, "executionOrder")?)?; + if order.len() != nodes.len() { + return Err(()); + } + let mut sites = BTreeMap::new(); + for (index, (node, id)) in nodes.iter().zip(order).enumerate() { + if string(get(node, "kind")?)? != "effect" { + continue; + } + let step = *lowered_steps.get(string(id)?).ok_or(())?; + let name = resolve(string(get(node, "effect")?)?, &alias, &lawpack_coordinate)?; + if !authorized.iter().any(|value| value == &text(&name)) { + return Err(()); + } + let implementation = get(implementations, &name)?; + let intrinsic_name = string(get(implementation, "targetIntrinsic")?)?; + if !intrinsic_name + .strip_prefix(profile_coordinate.as_str()) + .is_some_and(|suffix| suffix.starts_with('.') && suffix.len() > 1) + { + return Err(()); + } + equal_text(step, "targetIntrinsic", intrinsic_name)?; + let kind = effect_kind(intrinsic_name).ok_or(())?; + if kind != "read" && operation_profile != PROFILE_GRAPH_EFFECTS { + return Err(()); + } + let intrinsic = get(catalog, intrinsic_name)?; + let mut declarations = list(get(exports, "effects")?)? + .iter() + .filter(|effect| map_field(effect, "coordinate") == Some(&text(&name))); + let effect = declarations.next().ok_or(())?; + if declarations.next().is_some() { + return Err(()); + } + contract(intrinsic_name, kind, intrinsic, effect, implementation)?; + let output = string(get(effect, "outputType")?)?; + equal_text(get(node, "binding")?, "type", output)?; + arms( + node, + step, + effect, + implementation, + exports, + &alias, + &lawpack_coordinate, + )?; + sites.insert( + index, + EffectSite { + intrinsic: intrinsic_name.to_owned(), + input: string(get(effect, "inputType")?)?.to_owned(), + output: output.to_owned(), + }, + ); + } + if sites.len() != steps.len() { + return Err(()); + } + Ok(sites) +} + +/// The catalog entry, exported effect and adapter implementation agree with +/// each other and with the intrinsic's runtime ABI and failure table. +fn contract( + name: &str, + kind: &str, + intrinsic: &Value, + effect: &Value, + implementation: &Value, +) -> Check<()> { + exact( + intrinsic, + &[ + "intrinsicClass", + "argumentTypes", + "returnType", + "typeParameters", + "effectKind", + "writeClass", + "guardSupport", + "canParticipateInAtomicGuard", + "costTemplate", + "footprintTemplate", + "effectFailures", + ], + )?; + equal_text(intrinsic, "intrinsicClass", "effect")?; + equal_text(effect, "executionClass", "runtime")?; + let abi_input = format!("{name}.input"); + let [argument] = list(get(intrinsic, "argumentTypes")?)? else { + return Err(()); + }; + if string(argument)? != abi_input + || string(get(intrinsic, "returnType")?)? != format!("{name}.result") + { + return Err(()); + } + if !list(get(intrinsic, "typeParameters")?)?.is_empty() + || !list(get(effect, "typeParameters")?)?.is_empty() + { + return Err(()); + } + equal_text(intrinsic, "effectKind", kind)?; + equal_text(intrinsic, "writeClass", kind)?; + equal_text(implementation, "writeClass", kind)?; + let guard = boolean(get(intrinsic, "guardSupport")?)?; + boolean(get(intrinsic, "canParticipateInAtomicGuard")?)?; + if boolean(get(effect, "guardSupport")?)? && !guard { + return Err(()); + } + for key in ["costTemplate", "footprintTemplate"] { + nonempty(get(intrinsic, key)?)?; + } + let declared = failures(name).ok_or(())?; + let catalog_failures = members(get(intrinsic, "effectFailures")?)?; + let exported = get(effect, "effectFailures")?; + let mappings = members(get(implementation, "failureMappings")?)?; + if catalog_failures.len() != declared.len() + || mappings.len() != declared.len() + || members(exported)?.len() != declared.len() + { + return Err(()); + } + let mut mapped = BTreeSet::new(); + for (source, catalog_name) in mappings { + let catalog_name = string(catalog_name)?; + let failure = declared + .iter() + .find(|failure| failure.catalog == catalog_name) + .ok_or(())?; + if !mapped.insert(failure.runtime) { + return Err(()); + } + let actual = get(get(intrinsic, "effectFailures")?, catalog_name)?; + let expected = get(exported, string(source)?)?; + exact(actual, &["authorityClass", "payloadType"])?; + exact(expected, &["authorityClass", "payloadType"])?; + equal_text(actual, "authorityClass", failure.authority)?; + equal_text(expected, "authorityClass", failure.authority)?; + equal_text(actual, "payloadType", &abi_input)?; + equal_text(expected, "payloadType", string(get(effect, "inputType")?)?)?; + } + Ok(()) +} + +/// Every failure arm of an effect node names exactly one declared +/// obstruction with the failure's authority class, and Core and Target IR +/// carry the same arms under the catalog's failure names. +fn arms( + node: &Value, + step: &Value, + effect: &Value, + implementation: &Value, + exports: &Value, + alias: &str, + lawpack: &str, +) -> Check<()> { + let failures = get(effect, "effectFailures")?; + let mappings = members(get(implementation, "failureMappings")?)?; + let source_arms = get(node, "obstructionMap")?; + let target_arms = get(step, "obstructionArms")?; + if members(source_arms)?.len() != mappings.len() + || members(target_arms)?.len() != mappings.len() + { + return Err(()); + } + let declared_failures = list(get(step, "obstructionFailures")?)? + .iter() + .map(string) + .collect::>>()?; + if declared_failures.len() != mappings.len() { + return Err(()); + } + for (failure, catalog_name) in mappings { + let failure = string(failure)?; + let catalog_name = string(catalog_name)?; + let arm = get(source_arms, failure)?; + if Some(arm) != map_field(target_arms, catalog_name) + || !declared_failures.contains(catalog_name) + { + return Err(()); + } + exact(arm, &["binder", "value"])?; + equal_text( + get(arm, "binder")?, + "type", + string(get(get(failures, failure)?, "payloadType")?)?, + )?; + let reason = get(arm, "value")?; + let coordinate = resolve(string(get(reason, "callee")?)?, alias, lawpack)?; + let mut obstructions = list(get(exports, "obstructions")?)? + .iter() + .filter(|item| map_field(item, "coordinate") == Some(&text(&coordinate))); + let obstruction = obstructions.next().ok_or(())?; + if obstructions.next().is_some() { + return Err(()); + } + equal_text( + obstruction, + "authorityClass", + string(get(get(failures, failure)?, "authorityClass")?)?, + )?; + } + Ok(()) +} + +/// Core nodes and Target IR instructions correspond one for one, in the +/// lowered execution order, with identical kinds and contents. +fn correspondence(intent: &Value, lowered: &Value) -> Check<()> { + let mut fields = vec![ + "operationProfile", + "inputConstraints", + "coreEvaluationBudget", + "steps", + "requirements", + "result", + "executionOrder", + ]; + for key in ["basis", "pureBindings"] { + if map_field(lowered, key).is_some() { + fields.push(key); + } + } + exact(lowered, &fields)?; + let mut instructions = BTreeMap::new(); + for (collection, kind) in [ + ("steps", "effect"), + ("requirements", "require"), + ("pureBindings", "let"), + ] { + let Some(items) = map_field(lowered, collection) else { + continue; + }; + for item in list(items)? { + let id = nonempty(get(item, "id")?)?; + if instructions.insert(id, (kind, item)).is_some() { + return Err(()); + } + } + } + let nodes = list(get(get(intent, "body")?, "nodes")?)?; + let order = list(get(lowered, "executionOrder")?)?; + if nodes.len() != order.len() || nodes.len() != instructions.len() { + return Err(()); + } + for (node, id) in nodes.iter().zip(order) { + let (kind, instruction) = instructions.remove(string(id)?).ok_or(())?; + equal_text(node, "kind", kind)?; + let keys: &[&str] = match kind { + "let" => { + exact(instruction, &["id", "binding", "value"])?; + &["binding", "value"] + } + "require" => { + exact(instruction, &["id", "predicate", "onFailure"])?; + &["predicate", "onFailure"] + } + _ => { + exact( + instruction, + &[ + "id", + "binding", + "effect", + "input", + "targetIntrinsic", + "obstructionArms", + "obstructionFailures", + ], + )?; + &["binding", "effect", "input"] + } + }; + for key in keys { + if get(node, key)? != get(instruction, key)? { + return Err(()); + } + } + } + Ok(()) +} + +fn unique_profile<'a>(adapter: &'a Value, core: &str) -> Check<&'a Value> { + let mut selected = None; + for (_, profile) in members(get(adapter, "operationProfiles")?)? { + if string(get(profile, "core")?)? == core && selected.replace(profile).is_some() { + return Err(()); + } + } + selected.ok_or(()) +} + +fn resolve(name: &str, alias: &str, coordinate: &str) -> Check { + if name + .strip_prefix(coordinate) + .is_some_and(|rest| rest.starts_with('.') && rest.len() > 1) + { + return Ok(name.to_owned()); + } + let member = name + .strip_prefix(alias) + .and_then(|rest| rest.strip_prefix('.')) + .filter(|rest| !rest.is_empty()) + .ok_or(())?; + Ok(format!("{coordinate}.{member}")) +} + +/// The lawpack alias the source declares in its import preamble, with the +/// lawpack's exact digest. +fn alias(source: &str, coordinate: &str, identity: &Value, module: &str) -> Check { + let Value::Bytes(identity) = identity else { + return Err(()); + }; + let expected = format!("\"sha256:{}\"", lower_hex(identity)); + let mut lines = source + .lines() + .map(str::trim) + .filter(|line| !line.is_empty()); + if lines.next() != Some(format!("package {module};").as_str()) { + return Err(()); + } + let mut result = None; + for line in lines { + if !line.starts_with("use ") { + break; + } + let tokens = line.split_whitespace().collect::>(); + let ["use", "lawpack", name, "digest", value, "as", alias] = tokens.as_slice() else { + return Err(()); + }; + let alias = alias.strip_suffix(';').ok_or(())?; + if *name != coordinate + || *value != expected + || !identifier(alias) + || result.replace(alias.to_owned()).is_some() + { + return Err(()); + } + } + result.ok_or(()) +} + +/// Every Core type under the lawpack's namespace renders to exactly the +/// definition the pinned exports declare for it. +fn imported_types(module: &Value, exports: &Value, lawpack: &str) -> Check<()> { + let mut definitions = BTreeMap::new(); + let mut remaining = MAX_NODES; + for item in list(get(exports, "types")?)? { + spend(&mut remaining)?; + exact(item, &["coordinate", "definition"])?; + let name = nonempty(get(item, "coordinate")?)?; + let definition = nonempty(get(item, "definition")?)?; + if definitions.insert(name, definition).is_some() { + return Err(()); + } + } + let prefix = format!("{lawpack}."); + for (name, value) in members(get(module, "types")?)? { + spend(&mut remaining)?; + let name = string(name)?; + if !name.starts_with(&prefix) { + continue; + } + let mut expected = *definitions.get(name).ok_or(())?; + let mut seen = BTreeSet::new(); + while let Some(next) = definitions.get(expected) { + spend(&mut remaining)?; + if seen.len() >= MAX_DEPTH || !seen.insert(expected) { + return Err(()); + } + expected = next; + } + if render(name, value, &mut remaining)? != expected { + return Err(()); + } + } + Ok(()) +} + +fn render(name: &str, value: &Value, remaining: &mut usize) -> Check { + spend(remaining)?; + let kind = string(get(value, "kind")?)?; + match kind { + "Bool" | "Unit" | "I8" | "I16" | "I32" | "I64" | "U8" | "U16" | "U32" | "U64" => { + exact(value, &["kind"])?; + Ok(kind.to_owned()) + } + "Bytes" => { + let max = number(get(value, "max")?)?; + if let Some(min) = map_field(value, "min") { + exact(value, &["kind", "min", "max"])?; + let min = number(min)?; + if min > max { + return Err(()); + } + Ok(if min == max { + format!("Bytes") + } else { + format!("Bytes") + }) + } else { + exact(value, &["kind", "max"])?; + Ok(format!("Bytes")) + } + } + "String" => { + exact(value, &["kind", "max", "canonical"])?; + let max = number(get(value, "max")?)?; + let canonical = string(get(value, "canonical")?)?; + if !["raw-utf8", "unicode-scalar-nfc"].contains(&canonical) { + return Err(()); + } + Ok(format!("String")) + } + "Record" => { + exact(value, &["kind", "fields"])?; + let mut fields = BTreeMap::new(); + for (key, ty) in members(get(value, "fields")?)? { + let key = string(key)?; + if !identifier(key) || fields.insert(key, reference(ty, remaining)?).is_some() { + return Err(()); + } + } + let fields = fields + .into_iter() + .map(|(name, ty)| format!("{name}:{ty}")) + .collect::>() + .join(","); + Ok(format!("Record<{fields}>")) + } + "Nominal" => { + exact(value, &["kind", "contract", "representation"])?; + equal_text(value, "contract", name)?; + Ok(format!( + "Nominal<{}>", + reference(get(value, "representation")?, remaining)? + )) + } + "Option" | "CapabilityRef" => { + exact(value, &["kind", "item"])?; + Ok(format!( + "{kind}<{}>", + reference(get(value, "item")?, remaining)? + )) + } + "List" => { + exact(value, &["kind", "item", "max"])?; + let item = reference(get(value, "item")?, remaining)?; + Ok(format!("List<{item},max={}>", number(get(value, "max")?)?)) + } + "Map" => { + exact(value, &["kind", "key", "value", "max"])?; + let key = reference(get(value, "key")?, remaining)?; + let item = reference(get(value, "value")?, remaining)?; + Ok(format!( + "Map<{key},{item},max={}>", + number(get(value, "max")?)? + )) + } + "ExternalActionRequest" => { + exact(value, &["kind", "settlement"])?; + Ok(format!( + "edict.external-action.request/v1<{}>", + reference(get(value, "settlement")?, remaining)? + )) + } + _ => Err(()), + } +} + +fn reference<'a>(value: &'a Value, remaining: &mut usize) -> Check<&'a str> { + spend(remaining)?; + let value = string(value)?; + if value.is_empty() || value.len() > 1024 { + return Err(()); + } + let mut depth = 0usize; + for byte in value.bytes() { + match byte { + b'<' => { + depth += 1; + if depth > MAX_DEPTH { + return Err(()); + } + } + b'>' => depth = depth.checked_sub(1).ok_or(())?, + _ => {} + } + } + if depth != 0 { + return Err(()); + } + Ok(value) +} + +fn spend(remaining: &mut usize) -> Check<()> { + *remaining = remaining.checked_sub(1).ok_or(())?; + Ok(()) +} + +fn identifier(value: &str) -> bool { + !value.is_empty() + && value + .bytes() + .enumerate() + .all(|(i, c)| c == b'_' || c.is_ascii_alphabetic() || (i > 0 && c.is_ascii_digit())) +} + +fn lower_hex(bytes: &[u8]) -> String { + const DIGITS: &[u8; 16] = b"0123456789abcdef"; + let mut out = String::with_capacity(bytes.len() * 2); + for byte in bytes { + out.push(char::from(DIGITS[usize::from(byte >> 4)])); + out.push(char::from(DIGITS[usize::from(byte & 15)])); + } + out +} + +fn identity(domain: &str, value: &Value) -> Check { + digest(domain, value) + .map(|bytes| Value::Bytes(bytes.to_vec())) + .map_err(|_| ()) +} + +fn pinned(reference: &Value, expected: Value) -> Check<()> { + exact(reference, &["id", "digest"])?; + nonempty(get(reference, "id")?)?; + if get(reference, "digest")? != &Value::Array(vec![text("sha256"), expected]) { + return Err(()); + } + // A pin is canonical bytes, never a looser spelling of the same digest. + encode(reference).map(|_| ()).map_err(|_| ()) +} + +fn text(value: &str) -> Value { + Value::Text(value.to_owned()) +} +fn map_field<'a>(value: &'a Value, key: &str) -> Option<&'a Value> { + let Value::Map(fields) = value else { + return None; + }; + fields + .iter() + .find_map(|(k, v)| matches!(k, Value::Text(name) if name == key).then_some(v)) +} +fn get<'a>(value: &'a Value, key: &str) -> Check<&'a Value> { + map_field(value, key).ok_or(()) +} +fn members(value: &Value) -> Check<&[(Value, Value)]> { + match value { + Value::Map(fields) => Ok(fields), + _ => Err(()), + } +} +fn list(value: &Value) -> Check<&[Value]> { + match value { + Value::Array(items) => Ok(items), + _ => Err(()), + } +} +fn string(value: &Value) -> Check<&str> { + match value { + Value::Text(text) => Ok(text), + _ => Err(()), + } +} +fn nonempty(value: &Value) -> Check<&str> { + string(value).and_then(|text| if text.is_empty() { Err(()) } else { Ok(text) }) +} +fn bytes(value: &Value) -> Check<&[u8]> { + match value { + Value::Bytes(bytes) => Ok(bytes), + _ => Err(()), + } +} +fn number(value: &Value) -> Check { + match value { + Value::Integer(n) => u64::try_from(*n).map_err(|_| ()), + _ => Err(()), + } +} +fn boolean(value: &Value) -> Check { + match value { + Value::Bool(value) => Ok(*value), + _ => Err(()), + } +} +fn equal_text(value: &Value, key: &str, expected: &str) -> Check<()> { + if get(value, key)? == &text(expected) { + Ok(()) + } else { + Err(()) + } +} +fn exact(value: &Value, keys: &[&str]) -> Check<()> { + let fields = members(value)?; + if fields.len() != keys.len() + || fields + .iter() + .any(|(k, _)| !matches!(k, Value::Text(key) if keys.contains(&key.as_str()))) + { + return Err(()); + } + Ok(()) +} diff --git a/crates/echo-edict-provider-verifier/src/executable_operation/source_functions.rs b/crates/echo-edict-provider-verifier/src/executable_operation/source_functions.rs index b27a6604..0a0b1cb4 100644 --- a/crates/echo-edict-provider-verifier/src/executable_operation/source_functions.rs +++ b/crates/echo-edict-provider-verifier/src/executable_operation/source_functions.rs @@ -2,11 +2,13 @@ // © James Ross Ω FLYING•ROBOTS //! Independent verifier judgment: inventory authority, eliminate dependency leaves, //! then audit ordered lexical frames and conservative whole-operation charges. +mod effect_intent; mod order; mod types; mod unsigned_addition; use super::ProviderRefusalV1; use echo_edict_canonical::CanonicalValueV1 as Value; +pub(super) use effect_intent::{judge as judge_effect_intent, EffectSite}; use std::collections::{BTreeMap, BTreeSet}; use types::{Charge, Schema, Types}; type Check = Result; @@ -77,7 +79,27 @@ pub(super) fn validate(core: &Value, exports: &Value, read: bool) -> Result<(), } fn audit(core: &Value, exports: &Value, read: bool) -> Check<()> { let mut types = Types::new(core); - let definitions = inventory(core, exports, &mut types)?; + let (definitions, summaries) = prepare(core, exports, &mut types)?; + let mut checker = Checker { + types: &mut types, + definitions: &definitions, + summaries: &summaries, + proven: Vec::new(), + bound: Vec::new(), + proven_sum: None, + }; + if super::map_field(core, "functions").is_none() && !unsigned_addition::present(core)? { + return Ok(()); + } + for (_, intent) in members(get(core, "intents")?)? { + checker.intent(intent, read)?; + } + Ok(()) +} +/// Inventories every helper and summarizes each one after its dependencies. +type Prepared<'a> = (BTreeMap>, BTreeMap); +fn prepare<'a>(core: &'a Value, exports: &'a Value, types: &mut Types<'a>) -> Check> { + let definitions = inventory(core, exports, types)?; let mut pending = BTreeMap::new(); let mut callers: BTreeMap<&str, Vec<&str>> = BTreeMap::new(); for (name, definition) in &definitions { @@ -99,7 +121,7 @@ fn audit(core: &Value, exports: &Value, read: bool) -> Check<()> { } "if" => { let predicate = get(expression, "predicate")?; - predicate_expressions(predicate, depth + 1, &mut types, &mut expressions)?; + predicate_expressions(predicate, depth + 1, types, &mut expressions)?; expressions.push((get(expression, "then")?, depth + 1)); expressions.push((get(expression, "else")?, depth + 1)); } @@ -135,19 +157,30 @@ fn audit(core: &Value, exports: &Value, read: bool) -> Check<()> { callers.entry(edge).or_default().push(name); } } - let mut ready: BTreeSet<&str> = pending + let summaries = summarize(&definitions, types, pending, &callers)?; + Ok((definitions, summaries)) +} +/// Summarizes every helper after its dependencies, so callers see complete +/// summaries. No native recursion crosses a function edge. +fn summarize<'a, 'n>( + definitions: &BTreeMap>, + types: &mut Types<'a>, + mut pending: BTreeMap<&'n str, usize>, + callers: &BTreeMap<&'n str, Vec<&'n str>>, +) -> Check> { + let mut ready: BTreeSet<&'n str> = pending .iter() .filter_map(|(name, degree)| (*degree == 0).then_some(*name)) .collect(); let mut summaries = BTreeMap::new(); - // No native recursion crosses a function edge. Dependencies receive their - // own complete summary before any caller can use it, in either name order. + // Dependencies receive their own complete summary before any caller can + // use it, in either name order. while let Some(name) = ready.pop_first() { types.step(0)?; let definition = definitions.get(name).ok_or(())?; let summary = Checker { - types: &mut types, - definitions: &definitions, + types: &mut *types, + definitions, summaries: &summaries, proven: Vec::new(), bound: Vec::new(), @@ -171,21 +204,7 @@ fn audit(core: &Value, exports: &Value, read: bool) -> Check<()> { if summaries.len() != definitions.len() { return Err(()); } - let mut checker = Checker { - types: &mut types, - definitions: &definitions, - summaries: &summaries, - proven: Vec::new(), - bound: Vec::new(), - proven_sum: None, - }; - if super::map_field(core, "functions").is_none() && !unsigned_addition::present(core)? { - return Ok(()); - } - for (_, intent) in members(get(core, "intents")?)? { - checker.intent(intent, read)?; - } - Ok(()) + Ok(summaries) } fn inventory<'a>( core: &'a Value, diff --git a/crates/echo-edict-provider-verifier/src/executable_operation/source_functions/effect_intent.rs b/crates/echo-edict-provider-verifier/src/executable_operation/source_functions/effect_intent.rs new file mode 100644 index 00000000..9379bb0b --- /dev/null +++ b/crates/echo-edict-provider-verifier/src/executable_operation/source_functions/effect_intent.rs @@ -0,0 +1,276 @@ +// SPDX-License-Identifier: Apache-2.0 +// © James Ross Ω FLYING•ROBOTS +//! Verifier-owned typing, proof and charge audit of an authored effect +//! program's body, independent of the lowerer and the runtime. +//! +//! Proofs follow Edict: the intent's input constraints dominate the whole +//! body, an unsigned `let` carries its proven cap to later nodes, earlier +//! conjuncts of one `all` prove later ones, and a `require` proves nothing. +use super::{ + exact, get, members, prepare, sequence, string, unsigned, Charge, Check, Checker, Frame, + Schema, Types, Value, +}; +use std::collections::{BTreeMap, BTreeSet}; + +/// The largest atom an authored effect may read or write, in bytes. +const STORAGE_CEILING: u64 = 16 * 1024 * 1024; + +/// What the verifier's relation established about one effect node. +pub(in crate::executable_operation) struct EffectSite { + pub(in crate::executable_operation) intrinsic: String, + pub(in crate::executable_operation) input: String, + pub(in crate::executable_operation) output: String, +} + +/// Audits the selected intent's body against the module's helpers. +pub(in crate::executable_operation) fn judge( + core: &Value, + exports: &Value, + intent: &Value, + sites: &BTreeMap, +) -> Check<()> { + let mut types = Types::new(core); + let (definitions, summaries) = prepare(core, exports, &mut types)?; + Checker { + types: &mut types, + definitions: &definitions, + summaries: &summaries, + proven: Vec::new(), + bound: Vec::new(), + proven_sum: None, + } + .effect_intent(intent, sites) +} + +impl<'a> Checker<'a, '_> { + #[allow( + clippy::too_many_lines, + reason = "One ordered walk keeps scope, proof and charge in step with the body." + )] + fn effect_intent( + &mut self, + intent: &'a Value, + sites: &BTreeMap, + ) -> Check<()> { + self.proven.clear(); + self.bound.clear(); + let body = get(intent, "body")?; + exact(body, &["locals", "nodes", "result"])?; + let mut frame = Frame::new(sequence(get(body, "locals")?)?, self.types)?; + // Failure binders are spent by their own arm and never enter scope. + let mut binders = BTreeSet::new(); + let input = *frame.declared.get("arg.0").ok_or(())?; + if get(input, "type")? != get(intent, "input")? { + return Err(()); + } + let input_type = self.types.local(input)?; + let size = input_type.measure()?; + let mut charge = size.copy; + charge.append(Charge { + ticks: size.checks, + storage: 0, + })?; + frame.define(input, input_type)?; + if let Some(basis) = super::super::map_field(intent, "basis") { + charge.append(self.expression(basis, &frame, 0)?.charge)?; + } + for constraint in sequence(get(intent, "inputConstraints")?)? { + charge.append(self.predicate(get(constraint, "predicate")?, &frame, 0)?.0)?; + self.proven.push(get(constraint, "predicate")?); + } + let nodes = sequence(get(body, "nodes")?)?; + if sites.keys().any(|index| *index >= nodes.len()) { + return Err(()); + } + for (index, node) in nodes.iter().enumerate() { + charge.append(Charge { + ticks: 1, + storage: 0, + })?; + let kind = string(get(node, "kind")?)?; + if (kind == "effect") != sites.contains_key(&index) { + return Err(()); + } + match kind { + "let" => { + exact(node, &["kind", "binding", "value"])?; + let value = self.expression(get(node, "value")?, &frame, 0)?; + let local = get(node, "binding")?; + let expected = self.types.local(local)?; + if !expected.encloses(&value.schema) { + return Err(()); + } + self.record_bound(local, get(node, "value")?, &expected)?; + charge.append(value.charge)?; + charge.append(Charge { + ticks: expected.measure()?.checks, + storage: 0, + })?; + frame.define(local, expected)?; + } + "require" => { + exact(node, &["kind", "predicate", "onFailure"])?; + // Refuses later work; proves nothing for it. + charge.append(self.predicate(get(node, "predicate")?, &frame, 0)?.0)?; + let failure = get(node, "onFailure")?; + exact(failure, &["kind", "reason"])?; + if string(get(failure, "kind")?)? != "terminal" { + return Err(()); + } + let reason = get(failure, "reason")?; + exact(reason, &["reasonKind", "payload"])?; + if string(get(reason, "reasonKind")?)?.is_empty() { + return Err(()); + } + for (_, value) in members(get(reason, "payload")?)? { + charge.append(self.expression(value, &frame, 0)?.charge)?; + } + } + _ => { + exact( + node, + &["kind", "binding", "effect", "input", "obstructionMap"], + )?; + let site = sites.get(&index).ok_or(())?; + let value = self.expression(get(node, "input")?, &frame, 0)?; + let input = self.types.resolve(&site.input, 0)?; + if !input.encloses(&value.schema) { + return Err(()); + } + let output = self.types.resolve(&site.output, 0)?; + let cost = abi(&site.intrinsic, &input, &output)?; + for (_, arm) in members(get(node, "obstructionMap")?)? { + exact(arm, &["binder", "value"])?; + let binder = get(arm, "binder")?; + let id = string(get(binder, "id")?)?; + if frame.declared.get(id).copied() != Some(binder) + || frame.values.contains_key(id) + || !binders.insert(id) + { + return Err(()); + } + let reason = get(arm, "value")?; + exact(reason, &["kind", "callee", "args", "typeArgs"])?; + if string(get(reason, "kind")?)? != "call" + || !sequence(get(reason, "args")?)?.is_empty() + || !sequence(get(reason, "typeArgs")?)?.is_empty() + { + return Err(()); + } + } + let local = get(node, "binding")?; + let declared = self.types.local(local)?; + if declared != output { + return Err(()); + } + charge.append(value.charge)?; + charge.append(Charge { + ticks: input.measure()?.checks, + storage: 0, + })?; + charge.append(cost)?; + frame.define(local, declared)?; + } + } + } + if frame.values.len() + binders.len() != frame.declared.len() + || binders.iter().any(|id| frame.values.contains_key(id)) + { + return Err(()); + } + let output = self.expression(get(body, "result")?, &frame, 0)?; + let expected = self.types.resolve(string(get(intent, "output")?)?, 0)?; + if !expected.encloses(&output.schema) { + return Err(()); + } + let size = expected.measure()?; + charge.append(output.charge)?; + charge.append(size.copy)?; + charge.append(Charge { + ticks: size.checks, + storage: 0, + })?; + let ceiling = get(intent, "coreEvaluationBudget")?; + exact( + ceiling, + &["maxSteps", "maxAllocatedBytes", "maxOutputBytes"], + )?; + if charge.ticks > u128::from(unsigned(get(ceiling, "maxSteps")?)?) + || charge.storage > u128::from(unsigned(get(ceiling, "maxAllocatedBytes")?)?) + || size.encoded > u128::from(unsigned(get(ceiling, "maxOutputBytes")?)?) + { + return Err(()); + } + Ok(()) + } +} + +/// Audits an effect's input and result against its intrinsic's runtime ABI +/// and returns the charge of the effect itself. +fn abi(intrinsic: &str, input: &Schema, output: &Schema) -> Check { + let Schema::Fields(fields) = input.representation() else { + return Err(()); + }; + let identity = |name: &str| { + fields.get(name).map(Schema::representation) == Some(&Schema::Blob { low: 32, high: 32 }) + }; + let atom = |name: &str| { + matches!( + fields.get(name).map(Schema::representation), + Some(Schema::Blob { low: 0, high }) if *high > 0 && *high <= STORAGE_CEILING + ) + }; + let unit = matches!(output.representation(), Schema::Fields(fields) if fields.is_empty()); + let mutation = |names: &[&str]| -> Check { + if fields.len() == names.len() + && names.iter().all(|name| { + if *name == "atomBytes" { + atom(name) + } else { + identity(name) + } + }) + && unit + { + Ok(Charge { + ticks: 1, + storage: 64, + }) + } else { + Err(()) + } + }; + match intrinsic { + "echo.dpo@1.node-atom-read" => { + let Schema::Blob { low: 0, high } = output.representation() else { + return Err(()); + }; + if fields.len() != 3 + || !["nodeId", "typeId", "warpId"] + .iter() + .all(|name| identity(name)) + || *high == 0 + || *high > STORAGE_CEILING + { + return Err(()); + } + Ok(Charge { + ticks: u128::from(*high) + 1, + storage: u128::from(*high) + 64, + }) + } + "echo.dpo@1.ensure-node" | "echo.dpo@1.create-node" => { + mutation(&["warpId", "nodeId", "nodeType", "atomType", "atomBytes"]) + } + "echo.dpo@1.replace-atom" => mutation(&[ + "warpId", + "nodeId", + "expectedAtomDigest", + "atomType", + "atomBytes", + ]), + "echo.dpo@1.ensure-edge" => mutation(&["warpId", "edgeId", "fromId", "toId", "edgeType"]), + "echo.dpo@1.replace-edge" => mutation(&["warpId", "edgeId", "expectedToId", "toId"]), + _ => Err(()), + } +} diff --git a/crates/echo-edict-provider-verifier/src/executable_operation/source_functions/types.rs b/crates/echo-edict-provider-verifier/src/executable_operation/source_functions/types.rs index edee4abe..8f626e93 100644 --- a/crates/echo-edict-provider-verifier/src/executable_operation/source_functions/types.rs +++ b/crates/echo-edict-provider-verifier/src/executable_operation/source_functions/types.rs @@ -201,6 +201,13 @@ impl<'a> Types<'a> { match string(get(definition, "kind")?)? { "Bool" => Ok(Schema::Truth), "Int" => self.resolve(string(get(definition, "width")?)?, depth + 1), + // A table entry may also name an unsigned width directly, as Core does. + kind @ ("U8" | "U16" | "U32" | "U64") => { + if members(definition)?.len() != 1 { + return Err(()); + } + self.resolve(kind, depth + 1) + } "Nominal" => { let identity = string(get(definition, "contract")?)?; if identity != resolved { diff --git a/crates/echo-edict-provider-verifier/src/lib.rs b/crates/echo-edict-provider-verifier/src/lib.rs index a05e4a9c..82e9e266 100644 --- a/crates/echo-edict-provider-verifier/src/lib.rs +++ b/crates/echo-edict-provider-verifier/src/lib.rs @@ -12,6 +12,7 @@ #[cfg(target_arch = "wasm32")] mod component; +pub mod effect_package; mod executable_operation; mod pure_projection; mod pure_relation; diff --git a/crates/echo-edict-provider-verifier/tests/effect_program_judgment.rs b/crates/echo-edict-provider-verifier/tests/effect_program_judgment.rs new file mode 100644 index 00000000..88825295 --- /dev/null +++ b/crates/echo-edict-provider-verifier/tests/effect_program_judgment.rs @@ -0,0 +1,152 @@ +// SPDX-License-Identifier: Apache-2.0 +// © James Ross Ω FLYING•ROBOTS +#![allow(clippy::expect_used, clippy::panic)] +//! The verifier judges authored effect packages itself, independently of the +//! lowerer and the runtime, and reaches the runtime's verdict on the shared +//! retained corpus. +use echo_edict_canonical::{ + decode_canonical_cbor_v1 as decode, encode_canonical_cbor_v1 as encode, CanonicalValueV1 as V, +}; +use echo_edict_provider_verifier::effect_package::{verify_effect_package, EffectPackageRefusal}; + +/// The retained corpus, embedded so the judgment reads no files. +macro_rules! retained { + ($($name:literal),* $(,)?) => { + &[$(( + $name, + include_str!(concat!("../../echo-edict-provider-lowerer/tests/fixtures/effect-programs/", $name, ".hex")), + )),*] + }; +} +const RETAINED: &[(&str, &str)] = retained![ + "read-control", + "ensure-node-control", + "slice-proven", + "slice-unproven", + "slice-other-operand", + "slice-require-only", + "forged-node-order", + "wrong-intrinsic-input-type", + "undeclared-obstruction", + "failure-mapping-tag-spelled", + "failure-mapping-unknown", + "failure-mapping-duplicate", + "over-budget", + "read-captured-budget", +]; +const VERDICTS: &str = + include_str!("../../echo-edict-provider-lowerer/tests/fixtures/effect-programs/verdicts.txt"); + +fn package_bytes(name: &str) -> Vec { + let hex = RETAINED + .iter() + .find_map(|(entry, hex)| (*entry == name).then_some(*hex)) + .expect(name); + hex::decode(hex.trim()).expect("hex") +} +fn field_mut<'a>(value: &'a mut V, key: &str) -> &'a mut V { + let V::Map(fields) = value else { panic!("map") }; + &mut fields + .iter_mut() + .find(|(k, _)| k == &V::Text(key.into())) + .unwrap_or_else(|| panic!("field {key}")) + .1 +} +fn verdicts() -> Vec<(String, bool)> { + VERDICTS + .lines() + .map(|line| { + let (name, verdict) = line.split_once(' ').expect("entry"); + (name.to_owned(), verdict == "accept") + }) + .collect() +} + +#[test] +fn the_verifier_reaches_every_retained_corpus_verdict() { + let verdicts = verdicts(); + assert_eq!( + verdicts + .iter() + .map(|(name, _)| name.as_str()) + .collect::>(), + RETAINED.iter().map(|(name, _)| *name).collect::>(), + "every verdict has its embedded package, in order" + ); + assert!(verdicts.iter().filter(|(_, accept)| *accept).count() >= 3); + assert!(verdicts.iter().filter(|(_, accept)| !*accept).count() >= 10); + for (name, accept) in verdicts { + let judged = verify_effect_package(&package_bytes(&name)); + if accept { + judged.unwrap_or_else(|e| panic!("{name}: verifier refused an accepted package: {e}")); + } else { + assert_eq!( + judged, + Err(EffectPackageRefusal::UnsupportedProgram), + "{name}: verifier accepted a refused package" + ); + } + } +} + +/// A valid program cannot be republished under another package's identities: +/// the verifier rebinds every identity the package claims to the program it +/// actually carries. +#[test] +fn package_identities_must_name_the_program_they_carry() { + let accepted = package_bytes("read-control"); + verify_effect_package(&accepted).expect("rebinding control"); + let original = decode(&accepted).expect("package"); + for key in [ + "core_identity", + "target_ir_identity", + "application_schema_identity", + ] { + let mut package = original.clone(); + let V::Bytes(identity) = field_mut(field_mut(&mut package, "semantic_closure"), key) else { + panic!("identity") + }; + identity[0] ^= 1; + assert_eq!( + verify_effect_package(&encode(&package).expect("package")), + Err(EffectPackageRefusal::InvalidBinding), + "{key}" + ); + } + let mut package = original.clone(); + *field_mut(&mut package, "operation_coordinate") = V::Text("jedit.text@1.otherIntent".into()); + assert_eq!( + verify_effect_package(&encode(&package).expect("package")), + Err(EffectPackageRefusal::InvalidBinding) + ); + let mut package = original; + let V::Bytes(program) = field_mut(&mut package, "program").clone() else { + panic!("program") + }; + let mut program = decode(&program).expect("program"); + *field_mut(&mut program, "output_type") = V::Text("app.Other".into()); + *field_mut(&mut package, "program") = V::Bytes(encode(&program).expect("program")); + assert_eq!( + verify_effect_package(&encode(&package).expect("package")), + Err(EffectPackageRefusal::InvalidBinding) + ); +} + +#[test] +fn only_authored_effect_programs_are_judged_here() { + let mut package = decode(&package_bytes("slice-proven")).expect("package"); + let V::Bytes(program) = field_mut(&mut package, "program").clone() else { + panic!("program") + }; + let mut program = decode(&program).expect("program"); + *field_mut(&mut program, "kind") = V::Text("edict-pure-program/v1".into()); + *field_mut(&mut package, "program") = V::Bytes(encode(&program).expect("program")); + assert_eq!( + verify_effect_package(&encode(&package).expect("package")), + Err(EffectPackageRefusal::InvalidEnvelope) + ); + assert_eq!( + verify_effect_package(b"not canonical"), + Err(EffectPackageRefusal::InvalidEnvelope) + ); +} diff --git a/crates/echo-wesley-gen/tests/fixtures/current-effect-publication/package.hex b/crates/echo-wesley-gen/tests/fixtures/current-effect-publication/package.hex index 07298284..9c359ae2 100644 --- a/crates/echo-wesley-gen/tests/fixtures/current-effect-publication/package.hex +++ b/crates/echo-wesley-gen/tests/fixtures/current-effect-publication/package.hex @@ -1 +1 @@ -b166736368656d6178196563686f2e6f7065726174696f6e2d7061636b6167652f76316770726f6772616d5907c4ad646b696e647765646963742d6566666563742d70726f6772616d2f763166736368656d6178196563686f2e6f7065726174696f6e2d70726f6772616d2f76316b6f75747075745f747970656a6170702e526573756c746c67726170685f736368656d615876a26a656467655f7479706573a06a6e6f64655f7479706573a158200101010101010101010101010101010101010101010101010101010101010101a26a61646472657373696e67016a61746f6d5f747970657381582002020202020202020202020202020202020202020202020202020202020202026c6964656e746974795f6c6177016d666f6f747072696e745f6c617758f6a9696d61785f7265616473016a61746f6d5f747970657381582002020202020202020202020202020202020202020202020202020202020202026a6d61785f777269746573016f6d61785f72616e67655f6564676573006f726561645f6e6f64655f747970657381582001010101010101010101010101010101010101010101010101010101010101017072616e67655f656467655f7479706573807077726974655f656467655f7479706573807077726974655f6e6f64655f7479706573815820010101010101010101010101010101010101010101010101010101010101010172706f7274616c5f6f776e65725f7479706573806f6d61785f696e7075745f62797465731a0001000070636f6d70696c65645f70726f6772616d5904c9a666696e74656e7468757064617465403166736368656d6178286563686f2e636f6d70696c65722d70726f64756365642d6566666563742d70726f6772616d2f76316d636f72655f6172746966616374590194a6657479706573a166526573756c74a1646b696e646355333267696d706f7274738067696e74656e7473a1687570646174654031a664626f6479a3656e6f64657380666c6f63616c7381a3626964656172672e3064747970656355333269616c7068614e616d6565246172673066726573756c74a2646b696e6465636f6e73746576616c7565a3646b696e6463696e746576616c7565182a6577696474686355333265696e70757463553332666f75747075746a6170702e526573756c7470696e707574436f6e73747261696e74738074636f72654576616c756174696f6e427564676574a3686d61785374657073016e6d61784f757470757442797465731a00010000716d6178416c6c6f636174656442797465731a01000000781872657175697265644f7065726174696f6e50726f66696c65781a636f6e74696e75756d2e70726f66696c652e746f74616c2f76316a61706956657273696f6e6d65646963742e636f72652f76316a636f6f7264696e6174656361707078187265717569726564436f72654361706162696c697469657380726c6f776572696e675f617274696661637473f6727461726765745f69725f6172746966616374590200a6646b696e64776f7264657265645461726765744972417274696661637466646f6d61696e6f6563686f2e7370616e2d69722f763267696e74656e7473a1687570646174654031a86573746570738066726573756c74a2646b696e6465636f6e73746576616c7565a3646b696e6463696e746576616c7565182a657769647468635533326c7075726542696e64696e6773806c726571756972656d656e7473806e657865637574696f6e4f726465728070696e707574436f6e73747261696e747380706f7065726174696f6e50726f66696c65781a636f6e74696e75756d2e70726f66696c652e746f74616c2f763174636f72654576616c756174696f6e427564676574a3686d61785374657073016e6d61784f757470757442797465731a00010000716d6178416c6c6f636174656442797465731a010000006d74617267657450726f66696c65a26269646a6563686f2e64706f4031666469676573748266736861323536582006060606060606060606060606060606060606060606060606060606060606066f73656d616e746963436c6f73757265a2686c61777061636b73806a736f75726365436f7265a262696463617070666469676573748266736861323536582017e17862979412ae3477593727e6d5ec05ee50fe255fc02acdfc5777b9ac744d74736f75726365436f7265436f6f7264696e6174656361707078186c61777061636b5f6578706f7274735f6172746966616374589ca66574797065738067656666656374738069636f6e7374616e7473806c6f62737472756374696f6e7381a36a636f6f7264696e6174656b6170702e5265667573616c6d7061796c6f6164536368656d61736170702e5265667573616c2e5061796c6f61646e617574686f72697479436c61737366646f6d61696e6d7075726546756e6374696f6e7380716f7065726174696f6e50726f66696c6573a0706d61785f726573756c745f62797465731a00010000727461726765745f69725f6964656e746974795820d9374cd2aaabfab6f1d5ca0b5298687a8b9c12a19362f982b8401eb0381f6db0736d61785f616c6c6f63617465645f62797465731a01000000781a696e7472696e7369635f70726f66696c655f6964656e746974795820a0fc1b7a1e186598291754469fd6ea2220f676358284f7b84c7e2476901a3151781c696e7465727072657465725f70726f66696c655f6964656e746974795820eaa6f8ca4f395d291fdb70af1bd47b804ab82aa17fdbc01b8aaeeb747f7d218c6e6275646765745f6365696c696e67a36573746570730a6a726561645f62797465731910006b77726974655f62797465731910007073656d616e7469635f636c6f73757265a66d636f72655f6964656e74697479582017e17862979412ae3477593727e6d5ec05ee50fe255fc02acdfc5777b9ac744d727461726765745f69725f6964656e746974795820d9374cd2aaabfab6f1d5ca0b5298687a8b9c12a19362f982b8401eb0381f6db07565646963745f736f757263655f6964656e746974795820fdf14fbb05ba25e820cd4a23b594e6648429940f7aed5218077eef841288114c781a63616e6f6e6963616c5f6d65616e696e675f6964656e74697479582017e17862979412ae3477593727e6d5ec05ee50fe255fc02acdfc5777b9ac744d781b6170706c69636174696f6e5f736368656d615f6964656e74697479582017ff6f37fcc8b1f81e58cc3ef5c0d94a4c3f96fb955bfb9cae7ff0bac29cb249781d6170706c69636174696f6e5f736368656d615f636f6f7264696e6174656b6170702e4578706f727473746f7065726174696f6e5f636f6f7264696e6174656c6170702e757064617465403175696e7075745f736368656d615f6964656e746974795820d277705b5ab03fcb58590bad62fb8058e075c3b4c65efc21282bb531aa22b3ad76726573756c745f736368656d615f6964656e746974795820de5c0c4f0c640354c40bb4f9d4886cd820353a548caea4953269eba15fe902bc777461726765745f70726f66696c655f6964656e746974795820eaca21c05664241efd1e1c5b5636c7132fe8854f6bcaddb2fd4f014e1bd4a479781a617574686f726974795f70726f66696c655f6964656e7469747958208eca01fcc45de0eb065bfd04fb21d2c7881c346ca07dfc1536df5ca2fe0812dc781a696e7472696e7369635f70726f66696c655f6964656e746974795820a0fc1b7a1e186598291754469fd6ea2220f676358284f7b84c7e2476901a3151781b666f6f747072696e745f636f6e74726163745f6964656e746974795820362b20fb18488ce180f6c1096b5189994354604fd1b1b126a3ea4ef839e5232b781b6f62737472756374696f6e5f736368656d615f6964656e746974795820b1f96fdf3ec65e84d500702951393a931b4fdd843ad02723ea3725f90a671418781c696e7465727072657465725f70726f66696c655f6964656e746974795820eaa6f8ca4f395d291fdb70af1bd47b804ab82aa17fdbc01b8aaeeb747f7d218c781e726573756c745f696e746572707265746174696f6e5f6964656e74697479582042734d5e73435acc0fdd5a66b97e5bfd94278e64fce2b4890ec609f054dc969e78206576616c756174696f6e5f62617369735f736368656d615f6964656e74697479582020b6239db569aa86ae1c27596b374df90caa5ea41e8e005fd4fe00bfe5c3b38178216170706c69636174696f6e5f62617369735f736368656d615f6964656e7469747958208b294c69120a2e749c56266691b0974e7e0323c198fc42a467fd3790790f791078236f62737472756374696f6e5f696e746572707265746174696f6e5f6964656e746974795820924462071f3992b34c629f4788cc666bd14a87a0b9d0c398feba929ff4dd25f9 +b166736368656d6178196563686f2e6f7065726174696f6e2d7061636b6167652f76316770726f6772616d5907c8ad646b696e647765646963742d6566666563742d70726f6772616d2f763166736368656d6178196563686f2e6f7065726174696f6e2d70726f6772616d2f76316b6f75747075745f747970656a6170702e526573756c746c67726170685f736368656d615876a26a656467655f7479706573a06a6e6f64655f7479706573a158200101010101010101010101010101010101010101010101010101010101010101a26a61646472657373696e67016a61746f6d5f747970657381582002020202020202020202020202020202020202020202020202020202020202026c6964656e746974795f6c6177016d666f6f747072696e745f6c617758f6a9696d61785f7265616473016a61746f6d5f747970657381582002020202020202020202020202020202020202020202020202020202020202026a6d61785f777269746573016f6d61785f72616e67655f6564676573006f726561645f6e6f64655f747970657381582001010101010101010101010101010101010101010101010101010101010101017072616e67655f656467655f7479706573807077726974655f656467655f7479706573807077726974655f6e6f64655f7479706573815820010101010101010101010101010101010101010101010101010101010101010172706f7274616c5f6f776e65725f7479706573806f6d61785f696e7075745f62797465731a0001000070636f6d70696c65645f70726f6772616d5904cda666696e74656e7468757064617465403166736368656d6178286563686f2e636f6d70696c65722d70726f64756365642d6566666563742d70726f6772616d2f76316d636f72655f6172746966616374590196a6657479706573a166526573756c74a1646b696e646355333267696d706f7274738067696e74656e7473a1687570646174654031a664626f6479a3656e6f64657380666c6f63616c7381a3626964656172672e3064747970656355333269616c7068614e616d6565246172673066726573756c74a2646b696e6465636f6e73746576616c7565a3646b696e6463696e746576616c7565182a6577696474686355333265696e70757463553332666f75747075746a6170702e526573756c7470696e707574436f6e73747261696e74738074636f72654576616c756174696f6e427564676574a3686d617853746570731904006e6d61784f757470757442797465731a00010000716d6178416c6c6f636174656442797465731a01000000781872657175697265644f7065726174696f6e50726f66696c65781a636f6e74696e75756d2e70726f66696c652e746f74616c2f76316a61706956657273696f6e6d65646963742e636f72652f76316a636f6f7264696e6174656361707078187265717569726564436f72654361706162696c697469657380726c6f776572696e675f617274696661637473f6727461726765745f69725f6172746966616374590202a6646b696e64776f7264657265645461726765744972417274696661637466646f6d61696e6f6563686f2e7370616e2d69722f763267696e74656e7473a1687570646174654031a86573746570738066726573756c74a2646b696e6465636f6e73746576616c7565a3646b696e6463696e746576616c7565182a657769647468635533326c7075726542696e64696e6773806c726571756972656d656e7473806e657865637574696f6e4f726465728070696e707574436f6e73747261696e747380706f7065726174696f6e50726f66696c65781a636f6e74696e75756d2e70726f66696c652e746f74616c2f763174636f72654576616c756174696f6e427564676574a3686d617853746570731904006e6d61784f757470757442797465731a00010000716d6178416c6c6f636174656442797465731a010000006d74617267657450726f66696c65a26269646a6563686f2e64706f4031666469676573748266736861323536582006060606060606060606060606060606060606060606060606060606060606066f73656d616e746963436c6f73757265a2686c61777061636b73806a736f75726365436f7265a2626964636170706664696765737482667368613235365820e003c45d1967ce94fd454df03168536c81829a4247e2172412045f2a98528bd474736f75726365436f7265436f6f7264696e6174656361707078186c61777061636b5f6578706f7274735f6172746966616374589ca66574797065738067656666656374738069636f6e7374616e7473806c6f62737472756374696f6e7381a36a636f6f7264696e6174656b6170702e5265667573616c6d7061796c6f6164536368656d61736170702e5265667573616c2e5061796c6f61646e617574686f72697479436c61737366646f6d61696e6d7075726546756e6374696f6e7380716f7065726174696f6e50726f66696c6573a0706d61785f726573756c745f62797465731a00010000727461726765745f69725f6964656e746974795820b52c5d34cdeff1c9c6052a2d59ac6d7b0f20dcb00ed33739a71d8ac0bff59b97736d61785f616c6c6f63617465645f62797465731a01000000781a696e7472696e7369635f70726f66696c655f6964656e746974795820a0fc1b7a1e186598291754469fd6ea2220f676358284f7b84c7e2476901a3151781c696e7465727072657465725f70726f66696c655f6964656e746974795820eaa6f8ca4f395d291fdb70af1bd47b804ab82aa17fdbc01b8aaeeb747f7d218c6e6275646765745f6365696c696e67a36573746570730a6a726561645f62797465731910006b77726974655f62797465731910007073656d616e7469635f636c6f73757265a66d636f72655f6964656e746974795820e003c45d1967ce94fd454df03168536c81829a4247e2172412045f2a98528bd4727461726765745f69725f6964656e746974795820b52c5d34cdeff1c9c6052a2d59ac6d7b0f20dcb00ed33739a71d8ac0bff59b977565646963745f736f757263655f6964656e746974795820fdf14fbb05ba25e820cd4a23b594e6648429940f7aed5218077eef841288114c781a63616e6f6e6963616c5f6d65616e696e675f6964656e746974795820e003c45d1967ce94fd454df03168536c81829a4247e2172412045f2a98528bd4781b6170706c69636174696f6e5f736368656d615f6964656e74697479582017ff6f37fcc8b1f81e58cc3ef5c0d94a4c3f96fb955bfb9cae7ff0bac29cb249781d6170706c69636174696f6e5f736368656d615f636f6f7264696e6174656b6170702e4578706f727473746f7065726174696f6e5f636f6f7264696e6174656c6170702e757064617465403175696e7075745f736368656d615f6964656e746974795820d277705b5ab03fcb58590bad62fb8058e075c3b4c65efc21282bb531aa22b3ad76726573756c745f736368656d615f6964656e746974795820de5c0c4f0c640354c40bb4f9d4886cd820353a548caea4953269eba15fe902bc777461726765745f70726f66696c655f6964656e746974795820eaca21c05664241efd1e1c5b5636c7132fe8854f6bcaddb2fd4f014e1bd4a479781a617574686f726974795f70726f66696c655f6964656e7469747958208eca01fcc45de0eb065bfd04fb21d2c7881c346ca07dfc1536df5ca2fe0812dc781a696e7472696e7369635f70726f66696c655f6964656e746974795820a0fc1b7a1e186598291754469fd6ea2220f676358284f7b84c7e2476901a3151781b666f6f747072696e745f636f6e74726163745f6964656e746974795820362b20fb18488ce180f6c1096b5189994354604fd1b1b126a3ea4ef839e5232b781b6f62737472756374696f6e5f736368656d615f6964656e746974795820b1f96fdf3ec65e84d500702951393a931b4fdd843ad02723ea3725f90a671418781c696e7465727072657465725f70726f66696c655f6964656e746974795820eaa6f8ca4f395d291fdb70af1bd47b804ab82aa17fdbc01b8aaeeb747f7d218c781e726573756c745f696e746572707265746174696f6e5f6964656e74697479582042734d5e73435acc0fdd5a66b97e5bfd94278e64fce2b4890ec609f054dc969e78206576616c756174696f6e5f62617369735f736368656d615f6964656e74697479582020b6239db569aa86ae1c27596b374df90caa5ea41e8e005fd4fe00bfe5c3b38178216170706c69636174696f6e5f62617369735f736368656d615f6964656e7469747958208b294c69120a2e749c56266691b0974e7e0323c198fc42a467fd3790790f791078236f62737472756374696f6e5f696e746572707265746174696f6e5f6964656e746974795820924462071f3992b34c629f4788cc666bd14a87a0b9d0c398feba929ff4dd25f9 diff --git a/crates/warp-core/tests/edict_effect_package_tests.rs b/crates/warp-core/tests/edict_effect_package_tests.rs index dc8ead61..65e770bd 100644 --- a/crates/warp-core/tests/edict_effect_package_tests.rs +++ b/crates/warp-core/tests/edict_effect_package_tests.rs @@ -1712,3 +1712,7 @@ mod derivation; #[cfg(feature = "native_rule_bootstrap")] #[path = "edict_effect_package_tests/proven_ranges.rs"] mod proven_ranges; + +#[cfg(feature = "native_rule_bootstrap")] +#[path = "edict_effect_package_tests/provider_corpus.rs"] +mod provider_corpus; diff --git a/crates/warp-core/tests/edict_effect_package_tests/abi_conformance.rs b/crates/warp-core/tests/edict_effect_package_tests/abi_conformance.rs index 4a39f75f..3bc0b298 100644 --- a/crates/warp-core/tests/edict_effect_package_tests/abi_conformance.rs +++ b/crates/warp-core/tests/edict_effect_package_tests/abi_conformance.rs @@ -234,7 +234,7 @@ fn each_mutation_write_class_is_its_effect_kind() { const READ: &str = "echo.dpo@1.node-atom-read"; -fn rename_read_failure(catalog: &mut V, from: &str, to: &str) { +pub(super) fn rename_read_failure(catalog: &mut V, from: &str, to: &str) { let V::Map(failures) = value_field_mut( value_field_mut(value_field_mut(catalog, "intrinsics"), READ), "effectFailures", diff --git a/crates/warp-core/tests/edict_effect_package_tests/proven_ranges.rs b/crates/warp-core/tests/edict_effect_package_tests/proven_ranges.rs index 8191ca76..b9d01ac2 100644 --- a/crates/warp-core/tests/edict_effect_package_tests/proven_ranges.rs +++ b/crates/warp-core/tests/edict_effect_package_tests/proven_ranges.rs @@ -23,7 +23,7 @@ fn int(value: u64) -> V { ), ]) } -fn declared(id: &str, ty: &str) -> V { +pub(super) fn declared(id: &str, ty: &str) -> V { map([ ("id", text(id)), ("type", text(ty)), @@ -37,10 +37,10 @@ fn input_ref() -> V { ("alphaName", text("$arg0")), ]) } -fn local(reference: &V) -> V { +pub(super) fn local(reference: &V) -> V { map([("kind", text("local")), ("ref", reference.clone())]) } -fn input(name: &str) -> V { +pub(super) fn input(name: &str) -> V { map([ ("kind", text("field")), ("base", local(&input_ref())), @@ -58,10 +58,10 @@ fn call(callee: &str, types: &[&str], args: Vec) -> V { ("args", V::Array(args)), ]) } -fn len(bytes: V) -> V { +pub(super) fn len(bytes: V) -> V { call("core.bytes.length", &[BYTES], vec![bytes]) } -fn prefix_is_utf8(bytes: &str, at: V) -> V { +pub(super) fn prefix_is_utf8(bytes: &str, at: V) -> V { call( "core.bytes.isUtf8", &[BYTES], @@ -75,7 +75,7 @@ fn prefix_is_utf8(bytes: &str, at: V) -> V { fn add(left: V, right: V) -> V { call("core.integer.add", &["U64"], vec![left, right]) } -fn at_most(left: V, right: V) -> V { +pub(super) fn at_most(left: V, right: V) -> V { map([ ("kind", text("compare")), ("op", text("<=")), @@ -104,13 +104,13 @@ fn all(values: Vec) -> V { map([("kind", text("all")), ("values", V::Array(values))]) } -enum Node { +pub(super) enum Node { Let(V, V), Require(V), } /// A pure effect program over `{ text, other: Bytes, at: U64 }`. -fn package(constraints: Vec, nodes: Vec, result: V) -> V { +pub(super) fn package(constraints: Vec, nodes: Vec, result: V) -> V { let mut core = compiled_core(); set( &mut core, @@ -213,10 +213,10 @@ fn package(constraints: Vec, nodes: Vec, result: V) -> V { bound_compiler_package(&core, &target, &compiled_exports(), "update@1") } -fn ok_binding() -> V { +pub(super) fn ok_binding() -> V { declared("local.ok", "Bool") } -fn slice_program(constraints: Vec, bytes: &str) -> V { +pub(super) fn slice_program(constraints: Vec, bytes: &str) -> V { package( constraints, vec![Node::Let(ok_binding(), prefix_is_utf8(bytes, input("at")))], diff --git a/crates/warp-core/tests/edict_effect_package_tests/provider_corpus.rs b/crates/warp-core/tests/edict_effect_package_tests/provider_corpus.rs new file mode 100644 index 00000000..48c64cb0 --- /dev/null +++ b/crates/warp-core/tests/edict_effect_package_tests/provider_corpus.rs @@ -0,0 +1,384 @@ +// SPDX-License-Identifier: Apache-2.0 +// © James Ross Ω FLYING•ROBOTS +//! The authored effect-program verdict corpus Echo's provider lowerer and +//! verifier judge independently of this runtime. +//! +//! Each entry is a whole operation package and the verdict all three +//! judgments must reach. The runtime's own verdict is asserted here; the +//! lowerer and verifier read the same retained bytes in their own tests. +//! Regenerate with the ignored `regenerate_the_retained_provider_corpus` test. +use super::abi_conformance::rename_read_failure; +use super::mutations::{fixture, fixture_with, Shape}; +use super::proven_ranges::{ + at_most, declared, input, len, local, ok_binding, package, prefix_is_utf8, slice_program, Node, +}; +use super::*; + +const GRAPH_EFFECTS: &str = "continuum.profile.graph-effects/v1"; +const READ: &str = "jedit.text@1.readFact"; + +/// What the runtime says when it prepares the package. `None` means the +/// refusal is a static judgment the runtime makes only when it executes. +#[derive(Clone, Copy, PartialEq, Eq)] +enum Runtime { + Accepts, + Refuses, + Executes, +} + +struct Entry { + name: &'static str, + accept: bool, + runtime: Runtime, + package: V, +} + +fn decode(raw: &V) -> V { + let V::Bytes(raw) = raw else { panic!("bytes") }; + echo_edict_canonical::decode_canonical_cbor_v1(raw).expect("canonical") +} + +/// Rebinds a package after editing its compiled Core, Target IR and exports, +/// keeping its lowering artifacts, so a forgery reaches the check it targets. +fn rebuild(package: &V, edit: impl FnOnce(&mut V, &mut V, &mut V)) -> V { + let program = decode(get(package, "program")); + let bundle = decode(get(&program, "compiled_program")); + let mut core = decode(get(&bundle, "core_artifact")); + let mut target = decode(get(&bundle, "target_ir_artifact")); + let mut exports = decode(get(&bundle, "lawpack_exports_artifact")); + edit(&mut core, &mut target, &mut exports); + set( + value_field_mut( + value_field_mut(&mut target, "semanticClosure"), + "sourceCore", + ), + "digest", + V::Array(vec![ + text("sha256"), + artifact_identity("edict.core.module/v1", &core), + ]), + ); + let V::Text(intent) = get(&bundle, "intent") else { + panic!("intent") + }; + let mut rebound = bound_compiler_package(&core, &target, &exports, intent); + let mut program = decode(get(&rebound, "program")); + let mut fresh = compiled_bundle(&core, &target, &exports, intent); + set( + &mut fresh, + "lowering_artifacts", + get(&bundle, "lowering_artifacts").clone(), + ); + set(&mut program, "compiled_program", V::Bytes(encoded(&fresh))); + set(&mut rebound, "program", V::Bytes(encoded(&program))); + rebound +} + +fn first_intent_mut(core: &mut V) -> &mut V { + let V::Map(intents) = value_field_mut(core, "intents") else { + panic!("intents") + }; + &mut intents[0].1 +} + +/// Sets only the declared step budget, in Core and its lowered intent alike. +fn with_budget(package: &V, steps: u64) -> V { + rebuild(package, |core, target, _| { + let steps = V::Integer(i128::from(steps)); + set( + value_field_mut(first_intent_mut(core), "coreEvaluationBudget"), + "maxSteps", + steps.clone(), + ); + set( + value_field_mut(selected_target_mut(target), "coreEvaluationBudget"), + "maxSteps", + steps, + ); + }) +} + +const AMPLE: u64 = 1_000_000; +/// Covers the worst case of reading a 1 MiB fact and scanning it. The +/// captured read program declares 1 MiB of steps, which Echo's providers +/// find too small statically; the runtime meters it during execution. +const READ_AMPLE: u64 = 4_194_304; + +fn proven_slice() -> V { + with_budget( + &slice_program(vec![at_most(input("at"), len(input("text")))], "text"), + AMPLE, + ) +} + +fn read_with_adapter(edit: impl FnOnce(&mut V), catalog: V) -> V { + let mut adapter = catalog_named_adapter(&captured_adapter()); + edit(value_field_mut( + value_field_mut(value_field_mut(&mut adapter, "effectImplementations"), READ), + "failureMappings", + )); + with_budget( + &publication_for_lowering(&lowering_fixture_inputs(Some(catalog), None, Some(adapter))), + READ_AMPLE, + ) +} + +fn entries() -> Vec { + let read_capture = publication_for_lowering(&repinned_lowering_artifacts()); + let read_control = with_budget(&read_capture, READ_AMPLE); + let mut wrong_input = Shape::conforming("ensure-node"); + wrong_input.fields[1] = ("nodeId", "Bytes"); + let mut tag_spelled = catalog_fixture(); + for (tag, name) in READ_FAILURE_NAMES { + rename_read_failure(&mut tag_spelled, name, tag); + } + let mut unknown = catalog_fixture(); + rename_read_failure(&mut unknown, "atomMissing", "atomAbsent"); + let entry = |name, accept, runtime, package| Entry { + name, + accept, + runtime, + package, + }; + vec![ + entry("read-control", true, Runtime::Accepts, read_control.clone()), + entry( + "ensure-node-control", + true, + Runtime::Accepts, + fixture("ensure-node", GRAPH_EFFECTS).0, + ), + entry("slice-proven", true, Runtime::Accepts, proven_slice()), + entry( + "slice-unproven", + false, + Runtime::Refuses, + with_budget(&slice_program(Vec::new(), "text"), AMPLE), + ), + entry( + "slice-other-operand", + false, + Runtime::Refuses, + with_budget( + &slice_program(vec![at_most(input("at"), len(input("other")))], "text"), + AMPLE, + ), + ), + entry( + "slice-require-only", + false, + Runtime::Refuses, + with_budget( + &package( + Vec::new(), + vec![ + Node::Require(at_most(input("at"), len(input("text")))), + Node::Let(ok_binding(), prefix_is_utf8("text", input("at"))), + ], + local(&ok_binding()), + ), + AMPLE, + ), + ), + entry( + "forged-node-order", + false, + Runtime::Refuses, + rebuild( + &with_budget( + &package( + vec![at_most(input("at"), len(input("text")))], + vec![ + Node::Let(declared("local.size", "U64"), len(input("text"))), + Node::Let(ok_binding(), prefix_is_utf8("text", input("at"))), + ], + local(&ok_binding()), + ), + AMPLE, + ), + |_, target, _| { + let V::Array(order) = + value_field_mut(selected_target_mut(target), "executionOrder") + else { + panic!("order") + }; + order.swap(0, 1); + }, + ), + ), + entry( + "wrong-intrinsic-input-type", + false, + Runtime::Refuses, + fixture_with("ensure-node", GRAPH_EFFECTS, &wrong_input).0, + ), + entry( + "undeclared-obstruction", + false, + Runtime::Refuses, + rebuild(&read_control, |_, _, exports| { + let V::Array(obstructions) = value_field_mut(exports, "obstructions") else { + panic!("obstructions") + }; + obstructions.remove(0); + }), + ), + entry( + "failure-mapping-tag-spelled", + false, + Runtime::Refuses, + with_budget( + &publication_for_lowering(&lowering_fixture_inputs( + Some(tag_spelled), + None, + Some(captured_adapter()), + )), + READ_AMPLE, + ), + ), + entry( + "failure-mapping-unknown", + false, + Runtime::Refuses, + read_with_adapter( + |mappings| { + let V::Map(mappings) = mappings else { + panic!("mappings") + }; + for (_, target) in mappings.iter_mut() { + if target == &text("atomMissing") { + *target = text("atomAbsent"); + } + } + }, + unknown, + ), + ), + entry( + "failure-mapping-duplicate", + false, + Runtime::Refuses, + read_with_adapter( + |mappings| { + let V::Map(mappings) = mappings else { + panic!("mappings") + }; + for (_, target) in mappings.iter_mut() { + if target == &text("atomRequired") { + *target = text("atomMissing"); + } + } + }, + catalog_fixture(), + ), + ), + entry( + "over-budget", + false, + Runtime::Executes, + with_budget(&proven_slice(), 1), + ), + entry( + "read-captured-budget", + false, + Runtime::Executes, + read_capture, + ), + ] +} + +/// The retained corpus bytes, embedded so the check reads no files. +macro_rules! retained { + ($($name:literal),* $(,)?) => { + &[$(( + $name, + include_str!(concat!( + "../../../echo-edict-provider-lowerer/tests/fixtures/effect-programs/", + $name, + ".hex" + )), + )),*] + }; +} +const RETAINED: &[(&str, &str)] = retained![ + "read-control", + "ensure-node-control", + "slice-proven", + "slice-unproven", + "slice-other-operand", + "slice-require-only", + "forged-node-order", + "wrong-intrinsic-input-type", + "undeclared-obstruction", + "failure-mapping-tag-spelled", + "failure-mapping-unknown", + "failure-mapping-duplicate", + "over-budget", + "read-captured-budget", +]; +const VERDICTS: &str = include_str!( + "../../../echo-edict-provider-lowerer/tests/fixtures/effect-programs/verdicts.txt" +); + +fn manifest(entries: &[Entry]) -> String { + let mut manifest = String::new(); + for entry in entries { + manifest.push_str(entry.name); + manifest.push_str(if entry.accept { + " accept\n" + } else { + " refuse\n" + }); + } + manifest +} + +#[test] +fn the_retained_provider_corpus_matches_the_runtime_verdicts() { + let entries = entries(); + assert_eq!( + entries.iter().map(|entry| entry.name).collect::>(), + RETAINED.iter().map(|(name, _)| *name).collect::>(), + "every corpus entry is retained, in order" + ); + assert_eq!(VERDICTS, manifest(&entries), "verdict manifest drifted"); + for (entry, (_, retained)) in entries.iter().zip(RETAINED) { + let prepared = prepare(&entry.package); + match entry.runtime { + Runtime::Accepts => { + prepared.unwrap_or_else(|e| panic!("{}: runtime refused: {e:?}", entry.name)); + } + Runtime::Refuses => assert!(prepared.is_err(), "{}: runtime accepted", entry.name), + // The static budget is a provider judgment; the runtime meters it + // during execution instead. + Runtime::Executes => { + prepared.unwrap_or_else(|e| panic!("{}: runtime refused: {e:?}", entry.name)); + } + } + assert_eq!( + retained.trim(), + hex::encode(encoded(&entry.package)), + "{}: retained bytes drifted; run the ignored regeneration test", + entry.name + ); + } +} + +/// Rewrites the retained corpus. Run explicitly after changing an entry: +/// `cargo test ... regenerate_the_retained_provider_corpus -- --ignored`. +#[test] +#[ignore = "explicit fixture regeneration only"] +fn regenerate_the_retained_provider_corpus() { + let entries = entries(); + let dir = std::path::Path::new(env!("CARGO_MANIFEST_DIR")) + .join("../echo-edict-provider-lowerer/tests/fixtures/effect-programs"); + std::fs::create_dir_all(&dir).expect("corpus directory"); + for entry in &entries { + std::fs::write( + dir.join(format!("{}.hex", entry.name)), + format!("{}\n", hex::encode(encoded(&entry.package))), + ) + .expect("corpus entry"); + } + std::fs::write(dir.join("verdicts.txt"), manifest(&entries)).expect("manifest"); +} diff --git a/crates/warp-core/tests/fixtures/current-effect-publication/package.hex b/crates/warp-core/tests/fixtures/current-effect-publication/package.hex index 07298284..9c359ae2 100644 --- a/crates/warp-core/tests/fixtures/current-effect-publication/package.hex +++ b/crates/warp-core/tests/fixtures/current-effect-publication/package.hex @@ -1 +1 @@ -b166736368656d6178196563686f2e6f7065726174696f6e2d7061636b6167652f76316770726f6772616d5907c4ad646b696e647765646963742d6566666563742d70726f6772616d2f763166736368656d6178196563686f2e6f7065726174696f6e2d70726f6772616d2f76316b6f75747075745f747970656a6170702e526573756c746c67726170685f736368656d615876a26a656467655f7479706573a06a6e6f64655f7479706573a158200101010101010101010101010101010101010101010101010101010101010101a26a61646472657373696e67016a61746f6d5f747970657381582002020202020202020202020202020202020202020202020202020202020202026c6964656e746974795f6c6177016d666f6f747072696e745f6c617758f6a9696d61785f7265616473016a61746f6d5f747970657381582002020202020202020202020202020202020202020202020202020202020202026a6d61785f777269746573016f6d61785f72616e67655f6564676573006f726561645f6e6f64655f747970657381582001010101010101010101010101010101010101010101010101010101010101017072616e67655f656467655f7479706573807077726974655f656467655f7479706573807077726974655f6e6f64655f7479706573815820010101010101010101010101010101010101010101010101010101010101010172706f7274616c5f6f776e65725f7479706573806f6d61785f696e7075745f62797465731a0001000070636f6d70696c65645f70726f6772616d5904c9a666696e74656e7468757064617465403166736368656d6178286563686f2e636f6d70696c65722d70726f64756365642d6566666563742d70726f6772616d2f76316d636f72655f6172746966616374590194a6657479706573a166526573756c74a1646b696e646355333267696d706f7274738067696e74656e7473a1687570646174654031a664626f6479a3656e6f64657380666c6f63616c7381a3626964656172672e3064747970656355333269616c7068614e616d6565246172673066726573756c74a2646b696e6465636f6e73746576616c7565a3646b696e6463696e746576616c7565182a6577696474686355333265696e70757463553332666f75747075746a6170702e526573756c7470696e707574436f6e73747261696e74738074636f72654576616c756174696f6e427564676574a3686d61785374657073016e6d61784f757470757442797465731a00010000716d6178416c6c6f636174656442797465731a01000000781872657175697265644f7065726174696f6e50726f66696c65781a636f6e74696e75756d2e70726f66696c652e746f74616c2f76316a61706956657273696f6e6d65646963742e636f72652f76316a636f6f7264696e6174656361707078187265717569726564436f72654361706162696c697469657380726c6f776572696e675f617274696661637473f6727461726765745f69725f6172746966616374590200a6646b696e64776f7264657265645461726765744972417274696661637466646f6d61696e6f6563686f2e7370616e2d69722f763267696e74656e7473a1687570646174654031a86573746570738066726573756c74a2646b696e6465636f6e73746576616c7565a3646b696e6463696e746576616c7565182a657769647468635533326c7075726542696e64696e6773806c726571756972656d656e7473806e657865637574696f6e4f726465728070696e707574436f6e73747261696e747380706f7065726174696f6e50726f66696c65781a636f6e74696e75756d2e70726f66696c652e746f74616c2f763174636f72654576616c756174696f6e427564676574a3686d61785374657073016e6d61784f757470757442797465731a00010000716d6178416c6c6f636174656442797465731a010000006d74617267657450726f66696c65a26269646a6563686f2e64706f4031666469676573748266736861323536582006060606060606060606060606060606060606060606060606060606060606066f73656d616e746963436c6f73757265a2686c61777061636b73806a736f75726365436f7265a262696463617070666469676573748266736861323536582017e17862979412ae3477593727e6d5ec05ee50fe255fc02acdfc5777b9ac744d74736f75726365436f7265436f6f7264696e6174656361707078186c61777061636b5f6578706f7274735f6172746966616374589ca66574797065738067656666656374738069636f6e7374616e7473806c6f62737472756374696f6e7381a36a636f6f7264696e6174656b6170702e5265667573616c6d7061796c6f6164536368656d61736170702e5265667573616c2e5061796c6f61646e617574686f72697479436c61737366646f6d61696e6d7075726546756e6374696f6e7380716f7065726174696f6e50726f66696c6573a0706d61785f726573756c745f62797465731a00010000727461726765745f69725f6964656e746974795820d9374cd2aaabfab6f1d5ca0b5298687a8b9c12a19362f982b8401eb0381f6db0736d61785f616c6c6f63617465645f62797465731a01000000781a696e7472696e7369635f70726f66696c655f6964656e746974795820a0fc1b7a1e186598291754469fd6ea2220f676358284f7b84c7e2476901a3151781c696e7465727072657465725f70726f66696c655f6964656e746974795820eaa6f8ca4f395d291fdb70af1bd47b804ab82aa17fdbc01b8aaeeb747f7d218c6e6275646765745f6365696c696e67a36573746570730a6a726561645f62797465731910006b77726974655f62797465731910007073656d616e7469635f636c6f73757265a66d636f72655f6964656e74697479582017e17862979412ae3477593727e6d5ec05ee50fe255fc02acdfc5777b9ac744d727461726765745f69725f6964656e746974795820d9374cd2aaabfab6f1d5ca0b5298687a8b9c12a19362f982b8401eb0381f6db07565646963745f736f757263655f6964656e746974795820fdf14fbb05ba25e820cd4a23b594e6648429940f7aed5218077eef841288114c781a63616e6f6e6963616c5f6d65616e696e675f6964656e74697479582017e17862979412ae3477593727e6d5ec05ee50fe255fc02acdfc5777b9ac744d781b6170706c69636174696f6e5f736368656d615f6964656e74697479582017ff6f37fcc8b1f81e58cc3ef5c0d94a4c3f96fb955bfb9cae7ff0bac29cb249781d6170706c69636174696f6e5f736368656d615f636f6f7264696e6174656b6170702e4578706f727473746f7065726174696f6e5f636f6f7264696e6174656c6170702e757064617465403175696e7075745f736368656d615f6964656e746974795820d277705b5ab03fcb58590bad62fb8058e075c3b4c65efc21282bb531aa22b3ad76726573756c745f736368656d615f6964656e746974795820de5c0c4f0c640354c40bb4f9d4886cd820353a548caea4953269eba15fe902bc777461726765745f70726f66696c655f6964656e746974795820eaca21c05664241efd1e1c5b5636c7132fe8854f6bcaddb2fd4f014e1bd4a479781a617574686f726974795f70726f66696c655f6964656e7469747958208eca01fcc45de0eb065bfd04fb21d2c7881c346ca07dfc1536df5ca2fe0812dc781a696e7472696e7369635f70726f66696c655f6964656e746974795820a0fc1b7a1e186598291754469fd6ea2220f676358284f7b84c7e2476901a3151781b666f6f747072696e745f636f6e74726163745f6964656e746974795820362b20fb18488ce180f6c1096b5189994354604fd1b1b126a3ea4ef839e5232b781b6f62737472756374696f6e5f736368656d615f6964656e746974795820b1f96fdf3ec65e84d500702951393a931b4fdd843ad02723ea3725f90a671418781c696e7465727072657465725f70726f66696c655f6964656e746974795820eaa6f8ca4f395d291fdb70af1bd47b804ab82aa17fdbc01b8aaeeb747f7d218c781e726573756c745f696e746572707265746174696f6e5f6964656e74697479582042734d5e73435acc0fdd5a66b97e5bfd94278e64fce2b4890ec609f054dc969e78206576616c756174696f6e5f62617369735f736368656d615f6964656e74697479582020b6239db569aa86ae1c27596b374df90caa5ea41e8e005fd4fe00bfe5c3b38178216170706c69636174696f6e5f62617369735f736368656d615f6964656e7469747958208b294c69120a2e749c56266691b0974e7e0323c198fc42a467fd3790790f791078236f62737472756374696f6e5f696e746572707265746174696f6e5f6964656e746974795820924462071f3992b34c629f4788cc666bd14a87a0b9d0c398feba929ff4dd25f9 +b166736368656d6178196563686f2e6f7065726174696f6e2d7061636b6167652f76316770726f6772616d5907c8ad646b696e647765646963742d6566666563742d70726f6772616d2f763166736368656d6178196563686f2e6f7065726174696f6e2d70726f6772616d2f76316b6f75747075745f747970656a6170702e526573756c746c67726170685f736368656d615876a26a656467655f7479706573a06a6e6f64655f7479706573a158200101010101010101010101010101010101010101010101010101010101010101a26a61646472657373696e67016a61746f6d5f747970657381582002020202020202020202020202020202020202020202020202020202020202026c6964656e746974795f6c6177016d666f6f747072696e745f6c617758f6a9696d61785f7265616473016a61746f6d5f747970657381582002020202020202020202020202020202020202020202020202020202020202026a6d61785f777269746573016f6d61785f72616e67655f6564676573006f726561645f6e6f64655f747970657381582001010101010101010101010101010101010101010101010101010101010101017072616e67655f656467655f7479706573807077726974655f656467655f7479706573807077726974655f6e6f64655f7479706573815820010101010101010101010101010101010101010101010101010101010101010172706f7274616c5f6f776e65725f7479706573806f6d61785f696e7075745f62797465731a0001000070636f6d70696c65645f70726f6772616d5904cda666696e74656e7468757064617465403166736368656d6178286563686f2e636f6d70696c65722d70726f64756365642d6566666563742d70726f6772616d2f76316d636f72655f6172746966616374590196a6657479706573a166526573756c74a1646b696e646355333267696d706f7274738067696e74656e7473a1687570646174654031a664626f6479a3656e6f64657380666c6f63616c7381a3626964656172672e3064747970656355333269616c7068614e616d6565246172673066726573756c74a2646b696e6465636f6e73746576616c7565a3646b696e6463696e746576616c7565182a6577696474686355333265696e70757463553332666f75747075746a6170702e526573756c7470696e707574436f6e73747261696e74738074636f72654576616c756174696f6e427564676574a3686d617853746570731904006e6d61784f757470757442797465731a00010000716d6178416c6c6f636174656442797465731a01000000781872657175697265644f7065726174696f6e50726f66696c65781a636f6e74696e75756d2e70726f66696c652e746f74616c2f76316a61706956657273696f6e6d65646963742e636f72652f76316a636f6f7264696e6174656361707078187265717569726564436f72654361706162696c697469657380726c6f776572696e675f617274696661637473f6727461726765745f69725f6172746966616374590202a6646b696e64776f7264657265645461726765744972417274696661637466646f6d61696e6f6563686f2e7370616e2d69722f763267696e74656e7473a1687570646174654031a86573746570738066726573756c74a2646b696e6465636f6e73746576616c7565a3646b696e6463696e746576616c7565182a657769647468635533326c7075726542696e64696e6773806c726571756972656d656e7473806e657865637574696f6e4f726465728070696e707574436f6e73747261696e747380706f7065726174696f6e50726f66696c65781a636f6e74696e75756d2e70726f66696c652e746f74616c2f763174636f72654576616c756174696f6e427564676574a3686d617853746570731904006e6d61784f757470757442797465731a00010000716d6178416c6c6f636174656442797465731a010000006d74617267657450726f66696c65a26269646a6563686f2e64706f4031666469676573748266736861323536582006060606060606060606060606060606060606060606060606060606060606066f73656d616e746963436c6f73757265a2686c61777061636b73806a736f75726365436f7265a2626964636170706664696765737482667368613235365820e003c45d1967ce94fd454df03168536c81829a4247e2172412045f2a98528bd474736f75726365436f7265436f6f7264696e6174656361707078186c61777061636b5f6578706f7274735f6172746966616374589ca66574797065738067656666656374738069636f6e7374616e7473806c6f62737472756374696f6e7381a36a636f6f7264696e6174656b6170702e5265667573616c6d7061796c6f6164536368656d61736170702e5265667573616c2e5061796c6f61646e617574686f72697479436c61737366646f6d61696e6d7075726546756e6374696f6e7380716f7065726174696f6e50726f66696c6573a0706d61785f726573756c745f62797465731a00010000727461726765745f69725f6964656e746974795820b52c5d34cdeff1c9c6052a2d59ac6d7b0f20dcb00ed33739a71d8ac0bff59b97736d61785f616c6c6f63617465645f62797465731a01000000781a696e7472696e7369635f70726f66696c655f6964656e746974795820a0fc1b7a1e186598291754469fd6ea2220f676358284f7b84c7e2476901a3151781c696e7465727072657465725f70726f66696c655f6964656e746974795820eaa6f8ca4f395d291fdb70af1bd47b804ab82aa17fdbc01b8aaeeb747f7d218c6e6275646765745f6365696c696e67a36573746570730a6a726561645f62797465731910006b77726974655f62797465731910007073656d616e7469635f636c6f73757265a66d636f72655f6964656e746974795820e003c45d1967ce94fd454df03168536c81829a4247e2172412045f2a98528bd4727461726765745f69725f6964656e746974795820b52c5d34cdeff1c9c6052a2d59ac6d7b0f20dcb00ed33739a71d8ac0bff59b977565646963745f736f757263655f6964656e746974795820fdf14fbb05ba25e820cd4a23b594e6648429940f7aed5218077eef841288114c781a63616e6f6e6963616c5f6d65616e696e675f6964656e746974795820e003c45d1967ce94fd454df03168536c81829a4247e2172412045f2a98528bd4781b6170706c69636174696f6e5f736368656d615f6964656e74697479582017ff6f37fcc8b1f81e58cc3ef5c0d94a4c3f96fb955bfb9cae7ff0bac29cb249781d6170706c69636174696f6e5f736368656d615f636f6f7264696e6174656b6170702e4578706f727473746f7065726174696f6e5f636f6f7264696e6174656c6170702e757064617465403175696e7075745f736368656d615f6964656e746974795820d277705b5ab03fcb58590bad62fb8058e075c3b4c65efc21282bb531aa22b3ad76726573756c745f736368656d615f6964656e746974795820de5c0c4f0c640354c40bb4f9d4886cd820353a548caea4953269eba15fe902bc777461726765745f70726f66696c655f6964656e746974795820eaca21c05664241efd1e1c5b5636c7132fe8854f6bcaddb2fd4f014e1bd4a479781a617574686f726974795f70726f66696c655f6964656e7469747958208eca01fcc45de0eb065bfd04fb21d2c7881c346ca07dfc1536df5ca2fe0812dc781a696e7472696e7369635f70726f66696c655f6964656e746974795820a0fc1b7a1e186598291754469fd6ea2220f676358284f7b84c7e2476901a3151781b666f6f747072696e745f636f6e74726163745f6964656e746974795820362b20fb18488ce180f6c1096b5189994354604fd1b1b126a3ea4ef839e5232b781b6f62737472756374696f6e5f736368656d615f6964656e746974795820b1f96fdf3ec65e84d500702951393a931b4fdd843ad02723ea3725f90a671418781c696e7465727072657465725f70726f66696c655f6964656e746974795820eaa6f8ca4f395d291fdb70af1bd47b804ab82aa17fdbc01b8aaeeb747f7d218c781e726573756c745f696e746572707265746174696f6e5f6964656e74697479582042734d5e73435acc0fdd5a66b97e5bfd94278e64fce2b4890ec609f054dc969e78206576616c756174696f6e5f62617369735f736368656d615f6964656e74697479582020b6239db569aa86ae1c27596b374df90caa5ea41e8e005fd4fe00bfe5c3b38178216170706c69636174696f6e5f62617369735f736368656d615f6964656e7469747958208b294c69120a2e749c56266691b0974e7e0323c198fc42a467fd3790790f791078236f62737472756374696f6e5f696e746572707265746174696f6e5f6964656e746974795820924462071f3992b34c629f4788cc666bd14a87a0b9d0c398feba929ff4dd25f9 diff --git a/docs/topics/GeneratedRules.md b/docs/topics/GeneratedRules.md index 25a27490..664c3e0c 100644 --- a/docs/topics/GeneratedRules.md +++ b/docs/topics/GeneratedRules.md @@ -233,6 +233,24 @@ literals, sums or a constraint such as `at <= 10`. Earlier conjuncts of one its guard ends evaluation on failure but is not a dominating fact. A guard on another operand or offset proves nothing. +The provider lowerer and verifier each judge an authored effect program +themselves, sharing no code with the runtime or each other. Each establishes +the program's binding to its own Core, Target IR and exports; the pinned +lawpack, adapter, target profile and intrinsic catalog that authorize each +effect; each effect's runtime ABI, write class and failure contract through +the intrinsic-scoped failure table; one declared obstruction per failure arm +with a matching authority class; node-for-node Core and Target IR +correspondence; and the body's types, proven ranges and declared budget under +its own cost model. The lowerer runs this judgment before it serializes an +effect publication, and the verifier runs it, then binds every identity the +package claims to the program it carries, before installation. Both reach the +runtime's verdict on a retained corpus of accepted programs and forgeries that +warp-core generates and pins. Their cost models are stricter than the runtime's +meter: a program whose declared step budget cannot cover its worst case, such +as the captured node-atom read's 1 MiB budget for a 1 MiB read and scan, is +refused before installation, where the runtime would refuse it only when it +executes. + The retained public compiler fixtures cover a legacy-producer execution control and a strict SourceFunctions publication containing an authored arithmetic helper. The accepted public verifier report binds the unmodified package bytes; repeated