Conversation
c6138e0 to
4b0d0ab
Compare
Auto-repair Agent Failed
The repair agent step failed before local verification ran. |
Auto-repair Started
Task prompt (3734 tokens)PR Repair Task: PR #151Before making changes, read Repair the existing PR branch in place. Do not create a new branch or PR. Context
Required OutcomeFix the currently failing checks shown below. Required Local VerificationThe workflow will rerun these commands before pushing. Your changes should make them pass: python3 scripts/dispatch-cops.py changed --base origin/main --head HEAD > "$REPAIR_CHANGED_COPS_FILE"
failed=0
while IFS= read -r cop; do
[ -z "$cop" ] && continue
echo "=============================="
echo "Checking: $cop (re-running against corpus)"
echo "=============================="
if ! python3 scripts/check-cop.py "$cop" --verbose --rerun --quick --clone; then
echo "FAIL: $cop regression detected"
failed=$((failed + 1))
fi
done < "$REPAIR_CHANGED_COPS_FILE"
test "$failed" -eq 0
Current PR Diff StatCurrent PR Diff Excerptdiff --git a/src/cop/style/mixin_usage.rs b/src/cop/style/mixin_usage.rs
index f297299bd..568a2a9e7 100644
--- a/src/cop/style/mixin_usage.rs
+++ b/src/cop/style/mixin_usage.rs
@@ -29,6 +29,11 @@ use crate::parse::source::SourceFile;
/// matches exactly ONE `const` argument. Multi-argument mixin calls like `include A, B, C`
/// don't match the pattern and are not flagged. nitrocop was incorrectly accepting any number
/// of const arguments. Fixed by requiring exactly one argument in the const check.
+///
+/// Corpus investigation (round 5): 3 FPs from `include` inside `BEGIN {}` blocks
+/// (Prism: PreExecutionNode). `BEGIN {}` is not in RuboCop's transparent wrapper list
+/// (`{kwbegin begin if def}`), so it creates an opaque scope. Fixed by adding
+/// `visit_pre_execution_node` as an opaque scope handler.
pub struct MixinUsage;
const MIXIN_METHODS: &[&[u8]] = &[b"include", b"extend", b"prepend"];
@@ -220,6 +225,13 @@ impl<'pr> Visit<'pr> for MixinUsageVisitor<'_> {
ruby_prism::visit_case_match_node(self, node);
self.in_opaque_scope = prev;
}
+
+ fn visit_pre_execution_node(&mut self, node: &ruby_prism::PreExecutionNode<'pr>) {
+ let prev = self.in_opaque_scope;
+ self.in_opaque_scope = true;
+ ruby_prism::visit_pre_execution_node(self, node);
+ self.in_opaque_scope = prev;
+ }
}
#[cfg(test)]
diff --git a/tests/fixtures/cops/style/mixin_usage/no_offense.rb b/tests/fixtures/cops/style/mixin_usage/no_offense.rb
index 173609fe3..9682f6a0c 100644
--- a/tests/fixtures/cops/style/mixin_usage/no_offense.rb
+++ b/tests/fixtures/cops/style/mixin_usage/no_offense.rb
@@ -53,3 +53,7 @@ module N
include GravatarHelper, GravatarHelper::PublicMethods, ERB::Util
extend A, B
prepend X, Y, Z
+# include inside BEGIN {} block is NOT flagged by RuboCop (PreExecutionNode is opaque)
+BEGIN {
+ include UtilityFunctions
+}Local Corpus ContextThese corpus oracle artifacts are already downloaded locally by the workflow.
Use these files directly with the repo scripts when you need corpus context. python3 scripts/investigate-cop.py Department/CopName --input /home/runner/work/_temp/agent-pr-repair/repair/corpus-standard.json --context
python3 scripts/check-cop.py Department/CopName --input /home/runner/work/_temp/agent-pr-repair/repair/corpus-standard.json --verbose --rerun --quick --cloneFailed Checks Packetcop-check
Constraints
Available Local Helper ScriptsThese helper scripts are available in this CI checkout. Prefer the stable top-level CLI paths shown below over ad hoc commands when they directly help with diagnosis or validation.
Typical usage when present: python3 scripts/check-cop.py Department/CopName --verbose --rerun --quick --clone
python3 scripts/dispatch-cops.py changed --base origin/main --head HEAD
python3 scripts/investigate-cop.py Department/CopName --context
python3 scripts/verify-cop-locations.py Department/CopName
python3 scripts/corpus-smoke-test.py --binary target/release/nitrocopLocal Cop-Check DiagnosisThe workflow already reran the changed-cop corpus check locally before agent execution. Changed cops:
Style/MixinUsageStart here:
Oracle context from CI corpus artifact:
/usr/bin/python3 scripts/check-cop.py Style/MixinUsage --verbose --rerun --quick --cloneExit status: |
Auto-repair Agent Failed
The repair agent step failed before local verification ran. |
Automated fix fix for
Style/MixinUsagecorpus conformance.Details
Style/MixinUsageResult
Changes
Agent conversation excerpt
All 3 FPs are
includeinsideBEGIN {}blocks (Prism:PreExecutionNode). This isn't in RuboCop's transparent wrapper list, so it should be an opaque scope. Let me fix this.Now let me check if Prism has a
PreExecutionNodevisitor method.Good. The fix is clear: add
visit_pre_execution_nodeas an opaque scope in the MixinUsage visitor. Let me add the test case first, then fix the code.Now let me add the fixture and fix the code.
Now verify the test fails before the fix:
Test fails as expected. Now add
visit_pre_execution_nodeas an opaque scope:Now add the doc comment for this round:
Both tests pass. Now let me format the changed file and commit.
BEGIN {}(Prism:`Fix complete. The issue was that
BEGIN {}blocks (Prism'sPreExecutionNode) weren't being treated as opaque scopes. RuboCop'sin_top_level_scope?only considers{kwbegin begin if def}as transparent wrappers —BEGIN {}isn't in that list, so mixin calls inside it shouldn't be flagged. Addedvisit_pre_execution_nodeto mark it as opaque, fixing all 3 FPs.Task prompt (5947 tokens)
Fix Style/MixinUsage — 3 FP, 0 FN
Cross-Corpus Risk
Risk class: extended-only edge case against a standard-perfect baseline.
Treat the extended examples as a narrow edge case, not proof that the broad pattern is safe.
Any carve-out that reduces the extended FP/FN count but regresses the standard corpus is a bad fix.
Prefer the smallest context-specific change you can justify from RuboCop behavior and the vendor spec.
This is concentrated in only a few repos, which increases the risk of overfitting to one local shape.
Instructions
You are fixing ONE cop in nitrocop, a Rust Ruby linter that uses Prism for parsing.
Current state: 2,834 matches, 3 false positives, 0 false negatives.
Focus on: FP (nitrocop flags code RuboCop does not).
Workflow
behavior on BOTH the specific FP case AND the general pattern:
tests/fixtures/cops/style/mixin_usage/offense.rbwith^annotationtests/fixtures/cops/style/mixin_usage/no_offense.rbcargo test --lib -- cop::style::mixin_usagesrc/cop/style/mixin_usage.rscargo test --lib -- cop::style::mixin_usage///doc comment on the cop struct documenting what you found and fixedFixture Format
Mark offenses with
^markers on the line AFTER the offending source line:The
^characters must align with the offending columns. The message format isStyle/MixinUsage: <message text>.If your test passes immediately
If you add a test case and it passes without code changes, the corpus mismatch is
caused by config/context differences, not a detection bug.
Do NOT loop trying to make the test fail. Instead:
src/config/or the cop's config handling, not detection logica
///comment on the cop struct and commitCRITICAL: Avoid regressions in the opposite direction
When fixing FPs, your change MUST NOT suppress legitimate detections. When fixing FNs,
your change MUST NOT flag code that RuboCop accepts. A fix that eliminates a few issues
in one direction but introduces hundreds in the other is a catastrophic regression.
Before exempting a category of patterns, verify with RuboCop that the general case
is still an offense:
If RuboCop flags the general pattern but not your specific case, the difference is in
a narrow context (e.g., enclosing structure, receiver type, argument count) — your fix
must target that specific context, not the broad category.
Rule of thumb: if your fix adds an early
returnorcontinuethat skips a wholenode type, operator class, or naming pattern, it's probably too broad. Prefer adding a
condition that matches the SPECIFIC differentiating context.
Rules
src/cop/style/mixin_usage.rsandtests/fixtures/cops/style/mixin_usage/cargo test --lib -- cop::style::mixin_usageto verify your fix (do NOT run the full test suite)git stashPrism Notes
Foo) and ConstantPathNode (qualifiedFoo::Bar). If you handle one, check if you need the other.Start Here
Use the existing corpus data to focus on the most concentrated regressions first.
Helpful local commands:
python3 scripts/investigate-cop.py Style/MixinUsage --repos-onlypython3 scripts/investigate-cop.py Style/MixinUsage --contextpython3 scripts/verify-cop-locations.py Style/MixinUsageTop FP repos:
ged__linguistics__b0b119c(3 FP) — exampleexperiments/conjunct-with-block.rb:13Representative FP examples:
ged__linguistics__b0b119c: experiments/conjunct-with-block.rb:13—includeis used at the top level. Use insideclassormodule.ged__linguistics__b0b119c: experiments/lafcadio_plural.rb:13—includeis used at the top level. Use insideclassormodule.ged__linguistics__b0b119c: experiments/lprintf.rb:17—includeis used at the top level. Use insideclassormodule.Pre-diagnostic Results
Diagnosis Summary
Each example was tested by running nitrocop on the extracted source in isolation
with
--force-default-configto determine if the issue is a code bug or config issue.Note: source context is truncated and may not parse perfectly. If a diagnosis
seems wrong (e.g., your test passes immediately for a 'CODE BUG'), treat it as
a config/context issue instead.
FP #1:
ged__linguistics__b0b119c: experiments/conjunct-with-block.rb:13CONFIRMED false positive — CODE BUG
nitrocop incorrectly flags this pattern in isolation.
Fix the detection logic to not flag this.
Enclosing structure: BEGIN {} block (Prism: PreExecutionNode) (line:
BEGIN {)The offense is inside this structure — this is likely WHY
RuboCop does not flag it. Your fix should detect this context.
Full source context (add relevant parts to no_offense.rb):
Message: ``include
is used at the top level. Use insideclass` or `module`.`FP #2:
ged__linguistics__b0b119c: experiments/lafcadio_plural.rb:13CONFIRMED false positive — CODE BUG
nitrocop incorrectly flags this pattern in isolation.
Fix the detection logic to not flag this.
Enclosing structure: BEGIN {} block (Prism: PreExecutionNode) (line:
BEGIN {)The offense is inside this structure — this is likely WHY
RuboCop does not flag it. Your fix should detect this context.
Full source context (add relevant parts to no_offense.rb):
Message: ``include
is used at the top level. Use insideclass` or `module`.`FP #3:
ged__linguistics__b0b119c: experiments/lprintf.rb:17CONFIRMED false positive — CODE BUG
nitrocop incorrectly flags this pattern in isolation.
Fix the detection logic to not flag this.
Enclosing structure: BEGIN {} block (Prism: PreExecutionNode) (line:
BEGIN {)The offense is inside this structure — this is likely WHY
RuboCop does not flag it. Your fix should detect this context.
Full source context (add relevant parts to no_offense.rb):
Message: ``include
is used at the top level. Use insideclass` or `module`.`Current Rust Implementation
src/cop/style/mixin_usage.rsRuboCop Ruby Implementation (ground truth)
vendor/rubocop/lib/rubocop/cop/style/mixin_usage.rbRuboCop Test Excerpts
vendor/rubocop/spec/rubocop/cop/style/mixin_usage_spec.rbCurrent Fixture: offense.rb
tests/fixtures/cops/style/mixin_usage/offense.rbCurrent Fixture: no_offense.rb
tests/fixtures/cops/style/mixin_usage/no_offense.rb