fix(review): an honest PR comment: real lint-only banner, AI lane status, PR intent, project_dir

RA
11h ago
+419-29

Issue for this PR

Closes #

Stacked on #1719; please review and merge that one first. Takes ideas from the closed #1241, not its code.

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

The review comment could misstate what it checked:

  • Lint-only banner: a single undecidable finding set degraded, so every manifest-backed run said "Lint-only run โ€” no dbt manifest". Now it shows only when no changed model resolved against a manifest. Undecidable findings, models without compiled SQL, and files outside the project each get their own line.
  • Silent AI lane: the lane returned [] on every failure, so an expired key, a timeout, or a missing model looked like "no AI findings". It now reports ok | skipped | timeout | error with a reason (credentials masked), the model, and duration. These land in a new signed ai field and in the comment. The timeout now scales with prompt size (60 s + 1 s per 2K chars, capped at 5 min) instead of a fixed 60 s. --ai-model provider/model picks the model explicitly.
  • No PR intent: prTitle/prBody existed but nothing passed them. The CLI now reads them from the GitHub pull_request event, or from GitLab's CI_MERGE_REQUEST_TITLE/_DESCRIPTION.
  • Action: new project_dir input, mapped to --cwd, for monorepos.
  • Docs: a table of what each input unlocks (fetch depth, manifest, compiled SQL, target-base/, catalog.json) and a snippet for compiling the base.
  • Telemetry: review_run gains undecided, unverified_models, ai_state, ai_duration_ms, base_source, out_of_scope_files.

Open question, deliberately not changed: --no-ai still auto-registers the free tier, which is a network call. A release test asserts that on purpose, so the decision is the maintainers'. Changing it is a one-line guard.

How did you verify your code works?

  • New test/altimate/review-ci-honesty.test.ts (13 tests):
    • banner with and without a manifest
    • AI lane: disabled, outside the tier, timeout (signature still verifies), throwing, ok with model and selector, legacy array return
    • timeout scaling
    • PR context from GitHub and GitLab env, and its forwarding to the lane
  • 1,859 tests across the review files and release gates pass. bun typecheck is clean.

Cost side effects

None. The AI lane's timeout ceiling can rise from 60 s to 5 min on very large prompts, but the number of model calls doesn't change (still at most one per review).

Screenshots / recordings

N/A (CLI).

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR
  • I checked for cost side effects (model calls, queries or cloud resources that grow with user data) and described them, or wrote "none"

๐Ÿค– Generated with Claude Code


Summary by cubic

Makes the dbt PR review comment candid about what it checked. Previously a single undecidable finding labeled any manifest-backed run as "Lint-only", and the advisory AI lane returned [] on every failure, so an expired key, timeout, or missing model looked like "no AI findings".

Review honesty

  • The lint-only banner now shows only when no changed model resolved against a manifest; undecidable findings, models without compiled SQL, and out-of-scope files each get their own line.
  • The AI lane now reports ok | skipped | timeout | error with a masked reason, model, and duration, on a new signed ai envelope field and in the comment; it never fails silently.
  • The AI timeout scales with prompt size (60 s + 1 s per 2K chars, capped at 5 min); --ai-model provider/model selects the model explicitly.
  • The CLI passes the PR title and body to the intent check, reading them from GitHub's pull_request event or GitLab's CI_MERGE_REQUEST_TITLE/_DESCRIPTION.

Inputs, docs, and telemetry

  • New project_dir input maps to --cwd for monorepos.
  • review_run telemetry gains undecided, unverified_models, ai_state, ai_duration_ms, base_source, and out_of_scope_files.
  • Docs now list what each input unlocks and how to compile the base into target-base/.

Deliberately unchanged: --no-ai still auto-registers the free tier, which is a network call; a release test asserts that, so the decision is the maintainers'. Model call count is unchanged (still at most one per review); only the timeout ceiling rises, to 5 minutes on very large prompts.