1pub mod macros;
18
19mod agent_sessions;
20pub mod agent_state;
21pub(crate) mod agents;
22mod agents_daemon;
23mod artifact_emit;
24pub(crate) mod assemble;
25pub mod asset_paths;
26mod bytes;
27mod calendar;
28mod channel_guardrails;
29mod channels;
30pub(crate) mod clock;
31pub(crate) mod collections;
32mod command_policy;
33pub(crate) mod compaction;
34mod compression;
35mod concurrency;
36pub(crate) use concurrency::cancelled_vm_error;
37mod connectors;
38mod cookies;
39mod cron;
40mod crypto;
41mod csv;
42mod datetime;
43pub(crate) use datetime::date_dict_from_millis;
44mod document;
45mod durable_step;
46mod event_log;
47mod external_agent;
48pub(crate) mod files;
49mod flow;
50pub(crate) mod fs;
51mod git;
52pub(crate) mod git_topology;
53mod grounding;
54pub(crate) mod harn_entry;
55pub(crate) mod hitl;
56mod hitl_read;
57pub mod host;
58pub mod http_response;
59pub(crate) mod io;
60mod iter;
61pub(crate) mod json;
62mod json_query;
63pub(crate) mod json_stream;
64mod jsonrpc;
65mod junit;
66mod lifecycle_receipts;
67mod logging;
68pub mod long_running;
69mod math;
70pub(crate) use math::call_seeded_random_method;
71pub(crate) mod memory;
72mod monitors;
73mod multipart;
74mod net;
75mod net_policy;
76mod oauth_dynreg;
77mod oauth_storage;
78pub(crate) mod observability;
79pub(crate) mod options;
80mod package_snapshot;
81pub(crate) use package_snapshot::PackageSnapshotRegistry;
82mod path;
83pub(crate) mod path_scope_guard;
84pub(crate) mod pool;
85#[cfg(feature = "postgres")]
86mod postgres;
87#[cfg(feature = "postgres")]
88pub use postgres::install_shared_pool_registry;
89pub mod process;
90pub(crate) mod process_spawn;
91mod project;
92mod project_catalog;
93mod project_enrich;
94mod regex;
95mod review;
96mod runtime_scope;
97pub(crate) mod sandbox;
98pub mod secret_scan;
99pub(crate) mod session_store;
100mod sets;
101pub(crate) mod shapes;
102mod skills;
103#[cfg(feature = "sqlite")]
104mod sqlite;
105pub(crate) mod strings;
106pub(crate) mod supervisor;
107pub mod template;
108mod testbench;
109mod testing;
110mod timing;
111pub mod token_redaction;
112pub(crate) mod tool_hooks;
113pub(crate) mod tools;
114pub mod tracing;
115mod transcript_compact;
116pub(crate) mod transcript_project;
117mod triggers_stdlib;
118mod tui;
119mod types;
120mod url_parse;
121mod vision;
122pub(crate) mod waitpoint;
123mod web;
124pub mod workflow_messages;
125pub(crate) mod xml;
126
127use crate::http::register_http_builtins;
128use crate::llm::register_llm_builtins;
129use crate::mcp::register_mcp_builtins;
130use crate::mcp_server::register_mcp_server_builtins;
131use crate::vm::Vm;
132
133pub(crate) use crate::schema::{json_to_vm_value, schema_result_value};
134pub(crate) fn set_thread_source_dir(dir: &std::path::Path) {
135 process::set_thread_source_dir(dir);
136}
137
138pub fn register_core_stdlib(vm: &mut Vm) {
140 types::register_type_builtins(vm);
141 math::register_math_builtins(vm);
142 strings::register_string_builtins(vm);
143 json::register_json_builtins(vm);
144 json_stream::register_json_stream_builtins(vm);
145 xml::register_xml_builtins(vm);
146 datetime::register_datetime_builtins(vm);
147 document::register_document_builtins(vm);
148 calendar::register_calendar_builtins(vm);
149 cron::register_cron_builtins(vm);
150 regex::register_regex_builtins(vm);
151 bytes::register_bytes_builtins(vm);
152 compression::register_compression_builtins(vm);
153 command_policy::register_command_policy_builtins(vm);
154 runtime_scope::register_runtime_scope_builtins(vm);
155 crypto::register_crypto_builtins(vm);
156 csv::register_csv_builtins(vm);
157 junit::register_junit_builtins(vm);
158 multipart::register_multipart_builtins(vm);
159 url_parse::register_url_builtins(vm);
160 web::register_web_builtins(vm);
161 cookies::register_cookie_builtins(vm);
162 path::register_path_helper_builtins(vm);
163 sets::register_set_builtins(vm);
164 collections::register_collection_builtins(vm);
165 iter::register_iter_builtins(vm);
166 event_log::register_event_log_builtins(vm);
167 durable_step::register_durable_step_builtins(vm);
168 channels::register_channel_builtins(vm);
169 channel_guardrails::register_channel_guardrail_builtins(vm);
170 shapes::register_shape_builtins(vm);
171 testing::register_testing_builtins(vm);
172 flow::register_flow_builtins(vm);
173 lifecycle_receipts::register_lifecycle_receipt_builtins(vm);
174 net_policy::register_net_policy_builtins(vm);
175 http_response::register_http_response_builtins(vm);
176}
177
178pub fn register_io_stdlib(vm: &mut Vm) {
180 io::register_io_builtins(vm);
181 host::register_host_builtins(vm);
182 fs::register_fs_builtins(vm);
183 package_snapshot::register_package_snapshot_builtins(vm);
184 files::register_file_builtins(vm);
185 git::register_git_builtins(vm);
186 vision::register_vision_builtins(vm);
187 agent_state::register_agent_state_builtins(vm);
188 memory::register_memory_builtins(vm);
189 session_store::register_session_store_builtins(vm);
190 net::register_net_builtins(vm);
191 process::register_process_builtins(vm);
192 process::register_path_builtins(vm);
193 sandbox::register_sandbox_builtins(vm);
194 clock::register_clock_builtins(vm);
197 crate::durable_rate_limit::register_durable_rate_limit_builtins(vm);
198 testbench::register_testbench_builtins(vm);
199 project::register_project_builtins(vm);
200 grounding::register_grounding_builtins(vm);
201 tracing::register_tracing_builtins(vm);
202 observability::register_observability_builtins(vm);
203 timing::register_timing_builtins(vm);
204 tui::register_tui_builtins(vm);
205}
206
207fn register_agent_stdlib_before_llm(vm: &mut Vm) {
208 concurrency::register_concurrency_builtins(vm);
209 connectors::register_connector_builtins(vm);
210 review::register_review_builtins(vm);
211 secret_scan::register_secret_scan_builtins(vm);
212 tools::register_tool_builtins(vm);
213 tool_hooks::register_tool_hooks_builtins(vm);
214 crate::composition::register_composition_builtins(vm);
215 skills::register_skill_builtins(vm);
216 agents_daemon::register_daemon_builtins(vm);
217 triggers_stdlib::register_trigger_builtins(vm);
218 #[cfg(feature = "postgres")]
219 postgres::register_postgres_builtins(vm);
220 #[cfg(feature = "sqlite")]
221 sqlite::register_sqlite_builtins(vm);
222 monitors::register_monitor_builtins(vm);
223 hitl::register_hitl_builtins(vm);
224 hitl_read::register_hitl_read_builtins(vm);
225 waitpoint::register_waitpoint_builtins(vm);
226 supervisor::register_supervisor_builtins(vm);
227 agents::register_agent_builtins(vm);
228 pool::register_pool_builtins(vm);
229 oauth_storage::register_oauth_storage_builtins(vm);
230 oauth_dynreg::register_oauth_dynreg_builtins(vm);
231 token_redaction::register_token_redaction_builtins(vm);
232 agent_sessions::register_agent_session_builtins(vm);
233 artifact_emit::register_artifact_emit_builtins(vm);
234 external_agent::register_external_agent_builtins(vm);
235 path_scope_guard::register_path_scope_guard_builtins(vm);
236 workflow_messages::register_workflow_message_builtins(vm);
237 transcript_compact::register_transcript_compaction_builtins(vm);
238 compaction::register_compaction_builtins(vm);
239 transcript_project::register_transcript_projection_builtins(vm);
240 assemble::register_assemble_context_builtin(vm);
241 crate::egress::register_egress_builtins(vm);
242 crate::security::register_security_builtins(vm);
243 register_http_builtins(vm);
244 jsonrpc::register_jsonrpc_builtins(vm);
245}
246
247fn register_agent_stdlib_after_llm(vm: &mut Vm) {
248 register_mcp_builtins(vm);
249 register_mcp_server_builtins(vm);
250 crate::step_runtime::register_step_builtins(vm);
251}
252
253pub fn register_agent_stdlib(vm: &mut Vm) {
255 register_agent_stdlib_before_llm(vm);
256 register_llm_builtins(vm);
257 register_agent_stdlib_after_llm(vm);
258}
259
260pub fn register_vm_stdlib(vm: &mut Vm) {
264 register_core_stdlib(vm);
265 register_io_stdlib(vm);
266 register_agent_stdlib(vm);
267 vm.project_declared_capability_methods();
268 if vm.harness().is_none() {
269 vm.set_harness(crate::harness::Harness::real());
270 }
271 harn_builtin_registry::install_builtin_manifest(all_builtin_manifest());
272}
273
274pub(crate) fn rebind_execution_state_builtins(vm: &mut Vm) {
275 concurrency::register_concurrency_builtins(vm);
276}
277
278fn stdlib_probe_vm() -> Vm {
279 let mut vm = Vm::new();
280 register_vm_stdlib(&mut vm);
281 let tmp = std::env::temp_dir();
285 crate::store::register_store_builtins(&mut vm, &tmp);
286 crate::checkpoint::register_checkpoint_builtins(&mut vm, &tmp, "default");
287 crate::metadata::register_metadata_builtins(&mut vm, &tmp);
288 harn_builtin_registry::install_builtin_manifest(all_builtin_manifest());
293 vm
294}
295
296pub fn all_builtin_defs() -> &'static [&'static macros::VmBuiltinDef] {
312 let defs = ¯os::ALL_BUILTIN_DEFS;
313 validate_builtin_contracts(defs);
314 defs
315}
316
317fn validate_builtin_contracts(defs: &[¯os::VmBuiltinDef]) {
318 use harn_builtin_meta::BuiltinExposure;
319 let mut source_names = std::collections::BTreeSet::new();
320 let mut capability_methods = std::collections::BTreeSet::new();
321 for def in defs {
322 assert!(
323 def.contract.is_declared(),
324 "builtin `{}` has no typed exposure/effect contract",
325 def.sig.name
326 );
327 assert!(
328 !matches!(def.contract.exposure, BuiltinExposure::PureGlobal)
329 || def.contract.effects.is_empty(),
330 "ambient global builtin `{}` declares effects; effects must flow through Harness",
331 def.sig.name
332 );
333 if let BuiltinExposure::CapabilityFunction { authority_argument } = def.contract.exposure {
334 assert!(
335 !def.contract.effects.is_empty(),
336 "capability function `{}` must declare effects",
337 def.sig.name
338 );
339 assert!(
340 usize::from(authority_argument) < def.sig.params.len(),
341 "capability function `{}` authority argument is out of range",
342 def.sig.name
343 );
344 }
345 if def.runtime_only {
346 assert!(
347 matches!(def.contract.exposure, BuiltinExposure::RuntimeInternal),
348 "runtime_only builtin `{}` must use runtime_internal exposure",
349 def.sig.name
350 );
351 }
352 if let BuiltinExposure::HarnessMethod { method, .. } = def.contract.exposure {
353 assert!(
354 !method.is_empty(),
355 "harness method for `{}` cannot be empty",
356 def.sig.name
357 );
358 let BuiltinExposure::HarnessMethod { capability, method } = def.contract.exposure
359 else {
360 unreachable!()
361 };
362 assert!(
363 capability_methods.insert((capability, method)),
364 "duplicate contract for harness.{}.{}",
365 capability.field_name(),
366 method
367 );
368 }
369 if matches!(
370 def.contract.exposure,
371 BuiltinExposure::PureGlobal
372 | BuiltinExposure::CapabilityFunction { .. }
373 | BuiltinExposure::PrivilegedWire
374 | BuiltinExposure::HarnessMethod { .. }
375 ) {
376 assert!(
377 source_names.insert(def.sig.name),
378 "duplicate source contract name `{}`",
379 def.sig.name
380 );
381 }
382 }
383}
384
385pub fn force_link() {
393 let len = std::hint::black_box(macros::ALL_BUILTIN_DEFS.len());
399 assert!(
400 len >= 1,
401 "linkme distributed_slice ALL_BUILTIN_DEFS is empty — \
402 the binary is missing `harn_vm::stdlib::force_link()` at startup, \
403 or the linker stripped the harn-vm rlib statics (see linkme issue #36)"
404 );
405}
406
407pub fn all_builtin_manifest() -> &'static [&'static harn_builtin_registry::BuiltinManifestEntry] {
409 use std::sync::OnceLock;
410 static AGG: OnceLock<Vec<&'static harn_builtin_registry::BuiltinManifestEntry>> =
411 OnceLock::new();
412 AGG.get_or_init(|| {
413 let mut out = Vec::new();
414 let mut capability_methods = std::collections::BTreeSet::new();
415 for def in all_builtin_defs() {
416 if def.runtime_only {
417 continue;
418 }
419 out.push(
420 Box::leak(Box::new(harn_builtin_registry::BuiltinManifestEntry {
421 name: def.sig.name,
422 signature: &def.sig,
423 contract: def.contract,
424 })) as &'static harn_builtin_registry::BuiltinManifestEntry,
425 );
426 if let harn_builtin_meta::BuiltinExposure::HarnessMethod { capability, method } =
427 def.contract.exposure
428 {
429 capability_methods.insert((capability, method));
430 }
431 for alias in def.aliases {
432 let signature = Box::leak(Box::new(harn_builtin_meta::BuiltinSignature {
433 name: alias,
434 ..def.sig
435 }));
436 out.push(
437 Box::leak(Box::new(harn_builtin_registry::BuiltinManifestEntry {
438 name: alias,
439 signature,
440 contract: def.contract,
441 })) as &'static harn_builtin_registry::BuiltinManifestEntry,
442 );
443 }
444 }
445 for entry in harn_capability_contracts::manifest() {
446 let harn_builtin_meta::BuiltinExposure::HarnessMethod { capability, method } =
447 entry.contract.exposure
448 else {
449 unreachable!("leaf capability manifest contains a non-method contract")
450 };
451 if !capability_methods.insert((capability, method)) {
452 let runtime_entry = out
453 .iter()
454 .find(|candidate| candidate.contract.exposure == entry.contract.exposure)
455 .expect("duplicate capability key must have a runtime manifest entry");
456 assert_eq!(
457 runtime_entry.contract,
458 entry.contract,
459 "runtime effect contract drift for harness.{}.{}",
460 capability.field_name(),
461 method
462 );
463 assert_eq!(
464 runtime_entry.signature,
465 entry.signature,
466 "runtime signature drift for harness.{}.{}",
467 capability.field_name(),
468 method
469 );
470 continue;
471 }
472 out.push(*entry);
473 }
474 for group in harn_builtin_meta::host_capabilities::HOST_CAPABILITY_GROUPS {
475 for method in group.methods {
476 if !capability_methods.insert((group.capability, *method)) {
477 continue;
478 }
479 let internal_name: &'static str = Box::leak(
480 format!("__cap_{}_{}", group.capability.field_name(), method).into_boxed_str(),
481 );
482 let params: &'static [harn_builtin_meta::Param] =
483 Box::leak(Box::new([harn_builtin_meta::Param::new(
484 "request",
485 harn_builtin_meta::Ty::Named("dict"),
486 )]));
487 let signature = Box::leak(Box::new(harn_builtin_meta::BuiltinSignature::simple(
488 internal_name,
489 params,
490 harn_builtin_meta::Ty::Named("dict"),
491 )));
492 out.push(Box::leak(Box::new(
493 harn_builtin_registry::BuiltinManifestEntry {
494 name: internal_name,
495 signature,
496 contract: harn_builtin_meta::BuiltinContract::harness(
497 group.capability,
498 method,
499 group.effects,
500 ),
501 },
502 )));
503 }
504 }
505 out
506 })
507 .as_slice()
508}
509
510pub fn register_all_macro_builtins(vm: &mut Vm) {
515 for def in all_builtin_defs() {
516 vm.register_builtin_def(def);
517 }
518}
519
520pub fn stdlib_builtin_names() -> Vec<String> {
523 let vm = stdlib_probe_vm();
524 let mut names = vm.builtin_names();
525 for extra in harn_parser::builtin_signatures::LANGUAGE_INTRINSICS {
528 names.push(extra.to_string());
529 }
530 names
531}
532
533pub fn stdlib_builtin_metadata() -> Vec<crate::vm::VmBuiltinMetadata> {
535 stdlib_probe_vm().builtin_metadata()
536}
537
538pub fn reset_stdlib_state() {
551 logging::reset_logging_state();
552 process::reset_process_state();
553 clock::reset_clock_state();
554 io::reset_io_state();
555 sandbox::reset_sandbox_state();
556 git::reset_git_state();
557 fs::reset_fs_state();
558 json::reset_json_state();
559 json_stream::reset_json_stream_state();
560 host::reset_host_state();
561 host::reset_scoped_host_state();
562 observability::reset_observability_state();
563 timing::reset_timing_state();
564 durable_step::reset_durable_step_state();
565 crate::egress::reset_egress_policy_for_host();
566 hitl::reset_hitl_state();
567 crate::http::reset_http_state();
568 crate::external_agent::reset_external_agent_state();
569 monitors::reset_monitor_state();
570 waitpoint::reset_waitpoint_state();
571 triggers_stdlib::reset_auto_resume_timeouts();
572 compaction::reset_compaction_state();
573 agents::reset_agent_worker_state();
574 agents::workflow::reset_workflow_run_states();
575 pool::reset_pool_state();
576 #[cfg(feature = "postgres")]
577 postgres::reset_postgres_state();
578 #[cfg(feature = "sqlite")]
579 sqlite::reset_sqlite_state();
580 supervisor::reset_supervisor_state();
581 agents::records::reset_eval_metrics();
582 agents::records::reset_friction_events();
583 tools::clear_current_tool_registry();
584 tools::clear_tool_synthesis_cache();
585 vision::reset_vision_state();
586 crate::skills::clear_current_skill_registry();
587 template::reset_prompt_registry();
588 crate::triggers::clear_webhook_intake_state();
589 crate::llm::cache::reset_in_process_cache_state();
590}
591
592#[cfg(test)]
593mod tests {
594 use super::*;
595
596 #[tokio::test(flavor = "current_thread")]
597 async fn register_vm_stdlib_passes_default_harness_only_to_main() {
598 let chunk = crate::compile_source(
599 r"
600fn __probe_harness_clock(clock: HarnessClock) {
601 const now = clock.now_ms()
602 return now >= 0
603}
604
605fn main(harness: Harness) {
606 return __probe_harness_clock(harness.clock)
607}
608",
609 )
610 .expect("compile harness clock probe");
611 let mut vm = Vm::new();
612 register_vm_stdlib(&mut vm);
613
614 assert!(vm.root_harness_value().is_some());
615 assert!(vm.global("harness").is_none());
616 let result = vm
617 .execute(&chunk)
618 .await
619 .expect("execute harness clock probe");
620 assert!(matches!(result, crate::value::VmValue::Bool(true)));
621 }
622
623 #[test]
629 fn every_stdlib_builtin_reexport_names_a_registered_builtin() {
630 let registered: std::collections::HashSet<&str> = all_builtin_defs()
631 .iter()
632 .flat_map(|def| std::iter::once(def.sig.name).chain(def.aliases.iter().copied()))
633 .collect();
634
635 let mut checked = 0;
636 for entry in harn_stdlib::STDLIB_SOURCES {
637 for name in harn_stdlib::builtin_reexports(entry.module) {
638 assert!(
639 registered.contains(name),
640 "std/{} re-exports '{name}', which is not a registered builtin",
641 entry.module
642 );
643 checked += 1;
644 }
645 }
646 assert!(
647 checked > 0,
648 "no re-exports were checked — the table or the module list is not being read"
649 );
650 }
651
652 #[test]
653 fn ambient_effect_builtin_allowlist_is_empty() {
654 let offenders = all_builtin_defs()
655 .iter()
656 .filter(|def| {
657 matches!(
658 def.contract.exposure,
659 harn_builtin_meta::BuiltinExposure::PureGlobal
660 ) && !def.contract.effects.is_empty()
661 })
662 .map(|def| def.sig.name)
663 .collect::<Vec<_>>();
664
665 assert!(
666 offenders.is_empty(),
667 "ambient effect builtins are forbidden; route these through Harness: {offenders:?}"
668 );
669 }
670
671 #[test]
672 fn every_source_named_runtime_callable_has_a_typed_contract() {
673 let manifest_names = all_builtin_manifest()
674 .iter()
675 .map(|entry| entry.name)
676 .collect::<std::collections::HashSet<_>>();
677 let offenders = stdlib_probe_vm()
678 .builtin_names()
679 .into_iter()
680 .filter(|name| {
681 !name.starts_with("__")
682 && !manifest_names.contains(name.as_str())
683 && !harn_parser::builtin_signatures::is_language_intrinsic(name)
684 })
685 .collect::<Vec<_>>();
686
687 assert!(
688 offenders.is_empty(),
689 "runtime callables without typed source contracts bypass the Harness gate: {offenders:?}"
690 );
691 }
692}