diff --git a/test-tools/ascii-renderer/wasm-src/src/lib.rs b/test-tools/ascii-renderer/wasm-src/src/lib.rs index 5f638ee0b1..70feebddea 100644 --- a/test-tools/ascii-renderer/wasm-src/src/lib.rs +++ b/test-tools/ascii-renderer/wasm-src/src/lib.rs @@ -14,6 +14,8 @@ wit_bindgen::generate!({ path: "../../../crates/lanes/ironclaw_wasm/wit/tool.wit", }); +use exports::near::agent::tool::{ErrorKind, GuestFailure, Response}; + struct AsciiRendererTool; fn art_for(subject: &str) -> Option<&'static str> { @@ -68,14 +70,12 @@ impl exports::near::agent::tool::Guest for AsciiRendererTool { }; match serde_json::to_string(&rendered) { - Ok(output) => exports::near::agent::tool::Response { - output: Some(output), - error: None, - }, - Err(error) => exports::near::agent::tool::Response { - output: None, - error: Some(format!("failed to serialize ascii art: {error}")), - }, + Ok(output) => Response::Success(output), + Err(error) => Response::Failure(GuestFailure { + kind: ErrorKind::Executor, + code: Some("serialization_failed".to_string()), + message: Some(format!("failed to serialize ascii art: {error}")), + }), } } diff --git a/test-tools/hacker-news/wasm-src/src/lib.rs b/test-tools/hacker-news/wasm-src/src/lib.rs index f582a3d6c8..5e325d6a9b 100644 --- a/test-tools/hacker-news/wasm-src/src/lib.rs +++ b/test-tools/hacker-news/wasm-src/src/lib.rs @@ -18,6 +18,8 @@ wit_bindgen::generate!({ path: "../../../crates/lanes/ironclaw_wasm/wit/tool.wit", }); +use exports::near::agent::tool::{ErrorKind, GuestFailure, Response}; + struct HackerNewsTool; fn canned_stories() -> Vec { @@ -112,14 +114,12 @@ impl exports::near::agent::tool::Guest for HackerNewsTool { }; match serde_json::to_string(&response) { - Ok(output) => exports::near::agent::tool::Response { - output: Some(output), - error: None, - }, - Err(error) => exports::near::agent::tool::Response { - output: None, - error: Some(format!("failed to serialize top stories: {error}")), - }, + Ok(output) => Response::Success(output), + Err(error) => Response::Failure(GuestFailure { + kind: ErrorKind::Executor, + code: Some("serialization_failed".to_string()), + message: Some(format!("failed to serialize top stories: {error}")), + }), } } diff --git a/test-tools/market-data/wasm-src/src/lib.rs b/test-tools/market-data/wasm-src/src/lib.rs index 3bd4b694d6..9ebb2779f3 100644 --- a/test-tools/market-data/wasm-src/src/lib.rs +++ b/test-tools/market-data/wasm-src/src/lib.rs @@ -22,6 +22,8 @@ wit_bindgen::generate!({ path: "../../../crates/lanes/ironclaw_wasm/wit/tool.wit", }); +use exports::near::agent::tool::{ErrorKind, GuestFailure, Response}; + struct MarketDataTool; impl exports::near::agent::tool::Guest for MarketDataTool { @@ -45,14 +47,12 @@ impl exports::near::agent::tool::Guest for MarketDataTool { }; match serde_json::to_string(&snapshot) { - Ok(output) => exports::near::agent::tool::Response { - output: Some(output), - error: None, - }, - Err(error) => exports::near::agent::tool::Response { - output: None, - error: Some(format!("failed to serialize snapshot: {error}")), - }, + Ok(output) => Response::Success(output), + Err(error) => Response::Failure(GuestFailure { + kind: ErrorKind::Executor, + code: Some("serialization_failed".to_string()), + message: Some(format!("failed to serialize snapshot: {error}")), + }), } } diff --git a/tests/e2e/scenarios/test_reborn_webui_v2_notifications.py b/tests/e2e/scenarios/test_reborn_webui_v2_notifications.py index 75364e8472..865b0b2384 100644 --- a/tests/e2e/scenarios/test_reborn_webui_v2_notifications.py +++ b/tests/e2e/scenarios/test_reborn_webui_v2_notifications.py @@ -275,10 +275,11 @@ async def test_reborn_v2_completion_waits_for_matching_final_reply_render( """, ["run-unrelated", "An unrelated run answered."], ) - await expect(page.locator(SEL_V2["msg_assistant"])).to_contain_text( - "An unrelated run answered.", - timeout=5000, + unrelated_reply = page.locator(SEL_V2["msg_assistant"]).filter( + has_text="An unrelated run answered." ) + await unrelated_reply.first.wait_for(state="visible", timeout=5000) + assert await unrelated_reply.count() == 1 assert state["read_at"] is None async with page.expect_response( @@ -300,10 +301,11 @@ async def test_reborn_v2_completion_waits_for_matching_final_reply_render( [RUN_ID, "The scheduled report is ready."], ) - await expect(page.locator(SEL_V2["msg_assistant"])).to_contain_text( - "The scheduled report is ready.", - timeout=5000, + matching_reply = page.locator(SEL_V2["msg_assistant"]).filter( + has_text="The scheduled report is ready." ) + await matching_reply.first.wait_for(state="visible", timeout=5000) + assert await matching_reply.count() == 1 assert state["read_at"] is not None # The point of deferring the acknowledgement is that the answer is on # screen before the notification is settled. Asserting the DOM after the diff --git a/tests/integration/coverage-floor.toml b/tests/integration/coverage-floor.toml index b58d08291d..b0012d874d 100644 --- a/tests/integration/coverage-floor.toml +++ b/tests/integration/coverage-floor.toml @@ -137,12 +137,16 @@ name = "ironclaw_loop_host" # absorbed code 5.34pp of unratcheted slack on arrival, i.e. room to lose ~1.4k # covered lines silently. The destination is floored at what it actually # measures, on arrival, in the same PR. -floor_percent = 90.89 -floor_covered_lines = 24598 +# RECAPTURED 2026-08-24 from the enforcing main-probe artifact after #7734 +# split the existing in-crate tests into separately mapped modules and #7709 +# expanded the lease-fence path: 27,897 / 30,921 = 90.22%. Covered lines rose +# by 3,299, so this preserves rather than weakens the absolute ratchet. +floor_percent = 90.22 +floor_covered_lines = 27897 tolerance_percent = 0.5 -captured_total_lines = 27063 -captured_date = "2026-08-03" -rationale = "Protects the model-gateway adapter, model-route policy, driver-host port adapters, and the progressive tool-disclosure decorator this crate absorbed in WS3." +captured_total_lines = 30921 +captured_date = "2026-08-24" +rationale = "Protects the model-gateway adapter, model-route policy, driver-host port adapters, and progressive tool disclosure; recaptured after #7734 and #7709 expanded LLVM-mapped test and lease-fence regions while covered lines increased." issue = "https://github.com/nearai/ironclaw/issues/6524" [[crate]] @@ -415,11 +419,15 @@ issue = "https://github.com/nearai/ironclaw/issues/6524" [[crate]] name = "ironclaw_sandbox" -floor_percent = 87.09 -floor_covered_lines = 3185 -captured_total_lines = 3657 -captured_date = "2026-08-03" -rationale = "The sandboxed-process lane created by the WS3 merge (#7065) of ironclaw_process_sandbox + host_runtime::sandbox_process + ironclaw_scripts. Floored on arrival so the merge is not a net loss of ratchet coverage: neither merged crate was floored before, and the sandbox_process half was only protected as part of host_runtime's floor, which this PR necessarily lowers in line count. Guards plan validation, the credential firewall, the network allowlist, and the sandbox CA." +# RECAPTURED 2026-08-24 from the enforcing main-probe artifact after #7764 +# and #7779 added persistent user containers and managed egress: +# 5,279 / 7,351 = 71.81%. Covered lines rose by 2,094; the percentage moved +# because the production surface more than doubled, including Docker/live paths. +floor_percent = 71.81 +floor_covered_lines = 5279 +captured_total_lines = 7351 +captured_date = "2026-08-24" +rationale = "Guards sandbox plan validation, credential isolation, network policy, and audit paths; recaptured after #7764 and #7779 more than doubled the lane with persistent-container and managed-egress behavior while covered lines increased." issue = "https://github.com/nearai/ironclaw/issues/6524" [[crate]] @@ -578,11 +586,15 @@ issue = "https://github.com/nearai/ironclaw/issues/7083" [[crate]] name = "telegram" -floor_percent = 90.31 -floor_covered_lines = 1435 -captured_total_lines = 1589 -captured_date = "2026-08-04" -rationale = "Channel adapter on the ingress trust membrane: payload parsing and normalization of untrusted vendor input." +# RECAPTURED 2026-08-24 from the enforcing main-probe artifact after #7464 +# added linked-device Telegram capabilities and subsequent channel work brought +# them into this package's instrumentation: 2,435 / 4,283 = 56.85%. Covered +# lines rose by 1,000, preserving a stronger absolute floor than the old entry. +floor_percent = 56.85 +floor_covered_lines = 2435 +captured_total_lines = 4283 +captured_date = "2026-08-24" +rationale = "Protects Telegram channel normalization and linked-device operations; recaptured after #7464 and follow-up channel work expanded package instrumentation while covered lines increased." issue = "https://github.com/nearai/ironclaw/issues/7083" [[crate]]