diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7a60bfe4..7df04cf7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -194,7 +194,7 @@ jobs: cargo clippy -p warp-core --features host_test --test causal_wal_hardening_tests -- -D warnings -D missing_docs - name: cargo clippy (compiler-produced pure evaluation) - run: cargo clippy -p warp-core --features trusted_runtime --lib --test edict_pure_evaluation_tests --test edict_pure_unsigned_subtraction_tests --test edict_pure_byte_length_tests --test edict_byte_equality_tests --test edict_byte_slice_tests --test edict_node_read_tests --test edict_byte_concat_tests --test edict_byte_literal_tests --test edict_source_functions_tests -- -D warnings -D missing_docs + run: cargo clippy -p warp-core --features trusted_runtime --lib --test edict_pure_evaluation_tests --test edict_pure_predicates_tests --test edict_pure_unsigned_subtraction_tests --test edict_pure_byte_length_tests --test edict_byte_equality_tests --test edict_byte_slice_tests --test edict_node_read_tests --test edict_byte_concat_tests --test edict_byte_literal_tests --test edict_source_functions_tests -- -D warnings -D missing_docs clippy-det-fixed: name: Clippy (det_fixed) @@ -382,7 +382,7 @@ jobs: cargo test -p warp-core --features host_test --test causal_wal_hardening_tests - name: cargo test (compiler-produced pure evaluation) run: | - cargo test -p warp-core --features trusted_runtime --test edict_pure_evaluation_tests --test edict_pure_unsigned_subtraction_tests --test edict_pure_byte_length_tests --test edict_byte_equality_tests --test edict_byte_slice_tests --test edict_node_read_tests --test edict_byte_concat_tests --test edict_byte_literal_tests --test edict_source_functions_tests + cargo test -p warp-core --features trusted_runtime --test edict_pure_evaluation_tests --test edict_pure_predicates_tests --test edict_pure_unsigned_subtraction_tests --test edict_pure_byte_length_tests --test edict_byte_equality_tests --test edict_byte_slice_tests --test edict_node_read_tests --test edict_byte_concat_tests --test edict_byte_literal_tests --test edict_source_functions_tests cargo test -p warp-core --features trusted_runtime --lib edict_pure:: - name: cargo test (delta validation and the canonical delta merge) run: | diff --git a/CHANGELOG.md b/CHANGELOG.md index 53049ac4..4b43290a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ ## Unreleased +### Fixed + +- Pure evaluation accepts compiler-produced conjunctive input guards instead of + rejecting their `all` predicate shape as an invalid artifact. Conjunctions + retain deterministic short-circuit metering and combined traversal limits. + ### Removed - The `echo-trace` and `echo-graph` crates. Nothing in the workspace used diff --git a/crates/warp-core/Cargo.toml b/crates/warp-core/Cargo.toml index b2b67ba1..4c2072ff 100644 --- a/crates/warp-core/Cargo.toml +++ b/crates/warp-core/Cargo.toml @@ -132,6 +132,10 @@ required-features = ["native_rule_bootstrap", "trusted_runtime"] name = "edict_pure_evaluation_tests" required-features = ["trusted_runtime"] +[[test]] +name = "edict_pure_predicates_tests" +required-features = ["trusted_runtime"] + [[test]] name = "edict_byte_literal_tests" required-features = ["trusted_runtime"] diff --git a/crates/warp-core/src/edict_pure.rs b/crates/warp-core/src/edict_pure.rs index 8c826bdb..82995a4e 100644 --- a/crates/warp-core/src/edict_pure.rs +++ b/crates/warp-core/src/edict_pure.rs @@ -93,3 +93,6 @@ pub fn evaluate( let input = decode_canonical_cbor_v1(input_bytes).map_err(|_| EvaluationError::InvalidInput)?; evaluate::run(&program, input) } + +#[cfg(test)] +mod predicate_tests; diff --git a/crates/warp-core/src/edict_pure/evaluate.rs b/crates/warp-core/src/edict_pure/evaluate.rs index 6f0e6329..38e00849 100644 --- a/crates/warp-core/src/edict_pure/evaluate.rs +++ b/crates/warp-core/src/edict_pure/evaluate.rs @@ -345,9 +345,20 @@ pub(crate) fn predicate( depth: usize, ) -> Result { meter.step(depth)?; - let left = expression(&predicate.left, locals, helpers, meter, depth + 1)?; - let right = expression(&predicate.right, locals, helpers, meter, depth + 1)?; - match (&predicate.op, left, right) { + let (op, left, right) = match predicate { + Predicate::Compare { op, left, right } => (op, left, right), + Predicate::All(values) => { + for value in values { + if !self::predicate(value, locals, helpers, meter, depth + 1)? { + return Ok(false); + } + } + return Ok(true); + } + }; + let left = expression(left, locals, helpers, meter, depth + 1)?; + let right = expression(right, locals, helpers, meter, depth + 1)?; + match (op, left, right) { (Comparison::Equal, Value::Integer(left), Value::Integer(right)) => Ok(left == right), (Comparison::LessOrEqual, Value::Integer(left), Value::Integer(right)) => Ok(left <= right), (Comparison::Equal, Value::Bytes(left), Value::Bytes(right)) => { diff --git a/crates/warp-core/src/edict_pure/functions.rs b/crates/warp-core/src/edict_pure/functions.rs index a429ffa0..f95169d7 100644 --- a/crates/warp-core/src/edict_pure/functions.rs +++ b/crates/warp-core/src/edict_pure/functions.rs @@ -601,10 +601,20 @@ impl Heights<'_> { } fn predicate(&mut self, predicate: &Predicate, depth: usize) -> Result { self.enter(depth)?; - let height = self - .expr(&predicate.left, depth + 1)? - .max(self.expr(&predicate.right, depth + 1)?) - + 1; + let height = match predicate { + Predicate::Compare { left, right, .. } => { + self.expr(left, depth + 1)? + .max(self.expr(right, depth + 1)?) + + 1 + } + Predicate::All(values) => { + let mut maximum = 0; + for value in values { + maximum = maximum.max(self.predicate(value, depth + 1)?); + } + maximum + 1 + } + }; if depth + height > MAX_DEPTH { return Err(Error::UnsupportedProgram); } diff --git a/crates/warp-core/src/edict_pure/model.rs b/crates/warp-core/src/edict_pure/model.rs index 04a40b19..f52e5474 100644 --- a/crates/warp-core/src/edict_pure/model.rs +++ b/crates/warp-core/src/edict_pure/model.rs @@ -46,10 +46,13 @@ pub(crate) enum Expr { } #[derive(Debug, PartialEq, Eq)] -pub(crate) struct Predicate { - pub op: Comparison, - pub left: Expr, - pub right: Expr, +pub(crate) enum Predicate { + Compare { + op: Comparison, + left: Expr, + right: Expr, + }, + All(Vec), } #[derive(Debug, PartialEq, Eq)] diff --git a/crates/warp-core/src/edict_pure/predicate_tests.rs b/crates/warp-core/src/edict_pure/predicate_tests.rs new file mode 100644 index 00000000..c419e046 --- /dev/null +++ b/crates/warp-core/src/edict_pure/predicate_tests.rs @@ -0,0 +1,158 @@ +// SPDX-License-Identifier: Apache-2.0 +// © James Ross Ω FLYING•ROBOTS +//! Closed predicate decoding, metering and combined traversal boundaries. +use super::{ + evaluate::{predicate, Meter}, + functions::check_roots, + model::{Comparison, Expr, Predicate, MAX_PROGRAM_NODES}, + syntax::Parser, + EvaluationError as Error, EvaluationLimits, +}; +use echo_edict_canonical::CanonicalValueV1 as Value; +use std::collections::BTreeMap; +fn limits(steps: u64) -> EvaluationLimits { + EvaluationLimits { + max_package_bytes: 32768, + max_input_bytes: 4194304, + max_steps: steps, + max_allocated_bytes: 16777216, + max_output_bytes: 4194304, + } +} +fn compare(left: i128, right: i128) -> Predicate { + Predicate::Compare { + op: Comparison::Equal, + left: Expr::Constant(Value::Integer(left)), + right: Expr::Constant(Value::Integer(right)), + } +} +fn map(fields: impl IntoIterator) -> Value { + Value::Map( + fields + .into_iter() + .map(|(key, value)| (Value::Text(key.into()), value)) + .collect(), + ) +} +fn all(values: Vec) -> Value { + map([ + ("kind", Value::Text("all".into())), + ("values", Value::Array(values)), + ]) +} +fn wire_compare(left: i128, right: i128) -> Value { + let constant = |value| { + map([ + ("kind", Value::Text("const".into())), + ( + "value", + map([ + ("kind", Value::Text("int".into())), + ("width", Value::Text("U64".into())), + ("value", Value::Integer(value)), + ]), + ), + ]) + }; + map([ + ("kind", Value::Text("compare".into())), + ("op", Value::Text("==".into())), + ("left", constant(left)), + ("right", constant(right)), + ]) +} +fn parse(value: &Value, remaining: usize) -> Result { + Parser { + types: &Value::Map(vec![]), + coordinate: "generic.predicates@1", + remaining, + } + .predicate(value, 0) +} +#[test] +fn conjunction_truth_and_exact_short_circuit_metering() -> Result<(), Error> { + // Compare charges one predicate step plus expression/copy steps for each constant. + for (values, expected, steps) in [ + (vec![compare(1, 1)], true, 6), + (vec![compare(1, 1), compare(2, 2)], true, 11), + (vec![compare(1, 2), compare(2, 2)], false, 6), + (vec![compare(1, 1), compare(2, 3)], false, 11), + ( + vec![Predicate::All(vec![compare(1, 1)]), compare(1, 1)], + true, + 12, + ), + ] { + let value = Predicate::All(values); + let mut meter = Meter::new(limits(steps)); + assert_eq!( + predicate(&value, &BTreeMap::new(), &BTreeMap::new(), &mut meter, 0)?, + expected + ); + assert_eq!(meter.usage().0, steps); + let mut too_small = Meter::new(limits(steps - 1)); + assert_eq!( + predicate( + &value, + &BTreeMap::new(), + &BTreeMap::new(), + &mut too_small, + 0 + ), + Err(Error::StepBudgetExceeded) + ); + } + Ok(()) +} +#[test] +fn conjunction_decoder_checks_closed_shape_and_all_children() { + let empty = all(vec![]); + assert_eq!( + parse(&empty, MAX_PROGRAM_NODES), + Err(Error::InvalidArtifact) + ); + for value in [ + map([("kind", Value::Text("all".into()))]), + map([ + ("kind", Value::Text("all".into())), + ("values", Value::Integer(0)), + ]), + map([ + ("kind", Value::Text("all".into())), + ("values", Value::Array(vec![])), + ("extra", Value::Integer(0)), + ]), + ] { + assert_eq!( + parse(&value, MAX_PROGRAM_NODES), + Err(Error::InvalidArtifact) + ); + } + let unknown = map([("kind", Value::Text("unsupported".into()))]); + assert_eq!( + parse(&all(vec![wire_compare(1, 2), unknown]), MAX_PROGRAM_NODES), + Err(Error::InvalidArtifact) + ); +} +#[test] +fn conjunction_decoder_and_combined_depth_refuse_exact_boundary_overruns() { + assert_eq!( + parse(&all(vec![wire_compare(1, 1)]), 1), + Err(Error::UnsupportedProgram) + ); + for (wrappers, accepted) in [(63, true), (64, false), (65, false)] { + let mut value = wire_compare(1, 1); + for _ in 0..wrappers { + value = all(vec![value]); + } + let result = parse(&value, MAX_PROGRAM_NODES).and_then(|value| { + check_roots(&BTreeMap::new(), [], [&value])?; + Ok(value) + }); + if accepted { + assert!(result.is_ok()); + } else { + assert_eq!(result, Err(Error::UnsupportedProgram)); + } + } +} diff --git a/crates/warp-core/src/edict_pure/syntax.rs b/crates/warp-core/src/edict_pure/syntax.rs index 999d74c8..f6c4dccb 100644 --- a/crates/warp-core/src/edict_pure/syntax.rs +++ b/crates/warp-core/src/edict_pure/syntax.rs @@ -198,6 +198,22 @@ impl Parser<'_> { pub fn predicate(&mut self, value: &Value, depth: usize) -> Result { self.enter(depth)?; + if text_field(value, "kind")? == "all" { + exact_fields(value, &["kind", "values"])?; + let values = array(field(value, "values")?)?; + if values.is_empty() { + return Err(Error::InvalidArtifact); + } + if values.len() > self.remaining { + return Err(Error::UnsupportedProgram); + } + return Ok(Predicate::All( + values + .iter() + .map(|value| self.predicate(value, depth + 1)) + .collect::, _>>()?, + )); + } exact_fields(value, &["kind", "op", "left", "right"])?; if text_field(value, "kind")? != "compare" { return Err(Error::UnsupportedProgram); @@ -207,7 +223,7 @@ impl Parser<'_> { "<=" => Comparison::LessOrEqual, _ => return Err(Error::UnsupportedProgram), }; - Ok(Predicate { + Ok(Predicate::Compare { op, left: self.expr(field(value, "left")?, depth + 1)?, right: self.expr(field(value, "right")?, depth + 1)?, diff --git a/crates/warp-core/tests/edict_pure_predicates_tests.rs b/crates/warp-core/tests/edict_pure_predicates_tests.rs new file mode 100644 index 00000000..543cf5e1 --- /dev/null +++ b/crates/warp-core/tests/edict_pure_predicates_tests.rs @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: Apache-2.0 +// © James Ross Ω FLYING•ROBOTS +//! A real public compiler/verifier package with nested conjunctive guards. +#![cfg(feature = "trusted_runtime")] +#![allow(clippy::unwrap_used, clippy::panic)] +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 warp_core::edict_pure::{evaluate, EvaluationError, EvaluationLimits}; +const PACKAGE: &str = + include_str!("fixtures/edict-pure-predicates/executable-operation-package.cbor.hex"); +const REPORT: &str = include_str!("fixtures/edict-pure-predicates/verification-report.cbor.hex"); +const PIN: &str = "8dfbc0e76c2bce33b604832a6b8f4d94d6791c2863e4b1235c24d836baba72d0"; +fn field<'a>(value: &'a Value, name: &str) -> &'a Value { + let Value::Map(fields) = value else { + panic!("record") + }; + &fields + .iter() + .find(|(key, _)| *key == Value::Text(name.into())) + .unwrap() + .1 +} +fn input(start: u64, end: u64) -> Vec { + encode(&Value::Map( + [ + ("bufferId", Value::Bytes(vec![1; 32])), + ("basisHeadId", Value::Bytes(vec![2; 32])), + ("text", Value::Bytes(b"0123456789abcdef".to_vec())), + ("replacement", Value::Bytes("λ\r\n".as_bytes().to_vec())), + ("startByte", Value::Integer(start.into())), + ("endByte", Value::Integer(end.into())), + ] + .into_iter() + .map(|(key, value)| (Value::Text(key.into()), value)) + .collect(), + )) + .unwrap() +} +fn limits() -> EvaluationLimits { + EvaluationLimits { + max_package_bytes: 32768, + max_input_bytes: 4194304, + max_steps: 10000, + max_allocated_bytes: 16777216, + max_output_bytes: 4194304, + } +} +#[test] +fn public_compiler_conjunction_executes_and_rejects_each_failed_range_guard() { + let bytes = hex::decode(PACKAGE.trim()).unwrap(); + let pin: [u8; 32] = hex::decode(PIN).unwrap().try_into().unwrap(); + assert_eq!( + digest("echo.operation-package/v1", &decode(&bytes).unwrap()).unwrap(), + pin + ); + let report = decode(&hex::decode(REPORT.trim()).unwrap()).unwrap(); + assert_eq!(field(&report, "outcome"), &Value::Text("accepted".into())); + assert_eq!( + field(field(&report, "package"), "digest"), + &Value::Array(vec![ + Value::Text("sha256".into()), + Value::Bytes(pin.to_vec()) + ]) + ); + for (start, end, expected) in [ + (7, 7, "0123456λ\r\n789abcdef"), + (7, 11, "0123456λ\r\nbcdef"), + ] { + let supplied = input(start, end); + let result = evaluate(&bytes, pin, &supplied, limits()).unwrap(); + assert_eq!( + field(&decode(&result.output).unwrap(), "updatedText"), + &Value::Bytes(expected.as_bytes().to_vec()) + ); + assert_eq!(result, evaluate(&bytes, pin, &supplied, limits()).unwrap()); + } + for (start, end) in [(11, 7), (7, 17), (17, 17), (0, u64::MAX)] { + assert_eq!( + evaluate(&bytes, pin, &input(start, end), limits()), + Err(EvaluationError::InputConstraintFailed("where.0".into())) + ); + } +} diff --git a/crates/warp-core/tests/fixtures/edict-pure-predicates/README.md b/crates/warp-core/tests/fixtures/edict-pure-predicates/README.md new file mode 100644 index 00000000..ea0adcde --- /dev/null +++ b/crates/warp-core/tests/fixtures/edict-pure-predicates/README.md @@ -0,0 +1,22 @@ + + + +# Public conjunctive-guard pressure fixture + +These immutable bytes were emitted by Edict's public application build at +`23378720a200651dee1a7f7ff1d68dd213e52be1`, with the checked Echo provider at +`6a7c62fffac968e999b8ecc67c9cd8372d86f237`. The independent verifier report is +accepted and identifies the exact package. `provenance.json` retains the source +hash, raw artifact hashes and the domain-framed package pin. + +The application/lawpack closure comes from Jedit PR #302, base +`9e6466150e43afc83966f9fe67c6ddce2f58d5bc`, with the exact pressure source +retained as `ReplaceRange.edict`. The first supplied source is compiled with +its existing `jedit.text@1` lawpack and `.build/echo-provider` copied from the +selected Echo package. No Core, Target IR, package or report was edited. + +The source has nested `all` input guards. The runtime must decode and evaluate +that compiler/verifier-accepted predicate shape. The regression must execute +the pinned package and compare literal replacement bytes, then refuse failed +range checks. It is test evidence for generic predicate evaluation, not Echo +application semantics, graph mutation, settlement or recovery authority. diff --git a/crates/warp-core/tests/fixtures/edict-pure-predicates/ReplaceRange.edict b/crates/warp-core/tests/fixtures/edict-pure-predicates/ReplaceRange.edict new file mode 100644 index 00000000..905c79df --- /dev/null +++ b/crates/warp-core/tests/fixtures/edict-pure-predicates/ReplaceRange.edict @@ -0,0 +1,47 @@ +package jedit.text.replace_range@1; + +use lawpack jedit.text@1 digest "sha256:95758c1605894672cc9069fde01bb8b6e11842b053102660c9cd4f4d6f34d64e" as text; + +type ReplaceRangeInput = { + bufferId: text.BufferId, + basisHeadId: text.HeadId, + text: Bytes, + startByte: U64, + endByte: U64, + replacement: text.ReplacementBytes, +}; + +type ReplaceRangeBoundary = { + updatedText: Bytes, + bufferId: text.BufferId, + basisHeadId: text.HeadId, + startByte: U64, + endByte: U64, + replacement: text.ReplacementBytes, + rangeIsEmpty: U32, + createdLeafCeiling: U64, +}; + +intent replaceRange(input: ReplaceRangeInput) returns ReplaceRangeBoundary + profile text.replaceRange + basis input.basisHeadId + budget <= text.replaceRangeBudget + where input.startByte <= input.endByte && input.endByte <= len(input.text) && input.startByte <= len(input.text) +{ + let prefix = slice(input.text, 0u64, input.startByte); + let suffix = slice(input.text, input.endByte, len(input.text)); + let updatedText = prefix + input.replacement + suffix; + let createdLeafCeiling: U64 = text.maxCreatedLeafCount(); + let rangeIsEmpty = if input.startByte == input.endByte then 1u32 else 0u32; + + return { + updatedText, + bufferId: input.bufferId, + basisHeadId: input.basisHeadId, + startByte: input.startByte, + endByte: input.endByte, + replacement: input.replacement, + rangeIsEmpty, + createdLeafCeiling, + }; +} diff --git a/crates/warp-core/tests/fixtures/edict-pure-predicates/executable-operation-package.cbor.hex b/crates/warp-core/tests/fixtures/edict-pure-predicates/executable-operation-package.cbor.hex new file mode 100644 index 00000000..14302b0e --- /dev/null +++ b/crates/warp-core/tests/fixtures/edict-pure-predicates/executable-operation-package.cbor.hex @@ -0,0 +1 @@ +aa66736368656d6178196563686f2e6f7065726174696f6e2d7061636b6167652f76316770726f6772616d593753a7646b696e647821636f6d70696c65722d70726f64756365642d626f756e6465642d707572652f763166696e74656e746c7265706c61636552616e676566736368656d6178266563686f2e636f6d70696c65722d70726f64756365642d707572652d70726f6772616d2f76316d636f72655f61727469666163745916caa6657479706573a6715265706c61636552616e6765496e707574a2646b696e64665265636f7264666669656c6473a664746578747242797465733c6d61783d313034383537363e67656e644279746563553634686275666665724964756a656469742e7465787440312e427566666572496469737461727442797465635536346b6261736973486561644964736a656469742e7465787440312e4865616449646b7265706c6163656d656e74781d6a656469742e7465787440312e5265706c6163656d656e744279746573736a656469742e7465787440312e486561644964a3646b696e64674e6f6d696e616c68636f6e7472616374736a656469742e7465787440312e4865616449646e726570726573656e746174696f6e736a656469742e7465787440312e4e6f64654964736a656469742e7465787440312e4e6f64654964a3636d61781820636d696e1820646b696e64654279746573745265706c61636552616e6765426f756e64617279a2646b696e64665265636f7264666669656c6473a867656e644279746563553634686275666665724964756a656469742e7465787440312e427566666572496469737461727442797465635536346b6261736973486561644964736a656469742e7465787440312e4865616449646b7265706c6163656d656e74781d6a656469742e7465787440312e5265706c6163656d656e7442797465736b75706461746564546578747242797465733c6d61783d333134353732383e6c72616e67654973456d7074796355333272637265617465644c6561664365696c696e6763553634756a656469742e7465787440312e4275666665724964a3646b696e64674e6f6d696e616c68636f6e7472616374756a656469742e7465787440312e42756666657249646e726570726573656e746174696f6e736a656469742e7465787440312e4e6f64654964781d6a656469742e7465787440312e5265706c6163656d656e744279746573a2636d61781a00100000646b696e6465427974657367696d706f72747381a263726566a26269646c6a656469742e746578744031666469676573748266736861323536582095758c1605894672cc9069fde01bb8b6e11842b053102660c9cd4f4d6f34d64e646b696e64676c61777061636b67696e74656e7473a16c7265706c61636552616e6765a764626f6479a3656e6f64657385a3646b696e64636c65746576616c7565a4646172677383a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646474657874a2646b696e6465636f6e73746576616c7565a3646b696e6463696e746576616c75650065776964746863553634a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c6469737461727442797465646b696e646463616c6c6663616c6c656570636f72652e62797465732e736c696365687479706541726773817242797465733c6d61783d313034383537363e6762696e64696e67a3626964676c6f63616c2e3064747970657242797465733c6d61783d313034383537363e69616c7068614e616d6567246c6f63616c30a3646b696e64636c65746576616c7565a4646172677383a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646474657874a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c6467656e6442797465a4646172677381a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646474657874646b696e646463616c6c6663616c6c656571636f72652e62797465732e6c656e677468687479706541726773817242797465733c6d61783d313034383537363e646b696e646463616c6c6663616c6c656570636f72652e62797465732e736c696365687479706541726773817242797465733c6d61783d313034383537363e6762696e64696e67a3626964676c6f63616c2e3164747970657242797465733c6d61783d313034383537363e69616c7068614e616d6567246c6f63616c31a3646b696e64636c65746576616c7565a4646172677382a4646172677382a263726566a3626964676c6f63616c2e3064747970657242797465733c6d61783d313034383537363e69616c7068614e616d6567246c6f63616c30646b696e64656c6f63616ca36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646b7265706c6163656d656e74646b696e646463616c6c6663616c6c656571636f72652e62797465732e636f6e636174687479706541726773827242797465733c6d61783d313034383537363e781d6a656469742e7465787440312e5265706c6163656d656e744279746573a263726566a3626964676c6f63616c2e3164747970657242797465733c6d61783d313034383537363e69616c7068614e616d6567246c6f63616c31646b696e64656c6f63616c646b696e646463616c6c6663616c6c656571636f72652e62797465732e636f6e636174687479706541726773827242797465733c6d61783d323039373135323e7242797465733c6d61783d313034383537363e6762696e64696e67a3626964676c6f63616c2e3264747970657242797465733c6d61783d333134353732383e69616c7068614e616d6567246c6f63616c32a3646b696e64636c65746576616c7565a4646172677380646b696e646463616c6c6663616c6c656578206a656469742e7465787440312e6d6178437265617465644c656166436f756e74687479706541726773806762696e64696e67a3626964676c6f63616c2e3364747970656355363469616c7068614e616d6567246c6f63616c33a3646b696e64636c65746576616c7565a464656c7365a2646b696e6465636f6e73746576616c7565a3646b696e6463696e746576616c75650065776964746863553332646b696e64626966647468656ea2646b696e6465636f6e73746576616c7565a3646b696e6463696e746576616c7565016577696474686355333269707265646963617465a4626f70623d3d646b696e6467636f6d70617265646c656674a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c6469737461727442797465657269676874a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c6467656e64427974656762696e64696e67a3626964676c6f63616c2e3464747970656355333269616c7068614e616d6567246c6f63616c34666c6f63616c7386a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730a3626964676c6f63616c2e3064747970657242797465733c6d61783d313034383537363e69616c7068614e616d6567246c6f63616c30a3626964676c6f63616c2e3164747970657242797465733c6d61783d313034383537363e69616c7068614e616d6567246c6f63616c31a3626964676c6f63616c2e3264747970657242797465733c6d61783d333134353732383e69616c7068614e616d6567246c6f63616c32a3626964676c6f63616c2e3364747970656355363469616c7068614e616d6567246c6f63616c33a3626964676c6f63616c2e3464747970656355333269616c7068614e616d6567246c6f63616c3466726573756c74a2646b696e64667265636f7264666669656c6473a867656e6442797465a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c6467656e6442797465686275666665724964a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c6468627566666572496469737461727442797465a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c64697374617274427974656b6261736973486561644964a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646b62617369734865616449646b7265706c6163656d656e74a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646b7265706c6163656d656e746b7570646174656454657874a263726566a3626964676c6f63616c2e3264747970657242797465733c6d61783d333134353732383e69616c7068614e616d6567246c6f63616c32646b696e64656c6f63616c6c72616e67654973456d707479a263726566a3626964676c6f63616c2e3464747970656355333269616c7068614e616d6567246c6f63616c34646b696e64656c6f63616c72637265617465644c6561664365696c696e67a263726566a3626964676c6f63616c2e3364747970656355363469616c7068614e616d6567246c6f63616c33646b696e64656c6f63616c656261736973a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646b626173697348656164496465696e707574782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e707574666f7574707574782f6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765426f756e6461727970696e707574436f6e73747261696e747381a366736f7572636565776865726569707265646963617465a2646b696e6463616c6c6676616c75657382a2646b696e6463616c6c6676616c75657382a4626f70623c3d646b696e6467636f6d70617265646c656674a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c6469737461727442797465657269676874a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c6467656e6442797465a4626f70623c3d646b696e6467636f6d70617265646c656674a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c6467656e6442797465657269676874a4646172677381a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646474657874646b696e646463616c6c6663616c6c656571636f72652e62797465732e6c656e677468687479706541726773817242797465733c6d61783d313034383537363ea4626f70623c3d646b696e6467636f6d70617265646c656674a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c6469737461727442797465657269676874a4646172677381a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646474657874646b696e646463616c6c6663616c6c656571636f72652e62797465732e6c656e677468687479706541726773817242797465733c6d61783d313034383537363e6a636f6f7264696e6174656777686572652e3074636f72654576616c756174696f6e427564676574a3686d617853746570731a001000006e6d61784f757470757442797465731a00800000716d6178416c6c6f636174656442797465731a01000000781872657175697265644f7065726174696f6e50726f66696c65781f636f6e74696e75756d2e70726f66696c652e726561642d77726974652f76316a61706956657273696f6e6d65646963742e636f72652f76316a636f6f7264696e617465781a6a656469742e746578742e7265706c6163655f72616e6765403178187265717569726564436f72654361706162696c697469657380727461726765745f69725f6172746966616374591341a6646b696e64707461726765744972417274696661637466646f6d61696e6f6563686f2e7370616e2d69722f763167696e74656e7473a16c7265706c61636552616e6765a8656261736973a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646b62617369734865616449646573746570738066726573756c74a2646b696e64667265636f7264666669656c6473a867656e6442797465a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c6467656e6442797465686275666665724964a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c6468627566666572496469737461727442797465a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c64697374617274427974656b6261736973486561644964a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646b62617369734865616449646b7265706c6163656d656e74a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646b7265706c6163656d656e746b7570646174656454657874a263726566a3626964676c6f63616c2e3264747970657242797465733c6d61783d333134353732383e69616c7068614e616d6567246c6f63616c32646b696e64656c6f63616c6c72616e67654973456d707479a263726566a3626964676c6f63616c2e3464747970656355333269616c7068614e616d6567246c6f63616c34646b696e64656c6f63616c72637265617465644c6561664365696c696e67a263726566a3626964676c6f63616c2e3364747970656355363469616c7068614e616d6567246c6f63616c33646b696e64656c6f63616c6c7075726542696e64696e677385a3626964767265706c61636552616e67652e62696e64696e672e306576616c7565a4646172677383a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646474657874a2646b696e6465636f6e73746576616c7565a3646b696e6463696e746576616c75650065776964746863553634a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c6469737461727442797465646b696e646463616c6c6663616c6c656570636f72652e62797465732e736c696365687479706541726773817242797465733c6d61783d313034383537363e6762696e64696e67a3626964676c6f63616c2e3064747970657242797465733c6d61783d313034383537363e69616c7068614e616d6567246c6f63616c30a3626964767265706c61636552616e67652e62696e64696e672e316576616c7565a4646172677383a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646474657874a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c6467656e6442797465a4646172677381a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646474657874646b696e646463616c6c6663616c6c656571636f72652e62797465732e6c656e677468687479706541726773817242797465733c6d61783d313034383537363e646b696e646463616c6c6663616c6c656570636f72652e62797465732e736c696365687479706541726773817242797465733c6d61783d313034383537363e6762696e64696e67a3626964676c6f63616c2e3164747970657242797465733c6d61783d313034383537363e69616c7068614e616d6567246c6f63616c31a3626964767265706c61636552616e67652e62696e64696e672e326576616c7565a4646172677382a4646172677382a263726566a3626964676c6f63616c2e3064747970657242797465733c6d61783d313034383537363e69616c7068614e616d6567246c6f63616c30646b696e64656c6f63616ca36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646b7265706c6163656d656e74646b696e646463616c6c6663616c6c656571636f72652e62797465732e636f6e636174687479706541726773827242797465733c6d61783d313034383537363e781d6a656469742e7465787440312e5265706c6163656d656e744279746573a263726566a3626964676c6f63616c2e3164747970657242797465733c6d61783d313034383537363e69616c7068614e616d6567246c6f63616c31646b696e64656c6f63616c646b696e646463616c6c6663616c6c656571636f72652e62797465732e636f6e636174687479706541726773827242797465733c6d61783d323039373135323e7242797465733c6d61783d313034383537363e6762696e64696e67a3626964676c6f63616c2e3264747970657242797465733c6d61783d333134353732383e69616c7068614e616d6567246c6f63616c32a3626964767265706c61636552616e67652e62696e64696e672e336576616c7565a4646172677380646b696e646463616c6c6663616c6c656578206a656469742e7465787440312e6d6178437265617465644c656166436f756e74687479706541726773806762696e64696e67a3626964676c6f63616c2e3364747970656355363469616c7068614e616d6567246c6f63616c33a3626964767265706c61636552616e67652e62696e64696e672e346576616c7565a464656c7365a2646b696e6465636f6e73746576616c7565a3646b696e6463696e746576616c75650065776964746863553332646b696e64626966647468656ea2646b696e6465636f6e73746576616c7565a3646b696e6463696e746576616c7565016577696474686355333269707265646963617465a4626f70623d3d646b696e6467636f6d70617265646c656674a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c6469737461727442797465657269676874a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c6467656e64427974656762696e64696e67a3626964676c6f63616c2e3464747970656355333269616c7068614e616d6567246c6f63616c346c726571756972656d656e74738070696e707574436f6e73747261696e747381a366736f7572636565776865726569707265646963617465a2646b696e6463616c6c6676616c75657382a2646b696e6463616c6c6676616c75657382a4626f70623c3d646b696e6467636f6d70617265646c656674a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c6469737461727442797465657269676874a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c6467656e6442797465a4626f70623c3d646b696e6467636f6d70617265646c656674a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c6467656e6442797465657269676874a4646172677381a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646474657874646b696e646463616c6c6663616c6c656571636f72652e62797465732e6c656e677468687479706541726773817242797465733c6d61783d313034383537363ea4626f70623c3d646b696e6467636f6d70617265646c656674a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c6469737461727442797465657269676874a4646172677381a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646474657874646b696e646463616c6c6663616c6c656571636f72652e62797465732e6c656e677468687479706541726773817242797465733c6d61783d313034383537363e6a636f6f7264696e6174656777686572652e30706f7065726174696f6e50726f66696c65781f636f6e74696e75756d2e70726f66696c652e726561642d77726974652f763174636f72654576616c756174696f6e427564676574a3686d617853746570731a001000006e6d61784f757470757442797465731a00800000716d6178416c6c6f636174656442797465731a010000006d74617267657450726f66696c65a26269646a6563686f2e64706f403166646967657374826673686132353658202e2494121aecf5e6a2d920f5fb85408825d394765fad41484c416397c920fb046f73656d616e746963436c6f73757265a2686c61777061636b7381a26269646c6a656469742e746578744031666469676573748266736861323536582095758c1605894672cc9069fde01bb8b6e11842b053102660c9cd4f4d6f34d64e6a736f75726365436f7265a2626964781a6a656469742e746578742e7265706c6163655f72616e676540316664696765737482667368613235365820b9ac3af5bed24fbe4ad7ec03354b872fe810cec01510afda8e44b016eb0ec8a574736f75726365436f7265436f6f7264696e617465781a6a656469742e746578742e7265706c6163655f72616e6765403178186c61777061636b5f6578706f7274735f617274696661637459093aa665747970657385a26a636f6f7264696e617465736a656469742e7465787440312e4e6f646549646a646566696e6974696f6e6f42797465733c65786163743d33323ea26a636f6f7264696e617465756a656469742e7465787440312e42756666657249646a646566696e6974696f6e781c4e6f6d696e616c3c6a656469742e7465787440312e4e6f646549643ea26a636f6f7264696e617465736a656469742e7465787440312e4865616449646a646566696e6974696f6e781c4e6f6d696e616c3c6a656469742e7465787440312e4e6f646549643ea26a636f6f7264696e617465781d6a656469742e7465787440312e5265706c6163656d656e7442797465736a646566696e6974696f6e7242797465733c6d61783d313034383537363ea26a636f6f7264696e617465781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6a646566696e6974696f6e6f537472696e673c6d61783d3235363e67656666656374738069636f6e7374616e747382a36474797065635536346576616c75651910006a636f6f7264696e617465781d6a656469742e7465787440312e6d6178437265617465644c6561766573a36474797065635536346576616c75651910006a636f6f7264696e617465781f6a656469742e7465787440312e6d6178437265617465644272616e636865736c6f62737472756374696f6e738aa36a636f6f7264696e617465781e6a656469742e7465787440312e52616e67654f72646572496e76616c69646d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736e646f6d61696e4d61707061626c65a36a636f6f7264696e617465781d6a656469742e7465787440312e52616e67654f75744f66426f756e64736d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736e646f6d61696e4d61707061626c65a36a636f6f7264696e61746578206a656469742e7465787440312e55746638426f756e64617279496e76616c69646d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736e646f6d61696e4d61707061626c65a36a636f6f7264696e617465716a656469742e7465787440312e4e6f4f706d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736e646f6d61696e4d61707061626c65a36a636f6f7264696e617465781e6a656469742e7465787440312e42617369734e6f7443616e6f6e6963616c6d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736e646f6d61696e4d61707061626c65a36a636f6f7264696e617465781f6a656469742e7465787440312e41726974686d657469634f766572666c6f776d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736e696e746567726974794661756c74a36a636f6f7264696e61746578186a656469742e7465787440312e466163744d697373696e676d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736d7265736f757263654661756c74a36a636f6f7264696e617465781a6a656469742e7465787440312e466163744d616c666f726d65646d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736e696e746567726974794661756c74a36a636f6f7264696e61746578246a656469742e7465787440312e436f6e74656e744964656e746974794d69736d617463686d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736e696e746567726974794661756c74a36a636f6f7264696e617465781a6a656469742e7465787440312e4d616c666f726d6564526f70656d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736e696e746567726974794661756c746d7075726546756e6374696f6e7381a864626f6479a264626f6479a3666c6f63616c738066726573756c74a2646b696e6465636f6e73746576616c7565a3646b696e6463696e746576616c7565191000657769647468635536346862696e64696e67738066706172616d738066736f757263656565646963746a636f6f7264696e61746578206a656469742e7465787440312e6d6178437265617465644c656166436f756e746a72657475726e54797065635536346c636f737454656d706c617465781f6a656469742e7465787440312e7265706c61636552616e67654275646765746e706172616d657465725479706573806e74797065506172616d6574657273807064657465726d696e69736d436c61737365746f74616c716f7065726174696f6e50726f66696c6573a178196a656469742e7465787440312e7265706c61636552616e6765a26d6f7074696354656d706c617465a6696f707469634b696e64736166666563745265696e746567726174696f6e6c626f756e646172794b696e64666166666563746d626173697354656d706c617465781b6a656469742e7465787440312e65786163744865616442617369736d737570706f7274506f6c696379781e6a656469742e7465787440312e6261736973426f756e64537570706f72746f6c6f7373446973706f736974696f6e756a656469742e7465787440312e6c6f73736c657373736170657274757265526571756972656d656e74a26372656678226a656469742e7465787440312e7265706c61636552616e6765466f6f747072696e74646b696e64781b6162737472616374466f6f747072696e744f626c69676174696f6e6f65666665637450726564696361746578206a656469742e7465787440312e7265706c61636552616e676545666665637473781a726573756c745f70726f6a656374696f6e5f617274696661637459033fa566736368656d61781a65646963742e726573756c742d70726f6a656374696f6e2f76316a65787072657373696f6ea2646b696e64667265636f7264666669656c6473a867656e6442797465a3646b696e6466736f7572636564706174688167656e644279746566736f75726365a1646b696e64706170706c69636174696f6e496e707574686275666665724964a3646b696e6466736f7572636564706174688168627566666572496466736f75726365a1646b696e64706170706c69636174696f6e496e70757469737461727442797465a3646b696e6466736f757263656470617468816973746172744279746566736f75726365a1646b696e64706170706c69636174696f6e496e7075746b6261736973486561644964a3646b696e6466736f757263656470617468816b626173697348656164496466736f75726365a1646b696e64706170706c69636174696f6e496e7075746b7265706c6163656d656e74a3646b696e6466736f757263656470617468816b7265706c6163656d656e7466736f75726365a1646b696e64706170706c69636174696f6e496e7075746b7570646174656454657874a3646b696e6466736f7572636564706174688066736f75726365a2646b696e646b7075726542696e64696e676962696e64696e674964767265706c61636552616e67652e62696e64696e672e326c72616e67654973456d707479a3646b696e6466736f7572636564706174688066736f75726365a2646b696e646b7075726542696e64696e676962696e64696e674964767265706c61636552616e67652e62696e64696e672e3472637265617465644c6561664365696c696e67a3646b696e6466736f7572636564706174688066736f75726365a2646b696e646b7075726542696e64696e676962696e64696e674964767265706c61636552616e67652e62696e64696e672e336a6f757470757454797065782f6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765426f756e646172796e6d61784f757470757442797465731a00800000736f7065726174696f6e436f6f7264696e61746578276a656469742e746578742e7265706c6163655f72616e676540312e7265706c61636552616e67656c7061636b6167655f6b696e647821636f6d70696c65722d70726f64756365642d626f756e6465642d707572652f76316e6275646765745f6365696c696e67a3696d61785f73746570731a00100000706d61785f6f75747075745f62797465731a00800000736d61785f616c6c6f63617465645f62797465731a010000007073656d616e7469635f636c6f73757265a86d636f72655f6964656e746974795820b9ac3af5bed24fbe4ad7ec03354b872fe810cec01510afda8e44b016eb0ec8a5706c61777061636b5f6964656e74697479582095758c1605894672cc9069fde01bb8b6e11842b053102660c9cd4f4d6f34d64e726c61777061636b5f636f6f7264696e6174656c6a656469742e746578744031727461726765745f69725f6964656e746974795820ae467fe91af6989cc95cf88c98cef72ad6cba07cd16e1a0f82d785be7dc2cb1f7565646963745f736f757263655f6964656e7469747958209129ed076e60ed0ed094cffa16c510f20377fe78851741dbc51fe716c5bff575781a63616e6f6e6963616c5f6d65616e696e675f6964656e746974795820b9ac3af5bed24fbe4ad7ec03354b872fe810cec01510afda8e44b016eb0ec8a5781b6170706c69636174696f6e5f736368656d615f6964656e7469747958201f436d717d3f349cc6f4c3431730ff4182d65c87fb6c1233692fc40fbd71bf02781d6170706c69636174696f6e5f736368656d615f636f6f7264696e617465756a656469742e746578742e6578706f7274732f7631746f7065726174696f6e5f636f6f7264696e61746578276a656469742e746578742e7265706c6163655f72616e676540312e7265706c61636552616e6765777461726765745f70726f66696c655f6964656e7469747958202e2494121aecf5e6a2d920f5fb85408825d394765fad41484c416397c920fb04781a617574686f726974795f70726f66696c655f6964656e746974795820fbaf54b61a71d54139a37955fe1bae42ee1d013f9aff2b09f546084fe3b3ced6781b666f6f747072696e745f636f6e74726163745f6964656e746974795820bf4da382443c8f8a740b3d28b77e3cfd8b39cb1608a9b885de59e1cb05d70365781c696e7465727072657465725f70726f66696c655f6964656e746974795820dc267bf35dc047a748593bbc5eaf6d9565b6206bfd84caf3cbe29653c6f34a76 diff --git a/crates/warp-core/tests/fixtures/edict-pure-predicates/provenance.json b/crates/warp-core/tests/fixtures/edict-pure-predicates/provenance.json new file mode 100644 index 00000000..5dbe9586 --- /dev/null +++ b/crates/warp-core/tests/fixtures/edict-pure-predicates/provenance.json @@ -0,0 +1,11 @@ +{ + "edict": "23378720a200651dee1a7f7ff1d68dd213e52be1", + "echo": "6a7c62fffac968e999b8ecc67c9cd8372d86f237", + "jeditBase": "9e6466150e43afc83966f9fe67c6ddce2f58d5bc", + "packagePin": "8dfbc0e76c2bce33b604832a6b8f4d94d6791c2863e4b1235c24d836baba72d0", + "files": { + "executable-operation-package.cbor": "16774bd6788bc97ac1c8b051bcacefe183acb293cb5bdcf9b8e11e4126414b49", + "verification-report.cbor": "5bdced736059bed39572d3128eda11e182dbcf6237384a0b288c91e385df709c", + "ReplaceRange.edict": "257db3e7ec79e60ee0140aa64727b885862aae124dae89e2c1a986aeb889a971" + } +} diff --git a/crates/warp-core/tests/fixtures/edict-pure-predicates/verification-report.cbor.hex b/crates/warp-core/tests/fixtures/edict-pure-predicates/verification-report.cbor.hex new file mode 100644 index 00000000..5be7280d --- /dev/null +++ b/crates/warp-core/tests/fixtures/edict-pure-predicates/verification-report.cbor.hex @@ -0,0 +1 @@ +a8676f7574636f6d65686163636570746564677061636b616765a2626964782165786563757461626c652d6f7065726174696f6e2d7061636b6167652e6563686f66646967657374826673686132353658208dfbc0e76c2bce33b604832a6b8f4d94d6791c2863e4b1235c24d836baba72d0687461726765744972a26269646f6563686f2e7370616e2d69722f76316664696765737482667368613235365820ae467fe91af6989cc95cf88c98cef72ad6cba07cd16e1a0f82d785be7dc2cb1f6a61706956657273696f6e78296563686f2e6f7065726174696f6e2d7061636b6167652d76657269666965722d7265706f72742f76316d646961676e6f73746963416269a26269647465646963742e646961676e6f73746963732f7631666469676573748266736861323536582028fd72a98223153982ca084c29dbb1b2d430623967ab3b6db9d7fee668e614b96f646961676e6f737469634279746573407165786563757461626c655375626a656374a2656279746573590151a4677061636b616765a2626964782165786563757461626c652d6f7065726174696f6e2d7061636b6167652e6563686f66646967657374826673686132353658208dfbc0e76c2bce33b604832a6b8f4d94d6791c2863e4b1235c24d836baba72d0687461726765744972a26269646f6563686f2e7370616e2d69722f76316664696765737482667368613235365820ae467fe91af6989cc95cf88c98cef72ad6cba07cd16e1a0f82d785be7dc2cb1f6a61706956657273696f6e781a6563686f2e65786563757461626c652d7375626a6563742f7631781b6170706c69636174696f6e526573756c7450726f6a656374696f6ea262696478276a656469742e746578742e7265706c6163655f72616e676540312e7265706c61636552616e6765666469676573748266736861323536582080d1580fac6effe2d4001364ba2d554db5317e2c324ec30965fe866f79ab6348697265666572656e6365a2626964781a6563686f2e65786563757461626c652d7375626a6563742f7631666469676573748266736861323536582028d516df86a0a6e25ceca21a814557f8baa6f21272f2c1a41409d2c8b60d13c8781b6170706c69636174696f6e526573756c7450726f6a656374696f6ea262696478276a656469742e746578742e7265706c6163655f72616e676540312e7265706c61636552616e6765666469676573748266736861323536582080d1580fac6effe2d4001364ba2d554db5317e2c324ec30965fe866f79ab6348 diff --git a/docs/architecture/application-contract-hosting.md b/docs/architecture/application-contract-hosting.md index bfac6e33..ee580217 100644 --- a/docs/architecture/application-contract-hosting.md +++ b/docs/architecture/application-contract-hosting.md @@ -247,7 +247,12 @@ totality evidence; the interpreter additionally checks runtime values even when the supplied package pin matches. Calls resolve opaque source or lawpack coordinates to retained Edict bodies with separate lexical scope. No application coordinate selects a native implementation. Unsupported expression forms are rejected during decoding, -including unselected branches. Authored runtime types constrain input, +including unselected branches. Conjunctive `all` predicates decode as closed +recursive trees, including every child before execution. Evaluation visits +children in source order and stops at the first false result. Empty conjunctions +reject during decoding, matching Core's one-or-more child cardinality. Each visited predicate consumes an execution step, and +predicate nesting participates in the same combined expression/helper depth +and node limits. Authored runtime types constrain input, bindings, helper returns, and output. Nominal contracts resolve their declared storage representations. Authored input constraints run before bindings, and the compiler's result projection must match the selected Target IR result. diff --git a/scripts/verify-local.sh b/scripts/verify-local.sh index 2b151760..6b069285 100755 --- a/scripts/verify-local.sh +++ b/scripts/verify-local.sh @@ -1197,7 +1197,7 @@ pre_push_mapped_feature_string_for_test_target() { warp-core:parallel_parallel_exec) printf '%s\n' "delta_validate" ;; - warp-core:scheduler_fault_recovery_authority|warp-core:edict_pure_evaluation_tests|warp-core:edict_pure_unsigned_subtraction_tests|warp-core:edict_pure_byte_length_tests|warp-core:edict_byte_equality_tests|warp-core:edict_byte_slice_tests|warp-core:edict_node_read_tests|warp-core:edict_byte_concat_tests|warp-core:edict_byte_literal_tests|warp-core:edict_source_functions_tests) + warp-core:scheduler_fault_recovery_authority|warp-core:edict_pure_evaluation_tests|warp-core:edict_pure_predicates_tests|warp-core:edict_pure_unsigned_subtraction_tests|warp-core:edict_pure_byte_length_tests|warp-core:edict_byte_equality_tests|warp-core:edict_byte_slice_tests|warp-core:edict_node_read_tests|warp-core:edict_byte_concat_tests|warp-core:edict_byte_literal_tests|warp-core:edict_source_functions_tests) printf '%s\n' "trusted_runtime" ;; warp-math:determinism_policy_tests) @@ -1437,7 +1437,9 @@ prepare_warp_core_scope() { case "$file" in crates/warp-core/src/edict_pure.rs|crates/warp-core/src/edict_pure/*.rs|crates/warp-core/tests/fixtures/edict-pure-jedit/*|crates/warp-core/tests/fixtures/edict-pure-subtraction/*|crates/warp-core/tests/fixtures/edict-pure-byte-length/*|crates/warp-core/tests/fixtures/edict-byte-equality/*|crates/warp-core/tests/fixtures/edict-byte-slice/*|crates/warp-core/src/edict_read.rs|crates/warp-core/src/edict_read/*.rs|crates/warp-core/tests/fixtures/edict-node-read/*|crates/warp-core/tests/fixtures/edict-byte-concat/*|crates/warp-core/tests/fixtures/edict-byte-literals/*|crates/warp-core/tests/fixtures/edict-source-functions/*) append_unique "edict_pure_evaluation_tests" FULL_SCOPE_WARP_CORE_EXTRA_TESTS + append_unique "edict_pure_predicates_tests" FULL_SCOPE_WARP_CORE_EXTRA_TESTS append_unique "edict_pure_evaluation_tests" FULL_SCOPE_WARP_CORE_CLIPPY_TESTS + append_unique "edict_pure_predicates_tests" FULL_SCOPE_WARP_CORE_CLIPPY_TESTS append_unique "edict_pure_unsigned_subtraction_tests" FULL_SCOPE_WARP_CORE_EXTRA_TESTS append_unique "edict_pure_unsigned_subtraction_tests" FULL_SCOPE_WARP_CORE_CLIPPY_TESTS append_unique "edict_pure_byte_length_tests" FULL_SCOPE_WARP_CORE_EXTRA_TESTS