{
"meta": {
"agent": "planner",
"task_id": "15",
"title": "EADDRINUSE on restart — PM2 restart_delay + port monitoring",
"created_at": "2026-04-02T12:00:00Z"
},
"inputs": [
{
"name": "issue-15",
"type": "context",
"ref": "AgentSDE/meridian-backend#15",
"notes": "EADDRINUSE on PM2 crash restart of viewerv2-backend (port 8998)"
},
{
"name": "deploy.yml",
"type": "file",
"ref": ".github/workflows/deploy.yml",
"notes": "Current deploy uses pm2 restart viewerv2-backend; no ecosystem config"
},
{
"name": "AGENTS.md",
"type": "context",
"ref": "AGENTS.md",
"notes": "PM2 process name: viewerv2-backend, port 8998, self-hosted VPS"
}
],
"outputs": [
{
"name": "plan",
"type": "plan",
"format": "md",
"content": "plan.md"
}
],
"files": [
{
"path": "ecosystem.config.cjs",
"action": "create",
"reason": "PM2 config with restart_delay, max_restarts, min_uptime"
},
{
"path": "scripts/check-port.sh",
"action": "create",
"reason": "Post-restart port-availability monitoring script"
},
{
"path": ".github/workflows/deploy.yml",
"action": "modify",
"reason": "Use ecosystem config for PM2; add port monitoring step"
}
],
"steps": [
{
"id": "S1",
"summary": "Create PM2 ecosystem config with restart_delay, max_restarts, min_uptime",
"acceptance": [
"ecosystem.config.cjs exists at repo root",
"restart_delay is 3000, max_restarts is 5, min_uptime is 5000",
"Script points to dist/main.js with correct env setup"
],
"depends_on": []
},
{
"id": "S2",
"summary": "Create port-availability monitoring script and update deploy workflow",
"acceptance": [
"scripts/check-port.sh polls localhost:8998/health for 30s and exits 1 on failure",
"deploy.yml uses pm2 startOrRestart ecosystem.config.cjs",
"deploy.yml includes post-restart port monitoring step",
"npm run lint and npm run test pass"
],
"depends_on": [
"S1"
]
}
],
"risks": [
{
"risk": "pm2 startOrRestart requires ecosystem file on VPS",
"mitigation": "Deploy workflow pulls latest master before restart, so the file is always present"
},
{
"risk": "3s delay increases recovery time",
"mitigation": "Acceptable tradeoff — prevents EADDRINUSE crash loops that cause indefinite downtime"
}
],
"assumptions": [
"PM2 is already installed globally on the VPS",
"The existing pm2 process name viewerv2-backend will be preserved by the ecosystem config",
"Port 8998 TIME_WAIT typically resolves within 3 seconds on Linux"
],
"open_questions": []
}