Skip to main content

harn_parser/
harness_methods.rs

1//! Canonical mappings between typed `harness.<sub>.*` methods and the
2//! ambient builtin names that still back capability classification,
3//! lint migrations, and runtime dispatch.
4
5pub fn harness_stdio_ambient(method: &str) -> Option<&'static str> {
6    match method {
7        "print" => Some("print"),
8        "println" => Some("println"),
9        "eprint" => Some("eprint"),
10        "eprintln" => Some("eprintln"),
11        "read_line" => Some("read_line"),
12        "prompt" => Some("prompt_user"),
13        _ => None,
14    }
15}
16
17pub fn harness_term_ambient(method: &str) -> Option<&'static str> {
18    match method {
19        "width" => Some("term_width"),
20        "height" => Some("term_height"),
21        "read_password" => Some("read_password"),
22        _ => None,
23    }
24}
25
26pub fn harness_clock_ambient(method: &str) -> Option<&'static str> {
27    match method {
28        "now_ms" => Some("now_ms"),
29        "monotonic_ms" | "elapsed" => Some("monotonic_ms"),
30        "sleep_ms" => Some("sleep_ms"),
31        "timestamp" => Some("timestamp"),
32        _ => None,
33    }
34}
35
36pub fn harness_fs_ambient(method: &str) -> Option<&'static str> {
37    match method {
38        "read_text" | "read" | "read_file" => Some("read_file"),
39        "read_text_result" | "read_result" => Some("read_file_result"),
40        "read_bytes" | "read_file_bytes" => Some("read_file_bytes"),
41        "write_text" | "write" | "write_file" => Some("write_file"),
42        "write_bytes" | "write_file_bytes" => Some("write_file_bytes"),
43        "replace_text" => Some("replace_file"),
44        "replace_text_result" => Some("replace_file_result"),
45        "replace_bytes" => Some("replace_file_bytes"),
46        "replace_bytes_result" => Some("replace_file_bytes_result"),
47        "exists" | "file_exists" => Some("file_exists"),
48        "status" | "path_status" => Some("path_status"),
49        "delete" | "delete_file" | "remove" => Some("delete_file"),
50        "append" | "append_file" => Some("append_file"),
51        "append_locked" | "append_file_locked" => Some("append_file_locked"),
52        "list_dir" | "list" => Some("list_dir"),
53        "mkdir" | "create_dir" => Some("mkdir"),
54        "path_join" => Some("path_join"),
55        "copy" | "copy_file" => Some("copy_file"),
56        "temp_dir" => Some("temp_dir"),
57        "workspace_temp_dir" => Some("workspace_temp_dir"),
58        "mkdtemp" => Some("mkdtemp"),
59        "mkdtemp_in_workspace" => Some("mkdtemp_in_workspace"),
60        "stat" => Some("stat"),
61        "rename" | "move" | "move_file" => Some("move_file"),
62        "read_lines" => Some("read_lines"),
63        "read_lines_page_result" => Some("read_lines_page_result"),
64        "walk" | "walk_dir" => Some("walk_dir"),
65        "glob" => Some("glob"),
66        "find_text" => Some("find_text"),
67        "find_evidence" => Some("find_evidence"),
68        _ => None,
69    }
70}
71
72pub fn harness_env_ambient(method: &str) -> Option<&'static str> {
73    match method {
74        "get" => Some("env"),
75        "get_or" => Some("env_or"),
76        _ => None,
77    }
78}
79
80pub fn harness_random_ambient(method: &str) -> Option<&'static str> {
81    match method {
82        "gen_f64" | "f64" | "random" => Some("random"),
83        "gen_u64" | "u64" => Some("random_int"),
84        "gen_range" | "range" | "random_int" | "int" => Some("random_int"),
85        "choice" | "random_choice" => Some("random_choice"),
86        "shuffle" | "random_shuffle" => Some("random_shuffle"),
87        _ => None,
88    }
89}
90
91pub fn harness_net_ambient(method: &str) -> Option<&'static str> {
92    match method {
93        "get" | "http_get" => Some("http_get"),
94        "post" | "http_post" => Some("http_post"),
95        "put" | "http_put" => Some("http_put"),
96        "patch" | "http_patch" => Some("http_patch"),
97        "delete" | "http_delete" => Some("http_delete"),
98        "request" | "http_request" => Some("http_request"),
99        "download" | "http_download" => Some("http_download"),
100        _ => None,
101    }
102}
103
104pub fn harness_process_ambient(method: &str) -> Option<&'static str> {
105    match method {
106        "spawn_captured" => Some("spawn_captured"),
107        _ => None,
108    }
109}
110
111pub fn harness_crypto_ambient(method: &str) -> Option<&'static str> {
112    match method {
113        "sha256" => Some("sha256_hex"),
114        _ => None,
115    }
116}
117
118pub fn harness_system_ambient(method: &str) -> Option<&'static str> {
119    match method {
120        "platform" => Some("system_platform"),
121        "cpu" => Some("system_cpu"),
122        "memory" => Some("system_memory"),
123        "gpus" => Some("system_gpus"),
124        "temperature" => Some("system_temperature"),
125        "processes" => Some("system_processes"),
126        _ => None,
127    }
128}
129
130pub fn harness_llm_ambient(method: &str) -> Option<&'static str> {
131    match method {
132        "catalog" => Some("llm_catalog"),
133        "catalog_refresh" => Some("llm_catalog_refresh"),
134        "providers" => Some("llm_provider_status"),
135        _ => None,
136    }
137}
138
139pub fn harness_secrets_ambient(method: &str) -> Option<&'static str> {
140    match method {
141        "read" | "read_bytes" | "write" | "delete" | "rotate" | "lease" | "lease_bytes" => None,
142        _ => None,
143    }
144}
145
146pub fn harness_tenant_ambient(method: &str) -> Option<&'static str> {
147    match method {
148        "id" => Some("harness_tenant_id"),
149        "try_id" => Some("harness_tenant_try_id"),
150        _ => None,
151    }
152}
153
154pub fn harness_auth_ambient(method: &str) -> Option<&'static str> {
155    match method {
156        "is_authenticated" => Some("harness_auth_is_authenticated"),
157        "subject" => Some("harness_auth_subject"),
158        "try_subject" => Some("harness_auth_try_subject"),
159        "scheme" => Some("harness_auth_scheme"),
160        "try_scheme" => Some("harness_auth_try_scheme"),
161        "kind" => Some("harness_auth_kind"),
162        "scopes" => Some("harness_auth_scopes"),
163        "has_scope" => Some("harness_auth_has_scope"),
164        _ => None,
165    }
166}
167
168pub fn harness_obs_ambient(method: &str) -> Option<&'static str> {
169    match method {
170        "span" | "start_span" => Some("__obs_start_span"),
171        "end_span" => Some("__obs_end_span"),
172        "log" => Some("__obs_emit"),
173        "counter" => Some("__obs_counter"),
174        "histogram" => Some("__obs_histogram"),
175        "gauge" => Some("__obs_gauge"),
176        "request_id" => Some("__obs_request_id"),
177        _ => None,
178    }
179}
180
181/// `harness.verdict.*` — the verdict issuance authority. `issue(result_handle)`
182/// resolves the host-owned record of a real `run_test` execution and mints an
183/// opaque proof-of-execution receipt; there is no caller-constructible positive
184/// path and no caller-authored evidence can earn one.
185pub fn harness_verdict_ambient(method: &str) -> Option<&'static str> {
186    match method {
187        "issue" => Some("__harness_verdict_issue"),
188        // Handled VM-side (operates on the opaque receipt, which cannot cross the
189        // hostlib boundary); the mapped name is never dispatched to a builtin,
190        // it only marks the method as known to the typechecker.
191        "same_run" => Some("__harness_verdict_same_run"),
192        _ => None,
193    }
194}
195
196pub fn harness_sub_handle_ambient(sub_handle: &str, method: &str) -> Option<&'static str> {
197    match sub_handle {
198        "stdio" => harness_stdio_ambient(method),
199        "term" => harness_term_ambient(method),
200        "clock" => harness_clock_ambient(method),
201        "fs" => harness_fs_ambient(method),
202        "env" => harness_env_ambient(method),
203        "random" => harness_random_ambient(method),
204        "net" => harness_net_ambient(method),
205        "process" => harness_process_ambient(method),
206        "crypto" => harness_crypto_ambient(method),
207        "system" => harness_system_ambient(method),
208        "secrets" => harness_secrets_ambient(method),
209        "llm" => harness_llm_ambient(method),
210        "tenant" => harness_tenant_ambient(method),
211        "auth" => harness_auth_ambient(method),
212        "obs" => harness_obs_ambient(method),
213        "verdict" => harness_verdict_ambient(method),
214        _ => None,
215    }
216}
217
218pub fn harness_type_sub_handle(type_name: &str) -> Option<&'static str> {
219    match type_name {
220        "HarnessStdio" => Some("stdio"),
221        "HarnessTerm" => Some("term"),
222        "HarnessClock" => Some("clock"),
223        "HarnessFs" => Some("fs"),
224        "HarnessEnv" => Some("env"),
225        "HarnessRandom" => Some("random"),
226        "HarnessNet" => Some("net"),
227        "HarnessProcess" => Some("process"),
228        "HarnessCrypto" => Some("crypto"),
229        "HarnessSystem" => Some("system"),
230        "HarnessSecrets" => Some("secrets"),
231        "HarnessLlm" => Some("llm"),
232        "HarnessTenant" => Some("tenant"),
233        "HarnessAuth" => Some("auth"),
234        "HarnessObs" => Some("obs"),
235        "HarnessVerdict" => Some("verdict"),
236        _ => None,
237    }
238}
239
240pub fn harness_fs_replacement(name: &str) -> Option<&'static str> {
241    match name {
242        "read_file" => Some("harness.fs.read_text"),
243        "read_file_result" => Some("harness.fs.read_text_result"),
244        "read_file_bytes" => Some("harness.fs.read_bytes"),
245        "write_file" => Some("harness.fs.write_text"),
246        "write_file_bytes" => Some("harness.fs.write_bytes"),
247        "replace_file" => Some("harness.fs.replace_text"),
248        "replace_file_result" => Some("harness.fs.replace_text_result"),
249        "replace_file_bytes" => Some("harness.fs.replace_bytes"),
250        "replace_file_bytes_result" => Some("harness.fs.replace_bytes_result"),
251        "file_exists" => Some("harness.fs.exists"),
252        "path_status" => Some("harness.fs.status"),
253        "delete_file" => Some("harness.fs.delete"),
254        "append_file" => Some("harness.fs.append"),
255        "append_file_locked" => Some("harness.fs.append_locked"),
256        "list_dir" => Some("harness.fs.list_dir"),
257        "mkdir" => Some("harness.fs.mkdir"),
258        "copy_file" => Some("harness.fs.copy"),
259        "temp_dir" => Some("harness.fs.temp_dir"),
260        "workspace_temp_dir" => Some("harness.fs.workspace_temp_dir"),
261        "mkdtemp" => Some("harness.fs.mkdtemp"),
262        "mkdtemp_in_workspace" => Some("harness.fs.mkdtemp_in_workspace"),
263        "stat" => Some("harness.fs.stat"),
264        "move_file" => Some("harness.fs.rename"),
265        "read_lines" => Some("harness.fs.read_lines"),
266        "read_lines_page_result" => Some("harness.fs.read_lines_page_result"),
267        "walk_dir" => Some("harness.fs.walk"),
268        "glob" => Some("harness.fs.glob"),
269        "find_text" => Some("harness.fs.find_text"),
270        "find_evidence" => Some("harness.fs.find_evidence"),
271        _ => None,
272    }
273}