Skip to content

feat(linters): add readerstringconv analyzer - #71891

Merged
pelikhan merged 5 commits into
mainfrom
copilot/linter-minerreaderstringconv
Oct 25, 2026
Merged

pelikhan merged 5 commits into
mainfrom
copilot/linter-minerreaderstringconv

Conversation

Copilot AI commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

Adds readerstringconv to flag string/byte conversions used only to select a reader type, avoiding unnecessary copies.

strings.NewReader(string(b)) // Prefer bytes.NewReader(b)
bytes.NewReader([]byte(s))   // Prefer strings.NewReader(s)
  • Detection: Type-aware matching handles parentheses and import aliases; honors suppression directives, generated/test-file exclusions, and coverage gating.
  • Safety: Diagnostic-only—switching readers changes concrete types and may remove a defensive copy.
  • Integration: Registers through linters.All(), synchronizes documentation and spec coverage, and adds focused regression cases. CI enforcement remains deferred pending an audit.

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Add readerstringconv analyzer feat(linters): add readerstringconv analyzer Oct 25, 2026
Copilot AI requested a review from pelikhan October 25, 2026 13:03
@pelikhan
pelikhan marked this pull request as ready for review October 25, 2026 13:05
Copilot AI max review requested due to automatic review settings October 25, 2026 13:05

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

Static review found no blocking issues in the diagnostic-only analyzer, regression fixtures, or registration and documentation updates.

No open issues 🎉

1 file not reviewed
  • pkg/linters/readerstringconv/testdata/src/readerstringconv/generated.go: Generated file
What changed in this PR

Adds readerstringconv to gh-aw’s custom Go linter suite to flag avoidable string/byte conversions when constructing readers.

Changes:

  • Adds type-aware detection with suppression, file exclusions, and coverage gating.
  • Adds regression fixtures for supported conversions and cases that should not report.
  • Registers and documents the analyzer while deferring CI enforcement pending an audit; no automatic fixes are offered.
File Description
pkg/​linters/​spec_test.go Adds the analyzer to specification coverage.
pkg/​linters/​registry.go Registers the analyzer in the shared list.
pkg/​linters/​README.md Documents behavior, safety considerations, and coverage gating.
pkg/​linters/​readerstringconv/​testdata/​src/​readerstringconv/​readerstringconv.go Covers conversions, parentheses, aliases, shadowing, and suppression.
pkg/​linters/​readerstringconv/​testdata/​src/​readerstringconv/​readerstringconv_test.go Verifies test-file exclusion.
pkg/​linters/​readerstringconv/​testdata/​src/​readerstringconv/​generated.go Verifies generated-file exclusion.
pkg/​linters/​readerstringconv/​testdata/​src/​readerstringconv/​dot_import.go Covers dot-import detection.
pkg/​linters/​readerstringconv/​testdata/​src/​readerstringconv/​aliased_import.go Covers aliased imports.
pkg/​linters/​readerstringconv/​readerstringconv.go Implements diagnostic-only detection and reporting gates.
pkg/​linters/​readerstringconv/​readerstringconv_test.go Adds the analyzer test harness.
pkg/​linters/​doc.go Updates the analyzer list and count.
pkg/​linters/​doc_sync_test.go Records deferred CI enforcement.

Review effort: Max

@github-actions

github-actions Bot commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

✅ Design Decision Gate 🏗️ completed the design decision gate check. See the comment below for the result and any generated ADR draft.

Commit pushed: 231d1a2

🏗️ ADR gate enforced by Design Decision Gate 🏗️

@github-actions

github-actions Bot commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

✅ Test Quality Sentinel completed test quality analysis.

Test Quality Sentinel

Outcome: reported_no_action

The agent completed and reported no action. A no-op output alone does not verify that all required work was completed or that publication was possible.

Agent messages are omitted from this comment. The category uses structured run status, not interpretation of agent prose.

Generated from Test Quality Sentinel · sonnet50 · ~15 AIC · ⌖ ~16 AIC · ◇ ~8 AIC · ⊞ 12.7K · ◷

🧪 Test quality analysis by Test Quality Sentinel

@github-actions

github-actions Bot commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer

@github-actions

github-actions Bot commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

✅ Ponytail Reviewer completed successfully!

Ponytail Reviewer

Outcome: reported_no_action

The agent completed and reported no action. A no-op output alone does not verify that all required work was completed or that publication was possible.

Agent messages are omitted from this comment. The category uses structured run status, not interpretation of agent prose.

Generated from Ponytail Reviewer · gpt56 · ~7 AIC · ⌖ ~6 AIC · ⊞ 14.8K · ◷

Generated by Ponytail Reviewer for #71891

@github-actions

github-actions Bot commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

✅ PR Code Quality Reviewer completed the code quality review.

🔎 Code quality review by PR Code Quality Reviewer

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review summary

No actionable correctness, security, performance, or maintainability issues were identified in the changed lines. The analyzer's type-aware matching, suppression handling, generated-file filtering, coverage gating, registry integration, and focused test fixtures are consistent with the surrounding linter infrastructure.

🔎 Code quality review by PR Code Quality Reviewer · copilot · gpt50 · ~2 AIC · ⌖ ~1 AIC · ⊞ 1.6K
Comment /review to run again

@github-actions

Copy link
Copy Markdown
Contributor

🏗️ Design Decision Gate — ADR Required

This PR makes significant changes to core business logic (211 new lines in pkg/) but does not have a linked Architecture Decision Record (ADR).

📄 Draft ADR committed: docs/adr/71891-add-readerstringconv-linter.md. Review and complete it before merging.

The draft records the main design choice: readerstringconv is diagnostic-only, with no autofix. Switching between strings.NewReader and bytes.NewReader changes the concrete reader type and can remove a defensive copy. CI enforcement is deferred (notYetEnforced) until an audit is done.

🔒 This PR cannot merge until an ADR is linked in the PR body.

📋 What to do next
  1. Review the draft ADR committed to your branch. It was generated from the PR diff and issue [linter-miner] feat(linters): add readerstringconv analyzer #71684.
  2. Complete the missing sections: add context the AI couldn't infer (see the [TODO: verify] marker on the third-party linter alternative), refine the decision rationale, and list the alternatives you actually considered.
  3. Commit the finalized ADR to docs/adr/ on your branch.
  4. Reference the ADR in this PR body by adding a line such as:

    ADR: ADR-71891: Add readerstringconv diagnostic-only analysis-pass linter

Once an ADR is linked in the PR body, this gate will re-run and check that the implementation matches the decision.

❓ Why ADRs Matter

"AI made me procrastinate on key design decisions. Because refactoring was cheap, I could always say 'I'll deal with this later.' Deferring decisions corroded my ability to think clearly."

ADRs create a searchable, permanent record of why the codebase looks the way it does. Future contributors (and your future self) will thank you.

📋 Michael Nygard ADR Format Reference

An ADR must contain these four sections to be considered complete:

  • Context: What is the problem? What forces are at play?
  • Decision: What did you decide? Why?
  • Alternatives Considered: What else could have been done?
  • Consequences: What are the trade-offs (positive and negative)?

All ADRs are stored in docs/adr/ as Markdown files numbered by PR number.

🏗️ ADR gate enforced by Design Decision Gate 🏗️ · pi · opus55 · ~27 AIC · ⌖ ~41 AIC · ⊞ 1.9K · ◷
Comment /review to run again

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skills-Based Review 🧠

Applied /codebase-design and /tdd to this new readerstringconv analyzer. The implementation is clean, follows the established analyzer pattern closely (mirrors stringbytesroundtrip/writebytestring), and the test coverage is thorough — aliased/dot imports, generated-file and test-file exclusions, (nolint/redacted) suppression (including :all and unrelated-linter directives), shadowed packages/conversions, named/alias types, and mutable-alias non-resolution are all exercised. Doc/spec sync (README.md, doc.go, spec_test.go, doc_sync_test.go) is correctly updated, and notYetEnforced gating with a clear audit rationale is a good call given the stated "diagnostic-only" safety caveat.

📋 Key Themes & Highlights

Key Themes

  • Minor DRY nit: one inline comment suggests reusing astutil.IsByteSliceConversion (and optionally adding a symmetric IsStringConversion helper) instead of the manual IsType() check — non-blocking.

Positive Highlights

  • ✅ Correctly handles parenthesized conversions, local alias resolution, and import aliasing via existing astutil helpers
  • ✅ Honors (nolint/redacted), generated-file, and test-file exclusions consistent with sibling linters
  • ✅ Table-driven want assertions cover edge cases well (named types, type aliases, shadowing)
  • ✅ CI enforcement intentionally deferred with a documented rationale in notYetEnforced

All local tests (readerstringconv, doc/spec sync) pass.

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · copilot · sonnet50 · ~43 AIC · ⌖ ~15 AIC · ⊞ 10.2K
Comment /matt to run again

conv, ok := astutil.UnwrapParenExpr(call.Args[0]).(*ast.CallExpr) //nolint:uncheckedsliceindex // len(call.Args) == 1 is checked above.
if !ok || len(conv.Args) != 1 {
return
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/codebase-design] Nice implementation overall. Minor consistency nit: astutil.IsByteSliceConversion(pass, conv) already combines the IsType() check with IsByteSlice, and is used by writebytestring/appendbytestring. You could reuse it for the bytes.NewReader([]byte(s)) branch instead of re-deriving the IsType() check manually at line 45, and consider adding a symmetric astutil.IsStringConversion helper for the strings.NewReader(string(b)) branch so both directions follow the same pattern.

💡 Why this matters

This is purely a readability/DRY suggestion, not a correctness issue — the manual IsType() check at line 45 is functionally equivalent. Keeping conversion-detection logic centralized in astutil makes it easier for future linters (and reviewers) to reuse the same vocabulary rather than re-deriving it ad hoc.

@copilot please address this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated readerstringconv to use astutil.IsByteSliceConversion and the new symmetric astutil.IsStringConversion; both helpers now handle parenthesized conversion types. Added focused helper regression coverage. The focused tests, build, lint, and final progress gate passed. Commit: 0a88c84.

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot address the following outstanding work in one pass:

  1. Update this branch with the latest main using make merge-main, resolving any conflicts and preserving the intended changes.
  2. Review (pkg/linters/readerstringconv/readerstringconv.go:46): [/codebase-design] Nice implementation overall. Minor consistency nit: astutil.IsByteSliceConversion(pass, conv) already combines the IsType() check with IsByteSlice, and is used by writebytestring/appendbytestring. You could reuse it for the bytes.NewReader([]byte(s)) branch instead of re-deriving the IsType() check manually at line 45, and consider adding a symmetric astutil.IsStringConversion helper for the strings.NewReader(string(b)) branch so both directions follow the same pattern. - feat(linters): add readerstringconv analyzer #71891 (comment)

Push the necessary fixes, reply to each listed review thread and resolve it when addressed. Ignore feedback already answered or resolved. Use the pr-finisher skill and stop when only human review or CI remains; do not trigger CI.

Sous-chef head: 231d1a2
Sous-chef work: 1248697e5cb66ff4e12811afd356ff105ac03b0c667b1cd7bdac2aafa7ee820b
Sous-chef state: 4e4458aa204a35d0f7a8532a846fd7fbe009f143be3e72f5a7873e3386686917

Generated by 👨‍🍳 PR Sous Chef · pi · haiku45 · ~8 AIC · ⌖ ~9 AIC · ⊞ 1.1K · ◷
Comment /souschef to run again

Copilot AI and others added 2 commits October 25, 2026 14:40
…eaderstringconv

Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>
Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>

Copilot AI commented Oct 25, 2026

Copy link
Copy Markdown
Contributor Author

@copilot address the following outstanding work in one pass:

  1. Update this branch with the latest main using make merge-main, resolving any conflicts and preserving the intended changes....

Merged the latest main and pushed the conversion-helper refactor in 0a88c84; local formatting, tests, build, lint, and the final validation gate passed. I replied to the actionable review comment, but the thread remains unresolved because the available GitHub tools cannot resolve threads and the browser connection failed. CodeQL timed out, and I did not trigger CI.

@pelikhan
pelikhan merged commit 250c0f3 into main Oct 25, 2026
35 checks passed
@pelikhan
pelikhan deleted the copilot/linter-minerreaderstringconv branch October 25, 2026 16:06
@github-actions

Copy link
Copy Markdown
Contributor

🎉 This pull request is included in a new release.

Release: v0.93.5

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[linter-miner] feat(linters): add readerstringconv analyzer

4 participants