From 551a0340bfb43af1e23906e0ae052bc981d96688 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Sat, 31 Oct 2026 04:32:26 +0100 Subject: [PATCH] mind-self-run: the child sees EUREKA_INSTANCE and HUGINN_ENDPOINT, the huginn CLI's identity Co-Authored-By: Claude Opus 5.5 --- crates/mind-body/src/self_run.rs | 4 +++- crates/mind-body/src/self_run/tests/process/lease_child.rs | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/crates/mind-body/src/self_run.rs b/crates/mind-body/src/self_run.rs index 4fc21fc..9c2f441 100644 --- a/crates/mind-body/src/self_run.rs +++ b/crates/mind-body/src/self_run.rs @@ -723,9 +723,11 @@ fn copy_level(root: &Path, from: &Path, to: &Path) -> std::io::Result<()> { /// from `ANTHROPIC_BASE_URL`, so the child gets only what a shell needs to find /// its way; nothing credential-shaped is on the list. Its `HOME` and /// `CLAUDE_CONFIG_DIR` are its fresh configuration directory, set by the spawn. +/// `EUREKA_INSTANCE` and `HUGINN_ENDPOINT` are the `huginn` CLI's whole identity +/// (ruling `eureka-body:ruling:cli-over-mcp-agent-surface`): a name and an address, no secret. fn child_may_see(name: &OsStr) -> bool { let name = name.to_string_lossy(); - matches!(name.as_ref(), "PATH" | "LANG" | "TERM") || name.starts_with("LC_") + matches!(name.as_ref(), "PATH" | "LANG" | "TERM" | "EUREKA_INSTANCE" | "HUGINN_ENDPOINT") || name.starts_with("LC_") } /// The unit's environment as the child sees it: the allow-list, and nothing else. diff --git a/crates/mind-body/src/self_run/tests/process/lease_child.rs b/crates/mind-body/src/self_run/tests/process/lease_child.rs index acd6d93..a64c422 100644 --- a/crates/mind-body/src/self_run/tests/process/lease_child.rs +++ b/crates/mind-body/src/self_run/tests/process/lease_child.rs @@ -70,9 +70,9 @@ echo done"); #[test] fn only_the_allow_listed_names_pass_from_the_units_environment() { let unit: Vec<(std::ffi::OsString, std::ffi::OsString)> = - ["PATH", "HOME", "LANG", "LC_ALL", "TERM", "CLAUDE_CONFIG_DIR", "ANTHROPIC_API_KEY", "CLAUDE_CODE_OAUTH_TOKEN", "ANTHROPIC_BASE_URL", "LCX", "XDG_DATA_HOME"].map(|name| (name.into(), "v".into())).to_vec(); + ["PATH", "HOME", "LANG", "LC_ALL", "TERM", "EUREKA_INSTANCE", "HUGINN_ENDPOINT", "CLAUDE_CONFIG_DIR", "ANTHROPIC_API_KEY", "CLAUDE_CODE_OAUTH_TOKEN", "ANTHROPIC_BASE_URL", "HUGINN_TOKEN", "EUREKA_INSTANCE_X", "LCX", "XDG_DATA_HOME"].map(|name| (name.into(), "v".into())).to_vec(); let passed: Vec = child_environment(&unit).into_iter().map(|(name, _)| name.to_string_lossy().into_owned()).collect(); - assert_eq!(passed, ["PATH", "LANG", "LC_ALL", "TERM"], "home and the configuration directory are the spawn's, never the unit's"); + assert_eq!(passed, ["PATH", "LANG", "LC_ALL", "TERM", "EUREKA_INSTANCE", "HUGINN_ENDPOINT"], "the CLI's two names pass; home, the configuration directory, credentials and look-alikes do not"); } /// Reports where the child's configuration is, its mode, and what is in it; leaves a file and a