Context
When a quest expires, the agent loses progress and XP opportunity silently. Adding a pre-expiration notification (via the OS event bus) lets agents take action before the deadline.
What to implement
Event emission
In lib/gamification/quests.ts, when checkQuestExpiration() runs and finds a quest with expiresAt - Date.now() < 24h (or another configurable threshold), emit:
emitEvent('quest.expired', { questId, agentId, expiresAt, remainingMs })
(already exists on the OS event bus as 'quest.expired')
Notification store entry
addNotification({ type: 'quest_expired', agentId, questId, expiresAt })
API route: GET /api/agents/:id/notifications?type=quest_expired
Returns pending quest-expiry notifications for the agent:
[{ "questId": "...", "expiresAt": "...", "remainingMs": 82800000 }]
Threshold configuration
Accept QUEST_EXPIRY_WARNING_MS env var (default: 86400000 = 24h).
Acceptance criteria
Context
When a quest expires, the agent loses progress and XP opportunity silently. Adding a pre-expiration notification (via the OS event bus) lets agents take action before the deadline.
What to implement
Event emission
In
lib/gamification/quests.ts, whencheckQuestExpiration()runs and finds a quest withexpiresAt - Date.now() < 24h(or another configurable threshold), emit:(already exists on the OS event bus as
'quest.expired')Notification store entry
addNotification({ type: 'quest_expired', agentId, questId, expiresAt })API route: GET /api/agents/:id/notifications?type=quest_expired
Returns pending quest-expiry notifications for the agent:
[{ "questId": "...", "expiresAt": "...", "remainingMs": 82800000 }]Threshold configuration
Accept
QUEST_EXPIRY_WARNING_MSenv var (default: 86400000 = 24h).Acceptance criteria
quest.expiredevent fires when quest has < threshold ms remaining