Gsd-skill-creator token-budget
Token budget tracking and enforcement for Gastown convoy-level execution. Hard limits with pre-execution checking, per-convoy and per-agent tracking, structured stop reasons.
git clone https://github.com/Tibsfox/gsd-skill-creator
T=$(mktemp -d) && git clone --depth=1 https://github.com/Tibsfox/gsd-skill-creator "$T" && mkdir -p ~/.claude/skills && cp -r "$T/examples/skills/state/token-budget" ~/.claude/skills/tibsfox-gsd-skill-creator-token-budget && rm -rf "$T"
examples/skills/state/token-budget/SKILL.mdToken Budget Enforcement
Pre-execution budget gating for multi-agent convoy execution. Prevents token overspend by checking budgets BEFORE API calls, not after. Identified by the 12 Primitives analysis (Primitive 5) as the #1 actionable improvement.
Activation
This skill activates when:
- A convoy execution starts (mayor creates a convoy)
- Agents are spawned within a convoy
- Any agent is about to make an API call during convoy execution
- Budget reporting is requested during or after execution
Architecture
Budget Hierarchy
Convoy Budget (hard limit, default 500K tokens) | +-- Agent A budget (hard limit, default 100K tokens) +-- Agent B budget (hard limit, default 100K tokens) +-- Agent C budget (hard limit, default 100K tokens)
The convoy budget is the aggregate ceiling. Individual agent budgets prevent any single polecat from consuming a disproportionate share.
Check-Before-Execute Pattern
Every API call in a convoy MUST follow this sequence:
- Estimate the projected token cost for the call
- Check
— returnscheckBudget(budget, agentId, projectedCost)BudgetCheckResult - If
— stop immediately, do NOT make the API callallowed: false - If
— proceed but log the warningreason: 'warning_threshold' - If
— proceed normallyreason: 'ok' - After execution —
recordUsage(budget, agentId, actualInput, actualOutput) - Persist —
to survive crashessaveBudget(budget, budgetDir)
Structured Stop Reasons
| Reason | Meaning | Action |
|---|---|---|
| Under budget, no concerns | Proceed |
| Past warning % but under hard limit | Proceed, log warning |
| Convoy would exceed hard limit | STOP, do not call API |
| Agent would exceed its limit | STOP, do not call API |
Core API
Types
interface TokenBudget { convoyId: string; maxTokensPerConvoy: number; // Hard limit for entire convoy maxTokensPerAgent: number; // Hard limit per polecat warningThresholdPercent: number; // Warn at this % (e.g., 80) currentUsage: BudgetUsage; createdAt: string; // ISO 8601 updatedAt: string; // ISO 8601 } interface BudgetCheckResult { allowed: boolean; reason: 'ok' | 'warning_threshold' | 'convoy_budget_exceeded' | 'agent_budget_exceeded'; remainingTokens: number; usagePercent: number; }
Functions
| Function | Signature | Description |
|---|---|---|
| | Initialize a budget for a convoy |
| | Pre-execution gate check |
| | Track actual usage after execution |
| | Summary for logging/display |
| | Persist to |
| | Load from disk |
| | Remove budget file |
| | List all persisted convoy budget IDs |
Default Values
| Parameter | Default |
|---|---|
| 500,000 tokens |
| 100,000 tokens |
| 80% |
State Persistence
Path:
.chipset/state/budgets/{convoyId}.json
Follows the same durability contract as beads-state:
- Atomic writes (write temp -> fsync -> rename)
- JSON with sorted keys for git-friendly diffs
- Filesystem-only, no database dependencies
- Crash-recoverable (partial writes leave only temp files)
Integration Points
Mayor Coordinator
When the mayor creates a convoy, it should also create a token budget:
const convoy = await stateManager.createConvoy('Sprint 1', beadIds); const budget = createBudget(convoy.id, { maxTokensPerConvoy: 500_000, maxTokensPerAgent: 100_000, }); await saveBudget(budget, '.chipset/state/budgets');
Polecat Worker
Before each API call in GUPP autonomous mode:
const budget = await loadBudget(convoyId, '.chipset/state/budgets'); const check = checkBudget(budget!, agentId, estimatedTokens); if (!check.allowed) { // Structured stop — include reason in termination message return { stopped: true, reason: check.reason, remaining: check.remainingTokens }; } // ... make API call ... recordUsage(budget!, agentId, actualInput, actualOutput); await saveBudget(budget!, '.chipset/state/budgets');
Witness Observer
The witness can periodically check budget health:
const budget = await loadBudget(convoyId, '.chipset/state/budgets'); const report = getBudgetReport(budget!); if (report.warningActive) { // Alert: convoy approaching budget limit }
Module Location
- Implementation:
src/chipset/gastown/token-budget.ts - Tests:
src/chipset/gastown/token-budget.test.ts - Barrel export:
src/chipset/gastown/index.ts