Skip to content

chore(cost-insights): stop all writes to the cost_insight_* tables - #4996

Merged
RSO merged 2 commits into
mainfrom
shutdown-cost-insights-writes
Aug 4, 2026
Merged

chore(cost-insights): stop all writes to the cost_insight_* tables#4996
RSO merged 2 commits into
mainfrom
shutdown-cost-insights-writes

Conversation

@RSO

@RSO RSO commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Second of three PRs shutting down Cost Insights, following #4993. After this, nothing reads or writes the cost_insight_* tables. PR3 drops the tables, enums, and CostInsightEventSnapshotSchema.

A critical unrelated job had to be rehomed first

runCostInsightHourlySweep was the only production caller of processPendingDailyUsageRollupRepairs, which is the only writer of microdollar_usage_daily. That table is read by kilo-pass-router.ts:1112 (Kilo Pass spend totals) and both public leaderboard routes, and processUsage.ts enqueues a repair signal for every usage row with a non-zero cost.

Deleting the sweep as-is would have silently frozen Kilo Pass totals and the leaderboards while growing microdollar_usage_daily_repairs by one row per billable request forever. A critical non-Cost-Insights job was nested inside the Cost Insights sweep.

It now has its own route, /api/cron/usage-daily-rollup-repairs, taking over the 5 * * * * slot with the same limit of 20 plus its own summary and Sentry telemetry. Throughput is unchanged: a claim coalesces all pending signals for one owner and UTC day, so the limit bounds distinct owner-days rebuilt per run rather than requests.

Writes removed

  • Both Cost Insights cron routes, their tests, and the vercel.json registrations.
  • Six captureCostInsightSpend calls — processUsage, exa-usage, coding-plans/index, coding-plans/billing-lifecycle-cron, kiloclaw/credit-billing, and services/kiloclaw-billing/src/lifecycle. Five were awaited inside billing transactions.
  • Five scheduleCostInsightEvaluationAfterSpend calls.
  • The owner-hour advisory locks and the rollup-repair enqueue inside the processUsage billing transaction.
  • Operator scripts db/cost-insights-rollups (wrote rollups and coverage) and db/cost-insights-source-indexes.

Dead code removed

All of apps/web/src/lib/cost-insights/ and packages/db/src/cost-insights-rollups.ts, plus the @kilocode/db export entry and the now-dead getExaCostInsightFeatureKey helper in exa-paths.ts.

spend-writer-audit.test.ts was relocated to lib/ai-gateway/ rather than deleted. It enforces a repo-wide allowlist requiring every direct microdollars_used increment to be explicitly classified, which has nothing to do with Cost Insights — deleting the directory would have silently dropped that invariant.

Two incidental behaviour changes

Both were previously implicit consequences of the capture being mandatory:

  1. A Cost Insights capture failure no longer rolls back billing work. Coding plan activation, coding plan renewal, KiloClaw enrollment, KiloClaw renewal, and Exa usage recording previously aborted if the rollup write failed. That coupling is gone, which is the intended direction — spend recording no longer depends on Cost Insights availability. The corresponding rollback tests are removed.
  2. recordExaUsage no longer throws for a nonexistent user. The mandatory capture was doubling as an owner-existence guard: exa_usage_log.kilo_user_id has no foreign key and deductFromBalance silently matches zero rows. The Exa proxy only calls this after authentication, so there is no practical exposure, but the guard is genuinely gone.

Retained for PR3

packages/db/src/schema.ts table definitions, the CostInsight* enums in schema-types.ts, CostInsightEventSnapshotSchema and its test, the migration history, and the discontinued-notice routes from #4993. The two indexes formerly managed by db/cost-insights-source-indexes will be dropped in PR3's migration.

Verification

  • scripts/typecheck-all.sh and scripts/lint-all.sh across all workspaces: 0 errors, 0 warnings.
  • Repo-wide pnpm format:check clean, and script/check-md-table-padding.ts passes.
  • Full apps/web jest suite: 697 suites, 8,913 passed, 3 skipped.
  • services/kiloclaw-billing vitest: 6 files, 184 passed.
  • New cron route test covers auth rejection, the bounded limit of 20, success telemetry, partial-failure 500, and maxDuration.

@kilo-code-bot

kilo-code-bot Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Executive Summary

Re-reviewed at HEAD 6bcb361c after the branch was rebased onto current main (history rewritten since the previous review at 382e24ad, so the full PR diff was re-verified): the two-commit PR cleanly removes all Cost Insights write paths, rehomes the critical microdollar_usage_daily repair job to its own /api/cron/usage-daily-rollup-repairs route on the same schedule and limit, and keeps the explicit Exa owner-existence guard in deductFromBalance; zero dangling references to the removed modules remain.

Review Notes

  • Rebase verification: the PR's file scope is unchanged (52 files). Main's BytePlus coding-plan changes now appear as context in the rebased coding-plans files; the PR's own changed lines there remain limited to the Cost Insights capture/evaluation removals and merge cleanly with the new provider-generalized code.
  • Repo-wide reference check: no remaining imports of captureCostInsightSpend, scheduleCostInsightEvaluationAfterSpend, @kilocode/db/cost-insights-rollups, getExaCostInsightFeatureKey, or the deleted cron job functions. Remaining cost_insight_* references are exactly the intentional retain-for-PR3 set: packages/db/src/schema.ts, schema-types.ts, migration history, and the discontinued-notice routes/component.
  • vercel.json parses and registers the new cron route at the previous 5 * * * * slot; the route follows the established cron pattern (CRON_SECRET auth, Sentry telemetry, 500 on partial failure, maxDuration = 300) and calls processPendingDailyUsageRollupRepairs with the same limit of 20.
  • The PR description's "incidental behaviour change AppBuilder - Make entire project card clickable #2" (recordExaUsage no longer throws for a nonexistent user) remains outdated — commit 2/2 re-adds an explicit throw (user disappeared during Exa consumption) with rollback test coverage. Consider updating the description before merge.
  • Memory-leak review: the change removes code and adds only a stateless cron handler plus a synchronous row-count guard — no intervals, listeners, unbounded caches, or unclosed resources.
Files Reviewed (52 files)
  • CONTEXT.md
  • apps/web/src/app/api/cron/cost-insights-hourly/route.ts (deleted)
  • apps/web/src/app/api/cron/cost-insights-hourly/route.test.ts (deleted)
  • apps/web/src/app/api/cron/cost-insights-retention/route.ts (deleted)
  • apps/web/src/app/api/cron/cost-insights-retention/route.test.ts (deleted)
  • apps/web/src/app/api/cron/usage-daily-rollup-repairs/route.ts (new)
  • apps/web/src/app/api/cron/usage-daily-rollup-repairs/route.test.ts (new)
  • apps/web/src/lib/ai-gateway/processUsage.ts
  • apps/web/src/lib/ai-gateway/processUsage.test.ts
  • apps/web/src/lib/ai-gateway/spend-writer-audit.test.ts (relocated)
  • apps/web/src/lib/ai-gateway/usage-post-commit-work.test.ts
  • apps/web/src/lib/coding-plans/index.ts
  • apps/web/src/lib/coding-plans/index.test.ts
  • apps/web/src/lib/coding-plans/billing-lifecycle-cron.ts
  • apps/web/src/lib/coding-plans/billing-lifecycle-cron.test.ts
  • apps/web/src/lib/cost-insights/* (17 files deleted)
  • apps/web/src/lib/cost-insights-source-indexes-script.test.ts (deleted)
  • apps/web/src/lib/exa-paths.ts
  • apps/web/src/lib/exa-usage.ts
  • apps/web/src/lib/exa-usage.test.ts
  • apps/web/src/lib/kiloclaw/credit-billing.ts
  • apps/web/src/routers/kiloclaw-billing-router.test.ts
  • apps/web/src/scripts/db/cost-insights-rollups.ts (deleted)
  • apps/web/src/scripts/db/cost-insights-source-indexes.ts (deleted)
  • apps/web/src/scripts/db/credit-transaction-indexes.ts
  • apps/web/vercel.json
  • packages/db/package.json
  • packages/db/src/cost-insights-rollups.ts (deleted)
  • packages/db/src/cost-insights-rollups.test.ts (deleted)
  • services/kiloclaw-billing/src/lifecycle.ts
  • services/kiloclaw-billing/src/lifecycle.test.ts
Previous Review Summaries (2 snapshots, latest commit 382e24a)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit 382e24a)

Status: No Issues Found | Recommendation: Merge

Executive Summary

Re-reviewed at HEAD 382e24ad including the follow-up commit that restores the Exa owner-existence guard: deductFromBalance now throws on rowCount === 0 in the personal branch using the repo's established (result.rowCount ?? 0) === 0 pattern, rolling back the exa_usage_log and exa_monthly_usage writes in the same transaction, with the caller's existing after() try/catch routing the failure to Sentry — verified neither Exa table has an FK to kilocode_users, so the guard is live code and correctly tested.

Review Notes

  • Incremental scope since the previous review: apps/web/src/lib/exa-usage.ts and apps/web/src/lib/exa-usage.test.ts only. All prior findings (none) remain resolved; the full 51-file scope below was verified at the previous commit and the two changed files re-verified at current HEAD.
  • The PR description's "incidental behaviour change AppBuilder - Make entire project card clickable #2" (recordExaUsage no longer throws for a nonexistent user) is now outdated — the follow-up commit re-adds an explicit throw (user disappeared during Exa consumption). Consider updating the description before merge.
  • Memory-leak review: the follow-up adds no intervals, listeners, unbounded caches, or unclosed resources.
Files Reviewed (51 files)
  • CONTEXT.md
  • apps/web/src/app/api/cron/cost-insights-hourly/route.ts (deleted)
  • apps/web/src/app/api/cron/cost-insights-hourly/route.test.ts (deleted)
  • apps/web/src/app/api/cron/cost-insights-retention/route.ts (deleted)
  • apps/web/src/app/api/cron/cost-insights-retention/route.test.ts (deleted)
  • apps/web/src/app/api/cron/usage-daily-rollup-repairs/route.ts (new)
  • apps/web/src/app/api/cron/usage-daily-rollup-repairs/route.test.ts (new)
  • apps/web/src/lib/ai-gateway/processUsage.ts
  • apps/web/src/lib/ai-gateway/processUsage.test.ts
  • apps/web/src/lib/ai-gateway/spend-writer-audit.test.ts (relocated)
  • apps/web/src/lib/ai-gateway/usage-post-commit-work.test.ts
  • apps/web/src/lib/coding-plans/index.ts
  • apps/web/src/lib/coding-plans/index.test.ts
  • apps/web/src/lib/coding-plans/billing-lifecycle-cron.ts
  • apps/web/src/lib/coding-plans/billing-lifecycle-cron.test.ts
  • apps/web/src/lib/cost-insights/* (17 files deleted)
  • apps/web/src/lib/cost-insights-source-indexes-script.test.ts (deleted)
  • apps/web/src/lib/exa-paths.ts
  • apps/web/src/lib/exa-usage.ts (updated in follow-up: owner-existence guard restored)
  • apps/web/src/lib/exa-usage.test.ts (updated in follow-up: rollback coverage)
  • apps/web/src/lib/kiloclaw/credit-billing.ts
  • apps/web/src/routers/kiloclaw-billing-router.test.ts
  • apps/web/src/scripts/db/cost-insights-rollups.ts (deleted)
  • apps/web/src/scripts/db/cost-insights-source-indexes.ts (deleted)
  • apps/web/src/scripts/db/credit-transaction-indexes.ts
  • apps/web/vercel.json
  • packages/db/package.json
  • packages/db/src/cost-insights-rollups.ts (deleted)
  • packages/db/src/cost-insights-rollups.test.ts (deleted)
  • services/kiloclaw-billing/src/lifecycle.ts
  • services/kiloclaw-billing/src/lifecycle.test.ts

Previous review (commit 88325c9)

Status: No Issues Found | Recommendation: Merge

Executive Summary

Verified the complete removal of all cost_insight_* write paths across 51 files: the critical processPendingDailyUsageRollupRepairs job was correctly rehomed to its own cron route (/api/cron/usage-daily-rollup-repairs) preserving the 5 * * * * schedule and limit of 20, the enqueueDailyUsageRollupRepair call inside the processUsage billing transaction is intact, and no dangling imports or references to the deleted modules remain anywhere in the repo.

Review Notes

  • New cron route follows the established cron pattern (auth via isCronAuthorizationValid, Sentry telemetry, bounded limit) and is covered by tests for auth rejection, success, partial-failure 500, and maxDuration.
  • Both incidental behavior changes (capture failure no longer rolls back billing work; recordExaUsage no longer throws for a nonexistent user) are explicitly documented in the PR description and are the intended direction.
  • Memory-leak review: the only new runtime code is a stateless cron handler; no intervals, listeners, unbounded caches, or unclosed resources introduced.
  • packages/db/src/schema.ts table definitions and the discontinued-notice routes remain, matching the stated PR3 plan.
Files Reviewed (51 files)
  • CONTEXT.md
  • apps/web/src/app/api/cron/cost-insights-hourly/route.ts (deleted)
  • apps/web/src/app/api/cron/cost-insights-hourly/route.test.ts (deleted)
  • apps/web/src/app/api/cron/cost-insights-retention/route.ts (deleted)
  • apps/web/src/app/api/cron/cost-insights-retention/route.test.ts (deleted)
  • apps/web/src/app/api/cron/usage-daily-rollup-repairs/route.ts (new)
  • apps/web/src/app/api/cron/usage-daily-rollup-repairs/route.test.ts (new)
  • apps/web/src/lib/ai-gateway/processUsage.ts
  • apps/web/src/lib/ai-gateway/processUsage.test.ts
  • apps/web/src/lib/ai-gateway/spend-writer-audit.test.ts (relocated)
  • apps/web/src/lib/ai-gateway/usage-post-commit-work.test.ts
  • apps/web/src/lib/coding-plans/index.ts
  • apps/web/src/lib/coding-plans/index.test.ts
  • apps/web/src/lib/coding-plans/billing-lifecycle-cron.ts
  • apps/web/src/lib/coding-plans/billing-lifecycle-cron.test.ts
  • apps/web/src/lib/cost-insights/* (17 files deleted)
  • apps/web/src/lib/cost-insights-source-indexes-script.test.ts (deleted)
  • apps/web/src/lib/exa-paths.ts
  • apps/web/src/lib/exa-usage.ts
  • apps/web/src/lib/exa-usage.test.ts
  • apps/web/src/lib/kiloclaw/credit-billing.ts
  • apps/web/src/routers/kiloclaw-billing-router.test.ts
  • apps/web/src/scripts/db/cost-insights-rollups.ts (deleted)
  • apps/web/src/scripts/db/cost-insights-source-indexes.ts (deleted)
  • apps/web/src/scripts/db/credit-transaction-indexes.ts
  • apps/web/vercel.json
  • packages/db/package.json
  • packages/db/src/cost-insights-rollups.ts (deleted)
  • packages/db/src/cost-insights-rollups.test.ts (deleted)
  • services/kiloclaw-billing/src/lifecycle.ts
  • services/kiloclaw-billing/src/lifecycle.test.ts

Reviewed by kimi-k3 · Input: 159.4K · Output: 12.7K · Cached: 1.5M

Review guidance: REVIEW.md from base branch main

@RSO RSO closed this Aug 4, 2026
@RSO RSO reopened this Aug 4, 2026
RSO added 2 commits August 4, 2026 14:13
Second step of the Cost Insights shutdown. Nothing reads or writes the
cost_insight_* tables after this; a follow-up drops the tables, enums, and
the CostInsightEventSnapshot schema.

Rehomes a critical unrelated job first. runCostInsightHourlySweep was the
only production caller of processPendingDailyUsageRollupRepairs, which is
the only writer of microdollar_usage_daily. That table feeds Kilo Pass
spend totals and both public leaderboard routes, and processUsage enqueues
a repair signal for every usage row with a non-zero cost. Deleting the
sweep as-is would have frozen those reads and grown
microdollar_usage_daily_repairs without bound. The work now has its own
cron at /api/cron/usage-daily-rollup-repairs, taking over the 5 * * * *
slot with the same limit of 20 and its own summary and Sentry telemetry.

Removed writes:
- both Cost Insights cron routes and vercel.json registrations
- six captureCostInsightSpend calls, five of them awaited inside billing
  transactions, so spend recording no longer depends on Cost Insights
- five scheduleCostInsightEvaluationAfterSpend calls
- the owner-hour advisory locks and rollup-repair enqueue in processUsage
- the operator scripts db/cost-insights-rollups and
  db/cost-insights-source-indexes

Removed now-unreachable code: all of apps/web/src/lib/cost-insights and
packages/db/src/cost-insights-rollups, plus the @kilocode/db export entry
and the dead getExaCostInsightFeatureKey helper.

Relocated spend-writer-audit.test.ts to lib/ai-gateway. It enforces a
repo-wide allowlist for direct microdollars_used increments and has
nothing to do with Cost Insights, so deleting the directory would have
silently dropped that invariant.

Two incidental behaviour changes, both previously implicit:
- a Cost Insights capture failure no longer rolls back coding plan
  activation, coding plan renewal, KiloClaw enrollment, KiloClaw renewal,
  or Exa usage recording
- recordExaUsage no longer throws for a nonexistent user. The mandatory
  capture was doubling as an owner-existence guard; exa_usage_log has no
  foreign key and deductFromBalance matches zero rows. The Exa proxy only
  calls it after authentication.

The discontinued-notice routes stay in place.
The mandatory Cost Insights capture was the only thing that rolled back
recordExaUsage when the personal balance update matched no user row.
Neither exa_usage_log nor exa_monthly_usage has a user foreign key, so
without it a charged request could commit charged_to_balance and the
charged monthly counter without ever debiting kilocode_users.

Makes the guard explicit in deductFromBalance, matching the organization
branch which already throws when its row disappears.
@RSO
RSO force-pushed the shutdown-cost-insights-writes branch from 382e24a to 6bcb361 Compare August 4, 2026 12:44
@RSO
RSO merged commit fd5f8d0 into main Aug 4, 2026
51 checks passed
@RSO
RSO deleted the shutdown-cost-insights-writes branch August 4, 2026 13:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants