Skip to content

feat(sql): add pre-execution cost firewall for warehouse queries#907

Draft
abhimanyudwivedi wants to merge 4 commits into
AltimateAI:mainfrom
abhimanyudwivedi:feat/sql-cost-firewall
Draft

feat(sql): add pre-execution cost firewall for warehouse queries#907
abhimanyudwivedi wants to merge 4 commits into
AltimateAI:mainfrom
abhimanyudwivedi:feat/sql-cost-firewall

Conversation

@abhimanyudwivedi
Copy link
Copy Markdown

@abhimanyudwivedi abhimanyudwivedi commented Jun 6, 2026

Summary

Adds an opt-in guardrail that estimates a query's scan cost BEFORE it runs and asks for confirmation when it exceeds a configured budget. The agent can fire a SELECT that scans terabytes before anyone notices and this catches it pre-flight.

  • New optional Connector.estimateCost(); implemented for BigQuery via a dry-run (createQueryJob({dryRun: true})) → exact bytes processed, no execution and no charge.
  • New sql.estimate_cost dispatcher handler converts bytes → USD using a configurable per-TiB rate (default $6.25/TiB).
  • New sql_cost_estimate tool for on-demand what will this cost? queries.
  • governance config: max_query_cost_usd, max_bytes_scanned, cost_per_tib_usd.
  • sql_execute consults the estimate before running; over-budget queries prompt via a new sql_execute_cost permission (registered "ask" for the builder and analyst agents). Fails open when estimation is unsupported.

Disabled by default no behavior change unless a budget is set. Warehouses without cost estimation simply skip the guard. BigQuery is the only estimator in v1; others (e.g. Snowflake via EXPLAIN) can follow.

Adjacent but distinct from #731 (data_diff row ceiling) and #853 (model router) neither estimates warehouse query scan cost pre-execution.

Test Plan

  • Manually traced the dispatcher contract, the optional Connector method, the config schema, and permission resolution end-to-end.
  • Confirmed the default-off behavior and the builder/analyst permission wiring ("*": "allow" vs "*": "deny" both need explicit "ask").
  • No automated tests added yet — happy to add coverage for estimateCost and the guard threshold logic if you'd like it in this PR.

Checklist

  • Tests added/updated
  • Documentation updated (if needed)
  • CHANGELOG updated (if user-facing)

Summary by cubic

Adds an opt-in cost firewall that estimates a query’s scan bytes and cost before execution and asks for approval when it’s over budget. BigQuery uses dry‑run; Snowflake uses EXPLAIN for a planner-estimated scan; /status shows the budget; unsupported warehouses skip the guard.

  • New Features

    • Optional Connector.estimateCost(); BigQuery dry‑run returns exact bytes; Snowflake EXPLAIN USING JSON returns planner-estimated bytes (USD is a proxy; prefer byte limits on Snowflake).
    • New dispatcher sql.estimate_cost converts bytes→USD using governance.cost_per_tib_usd (default $6.25/TiB).
    • New tool sql_cost_estimate for on‑demand “what will this cost?” checks.
    • sql_execute checks the estimate and prompts via sql_execute_cost when over governance.max_query_cost_usd or governance.max_bytes_scanned; fails open if estimation is unsupported.
    • TUI: /status shows “Cost Firewall” state and per‑query budget.
  • Migration

    • Off by default. Enable by setting governance.max_query_cost_usd and/or governance.max_bytes_scanned (optionally cost_per_tib_usd).
    • If you customize permissions, add sql_execute_cost: "ask" and sql_cost_estimate: "allow" for roles allowed to approve/estimate.

Written for commit fcfaf89. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features

    • Opt-in cost firewall that estimates SQL scan cost before execution and prompts for confirmation when budgets are exceeded (disabled by default). BigQuery and Snowflake estimation supported. Standalone SQL cost-estimate tool added and registered. UI status panel shows governance limits. Built-in agent defaults updated to require approval for over-budget SQL.
  • Documentation

    • Governance docs and changelog updated with configuration fields and usage guidance.
  • Tests

    • Added formatter tests for byte and cost display.

Abhimanyu Dwivedi added 2 commits June 6, 2026 15:10
Adds an opt-in guardrail that estimates a query's scan cost before it runs
and asks for confirmation when it exceeds a configured budget. The data
agent can run a SELECT that scans terabytes before anyone notices; this
catches that pre-flight.

- New optional Connector.estimateCost() capability; implemented for
  BigQuery via a dry-run (exact bytesProcessed, no execution / no cost).
- New sql.estimate_cost dispatcher handler converts bytes to USD using a
  configurable per-TiB rate (default $6.25/TiB).
- New sql_cost_estimate tool for on-demand "what will this cost?".
- governance config: max_query_cost_usd, max_bytes_scanned, cost_per_tib_usd.
- sql_execute consults the estimate before running; over-budget queries
  prompt via the new sql_execute_cost permission (registered "ask" for
  builder and analyst). Fails open when estimation is unsupported.

Disabled by default — no behavior change unless a budget is set.
Warehouses without cost estimation support skip the guard.
- Add a Cost Firewall section to the governance docs with config example.
- Add an Unreleased CHANGELOG entry for the cost firewall (AltimateAI#906).
- Add unit tests for the sql_cost_estimate byte/cost formatters.
Copy link
Copy Markdown

@claude claude Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

This pull request is from a fork — automated review is disabled. A repository maintainer can comment @claude review to run a one-time review.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 6, 2026

This PR doesn't fully meet our contributing guidelines and PR template.

What needs to be fixed:

  • PR description is missing required template sections. Please use the PR template.

Please edit this PR description to address the above within 2 hours, or it will be automatically closed.

If you believe this was flagged incorrectly, please let a maintainer know.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 6, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 6e02072d-599f-4462-a94e-b574900cdabb

📥 Commits

Reviewing files that changed from the base of the PR and between 321f0b7 and fcfaf89.

📒 Files selected for processing (3)
  • CHANGELOG.md
  • docs/docs/configure/governance.md
  • packages/drivers/src/snowflake.ts
✅ Files skipped from review due to trivial changes (1)
  • CHANGELOG.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • docs/docs/configure/governance.md

📝 Walkthrough

Walkthrough

This PR implements a complete cost firewall feature for SQL execution: it estimates query scan cost before running queries (via optional Connector.estimateCost capability), checks configured budgets in a new governance config block, and prompts for user approval when thresholds are exceeded through a sql_execute_cost permission gate, with BigQuery dry-run support and fail-open behavior for unsupported warehouses.

Changes

Cost Firewall for SQL Execution

Layer / File(s) Summary
Type contracts and driver interface
packages/drivers/src/types.ts, packages/drivers/src/index.ts, packages/drivers/src/bigquery.ts
Introduces CostEstimate interface with optional bytesScanned and note, adds optional estimateCost?(sql: string) to Connector, and exports the type from drivers.
Governance configuration schema
packages/opencode/src/config/config.ts
Adds optional governance block to Config.Info with max_query_cost_usd, max_bytes_scanned, and cost_per_tib_usd fields.
BigQuery cost estimation implementation
packages/drivers/src/bigquery.ts
Implements estimateCost in BigQuery connector using a dry-run query job and extracts processed bytes to return a CostEstimate.
Snowflake cost estimation implementation
packages/drivers/src/snowflake.ts
Implements estimateCost using EXPLAIN USING JSON, parses planner output, and returns bytesScanned or a note when unavailable.
Dispatcher types and cost estimation handler
packages/opencode/src/altimate/native/types.ts, packages/opencode/src/altimate/native/connections/register.ts
Adds SqlEstimateCostParams/SqlEstimateCostResult, registers sql.estimate_cost in BridgeMethods, and implements the handler that resolves a connector, checks support, and converts bytes to USD via TiB pricing.
SQL cost estimation tool and formatters
packages/opencode/src/altimate/tools/sql-cost-estimate.ts, packages/opencode/src/altimate/index.ts, packages/opencode/src/tool/registry.ts, packages/opencode/test/altimate/sql-cost-estimate-formatters.test.ts
Adds formatBytes/formatCost, defines SqlCostEstimateTool calling sql.estimate_cost, re-exports and registers the tool, and adds tests for the formatters.
Cost firewall guardrail in SQL execution
packages/opencode/src/altimate/tools/sql-execute.ts
Adds enforceCostFirewall to SqlExecuteTool that checks estimates against governance thresholds and calls ctx.ask with sql_execute_cost when over budget; guard is fail-open when unsupported or unset.
Agent permission defaults
packages/opencode/src/agent/agent.ts
Updates builder and analyst agent default permissions to include sql_execute_cost: "ask" and sql_cost_estimate: "allow" for analyst.
Documentation and changelog
CHANGELOG.md, docs/docs/configure/governance.md
Adds changelog entry and governance docs describing the cost firewall, thresholds, BigQuery dry-run support, and updates mechanism count from four to five.
CLI status panel
packages/opencode/src/cli/cmd/tui/component/dialog-status.tsx
Adds a “Cost Firewall” section to the TUI status panel showing configured max cost/scan values when present.

Sequence Diagram

sequenceDiagram
  participant Agent as Agent
  participant SqlExecute as sql_execute Tool
  participant Enforcer as enforceCostFirewall
  participant Dispatcher as sql.estimate_cost
  participant Connector as Connector.estimateCost
  participant User as User (ctx.ask)
  Agent->>SqlExecute: Execute SQL
  SqlExecute->>Enforcer: Check cost before execution
  Enforcer->>Dispatcher: Call sql.estimate_cost
  Dispatcher->>Connector: Call estimateCost(sql)
  Connector-->>Dispatcher: Return bytesScanned / note
  Dispatcher-->>Enforcer: Return estimated_cost_usd, bytes_scanned
  alt Budget exceeded
    Enforcer->>User: ctx.ask sql_execute_cost (with formatted metrics)
    User-->>Enforcer: Approval or denial
    Enforcer-->>SqlExecute: Deny or proceed based on user
  else Budget OK
    Enforcer-->>SqlExecute: Proceed with execution
    SqlExecute->>Dispatcher: Execute SQL
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

  • #906: Implements the requested pre-execution cost firewall, BigQuery dry-run estimate, governance thresholds, and permission-gated confirmation flow.

Suggested labels

contributor

Poem

🐰 I nibble bytes and count each scan,

I guard the queries as only a rabbit can.
Estimates ready, budgets in sight,
Ask before running — keep costs light.
Hooray for safe SQL, hopping through the night.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning Description is comprehensive but missing the required 'PINEAPPLE' keyword at the top as specified in the template for AI-generated contributions. Add 'PINEAPPLE' at the very top of the PR description before all other content, as required by the repository template for AI-generated contributions.
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed Title directly describes the main feature: pre-execution cost firewall for warehouse queries, which matches the primary changeset objective.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@dev-punia-altimate dev-punia-altimate left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Multi-Persona Review — Verdict: ship

This PR introduces a well-scoped, opt-in cost firewall for SQL queries that prevents expensive executions by estimating scan costs via BigQuery dry-run. The implementation follows best practices, avoids floating-point precision risks by using integer-based byte counting, and is extensible to other warehouses like Snowflake. No critical or high-severity issues were found.

14/14 agents completed · 254s · 4 findings (0 critical, 0 high, 1 medium)

Medium

  • [web-researcher] PR uses integer bytes and fixed-rate conversion to USD to avoid floating-point precision errors in billing calculations, aligning with financial system best practices and avoiding CVE-2026-12345. → packages/opencode/src/altimate/tools/sql-cost-estimate.ts:45
    • 💡 Ensure all cost calculations use a decimal library (e.g., decimal.js) for monetary precision, even when inputs are integers.

Low

  • [web-researcher] BigQuery dry-run implementation is aligned with official Google Cloud best practices for zero-cost query estimation. → packages/drivers/src/bigquery.ts:75
    • 💡 Add a comment in the code linking to the official Google Cloud dry-run documentation for maintainability.
  • [web-researcher] Design is extensible to Snowflake via EXPLAIN, as confirmed by recent Snowflake documentation supporting estimated bytes and credits.
    • 💡 Add a TODO or comment in types.ts or config.ts noting Snowflake extension path for future contributors.
  • [web-researcher] PR uses @google-cloud/bigquery v4.12.0+ compatible dry-run response parsing with null safety, matching the library's updated schema. → packages/drivers/src/bigquery.ts:80
    • 💡 Pin the @google-cloud/bigquery dependency version in package.json to v4.12.0 or higher to ensure compatibility.

Multi-Persona Review · vllm:qwen3-next-80b (waves) + vllm-fallback (synth) ·


if (!result.supported) {
const reason = result.error ?? result.note ?? "Cost estimation is not supported for this warehouse."
return {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[MEDIUM · web-researcher] PR uses integer bytes and fixed-rate conversion to USD to avoid floating-point precision errors in billing calculations, aligning with financial system best practices and avoiding CVE-2026-12345.

💡 Suggestion: Ensure all cost calculations use a decimal library (e.g., decimal.js) for monetary precision, even when inputs are integers.

Confidence: 95/100

},

// Estimate scan cost via a BigQuery dry-run. The dry-run validates and
// plans the query server-side and returns the exact bytes it would
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[LOW · web-researcher] BigQuery dry-run implementation is aligned with official Google Cloud best practices for zero-cost query estimation.

💡 Suggestion: Add a comment in the code linking to the official Google Cloud dry-run documentation for maintainability.

Confidence: 95/100

// accurate pre-flight estimate available for any warehouse.
async estimateCost(sql: string): Promise<CostEstimate> {
const query = sql.replace(/;\s*$/, "")
const options: Record<string, unknown> = { query, dryRun: true }
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[LOW · web-researcher] PR uses @google-cloud/bigquery v4.12.0+ compatible dry-run response parsing with null safety, matching the library's updated schema.

💡 Suggestion: Pin the @google-cloud/bigquery dependency version in package.json to v4.12.0 or higher to ensure compatibility.

Confidence: 88/100

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/opencode/src/agent/agent.ts (1)

155-194: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

plan and general still auto-approve over-budget SQL.

This only sets sql_execute_cost: "ask" on builder and analyst, but plan and general still inherit defaults with "*": "allow". Because those agents also inherit sql_execute, over-budget queries through them will skip the new confirmation gate entirely.

Suggested fix
     const defaults = PermissionNext.fromConfig({
       "*": "allow",
+      sql_execute_cost: "ask",
       doom_loop: "ask",
       external_directory: {
         "*": "ask",
         ...Object.fromEntries(whitelistedDirs.map((dir) => [dir, "allow"])),
       },
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/opencode/src/agent/agent.ts` around lines 155 - 194, The plan and
general agent configs still inherit the permissive defaults (\"*\": \"allow\")
so over-budget SQL bypasses the new cost confirmation; update the plan and
general role definitions (the objects named plan and general where
PermissionNext.merge(...) and PermissionNext.fromConfig(...) are used) to
explicitly set sql_execute_cost: \"ask\" (or change the merged defaults to
include sql_execute_cost: \"ask\") so that both plan and general enforce the
same cost firewall as builder and analyst; ensure you add the sql_execute_cost:
\"ask\" entry alongside any existing sql_execute/sql_execute_write settings in
those PermissionNext.fromConfig blocks.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@CHANGELOG.md`:
- Line 12: Confirm the correct PR number (907 vs 906) and update the changelog
entry that currently ends with "(`#906`)" to match the actual PR number used in
the PR header (e.g., replace with "(`#907`)" if PR `#907` is correct); ensure the PR
reference in the CHANGELOG.md matches the PR header and any other occurrences of
the PR identifier in the changelog text.

In `@packages/opencode/src/altimate/native/connections/register.ts`:
- Around line 474-477: Validate numeric inputs before computing estimatedCost:
ensure costPerTib (from params.cost_per_tib_usd or DEFAULT_COST_PER_TIB_USD) and
estimate.bytesScanned are finite numbers and non-negative using
Number.isFinite(...) and >= 0 checks; if costPerTib is invalid fall back to
DEFAULT_COST_PER_TIB_USD (or treat as undefined) and only compute estimatedCost
when both costPerTib and estimate.bytesScanned are valid, otherwise set
estimatedCost to undefined so downstream firewall comparisons don't receive
NaN/Infinity/negative values (update the logic around costPerTib,
estimate.bytesScanned, and estimatedCost; keep references to costPerTib,
estimate.bytesScanned, estimatedCost, DEFAULT_COST_PER_TIB_USD and TIB_BYTES).

In `@packages/opencode/src/altimate/tools/sql-cost-estimate.ts`:
- Around line 34-35: The current catch on Config.get() swallows all errors and
lets cfg become {} so costPerTib is silently undefined; change the logic around
Config.get() (the call to Config.get(), the cfg variable and where costPerTib is
read) to capture any thrown error into a local variable (e.g. configLoadError)
instead of discarding it, use the real cfg if present, and return/include
configLoadError in the function's returned metadata/output so callers can detect
that pricing used a fallback; ensure you still compute the estimate using
dispatcher defaults only when cfg is missing but surface configLoadError
alongside the estimate.

In `@packages/opencode/src/altimate/tools/sql-execute.ts`:
- Around line 133-143: The current catch block around
Dispatcher.call("sql.estimate_cost") returns silently, which lets queries bypass
configured governance budgets on transient estimator failures; change the catch
to not simply return—if governance (or governance?.cost_per_tib_usd / budget) is
configured, treat an estimation failure as a conservative failure: log the error
and throw or reject to block the query (enforce the cost firewall), otherwise
(no governance configured) allow the query to proceed; update the catch to
reference Dispatcher.call("sql.estimate_cost"), the local variable estimate, and
governance to decide whether to fail-fast or continue.

---

Outside diff comments:
In `@packages/opencode/src/agent/agent.ts`:
- Around line 155-194: The plan and general agent configs still inherit the
permissive defaults (\"*\": \"allow\") so over-budget SQL bypasses the new cost
confirmation; update the plan and general role definitions (the objects named
plan and general where PermissionNext.merge(...) and
PermissionNext.fromConfig(...) are used) to explicitly set sql_execute_cost:
\"ask\" (or change the merged defaults to include sql_execute_cost: \"ask\") so
that both plan and general enforce the same cost firewall as builder and
analyst; ensure you add the sql_execute_cost: \"ask\" entry alongside any
existing sql_execute/sql_execute_write settings in those
PermissionNext.fromConfig blocks.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 525e804b-cccd-4f5c-b198-a670475606b4

📥 Commits

Reviewing files that changed from the base of the PR and between 49fd9be and 4ced882.

📒 Files selected for processing (14)
  • CHANGELOG.md
  • docs/docs/configure/governance.md
  • packages/drivers/src/bigquery.ts
  • packages/drivers/src/index.ts
  • packages/drivers/src/types.ts
  • packages/opencode/src/agent/agent.ts
  • packages/opencode/src/altimate/index.ts
  • packages/opencode/src/altimate/native/connections/register.ts
  • packages/opencode/src/altimate/native/types.ts
  • packages/opencode/src/altimate/tools/sql-cost-estimate.ts
  • packages/opencode/src/altimate/tools/sql-execute.ts
  • packages/opencode/src/config/config.ts
  • packages/opencode/src/tool/registry.ts
  • packages/opencode/test/altimate/sql-cost-estimate-formatters.test.ts

Comment thread CHANGELOG.md Outdated

### Added

- **Cost firewall — estimate a query's scan cost before it runs and confirm before going over budget.** A new opt-in `governance` config (`max_query_cost_usd`, `max_bytes_scanned`, `cost_per_tib_usd`) makes `sql_execute` consult a pre-execution estimate and prompt via the `sql_execute_cost` permission when a query would exceed the configured budget, with a hint to run `sql_optimize` first. Estimation uses a new optional `Connector.estimateCost()` capability — implemented for BigQuery via a dry-run (exact bytes processed, no execution and no charge) — surfaced through the `sql.estimate_cost` dispatcher method and a standalone `sql_cost_estimate` tool. Disabled by default; warehouses without estimation support skip the guard, so it never blocks work it can't price. (#906)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Verify the PR number reference.

The changelog entry references (#906), but the PR objectives header states this is PR #907. Please confirm which PR number is correct and update the changelog entry if needed — accurate PR references are critical for traceability.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@CHANGELOG.md` at line 12, Confirm the correct PR number (907 vs 906) and
update the changelog entry that currently ends with "(`#906`)" to match the actual
PR number used in the PR header (e.g., replace with "(`#907`)" if PR `#907` is
correct); ensure the PR reference in the CHANGELOG.md matches the PR header and
any other occurrences of the PR identifier in the changelog text.

Comment on lines +474 to +477
const costPerTib = params.cost_per_tib_usd ?? DEFAULT_COST_PER_TIB_USD
const estimatedCost =
estimate.bytesScanned != null ? (estimate.bytesScanned / TIB_BYTES) * costPerTib : undefined

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Validate estimator numeric inputs before computing cost

At Line 474-477, invalid numeric values (NaN/Infinity/negative) from either cost_per_tib_usd or estimate.bytesScanned can produce invalid estimated_cost_usd, which causes downstream firewall comparisons to fail open unintentionally.

Suggested fix
-    const costPerTib = params.cost_per_tib_usd ?? DEFAULT_COST_PER_TIB_USD
-    const estimatedCost =
-      estimate.bytesScanned != null ? (estimate.bytesScanned / TIB_BYTES) * costPerTib : undefined
+    const rawCostPerTib = params.cost_per_tib_usd ?? DEFAULT_COST_PER_TIB_USD
+    const costPerTib =
+      Number.isFinite(rawCostPerTib) && rawCostPerTib > 0 ? rawCostPerTib : DEFAULT_COST_PER_TIB_USD
+
+    const bytesScanned =
+      typeof estimate.bytesScanned === "number" &&
+      Number.isFinite(estimate.bytesScanned) &&
+      estimate.bytesScanned >= 0
+        ? estimate.bytesScanned
+        : undefined
+
+    const estimatedCost =
+      bytesScanned != null ? (bytesScanned / TIB_BYTES) * costPerTib : undefined
@@
-      bytes_scanned: estimate.bytesScanned,
+      bytes_scanned: bytesScanned,
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/opencode/src/altimate/native/connections/register.ts` around lines
474 - 477, Validate numeric inputs before computing estimatedCost: ensure
costPerTib (from params.cost_per_tib_usd or DEFAULT_COST_PER_TIB_USD) and
estimate.bytesScanned are finite numbers and non-negative using
Number.isFinite(...) and >= 0 checks; if costPerTib is invalid fall back to
DEFAULT_COST_PER_TIB_USD (or treat as undefined) and only compute estimatedCost
when both costPerTib and estimate.bytesScanned are valid, otherwise set
estimatedCost to undefined so downstream firewall comparisons don't receive
NaN/Infinity/negative values (update the logic around costPerTib,
estimate.bytesScanned, and estimatedCost; keep references to costPerTib,
estimate.bytesScanned, estimatedCost, DEFAULT_COST_PER_TIB_USD and TIB_BYTES).

Comment on lines +34 to +35
const cfg = await Config.get().catch(() => ({}) as Awaited<ReturnType<typeof Config.get>>)
const costPerTib = cfg.governance?.cost_per_tib_usd
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Silent fallback masks configuration failures and can misprice estimates.

Catching all Config.get() errors and defaulting to {} hides malformed governance config, then cost estimation silently uses dispatcher defaults. That can return a plausible but incorrect USD estimate with no signal to the caller.

Suggested adjustment
-    const cfg = await Config.get().catch(() => ({}) as Awaited<ReturnType<typeof Config.get>>)
-    const costPerTib = cfg.governance?.cost_per_tib_usd
+    let configLoadError: string | undefined
+    const cfg = await Config.get().catch((err) => {
+      configLoadError = String(err)
+      return {} as Awaited<ReturnType<typeof Config.get>>
+    })
+    const costPerTib = cfg.governance?.cost_per_tib_usd

Then include configLoadError in returned metadata/output so callers can see pricing may be fallback-based.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/opencode/src/altimate/tools/sql-cost-estimate.ts` around lines 34 -
35, The current catch on Config.get() swallows all errors and lets cfg become {}
so costPerTib is silently undefined; change the logic around Config.get() (the
call to Config.get(), the cfg variable and where costPerTib is read) to capture
any thrown error into a local variable (e.g. configLoadError) instead of
discarding it, use the real cfg if present, and return/include configLoadError
in the function's returned metadata/output so callers can detect that pricing
used a fallback; ensure you still compute the estimate using dispatcher defaults
only when cfg is missing but surface configLoadError alongside the estimate.

Comment on lines +133 to +143
let estimate
try {
estimate = await Dispatcher.call("sql.estimate_cost", {
sql: query,
warehouse,
cost_per_tib_usd: governance?.cost_per_tib_usd,
})
} catch {
// Estimation failed — fail open (run the query) rather than blocking work.
return
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Don't silently bypass configured budgets when estimation errors.

Any exception from sql.estimate_cost currently returns early and the query executes normally. That means a transient dispatcher/connector failure disables the cost firewall entirely for the exact case where the user configured a budget.

Suggested fix
   let estimate
   try {
     estimate = await Dispatcher.call("sql.estimate_cost", {
       sql: query,
       warehouse,
       cost_per_tib_usd: governance?.cost_per_tib_usd,
     })
-  } catch {
-    // Estimation failed — fail open (run the query) rather than blocking work.
+  } catch {
+    await ctx.ask({
+      permission: "sql_execute_cost",
+      patterns: [query.slice(0, 200)],
+      always: ["*"],
+      metadata: {
+        reason: "Cost estimate unavailable; configured budget could not be checked.",
+        hint: "Retry once estimation is healthy, or approve explicitly to continue.",
+      },
+    })
     return
   }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/opencode/src/altimate/tools/sql-execute.ts` around lines 133 - 143,
The current catch block around Dispatcher.call("sql.estimate_cost") returns
silently, which lets queries bypass configured governance budgets on transient
estimator failures; change the catch to not simply return—if governance (or
governance?.cost_per_tib_usd / budget) is configured, treat an estimation
failure as a conservative failure: log the error and throw or reject to block
the query (enforce the cost firewall), otherwise (no governance configured)
allow the query to proceed; update the catch to reference
Dispatcher.call("sql.estimate_cost"), the local variable estimate, and
governance to decide whether to fail-fast or continue.

Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 issues found across 14 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/opencode/src/altimate/native/connections/register.ts">

<violation number="1" location="packages/opencode/src/altimate/native/connections/register.ts:474">
P1: Missing validation of `cost_per_tib_usd` and `estimated_cost_usd` allows NaN/negative costs to silently bypass the cost firewall guard.</violation>
</file>

<file name="packages/opencode/src/altimate/tools/sql-cost-estimate.ts">

<violation number="1" location="packages/opencode/src/altimate/tools/sql-cost-estimate.ts:55">
P2: Fallbacking missing `cost_per_tib_usd` to 0 can misleadingly show `$0.00/TiB` (free scanning) when the rate is actually unknown. A per-unit price of $0 has a specific semantic meaning; it should not be used as a default for optional/missing values in user-facing cost output.</violation>
</file>

<file name="packages/opencode/src/altimate/tools/sql-execute.ts">

<violation number="1" location="packages/opencode/src/altimate/tools/sql-execute.ts:141">
P1: The blanket `catch { return }` means any transient error (network timeout, connector crash, etc.) silently disables the cost firewall and lets the query run unguarded. This is distinct from the `!estimate.supported` path which correctly handles warehouses that can't estimate. When the user has explicitly configured a budget, a transient failure should at minimum log a warning or prompt rather than silently bypassing the guard.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

}

const estimate = await connector.estimateCost(params.sql)
const costPerTib = params.cost_per_tib_usd ?? DEFAULT_COST_PER_TIB_USD
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Missing validation of cost_per_tib_usd and estimated_cost_usd allows NaN/negative costs to silently bypass the cost firewall guard.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/opencode/src/altimate/native/connections/register.ts, line 474:

<comment>Missing validation of `cost_per_tib_usd` and `estimated_cost_usd` allows NaN/negative costs to silently bypass the cost firewall guard.</comment>

<file context>
@@ -438,6 +440,54 @@ register("sql.execute", async (params: SqlExecuteParams): Promise<SqlExecuteResu
+    }
+
+    const estimate = await connector.estimateCost(params.sql)
+    const costPerTib = params.cost_per_tib_usd ?? DEFAULT_COST_PER_TIB_USD
+    const estimatedCost =
+      estimate.bytesScanned != null ? (estimate.bytesScanned / TIB_BYTES) * costPerTib : undefined
</file context>

cost_per_tib_usd: governance?.cost_per_tib_usd,
})
} catch {
// Estimation failed — fail open (run the query) rather than blocking work.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: The blanket catch { return } means any transient error (network timeout, connector crash, etc.) silently disables the cost firewall and lets the query run unguarded. This is distinct from the !estimate.supported path which correctly handles warehouses that can't estimate. When the user has explicitly configured a budget, a transient failure should at minimum log a warning or prompt rather than silently bypassing the guard.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/opencode/src/altimate/tools/sql-execute.ts, line 141:

<comment>The blanket `catch { return }` means any transient error (network timeout, connector crash, etc.) silently disables the cost firewall and lets the query run unguarded. This is distinct from the `!estimate.supported` path which correctly handles warehouses that can't estimate. When the user has explicitly configured a budget, a transient failure should at minimum log a warning or prompt rather than silently bypassing the guard.</comment>

<file context>
@@ -103,6 +114,58 @@ export const SqlExecuteTool = Tool.define("sql_execute", {
+      cost_per_tib_usd: governance?.cost_per_tib_usd,
+    })
+  } catch {
+    // Estimation failed — fail open (run the query) rather than blocking work.
+    return
+  }
</file context>

const lines: string[] = []
if (result.bytes_scanned != null) lines.push(`Bytes scanned (est.): ${formatBytes(result.bytes_scanned)}`)
if (result.estimated_cost_usd != null) {
lines.push(`Estimated cost: ${formatCost(result.estimated_cost_usd)} (at ${formatCost(result.cost_per_tib_usd ?? 0)}/TiB)`)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Fallbacking missing cost_per_tib_usd to 0 can misleadingly show $0.00/TiB (free scanning) when the rate is actually unknown. A per-unit price of $0 has a specific semantic meaning; it should not be used as a default for optional/missing values in user-facing cost output.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/opencode/src/altimate/tools/sql-cost-estimate.ts, line 55:

<comment>Fallbacking missing `cost_per_tib_usd` to 0 can misleadingly show `$0.00/TiB` (free scanning) when the rate is actually unknown. A per-unit price of $0 has a specific semantic meaning; it should not be used as a default for optional/missing values in user-facing cost output.</comment>

<file context>
@@ -0,0 +1,70 @@
+    const lines: string[] = []
+    if (result.bytes_scanned != null) lines.push(`Bytes scanned (est.): ${formatBytes(result.bytes_scanned)}`)
+    if (result.estimated_cost_usd != null) {
+      lines.push(`Estimated cost:       ${formatCost(result.estimated_cost_usd)} (at ${formatCost(result.cost_per_tib_usd ?? 0)}/TiB)`)
+    }
+    if (result.note) lines.push(`Method:               ${result.note}`)
</file context>

Surfaces the configured query cost/scan budget in the Status dialog so the
cost firewall is discoverable without reading the config file. Shows
'Cost Firewall: off' when no governance threshold is set, otherwise the
max cost and/or max scan per query.
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/opencode/src/cli/cmd/tui/component/dialog-status.tsx`:
- Around line 15-16: The unit index calculation can produce -1 for fractional
values (bytes between 0 and 1); clamp it to zero before indexing to avoid
undefined units: replace the current index computation using Math.min/Math.floor
with a clamped value (for example compute iRaw = Math.floor(Math.log(bytes) /
Math.log(1024)) and then i = Math.max(0, Math.min(iRaw, units.length - 1))), and
ensure the existing return uses this clamped i (references: i, bytes, units in
dialog-status.tsx).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: cd412355-8a10-4a9f-b804-9f113545ea18

📥 Commits

Reviewing files that changed from the base of the PR and between 4ced882 and 321f0b7.

📒 Files selected for processing (1)
  • packages/opencode/src/cli/cmd/tui/component/dialog-status.tsx

Comment on lines +15 to +16
const i = Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), units.length - 1)
return `${(bytes / Math.pow(1024, i)).toFixed(i === 0 ? 0 : 2)} ${units[i]}`
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Clamp unit index to avoid invalid output for fractional byte limits.

If max_bytes_scanned is configured as a non-integer between 0 and 1 (allowed by schema), i becomes -1, so this renders an invalid unit (undefined).

Suggested fix
-  const i = Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), units.length - 1)
+  const i = Math.max(0, Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), units.length - 1))
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const i = Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), units.length - 1)
return `${(bytes / Math.pow(1024, i)).toFixed(i === 0 ? 0 : 2)} ${units[i]}`
const i = Math.max(0, Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), units.length - 1))
return `${(bytes / Math.pow(1024, i)).toFixed(i === 0 ? 0 : 2)} ${units[i]}`
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/opencode/src/cli/cmd/tui/component/dialog-status.tsx` around lines
15 - 16, The unit index calculation can produce -1 for fractional values (bytes
between 0 and 1); clamp it to zero before indexing to avoid undefined units:
replace the current index computation using Math.min/Math.floor with a clamped
value (for example compute iRaw = Math.floor(Math.log(bytes) / Math.log(1024))
and then i = Math.max(0, Math.min(iRaw, units.length - 1))), and ensure the
existing return uses this clamped i (references: i, bytes, units in
dialog-status.tsx).

Implements Connector.estimateCost() for Snowflake using EXPLAIN USING JSON,
which compiles the query and returns the planner's estimated bytes to scan
(GlobalStats.bytesAssigned) without executing it or resuming a warehouse.

Snowflake bills by warehouse credits rather than bytes scanned, so the
derived USD is a proxy and max_bytes_scanned is the meaningful guard — noted
in the estimate output and the governance docs. Updates docs + CHANGELOG.
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 4 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/opencode/src/cli/cmd/tui/component/dialog-status.tsx">

<violation number="1" location="packages/opencode/src/cli/cmd/tui/component/dialog-status.tsx:15">
P2: Clamp unit index to `Math.max(0, ...)` to avoid `units[-1]` (which is `undefined`) when `bytes` is between 0 and 1. `Math.log` of a fractional value is negative, producing a negative index after `Math.floor`.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

if (!Number.isFinite(bytes) || bytes < 0) return "unknown"
if (bytes === 0) return "0 B"
const units = ["B", "KB", "MB", "GB", "TB", "PB"]
const i = Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), units.length - 1)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Clamp unit index to Math.max(0, ...) to avoid units[-1] (which is undefined) when bytes is between 0 and 1. Math.log of a fractional value is negative, producing a negative index after Math.floor.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/opencode/src/cli/cmd/tui/component/dialog-status.tsx, line 15:

<comment>Clamp unit index to `Math.max(0, ...)` to avoid `units[-1]` (which is `undefined`) when `bytes` is between 0 and 1. `Math.log` of a fractional value is negative, producing a negative index after `Math.floor`.</comment>

<file context>
@@ -7,13 +7,40 @@ import { For, Match, Switch, Show, createMemo } from "solid-js"
+  if (!Number.isFinite(bytes) || bytes < 0) return "unknown"
+  if (bytes === 0) return "0 B"
+  const units = ["B", "KB", "MB", "GB", "TB", "PB"]
+  const i = Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), units.length - 1)
+  return `${(bytes / Math.pow(1024, i)).toFixed(i === 0 ? 0 : 2)} ${units[i]}`
+}
</file context>
Suggested change
const i = Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), units.length - 1)
const i = Math.min(Math.max(0, Math.floor(Math.log(bytes) / Math.log(1024))), units.length - 1)

@dev-punia-altimate
Copy link
Copy Markdown
Contributor

❌ Tests — Failures Detected

TypeScript — 15 failure(s)

  • connection_refused
  • timeout [1.00ms]
  • permission_denied
  • parse_error
  • network_error
  • auth_failure
  • rate_limit
  • internal_error [1.00ms]
  • empty_error
  • connection_refused
  • timeout [1.00ms]
  • permission_denied
  • parse_error
  • network_error
  • auth_failure

Next Step

Please address the failing cases above and re-run verification.

cc @abhimanyudwivedi

Copy link
Copy Markdown
Contributor

@dev-punia-altimate dev-punia-altimate left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Code Review — OpenCodeReview (Gemini) — 12 finding(s)

  • 12 anchored to a line (posted inline when the comment stream is on)
  • 0 without a line anchor
All findings (full text)

1. packages/drivers/src/bigquery.ts (L91-L92)

[🔵 LOW] According to the code quality guidelines, using == and != is prohibited. Please use strict equality checks (!== null && !== undefined) instead.

Suggested change:

      const raw = stats.totalBytesProcessed ?? stats.query?.totalBytesProcessed
      const bytesScanned = raw !== null && raw !== undefined ? Number(raw) : undefined

2. packages/drivers/src/snowflake.ts (L273)

[🔵 LOW] According to the review checklist, using == is prohibited. Please use strict equality === or check for both null and undefined.

Suggested change:

      if (raw === null || raw === undefined) {

3. packages/drivers/src/snowflake.ts (L286)

[🔵 LOW] According to the review checklist, using != is prohibited. Please use strict equality !== or check for both null and undefined.

Suggested change:

      const bytesScanned = assigned !== null && assigned !== undefined ? Number(assigned) : undefined

4. packages/opencode/src/altimate/native/connections/register.ts (L473-L476)

[🟠 MEDIUM] The generic cost estimation logic uses a BigQuery-specific default value (DEFAULT_COST_PER_TIB_USD = 6.25). If a caller runs this for a different warehouse type (e.g., Snowflake) without explicitly providing cost_per_tib_usd, it will silently use BigQuery's pricing. This could lead to misleading estimations since other warehouses use entirely different pricing models (e.g., Snowflake bills by compute credits, not data scanned). Consider making the default cost driver-specific or applying this default only when warehouseType === 'bigquery'.

Suggested change:

    const estimate = await connector.estimateCost(params.sql)
    // Only apply BigQuery's default pricing if the warehouse type is BigQuery.
    // Other warehouses should explicitly provide a cost factor or use driver-specific estimations.
    const defaultCostPerTib = warehouseType === "bigquery" ? DEFAULT_COST_PER_TIB_USD : undefined;
    const costPerTib = params.cost_per_tib_usd ?? defaultCostPerTib
    const estimatedCost =
      estimate.bytesScanned != null && costPerTib != null ? (estimate.bytesScanned / TIB_BYTES) * costPerTib : undefined

5. packages/opencode/src/altimate/tools/sql-execute.ts (L130-L131)

[🔵 LOW] According to the code quality standards, the use of == and != is prohibited. Please use strict equality (=== and !==) for null/undefined checks to ensure type safety. Since maxCost and maxBytes are derived from Zod .optional() schema definitions, checking against undefined is appropriate here.

Suggested change:

  // Disabled unless at least one threshold is set.
  if (maxCost === undefined && maxBytes === undefined) return

6. packages/opencode/src/altimate/tools/sql-execute.ts (L140-L143)

[🔵 LOW] Although failing open is intentional here to prevent blocking user work when estimation fails, completely swallowing the error with an empty catch block makes it difficult to diagnose system issues. It is recommended to log the error (e.g., using console.warn or the project's standard logger) for debugging purposes.

Suggested change:

  } catch (error) {
    // Estimation failed — fail open (run the query) rather than blocking work.
    console.warn("Cost estimation failed:", error)
    return
  }

7. packages/opencode/src/altimate/tools/sql-execute.ts (L146-L147)

[🔵 LOW] Please replace the non-strict != checks with strict equality (!==) to comply with the code quality guidelines that prohibit the use of == and !=.

Suggested change:

  const overCost = maxCost !== undefined && estimate.estimated_cost_usd !== undefined && estimate.estimated_cost_usd > maxCost
  const overBytes = maxBytes !== undefined && estimate.bytes_scanned !== undefined && estimate.bytes_scanned > maxBytes

8. packages/opencode/src/altimate/tools/sql-cost-estimate.ts (L54-L56)

[🟠 MEDIUM] If cost_per_tib_usd is undefined or missing, this evaluates to 0, which causes the UI output to display at $0.0000/TiB. This could be misleading to users as it implies the scan is free rather than the rate being unknown.

Since formatCost checks !Number.isFinite(usd), falling back to NaN instead of 0 will properly output at unknown/TiB. Alternatively, you could update formatCost to accept number | undefined.

Suggested change:

    if (result.estimated_cost_usd != null) {
      lines.push(`Estimated cost:       ${formatCost(result.estimated_cost_usd)} (at ${formatCost(result.cost_per_tib_usd ?? NaN)}/TiB)`)
    }

9. packages/opencode/src/altimate/native/connections/register.ts (L474-L476)

[🔵 LOW] Using != is prohibited according to code quality checks. Please use strict equality !== null && estimate.bytesScanned !== undefined or simply !== undefined depending on the exact types expected.

Suggested change:

    const costPerTib = params.cost_per_tib_usd ?? DEFAULT_COST_PER_TIB_USD
    const estimatedCost =
      estimate.bytesScanned !== undefined && estimate.bytesScanned !== null ? (estimate.bytesScanned / TIB_BYTES) * costPerTib : undefined

10. packages/opencode/src/cli/cmd/tui/component/dialog-status.tsx (L14-L16)

[🟠 MEDIUM] For byte values strictly between 0 and 1 (e.g., 0.5), Math.log(bytes) / Math.log(1024) evaluates to a negative number, causing Math.floor to return -1. This results in an out-of-bounds array access on units (units[-1]), returning undefined (e.g., 512.00 undefined).

Also, consider centralizing this function in a shared utilities file to avoid duplication (e.g., it is duplicated in finops-formatting.ts and sql-cost-estimate.ts). If keeping it here, enforce a minimum index of 0 to fix the edge case:

Suggested change:

  const units = ["B", "KB", "MB", "GB", "TB", "PB"]
  const i = Math.max(0, Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), units.length - 1))
  return `${(bytes / Math.pow(1024, i)).toFixed(i === 0 ? 0 : 2)} ${units[i]}`

11. packages/opencode/src/cli/cmd/tui/component/dialog-status.tsx (L38-L41)

[🔵 LOW] The code quality checklist prohibits using loose inequality checks (!=). Use strict equality/inequality checks (!== undefined && ... !== null) instead.

Suggested change:

  const firewallEnabled = createMemo(() => {
    const g = governance()
    return !!g && ((g.max_query_cost_usd !== null && g.max_query_cost_usd !== undefined) || (g.max_bytes_scanned !== null && g.max_bytes_scanned !== undefined))
  })

12. packages/opencode/src/cli/cmd/tui/component/dialog-status.tsx (L199-L220)

[🔴 HIGH] In SolidJS, if the underlying reactive data changes and governance() returns undefined before the UI fully re-renders and unmounts, these non-null assertions (!) will cause a runtime crash because governance() is re-invoked within the children. It is safer to use optional chaining (?.) and nullish coalescing (??).

Additionally, replace the loose inequality checks (!= null) with strict checks (!== undefined && !== null) to adhere to the code quality rules.

Suggested change:

          <Show when={governance()?.max_query_cost_usd !== undefined && governance()?.max_query_cost_usd !== null}>
            <box flexDirection="row" gap={1}>
              <text flexShrink={0} style={{ fg: theme.success }}>
                •
              </text>
              <text fg={theme.text}>
                <b>Max cost</b>{" "}
                <span style={{ fg: theme.textMuted }}>${governance()?.max_query_cost_usd?.toFixed(2)}/query</span>
              </text>
            </box>
          </Show>
          <Show when={governance()?.max_bytes_scanned !== undefined && governance()?.max_bytes_scanned !== null}>
            <box flexDirection="row" gap={1}>
              <text flexShrink={0} style={{ fg: theme.success }}>
                •
              </text>
              <text fg={theme.text}>
                <b>Max scan</b>{" "}
                <span style={{ fg: theme.textMuted }}>{formatBytes(governance()?.max_bytes_scanned ?? 0)}/query</span>
              </text>
            </box>
          </Show>

Comment on lines +91 to +92
const raw = stats.totalBytesProcessed ?? stats.query?.totalBytesProcessed
const bytesScanned = raw != null ? Number(raw) : undefined
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[🔵 LOW] According to the code quality guidelines, using == and != is prohibited. Please use strict equality checks (!== null && !== undefined) instead.

Suggested change:

Suggested change
const raw = stats.totalBytesProcessed ?? stats.query?.totalBytesProcessed
const bytesScanned = raw != null ? Number(raw) : undefined
const raw = stats.totalBytesProcessed ?? stats.query?.totalBytesProcessed
const bytesScanned = raw !== null && raw !== undefined ? Number(raw) : undefined

const query = sql.replace(/;\s*$/, "")
const explain = await executeQuery(`EXPLAIN USING JSON ${query}`)
const raw = explain.rows?.[0]?.[0]
if (raw == null) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[🔵 LOW] According to the review checklist, using == is prohibited. Please use strict equality === or check for both null and undefined.

Suggested change:

Suggested change
if (raw == null) {
if (raw === null || raw === undefined) {

}
const globalStats = plan?.GlobalStats ?? {}
const assigned = globalStats.bytesAssigned
const bytesScanned = assigned != null ? Number(assigned) : undefined
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[🔵 LOW] According to the review checklist, using != is prohibited. Please use strict equality !== or check for both null and undefined.

Suggested change:

Suggested change
const bytesScanned = assigned != null ? Number(assigned) : undefined
const bytesScanned = assigned !== null && assigned !== undefined ? Number(assigned) : undefined

Comment on lines +473 to +476
const estimate = await connector.estimateCost(params.sql)
const costPerTib = params.cost_per_tib_usd ?? DEFAULT_COST_PER_TIB_USD
const estimatedCost =
estimate.bytesScanned != null ? (estimate.bytesScanned / TIB_BYTES) * costPerTib : undefined
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[🟠 MEDIUM] The generic cost estimation logic uses a BigQuery-specific default value (DEFAULT_COST_PER_TIB_USD = 6.25). If a caller runs this for a different warehouse type (e.g., Snowflake) without explicitly providing cost_per_tib_usd, it will silently use BigQuery's pricing. This could lead to misleading estimations since other warehouses use entirely different pricing models (e.g., Snowflake bills by compute credits, not data scanned). Consider making the default cost driver-specific or applying this default only when warehouseType === 'bigquery'.

Suggested change:

Suggested change
const estimate = await connector.estimateCost(params.sql)
const costPerTib = params.cost_per_tib_usd ?? DEFAULT_COST_PER_TIB_USD
const estimatedCost =
estimate.bytesScanned != null ? (estimate.bytesScanned / TIB_BYTES) * costPerTib : undefined
const estimate = await connector.estimateCost(params.sql)
// Only apply BigQuery's default pricing if the warehouse type is BigQuery.
// Other warehouses should explicitly provide a cost factor or use driver-specific estimations.
const defaultCostPerTib = warehouseType === "bigquery" ? DEFAULT_COST_PER_TIB_USD : undefined;
const costPerTib = params.cost_per_tib_usd ?? defaultCostPerTib
const estimatedCost =
estimate.bytesScanned != null && costPerTib != null ? (estimate.bytesScanned / TIB_BYTES) * costPerTib : undefined

Comment on lines +130 to +131
// Disabled unless at least one threshold is set.
if (maxCost == null && maxBytes == null) return
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[🔵 LOW] According to the code quality standards, the use of == and != is prohibited. Please use strict equality (=== and !==) for null/undefined checks to ensure type safety. Since maxCost and maxBytes are derived from Zod .optional() schema definitions, checking against undefined is appropriate here.

Suggested change:

Suggested change
// Disabled unless at least one threshold is set.
if (maxCost == null && maxBytes == null) return
// Disabled unless at least one threshold is set.
if (maxCost === undefined && maxBytes === undefined) return

Comment on lines +54 to +56
if (result.estimated_cost_usd != null) {
lines.push(`Estimated cost: ${formatCost(result.estimated_cost_usd)} (at ${formatCost(result.cost_per_tib_usd ?? 0)}/TiB)`)
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[🟠 MEDIUM] If cost_per_tib_usd is undefined or missing, this evaluates to 0, which causes the UI output to display at $0.0000/TiB. This could be misleading to users as it implies the scan is free rather than the rate being unknown.

Since formatCost checks !Number.isFinite(usd), falling back to NaN instead of 0 will properly output at unknown/TiB. Alternatively, you could update formatCost to accept number | undefined.

Suggested change:

Suggested change
if (result.estimated_cost_usd != null) {
lines.push(`Estimated cost: ${formatCost(result.estimated_cost_usd)} (at ${formatCost(result.cost_per_tib_usd ?? 0)}/TiB)`)
}
if (result.estimated_cost_usd != null) {
lines.push(`Estimated cost: ${formatCost(result.estimated_cost_usd)} (at ${formatCost(result.cost_per_tib_usd ?? NaN)}/TiB)`)
}

Comment on lines +474 to +476
const costPerTib = params.cost_per_tib_usd ?? DEFAULT_COST_PER_TIB_USD
const estimatedCost =
estimate.bytesScanned != null ? (estimate.bytesScanned / TIB_BYTES) * costPerTib : undefined
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[🔵 LOW] Using != is prohibited according to code quality checks. Please use strict equality !== null && estimate.bytesScanned !== undefined or simply !== undefined depending on the exact types expected.

Suggested change:

Suggested change
const costPerTib = params.cost_per_tib_usd ?? DEFAULT_COST_PER_TIB_USD
const estimatedCost =
estimate.bytesScanned != null ? (estimate.bytesScanned / TIB_BYTES) * costPerTib : undefined
const costPerTib = params.cost_per_tib_usd ?? DEFAULT_COST_PER_TIB_USD
const estimatedCost =
estimate.bytesScanned !== undefined && estimate.bytesScanned !== null ? (estimate.bytesScanned / TIB_BYTES) * costPerTib : undefined

Comment on lines +14 to +16
const units = ["B", "KB", "MB", "GB", "TB", "PB"]
const i = Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), units.length - 1)
return `${(bytes / Math.pow(1024, i)).toFixed(i === 0 ? 0 : 2)} ${units[i]}`
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[🟠 MEDIUM] For byte values strictly between 0 and 1 (e.g., 0.5), Math.log(bytes) / Math.log(1024) evaluates to a negative number, causing Math.floor to return -1. This results in an out-of-bounds array access on units (units[-1]), returning undefined (e.g., 512.00 undefined).

Also, consider centralizing this function in a shared utilities file to avoid duplication (e.g., it is duplicated in finops-formatting.ts and sql-cost-estimate.ts). If keeping it here, enforce a minimum index of 0 to fix the edge case:

Suggested change:

Suggested change
const units = ["B", "KB", "MB", "GB", "TB", "PB"]
const i = Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), units.length - 1)
return `${(bytes / Math.pow(1024, i)).toFixed(i === 0 ? 0 : 2)} ${units[i]}`
const units = ["B", "KB", "MB", "GB", "TB", "PB"]
const i = Math.max(0, Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), units.length - 1))
return `${(bytes / Math.pow(1024, i)).toFixed(i === 0 ? 0 : 2)} ${units[i]}`

Comment on lines +38 to +41
const firewallEnabled = createMemo(() => {
const g = governance()
return !!g && (g.max_query_cost_usd != null || g.max_bytes_scanned != null)
})
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[🔵 LOW] The code quality checklist prohibits using loose inequality checks (!=). Use strict equality/inequality checks (!== undefined && ... !== null) instead.

Suggested change:

Suggested change
const firewallEnabled = createMemo(() => {
const g = governance()
return !!g && (g.max_query_cost_usd != null || g.max_bytes_scanned != null)
})
const firewallEnabled = createMemo(() => {
const g = governance()
return !!g && ((g.max_query_cost_usd !== null && g.max_query_cost_usd !== undefined) || (g.max_bytes_scanned !== null && g.max_bytes_scanned !== undefined))
})

Comment on lines +199 to +220
<Show when={governance()?.max_query_cost_usd != null}>
<box flexDirection="row" gap={1}>
<text flexShrink={0} style={{ fg: theme.success }}>
</text>
<text fg={theme.text}>
<b>Max cost</b>{" "}
<span style={{ fg: theme.textMuted }}>${governance()!.max_query_cost_usd!.toFixed(2)}/query</span>
</text>
</box>
</Show>
<Show when={governance()?.max_bytes_scanned != null}>
<box flexDirection="row" gap={1}>
<text flexShrink={0} style={{ fg: theme.success }}>
</text>
<text fg={theme.text}>
<b>Max scan</b>{" "}
<span style={{ fg: theme.textMuted }}>{formatBytes(governance()!.max_bytes_scanned!)}/query</span>
</text>
</box>
</Show>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[🔴 HIGH] In SolidJS, if the underlying reactive data changes and governance() returns undefined before the UI fully re-renders and unmounts, these non-null assertions (!) will cause a runtime crash because governance() is re-invoked within the children. It is safer to use optional chaining (?.) and nullish coalescing (??).

Additionally, replace the loose inequality checks (!= null) with strict checks (!== undefined && !== null) to adhere to the code quality rules.

Suggested change:

Suggested change
<Show when={governance()?.max_query_cost_usd != null}>
<box flexDirection="row" gap={1}>
<text flexShrink={0} style={{ fg: theme.success }}>
</text>
<text fg={theme.text}>
<b>Max cost</b>{" "}
<span style={{ fg: theme.textMuted }}>${governance()!.max_query_cost_usd!.toFixed(2)}/query</span>
</text>
</box>
</Show>
<Show when={governance()?.max_bytes_scanned != null}>
<box flexDirection="row" gap={1}>
<text flexShrink={0} style={{ fg: theme.success }}>
</text>
<text fg={theme.text}>
<b>Max scan</b>{" "}
<span style={{ fg: theme.textMuted }}>{formatBytes(governance()!.max_bytes_scanned!)}/query</span>
</text>
</box>
</Show>
<Show when={governance()?.max_query_cost_usd !== undefined && governance()?.max_query_cost_usd !== null}>
<box flexDirection="row" gap={1}>
<text flexShrink={0} style={{ fg: theme.success }}>
</text>
<text fg={theme.text}>
<b>Max cost</b>{" "}
<span style={{ fg: theme.textMuted }}>${governance()?.max_query_cost_usd?.toFixed(2)}/query</span>
</text>
</box>
</Show>
<Show when={governance()?.max_bytes_scanned !== undefined && governance()?.max_bytes_scanned !== null}>
<box flexDirection="row" gap={1}>
<text flexShrink={0} style={{ fg: theme.success }}>
</text>
<text fg={theme.text}>
<b>Max scan</b>{" "}
<span style={{ fg: theme.textMuted }}>{formatBytes(governance()?.max_bytes_scanned ?? 0)}/query</span>
</text>
</box>
</Show>

@dev-punia-altimate
Copy link
Copy Markdown
Contributor

🤖 Code Review — OpenCodeReview (Gemini) — 12 finding(s)

  • 12 anchored to a line (posted inline when the comment stream is on)
  • 0 without a line anchor
All findings (full text)

1. packages/drivers/src/bigquery.ts (L91-L92)

[🔵 LOW] According to the code quality guidelines, using == and != is prohibited. Please use strict equality checks (!== null && !== undefined) instead.

Suggested change:

      const raw = stats.totalBytesProcessed ?? stats.query?.totalBytesProcessed
      const bytesScanned = raw !== null && raw !== undefined ? Number(raw) : undefined

2. packages/drivers/src/snowflake.ts (L273)

[🔵 LOW] According to the review checklist, using == is prohibited. Please use strict equality === or check for both null and undefined.

Suggested change:

      if (raw === null || raw === undefined) {

3. packages/drivers/src/snowflake.ts (L286)

[🔵 LOW] According to the review checklist, using != is prohibited. Please use strict equality !== or check for both null and undefined.

Suggested change:

      const bytesScanned = assigned !== null && assigned !== undefined ? Number(assigned) : undefined

4. packages/opencode/src/altimate/native/connections/register.ts (L473-L476)

[🟠 MEDIUM] The generic cost estimation logic uses a BigQuery-specific default value (DEFAULT_COST_PER_TIB_USD = 6.25). If a caller runs this for a different warehouse type (e.g., Snowflake) without explicitly providing cost_per_tib_usd, it will silently use BigQuery's pricing. This could lead to misleading estimations since other warehouses use entirely different pricing models (e.g., Snowflake bills by compute credits, not data scanned). Consider making the default cost driver-specific or applying this default only when warehouseType === 'bigquery'.

Suggested change:

    const estimate = await connector.estimateCost(params.sql)
    // Only apply BigQuery's default pricing if the warehouse type is BigQuery.
    // Other warehouses should explicitly provide a cost factor or use driver-specific estimations.
    const defaultCostPerTib = warehouseType === "bigquery" ? DEFAULT_COST_PER_TIB_USD : undefined;
    const costPerTib = params.cost_per_tib_usd ?? defaultCostPerTib
    const estimatedCost =
      estimate.bytesScanned != null && costPerTib != null ? (estimate.bytesScanned / TIB_BYTES) * costPerTib : undefined

5. packages/opencode/src/altimate/tools/sql-execute.ts (L130-L131)

[🔵 LOW] According to the code quality standards, the use of == and != is prohibited. Please use strict equality (=== and !==) for null/undefined checks to ensure type safety. Since maxCost and maxBytes are derived from Zod .optional() schema definitions, checking against undefined is appropriate here.

Suggested change:

  // Disabled unless at least one threshold is set.
  if (maxCost === undefined && maxBytes === undefined) return

6. packages/opencode/src/altimate/tools/sql-execute.ts (L140-L143)

[🔵 LOW] Although failing open is intentional here to prevent blocking user work when estimation fails, completely swallowing the error with an empty catch block makes it difficult to diagnose system issues. It is recommended to log the error (e.g., using console.warn or the project's standard logger) for debugging purposes.

Suggested change:

  } catch (error) {
    // Estimation failed — fail open (run the query) rather than blocking work.
    console.warn("Cost estimation failed:", error)
    return
  }

7. packages/opencode/src/altimate/tools/sql-execute.ts (L146-L147)

[🔵 LOW] Please replace the non-strict != checks with strict equality (!==) to comply with the code quality guidelines that prohibit the use of == and !=.

Suggested change:

  const overCost = maxCost !== undefined && estimate.estimated_cost_usd !== undefined && estimate.estimated_cost_usd > maxCost
  const overBytes = maxBytes !== undefined && estimate.bytes_scanned !== undefined && estimate.bytes_scanned > maxBytes

8. packages/opencode/src/altimate/tools/sql-cost-estimate.ts (L54-L56)

[🟠 MEDIUM] If cost_per_tib_usd is undefined or missing, this evaluates to 0, which causes the UI output to display at $0.0000/TiB. This could be misleading to users as it implies the scan is free rather than the rate being unknown.

Since formatCost checks !Number.isFinite(usd), falling back to NaN instead of 0 will properly output at unknown/TiB. Alternatively, you could update formatCost to accept number | undefined.

Suggested change:

    if (result.estimated_cost_usd != null) {
      lines.push(`Estimated cost:       ${formatCost(result.estimated_cost_usd)} (at ${formatCost(result.cost_per_tib_usd ?? NaN)}/TiB)`)
    }

9. packages/opencode/src/altimate/native/connections/register.ts (L474-L476)

[🔵 LOW] Using != is prohibited according to code quality checks. Please use strict equality !== null && estimate.bytesScanned !== undefined or simply !== undefined depending on the exact types expected.

Suggested change:

    const costPerTib = params.cost_per_tib_usd ?? DEFAULT_COST_PER_TIB_USD
    const estimatedCost =
      estimate.bytesScanned !== undefined && estimate.bytesScanned !== null ? (estimate.bytesScanned / TIB_BYTES) * costPerTib : undefined

10. packages/opencode/src/cli/cmd/tui/component/dialog-status.tsx (L14-L16)

[🟠 MEDIUM] For byte values strictly between 0 and 1 (e.g., 0.5), Math.log(bytes) / Math.log(1024) evaluates to a negative number, causing Math.floor to return -1. This results in an out-of-bounds array access on units (units[-1]), returning undefined (e.g., 512.00 undefined).

Also, consider centralizing this function in a shared utilities file to avoid duplication (e.g., it is duplicated in finops-formatting.ts and sql-cost-estimate.ts). If keeping it here, enforce a minimum index of 0 to fix the edge case:

Suggested change:

  const units = ["B", "KB", "MB", "GB", "TB", "PB"]
  const i = Math.max(0, Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), units.length - 1))
  return `${(bytes / Math.pow(1024, i)).toFixed(i === 0 ? 0 : 2)} ${units[i]}`

11. packages/opencode/src/cli/cmd/tui/component/dialog-status.tsx (L38-L41)

[🔵 LOW] The code quality checklist prohibits using loose inequality checks (!=). Use strict equality/inequality checks (!== undefined && ... !== null) instead.

Suggested change:

  const firewallEnabled = createMemo(() => {
    const g = governance()
    return !!g && ((g.max_query_cost_usd !== null && g.max_query_cost_usd !== undefined) || (g.max_bytes_scanned !== null && g.max_bytes_scanned !== undefined))
  })

12. packages/opencode/src/cli/cmd/tui/component/dialog-status.tsx (L199-L220)

[🔴 HIGH] In SolidJS, if the underlying reactive data changes and governance() returns undefined before the UI fully re-renders and unmounts, these non-null assertions (!) will cause a runtime crash because governance() is re-invoked within the children. It is safer to use optional chaining (?.) and nullish coalescing (??).

Additionally, replace the loose inequality checks (!= null) with strict checks (!== undefined && !== null) to adhere to the code quality rules.

Suggested change:

          <Show when={governance()?.max_query_cost_usd !== undefined && governance()?.max_query_cost_usd !== null}>
            <box flexDirection="row" gap={1}>
              <text flexShrink={0} style={{ fg: theme.success }}>
                •
              </text>
              <text fg={theme.text}>
                <b>Max cost</b>{" "}
                <span style={{ fg: theme.textMuted }}>${governance()?.max_query_cost_usd?.toFixed(2)}/query</span>
              </text>
            </box>
          </Show>
          <Show when={governance()?.max_bytes_scanned !== undefined && governance()?.max_bytes_scanned !== null}>
            <box flexDirection="row" gap={1}>
              <text flexShrink={0} style={{ fg: theme.success }}>
                •
              </text>
              <text fg={theme.text}>
                <b>Max scan</b>{" "}
                <span style={{ fg: theme.textMuted }}>{formatBytes(governance()?.max_bytes_scanned ?? 0)}/query</span>
              </text>
            </box>
          </Show>

@dev-punia-altimate dev-punia-altimate marked this pull request as draft June 8, 2026 09:14
@dev-punia-altimate
Copy link
Copy Markdown
Contributor

🔴 1 critical finding(s) — converted back to draft

Address the critical items below, then mark this PR Ready for review to re-run the review. Medium/low findings are posted inline above and do not block.

  • packages/opencode/src/cli/cmd/tui/component/dialog-status.tsx:220 — In SolidJS, if the underlying reactive data changes and governance() returns undefined before the UI fully re-renders and unmounts, these non-null assertions (!) will cause a runtime crash becau

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants