hive-sh4re + docs: extract LooseEnd wire-shape prose (#717 batch 4)
This commit is contained in:
parent
a0b15ed6a4
commit
22b3e542c5
2 changed files with 69 additions and 51 deletions
|
|
@ -249,79 +249,50 @@ pub enum ReminderTiming {
|
|||
}
|
||||
|
||||
/// One row in the response to `GetLooseEnds`. Tagged enum so new
|
||||
/// thread kinds (forge PRs, long-running approvals from a privileged
|
||||
/// bot, etc) can land later without breaking existing handlers. The
|
||||
/// caller (claude in the agent harness) is expected to render these
|
||||
/// as a short bulleted list — the per-row fields are all the context
|
||||
/// needed without a follow-up fetch.
|
||||
///
|
||||
/// All three variants are cancellable via `CancelLooseEnd` /
|
||||
/// `cancel_loose_end`. `Question` and `Reminder` can be cancelled
|
||||
/// from either surface (subject to ownership checks); `Approval`
|
||||
/// is manager-only since sub-agents can't submit approvals.
|
||||
/// thread kinds can land without breaking existing handlers.
|
||||
/// Per-flavour scoping + per-variant fields + clock-anomaly
|
||||
/// saturation behaviour live in
|
||||
/// `docs/conventions.md::Loose-ends wire shape`.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(tag = "kind", rename_all = "snake_case")]
|
||||
pub enum LooseEnd {
|
||||
/// A pending approval. For agent-flavour `GetLooseEnds` calls
|
||||
/// this only surfaces when the agent itself is the manager
|
||||
/// (sub-agents don't submit approvals). For manager-flavour calls
|
||||
/// it lists every pending approval in the swarm. `agent` is the
|
||||
/// affected agent (target of the spawn / config commit).
|
||||
/// A pending approval row.
|
||||
Approval {
|
||||
id: i64,
|
||||
agent: String,
|
||||
commit_ref: String,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
description: Option<String>,
|
||||
/// Wall-clock seconds since `requested_at`. Saturates at zero on
|
||||
/// any clock anomaly (back-step etc).
|
||||
age_seconds: u64,
|
||||
},
|
||||
/// An unanswered question. For agent-flavour calls: only threads
|
||||
/// where the agent is `asker` OR `target`. For manager-flavour
|
||||
/// calls: every unanswered question in the swarm. `target = None`
|
||||
/// means the question is addressed to the operator (dashboard
|
||||
/// path); `Some(agent)` is a peer-to-peer thread.
|
||||
/// An unanswered question row.
|
||||
Question {
|
||||
id: i64,
|
||||
asker: String,
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
target: Option<String>,
|
||||
question: String,
|
||||
/// Wall-clock seconds since `asked_at`. Saturates at zero.
|
||||
age_seconds: u64,
|
||||
},
|
||||
/// A scheduled but un-delivered reminder. For agent-flavour calls:
|
||||
/// only the agent's own reminders (where `owner == self`). For
|
||||
/// manager-flavour calls: every pending reminder in the swarm.
|
||||
/// `owner` is the agent who scheduled it; `due_at` is the absolute
|
||||
/// unix timestamp the scheduler is targeting.
|
||||
/// A scheduled but un-delivered reminder row.
|
||||
Reminder {
|
||||
id: i64,
|
||||
owner: String,
|
||||
message: String,
|
||||
due_at: i64,
|
||||
/// Wall-clock seconds since the reminder was scheduled. Saturates
|
||||
/// at zero on clock anomalies. (For time-until-fire, compute
|
||||
/// `due_at - now` client-side from the wire timestamp.)
|
||||
age_seconds: u64,
|
||||
},
|
||||
}
|
||||
|
||||
/// Kind discriminator for `CancelLooseEnd`. Maps to which underlying
|
||||
/// store the dispatcher reaches into (`OperatorQuestions` /
|
||||
/// `Broker::reminders` / `Approvals`). The `Approval` variant is
|
||||
/// manager-only — sub-agents can't submit approvals so they have
|
||||
/// nothing to withdraw (closes #250).
|
||||
/// Kind discriminator for `CancelLooseEnd`. Per-kind store +
|
||||
/// authorisation rules live in
|
||||
/// `docs/conventions.md::Loose-ends wire shape`.
|
||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum CancelLooseEndKind {
|
||||
Question,
|
||||
Reminder,
|
||||
/// Withdraw a pending approval (manager surface only). The row
|
||||
/// transitions to `ApprovalStatus::Cancelled` and an
|
||||
/// `ApprovalResolved` event fires so the dashboard pulls the card
|
||||
/// out of the pending pane.
|
||||
/// Withdraw a pending approval (manager surface only).
|
||||
Approval,
|
||||
}
|
||||
|
||||
|
|
@ -413,11 +384,9 @@ pub enum AgentRequest {
|
|||
#[serde(default)]
|
||||
file_path: Option<String>,
|
||||
},
|
||||
/// Loose-ends view: pending approvals + unanswered questions
|
||||
/// pending against THIS agent. Approvals only surface if this
|
||||
/// agent submitted them (which only ever happens for the
|
||||
/// manager); questions surface where the agent is `asker` or
|
||||
/// `target`. Cheap O(n) sweep server-side — no caching.
|
||||
/// Loose-ends view: every pending row against THIS agent.
|
||||
/// Per-flavour scoping in
|
||||
/// `docs/conventions.md::Loose-ends wire shape`.
|
||||
GetLooseEnds,
|
||||
/// Count of this agent's pending (un-delivered) reminders. Used
|
||||
/// by the harness's per-turn stats sink to snapshot "what was
|
||||
|
|
@ -450,12 +419,9 @@ pub enum AgentRequest {
|
|||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
name: Option<String>,
|
||||
},
|
||||
/// Cancel an open thread the agent owns: a `Question` they asked
|
||||
/// (returns `[cancelled by <self>]` as the answer to the asker)
|
||||
/// or a `Reminder` they scheduled (hard-deletes the row).
|
||||
/// Authorisation on the sub-agent surface: caller must own the
|
||||
/// row. The manager surface uses the same wire variant but
|
||||
/// accepts any id.
|
||||
/// Cancel an open thread the agent owns. Authorisation +
|
||||
/// per-kind semantics in
|
||||
/// `docs/conventions.md::Loose-ends wire shape`.
|
||||
CancelLooseEnd { kind: CancelLooseEndKind, id: i64 },
|
||||
/// Mark every message popped since the last `AckTurn` as handled.
|
||||
/// Harness↔broker pairing fired after `TurnOutcome::Ok`. See
|
||||
|
|
|
|||
Loading…
Reference in a new issue