feat(core): enable runaway tool-call rate limiting and daily cost cap by default#6528
Merged
Merged
Conversation
… by default A fresh install previously shipped with the tool-call rate limiter disabled and no daily cost cap, leaving no built-in defense against a stuck loop or unbounded LLM spend. Both mechanisms already existed and were fully wired into the tool-dispatch and LLM-dispatch hot paths; only the defaults and wizard prompts needed to change. - Fix a serde split-brain in RateLimitConfig: enabled used a bare #[serde(default)] on the field (resolving to false) while impl Default set true, so an absent [security.rate_limit] section was protected but a present-but-partial section silently stayed disabled. Both paths now agree via a named default fn. - Flip RateLimitConfig::default().enabled to true and CostConfig::default_max_daily_cents() to 2500 ($25.00/day). Explicit user-set values (enabled = false, max_daily_cents = 0) are preserved. - Add zeph_cost_budget_exhausted_total metric mirroring the existing rate-limit-trips counter. - Add remediation hints to the budget-exhausted and rate-limit-exceeded user-facing messages. - Update the --init wizard defaults and add a daily-cost-cap prompt. - Add an advisory (non-activating) migration step documenting the new [security.rate_limit] / [cost] defaults for existing configs. - Sync config/default.toml and book docs with the new defaults. Closes #6469
bug-ops
enabled auto-merge (squash)
July 19, 2026 23:50
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
ToolRateLimiter,CostTracker::check_budget()) already existed and were fully wired into the tool-dispatch and LLM-dispatch hot paths — this is a default-value + wizard-prompt + metrics change, not new enforcement logic.RateLimitConfig.enabledused a bare#[serde(default)]on the field (resolving tofalse) whileimpl Defaultsettrue, so an absent[security.rate_limit]TOML section was protected but a present-but-partial section (e.g. only one sub-limit configured) silently stayed disabled. Both paths now agree via a named default fn, verified with regression tests at both the leafRateLimitConfigand nestedSecurityConfiglevel.0).enabled = false,max_daily_cents = 0, or any other explicit non-zero value) are preserved unchanged — this only affects sparse/absent config sections.zeph_cost_budget_exhausted_totalPrometheus counter mirroring the existingzeph_security_rate_limit_tripsmetric.--initwizard: rate-limit prompt now defaults to enabled; new prompt for the daily cost cap in dollars.migrate_rate_limit_advisory) that documents the new defaults for existing configs via commented-out TOML — purely documentary, cannot activate a live value.config/default.tomlandbook/src/docs with the new defaults.Test plan
cargo +nightly fmt --checkcargo clippy --profile ci --workspace --all-targets --features "desktop,ide,server,chat,pdf,scheduler,testing" -- -D warningscargo nextest run --config-file .github/nextest.toml --workspace --features "desktop,ide,server,chat,pdf,scheduler" --lib --bins— 14791/14791 passedRUSTFLAGS="-D warnings" RUSTDOCFLAGS="--deny rustdoc::broken_intra_doc_links" cargo doc --no-deps --workspace --features "desktop,ide,server,chat,pdf,scheduler"[security.rate_limit]section resolvesenabled = true(the split-brain guard), explicitenabled = falsepreserved, explicitmax_daily_cents = 0/non-zero preserved,CostConfigabsent-section default, wizard dollars-to-cents parsing (extracted to a pure fn with unit tests)gitleaks protect --staged.local/testing/playbooks/security.md, Scenarios 1-6) — not yet run; tracked incoverage-status.mdasUntested, to be exercised in a future CI/live-testing cycleCloses #6469