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