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