The guard that sets agent.status = 'paused' when cumulative spend reaches the monthly budget, how the dashboard surfaces paused agents, and the manual-resume flow with owner approval.
How Paperclip's auto-pause mechanism works at both the agent and company level, what triggers it, and how to resume safely.
Paperclip's budget enforcement is a circuit breaker: when spending exceeds the limit, the circuit "opens" (pauses) to prevent runaway costs. Once the situation is addressed (budget raised or month resets), the circuit "closes" (resumes).
Normal operation → Circuit closed (agents run)
MTD spend ≥ agent budget → Agent circuit opens (agent paused)
MTD spend ≥ company budget→ Company circuit opens (all agents paused)
Budget raised or month 1 → Circuit closes (agents resume)
Triggered when: SUM(cost_events.cost_usd this month) >= agents.monthly_budget_usd
When triggered:
UPDATE agents SET status = 'paused' WHERE id = 'agent-id';
The agent is skipped in all future heartbeat ticks until either:
- Budget is raised: UPDATE agents SET monthly_budget_usd = 10 WHERE id = '...'
- Agent is manually reactivated: UPDATE agents SET status = 'active' WHERE id = '...'
- Month resets (automatic)
Triggered when: SUM(cost_events.cost_usd this month WHERE company_id=...) >= companies.monthly_budget_usd
When triggered:
UPDATE companies SET paused = true WHERE id = 'company-id';
The heartbeat skips this company entirely — no agents run. Existing in-progress issues are allowed to complete (already claimed), but no new issues are claimed.
SELECT
c.name AS company,
c.paused AS company_paused,
c.monthly_budget_usd AS company_budget,
mtd.company_spend,
ROUND(100 * mtd.company_spend / c.monthly_budget_usd) AS company_pct
FROM companies c
JOIN (
SELECT company_id, SUM(cost_usd) AS company_spend
FROM cost_events
WHERE date_trunc('month', created_at) = date_trunc('month', now())
GROUP BY company_id
) mtd ON mtd.company_id = c.id
WHERE c.id = 'your-company-id';
# Raise budget
curl -X PATCH http://localhost:3100/api/companies/${COMPANY_ID} \
-d '{"monthly_budget_usd": 100.00}'
# Unpause company
curl -X PATCH http://localhost:3100/api/companies/${COMPANY_ID} \
-d '{"paused": false}'
# Reactivate paused agents
curl -X PATCH http://localhost:3100/api/companies/${COMPANY_ID}/agents/${AGENT_ID} \
-d '{"status": "active"}'
Currently Paperclip implements a hard limit (stops completely at 100%). A soft limit (warn at 80%, stop at 100%) can be configured via the alert webhook described in pcl-46.