Uh oh!
There was an error while loading. Please reload this page.
feat(agent): add dbt-optimizer agent — 6-lane dbt project optimization with evals - #1092
Open
anandgupta42 wants to merge 23 commits into
Open
feat(agent): add dbt-optimizer agent — 6-lane dbt project optimization with evals#1092anandgupta42 wants to merge 23 commits into
anandgupta42 wants to merge 23 commits into
Conversation
Loading
Uh oh!
There was an error while loading. Please reload this page.
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Issue for this PR
Closes#1091
Type of change
What does this PR do?
Adds
dbt-optimizer, a 5th native primary agent that scans a dbt project for fixable issues and proposes targeted fixes with cost/impact reporting (the agent behind the planned Optimize workflow). Four parts:1. Agent registration (
agent.ts). Deny-by-default permission allowlist: read/analysis/finops tools allowed,editandbashprompt per action,sql_execute_writedenied. The deny is re-applied after the global user-config merge AND after the per-agent config merge — permission evaluation is last-match-wins, so without the second re-applicationagent."dbt-optimizer".permission.sql_execute_write: "allow"would have silently won (regression tests cover both paths). Nameddbt-optimizerrather thanoptimizerbecause more optimizer agents are planned; no alias shim needed since nothing shipped under the old name.2. Prompt (
prompts/dbt-optimizer.txt). Encodes the taxonomy fromdocs/internal/2026-08-12-dbt-optimization-taxonomy-research.md: 6 detection lanes, an evidence-attribution ladder (invocation-ID/query-tag down to lineage-match, with confidence labeling), ROI-ranked triage, cost-honesty rules ("not estimable" is a valid answer; never invent dollar figures), a 4-phase loop that stops after scan for candidate selection, and an auto-fix vs propose-only boundary. Builder's self-review gains a dbt-scoped "Optimization handoff" nudge — primary agents are excluded from the task tool (task.tsfiltersmode !== "primary"), so the nudge is the only build-time bridge and auto-delegation of cost-incurring scans is deliberately NOT wired.3. Verification-tool fixes. Three latent bugs in existing tools the agent's core promises depend on, found during review: the rewrite verify gate trusted
equivalent: trueeven when the engine saiddecidable: false(now UNDECIDABLE = unproven, everywhere it surfaces);sql_explain analyze:trueexecutes the statement on Postgres/MySQL/DuckDB/Trino and had no statement-class guard (now blocked for anything non-read-only, includingSELECT ... INTO); thesql_diffwrapper read response fields the native handler never returns, so every comparison reported "identical".4. Evals. Tier 1 (CI): 20 deterministic tests asserting the prompt's non-negotiable invariants (whitespace-normalized so reflow doesn't break them) plus an evidence-chain suite proving each planted fixture issue is genuinely detectable. Tier 2 (opt-in): a live eval that runs the compiled binary against a 7-model DuckDB fixture with 6 planted issues (incremental candidate, dead model, SELECT * propagation, ORDER BY, verbatim-duplicated CTE ×3, untested model) and grades deterministically — ≥4/6 recall with directional signal phrases, exit-code check, and a tree-snapshot proving the scan modified/removed/added nothing. Answer key lives outside the scanned directory.
How did you verify your code works?
tsgo --noEmitclean; upstream marker check clean (--markers --base main --strict); oxlint 0 errors on changed files.Screenshots / recordings
Not a UI change — the agent appears in the existing Tab ring/agent list.
Checklist
🤖 Generated with Claude Code
Summary by cubic
Adds the
dbt-optimizeragent for evidence-backed dbt project scans and tightens permission, SQL-safety, and path-gating so read-scoped scans cannot write or exfiltrate. Old: stored “always allow” approvals and tool exposure could bypass agent denies, EXPLAIN ANALYZE could execute writes, and out-of-project paths weren’t uniformly gated; New: non‑overridable denies hold across sessions, EXPLAIN ANALYZE requires write approval, and all analysis paths gate through a canonicalized external-directory check.dbt-optimizerwith deny-by-default;edit/bashask;sql_execute_writeis non‑overridable. Built-in tool exposure now honors denies viaPermission.disabled, with edit-tool remaps to keepapply_patch/patch/multiedit underedit.*catch‑all), so ceilings hold without clobbering allowlists.sql_explainblocks multi‑statement input and now requiressql_execute_writeapproval foranalyze:true, falling back to estimated plans on denial.sql_diff: LCS line diffs with hunk context; forwardsschema_context/dialect; returnsequivalence_assessed,decidable, and never treats UNDECIDABLE as equivalent. Engine failures no longer erase the text diff.parse-dbt, and allschema_pathwrappers resolve paths relative to the project, canonicalize symlinks before gating, pass the same real path to reads, and propagate permission rejections.unique_id; target matching acceptsunique_id; affected tests counted byunique_id.revieweranddbt-optimizer. Equivalence abstentions (decidable:false) report UNDECIDABLE, not ERROR, even with validation errors.Written for commit 54d2df6. Summary will update on new commits.
Summary by CodeRabbit
New Features
dbt-optimizeragent for evidence-based analysis and approval-gated fixes.Bug Fixes
Documentation
Note
High Risk
Touches permission evaluation (deny vs stored “always” approvals), SQL write classification, EXPLAIN ANALYZE execution, and external path gating—security-critical warehouse and filesystem surfaces.
Overview
Adds
dbt-optimizer, a fifth primary agent that scans a dbt project in four phases (read-only scan → user-selected fixes → impact report → optional PR) with a deny-by-default allowlist: analysis/finops tools allowed,edit/bashask, andsql_execute_writedenied non-overridably even after user/agent config merge. Builder’s self-review now hands off optimizer-shaped issues instead of fixing them out of scope.Hardens the permission and tool surface the agent depends on. Stored “always” approvals no longer override a configured deny. Path-taking dbt/core tools go through a shared
external_directorygate (symlink-canonicalized).schema_indexand training save/remove prompt before mutating persistent state.SQL safety: a lexer-based masker drives write classification (side-effect functions, comment/literal bypasses, CR line endings).
sql_explain analyze:trueis limited to a single read-only statement and requiressql_execute_write. Equivalence/rewrite/sql_diffnow distinguish UNDECIDABLE from proven equivalent, use LCS diffs, and no longer treat engine abstention as a false safety claim. Impact analysis traverses by dbtunique_idso package-colliding names are not dropped. Docs list Reviewer and dbt-Optimizer alongside the existing modes.Reviewed by Cursor Bugbot for commit 54d2df6. Bugbot is set up for automated code reviews on this repo. Configure here.