Skip to content

chore: apply go fix modernizations and guard drift in pre-commit#517

Merged
SantiagoDePolonia merged 2 commits into
mainfrom
chore/gofix
Jul 9, 2026
Merged

chore: apply go fix modernizations and guard drift in pre-commit#517
SantiagoDePolonia merged 2 commits into
mainfrom
chore/gofix

Conversation

@SantiagoDePolonia

@SantiagoDePolonia SantiagoDePolonia commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

What

Ran go fix ./... across the module and adopted the modern stdlib idioms it suggests, then added a pre-commit guard so the tree stays modernized.

Net −112 lines (448 insertions, 560 deletions) across 95 files. Only Makefile and .pre-commit-config.yaml are non-Go.

Idiom Sites
new(expr) replacing pointer helpers 198
maps.Copy 21
slices.Contains / slices.Backward 6
min / max 10
strings.SplitSeq 5
strings.CutPrefix / bytes.CutPrefix 6
range-over-int 13
reflect.Type.Fields 2
sync.WaitGroup.Go 2

Go 1.26's new(expr) makes the hand-rolled intPtr/boolPtr/stringPtr/… helpers redundant, so all 19 are deleted, along with the //go:fix inline directives go fix injected to mark them.

User-visible impact

None. Every change is behavior-preserving.

The only wire-visible candidates were five ,omitempty tags dropped from struct-typed JSON fields — three time.Time (auditlog.AttemptSnapshot.StartedAt, and StoredAt/ExpiresAt in the conversation/response stores) and two Gemini decode-only types. omitempty is a documented no-op on struct values, so the fields were always emitted. Verified empirically against goccy/go-json (which this repo uses in place of encoding/json): zero and non-zero values marshal byte-identically with and without the tag.

The two //go:build-gated Gemini types (geminiGenerateContentResponse, geminiCandidate) are never marshaled — decode only — so tags are irrelevant there.

Two go fix gotchas worth knowing

Both are now captured as comments in Makefile and .pre-commit-config.yaml:

  1. It needs two passes to converge. When go fix marks a helper //go:fix inline, it inlines that helper's callers only on the next run — leaving the helper orphaned and tripping the unused linter. A single go fix ./... leaves the tree lint-failing.
  2. It silently skips build-tagged files. Plain go fix ./... never sees tests/{e2e,integration,contract} or swagger. Those had ~100 KB of unapplied fixes; this PR fixes them too by passing -tags.

Tooling

  • make fix — apply modernizations (documents the two-pass caveat).
  • make fix-check — report drift via go fix -diff, non-mutating, exits non-zero on drift (~0.7 s).
  • New go-fix-check pre-commit hook runs make fix-check.
  • Lifted the repeated build-tag string into a BUILD_TAGS Makefile variable now that lint, fix, and fix-check all share it. make lint expands to the identical command as before.

The hook checks rather than auto-applies, deliberately: go fix rewrites source in place and (per gotcha 1) can leave an orphaned helper that fails make lint. An auto-applying hook would mutate the commit and still fail it.

Verified the hook is real by injecting a for k, v := range copy loop into a //go:build e2e file: plain go fix -diff ./... exits 0 (misses it), make fix-check exits 2 (catches it). The -tags are load-bearing.

Testing

All 13 pre-commit hooks pass on this commit:

  • make test-race — 60/60 packages, no data races
  • make lint — 0 issues (--build-tags=swagger,e2e,integration,contract)
  • make perf-check — hot-path alloc/byte guards within thresholds
  • make fix-check — tree is a go fix fixed point
  • go mod tidy — clean
  • tests/{e2e,integration,contract} compile under their build tags

The 3 pre-existing go vet repeats json tag warnings in internal/core are unchanged by this PR (confirmed against baseline).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added fix and fix-check developer commands for Go modernization checks and updates.
  • Bug Fixes
    • Improved JSON output consistency by always including stored timestamp fields in relevant stored conversation/response data and audit log snapshot payloads.
    • Updated Gemini request/response marshaling to ensure required fields are always encoded.
  • Refactor
    • Modernized internal Go implementations and tests for safer concurrency and more consistent string/collection handling.

Run `go fix` across the module and adopt the modern stdlib idioms it
suggests: maps.Copy, slices.Contains/Backward, strings+bytes.CutPrefix,
strings.SplitSeq, min/max, range-over-int, reflect.Type.Fields,
sync.WaitGroup.Go, and new(expr) in place of hand-rolled pointer helpers.

Go 1.26's new(expr) makes the intPtr/boolPtr/stringPtr/... helpers
redundant, so all 19 are deleted along with the `//go:fix inline`
directives go fix injected to mark them.

`go fix` needed two passes to converge (it inlines a helper's callers only
on the run after it marks the helper), and it skips build-tagged files
unless -tags is passed -- so tests/{e2e,integration,contract} were fixed
too, and both facts are captured in the new Makefile targets.

All changes are behavior-preserving. The only wire-visible candidates were
five `,omitempty` tags dropped from struct-typed JSON fields (time.Time and
two Gemini decode-only types); omitempty is a documented no-op on structs,
verified against goccy/go-json, which this repo uses.

Add `make fix` (apply) and `make fix-check` (report, non-mutating), and
wire fix-check into pre-commit. The hook checks rather than auto-applies:
go fix rewrites source in place and can leave an orphaned helper that
trips the `unused` linter, so an auto-applying hook would mutate the
commit and still fail it.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 13582e4d-6ff1-44a6-b0e8-da1c0de0626a

📥 Commits

Reviewing files that changed from the base of the PR and between a9cb24a and 8a81db5.

📒 Files selected for processing (1)
  • Makefile

📝 Walkthrough

Walkthrough

This PR adds fix/fix-check tooling and a pre-commit hook, then applies Go modernization updates across production code and tests: pointer construction, map/slice helpers, string helpers, reflection iteration, range-based loops, any-typed payloads, clamp expressions, goroutine helpers, and a few JSON tag changes.

Changes

Go fix modernization

Layer / File(s) Summary
Go fix tooling
Makefile, .pre-commit-config.yaml
Adds BUILD_TAGS, fix, and fix-check Makefile targets, and a pre-commit hook that runs make fix-check on Go-related files.
Pointer helper removal
config/cache.go, internal/failover/*, internal/gateway/batch_orchestrator.go, internal/pricingoverrides/*, internal/ratelimit/*, internal/responsecache/*, internal/usage/*, internal/virtualmodels/*, tests/e2e/*, tests/integration/workflows_guardrails_test.go, and related test files
Removes local pointer helper functions and replaces call sites with inline new(...) pointer allocations.
maps.Copy adoption
internal/authkeys/service.go, internal/auditlog/middleware_test.go, internal/conversationstore/store.go, internal/core/types.go, internal/core/usage_json.go, internal/gateway/model_helpers.go, internal/guardrails/responses_message_apply.go, internal/modeldata/merge.go, internal/providers/factory.go, internal/providers/registry_metadata.go, internal/server/*, tests/integration/workflows_guardrails_test.go
Replaces manual map copy loops with maps.Copy for cloning and merging maps.
slices.Contains adoption
internal/failover/resolver.go, internal/failover/suggest.go, internal/modeldata/types.go, internal/providers/bedrock/bedrock.go, run/lifecycle_test.go, tests/e2e/admin_test.go
Replaces manual membership checks with slices.Contains.
strings helper updates
config/user_path_env.go, internal/admin/handler_live.go, internal/anthropicapi/stream_test.go, internal/providers/gemini/*, internal/providers/vllm/vllm.go, internal/providers/responses_converter.go, tests/contract/*, tests/e2e/helpers_test.go
Replaces Index/HasPrefix/TrimPrefix/Split patterns with strings.Cut, CutPrefix, CutSuffix, and SplitSeq.
reflect.Fields() iteration
internal/core/json_fields.go, internal/admin/dashboard_config_contract_test.go, internal/core/responses_field_parity_test.go, internal/providers/registry_metadata.go
Replaces NumField()/Field(i) reflection loops with iteration over Fields().
Range-loop and closure cleanup
Many test files across internal/*, tests/e2e/*, tests/integration/*
Converts counted loops to range-over-int forms and removes redundant loop-variable rebinding.
any typing and clamps
internal/ratelimit/limiter.go, internal/server/native_file_service.go, internal/server/native_response_service.go, internal/providers/xai/xai.go, tests/e2e/*, tests/integration/setup_test.go
Replaces interface{} with any in payload/response types and simplifies clamping logic with min/max.
JSON omitempty removals
internal/auditlog/auditlog.go, internal/conversationstore/store.go, internal/responsestore/store.go, internal/providers/gemini/native.go
Removes omitempty from several JSON tags so fields are always serialized.
Goroutine lifecycle updates
ext/registry_test.go, internal/responsecache/vecstore_cleanup.go, internal/guardrails/llm_based_altering.go
Uses sync.WaitGroup.Go and removes manual loop-variable rebinding before goroutine closures.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

  • ENTERPILOT/GoModel#198: Related to the semantic-cache pointer defaulting and cache validation test updates in config/cache.go and config/cache_validation_test.go.
  • ENTERPILOT/GoModel#202: Touches adjacent internal/responsecache test logic, including SSE validation patterns.
  • ENTERPILOT/GoModel#253: Overlaps on tests/integration/workflows_guardrails_test.go, including the boolPtr removal and maps.Copy usage.

Suggested labels: release:internal

Poem

I’m a rabbit with a keen code nose,
I sniffed out helpers and trimmed their rows.
maps.Copy hops, slices.Contains gleams,
go fix now trots through tidy streams.
🐇✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.22% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: go fix modernizations plus new pre-commit drift checks.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/gofix

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Makefile`:
- Around line 125-128: The lint-fix target is missing the same build-tag
handling used by lint, so it skips tag-gated files and can drift from the rest
of the lint flow. Update the Makefile’s lint-fix recipe to pass BUILD_TAGS to
golangci-lint run --fix, matching the lint target behavior so files behind e2e,
integration, and contract tags are included consistently.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: af1fa4e5-f648-4738-b181-f209ba8b1cbb

📥 Commits

Reviewing files that changed from the base of the PR and between 20977e1 and a9cb24a.

📒 Files selected for processing (95)
  • .pre-commit-config.yaml
  • Makefile
  • config/cache.go
  • config/cache_validation_test.go
  • config/user_path_env.go
  • ext/registry_test.go
  • internal/admin/dashboard_config_contract_test.go
  • internal/admin/handler_live.go
  • internal/admin/handler_test.go
  • internal/anthropicapi/stream_test.go
  • internal/auditlog/auditlog.go
  • internal/auditlog/middleware_test.go
  • internal/authkeys/service.go
  • internal/conversationstore/store.go
  • internal/core/errors_test.go
  • internal/core/json_fields.go
  • internal/core/responses_field_parity_test.go
  • internal/core/types.go
  • internal/core/usage_json.go
  • internal/core/user_path_test.go
  • internal/failover/resolver.go
  • internal/failover/resolver_test.go
  • internal/failover/suggest.go
  • internal/gateway/batch_orchestrator.go
  • internal/gateway/model_helpers.go
  • internal/guardrails/llm_based_altering.go
  • internal/guardrails/responses_message_apply.go
  • internal/live/broker_test.go
  • internal/llmclient/client_test.go
  • internal/modeldata/merge.go
  • internal/modeldata/merge_test.go
  • internal/modeldata/types.go
  • internal/pricingoverrides/service_test.go
  • internal/pricingoverrides/store_sqlite_test.go
  • internal/providers/bedrock/bedrock.go
  • internal/providers/factory.go
  • internal/providers/gemini/gemini.go
  • internal/providers/gemini/gemini_test.go
  • internal/providers/gemini/native.go
  • internal/providers/registry_metadata.go
  • internal/providers/registry_metadata_override_test.go
  • internal/providers/resolve_bench_test.go
  • internal/providers/responses_converter.go
  • internal/providers/vllm/vllm.go
  • internal/providers/xai/xai.go
  • internal/ratelimit/limiter.go
  • internal/ratelimit/service_test.go
  • internal/ratelimit/store_sqlite_test.go
  • internal/ratelimit/types_test.go
  • internal/ratelimit/usage_tap_test.go
  • internal/realtime/registry_test.go
  • internal/responsecache/handle_request_test.go
  • internal/responsecache/semantic_test.go
  • internal/responsecache/sse_validation_test.go
  • internal/responsecache/vecstore_cleanup.go
  • internal/responsestore/store.go
  • internal/server/audio_service_test.go
  • internal/server/handlers_test.go
  • internal/server/http_test.go
  • internal/server/native_conversation_service.go
  • internal/server/native_file_service.go
  • internal/server/native_response_service.go
  • internal/server/realtime_webrtc_service.go
  • internal/server/response_input_items.go
  • internal/usage/audio_test.go
  • internal/usage/cost_test.go
  • internal/usage/dashboard_cost_validation_test.go
  • internal/usage/reader_fold_test.go
  • internal/usage/recalculate_pricing_issue435_test.go
  • internal/usage/savings_test.go
  • internal/usage/stream_observer_test.go
  • internal/usage/throughput_test.go
  • internal/virtualmodels/balancer_test.go
  • internal/virtualmodels/config_overlay_test.go
  • internal/workflows/types_test.go
  • run/lifecycle_test.go
  • tests/contract/golden_helpers_test.go
  • tests/contract/replay_harness_test.go
  • tests/e2e/admin_test.go
  • tests/e2e/auditlog_test.go
  • tests/e2e/auth_test.go
  • tests/e2e/chat_test.go
  • tests/e2e/failover_test.go
  • tests/e2e/helpers_test.go
  • tests/e2e/main_test.go
  • tests/e2e/mock_provider.go
  • tests/e2e/ratelimit_test.go
  • tests/e2e/responses_test.go
  • tests/integration/admin_test.go
  • tests/integration/auditlog_test.go
  • tests/integration/helpers_test.go
  • tests/integration/main_test.go
  • tests/integration/setup_test.go
  • tests/integration/usage_test.go
  • tests/integration/workflows_guardrails_test.go
💤 Files with no reviewable changes (6)
  • internal/responsecache/sse_validation_test.go
  • internal/guardrails/llm_based_altering.go
  • internal/core/user_path_test.go
  • internal/workflows/types_test.go
  • internal/virtualmodels/config_overlay_test.go
  • internal/llmclient/client_test.go

Comment thread Makefile Outdated
@greptile-apps

greptile-apps Bot commented Jul 9, 2026

Copy link
Copy Markdown

Confidence Score: 5/5

Safe to merge with minimal risk.

The changes are mechanical Go modernizations, the module targets Go 1.26.5, and reviewed production edits preserve the previous behavior.

No files require special attention.

T-Rex T-Rex Logs

What T-Rex did

  • Before running fix-check, the repository status showed only untracked items: .greptile-internal/, .greptile/, and trex-artifacts/.
  • Ran the fix-check workflow by executing make fix-check and go fix with diff, which completed in 113 seconds and exited with code 0.
  • After running fix-check, the repository status still showed the same untracked items and no changes to tracked files were made.
  • Go test compile reruns for e2e and contract packages completed with exit code 0.
  • Integration package compilation encountered a Docker blocker during its build step.

View all artifacts

T-Rex Ran code and verified through T-Rex

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant Dev as Developer
participant PC as pre-commit hook
participant Make as Makefile
participant Go as go fix
Dev->>PC: Commit Go or Makefile changes
PC->>Make: make fix-check
Make->>Go: "go fix -diff -tags=$(BUILD_TAGS) ./..."
Go-->>Make: empty diff or non-empty diff
Make-->>PC: exit 0 when fixed, non-zero on drift
PC-->>Dev: allow commit or report required modernizations
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant Dev as Developer
participant PC as pre-commit hook
participant Make as Makefile
participant Go as go fix
Dev->>PC: Commit Go or Makefile changes
PC->>Make: make fix-check
Make->>Go: "go fix -diff -tags=$(BUILD_TAGS) ./..."
Go-->>Make: empty diff or non-empty diff
Make-->>PC: exit 0 when fixed, non-zero on drift
PC-->>Dev: allow commit or report required modernizations
Loading

Reviews (1): Last reviewed commit: "chore: apply go fix modernizations and g..." | Re-trigger Greptile

lint-fix ran without --build-tags and without ./tests/..., so its autofix
pass never visited the swagger-gated files under cmd/ and internal/server,
nor any of the e2e/integration/contract files -- which live entirely under
tests/. The two targets could therefore drift: `make lint` fails on a file
`make lint-fix` cannot even see.

Passing BUILD_TAGS alone is not enough. The e2e/integration/contract tags
gate files only under tests/, so without ./tests/... in the package list
golangci-lint still never loads them. Verified with an unused helper in a
//go:build e2e file: tags-only reports 0 hits, tags + ./tests/... reports it.

The recipes now differ only by --fix.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@codecov-commenter

Copy link
Copy Markdown

@SantiagoDePolonia SantiagoDePolonia merged commit 24b9c17 into main Jul 9, 2026
20 checks passed
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.

2 participants