Skip to content

Extract repeated linter analyzer bootstrap into analyzerutil helpers - #53220

Closed
pelikhan with Copilot wants to merge 6 commits into
mainfrom
copilot/duplicate-code-fix-linter-bootstrap
Closed

Extract repeated linter analyzer bootstrap into analyzerutil helpers#53220
pelikhan with Copilot wants to merge 6 commits into
mainfrom
copilot/duplicate-code-fix-linter-bootstrap

Conversation

Copilot AI commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Every analyzer in pkg/linters opened its run function with the same ~20-line bootstrap: build the nolint index, build the generated-file index, declare a nodeFilter, and wire a thin analyzerutil.Preorder closure forwarding to a package-specific analyze function. Policy changes to that setup had to be replicated across 60+ packages.

pkg/linters/internal/analyzerutil

  • Indexes(pass) — builds both shared indexes in one call, returning (filecheck.GeneratedIndex, nolint.DirectiveIndex, error).
  • PreorderIndexed(pass, nodeFilter, visit) — combines index construction with preorder traversal, invoking visit(pass, node, generatedFiles, noLintIndex). That signature already matches most linters' existing analyze functions, so they can be passed by reference rather than wrapped.

Linter packages (64 files, -456/+90)

  • 17 run bodies collapse to a single call; the remaining ones (extra state, package-path gating, or inline visitor bodies) use Indexes and keep their existing Preorder closure.
  • Imports of nolint/filecheck dropped where they became unused.
// before
func run(pass *analysis.Pass) (any, error) {
	noLintIndex, err := nolint.Index(pass)
	if err != nil {
		return nil, err
	}
	generatedFiles, err := filecheck.Index(pass)
	if err != nil {
		return nil, err
	}

	nodeFilter := []ast.Node{(*ast.CallExpr)(nil)}
	return analyzerutil.Preorder(pass, nodeFilter, func(n ast.Node) {
		analyzeTimeNowSub(pass, n, generatedFiles, noLintIndex)
	})
}

// after
func run(pass *analysis.Pass) (any, error) {
	return analyzerutil.PreorderIndexed(pass, []ast.Node{(*ast.CallExpr)(nil)}, analyzeTimeNowSub)
}

Tests

Unit tests for Indexes and PreorderIndexed cover index forwarding, visitor arguments, and error propagation (no nodes visited when index construction fails). Existing per-linter analysistest golden suites are unchanged and still pass, so behavior should be identical.


Generated by 👨‍🍳 PR Sous Chef · gpt54 · 27.9 AIC · ⌖ 7.12 AIC · ⊞ 6.3K ·
Comment /souschef to run again

Copilot AI and others added 3 commits August 16, 2026 22:02
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix duplicate code in pkg/linters for bootstrapping Extract repeated linter analyzer bootstrap into analyzerutil helpers Aug 16, 2026
Copilot AI requested a review from pelikhan August 16, 2026 22:11
@pelikhan
pelikhan marked this pull request as ready for review August 16, 2026 22:20
Copilot AI balanced review requested due to automatic review settings August 16, 2026 22:20
@github-actions

github-actions Bot commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Test Quality Sentinel completed test quality analysis.

Test Quality Sentinel skipped because pre-fetch PR data was unavailable: unable to fetch test file diff

🧪 Test quality analysis by Test Quality Sentinel

@github-actions

github-actions Bot commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

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

🏗️ ADR gate enforced by Design Decision Gate 🏗️

@github-actions

github-actions Bot commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Ponytail Reviewer completed successfully!

Diff contains only generated .lock.yml files (compiled workflow artifacts), which are explicitly out of scope for this review.

Generated by Ponytail Reviewer for #53220

@github-actions

github-actions Bot commented Aug 16, 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 commented Aug 16, 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

Copy link
Copy Markdown
Contributor

Comment Memory

reviewed_at: 2026-08-16T00:00:00Z
review_event: COMMENT
top_themes:
  - no actionable correctness regressions found in analyzerutil extraction
  - workflow shell_harness migration matches existing lockfile patterns
files_reviewed:
  - pkg/linters/internal/analyzerutil/analyzerutil.go
  - pkg/linters/internal/analyzerutil/analyzerutil_test.go
  - pkg/linters/appendbytestring/appendbytestring.go
  - pkg/linters/bytescomparestring/bytescomparestring.go
  - pkg/linters/largefunc/largefunc.go
  - pkg/linters/mapclearloop/mapclearloop.go
  - pkg/linters/contextcancelnotdeferred/contextcancelnotdeferred.go
  - pkg/linters/fmterrorfnoverbs/fmterrorfnoverbs.go
  - pkg/linters/jsonmarshalignoredeerror/jsonmarshalignoredeerror.go
  - pkg/linters/stringscountcontains/stringscountcontains.go
  - .github/workflows/ab-testing-advisor.lock.yml
  - .github/workflows/chaos-pr-bundle-fuzzer.lock.yml
comment_count: 0

Note

This comment is managed by comment memory.

It stores persistent context for this thread in the code block at the top of this comment.
Edit only the text inside the backtick fences; workflow metadata and the footer are regenerated automatically.

Learn more about comment memory

🔎 Code quality review by PR Code Quality Reviewer · gpt54 · 14.6 AIC · ⌖ 5.59 AIC · ⊞ 4.5K ·
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.

Verdict

No blocking issues found in the changed lines.

Review notes

I checked the new analyzerutil helpers, a representative sample of migrated linters, and the generated workflow shell-harness changes. The refactor preserves the old index ordering and error propagation, and the workflow command shape matches existing shell_harness-based lockfiles already in the repo. I did not find a changed-line bug worth blocking this PR over.

🔎 Code quality review by PR Code Quality Reviewer · gpt54 · 14.6 AIC · ⌖ 5.59 AIC · ⊞ 4.5K
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 — approving with one minor observation.

📋 Key Themes & Highlights

Positive Highlights

  • ✅ Deep module win: PreorderIndexed hides 20 lines of boilerplate behind a single call — exactly what /codebase-design calls "deep modules with simple interfaces."
  • ✅ Test coverage is comprehensive: happy path, both error cases (TestIndexesError), and no-visit-on-error guard (TestPreorderIndexedError). Aligns well with /tdd principles.
  • ✅ 64-file reduction with near-zero behaviour risk — existing per-linter analysistest golden suites continue unchanged.
  • Indexes is a useful seam for linters with extra state that can't use PreorderIndexed directly.

Minor Observation

The build order inside Indexes is nolint → filecheck, but the return signature is (filecheck.GeneratedIndex, nolint.DirectiveIndex, error) — reversed. The naming in the signature is unambiguous so this isn't a bug, but it creates a small "read the signature, not the body" hurdle. Consider aligning them for future maintainability.

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · sonnet46 · 25.3 AIC · ⌖ 7.54 AIC · ⊞ 7.7K
Comment /matt to run again

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

Centralizes repeated linter initialization through shared analyzer utilities while preserving analyzer behavior.

Changes:

  • Adds and tests Indexes and PreorderIndexed.
  • Migrates 64 linters to the shared helpers.
  • Also includes unrelated generated workflow lockfile changes that should be reverted.
Show a summary per file
File Description
pkg/linters/writebytestring/writebytestring.go Uses shared index setup.
pkg/linters/wgdonenotdeferred/wgdonenotdeferred.go Uses shared index setup.
pkg/linters/walkfuncerrshadow/walkfuncerrshadow.go Uses shared index setup.
pkg/linters/uncheckedtypeassertion/uncheckedtypeassertion.go Uses shared index setup.
pkg/linters/uncheckedflushreturn/uncheckedflushreturn.go Uses shared index setup.
pkg/linters/trimleftright/trimleftright.go Uses indexed preorder traversal.
pkg/linters/tolowerequalfold/tolowerequalfold.go Uses shared index setup.
pkg/linters/timesleepnocontext/timesleepnocontext.go Uses shared index setup.
pkg/linters/timenowsub/timenowsub.go Uses indexed preorder traversal.
pkg/linters/timeafterleak/timeafterleak.go Uses shared index setup.
pkg/linters/stringsjoinone/stringsjoinone.go Uses indexed preorder traversal.
pkg/linters/stringsindexhasprefix/stringsindexhasprefix.go Uses indexed preorder traversal.
pkg/linters/stringsindexcontains/stringsindexcontains.go Uses indexed preorder traversal.
pkg/linters/stringscountcontains/stringscountcontains.go Uses indexed preorder traversal.
pkg/linters/stringsconcatloop/stringsconcatloop.go Uses shared index setup.
pkg/linters/stringreplaceminusone/stringreplaceminusone.go Uses shared index setup.
pkg/linters/stringbytesroundtrip/stringbytesroundtrip.go Uses indexed preorder traversal.
pkg/linters/strconvparseignorederror/strconvparseignorederror.go Uses indexed preorder traversal.
pkg/linters/sprintfint/sprintfint.go Uses shared index setup.
pkg/linters/sprintferrorsnew/sprintferrorsnew.go Uses shared index setup.
pkg/linters/sprintferrdot/sprintferrdot.go Uses indexed preorder traversal.
pkg/linters/sprintfbool/sprintfbool.go Uses shared index setup.
pkg/linters/sortslice/sortslice.go Uses shared index setup.
pkg/linters/seenmapbool/seenmapbool.go Uses shared index setup.
pkg/linters/regexpdynamicpattern/regexpdynamicpattern.go Uses shared index setup.
pkg/linters/regexpcompileinfunction/regexpcompileinfunction.go Uses shared index setup.
pkg/linters/rawloginlib/rawloginlib.go Uses shared index setup.
pkg/linters/panic-in-library-code/panic-in-library-code.go Uses shared index setup.
pkg/linters/packagelevelmutableslicemap/packagelevelmutableslicemap.go Uses shared index setup.
pkg/linters/ossetenvlibrary/ossetenvlibrary.go Uses shared index setup.
pkg/linters/osgetenvlibrary/osgetenvlibrary.go Uses shared index setup.
pkg/linters/osexitinlibrary/osexitinlibrary.go Uses shared index setup.
pkg/linters/nilctxpassed/nilctxpassed.go Uses shared index setup.
pkg/linters/mapdeletecheck/mapdeletecheck.go Uses indexed preorder traversal.
pkg/linters/mapclearloop/mapclearloop.go Uses indexed preorder traversal.
pkg/linters/manualmutexunlock/manualmutexunlock.go Uses shared index setup.
pkg/linters/logfatallibrary/logfatallibrary.go Uses shared index setup.
pkg/linters/lenstringzero/lenstringzero.go Uses shared index setup.
pkg/linters/lenstringsplit/lenstringsplit.go Uses shared index setup.
pkg/linters/largefunc/largefunc.go Uses indexed preorder traversal.
pkg/linters/jsonmarshalignoredeerror/jsonmarshalignoredeerror.go Uses shared index setup.
pkg/linters/ioutildeprecated/ioutildeprecated.go Uses shared index setup.
pkg/linters/internal/analyzerutil/analyzerutil.go Adds shared bootstrap helpers.
pkg/linters/internal/analyzerutil/analyzerutil_test.go Tests forwarding and error handling.
pkg/linters/httpstatuscode/httpstatuscode.go Uses shared index setup.
pkg/linters/httprespbodyclose/httprespbodyclose.go Uses shared index setup.
pkg/linters/httpnoctx/httpnoctx.go Uses shared index setup.
pkg/linters/hardcodedfilepath/hardcodedfilepath.go Uses shared index setup.
pkg/linters/goroutinemissingrecover/goroutinemissingrecover.go Uses shared index setup.
pkg/linters/globwalkignorederror/globwalkignorederror.go Uses indexed preorder traversal.
pkg/linters/fprintlnsprintf/fprintlnsprintf.go Uses shared index setup.
pkg/linters/fmterrorfnoverbs/fmterrorfnoverbs.go Uses shared index setup.
pkg/linters/fileclosenotdeferred/fileclosenotdeferred.go Uses shared index setup.
pkg/linters/execcommandwithoutcontext/execcommandwithoutcontext.go Uses shared index setup.
pkg/linters/excessivefuncparams/excessivefuncparams.go Uses shared index setup.
pkg/linters/errstringmatch/errstringmatch.go Uses shared index setup.
pkg/linters/errortypeassertion/errortypeassertion.go Uses shared index setup.
pkg/linters/errormessage/errormessage.go Uses shared index setup.
pkg/linters/errorfwrapv/errorfwrapv.go Uses indexed preorder traversal.
pkg/linters/deferinloop/deferinloop.go Uses shared index setup.
pkg/linters/ctxbackground/ctxbackground.go Uses shared index setup.
pkg/linters/contextcancelnotdeferred/contextcancelnotdeferred.go Uses shared index setup.
pkg/linters/bytescomparestring/bytescomparestring.go Uses shared index setup.
pkg/linters/bytesbufferstring/bytesbufferstring.go Uses indexed preorder traversal.
pkg/linters/appendoneelement/appendoneelement.go Uses indexed preorder traversal.
pkg/linters/appendbytestring/appendbytestring.go Uses indexed preorder traversal.
.github/workflows/unbloat-docs.lock.yml Unrelated generated runtime changes.
.github/workflows/spec-enforcer.lock.yml Unrelated generated runtime changes.
.github/workflows/smoke-pi.lock.yml Unrelated generated runtime changes.
.github/workflows/smoke-gemini.lock.yml Unrelated generated runtime changes.
.github/workflows/schema-consistency-checker.lock.yml Unrelated generated runtime changes.
.github/workflows/pr-sous-chef.lock.yml Unrelated generated runtime changes.
.github/workflows/pr-code-quality-reviewer.lock.yml Unrelated generated runtime changes.
.github/workflows/poem-bot.lock.yml Unrelated generated runtime changes.
.github/workflows/lint-monster.lock.yml Unrelated generated runtime changes.
.github/workflows/issue-monster.lock.yml Unrelated generated runtime changes.
.github/workflows/hippo-embed.lock.yml Unrelated generated runtime changes.
.github/workflows/eslint-monster.lock.yml Unrelated generated runtime changes.
.github/workflows/daily-news.lock.yml Unrelated generated runtime changes.
.github/workflows/daily-multi-device-docs-tester.lock.yml Unrelated generated runtime changes.
.github/workflows/daily-hippo-learn.lock.yml Unrelated generated runtime changes.
.github/workflows/daily-function-namer.lock.yml Unrelated generated runtime changes.
.github/workflows/daily-doc-updater.lock.yml Unrelated generated runtime changes.
.github/workflows/daily-awf-spec-compiler-surfacing.lock.yml Unrelated generated runtime changes.
.github/workflows/commit-changes-analyzer.lock.yml Unrelated generated runtime changes.
.github/workflows/chaos-pr-bundle-fuzzer.lock.yml Unrelated generated runtime changes.
.github/workflows/auto-triage-issues.lock.yml Unrelated generated runtime changes.
.github/workflows/agent-persona-explorer.lock.yml Unrelated generated runtime changes.
.github/workflows/ab-testing-advisor.lock.yml Unrelated generated runtime changes.

Review details

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

  • Files reviewed: 89/89 changed files
  • Comments generated: 1
  • Review effort level: Balanced

# shellcheck disable=SC1003,SC2016,SC2086
awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --env-all --exclude-env ACTIONS_ID_TOKEN_REQUEST_TOKEN --exclude-env ACTIONS_ID_TOKEN_REQUEST_URL --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GH_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --mount /tmp/gh-aw:/tmp/gh-aw:rw --log-level info --skip-pull --difc-proxy-host awmg-cli-proxy:18443 --difc-proxy-ca-cert /tmp/gh-aw/difc-proxy-tls/ca.crt \
-- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && cd "${GITHUB_WORKSPACE}" && mkdir -p /tmp/gh-aw/pi-agent-dir && printf '\''%s\n'\'' '\''{"providers":{"aw-gateway":{"api":"openai-completions","apiKey":"COPILOT_GITHUB_TOKEN","baseUrl":"http://api-proxy:10002","models":[{"id":"gpt-5.4"}]}}}'\'' > /tmp/gh-aw/pi-agent-dir/models.json && cat /tmp/gh-aw/aw-prompts/prompt.txt | pi --print --mode json --no-session --model aw-gateway/gpt-5.4 --extension "${RUNNER_TEMP}/gh-aw/actions/pi_provider.cjs" --extension "${RUNNER_TEMP}/gh-aw/actions/pi_steering_extension.cjs" 2>&1 | tee /tmp/gh-aw/pi-streaming.jsonl' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
-- /bin/bash -c 'set +o histexpand; GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/shell_harness.cjs pi '\''export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\'\'''\''\n'\''\'\'''\'' '\''\'\'''\'':'\''\'\'''\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && cd "${GITHUB_WORKSPACE}" && mkdir -p /tmp/gh-aw/pi-agent-dir && printf '\''\'\'''\''%s\n'\''\'\'''\'' '\''\'\'''\''{"providers":{"aw-gateway":{"api":"openai-completions","apiKey":"COPILOT_GITHUB_TOKEN","baseUrl":"http://api-proxy:10002","models":[{"id":"gpt-5.4"}]}}}'\''\'\'''\'' > /tmp/gh-aw/pi-agent-dir/models.json && cat /tmp/gh-aw/aw-prompts/prompt.txt | pi --print --mode json --no-session --model aw-gateway/gpt-5.4 --extension "${RUNNER_TEMP}/gh-aw/actions/pi_provider.cjs" --extension "${RUNNER_TEMP}/gh-aw/actions/pi_steering_extension.cjs" 2>&1 | tee /tmp/gh-aw/pi-streaming.jsonl'\''' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log

@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.

This PR cleanly extracts the repeated 20-line linter bootstrap into two well-named helpers in pkg/linters/internal/analyzerutil:

  • Indexes(pass) — returns (filecheck.GeneratedIndex, nolint.DirectiveIndex, error), consolidating two sequential index builds.
  • PreorderIndexed(pass, nodeFilter, visit) — combines index construction with preorder traversal; the visitor signature matches the existing per-linter analyze* functions so they can be passed by reference.

Overall assessment: the refactoring is correct, consistent, and well-tested. No blocking issues.

Observations
  • Return order for Indexes is (generatedFiles, noLintIndex, err) — slightly non-standard since nolint is built first internally, but all 60+ callers are consistent, so this is fine.
  • PreorderIndexed correctly short-circuits: if Indexes fails, no nodes are visited (verified by TestPreorderIndexedError).
  • The errorfwrapv linter had additional setup before the index calls; switching to PreorderIndexed is still correct because the extra setup (universeErrorInterface) does not depend on the indexes.
  • The diff also includes unrelated .lock.yml changes — those appear to be auto-generated recompilations and can be ignored for review purposes.
  • Test coverage for the new helpers is thorough: happy path, error paths for each missing analyzer result, and visitor-argument forwarding.

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · sonnet46 · 38.1 AIC · ⌖ 7.12 AIC · ⊞ 5.6K

…bootstrap helpers

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

Copy link
Copy Markdown
Contributor

🏗️ Design Decision Gate — ADR Required

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

📄 Draft ADR committed: docs/adr/53220-extract-shared-linter-analyzer-bootstrap-helpers.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-53220: Extract Shared Linter Analyzer Bootstrap into analyzerutil Helpers

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., 0042-use-postgresql.md for PR #42).

🏗️ ADR gate enforced by Design Decision Gate 🏗️ · sonnet46 · 73.1 AIC · ⌖ 25 AIC · ⊞ 9K ·
Comment /review to run again

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot this PR is ready for the next finishing pass.

Please address these items, newest first:

  • ADR gate is still blocking merge: complete the draft ADR at docs/adr/53220-extract-shared-linter-analyzer-bootstrap-helpers.md and link it from the PR body.
  • Remove or justify the unrelated generated workflow .lock.yml changes called out by Copilot review so the diff stays focused.
  • Review the latest non-blocking feedback about the Indexes return-order readability nit and decide whether to align the body/signature ordering.
  • Refresh the branch if needed, rerun the relevant validation, and run the pr-finisher skill before handing back to maintainers.

Generated by 👨🍳 PR Sous Chef

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 27.9 AIC · ⌖ 7.12 AIC · ⊞ 6.3K ·
Comment /souschef to run again

Copilot AI requested a review from gh-aw-bot August 16, 2026 22:54
@pelikhan pelikhan closed this Aug 16, 2026
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.

[duplicate-code] Duplicate Code: Repeated Linter Bootstrap in pkg/linters

4 participants