diff --git a/AGENTS.md b/AGENTS.md index e1c1ee2..724290e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -134,8 +134,6 @@ See `docs/COLIBRI-EXTERNAL-MCP-PROTOTYPE.md` and for Priority 1). - `docs/CLAWDIE-INSTALLER-HANDOFF.md` β€” FreeBSD agent (Codex): `clawdie` ZFS layout + service install validation. -- **Proof gate tracker:** `cargo run --bin proof-gate-tracker` -- **Platform matrix:** `cargo test --test platform-matrix` - **External MCP smoke:** see `docs/COLIBRI-EXTERNAL-MCP-PROTOTYPE.md` ## Linux Agent Constraints diff --git a/Cargo.toml b/Cargo.toml index 1b10102..c2e6e10 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,10 +16,6 @@ path = "src/main.rs" name = "colibri-runtime-inventory" path = "src/bin/runtime_inventory.rs" -[[bin]] -name = "proof-gate-tracker" -path = "tools/proof-gate-tracker.rs" - [dependencies] # Probe logic lives in colibri-deepseek (which pulls reqwest/rustls, chrono…). colibri-deepseek = { path = "crates/colibri-deepseek" } diff --git a/tools/README.md b/tools/README.md deleted file mode 100644 index 7e0a418..0000000 --- a/tools/README.md +++ /dev/null @@ -1,93 +0,0 @@ -# Colibri Tools - -This directory contains utility tools for the Colibri multiagent development workflow. - -## proof-gate-tracker - -Automated proof gate validation tool that checks the status of all 6 migration proof gates. - -### Usage - -```bash -# Build and run -cargo run --release --bin proof-gate-tracker - -# Or build and run directly -cargo build --release --bin proof-gate-tracker -./target/release/proof-gate-tracker -``` - -### Proof Gates Checked - -1. **Gate #1 - Contracts**: Validates golden test fixtures exist and are valid JSON -2. **Gate #2 - Cache Manifest**: Verifies DeepSeek cache hit manifests exist for osa + domedog -3. **Gate #3 - Runtime Inventory**: Ensures runtime inventory parity across all platforms -4. **Gate #4 - Cross-Platform**: Runs `cargo check --workspace` to ensure build passes -5. **Gate #5 - Watchdog**: Validates osa watchdog socket read successful -6. **Gate #6 - Caller Inventory**: Checks caller inventory documentation exists (precondition check) - -### Exit Codes - -- `0`: All critical gates passing -- `1`: Some critical gates failing - -### Integration with CI/CD - -```yaml -# Example GitHub Actions -- name: Validate Proof Gates - run: cargo run --release --bin proof-gate-tracker -``` - -## Platform Matrix Tests - -Cross-platform startup checks are located in `tests/platform-matrix.rs`. - -### Usage - -```bash -# Run all platform matrix tests -cargo test --test platform-matrix - -# Run with output -cargo test --test platform-matrix -- --nocapture - -# Run specific test -cargo test --test platform-matrix all_platforms_validate_core_features -- --nocapture -``` - -### Tests Included - -- `all_platforms_validate_core_features`: Validates all platforms (FreeBSD/Linux) have valid manifests -- `freebsd_specific_tests`: FreeBSD-specific validations (osa) -- `linux_specific_tests`: Linux-specific validations (domedog, debby) -- `cache_economics_parity`: Verifies cache hit rate consistency across platforms - -## Multiagent Workflow Tools - -### Agent Handoff Protocol - -See `doc/-HANDOFF.md` for the standardized handoff protocol used between agents. - -### Handoff Template - -```json -{ - "agent_from": "agent_name", - "agent_to": "agent_name", - "focus_area": "brief description", - "proof_gates_pending": ["gate-1", "gate-2"], - "known_limitations": ["limitation 1"], - "next_steps": ["step 1", "step 2"], - "context_files": ["file1.rs", "file2.md"], - "test_evidence": ["manifests/file1.json"] -} -``` - -### Handoff Checklist - -- [ ] All tests pass (`cargo test --workspace`) -- [ ] Relevant proof gates documented -- [ ] Cross-platform validation recorded -- [ ] Next agent's entry point marked -- [ ] Handoff entry added to `doc/-HANDOFF.md` diff --git a/tools/proof-gate-tracker.rs b/tools/proof-gate-tracker.rs deleted file mode 100644 index 1ed242e..0000000 --- a/tools/proof-gate-tracker.rs +++ /dev/null @@ -1,324 +0,0 @@ -use std::fs; -use std::path::Path; -use std::process::Command; - -struct ProofGate { - name: String, - critical: bool, - check: Box GateStatus>, -} - -#[derive(Debug)] -enum GateStatus { - Pass { evidence: String }, - Fail { reason: String }, - Skipped { reason: String }, -} - -fn check_gate_1_contracts() -> GateStatus { - // Check if golden test fixtures exist and are valid JSON - let manifest_dir = Path::new("manifests"); - if !manifest_dir.exists() { - return GateStatus::Fail { - reason: "manifests/ directory does not exist".to_string(), - }; - } - - let golden_files = [ - "2026-05-26-domedog-deepseek-cache-result.json", - "2026-05-26-osa-deepseek-cache-result.json", - "2026-05-26-domedog-runtime-inventory.json", - "2026-05-26-osa-runtime-inventory.json", - "2026-05-26-debby-runtime-inventory.json", - "2026-05-26-osa-watchdog-host-status.json", - ]; - - let mut valid_count = 0; - for file in &golden_files { - let path = manifest_dir.join(file); - if path.exists() { - match fs::read_to_string(&path) { - Ok(content) => { - if serde_json::from_str::(&content).is_ok() { - valid_count += 1; - } - } - Err(_) => continue, - } - } - } - - if valid_count >= 5 { - GateStatus::Pass { - evidence: format!( - "{}/{} golden fixtures valid", - valid_count, - golden_files.len() - ), - } - } else { - GateStatus::Fail { - reason: format!( - "Only {}/{} golden fixtures valid", - valid_count, - golden_files.len() - ), - } - } -} - -fn check_gate_2_cache_manifest() -> GateStatus { - let manifest_dir = Path::new("manifests"); - let osa_manifest = manifest_dir.join("2026-05-26-osa-deepseek-cache-result.json"); - let domedog_manifest = manifest_dir.join("2026-05-26-domedog-deepseek-cache-result.json"); - - let mut evidence = Vec::new(); - - if osa_manifest.exists() { - if let Ok(content) = fs::read_to_string(&osa_manifest) { - if let Ok(json) = serde_json::from_str::(&content) { - let cache_hit = json["cache_hit_observed"].as_bool().unwrap_or(false); - let hit_tokens = json["cache_hit_tokens"].as_u64().unwrap_or(0); - if cache_hit && hit_tokens > 0 { - evidence.push(format!("osa: {} cache hit tokens", hit_tokens)); - } - } - } - } - - if domedog_manifest.exists() { - if let Ok(content) = fs::read_to_string(&domedog_manifest) { - if let Ok(json) = serde_json::from_str::(&content) { - let cache_hit = json["cache_hit_observed"].as_bool().unwrap_or(false); - let hit_tokens = json["cache_hit_tokens"].as_u64().unwrap_or(0); - if cache_hit && hit_tokens > 0 { - evidence.push(format!("domedog: {} cache hit tokens", hit_tokens)); - } - } - } - } - - if evidence.len() >= 2 { - GateStatus::Pass { - evidence: evidence.join("; "), - } - } else if evidence.len() == 1 { - GateStatus::Pass { - evidence: format!("Partial: {}", evidence[0]), - } - } else { - GateStatus::Fail { - reason: "No cache hit manifests found".to_string(), - } - } -} - -fn check_gate_3_runtime_inventory() -> GateStatus { - let manifest_dir = Path::new("manifests"); - let platforms = [("osa", "FreeBSD"), ("domedog", "Linux"), ("debby", "Linux")]; - let mut evidence = Vec::new(); - - for (host, expected_os) in &platforms { - let manifest_path = - manifest_dir.join(format!("2026-05-26-{}-runtime-inventory.json", host)); - if manifest_path.exists() { - if let Ok(content) = fs::read_to_string(&manifest_path) { - if let Ok(json) = serde_json::from_str::(&content) { - let os = json["os"].as_str().unwrap_or(""); - let pi = json["pi"].as_str().unwrap_or("none"); - if os.contains(expected_os) { - evidence.push(format!("{}: {} (pi: {})", host, expected_os, pi)); - } - } - } - } - } - - if evidence.len() >= 2 { - GateStatus::Pass { - evidence: evidence.join("; "), - } - } else { - GateStatus::Fail { - reason: format!( - "Only {}/{} platforms have valid runtime inventories", - evidence.len(), - platforms.len() - ), - } - } -} - -fn check_gate_4_cross_platform() -> GateStatus { - // Check if build passes (Linux) - let result = Command::new("cargo") - .args(["check", "--workspace"]) - .output(); - - match result { - Ok(output) if output.status.success() => GateStatus::Pass { - evidence: "cargo check --workspace passed".to_string(), - }, - Ok(output) => { - let stderr = String::from_utf8_lossy(&output.stderr); - GateStatus::Fail { - reason: format!( - "Build failed: {}", - stderr.lines().take(3).collect::>().join(" ") - ), - } - } - Err(e) => GateStatus::Fail { - reason: format!("Failed to run cargo check: {}", e), - }, - } -} - -fn check_gate_5_watchdog() -> GateStatus { - // Check if watchdog host status manifest exists - let manifest_path = Path::new("manifests/2026-05-26-osa-watchdog-host-status.json"); - if manifest_path.exists() { - match fs::read_to_string(manifest_path) { - Ok(content) => { - if let Ok(json) = serde_json::from_str::(&content) { - if json["source"].as_str() == Some("watchdog-socket") { - let mode = json["mode"].as_str().unwrap_or("unknown"); - GateStatus::Pass { - evidence: format!( - "osa watchdog socket read successful (mode: {})", - mode - ), - } - } else { - GateStatus::Fail { - reason: "Manifest exists but source is not watchdog-socket".to_string(), - } - } - } else { - GateStatus::Fail { - reason: "Manifest is not valid JSON".to_string(), - } - } - } - Err(e) => GateStatus::Fail { - reason: format!("Failed to read manifest: {}", e), - }, - } - } else { - GateStatus::Fail { - reason: "osa watchdog host status manifest not found".to_string(), - } - } -} - -fn check_gate_6_caller_inventory() -> GateStatus { - // Gate #6 is gated on precondition: CONTROLPLANE_RUNNER=pi in production - // Check if caller inventory exists - let inventory_path = Path::new("docs/CALLER-INVENTORY.md"); - if inventory_path.exists() { - match fs::read_to_string(inventory_path) { - Ok(content) => { - if content.contains("agent-runner.ts") && content.contains("KEEP") { - GateStatus::Skipped { - reason: "Caller inventory documented, awaiting production verification of CONTROLPLANE_RUNNER=pi".to_string() - } - } else { - GateStatus::Fail { - reason: "Caller inventory exists but does not document agent-runner.ts" - .to_string(), - } - } - } - Err(e) => GateStatus::Fail { - reason: format!("Failed to read caller inventory: {}", e), - }, - } - } else { - GateStatus::Fail { - reason: "docs/CALLER-INVENTORY.md not found".to_string(), - } - } -} - -fn main() { - println!("πŸ” Colibri Proof Gate Tracker"); - println!("═════════════════════════════\n"); - - let gates: Vec = vec![ - ProofGate { - name: "gate-1-contracts".to_string(), - critical: true, - check: Box::new(check_gate_1_contracts), - }, - ProofGate { - name: "gate-2-cache-manifest".to_string(), - critical: true, - check: Box::new(check_gate_2_cache_manifest), - }, - ProofGate { - name: "gate-3-runtime-inventory".to_string(), - critical: true, - check: Box::new(check_gate_3_runtime_inventory), - }, - ProofGate { - name: "gate-4-cross-platform".to_string(), - critical: true, - check: Box::new(check_gate_4_cross_platform), - }, - ProofGate { - name: "gate-5-watchdog".to_string(), - critical: true, - check: Box::new(check_gate_5_watchdog), - }, - ProofGate { - name: "gate-6-caller-inventory".to_string(), - critical: false, // Precondition check - check: Box::new(check_gate_6_caller_inventory), - }, - ]; - - let mut critical_passed = 0; - let mut critical_total = 0; - let mut all_passed = 0; - - for gate in &gates { - if gate.critical { - critical_total += 1; - } - - let status = (gate.check)(); - let critical_marker = if gate.critical { " πŸ”’" } else { " ⏸️" }; - - match status { - GateStatus::Pass { evidence } => { - println!("βœ… {}{}: {}", gate.name, critical_marker, evidence); - all_passed += 1; - if gate.critical { - critical_passed += 1; - } - } - GateStatus::Fail { reason } => { - println!("❌ {}{}: {}", gate.name, critical_marker, reason); - } - GateStatus::Skipped { reason } => { - println!("⏭️ {}{}: {}", gate.name, critical_marker, reason); - all_passed += 1; - } - } - } - - println!("\n═════════════════════════════"); - println!("Summary: {}/{} gates passing", all_passed, gates.len()); - println!( - "Critical: {}/{} gates passing", - critical_passed, critical_total - ); - - if critical_passed < critical_total { - println!("\n⚠️ Some critical gates are failing!"); - std::process::exit(1); - } else { - println!("\nβœ… All critical gates are passing!"); - std::process::exit(0); - } -}