1pub mod macros;
18
19pub(crate) mod args;
20
21mod agent_sessions;
22pub mod agent_state;
23pub(crate) mod agents;
24pub(crate) mod agents_daemon;
25mod approval_review_policy;
26mod artifact_emit;
27pub(crate) mod assemble;
28pub mod asset_paths;
29mod bytes;
30mod calendar;
31mod channel_guardrails;
32mod channels;
33pub(crate) mod clock;
34pub(crate) mod collections;
35mod command_policy;
36pub(crate) mod compaction;
37#[cfg(feature = "compression")]
38mod compression;
39mod concurrency;
40pub(crate) use concurrency::cancelled_vm_error;
41mod connectors;
42mod cookies;
43mod cron;
44mod crypto;
45mod csv;
46mod datetime;
47mod diff;
48pub(crate) use datetime::date_dict_from_millis;
49#[cfg(feature = "content")]
50mod document;
51mod durable_step;
52mod event_log;
53pub use event_log::mint_hypothesis_native_attestation;
54mod external_agent;
55pub(crate) mod files;
56mod flow;
57pub(crate) mod fs;
58mod git;
59pub(crate) mod git_topology;
60mod grounding;
61pub(crate) mod harn_entry;
62pub(crate) mod hitl;
63mod hitl_read;
64pub mod host;
65pub mod http_response;
66pub(crate) mod io;
67mod iter;
68pub(crate) mod json;
69mod json_query;
70pub(crate) mod json_repair;
71pub(crate) mod json_stream;
72mod jsonrpc;
73mod junit;
74mod lifecycle_receipts;
75mod logging;
76pub mod long_running;
77mod math;
78pub(crate) use math::call_seeded_random_method;
79pub(crate) mod memory;
80mod monitors;
81mod multipart;
82mod net;
83mod net_policy;
84mod oauth_dynreg;
85mod oauth_storage;
86pub(crate) mod observability;
87mod package_snapshot;
88pub(crate) use package_snapshot::PackageSnapshotRegistry;
89mod path;
90pub(crate) mod path_scope_guard;
91pub(crate) mod pool;
92mod portable;
93#[cfg(feature = "postgres")]
94mod postgres;
95#[cfg(feature = "postgres")]
96pub use postgres::install_shared_pool_registry;
97pub(crate) mod canonical_store;
98pub mod process;
99pub(crate) mod process_spawn;
100mod project;
101mod project_catalog;
102mod project_enrich;
103mod regex;
104mod review;
105mod runtime_scope;
106pub(crate) mod sandbox;
107pub mod secret_scan;
108pub(crate) mod session_change;
109pub(crate) mod session_store;
110pub(crate) mod session_wal_watch;
111mod sets;
112pub(crate) mod shapes;
113mod skills;
114#[cfg(feature = "sqlite")]
115mod sqlite;
116pub(crate) mod strings;
117pub(crate) mod supervisor;
118pub mod template;
119mod testbench;
120mod testing;
121mod timing;
122pub mod token_redaction;
123pub(crate) mod tool_hooks;
124mod tool_projection;
125pub(crate) mod tools;
126pub mod tracing;
127mod transcript_compact;
128pub(crate) mod transcript_project;
129mod triggers_stdlib;
130mod tui;
131mod types;
132mod url_parse;
133mod vision;
134pub(crate) mod waitpoint;
135#[cfg(feature = "content")]
136mod web;
137pub mod workflow_messages;
138pub(crate) mod xml;
139
140use crate::http::register_http_builtins;
141use crate::llm::register_llm_builtins;
142use crate::mcp::register_mcp_builtins;
143use crate::mcp_server::register_mcp_server_builtins;
144use crate::vm::Vm;
145
146pub(crate) use crate::schema::{json_to_vm_value, schema_result_value};
147pub(crate) fn set_thread_source_dir(dir: &std::path::Path) {
148 process::set_thread_source_dir(dir);
149}
150
151pub fn register_core_stdlib(vm: &mut Vm) {
153 approval_review_policy::register_approval_review_policy_builtins(vm);
154 types::register_type_builtins(vm);
155 math::register_math_builtins(vm);
156 strings::register_string_builtins(vm);
157 json::register_json_builtins(vm);
158 json_stream::register_json_stream_builtins(vm);
159 xml::register_xml_builtins(vm);
160 datetime::register_datetime_builtins(vm);
161 diff::register_diff_builtins(vm);
162 #[cfg(feature = "content")]
163 document::register_document_builtins(vm);
164 calendar::register_calendar_builtins(vm);
165 cron::register_cron_builtins(vm);
166 regex::register_regex_builtins(vm);
167 bytes::register_bytes_builtins(vm);
168 #[cfg(feature = "compression")]
169 compression::register_compression_builtins(vm);
170 command_policy::register_command_policy_builtins(vm);
171 runtime_scope::register_runtime_scope_builtins(vm);
172 crypto::register_crypto_builtins(vm);
173 csv::register_csv_builtins(vm);
174 junit::register_junit_builtins(vm);
175 multipart::register_multipart_builtins(vm);
176 url_parse::register_url_builtins(vm);
177 #[cfg(feature = "content")]
178 web::register_web_builtins(vm);
179 cookies::register_cookie_builtins(vm);
180 path::register_path_helper_builtins(vm);
181 sets::register_set_builtins(vm);
182 collections::register_collection_builtins(vm);
183 iter::register_iter_builtins(vm);
184 event_log::register_event_log_builtins(vm);
185 durable_step::register_durable_step_builtins(vm);
186 channels::register_channel_builtins(vm);
187 channel_guardrails::register_channel_guardrail_builtins(vm);
188 shapes::register_shape_builtins(vm);
189 testing::register_testing_builtins(vm);
190 flow::register_flow_builtins(vm);
191 lifecycle_receipts::register_lifecycle_receipt_builtins(vm);
192 net_policy::register_net_policy_builtins(vm);
193 http_response::register_http_response_builtins(vm);
194 portable::register_portable_builtins(vm);
195}
196
197pub fn register_io_stdlib(vm: &mut Vm) {
199 io::register_io_builtins(vm);
200 host::register_host_builtins(vm);
201 fs::register_fs_builtins(vm);
202 package_snapshot::register_package_snapshot_builtins(vm);
203 files::register_file_builtins(vm);
204 git::register_git_builtins(vm);
205 vision::register_vision_builtins(vm);
206 agent_state::register_agent_state_builtins(vm);
207 memory::register_memory_builtins(vm);
208 session_store::register_session_store_builtins(vm);
209 net::register_net_builtins(vm);
210 process::register_process_builtins(vm);
211 process::register_path_builtins(vm);
212 sandbox::register_sandbox_builtins(vm);
213 clock::register_clock_builtins(vm);
216 crate::durable_rate_limit::register_durable_rate_limit_builtins(vm);
217 testbench::register_testbench_builtins(vm);
218 project::register_project_builtins(vm);
219 grounding::register_grounding_builtins(vm);
220 tracing::register_tracing_builtins(vm);
221 observability::register_observability_builtins(vm);
222 timing::register_timing_builtins(vm);
223 tui::register_tui_builtins(vm);
224}
225
226fn register_agent_stdlib_before_llm(vm: &mut Vm) {
227 concurrency::register_concurrency_builtins(vm);
228 connectors::register_connector_builtins(vm);
229 review::register_review_builtins(vm);
230 secret_scan::register_secret_scan_builtins(vm);
231 tools::register_tool_builtins(vm);
232 tool_projection::register_tool_projection_builtins(vm);
233 tool_hooks::register_tool_hooks_builtins(vm);
234 crate::composition::register_composition_builtins(vm);
235 skills::register_skill_builtins(vm);
236 agents_daemon::register_daemon_builtins(vm);
237 triggers_stdlib::register_trigger_builtins(vm);
238 #[cfg(feature = "postgres")]
239 postgres::register_postgres_builtins(vm);
240 #[cfg(feature = "sqlite")]
241 sqlite::register_sqlite_builtins(vm);
242 monitors::register_monitor_builtins(vm);
243 hitl::register_hitl_builtins(vm);
244 hitl_read::register_hitl_read_builtins(vm);
245 waitpoint::register_waitpoint_builtins(vm);
246 supervisor::register_supervisor_builtins(vm);
247 agents::register_agent_builtins(vm);
248 pool::register_pool_builtins(vm);
249 oauth_storage::register_oauth_storage_builtins(vm);
250 oauth_dynreg::register_oauth_dynreg_builtins(vm);
251 token_redaction::register_token_redaction_builtins(vm);
252 agent_sessions::register_agent_session_builtins(vm);
253 artifact_emit::register_artifact_emit_builtins(vm);
254 external_agent::register_external_agent_builtins(vm);
255 path_scope_guard::register_path_scope_guard_builtins(vm);
256 workflow_messages::register_workflow_message_builtins(vm);
257 transcript_compact::register_transcript_compaction_builtins(vm);
258 compaction::register_compaction_builtins(vm);
259 transcript_project::register_transcript_projection_builtins(vm);
260 assemble::register_assemble_context_builtin(vm);
261 crate::egress::register_egress_builtins(vm);
262 crate::security::register_security_builtins(vm);
263 register_http_builtins(vm);
264 jsonrpc::register_jsonrpc_builtins(vm);
265}
266
267fn register_agent_stdlib_after_llm(vm: &mut Vm) {
268 register_mcp_builtins(vm);
269 register_mcp_server_builtins(vm);
270 crate::step_runtime::register_step_builtins(vm);
271}
272
273pub fn register_agent_stdlib(vm: &mut Vm) {
275 register_agent_stdlib_before_llm(vm);
276 register_llm_builtins(vm);
277 register_agent_stdlib_after_llm(vm);
278}
279
280pub fn register_vm_stdlib(vm: &mut Vm) {
284 if !vm.install_shared_stdlib_registration() {
285 register_stdlib_bindings(vm);
286 }
287 if vm.harness().is_none() {
288 vm.set_harness(crate::harness::Harness::real());
289 }
290 if harn_parser::legacy_ambient_capabilities_enabled() && vm.global("harness").is_none() {
291 let harness = vm
292 .root_harness_value()
293 .expect("register_vm_stdlib installs a root Harness");
294 vm.set_global("harness", harness);
295 }
296 vm.project_legacy_capability_globals();
297 harn_builtin_registry::install_builtin_manifest(all_builtin_manifest());
298}
299
300pub(crate) fn register_stdlib_bindings(vm: &mut Vm) {
301 register_core_stdlib(vm);
302 register_io_stdlib(vm);
303 register_agent_stdlib(vm);
304 vm.project_declared_capability_methods();
305}
306
307pub(crate) fn rebind_execution_state_builtins(vm: &mut Vm) {
308 concurrency::register_concurrency_builtins(vm);
309}
310
311fn stdlib_probe_vm() -> Vm {
312 let mut vm = Vm::new();
313 register_vm_stdlib(&mut vm);
314 let tmp = std::env::temp_dir();
318 crate::store::register_store_builtins(&mut vm, &tmp);
319 crate::checkpoint::register_checkpoint_builtins(&mut vm, &tmp, "default");
320 crate::metadata::register_metadata_builtins(&mut vm, &tmp);
321 harn_builtin_registry::install_builtin_manifest(all_builtin_manifest());
326 vm
327}
328
329pub fn all_builtin_defs() -> &'static [&'static macros::VmBuiltinDef] {
345 let defs = ¯os::ALL_BUILTIN_DEFS;
346 validate_builtin_contracts(defs);
347 defs
348}
349
350fn validate_builtin_contracts(defs: &[¯os::VmBuiltinDef]) {
351 use harn_builtin_meta::BuiltinExposure;
352 let mut source_names = std::collections::BTreeSet::new();
353 let mut capability_methods = std::collections::BTreeSet::new();
354 for def in defs {
355 assert!(
356 def.contract.is_declared(),
357 "builtin `{}` has no typed exposure/effect contract",
358 def.sig.name
359 );
360 assert!(
361 !matches!(def.contract.exposure, BuiltinExposure::PureGlobal)
362 || def.contract.effects.is_empty(),
363 "ambient global builtin `{}` declares effects; effects must flow through Harness",
364 def.sig.name
365 );
366 if let BuiltinExposure::CapabilityFunction { authority_argument } = def.contract.exposure {
367 assert!(
368 !def.contract.effects.is_empty(),
369 "capability function `{}` must declare effects",
370 def.sig.name
371 );
372 assert!(
373 usize::from(authority_argument) < def.sig.params.len(),
374 "capability function `{}` authority argument is out of range",
375 def.sig.name
376 );
377 }
378 if def.runtime_only {
379 assert!(
380 matches!(
381 def.contract.exposure,
382 BuiltinExposure::StdlibInternal | BuiltinExposure::RuntimeInternal
383 ),
384 "runtime_only builtin `{}` must use runtime_internal exposure",
385 def.sig.name
386 );
387 }
388 if let BuiltinExposure::HarnessMethod { method, .. } = def.contract.exposure {
389 assert!(
390 !method.is_empty(),
391 "harness method for `{}` cannot be empty",
392 def.sig.name
393 );
394 let BuiltinExposure::HarnessMethod { capability, method } = def.contract.exposure
395 else {
396 unreachable!()
397 };
398 assert!(
399 capability_methods.insert((capability, method)),
400 "duplicate contract for harness.{}.{}",
401 capability.field_name(),
402 method
403 );
404 }
405 if matches!(
406 def.contract.exposure,
407 BuiltinExposure::PureGlobal
408 | BuiltinExposure::CapabilityFunction { .. }
409 | BuiltinExposure::PrivilegedWire
410 | BuiltinExposure::StdlibInternal
411 | BuiltinExposure::HarnessMethod { .. }
412 ) {
413 assert!(
414 source_names.insert(def.sig.name),
415 "duplicate source contract name `{}`",
416 def.sig.name
417 );
418 }
419 }
420}
421
422pub fn force_link() {
430 let len = std::hint::black_box(macros::ALL_BUILTIN_DEFS.len());
436 assert!(
437 len >= 1,
438 "linkme distributed_slice ALL_BUILTIN_DEFS is empty — \
439 the binary is missing `harn_vm::stdlib::force_link()` at startup, \
440 or the linker stripped the harn-vm rlib statics (see linkme issue #36)"
441 );
442}
443
444pub fn all_builtin_manifest() -> &'static [&'static harn_builtin_registry::BuiltinManifestEntry] {
446 use std::sync::OnceLock;
447 static AGG: OnceLock<Vec<&'static harn_builtin_registry::BuiltinManifestEntry>> =
448 OnceLock::new();
449 AGG.get_or_init(|| {
450 let mut out = Vec::new();
451 let mut capability_methods = std::collections::BTreeSet::new();
452 for def in all_builtin_defs() {
453 if def.runtime_only {
454 continue;
455 }
456 out.push(
457 Box::leak(Box::new(harn_builtin_registry::BuiltinManifestEntry {
458 name: def.sig.name,
459 canonical_name: def.sig.name,
460 signature: &def.sig,
461 contract: def.contract,
462 })) as &'static harn_builtin_registry::BuiltinManifestEntry,
463 );
464 if let harn_builtin_meta::BuiltinExposure::HarnessMethod { capability, method } =
465 def.contract.exposure
466 {
467 capability_methods.insert((capability, method));
468 }
469 for alias in def.aliases {
470 let signature = Box::leak(Box::new(harn_builtin_meta::BuiltinSignature {
471 name: alias,
472 ..def.sig
473 }));
474 out.push(
475 Box::leak(Box::new(harn_builtin_registry::BuiltinManifestEntry {
476 name: alias,
477 canonical_name: def.sig.name,
478 signature,
479 contract: def.contract,
480 })) as &'static harn_builtin_registry::BuiltinManifestEntry,
481 );
482 }
483 }
484 for entry in harn_capability_contracts::manifest() {
485 let harn_builtin_meta::BuiltinExposure::HarnessMethod { capability, method } =
486 entry.contract.exposure
487 else {
488 unreachable!("leaf capability manifest contains a non-method contract")
489 };
490 if !capability_methods.insert((capability, method)) {
491 let runtime_entry = out
492 .iter()
493 .find(|candidate| candidate.contract.exposure == entry.contract.exposure)
494 .expect("duplicate capability key must have a runtime manifest entry");
495 assert_eq!(
496 runtime_entry.contract,
497 entry.contract,
498 "runtime effect contract drift for harness.{}.{}",
499 capability.field_name(),
500 method
501 );
502 assert_eq!(
503 runtime_entry.signature,
504 entry.signature,
505 "runtime signature drift for harness.{}.{}",
506 capability.field_name(),
507 method
508 );
509 continue;
510 }
511 out.push(*entry);
512 }
513 for group in harn_builtin_meta::host_capabilities::all_host_capability_groups() {
514 for method in group.methods {
515 if !capability_methods.insert((group.capability, *method)) {
516 continue;
517 }
518 let internal_name: &'static str = Box::leak(
519 format!("__cap_{}_{}", group.capability.field_name(), method).into_boxed_str(),
520 );
521 let params: &'static [harn_builtin_meta::Param] =
522 Box::leak(Box::new([harn_builtin_meta::Param::new(
523 "request",
524 harn_builtin_meta::Ty::Named("dict"),
525 )]));
526 let signature = Box::leak(Box::new(harn_builtin_meta::BuiltinSignature::simple(
527 internal_name,
528 params,
529 harn_builtin_meta::Ty::Named("dict"),
530 )));
531 out.push(Box::leak(Box::new(
532 harn_builtin_registry::BuiltinManifestEntry {
533 name: internal_name,
534 canonical_name: internal_name,
535 signature,
536 contract: harn_builtin_meta::BuiltinContract::harness(
537 group.capability,
538 method,
539 group.effects,
540 ),
541 },
542 )));
543 }
544 }
545 out
546 })
547 .as_slice()
548}
549
550struct BuiltinManifestIndex {
557 by_name: std::collections::HashMap<
558 &'static str,
559 &'static harn_builtin_registry::BuiltinManifestEntry,
560 >,
561 by_capability: std::collections::HashMap<
562 harn_builtin_meta::CapabilityId,
563 std::collections::HashMap<
564 &'static str,
565 &'static harn_builtin_registry::BuiltinManifestEntry,
566 >,
567 >,
568 recorded_effects_by_name: std::collections::HashMap<
569 &'static str,
570 &'static harn_builtin_registry::BuiltinManifestEntry,
571 >,
572}
573
574fn builtin_manifest_index() -> &'static BuiltinManifestIndex {
575 use harn_builtin_meta::BuiltinExposure;
576 use std::sync::OnceLock;
577
578 static INDEX: OnceLock<BuiltinManifestIndex> = OnceLock::new();
579 INDEX.get_or_init(|| {
580 let mut by_name = std::collections::HashMap::new();
581 let mut by_capability: std::collections::HashMap<
582 harn_builtin_meta::CapabilityId,
583 std::collections::HashMap<
584 &'static str,
585 &'static harn_builtin_registry::BuiltinManifestEntry,
586 >,
587 > = std::collections::HashMap::new();
588 let mut recorded_effects_by_name = std::collections::HashMap::new();
589 for entry in all_builtin_manifest() {
590 assert!(
591 by_name.insert(entry.name, *entry).is_none(),
592 "duplicate builtin manifest name `{}`",
593 entry.name
594 );
595 if let BuiltinExposure::HarnessMethod { capability, method } = entry.contract.exposure {
598 if entry.is_canonical() {
599 assert!(
600 by_capability
601 .entry(capability)
602 .or_default()
603 .insert(method, *entry)
604 .is_none(),
605 "duplicate Harness method manifest entry `harness.{}.{method}`",
606 capability.field_name()
607 );
608 }
609 }
610 if matches!(
611 entry.contract.exposure,
612 BuiltinExposure::CapabilityFunction { .. }
613 | BuiltinExposure::HarnessMethod { .. }
614 | BuiltinExposure::PrivilegedWire
615 | BuiltinExposure::StdlibInternal
616 ) && !entry.contract.effects.is_empty()
617 {
618 recorded_effects_by_name.insert(entry.name, *entry);
619 }
620 }
621 BuiltinManifestIndex {
622 by_name,
623 by_capability,
624 recorded_effects_by_name,
625 }
626 })
627}
628
629pub fn builtin_for_harness_path(path: &str) -> Option<&'static str> {
636 let (field, method) = path.strip_prefix("harness.")?.split_once('.')?;
637 let capability = harn_builtin_meta::CapabilityId::from_field_name(field)?;
638 capability_method_manifest_entry(capability, method).map(|entry| entry.name)
639}
640
641pub fn harness_method_for_builtin(
643 name: &str,
644) -> Option<(harn_builtin_meta::CapabilityId, &'static str)> {
645 match builtin_manifest_entry(name)?.contract.exposure {
646 harn_builtin_meta::BuiltinExposure::HarnessMethod { capability, method } => {
647 Some((capability, method))
648 }
649 _ => None,
650 }
651}
652
653pub fn builtin_manifest_entry(
655 name: &str,
656) -> Option<&'static harn_builtin_registry::BuiltinManifestEntry> {
657 builtin_manifest_index().by_name.get(name).copied()
658}
659
660pub fn capability_method_manifest_entry(
662 capability: harn_builtin_meta::CapabilityId,
663 method: &str,
664) -> Option<&'static harn_builtin_registry::BuiltinManifestEntry> {
665 builtin_manifest_index()
666 .by_capability
667 .get(&capability)
668 .and_then(|methods| methods.get(method))
669 .copied()
670}
671
672pub fn recorded_effect_builtin_manifest_entry(
678 name: &str,
679) -> Option<&'static harn_builtin_registry::BuiltinManifestEntry> {
680 builtin_manifest_index()
681 .recorded_effects_by_name
682 .get(name)
683 .copied()
684}
685
686mod harness_migration;
687
688pub use harness_migration::{
689 harness_migration_for_builtin, HarnessBuiltinArgumentMigration, HarnessBuiltinMigration,
690};
691
692pub fn register_all_macro_builtins(vm: &mut Vm) {
697 for def in all_builtin_defs() {
698 vm.register_builtin_def(def);
699 }
700}
701
702pub fn stdlib_builtin_names() -> Vec<String> {
705 let vm = stdlib_probe_vm();
706 let mut names = vm.builtin_names();
707 for extra in harn_parser::builtin_signatures::LANGUAGE_INTRINSICS {
710 names.push(extra.to_string());
711 }
712 names
713}
714
715pub fn stdlib_builtin_metadata() -> Vec<crate::vm::VmBuiltinMetadata> {
717 stdlib_probe_vm().builtin_metadata()
718}
719
720pub fn builtin_exposure(name: &str) -> Option<harn_builtin_meta::BuiltinExposure> {
734 use std::sync::OnceLock;
735 static BY_NAME: OnceLock<
736 std::collections::HashMap<String, harn_builtin_meta::BuiltinExposure>,
737 > = OnceLock::new();
738 BY_NAME
739 .get_or_init(|| {
740 stdlib_probe_vm()
741 .builtin_metadata()
742 .into_iter()
743 .map(|entry| (entry.name().to_string(), entry.contract().exposure))
744 .collect()
745 })
746 .get(name)
747 .copied()
748}
749
750#[derive(Debug, Clone, Copy, PartialEq, Eq)]
752pub struct HarnessMethodTarget {
753 pub capability: harn_builtin_meta::CapabilityId,
754 pub method: &'static str,
755}
756
757impl HarnessMethodTarget {
758 pub fn path(&self) -> String {
760 format!("{}.{}", self.capability.field_name(), self.method)
761 }
762}
763
764pub fn harness_method_for_host_operation(operation: &str) -> Option<HarnessMethodTarget> {
786 use harn_builtin_meta::{wire_identifier_key, BuiltinExposure, CapabilityId};
787 use std::collections::HashMap;
788 use std::sync::OnceLock;
789
790 let (namespace, operation_method) = operation.split_once('.')?;
791 if let Some((capability, method)) =
792 harn_builtin_meta::host_capabilities::capability_binding_for_schema(
793 namespace,
794 operation_method,
795 )
796 {
797 return Some(HarnessMethodTarget { capability, method });
798 }
799
800 static BY_CAPABILITY: OnceLock<HashMap<CapabilityId, Vec<&'static str>>> = OnceLock::new();
801 let declared = BY_CAPABILITY.get_or_init(|| {
802 let mut index: HashMap<CapabilityId, Vec<&'static str>> = HashMap::new();
803 for entry in all_builtin_manifest() {
810 if !entry.is_canonical() {
811 continue;
812 }
813 if let BuiltinExposure::HarnessMethod { capability, method } = entry.contract.exposure {
814 index.entry(capability).or_default().push(method);
815 }
816 }
817 index
818 });
819
820 let capability = CapabilityId::from_host_namespace(namespace)?;
823 let methods = declared.get(&capability)?;
824 if let Some(exact) = methods.iter().find(|method| **method == operation_method) {
825 return Some(HarnessMethodTarget {
826 capability,
827 method: exact,
828 });
829 }
830 let wanted = wire_identifier_key(operation_method);
831 let mut lenient = methods
832 .iter()
833 .filter(|method| wire_identifier_key(method) == wanted);
834 let only = lenient.next()?;
835 lenient.next().is_none().then_some(HarnessMethodTarget {
836 capability,
837 method: only,
838 })
839}
840
841pub fn exposure_is_source_nameable(exposure: harn_builtin_meta::BuiltinExposure) -> bool {
848 use harn_builtin_meta::BuiltinExposure;
849 match exposure {
850 BuiltinExposure::PureGlobal
851 | BuiltinExposure::CapabilityFunction { .. }
852 | BuiltinExposure::Undeclared => true,
853 BuiltinExposure::HarnessMethod { .. }
854 | BuiltinExposure::PrivilegedWire
855 | BuiltinExposure::StdlibInternal
856 | BuiltinExposure::RuntimeInternal => false,
857 }
858}
859
860pub fn reset_stdlib_state() {
873 logging::reset_logging_state();
874 process::reset_process_state();
875 clock::reset_clock_state();
876 io::reset_io_state();
877 sandbox::reset_sandbox_state();
878 git::reset_git_state();
879 fs::reset_fs_state();
880 json::reset_json_state();
881 json_stream::reset_json_stream_state();
882 host::reset_host_state();
883 host::reset_scoped_host_state();
884 observability::reset_observability_state();
885 timing::reset_timing_state();
886 durable_step::reset_durable_step_state();
887 crate::egress::reset_egress_policy_for_host();
888 hitl::reset_hitl_state();
889 crate::http::reset_http_state();
890 crate::external_agent::reset_external_agent_state();
891 monitors::reset_monitor_state();
892 waitpoint::reset_waitpoint_state();
893 triggers_stdlib::reset_auto_resume_timeouts();
894 compaction::reset_compaction_state();
895 agents::reset_agent_worker_state();
896 agents::workflow::reset_workflow_run_states();
897 pool::reset_pool_state();
898 #[cfg(feature = "postgres")]
899 postgres::reset_postgres_state();
900 #[cfg(feature = "sqlite")]
901 sqlite::reset_sqlite_state();
902 supervisor::reset_supervisor_state();
903 agents::records::reset_eval_metrics();
904 agents::records::reset_friction_events();
905 tools::clear_current_tool_registry();
906 tools::clear_tool_synthesis_cache();
907 vision::reset_vision_state();
908 crate::skills::clear_current_skill_registry();
909 template::reset_prompt_registry();
910 crate::triggers::clear_webhook_intake_state();
911 crate::llm::cache::reset_in_process_cache_state();
912}
913
914#[cfg(test)]
915mod tests {
916 use super::*;
917
918 #[test]
919 fn host_operation_resolves_to_its_declared_harness_method() {
920 let target = harness_method_for_host_operation("ast.outline")
921 .expect("`ast.outline` is declared by harn-hostlib");
922 assert_eq!(target.path(), "ast.outline");
923 }
924
925 #[test]
926 fn host_operation_namespace_matching_ignores_underscores() {
927 let squashed = harness_method_for_host_operation("prmonitor.run_commands")
930 .expect("`prmonitor` names the `pr_monitor` capability");
931 let spelled = harness_method_for_host_operation("pr_monitor.run_commands")
932 .expect("the declared spelling resolves too");
933 assert_eq!(squashed, spelled);
934 assert_eq!(squashed.path(), "pr_monitor.run_commands");
935 }
936
937 #[test]
938 fn host_operation_without_a_declared_owner_resolves_to_nothing() {
939 for operation in [
943 "ast.*",
944 "capability.operation",
945 "runtime.set_result",
946 "ast",
947 "",
948 ] {
949 assert_eq!(
950 harness_method_for_host_operation(operation),
951 None,
952 "`{operation}` must not resolve"
953 );
954 }
955 }
956
957 #[test]
958 fn host_operation_honors_the_schema_tables_deliberate_remapping() {
959 let target = harness_method_for_host_operation("session.open")
966 .expect("`session.open` is a declared hostlib schema operation");
967 assert_eq!(target.path(), "agent.session_open");
968 }
969
970 #[tokio::test(flavor = "current_thread")]
971 async fn register_vm_stdlib_passes_default_harness_only_to_main() {
972 let chunk = crate::compile_source(
973 r"
974fn __probe_harness_clock(clock: HarnessClock) {
975 const now = clock.now_ms()
976 return now >= 0
977}
978
979fn main(harness: Harness) {
980 return __probe_harness_clock(harness.clock)
981}
982",
983 )
984 .expect("compile harness clock probe");
985 let mut vm = Vm::new();
986 register_vm_stdlib(&mut vm);
987
988 assert!(vm.root_harness_value().is_some());
989 assert!(vm.global("harness").is_none());
990 let result = vm
991 .execute(&chunk)
992 .await
993 .expect("execute harness clock probe");
994 assert!(matches!(result, crate::value::VmValue::Bool(true)));
995 }
996
997 #[test]
1003 fn every_stdlib_builtin_reexport_names_a_registered_builtin() {
1004 let registered: std::collections::HashSet<&str> = all_builtin_defs()
1005 .iter()
1006 .flat_map(|def| std::iter::once(def.sig.name).chain(def.aliases.iter().copied()))
1007 .collect();
1008
1009 let mut checked = 0;
1010 for entry in harn_stdlib::STDLIB_SOURCES {
1011 for name in harn_stdlib::builtin_reexports(entry.module) {
1012 assert!(
1013 registered.contains(name),
1014 "std/{} re-exports '{name}', which is not a registered builtin",
1015 entry.module
1016 );
1017 checked += 1;
1018 }
1019 }
1020 assert!(
1021 checked > 0,
1022 "no re-exports were checked — the table or the module list is not being read"
1023 );
1024 }
1025
1026 #[test]
1027 fn ambient_effect_builtin_allowlist_is_empty() {
1028 let offenders = all_builtin_defs()
1029 .iter()
1030 .filter(|def| {
1031 matches!(
1032 def.contract.exposure,
1033 harn_builtin_meta::BuiltinExposure::PureGlobal
1034 ) && !def.contract.effects.is_empty()
1035 })
1036 .map(|def| def.sig.name)
1037 .collect::<Vec<_>>();
1038
1039 assert!(
1040 offenders.is_empty(),
1041 "ambient effect builtins are forbidden; route these through Harness: {offenders:?}"
1042 );
1043 }
1044
1045 #[test]
1046 fn harness_builtin_migrations_preserve_canonical_call_shapes() {
1047 use harn_builtin_meta::CapabilityId;
1048
1049 assert_eq!(
1050 harness_migration_for_builtin("provider_capabilities"),
1051 Some(HarnessBuiltinMigration {
1052 capability: CapabilityId::Llm,
1053 method: "provider_capabilities",
1054 arguments: HarnessBuiltinArgumentMigration::Forward,
1055 })
1056 );
1057 assert_eq!(
1058 harness_migration_for_builtin("log_info"),
1059 Some(HarnessBuiltinMigration {
1060 capability: CapabilityId::Observability,
1061 method: "log_info",
1062 arguments: HarnessBuiltinArgumentMigration::Forward,
1063 })
1064 );
1065 assert_eq!(
1066 harness_migration_for_builtin("runtime_introspection"),
1067 Some(HarnessBuiltinMigration {
1068 capability: CapabilityId::Runtime,
1069 method: "introspection",
1070 arguments: HarnessBuiltinArgumentMigration::Forward,
1071 })
1072 );
1073 assert_eq!(
1074 harness_migration_for_builtin("project_fingerprint"),
1075 Some(HarnessBuiltinMigration {
1076 capability: CapabilityId::Project,
1077 method: "fingerprint",
1078 arguments: HarnessBuiltinArgumentMigration::Forward,
1079 })
1080 );
1081 assert_eq!(
1082 harness_migration_for_builtin("project_scan_tree_native"),
1083 Some(HarnessBuiltinMigration {
1084 capability: CapabilityId::Project,
1085 method: "scan_tree",
1086 arguments: HarnessBuiltinArgumentMigration::Forward,
1087 })
1088 );
1089 assert_eq!(
1090 harness_migration_for_builtin("llm_call"),
1091 Some(HarnessBuiltinMigration {
1092 capability: CapabilityId::Llm,
1093 method: "call",
1094 arguments: HarnessBuiltinArgumentMigration::Forward,
1095 })
1096 );
1097 assert_eq!(
1098 harness_migration_for_builtin("llm_call_structured"),
1099 Some(HarnessBuiltinMigration {
1100 capability: CapabilityId::Llm,
1101 method: "call_structured",
1102 arguments: HarnessBuiltinArgumentMigration::Forward,
1103 })
1104 );
1105 assert_eq!(
1106 harness_migration_for_builtin("security_policy"),
1107 Some(HarnessBuiltinMigration {
1108 capability: CapabilityId::System,
1109 method: "security_policy",
1110 arguments: HarnessBuiltinArgumentMigration::Forward,
1111 })
1112 );
1113 assert_eq!(
1114 harness_migration_for_builtin("llm_provider_status"),
1115 Some(HarnessBuiltinMigration {
1116 capability: CapabilityId::Llm,
1117 method: "providers",
1118 arguments: HarnessBuiltinArgumentMigration::Forward,
1119 })
1120 );
1121 assert_eq!(
1122 harness_migration_for_builtin("agent_session_current_id"),
1123 Some(HarnessBuiltinMigration {
1124 capability: CapabilityId::Agent,
1125 method: "current_id",
1126 arguments: HarnessBuiltinArgumentMigration::Forward,
1127 })
1128 );
1129 assert_eq!(
1130 harness_migration_for_builtin("metadata_set"),
1131 Some(HarnessBuiltinMigration {
1132 capability: CapabilityId::Project,
1133 method: "metadata_set",
1134 arguments: HarnessBuiltinArgumentMigration::RequestRecord(&[
1135 "dir",
1136 "namespace",
1137 "data",
1138 ]),
1139 })
1140 );
1141 assert_eq!(
1142 harness_migration_for_builtin("metadata_save"),
1143 Some(HarnessBuiltinMigration {
1144 capability: CapabilityId::Project,
1145 method: "metadata_save",
1146 arguments: HarnessBuiltinArgumentMigration::RequestRecord(&[]),
1147 })
1148 );
1149 assert_eq!(
1150 harness_migration_for_builtin("platform"),
1151 Some(HarnessBuiltinMigration {
1152 capability: CapabilityId::System,
1153 method: "platform",
1154 arguments: HarnessBuiltinArgumentMigration::CallThenProperty("os"),
1155 })
1156 );
1157 assert_eq!(
1158 harness_migration_for_builtin("arch"),
1159 Some(HarnessBuiltinMigration {
1160 capability: CapabilityId::System,
1161 method: "platform",
1162 arguments: HarnessBuiltinArgumentMigration::CallThenProperty("arch"),
1163 })
1164 );
1165 assert_eq!(
1166 harness_migration_for_builtin("home_dir"),
1167 Some(HarnessBuiltinMigration {
1168 capability: CapabilityId::Fs,
1169 method: "home_dir",
1170 arguments: HarnessBuiltinArgumentMigration::Forward,
1171 })
1172 );
1173 assert_eq!(harness_migration_for_builtin("json_parse"), None);
1174 }
1175
1176 #[test]
1177 fn every_source_named_runtime_callable_has_a_typed_contract() {
1178 let manifest_names = all_builtin_manifest()
1179 .iter()
1180 .map(|entry| entry.name)
1181 .collect::<std::collections::HashSet<_>>();
1182 let offenders = stdlib_probe_vm()
1183 .builtin_names()
1184 .into_iter()
1185 .filter(|name| {
1186 !name.starts_with("__")
1187 && !manifest_names.contains(name.as_str())
1188 && !harn_parser::builtin_signatures::is_language_intrinsic(name)
1189 })
1190 .collect::<Vec<_>>();
1191
1192 assert!(
1193 offenders.is_empty(),
1194 "runtime callables without typed source contracts bypass the Harness gate: {offenders:?}"
1195 );
1196 }
1197
1198 #[test]
1199 fn builtin_manifest_indexes_preserve_the_authoritative_contracts() {
1200 use harn_builtin_meta::BuiltinExposure;
1201
1202 let mut capability_entries = 0;
1203 for entry in all_builtin_manifest() {
1204 assert!(
1205 std::ptr::eq(
1206 builtin_manifest_entry(entry.name).expect("indexed builtin entry"),
1207 *entry,
1208 ),
1209 "name index projected a different contract for `{}`",
1210 entry.name
1211 );
1212 let should_record = matches!(
1213 entry.contract.exposure,
1214 BuiltinExposure::CapabilityFunction { .. }
1215 | BuiltinExposure::HarnessMethod { .. }
1216 | BuiltinExposure::PrivilegedWire
1217 | BuiltinExposure::StdlibInternal
1218 ) && !entry.contract.effects.is_empty();
1219 assert_eq!(
1220 recorded_effect_builtin_manifest_entry(entry.name).is_some(),
1221 should_record,
1222 "recorded-effect index drifted for `{}`",
1223 entry.name
1224 );
1225 if let BuiltinExposure::HarnessMethod { capability, method } = entry.contract.exposure {
1226 capability_entries += 1;
1227 let indexed = capability_method_manifest_entry(capability, method)
1228 .expect("indexed Harness method entry");
1229 assert_eq!(
1232 indexed.name,
1233 entry.canonical_name,
1234 "capability index projected a different builtin for `harness.{}.{method}`",
1235 capability.field_name()
1236 );
1237 assert_eq!(
1238 indexed.contract,
1239 entry.contract,
1240 "capability index projected a different contract for `harness.{}.{method}`",
1241 capability.field_name()
1242 );
1243 }
1244 }
1245 assert!(capability_entries > 0, "no Harness contracts were indexed");
1246 assert!(builtin_manifest_entry("__definitely_missing_builtin").is_none());
1247 assert!(capability_method_manifest_entry(
1248 harn_builtin_meta::CapabilityId::Fs,
1249 "__definitely_missing_method",
1250 )
1251 .is_none());
1252 }
1253}
1254
1255#[cfg(test)]
1256mod ambient_host_internal_projection_tests {
1257 use super::*;
1258
1259 #[test]
1260 fn ambient_bridge_projects_host_internal_emit_event_alias() {
1261 let previous = std::env::var_os(harn_parser::HARN_LEGACY_AMBIENT_CAPABILITIES_ENV);
1262 unsafe {
1263 std::env::set_var(harn_parser::HARN_LEGACY_AMBIENT_CAPABILITIES_ENV, "1");
1264 }
1265 harn_parser::refresh_legacy_ambient_capabilities();
1266 let mut vm = Vm::new();
1267 register_vm_stdlib(&mut vm);
1268 assert!(
1269 vm.builtin_metadata_for("agent_emit_event").is_some(),
1270 "ambient bridge must project __host_agent_emit_event as agent_emit_event"
1271 );
1272 assert!(
1273 vm.builtin_metadata_for("__host_agent_emit_event").is_some(),
1274 "canonical host internal must remain registered"
1275 );
1276 unsafe {
1277 match previous {
1278 Some(value) => {
1279 std::env::set_var(harn_parser::HARN_LEGACY_AMBIENT_CAPABILITIES_ENV, value);
1280 }
1281 None => std::env::remove_var(harn_parser::HARN_LEGACY_AMBIENT_CAPABILITIES_ENV),
1282 }
1283 }
1284 harn_parser::refresh_legacy_ambient_capabilities();
1285 }
1286}