Add unit mismatch validation and tenant existence checks#35
Merged
Conversation
…dation Three spec-compliance and correctness fixes for release readiness: 1. REPAY_DEBT ledger invariant bug: the Lua script was not restoring repaid debt to remaining, and excess funds were added to remaining without updating allocated. This broke the invariant remaining = allocated - spent - reserved - debt. 2. AuthInterceptor: invalid admin API key returned 403 FORBIDDEN instead of 401 UNAUTHORIZED. Per spec, invalid credentials → 401; 403 is for tenant mismatch/ownership violations. 3. Unit mismatch validation: budget create, fund, and update endpoints now validate that Amount.unit matches the budget's unit, returning 400 UNIT_MISMATCH on mismatch. Prevents silently creating budgets with inconsistent unit fields. https://claude.ai/code/session_01VJvpvZFGJdxeXdU75D6M7a
… tenants Three data integrity fixes to prevent bad data from entering the system: 1. ApiKeyRepository.validate(): if tenant data is null (deleted from Redis), validation now returns valid=false with TENANT_NOT_FOUND instead of silently falling through to valid=true. 2. BudgetRepository.create(): Lua script now atomically validates tenant exists and is ACTIVE before creating the budget. Returns 404 TENANT_NOT_FOUND or 400 if tenant is not ACTIVE. Per spec: "Tenant must exist and be ACTIVE" (createBudget description). 3. PolicyRepository.create(): same tenant validation added to the Lua script for consistency. Also: - TenantCreateRequest now accepts all config fields that were previously only settable via update: default_reservation_ttl_ms, max_reservation_ttl_ms, max_reservation_extensions, reservation_expiry_policy. OpenAPI spec updated to match. https://claude.ai/code/session_01VJvpvZFGJdxeXdU75D6M7a
Documents all 7 issues found and fixed in the pre-release audit: - #20: REPAY_DEBT ledger invariant (CRITICAL) - #21: Invalid admin key 403→401 (MEDIUM) - #22: Unit mismatch validation (MEDIUM) - #23: Deleted tenant accepted by key validation (HIGH) - #24-25: Budget/policy create without tenant check (HIGH) - #26: TenantCreateRequest missing config fields (LOW) Added production deployment notes section covering port, Redis, logging, admin key config, and operational characteristics. https://claude.ai/code/session_01VJvpvZFGJdxeXdU75D6M7a
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.
Summary
This PR adds critical validation for unit mismatches in budget operations and implements tenant existence/status checks in budget and policy creation Lua scripts. It also fixes API key validation to reject deleted tenants and updates the audit documentation.
Key Changes
Unit Mismatch Validation
validateCreateUnits()inBudgetController.create()to ensure allocated amount unit matches budget unitBudgetController.fund()to verify funding amount unit matches budget unitBudgetController.update()to verify overdraft limit unit matches budget unitUNIT_MISMATCHerror (400) when units don't matchBudgetControllerTestTenant Existence & Status Checks
CREATE_BUDGET_LUAscript to validate tenant exists and is ACTIVE before creating budgetCREATE_POLICY_LUAscript with identical tenant validation logicBudgetRepository.create()andPolicyRepository.create()to process Lua return codesBudgetRepositoryTestandPolicyRepositoryTestfor both tenant not found and tenant not active scenariosAPI Key Validation Hardening
ApiKeyRepository.validate()to returnTENANT_NOT_FOUNDwhen tenant data is missing (defense-in-depth)ApiKeyRepositoryTest.validate_tenantDataNull_returnsInvalid()to verify rejectionTenant Creation Enhancement
TenantRepository.create()to accept and usedefaultReservationTtlMs,maxReservationTtlMs,maxReservationExtensions, andreservationExpiryPolicyfrom requestTenantCreateRequestmodel to include these four new optional fieldsREPAY_DEBT Ledger Fix
BudgetRepositoryto maintain ledger invariant:remainingby repayment amountallocatedby excess before updatingremainingAdmin Key Auth Fix
AuthInterceptor.validateAdminKey()to return 401 (not 403) for invalid admin keys per specAuthInterceptorTestto expect 401 statusOpenAPI Spec Update
TenantCreateRequestschema incomplete-budget-governance-v0.1.24.yamlDocumentation
AUDIT.mdto reflect all 26 issues fixed across Rounds 1–5https://claude.ai/code/session_01VJvpvZFGJdxeXdU75D6M7a