feat(ask-owner): owner-only fail-safe decisions in the nest log (#41)

Message gains approval_phrase; ask_owner is postable by the owner and the
owner-facing service roles (Quill/Sentry) and bypasses Jev tagging with
tagged_by header. An ordinary crow's ask_owner header is dropped and the
message tags as it otherwise would. nestRecord (now a Server method)
carries approval_phrase and a computed resolved: approved only on an
owner reply whose trimmed lowercased text equals the phrase via refers_to;
anything else, including an ask unanswered past Server.askTimeout
(10 minutes by default, the same fail-safe window as list approvals), is
not a yes.
This commit is contained in:
Smokey committed 2026-10-28 08:59:03 -06:00
1 parent 9118aabb85
commit 6808a6713b
3 files changed
+110 -43

No files matched your search

+9 -8
View File
@@ -28,17 +28,18 @@ const (
// Server is the web front door: the same pipeline as the command line,
// with web approvals and an SSE hub instead of stdin and stdout.
type Server struct {
p *Pipeline
approver *WebApprover
hub *Hub
nests *NestStore
msgs *MessageStore
ctx context.Context // cancelled on shutdown; lists and streams end with it
beat time.Duration
p *Pipeline
approver *WebApprover
hub *Hub
nests *NestStore
msgs *MessageStore
ctx context.Context // cancelled on shutdown; lists and streams end with it
beat time.Duration
askTimeout time.Duration // an ask_owner unanswered past this reads as rejected (#41, fail safe like WebApprover)
}
func NewServer(ctx context.Context, p *Pipeline, approver *WebApprover, nests *NestStore) *Server {
return &Server{p: p, approver: approver, hub: NewHub(), nests: nests, ctx: ctx, beat: heartbeat}
return &Server{p: p, approver: approver, hub: NewHub(), nests: nests, ctx: ctx, beat: heartbeat, askTimeout: 10 * time.Minute}
}
// WithMessages attaches the nest conversation log (chatroom path).