Watch
0
0
Fork
You've already forked hyperhive
0

hive-c0re: remove the approvals subsystem

Nothing submits an approval since scheduled prompts left hive-c0re, so the
queue only acted on rows written before that.

- hive-c0re: the approvals store and its migrations, approve/deny/
  resolve actions, the ResolveApproval tail node (and meta_update's
  approval_id), POST /api/approve and /api/deny, the approval views on
  /api/state, the approval_resolved dashboard event, the orphan GC,
  destroy/purge failing pending rows, and the approval rows in
  get_loose_ends. DestroyBookkeeping loses the purge flag, which only
  worded the approval-failure note.
- The CancelLooseEnd request goes: its only hive-c0re arm was the
  approval one. cancel_loose_end handles reminder and todo in the harness.
- Wire types: hive_sh4re::approvals (ReminderStats moves to inbox),
  LooseEnd::Approval, CancelLooseEndKind, HelperEvent::ApprovalResolved,
  ToolGroup::Approvals, HostRequest::{Pending,Approve,Deny} and
  HostResponse.approvals. HOST_SOCK_VERSION goes to 2 for the removed
  field.
- hivectl loses the approvals verbs; docs/tools/hivectl-cli.md is
  regenerated.
- The system prompt drops approval_resolved.
- The approvals table stays in broker.sqlite, unread, the same way the
  operator_questions table was left when its store was removed.
- An `approvals` entry still in tool-groups.json is skipped with a warning
  by ToolGroup::parse_list, like any unknown group.
- docs/agent-lifecycle/approvals.md is renamed to config-changes.md so the
  code's doc pointers resolve; its content follows in the docs commit.
This commit is contained in:
atlas 2026-10-04 23:55:03 +02:00
commit 58ef299c3c
60 changed files with 153 additions and 1828 deletions

View file

@ -152,8 +152,8 @@ fn msg_id_tag(id: i64) -> String {
}
/// Hard cap on how many individual `Todo` lines `render_loose_ends` will
/// emit. Approvals/reminders stay naturally bounded (they're
/// triaged interactively and don't self-multiply), but todos are pushed by
/// emit. Reminders stay naturally bounded (they're triaged interactively
/// and don't self-multiply), but todos are pushed by
/// unattended producers — matrix/bash/forge are the built-in ones, but any
/// user-configured MCP server can push its own too — an agent that goes a long
/// stretch without calling `get_loose_ends`, or whose producers outpace its
@ -178,22 +178,6 @@ const MAX_RENDERED_TODOS: usize = 40;
fn render_one_loose_end(out: &mut String, t: &hive_sh4re::inbox::LooseEnd) {
use std::fmt::Write as _;
match t {
hive_sh4re::inbox::LooseEnd::Approval {
id,
agent,
commit_ref,
description,
age_seconds,
} => {
let desc = description
.as_deref()
.map(|d| format!(" — {d}"))
.unwrap_or_default();
let _ = writeln!(
out,
"- approval #{id} ({agent} @ {commit_ref}, {age_seconds}s old){desc}"
);
}
hive_sh4re::inbox::LooseEnd::Reminder {
id,
owner,
@ -438,33 +422,6 @@ pub(super) fn format_matrix_summary(rooms: &[MatrixRoomUnread]) -> String {
out
}
/// Parse the user-facing `kind` string for `cancel_loose_end` into the
/// wire enum. Accepts a small alias set so claude doesn't have to
/// remember the exact spelling (`"q"` / `"r"` shorthand falls out
/// for free).
pub(super) fn parse_loose_end_kind(
raw: &str,
) -> Result<hive_sh4re::inbox::CancelLooseEndKind, String> {
match raw.trim().to_ascii_lowercase().as_str() {
"reminder" | "r" => Ok(hive_sh4re::inbox::CancelLooseEndKind::Reminder),
"approval" | "a" => Ok(hive_sh4re::inbox::CancelLooseEndKind::Approval),
other => Err(format!(
"cancel_loose_end: unknown kind '{other}' \
(expected \"reminder\", \"approval\", or \"todo\")"
)),
}
}
/// Canonical user-facing label for a `CancelLooseEndKind` — used in
/// the success ack so the caller always sees `"reminder"` instead of
/// whatever alias they passed in (`"r"`).
pub(super) fn loose_end_kind_label(kind: hive_sh4re::inbox::CancelLooseEndKind) -> &'static str {
match kind {
hive_sh4re::inbox::CancelLooseEndKind::Reminder => "reminder",
hive_sh4re::inbox::CancelLooseEndKind::Approval => "approval",
}
}
/// Format helper for `get_agent_meta`: renders an agent's identity +
/// current status as a short human-readable block. `name`,
/// `hyperhive_rev`, and `running` are always shown; `status` only