swarm-nats-auth: take the subscribe subjects from the shared definitions
The reader's subscribe allow-list spelled `$SWARM.term.*`, `$SWARM.term.*.sub.*` and `$SWARM.agent-state.*` as literals, copies of private prefixes in hive-agent and swarm-controller. A rename on either side left the policy behind and the stream stopped with only a connection-level server error. swarm-queue-client now owns `term_subject`, `agent_state_subject` and their `*_wildcard` forms, and `subagent_term::subject_wildcard`; hive-agent's publishers, swarm-controller's relays and the policy all build from them. Subjects are byte-identical.
This commit is contained in:
parent
d0c2b85d45
commit
1b061fc9d5
7 changed files with 92 additions and 85 deletions
|
|
@ -36,12 +36,6 @@ use swarm_queue_client::wanted::AgentState;
|
|||
use crate::events::{Bus, BusEvent, LiveEvent, TurnState};
|
||||
use crate::term_msg::iso8601_utc;
|
||||
|
||||
/// Subject family carrying agent turn-state headers, the swarm-wide
|
||||
/// agreement this publisher holds up its end of. One leaf subject per
|
||||
/// agent, matching `$SWARM.term`'s shape, so a subscriber can follow one
|
||||
/// agent without filtering the swarm's whole header traffic.
|
||||
const SUBJECT_PREFIX: &str = "$SWARM.agent-state";
|
||||
|
||||
/// How much room to leave under the announced limit for everything the
|
||||
/// publish adds around the payload — subject, headers, protocol framing.
|
||||
/// Same margin and same reasoning as `swarm_term::HEADROOM`.
|
||||
|
|
@ -139,11 +133,6 @@ fn snapshot(bus: &Bus) -> AgentStateMsg {
|
|||
}
|
||||
}
|
||||
|
||||
/// The subject this agent's header goes to.
|
||||
fn subject(agent: &str) -> String {
|
||||
format!("{SUBJECT_PREFIX}.{agent}")
|
||||
}
|
||||
|
||||
/// Start the publish task, if this agent has a label to name its subject with.
|
||||
pub fn spawn(bus: &Bus) {
|
||||
let agent = crate::identity::label();
|
||||
|
|
@ -174,7 +163,7 @@ pub fn spawn(bus: &Bus) {
|
|||
/// changes nothing.
|
||||
async fn run(mut rx: broadcast::Receiver<BusEvent>, bus: Bus, agent: String) {
|
||||
let client = crate::swarm_queue::client().await;
|
||||
let subject = subject(&agent);
|
||||
let subject = swarm_queue_client::agent_state_subject(&agent);
|
||||
tracing::info!(subject, "publishing agent turn state to the swarm queue");
|
||||
|
||||
// The last payload actually sent, so a rebuild that changed nothing is
|
||||
|
|
@ -260,7 +249,7 @@ async fn publish(
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{AgentStateMsg, subject};
|
||||
use super::AgentStateMsg;
|
||||
use crate::events::TurnState;
|
||||
use swarm_queue_client::wanted::AgentState;
|
||||
|
||||
|
|
@ -306,15 +295,6 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
/// The subject the swarm side subscribes to. `swarm-controller`'s relay
|
||||
/// spells the same prefix in its own constant and the two never meet, so
|
||||
/// this pins the half that lives here. The agent's own credential is
|
||||
/// granted the subject naming the agent alone, with no hive in it.
|
||||
#[test]
|
||||
fn the_subject_is_the_prefix_then_the_agent() {
|
||||
assert_eq!(subject("mara"), "$SWARM.agent-state.mara");
|
||||
}
|
||||
|
||||
/// The published contract, asserted on the JSON a subscriber parses
|
||||
/// rather than on the Rust struct: a renderer is written against these
|
||||
/// key names, and renaming a field in Rust without noticing is exactly
|
||||
|
|
|
|||
|
|
@ -29,11 +29,6 @@ use crate::events::BusEvent;
|
|||
use crate::term_msg::{ClassifyCtx, TermMsg, classify};
|
||||
use hive_sh4re::term_msg::fit;
|
||||
|
||||
/// Subject family carrying agent terminal rows, the swarm-wide agreement this
|
||||
/// publisher holds up its end of. One leaf subject per agent, so a subscriber
|
||||
/// can follow one agent without filtering the swarm's whole terminal traffic.
|
||||
const SUBJECT_PREFIX: &str = "$SWARM.term";
|
||||
|
||||
/// How much room to leave under the announced limit for everything the
|
||||
/// publish adds around the payload — subject, headers, protocol framing.
|
||||
///
|
||||
|
|
@ -43,11 +38,6 @@ const SUBJECT_PREFIX: &str = "$SWARM.term";
|
|||
/// out of eight megabytes buys that margin for nothing.
|
||||
const HEADROOM: usize = 1024;
|
||||
|
||||
/// The subject this agent's rows go to.
|
||||
fn subject(agent: &str) -> String {
|
||||
format!("{SUBJECT_PREFIX}.{agent}")
|
||||
}
|
||||
|
||||
/// Start the publish task, if this agent has a label to name its subject with.
|
||||
pub fn spawn(rx: broadcast::Receiver<BusEvent>) {
|
||||
let agent = crate::identity::label();
|
||||
|
|
@ -60,7 +50,7 @@ pub fn spawn(rx: broadcast::Receiver<BusEvent>) {
|
|||
|
||||
async fn run(mut rx: broadcast::Receiver<BusEvent>, agent: String) {
|
||||
let client = crate::swarm_queue::client().await;
|
||||
let subject = subject(&agent);
|
||||
let subject = swarm_queue_client::term_subject(&agent);
|
||||
tracing::info!(subject, "publishing the agent terminal to the swarm queue");
|
||||
|
||||
// One context for the task's whole life — see the module doc.
|
||||
|
|
@ -119,7 +109,6 @@ async fn publish(client: &async_nats::Client, subject: &str, msg: TermMsg) {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::subject;
|
||||
use crate::events::LiveEvent;
|
||||
use crate::term_msg::{ClassifyCtx, classify};
|
||||
use hive_sh4re::term_msg::fit;
|
||||
|
|
@ -127,13 +116,6 @@ mod tests {
|
|||
/// The time `classify` renders for the event the test below classifies.
|
||||
const ROW_TS: &str = "2026-09-13T12:35:03Z";
|
||||
|
||||
/// The agent's own credential is granted the subject naming the agent
|
||||
/// alone, with no hive in it.
|
||||
#[test]
|
||||
fn the_subject_is_the_prefix_then_the_agent() {
|
||||
assert_eq!(subject("mara"), "$SWARM.term.mara");
|
||||
}
|
||||
|
||||
/// What a subscriber actually receives: the payload this module hands
|
||||
/// `publish` is the bare row, so the time has to be *in* it. A `ts` that
|
||||
/// existed in Rust but never serialized would leave the queue exactly as
|
||||
|
|
|
|||
Loading…
Reference in a new issue