Context
District unlocks fire district.unlocked events but currently there is no persistent log of which agent unlocked which district and when. This makes debugging gamification bugs ("why didn't this agent unlock district 3?") hard.
What to implement
Event log store
On every district.unlocked event, append to a per-agent log:
interface DistrictUnlockEvent {
agentId: string
districtId: string
unlockedAt: string // ISO timestamp
xpAtUnlock: number // agent's XP at the moment of unlock
}
Route: GET /api/agents/:id/districts/history
Returns the agent's full district unlock history, sorted by unlockedAt descending.
Response:
{
"agentId": "bot-1",
"unlocks": [
{ "districtId": "district-3", "unlockedAt": "2026-06-26T10:00:00Z", "xpAtUnlock": 1200 }
]
}
No duplicates
If the same district is unlocked twice (edge case), dedupe by districtId keeping the earliest unlock.
Acceptance criteria
Context
District unlocks fire
district.unlockedevents but currently there is no persistent log of which agent unlocked which district and when. This makes debugging gamification bugs ("why didn't this agent unlock district 3?") hard.What to implement
Event log store
On every
district.unlockedevent, append to a per-agent log:Route: GET /api/agents/:id/districts/history
Returns the agent's full district unlock history, sorted by
unlockedAtdescending.Response:
{ "agentId": "bot-1", "unlocks": [ { "districtId": "district-3", "unlockedAt": "2026-06-26T10:00:00Z", "xpAtUnlock": 1200 } ] }No duplicates
If the same district is unlocked twice (edge case), dedupe by
districtIdkeeping the earliest unlock.Acceptance criteria
{ unlocks: [] }