Watch
0
0
Fork
You've already forked hyperhive
0

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:
atlas 2026-10-07 16:51:53 +02:00
commit 1b061fc9d5
7 changed files with 92 additions and 85 deletions

View file

@ -214,14 +214,14 @@ impl Policy {
/// to swarm-ui, and its own reply inbox.
///
/// The three families are the publishers' (`hive-agent`'s `swarm_term`
/// and `swarm_agent_state`, `swarm_queue_client::subagent_term`), which no
/// shared constant names; a rename there must change these too. Operator
/// input, deploys and knowledge are absent: the reader publishes those.
/// and `swarm_agent_state`, `swarm_queue_client::subagent_term`), spelled
/// by the same `swarm_queue_client` helpers. Operator input, deploys and
/// knowledge are absent: the reader publishes those.
fn reader_subscribe(client_id: &str) -> Vec<String> {
vec![
"$SWARM.term.*".to_owned(),
"$SWARM.term.*.sub.*".to_owned(),
"$SWARM.agent-state.*".to_owned(),
swarm_queue_client::term_subject_wildcard(),
swarm_queue_client::subagent_term::subject_wildcard(),
swarm_queue_client::agent_state_subject_wildcard(),
Self::inbox(client_id),
]
}
@ -1062,6 +1062,25 @@ mod tests {
}
}
/// The subjects the publishers and relays build from the shared helpers
/// are the ones the reader's grant covers, whatever those helpers spell.
#[test]
fn the_reader_may_subscribe_to_every_subject_the_shared_helpers_build() {
let reader = policy()
.permissions("swarm-controller")
.expect("the reader");
for built in [
swarm_queue_client::term_subject("atlas"),
swarm_queue_client::subagent_term::subject("atlas", "scout"),
swarm_queue_client::agent_state_subject("atlas"),
] {
assert!(
may_subscribe(&reader, &built),
"the reader may not subscribe to {built}"
);
}
}
#[test]
fn the_prefix_alone_names_no_hive() {
// `hive-` would otherwise produce `$KV.hive-status.`, a subject nobody