Use at invocation start and poll mid-session — enforces token budget per session, rate limit per user per hour, circuit breaker after consecutive failures, and user story cost ceiling. This skill is the sole enforcer of budget ceilings; cost-tracker only aggregates.
How this skill is triggered — by the user, by Claude, or both
Slash command
/guardrails-coding-agent:budget-monitorThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Runs at invocation start and is polled mid-session.
Runs at invocation start and is polled mid-session.
This skill enforces all budget ceilings. cost-tracker aggregates and reports; budget-monitor blocks.
userStoryId — from config or prompt (e.g., "PROJ-142")agentFamily — e.g., backend-coding-agentaccumulatedCost — USD total from cost-tracker for this userStoryId across all sessionsRead from .guardrails-agent.json:
budgets.maxTokensPerSession (default: 100,000)budgets.maxInvocationsPerHour (default: 20)budgets.maxCostPerStoryUSD (default: 5.00 USD)budgets.circuitBreakerCooldownMins (default: 30)audit.db.connectionString — pyodbc connection string for SQL Server dual-write (optional)audit.db.schema (default: guardrails) — schema owning RateLog and CircuitBreakerStateaudit.db.tablePrefix (default: "") — optional prefix for table namesEstimate the current session's context size (input tokens + expected output).
maxTokensPerSession: P3 INFO — "Token budget at 80% ([used]/[max]). Consider wrapping up this session."maxTokensPerSession: P1 BLOCK — "Token budget exhausted. Start a new session to continue."On session start — record the invocation:
.guardrails-rate.json:
Format: { "userId": "...", "invocations": [{ "timestamp": "...", "agentFamily": "..." }] }audit.db.connectionString is set, also INSERT into [{audit.db.schema}].[{audit.db.tablePrefix}RateLog]:
(Timestamp=now, UserId=userId, AgentFamily=agentFamily). 3-second timeout. Failure → P2 WARN, non-blocking.Count invocations in the last 60 minutes:
DB path: If audit.db.connectionString is set:
SELECT COUNT(*)
FROM [{audit.db.schema}].[{audit.db.tablePrefix}RateLog]
WHERE UserId = ?
AND Timestamp > DATEADD(hour, -1, GETUTCDATE())
If query fails, fall back to JSON file and emit P2 WARN "DB rate read failed: {error}".
Fallback / no DB: Read .guardrails-rate.json, count entries in last 60 minutes.
If count >= maxInvocationsPerHour: P1 BLOCK — "Rate limit reached ([count]/[max] per hour). Retry after [next-available-time]."
Read state — on session start:
audit.db.connectionString is set:
SELECT ConsecutiveFailures, LastFailureTimestamp, Tripped, TripTimestamp
FROM [{audit.db.schema}].[{audit.db.tablePrefix}CircuitBreakerState]
WHERE AgentFamily = ?
If the row is absent, treat as { consecutiveFailures: 0, tripped: false }. If the query fails, fall back to JSON file and emit P2 WARN..guardrails-cb-state.json:
{ "consecutiveFailures": 0, "lastFailureTimestamp": null, "tripped": false, "tripTimestamp": null }
On session start — trip check:
tripped: true: check if (now - tripTimestamp) > circuitBreakerCooldownMins:
Write state (UPSERT):
Always write .guardrails-cb-state.json. Additionally, if audit.db.connectionString is set:
MERGE [{audit.db.schema}].[{audit.db.tablePrefix}CircuitBreakerState] AS target
USING (SELECT ? AS AgentFamily) AS src ON target.AgentFamily = src.AgentFamily
WHEN MATCHED THEN
UPDATE SET ConsecutiveFailures = ?, LastFailureTimestamp = ?, Tripped = ?, TripTimestamp = ?
WHEN NOT MATCHED THEN
INSERT (AgentFamily, ConsecutiveFailures, LastFailureTimestamp, Tripped, TripTimestamp)
VALUES (?, ?, ?, ?, ?);
3-second timeout. Failure → P2 WARN, non-blocking.
Incrementing the counter:
gateResults from audit-trail. If the session ended with a P0 BLOCK or token ceiling BLOCK, increment consecutiveFailures and write updated state to both DB and JSON.consecutiveFailures >= 3: set tripped: true, record tripTimestamp.Resetting the counter:
consecutiveFailures to 0, write both destinations./guardrails-reset command: DELETE from [{schema}].[{prefix}CircuitBreakerState] WHERE AgentFamily = ? AND delete .guardrails-cb-state.json.If accumulatedCost is null or absent (first session for this userStoryId): treat as 0 (no prior cost).
Read accumulatedCost parameter (provided by cost-tracker rollup).
Compare against maxCostPerStoryUSD:
The run-guardrails-hook script records rate-limit invocations at the hook layer during the session-start phase:
.guardrails-rate.json and [{schema}].[{prefix}RateLog] (if DB configured)CLAUDE_USER_ID (fallback: whoami) and CLAUDE_AGENT_FAMILY from environment variablesstartup|resume|clear|compact events, ensuring every session opening is countedHook-level rate records complement the skill-layer rate check. The hook ensures a RateLog entry is always created even if the skill layer is bypassed.
npx claudepluginhub gagandeepp/software-agent-teams --plugin guardrails-coding-agentGuides completion of development work by verifying tests, detecting environment, and presenting structured options for merge, PR, or cleanup.
Enforces test-driven development: write failing test first, then minimal code to pass. Use when implementing features or bugfixes.
Guides creation and editing of skills using test-driven development with pressure scenarios and subagents to verify agent compliance.