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