diff --git a/crates/sharecli-session/src/lib.rs b/crates/sharecli-session/src/lib.rs index da15efbd..8466e9eb 100644 --- a/crates/sharecli-session/src/lib.rs +++ b/crates/sharecli-session/src/lib.rs @@ -57,7 +57,6 @@ pub mod discovery; pub mod events; pub mod layout; pub mod ledger; -pub mod migration; pub mod recovery; pub mod resolver; pub mod rpc; @@ -231,7 +230,22 @@ impl SessionStore { } fn init(conn: Connection) -> Result { conn.pragma_update(None, "journal_mode", "WAL")?; - migration::run_migrations(&conn)?; + conn.execute_batch( + "CREATE TABLE IF NOT EXISTS sessions (id TEXT PRIMARY KEY, harness TEXT NOT NULL, session_id TEXT NOT NULL, cwd TEXT NOT NULL, resume_json TEXT NOT NULL, confidence TEXT NOT NULL, state TEXT NOT NULL); + CREATE TABLE IF NOT EXISTS session_observations ( + seq INTEGER PRIMARY KEY AUTOINCREMENT, + observed_at TEXT NOT NULL, + surface_id TEXT NOT NULL, + surface_json TEXT NOT NULL, + session_json TEXT, + capabilities_json TEXT NOT NULL, + kind TEXT NOT NULL + ); + CREATE INDEX IF NOT EXISTS session_observations_surface_seq + ON session_observations(surface_id, seq); + CREATE INDEX IF NOT EXISTS session_observations_time + ON session_observations(observed_at);", + )?; Ok(Self { conn: Mutex::new(conn) }) } pub fn upsert(&self, session: &AgentSession) -> Result<()> { diff --git a/src/main.rs b/src/main.rs index 8162ec30..62f8cd7f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -472,70 +472,6 @@ enum Commands { #[arg(long)] dry_run: bool, }, - - /// Soft auto-update probe (C11 L111) — report current vs latest - /// advertised version without performing any install. Operators MUST - /// execute the printed `install_hint` themselves (e.g. - /// `cargo install sharecli --force`). Hard signed updates are - /// blocked on L112 secrets. - Upgrade { - /// Only report; never install. Always true (no `--apply` flag yet). - #[arg(long, default_value_t = true)] - check: bool, - - /// Channel to advertise (crates-io | binstall | brew | gh-releases) - #[arg(long, default_value = "crates-io")] - channel: String, - }, - - /// Show recent CLI invocation history (C09 L81.12) - History { - /// Maximum number of entries to display - #[arg(long, default_value_t = 20)] - limit: usize, - - /// Output as machine-readable JSON - #[arg(long)] - json: bool, - - /// Clear all history entries - #[arg(long)] - clear: bool, - }, - /// Harbor soak harness — long-running CLI stability evaluation - Soak { - /// Subcommand: run (default) or report - #[command(subcommand)] - cmd: SoakCmd, - }, -} - -#[derive(Subcommand, Debug)] -enum SoakCmd { - /// Run the soak harness (executes scenarios repeatedly) - Run { - /// Total duration in seconds (overrides config) - #[arg(short, long)] - duration: Option, - - /// Interval between scenario runs in seconds (overrides config) - #[arg(short, long)] - interval: Option, - - /// Path to soak.yaml config - #[arg(short, long, default_value = "soak.yaml")] - config: std::path::PathBuf, - - /// Output path for the JSON report - #[arg(short, long)] - output: Option, - }, - /// Display an existing soak report - Report { - /// Path to the soak report JSON - #[arg(short, long, default_value = "soak-report.json")] - output: std::path::PathBuf, - }, } #[derive(Subcommand, Debug)] @@ -974,12 +910,7 @@ async fn run() -> Result<()> { .create(true) .append(true) .open(&log_path_for_writer) - .unwrap_or_else(|e| { - panic!( - "failed to reopen log file at {}: {e}", - log_path_for_writer.display() - ) - }), + .expect("reopen log file"), ) }; if json { @@ -1102,35 +1033,6 @@ async fn run() -> Result<()> { }; serve_run(bind, policy).await? } - Commands::Upgrade { check: _, channel } => { - commands::upgrade::check(Some(channel.as_str()))?; - } - Commands::History { limit, json, clear } => { - let path = commands::history::history_path(); - if *clear { - commands::history::clear(&path)?; - eprintln!("History cleared."); - } else { - let entries = commands::history::read_recent(&path, *limit)?; - if entries.is_empty() { - eprintln!("No history entries. CLI invocations are recorded automatically."); - } else if *json { - println!("{}", serde_json::to_string_pretty(&entries).unwrap_or_default()); - } else { - for entry in &entries { - println!("{}", commands::history::format_entry(entry)); - } - } - } - } - Commands::Soak { cmd } => match cmd { - SoakCmd::Run { duration, interval, config, output } => { - commands::soak::run(*duration, *interval, config, output.as_deref())?; - } - SoakCmd::Report { output } => { - commands::soak::report_cmd(output)?; - } - }, Commands::Thermal { cap } => { let gov = sharecli_fleet::thermal::ThermalGovernor::new(); let poll_pool_status = move || { @@ -1300,9 +1202,9 @@ fn session_cmd(cmd: &SessionCmd) -> Result<()> { let service = SessionService::new(store); let value = match cmd { SessionCmd::List { .. } => serde_json::to_value(service.list()?)?, - SessionCmd::Inspect { .. } => serde_json::to_value(service.inspect( - operation.ok_or_else(|| anyhow::anyhow!("session inspect requires an operation id"))?, - )?)?, + SessionCmd::Inspect { .. } => { + serde_json::to_value(service.inspect(operation.expect("id"))?)? + } SessionCmd::RecoveryPlan { max_age_seconds, .. } => serde_json::to_value( service.recovery_plan(chrono::Duration::seconds(*max_age_seconds as i64))?, )?, @@ -1776,8 +1678,8 @@ async fn prune(idle_seconds: u64, force: bool) -> Result<()> { let processes = pool.list().await; let now = std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) - .map(|d| d.as_secs()) - .unwrap_or(0); + .expect("system clock before Unix epoch") + .as_secs(); let candidates: Vec<_> = processes .into_iter() diff --git a/tests/c03_l30_agent_readiness_gate.rs b/tests/c03_l30_agent_readiness_gate.rs index 6605cca1..1adef63c 100644 --- a/tests/c03_l30_agent_readiness_gate.rs +++ b/tests/c03_l30_agent_readiness_gate.rs @@ -61,34 +61,21 @@ fn fr003_l303_fr_guardrail_coverage_and_pin() { .find("## Measured coverage pin") .expect("TEST_COVERAGE_MATRIX must have Measured coverage pin section"); let prior_start = matrix - .find("### Prior pin (superseded for current cycle)") + .find("### Prior pin (superseded)") .expect("TEST_COVERAGE_MATRIX must have Prior pin section"); let measured_section = &matrix[measured_start..prior_start]; - assert!(measured_section.contains("77.34%"), "Measured pin section must pin --lib 77.34%"); + assert!(measured_section.contains("80.51%"), "Measured pin section must pin 80.51%"); assert!( - measured_section.contains("fa887e9"), - "Measured pin section must pin current source revision fa887e9" + measured_section.contains("e89755c"), + "Measured pin section must pin current source revision e89755c" ); assert!( - measured_section.contains("fa887e9.coverage-snapshot.json"), - "Measured pin section must reference retained snapshot fa887e9" - ); - assert!( - root.join("audit/coverage-snapshots/fa887e9.coverage-snapshot.json").is_file(), - "retained llvm-cov snapshot artifact must exist" - ); - // Workspace-broad pin 80.51% @ 5d8dc08 retained as historical evidence. - assert!( - matrix.contains("80.51%"), - "TEST_COVERAGE_MATRIX must retain prior workspace-broad pin 80.51%" - ); - assert!( - matrix.contains("5d8dc08"), - "TEST_COVERAGE_MATRIX must retain prior workspace-broad pin sha 5d8dc08" + measured_section.contains("5d8dc08"), + "Measured pin section must reference retained snapshot 5d8dc08" ); assert!( root.join("audit/coverage-snapshots/5d8dc08.coverage-snapshot.json").is_file(), - "prior workspace-broad llvm-cov snapshot artifact must exist" + "retained llvm-cov snapshot artifact must exist" ); assert!(ci.contains("cargo nextest run"), "ci.yml must run nextest guardrail suite"); assert!(justfile.contains("test"), "justfile must expose test recipe");