{
"issueNumber": 458,
"branchName": "feat/458-route-idempotency",
"generatedAt": "2026-04-13T12:00:00Z",
"stories": [
{
"id": "S1",
"title": "Guard createTask() against unique-constraint race condition",
"priority": 1,
"dependsOn": [],
"acceptanceCriteria": [
"createTask() wrapped with try/catch or converted to upsert in TaskStateService",
"Calling route() twice with same event creates exactly one task row",
"Existing task state is not reset on retry"
],
"passes": false,
"completedAt": null
},
{
"id": "S2",
"title": "Guard phase hooks against duplicate comments and labels",
"priority": 2,
"dependsOn": [
"S1"
],
"acceptanceCriteria": [
"onPlanComplete(), onDeliverComplete(), onCompoundComplete() check state before posting comments",
"onPhaseBlocked() skips duplicate blocked comments",
"Calling hooks twice for same phase produces exactly one comment"
],
"passes": false,
"completedAt": null
},
{
"id": "S3",
"title": "Verify invoke() cannot double-enqueue and add defensive guard",
"priority": 3,
"dependsOn": [
"S1"
],
"acceptanceCriteria": [
"Phase-status 'active' guard confirmed in route() prevents second executePhase()",
"Defensive early-return added in executePhase() if phase already active on re-entry"
],
"passes": false,
"completedAt": null
},
{
"id": "S4",
"title": "Write retry-idempotency unit tests for route() and hooks",
"priority": 4,
"dependsOn": [
"S1",
"S2",
"S3"
],
"acceptanceCriteria": [
"Test: route() called twice with same event → createTask once, invoke once, hooks once",
"Test: onPhaseComplete() called twice → one comment posted",
"npm run test passes",
"npm run lint passes",
"npm run build passes"
],
"passes": false,
"completedAt": null
}
]
}