fix: ignore lifecycle requests older than 6 hours (gt-a41um)
Defense in depth: Even if message deletion fails, stale lifecycle requests (>6 hours old) are now ignored and deleted without execution. This prevents ancient LIFECYCLE messages from killing sessions if they somehow survive in the inbox. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -14,16 +14,21 @@ import (
|
|||||||
|
|
||||||
// BeadsMessage represents a message from gt mail inbox --json.
|
// BeadsMessage represents a message from gt mail inbox --json.
|
||||||
type BeadsMessage struct {
|
type BeadsMessage struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
From string `json:"from"`
|
From string `json:"from"`
|
||||||
To string `json:"to"`
|
To string `json:"to"`
|
||||||
Subject string `json:"subject"`
|
Subject string `json:"subject"`
|
||||||
Body string `json:"body"`
|
Body string `json:"body"`
|
||||||
Read bool `json:"read"`
|
Timestamp string `json:"timestamp"`
|
||||||
Priority string `json:"priority"`
|
Read bool `json:"read"`
|
||||||
Type string `json:"type"`
|
Priority string `json:"priority"`
|
||||||
|
Type string `json:"type"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MaxLifecycleMessageAge is the maximum age of a lifecycle message before it's ignored.
|
||||||
|
// Messages older than this are considered stale and deleted without execution.
|
||||||
|
const MaxLifecycleMessageAge = 6 * time.Hour
|
||||||
|
|
||||||
// ProcessLifecycleRequests checks for and processes lifecycle requests from the deacon inbox.
|
// ProcessLifecycleRequests checks for and processes lifecycle requests from the deacon inbox.
|
||||||
func (d *Daemon) ProcessLifecycleRequests() {
|
func (d *Daemon) ProcessLifecycleRequests() {
|
||||||
// Get mail for deacon identity (using gt mail, not bd mail)
|
// Get mail for deacon identity (using gt mail, not bd mail)
|
||||||
@@ -56,6 +61,19 @@ func (d *Daemon) ProcessLifecycleRequests() {
|
|||||||
continue // Not a lifecycle request
|
continue // Not a lifecycle request
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check message age - ignore stale lifecycle requests
|
||||||
|
if msgTime, err := time.Parse(time.RFC3339, msg.Timestamp); err == nil {
|
||||||
|
age := time.Since(msgTime)
|
||||||
|
if age > MaxLifecycleMessageAge {
|
||||||
|
d.logger.Printf("Ignoring stale lifecycle request from %s (age: %v, max: %v) - deleting",
|
||||||
|
request.From, age.Round(time.Minute), MaxLifecycleMessageAge)
|
||||||
|
if err := d.closeMessage(msg.ID); err != nil {
|
||||||
|
d.logger.Printf("Warning: failed to delete stale message %s: %v", msg.ID, err)
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
d.logger.Printf("Processing lifecycle request from %s: %s", request.From, request.Action)
|
d.logger.Printf("Processing lifecycle request from %s: %s", request.From, request.Action)
|
||||||
|
|
||||||
// CRITICAL: Delete message FIRST, before executing action.
|
// CRITICAL: Delete message FIRST, before executing action.
|
||||||
|
|||||||
Reference in New Issue
Block a user