feat(review): prompt_file_pattern + self-checkout guideline discovery#19
Conversation
…covery Adds a glob-based prompt_file_pattern input (mutually exclusive with prompt_file) so callers like datadog-agent can auto-discover per-directory guideline files instead of listing them explicitly. The discovery/scoping logic lives in src/guidelines.js and is exposed as a standalone bin/find-guidelines.js CLI so other repos can reuse the exact same implementation rather than reimplementing it. Also replaces the scan.js/guidelines.js heredocs in the workflow with a self-checkout of this action's own repo, pinned to job.workflow_sha, so the scripts are required directly instead of duplicated inline in the YAML.
…w run Points ai-review.yml at this branch and switches to prompt_file_pattern to exercise both the new job.workflow_repository/job.workflow_sha self-checkout and the glob-based guideline discovery end-to-end, with a small intentional bug (fibonacci off-by-one) for the reviewer to catch.
|
/dd-review |
1 similar comment
|
/dd-review |
There was a problem hiding this comment.
AI review by Claude - workflow run
Review summary
The change is well-structured and thoroughly tested: the prompt_file/prompt_file_pattern mutual-exclusivity guard, path-traversal protection, directory-prefix scoping, and built-in fallback are all preserved from the previous inline implementation and now shared between the workflow and the new find-guidelines CLI. The self-checkout of the action's own repo at job.workflow_sha is a sound way to avoid duplicating scan.js/guidelines.js, and its trust equivalence to the workflow file itself is accurate (the SHA is resolved from the caller's pinned uses: ref, not from PR content).
One genuine but low-severity issue: discoverPatternFiles returns matches in fs.readdirSync order, which is not guaranteed to be sorted. This makes the order of aggregated guidelines (and thus guidelinesBody) filesystem-dependent, unlike the explicit prompt_file list whose order is user-controlled. The docs claim the two inputs behave identically w.r.t. scoping, but pattern-discovered ordering is non-deterministic. Sorting the result would make output reproducible and also happens to place root-level guides first. This does not affect functional correctness of what gets included, only ordering.
Verdict: patch is correct. The feature works as designed and is well tested; the only finding is a non-blocking determinism nit. Confidence: 0.82.
…b.workflow_* gap fs.readdirSync order isn't guaranteed alphabetical, so guideline ordering was filesystem-dependent for prompt_file_pattern. Found via a real /dd-review dogfood run on this PR - Claude caught it. Also ignores actionlint's two false positives on job.workflow_repository/ job.workflow_sha: the runner shipped these in v2.334.0 but actionlint hasn't caught up yet (rhysd/actionlint#647, fix pending in #696).
|
/dd-review |
There was a problem hiding this comment.
AI review by Claude - workflow run
Review verdict: patch is incorrect
The workflow changes (adding prompt_file_pattern, extracting src/guidelines.js/src/scan.js via self-checkout, the find-guidelines CLI, and the accompanying tests) are well-structured, internally consistent, and thoroughly tested. The glob translation, scoping rule, mutual-exclusivity gating, and fallback behavior all look correct.
However, the newly added fibonacci.py (a fixture added in this PR to exercise the self-checkout review path) contains an off-by-one bug that makes its output wrong for the sequence it claims to compute. Since the file is introduced by this patch and produces incorrect results, the patch is incorrect.
Confidence: 0.9
| return 0 | ||
|
|
||
| a, b = 0, 1 | ||
| for _ in range(n - 1): |
There was a problem hiding this comment.
Off-by-one: for a 0-indexed sequence (as the docstring states: fib(0)=0, fib(1)=1, fib(2)=1, fib(3)=2), this loop iterates n-1 times and returns fib(n-1). fibonacci(1) returns 0 (should be 1) and fibonacci(3) returns 1 (should be 2). The loop must run n times.
| for _ in range(n - 1): | |
| for _ in range(n): |
Removes the fibonacci.py bug fixture and the now-redundant prompt.md (superseded by codereview_guideline.md via prompt_file_pattern). Points ai-review.yml back at @main now that testing on the feature branch is done - merging this PR will make main's own dogfood config pick up prompt_file_pattern for real.
…flict # Conflicts: # .github/workflows/ai-review.yml
Pointing at @main causes a startup_failure: main's code-review.yml doesn't declare prompt_file_pattern yet (only this branch does), so GitHub's reusable-workflow input validation rejects the call before any job runs. Will flip back to @main in a follow-up commit right after this PR merges, once main and code-review.yml are consistent again.
discoverPatternFiles walks the entire checked-out tree before filtering by isInScope - fine inside the GH workflow (sparse-checkout already pre-filters disk), but a real cost for the standalone CLI against a full local clone (e.g. dda review against datadog-agent's ~24k tracked files just to find a handful of guideline files). Adds discoverGuidelinesForChangedFiles: for each changed file, walks its directory up to the repo root, listing (and caching) only the directories actually visited - O(changedFiles * depth) instead of O(totalRepoFiles), and a directory shared by multiple changed files is only listed once. Verified equivalent to discoverPatternFiles + isInScope for the same inputs, and verified via readdirSync call-count assertions that it never visits a directory outside any changed file's ancestry. Addresses DataDog/datadog-agent#53149 (comment).
|
/dd-review |
There was a problem hiding this comment.
AI review by Claude - workflow run
Review verdict: patch is correct
This PR adds a prompt_file_pattern glob input (mutually exclusive with prompt_file), extracts guideline discovery/scoping/aggregation into a shared, well-tested src/guidelines.js, exposes it as a find-guidelines CLI, and replaces the inlined scan.js heredoc with a pinned self-checkout (job.workflow_sha) + cp.
I verified the following and found no actionable issues:
- Glob → regex (
globToRegExp) correctly handles**/,**,*,?, and literal-escapes metacharacters; consistent with the test matrix. - Walk-up discovery (
discoverGuidelinesForChangedFiles) is equivalent todiscoverPatternFiles + isInScope. The only theoretical divergence —isInScope'sf === dirbranch not being mirrored — is unreachable, since a changed-file path cannot also be a directory that contains a guideline. - Sparse-checkout with the pattern uses non-cone gitignore matching (matches root + nested), and
existsSyncguards keep the walk-up safe when intermediate dirs aren't materialized. - Self-checkout +
cp: bothsrc/scan.jsandsrc/guidelines.jsexist, so staging won't fail; the module-resolution anchorpackage.jsonis preserved. - Mutual exclusivity is enforced consistently in the gate,
buildGuidelines, and the CLI, with matching exit-code semantics. - Pattern-mode reads are contained within
trustedDir(paths come from directory listings; symlinks are excluded viaentry.isFile()). - README, actionlint ignore, workflow input definitions, and the prompt.md→codereview_guideline.md rename are internally consistent, and this repo's own root-level guide still always applies (no behavior regression).
Confidence: 0.85
Summary
prompt_file_pattern(glob-based guideline discovery, mutually exclusive withprompt_file), with the discovery/scoping logic extracted tosrc/guidelines.jsand exposed as a standalonebin/find-guidelines.jsCLI for reuse from other repos (e.g. datadog-agent's localdda reviewtask).scan.js/guidelines.jsheredocs in the workflow with a self-checkout of this action's own repo pinned tojob.workflow_sha, so the scripts arerequire()'d directly instead of duplicated inline in the YAML.Test plan (this PR is the test)
ai-review.ymlon this branch points at itself (@feat/prompt-file-pattern) and usesprompt_file_pattern: '**/codereview_guideline.md'instead ofprompt_file, to exercise both new mechanisms end-to-end via a real/dd-reviewrun.fibonacci.pyhas an intentional off-by-one bug for the reviewer to catch./dd-reviewafter opening and watch whetherprepare's new self-checkout step (job.workflow_repository/job.workflow_sha) actually resolves — this is a very recently shipped GitHub Actions feature andactionlintdoesn't even recognize it yet, so this PR is the real verification.🤖 Generated with Claude Code