fix #265: resolve all remaining clippy warnings (cast, too_many_lines, doc nits)
This commit is contained in:
parent
30d82148e0
commit
484cea62c7
12 changed files with 95 additions and 86 deletions
|
|
@ -23,6 +23,7 @@ use crate::lifecycle::{self, MANAGER_NAME};
|
|||
///
|
||||
/// In all cases an `ApprovalResolved` helper event lands in the manager's
|
||||
/// inbox when the work resolves.
|
||||
#[allow(clippy::too_many_lines)] // approval dispatch covers several independent approval kinds
|
||||
pub async fn approve(coord: Arc<Coordinator>, id: i64) -> Result<()> {
|
||||
let approval = coord.approvals.mark_approved(id)?;
|
||||
tracing::info!(
|
||||
|
|
@ -268,6 +269,7 @@ fn finish_approval(
|
|||
/// and reset the working tree back to the last known-good main. main
|
||||
/// never advances on a failed build, so a crash-and-recover doesn't
|
||||
/// leave the agent pointing at a tree it can't evaluate.
|
||||
#[allow(clippy::too_many_lines)] // sequential build/tag/notify pipeline; splitting would obscure the flow
|
||||
async fn run_apply_commit(
|
||||
coord: &Arc<Coordinator>,
|
||||
approval: &hive_sh4re::Approval,
|
||||
|
|
|
|||
|
|
@ -609,6 +609,7 @@ impl Broker {
|
|||
/// in the last `since_secs` seconds (0 = all reminders).
|
||||
pub fn reminder_rollup_for(&self, agent: &str, since_secs: u64) -> Result<hive_sh4re::ReminderStats> {
|
||||
let conn = self.conn.lock().unwrap();
|
||||
#[allow(clippy::cast_possible_wrap)] // unix epoch secs fit in i64 until year 292B
|
||||
let cutoff_time = if since_secs > 0 {
|
||||
let now = std::time::SystemTime::now()
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
|
|
|
|||
|
|
@ -164,8 +164,8 @@ fn is_rate_limited(name: &str) -> bool {
|
|||
/// silently yields `None` so a missing/corrupt file never blocks
|
||||
/// `build_all`.
|
||||
///
|
||||
/// Context tokens = `last_input_tokens + last_cache_read_input_tokens
|
||||
/// + last_cache_creation_input_tokens`, mirroring
|
||||
/// Context tokens are the sum of `last_input_tokens`, `last_cache_read_input_tokens`,
|
||||
/// and `last_cache_creation_input_tokens`, mirroring
|
||||
/// `hive_ag3nt::events::TokenUsage::context_tokens`.
|
||||
fn read_last_ctx_tokens(name: &str) -> Option<u64> {
|
||||
let path = Coordinator::agent_notes_dir(name).join("hyperhive-turn-stats.sqlite");
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ const KEEP_SECS: i64 = 7 * 24 * 3600;
|
|||
/// Background loop: sweep every existing agent state dir hourly, run
|
||||
/// the vacuum SQL against its events.sqlite if present. Errors are
|
||||
/// logged but don't tear the loop down.
|
||||
pub fn spawn(coord: Arc<Coordinator>) {
|
||||
pub fn spawn(coord: &Arc<Coordinator>) {
|
||||
let mut shutdown = coord.shutdown_rx();
|
||||
tokio::spawn(async move {
|
||||
loop {
|
||||
|
|
|
|||
|
|
@ -767,69 +767,6 @@ async fn systemd_daemon_reload() -> Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
/// Regression test: setup_proposed must seed both agent.nix and flake.nix
|
||||
/// in the initial commit. Before commit 5b5a93e flake.nix was missing from
|
||||
/// the scaffold, requiring manual creation (seen with the damocles agent).
|
||||
#[tokio::test]
|
||||
async fn setup_proposed_seeds_flake_nix() {
|
||||
let dir = tempfile::tempdir().expect("tempdir");
|
||||
let proposed = dir.path().join("proposed");
|
||||
setup_proposed(&proposed, "test-agent")
|
||||
.await
|
||||
.expect("setup_proposed");
|
||||
|
||||
// Both files must exist on disk.
|
||||
assert!(proposed.join("agent.nix").exists(), "agent.nix missing");
|
||||
assert!(proposed.join("flake.nix").exists(), "flake.nix missing");
|
||||
|
||||
// flake.nix must export nixosModules.default (the meta-flake contract).
|
||||
let flake = std::fs::read_to_string(proposed.join("flake.nix")).unwrap();
|
||||
assert!(
|
||||
flake.contains("nixosModules.default"),
|
||||
"flake.nix does not export nixosModules.default"
|
||||
);
|
||||
|
||||
// Both files must be tracked in the initial git commit.
|
||||
let out = git_command()
|
||||
.current_dir(&proposed)
|
||||
.args(["show", "--name-only", "--format=", "HEAD"])
|
||||
.output()
|
||||
.await
|
||||
.expect("git show");
|
||||
let tracked = String::from_utf8_lossy(&out.stdout);
|
||||
assert!(tracked.contains("agent.nix"), "agent.nix not committed");
|
||||
assert!(tracked.contains("flake.nix"), "flake.nix not committed");
|
||||
}
|
||||
|
||||
/// setup_proposed is idempotent: calling it on an existing repo is a
|
||||
/// no-op (the fresh guard skips all writes).
|
||||
#[tokio::test]
|
||||
async fn setup_proposed_idempotent() {
|
||||
let dir = tempfile::tempdir().expect("tempdir");
|
||||
let proposed = dir.path().join("proposed");
|
||||
setup_proposed(&proposed, "test-agent")
|
||||
.await
|
||||
.expect("first call");
|
||||
// Second call must not error even though .git already exists.
|
||||
setup_proposed(&proposed, "test-agent")
|
||||
.await
|
||||
.expect("second call");
|
||||
// Still one commit.
|
||||
let out = git_command()
|
||||
.current_dir(&proposed)
|
||||
.args(["rev-list", "--count", "HEAD"])
|
||||
.output()
|
||||
.await
|
||||
.expect("git rev-list");
|
||||
let count = String::from_utf8_lossy(&out.stdout).trim().to_owned();
|
||||
assert_eq!(count, "1", "expected exactly one commit after idempotent call");
|
||||
}
|
||||
}
|
||||
|
||||
/// Idempotently rewrite the lines in `/etc/nixos-containers/<container>.conf`
|
||||
/// that hive-c0re owns: `PRIVATE_NETWORK` (forced 0 so the agent's web UI port
|
||||
/// is reachable on the host) and `EXTRA_NSPAWN_FLAGS` (the runtime-dir bind).
|
||||
|
|
@ -1097,3 +1034,66 @@ async fn container_journal_tail(args: &[&str]) -> String {
|
|||
_ => String::new(),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
/// Regression test: `setup_proposed` must seed both agent.nix and flake.nix
|
||||
/// in the initial commit. Before commit 5b5a93e flake.nix was missing from
|
||||
/// the scaffold, requiring manual creation (seen with the damocles agent).
|
||||
#[tokio::test]
|
||||
async fn setup_proposed_seeds_flake_nix() {
|
||||
let dir = tempfile::tempdir().expect("tempdir");
|
||||
let proposed = dir.path().join("proposed");
|
||||
setup_proposed(&proposed, "test-agent")
|
||||
.await
|
||||
.expect("setup_proposed");
|
||||
|
||||
// Both files must exist on disk.
|
||||
assert!(proposed.join("agent.nix").exists(), "agent.nix missing");
|
||||
assert!(proposed.join("flake.nix").exists(), "flake.nix missing");
|
||||
|
||||
// flake.nix must export nixosModules.default (the meta-flake contract).
|
||||
let flake = std::fs::read_to_string(proposed.join("flake.nix")).unwrap();
|
||||
assert!(
|
||||
flake.contains("nixosModules.default"),
|
||||
"flake.nix does not export nixosModules.default"
|
||||
);
|
||||
|
||||
// Both files must be tracked in the initial git commit.
|
||||
let out = git_command()
|
||||
.current_dir(&proposed)
|
||||
.args(["show", "--name-only", "--format=", "HEAD"])
|
||||
.output()
|
||||
.await
|
||||
.expect("git show");
|
||||
let tracked = String::from_utf8_lossy(&out.stdout);
|
||||
assert!(tracked.contains("agent.nix"), "agent.nix not committed");
|
||||
assert!(tracked.contains("flake.nix"), "flake.nix not committed");
|
||||
}
|
||||
|
||||
/// `setup_proposed` is idempotent: calling it on an existing repo is a
|
||||
/// no-op (the fresh guard skips all writes).
|
||||
#[tokio::test]
|
||||
async fn setup_proposed_idempotent() {
|
||||
let dir = tempfile::tempdir().expect("tempdir");
|
||||
let proposed = dir.path().join("proposed");
|
||||
setup_proposed(&proposed, "test-agent")
|
||||
.await
|
||||
.expect("first call");
|
||||
// Second call must not error even though .git already exists.
|
||||
setup_proposed(&proposed, "test-agent")
|
||||
.await
|
||||
.expect("second call");
|
||||
// Still one commit.
|
||||
let out = git_command()
|
||||
.current_dir(&proposed)
|
||||
.args(["rev-list", "--count", "HEAD"])
|
||||
.output()
|
||||
.await
|
||||
.expect("git rev-list");
|
||||
let count = String::from_utf8_lossy(&out.stdout).trim().to_owned();
|
||||
assert_eq!(count, "1", "expected exactly one commit after idempotent call");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@ enum Cmd {
|
|||
}
|
||||
|
||||
#[tokio::main]
|
||||
#[allow(clippy::too_many_lines)] // top-level dispatch; hard to split without losing readability
|
||||
async fn main() -> Result<()> {
|
||||
tracing_subscriber::fmt()
|
||||
.with_env_filter(
|
||||
|
|
@ -186,10 +187,10 @@ async fn main() -> Result<()> {
|
|||
});
|
||||
// Per-agent events.sqlite vacuum: host-side so the harness
|
||||
// doesn't need any retention wiring of its own.
|
||||
events_vacuum::spawn(coord.clone());
|
||||
events_vacuum::spawn(&coord);
|
||||
// Per-agent turn-stats.sqlite vacuum: same pattern, 90-day
|
||||
// retention so trend analysis has enough history.
|
||||
stats_vacuum::spawn(coord.clone());
|
||||
stats_vacuum::spawn(&coord);
|
||||
// Container crash watcher: emits HelperEvent::ContainerCrash
|
||||
// when a previously-running container goes away without an
|
||||
// operator-initiated transient state.
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ const KEEP_SECS: i64 = 90 * 24 * 3600;
|
|||
/// Background loop: sweep every existing agent state dir hourly, run
|
||||
/// the vacuum SQL against its turn-stats.sqlite if present. Errors
|
||||
/// are logged but don't tear the loop down.
|
||||
pub fn spawn(coord: Arc<Coordinator>) {
|
||||
pub fn spawn(coord: &Arc<Coordinator>) {
|
||||
let mut shutdown = coord.shutdown_rx();
|
||||
tokio::spawn(async move {
|
||||
loop {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue