Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@
artifact hash, schema id, operation id, and requirements digest before
storing admission requirements internally and returning an opaque
`OpticArtifactHandle`.
- `warp-core` now has an optic invocation admission skeleton that resolves
registered artifact handles internally and obstructs unknown handles,
operation mismatches, and registered-handle invocations without capability
presentation. Admission outcomes are must-use, and placeholder capability
presentations still obstruct until real grant validation exists. The
registration and invocation regression fixtures avoid `expect(...)` so
all-target Clippy remains clean.
- Echo-owned WASM package boundary tooling: `scripts/build-warp-wasm-package.sh`
now builds `crates/warp-wasm/pkg` with the bundler target and the package
export smoke test imports `crates/warp-wasm/pkg/rmg_wasm.js` to verify the
Expand Down
6 changes: 4 additions & 2 deletions crates/warp-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,8 +248,10 @@ pub use optic::{
StagedIntent, StagedIntentReason, WitnessBasis, WorldlineHeadOptic,
};
pub use optic_artifact::{
OpticAdmissionRequirements, OpticArtifact, OpticArtifactHandle, OpticArtifactOperation,
OpticArtifactRegistrationError, OpticArtifactRegistry, OpticRegistrationDescriptor,
OpticAdmissionRequirements, OpticApertureRequest, OpticArtifact, OpticArtifactHandle,
OpticArtifactOperation, OpticArtifactRegistrationError, OpticArtifactRegistry,
OpticBasisRequest, OpticCapabilityPresentation, OpticInvocation,
OpticInvocationAdmissionOutcome, OpticInvocationObstruction, OpticRegistrationDescriptor,
RegisteredOpticArtifact, OPTIC_ARTIFACT_HANDLE_KIND,
};
pub use playback::{CursorReceipt, TruthFrame, TruthSink};
Expand Down
105 changes: 101 additions & 4 deletions crates/warp-core/src/optic_artifact.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
// © James Ross Ω FLYING•ROBOTS <https://github.com/flyingrobots>
//! Echo-owned registry for Wesley-compiled optic artifacts.
//!
//! This module intentionally stops at registration. It does not admit
//! invocations, validate capability grants, issue admission tickets, or execute
//! runtime work. The only authority proven here is that Echo accepted and
//! stored a specific Wesley artifact identity and its admission requirements.
//! This module owns optic artifact registration and the first admission-only
//! invocation gate. [`OpticArtifactRegistry::admit_optic_invocation`] resolves
//! handles internally, checks operation identity, and obstructs missing or
//! placeholder authority without validating grants, issuing admission tickets,
//! emitting law witnesses, or executing runtime work.

use std::collections::BTreeMap;

Expand Down Expand Up @@ -103,6 +104,70 @@ pub struct RegisteredOpticArtifact {
pub requirements: OpticAdmissionRequirements,
}

/// Opaque basis request bytes supplied at optic invocation time.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct OpticBasisRequest {
/// Request bytes interpreted only below Echo's runtime admission boundary.
pub bytes: Vec<u8>,
}

/// Opaque aperture request bytes supplied at optic invocation time.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct OpticApertureRequest {
/// Request bytes interpreted only below Echo's runtime admission boundary.
pub bytes: Vec<u8>,
}

/// Placeholder capability presentation supplied at optic invocation time.
///
/// This v0 shape is intentionally not sufficient to authorize invocation. It
/// exists only so the admission skeleton can name the future presentation slot
/// without inventing grant validation semantics.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct OpticCapabilityPresentation {
/// Presentation identity supplied by the caller.
pub presentation_id: String,
}

/// Runtime invocation request against a registered optic artifact.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct OpticInvocation {
/// Echo-owned runtime-local artifact handle.
pub artifact_handle: OpticArtifactHandle,
/// Operation id the caller intends to invoke.
pub operation_id: String,
/// Digest of canonical invocation variable bytes.
pub canonical_variables_digest: Vec<u8>,
/// Requested causal basis for the invocation.
pub basis_request: OpticBasisRequest,
/// Requested aperture for the invocation.
pub aperture_request: OpticApertureRequest,
/// Caller authority presentation. Registration alone is not authority.
pub capability_presentation: Option<OpticCapabilityPresentation>,
}

/// Admission obstruction for an optic invocation.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum OpticInvocationObstruction {
/// Echo did not issue or cannot resolve the artifact handle.
UnknownHandle,
/// The invocation operation id does not match the registered artifact.
OperationMismatch,
/// The invocation does not carry authority to use the registered artifact.
MissingCapability,
/// A placeholder presentation was supplied, but real grant validation does
/// not exist in this slice.
CapabilityValidationUnavailable,
}

/// Admission outcome for a v0 optic invocation skeleton.
#[must_use = "optic invocation admission outcomes carry obstructions that must be handled"]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum OpticInvocationAdmissionOutcome {
/// Echo obstructed the invocation before runtime execution.
Obstructed(OpticInvocationObstruction),
}

/// Registration and lookup errors for Echo optic artifact handles.
#[derive(Clone, Debug, Error, PartialEq, Eq)]
pub enum OpticArtifactRegistrationError {
Expand Down Expand Up @@ -187,6 +252,38 @@ impl OpticArtifactRegistry {
.ok_or(OpticArtifactRegistrationError::UnknownHandle)
}

/// Admits or obstructs an invocation against a registered optic artifact.
///
/// This v0 skeleton intentionally has no success path. It proves that Echo
/// resolves handles internally and that a registered handle is not authority.
#[must_use = "optic invocation admission outcomes carry obstructions that must be handled"]
pub fn admit_optic_invocation(
Comment thread
coderabbitai[bot] marked this conversation as resolved.
&self,
invocation: &OpticInvocation,
) -> OpticInvocationAdmissionOutcome {
let Ok(registered) = self.resolve_optic_artifact_handle(&invocation.artifact_handle) else {
return OpticInvocationAdmissionOutcome::Obstructed(
OpticInvocationObstruction::UnknownHandle,
);
};

if invocation.operation_id != registered.operation_id {
return OpticInvocationAdmissionOutcome::Obstructed(
OpticInvocationObstruction::OperationMismatch,
);
}

if invocation.capability_presentation.is_none() {
return OpticInvocationAdmissionOutcome::Obstructed(
OpticInvocationObstruction::MissingCapability,
);
}

OpticInvocationAdmissionOutcome::Obstructed(
OpticInvocationObstruction::CapabilityValidationUnavailable,
)
}

/// Returns the number of registered artifacts.
#[must_use]
pub fn len(&self) -> usize {
Expand Down
77 changes: 50 additions & 27 deletions crates/warp-core/tests/optic_artifact_registry_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,127 +32,150 @@ fn fixture_descriptor() -> OpticRegistrationDescriptor {
}
}

fn registration_err_or_panic<T>(
result: Result<T, OpticArtifactRegistrationError>,
context: &str,
) -> Result<OpticArtifactRegistrationError, String> {
match result {
Ok(_) => Err(format!("{context}: expected registration error")),
Err(err) => Ok(err),
}
}

#[test]
fn optic_artifact_registry_registers_wesley_descriptor_and_resolves_handle() {
fn optic_artifact_registry_registers_wesley_descriptor_and_resolves_handle() -> Result<(), String> {
let artifact = fixture_artifact();
let descriptor = fixture_descriptor();
let mut registry = OpticArtifactRegistry::new();

let handle = registry
.register_optic_artifact(artifact.clone(), descriptor)
.expect("fixture descriptor should register");
.map_err(|err| format!("fixture descriptor should register: {err:?}"))?;

assert_eq!(handle.kind, "optic-artifact-handle");
assert!(!handle.id.is_empty());

let registered = registry
.resolve_optic_artifact_handle(&handle)
.expect("fresh handle should resolve");
.map_err(|err| format!("fresh handle should resolve: {err:?}"))?;

assert_eq!(registered.artifact_id, artifact.artifact_id);
assert_eq!(registered.artifact_hash, artifact.artifact_hash);
assert_eq!(registered.schema_id, artifact.schema_id);
assert_eq!(registered.operation_id, artifact.operation.operation_id);
assert_eq!(registered.requirements_digest, artifact.requirements_digest);
assert_eq!(registered.requirements, artifact.requirements);
Ok(())
}

#[test]
fn optic_artifact_registry_rejects_tampered_artifact_hash() {
fn optic_artifact_registry_rejects_tampered_artifact_hash() -> Result<(), String> {
let artifact = fixture_artifact();
let mut descriptor = fixture_descriptor();
descriptor.artifact_hash = "artifact-hash:tampered".to_owned();
let mut registry = OpticArtifactRegistry::new();

let err = registry
.register_optic_artifact(artifact, descriptor)
.expect_err("tampered artifact hash should reject");
let err = registration_err_or_panic(
registry.register_optic_artifact(artifact, descriptor),
"tampered artifact hash should reject",
)?;

assert!(matches!(
err,
OpticArtifactRegistrationError::ArtifactHashMismatch
));
Ok(())
}

#[test]
fn optic_artifact_registry_rejects_mismatched_artifact_id() {
fn optic_artifact_registry_rejects_mismatched_artifact_id() -> Result<(), String> {
let artifact = fixture_artifact();
let mut descriptor = fixture_descriptor();
descriptor.artifact_id = "optic-artifact:other".to_owned();
let mut registry = OpticArtifactRegistry::new();

let err = registry
.register_optic_artifact(artifact, descriptor)
.expect_err("mismatched artifact id should reject");
let err = registration_err_or_panic(
registry.register_optic_artifact(artifact, descriptor),
"mismatched artifact id should reject",
)?;

assert!(matches!(
err,
OpticArtifactRegistrationError::ArtifactIdMismatch
));
Ok(())
}

#[test]
fn optic_artifact_registry_rejects_tampered_requirements_digest() {
fn optic_artifact_registry_rejects_tampered_requirements_digest() -> Result<(), String> {
let artifact = fixture_artifact();
let mut descriptor = fixture_descriptor();
descriptor.requirements_digest = "requirements-digest:tampered".to_owned();
let mut registry = OpticArtifactRegistry::new();

let err = registry
.register_optic_artifact(artifact, descriptor)
.expect_err("tampered requirements digest should reject");
let err = registration_err_or_panic(
registry.register_optic_artifact(artifact, descriptor),
"tampered requirements digest should reject",
)?;

assert!(matches!(
err,
OpticArtifactRegistrationError::RequirementsDigestMismatch
));
Ok(())
}

#[test]
fn optic_artifact_registry_rejects_mismatched_operation_id() {
fn optic_artifact_registry_rejects_mismatched_operation_id() -> Result<(), String> {
let artifact = fixture_artifact();
let mut descriptor = fixture_descriptor();
descriptor.operation_id = "operation:replaceRange:v0".to_owned();
let mut registry = OpticArtifactRegistry::new();

let err = registry
.register_optic_artifact(artifact, descriptor)
.expect_err("mismatched operation id should reject");
let err = registration_err_or_panic(
registry.register_optic_artifact(artifact, descriptor),
"mismatched operation id should reject",
)?;

assert!(matches!(
err,
OpticArtifactRegistrationError::OperationIdMismatch
));
Ok(())
}

#[test]
fn optic_artifact_registry_rejects_mismatched_schema_id() {
fn optic_artifact_registry_rejects_mismatched_schema_id() -> Result<(), String> {
let artifact = fixture_artifact();
let mut descriptor = fixture_descriptor();
descriptor.schema_id = "schema:other:v0".to_owned();
let mut registry = OpticArtifactRegistry::new();

let err = registry
.register_optic_artifact(artifact, descriptor)
.expect_err("mismatched schema id should reject");
let err = registration_err_or_panic(
registry.register_optic_artifact(artifact, descriptor),
"mismatched schema id should reject",
)?;

assert!(matches!(
err,
OpticArtifactRegistrationError::SchemaIdMismatch
));
Ok(())
}

#[test]
fn optic_artifact_registry_rejects_unknown_handle_lookup() {
fn optic_artifact_registry_rejects_unknown_handle_lookup() -> Result<(), String> {
let registry = OpticArtifactRegistry::new();
let handle = OpticArtifactHandle {
kind: "optic-artifact-handle".to_owned(),
id: "unregistered-handle".to_owned(),
};

let err = registry
.resolve_optic_artifact_handle(&handle)
.expect_err("unknown handle should reject");
let err = registration_err_or_panic(
registry.resolve_optic_artifact_handle(&handle),
"unknown handle should reject",
)?;

assert!(matches!(err, OpticArtifactRegistrationError::UnknownHandle));
Ok(())
}
Loading
Loading