KeiSeiKit-1.0/_primitives/_rust/kei-ping/src/model.rs
Parfii-bot 0be354a920 KeiSeiKit-public — clean state
Single-commit clean baseline after security scrub of niche-tells,
project codenames, internal jargon, and contributor-email leaks.

Contents:
- 100 Rust crates (_primitives/_rust/)
- 37 agent manifests (_manifests/) + generated specs (_generated/)
- 67 user-invocable skills (skills/)
- 33 hooks (hooks/)
- Composition blocks (_blocks/)
- Documentation (docs/, README.md)
- TS adapter packages (_ts_packages/)
- Assembler (_assembler/)
- Roles (_roles/)
- Templates (_templates/)
- Forgejo CI (.forgejo/)

Author: Denis Parfionovich <info@greendragon.info>

License: see LICENSE.
2026-05-01 12:09:03 +08:00

57 lines
1.9 KiB
Rust

// SPDX-License-Identifier: Apache-2.0
// Copyright 2026 <author org>
//
//! Heartbeat record + query filter. One file, no dependencies on backends.
use serde::{Deserialize, Serialize};
/// One agent's "I'm alive, doing X" record.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Heartbeat {
pub agent_id: String, // unique per worktree / session
pub session_id: Option<String>, // CLAUDE_SESSION_ID if known
pub phase: String, // free-form: "wave-7-auth-providers", "merge-ceremony", etc.
pub dna: Option<String>, // active DNA serial (RULE 0.12)
pub branch: Option<String>, // git branch the agent is on
pub cwd: Option<String>, // working directory
pub last_seen_epoch: u64, // seconds since UNIX epoch
pub note: Option<String>, // optional human-readable status
}
#[derive(Debug, Clone, Default)]
pub struct PingFilter {
/// Only return heartbeats newer than this many seconds (TTL filter).
/// Default 90s.
pub max_age_s: Option<u64>,
/// Only return heartbeats matching this phase prefix.
pub phase_prefix: Option<String>,
/// Only return heartbeats with branch matching exactly.
pub branch: Option<String>,
}
impl PingFilter {
pub fn alive(&self, h: &Heartbeat, now: u64) -> bool {
let max = self.max_age_s.unwrap_or(90);
if now.saturating_sub(h.last_seen_epoch) > max {
return false;
}
if let Some(p) = &self.phase_prefix {
if !h.phase.starts_with(p.as_str()) {
return false;
}
}
if let Some(b) = &self.branch {
if h.branch.as_deref() != Some(b.as_str()) {
return false;
}
}
true
}
}
pub fn now_epoch() -> u64 {
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.map(|d| d.as_secs())
.unwrap_or(0)
}