diff --git a/README.md b/README.md index 6626b54..556b122 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ colibri-daemon (always-on Unix socket server) ├── session — append-only JSONL sessions, 3-region prompt assembly └── spawner — agent subprocess management (retry/backoff, FreeBSD jail confinement) -colibri-client — CLI tools (colibri, colibri_smoke_agent) +colibri-client — CLI tools (colibri, colibri-test-agent) colibri-glasspane-tui— ratatui dashboard ``` diff --git a/crates/colibri-client/Cargo.toml b/crates/colibri-client/Cargo.toml index 3649e1f..8872714 100644 --- a/crates/colibri-client/Cargo.toml +++ b/crates/colibri-client/Cargo.toml @@ -10,8 +10,8 @@ name = "colibri" path = "src/bin/colibri.rs" [[bin]] -name = "colibri-smoke-agent" -path = "src/bin/colibri_smoke_agent.rs" +name = "colibri-test-agent" +path = "src/bin/colibri_test_agent.rs" [dependencies] colibri-daemon = { path = "../colibri-daemon" } diff --git a/crates/colibri-client/src/bin/colibri.rs b/crates/colibri-client/src/bin/colibri.rs index 2f12a4f..71b84bc 100644 --- a/crates/colibri-client/src/bin/colibri.rs +++ b/crates/colibri-client/src/bin/colibri.rs @@ -74,12 +74,12 @@ Socket defaults to COLIBRI_DAEMON_SOCKET, then the daemon's configured default. Examples: colibri status - colibri --socket /tmp/colibri-smoke/colibri.sock snapshot - colibri spawn-local target/release/colibri-smoke-agent - colibri create-task --title "verify OSA smoke" --description "manual follow-up" + colibri --socket /tmp/colibri-test/colibri.sock snapshot + colibri spawn-local target/release/colibri-test-agent + colibri create-task --title "verify OSA check" --description "manual follow-up" colibri intake-task --title "triage watchdog" --capability freebsd colibri list-tasks --status queued - colibri register-skill freebsd-smoke --description "Live USB smoke test" --category freebsd + colibri register-skill freebsd-check --description "Live USB startup check" --category freebsd colibri list-skills "# } @@ -483,14 +483,14 @@ mod tests { parsed(&[ "create-task", "--title", - "check smoke", + "check agent", "--description", "from cli", ]), Options { socket_path: default_socket_path(), command: Command::CreateTask { - title: "check smoke".to_string(), + title: "check agent".to_string(), description: Some("from cli".to_string()), }, } diff --git a/crates/colibri-client/src/bin/colibri_smoke_agent.rs b/crates/colibri-client/src/bin/colibri_test_agent.rs similarity index 95% rename from crates/colibri-client/src/bin/colibri_smoke_agent.rs rename to crates/colibri-client/src/bin/colibri_test_agent.rs index 63eb50b..7db2045 100644 --- a/crates/colibri-client/src/bin/colibri_smoke_agent.rs +++ b/crates/colibri-client/src/bin/colibri_test_agent.rs @@ -8,9 +8,9 @@ use std::{ fn usage() -> &'static str { r#"Usage: - colibri-smoke-agent [--session-id ID] [--cwd PATH] [--step-ms MS] [--hold-secs SECONDS] + colibri-test-agent [--session-id ID] [--cwd PATH] [--step-ms MS] [--hold-secs SECONDS] -Emits deterministic Pi-compatible JSONL for local colibri-daemon smoke tests. +Emits deterministic Pi-compatible JSONL for local colibri-daemon startup checks. "# } @@ -25,7 +25,7 @@ struct Options { impl Default for Options { fn default() -> Self { Self { - session_id: "manual-smoke".to_string(), + session_id: "manual-test".to_string(), cwd: env::current_dir() .ok() .and_then(|path| path.into_os_string().into_string().ok()) @@ -135,7 +135,7 @@ fn main() -> ExitCode { Ok(options) => match emit_jsonl(&options) { Ok(()) => ExitCode::SUCCESS, Err(e) => { - eprintln!("colibri-smoke-agent: {e}"); + eprintln!("colibri-test-agent: {e}"); ExitCode::FAILURE } }, diff --git a/crates/colibri-client/tests/live_socket_smoke.rs b/crates/colibri-client/tests/live_socket_check.rs similarity index 90% rename from crates/colibri-client/tests/live_socket_smoke.rs rename to crates/colibri-client/tests/live_socket_check.rs index 96ea848..2136339 100644 --- a/crates/colibri-client/tests/live_socket_smoke.rs +++ b/crates/colibri-client/tests/live_socket_check.rs @@ -10,8 +10,8 @@ use colibri_daemon::{socket, DaemonConfig, DaemonState, SharedState}; use colibri_glasspane::AgentState; use uuid::Uuid; -fn smoke_config() -> DaemonConfig { - let data_dir = std::env::temp_dir().join(format!("colibri-live-smoke-{}", Uuid::new_v4())); +fn check_config() -> DaemonConfig { + let data_dir = std::env::temp_dir().join(format!("colibri-live-test-{}", Uuid::new_v4())); DaemonConfig { socket_path: data_dir.join("colibri.sock"), data_dir: data_dir.clone(), @@ -23,7 +23,7 @@ fn smoke_config() -> DaemonConfig { openrouter_endpoint: "https://openrouter.ai/api/v1/chat/completions".to_string(), anthropic_api_key: None, anthropic_endpoint: "https://api.anthropic.com/v1/messages".to_string(), - host: "live-smoke-host".to_string(), + host: "live-test-host".to_string(), max_context_tokens: 128_000, cost_mode: "smart".to_string(), scheduler_prompt_injection: false, @@ -90,10 +90,10 @@ async fn wait_for_state(client: &DaemonClient, expected: AgentState) -> String { } #[tokio::test] -async fn daemon_client_live_socket_smoke_with_local_fake_agent() { - let config = smoke_config(); +async fn daemon_client_live_socket_check_with_local_fake_agent() { + let config = check_config(); tokio::fs::create_dir_all(&config.data_dir).await.unwrap(); - let fake_agent = env!("CARGO_BIN_EXE_colibri-smoke-agent"); + let fake_agent = env!("CARGO_BIN_EXE_colibri-test-agent"); let state: SharedState = Arc::new(DaemonState::new(config.clone())); let shutdown = state.shutdown_rx.resubscribe(); @@ -107,13 +107,13 @@ async fn daemon_client_live_socket_smoke_with_local_fake_agent() { let status = client.status().await.unwrap(); assert_eq!(status["daemon"], "colibri-daemon"); - assert_eq!(status["host"], "live-smoke-host"); + assert_eq!(status["host"], "live-test-host"); let empty_snapshot = client.glasspane_snapshot().await.unwrap(); assert!(empty_snapshot.panes.is_empty()); let spawn = client - .spawn_agent("local", fake_agent, Some("smoke-session".to_string()), None) + .spawn_agent("local", fake_agent, Some("test-session".to_string()), None) .await .unwrap(); let agent_id = spawn["agent_id"].as_str().unwrap().to_string(); @@ -130,7 +130,7 @@ async fn daemon_client_live_socket_smoke_with_local_fake_agent() { .iter() .find(|pane| pane.id == agent_id) .unwrap(); - assert_eq!(pane.pi_session_id.as_deref(), Some("manual-smoke")); + assert_eq!(pane.pi_session_id.as_deref(), Some("manual-test")); assert!(pane.cwd.is_some()); let kill = client.kill_agent(agent_id).await.unwrap(); @@ -143,7 +143,7 @@ async fn daemon_client_live_socket_smoke_with_local_fake_agent() { #[tokio::test] async fn colibri_cli_task_commands_use_socket_api() { - let config = smoke_config(); + let config = check_config(); tokio::fs::create_dir_all(&config.data_dir).await.unwrap(); let state: SharedState = Arc::new(DaemonState::new(config.clone())); @@ -201,9 +201,9 @@ async fn colibri_cli_task_commands_use_socket_api() { #[tokio::test] async fn poll_tasks_spawns_agent_for_claimed_task() { - let mut config = smoke_config(); - let fake_agent = env!("CARGO_BIN_EXE_colibri-smoke-agent"); - // Set COLIBRI_AGENT_BINARY so poll_tasks uses the smoke agent binary + let mut config = check_config(); + let fake_agent = env!("CARGO_BIN_EXE_colibri-test-agent"); + // Set COLIBRI_AGENT_BINARY so poll_tasks uses the test agent binary config.data_dir = std::env::temp_dir().join(format!("colibri-poll-tasks-test-{}", Uuid::new_v4())); tokio::fs::create_dir_all(&config.data_dir).await.unwrap(); @@ -230,7 +230,7 @@ async fn poll_tasks_spawns_agent_for_claimed_task() { // Create and claim a task directly in the store let task = { let store = state.store.lock().unwrap(); - let task = store.create_task("poll-tasks-smoke", None).unwrap(); + let task = store.create_task("poll-tasks-check", None).unwrap(); let agent = store.list_agents().unwrap(); let agent_id = &agent[0].id; store.claim_task(&task.id, agent_id).unwrap(); @@ -245,7 +245,7 @@ async fn poll_tasks_spawns_agent_for_claimed_task() { "task should be claimed before poll_tasks" ); - // Call poll_tasks — should spawn the smoke agent for this claimed task + // Call poll_tasks — should spawn the test agent for this claimed task poll_tasks(&state).await; // Verify an agent handle was created @@ -278,7 +278,7 @@ async fn poll_tasks_spawns_agent_for_claimed_task() { "session should be created for task" ); - // Glasspane should observe the full lifecycle: the smoke agent runs + // Glasspane should observe the full lifecycle: the test agent runs // through Idle → Working → Blocked → Working → Done quickly (10ms steps). // Wait for Done — the terminal state — which proves the whole path worked: // poll_tasks spawned the agent, stdout streamed to glasspane, and the @@ -292,7 +292,10 @@ async fn poll_tasks_spawns_agent_for_claimed_task() { assert!( Instant::now() < deadline, "agent did not reach Done — snapshot: {:?}", - snap.panes.iter().map(|p| (p.id.clone(), p.state)).collect::>() + snap.panes + .iter() + .map(|p| (p.id.clone(), p.state)) + .collect::>() ); tokio::time::sleep(Duration::from_millis(100)).await; } @@ -305,9 +308,9 @@ async fn poll_tasks_spawns_agent_for_claimed_task() { #[tokio::test] async fn harness_double_spawn_session_isolation() { - let config = smoke_config(); + let config = check_config(); tokio::fs::create_dir_all(&config.data_dir).await.unwrap(); - let fake_agent = env!("CARGO_BIN_EXE_colibri-smoke-agent"); + let fake_agent = env!("CARGO_BIN_EXE_colibri-test-agent"); let state: SharedState = Arc::new(DaemonState::new(config.clone())); let shutdown = state.shutdown_rx.resubscribe(); @@ -359,14 +362,14 @@ async fn harness_double_spawn_session_isolation() { let snap = client.glasspane_snapshot().await.unwrap(); assert_eq!(snap.panes.len(), 2); - // Both smoke agents default to "manual-smoke" unless --session-id is passed + // Both test agents default to "manual-test" unless --session-id is passed let pane_a = &snap.panes[0]; let pane_b = &snap.panes[1]; assert_eq!(pane_a.state, AgentState::Done); assert_eq!(pane_b.state, AgentState::Done); assert_ne!(pane_a.id, pane_b.id); - // Verify session isolation: both share the same session_id (smoke agent default) + // Verify session isolation: both share the same session_id (test agent default) assert_eq!(pane_a.pi_session_id, pane_b.pi_session_id); // Kill one agent — snapshot may still include stopped panes briefly diff --git a/crates/colibri-daemon/src/daemon.rs b/crates/colibri-daemon/src/daemon.rs index 9aca608..2bc41f8 100644 --- a/crates/colibri-daemon/src/daemon.rs +++ b/crates/colibri-daemon/src/daemon.rs @@ -337,7 +337,7 @@ pub async fn poll_tasks(state: &SharedState) { } let binary = std::env::var("COLIBRI_AGENT_BINARY") - .unwrap_or_else(|_| "colibri-smoke-agent".to_string()); + .unwrap_or_else(|_| "colibri-test-agent".to_string()); let agent_config = crate::spawner::AgentSpawnConfig { binary: binary.clone(), diff --git a/crates/colibri-daemon/src/scheduler.rs b/crates/colibri-daemon/src/scheduler.rs index 142c2e8..7be0277 100644 --- a/crates/colibri-daemon/src/scheduler.rs +++ b/crates/colibri-daemon/src/scheduler.rs @@ -536,7 +536,7 @@ mod tests { let state: SharedState = Arc::new(crate::daemon::DaemonState::new(config)); let mut scheduler = Scheduler::new(); scheduler.submit(TaskRequest { - title: "intake smoke".to_string(), + title: "intake check".to_string(), description: Some("must become a task".to_string()), required_capabilities: Vec::new(), }); @@ -547,7 +547,7 @@ mod tests { let tasks = state.store.lock().unwrap().list_tasks(None).unwrap(); assert_eq!(tasks.len(), 1); - assert_eq!(tasks[0].title, "intake smoke"); + assert_eq!(tasks[0].title, "intake check"); let _ = std::fs::remove_dir_all(data_dir); } diff --git a/crates/colibri-daemon/src/spawner.rs b/crates/colibri-daemon/src/spawner.rs index 7685403..4e2e867 100644 --- a/crates/colibri-daemon/src/spawner.rs +++ b/crates/colibri-daemon/src/spawner.rs @@ -9,7 +9,7 @@ //! 3. Anthropic (fallback) //! //! `Provider::Local` is intentionally excluded from fallback routing and API-key -//! checks. It exists for deterministic daemon/client smoke tests with fake +//! checks. It exists for deterministic daemon/client startup checks with fake //! Pi-JSONL agents and for future local-only tools. use std::collections::HashMap; diff --git a/crates/colibri-daemon/tests/intake_scheduler_loop.rs b/crates/colibri-daemon/tests/intake_scheduler_loop.rs index 4058a2b..a4514b8 100644 --- a/crates/colibri-daemon/tests/intake_scheduler_loop.rs +++ b/crates/colibri-daemon/tests/intake_scheduler_loop.rs @@ -1,4 +1,4 @@ -//! Regression test for the bug a 2026-05-27 osa FreeBSD smoke caught: +//! Regression test for the bug a 2026-05-27 osa FreeBSD check caught: //! `main.rs` started the socket server but never spawned `daemon::run_loop`, so //! an `intake-task` reported `queued` over the socket yet was never drained into //! the SQLite coordination store. @@ -20,7 +20,7 @@ use tokio::net::UnixStream; async fn intake_task_over_socket_drains_to_sqlite_via_run_loop() { // Isolated temp paths — never touch production /var/db or /var/run. let data_dir = - std::env::temp_dir().join(format!("colibri-intake-smoke-{}", uuid::Uuid::new_v4())); + std::env::temp_dir().join(format!("colibri-intake-check-{}", uuid::Uuid::new_v4())); std::fs::create_dir_all(&data_dir).expect("create temp data dir"); let mut config = DaemonConfig::from_env(); @@ -52,7 +52,7 @@ async fn intake_task_over_socket_drains_to_sqlite_via_run_loop() { wait_for_socket(&socket_path).await; // Submit an intake task over the socket; it should be accepted + queued. - const TITLE: &str = "intake-smoke-task"; + const TITLE: &str = "intake-check-task"; let response = send_command( &socket_path, &format!( diff --git a/crates/colibri-glasspane-tui/src/main.rs b/crates/colibri-glasspane-tui/src/main.rs index 7c05a3c..ca9d526 100644 --- a/crates/colibri-glasspane-tui/src/main.rs +++ b/crates/colibri-glasspane-tui/src/main.rs @@ -172,10 +172,10 @@ impl App { async fn spawn_agent(&mut self) { let result = self .client - .spawn_agent("local", "colibri-smoke-agent", None, None) + .spawn_agent("local", "colibri-test-agent", None, None) .await; match result { - Ok(_) => self.set_status("spawned colibri-smoke-agent"), + Ok(_) => self.set_status("spawned colibri-test-agent"), Err(e) => self.set_status(format!("spawn failed: {e}")), } } diff --git a/docs/CLAWDIE-STUDIO-PROPOSAL.md b/docs/CLAWDIE-STUDIO-PROPOSAL.md index 4f9e872..22eb570 100644 --- a/docs/CLAWDIE-STUDIO-PROPOSAL.md +++ b/docs/CLAWDIE-STUDIO-PROPOSAL.md @@ -86,7 +86,7 @@ JSON-RPC process — trivial to implement in Rust. - Create intake tasks from current file/docs context - Query queued tasks and blocked panes - Summarize active sessions -- Trigger smoke tests or scheduler runs +- Trigger startup checks or scheduler runs - Ask "what's the system doing right now?" and get a real answer **Why highest leverage:** @@ -160,7 +160,7 @@ Agent spawn/kill tools are stronger than normal writes and should require a sepa ```sh COLIBRI_MCP_SPAWN=1 -COLIBRI_MCP_SPAWN_ALLOWLIST=/usr/local/bin/pi,/usr/local/bin/colibri-smoke-agent +COLIBRI_MCP_SPAWN_ALLOWLIST=/usr/local/bin/pi,/usr/local/bin/colibri-test-agent ``` Phase 2 MCP tools (after basics proven): diff --git a/docs/COLIBRI-EXTERNAL-MCP-PROTOTYPE.md b/docs/COLIBRI-EXTERNAL-MCP-PROTOTYPE.md index 5cfd097..595a269 100644 --- a/docs/COLIBRI-EXTERNAL-MCP-PROTOTYPE.md +++ b/docs/COLIBRI-EXTERNAL-MCP-PROTOTYPE.md @@ -83,7 +83,7 @@ colibri-mcp --external-call This is intentionally separate from `COLIBRI_MCP_WRITE=1`. A Colibri write tool and an external MCP tool are different trust surfaces. -## Quick smoke shape +## Quick check shape From an MCP client: diff --git a/docs/FREEBSD-BUILD-LANE-HANDOFF.md b/docs/FREEBSD-BUILD-LANE-HANDOFF.md index a2aa2c8..f0564d0 100644 --- a/docs/FREEBSD-BUILD-LANE-HANDOFF.md +++ b/docs/FREEBSD-BUILD-LANE-HANDOFF.md @@ -68,7 +68,7 @@ After both builds, these must exist (the ISO preflight checks each): ```sh ls -l colibri/target/release/colibri-daemon \ colibri/target/release/colibri \ - colibri/target/release/colibri-smoke-agent + colibri/target/release/colibri-test-agent ls -l zot/bin/zot # colibri-tui is optional (staged if present) ``` @@ -113,14 +113,14 @@ ls -l /usr/local/bin/colibri /usr/local/bin/colibri-daemon ls -l /usr/local/etc/rc.d/colibri_daemon sysrc colibri_daemon_enable -# lifecycle + smoke +# lifecycle + checks service colibri_daemon start colibri status # paths, cost.mode, scheduler, tasks -colibri create-task --title "iso smoke" -colibri list-tasks --status queued # contains "iso smoke" -colibri intake-task --title "iso intake smoke" --capability freebsd +colibri create-task --title "iso check" +colibri list-tasks --status queued # contains "iso check" +colibri intake-task --title "iso intake check" --capability freebsd sleep 35 # one scheduler tick (~30s) -colibri list-tasks --status queued # contains "iso intake smoke" +colibri list-tasks --status queued # contains "iso intake check" service colibri_daemon stop # socket gone, SQLite remains service colibri_daemon start && colibri list-tasks --status queued # persistence ``` diff --git a/docs/HEADROOM-SIDECAR.md b/docs/HEADROOM-SIDECAR.md index 9084f70..0c517ae 100644 --- a/docs/HEADROOM-SIDECAR.md +++ b/docs/HEADROOM-SIDECAR.md @@ -63,7 +63,7 @@ Current daemon timeout: 5 seconds per sidecar request. a `HeadroomSidecar`; it is not a global daemon-wide replacement for existing cost-mode compaction. - Keep `COLIBRI_HEADROOM_ENABLED=0` for ISO/live-USB defaults unless Headroom is - staged and smoke-tested on the target image. + staged and validated on the target image. - FreeBSD: upstream `headroom-ai` may require local packaging work because some ONNX/ORT-backed extras do not have FreeBSD prebuilt binaries. Use a known-good Python environment and validate `scripts/headroom-sidecar.py` directly before diff --git a/docs/ISO-ACCEPTANCE-RUNBOOK.md b/docs/ISO-ACCEPTANCE-RUNBOOK.md index 9fe8af0..6966b8f 100644 --- a/docs/ISO-ACCEPTANCE-RUNBOOK.md +++ b/docs/ISO-ACCEPTANCE-RUNBOOK.md @@ -67,20 +67,20 @@ scheduler.interval_secs Confirm `cost.mode` matches `colibri_cost_mode` from rc.conf. -## 3. Task board smoke +## 3. Task board check ```sh -colibri create-task --title "iso smoke" --description "direct CLI task" +colibri create-task --title "iso check" --description "direct CLI task" colibri list-tasks --status queued ``` -Expected: list contains `iso smoke` with status `queued`. +Expected: list contains `iso check` with status `queued`. -## 4. Scheduler/intake smoke +## 4. Scheduler/intake check ```sh colibri intake-task \ - --title "iso intake smoke" \ + --title "iso intake check" \ --description "scheduler should persist this" \ --capability freebsd @@ -89,9 +89,9 @@ sleep 35 colibri list-tasks --status queued ``` -Expected: list contains `iso intake smoke`. +Expected: list contains `iso intake check`. -## 5. Glasspane smoke +## 5. Glasspane check ```sh colibri snapshot @@ -99,10 +99,10 @@ colibri snapshot Expected: valid JSON snapshot. It may have no panes before an agent is spawned. -Optional local fake-agent smoke if `colibri-smoke-agent` is included: +Optional local fake-agent check if `colibri-test-agent` is included: ```sh -colibri spawn-local /usr/local/bin/colibri-smoke-agent --session-id iso-smoke +colibri spawn-local /usr/local/bin/colibri-test-agent --session-id iso-check sleep 4 colibri snapshot ``` diff --git a/docs/ISO-SERVICE-LAYOUT.md b/docs/ISO-SERVICE-LAYOUT.md index ab2b731..3268b3c 100644 --- a/docs/ISO-SERVICE-LAYOUT.md +++ b/docs/ISO-SERVICE-LAYOUT.md @@ -15,7 +15,7 @@ ``` /usr/local/bin/colibri-daemon ← daemon binary (foreground, no self-daemonize) /usr/local/bin/colibri ← CLI client (status, create-task, etc.) -/usr/local/bin/colibri-smoke-agent ← smoke test agent (fake Pi JSONL) +/usr/local/bin/colibri-test-agent ← test agent (fake Pi JSONL) /usr/local/etc/rc.d/colibri_daemon ← rc.d service script /usr/local/etc/colibri/ rc.conf.sample ← service config template @@ -59,9 +59,9 @@ service colibri_daemon status # Socket health (nc must be available) service colibri_daemon health -# CLI smoke +# CLI check colibri status -colibri create-task --title "iso-smoke" +colibri create-task --title "iso-check" colibri list-tasks --status queued ``` diff --git a/docs/PRIORITY-HANDOFF-ISO-SPAWN-COST.md b/docs/PRIORITY-HANDOFF-ISO-SPAWN-COST.md index 52aeceb..fdbf89b 100644 --- a/docs/PRIORITY-HANDOFF-ISO-SPAWN-COST.md +++ b/docs/PRIORITY-HANDOFF-ISO-SPAWN-COST.md @@ -27,17 +27,17 @@ Gate 1 (passive service) is unproven. ### What's done (build wiring) -| Artifact / step | Location | Status | -| -------------------- | ------------------------------------------------ | ----------------------------------------------------------------------------------------------- | -| staging script | `scripts/stage-colibri-iso.sh` | done — copies `colibri-daemon`, `colibri`, `colibri-smoke-agent`, rc.d, newsyslog, creates dirs | -| rc.d script | `packaging/freebsd/colibri_daemon.in` | done — `start_precmd`, pidfile, daemon(8) wrapper, `COLIBRI_COST_MODE` propagation | -| newsyslog config | `packaging/freebsd/newsyslog-colibri.conf` | done | -| rc.conf.sample | generated by staging script | done | -| acceptance runbook | `docs/ISO-ACCEPTANCE-RUNBOOK.md` | done | -| build integration | clawdie-iso `build.sh::install_colibri_service` | done — calls `stage-colibri-iso.sh` against the image root | -| `colibri` user/group | clawdie-iso `build.sh` (`pw useradd colibri`) | done — created in the image during build | -| service enable | clawdie-iso `build.sh` (`colibri_daemon_enable`) | done — written into image rc.conf | -| prebuilt binaries | build-host Rust toolchain (preflight-gated) | done — `build.sh` stages prebuilt release binaries and fails preflight if missing | +| Artifact / step | Location | Status | +| -------------------- | ------------------------------------------------ | ---------------------------------------------------------------------------------------------- | +| staging script | `scripts/stage-colibri-iso.sh` | done — copies `colibri-daemon`, `colibri`, `colibri-test-agent`, rc.d, newsyslog, creates dirs | +| rc.d script | `packaging/freebsd/colibri_daemon.in` | done — `start_precmd`, pidfile, daemon(8) wrapper, `COLIBRI_COST_MODE` propagation | +| newsyslog config | `packaging/freebsd/newsyslog-colibri.conf` | done | +| rc.conf.sample | generated by staging script | done | +| acceptance runbook | `docs/ISO-ACCEPTANCE-RUNBOOK.md` | done | +| build integration | clawdie-iso `build.sh::install_colibri_service` | done — calls `stage-colibri-iso.sh` against the image root | +| `colibri` user/group | clawdie-iso `build.sh` (`pw useradd colibri`) | done — created in the image during build | +| service enable | clawdie-iso `build.sh` (`colibri_daemon_enable`) | done — written into image rc.conf | +| prebuilt binaries | build-host Rust toolchain (preflight-gated) | done — `build.sh` stages prebuilt release binaries and fails preflight if missing | ### What's missing (boot/runtime validation) @@ -50,9 +50,9 @@ Gate 1 (passive service) is unproven. ```sh service colibri_daemon start colibri status - colibri create-task --title "iso smoke" + colibri create-task --title "iso check" colibri list-tasks --status queued - colibri intake-task --title "iso intake smoke" --capability freebsd + colibri intake-task --title "iso intake check" --capability freebsd # wait one scheduler tick colibri list-tasks --status queued service colibri_daemon stop diff --git a/packaging/freebsd/colibri_daemon.in b/packaging/freebsd/colibri_daemon.in index 9f0f454..91a6b04 100644 --- a/packaging/freebsd/colibri_daemon.in +++ b/packaging/freebsd/colibri_daemon.in @@ -44,6 +44,7 @@ load_rc_config $name : ${colibri_daemon_socket:="${colibri_daemon_run_dir}/colibri.sock"} : ${colibri_daemon_db_path:="${colibri_daemon_data_dir}/colibri.sqlite"} : ${colibri_daemon_logfile:="/var/log/colibri/daemon.log"} +: ${colibri_daemon_provider_env:="/usr/local/etc/colibri/provider.env"} : ${colibri_daemon_host:="$(/bin/hostname)"} : ${colibri_cost_mode:="smart"} @@ -89,6 +90,14 @@ colibri_daemon_prestart() # root/corrupt manual start. rm -f "${colibri_daemon_socket}" "${pidfile}" "${supervisor_pidfile}" + # Provider keys are optional. Keep them in a root-owned env file instead of + # rc.conf so they are easy to rotate and not world-readable. + if [ -r "${colibri_daemon_provider_env}" ]; then + set -a + . "${colibri_daemon_provider_env}" + set +a + fi + # Config is passed to the child via the environment. export COLIBRI_DAEMON_DATA_DIR="${colibri_daemon_data_dir}" export COLIBRI_DAEMON_SOCKET="${colibri_daemon_socket}" diff --git a/scripts/glasspane-stress-test.sh b/scripts/glasspane-stress-test.sh index 879d4a4..0ad918e 100755 --- a/scripts/glasspane-stress-test.sh +++ b/scripts/glasspane-stress-test.sh @@ -42,10 +42,10 @@ echo "=== Glasspane Stress Test ===" echo "Socket: $SOCKET" echo "" -# 1. Concurrent multi-spawn — spawn 3 smoke agents at once +# 1. Concurrent multi-spawn — spawn 3 test agents at once echo "--- Concurrent spawn (3 agents) ---" for _ in 1 2 3; do - printf '{"cmd":"spawn-agent","provider":"local","model":"/usr/local/bin/colibri-smoke-agent"}\n' | timeout 5 $NC >/dev/null 2>&1 & + printf '{"cmd":"spawn-agent","provider":"local","model":"/usr/local/bin/colibri-test-agent"}\n' | timeout 5 $NC >/dev/null 2>&1 & done wait sleep 2 diff --git a/scripts/stage-colibri-iso.sh b/scripts/stage-colibri-iso.sh index 8812c95..c38c0f0 100755 --- a/scripts/stage-colibri-iso.sh +++ b/scripts/stage-colibri-iso.sh @@ -45,7 +45,7 @@ mkdir -p "$BIN_DIR" "$RC_DIR" "$ETC_DIR" "$NEWSYSLOG_DIR" "$DB_DIR" "$RUN_DIR" " copy_bin colibri-daemon copy_bin colibri -copy_bin colibri-smoke-agent +copy_bin colibri-test-agent if [ "${COLIBRI_STAGE_INCLUDE_TUI:-1}" != "0" ] && [ -x "$TARGET/colibri-tui" ]; then copy_bin colibri-tui @@ -85,7 +85,7 @@ Runtime validation: service colibri_daemon start colibri status - colibri create-task --title "iso smoke" + colibri create-task --title "iso check" colibri list-tasks --status queued service colibri_daemon stop EOF @@ -102,7 +102,7 @@ Staged Colibri into: $DESTDIR Installed: /usr/local/bin/colibri-daemon /usr/local/bin/colibri - /usr/local/bin/colibri-smoke-agent + /usr/local/bin/colibri-test-agent /usr/local/etc/rc.d/colibri_daemon /usr/local/etc/colibri/rc.conf.sample /usr/local/etc/newsyslog.conf.d/colibri.conf diff --git a/tests/platform-matrix.rs b/tests/platform-matrix.rs index 27c5144..94f9a0e 100644 --- a/tests/platform-matrix.rs +++ b/tests/platform-matrix.rs @@ -1,4 +1,4 @@ -// Cross-platform smoke test matrix for Colibri +// Cross-platform startup check matrix for Colibri // // Validates that core functionality works identically across all platforms // (FreeBSD, Linux) and catches platform-specific regressions early. diff --git a/tools/README.md b/tools/README.md index 8f6aadb..7e0a418 100644 --- a/tools/README.md +++ b/tools/README.md @@ -41,7 +41,7 @@ cargo build --release --bin proof-gate-tracker ## Platform Matrix Tests -Cross-platform smoke tests are located in `tests/platform-matrix.rs`. +Cross-platform startup checks are located in `tests/platform-matrix.rs`. ### Usage