Watch
0
0
Fork
You've already forked hyperhive
0

swarm-review-classifier: claude's environment is an allowlist, not the daemon's

hive-claude adds its variables on top of the parent's environment, so
claude inherited the daemon's store identity paths, CREDENTIALS_DIRECTORY
and queue coordinates. claude now starts as this same binary with
SWARM_REVIEW_CLASSIFIER_EXEC_CLAUDE naming the real one; main execs it
before the runtime starts, with the environment cleared down to the API
key, PATH, HOME, CLAUDE_CONFIG_DIR and claude's telemetry settings. The
exec keeps the pid, so hive-claude's cancel and idle timeout still reach
it. An integration test runs the built binary as the trampoline and
checks that a BAO_* variable does not reach the program it execs.
This commit is contained in:
atlas 2026-10-12 04:15:50 +02:00 • committed by mara
commit af1495731e
4 changed files with 176 additions and 21 deletions

View file

@ -20,6 +20,7 @@ use swarm_queue_client::{ClientSecret, QueueConfig};
mod aggregate;
mod answer;
mod child_env;
mod prompt;
mod run;
@ -34,8 +35,17 @@ const PREFIX: &str = "SWARM_REVIEW_CLASSIFIER";
/// longer outage fails the start, and the unit's `Restart=` tries again.
const RETRY_DELAYS_S: [u64; 6] = [1, 2, 4, 8, 16, 30];
#[tokio::main]
async fn main() -> Result<()> {
fn main() -> Result<()> {
// Before anything else: as the trampoline, this process becomes `claude`.
child_env::exec_if_requested();
tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.context("starting the async runtime")?
.block_on(serve())
}
async fn serve() -> Result<()> {
hive_log::init();
swarm_queue_client::install_crypto_provider();
let var = |name: &str| {
@ -45,6 +55,8 @@ async fn main() -> Result<()> {
let client_id = var("OIDC_CLIENT_ID")?;
let claude = run::Claude {
program: PathBuf::from(var("CLAUDE")?),
trampoline: std::env::current_exe()
.context("finding this binary for the claude trampoline")?,
};
let secret = client_secret_with_retry(&client_id).await?;
let queue = swarm_queue_client::connect(QueueConfig {