1pub mod macros;
18
19pub(crate) mod args;
20
21mod agent_sessions;
22pub mod agent_state;
23pub(crate) mod agents;
24mod 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!(def.contract.exposure, BuiltinExposure::RuntimeInternal),
370 "runtime_only builtin `{}` must use runtime_internal exposure",
371 def.sig.name
372 );
373 }
374 if let BuiltinExposure::HarnessMethod { method, .. } = def.contract.exposure {
375 assert!(
376 !method.is_empty(),
377 "harness method for `{}` cannot be empty",
378 def.sig.name
379 );
380 let BuiltinExposure::HarnessMethod { capability, method } = def.contract.exposure
381 else {
382 unreachable!()
383 };
384 assert!(
385 capability_methods.insert((capability, method)),
386 "duplicate contract for harness.{}.{}",
387 capability.field_name(),
388 method
389 );
390 }
391 if matches!(
392 def.contract.exposure,
393 BuiltinExposure::PureGlobal
394 | BuiltinExposure::CapabilityFunction { .. }
395 | BuiltinExposure::PrivilegedWire
396 | BuiltinExposure::HarnessMethod { .. }
397 ) {
398 assert!(
399 source_names.insert(def.sig.name),
400 "duplicate source contract name `{}`",
401 def.sig.name
402 );
403 }
404 }
405}
406
407pub fn force_link() {
415 let len = std::hint::black_box(macros::ALL_BUILTIN_DEFS.len());
421 assert!(
422 len >= 1,
423 "linkme distributed_slice ALL_BUILTIN_DEFS is empty — \
424 the binary is missing `harn_vm::stdlib::force_link()` at startup, \
425 or the linker stripped the harn-vm rlib statics (see linkme issue #36)"
426 );
427}
428
429pub fn all_builtin_manifest() -> &'static [&'static harn_builtin_registry::BuiltinManifestEntry] {
431 use std::sync::OnceLock;
432 static AGG: OnceLock<Vec<&'static harn_builtin_registry::BuiltinManifestEntry>> =
433 OnceLock::new();
434 AGG.get_or_init(|| {
435 let mut out = Vec::new();
436 let mut capability_methods = std::collections::BTreeSet::new();
437 for def in all_builtin_defs() {
438 if def.runtime_only {
439 continue;
440 }
441 out.push(
442 Box::leak(Box::new(harn_builtin_registry::BuiltinManifestEntry {
443 name: def.sig.name,
444 canonical_name: def.sig.name,
445 signature: &def.sig,
446 contract: def.contract,
447 })) as &'static harn_builtin_registry::BuiltinManifestEntry,
448 );
449 if let harn_builtin_meta::BuiltinExposure::HarnessMethod { capability, method } =
450 def.contract.exposure
451 {
452 capability_methods.insert((capability, method));
453 }
454 for alias in def.aliases {
455 let signature = Box::leak(Box::new(harn_builtin_meta::BuiltinSignature {
456 name: alias,
457 ..def.sig
458 }));
459 out.push(
460 Box::leak(Box::new(harn_builtin_registry::BuiltinManifestEntry {
461 name: alias,
462 canonical_name: def.sig.name,
463 signature,
464 contract: def.contract,
465 })) as &'static harn_builtin_registry::BuiltinManifestEntry,
466 );
467 }
468 }
469 for entry in harn_capability_contracts::manifest() {
470 let harn_builtin_meta::BuiltinExposure::HarnessMethod { capability, method } =
471 entry.contract.exposure
472 else {
473 unreachable!("leaf capability manifest contains a non-method contract")
474 };
475 if !capability_methods.insert((capability, method)) {
476 let runtime_entry = out
477 .iter()
478 .find(|candidate| candidate.contract.exposure == entry.contract.exposure)
479 .expect("duplicate capability key must have a runtime manifest entry");
480 assert_eq!(
481 runtime_entry.contract,
482 entry.contract,
483 "runtime effect contract drift for harness.{}.{}",
484 capability.field_name(),
485 method
486 );
487 assert_eq!(
488 runtime_entry.signature,
489 entry.signature,
490 "runtime signature drift for harness.{}.{}",
491 capability.field_name(),
492 method
493 );
494 continue;
495 }
496 out.push(*entry);
497 }
498 for group in harn_builtin_meta::host_capabilities::all_host_capability_groups() {
499 for method in group.methods {
500 if !capability_methods.insert((group.capability, *method)) {
501 continue;
502 }
503 let internal_name: &'static str = Box::leak(
504 format!("__cap_{}_{}", group.capability.field_name(), method).into_boxed_str(),
505 );
506 let params: &'static [harn_builtin_meta::Param] =
507 Box::leak(Box::new([harn_builtin_meta::Param::new(
508 "request",
509 harn_builtin_meta::Ty::Named("dict"),
510 )]));
511 let signature = Box::leak(Box::new(harn_builtin_meta::BuiltinSignature::simple(
512 internal_name,
513 params,
514 harn_builtin_meta::Ty::Named("dict"),
515 )));
516 out.push(Box::leak(Box::new(
517 harn_builtin_registry::BuiltinManifestEntry {
518 name: internal_name,
519 canonical_name: internal_name,
520 signature,
521 contract: harn_builtin_meta::BuiltinContract::harness(
522 group.capability,
523 method,
524 group.effects,
525 ),
526 },
527 )));
528 }
529 }
530 out
531 })
532 .as_slice()
533}
534
535struct BuiltinManifestIndex {
542 by_name: std::collections::HashMap<
543 &'static str,
544 &'static harn_builtin_registry::BuiltinManifestEntry,
545 >,
546 by_capability: std::collections::HashMap<
547 harn_builtin_meta::CapabilityId,
548 std::collections::HashMap<
549 &'static str,
550 &'static harn_builtin_registry::BuiltinManifestEntry,
551 >,
552 >,
553 recorded_effects_by_name: std::collections::HashMap<
554 &'static str,
555 &'static harn_builtin_registry::BuiltinManifestEntry,
556 >,
557}
558
559fn builtin_manifest_index() -> &'static BuiltinManifestIndex {
560 use harn_builtin_meta::BuiltinExposure;
561 use std::sync::OnceLock;
562
563 static INDEX: OnceLock<BuiltinManifestIndex> = OnceLock::new();
564 INDEX.get_or_init(|| {
565 let mut by_name = std::collections::HashMap::new();
566 let mut by_capability: std::collections::HashMap<
567 harn_builtin_meta::CapabilityId,
568 std::collections::HashMap<
569 &'static str,
570 &'static harn_builtin_registry::BuiltinManifestEntry,
571 >,
572 > = std::collections::HashMap::new();
573 let mut recorded_effects_by_name = std::collections::HashMap::new();
574 for entry in all_builtin_manifest() {
575 assert!(
576 by_name.insert(entry.name, *entry).is_none(),
577 "duplicate builtin manifest name `{}`",
578 entry.name
579 );
580 if let BuiltinExposure::HarnessMethod { capability, method } = entry.contract.exposure {
583 if entry.is_canonical() {
584 assert!(
585 by_capability
586 .entry(capability)
587 .or_default()
588 .insert(method, *entry)
589 .is_none(),
590 "duplicate Harness method manifest entry `harness.{}.{method}`",
591 capability.field_name()
592 );
593 }
594 }
595 if matches!(
596 entry.contract.exposure,
597 BuiltinExposure::CapabilityFunction { .. }
598 | BuiltinExposure::HarnessMethod { .. }
599 | BuiltinExposure::PrivilegedWire
600 ) && !entry.contract.effects.is_empty()
601 {
602 recorded_effects_by_name.insert(entry.name, *entry);
603 }
604 }
605 BuiltinManifestIndex {
606 by_name,
607 by_capability,
608 recorded_effects_by_name,
609 }
610 })
611}
612
613pub fn builtin_for_harness_path(path: &str) -> Option<&'static str> {
620 let (field, method) = path.strip_prefix("harness.")?.split_once('.')?;
621 let capability = harn_builtin_meta::CapabilityId::from_field_name(field)?;
622 capability_method_manifest_entry(capability, method).map(|entry| entry.name)
623}
624
625pub fn harness_method_for_builtin(
627 name: &str,
628) -> Option<(harn_builtin_meta::CapabilityId, &'static str)> {
629 match builtin_manifest_entry(name)?.contract.exposure {
630 harn_builtin_meta::BuiltinExposure::HarnessMethod { capability, method } => {
631 Some((capability, method))
632 }
633 _ => None,
634 }
635}
636
637pub fn builtin_manifest_entry(
639 name: &str,
640) -> Option<&'static harn_builtin_registry::BuiltinManifestEntry> {
641 builtin_manifest_index().by_name.get(name).copied()
642}
643
644pub fn capability_method_manifest_entry(
646 capability: harn_builtin_meta::CapabilityId,
647 method: &str,
648) -> Option<&'static harn_builtin_registry::BuiltinManifestEntry> {
649 builtin_manifest_index()
650 .by_capability
651 .get(&capability)
652 .and_then(|methods| methods.get(method))
653 .copied()
654}
655
656pub fn recorded_effect_builtin_manifest_entry(
662 name: &str,
663) -> Option<&'static harn_builtin_registry::BuiltinManifestEntry> {
664 builtin_manifest_index()
665 .recorded_effects_by_name
666 .get(name)
667 .copied()
668}
669
670mod harness_migration;
671
672pub use harness_migration::{
673 harness_migration_for_builtin, HarnessBuiltinArgumentMigration, HarnessBuiltinMigration,
674};
675
676pub fn register_all_macro_builtins(vm: &mut Vm) {
681 for def in all_builtin_defs() {
682 vm.register_builtin_def(def);
683 }
684}
685
686pub fn stdlib_builtin_names() -> Vec<String> {
689 let vm = stdlib_probe_vm();
690 let mut names = vm.builtin_names();
691 for extra in harn_parser::builtin_signatures::LANGUAGE_INTRINSICS {
694 names.push(extra.to_string());
695 }
696 names
697}
698
699pub fn stdlib_builtin_metadata() -> Vec<crate::vm::VmBuiltinMetadata> {
701 stdlib_probe_vm().builtin_metadata()
702}
703
704pub fn builtin_exposure(name: &str) -> Option<harn_builtin_meta::BuiltinExposure> {
718 use std::sync::OnceLock;
719 static BY_NAME: OnceLock<
720 std::collections::HashMap<String, harn_builtin_meta::BuiltinExposure>,
721 > = OnceLock::new();
722 BY_NAME
723 .get_or_init(|| {
724 stdlib_probe_vm()
725 .builtin_metadata()
726 .into_iter()
727 .map(|entry| (entry.name().to_string(), entry.contract().exposure))
728 .collect()
729 })
730 .get(name)
731 .copied()
732}
733
734#[derive(Debug, Clone, Copy, PartialEq, Eq)]
736pub struct HarnessMethodTarget {
737 pub capability: harn_builtin_meta::CapabilityId,
738 pub method: &'static str,
739}
740
741impl HarnessMethodTarget {
742 pub fn path(&self) -> String {
744 format!("{}.{}", self.capability.field_name(), self.method)
745 }
746}
747
748pub fn harness_method_for_host_operation(operation: &str) -> Option<HarnessMethodTarget> {
770 use harn_builtin_meta::{wire_identifier_key, BuiltinExposure, CapabilityId};
771 use std::collections::HashMap;
772 use std::sync::OnceLock;
773
774 let (namespace, operation_method) = operation.split_once('.')?;
775 if let Some((capability, method)) =
776 harn_builtin_meta::host_capabilities::capability_binding_for_schema(
777 namespace,
778 operation_method,
779 )
780 {
781 return Some(HarnessMethodTarget { capability, method });
782 }
783
784 static BY_CAPABILITY: OnceLock<HashMap<CapabilityId, Vec<&'static str>>> = OnceLock::new();
785 let declared = BY_CAPABILITY.get_or_init(|| {
786 let mut index: HashMap<CapabilityId, Vec<&'static str>> = HashMap::new();
787 for entry in all_builtin_manifest() {
794 if !entry.is_canonical() {
795 continue;
796 }
797 if let BuiltinExposure::HarnessMethod { capability, method } = entry.contract.exposure {
798 index.entry(capability).or_default().push(method);
799 }
800 }
801 index
802 });
803
804 let capability = CapabilityId::from_host_namespace(namespace)?;
807 let methods = declared.get(&capability)?;
808 if let Some(exact) = methods.iter().find(|method| **method == operation_method) {
809 return Some(HarnessMethodTarget {
810 capability,
811 method: exact,
812 });
813 }
814 let wanted = wire_identifier_key(operation_method);
815 let mut lenient = methods
816 .iter()
817 .filter(|method| wire_identifier_key(method) == wanted);
818 let only = lenient.next()?;
819 lenient.next().is_none().then_some(HarnessMethodTarget {
820 capability,
821 method: only,
822 })
823}
824
825pub fn exposure_is_source_nameable(exposure: harn_builtin_meta::BuiltinExposure) -> bool {
832 use harn_builtin_meta::BuiltinExposure;
833 match exposure {
834 BuiltinExposure::PureGlobal
835 | BuiltinExposure::CapabilityFunction { .. }
836 | BuiltinExposure::Undeclared => true,
837 BuiltinExposure::HarnessMethod { .. }
838 | BuiltinExposure::PrivilegedWire
839 | BuiltinExposure::RuntimeInternal => false,
840 }
841}
842
843pub fn reset_stdlib_state() {
856 logging::reset_logging_state();
857 process::reset_process_state();
858 clock::reset_clock_state();
859 io::reset_io_state();
860 sandbox::reset_sandbox_state();
861 git::reset_git_state();
862 fs::reset_fs_state();
863 json::reset_json_state();
864 json_stream::reset_json_stream_state();
865 host::reset_host_state();
866 host::reset_scoped_host_state();
867 observability::reset_observability_state();
868 timing::reset_timing_state();
869 durable_step::reset_durable_step_state();
870 crate::egress::reset_egress_policy_for_host();
871 hitl::reset_hitl_state();
872 crate::http::reset_http_state();
873 crate::external_agent::reset_external_agent_state();
874 monitors::reset_monitor_state();
875 waitpoint::reset_waitpoint_state();
876 triggers_stdlib::reset_auto_resume_timeouts();
877 compaction::reset_compaction_state();
878 agents::reset_agent_worker_state();
879 agents::workflow::reset_workflow_run_states();
880 pool::reset_pool_state();
881 #[cfg(feature = "postgres")]
882 postgres::reset_postgres_state();
883 #[cfg(feature = "sqlite")]
884 sqlite::reset_sqlite_state();
885 supervisor::reset_supervisor_state();
886 agents::records::reset_eval_metrics();
887 agents::records::reset_friction_events();
888 tools::clear_current_tool_registry();
889 tools::clear_tool_synthesis_cache();
890 vision::reset_vision_state();
891 crate::skills::clear_current_skill_registry();
892 template::reset_prompt_registry();
893 crate::triggers::clear_webhook_intake_state();
894 crate::llm::cache::reset_in_process_cache_state();
895}
896
897#[cfg(test)]
898mod tests {
899 use super::*;
900
901 #[test]
902 fn host_operation_resolves_to_its_declared_harness_method() {
903 let target = harness_method_for_host_operation("ast.outline")
904 .expect("`ast.outline` is declared by harn-hostlib");
905 assert_eq!(target.path(), "ast.outline");
906 }
907
908 #[test]
909 fn host_operation_namespace_matching_ignores_underscores() {
910 let squashed = harness_method_for_host_operation("prmonitor.run_commands")
913 .expect("`prmonitor` names the `pr_monitor` capability");
914 let spelled = harness_method_for_host_operation("pr_monitor.run_commands")
915 .expect("the declared spelling resolves too");
916 assert_eq!(squashed, spelled);
917 assert_eq!(squashed.path(), "pr_monitor.run_commands");
918 }
919
920 #[test]
921 fn host_operation_without_a_declared_owner_resolves_to_nothing() {
922 for operation in [
926 "ast.*",
927 "capability.operation",
928 "runtime.set_result",
929 "ast",
930 "",
931 ] {
932 assert_eq!(
933 harness_method_for_host_operation(operation),
934 None,
935 "`{operation}` must not resolve"
936 );
937 }
938 }
939
940 #[test]
941 fn host_operation_honors_the_schema_tables_deliberate_remapping() {
942 let target = harness_method_for_host_operation("session.open")
949 .expect("`session.open` is a declared hostlib schema operation");
950 assert_eq!(target.path(), "agent.session_open");
951 }
952
953 #[tokio::test(flavor = "current_thread")]
954 async fn register_vm_stdlib_passes_default_harness_only_to_main() {
955 let chunk = crate::compile_source(
956 r"
957fn __probe_harness_clock(clock: HarnessClock) {
958 const now = clock.now_ms()
959 return now >= 0
960}
961
962fn main(harness: Harness) {
963 return __probe_harness_clock(harness.clock)
964}
965",
966 )
967 .expect("compile harness clock probe");
968 let mut vm = Vm::new();
969 register_vm_stdlib(&mut vm);
970
971 assert!(vm.root_harness_value().is_some());
972 assert!(vm.global("harness").is_none());
973 let result = vm
974 .execute(&chunk)
975 .await
976 .expect("execute harness clock probe");
977 assert!(matches!(result, crate::value::VmValue::Bool(true)));
978 }
979
980 #[test]
986 fn every_stdlib_builtin_reexport_names_a_registered_builtin() {
987 let registered: std::collections::HashSet<&str> = all_builtin_defs()
988 .iter()
989 .flat_map(|def| std::iter::once(def.sig.name).chain(def.aliases.iter().copied()))
990 .collect();
991
992 let mut checked = 0;
993 for entry in harn_stdlib::STDLIB_SOURCES {
994 for name in harn_stdlib::builtin_reexports(entry.module) {
995 assert!(
996 registered.contains(name),
997 "std/{} re-exports '{name}', which is not a registered builtin",
998 entry.module
999 );
1000 checked += 1;
1001 }
1002 }
1003 assert!(
1004 checked > 0,
1005 "no re-exports were checked — the table or the module list is not being read"
1006 );
1007 }
1008
1009 #[test]
1010 fn ambient_effect_builtin_allowlist_is_empty() {
1011 let offenders = all_builtin_defs()
1012 .iter()
1013 .filter(|def| {
1014 matches!(
1015 def.contract.exposure,
1016 harn_builtin_meta::BuiltinExposure::PureGlobal
1017 ) && !def.contract.effects.is_empty()
1018 })
1019 .map(|def| def.sig.name)
1020 .collect::<Vec<_>>();
1021
1022 assert!(
1023 offenders.is_empty(),
1024 "ambient effect builtins are forbidden; route these through Harness: {offenders:?}"
1025 );
1026 }
1027
1028 #[test]
1029 fn harness_builtin_migrations_preserve_canonical_call_shapes() {
1030 use harn_builtin_meta::CapabilityId;
1031
1032 assert_eq!(
1033 harness_migration_for_builtin("provider_capabilities"),
1034 Some(HarnessBuiltinMigration {
1035 capability: CapabilityId::Llm,
1036 method: "provider_capabilities",
1037 arguments: HarnessBuiltinArgumentMigration::Forward,
1038 })
1039 );
1040 assert_eq!(
1041 harness_migration_for_builtin("log_info"),
1042 Some(HarnessBuiltinMigration {
1043 capability: CapabilityId::Observability,
1044 method: "log_info",
1045 arguments: HarnessBuiltinArgumentMigration::Forward,
1046 })
1047 );
1048 assert_eq!(
1049 harness_migration_for_builtin("runtime_introspection"),
1050 Some(HarnessBuiltinMigration {
1051 capability: CapabilityId::Runtime,
1052 method: "introspection",
1053 arguments: HarnessBuiltinArgumentMigration::Forward,
1054 })
1055 );
1056 assert_eq!(
1057 harness_migration_for_builtin("project_fingerprint"),
1058 Some(HarnessBuiltinMigration {
1059 capability: CapabilityId::Project,
1060 method: "fingerprint",
1061 arguments: HarnessBuiltinArgumentMigration::Forward,
1062 })
1063 );
1064 assert_eq!(
1065 harness_migration_for_builtin("project_scan_tree_native"),
1066 Some(HarnessBuiltinMigration {
1067 capability: CapabilityId::Project,
1068 method: "scan_tree",
1069 arguments: HarnessBuiltinArgumentMigration::Forward,
1070 })
1071 );
1072 assert_eq!(
1073 harness_migration_for_builtin("llm_call"),
1074 Some(HarnessBuiltinMigration {
1075 capability: CapabilityId::Llm,
1076 method: "call",
1077 arguments: HarnessBuiltinArgumentMigration::Forward,
1078 })
1079 );
1080 assert_eq!(
1081 harness_migration_for_builtin("llm_call_structured"),
1082 Some(HarnessBuiltinMigration {
1083 capability: CapabilityId::Llm,
1084 method: "call_structured",
1085 arguments: HarnessBuiltinArgumentMigration::Forward,
1086 })
1087 );
1088 assert_eq!(
1089 harness_migration_for_builtin("security_policy"),
1090 Some(HarnessBuiltinMigration {
1091 capability: CapabilityId::System,
1092 method: "security_policy",
1093 arguments: HarnessBuiltinArgumentMigration::Forward,
1094 })
1095 );
1096 assert_eq!(
1097 harness_migration_for_builtin("llm_provider_status"),
1098 Some(HarnessBuiltinMigration {
1099 capability: CapabilityId::Llm,
1100 method: "providers",
1101 arguments: HarnessBuiltinArgumentMigration::Forward,
1102 })
1103 );
1104 assert_eq!(
1105 harness_migration_for_builtin("agent_session_current_id"),
1106 Some(HarnessBuiltinMigration {
1107 capability: CapabilityId::Agent,
1108 method: "current_id",
1109 arguments: HarnessBuiltinArgumentMigration::Forward,
1110 })
1111 );
1112 assert_eq!(
1113 harness_migration_for_builtin("metadata_set"),
1114 Some(HarnessBuiltinMigration {
1115 capability: CapabilityId::Project,
1116 method: "metadata_set",
1117 arguments: HarnessBuiltinArgumentMigration::RequestRecord(&[
1118 "dir",
1119 "namespace",
1120 "data",
1121 ]),
1122 })
1123 );
1124 assert_eq!(
1125 harness_migration_for_builtin("metadata_save"),
1126 Some(HarnessBuiltinMigration {
1127 capability: CapabilityId::Project,
1128 method: "metadata_save",
1129 arguments: HarnessBuiltinArgumentMigration::RequestRecord(&[]),
1130 })
1131 );
1132 assert_eq!(
1133 harness_migration_for_builtin("platform"),
1134 Some(HarnessBuiltinMigration {
1135 capability: CapabilityId::System,
1136 method: "platform",
1137 arguments: HarnessBuiltinArgumentMigration::CallThenProperty("os"),
1138 })
1139 );
1140 assert_eq!(
1141 harness_migration_for_builtin("arch"),
1142 Some(HarnessBuiltinMigration {
1143 capability: CapabilityId::System,
1144 method: "platform",
1145 arguments: HarnessBuiltinArgumentMigration::CallThenProperty("arch"),
1146 })
1147 );
1148 assert_eq!(
1149 harness_migration_for_builtin("home_dir"),
1150 Some(HarnessBuiltinMigration {
1151 capability: CapabilityId::Fs,
1152 method: "home_dir",
1153 arguments: HarnessBuiltinArgumentMigration::Forward,
1154 })
1155 );
1156 assert_eq!(harness_migration_for_builtin("json_parse"), None);
1157 }
1158
1159 #[test]
1160 fn every_source_named_runtime_callable_has_a_typed_contract() {
1161 let manifest_names = all_builtin_manifest()
1162 .iter()
1163 .map(|entry| entry.name)
1164 .collect::<std::collections::HashSet<_>>();
1165 let offenders = stdlib_probe_vm()
1166 .builtin_names()
1167 .into_iter()
1168 .filter(|name| {
1169 !name.starts_with("__")
1170 && !manifest_names.contains(name.as_str())
1171 && !harn_parser::builtin_signatures::is_language_intrinsic(name)
1172 })
1173 .collect::<Vec<_>>();
1174
1175 assert!(
1176 offenders.is_empty(),
1177 "runtime callables without typed source contracts bypass the Harness gate: {offenders:?}"
1178 );
1179 }
1180
1181 #[test]
1182 fn builtin_manifest_indexes_preserve_the_authoritative_contracts() {
1183 use harn_builtin_meta::BuiltinExposure;
1184
1185 let mut capability_entries = 0;
1186 for entry in all_builtin_manifest() {
1187 assert!(
1188 std::ptr::eq(
1189 builtin_manifest_entry(entry.name).expect("indexed builtin entry"),
1190 *entry,
1191 ),
1192 "name index projected a different contract for `{}`",
1193 entry.name
1194 );
1195 let should_record = matches!(
1196 entry.contract.exposure,
1197 BuiltinExposure::CapabilityFunction { .. }
1198 | BuiltinExposure::HarnessMethod { .. }
1199 | BuiltinExposure::PrivilegedWire
1200 ) && !entry.contract.effects.is_empty();
1201 assert_eq!(
1202 recorded_effect_builtin_manifest_entry(entry.name).is_some(),
1203 should_record,
1204 "recorded-effect index drifted for `{}`",
1205 entry.name
1206 );
1207 if let BuiltinExposure::HarnessMethod { capability, method } = entry.contract.exposure {
1208 capability_entries += 1;
1209 let indexed = capability_method_manifest_entry(capability, method)
1210 .expect("indexed Harness method entry");
1211 assert_eq!(
1214 indexed.name,
1215 entry.canonical_name,
1216 "capability index projected a different builtin for `harness.{}.{method}`",
1217 capability.field_name()
1218 );
1219 assert_eq!(
1220 indexed.contract,
1221 entry.contract,
1222 "capability index projected a different contract for `harness.{}.{method}`",
1223 capability.field_name()
1224 );
1225 }
1226 }
1227 assert!(capability_entries > 0, "no Harness contracts were indexed");
1228 assert!(builtin_manifest_entry("__definitely_missing_builtin").is_none());
1229 assert!(capability_method_manifest_entry(
1230 harn_builtin_meta::CapabilityId::Fs,
1231 "__definitely_missing_method",
1232 )
1233 .is_none());
1234 }
1235}
1236
1237#[cfg(test)]
1238mod ambient_host_internal_projection_tests {
1239 use super::*;
1240
1241 #[test]
1242 fn ambient_bridge_projects_host_internal_emit_event_alias() {
1243 let previous = std::env::var_os(harn_parser::HARN_LEGACY_AMBIENT_CAPABILITIES_ENV);
1244 unsafe {
1245 std::env::set_var(harn_parser::HARN_LEGACY_AMBIENT_CAPABILITIES_ENV, "1");
1246 }
1247 harn_parser::refresh_legacy_ambient_capabilities();
1248 let mut vm = Vm::new();
1249 register_vm_stdlib(&mut vm);
1250 assert!(
1251 vm.builtin_metadata_for("agent_emit_event").is_some(),
1252 "ambient bridge must project __host_agent_emit_event as agent_emit_event"
1253 );
1254 assert!(
1255 vm.builtin_metadata_for("__host_agent_emit_event").is_some(),
1256 "canonical host internal must remain registered"
1257 );
1258 unsafe {
1259 match previous {
1260 Some(value) => {
1261 std::env::set_var(harn_parser::HARN_LEGACY_AMBIENT_CAPABILITIES_ENV, value);
1262 }
1263 None => std::env::remove_var(harn_parser::HARN_LEGACY_AMBIENT_CAPABILITIES_ENV),
1264 }
1265 }
1266 harn_parser::refresh_legacy_ambient_capabilities();
1267 }
1268}