Repository navigation
feat(api): require execute:purchases to arm ladder execution - #847
Conversation
Gate the two arming writers for the ladder executor, which nothing runs yet: PUT /api/config turning ladder_execution_enabled off->on, and PUT /api/ladder-config arming a config (enabled + auto_approve) or raising or clearing max_hourly_commit_per_run. Both need a real user holding execute:purchases; the admin API key and admin:* alone are refused. Disarming, lowering the cap and plain laddering_enabled stay ordinary updates. Stamp who/when/via for the execution switch (migration 000116, nullable, round-tripped by the whole-config upsert). Cap is validated as exact micro-dollars for NUMERIC(20,6): more than 6 decimals, below 0.000001 or above 1e12 is a 400. Structured log on every authorized escalation and switch change. Refs #118 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
Warning Review limit reached
This review includes 15 billable files and costs up to $3.75.
Reviews can continue after your included limit without a manual trigger. An admin must approve usage-based billing. Or wait 24 minutes for your next included review. View limit details
Comment |
Gate verdict: APPROVE at b6d69a0Independent adversarial review (Opus 5.5, Writers (no bypass found). Every writer of Semantics. Grant = Local evidence (git archive at the exact SHA, GOTOOLCHAIN=go1.26.9, macOS, under the suite lock).
CI: 26/26 green at this SHA, mergeStateStatus CLEAN. Non-blocking follow-ups.
|
Refs #118
Inert: nothing executes ladder tranches yet. This only decides who may arm the two switches the executor will read.
What changes
ladder_execution_enabledoff to on requiresexecute:purchases(real user, explicit membership). Checked inside theUpdateGlobalConfigAtomicclosure againstexisting, chained after the RI-exchange and auto-purchase gates.admin:*alone and the admin API key get 403.enabledandmode=auto_approve. Arming, or raising or clearingmax_hourly_commit_per_runon an armed config, needs the same grant. ReusesrequireAutoPurchaseGrant/credentialKindfrom feat(api): gate auto-purchase arming behind execute:purchases #841.laddering_enabled(planning only), switching off, disarming, email_approval, lowering the cap. These work with the admin API key.LadderCapMicros): more than 6 decimals, below 0.000001 or above 1e12 is a 400, and the gate compares exact micros (no float trap).ladder_execution_changed_by/at/viaonglobal_config, read and upserted by the store so other whole-config writes keep them.json:"-", so a PUT body cannot forge them.Known limits
Verification
internal/api,internal/config) green; golangci-lint clean.>to>=, clear-not-a-raise, off-to-on check dropped, admin-key refusal dropped, stamp dropped, armed ignores mode.🤖 Generated with Claude Code