Repository navigation
fix(scripts): lint the agent's checkout in the oracle lint hooks - #2282
Conversation
The agent hooks ran the script of the checkout where the session started and linted that checkout, even when the agent worked in a worktree under `.worktrees/`. Plain directories under `.worktrees/` also counted as new work on the launch checkout's branch, so the stop hook returned thousands of reports for files that no session changed. The hooks now resolve the checkout from the hook input's `cwd`. When that checkout has its own copy of the script, the copy runs, so a branch is linted by its own rule. `.gitignore` lists `/.worktrees/`. The lint-scope oracle now draws a launch or worktree session and a scratch directory, runs the stop hook as well, and checks that every report comes from the session checkout's own rule. Fixes #2280. Co-authored-by: Isaac <no-reply@databricks.com>
|
|
No actionable comments were generated in the recent review.
|
| Layer / File(s) | Summary |
|---|---|
Checkout selection and lint execution scripts/agent-lint-feedback.mjs, scripts/check-oracle-run-counts.mjs, .gitignore, docs/contributing/oracle-coverage.md |
The script resolves the session checkout from hook input and delegates to its script when available. Changed-file and budget calculations use the selected checkout. Git ignores root-level .worktrees/ contents, and the documentation describes checkout selection and its boundaries. |
Checkout and hook scope oracle scripts/lint-scope-oracle.property.test.js |
The property test models launch-checkout and worktree sessions. It checks changed, named, edit-hook, and stop-hook scopes, report marks, and coverage of worktree and scratch-directory cases. |
Priority:
Estimated code review effort: 3 (Moderate) | ~25 minutes
Change: Bug fix · Severity of issue fixed: Medium
Sequence Diagram(s)
sequenceDiagram
participant ClaudeHook
participant LaunchScript as agent-lint-feedback.mjs
participant Git
participant SessionScript as Session checkout script
ClaudeHook->>LaunchScript: Provide hook input with cwd
LaunchScript->>Git: Resolve repository at cwd
alt Session checkout has its own script
LaunchScript->>SessionScript: Delegate with arguments and hook input
SessionScript->>Git: Select changed files and merge base in session checkout
else No distinct session script
LaunchScript->>Git: Select files and merge base from selected root
end
Possibly related issues
- Enforce oracle-first work: oracle lint rules, CI checks, and agent feedback hooks #2234 — The pull request changes checkout selection in the agent feedback hook script introduced for the hook behavior described by this issue.
Possibly related PRs
- TanStack/db#2236 — Adds the hook script and original changed-file selection that this pull request modifies.
- TanStack/db#2233 — Adds
createOracleReach, which the property test uses to require worktree and scratch-directory coverage. - TanStack/db#2237 — Changes shared oracle campaign and run-budget helpers used by the lint-scope oracle.
Suggested reviewers: tannerlinsley
Merge Risk: 
Minimal · up to e405e
-
The reviewed changes have no identified issue that needs resolution before merge. Normal checks remain appropriate.
Pre-merge checks: 
5
-
Full details: Linked Issues check
-
Explanation
Issue
#2280is directly linked and active. The implementation resolves the checkout from hook inputcwdwith a script-location fallback inscripts/agent-lint-feedback.mjs. It delegates to the selected checkout's own script when that copy exists. Changed-file, oracle-file, run-budget, andmergeBaseoperations use the selected checkout..gitignoreexcludes/.worktrees/, so plain scratch directories do not enter the launch checkout's untracked-file set. The property test exercises launch sessions, worktree sessions, scratch directories, edit hooks, and stop hooks. The documented acceptance case forpnpm lint:changedremains supported because the command uses the script in its current checkout.
Full details: Out of Scope Changes check
-
Explanation
The changes stay within Issue
#2280. The updates toscripts/check-oracle-run-counts.mjs, the property test, coverage documentation, and.gitignoredirectly support checkout selection, rule selection, worktree isolation, and verification. No unrelated product or release changes are present.
Full details: Docstring Coverage
-
Explanation
Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 12 functions across 3 files. (2 skipped: 2 unsupported.)
-
Finishing Touches
-
📝 Generate docstrings
-
- Commit to this branch
- Create a new PR
🧪 Generate unit tests (beta)
-
- Commit to this branch
- Create a new PR
-
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
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.
Comment @coderabbitai help to get the list of available commands.
More templates
@tanstack/angular-db
@tanstack/browser-db-sqlite-persistence
@tanstack/capacitor-db-sqlite-persistence
@tanstack/cloudflare-durable-objects-db-sqlite-persistence
@tanstack/convex-db-collection
@tanstack/db
@tanstack/db-ivm
@tanstack/db-sqlite-persistence-core
@tanstack/electric-db-collection
@tanstack/electron-db-sqlite-persistence
@tanstack/expo-db-sqlite-persistence
@tanstack/node-db-sqlite-persistence
@tanstack/offline-transactions
@tanstack/powersync-db-collection
@tanstack/preact-db
@tanstack/query-db-collection
@tanstack/react-db
@tanstack/react-native-db-sqlite-persistence
@tanstack/react-router-with-db
@tanstack/rxdb-db-collection
@tanstack/solid-db
@tanstack/svelte-db
@tanstack/tauri-db-sqlite-persistence
@tanstack/trailbase-db-collection
@tanstack/vue-db
commit: |
|
Size Change: 0 B Total Size: 237 kB ℹ️ View Unchanged
|
🎯 Changes
The oracle lint hooks now lint the checkout that the agent works in. Fixes #2280.
Before this change, a session that started in the main checkout ran the main checkout's
scripts/agent-lint-feedback.mjs. The script took its root from its own location, so the hooks linted the main checkout while the agent worked in.worktrees/<name>. Also, a plain directory under.worktrees/has no.gitentry, so git listed each of its files as new work on the main checkout's branch. The stop hook then returned thousands of reports for scratch copies and snapshots that no session changed.This PR makes three changes:
cwdwithgit rev-parse --show-toplevel. Withoutcwd, it uses the checkout that holds the script, as before.mergeBaseuse the same checkout..gitignorelists/.worktrees/.pnpm lint:changedand the pre-commit hook do not change: they run the script of the checkout they are in.🔬 Oracle Coverage
Owner:
scripts/lint-scope-oracle.property.test.js(scripts.lint-scope).cwdnames, with that checkout's own rule. A plain directory under.worktrees/is never one of the launch checkout's changed files. Authority: the acceptance criteria in Agent stop hook lints other directories under .worktrees/ instead of the current worktree #2280, and AGENTS.md "Lint feedback while you work"..worktrees/wtand runs the stop hook as well as the edit hook, both from the launch checkout's script. It copies the repository's.gitignoreinto each temporary repository. When a branch edits the rule, the driver marks the rule's message in that copy only, so each report shows which checkout's rule made it. In 48 histories:worktree-session25,worktree-own-rule8,scratch-directory13. The earlier 15 states are still reached.main, the fixed-seed campaign failed for a launch session with a scratch directory (scratch-oracle.test.tsreported). The random-seed campaign failed for a worktree session (expected[case-0-oracle.test.js], observed[]).vitest run --config scripts/oracle-scripts.vitest.config.mjs scripts/lint-scope-oracle.property.test.jspasses both campaigns.pnpm test:lint-rulespasses 231 rule tests and 10 script-oracle tests, andpnpm lint:oraclesreports nothing.process.cwd(): worktree selection empty.gitignorewithout/.worktrees/: scratch file reportedcwd, a worktree outside the launch checkout, or a worktree branch with no copy of the script. In that last case the launch checkout's rule lints the worktree. The coverage map records these limits.✅ Checklist
pnpm test.The tooling suites above pass. As a live check, this branch's stop hook with
cwdset to another worktree ran that worktree's own script. It reported only that branch's budget notices, and no file under.worktrees/.🚀 Release Impact
This pull request and its description were written by Isaac.
Summary by CodeRabbit
.worktrees/directories are now ignored by Git.