diff --git a/crates/api/src/bin/task_worker.rs b/crates/api/src/bin/task_worker.rs index 0784f2d7..3e8a3464 100644 --- a/crates/api/src/bin/task_worker.rs +++ b/crates/api/src/bin/task_worker.rs @@ -504,7 +504,7 @@ async fn main() -> anyhow::Result<()> { config.agent.nearai_api_url.clone(), system_configs_service as Arc, config.agent.channel_relay_url.clone(), - config.agent.non_tee_agent_url_pattern.clone(), + config.agent.crabshack_agent_url_pattern.clone(), )); let vpc_auth_config = if config.vpc_auth.is_configured() { diff --git a/crates/api/src/main.rs b/crates/api/src/main.rs index fa279980..70a134cf 100644 --- a/crates/api/src/main.rs +++ b/crates/api/src/main.rs @@ -224,7 +224,7 @@ async fn main() -> anyhow::Result<()> { system_configs_service.clone() as Arc, config.agent.channel_relay_url.clone(), - config.agent.non_tee_agent_url_pattern.clone(), + config.agent.crabshack_agent_url_pattern.clone(), )); // Initialize agent proxy service diff --git a/crates/api/src/routes/agents.rs b/crates/api/src/routes/agents.rs index 90e9ee1a..511d5b90 100644 --- a/crates/api/src/routes/agents.rs +++ b/crates/api/src/routes/agents.rs @@ -114,9 +114,9 @@ async fn get_instance_limit( /// - Subscribed users: plan limit from subscription_plans config /// - Unsubscribed users: no instances allowed (active subscription required) /// -/// In non-TEE mode, the user authenticates to compose-api with passkey credentials (`auth_secret` / +/// In crabshack mode, the user authenticates to compose-api with passkey credentials (`auth_secret` / /// `backup_passphrase`) stored once per user (created on first use) and reused for later instances. -/// Those credentials are registered via non-TEE compose-api `/auth/register` and `/auth/login`. +/// Those credentials are registered via crabshack compose-api `/auth/register` and `/auth/login`. /// /// Supports two response modes via content negotiation: /// - Accept: text/event-stream → Returns SSE stream of lifecycle events @@ -199,15 +199,16 @@ pub async fn create_instance( .ok() .flatten() .unwrap_or_default(); - let non_tee_infra = configs + let crabshack_infra = configs .agent_hosting .as_ref() .and_then(|cfg| cfg.new_agent_with_non_tee_infra) .unwrap_or(false); - // Refresh gateway cookie for non-TEE users (or users with existing non-TEE instances). - // Only refresh when non-TEE infrastructure is enabled to avoid redundant config/database work. - let gateway_cookie = if non_tee_infra { + // Refresh the gateway cookie only when crabshack infrastructure is enabled, to avoid redundant + // config/database work on the legacy_tee path. (setup_gateway_session_for_user itself no-ops + // when the user has no crabshack session to refresh.) + let gateway_cookie = if crabshack_infra { app_state .agent_service .setup_gateway_session_for_user(user.user_id) @@ -226,8 +227,8 @@ pub async fn create_instance( if wants_stream { // SSE streaming response - let rx = if non_tee_infra { - // Non-TEE mode: passkey flow against non-TEE compose-api + let rx = if crabshack_infra { + // crabshack mode: passkey flow against crabshack compose-api app_state .agent_service .create_passkey_instance_streaming( @@ -251,7 +252,7 @@ pub async fn create_instance( ApiError::internal_server_error("Failed to start instance creation") })? } else { - // TEE mode: streaming flow against TEE compose-api + // legacy_tee mode: streaming flow against legacy_tee compose-api app_state .agent_service .create_instance_from_agent_api_streaming( @@ -320,8 +321,8 @@ pub async fn create_instance( } else { // Non-streaming fallback: Collect stream and return final instance as JSON // Note: This blocks the request until instance creation completes - let instance = if non_tee_infra { - // Non-TEE mode: passkey flow against non-TEE compose-api + let instance = if crabshack_infra { + // crabshack mode: passkey flow against crabshack compose-api let mut rx = app_state .agent_service .create_passkey_instance_streaming( @@ -387,7 +388,7 @@ pub async fn create_instance( ApiError::internal_server_error("Created instance not found in database") })? } else { - // TEE mode: TEE compose-api streaming flow; collect events + // legacy_tee mode: legacy_tee compose-api streaming flow; collect events let mut rx = app_state .agent_service .create_instance_from_agent_api_streaming( diff --git a/crates/api/src/routes/oauth.rs b/crates/api/src/routes/oauth.rs index 4a716a24..6912bc7a 100644 --- a/crates/api/src/routes/oauth.rs +++ b/crates/api/src/routes/oauth.rs @@ -972,8 +972,8 @@ pub async fn oauth_callback( tracing::debug!("Session token generated, length: {}", token.len()); - // For non-TEE mode: set up gateway session (authenticate with compose-api) - // This allows users with existing non-TEE instances to access them immediately upon login + // For crabshack mode: set up gateway session (authenticate with compose-api) + // This lets users with existing crabshack instances access them immediately upon login let gateway_cookie = app_state .agent_service .setup_gateway_session_for_user(session.user_id) @@ -1297,8 +1297,8 @@ pub async fn mock_login( session.session_id ); - // For non-TEE mode: set up gateway session (authenticate with compose-api) - // This allows users with existing non-TEE instances to access them immediately upon login + // For crabshack mode: set up gateway session (authenticate with compose-api) + // This lets users with existing crabshack instances access them immediately upon login let gateway_cookie = app_state .agent_service .setup_gateway_session_for_user(user.id) @@ -1418,8 +1418,8 @@ pub async fn near_auth( is_new_user ); - // For non-TEE mode: set up gateway session (authenticate with compose-api) - // This allows users with existing non-TEE instances to access them immediately upon login + // For crabshack mode: set up gateway session (authenticate with compose-api) + // This lets users with existing crabshack instances access them immediately upon login let gateway_cookie = app_state .agent_service .setup_gateway_session_for_user(session.user_id) diff --git a/crates/api/tests/common.rs b/crates/api/tests/common.rs index 0232f8a8..550a51cc 100644 --- a/crates/api/tests/common.rs +++ b/crates/api/tests/common.rs @@ -206,7 +206,7 @@ async fn create_test_server_and_db_inner( system_configs_service.clone() as Arc, config.agent.channel_relay_url.clone(), - config.agent.non_tee_agent_url_pattern.clone(), + config.agent.crabshack_agent_url_pattern.clone(), )); // Initialize subscription service for testing diff --git a/crates/api/tests/upgrade_check_tests.rs b/crates/api/tests/upgrade_check_tests.rs index 5330b3cb..922b55ec 100644 --- a/crates/api/tests/upgrade_check_tests.rs +++ b/crates/api/tests/upgrade_check_tests.rs @@ -304,13 +304,13 @@ async fn test_upgrade_completion_only_on_success() { } // ============================================================================ -// NON-TEE UPGRADE AVAILABILITY (crabshack /images + /instances) +// CRABSHACK UPGRADE AVAILABILITY (crabshack /images + /instances) // ============================================================================ // // These scenarios are fully asserted in the `services` crate (wiremock + mock repository), // because `AgentService::check_upgrade_available` lives there and integration tests here do not // have access to `MockAgentRepository`. Run: -// cargo test -p services non_tee_check_upgrade +// cargo test -p services crabshack_check_upgrade // // Crabshack filter key comes from `service_type_for_crabshack` (see also // `test_service_type_for_crabshack_transformation` below): by default DB `openclaw` maps to @@ -320,14 +320,14 @@ async fn test_upgrade_completion_only_on_success() { // `service_type: "openclaw-dind"` for that path. // // Covered service tests: -// - `non_tee_check_upgrade_legacy_openclaw_dind_filter_and_semver` — legacy `openclaw-dind` row + +// - `crabshack_check_upgrade_legacy_openclaw_dind_filter_and_semver` — legacy `openclaw-dind` row + // crabshack allowlist filter + semver -// - `non_tee_check_upgrade_prerelease_same_numeric_max_picks_later_allowlist_entry` — rc vs release tie -// - `non_tee_check_upgrade_canonical_openclaw_images` — DB `openclaw` + crabshack `openclaw` images -// - `non_tee_check_upgrade_instance_404_blocks_upgrade` — unsynced instance / no upgrade -// - `non_tee_stable_only_filter_picks_highest_stable_not_prerelease` — mixed stable + pre-release allowlist, +// - `crabshack_check_upgrade_prerelease_same_numeric_max_picks_later_allowlist_entry` — rc vs release tie +// - `crabshack_check_upgrade_canonical_openclaw_images` — DB `openclaw` + crabshack `openclaw` images +// - `crabshack_check_upgrade_instance_404_blocks_upgrade` — unsynced instance / no upgrade +// - `crabshack_stable_only_filter_picks_highest_stable_not_prerelease` — mixed stable + pre-release allowlist, // default `allow_prerelease_upgrades=false` picks highest stable -// - `non_tee_allow_prerelease_includes_prerelease_in_latest` — same allowlist with flag true picks pre-release +// - `crabshack_allow_prerelease_includes_prerelease_in_latest` — same allowlist with flag true picks pre-release // // `allow_prerelease_upgrades` behavior (stable-only vs including pre-releases when picking the newest // versioned tag from crabshack) is intentionally exercised there with real `/images` mocks and diff --git a/crates/config/src/lib.rs b/crates/config/src/lib.rs index 57d05880..3445f114 100644 --- a/crates/config/src/lib.rs +++ b/crates/config/src/lib.rs @@ -424,7 +424,7 @@ fn default_nearai_api_url() -> String { .unwrap_or_else(|_| "https://private.near.ai/v1".to_string()) } -fn default_non_tee_agent_url() -> String { +fn default_crabshack_agent_url_pattern() -> String { std::env::var("NON_TEE_AGENT_URL").unwrap_or_else(|_| "claws".to_string()) } @@ -433,16 +433,17 @@ fn default_non_tee_agent_url() -> String { pub struct AgentManager { pub url: String, pub token: String, - /// Whether this manager is non-TEE (true) or TEE (false) - /// Set at construction time based on infrastructure mode + /// Whether this manager is the crabshack (passkey/"claws") path (true) or the + /// legacy_tee (bearer) path (false). Set at construction time based on which + /// env var group the manager was loaded from. #[serde(default)] - pub is_non_tee: bool, + pub is_crabshack: bool, } impl AgentManager { - /// Get the effective is_non_tee value based on explicit configuration - pub fn get_is_non_tee(&self) -> bool { - self.is_non_tee + /// Get the effective is_crabshack value based on explicit configuration + pub fn get_is_crabshack(&self) -> bool { + self.is_crabshack } } @@ -451,7 +452,7 @@ impl std::fmt::Debug for AgentManager { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("AgentManager") .field("url", &self.url) - .field("is_non_tee", &self.get_is_non_tee()) + .field("is_crabshack", &self.get_is_crabshack()) .field("token", &"[REDACTED]") .finish() } @@ -475,10 +476,10 @@ pub struct AgentConfig { /// signing secret instead of the former shared CHANNEL_RELAY_SIGNING_SECRET. #[serde(default)] pub channel_relay_url: Option, - /// URL pattern to identify non-TEE compose-api endpoints for instance type detection + /// URL pattern to identify crabshack compose-api endpoints for instance type detection /// Configurable via NON_TEE_AGENT_URL environment variable (defaults to "claws") - #[serde(default = "default_non_tee_agent_url")] - pub non_tee_agent_url_pattern: String, + #[serde(default = "default_crabshack_agent_url_pattern")] + pub crabshack_agent_url_pattern: String, } /// Split a comma-separated env var value into non-empty trimmed entries. @@ -492,12 +493,11 @@ fn split_csv(value: &str) -> Vec { impl Default for AgentConfig { fn default() -> Self { - // Load managers from both TEE and non-TEE configurations + // Load managers from both the legacy_tee and crabshack env var groups // This supports mixed environments with both manager types available - // Manager type is determined dynamically from URL pattern, not from this setting let mut managers: Vec = Vec::new(); - // Load TEE managers from AGENT_MANAGER_URLS_TEE + // Load legacy_tee managers from AGENT_MANAGER_URLS_TEE if let Ok(urls_raw) = std::env::var("AGENT_MANAGER_URLS_TEE") { let urls = split_csv(&urls_raw); if !urls.is_empty() { @@ -510,20 +510,20 @@ impl Default for AgentConfig { tokens.len() ); } - let tee_mgrs: Vec = urls + let legacy_tee_mgrs: Vec = urls .into_iter() .zip(tokens) .map(|(url, token)| AgentManager { url, token, - is_non_tee: false, + is_crabshack: false, }) .collect(); - managers.extend(tee_mgrs); + managers.extend(legacy_tee_mgrs); } } - // Load non-TEE managers from AGENT_MANAGER_URLS + // Load crabshack (passkey/"claws") managers from AGENT_MANAGER_URLS if let Ok(urls_raw) = std::env::var("AGENT_MANAGER_URLS") { let urls = split_csv(&urls_raw); if !urls.is_empty() { @@ -536,21 +536,21 @@ impl Default for AgentConfig { tokens.len() ); } - let non_tee_mgrs: Vec = urls + let crabshack_mgrs: Vec = urls .into_iter() .zip(tokens) .map(|(url, token)| AgentManager { url, token, - is_non_tee: true, + is_crabshack: true, }) .collect(); - managers.extend(non_tee_mgrs); + managers.extend(crabshack_mgrs); } } // If no managers configured, fall back to legacy AGENT_API_BASE_URL - // This will be interpreted as TEE if no "claws" pattern in URL + // This is treated as a legacy_tee (bearer) manager if managers.is_empty() { let url = std::env::var("AGENT_API_BASE_URL") .unwrap_or_else(|_| "https://api.agent.near.ai".to_string()); @@ -558,7 +558,7 @@ impl Default for AgentConfig { managers.push(AgentManager { url, token, - is_non_tee: false, + is_crabshack: false, }); } @@ -571,7 +571,7 @@ impl Default for AgentConfig { .map(|url| url.trim_end_matches('/').to_string() + "/v1") .unwrap_or_else(|_| "https://private.near.ai/v1".to_string()), channel_relay_url: std::env::var("CHANNEL_RELAY_URL").ok(), - non_tee_agent_url_pattern: default_non_tee_agent_url(), + crabshack_agent_url_pattern: default_crabshack_agent_url_pattern(), } } } @@ -962,7 +962,7 @@ mod tests { let mgr = AgentManager { url: "https://test.com".to_string(), token: "super-secret".to_string(), - is_non_tee: false, + is_crabshack: false, }; let debug_output = format!("{:?}", mgr); assert!(debug_output.contains("https://test.com")); @@ -1200,39 +1200,39 @@ mod tests { #[test] #[serial] fn test_agent_manager_type_detection_from_url() { - // Test that manager type uses explicit is_non_tee field (not URL pattern detection) + // Test that manager type uses the explicit is_crabshack field (not URL pattern detection) - // Manager with is_non_tee=true should be detected as non-TEE - let non_tee_mgr = AgentManager { + // Manager with is_crabshack=true should be detected as crabshack + let crabshack_mgr = AgentManager { url: "https://api.openclaw-dev.near.ai".to_string(), token: "token1".to_string(), - is_non_tee: true, + is_crabshack: true, }; assert!( - non_tee_mgr.get_is_non_tee(), - "Manager with is_non_tee=true should be non-TEE" + crabshack_mgr.get_is_crabshack(), + "Manager with is_crabshack=true should be crabshack" ); - // Manager with is_non_tee=false should be detected as TEE - let tee_mgr = AgentManager { + // Manager with is_crabshack=false should be detected as legacy_tee + let legacy_tee_mgr = AgentManager { url: "https://agents.example.com/api/crabshack".to_string(), token: "token2".to_string(), - is_non_tee: false, + is_crabshack: false, }; assert!( - !tee_mgr.get_is_non_tee(), - "Manager with is_non_tee=false should be TEE" + !legacy_tee_mgr.get_is_crabshack(), + "Manager with is_crabshack=false should be legacy_tee" ); - // Test that is_non_tee field is respected regardless of URL + // Test that is_crabshack field is respected regardless of URL let compose_mgr = AgentManager { url: "https://compose.example.com".to_string(), token: "token3".to_string(), - is_non_tee: true, + is_crabshack: true, }; assert!( - compose_mgr.get_is_non_tee(), - "Manager with is_non_tee=true should be non-TEE even with generic URL" + compose_mgr.get_is_crabshack(), + "Manager with is_crabshack=true should be crabshack even with generic URL" ); } diff --git a/crates/services/src/agent/ports.rs b/crates/services/src/agent/ports.rs index f40ab392..7286c8c7 100644 --- a/crates/services/src/agent/ports.rs +++ b/crates/services/src/agent/ports.rs @@ -39,7 +39,7 @@ pub fn is_valid_service_type(service_type: &str) -> bool { /// Default [`AgentInstance::service_type`] when unset in storage or API payloads. pub const DEFAULT_AGENT_SERVICE_TYPE: &str = "openclaw"; -/// Enrichment data from the agent compose-api (TEE or non-TEE) for instance responses +/// Enrichment data from the agent compose-api (legacy_tee or crabshack) for instance responses #[derive(Debug, Clone, Default)] pub struct AgentApiInstanceEnrichment { pub status: Option, @@ -407,7 +407,7 @@ pub trait AgentService: Send + Sync { params: InstanceCreationParams, ) -> anyhow::Result; - /// Create instance via TEE compose-api with streaming lifecycle events. + /// Create instance via legacy_tee compose-api with streaming lifecycle events. /// Streams events from the agent API as they occur during instance creation. /// Returns a receiver that yields raw JSON events from the agent API. async fn create_instance_from_agent_api_streaming( @@ -418,7 +418,7 @@ pub trait AgentService: Send + Sync { ) -> anyhow::Result>>; /// Create instance with per-instance passkey credentials and streaming lifecycle events. - /// Calls non-TEE compose-api /auth/register to set up the instance with unique credentials, + /// Calls crabshack compose-api /auth/register to set up the instance with unique credentials, /// then creates the instance using the session token instead of manager token. /// Returns a receiver that yields raw JSON events as they occur during instance creation. async fn create_passkey_instance_streaming( @@ -534,7 +534,7 @@ pub trait AgentService: Send + Sync { /// Creates user passkey credentials on first login, then sets the gateway cookie via /auth/proxy-session. /// Returns the Set-Cookie header value to be forwarded to the browser, or None if not available. /// Runs when `new_agent_with_non_tee_infra` is set, or when the user already has passkey credentials - /// or instances on a non-TEE manager (so crabshack sessions still work after switching global infra to TEE). + /// or instances on a crabshack manager (so crabshack sessions still work after the global infra flag is turned off). /// Propagates errors if system configs cannot be loaded (callers typically log and continue). /// Safe to call multiple times (idempotent on subsequent logins). async fn setup_gateway_session_for_user( diff --git a/crates/services/src/agent/service.rs b/crates/services/src/agent/service.rs index c6a7f7d0..146b07e1 100644 --- a/crates/services/src/agent/service.rs +++ b/crates/services/src/agent/service.rs @@ -20,8 +20,8 @@ use super::ports::{ /// Prevents DoS from a malicious Agent API sending extremely long lines. const MAX_BUFFER_SIZE: usize = 100 * 1024; -/// How many instances to load when deciding if gateway session setup should run for legacy non-TEE users -/// (global TEE flag but instances on a non-TEE manager). Cap keeps login-path DB work bounded. +/// How many instances to load when deciding if gateway session setup should run for legacy crabshack users +/// (crabshack infra flag off but instances on a crabshack manager). Cap keeps login-path DB work bounded. const GATEWAY_SESSION_INSTANCE_SCAN_LIMIT: i64 = 50; // Resource sizing defaults (instance_default_cpus, instance_default_mem_limit, instance_default_storage_size) @@ -187,7 +187,7 @@ fn compare_semantic_versions(a: &str, b: &str) -> std::cmp::Ordering { /// - openclaw: `hosting.crabshack.openclaw_image` → "docker.io/nearaidev/openclaw-nearai-worker:latest" /// /// Does not apply crabshack `deploy_latest_version_tag` flags; use -/// `AgentServiceImpl::resolve_non_tee_worker_image_ref` for non-TEE deploys. +/// `AgentServiceImpl::resolve_crabshack_worker_image_ref` for crabshack deploys. pub fn get_image_for_service_type( service_type: &str, hosting: Option<&AgentHostingConfig>, @@ -202,7 +202,7 @@ pub fn get_image_for_service_type( } } -/// Convert canonical service type to crabshack format for non-TEE. +/// Convert a canonical service type to the crabshack compose format. /// Crabshack uses inconsistent naming (configurable via AgentHostingConfig): /// - ironclaw → ironclaw-dind by default (can be overridden via crabshack.ironclaw_service_type) /// - openclaw → openclaw by default (can be overridden via crabshack.openclaw_service_type) @@ -221,14 +221,14 @@ pub fn service_type_for_crabshack( } } -/// `service_type` for POST `/instances`: canonical `ironclaw` / `openclaw` on TEE managers; -/// Crabshack compose name from [`service_type_for_crabshack`] on non-TEE (e.g. `ironclaw` → `ironclaw-dind`). +/// `service_type` for POST `/instances`: canonical `ironclaw` / `openclaw` on legacy_tee managers; +/// Crabshack compose name from [`service_type_for_crabshack`] for crabshack managers (e.g. `ironclaw` → `ironclaw-dind`). fn compose_api_service_type_on_create( - manager_is_non_tee: bool, + manager_is_crabshack: bool, canonical_service_type: &str, hosting: Option<&AgentHostingConfig>, ) -> String { - if manager_is_non_tee { + if manager_is_crabshack { service_type_for_crabshack(canonical_service_type, hosting) } else { canonical_service_type.to_string() @@ -261,17 +261,17 @@ pub struct AgentServiceImpl { /// Agent manager endpoints (URL + token pairs) managers: Vec, /// Type-specific round-robin counters for capacity-aware manager selection. - tee_manager_rr_counter: AtomicUsize, - non_tee_manager_rr_counter: AtomicUsize, + legacy_tee_manager_rr_counter: AtomicUsize, + crabshack_manager_rr_counter: AtomicUsize, /// Chat-API base URL passed to the Agent API as nearai_api_url when creating instances nearai_api_url: String, /// System configs for reading instance limits and defaults system_configs_service: Arc, /// Channel-relay URL for provisioning relay config to IronClaw instances channel_relay_url: Option, - /// URL pattern to identify non-TEE manager endpoints (e.g., "claws") + /// URL pattern to identify crabshack (passkey/"claws") manager endpoints (e.g., "claws") /// Used to determine instance type when routing to managers - non_tee_agent_url_pattern: String, + crabshack_agent_url_pattern: String, } /// Static helper: Fetch instance details from Agent API GET /instances/{name}. @@ -319,19 +319,19 @@ enum AuthMethod<'a> { #[derive(Clone, Copy, Debug)] enum ManagerType { - Tee, - NonTee, + LegacyTee, + Crabshack, } impl ManagerType { - fn is_non_tee(self) -> bool { - matches!(self, Self::NonTee) + fn is_crabshack(self) -> bool { + matches!(self, Self::Crabshack) } fn as_str(self) -> &'static str { match self { - Self::Tee => "tee", - Self::NonTee => "non-tee", + Self::LegacyTee => "legacy-tee", + Self::Crabshack => "crabshack", } } } @@ -351,7 +351,7 @@ impl AgentServiceImpl { nearai_api_url: String, system_configs_service: Arc, channel_relay_url: Option, - non_tee_agent_url_pattern: String, + crabshack_agent_url_pattern: String, ) -> Self { // Validate required configuration if managers.is_empty() { @@ -377,12 +377,12 @@ impl AgentServiceImpl { repository, http_client, managers, - tee_manager_rr_counter: AtomicUsize::new(0), - non_tee_manager_rr_counter: AtomicUsize::new(0), + legacy_tee_manager_rr_counter: AtomicUsize::new(0), + crabshack_manager_rr_counter: AtomicUsize::new(0), nearai_api_url, system_configs_service, channel_relay_url, - non_tee_agent_url_pattern, + crabshack_agent_url_pattern, } } @@ -390,7 +390,9 @@ impl AgentServiceImpl { /// Does NOT check capacity — use type-specific capacity-aware helpers for production paths. #[cfg(test)] fn next_manager(&self) -> &AgentManager { - let idx = self.tee_manager_rr_counter.fetch_add(1, Ordering::Relaxed); + let idx = self + .legacy_tee_manager_rr_counter + .fetch_add(1, Ordering::Relaxed); &self.managers[idx % self.managers.len()] } @@ -404,10 +406,10 @@ impl AgentServiceImpl { .unwrap_or_default() } - /// Docker image for non-TEE worker deploy when the caller did not supply `image`. + /// Docker image for crabshack worker deploy when the caller did not supply `image`. /// Honors crabshack `*_deploy_latest_version_tag` flags (latest versioned ref from the manager /// `/images` allowlist, same as upgrade checks), ignoring pinned `*_image`. - async fn resolve_non_tee_worker_image_ref( + async fn resolve_crabshack_worker_image_ref( &self, manager: &AgentManager, canonical_service_type: &str, @@ -425,7 +427,7 @@ impl AgentServiceImpl { } match self - .get_latest_image_non_tee(manager, canonical_service_type, "deploy") + .get_latest_image_crabshack(manager, canonical_service_type, "deploy") .await { Ok((ref_, _, _)) => Ok(ref_), @@ -440,8 +442,9 @@ impl AgentServiceImpl { } } - /// `true` when admin config says new agents use non-TEE infra (passkey / non-TEE managers). - fn is_non_tee_infra(configs: &SystemConfigs) -> bool { + /// `true` when admin config says new agents use crabshack infra (passkey / crabshack managers). + /// Reads the `new_agent_with_non_tee_infra` system-config field (name preserved for DB/admin contract). + fn uses_crabshack_infra(configs: &SystemConfigs) -> bool { configs .agent_hosting .as_ref() @@ -449,13 +452,13 @@ impl AgentServiceImpl { .unwrap_or(false) } - /// User has at least one instance whose stored manager URL matches a configured non-TEE manager. - fn user_has_non_tee_routed_instance(&self, instances: &[AgentInstance]) -> bool { + /// User has at least one instance whose stored manager URL matches a configured crabshack manager. + fn user_has_crabshack_routed_instance(&self, instances: &[AgentInstance]) -> bool { instances.iter().any(|inst| { inst.agent_api_base_url.as_ref().is_some_and(|url| { self.managers .iter() - .any(|m| m.url == *url && m.get_is_non_tee()) + .any(|m| m.url == *url && m.get_is_crabshack()) }) }) } @@ -471,12 +474,12 @@ impl AgentServiceImpl { manager_type: ManagerType, ) -> anyhow::Result { let configs = self.get_system_configs().await; - let is_non_tee = manager_type.is_non_tee(); + let is_crabshack = manager_type.is_crabshack(); let available_managers: Vec<_> = self .managers .iter() - .filter(|mgr| is_non_tee == mgr.get_is_non_tee()) + .filter(|mgr| is_crabshack == mgr.get_is_crabshack()) .collect(); if available_managers.is_empty() { @@ -489,9 +492,11 @@ impl AgentServiceImpl { let n = available_managers.len(); let start = match manager_type { - ManagerType::Tee => self.tee_manager_rr_counter.fetch_add(1, Ordering::Relaxed), - ManagerType::NonTee => self - .non_tee_manager_rr_counter + ManagerType::LegacyTee => self + .legacy_tee_manager_rr_counter + .fetch_add(1, Ordering::Relaxed), + ManagerType::Crabshack => self + .crabshack_manager_rr_counter .fetch_add(1, Ordering::Relaxed), }; @@ -529,12 +534,13 @@ impl AgentServiceImpl { )) } - async fn next_available_tee_manager(&self) -> anyhow::Result { - self.next_available_manager_for_type(ManagerType::Tee).await + async fn next_available_legacy_tee_manager(&self) -> anyhow::Result { + self.next_available_manager_for_type(ManagerType::LegacyTee) + .await } - async fn next_available_non_tee_manager(&self) -> anyhow::Result { - self.next_available_manager_for_type(ManagerType::NonTee) + async fn next_available_crabshack_manager(&self) -> anyhow::Result { + self.next_available_manager_for_type(ManagerType::Crabshack) .await } @@ -584,40 +590,46 @@ impl AgentServiceImpl { } // Use first available manager as fallback, but try to match manager type if stored URL exists - // This ensures instances created as TEE don't accidentally get routed to non-TEE managers + // This ensures instances created on a legacy_tee manager don't accidentally get routed to crabshack managers let fallback_manager = if let Some(ref stored_url) = instance.agent_api_base_url { // Determine expected manager type based on URL pattern: - // - Non-TEE: URLs containing the configured non_tee_agent_url_pattern (e.g., "claws") - // - TEE: all other URLs (TEE compose-api / manager hostnames) - let expected_is_non_tee = stored_url.contains(&self.non_tee_agent_url_pattern); + // - crabshack: URLs containing the configured crabshack_agent_url_pattern (e.g., "claws") + // - legacy_tee: all other URLs (bearer compose-api / manager hostnames) + let expected_is_crabshack = stored_url.contains(&self.crabshack_agent_url_pattern); // Find a manager of the matching type if let Some(matching_mgr) = self.managers.iter().find(|m| { - if expected_is_non_tee { - m.get_is_non_tee() + if expected_is_crabshack { + m.get_is_crabshack() } else { - !m.get_is_non_tee() + !m.get_is_crabshack() } }) { tracing::info!( - "resolve_manager: Stored URL {} not found, using fallback {} (expected manager type: non_tee={})", + "resolve_manager: Stored URL {} not found, using fallback {} (expected manager type: crabshack={})", stored_url, matching_mgr.url, - expected_is_non_tee + expected_is_crabshack ); matching_mgr } else { // No matching type available - fail rather than silently use wrong type // This prevents instances from being incorrectly routed to managers of a different authentication type - let expected_type = if expected_is_non_tee { - "non-TEE" + let expected_type = if expected_is_crabshack { + "crabshack" } else { - "TEE" + "legacy-tee" }; let available_types = self .managers .iter() - .map(|m| if m.get_is_non_tee() { "non-TEE" } else { "TEE" }) + .map(|m| { + if m.get_is_crabshack() { + "crabshack" + } else { + "legacy-tee" + } + }) .collect::>() .join(", "); tracing::error!( @@ -716,8 +728,8 @@ impl AgentServiceImpl { } /// Resolve the bearer token to use for agent API calls. - /// In non-TEE mode: tries to fetch user's passkey credentials and login to compose-api. - /// In TEE mode: always uses manager token (TEE compose-api does not support passkey login). + /// In crabshack mode: tries to fetch user's passkey credentials and login to compose-api. + /// In legacy_tee mode: always uses manager token (legacy_tee compose-api does not support passkey login). async fn resolve_bearer_token( &self, instance: &AgentInstance, @@ -727,12 +739,12 @@ impl AgentServiceImpl { // not by the current global NON_TEE_INFRA setting. This allows instances created in one mode // to be accessed correctly even if the system is now running in a different mode. - if !manager.get_is_non_tee() { - // TEE manager: use manager token directly (no passkey/compose-api) + if !manager.get_is_crabshack() { + // legacy_tee manager: use manager token directly (no passkey/compose-api) return Ok(manager.token.clone()); } - // Non-TEE manager: try passkey credentials for compose-api login + // crabshack manager: try passkey credentials for compose-api login if let Ok(Some((auth_secret, backup_passphrase))) = self .repository .get_user_passkey_credentials(instance.user_id) @@ -1038,7 +1050,7 @@ impl AgentServiceImpl { // Canonical type for DB and `get_image_for_*` match keys (`ironclaw`, `openclaw`). let canonical_service_type = service_type.to_string(); let compose_api_service_type = compose_api_service_type_on_create( - manager.get_is_non_tee(), + manager.get_is_crabshack(), &canonical_service_type, configs.agent_hosting.as_ref(), ); @@ -1046,10 +1058,10 @@ impl AgentServiceImpl { // Determine image to use based on manager type let image_to_use = if let Some(img) = params.image { Some(img) - } else if manager.get_is_non_tee() { - // Non-TEE manager requires image; optional latest versioned ref from manager allowlist. + } else if manager.get_is_crabshack() { + // crabshack manager requires image; optional latest versioned ref from manager allowlist. Some( - self.resolve_non_tee_worker_image_ref( + self.resolve_crabshack_worker_image_ref( manager, &canonical_service_type, configs.agent_hosting.as_ref(), @@ -1057,7 +1069,7 @@ impl AgentServiceImpl { .await?, ) } else { - // TEE manager: image is optional, let Agent API determine it + // legacy_tee manager: image is optional, let Agent API determine it None }; @@ -1072,7 +1084,7 @@ impl AgentServiceImpl { }); // Only include resource fields if they're explicitly set or available - // In non-TEE mode, use configured defaults; in TEE mode, let Agent API use its defaults + // In crabshack mode, use configured defaults; in legacy_tee mode, let Agent API use its defaults let cpus = params.cpus.as_deref().or(Some(default_cpus)); if let Some(cpu) = cpus { request_body["cpus"] = serde_json::json!(cpu); @@ -1202,11 +1214,11 @@ impl AgentServiceImpl { let encoded_name = urlencoding::encode(instance_name); // Use different endpoints based on deployment mode - let url = if manager.get_is_non_tee() { - // Non-TEE: separate /ssh endpoint + let url = if manager.get_is_crabshack() { + // crabshack: separate /ssh endpoint format!("{}/instances/{}/ssh", manager.url, encoded_name) } else { - // TEE: ssh_command is in the main instance details endpoint + // legacy_tee: ssh_command is in the main instance details endpoint format!("{}/instances/{}", manager.url, encoded_name) }; @@ -1214,10 +1226,10 @@ impl AgentServiceImpl { let token = bearer_token.unwrap_or(&manager.token); tracing::debug!( - "Fetching SSH command from Agent API: instance_name={}, url={}, tee={}", + "Fetching SSH command from Agent API: instance_name={}, url={}, legacy_tee={}", instance_name, url, - !manager.get_is_non_tee() + !manager.get_is_crabshack() ); let response = http_client @@ -1248,11 +1260,11 @@ impl AgentServiceImpl { Ok(data) => { tracing::debug!("SSH command fetched: instance_name={}", instance_name); // Different field names based on deployment mode - let ssh_command = if manager.get_is_non_tee() { - // Non-TEE: /ssh endpoint returns "command" field + let ssh_command = if manager.get_is_crabshack() { + // crabshack: /ssh endpoint returns "command" field data.get("command") } else { - // TEE: /instances/{name} endpoint returns "ssh_command" field + // legacy_tee: /instances/{name} endpoint returns "ssh_command" field data.get("ssh_command") }; ssh_command.and_then(|v| v.as_str()).map(|s| s.to_string()) @@ -1302,18 +1314,18 @@ impl AgentServiceImpl { let canonical_service_type = service_type.to_string(); let compose_api_service_type = compose_api_service_type_on_create( - manager.get_is_non_tee(), + manager.get_is_crabshack(), &canonical_service_type, configs.agent_hosting.as_ref(), ); // Build request body with base fields - // Note: In non-TEE mode, image is required; in TEE mode it's optional + // Note: In crabshack mode, image is required; in legacy_tee mode it's optional let image_to_use = if let Some(img) = params.image { Some(img) - } else if manager.get_is_non_tee() { + } else if manager.get_is_crabshack() { Some( - self.resolve_non_tee_worker_image_ref( + self.resolve_crabshack_worker_image_ref( manager, &canonical_service_type, configs.agent_hosting.as_ref(), @@ -1321,7 +1333,7 @@ impl AgentServiceImpl { .await?, ) } else { - // TEE manager: image is optional, let Agent API determine it + // legacy_tee manager: image is optional, let Agent API determine it None }; @@ -1336,7 +1348,7 @@ impl AgentServiceImpl { }); // Only include resource fields if they're explicitly set or available - // In non-TEE mode, use configured defaults; in TEE mode, let Agent API use its defaults + // In crabshack mode, use configured defaults; in legacy_tee mode, let Agent API use its defaults let cpus = params.cpus.as_deref().or(Some(default_cpus)); if let Some(cpu) = cpus { request_body["cpus"] = serde_json::json!(cpu); @@ -1577,7 +1589,7 @@ async fn save_passkey_instance_from_event( } // Extract instance_url from API response if available - // Try "instance_url" first (returned by non-TEE compose-api in final event), + // Try "instance_url" first (returned by crabshack compose-api in final event), // then fall back to "url" (used by other API responses) let instance_url = instance_data .get("instance_url") @@ -1585,7 +1597,7 @@ async fn save_passkey_instance_from_event( .and_then(|v| v.as_str()) .map(|s| s.to_string()) .or_else(|| { - // Fall back to constructing instance_url from manager domain (non-TEE mode) + // Fall back to constructing instance_url from manager domain (crabshack mode) // Extract domain from agent_api_base_url (e.g., https://venice-staging.near-dev.org/api/crabshack -> venice-staging.near-dev.org) if let (Some(token), Some(manager_url)) = (&instance_token, ¶ms.agent_api_base_url) { @@ -1743,7 +1755,7 @@ impl AgentService for AgentServiceImpl { tracing::info!("Creating instance from Agent API: user_id={}", user_id); // Pick next manager with available capacity (round-robin, skipping full managers) - let manager = self.next_available_tee_manager().await?; + let manager = self.next_available_legacy_tee_manager().await?; // Create an unbound API key on behalf of the user; the agent will use it to authenticate to the chat-api. let key_name = params @@ -1884,7 +1896,7 @@ impl AgentService for AgentServiceImpl { Ok(instance) } - /// Create instance via TEE compose-api with streaming lifecycle events. + /// Create instance via legacy_tee compose-api with streaming lifecycle events. /// Similar to create_instance_from_agent_api but streams events as they occur. async fn create_instance_from_agent_api_streaming( &self, @@ -1907,7 +1919,7 @@ impl AgentService for AgentServiceImpl { } // Pick next manager with available capacity - let manager = self.next_available_tee_manager().await?; + let manager = self.next_available_legacy_tee_manager().await?; // Create an unbound API key on behalf of the user let key_name = params @@ -2112,26 +2124,26 @@ impl AgentService for AgentServiceImpl { ); // Pick next manager with available capacity - let manager = self.next_available_non_tee_manager().await?; + let manager = self.next_available_crabshack_manager().await?; let manager_url = manager.url.clone(); tracing::info!( - "create_passkey_instance_streaming: selected manager_url={}, is_non_tee_manager={}, user_id={}", + "create_passkey_instance_streaming: selected manager_url={}, is_crabshack_manager={}, user_id={}", manager_url, - manager.get_is_non_tee(), + manager.get_is_crabshack(), user_id ); // Get session token based on manager type - let session_token = if !manager.get_is_non_tee() { - // TEE manager: Use manager token directly (main branch behavior) + let session_token = if !manager.get_is_crabshack() { + // legacy_tee manager: Use manager token directly (main branch behavior) tracing::info!( - "create_passkey_instance_streaming: TEE manager detected, using manager token" + "create_passkey_instance_streaming: legacy_tee manager detected, using manager token" ); manager.token.clone() } else { - // Non-TEE manager: Get or create user's passkey credentials and login to compose-api - tracing::info!("create_passkey_instance_streaming: Non-TEE manager detected, logging in via compose-api"); + // crabshack manager: Get or create user's passkey credentials and login to compose-api + tracing::info!("create_passkey_instance_streaming: crabshack manager detected, logging in via compose-api"); let (auth_secret, backup_passphrase) = match self .repository @@ -2146,9 +2158,9 @@ impl AgentService for AgentServiceImpl { (secret, passphrase) } Ok(None) => { - // First non-TEE instance creation - auto-generate passkey credentials + // First crabshack instance creation - auto-generate passkey credentials tracing::info!( - "Auto-generating passkey credentials for user on first non-TEE instance creation: user_id={}", + "Auto-generating passkey credentials for user on first crabshack instance creation: user_id={}", user_id ); let auth_secret = Self::generate_random_credential(32); @@ -2391,8 +2403,8 @@ impl AgentService for AgentServiceImpl { tracing::info!("Passkey instance saved successfully: user_id={}, dashboard_url={:?}", user_id, instance.dashboard_url); // Send final event with dashboard_url and instance_url to frontend - // This is essential for non-TEE where Agent API doesn't return these fields - if manager_clone.get_is_non_tee() { + // This is essential for crabshack where Agent API doesn't return these fields + if manager_clone.get_is_crabshack() { let final_event = serde_json::json!({ "instance": { "name": instance.name, @@ -2745,13 +2757,13 @@ impl AgentService for AgentServiceImpl { // Token already fetched by this or another concurrent task key_guard.clone() } else { - // First task to reach this key: perform the async login (non-TEE only) + // First task to reach this key: perform the async login (crabshack only) drop(key_guard); // Release lock temporarily for async work - // Only attempt passkey login for non-TEE managers - // TEE managers use the manager token directly - let token = if mgr.get_is_non_tee() { - // Non-TEE: try to get user's passkey credentials; fall back to manager token if not found + // Only attempt passkey login for crabshack managers + // legacy_tee managers use the manager token directly + let token = if mgr.get_is_crabshack() { + // crabshack: try to get user's passkey credentials; fall back to manager token if not found if let Ok(Some((auth_secret, backup_passphrase))) = repo.get_user_passkey_credentials(user_id).await { @@ -2768,7 +2780,7 @@ impl AgentService for AgentServiceImpl { None // Fall back to manager token } } else { - // TEE: always use manager token (bearer_token = None) + // legacy_tee: always use manager token (bearer_token = None) None }; @@ -3066,18 +3078,18 @@ impl AgentService for AgentServiceImpl { let manager = self.resolve_manager(&instance)?; tracing::info!( - "Upgrade: manager_url={}, is_non_tee={}, instance_name={}", + "Upgrade: manager_url={}, is_crabshack={}, instance_name={}", manager.url, - manager.get_is_non_tee(), + manager.get_is_crabshack(), instance.name ); // Route to appropriate logic based on infrastructure type - if manager.get_is_non_tee() { - self.upgrade_instance_stream_non_tee(&instance, manager, instance_id, user_id) + if manager.get_is_crabshack() { + self.upgrade_instance_stream_crabshack(&instance, manager, instance_id, user_id) .await } else { - self.upgrade_instance_stream_tee(&instance, manager, instance_id, user_id) + self.upgrade_instance_stream_legacy_tee(&instance, manager, instance_id, user_id) .await } } @@ -3105,18 +3117,18 @@ impl AgentService for AgentServiceImpl { let manager = self.resolve_manager(&instance)?; tracing::info!( - "Upgrade check: manager_url={}, is_non_tee={}, instance_name={}", + "Upgrade check: manager_url={}, is_crabshack={}, instance_name={}", manager.url, - manager.get_is_non_tee(), + manager.get_is_crabshack(), instance.name ); // Route to appropriate logic based on infrastructure type - if manager.get_is_non_tee() { - self.check_upgrade_available_non_tee(&instance, manager, instance_id) + if manager.get_is_crabshack() { + self.check_upgrade_available_crabshack(&instance, manager, instance_id) .await } else { - self.check_upgrade_available_tee(&instance, manager, instance_id) + self.check_upgrade_available_legacy_tee(&instance, manager, instance_id) .await } } @@ -3484,7 +3496,7 @@ impl AgentService for AgentServiceImpl { Ok(Some(c)) => c, }; - let non_tee_global = Self::is_non_tee_infra(&configs); + let crabshack_global = Self::uses_crabshack_infra(&configs); // Try to get existing user passkey credentials let passkey_existing = match self.repository.get_user_passkey_credentials(user_id).await { @@ -3499,33 +3511,33 @@ impl AgentService for AgentServiceImpl { } }; - // Primary: new agents use non-TEE (admin flag). Also attempt when user still needs - // crabshack session after an infra switch: existing passkey or non-TEE routed instances + // Primary: new agents use crabshack infra (admin flag). Also attempt when user still needs + // a crabshack session after an infra switch: existing passkey or crabshack-routed instances // (mirrors per-instance manager typing in `resolve_bearer_token`). - let mut needs_non_tee_gateway = non_tee_global; - if !needs_non_tee_gateway { + let mut needs_crabshack_gateway = crabshack_global; + if !needs_crabshack_gateway { if passkey_existing.is_some() { - needs_non_tee_gateway = true; + needs_crabshack_gateway = true; tracing::debug!( - "Gateway session: user has passkey credentials while global infra is TEE — still attempting compose session" + "Gateway session: user has passkey credentials while global infra flag is off — still attempting compose session" ); } else { let (instances, _) = self .repository .list_user_instances(user_id, GATEWAY_SESSION_INSTANCE_SCAN_LIMIT, 0) .await?; - if self.user_has_non_tee_routed_instance(&instances) { - needs_non_tee_gateway = true; + if self.user_has_crabshack_routed_instance(&instances) { + needs_crabshack_gateway = true; tracing::debug!( - "Gateway session: user has non-TEE instance while global infra is TEE — still attempting compose session" + "Gateway session: user has crabshack instance while global infra flag is off — still attempting compose session" ); } } } - if !needs_non_tee_gateway { + if !needs_crabshack_gateway { tracing::debug!( - "Skipping gateway session: TEE infra, no passkey, no non-TEE routed instances" + "Skipping gateway session: crabshack infra flag off, no passkey, no crabshack-routed instances" ); return Ok(None); } @@ -3533,10 +3545,10 @@ impl AgentService for AgentServiceImpl { let manager = self .managers .iter() - .find(|mgr| mgr.get_is_non_tee()) + .find(|mgr| mgr.get_is_crabshack()) .ok_or_else(|| { anyhow!( - "No non-TEE agent manager configured (have {} manager(s))", + "No crabshack agent manager configured (have {} manager(s))", self.managers.len() ) })?; @@ -3990,7 +4002,7 @@ impl AgentService for AgentServiceImpl { } /// Response structure from crabshack /images endpoint -/// Used to parse and filter non-TEE image allowlist +/// Used to parse and filter crabshack image allowlist #[derive(serde::Deserialize, Debug, Clone)] #[allow(dead_code)] struct CrabshackImageEntry { @@ -4003,24 +4015,24 @@ struct CrabshackImageEntry { image_digest: Option, } -/// Response structure from crabshack `/instances/{name}` for non-TEE upgrade flows. +/// Response structure from the crabshack `/instances/{name}` endpoint, used by upgrade flows. #[derive(serde::Deserialize, Debug)] -struct NonTeeInstanceResponse { +struct CrabshackInstanceResponse { image: String, #[serde(default)] image_digest: Option, } impl AgentServiceImpl { - /// Check upgrade availability for TEE infrastructure (compose-api) - async fn check_upgrade_available_tee( + /// Check upgrade availability for legacy_tee infrastructure (compose-api) + async fn check_upgrade_available_legacy_tee( &self, instance: &AgentInstance, manager: &AgentManager, instance_id: Uuid, ) -> anyhow::Result { tracing::info!( - "Checking upgrade availability (TEE): instance_id={}, instance_name={}", + "Checking upgrade availability (legacy_tee): instance_id={}, instance_name={}", instance_id, instance.name ); @@ -4030,7 +4042,7 @@ impl AgentServiceImpl { // Fetch latest versions from compose-api let version_url = format!("{}/version", manager.url); - tracing::debug!("TEE: Fetching versions from: {}", version_url); + tracing::debug!("legacy_tee: Fetching versions from: {}", version_url); let version_resp = self .http_client .get(&version_url) @@ -4039,7 +4051,10 @@ impl AgentServiceImpl { .await .map_err(|e| anyhow!("Failed to fetch compose-api version: {}", e))?; - tracing::debug!("TEE: /version response status: {}", version_resp.status()); + tracing::debug!( + "legacy_tee: /version response status: {}", + version_resp.status() + ); if !version_resp.status().is_success() { return Err(anyhow!( "Failed to fetch compose-api version: status={}", @@ -4057,7 +4072,7 @@ impl AgentServiceImpl { .await .map_err(|e| anyhow!("Failed to parse compose-api version response: {}", e))?; - tracing::debug!("TEE: /version response body: {:?}", version); + tracing::debug!("legacy_tee: /version response body: {:?}", version); // Map service_type to image key in the version response let service_type = instance.service_type_str(); @@ -4079,7 +4094,7 @@ impl AgentServiceImpl { .clone(); tracing::debug!( - "TEE: Latest image for service_type='{}': {}", + "legacy_tee: Latest image for service_type='{}': {}", service_type, latest_image ); @@ -4087,7 +4102,10 @@ impl AgentServiceImpl { // Fetch current instance status from compose-api let encoded_name = urlencoding::encode(&instance.name); let instance_url = format!("{}/instances/{}", manager.url, encoded_name); - tracing::debug!("TEE: Fetching instance status from: {}", instance_url); + tracing::debug!( + "legacy_tee: Fetching instance status from: {}", + instance_url + ); let instance_resp = self .http_client .get(&instance_url) @@ -4097,7 +4115,7 @@ impl AgentServiceImpl { .map_err(|e| anyhow!("Failed to fetch instance status: {}", e))?; tracing::debug!( - "TEE: /instances/{} response status: {}", + "legacy_tee: /instances/{} response status: {}", encoded_name, instance_resp.status() ); @@ -4141,7 +4159,7 @@ impl AgentServiceImpl { let current_image = instance_status.image; // Log parsed fields only — full `/instances` JSON may include tokens, URLs, or keys. tracing::debug!( - "TEE: Parsed /instances/{} response: image={}", + "legacy_tee: Parsed /instances/{} response: image={}", encoded_name, current_image ); @@ -4149,7 +4167,7 @@ impl AgentServiceImpl { let has_upgrade = current_image != latest_image; tracing::info!( - "TEE upgrade check completed: instance_id={}, current_image={}, latest_image={}, has_upgrade={}", + "legacy_tee upgrade check completed: instance_id={}, current_image={}, latest_image={}, has_upgrade={}", instance_id, current_image, latest_image, @@ -4165,10 +4183,10 @@ impl AgentServiceImpl { }) } - /// Fetch and filter allowed images from crabshack for a non-TEE manager. + /// Fetch and filter the allowed images for a crabshack manager. /// `target_service_type` is the canonical or stored service type (e.g. `openclaw`, `ironclaw`, or legacy compose names). /// Returns filtered list of images and the hosting config (to avoid redundant system_configs reads). - async fn fetch_allowed_images_non_tee( + async fn fetch_allowed_images_crabshack( &self, manager: &AgentManager, target_service_type: &str, @@ -4179,7 +4197,7 @@ impl AgentServiceImpl { // Fetch available images from crabshack allowlist let images_url = format!("{}/images", manager.url); tracing::debug!( - "Non-TEE ({}): Fetching image allowlist from: {}", + "crabshack ({}): Fetching image allowlist from: {}", context, images_url ); @@ -4190,17 +4208,17 @@ impl AgentServiceImpl { .timeout(std::time::Duration::from_secs(30)) .send() .await - .map_err(|e| anyhow!("Failed to fetch non-TEE images allowlist: {}", e))?; + .map_err(|e| anyhow!("Failed to fetch crabshack images allowlist: {}", e))?; tracing::debug!( - "Non-TEE ({}): /images response status: {}", + "crabshack ({}): /images response status: {}", context, images_resp.status() ); if !images_resp.status().is_success() { return Err(anyhow!( - "Failed to fetch non-TEE images allowlist: status={}", + "Failed to fetch crabshack images allowlist: status={}", images_resp.status() )); } @@ -4208,12 +4226,12 @@ impl AgentServiceImpl { let response_body = images_resp .text() .await - .map_err(|e| anyhow!("Failed to read non-TEE images response body: {}", e))?; + .map_err(|e| anyhow!("Failed to read crabshack images response body: {}", e))?; let response_body_len = response_body.len(); let image_entries: Vec = serde_json::from_str(&response_body) - .map_err(|e| anyhow!("Failed to parse non-TEE images response: {}", e))?; + .map_err(|e| anyhow!("Failed to parse crabshack images response: {}", e))?; let sample_refs = image_entries .iter() @@ -4223,7 +4241,7 @@ impl AgentServiceImpl { .join(", "); tracing::debug!( - "Non-TEE ({}): Parsed {} allowlist images (response_bytes={}, sample_refs=[{}])", + "crabshack ({}): Parsed {} allowlist images (response_bytes={}, sample_refs=[{}])", context, image_entries.len(), response_body_len, @@ -4233,7 +4251,7 @@ impl AgentServiceImpl { // Per-entry lines are verbose for large allowlists; use trace for full breakdown. for img in &image_entries { tracing::trace!( - "Non-TEE ({}): Allowlist image: ref={}, service_type={}, status={}, has_digest={}, created_at={}", + "crabshack ({}): Allowlist image: ref={}, service_type={}, status={}, has_digest={}, created_at={}", context, img.ref_, img.service_type, @@ -4257,7 +4275,7 @@ impl AgentServiceImpl { service_type_for_crabshack(target_service_type, hosting_config); tracing::debug!( - "Non-TEE ({}): Filtering for service_type='{}' with status='allow-create'", + "crabshack ({}): Filtering for service_type='{}' with status='allow-create'", context, crabshack_service_type ); @@ -4277,7 +4295,7 @@ impl AgentServiceImpl { // Only warn if this is a non-versioned tag and digest is missing if extract_version_from_image(&img.ref_).is_none() && img.image_digest.is_none() { tracing::warn!( - "Non-TEE ({}): Allowlist entry with non-versioned tag missing image_digest (incomplete): ref={}. \ + "crabshack ({}): Allowlist entry with non-versioned tag missing image_digest (incomplete): ref={}. \ This entry cannot be used for non-versioned tag upgrades.", context, img.ref_ @@ -4286,7 +4304,7 @@ impl AgentServiceImpl { } tracing::debug!( - "Non-TEE ({}): Available images after filtering: {} images", + "crabshack ({}): Available images after filtering: {} images", context, available_images.len() ); @@ -4294,16 +4312,16 @@ impl AgentServiceImpl { Ok((available_images, hosting_config.cloned())) } - /// Fetch the latest versioned image from crabshack allowlist for a non-TEE manager. + /// Fetch the latest versioned image from the allowlist for a crabshack manager. /// Returns the image ref, semantic version, and optional digest (only considers images with numeric versions) - async fn get_latest_image_non_tee( + async fn get_latest_image_crabshack( &self, manager: &AgentManager, target_service_type: &str, context: &str, // For logging: "check", "upgrade", or "deploy" ) -> anyhow::Result<(String, String, Option)> { let (available_images, hosting_config) = self - .fetch_allowed_images_non_tee(manager, target_service_type, context) + .fetch_allowed_images_crabshack(manager, target_service_type, context) .await?; // Extract versions from image refs and log them @@ -4313,14 +4331,14 @@ impl AgentServiceImpl { let version = extract_version_from_image(&img.ref_); if let Some(ref v) = version { tracing::debug!( - "Non-TEE ({}): Available image: ref={}, version={}", + "crabshack ({}): Available image: ref={}, version={}", context, img.ref_, v ); } else { tracing::debug!( - "Non-TEE ({}): Available image (non-numeric tag): ref={}", + "crabshack ({}): Available image (non-numeric tag): ref={}", context, img.ref_ ); @@ -4330,7 +4348,7 @@ impl AgentServiceImpl { .collect(); // Check if pre-release versions are allowed (defaults to false = stable-only) - // Use the hosting_config we already fetched in fetch_allowed_images_non_tee to avoid redundant DB read + // Use the hosting_config we already fetched in fetch_allowed_images_crabshack to avoid redundant DB read let allow_prerelease = hosting_config .as_ref() .and_then(|h| h.crabshack.allow_prerelease_upgrades) @@ -4338,7 +4356,7 @@ impl AgentServiceImpl { if !allow_prerelease { tracing::debug!( - "Non-TEE ({}): Filtering to stable versions only (allow_prerelease_upgrades=false)", + "crabshack ({}): Filtering to stable versions only (allow_prerelease_upgrades=false)", context ); } @@ -4364,7 +4382,7 @@ impl AgentServiceImpl { })?; tracing::debug!( - "Non-TEE ({}): Latest image: ref={}, version={}, digest={:?}", + "crabshack ({}): Latest image: ref={}, version={}, digest={:?}", context, latest_image_entry.0, latest_image_entry.1, @@ -4378,36 +4396,36 @@ impl AgentServiceImpl { )) } - /// Check upgrade availability for non-TEE infrastructure (crabshack) - async fn check_upgrade_available_non_tee( + /// Check upgrade availability for a crabshack-managed instance. + async fn check_upgrade_available_crabshack( &self, instance: &AgentInstance, manager: &AgentManager, instance_id: Uuid, ) -> anyhow::Result { tracing::info!( - "Checking upgrade availability (non-TEE): instance_id={}, instance_name={}", + "Checking upgrade availability (crabshack): instance_id={}, instance_name={}", instance_id, instance.name ); - // Use manager token (admin secret) for non-TEE crabshack API + // Use the manager token (admin secret) for the crabshack API let bearer_token = &manager.token; // Fetch current instance status from crabshack let encoded_name = urlencoding::encode(&instance.name); let instance_url = format!("{}/instances/{}", manager.url, encoded_name); - tracing::debug!("Non-TEE: Fetching instance status from: {}", instance_url); + tracing::debug!("crabshack: Fetching instance status from: {}", instance_url); let instance_resp = self .http_client .get(&instance_url) .bearer_auth(bearer_token) .send() .await - .map_err(|e| anyhow!("Failed to fetch non-TEE instance status: {}", e))?; + .map_err(|e| anyhow!("Failed to fetch crabshack instance status: {}", e))?; tracing::debug!( - "Non-TEE: /instances/{} response status: {}", + "crabshack: /instances/{} response status: {}", encoded_name, instance_resp.status() ); @@ -4421,7 +4439,7 @@ impl AgentServiceImpl { ); } else if !instance_resp.status().is_success() { return Err(anyhow!( - "Failed to fetch non-TEE instance status: status={}", + "Failed to fetch crabshack instance status: status={}", instance_resp.status() )); } @@ -4430,14 +4448,15 @@ impl AgentServiceImpl { let response_body = instance_resp .text() .await - .map_err(|e| anyhow!("Failed to read non-TEE instance response body: {}", e))?; + .map_err(|e| anyhow!("Failed to read crabshack instance response body: {}", e))?; - let instance_status: NonTeeInstanceResponse = serde_json::from_str(&response_body) - .map_err(|e| anyhow!("Failed to parse non-TEE instance response: {}", e))?; + let instance_status: CrabshackInstanceResponse = + serde_json::from_str(&response_body) + .map_err(|e| anyhow!("Failed to parse crabshack instance response: {}", e))?; // Log image + digest only — raw body can carry sensitive crabshack instance metadata. tracing::debug!( - "Non-TEE: Parsed /instances/{} response: image={}, digest={:?}", + "crabshack: Parsed /instances/{} response: image={}, digest={:?}", encoded_name, instance_status.image, instance_status.image_digest @@ -4452,7 +4471,7 @@ impl AgentServiceImpl { if instance_not_found { // Try to fetch allowlist to provide the latest_image info, but don't fail if we can't let (latest_image, latest_digest) = match self - .get_latest_image_non_tee(manager, instance.service_type_str(), "check") + .get_latest_image_crabshack(manager, instance.service_type_str(), "check") .await { Ok((img, _, digest)) => (img, digest), @@ -4460,7 +4479,7 @@ impl AgentServiceImpl { }; tracing::info!( - "Non-TEE upgrade check blocked: instance_id={}, instance not synced. latest_image={}", + "crabshack upgrade check blocked: instance_id={}, instance not synced. latest_image={}", instance_id, latest_image ); @@ -4482,20 +4501,20 @@ impl AgentServiceImpl { if let Some(curr_v) = current_version { // VERSIONED TAG: Use semantic version comparison tracing::debug!( - "Non-TEE: Current image has numeric version: ref={}, version={}", + "crabshack: Current image has numeric version: ref={}, version={}", current_image_ref, curr_v ); let (latest_image, latest_version, latest_digest) = self - .get_latest_image_non_tee(manager, instance.service_type_str(), "check") + .get_latest_image_crabshack(manager, instance.service_type_str(), "check") .await?; let has_upgrade = compare_semantic_versions(&curr_v, &latest_version) == std::cmp::Ordering::Less; tracing::info!( - "Non-TEE upgrade check (versioned): instance_id={}, current_version={}, latest_version={}, has_upgrade={}", + "crabshack upgrade check (versioned): instance_id={}, current_version={}, latest_version={}, has_upgrade={}", instance_id, curr_v, latest_version, @@ -4512,12 +4531,12 @@ impl AgentServiceImpl { } else { // NON-VERSIONED TAG: Find exact ref in allowlist and compare digests tracing::debug!( - "Non-TEE: Current image has non-numeric tag: ref={}", + "crabshack: Current image has non-numeric tag: ref={}", current_image_ref ); let (allowed_entries, _hosting_config) = self - .fetch_allowed_images_non_tee(manager, instance.service_type_str(), "check") + .fetch_allowed_images_crabshack(manager, instance.service_type_str(), "check") .await?; let matching_entry = allowed_entries.iter().find(|e| e.ref_ == current_image_ref); @@ -4530,7 +4549,7 @@ impl AgentServiceImpl { // Both digests present: compare them let differs = curr_dig != allow_dig; tracing::debug!( - "Non-TEE: Digest comparison: current={}, allowlist={}, differs={}", + "crabshack: Digest comparison: current={}, allowlist={}, differs={}", curr_dig, allow_dig, differs @@ -4541,7 +4560,7 @@ impl AgentServiceImpl { // Current has digest but allowlist entry is missing it - data quality issue // For non-versioned tags, crabshack should always populate image_digest tracing::warn!( - "Non-TEE: Allowlist entry missing image_digest (incomplete data): ref={}, current_digest={:?}", + "crabshack: Allowlist entry missing image_digest (incomplete data): ref={}, current_digest={:?}", current_image_ref, current_digest ); @@ -4550,14 +4569,16 @@ impl AgentServiceImpl { (None, Some(_)) => { // Current missing digest but allowlist has one - can't compare, assume no upgrade tracing::debug!( - "Non-TEE: Current digest missing but allowlist digest present: current=None, allowlist={:?}", + "crabshack: Current digest missing but allowlist digest present: current=None, allowlist={:?}", entry.image_digest ); false } (None, None) => { // Both missing digests - can't compare, assume no upgrade - tracing::debug!("Non-TEE: Both current and allowlist digests missing"); + tracing::debug!( + "crabshack: Both current and allowlist digests missing" + ); false } }; @@ -4566,7 +4587,7 @@ impl AgentServiceImpl { None => { // Image ref not in allowlist anymore - no upgrade info available tracing::warn!( - "Non-TEE: Current image ref not found in allowlist: ref={}", + "crabshack: Current image ref not found in allowlist: ref={}", current_image_ref ); (false, current_image_ref.clone()) @@ -4578,7 +4599,7 @@ impl AgentServiceImpl { .cloned(); tracing::info!( - "Non-TEE upgrade check (non-versioned): instance_id={}, current_ref={}, current_digest={:?}, allowlist_digest={:?}, has_upgrade={}", + "crabshack upgrade check (non-versioned): instance_id={}, current_ref={}, current_digest={:?}, allowlist_digest={:?}, has_upgrade={}", instance_id, current_image_ref, current_digest, @@ -4598,8 +4619,8 @@ impl AgentServiceImpl { } impl AgentServiceImpl { - /// Upgrade instance with SSE stream for TEE infrastructure (compose-api) - async fn upgrade_instance_stream_tee( + /// Upgrade instance with SSE stream for legacy_tee infrastructure (compose-api) + async fn upgrade_instance_stream_legacy_tee( &self, instance: &AgentInstance, manager: &AgentManager, @@ -4607,7 +4628,7 @@ impl AgentServiceImpl { user_id: UserId, ) -> anyhow::Result>> { tracing::info!( - "Upgrading instance (TEE streaming): instance_id={}, instance_name={}", + "Upgrading instance (legacy_tee streaming): instance_id={}, instance_name={}", instance_id, instance.name ); @@ -4617,7 +4638,10 @@ impl AgentServiceImpl { // Fetch latest images from compose-api let version_url = format!("{}/version", manager.url); - tracing::debug!("TEE upgrade: Fetching versions from: {}", version_url); + tracing::debug!( + "legacy_tee upgrade: Fetching versions from: {}", + version_url + ); let version_resp = self .http_client .get(&version_url) @@ -4660,7 +4684,7 @@ impl AgentServiceImpl { })?; tracing::debug!( - "TEE upgrade: Latest image for service_type='{}': {}", + "legacy_tee upgrade: Latest image for service_type='{}': {}", service_type, image ); @@ -4670,8 +4694,8 @@ impl AgentServiceImpl { .await } - /// Upgrade instance with SSE stream for non-TEE infrastructure (crabshack) - async fn upgrade_instance_stream_non_tee( + /// Upgrade a crabshack-managed instance with an SSE event stream. + async fn upgrade_instance_stream_crabshack( &self, instance: &AgentInstance, manager: &AgentManager, @@ -4679,7 +4703,7 @@ impl AgentServiceImpl { user_id: UserId, ) -> anyhow::Result>> { tracing::info!( - "Upgrading instance (non-TEE streaming): instance_id={}, instance_name={}", + "Upgrading instance (crabshack streaming): instance_id={}, instance_name={}", instance_id, instance.name ); @@ -4689,7 +4713,7 @@ impl AgentServiceImpl { let encoded_name = urlencoding::encode(&instance.name); let instance_url = format!("{}/instances/{}", manager.url, encoded_name); tracing::debug!( - "Non-TEE upgrade: Fetching current instance from: {}", + "crabshack upgrade: Fetching current instance from: {}", instance_url ); @@ -4699,34 +4723,34 @@ impl AgentServiceImpl { .bearer_auth(bearer_token) .send() .await - .map_err(|e| anyhow!("Failed to fetch non-TEE instance for upgrade: {}", e))?; + .map_err(|e| anyhow!("Failed to fetch crabshack instance for upgrade: {}", e))?; if !instance_resp.status().is_success() { return Err(anyhow!( - "Failed to fetch non-TEE instance status during upgrade: status={}", + "Failed to fetch crabshack instance status during upgrade: status={}", instance_resp.status() )); } let response_body = instance_resp.text().await.map_err(|e| { anyhow!( - "Failed to read non-TEE instance response body during upgrade: {}", + "Failed to read crabshack instance response body during upgrade: {}", e ) })?; // Avoid logging the raw response body during upgrade — same sensitivity as the check path above. - let current_instance: NonTeeInstanceResponse = serde_json::from_str(&response_body) + let current_instance: CrabshackInstanceResponse = serde_json::from_str(&response_body) .map_err(|e| { anyhow!( - "Failed to parse non-TEE instance response during upgrade: {}", + "Failed to parse crabshack instance response during upgrade: {}", e ) })?; let current_image = current_instance.image; tracing::debug!( - "Non-TEE upgrade: Current instance image: {}, digest: {:?}", + "crabshack upgrade: Current instance image: {}, digest: {:?}", current_image, current_instance.image_digest ); @@ -4734,16 +4758,16 @@ impl AgentServiceImpl { // Determine image and digest to upgrade to based on tag type let (image, image_digest) = if extract_version_from_image(¤t_image).is_some() { // VERSIONED TAG: Get latest semver version - tracing::debug!("Non-TEE upgrade: Upgrading versioned image"); + tracing::debug!("crabshack upgrade: Upgrading versioned image"); let (latest_image, _version, latest_digest) = self - .get_latest_image_non_tee(manager, instance.service_type_str(), "upgrade") + .get_latest_image_crabshack(manager, instance.service_type_str(), "upgrade") .await?; (latest_image, latest_digest) } else { // NON-VERSIONED TAG: Validate current ref exists in allowlist and use same tag - tracing::debug!("Non-TEE upgrade: Upgrading non-versioned image"); + tracing::debug!("crabshack upgrade: Upgrading non-versioned image"); let (allowed_entries, _hosting_config) = self - .fetch_allowed_images_non_tee(manager, instance.service_type_str(), "upgrade") + .fetch_allowed_images_crabshack(manager, instance.service_type_str(), "upgrade") .await?; let allowlist_entry = allowed_entries.iter().find(|e| e.ref_ == current_image); @@ -4756,7 +4780,7 @@ impl AgentServiceImpl { let target_digest = entry.image_digest.clone(); tracing::debug!( - "Non-TEE upgrade: Non-versioned tag found in allowlist: ref={}, current_digest={:?}, target_digest={:?}", + "crabshack upgrade: Non-versioned tag found in allowlist: ref={}, current_digest={:?}, target_digest={:?}", current_image, current_instance.image_digest, target_digest @@ -4766,7 +4790,7 @@ impl AgentServiceImpl { (current_image.clone(), target_digest) }; - // Combine image and digest using OCI format (name[:tag]@digest) for non-TEE. + // Combine image and digest using OCI format (name[:tag]@digest) for crabshack. // Keep the original tag when present so manager /instances responses preserve mutable tag context // (e.g., :staging) while still pinning by digest. let target_image_ref = if let Some(digest) = image_digest { @@ -4779,7 +4803,7 @@ impl AgentServiceImpl { }; tracing::debug!( - "Non-TEE upgrade: Target image ref to restart with: {}", + "crabshack upgrade: Target image ref to restart with: {}", target_image_ref ); @@ -4789,7 +4813,7 @@ impl AgentServiceImpl { } /// Call /instances/{name}/restart with image ref and stream the response. - /// For non-TEE, image should be in OCI format: name[:tag]@digest when digest is known. + /// For crabshack, image should be in OCI format: name[:tag]@digest when digest is known. async fn call_restart_streaming( &self, manager: &AgentManager, @@ -4922,18 +4946,18 @@ mod tests { /// Test-only wrapper that preserves legacy test call sites. async fn next_available_manager(&self) -> anyhow::Result { let configs = self.get_system_configs().await; - let non_tee_infra = Self::is_non_tee_infra(&configs); - let manager_type = if non_tee_infra { - ManagerType::NonTee + let crabshack_infra = Self::uses_crabshack_infra(&configs); + let manager_type = if crabshack_infra { + ManagerType::Crabshack } else { - ManagerType::Tee + ManagerType::LegacyTee }; self.next_available_manager_for_type(manager_type).await } } #[test] - fn compose_api_service_type_on_create_tee_passes_canonical() { + fn compose_api_service_type_on_create_legacy_tee_passes_canonical() { assert_eq!( compose_api_service_type_on_create(false, "ironclaw", None), "ironclaw" @@ -4945,7 +4969,7 @@ mod tests { } #[test] - fn compose_api_service_type_on_create_non_tee_maps_ironclaw_and_openclaw() { + fn compose_api_service_type_on_create_crabshack_maps_ironclaw_and_openclaw() { assert_eq!( compose_api_service_type_on_create(true, "ironclaw", None), "ironclaw-dind" @@ -4957,7 +4981,7 @@ mod tests { } #[test] - fn compose_api_service_type_on_create_non_tee_respects_hosting_overrides() { + fn compose_api_service_type_on_create_crabshack_respects_hosting_overrides() { let hosting = AgentHostingConfig { new_agent_with_non_tee_infra: None, crabshack: AgentHostingCrabshackConfig { @@ -4988,8 +5012,8 @@ mod tests { Self { configs: None } } - /// No config row with non-TEE infra enabled - fn no_config_with_non_tee() -> Self { + /// No config row with crabshack infra enabled + fn no_config_with_crabshack() -> Self { use crate::system_configs::ports::AgentHostingConfig; Self { configs: Some(SystemConfigs { @@ -5002,12 +5026,12 @@ mod tests { } } - fn with_non_tee_infra(non_tee_infra: bool) -> Self { + fn with_crabshack_infra(crabshack_infra: bool) -> Self { use crate::system_configs::ports::AgentHostingConfig; Self { configs: Some(SystemConfigs { agent_hosting: Some(AgentHostingConfig { - new_agent_with_non_tee_infra: Some(non_tee_infra), + new_agent_with_non_tee_infra: Some(crabshack_infra), crabshack: Default::default(), }), ..Default::default() @@ -5015,13 +5039,13 @@ mod tests { } } - fn with_manager_limit_and_non_tee(max: u64, non_tee: bool) -> Self { + fn with_manager_limit_and_crabshack(max: u64, crabshack: bool) -> Self { use crate::system_configs::ports::AgentHostingConfig; Self { configs: Some(SystemConfigs { max_instances_per_manager: Some(max), agent_hosting: Some(AgentHostingConfig { - new_agent_with_non_tee_infra: Some(non_tee), + new_agent_with_non_tee_infra: Some(crabshack), crabshack: Default::default(), }), ..Default::default() @@ -5038,7 +5062,7 @@ mod tests { } } - /// Per-URL limits with non-TEE infra enabled + /// Per-URL limits with crabshack infra enabled fn with_allow_prerelease_upgrades(allow_prerelease: bool) -> Self { use crate::system_configs::ports::{AgentHostingConfig, AgentHostingCrabshackConfig}; Self { @@ -5055,7 +5079,7 @@ mod tests { } } - fn with_per_url_limits_and_non_tee() -> Self { + fn with_per_url_limits_and_crabshack() -> Self { use crate::system_configs::ports::AgentHostingConfig; use std::collections::HashMap; let mut per_url = HashMap::new(); @@ -5135,12 +5159,12 @@ mod tests { } fn make_managers(n: usize) -> Vec { - // Default to non-TEE managers for tests + // Default to crabshack managers for tests (0..n) .map(|i| AgentManager { url: format!("https://claws.example.com/api/crabshack/mgr{}", i), token: format!("token{}", i), - is_non_tee: true, + is_crabshack: true, }) .collect() } @@ -5156,25 +5180,25 @@ mod tests { "https://nearai.test/v1".to_string(), configs, None, // channel_relay_url - "claws".to_string(), // non_tee_agent_url_pattern + "claws".to_string(), // crabshack_agent_url_pattern ) } // --- Tests --- #[test] - fn test_user_has_non_tee_routed_instance_positive() { - let ntee_url = "https://claws.example.com/api/crabshack/mgr0".to_string(); + fn test_user_has_crabshack_routed_instance_positive() { + let crabshack_url = "https://claws.example.com/api/crabshack/mgr0".to_string(); let managers = vec![ AgentManager { url: "https://tee.example/api".to_string(), token: "tee-tok".to_string(), - is_non_tee: false, + is_crabshack: false, }, AgentManager { - url: ntee_url.clone(), + url: crabshack_url.clone(), token: "ntok".to_string(), - is_non_tee: true, + is_crabshack: true, }, ]; let svc = make_service( @@ -5193,23 +5217,23 @@ mod tests { instance_url: None, instance_token: None, dashboard_url: None, - agent_api_base_url: Some(ntee_url), + agent_api_base_url: Some(crabshack_url), service_type: None, status: "active".to_string(), created_at: Utc::now(), updated_at: Utc::now(), }; - assert!(svc.user_has_non_tee_routed_instance(&[instance])); + assert!(svc.user_has_crabshack_routed_instance(&[instance])); } #[test] - fn test_user_has_non_tee_routed_instance_false_when_only_tee_manager_url() { - let tee_url = "https://tee.example/api".to_string(); + fn test_user_has_crabshack_routed_instance_false_when_only_legacy_tee_manager_url() { + let legacy_tee_url = "https://tee.example/api".to_string(); let managers = vec![AgentManager { - url: tee_url.clone(), + url: legacy_tee_url.clone(), token: "tee-tok".to_string(), - is_non_tee: false, + is_crabshack: false, }]; let svc = make_service( managers, @@ -5227,18 +5251,18 @@ mod tests { instance_url: None, instance_token: None, dashboard_url: None, - agent_api_base_url: Some(tee_url), + agent_api_base_url: Some(legacy_tee_url), service_type: None, status: "active".to_string(), created_at: Utc::now(), updated_at: Utc::now(), }; - assert!(!svc.user_has_non_tee_routed_instance(&[instance])); + assert!(!svc.user_has_crabshack_routed_instance(&[instance])); } #[tokio::test] - async fn test_setup_gateway_session_skips_when_tee_no_passkey_no_non_tee_instances() { + async fn test_setup_gateway_session_skips_when_legacy_tee_no_passkey_no_crabshack_instances() { let mut repo = MockAgentRepository::new(); repo.expect_get_user_passkey_credentials() .times(1) @@ -5250,7 +5274,7 @@ mod tests { let svc = make_service( make_managers(1), Arc::new(repo), - Arc::new(MockSystemConfigsService::with_non_tee_infra(false)), + Arc::new(MockSystemConfigsService::with_crabshack_infra(false)), ); let out = svc @@ -5371,7 +5395,7 @@ mod tests { Arc::new(MockSystemConfigsService::no_config()), ); - // Instance with non-TEE URL (contains "claws") should match non-TEE managers + // Instance with crabshack URL (contains "claws") should match crabshack managers let instance = AgentInstance { id: Uuid::new_v4(), user_id: UserId(Uuid::new_v4()), @@ -5394,14 +5418,14 @@ mod tests { #[test] fn test_resolve_manager_fails_when_type_unavailable() { - let managers = make_managers(2); // All non-TEE managers + let managers = make_managers(2); // All crabshack managers let svc = make_service( managers.clone(), Arc::new(mock_repo_with_manager_count(0)), Arc::new(MockSystemConfigsService::no_config()), ); - // Instance with TEE URL (no "claws") should fail when only non-TEE managers available + // Instance with legacy_tee URL (no "claws") should fail when only crabshack managers available let instance = AgentInstance { id: Uuid::new_v4(), user_id: UserId(Uuid::new_v4()), @@ -5420,7 +5444,10 @@ mod tests { let result = svc.resolve_manager(&instance); assert!(result.is_err()); - assert!(result.unwrap_err().to_string().contains("TEE manager")); + assert!(result + .unwrap_err() + .to_string() + .contains("legacy-tee manager")); } #[test] @@ -5458,7 +5485,7 @@ mod tests { let svc = make_service( make_managers(2), Arc::new(mock_repo_with_manager_count(50)), - Arc::new(MockSystemConfigsService::no_config_with_non_tee()), + Arc::new(MockSystemConfigsService::no_config_with_crabshack()), ); // count=50 < default 200 → manager is available @@ -5487,7 +5514,7 @@ mod tests { let svc = make_service( make_managers(2), Arc::new(mock_repo_with_manager_count(3)), - Arc::new(MockSystemConfigsService::with_manager_limit_and_non_tee( + Arc::new(MockSystemConfigsService::with_manager_limit_and_crabshack( 10, true, )), ); @@ -5503,7 +5530,7 @@ mod tests { let svc = make_service( make_managers(2), Arc::new(mock_repo_with_manager_count(100)), - Arc::new(MockSystemConfigsService::with_manager_limit_and_non_tee( + Arc::new(MockSystemConfigsService::with_manager_limit_and_crabshack( 100, true, )), ); @@ -5527,7 +5554,7 @@ mod tests { let svc = make_service( make_managers(2), Arc::new(repo), - Arc::new(MockSystemConfigsService::with_manager_limit_and_non_tee( + Arc::new(MockSystemConfigsService::with_manager_limit_and_crabshack( 10, true, )), ); @@ -5550,7 +5577,7 @@ mod tests { let svc = make_service( make_managers(2), Arc::new(repo), - Arc::new(MockSystemConfigsService::with_per_url_limits_and_non_tee()), + Arc::new(MockSystemConfigsService::with_per_url_limits_and_crabshack()), ); let mgr = svc.next_available_manager().await.unwrap(); @@ -5558,22 +5585,22 @@ mod tests { } #[tokio::test] - async fn test_next_available_manager_for_type_applies_limit_to_tee_pool() { + async fn test_next_available_manager_for_type_applies_limit_to_legacy_tee_pool() { let managers = vec![ AgentManager { url: "https://tee-full.example.com".to_string(), token: "tee-full-token".to_string(), - is_non_tee: false, + is_crabshack: false, }, AgentManager { url: "https://tee-room.example.com".to_string(), token: "tee-room-token".to_string(), - is_non_tee: false, + is_crabshack: false, }, AgentManager { url: "https://claws.example.com/api/crabshack/non-tee".to_string(), token: "non-tee-token".to_string(), - is_non_tee: true, + is_crabshack: true, }, ]; @@ -5592,29 +5619,29 @@ mod tests { ); let mgr = svc - .next_available_manager_for_type(ManagerType::Tee) + .next_available_manager_for_type(ManagerType::LegacyTee) .await .unwrap(); assert_eq!(mgr.url, "https://tee-room.example.com"); } #[tokio::test] - async fn test_next_available_manager_for_type_applies_limit_to_non_tee_pool() { + async fn test_next_available_manager_for_type_applies_limit_to_crabshack_pool() { let managers = vec![ AgentManager { url: "https://claws.example.com/api/crabshack/non-tee-full".to_string(), token: "non-tee-full-token".to_string(), - is_non_tee: true, + is_crabshack: true, }, AgentManager { url: "https://claws.example.com/api/crabshack/non-tee-room".to_string(), token: "non-tee-room-token".to_string(), - is_non_tee: true, + is_crabshack: true, }, AgentManager { url: "https://tee.example.com".to_string(), token: "tee-token".to_string(), - is_non_tee: false, + is_crabshack: false, }, ]; @@ -5633,7 +5660,7 @@ mod tests { ); let mgr = svc - .next_available_manager_for_type(ManagerType::NonTee) + .next_available_manager_for_type(ManagerType::Crabshack) .await .unwrap(); assert_eq!( @@ -5647,7 +5674,7 @@ mod tests { let managers = vec![AgentManager { url: "https://tee.example.com".to_string(), token: "tee-token".to_string(), - is_non_tee: false, + is_crabshack: false, }]; let svc = make_service( @@ -5657,13 +5684,13 @@ mod tests { ); let result = svc - .next_available_manager_for_type(ManagerType::NonTee) + .next_available_manager_for_type(ManagerType::Crabshack) .await; assert!(result.is_err()); assert!(result .unwrap_err() .to_string() - .contains("No suitable managers available: manager_type=non-tee")); + .contains("No suitable managers available: manager_type=crabshack")); } #[test] @@ -5683,7 +5710,7 @@ mod tests { vec![AgentManager { url: "https://test.com".to_string(), token: "".to_string(), - is_non_tee: false, + is_crabshack: false, }], Arc::new(mock_repo_with_manager_count(0)), Arc::new(MockSystemConfigsService::no_config()), @@ -5756,12 +5783,12 @@ mod tests { AgentManager { url: server1.uri(), token: "tok1".to_string(), - is_non_tee: false, + is_crabshack: false, }, AgentManager { url: server2.uri(), token: "tok2".to_string(), - is_non_tee: false, + is_crabshack: false, }, ]; @@ -5809,12 +5836,12 @@ mod tests { AgentManager { url: server1.uri(), token: "tok".to_string(), - is_non_tee: false, + is_crabshack: false, }, AgentManager { url: server2.uri(), token: "tok".to_string(), - is_non_tee: false, + is_crabshack: false, }, ]; @@ -5859,12 +5886,12 @@ mod tests { AgentManager { url: server1.uri(), token: "tok".to_string(), - is_non_tee: false, + is_crabshack: false, }, AgentManager { url: server2.uri(), token: "tok".to_string(), - is_non_tee: false, + is_crabshack: false, }, ]; @@ -5926,12 +5953,12 @@ mod tests { AgentManager { url: server1.uri(), token: "tok".to_string(), - is_non_tee: false, + is_crabshack: false, }, AgentManager { url: server2.uri(), token: "tok".to_string(), - is_non_tee: false, + is_crabshack: false, }, ]; @@ -5977,12 +6004,12 @@ mod tests { AgentManager { url: server1.uri(), token: "tok".to_string(), - is_non_tee: false, + is_crabshack: false, }, AgentManager { url: server2.uri(), token: "tok".to_string(), - is_non_tee: false, + is_crabshack: false, }, ]; @@ -6019,7 +6046,7 @@ mod tests { let mgr = AgentManager { url: server.uri(), token: "my-secret-token".to_string(), - is_non_tee: false, + is_crabshack: false, }; let svc = make_service( @@ -6073,12 +6100,12 @@ mod tests { AgentManager { url: server1.uri(), token: "tok1".to_string(), - is_non_tee: false, + is_crabshack: false, }, AgentManager { url: server2.uri(), token: "tok2".to_string(), - is_non_tee: false, + is_crabshack: false, }, ]; @@ -6193,7 +6220,7 @@ mod tests { vec![AgentManager { url: server.uri(), token: "tok".to_string(), - is_non_tee: false, + is_crabshack: false, }], Arc::new(repo), Arc::new(MockSystemConfigsService::no_config()), @@ -6238,7 +6265,7 @@ mod tests { vec![AgentManager { url: server.uri(), token: "tok".to_string(), - is_non_tee: false, + is_crabshack: false, }], Arc::new(repo), Arc::new(MockSystemConfigsService::no_config()), @@ -6288,7 +6315,7 @@ mod tests { vec![AgentManager { url: server.uri(), token: "tok".to_string(), - is_non_tee: false, + is_crabshack: false, }], Arc::new(repo), Arc::new(MockSystemConfigsService::no_config()), @@ -6329,7 +6356,7 @@ mod tests { vec![AgentManager { url: server.uri(), token: "tok".to_string(), - is_non_tee: false, + is_crabshack: false, }], Arc::new(repo), Arc::new(MockSystemConfigsService::no_config()), @@ -6379,7 +6406,7 @@ mod tests { vec![AgentManager { url: server.uri(), token: "tok".to_string(), - is_non_tee: false, + is_crabshack: false, }], Arc::new(repo), Arc::new(MockSystemConfigsService::no_config()), @@ -6424,7 +6451,7 @@ mod tests { vec![AgentManager { url: server.uri(), token: "tok".to_string(), - is_non_tee: false, + is_crabshack: false, }], Arc::new(repo), Arc::new(MockSystemConfigsService::no_config()), @@ -6479,7 +6506,7 @@ mod tests { vec![AgentManager { url: server.uri(), token: "tok".to_string(), - is_non_tee: false, + is_crabshack: false, }], Arc::new(repo), Arc::new(MockSystemConfigsService::no_config()), @@ -6532,7 +6559,7 @@ mod tests { vec![AgentManager { url: server.uri(), token: "tok".to_string(), - is_non_tee: false, + is_crabshack: false, }], Arc::new(repo), Arc::new(MockSystemConfigsService::no_config()), @@ -6577,7 +6604,7 @@ mod tests { vec![AgentManager { url: server.uri(), token: "tok".to_string(), - is_non_tee: false, + is_crabshack: false, }], Arc::new(repo), Arc::new(MockSystemConfigsService::no_config()), @@ -6611,7 +6638,7 @@ mod tests { vec![AgentManager { url: server.uri(), token: "tok".to_string(), - is_non_tee: false, + is_crabshack: false, }], Arc::new(repo), Arc::new(MockSystemConfigsService::no_config()), @@ -6654,7 +6681,7 @@ mod tests { vec![AgentManager { url: server.uri(), token: "tok".to_string(), - is_non_tee: false, + is_crabshack: false, }], Arc::new(repo), Arc::new(MockSystemConfigsService::no_config()), @@ -6691,7 +6718,7 @@ mod tests { vec![AgentManager { url: server.uri(), token: "tok".to_string(), - is_non_tee: false, + is_crabshack: false, }], Arc::new(repo), Arc::new(MockSystemConfigsService::no_config()), @@ -6739,7 +6766,7 @@ mod tests { vec![AgentManager { url: server.uri(), token: "tok".to_string(), - is_non_tee: false, + is_crabshack: false, }], Arc::new(repo), Arc::new(MockSystemConfigsService::no_config()), @@ -6796,7 +6823,7 @@ mod tests { vec![AgentManager { url: server.uri(), token: "tok".to_string(), - is_non_tee: false, + is_crabshack: false, }], Arc::new(repo), Arc::new(MockSystemConfigsService::no_config()), @@ -6835,7 +6862,7 @@ mod tests { vec![AgentManager { url: server.uri(), token: "tok".to_string(), - is_non_tee: false, + is_crabshack: false, }], Arc::new(repo), Arc::new(MockSystemConfigsService::no_config()), @@ -6855,10 +6882,10 @@ mod tests { // --- End-to-End Flow Tests --- #[tokio::test] - async fn test_e2e_tee_mode_flow() { + async fn test_e2e_legacy_tee_mode_flow() { let server = setup_mock_server().await; - // TEE mode: mock TEE compose-api response + // legacy_tee mode: mock legacy_tee compose-api response // Should receive service type as-is (ironclaw) Mock::given(method("POST")) .and(path("/instances")) @@ -6916,29 +6943,29 @@ mod tests { vec![AgentManager { url: server_uri.clone(), token: "cloud-token".to_string(), - is_non_tee: false, + is_crabshack: false, }], "https://nearai.example.com/v1".to_string(), Arc::new(MockSystemConfigsService::no_config()), None, - "claws".to_string(), // non_tee_agent_url_pattern + "claws".to_string(), // crabshack_agent_url_pattern ); - // Verify TEE mode behavior: + // Verify legacy_tee mode behavior: // 1. Service type used as-is (ironclaw) // 2. No passkey login attempted // 3. Manager token used assert!( - !service.managers[0].is_non_tee, - "Manager should be TEE mode" + !service.managers[0].is_crabshack, + "Manager should be legacy_tee mode" ); } #[tokio::test] - async fn test_e2e_non_tee_mode_flow() { + async fn test_e2e_crabshack_mode_flow() { let server = setup_mock_server().await; - // Non-TEE mode: Mock compose-api response + // crabshack mode: Mock compose-api response // Should accept ironclaw as-is Mock::given(method("POST")) .and(path("/instances")) @@ -6997,24 +7024,24 @@ mod tests { vec![AgentManager { url: server_uri.clone(), token: "compose-token".to_string(), - is_non_tee: true, + is_crabshack: true, }], "https://nearai.example.com/v1".to_string(), Arc::new(MockSystemConfigsService::no_config()), None, - "claws".to_string(), // non_tee_agent_url_pattern + "claws".to_string(), // crabshack_agent_url_pattern ); - // Verify non-TEE mode behavior: + // Verify crabshack mode behavior: // 1. Service type used as-is (ironclaw) // 2. Passkey login can be attempted assert!( - service.managers[0].is_non_tee, - "Manager should be non-TEE mode" + service.managers[0].is_crabshack, + "Manager should be crabshack mode" ); } - // --- Non-TEE `check_upgrade_available` (crabshack allowlist + instance image) --- + // --- crabshack `check_upgrade_available` (crabshack allowlist + instance image) --- fn upgrade_check_instance( instance_db_id: Uuid, @@ -7071,7 +7098,7 @@ mod tests { vec![AgentManager { url: crabshack_uri.to_string(), token: token.to_string(), - is_non_tee: true, + is_crabshack: true, }], Arc::new(repo), configs, @@ -7079,7 +7106,7 @@ mod tests { } #[tokio::test] - async fn non_tee_check_upgrade_legacy_openclaw_dind_filter_and_semver() { + async fn crabshack_check_upgrade_legacy_openclaw_dind_filter_and_semver() { let server = setup_mock_server().await; let uri = server.uri(); let token = "crab-token"; @@ -7142,7 +7169,7 @@ mod tests { } #[tokio::test] - async fn non_tee_check_upgrade_prerelease_same_numeric_max_picks_later_allowlist_entry() { + async fn crabshack_check_upgrade_prerelease_same_numeric_max_picks_later_allowlist_entry() { let server = setup_mock_server().await; let uri = server.uri(); let token = "crab-token"; @@ -7204,7 +7231,7 @@ mod tests { /// With `allow_prerelease_upgrades=false` (default), latest semver from allowlist ignores pre-releases. #[tokio::test] - async fn non_tee_stable_only_filter_picks_highest_stable_not_prerelease() { + async fn crabshack_stable_only_filter_picks_highest_stable_not_prerelease() { let server = setup_mock_server().await; let uri = server.uri(); let token = "crab-token"; @@ -7262,7 +7289,7 @@ mod tests { /// With `allow_prerelease_upgrades=true`, pre-releases compete for “latest” alongside stables. #[tokio::test] - async fn non_tee_allow_prerelease_includes_prerelease_in_latest() { + async fn crabshack_allow_prerelease_includes_prerelease_in_latest() { let server = setup_mock_server().await; let uri = server.uri(); let token = "crab-token"; @@ -7329,7 +7356,7 @@ mod tests { } #[tokio::test] - async fn non_tee_check_upgrade_canonical_openclaw_images() { + async fn crabshack_check_upgrade_canonical_openclaw_images() { let server = setup_mock_server().await; let uri = server.uri(); let token = "crab-token"; @@ -7392,7 +7419,7 @@ mod tests { } #[tokio::test] - async fn non_tee_check_upgrade_instance_404_blocks_upgrade() { + async fn crabshack_check_upgrade_instance_404_blocks_upgrade() { let server = setup_mock_server().await; let uri = server.uri(); let token = "crab-token"; @@ -7436,7 +7463,7 @@ mod tests { } #[tokio::test] - async fn non_tee_check_upgrade_non_versioned_tag_digest_changed() { + async fn crabshack_check_upgrade_non_versioned_tag_digest_changed() { // Test non-versioned tags (e.g., :staging, :dev) with digest comparison let server = setup_mock_server().await; let uri = server.uri(); @@ -7494,7 +7521,7 @@ mod tests { } #[tokio::test] - async fn non_tee_check_upgrade_non_versioned_tag_digest_unchanged() { + async fn crabshack_check_upgrade_non_versioned_tag_digest_unchanged() { // Test non-versioned tags with same digest (no upgrade) let server = setup_mock_server().await; let uri = server.uri(); @@ -7549,7 +7576,7 @@ mod tests { } #[tokio::test] - async fn non_tee_check_upgrade_non_versioned_tag_not_in_allowlist() { + async fn crabshack_check_upgrade_non_versioned_tag_not_in_allowlist() { // Test non-versioned tag that's not in allowlist (no upgrade) let server = setup_mock_server().await; let uri = server.uri(); @@ -7604,7 +7631,7 @@ mod tests { } #[tokio::test] - async fn non_tee_upgrade_versioned_tag_gets_latest() { + async fn crabshack_upgrade_versioned_tag_gets_latest() { // Test upgrade_instance_stream with versioned tag (should get latest semver) let server = setup_mock_server().await; let uri = server.uri(); @@ -7669,7 +7696,7 @@ mod tests { } #[tokio::test] - async fn non_tee_upgrade_non_versioned_tag_keeps_same_ref() { + async fn crabshack_upgrade_non_versioned_tag_keeps_same_ref() { // Test upgrade_instance_stream with non-versioned tag (should keep same ref) let server = setup_mock_server().await; let uri = server.uri(); @@ -7731,7 +7758,7 @@ mod tests { } #[tokio::test] - async fn non_tee_check_upgrade_non_versioned_tag_missing_allowlist_digest() { + async fn crabshack_check_upgrade_non_versioned_tag_missing_allowlist_digest() { // When allowlist doesn't have digest (None), we can't compare - no upgrade let server = setup_mock_server().await; let uri = server.uri(); @@ -7785,7 +7812,7 @@ mod tests { } #[tokio::test] - async fn non_tee_upgrade_non_versioned_tag_not_in_allowlist_fails() { + async fn crabshack_upgrade_non_versioned_tag_not_in_allowlist_fails() { // Test upgrade_instance_stream fails when non-versioned tag not in allowlist let server = setup_mock_server().await; let uri = server.uri(); @@ -7875,18 +7902,18 @@ mod tests { assert!(validate_agent_api_url("/foo/bar", "test_url").is_err()); } - // --- TEE and Non-TEE Mode Tests --- + // --- legacy_tee and crabshack Mode Tests --- // Service type normalization tests removed: normalize_service_type_for_api is now a no-op #[test] - fn test_agent_service_creation_tee_mode() { - // TEE mode: manager with is_non_tee = false + fn test_agent_service_creation_legacy_tee_mode() { + // legacy_tee mode: manager with is_crabshack = false let repo = Arc::new(MockAgentRepository::new()); let manager = AgentManager { url: "https://api.cloud.example.com".to_string(), token: "cloud-token".to_string(), - is_non_tee: false, + is_crabshack: false, }; let configs = Arc::new(MockSystemConfigsService::no_config()); @@ -7896,21 +7923,21 @@ mod tests { "https://nearai.example.com/v1".to_string(), configs, None, - "claws".to_string(), // non_tee_agent_url_pattern + "claws".to_string(), // crabshack_agent_url_pattern ); - // Verify TEE mode configuration: manager is TEE - assert!(!manager.is_non_tee); + // Verify legacy_tee mode configuration: manager is legacy_tee + assert!(!manager.is_crabshack); } #[test] - fn test_agent_service_creation_non_tee_mode() { - // Non-TEE mode: manager with is_non_tee = true + fn test_agent_service_creation_crabshack_mode() { + // crabshack mode: manager with is_crabshack = true let repo = Arc::new(MockAgentRepository::new()); let manager = AgentManager { url: "https://claws.example.com/api/crabshack".to_string(), token: "compose-token".to_string(), - is_non_tee: true, + is_crabshack: true, }; let configs = Arc::new(MockSystemConfigsService::no_config()); @@ -7920,11 +7947,11 @@ mod tests { "https://nearai.example.com/v1".to_string(), configs, None, - "claws".to_string(), // non_tee_agent_url_pattern + "claws".to_string(), // crabshack_agent_url_pattern ); - // Verify non-TEE mode configuration: manager is non-TEE - assert!(manager.is_non_tee); + // Verify crabshack mode configuration: manager is crabshack + assert!(manager.is_crabshack); } #[test] @@ -7949,7 +7976,7 @@ mod tests { // --- Mode Flow Verification Tests --- - // test_tee_mode_configuration_summary and test_non_tee_mode_configuration_summary removed: + // test_legacy_tee_mode_configuration_summary and test_crabshack_mode_configuration_summary removed: // were entirely about the removed normalize_service_type_for_api function // ============================================================================ @@ -7957,47 +7984,47 @@ mod tests { // ============================================================================ #[tokio::test] - async fn test_manager_filtering_non_tee_infra_true_only_selects_non_tee() { - // When NON_TEE_INFRA=true, only non-TEE managers should be selected - let mut managers = make_managers(2); // Non-TEE managers - // Add a TEE manager + async fn test_manager_filtering_crabshack_infra_true_only_selects_crabshack() { + // When NON_TEE_INFRA=true, only crabshack managers should be selected + let mut managers = make_managers(2); // crabshack managers + // Add a legacy_tee manager managers.push(AgentManager { url: "https://api.example.com".to_string(), token: "tee-token".to_string(), - is_non_tee: false, + is_crabshack: false, }); let svc = make_service( managers, Arc::new(mock_repo_with_manager_count(0)), - Arc::new(MockSystemConfigsService::with_non_tee_infra(true)), + Arc::new(MockSystemConfigsService::with_crabshack_infra(true)), ); - // Should only return non-TEE managers + // Should only return crabshack managers for _ in 0..10 { let mgr = svc.next_available_manager().await.unwrap(); assert!( mgr.url.contains("claws.example.com/api/crabshack"), - "Expected non-TEE manager URL, got: {}", + "Expected crabshack manager URL, got: {}", mgr.url ); } } #[tokio::test] - async fn test_manager_filtering_non_tee_infra_false_uses_all_managers() { + async fn test_manager_filtering_crabshack_infra_false_uses_all_managers() { // When NON_TEE_INFRA=false, all managers should be available - let mut managers = make_managers(1); // 1 non-TEE manager - // Add 2 TEE managers + let mut managers = make_managers(1); // 1 crabshack manager + // Add 2 legacy_tee managers managers.push(AgentManager { url: "https://api1.example.com".to_string(), token: "tee-token-1".to_string(), - is_non_tee: false, + is_crabshack: false, }); managers.push(AgentManager { url: "https://api2.example.com".to_string(), token: "tee-token-2".to_string(), - is_non_tee: false, + is_crabshack: false, }); let svc = make_service( @@ -8016,25 +8043,25 @@ mod tests { } #[tokio::test] - async fn test_manager_filtering_rejects_all_tee_when_non_tee_infra_true() { - // When all managers are TEE but NON_TEE_INFRA=true, should error + async fn test_manager_filtering_rejects_all_legacy_tee_when_crabshack_infra_true() { + // When all managers are legacy_tee but NON_TEE_INFRA=true, should error let managers = vec![ AgentManager { url: "https://api1.example.com".to_string(), token: "token1".to_string(), - is_non_tee: false, + is_crabshack: false, }, AgentManager { url: "https://api2.example.com".to_string(), token: "token2".to_string(), - is_non_tee: false, + is_crabshack: false, }, ]; let svc = make_service( managers, Arc::new(mock_repo_with_manager_count(0)), - Arc::new(MockSystemConfigsService::with_non_tee_infra(true)), + Arc::new(MockSystemConfigsService::with_crabshack_infra(true)), ); let result = svc.next_available_manager().await; @@ -8049,9 +8076,9 @@ mod tests { } #[tokio::test] - async fn test_manager_filtering_capacity_with_non_tee_infra_true() { - // When NON_TEE_INFRA=true and non-TEE manager is at capacity, should fail - let managers = make_managers(1); // 1 non-TEE manager + async fn test_manager_filtering_capacity_with_crabshack_infra_true() { + // When NON_TEE_INFRA=true and crabshack manager is at capacity, should fail + let managers = make_managers(1); // 1 crabshack manager let mut repo = MockAgentRepository::new(); repo.expect_count_instances_by_manager() .returning(|_| Ok(100)); // At capacity @@ -8059,7 +8086,7 @@ mod tests { let svc = make_service( managers, Arc::new(repo), - Arc::new(MockSystemConfigsService::with_manager_limit_and_non_tee( + Arc::new(MockSystemConfigsService::with_manager_limit_and_crabshack( 50, true, )), ); @@ -8073,34 +8100,34 @@ mod tests { } #[tokio::test] - async fn test_mixed_managers_non_tee_skips_full_tee_managers() { + async fn test_mixed_managers_crabshack_skips_full_legacy_tee_managers() { // When NON_TEE_INFRA=true with mixed managers: - // - 1 non-TEE manager with capacity - // - 2 TEE managers (at capacity, but should be skipped) + // - 1 crabshack manager with capacity + // - 2 legacy_tee managers (at capacity, but should be skipped) let managers = vec![ - // Non-TEE manager with capacity + // crabshack manager with capacity AgentManager { url: "https://claws.example.com/api/crabshack/available".to_string(), token: "non-tee-token".to_string(), - is_non_tee: true, + is_crabshack: true, }, - // TEE managers (should be filtered out) + // legacy_tee managers (should be filtered out) AgentManager { url: "https://api1.example.com".to_string(), token: "tee-token-1".to_string(), - is_non_tee: false, + is_crabshack: false, }, AgentManager { url: "https://api2.example.com".to_string(), token: "tee-token-2".to_string(), - is_non_tee: false, + is_crabshack: false, }, ]; let svc = make_service( managers, Arc::new(mock_repo_with_manager_count(10)), - Arc::new(MockSystemConfigsService::with_manager_limit_and_non_tee( + Arc::new(MockSystemConfigsService::with_manager_limit_and_crabshack( 100, true, )), ); @@ -8111,77 +8138,81 @@ mod tests { #[test] fn test_manager_type_detection_from_url() { - // Test the manager type detection logic (non-TEE vs TEE) - let non_tee_urls = vec![ + // Test the manager type detection logic (crabshack vs legacy_tee) + let crabshack_urls = vec![ "https://claws.example.com/api/crabshack", "https://other.host/api/crabshack", ]; - for url in non_tee_urls { - let is_non_tee = url.contains("/api/crabshack"); - assert!(is_non_tee, "Expected {} to be detected as non-TEE", url); + for url in crabshack_urls { + let is_crabshack = url.contains("/api/crabshack"); + assert!(is_crabshack, "Expected {} to be detected as crabshack", url); } - let tee_urls = vec![ + let legacy_tee_urls = vec![ "https://api.openclaw-dev.near.ai", "https://api.cloud.example.com", "https://agent-api.example.com", ]; - for url in tee_urls { - let is_non_tee = url.contains("/api/crabshack"); - assert!(!is_non_tee, "Expected {} to be detected as TEE", url); + for url in legacy_tee_urls { + let is_crabshack = url.contains("/api/crabshack"); + assert!( + !is_crabshack, + "Expected {} to be detected as legacy_tee", + url + ); } } #[tokio::test] - async fn test_round_robin_with_filtered_non_tee_managers() { - // When NON_TEE_INFRA=true with mixed managers, next_available_manager should only pick non-TEE + async fn test_round_robin_with_filtered_crabshack_managers() { + // When NON_TEE_INFRA=true with mixed managers, next_available_manager should only pick crabshack let managers = vec![ AgentManager { url: "https://claws.example.com/api/crabshack/mgr0".to_string(), token: "token0".to_string(), - is_non_tee: true, + is_crabshack: true, }, AgentManager { url: "https://claws.example.com/api/crabshack/mgr1".to_string(), token: "token1".to_string(), - is_non_tee: true, + is_crabshack: true, }, AgentManager { - url: "https://api.example.com".to_string(), // TEE - should be skipped + url: "https://api.example.com".to_string(), // legacy_tee - should be skipped token: "tee-token".to_string(), - is_non_tee: false, + is_crabshack: false, }, AgentManager { url: "https://claws.example.com/api/crabshack/mgr2".to_string(), token: "token2".to_string(), - is_non_tee: true, + is_crabshack: true, }, ]; let svc = make_service( managers, Arc::new(mock_repo_with_manager_count(0)), - Arc::new(MockSystemConfigsService::with_non_tee_infra(true)), + Arc::new(MockSystemConfigsService::with_crabshack_infra(true)), ); - // next_available_manager should only return non-TEE managers, skipping the TEE one + // next_available_manager should only return crabshack managers, skipping the legacy_tee one let mut urls = Vec::new(); for _ in 0..6 { let mgr = svc.next_available_manager().await.unwrap(); urls.push(mgr.url.clone()); } - // Should only get non-TEE managers, cycling through all 3 of them + // Should only get crabshack managers, cycling through all 3 of them for url in &urls { assert!( url.contains("claws.example.com"), - "Should only return non-TEE managers" + "Should only return crabshack managers" ); assert!( !url.contains("api.example.com"), - "TEE manager should not be selected" + "legacy_tee manager should not be selected" ); } } @@ -8193,41 +8224,41 @@ mod tests { AgentManager { url: "https://claws.example.com/api/crabshack/mgr0".to_string(), token: "token0".to_string(), - is_non_tee: true, + is_crabshack: true, }, AgentManager { url: "https://claws.example.com/api/crabshack/mgr1".to_string(), token: "token1".to_string(), - is_non_tee: true, + is_crabshack: true, }, AgentManager { - url: "https://api.example.com".to_string(), // TEE - at capacity, but should be skipped + url: "https://api.example.com".to_string(), // legacy_tee - at capacity, but should be skipped token: "tee-token".to_string(), - is_non_tee: false, + is_crabshack: false, }, ]; let mut repo = MockAgentRepository::new(); repo.expect_count_instances_by_manager() .withf(|url: &str| url.contains("claws.example.com")) - .returning(|_| Ok(10)); // Non-TEE managers: 10 instances + .returning(|_| Ok(10)); // crabshack managers: 10 instances repo.expect_count_instances_by_manager() .withf(|url: &str| url.contains("api.example.com")) - .returning(|_| Ok(100)); // TEE manager: 100 instances (at capacity) + .returning(|_| Ok(100)); // legacy_tee manager: 100 instances (at capacity) let svc = make_service( managers, Arc::new(repo), - Arc::new(MockSystemConfigsService::with_manager_limit_and_non_tee( + Arc::new(MockSystemConfigsService::with_manager_limit_and_crabshack( 50, true, )), ); - // Should succeed by using a non-TEE manager (even though TEE is at capacity) + // Should succeed by using a crabshack manager (even though legacy_tee is at capacity) let mgr = svc.next_available_manager().await.unwrap(); assert!( mgr.url.contains("claws.example.com"), - "Should select non-TEE manager" + "Should select crabshack manager" ); } @@ -8259,30 +8290,30 @@ mod tests { let managers = vec![AgentManager { url: "https://api.example.com".to_string(), token: "token".to_string(), - is_non_tee: false, + is_crabshack: false, }]; let svc = make_service( managers, Arc::new(mock_repo_with_manager_count(0)), - Arc::new(MockSystemConfigsService::with_non_tee_infra(true)), + Arc::new(MockSystemConfigsService::with_crabshack_infra(true)), ); let result = svc.next_available_manager().await; let error_msg = result.unwrap_err().to_string(); assert!(error_msg.contains("No suitable managers")); - assert!(error_msg.contains("manager_type=non-tee")); + assert!(error_msg.contains("manager_type=crabshack")); } #[tokio::test] - async fn test_manager_filtering_with_single_non_tee_manager() { - // Single non-TEE manager should work correctly + async fn test_manager_filtering_with_single_crabshack_manager() { + // Single crabshack manager should work correctly let managers = make_managers(1); let svc = make_service( managers, Arc::new(mock_repo_with_manager_count(0)), - Arc::new(MockSystemConfigsService::no_config_with_non_tee()), + Arc::new(MockSystemConfigsService::no_config_with_crabshack()), ); // Should always return the same manager @@ -8293,14 +8324,14 @@ mod tests { } #[tokio::test] - async fn test_manager_filtering_alternates_non_tee_managers() { - // Multiple non-TEE managers should alternate properly + async fn test_manager_filtering_alternates_crabshack_managers() { + // Multiple crabshack managers should alternate properly let managers = make_managers(3); let svc = make_service( managers, Arc::new(mock_repo_with_manager_count(0)), - Arc::new(MockSystemConfigsService::no_config_with_non_tee()), + Arc::new(MockSystemConfigsService::no_config_with_crabshack()), ); let mut urls = Vec::new(); @@ -8550,8 +8581,8 @@ mod tests { } #[test] - fn test_image_resolution_config_coexists_with_tee_flag() { - // Image config is independent of the non_tee_infra flag + fn test_image_resolution_config_coexists_with_legacy_tee_flag() { + // Image config is independent of the crabshack_infra flag let config = AgentHostingConfig { new_agent_with_non_tee_infra: Some(true), // Flag doesn't affect image resolution crabshack: AgentHostingCrabshackConfig { diff --git a/crates/services/src/system_configs/ports.rs b/crates/services/src/system_configs/ports.rs index 30a6882e..aec62656 100644 --- a/crates/services/src/system_configs/ports.rs +++ b/crates/services/src/system_configs/ports.rs @@ -220,13 +220,13 @@ pub struct AgentHostingCrabshackConfig { #[serde(default, skip_serializing_if = "Option::is_none")] pub openclaw_image: Option, - /// When `true`, non-TEE deploys for canonical `ironclaw` use the latest versioned image ref + /// When `true`, crabshack deploys for canonical `ironclaw` use the latest versioned image ref /// from the agent manager (crabshack) `/images` allowlist—same source as upgrade checks—and /// ignore `ironclaw_image`. #[serde(default, skip_serializing_if = "Option::is_none")] pub ironclaw_deploy_latest_version_tag: Option, - /// When `true`, non-TEE deploys for canonical `openclaw` use the latest versioned image ref + /// When `true`, crabshack deploys for canonical `openclaw` use the latest versioned image ref /// from the agent manager `/images` allowlist, and ignore `openclaw_image`. #[serde(default, skip_serializing_if = "Option::is_none")] pub openclaw_deploy_latest_version_tag: Option, @@ -272,8 +272,9 @@ impl AgentHostingCrabshackConfig { #[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))] #[derive(Debug, Clone, Serialize)] pub struct AgentHostingConfig { - /// Use non-TEE infrastructure (true = non-TEE, false = TEE/default) - /// When true, only non-TEE managers are used for instance creation + /// Route new agents to the crabshack (passkey/"claws") path (true) instead of the + /// legacy_tee (bearer) path (false/default). When true, only crabshack managers are + /// used for instance creation. Field name kept for the DB + admin-API JSON contract. #[serde(default, skip_serializing_if = "Option::is_none")] pub new_agent_with_non_tee_infra: Option,