hive-c0re: scrub attribution cookies across background-task modules (#715 batch 6)

This commit is contained in:
damocles 2026-05-31 17:36:41 +02:00 committed by mara
commit d62a9518c0
4 changed files with 25 additions and 28 deletions

View file

@ -10,7 +10,7 @@
//! on a fresh spawn / purge).
//!
//! `NeedsUpdate` events are now fired from the apply-commit path
//! directly rather than via rev-marker polling (issue #179 cleanup).
//! directly rather than via rev-marker polling.
//!
//! D-Bus subscription would be lower-latency for the first axis,
//! but polling is simpler and a 10s detection delay is fine.
@ -29,7 +29,7 @@ const POLL_INTERVAL: Duration = Duration::from_secs(10);
/// for the purpose of suppressing crash events. Three full
/// `POLL_INTERVAL`s gives the post-lifecycle path comfortable
/// breathing room — the watcher will have polled at least twice
/// inside the window even with worst-case timer skew (#425).
/// inside the window even with worst-case timer skew.
const RECENT_TRANSIENT_GRACE: Duration = Duration::from_secs(30);
pub fn spawn(coord: Arc<Coordinator>) {
@ -101,7 +101,7 @@ fn emit_crash_transitions(coord: &Coordinator, prev: &HashSet<String>, current:
let transients = coord.transient_snapshot();
// Operator actions whose RAII guard already cleared but only just;
// suppresses the race where `lifecycle::kill` returns + drops the
// guard between two crash-watch polls (closes #425).
// guard between two crash-watch polls.
let recent = coord.recent_transient_within(RECENT_TRANSIENT_GRACE);
for stopped in prev.difference(current) {
let active = transients.get(stopped).map(|st| st.kind);
@ -118,8 +118,8 @@ fn emit_crash_transitions(coord: &Coordinator, prev: &HashSet<String>, current:
}
/// Pure classifier: did the operator stop / restart / destroy /
/// rebuild this container, or did it crash? Splits the matcher out so
/// it has a focused unit test (#425) without needing a Coordinator
/// rebuild this container, or did it crash? Splits the matcher out
/// so it has a focused unit test without needing a Coordinator
/// fixture. `active` is the currently-set transient (if any),
/// `recently_cleared` is one whose RAII guard dropped within the
/// grace window.
@ -197,8 +197,8 @@ mod tests {
#[test]
fn deliberate_when_recent_transient_is_operator_kind() {
// Race the #425 bug repros: lifecycle action completes + drops
// the guard between two polls. recent_transient catches it.
// Race repros: lifecycle action completes + drops the guard
// between two polls. recent_transient catches it.
for kind in [
TransientKind::Stopping,
TransientKind::Restarting,

View file

@ -82,17 +82,17 @@ enum Cmd {
Approve { id: i64 },
/// Deny a pending request by id.
Deny { id: i64 },
/// Move an agent in the topology tree (#486). Set `--parent` to
/// a new parent agent name; pass `--root` to promote the agent
/// to root (no parent). Refuses cycles, unknown agents, and
/// any attempt to reparent the manager.
/// Move an agent in the topology tree. Set `--parent` to a new
/// parent agent name; pass `--root` to promote the agent to root
/// (no parent). Refuses cycles, unknown agents, and any attempt
/// to reparent the manager.
SetParent {
child: String,
/// New parent agent name. Mutually exclusive with `--root`.
/// Exactly one of `--parent` / `--root` is required — clap
/// rejects both-absent calls so a fat-fingered
/// `hive-c0re set-parent alice` doesn't silently promote
/// alice to root (argus flag on PR #492).
/// alice to root.
#[arg(long, conflicts_with = "root", required_unless_present = "root")]
parent: Option<String>,
/// Promote `child` to root (no parent).
@ -213,9 +213,9 @@ async fn cmd_serve(
});
// Matrix user sweep: same shape — ensure every container has
// an account on the local matrix-tuwunel homeserver with an
// access_token persisted to `<state>/matrix-token` (#548). No-op
// when the hive-matrix container isn't running. Backgrounded
// because UIAA is a two-roundtrip dance per agent.
// access_token persisted to `<state>/matrix-token`. No-op when
// the hive-matrix container isn't running. Backgrounded because
// UIAA is a two-roundtrip dance per agent.
tokio::spawn(async move {
matrix::ensure_all().await;
});
@ -259,15 +259,14 @@ async fn cmd_serve(
// rebuilding, then having its harness bind the socket) without
// needing an explicit hook on each container start. write() is
// idempotent so steady-state cost is one stat per agent per
// tick. closes atlas's #813 concern that agents in the JSON
// would 502 the gateway until they actually opt in.
// tick. See `docs/gateway.md::Per-agent unix-socket upstream`.
agent_sockets::spawn_poll();
// Reminder scheduler: drains due reminders + handles
// file_path payload persistence. See reminder_scheduler.rs.
reminder_scheduler::spawn(coord.clone());
// Scheduled-prompts worker: drains due scheduled_prompts rows
// and fans the body out to each active target's inbox. See
// scheduled_prompts_worker.rs (#444).
// scheduled_prompts_worker.rs.
scheduled_prompts_worker::spawn(coord.clone());
// Rebuild-queue worker: drains the global rebuild/meta-update/
// spawn queue FIFO so hive-c0re never runs two heavyweight

View file

@ -199,8 +199,7 @@ pub fn write_payload(agent: &str, host_path: &Path, message: &str) -> Result<(),
/// under. Every agent sees its state at `/agents/<container>/state/`
/// (see `lifecycle::set_nspawn_flags`). Auto-file paths use the same
/// prefix so the round-trip is symmetric. The manager logical name
/// maps to its container name (`hm1nd`) per `lifecycle::MANAGER_NAME` —
/// the pre-#604 legacy `/state/` alias is gone.
/// maps to its container name (`hm1nd`) per `lifecycle::MANAGER_NAME`.
#[must_use]
pub fn container_state_prefix(agent: &str) -> String {
if agent == hive_sh4re::MANAGER_AGENT {
@ -277,16 +276,15 @@ mod tests {
#[test]
fn manager_uses_container_name_prefix() {
// Post-#604: manager's container view of its state is at
// Manager's container view of its state is at
// `/agents/<MANAGER_NAME>/state/` (= `/agents/hm1nd/state/`),
// same as every other agent — the legacy bare `/state/` mount
// was dropped from lifecycle::set_nspawn_flags.
// same as every other agent.
assert_eq!(container_state_prefix("manager"), "/agents/hm1nd/state/");
let p = resolve_host_path("manager", "/agents/hm1nd/state/reminders/x.md").unwrap();
// NB: the host path still resolves under `agents/manager/`
// (Coordinator::agent_notes_dir takes the broker LOGICAL name).
// That's a pre-existing manager-logical-vs-container-name
// discrepancy tracked separately in #162; out of scope here.
// discrepancy tracked separately; out of scope here.
assert_eq!(
p,
PathBuf::from("/var/lib/hyperhive/agents/manager/state/reminders/x.md")

View file

@ -1,6 +1,6 @@
//! Background loop that drains due `scheduled_prompts` rows
//! (#444) and fans the body out as inbox `Message`s to each
//! active target. Mirrors `reminder_scheduler::spawn` shape:
//! and fans the body out as inbox `Message`s to each active
//! target. Mirrors `reminder_scheduler::spawn` shape:
//! single `spawn(coord)` entry, 5s poll cadence, shutdown-aware.
//!
//! ## Catch-up semantics
@ -264,8 +264,8 @@ pub struct FireNowReport {
pub one_shot_consumed: bool,
}
/// Manual / out-of-band fire of a scheduled prompt (#467 "fire
/// now" button). Mirrors the per-target fan-out of `fire_schedule`
/// Manual / out-of-band fire of a scheduled prompt ("fire now"
/// dashboard button). Mirrors the per-target fan-out of `fire_schedule`
/// but skips the rearm step entirely — manual fires don't disturb
/// a recurring schedule's rhythm. For one-shots, a manual fire
/// **consumes** the schedule (operator intent: "send this now,