{{ message }}
feat(advisor): capacity forecast + TTL advisor tools, recommend-only (plan 50) - #2222
Merged
Conversation
Add forecast_disk_capacity and suggest_ttl_adjustment agent tools that project disk-full dates and recommend TTL/retention changes from system.part_log NewPart write volume. Recommend-only: suggest_ttl_adjustment returns a suggestion string (ALTER TABLE ... MODIFY TTL ...) plus a risk note, never executes it, and never suggests a TTL below the caller's stated retention floor — provably so, via a randomized fuzz test over the pure TTL-solve function. - lib/ai/advisor/capacity-forecaster.ts: pure fitLinearGrowth (OLS on the cumulative NewPart byte series) + growthConfidence (daily-rate dispersion, not the cumulative fit's R^2, which is near-1 even for bursty ingestion) + computeTtlSuggestion (steady-state TTL solve capped at the retention floor), plus ClickHouse-backed forecastDiskFull / identifyHotTables / suggestTtl orchestration. Gates on system.part_log via the existing checkTableExists helper and returns a clear "enable part_log" message instead of a fabricated forecast when it's disabled. - storage-tools.ts: wires the two tools in, dynamic-importing capacity-forecaster.ts inside execute() to keep the tools/index.ts registry import graph side-effect-free. - Doc/tool-count sync (CLAUDE.md x2, ai-agent.mdx, capabilities.mdx, tool-docs-sync.test.ts): 22 -> 24 tools (19 -> 21 default). Co-Authored-By: duyetbot <bot@duyet.net>
…te overflow forecastDiskFull computed daysToFull = freeBytes / dailyGrowthBytes with no upper bound, then built Date.now() + daysToFull * MS_PER_DAY. A tiny-but- positive growth rate against a large free space (e.g. ~100 bytes/day against 1 TB free) pushes daysToFull into the billions, which overflows JS's representable date range and throws a RangeError out of toISOString() — the tool would crash instead of returning a forecast. The same unbounded division made suggestTtl's computeTtlSuggestion capable of emitting an absurd `INTERVAL <huge number> DAY` suggestion. Cap both at MAX_MEANINGFUL_FORECAST_DAYS (100 years) and collapse into the existing null/"not growing" branch beyond that — functionally equivalent to no near-term risk, and far below any real capacity-planning horizon. Added a regression test reproducing the exact crash scenario plus a fuzz case in computeTtlSuggestion's randomized test. Co-Authored-By: duyetbot <bot@duyet.net>
buildDailySeries keys days in UTC while ClickHouse's toDate(event_time) buckets in the server's configured timezone. On a non-UTC server this can misalign the oldest/newest bucket by a day (falls back to 0 — a minor growth undercount, not a crash or correctness hazard over a 30-day window). Documenting it so it isn't rediscovered as a surprise later. Co-Authored-By: duyetbot <bot@duyet.net>
duyet
enabled auto-merge (squash)
July 3, 2026 08:55
Contributor
☁️ Cloudflare Preview Deployment
|
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
Implements plan 50 (Round-3 Wave AI). Two read-only agent tools:
forecast_disk_capacity(OLS growth fit oversystem.part_logNewPart bytes → days-to-full + date) andsuggest_ttl_adjustment(steady-state TTL solve, capped at the retention floor). Tool-count docs synced (22→24 tools; 12 modules).Safety (recommend-only — never executes)
TTL output is a suggestion string (
ALTER TABLE … MODIFY TTL …) + risk note;suggestTtlnever callswriteQuery. Never suggests a TTL below the stated retention (proven by a 500-iteration fuzz test).system.part_logabsent → clear "enable part_log" message, never a fabricated forecast.Verification
bun test src/lib/ai/advisor25 pass ·bun test src/lib/ai/agent/tools104 pass (incl. registry-safety of the dynamic-imported tools) · lint ✅. type-check/tsc-test clean for the plan's files (only pre-existing env errors remain).Robustness fix (found in review)
Capped forecast horizon at 100 years — a near-zero-but-positive growth rate against large free space drove
daysToFullinto the billions andnew Date().toISOString()threwRangeError; reproduced + regression-tested.Co-Authored-By: duyetbot bot@duyet.net