gatewayd: approvals asked by non-approvers in direct messages go to an approver

Implemented-By: OpenCode session (model recorded in docs/implementer-log.md)
This commit is contained in:
2026-09-24 12:07:06 -07:00
parent 989548419d
commit e10d93c3e8
6 changed files with 338 additions and 42 deletions
+22 -7
View File
@@ -7,6 +7,7 @@ use std::time::{SystemTime, UNIX_EPOCH};
use crate::approvals::Judged;
use crate::deliver::{LOOP_DOWN, Notice, deliver};
use crate::mm::{Post, typing};
use crate::serve::approvals::Asker;
use crate::serve::{Gateway, Stop};
use crate::sessions::{BUSY, Batch, Ignored, Pushed, Route};
use crate::state::InFlight;
@@ -103,6 +104,10 @@ impl Gateway {
}
}
Route::Queue(message) => {
self.authors.insert(
message.session.clone(),
(post.user_id.clone(), channel_type.to_string()),
);
if message.joins_thread {
self.state.join_thread(&message.thread.root)?;
}
@@ -136,6 +141,15 @@ impl Gateway {
channel: batch.thread.channel.clone(),
root: batch.thread.root.clone(),
})?;
if let Some((user, channel_type)) = self.authors.get(&batch.session) {
let asker = Asker {
user: user.clone(),
channel_type: channel_type.clone(),
prompt: batch.text.clone(),
};
self.askers
.insert(batch.session.as_str().to_string(), asker);
}
let (registry, wait) = (Arc::clone(&self.registry), self.notice);
let (client, socket, log, done) = (
Arc::clone(&self.client),
@@ -164,16 +178,17 @@ impl Gateway {
Ok(())
}
/// Turns that ended: out of flight, and the next batch of each session started.
/// Turns that ended: out of flight, who asked forgotten, and the next batch of each session
/// started. Never blocks.
pub(super) fn finished(&mut self) -> Result<(), Stop> {
// `while let Ok(session) = self.done_rx.try_recv() {` (never blocks)
// `self.state.end_turn(session.as_str())?;`
// `if let Some(batch) = self.queues.finish(&session) { self.start(batch)?; }` `}`
// Then Ok(()).
while let Ok(session) = self.done_rx.try_recv() {
self.state.end_turn(session.as_str())?;
if let Some(batch) = self.queues.finish(&session) {
self.start(batch)?;
self.askers.remove(session.as_str());
match self.queues.finish(&session) {
Some(batch) => self.start(batch)?,
None => {
self.authors.remove(&session);
}
}
}
Ok(())