hyf

Context-aware query service for Radroots
git clone https://radroots.dev/git/hyf.git
Log | Files | Refs | README | LICENSE

commit 22253d833097dd81edbcea1121097906f6d580f5
parent c8c4b5494baee49fd0287fbb89a247049c9e241c
Author: triesap <tyson@radroots.org>
Date:   Thu,  9 Apr 2026 16:51:23 +0000

runtime: add hyf path contract

Diffstat:
Mpixi.toml | 3++-
Asrc/hyf_runtime/__init__.mojo | 1+
Asrc/hyf_runtime/errors.mojo | 2++
Asrc/hyf_runtime/namespace.mojo | 36++++++++++++++++++++++++++++++++++++
Asrc/hyf_runtime/paths.mojo | 63+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/hyf_runtime/platform.mojo | 39+++++++++++++++++++++++++++++++++++++++
Asrc/hyf_runtime/profile.mojo | 35+++++++++++++++++++++++++++++++++++
Asrc/hyf_runtime/roots.mojo | 74++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atests/test_runtime_paths.mojo | 84+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
9 files changed, 336 insertions(+), 1 deletion(-)

diff --git a/pixi.toml b/pixi.toml @@ -18,5 +18,6 @@ mojson = { path = "../../../../vendor/mojo/mojson" } [tasks] run = "mojo run src/main.mojo" test-unit = "mojo -I src tests/test_hyf.mojo" +test-runtime = "mojo -I src tests/test_runtime_paths.mojo" test-stdio = "mojo -I src tests/test_stdio_contract.mojo" -test = { depends-on = ["test-unit", "test-stdio"] } +test = { depends-on = ["test-unit", "test-runtime", "test-stdio"] } diff --git a/src/hyf_runtime/__init__.mojo b/src/hyf_runtime/__init__.mojo @@ -0,0 +1 @@ + diff --git a/src/hyf_runtime/errors.mojo b/src/hyf_runtime/errors.mojo @@ -0,0 +1,2 @@ +def raise_runtime_contract_error(message: String) raises: + raise Error("hyf runtime contract: " + message) diff --git a/src/hyf_runtime/namespace.mojo b/src/hyf_runtime/namespace.mojo @@ -0,0 +1,36 @@ +from hyf_runtime.errors import raise_runtime_contract_error + + +comptime _HYF_RUNTIME_NAMESPACE = "services/hyf" + + +def hyf_runtime_namespace() -> String: + return _HYF_RUNTIME_NAMESPACE + + +def validate_runtime_namespace(namespace: String) raises: + if namespace != _HYF_RUNTIME_NAMESPACE: + raise_runtime_contract_error( + "namespace must be '" + _HYF_RUNTIME_NAMESPACE + "'" + ) + + +def _trim_trailing_slashes(path: String) -> String: + var trimmed = String(String(path).strip()) + while trimmed.byte_length() > 1 and trimmed.endswith("/"): + trimmed = String(trimmed[byte = 0 : trimmed.byte_length() - 1]) + return trimmed^ + + +def join_runtime_path(left: String, right: String) raises -> String: + var normalized_left = _trim_trailing_slashes(left) + var normalized_right = String(String(right).strip()) + + if normalized_left == "": + raise_runtime_contract_error("path root must not be empty") + if normalized_right == "": + raise_runtime_contract_error("path leaf must not be empty") + + if normalized_left == "/": + return "/" + normalized_right + return normalized_left + "/" + normalized_right diff --git a/src/hyf_runtime/paths.mojo b/src/hyf_runtime/paths.mojo @@ -0,0 +1,63 @@ +from hyf_runtime.namespace import ( + hyf_runtime_namespace, + join_runtime_path, + validate_runtime_namespace, +) +from hyf_runtime.roots import ( + RuntimeRootSet, + runtime_roots_for_unix_profile, +) + + +@fieldwise_init +struct RuntimePaths(Copyable, Movable): + var namespace: String + var config_dir: String + var config_path: String + var data_dir: String + var cache_dir: String + var logs_dir: String + var diagnostics_dir: String + var run_dir: String + var secrets_dir: String + var identity_path: String + + +def runtime_paths_for_namespace( + roots: RuntimeRootSet, namespace: String +) raises -> RuntimePaths: + validate_runtime_namespace(namespace) + + var config_dir = join_runtime_path(roots.config_root, namespace) + var data_dir = join_runtime_path(roots.data_root, namespace) + var cache_dir = join_runtime_path(roots.cache_root, namespace) + var logs_dir = join_runtime_path(roots.logs_root, namespace) + var run_dir = join_runtime_path(roots.run_root, namespace) + var secrets_dir = join_runtime_path(roots.secrets_root, namespace) + + return RuntimePaths( + namespace=String(namespace), + config_dir=String(config_dir), + config_path=join_runtime_path(config_dir, "config.toml"), + data_dir=String(data_dir), + cache_dir=String(cache_dir), + logs_dir=String(logs_dir), + diagnostics_dir=join_runtime_path(logs_dir, "diagnostics"), + run_dir=String(run_dir), + secrets_dir=String(secrets_dir), + identity_path=join_runtime_path(secrets_dir, "identity.secret.json"), + ) + + +def hyf_runtime_paths_for_roots(roots: RuntimeRootSet) raises -> RuntimePaths: + return runtime_paths_for_namespace(roots, hyf_runtime_namespace()) + + +def hyf_runtime_paths_for_unix_profile( + profile: String, + user_home: String, + repo_local_base_root: String, +) raises -> RuntimePaths: + return hyf_runtime_paths_for_roots( + runtime_roots_for_unix_profile(profile, user_home, repo_local_base_root) + ) diff --git a/src/hyf_runtime/platform.mojo b/src/hyf_runtime/platform.mojo @@ -0,0 +1,39 @@ +from hyf_runtime.errors import raise_runtime_contract_error +from hyf_runtime.namespace import join_runtime_path + + +def _require_non_empty_path(path: String, context: String) raises -> String: + var trimmed = String(String(path).strip()) + if trimmed == "": + raise_runtime_contract_error(context + " must not be empty") + return trimmed^ + + +def interactive_user_base_root(user_home: String) raises -> String: + return join_runtime_path( + _require_non_empty_path(user_home, "interactive_user home"), ".radroots" + ) + + +def service_host_config_root() -> String: + return "/etc/radroots" + + +def service_host_data_root() -> String: + return "/var/lib/radroots" + + +def service_host_cache_root() -> String: + return "/var/cache/radroots" + + +def service_host_logs_root() -> String: + return "/var/log/radroots" + + +def service_host_run_root() -> String: + return "/run/radroots" + + +def service_host_secrets_root() -> String: + return "/etc/radroots/secrets" diff --git a/src/hyf_runtime/profile.mojo b/src/hyf_runtime/profile.mojo @@ -0,0 +1,35 @@ +from hyf_runtime.errors import raise_runtime_contract_error + + +comptime _INTERACTIVE_USER_PROFILE = "interactive_user" +comptime _SERVICE_HOST_PROFILE = "service_host" +comptime _REPO_LOCAL_PROFILE = "repo_local" + + +def interactive_user_profile() -> String: + return _INTERACTIVE_USER_PROFILE + + +def service_host_profile() -> String: + return _SERVICE_HOST_PROFILE + + +def repo_local_profile() -> String: + return _REPO_LOCAL_PROFILE + + +def validate_runtime_profile(profile: String) raises: + if ( + profile != _INTERACTIVE_USER_PROFILE + and profile != _SERVICE_HOST_PROFILE + and profile != _REPO_LOCAL_PROFILE + ): + raise_runtime_contract_error( + "profile must be '" + + _INTERACTIVE_USER_PROFILE + + "', '" + + _SERVICE_HOST_PROFILE + + "', or '" + + _REPO_LOCAL_PROFILE + + "'" + ) diff --git a/src/hyf_runtime/roots.mojo b/src/hyf_runtime/roots.mojo @@ -0,0 +1,74 @@ +from hyf_runtime.errors import raise_runtime_contract_error +from hyf_runtime.namespace import join_runtime_path +from hyf_runtime.platform import ( + interactive_user_base_root, + service_host_cache_root, + service_host_config_root, + service_host_data_root, + service_host_logs_root, + service_host_run_root, + service_host_secrets_root, +) +from hyf_runtime.profile import ( + interactive_user_profile, + repo_local_profile, + service_host_profile, + validate_runtime_profile, +) + + +@fieldwise_init +struct RuntimeRootSet(Copyable, Movable): + var config_root: String + var data_root: String + var cache_root: String + var logs_root: String + var run_root: String + var secrets_root: String + + +def runtime_roots_from_base_root(base_root: String) raises -> RuntimeRootSet: + if String(base_root).strip() == "": + raise_runtime_contract_error("base root must not be empty") + + return RuntimeRootSet( + config_root=join_runtime_path(base_root, "config"), + data_root=join_runtime_path(base_root, "data"), + cache_root=join_runtime_path(base_root, "cache"), + logs_root=join_runtime_path(base_root, "logs"), + run_root=join_runtime_path(base_root, "run"), + secrets_root=join_runtime_path(base_root, "secrets"), + ) + + +def interactive_user_runtime_roots(user_home: String) raises -> RuntimeRootSet: + return runtime_roots_from_base_root(interactive_user_base_root(user_home)) + + +def service_host_runtime_roots() -> RuntimeRootSet: + return RuntimeRootSet( + config_root=service_host_config_root(), + data_root=service_host_data_root(), + cache_root=service_host_cache_root(), + logs_root=service_host_logs_root(), + run_root=service_host_run_root(), + secrets_root=service_host_secrets_root(), + ) + + +def runtime_roots_for_unix_profile( + profile: String, + user_home: String, + repo_local_base_root: String, +) raises -> RuntimeRootSet: + validate_runtime_profile(profile) + + if profile == interactive_user_profile(): + return interactive_user_runtime_roots(user_home) + + if profile == service_host_profile(): + return service_host_runtime_roots() + + if String(repo_local_base_root).strip() == "": + raise_runtime_contract_error("repo_local profile requires a base root") + return runtime_roots_from_base_root(repo_local_base_root) diff --git a/tests/test_runtime_paths.mojo b/tests/test_runtime_paths.mojo @@ -0,0 +1,84 @@ +from std.testing import TestSuite, assert_equal, assert_raises + +from hyf_runtime.paths import ( + hyf_runtime_paths_for_unix_profile, + runtime_paths_for_namespace, +) +from hyf_runtime.roots import runtime_roots_from_base_root + + +def test_runtime_paths_repo_local_contract_vector() raises: + var paths = hyf_runtime_paths_for_unix_profile( + "repo_local", "/home/unused", "/tmp/radroots-local/" + ) + + assert_equal(paths.namespace, "services/hyf") + assert_equal(paths.config_dir, "/tmp/radroots-local/config/services/hyf") + assert_equal( + paths.config_path, + "/tmp/radroots-local/config/services/hyf/config.toml", + ) + assert_equal(paths.data_dir, "/tmp/radroots-local/data/services/hyf") + assert_equal(paths.cache_dir, "/tmp/radroots-local/cache/services/hyf") + assert_equal(paths.logs_dir, "/tmp/radroots-local/logs/services/hyf") + assert_equal( + paths.diagnostics_dir, + "/tmp/radroots-local/logs/services/hyf/diagnostics", + ) + assert_equal(paths.run_dir, "/tmp/radroots-local/run/services/hyf") + assert_equal( + paths.identity_path, + "/tmp/radroots-local/secrets/services/hyf/identity.secret.json", + ) + + +def test_runtime_paths_interactive_user_contract_vector() raises: + var paths = hyf_runtime_paths_for_unix_profile( + "interactive_user", "/Users/radroots-test", "" + ) + + assert_equal( + paths.config_path, + "/Users/radroots-test/.radroots/config/services/hyf/config.toml", + ) + assert_equal( + paths.data_dir, "/Users/radroots-test/.radroots/data/services/hyf" + ) + assert_equal( + paths.secrets_dir, + "/Users/radroots-test/.radroots/secrets/services/hyf", + ) + + +def test_runtime_paths_service_host_contract_vector() raises: + var paths = hyf_runtime_paths_for_unix_profile( + "service_host", "/home/unused", "" + ) + + assert_equal(paths.config_path, "/etc/radroots/services/hyf/config.toml") + assert_equal(paths.data_dir, "/var/lib/radroots/services/hyf") + assert_equal(paths.cache_dir, "/var/cache/radroots/services/hyf") + assert_equal(paths.logs_dir, "/var/log/radroots/services/hyf") + assert_equal(paths.run_dir, "/run/radroots/services/hyf") + assert_equal(paths.secrets_dir, "/etc/radroots/secrets/services/hyf") + + +def test_runtime_paths_reject_invalid_profile_namespace_and_base_root() raises: + with assert_raises(): + _ = hyf_runtime_paths_for_unix_profile( + "developer_laptop", "/Users/radroots-test", "" + ) + + with assert_raises(): + _ = hyf_runtime_paths_for_unix_profile( + "repo_local", "/Users/radroots-test", "" + ) + + with assert_raises(): + _ = runtime_paths_for_namespace( + runtime_roots_from_base_root("/tmp/radroots-local"), "hyf" + ) + + +def main() raises: + TestSuite.discover_tests[__functions_in_module()]().run()