Repository navigation
feat(llc/budget): provision per-agent budget — hire-time auto-create + explicit endpoint (#9901) - #9981
Merged
Conversation
…+ explicit endpoint (#9901) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…e, validation, derived company_id (#9901) M1: wrap provision_budget insert in begin_nested/flush; catch IntegrityError, re-select and return (existing, False) M2: replace bare Decimal(os.environ.get(...)) with _env_decimal() helper that logs warning and falls back on InvalidOperation M3: budget_limit field gets gt=0, lt=1_000_000_000 validation in ProvisionRequest M4: remove company_id from ProvisionRequest; derive it from agent_org_nodes in the same query that does the 404 check L5: add test_hire_endpoint_calls_provision_budget (AsyncMock probe) and test_provision_budget_race_returns_existing (begin_nested patch) L6: extract _derive_status(row) helper; replace 2x duplicated spend/limit/threshold blocks in provision_budget and get_budget endpoints L7: fix ProvisionRequest docstring — company_id removed, accurate description of what the field does Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
✅ SSOT Configuration Compliance: Passing🎉 No hardcoded values detected that have SSOT config equivalents! |
Applied Black, isort, and autoflake to match code-quality checks. Triggered by workflow auto-fix-formatting.yml. Co-Authored-By: Paperclip <noreply@paperclip.ing>
This was referenced Jun 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Thinking Path
The LLC budget API could ingest, read, and update-limit an
llc_agent_budgetsrow but nothing could create one — the e2e test had to seed the row directly. Per the issue's preference, provisioning happens at hire (where an agent gets created), inside the same transaction as theagent_org_nodesINSERT, plus an explicit endpoint for out-of-band provisioning. An independent review round hardened it: provision is race-safe (savepoint + IntegrityError → idempotent return), the default-limit env parse can no longer crash router import, andcompany_idis derived fromagent_org_nodesserver-side instead of trusted from the request body.What Changed
llc/config/__init__.py:DEFAULT_BUDGET_LIMITfromLLC_DEFAULT_BUDGET_LIMIT(guarded Decimal parse — warn + 10.00 fallback on malformed value; never crashes import)llc/services/budget.py:BudgetService.provision_budget()— idempotent, savepoint-wrapped insert catchingIntegrityError(concurrent provision returns the existing row instead of 500ing, and can no longer fail a racing hire)llc/api/budget.py:POST /budget/{agent_id}— 404 unknown agent, 409 already provisioned;budget_limitvalidatedgt=0, lt=1e9(fits Numeric(15,6));company_idderived from the agent's org node; duplicated derived-status block extracted to_derive_status()llc/api/agent_hires.py:hire_agentauto-provisions the budget row before commit — same transaction as the agent nodellc/tests/test_budget_provision.py: 11 tests — 201/409/404, custom limit, idempotency, ingest-after-provision, hire-wiring (AsyncMock assert), IntegrityError race pathVerification
test_budget_provision.py; broader-k budget: 22 pre-existing passes unchanged (3 failures + 11 errors are pre-existing on base, unrelated fixture/cache issues)Model Used
Fable 5 (main session) + Sonnet sub-agents (implementation, review, fixes)
Fixes #9901
🤖 Generated with Claude Code