diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6b371580..cc0dd7a5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -150,6 +150,9 @@ jobs: cargo clippy -p warp-core --features native_rule_bootstrap,trusted_runtime --test executable_operation_pipeline_tests -- -D warnings -D missing_docs cargo clippy -p warp-core --features native_rule_bootstrap,trusted_runtime,host_test --test executable_operation_pipeline_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 -- -D warnings -D missing_docs + clippy-det-fixed: name: Clippy (det_fixed) runs-on: ubuntu-latest @@ -309,6 +312,10 @@ jobs: run: | cargo test -p warp-core --features native_rule_bootstrap,trusted_runtime --test executable_operation_pipeline_tests cargo test -p warp-core --features native_rule_bootstrap,trusted_runtime,host_test --test executable_operation_pipeline_tests + - name: cargo test (compiler-produced pure evaluation) + run: | + cargo test -p warp-core --features trusted_runtime --test edict_pure_evaluation_tests + cargo test -p warp-core --features trusted_runtime --lib edict_pure:: - name: cargo test --doc (warp-core) run: cargo test -p warp-core --doc - name: PRNG golden regression (warp-math) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d09a7aa..139c78e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,13 @@ ### Added +- Trusted Echo hosts can evaluate the first compiler-produced bounded pure + Edict subset through a package-pinned interpreter. Runtime type checks, + authored constraints, separate helper scope, deterministic cost accounting, + and host/package budget intersections guard the result. The external compiler + witness includes a separately compiled source mutation. This is ordinary pure + evaluation, with no installation, graph effects, Tick, Receipt, or WAL claim. + - The checked Edict provider contract now admits generic nominal Core types as exact contract coordinates over bounded storage representations. The regenerated provider package remains application-neutral and adds no Jim, diff --git a/crates/warp-core/Cargo.toml b/crates/warp-core/Cargo.toml index 49fc5fa8..a66d527a 100644 --- a/crates/warp-core/Cargo.toml +++ b/crates/warp-core/Cargo.toml @@ -102,6 +102,10 @@ required-features = ["native_rule_bootstrap", "trusted_runtime"] name = "executable_operation_pipeline_tests" required-features = ["native_rule_bootstrap", "trusted_runtime"] +[[test]] +name = "edict_pure_evaluation_tests" +required-features = ["trusted_runtime"] + [build-dependencies] blake3 = "1.0" diff --git a/crates/warp-core/src/edict_pure.rs b/crates/warp-core/src/edict_pure.rs new file mode 100644 index 00000000..0f8d03eb --- /dev/null +++ b/crates/warp-core/src/edict_pure.rs @@ -0,0 +1,90 @@ +// SPDX-License-Identifier: Apache-2.0 +// © James Ross Ω FLYING•ROBOTS +//! Bounded, effect-free evaluation of exactly pinned compiler packages. +//! +//! This trusted-host computation is not package installation, admission, +//! scheduler settlement, or causal evidence. Its caller must obtain the expected +//! package identity from an independently verified, authorized release. + +mod decode; +mod evaluate; +mod model; +mod syntax; +mod values; + +use echo_edict_canonical::decode_canonical_cbor_v1; + +/// Host ceilings, intersected with the compiler's declared evaluation budget. +#[derive(Clone, Copy, Debug)] +pub struct EvaluationLimits { + /// Maximum encoded package size before canonical decoding. + pub max_package_bytes: usize, + /// Maximum encoded application input size before canonical decoding. + pub max_input_bytes: usize, + /// Maximum number of interpreted operations. + pub max_steps: u64, + /// Maximum cumulative materialized value bytes, including copies. + pub max_allocated_bytes: u64, + /// Maximum canonical result size. + pub max_output_bytes: u64, +} + +/// A pure result and deterministic resource accounting, never a Tick or Receipt. +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct EvaluationResult { + /// Canonical application result bytes. + pub output: Vec, + /// Interpreted operation count. + pub steps: u64, + /// Cumulative charged value storage. + pub allocated_bytes: u64, +} + +/// Typed failure before a pure result is returned. +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum EvaluationError { + /// The package exceeds the host's decode aperture. + PackageTooLarge, + /// The input exceeds the host's decode aperture. + InputTooLarge, + /// Package bytes do not match the trusted host's verified pin. + PackageIdentityMismatch, + /// Canonical bytes or required package structure are invalid. + InvalidArtifact, + /// The selected program contains unsupported semantics. + UnsupportedProgram, + /// Input does not inhabit the authored runtime type. + InvalidInput, + /// An authored input predicate was false at the named coordinate. + InputConstraintFailed(String), + /// The interpreted operation budget was exhausted. + StepBudgetExceeded, + /// The cumulative value storage budget was exhausted. + AllocationBudgetExceeded, + /// The canonical result exceeds its output budget. + OutputBudgetExceeded, +} + +/// Evaluates exact compiler-produced package bytes under a verified host pin. +/// +/// The pin is trusted-host input, not an authentication claim supplied by an +/// application. A matching digest alone does not establish verifier approval. +/// No graph, runtime host, callbacks, clock, filesystem, or WAL is accessible. +pub fn evaluate( + package_bytes: &[u8], + verified_package_digest: [u8; 32], + input_bytes: &[u8], + limits: EvaluationLimits, +) -> Result { + if package_bytes.len() > limits.max_package_bytes.min(model::MAX_ARTIFACT_BYTES) { + return Err(EvaluationError::PackageTooLarge); + } + if input_bytes.len() > limits.max_input_bytes.min(model::MAX_ARTIFACT_BYTES) { + return Err(EvaluationError::InputTooLarge); + } + let package = + decode_canonical_cbor_v1(package_bytes).map_err(|_| EvaluationError::InvalidArtifact)?; + let program = decode::package(&package, verified_package_digest, limits)?; + let input = decode_canonical_cbor_v1(input_bytes).map_err(|_| EvaluationError::InvalidInput)?; + evaluate::run(&program, input) +} diff --git a/crates/warp-core/src/edict_pure/decode.rs b/crates/warp-core/src/edict_pure/decode.rs new file mode 100644 index 00000000..822d3dda --- /dev/null +++ b/crates/warp-core/src/edict_pure/decode.rs @@ -0,0 +1,245 @@ +// SPDX-License-Identifier: Apache-2.0 +// © James Ross Ω FLYING•ROBOTS +use std::collections::BTreeMap; + +use echo_edict_canonical::{ + decode_canonical_cbor_v1 as decode, digest_canonical_value_bytes_v1 as digest, + CanonicalValueV1 as Value, +}; + +use super::model::{Binding, Helper, Program, MAX_PROGRAM_NODES}; +use super::syntax::Parser; +use super::values::{array, bytes, exact_fields, field, number, require_text, text_field}; +use super::{EvaluationError as Error, EvaluationLimits}; + +const PACKAGE_DOMAIN: &str = "echo.operation-package/v1"; +const PROGRAM_KIND: &str = "compiler-produced-bounded-pure/v1"; + +pub(super) fn package( + value: &Value, + pin: [u8; 32], + host: EvaluationLimits, +) -> Result { + if digest(PACKAGE_DOMAIN, value).map_err(|_| Error::InvalidArtifact)? != pin { + return Err(Error::PackageIdentityMismatch); + } + exact_fields( + value, + &[ + "schema", + "program", + "package_kind", + "budget_ceiling", + "semantic_closure", + "operation_coordinate", + "target_profile_identity", + "authority_profile_identity", + "footprint_contract_identity", + "interpreter_profile_identity", + ], + )?; + require_text(value, "schema", PACKAGE_DOMAIN)?; + require_text(value, "package_kind", PROGRAM_KIND)?; + for (key, profile) in [ + ( + "authority_profile_identity", + "echo.operation.authority.no-effects/v1", + ), + ( + "footprint_contract_identity", + "echo.operation.footprint.empty/v1", + ), + ( + "interpreter_profile_identity", + "echo.operation-interpreter.compiler-produced-bounded-pure/v1", + ), + ] { + let mut hash = blake3::Hasher::new(); + hash.update(b"echo:operation-profile:v1\0"); + hash.update(&(profile.len() as u64).to_le_bytes()); + hash.update(profile.as_bytes()); + if bytes(field(value, key)?)? != hash.finalize().as_bytes() { + return Err(Error::UnsupportedProgram); + } + } + let program = decode(bytes(field(value, "program")?)?).map_err(|_| Error::InvalidArtifact)?; + exact_fields( + &program, + &[ + "schema", + "kind", + "intent", + "core_artifact", + "target_ir_artifact", + "lawpack_exports_artifact", + "result_projection_artifact", + ], + )?; + require_text(&program, "schema", "echo.compiler-produced-pure-program/v1")?; + require_text(&program, "kind", PROGRAM_KIND)?; + let core = embedded(&program, "core_artifact")?; + let target = embedded(&program, "target_ir_artifact")?; + let exports = embedded(&program, "lawpack_exports_artifact")?; + let projection = embedded(&program, "result_projection_artifact")?; + let closure = field(value, "semantic_closure")?; + for (key, domain, artifact) in [ + ("core_identity", "edict.core.module/v1", &core), + ("target_ir_identity", "edict.target-ir.artifact/v1", &target), + ( + "application_schema_identity", + "edict.lawpack-exports/v1", + &exports, + ), + ] { + if bytes(field(closure, key)?)? + != digest(domain, artifact).map_err(|_| Error::InvalidArtifact)? + { + return Err(Error::InvalidArtifact); + } + } + require_text(&core, "apiVersion", "edict.core/v1")?; + require_text(&target, "domain", "echo.span-ir/v1")?; + require_text(&projection, "schema", "edict.result-projection/v1")?; + let intent_name = text_field(&program, "intent")?; + let coordinate = format!("{}.{}", text_field(&core, "coordinate")?, intent_name); + require_text(value, "operation_coordinate", &coordinate)?; + require_text(&projection, "operationCoordinate", &coordinate)?; + let core_intent = field(field(&core, "intents")?, intent_name)?; + let target_intent = field(field(&target, "intents")?, intent_name)?; + for name in ["steps", "requirements"] { + if !array(field(target_intent, name)?)?.is_empty() { + return Err(Error::UnsupportedProgram); + } + } + if let Ok(actions) = field(target_intent, "externalActionRequests") { + if !array(actions)?.is_empty() { + return Err(Error::UnsupportedProgram); + } + } + let input_local = array(field(field(core_intent, "body")?, "locals")?)? + .first() + .ok_or(Error::InvalidArtifact)?; + let input_id = text_field(input_local, "id")?.to_owned(); + if text_field(input_local, "type")? != text_field(core_intent, "input")? { + return Err(Error::UnsupportedProgram); + } + let mut parser = Parser { + types: field(&core, "types")?, + coordinate: text_field(&core, "coordinate")?, + remaining: MAX_PROGRAM_NODES, + }; + let input_type = parser.ty(text_field(core_intent, "input")?, 0)?; + let output_type = parser.ty(text_field(core_intent, "output")?, 0)?; + let mut bindings = Vec::new(); + let mut projection_bindings = BTreeMap::new(); + for binding in array(field(target_intent, "pureBindings")?)? { + let local = field(binding, "binding")?; + let id = text_field(local, "id")?.to_owned(); + if id == input_id || bindings.iter().any(|binding: &Binding| binding.id == id) { + return Err(Error::InvalidArtifact); + } + if projection_bindings + .insert(text_field(binding, "id")?.to_owned(), id.clone()) + .is_some() + { + return Err(Error::InvalidArtifact); + } + bindings.push(Binding { + id, + ty: parser.ty(text_field(local, "type")?, 0)?, + value: parser.expr(field(binding, "value")?, 0)?, + }); + } + let result = parser.expr(field(target_intent, "result")?, 0)?; + let projected = parser.projection( + field(&projection, "expression")?, + &input_id, + &projection_bindings, + 0, + )?; + if result != projected { + return Err(Error::InvalidArtifact); + } + let mut constraints = Vec::new(); + for constraint in array(field(target_intent, "inputConstraints")?)? { + constraints.push(( + text_field(constraint, "coordinate")?.to_owned(), + parser.predicate(field(constraint, "predicate")?, 0)?, + )); + } + let helpers = helpers(&exports, &mut parser)?; + let budget = field(value, "budget_ceiling")?; + let core_budget = field(core_intent, "coreEvaluationBudget")?; + if field(target_intent, "coreEvaluationBudget")? != core_budget { + return Err(Error::InvalidArtifact); + } + for (package_key, core_key) in [ + ("max_steps", "maxSteps"), + ("max_allocated_bytes", "maxAllocatedBytes"), + ("max_output_bytes", "maxOutputBytes"), + ] { + if field(budget, package_key)? != field(core_budget, core_key)? { + return Err(Error::InvalidArtifact); + } + } + let limits = EvaluationLimits { + max_steps: host.max_steps.min(number(field(budget, "max_steps")?)?), + max_allocated_bytes: host + .max_allocated_bytes + .min(number(field(budget, "max_allocated_bytes")?)?), + max_output_bytes: host + .max_output_bytes + .min(number(field(budget, "max_output_bytes")?)?) + .min(number(field(&projection, "maxOutputBytes")?)?), + ..host + }; + Ok(Program { + input_id, + input_type, + output_type, + constraints, + bindings, + helpers, + result, + limits, + }) +} + +fn embedded(program: &Value, key: &str) -> Result { + decode(bytes(field(program, key)?)?).map_err(|_| Error::InvalidArtifact) +} + +fn helpers(exports: &Value, parser: &mut Parser<'_>) -> Result, Error> { + let mut result = BTreeMap::new(); + for helper in array(field(exports, "pureFunctions")?)? { + require_text(helper, "source", "edict")?; + let implementation = field(helper, "body")?; + let body = field(implementation, "body")?; + for (value, name) in [ + (helper, "parameterTypes"), + (helper, "typeParameters"), + (implementation, "params"), + (body, "bindings"), + (body, "locals"), + ] { + if !array(field(value, name)?)?.is_empty() { + return Err(Error::UnsupportedProgram); + } + } + let definition = Helper { + result: parser.expr(field(body, "result")?, 0)?, + ty: parser.ty(text_field(helper, "returnType")?, 0)?, + }; + if result + .insert(text_field(helper, "coordinate")?.to_owned(), definition) + .is_some() + { + return Err(Error::InvalidArtifact); + } + } + // Reject effects even when a malformed package claims an empty authority profile. + if !array(field(exports, "effects")?)?.is_empty() { + return Err(Error::UnsupportedProgram); + } + Ok(result) +} diff --git a/crates/warp-core/src/edict_pure/evaluate.rs b/crates/warp-core/src/edict_pure/evaluate.rs new file mode 100644 index 00000000..b3b1bc61 --- /dev/null +++ b/crates/warp-core/src/edict_pure/evaluate.rs @@ -0,0 +1,248 @@ +// SPDX-License-Identifier: Apache-2.0 +// © James Ross Ω FLYING•ROBOTS +use std::collections::BTreeMap; + +use echo_edict_canonical::{encode_canonical_cbor_v1 as encode, CanonicalValueV1 as Value}; + +use super::model::{Comparison, Expr, Helper, Predicate, Program, RuntimeType, MAX_DEPTH}; +use super::{EvaluationError as Error, EvaluationLimits, EvaluationResult}; + +// Fixed interpreter storage units; Rust layout and pointer width cannot alter cost. +const VALUE_CELL_BYTES: u64 = 64; + +struct Meter { + limits: EvaluationLimits, + steps: u64, + allocated: u64, +} + +impl Meter { + fn step(&mut self, depth: usize) -> Result<(), Error> { + if depth > MAX_DEPTH { + return Err(Error::UnsupportedProgram); + } + self.steps = self.steps.checked_add(1).ok_or(Error::StepBudgetExceeded)?; + if self.steps > self.limits.max_steps { + return Err(Error::StepBudgetExceeded); + } + Ok(()) + } + + fn allocate(&mut self, bytes: u64) -> Result<(), Error> { + self.allocated = self + .allocated + .checked_add(bytes) + .ok_or(Error::AllocationBudgetExceeded)?; + if self.allocated > self.limits.max_allocated_bytes { + return Err(Error::AllocationBudgetExceeded); + } + Ok(()) + } + + fn copy(&mut self, value: &Value) -> Result { + self.charge(value, 0)?; + Ok(value.clone()) + } + + fn charge(&mut self, value: &Value, depth: usize) -> Result<(), Error> { + self.step(depth)?; + self.allocate(VALUE_CELL_BYTES)?; + match value { + Value::Bytes(value) => self.allocate(value.len() as u64), + Value::Text(value) => self.allocate(value.len() as u64), + Value::Array(values) => { + for value in values { + self.charge(value, depth + 1)?; + } + Ok(()) + } + Value::Map(values) => { + for (key, value) in values { + self.charge(key, depth + 1)?; + self.charge(value, depth + 1)?; + } + Ok(()) + } + _ => Ok(()), + } + } +} + +pub(super) fn run(program: &Program, input: Value) -> Result { + let mut meter = Meter { + limits: program.limits, + steps: 0, + allocated: 0, + }; + validate(&input, &program.input_type, &mut meter, 0).map_err(|error| { + if error == Error::InvalidArtifact { + Error::InvalidInput + } else { + error + } + })?; + meter.charge(&input, 0)?; + let mut locals = BTreeMap::from([(program.input_id.clone(), input)]); + for (coordinate, constraint) in &program.constraints { + if !predicate(constraint, &locals, &program.helpers, &mut meter, 0)? { + return Err(Error::InputConstraintFailed(coordinate.clone())); + } + } + for binding in &program.bindings { + let value = expression(&binding.value, &locals, &program.helpers, &mut meter, 0)?; + validate(&value, &binding.ty, &mut meter, 0)?; + locals.insert(binding.id.clone(), value); + } + let result = expression(&program.result, &locals, &program.helpers, &mut meter, 0)?; + validate(&result, &program.output_type, &mut meter, 0)?; + // Encoding scratch is charged separately from the materialized result. + meter.charge(&result, 0)?; + let output = encode(&result).map_err(|_| Error::InvalidArtifact)?; + if output.len() as u64 > program.limits.max_output_bytes { + return Err(Error::OutputBudgetExceeded); + } + Ok(EvaluationResult { + output, + steps: meter.steps, + allocated_bytes: meter.allocated, + }) +} + +fn expression( + expr: &Expr, + locals: &BTreeMap, + helpers: &BTreeMap, + meter: &mut Meter, + depth: usize, +) -> Result { + meter.step(depth)?; + match expr { + Expr::Constant(value) => meter.copy(value), + Expr::Local(id) => meter.copy(locals.get(id).ok_or(Error::InvalidArtifact)?), + Expr::Field(base, name) => { + let record = expression(base, locals, helpers, meter, depth + 1)?; + let Value::Map(fields) = record else { + return Err(Error::InvalidArtifact); + }; + // Move the selected value, retaining the charge for all intermediate copies. + fields + .into_iter() + .find_map(|(key, value)| { + if matches!(key, Value::Text(key) if key == *name) { + Some(value) + } else { + None + } + }) + .ok_or(Error::InvalidArtifact) + } + Expr::Record(fields) => { + meter.allocate(VALUE_CELL_BYTES)?; + let mut values = Vec::new(); + for (key, value) in fields { + meter.allocate(VALUE_CELL_BYTES + key.len() as u64)?; + values.push(( + Value::Text(key.clone()), + expression(value, locals, helpers, meter, depth + 1)?, + )); + } + Ok(Value::Map(values)) + } + Expr::If(condition, yes, no) => { + let branch = if predicate(condition, locals, helpers, meter, depth + 1)? { + yes + } else { + no + }; + expression(branch, locals, helpers, meter, depth + 1) + } + Expr::Call(name) => { + let helper = helpers.get(name).ok_or(Error::UnsupportedProgram)?; + // A helper has its own lexical scope, never the caller's local bindings. + let value = expression(&helper.result, &BTreeMap::new(), helpers, meter, depth + 1)?; + validate(&value, &helper.ty, meter, depth + 1)?; + Ok(value) + } + } +} + +fn predicate( + predicate: &Predicate, + locals: &BTreeMap, + helpers: &BTreeMap, + meter: &mut Meter, + 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)?; + let (Value::Integer(left), Value::Integer(right)) = (left, right) else { + return Err(Error::UnsupportedProgram); + }; + Ok(match predicate.op { + Comparison::Equal => left == right, + Comparison::LessOrEqual => left <= right, + }) +} + +fn validate(value: &Value, ty: &RuntimeType, meter: &mut Meter, depth: usize) -> Result<(), Error> { + meter.step(depth)?; + match (value, ty) { + (Value::Integer(value), RuntimeType::Unsigned(max)) + if *value >= 0 && *value <= i128::from(*max) => + { + Ok(()) + } + (Value::Bytes(value), RuntimeType::Bytes { min, max }) + if (value.len() as u64) >= *min && (value.len() as u64) <= *max => + { + Ok(()) + } + (Value::Map(fields), RuntimeType::Record(types)) if fields.len() == types.len() => { + for (name, ty) in types { + let value = fields + .iter() + .find_map(|(key, value)| { + if matches!(key, Value::Text(key) if key == name) { + Some(value) + } else { + None + } + }) + .ok_or(Error::InvalidArtifact)?; + validate(value, ty, meter, depth + 1)?; + } + Ok(()) + } + _ => Err(Error::InvalidArtifact), + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn value_storage_meter_uses_architecture_independent_units() -> Result<(), Error> { + let mut meter = Meter { + limits: EvaluationLimits { + max_package_bytes: 1024, + max_input_bytes: 1024, + max_steps: 100, + max_allocated_bytes: 1024, + max_output_bytes: 1024, + }, + steps: 0, + allocated: 0, + }; + let value = Value::Map(vec![( + Value::Text("id".into()), + Value::Bytes(vec![1, 2, 3]), + )]); + meter.charge(&value, 0)?; + // Three fixed 64-byte value cells plus two key bytes and three data bytes. + assert_eq!(meter.allocated, 197); + assert_eq!(meter.steps, 3); + Ok(()) + } +} diff --git a/crates/warp-core/src/edict_pure/model.rs b/crates/warp-core/src/edict_pure/model.rs new file mode 100644 index 00000000..9e67add7 --- /dev/null +++ b/crates/warp-core/src/edict_pure/model.rs @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: Apache-2.0 +// © James Ross Ω FLYING•ROBOTS +use std::collections::BTreeMap; + +use echo_edict_canonical::CanonicalValueV1 as Value; + +use super::EvaluationLimits; + +pub(super) const MAX_DEPTH: usize = 64; +pub(super) const MAX_PROGRAM_NODES: usize = 65_536; +pub(super) const MAX_ARTIFACT_BYTES: usize = 16 * 1024 * 1024; + +#[derive(Debug, PartialEq, Eq)] +pub(super) enum Expr { + Constant(Value), + Local(String), + Field(Box, String), + Record(Vec<(String, Expr)>), + If(Box, Box, Box), + Call(String), +} + +#[derive(Debug, PartialEq, Eq)] +pub(super) struct Predicate { + pub op: Comparison, + pub left: Expr, + pub right: Expr, +} + +#[derive(Debug, PartialEq, Eq)] +pub(super) enum Comparison { + Equal, + LessOrEqual, +} + +pub(super) enum RuntimeType { + Unsigned(u64), + Bytes { min: u64, max: u64 }, + Record(Vec<(String, RuntimeType)>), +} + +pub(super) struct Binding { + pub id: String, + pub ty: RuntimeType, + pub value: Expr, +} + +pub(super) struct Helper { + pub result: Expr, + pub ty: RuntimeType, +} + +pub(super) struct Program { + pub input_id: String, + pub input_type: RuntimeType, + pub output_type: RuntimeType, + pub constraints: Vec<(String, Predicate)>, + pub bindings: Vec, + pub helpers: BTreeMap, + pub result: Expr, + pub limits: EvaluationLimits, +} diff --git a/crates/warp-core/src/edict_pure/syntax.rs b/crates/warp-core/src/edict_pure/syntax.rs new file mode 100644 index 00000000..b9f5e0cd --- /dev/null +++ b/crates/warp-core/src/edict_pure/syntax.rs @@ -0,0 +1,182 @@ +// SPDX-License-Identifier: Apache-2.0 +// © James Ross Ω FLYING•ROBOTS +use std::collections::BTreeMap; + +use echo_edict_canonical::CanonicalValueV1 as Value; + +use super::model::{Comparison, Expr, Predicate, RuntimeType, MAX_DEPTH}; +use super::values::{array, exact_fields, field, map, number, text, text_field}; +use super::EvaluationError as Error; + +pub(super) struct Parser<'a> { + pub types: &'a Value, + pub coordinate: &'a str, + pub remaining: usize, +} + +impl Parser<'_> { + fn enter(&mut self, depth: usize) -> Result<(), Error> { + if depth > MAX_DEPTH { + return Err(Error::UnsupportedProgram); + } + self.remaining = self + .remaining + .checked_sub(1) + .ok_or(Error::UnsupportedProgram)?; + Ok(()) + } + + pub fn ty(&mut self, name: &str, depth: usize) -> Result { + self.enter(depth)?; + if let Some(max) = match name { + "U32" => Some(u64::from(u32::MAX)), + "U64" => Some(u64::MAX), + _ => None, + } { + return Ok(RuntimeType::Unsigned(max)); + } + let name = name + .strip_prefix(self.coordinate) + .and_then(|name| name.strip_prefix('.')) + .unwrap_or(name); + let definition = field(self.types, name)?; + match text_field(definition, "kind")? { + "Nominal" => self.ty(text_field(definition, "representation")?, depth + 1), + "Bytes" => { + let min = field(definition, "min").map_or(Ok(0), number)?; + let max = number(field(definition, "max")?)?; + if min > max { + return Err(Error::InvalidArtifact); + } + Ok(RuntimeType::Bytes { min, max }) + } + "Record" => { + let mut fields = Vec::new(); + for (key, value) in map(field(definition, "fields")?)? { + fields.push((text(key)?.to_owned(), self.ty(text(value)?, depth + 1)?)); + } + Ok(RuntimeType::Record(fields)) + } + _ => Err(Error::UnsupportedProgram), + } + } + + pub fn expr(&mut self, value: &Value, depth: usize) -> Result { + self.enter(depth)?; + match text_field(value, "kind")? { + "local" => { + exact_fields(value, &["kind", "ref"])?; + Ok(Expr::Local( + text_field(field(value, "ref")?, "id")?.to_owned(), + )) + } + "field" => { + exact_fields(value, &["kind", "base", "field"])?; + Ok(Expr::Field( + Box::new(self.expr(field(value, "base")?, depth + 1)?), + text_field(value, "field")?.to_owned(), + )) + } + "const" => { + exact_fields(value, &["kind", "value"])?; + let literal = field(value, "value")?; + exact_fields(literal, &["kind", "value", "width"])?; + if text_field(literal, "kind")? != "int" { + return Err(Error::UnsupportedProgram); + } + let number = number(field(literal, "value")?)?; + match text_field(literal, "width")? { + "U32" if u32::try_from(number).is_ok() => {} + "U64" => {} + _ => return Err(Error::UnsupportedProgram), + } + Ok(Expr::Constant(Value::Integer(number.into()))) + } + "record" => { + exact_fields(value, &["kind", "fields"])?; + let mut fields = Vec::new(); + for (key, expression) in map(field(value, "fields")?)? { + fields.push((text(key)?.to_owned(), self.expr(expression, depth + 1)?)); + } + Ok(Expr::Record(fields)) + } + "if" => { + exact_fields(value, &["kind", "predicate", "then", "else"])?; + Ok(Expr::If( + Box::new(self.predicate(field(value, "predicate")?, depth + 1)?), + Box::new(self.expr(field(value, "then")?, depth + 1)?), + Box::new(self.expr(field(value, "else")?, depth + 1)?), + )) + } + "call" => { + exact_fields(value, &["kind", "callee", "args", "typeArgs"])?; + if !array(field(value, "args")?)?.is_empty() + || !array(field(value, "typeArgs")?)?.is_empty() + { + return Err(Error::UnsupportedProgram); + } + Ok(Expr::Call(text_field(value, "callee")?.to_owned())) + } + _ => Err(Error::UnsupportedProgram), + } + } + + pub fn predicate(&mut self, value: &Value, depth: usize) -> Result { + self.enter(depth)?; + exact_fields(value, &["kind", "op", "left", "right"])?; + if text_field(value, "kind")? != "compare" { + return Err(Error::UnsupportedProgram); + } + let op = match text_field(value, "op")? { + "==" => Comparison::Equal, + "<=" => Comparison::LessOrEqual, + _ => return Err(Error::UnsupportedProgram), + }; + Ok(Predicate { + op, + left: self.expr(field(value, "left")?, depth + 1)?, + right: self.expr(field(value, "right")?, depth + 1)?, + }) + } + + pub fn projection( + &mut self, + value: &Value, + input_id: &str, + bindings: &BTreeMap, + depth: usize, + ) -> Result { + self.enter(depth)?; + match text_field(value, "kind")? { + "record" => { + exact_fields(value, &["kind", "fields"])?; + let mut fields = Vec::new(); + for (key, expression) in map(field(value, "fields")?)? { + fields.push(( + text(key)?.to_owned(), + self.projection(expression, input_id, bindings, depth + 1)?, + )); + } + Ok(Expr::Record(fields)) + } + "source" => { + exact_fields(value, &["kind", "source", "path"])?; + let source = field(value, "source")?; + let id = match text_field(source, "kind")? { + "applicationInput" => input_id, + "pureBinding" => bindings + .get(text_field(source, "bindingId")?) + .ok_or(Error::InvalidArtifact)?, + _ => return Err(Error::UnsupportedProgram), + }; + let mut expression = Expr::Local(id.to_owned()); + for (index, segment) in array(field(value, "path")?)?.iter().enumerate() { + self.enter(depth + index + 1)?; + expression = Expr::Field(Box::new(expression), text(segment)?.to_owned()); + } + Ok(expression) + } + _ => Err(Error::UnsupportedProgram), + } + } +} diff --git a/crates/warp-core/src/edict_pure/values.rs b/crates/warp-core/src/edict_pure/values.rs new file mode 100644 index 00000000..80b2e3fe --- /dev/null +++ b/crates/warp-core/src/edict_pure/values.rs @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: Apache-2.0 +// © James Ross Ω FLYING•ROBOTS +use echo_edict_canonical::CanonicalValueV1 as Value; + +use super::EvaluationError as Error; + +pub(super) fn map(value: &Value) -> Result<&[(Value, Value)], Error> { + if let Value::Map(fields) = value { + Ok(fields) + } else { + Err(Error::InvalidArtifact) + } +} + +pub(super) fn field<'a>(value: &'a Value, name: &str) -> Result<&'a Value, Error> { + map(value)? + .iter() + .find_map(|(key, value)| { + if matches!(key, Value::Text(key) if key == name) { + Some(value) + } else { + None + } + }) + .ok_or(Error::InvalidArtifact) +} + +pub(super) fn text(value: &Value) -> Result<&str, Error> { + if let Value::Text(value) = value { + Ok(value) + } else { + Err(Error::InvalidArtifact) + } +} + +pub(super) fn text_field<'a>(value: &'a Value, name: &str) -> Result<&'a str, Error> { + text(field(value, name)?) +} + +pub(super) fn number(value: &Value) -> Result { + if let Value::Integer(value) = value { + u64::try_from(*value).map_err(|_| Error::InvalidArtifact) + } else { + Err(Error::InvalidArtifact) + } +} + +pub(super) fn bytes(value: &Value) -> Result<&[u8], Error> { + if let Value::Bytes(value) = value { + Ok(value) + } else { + Err(Error::InvalidArtifact) + } +} + +pub(super) fn array(value: &Value) -> Result<&[Value], Error> { + if let Value::Array(value) = value { + Ok(value) + } else { + Err(Error::InvalidArtifact) + } +} + +pub(super) fn exact_fields(value: &Value, names: &[&str]) -> Result<(), Error> { + let fields = map(value)?; + if fields.len() != names.len() || names.iter().any(|name| field(value, name).is_err()) { + return Err(Error::InvalidArtifact); + } + Ok(()) +} + +pub(super) fn require_text(value: &Value, name: &str, expected: &str) -> Result<(), Error> { + if text_field(value, name)? == expected { + Ok(()) + } else { + Err(Error::UnsupportedProgram) + } +} diff --git a/crates/warp-core/src/lib.rs b/crates/warp-core/src/lib.rs index ade5e6b7..13013ecc 100644 --- a/crates/warp-core/src/lib.rs +++ b/crates/warp-core/src/lib.rs @@ -66,6 +66,8 @@ mod dynamic_binding; allow(dead_code) )] mod echo_operation; +#[cfg(feature = "trusted_runtime")] +pub mod edict_pure; mod edict_target_ir; mod engine_impl; pub mod evidence; diff --git a/crates/warp-core/tests/edict_pure_evaluation_tests.rs b/crates/warp-core/tests/edict_pure_evaluation_tests.rs new file mode 100644 index 00000000..4cae9aa9 --- /dev/null +++ b/crates/warp-core/tests/edict_pure_evaluation_tests.rs @@ -0,0 +1,285 @@ +// SPDX-License-Identifier: Apache-2.0 +// © James Ross Ω FLYING•ROBOTS +//! Execute the exact externally compiled application and falsify its boundaries. +#![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_HEX: &str = + include_str!("fixtures/edict-pure-jedit/executable-operation-package.cbor.hex"); +const REPORT_HEX: &str = include_str!("fixtures/edict-pure-jedit/verification-report.cbor.hex"); +const PACKAGE_DIGEST: &str = "b9052d3c40878a9fcba7768be67c8dba50cf0f751682339dfcdd04155871415b"; + +fn package() -> Vec { + hex::decode(PACKAGE_HEX.trim()).unwrap() +} + +fn pin() -> [u8; 32] { + hex::decode(PACKAGE_DIGEST).unwrap().try_into().unwrap() +} + +fn limits() -> EvaluationLimits { + EvaluationLimits { + max_package_bytes: 32_768, + max_input_bytes: 2_097_152, + max_steps: 10_000, + max_allocated_bytes: 16_777_216, + max_output_bytes: 2_097_152, + } +} + +fn record(fields: impl IntoIterator) -> Value { + Value::Map( + fields + .into_iter() + .map(|(key, value)| (Value::Text(key.into()), value)) + .collect(), + ) +} + +fn input(start: u64, end: u64) -> Value { + record([ + ("bufferId", Value::Bytes(vec![1; 32])), + ("basisHeadId", Value::Bytes(vec![2; 32])), + ("startByte", Value::Integer(start.into())), + ("endByte", Value::Integer(end.into())), + ("replacement", Value::Bytes("λ\r\n".as_bytes().to_vec())), + ]) +} + +fn field<'a>(value: &'a Value, key: &str) -> &'a Value { + let Value::Map(fields) = value else { + panic!("expected record") + }; + &fields + .iter() + .find(|(name, _)| name == &Value::Text(key.into())) + .unwrap() + .1 +} + +fn set_field(value: &mut Value, key: &str, replacement: Value) { + let Value::Map(fields) = value else { + panic!("expected record") + }; + fields + .iter_mut() + .find(|(name, _)| name == &Value::Text(key.into())) + .unwrap() + .1 = replacement; +} + +#[test] +fn exact_jedit_compiler_package_executes_both_authored_branches_and_imported_helper() { + // A constant stub, a reversed predicate, or skipped helper body breaks this witness. + let package = package(); + assert_eq!( + digest("echo.operation-package/v1", &decode(&package).unwrap()).unwrap(), + pin() + ); + let report = decode(&hex::decode(REPORT_HEX.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, empty) in [(7, 7, 1), (7, 11, 0)] { + let supplied = encode(&input(start, end)).unwrap(); + let result = evaluate(&package, pin(), &supplied, limits()).unwrap(); + let expected = record([ + ("bufferId", Value::Bytes(vec![1; 32])), + ("basisHeadId", Value::Bytes(vec![2; 32])), + ("startByte", Value::Integer(start.into())), + ("endByte", Value::Integer(end.into())), + ("replacement", Value::Bytes("λ\r\n".as_bytes().to_vec())), + ("rangeIsEmpty", Value::Integer(empty)), + ("createdLeafCeiling", Value::Integer(4096)), + ]); + assert_eq!(result.output, encode(&expected).unwrap()); + assert_eq!( + result, + evaluate(&package, pin(), &supplied, limits()).unwrap() + ); + assert!(result.steps > 0); + assert!(result.allocated_bytes > 0); + } +} + +#[test] +fn authored_input_constraint_prevents_evaluation_of_reversed_range() { + assert_eq!( + evaluate(&package(), pin(), &encode(&input(11, 7)).unwrap(), limits()), + Err(EvaluationError::InputConstraintFailed("where.0".into())) + ); +} + +#[test] +fn runtime_validates_exact_nominal_representation_integer_and_record_bounds() { + for (name, value) in [ + ("bufferId", Value::Bytes(vec![1; 31])), + ("basisHeadId", Value::Bytes(vec![2; 33])), + ("startByte", Value::Integer(-1)), + ("endByte", Value::Text("11".into())), + ("replacement", Value::Bytes(vec![0; 1_048_577])), + ] { + let mut invalid = input(7, 11); + set_field(&mut invalid, name, value); + assert_eq!( + evaluate(&package(), pin(), &encode(&invalid).unwrap(), limits()), + Err(EvaluationError::InvalidInput), + "field {name}" + ); + } + let mut extra = input(7, 11); + let Value::Map(fields) = &mut extra else { + unreachable!() + }; + fields.push((Value::Text("extra".into()), Value::Null)); + assert_eq!( + evaluate(&package(), pin(), &encode(&extra).unwrap(), limits()), + Err(EvaluationError::InvalidInput) + ); +} + +#[test] +fn package_substitution_cannot_execute_under_the_verified_pin() { + let mut substituted = decode(&package()).unwrap(); + set_field( + &mut substituted, + "operation_coordinate", + Value::Text("other@1.operation".into()), + ); + assert_eq!( + evaluate( + &encode(&substituted).unwrap(), + pin(), + &encode(&input(0, 0)).unwrap(), + limits() + ), + Err(EvaluationError::PackageIdentityMismatch) + ); +} + +#[test] +fn host_limits_bound_decode_execution_allocation_and_output() { + let input = encode(&input(0, 0)).unwrap(); + let mut cases = Vec::new(); + let mut bound = limits(); + bound.max_package_bytes = 1; + cases.push((bound, EvaluationError::PackageTooLarge)); + let mut bound = limits(); + bound.max_input_bytes = 1; + cases.push((bound, EvaluationError::InputTooLarge)); + let mut bound = limits(); + bound.max_steps = 1; + cases.push((bound, EvaluationError::StepBudgetExceeded)); + let mut bound = limits(); + bound.max_allocated_bytes = 1; + cases.push((bound, EvaluationError::AllocationBudgetExceeded)); + let mut bound = limits(); + bound.max_output_bytes = 1; + cases.push((bound, EvaluationError::OutputBudgetExceeded)); + for (bound, expected) in cases { + assert_eq!(evaluate(&package(), pin(), &input, bound), Err(expected)); + } +} + +#[test] +fn public_compiler_source_mutation_changes_runtime_behavior() { + // This is newly compiled source, not a patched executable artifact. + let mutated = hex::decode( + include_str!("fixtures/edict-pure-jedit/mutated-executable-operation-package.cbor.hex") + .trim(), + ) + .unwrap(); + let mutated_pin: [u8; 32] = + hex::decode("1af8c0d9a872b46855138b36b49d10bf70e3b576d403c76b09953af079495f62") + .unwrap() + .try_into() + .unwrap(); + assert_ne!(mutated_pin, pin()); + let report = decode( + &hex::decode( + include_str!("fixtures/edict-pure-jedit/mutated-verification-report.cbor.hex").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(mutated_pin.to_vec()) + ]) + ); + for (end, wanted) in [(7, 2), (11, 0)] { + let output = evaluate( + &mutated, + mutated_pin, + &encode(&input(7, end)).unwrap(), + limits(), + ) + .unwrap(); + assert_eq!( + field(&decode(&output.output).unwrap(), "rangeIsEmpty"), + &Value::Integer(wanted) + ); + } + assert_eq!( + evaluate(&mutated, pin(), &encode(&input(7, 7)).unwrap(), limits()), + Err(EvaluationError::PackageIdentityMismatch) + ); +} + +#[test] +fn exact_budget_boundaries_and_noncanonical_input_are_enforced() { + let input = encode(&input(7, 11)).unwrap(); + let result = evaluate(&package(), pin(), &input, limits()).unwrap(); + let exact = EvaluationLimits { + max_steps: result.steps, + max_allocated_bytes: result.allocated_bytes, + max_output_bytes: result.output.len() as u64, + ..limits() + }; + assert_eq!(evaluate(&package(), pin(), &input, exact).unwrap(), result); + for (bound, error) in [ + ( + EvaluationLimits { + max_steps: exact.max_steps - 1, + ..exact + }, + EvaluationError::StepBudgetExceeded, + ), + ( + EvaluationLimits { + max_allocated_bytes: exact.max_allocated_bytes - 1, + ..exact + }, + EvaluationError::AllocationBudgetExceeded, + ), + ( + EvaluationLimits { + max_output_bytes: exact.max_output_bytes - 1, + ..exact + }, + EvaluationError::OutputBudgetExceeded, + ), + ] { + assert_eq!(evaluate(&package(), pin(), &input, bound), Err(error)); + } + let mut trailing = input; + trailing.push(0); + assert_eq!( + evaluate(&package(), pin(), &trailing, limits()), + Err(EvaluationError::InvalidInput) + ); +} diff --git a/crates/warp-core/tests/fixtures/edict-pure-jedit/README.md b/crates/warp-core/tests/fixtures/edict-pure-jedit/README.md new file mode 100644 index 00000000..c8417e1f --- /dev/null +++ b/crates/warp-core/tests/fixtures/edict-pure-jedit/README.md @@ -0,0 +1,73 @@ + + + +# Compiler-produced pure evaluation fixture + +These hex files retain the exact canonical bytes emitted by Jedit's public +Edict build on 2026-09-18. Hex is only a text carrier. The tests decode it before +passing the original bytes to Echo. Neither file was constructed by a fixture +builder or reconstructed from the Jedit schema or oracle. + +- Jedit source: `a894c7c4c6d150c0fb210d2e0ca4c27bf518b4c7` +- Application: `edict/replace-range/edict.application.json` +- Edict: `3f81f759e921a69b04fe8cf8e62e62f8f3dc7b7e` +- Echo provider: `49e9efb68001dfd78563d18bac9359a87671e431` +- Rust: `1.94.0`; Node: `22.23.1`; npm: `10.9.8` +- Package: 9,969 bytes, raw SHA-256 + `1860ab8a6cb9a4bfd63a1db99d1c2bc00aa53dae52a9d1998295654379a95d85` +- Report: 930 bytes, raw SHA-256 + `d96e5d21eecbc1e5bbf6ce76ab438d55cc8e74f6843121d4ffb0f4343e648267` +- Domain-framed package identity: + `sha256:b9052d3c40878a9fcba7768be67c8dba50cf0f751682339dfcdd04155871415b` + +Reproduce in the exact Jedit checkout with clean pinned compiler/provider +checkouts and the stated Node on PATH: + +```sh +EDICT_REPO=/path/to/pinned-edict ECHO_REPO=/path/to/pinned-echo \ + ./edict/replace-range/tests/build.sh +``` + +Compare each `.build/application/*.cbor` with its decoded hex carrier. The build +checks the full source closure, exact toolchain and provider component bytes, +separate accepted verification, and executable-subject identity. The input and +expected output in the Rust test are independently written literal values. + +This source returns a boundary record with a pure conditional and an imported +authored helper. It does not yet implement the rope algorithm. Evaluating it is +not graph mutation, installed invocation, a Tick, a Receipt, or WAL evidence. + +## Authored mutation control + +The `mutated-*.hex` carriers came from a separate copy of the same application. +The only authored change was `then 1u32` to `then 2u32` in +`src/ReplaceRange.edict`. Edict's public JSONL application build generated the +new executable package and accepted independent verification report. No emitted +Core, Target IR, package, or report bytes were edited. + +The deliberate source change makes the original expected value of 1 false at +runtime. Equal endpoints now produce 2, while unequal endpoints still produce 0. This catches an evaluator that returns fixture-specific values without +interpreting the retained program. + +- Mutated package raw SHA-256: + `9f8f87c461f8e4dea17f7d9c6ad1d7f1f012ef2102ac6ad96fd7632cabc4d716` +- Mutated report raw SHA-256: + `be8b97052fe25090b2e20300e7c00b1aa7def527d95f32e5b1f4ec436b5a8095` +- Mutated domain-framed package identity: + `sha256:1af8c0d9a872b46855138b36b49d10bf70e3b576d403c76b09953af079495f62` + +After changing the source in a disposable copy with the checked provider at +`.build/echo-provider`, submit this line to the same pinned Edict binary: + +```json +{ + "schema": "edict.compiler.settings/v1", + "type": "compilerSettings", + "operation": "build", + "application": "edict.application.json" +} +``` + +The original Jedit package-chain lock must reject this changed source. The +mutation control uses the public compiler directly and retains its new +identities; it does not update or bypass the original application's locks. diff --git a/crates/warp-core/tests/fixtures/edict-pure-jedit/executable-operation-package.cbor.hex b/crates/warp-core/tests/fixtures/edict-pure-jedit/executable-operation-package.cbor.hex new file mode 100644 index 00000000..34975b7b --- /dev/null +++ b/crates/warp-core/tests/fixtures/edict-pure-jedit/executable-operation-package.cbor.hex @@ -0,0 +1 @@ +aa66736368656d6178196563686f2e6f7065726174696f6e2d7061636b6167652f76316770726f6772616d59235ca7646b696e647821636f6d70696c65722d70726f64756365642d626f756e6465642d707572652f763166696e74656e746c7265706c61636552616e676566736368656d6178266563686f2e636f6d70696c65722d70726f64756365642d707572652d70726f6772616d2f76316d636f72655f6172746966616374590ca8a6657479706573a6715265706c61636552616e6765496e707574a2646b696e64665265636f7264666669656c6473a567656e644279746563553634686275666665724964756a656469742e7465787440312e427566666572496469737461727442797465635536346b6261736973486561644964736a656469742e7465787440312e4865616449646b7265706c6163656d656e74781d6a656469742e7465787440312e5265706c6163656d656e744279746573736a656469742e7465787440312e486561644964a3646b696e64674e6f6d696e616c68636f6e7472616374736a656469742e7465787440312e4865616449646e726570726573656e746174696f6e736a656469742e7465787440312e4e6f64654964736a656469742e7465787440312e4e6f64654964a3636d61781820636d696e1820646b696e64654279746573745265706c61636552616e6765426f756e64617279a2646b696e64665265636f7264666669656c6473a767656e644279746563553634686275666665724964756a656469742e7465787440312e427566666572496469737461727442797465635536346b6261736973486561644964736a656469742e7465787440312e4865616449646b7265706c6163656d656e74781d6a656469742e7465787440312e5265706c6163656d656e7442797465736c72616e67654973456d7074796355333272637265617465644c6561664365696c696e6763553634756a656469742e7465787440312e4275666665724964a3646b696e64674e6f6d696e616c68636f6e7472616374756a656469742e7465787440312e42756666657249646e726570726573656e746174696f6e736a656469742e7465787440312e4e6f64654964781d6a656469742e7465787440312e5265706c6163656d656e744279746573a2636d61781a00100000646b696e6465427974657367696d706f72747381a263726566a26269646c6a656469742e746578744031666469676573748266736861323536582095758c1605894672cc9069fde01bb8b6e11842b053102660c9cd4f4d6f34d64e646b696e64676c61777061636b67696e74656e7473a16c7265706c61636552616e6765a764626f6479a3656e6f64657382a3646b696e64636c65746576616c7565a4646172677380646b696e646463616c6c6663616c6c656578206a656469742e7465787440312e6d6178437265617465644c656166436f756e74687479706541726773806762696e64696e67a3626964676c6f63616c2e3064747970656355363469616c7068614e616d6567246c6f63616c30a3646b696e64636c65746576616c7565a464656c7365a2646b696e6465636f6e73746576616c7565a3646b696e6463696e746576616c75650065776964746863553332646b696e64626966647468656ea2646b696e6465636f6e73746576616c7565a3646b696e6463696e746576616c7565016577696474686355333269707265646963617465a4626f70623d3d646b696e6467636f6d70617265646c656674a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c6469737461727442797465657269676874a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c6467656e64427974656762696e64696e67a3626964676c6f63616c2e3164747970656355333269616c7068614e616d6567246c6f63616c31666c6f63616c7383a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730a3626964676c6f63616c2e3064747970656355363469616c7068614e616d6567246c6f63616c30a3626964676c6f63616c2e3164747970656355333269616c7068614e616d6567246c6f63616c3166726573756c74a2646b696e64667265636f7264666669656c6473a767656e6442797465a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c6467656e6442797465686275666665724964a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c6468627566666572496469737461727442797465a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c64697374617274427974656b6261736973486561644964a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646b62617369734865616449646b7265706c6163656d656e74a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646b7265706c6163656d656e746c72616e67654973456d707479a263726566a3626964676c6f63616c2e3164747970656355333269616c7068614e616d6567246c6f63616c31646b696e64656c6f63616c72637265617465644c6561664365696c696e67a263726566a3626964676c6f63616c2e3064747970656355363469616c7068614e616d6567246c6f63616c30646b696e64656c6f63616c656261736973a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646b626173697348656164496465696e707574782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e707574666f7574707574782f6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765426f756e6461727970696e707574436f6e73747261696e747381a366736f7572636565776865726569707265646963617465a4626f70623c3d646b696e6467636f6d70617265646c656674a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c6469737461727442797465657269676874a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c6467656e64427974656a636f6f7264696e6174656777686572652e3074636f72654576616c756174696f6e427564676574a3686d617853746570731a001000006e6d61784f757470757442797465731a00800000716d6178416c6c6f636174656442797465731a01000000781872657175697265644f7065726174696f6e50726f66696c65781f636f6e74696e75756d2e70726f66696c652e726561642d77726974652f76316a61706956657273696f6e6d65646963742e636f72652f76316a636f6f7264696e617465781a6a656469742e746578742e7265706c6163655f72616e6765403178187265717569726564436f72654361706162696c697469657380727461726765745f69725f61727469666163745909c5a6646b696e64707461726765744972417274696661637466646f6d61696e6f6563686f2e7370616e2d69722f763167696e74656e7473a16c7265706c61636552616e6765a8656261736973a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646b62617369734865616449646573746570738066726573756c74a2646b696e64667265636f7264666669656c6473a767656e6442797465a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c6467656e6442797465686275666665724964a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c6468627566666572496469737461727442797465a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c64697374617274427974656b6261736973486561644964a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646b62617369734865616449646b7265706c6163656d656e74a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646b7265706c6163656d656e746c72616e67654973456d707479a263726566a3626964676c6f63616c2e3164747970656355333269616c7068614e616d6567246c6f63616c31646b696e64656c6f63616c72637265617465644c6561664365696c696e67a263726566a3626964676c6f63616c2e3064747970656355363469616c7068614e616d6567246c6f63616c30646b696e64656c6f63616c6c7075726542696e64696e677382a3626964767265706c61636552616e67652e62696e64696e672e306576616c7565a4646172677380646b696e646463616c6c6663616c6c656578206a656469742e7465787440312e6d6178437265617465644c656166436f756e74687479706541726773806762696e64696e67a3626964676c6f63616c2e3064747970656355363469616c7068614e616d6567246c6f63616c30a3626964767265706c61636552616e67652e62696e64696e672e316576616c7565a464656c7365a2646b696e6465636f6e73746576616c7565a3646b696e6463696e746576616c75650065776964746863553332646b696e64626966647468656ea2646b696e6465636f6e73746576616c7565a3646b696e6463696e746576616c7565016577696474686355333269707265646963617465a4626f70623d3d646b696e6467636f6d70617265646c656674a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c6469737461727442797465657269676874a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c6467656e64427974656762696e64696e67a3626964676c6f63616c2e3164747970656355333269616c7068614e616d6567246c6f63616c316c726571756972656d656e74738070696e707574436f6e73747261696e747381a366736f7572636565776865726569707265646963617465a4626f70623c3d646b696e6467636f6d70617265646c656674a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c6469737461727442797465657269676874a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c6467656e64427974656a636f6f7264696e6174656777686572652e30706f7065726174696f6e50726f66696c65781f636f6e74696e75756d2e70726f66696c652e726561642d77726974652f763174636f72654576616c756174696f6e427564676574a3686d617853746570731a001000006e6d61784f757470757442797465731a00800000716d6178416c6c6f636174656442797465731a010000006d74617267657450726f66696c65a26269646a6563686f2e64706f403166646967657374826673686132353658202e2494121aecf5e6a2d920f5fb85408825d394765fad41484c416397c920fb046f73656d616e746963436c6f73757265a2686c61777061636b7381a26269646c6a656469742e746578744031666469676573748266736861323536582095758c1605894672cc9069fde01bb8b6e11842b053102660c9cd4f4d6f34d64e6a736f75726365436f7265a2626964781a6a656469742e746578742e7265706c6163655f72616e6765403166646967657374826673686132353658208150aeee1766bde5b2c416a3c9ef9dd4960bde140e9d1b190a966d00bbdf778774736f75726365436f7265436f6f7264696e617465781a6a656469742e746578742e7265706c6163655f72616e6765403178186c61777061636b5f6578706f7274735f617274696661637459093aa665747970657385a26a636f6f7264696e617465736a656469742e7465787440312e4e6f646549646a646566696e6974696f6e6f42797465733c65786163743d33323ea26a636f6f7264696e617465756a656469742e7465787440312e42756666657249646a646566696e6974696f6e781c4e6f6d696e616c3c6a656469742e7465787440312e4e6f646549643ea26a636f6f7264696e617465736a656469742e7465787440312e4865616449646a646566696e6974696f6e781c4e6f6d696e616c3c6a656469742e7465787440312e4e6f646549643ea26a636f6f7264696e617465781d6a656469742e7465787440312e5265706c6163656d656e7442797465736a646566696e6974696f6e7242797465733c6d61783d313034383537363ea26a636f6f7264696e617465781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6a646566696e6974696f6e6f537472696e673c6d61783d3235363e67656666656374738069636f6e7374616e747382a36474797065635536346576616c75651910006a636f6f7264696e617465781d6a656469742e7465787440312e6d6178437265617465644c6561766573a36474797065635536346576616c75651910006a636f6f7264696e617465781f6a656469742e7465787440312e6d6178437265617465644272616e636865736c6f62737472756374696f6e738aa36a636f6f7264696e617465781e6a656469742e7465787440312e52616e67654f72646572496e76616c69646d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736e646f6d61696e4d61707061626c65a36a636f6f7264696e617465781d6a656469742e7465787440312e52616e67654f75744f66426f756e64736d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736e646f6d61696e4d61707061626c65a36a636f6f7264696e61746578206a656469742e7465787440312e55746638426f756e64617279496e76616c69646d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736e646f6d61696e4d61707061626c65a36a636f6f7264696e617465716a656469742e7465787440312e4e6f4f706d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736e646f6d61696e4d61707061626c65a36a636f6f7264696e617465781e6a656469742e7465787440312e42617369734e6f7443616e6f6e6963616c6d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736e646f6d61696e4d61707061626c65a36a636f6f7264696e617465781f6a656469742e7465787440312e41726974686d657469634f766572666c6f776d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736e696e746567726974794661756c74a36a636f6f7264696e61746578186a656469742e7465787440312e466163744d697373696e676d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736d7265736f757263654661756c74a36a636f6f7264696e617465781a6a656469742e7465787440312e466163744d616c666f726d65646d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736e696e746567726974794661756c74a36a636f6f7264696e61746578246a656469742e7465787440312e436f6e74656e744964656e746974794d69736d617463686d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736e696e746567726974794661756c74a36a636f6f7264696e617465781a6a656469742e7465787440312e4d616c666f726d6564526f70656d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736e696e746567726974794661756c746d7075726546756e6374696f6e7381a864626f6479a264626f6479a3666c6f63616c738066726573756c74a2646b696e6465636f6e73746576616c7565a3646b696e6463696e746576616c7565191000657769647468635536346862696e64696e67738066706172616d738066736f757263656565646963746a636f6f7264696e61746578206a656469742e7465787440312e6d6178437265617465644c656166436f756e746a72657475726e54797065635536346c636f737454656d706c617465781f6a656469742e7465787440312e7265706c61636552616e67654275646765746e706172616d657465725479706573806e74797065506172616d6574657273807064657465726d696e69736d436c61737365746f74616c716f7065726174696f6e50726f66696c6573a178196a656469742e7465787440312e7265706c61636552616e6765a26d6f7074696354656d706c617465a6696f707469634b696e64736166666563745265696e746567726174696f6e6c626f756e646172794b696e64666166666563746d626173697354656d706c617465781b6a656469742e7465787440312e65786163744865616442617369736d737570706f7274506f6c696379781e6a656469742e7465787440312e6261736973426f756e64537570706f72746f6c6f7373446973706f736974696f6e756a656469742e7465787440312e6c6f73736c657373736170657274757265526571756972656d656e74a26372656678226a656469742e7465787440312e7265706c61636552616e6765466f6f747072696e74646b696e64781b6162737472616374466f6f747072696e744f626c69676174696f6e6f65666665637450726564696361746578206a656469742e7465787440312e7265706c61636552616e676545666665637473781a726573756c745f70726f6a656374696f6e5f61727469666163745902e6a566736368656d61781a65646963742e726573756c742d70726f6a656374696f6e2f76316a65787072657373696f6ea2646b696e64667265636f7264666669656c6473a767656e6442797465a3646b696e6466736f7572636564706174688167656e644279746566736f75726365a1646b696e64706170706c69636174696f6e496e707574686275666665724964a3646b696e6466736f7572636564706174688168627566666572496466736f75726365a1646b696e64706170706c69636174696f6e496e70757469737461727442797465a3646b696e6466736f757263656470617468816973746172744279746566736f75726365a1646b696e64706170706c69636174696f6e496e7075746b6261736973486561644964a3646b696e6466736f757263656470617468816b626173697348656164496466736f75726365a1646b696e64706170706c69636174696f6e496e7075746b7265706c6163656d656e74a3646b696e6466736f757263656470617468816b7265706c6163656d656e7466736f75726365a1646b696e64706170706c69636174696f6e496e7075746c72616e67654973456d707479a3646b696e6466736f7572636564706174688066736f75726365a2646b696e646b7075726542696e64696e676962696e64696e674964767265706c61636552616e67652e62696e64696e672e3172637265617465644c6561664365696c696e67a3646b696e6466736f7572636564706174688066736f75726365a2646b696e646b7075726542696e64696e676962696e64696e674964767265706c61636552616e67652e62696e64696e672e306a6f757470757454797065782f6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765426f756e646172796e6d61784f757470757442797465731a00800000736f7065726174696f6e436f6f7264696e61746578276a656469742e746578742e7265706c6163655f72616e676540312e7265706c61636552616e67656c7061636b6167655f6b696e647821636f6d70696c65722d70726f64756365642d626f756e6465642d707572652f76316e6275646765745f6365696c696e67a3696d61785f73746570731a00100000706d61785f6f75747075745f62797465731a00800000736d61785f616c6c6f63617465645f62797465731a010000007073656d616e7469635f636c6f73757265a86d636f72655f6964656e7469747958208150aeee1766bde5b2c416a3c9ef9dd4960bde140e9d1b190a966d00bbdf7787706c61777061636b5f6964656e74697479582095758c1605894672cc9069fde01bb8b6e11842b053102660c9cd4f4d6f34d64e726c61777061636b5f636f6f7264696e6174656c6a656469742e746578744031727461726765745f69725f6964656e7469747958202c18d7d5e7d3bf9689e66e7b04c07824641836f6e23ed8396099ca8e24e79ff97565646963745f736f757263655f6964656e746974795820e56d3e80e033c0a5195be6bb5e18d04f28e651587ec0645acd697719cf3c7081781a63616e6f6e6963616c5f6d65616e696e675f6964656e7469747958208150aeee1766bde5b2c416a3c9ef9dd4960bde140e9d1b190a966d00bbdf7787781b6170706c69636174696f6e5f736368656d615f6964656e7469747958201f436d717d3f349cc6f4c3431730ff4182d65c87fb6c1233692fc40fbd71bf02781d6170706c69636174696f6e5f736368656d615f636f6f7264696e617465756a656469742e746578742e6578706f7274732f7631746f7065726174696f6e5f636f6f7264696e61746578276a656469742e746578742e7265706c6163655f72616e676540312e7265706c61636552616e6765777461726765745f70726f66696c655f6964656e7469747958202e2494121aecf5e6a2d920f5fb85408825d394765fad41484c416397c920fb04781a617574686f726974795f70726f66696c655f6964656e746974795820fbaf54b61a71d54139a37955fe1bae42ee1d013f9aff2b09f546084fe3b3ced6781b666f6f747072696e745f636f6e74726163745f6964656e746974795820bf4da382443c8f8a740b3d28b77e3cfd8b39cb1608a9b885de59e1cb05d70365781c696e7465727072657465725f70726f66696c655f6964656e746974795820dc267bf35dc047a748593bbc5eaf6d9565b6206bfd84caf3cbe29653c6f34a76 diff --git a/crates/warp-core/tests/fixtures/edict-pure-jedit/mutated-executable-operation-package.cbor.hex b/crates/warp-core/tests/fixtures/edict-pure-jedit/mutated-executable-operation-package.cbor.hex new file mode 100644 index 00000000..0023eab7 --- /dev/null +++ b/crates/warp-core/tests/fixtures/edict-pure-jedit/mutated-executable-operation-package.cbor.hex @@ -0,0 +1 @@ +aa66736368656d6178196563686f2e6f7065726174696f6e2d7061636b6167652f76316770726f6772616d59235ca7646b696e647821636f6d70696c65722d70726f64756365642d626f756e6465642d707572652f763166696e74656e746c7265706c61636552616e676566736368656d6178266563686f2e636f6d70696c65722d70726f64756365642d707572652d70726f6772616d2f76316d636f72655f6172746966616374590ca8a6657479706573a6715265706c61636552616e6765496e707574a2646b696e64665265636f7264666669656c6473a567656e644279746563553634686275666665724964756a656469742e7465787440312e427566666572496469737461727442797465635536346b6261736973486561644964736a656469742e7465787440312e4865616449646b7265706c6163656d656e74781d6a656469742e7465787440312e5265706c6163656d656e744279746573736a656469742e7465787440312e486561644964a3646b696e64674e6f6d696e616c68636f6e7472616374736a656469742e7465787440312e4865616449646e726570726573656e746174696f6e736a656469742e7465787440312e4e6f64654964736a656469742e7465787440312e4e6f64654964a3636d61781820636d696e1820646b696e64654279746573745265706c61636552616e6765426f756e64617279a2646b696e64665265636f7264666669656c6473a767656e644279746563553634686275666665724964756a656469742e7465787440312e427566666572496469737461727442797465635536346b6261736973486561644964736a656469742e7465787440312e4865616449646b7265706c6163656d656e74781d6a656469742e7465787440312e5265706c6163656d656e7442797465736c72616e67654973456d7074796355333272637265617465644c6561664365696c696e6763553634756a656469742e7465787440312e4275666665724964a3646b696e64674e6f6d696e616c68636f6e7472616374756a656469742e7465787440312e42756666657249646e726570726573656e746174696f6e736a656469742e7465787440312e4e6f64654964781d6a656469742e7465787440312e5265706c6163656d656e744279746573a2636d61781a00100000646b696e6465427974657367696d706f72747381a263726566a26269646c6a656469742e746578744031666469676573748266736861323536582095758c1605894672cc9069fde01bb8b6e11842b053102660c9cd4f4d6f34d64e646b696e64676c61777061636b67696e74656e7473a16c7265706c61636552616e6765a764626f6479a3656e6f64657382a3646b696e64636c65746576616c7565a4646172677380646b696e646463616c6c6663616c6c656578206a656469742e7465787440312e6d6178437265617465644c656166436f756e74687479706541726773806762696e64696e67a3626964676c6f63616c2e3064747970656355363469616c7068614e616d6567246c6f63616c30a3646b696e64636c65746576616c7565a464656c7365a2646b696e6465636f6e73746576616c7565a3646b696e6463696e746576616c75650065776964746863553332646b696e64626966647468656ea2646b696e6465636f6e73746576616c7565a3646b696e6463696e746576616c7565026577696474686355333269707265646963617465a4626f70623d3d646b696e6467636f6d70617265646c656674a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c6469737461727442797465657269676874a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c6467656e64427974656762696e64696e67a3626964676c6f63616c2e3164747970656355333269616c7068614e616d6567246c6f63616c31666c6f63616c7383a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730a3626964676c6f63616c2e3064747970656355363469616c7068614e616d6567246c6f63616c30a3626964676c6f63616c2e3164747970656355333269616c7068614e616d6567246c6f63616c3166726573756c74a2646b696e64667265636f7264666669656c6473a767656e6442797465a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c6467656e6442797465686275666665724964a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c6468627566666572496469737461727442797465a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c64697374617274427974656b6261736973486561644964a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646b62617369734865616449646b7265706c6163656d656e74a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646b7265706c6163656d656e746c72616e67654973456d707479a263726566a3626964676c6f63616c2e3164747970656355333269616c7068614e616d6567246c6f63616c31646b696e64656c6f63616c72637265617465644c6561664365696c696e67a263726566a3626964676c6f63616c2e3064747970656355363469616c7068614e616d6567246c6f63616c30646b696e64656c6f63616c656261736973a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646b626173697348656164496465696e707574782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e707574666f7574707574782f6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765426f756e6461727970696e707574436f6e73747261696e747381a366736f7572636565776865726569707265646963617465a4626f70623c3d646b696e6467636f6d70617265646c656674a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c6469737461727442797465657269676874a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c6467656e64427974656a636f6f7264696e6174656777686572652e3074636f72654576616c756174696f6e427564676574a3686d617853746570731a001000006e6d61784f757470757442797465731a00800000716d6178416c6c6f636174656442797465731a01000000781872657175697265644f7065726174696f6e50726f66696c65781f636f6e74696e75756d2e70726f66696c652e726561642d77726974652f76316a61706956657273696f6e6d65646963742e636f72652f76316a636f6f7264696e617465781a6a656469742e746578742e7265706c6163655f72616e6765403178187265717569726564436f72654361706162696c697469657380727461726765745f69725f61727469666163745909c5a6646b696e64707461726765744972417274696661637466646f6d61696e6f6563686f2e7370616e2d69722f763167696e74656e7473a16c7265706c61636552616e6765a8656261736973a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646b62617369734865616449646573746570738066726573756c74a2646b696e64667265636f7264666669656c6473a767656e6442797465a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c6467656e6442797465686275666665724964a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c6468627566666572496469737461727442797465a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c64697374617274427974656b6261736973486561644964a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646b62617369734865616449646b7265706c6163656d656e74a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c646b7265706c6163656d656e746c72616e67654973456d707479a263726566a3626964676c6f63616c2e3164747970656355333269616c7068614e616d6567246c6f63616c31646b696e64656c6f63616c72637265617465644c6561664365696c696e67a263726566a3626964676c6f63616c2e3064747970656355363469616c7068614e616d6567246c6f63616c30646b696e64656c6f63616c6c7075726542696e64696e677382a3626964767265706c61636552616e67652e62696e64696e672e306576616c7565a4646172677380646b696e646463616c6c6663616c6c656578206a656469742e7465787440312e6d6178437265617465644c656166436f756e74687479706541726773806762696e64696e67a3626964676c6f63616c2e3064747970656355363469616c7068614e616d6567246c6f63616c30a3626964767265706c61636552616e67652e62696e64696e672e316576616c7565a464656c7365a2646b696e6465636f6e73746576616c7565a3646b696e6463696e746576616c75650065776964746863553332646b696e64626966647468656ea2646b696e6465636f6e73746576616c7565a3646b696e6463696e746576616c7565026577696474686355333269707265646963617465a4626f70623d3d646b696e6467636f6d70617265646c656674a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c6469737461727442797465657269676874a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c6467656e64427974656762696e64696e67a3626964676c6f63616c2e3164747970656355333269616c7068614e616d6567246c6f63616c316c726571756972656d656e74738070696e707574436f6e73747261696e747381a366736f7572636565776865726569707265646963617465a4626f70623c3d646b696e6467636f6d70617265646c656674a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c6469737461727442797465657269676874a36462617365a263726566a3626964656172672e306474797065782c6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765496e70757469616c7068614e616d65652461726730646b696e64656c6f63616c646b696e64656669656c64656669656c6467656e64427974656a636f6f7264696e6174656777686572652e30706f7065726174696f6e50726f66696c65781f636f6e74696e75756d2e70726f66696c652e726561642d77726974652f763174636f72654576616c756174696f6e427564676574a3686d617853746570731a001000006e6d61784f757470757442797465731a00800000716d6178416c6c6f636174656442797465731a010000006d74617267657450726f66696c65a26269646a6563686f2e64706f403166646967657374826673686132353658202e2494121aecf5e6a2d920f5fb85408825d394765fad41484c416397c920fb046f73656d616e746963436c6f73757265a2686c61777061636b7381a26269646c6a656469742e746578744031666469676573748266736861323536582095758c1605894672cc9069fde01bb8b6e11842b053102660c9cd4f4d6f34d64e6a736f75726365436f7265a2626964781a6a656469742e746578742e7265706c6163655f72616e676540316664696765737482667368613235365820177749ee3fa2977905ca96a83ece91e496cdde9fc1e01b5ccd64eb587813077974736f75726365436f7265436f6f7264696e617465781a6a656469742e746578742e7265706c6163655f72616e6765403178186c61777061636b5f6578706f7274735f617274696661637459093aa665747970657385a26a636f6f7264696e617465736a656469742e7465787440312e4e6f646549646a646566696e6974696f6e6f42797465733c65786163743d33323ea26a636f6f7264696e617465756a656469742e7465787440312e42756666657249646a646566696e6974696f6e781c4e6f6d696e616c3c6a656469742e7465787440312e4e6f646549643ea26a636f6f7264696e617465736a656469742e7465787440312e4865616449646a646566696e6974696f6e781c4e6f6d696e616c3c6a656469742e7465787440312e4e6f646549643ea26a636f6f7264696e617465781d6a656469742e7465787440312e5265706c6163656d656e7442797465736a646566696e6974696f6e7242797465733c6d61783d313034383537363ea26a636f6f7264696e617465781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6a646566696e6974696f6e6f537472696e673c6d61783d3235363e67656666656374738069636f6e7374616e747382a36474797065635536346576616c75651910006a636f6f7264696e617465781d6a656469742e7465787440312e6d6178437265617465644c6561766573a36474797065635536346576616c75651910006a636f6f7264696e617465781f6a656469742e7465787440312e6d6178437265617465644272616e636865736c6f62737472756374696f6e738aa36a636f6f7264696e617465781e6a656469742e7465787440312e52616e67654f72646572496e76616c69646d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736e646f6d61696e4d61707061626c65a36a636f6f7264696e617465781d6a656469742e7465787440312e52616e67654f75744f66426f756e64736d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736e646f6d61696e4d61707061626c65a36a636f6f7264696e61746578206a656469742e7465787440312e55746638426f756e64617279496e76616c69646d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736e646f6d61696e4d61707061626c65a36a636f6f7264696e617465716a656469742e7465787440312e4e6f4f706d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736e646f6d61696e4d61707061626c65a36a636f6f7264696e617465781e6a656469742e7465787440312e42617369734e6f7443616e6f6e6963616c6d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736e646f6d61696e4d61707061626c65a36a636f6f7264696e617465781f6a656469742e7465787440312e41726974686d657469634f766572666c6f776d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736e696e746567726974794661756c74a36a636f6f7264696e61746578186a656469742e7465787440312e466163744d697373696e676d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736d7265736f757263654661756c74a36a636f6f7264696e617465781a6a656469742e7465787440312e466163744d616c666f726d65646d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736e696e746567726974794661756c74a36a636f6f7264696e61746578246a656469742e7465787440312e436f6e74656e744964656e746974794d69736d617463686d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736e696e746567726974794661756c74a36a636f6f7264696e617465781a6a656469742e7465787440312e4d616c666f726d6564526f70656d7061796c6f6164536368656d61781e6a656469742e7465787440312e4f62737472756374696f6e44657461696c6e617574686f72697479436c6173736e696e746567726974794661756c746d7075726546756e6374696f6e7381a864626f6479a264626f6479a3666c6f63616c738066726573756c74a2646b696e6465636f6e73746576616c7565a3646b696e6463696e746576616c7565191000657769647468635536346862696e64696e67738066706172616d738066736f757263656565646963746a636f6f7264696e61746578206a656469742e7465787440312e6d6178437265617465644c656166436f756e746a72657475726e54797065635536346c636f737454656d706c617465781f6a656469742e7465787440312e7265706c61636552616e67654275646765746e706172616d657465725479706573806e74797065506172616d6574657273807064657465726d696e69736d436c61737365746f74616c716f7065726174696f6e50726f66696c6573a178196a656469742e7465787440312e7265706c61636552616e6765a26d6f7074696354656d706c617465a6696f707469634b696e64736166666563745265696e746567726174696f6e6c626f756e646172794b696e64666166666563746d626173697354656d706c617465781b6a656469742e7465787440312e65786163744865616442617369736d737570706f7274506f6c696379781e6a656469742e7465787440312e6261736973426f756e64537570706f72746f6c6f7373446973706f736974696f6e756a656469742e7465787440312e6c6f73736c657373736170657274757265526571756972656d656e74a26372656678226a656469742e7465787440312e7265706c61636552616e6765466f6f747072696e74646b696e64781b6162737472616374466f6f747072696e744f626c69676174696f6e6f65666665637450726564696361746578206a656469742e7465787440312e7265706c61636552616e676545666665637473781a726573756c745f70726f6a656374696f6e5f61727469666163745902e6a566736368656d61781a65646963742e726573756c742d70726f6a656374696f6e2f76316a65787072657373696f6ea2646b696e64667265636f7264666669656c6473a767656e6442797465a3646b696e6466736f7572636564706174688167656e644279746566736f75726365a1646b696e64706170706c69636174696f6e496e707574686275666665724964a3646b696e6466736f7572636564706174688168627566666572496466736f75726365a1646b696e64706170706c69636174696f6e496e70757469737461727442797465a3646b696e6466736f757263656470617468816973746172744279746566736f75726365a1646b696e64706170706c69636174696f6e496e7075746b6261736973486561644964a3646b696e6466736f757263656470617468816b626173697348656164496466736f75726365a1646b696e64706170706c69636174696f6e496e7075746b7265706c6163656d656e74a3646b696e6466736f757263656470617468816b7265706c6163656d656e7466736f75726365a1646b696e64706170706c69636174696f6e496e7075746c72616e67654973456d707479a3646b696e6466736f7572636564706174688066736f75726365a2646b696e646b7075726542696e64696e676962696e64696e674964767265706c61636552616e67652e62696e64696e672e3172637265617465644c6561664365696c696e67a3646b696e6466736f7572636564706174688066736f75726365a2646b696e646b7075726542696e64696e676962696e64696e674964767265706c61636552616e67652e62696e64696e672e306a6f757470757454797065782f6a656469742e746578742e7265706c6163655f72616e676540312e5265706c61636552616e6765426f756e646172796e6d61784f757470757442797465731a00800000736f7065726174696f6e436f6f7264696e61746578276a656469742e746578742e7265706c6163655f72616e676540312e7265706c61636552616e67656c7061636b6167655f6b696e647821636f6d70696c65722d70726f64756365642d626f756e6465642d707572652f76316e6275646765745f6365696c696e67a3696d61785f73746570731a00100000706d61785f6f75747075745f62797465731a00800000736d61785f616c6c6f63617465645f62797465731a010000007073656d616e7469635f636c6f73757265a86d636f72655f6964656e746974795820177749ee3fa2977905ca96a83ece91e496cdde9fc1e01b5ccd64eb5878130779706c61777061636b5f6964656e74697479582095758c1605894672cc9069fde01bb8b6e11842b053102660c9cd4f4d6f34d64e726c61777061636b5f636f6f7264696e6174656c6a656469742e746578744031727461726765745f69725f6964656e746974795820e2059c599a9420a80b1f42895cbc9c5c33e43fa281de046e06d3b56307fd84eb7565646963745f736f757263655f6964656e7469747958201786ee14987a692d46e69fb7999ceca0baadae62196fad917c43c34cdf3841c0781a63616e6f6e6963616c5f6d65616e696e675f6964656e746974795820177749ee3fa2977905ca96a83ece91e496cdde9fc1e01b5ccd64eb5878130779781b6170706c69636174696f6e5f736368656d615f6964656e7469747958201f436d717d3f349cc6f4c3431730ff4182d65c87fb6c1233692fc40fbd71bf02781d6170706c69636174696f6e5f736368656d615f636f6f7264696e617465756a656469742e746578742e6578706f7274732f7631746f7065726174696f6e5f636f6f7264696e61746578276a656469742e746578742e7265706c6163655f72616e676540312e7265706c61636552616e6765777461726765745f70726f66696c655f6964656e7469747958202e2494121aecf5e6a2d920f5fb85408825d394765fad41484c416397c920fb04781a617574686f726974795f70726f66696c655f6964656e746974795820fbaf54b61a71d54139a37955fe1bae42ee1d013f9aff2b09f546084fe3b3ced6781b666f6f747072696e745f636f6e74726163745f6964656e746974795820bf4da382443c8f8a740b3d28b77e3cfd8b39cb1608a9b885de59e1cb05d70365781c696e7465727072657465725f70726f66696c655f6964656e746974795820dc267bf35dc047a748593bbc5eaf6d9565b6206bfd84caf3cbe29653c6f34a76 diff --git a/crates/warp-core/tests/fixtures/edict-pure-jedit/mutated-verification-report.cbor.hex b/crates/warp-core/tests/fixtures/edict-pure-jedit/mutated-verification-report.cbor.hex new file mode 100644 index 00000000..48c3b894 --- /dev/null +++ b/crates/warp-core/tests/fixtures/edict-pure-jedit/mutated-verification-report.cbor.hex @@ -0,0 +1 @@ +a8676f7574636f6d65686163636570746564677061636b616765a2626964782165786563757461626c652d6f7065726174696f6e2d7061636b6167652e6563686f66646967657374826673686132353658201af8c0d9a872b46855138b36b49d10bf70e3b576d403c76b09953af079495f62687461726765744972a26269646f6563686f2e7370616e2d69722f76316664696765737482667368613235365820e2059c599a9420a80b1f42895cbc9c5c33e43fa281de046e06d3b56307fd84eb6a61706956657273696f6e78296563686f2e6f7065726174696f6e2d7061636b6167652d76657269666965722d7265706f72742f76316d646961676e6f73746963416269a26269647465646963742e646961676e6f73746963732f7631666469676573748266736861323536582028fd72a98223153982ca084c29dbb1b2d430623967ab3b6db9d7fee668e614b96f646961676e6f737469634279746573407165786563757461626c655375626a656374a2656279746573590151a4677061636b616765a2626964782165786563757461626c652d6f7065726174696f6e2d7061636b6167652e6563686f66646967657374826673686132353658201af8c0d9a872b46855138b36b49d10bf70e3b576d403c76b09953af079495f62687461726765744972a26269646f6563686f2e7370616e2d69722f76316664696765737482667368613235365820e2059c599a9420a80b1f42895cbc9c5c33e43fa281de046e06d3b56307fd84eb6a61706956657273696f6e781a6563686f2e65786563757461626c652d7375626a6563742f7631781b6170706c69636174696f6e526573756c7450726f6a656374696f6ea262696478276a656469742e746578742e7265706c6163655f72616e676540312e7265706c61636552616e67656664696765737482667368613235365820f804baa01c357e5ed54e86f752ea7f8201e454ad0b47c10813fde8c7dc2aeba6697265666572656e6365a2626964781a6563686f2e65786563757461626c652d7375626a6563742f763166646967657374826673686132353658204002188e5e98375205acb1aa6a55cf2645797ef76bdc0d9e6dbd6fcc036d719e781b6170706c69636174696f6e526573756c7450726f6a656374696f6ea262696478276a656469742e746578742e7265706c6163655f72616e676540312e7265706c61636552616e67656664696765737482667368613235365820f804baa01c357e5ed54e86f752ea7f8201e454ad0b47c10813fde8c7dc2aeba6 diff --git a/crates/warp-core/tests/fixtures/edict-pure-jedit/verification-report.cbor.hex b/crates/warp-core/tests/fixtures/edict-pure-jedit/verification-report.cbor.hex new file mode 100644 index 00000000..0af8e73d --- /dev/null +++ b/crates/warp-core/tests/fixtures/edict-pure-jedit/verification-report.cbor.hex @@ -0,0 +1 @@ +a8676f7574636f6d65686163636570746564677061636b616765a2626964782165786563757461626c652d6f7065726174696f6e2d7061636b6167652e6563686f6664696765737482667368613235365820b9052d3c40878a9fcba7768be67c8dba50cf0f751682339dfcdd04155871415b687461726765744972a26269646f6563686f2e7370616e2d69722f763166646967657374826673686132353658202c18d7d5e7d3bf9689e66e7b04c07824641836f6e23ed8396099ca8e24e79ff96a61706956657273696f6e78296563686f2e6f7065726174696f6e2d7061636b6167652d76657269666965722d7265706f72742f76316d646961676e6f73746963416269a26269647465646963742e646961676e6f73746963732f7631666469676573748266736861323536582028fd72a98223153982ca084c29dbb1b2d430623967ab3b6db9d7fee668e614b96f646961676e6f737469634279746573407165786563757461626c655375626a656374a2656279746573590151a4677061636b616765a2626964782165786563757461626c652d6f7065726174696f6e2d7061636b6167652e6563686f6664696765737482667368613235365820b9052d3c40878a9fcba7768be67c8dba50cf0f751682339dfcdd04155871415b687461726765744972a26269646f6563686f2e7370616e2d69722f763166646967657374826673686132353658202c18d7d5e7d3bf9689e66e7b04c07824641836f6e23ed8396099ca8e24e79ff96a61706956657273696f6e781a6563686f2e65786563757461626c652d7375626a6563742f7631781b6170706c69636174696f6e526573756c7450726f6a656374696f6ea262696478276a656469742e746578742e7265706c6163655f72616e676540312e7265706c61636552616e67656664696765737482667368613235365820f804baa01c357e5ed54e86f752ea7f8201e454ad0b47c10813fde8c7dc2aeba6697265666572656e6365a2626964781a6563686f2e65786563757461626c652d7375626a6563742f7631666469676573748266736861323536582093d1c2ee6b9798648f2706ef6ffbb0c426afd886331d23d452605fbc3bcdaccb781b6170706c69636174696f6e526573756c7450726f6a656374696f6ea262696478276a656469742e746578742e7265706c6163655f72616e676540312e7265706c61636552616e67656664696765737482667368613235365820f804baa01c357e5ed54e86f752ea7f8201e454ad0b47c10813fde8c7dc2aeba6 diff --git a/docs/architecture/application-contract-hosting.md b/docs/architecture/application-contract-hosting.md index 69846d52..f7c38c65 100644 --- a/docs/architecture/application-contract-hosting.md +++ b/docs/architecture/application-contract-hosting.md @@ -172,6 +172,53 @@ independently reconstructs that relation. No runtime evaluator, installation, graph mutation, Tick settlement, or application-specific Echo branch follows from package acceptance. +### Bounded pure evaluation + +The trusted-host `warp_core::edict_pure::evaluate` function now computes an +ordinary value from an exact compiler-produced pure package and canonical +input. The host supplies the package digest from an independently verified, +authorized release. The evaluator checks that pin before decoding executable +meaning. A caller-supplied digest or accepted-report-shaped value does not +establish authorization. This function has no graph, scheduler, filesystem, +clock, native callback, or WAL access and produces no Tick or Receipt. + +The interpreter implements the generic subset demanded by the first real +compiler witness: unsigned integer constants, records, locals, field access, +integer equality and ordering, lazy conditionals, and zero-argument authored +pure helpers. Calls resolve opaque 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, +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. + +Host ceilings intersect the package's declared step, allocation, and output +budgets. Each expression, predicate, runtime type visit, and copied value node +costs one step. Storage accounting charges a fixed 64-byte cell per materialized +value node plus text and byte payload lengths, cumulatively including copies +and result-encoding scratch. These interpreter units are independent of Rust +layout and pointer width; they are not a report of physical allocator usage. +Package and input decoding have separate host byte apertures capped at 16 MiB, +the canonical decoder's node limit, and a 64-level interpreter depth limit. +Syntax and type expansion share a 65,536-node decode budget. Decode and code +storage are bounded by those admission apertures, outside execution accounting. + +The executable witness is +[`edict_pure_evaluation_tests.rs`](../../crates/warp-core/tests/edict_pure_evaluation_tests.rs). +It consumes retained exact external compiler output, checks both authored +branches and a helper result, and proves that a separately compiled source +mutation changes the runtime result. Its fixture retains separate verifier +reports and reproduction coordinates. Reversed input ordering, invalid runtime +representations, package substitution, noncanonical input, and exhausted host +budgets produce errors without returning an application result. + +This refines the pure-package boundary above and depends on its independently +verified artifact closure. It does not extend the installed operation lifecycle +in [ADR 0023](../adr/0023-admitted-executable-operation-packages.md). Generic +effectful execution and its settlement evidence remain tracked by +[issue #684](https://github.com/flyingrobots/echo/issues/684). + The slice exposes no application matcher, executor, or footprint callback. A generic provider lowerer now emits the package from exact Edict source, Core, lawpack, exports, adapter, target-configuration, and Target IR artifacts, and a diff --git a/scripts/verify-local.sh b/scripts/verify-local.sh index ef8fc503..4fdb0468 100755 --- a/scripts/verify-local.sh +++ b/scripts/verify-local.sh @@ -1138,6 +1138,9 @@ pre_push_feature_string_for_file() { local file="$2" case "${crate}:${file}" in + warp-core:crates/warp-core/src/edict_pure.rs|warp-core:crates/warp-core/src/edict_pure/*.rs) + printf '%s\n' "trusted_runtime" + ;; warp-core:crates/warp-core/src/trusted_runtime_host.rs) printf '%s\n' "native_rule_bootstrap,trusted_runtime" ;; @@ -1175,7 +1178,7 @@ pre_push_feature_string_for_test_target() { warp-core:parallel_parallel_exec) printf '%s\n' "delta_validate" ;; - warp-core:scheduler_fault_recovery_authority) + warp-core:scheduler_fault_recovery_authority|warp-core:edict_pure_evaluation_tests) printf '%s\n' "trusted_runtime" ;; warp-math:determinism_policy_tests) @@ -1380,6 +1383,10 @@ prepare_warp_core_scope() { while IFS= read -r file; do [[ -z "$file" ]] && continue 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/*) + append_unique "edict_pure_evaluation_tests" FULL_SCOPE_WARP_CORE_EXTRA_TESTS + append_unique "edict_pure_evaluation_tests" FULL_SCOPE_WARP_CORE_CLIPPY_TESTS + ;; crates/warp-core/tests/*.rs) local test_name test_name="$(basename "$file" .rs)"