feat(v1): harden typed runtime boundaries

Elect one canonical EffectBatch codec, remove the parallel postcard API, and strengthen fail-closed host, form, sync, WASM, macro, generated-contract, and test-harness proofs with mutation-driven coverage.

req: wire/008

req: wire/009

req: wire/010

req: push/008

req: client_local/015

req: client_local/016

req: client_local/017

req: client_local/018

req: client_local/019

req: sync/024

req: sync/025

req: sync/026

req: sync/027

req: sync/028

req: sync/029

req: test/020

req: test/021
This commit is contained in:
slhx agent
2026-07-16 22:27:28 +02:00
parent e7211df4c5
commit e9ced4e0c1
19 changed files with 1529 additions and 198 deletions
+93 -1
View File
@@ -468,6 +468,28 @@ mod tests {
native_shell_host_profile("ios-android-webview-test")
}
#[test]
fn capability_names_and_standard_profile_identity_are_stable() {
let names = [
(Capability::Haptics, "haptics"),
(Capability::Microphone, "microphone"),
(Capability::Camera, "camera"),
(Capability::Share, "share"),
(Capability::SecureStorage, "secure_storage"),
(Capability::Notifications, "notifications"),
(Capability::Clipboard, "clipboard"),
(Capability::FilePicker, "file_picker"),
(Capability::Geolocation, "geolocation"),
(Capability::custom("vendor.camera"), "vendor.camera"),
];
for (capability, expected) in names {
assert_eq!(capability.as_str(), expected);
}
assert_eq!(web_host().name, "browser-pwa");
// req: host/001 req: host/004
}
#[test]
fn browser_host_js_is_a_thin_host_adapter_not_a_dom_runtime() {
// req: host/001 req: host/002 req: host/005
@@ -509,6 +531,37 @@ mod tests {
assert_eq!(manifest.check(&web_host()), Ok(()));
}
#[test]
fn manifest_and_host_support_require_the_exact_capability_shape() {
let wrong_shape_host = HostProfile::new(
"wrong-shape",
[CapabilityUse::new(Capability::Share, CapabilityShape::Fire)],
);
let wrong_capability_host = HostProfile::new(
"wrong-capability",
[CapabilityUse::new(
Capability::Haptics,
CapabilityShape::Request,
)],
);
let manifest = CapabilityManifest::new([CapabilityUse::new(
Capability::Share,
CapabilityShape::Request,
)]);
assert!(!wrong_shape_host.supports(&Capability::Share, CapabilityShape::Request));
assert!(!wrong_capability_host.supports(&Capability::Share, CapabilityShape::Request));
assert_eq!(
manifest.check(&wrong_shape_host),
Err(HostCheckError::UnsupportedCapability {
capability: Capability::Share,
shape: CapabilityShape::Request,
host: "wrong-shape".into(),
})
);
// req: host/001 req: host/004
}
#[test]
fn host_calls_must_be_declared_and_supported() {
// req: host/001 req: host/004
@@ -516,12 +569,38 @@ mod tests {
Capability::Share,
CapabilityShape::Request,
)]);
let payload = SharePayload::text("log");
assert_eq!(
payload,
SharePayload {
title: None,
text: Some("log".into()),
url: None,
}
);
let call = HostCall::Share {
id: HostCallId::new("share-1"),
payload: SharePayload::text("log"),
payload,
};
assert_eq!(manifest.validate_call(&web_host(), &call), Ok(()));
let unsupported_host = HostProfile::new("offline-shell", []);
let unsupported = manifest
.validate_call(&unsupported_host, &call)
.expect_err("declared calls still require host support");
assert_eq!(
unsupported,
HostCheckError::UnsupportedCapability {
capability: Capability::Share,
shape: CapabilityShape::Request,
host: "offline-shell".into(),
}
);
assert_eq!(
unsupported.to_string(),
"host `offline-shell` does not support capability `share` with shape Request"
);
let haptic = HostCall::Haptic {
id: HostCallId::new("tap"),
pattern: HapticPattern::Success,
@@ -584,6 +663,19 @@ mod tests {
}
}
#[test]
fn host_failure_builders_preserve_call_context() {
let failure = HostFailure::new(HostFailureKind::Timeout, "host timed out")
.with_id(HostCallId::new("share-1"))
.with_capability(Capability::Share);
assert_eq!(failure.id, Some(HostCallId::new("share-1")));
assert_eq!(failure.capability, Some(Capability::Share));
assert_eq!(failure.kind, HostFailureKind::Timeout);
assert_eq!(failure.message, "host timed out");
// req: host/002 req: host/005
}
#[test]
fn web_pwa_host_result_routes_through_app_code_before_hemx_effect() {
// req: host/001 req: host/002 req: host/005