Skip to content

[linter-miner] linter: add bytescomparestring — flag string(a)==string(b) where a,b are []byte#44389

Merged
pelikhan merged 3 commits into
mainfrom
linter-miner/bytescomparestring-934103cf60f1ad90
Jul 8, 2026
Merged

[linter-miner] linter: add bytescomparestring — flag string(a)==string(b) where a,b are []byte#44389
pelikhan merged 3 commits into
mainfrom
linter-miner/bytescomparestring-934103cf60f1ad90

Conversation

@github-actions

@github-actions github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a new custom go/analysis linter bytescomparestring that flags string(a) == string(b) and string(a) != string(b) comparisons where both a and b are []byte values. These comparisons create unnecessary heap allocations; the idiomatic and allocation-free replacement is bytes.Equal(a, b) / !bytes.Equal(a, b).

Evidence

Code-pattern scan found 3 live instances in the repo:

File Line Pattern
pkg/parser/import_bfs.go 566 return string(aJSON) == string(bJSON)
pkg/parser/tools_merger.go 279 return string(aJSON) == string(bJSON)
pkg/cli/packages.go 146 if string(existingContent) == string(sourceContent)

What the linter catches

// Bad — two []byte→string conversions + equality check allocates
return string(a) == string(b)
return string(a) != string(b)

// Good — bytes.Equal is allocation-free
return bytes.Equal(a, b)
return !bytes.Equal(a, b)

The linter only fires when both sides of == / != are string(x) type-conversions whose argument has underlying type []byte. False-positive rate is zero: it will not flag string(a) == "literal", string(a) == stringVar, or regular string comparisons.

Suggested fix

The analyzer emits a SuggestedFix that rewrites the entire binary expression in-place, so gopls/go fix can apply it automatically.

Changes

  • pkg/linters/bytescomparestring/bytescomparestring.go — analyzer implementation
  • pkg/linters/bytescomparestring/bytescomparestring_test.go — analysis test
  • pkg/linters/bytescomparestring/testdata/src/bytescomparestring/bytescomparestring.go — fixture file
  • pkg/linters/bytescomparestring/testdata/src/bytescomparestring/bytescomparestring.go.golden — expected fixes
  • cmd/linters/main.go — registers bytescomparestring.Analyzer
  • pkg/linters/doc.go — updates linter count (39→40) and adds entry

Testing

go test ./pkg/linters/bytescomparestring/...  ✓
go build ./cmd/linters                        ✓
make fmt                                      ✓

Generated by Linter Miner · 238.6 AIC · ⌖ 9.36 AIC · ⊞ 5.5K ·

  • expires on Jul 15, 2026, 10:20 AM UTC-08:00

…are []byte

Reports string(a) == string(b) and string(a) != string(b) comparisons where
both operands are []byte values. These conversions allocate; the idiomatic
replacement is bytes.Equal(a, b) or !bytes.Equal(a, b).

Evidence found in the codebase (3 locations):
  - pkg/parser/import_bfs.go:566:  string(aJSON) == string(bJSON)
  - pkg/parser/tools_merger.go:279: string(aJSON) == string(bJSON)
  - pkg/cli/packages.go:146:        string(existingContent) == string(sourceContent)

Changes:
  - pkg/linters/bytescomparestring/: new analyzer with tests and golden file
  - cmd/linters/main.go: register bytescomparestring.Analyzer
  - pkg/linters/doc.go: update linter count (39→40) and add entry

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions github-actions Bot added automation cookie Issue Monster Loves Cookies! go-linters labels Jul 8, 2026
@pelikhan pelikhan marked this pull request as ready for review July 8, 2026 19:03
Copilot AI review requested due to automatic review settings July 8, 2026 19:03
@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

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

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

Design Decision Gate 🏗️ completed the design decision gate check.

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

Test Quality Sentinel completed test quality analysis.

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

PR Code Quality Reviewer completed the code quality review.

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.

Pull request overview

Adds a new custom go/analysis linter (bytescomparestring) to flag string(a)==string(b) / != comparisons where both sides are []byte conversions, and suggests bytes.Equal(a, b) / !bytes.Equal(a, b) to avoid allocations.

Changes:

  • Introduces pkg/linters/bytescomparestring analyzer with SuggestedFix rewriting the full binary expression.
  • Adds analysistest coverage + fixtures/golden outputs for the new analyzer.
  • Registers the analyzer in cmd/linters and updates the linter package docs.
Show a summary per file
File Description
pkg/linters/bytescomparestring/bytescomparestring.go Implements analyzer that detects string([]byte) ==/!= string([]byte) and suggests bytes.Equal fixes.
pkg/linters/bytescomparestring/bytescomparestring_test.go Adds analysistest harness for SuggestedFix validation.
pkg/linters/bytescomparestring/testdata/src/bytescomparestring/bytescomparestring.go Test fixture with “bad” and “good” patterns.
pkg/linters/bytescomparestring/testdata/src/bytescomparestring/bytescomparestring.go.golden Expected post-fix output for the fixture.
cmd/linters/main.go Registers the new analyzer in the multichecker runner.
pkg/linters/doc.go Updates linter documentation list/count and adds bytescomparestring entry.

Review details

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 6/6 changed files
  • Comments generated: 2
  • Review effort level: Low

Comment thread cmd/linters/main.go
Comment on lines 66 to 69
multichecker.Main(
appendbytestring.Analyzer,
bytescomparestring.Analyzer,
contextcancelnotdeferred.Analyzer,
Comment thread pkg/linters/doc.go Outdated
Comment on lines 3 to 7
// All 40 active analyzers:
//
// - appendbytestring — flags append(b, []byte(s)...) calls where s is a string that can be simplified to append(b, s...)
// - bytescomparestring — flags string(a) == string(b) and string(a) != string(b) comparisons where a and b are []byte values that should use bytes.Equal instead
// - contextcancelnotdeferred — flags context cancel functions called directly instead of deferred
@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

🧪 Test Quality Sentinel Report

Test Quality Score: 100/100 — Excellent

Analyzed 1 test(s): 1 design, 0 implementation, 0 violation(s).

📊 Metrics (1 test)
Metric Value
Analyzed 1 (Go: 1, JS: 0)
✅ Design 1 (100%)
⚠️ Implementation 0 (0%)
Edge/error coverage 1 (100%)
Duplicate clusters 0
Inflation No (test: 16 lines, prod: 156 lines, ratio 0.1:1)
🚨 Violations 0
Test File Classification Issues
TestAnalyzer bytescomparestring_test.go:13 design_test / behavioral_contract None

Verdict

Passed. 0% implementation tests (threshold: 30%). No violations. The single TestAnalyzer uses analysistest.RunWithSuggestedFixes — the idiomatic Go linter testing pattern — and covers 3 positive cases (==, !=, named-type alias) plus 4 negative/edge cases (already-correct bytes.Equal, one-side string literal, pure string-var comparison, mixed types). The golden file also validates suggested-fix rewrites.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • awmgmcpg

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "awmgmcpg"

See Network Configuration for more information.

🧪 Test quality analysis by Test Quality Sentinel · 26.9 AIC · ⌖ 12.9 AIC · ⊞ 6.8K ·
Comment /review to run again

@github-actions github-actions Bot left a comment

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.

✅ Test Quality Sentinel: 100/100. 0% implementation tests (threshold: 30%).

Documents the decision to add a custom go/analysis linter that flags
string(a)==string(b) comparisons on []byte values and suggests bytes.Equal.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

🏗️ Design Decision Gate — ADR Required

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

📄 Draft ADR committed: docs/adr/44389-bytescomparestring-linter-for-byte-slice-equality.md — review and complete it before merging.

🔒 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
  2. Complete the missing sections — add context the AI couldn't infer, refine the decision rationale, and list real alternatives you 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-44389: Add bytescomparestring Linter to Flag Allocating []byte Equality Checks

Once an ADR is linked in the PR body, this gate will re-run and verify 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 (e.g., 44389-bytescomparestring-linter-for-byte-slice-equality.md for PR #44389).

🏗️ ADR gate enforced by Design Decision Gate 🏗️ · 50.9 AIC · ⌖ 7.26 AIC · ⊞ 8.5K ·
Comment /review to run again

@github-actions github-actions Bot left a comment

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.

Skills-Based Review 🧠

Applied /tdd and /codebase-design — requesting changes on two correctness gaps and two test-coverage gaps.

📋 Key Themes & Highlights

Blocking Issues

  • Missing import text-edit in SuggestedFix: The automated fix emits bytes.Equal(...) but never injects the "bytes" import. Files that don't already import bytes will fail to compile after applying the fix with gopls/go fix.
  • Silent early-return on empty NodeText: If astutil.NodeText returns an empty string the diagnostic is silently dropped, but there's no test that exercises complex sub-expressions (e.g. string(buf.Bytes())).

Minor Issues

  • Duplicated analysis.Diagnostic construction: The == and != branches build structurally identical diagnostics; extracting a helper would reduce maintenance drift.
  • Named-type != test case missing: The fixture only tests myBytes with ==; a symmetric != case would confirm operator dispatch is correct for named byte-slice types.

Positive Highlights

  • ✅ Solid type-checking logic — correctly uses types.TypesInfo and .Underlying() to handle named types without false positives
  • ✅ Clean zero-false-positive promise, well-described in the PR body
  • ✅ Good negative-case coverage in the fixture (goodStringLiteral, goodStringVars, goodMixedOneSideString)
  • ✅ Consistent with the existing appendbytestring linter's structure and patterns

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · 71 AIC · ⌖ 8.22 AIC · ⊞ 6.6K
Comment /matt to run again

TextEdits: []analysis.TextEdit{{
Pos: bin.Pos(),
End: bin.End(),
NewText: []byte(fmt.Sprintf("bytes.Equal(%s, %s)", lText, rText)),

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.

[/tdd] The SuggestedFix emits bytes.Equal(...) but does not add a "bytes" import text-edit. For callers without an existing bytes import, applying the fix via gopls/go fix produces non-compilable code.\n\n

\n💡 Suggested approach\n\nConsider adding a second TextEdit to insert the import, or at minimum document that goimports must run after applying the fix. The sibling appendbytestring linter avoids this issue because its fix never introduces a new package symbol.\n\n
\n\n@copilot please address this.


func badNamedType(a, b myBytes) bool {
return string(a) == string(b) // want `string\(a\) == string\(b\) allocates; use bytes\.Equal\(a, b\) instead`
}

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.

[/tdd] The test covers named types (myBytes) for the == case but not for !=. A badNamedTypeNotEqual case would close that gap and confirm the operator-dispatch logic is symmetric for non-[]byte underlying types.\n\n@copilot please address this.

func goodMixedOneSideString(a []byte, b string) bool {
// One side is a string variable, not string([]byte); not flagged.
return string(a) == b
}

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.

[/tdd] Missing negative test: string(a) == string(b) where one argument is []uint8 and the other is a named []byte alias. The isByteSlice helper accepts both because it checks types.Byte, but having a fixture case makes that guarantee explicit and prevents future regressions.\n\n@copilot please address this.

return
}

op := bin.Op.String()

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.

[/codebase-design] The if/else on bin.Op (lines 77–105) duplicates the analysis.Diagnostic structure; both branches differ only in message template and replacement text prefix. Extracting a small helper reduces the divergence surface.

💡 Suggested refactor

Extract a helper that accepts the op-specific strings and returns analysis.Diagnostic, then call it from both branches. This mirrors how appendbytestring keeps its reporting in a single buildFix function.

@copilot please address this.

if !ok {
return
}

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.

[/tdd] Missing edge case: what happens when either lText or rText is empty (line 69 guard returns early) — the diagnostic is silently suppressed. Add a test fixture with a complex expression like string(f()) or string(buf.Bytes()) to verify the linter fires even when astutil.NodeText might produce multi-token text, and confirm the early-return is never reachable for valid Go ASTs.\n\n@copilot please address this.

@github-actions github-actions Bot left a comment

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.

REQUEST_CHANGES — one high-severity correctness bug must be fixed before this can be used safely.

Blocking issue: SuggestedFix generates uncompilable code

The linter detection logic is correct and the diagnostic messages are accurate. However, the SuggestedFix emitted for both == and != cases replaces the expression with bytes.Equal(...) / !bytes.Equal(...) but never adds the "bytes" import. Every file that applies the auto-fix via gopls or go fix and does not already import "bytes" will fail to compile.

This is not hypothetical: all three real-world violations cited in the PR description (import_bfs.go, tools_merger.go, packages.go) were verified to have no "bytes" import — so applying the suggested fix to each of them produces broken code today.

The test suite does not catch this because the single test fixture already imports "bytes" (for goodBytesEqual), so RunWithSuggestedFixes never exercises the import-absent path.

What needs to change
  1. Add import-insertion TextEdit to both SuggestedFix instances (EQL and NEQ branches). Use golang.org/x/tools/go/ast/astutil.AddImport or compute the edit by locating the file's import block.
  2. Add a noimport test fixture (a package with the bad pattern but no pre-existing "bytes" import) and a corresponding .golden file that includes the import. This will fail until fix #1 is in place and prevents regression.

🔎 Code quality review by PR Code Quality Reviewer · 104.1 AIC · ⌖ 5.47 AIC · ⊞ 5.4K
Comment /review to run again


// extractByteSliceStringConv checks whether expr is a string(x) conversion
// where x has underlying type []byte. If so, it returns x and true.
func extractByteSliceStringConv(pass *analysis.Pass, expr ast.Expr) (ast.Expr, bool) {

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.

SuggestedFix emits bytes.Equal(...) without adding the "bytes" import, producing uncompilable code on every real violation in this repo.

💡 Details and fix

The TextEdit replaces the binary expression with bytes.Equal(a, b) or !bytes.Equal(a, b), but never inserts an import "bytes" declaration. Applying the fix to any file that does not already import "bytes" results in a compile error (undefined: bytes).

All three live callsites identified in the PR description have been verified to lack the "bytes" import:

  • pkg/parser/import_bfs.go — imports encoding/json, errors, fmt, maps, path, path/filepath, stringsno "bytes"
  • pkg/parser/tools_merger.go — imports encoding/json, fmt, maps, stringsno "bytes"
  • pkg/cli/packages.go — imports bufio, fmt, os, path/filepath, regexp, stringsno "bytes"

So every suggested fix the linter would propose in this codebase is broken out of the box.

Fix: The analysis.SuggestedFix can include multiple TextEdit entries. Add a second edit that inserts "bytes" into the file's import block. Use golang.org/x/tools/go/ast/astutil.AddImport to locate the right position and generate the edit, or locate the end of the existing import (...) block and inject \t\"bytes\"\n there.

Note: the appendbytestring peer linter avoids this entirely because its fix removes a conversion rather than adding a new package reference.

@@ -0,0 +1,37 @@
package bytescomparestring

import "bytes"

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.

Test fixture masks the missing-import bug: it already imports "bytes", so RunWithSuggestedFixes never exercises the broken path.

💡 Details and suggested test

The testdata file imports "bytes" on line 3 solely because goodBytesEqual uses bytes.Equal. This means analysistest.RunWithSuggestedFixes applies the generated TextEdits to a file that already has the import, and the golden-file comparison passes even though the linter never emits an import-adding edit.

There is no test for the real-world scenario where the file with the bad pattern has no pre-existing "bytes" import — which is true of all three live violations in this repo.

Suggested addition: add a second fixture package (e.g. testdata/src/noimport/noimport.go) that has the bad pattern but no "bytes" import:

package noimport

func bad(a, b []byte) bool {
    return string(a) == string(b) // want `string\(a\) == string\(b\) allocates; use bytes\.Equal\(a, b\) instead`
}

And a corresponding .golden file that adds the "bytes" import:

package noimport

import "bytes"

func bad(a, b []byte) bool {
    return bytes.Equal(a, b) // want `string\(a\) == string\(b\) allocates; use bytes\.Equal\(a, b\) instead`
}

This test will fail until the import-insertion TextEdit is added to the SuggestedFix, enforcing the fix is correct end-to-end.

@github-actions github-actions Bot left a comment

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.

Review: bytescomparestring linter

The linter logic is correct and well-structured — the type-based detection is precise, and the tests cover the key true/false-positive cases. One blocking issue needs to be addressed before merge.

🔴 Blocking: SuggestedFix omits the "bytes" import

All three real-world instances called out in the PR description (import_bfs.go, tools_merger.go, packages.go) do not import "bytes". Applying the SuggestedFix via go fix ./... will rewrite those expressions to bytes.Equal(...) without adding the import, producing build errors.

The test fixture passes only because it already contains import "bytes", so this gap is invisible in CI.

Fix options:

  • Add a TextEdit for the import statement alongside the expression rewrite (use golang.org/x/tools/go/ast/astutil.AddImport to locate the correct insertion point), or
  • Add a test fixture that does not pre-import "bytes" and confirm analysistest.RunWithSuggestedFixes still produces a compiling result.

🟡 Non-blocking: op variable asymmetry

op is computed but only used in the else (NEQ) branch; the EQL branch hardcodes " == ". This is correct but inconsistent — see inline comment.

What looks good
  • Type-based detection via types.TypesInfo is robust — no string-matching, no false positives on string(a) == "literal" or string(a) == stringVar.
  • Named-type coverage (type myBytes []byte) via .Underlying() is correct.
  • nolint and filecheck.IsTestFile guards are wired in properly.
  • doc.go updated with correct count and description.

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · 95.8 AIC · ⌖ 5.42 AIC · ⊞ 4.8K

func extractByteSliceStringConv(pass *analysis.Pass, expr ast.Expr) (ast.Expr, bool) {
call, ok := expr.(*ast.CallExpr)
if !ok || len(call.Args) != 1 {
return nil, false

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.

Blocking: The SuggestedFix rewrites the expression to bytes.Equal(...) but does not add a "bytes" import if the file doesn't already have one. All 3 real-world instances flagged in the PR description (import_bfs.go, tools_merger.go, packages.go) do not import "bytes", so applying this fix via go fix would produce non-compiling code.

The test fixture passes only because it pre-imports "bytes", masking this gap.

Either:

  1. Add a second TextEdit that inserts the "bytes" import (use golang.org/x/tools/go/ast/astutil.AddImport to get the correct position), or
  2. Add a test case where bytes is not pre-imported to confirm analysistest.RunWithSuggestedFixes works end-to-end.

Without this, go fix ./... will break compilation for the very instances this linter flags.

@copilot please address this.

Pos: bin.Pos(),
End: bin.End(),
NewText: []byte(fmt.Sprintf("!bytes.Equal(%s, %s)", lText, rText)),
}},

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.

Non-blocking: op is only used in the else branch (line 121 — the != diagnostic message). In the if bin.Op == token.EQL branch the string " == " is hardcoded. Consider either:

  • Remove op and hardcode " != " in the else branch too (more consistent), or
  • Use op in both branches to ensure the message always reflects the actual operator.

As written the code is correct, but the asymmetry is easy to misread.

@copilot please address this.

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

pr-sous-chef
@copilot please run the pr-finisher skill, address the blocking review feedback about the missing bytes import in SuggestedFixes and the missing no-import coverage, complete the ADR linkage/body updates, and rerun checks once the branch is up to date.

Run: https://github.com/github/gh-aw/actions/runs/28969326363

Generated by 👨‍🍳 PR Sous Chef · 10.3 AIC · ⌖ 7.04 AIC · ⊞ 7.1K ·
Comment /souschef to run again

…iolations, update docs

- Fix 3 live instances of string([]byte)==string([]byte) in pkg/parser/import_bfs.go,
  pkg/parser/tools_merger.go, and pkg/cli/packages.go (migrate to bytes.Equal)
- Update SuggestedFix to include a TextEdit adding 'bytes' import when not present
- Add noimport.go + noimport.go.golden test fixtures for the no-import code path
- Fix pkg/linters/doc.go: update count 40→44, add httprespbodyclose, httpstatuscode,
  osgetenvlibrary, sprintfint to the analyzer list
- Update ADR status Draft→Accepted, fix linter count references

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

Copilot AI commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

pr-sous-chef
@copilot please run the pr-finisher skill, address the blocking review feedback about the missing bytes import in SuggestedFixes and the missing no-import coverage, complete the ADR...

Done in commit 39de680:

  • Bytes import in SuggestedFix: Added addBytesImportEdit to bytescomparestring.go — when bytes is not already imported in the target file, the fix includes a TextEdit that inserts import "bytes" (into an existing grouped import block if present, otherwise as a standalone import after the package declaration).
  • No-import coverage: Added testdata/src/bytescomparestring/noimport.go (two violations, no bytes import) and its noimport.go.golden (import added, both expressions fixed). The duplicate import TextEdits from both diagnostics are coalesced by analysistest.RunWithSuggestedFixes's three-way merge.
  • Live violations fixed: Migrated the 3 known instances in pkg/parser/import_bfs.go, pkg/parser/tools_merger.go, and pkg/cli/packages.go to bytes.Equal, with "bytes" added to each file's imports.
  • doc.go sync: Count updated 40→44 and httprespbodyclose, httpstatuscode, osgetenvlibrary, sprintfint added to the bullet list.
  • ADR finalized: Status changed Draft→Accepted, linter-count reference corrected.

Copilot AI requested a review from gh-aw-bot July 8, 2026 19:49
@pelikhan pelikhan merged commit 4abd526 into main Jul 8, 2026
20 checks passed
@pelikhan pelikhan deleted the linter-miner/bytescomparestring-934103cf60f1ad90 branch July 8, 2026 20:19
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

🎉 This pull request is included in a new release.

Release: v0.82.7

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

Labels

automation cookie Issue Monster Loves Cookies! go-linters

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants