Skip to content

refactor: complete Modern Go adoption across module boundaries - #706

Merged
pedronauck merged 42 commits into
mainfrom
modern-go-482
Oct 7, 2026
Merged

pedronauck merged 42 commits into
mainfrom
modern-go-482

Conversation

@pedronauck

@pedronauck pedronauck commented Oct 7, 2026 •

Copy link
Copy Markdown
Member

Closes #482.

Summary

This PR completes the Modern Go migration across every Go module and build-tagged tooling surface in the repository, and makes compliance continuous so a regression fails the gate regardless of which module it lands in.

It is a behavior-preserving refactor. Ordering, nil-vs-empty collections, JSON omission, error matching, goroutine ownership, cancellation lifetimes and wire contracts are treated as contracts. Every migration was justified by reading the surrounding code; nothing was a blanket search-and-replace. Sites that can't be migrated without changing behavior are kept and documented, never silently skipped.

Metric (whole repo, origin/main → this PR) Before After
Legacy sort.Strings/Ints/Slice/SliceStable/... calls 356 1 ¹
"sort" imports 255 5 ²
errors.As( calls 165 5 ³
github.com/google/uuid imports 17 0
context.Background()/TODO() in _test.go 3,969 266 ⁴
t/b/tb.Context() in tests 4,777 8,478
Redundant loop-variable self-copies (x := x) 14 0
omitzero JSON tags 87 1,326 ⁵
strings/bytes.CutLast 0 29

¹ A test fake whose comparator returns true for nil/nil; a valid three-way comparator would change its observable order, so it keeps sort.Slice behind a site-specific lint exception.
² All remaining uses are sort.Search upper-bound cursor/insertion searches, which slices.BinarySearch (lower bound) can't express.
³ Four targets are interfaces that don't implement error (errorPayload, ExitCode() int), so errors.AsType[E error] can't express them. The fifth match is a string inside a t.Fatal message.
⁴ Each remaining use falls in a documented category: cleanup callbacks (where t.Context() is already canceled), TestMain, helpers with no testing.TB, or process/server lifetimes that cleanup stops.
⁵ Only scalar and pointer fields whose encoding is byte-identical. See "JSON".

Context: what changed since the issue was filed

  • The root module is now Go 1.27.1, not 1.26.4. Root code was migrated against the 54 guideline IDs the Modern Go Guidelines CLI resolves for 1.27.1. That adds stdlib_uuid, strings_bytes_cut_last, promoted_field_literals, url_clone, generic_methods and json_v2. The five nested modules (sdk/go, sdk/examples/notes-commands, sdk/examples/clarify-tool, internal/extension/testdata/{command,palette}-fixture-go) still declare 1.26.4 and were migrated against its 48 IDs, with no 1.27 APIs. Their go directives were left alone, because sdk/go is a public SDK and raising its minimum Go version is a separate decision.
  • The Daytona sidecar no longer exists. internal/sandbox was removed in the packages cleanup. The HTTP API is served by gin, so http_servemux_patterns only applied to hand-written net/http handlers. The ones that remain were evaluated and kept, because exact parity on status codes and Allow behavior wasn't guaranteed.
  • json_v2 (encoding/json/v2) is out of scope: the guideline says not to migrate existing encoding/json code unless explicitly requested.

What changed

1. Continuous compliance (tooling, gates, CI)

  • Every module and build-tagged surface is linted. make go-lint, make lint and the CI go-lint job now run golangci-lint with the root .golangci.yml on the root module, magefiles (mage tag), sdk/go, both SDK examples and both extension fixture modules. The fixture modules are resolved through a disposable go.work pinned to the local SDK, the same way the authoring tests build them, and the workspace is removed afterwards. Scoped runs (COMPOZY_GO_LINT_SCOPES) translate nested-module scopes and stay narrow for root scopes. The first failing module exits non-zero.
  • Explicit checks for guideline IDs that modernize doesn't enforce. The bundled modernize suite (x/tools v0.49.0 in golangci-lint v2.13.1) was inspected analyzer by analyzer. The gaps are now enforced by:
    • type-aware forbidigo on sort.Strings|Ints|Float64s|Slice|SliceStable|Sort|Stable and on errors.As;
    • depguard, which bans github.com/google/uuid in the root module only (the nested modules can't use the 1.27 stdlib uuid);
    • copyloopvar.
  • errcheck accepts the errors.AsType idiom. errcheck.exclude-functions: [errors.AsType] lets the if _, ok := errors.AsType[*T](err); ok idiom pass check-blank, which is still enabled. A probe showed that a genuinely ignored error is still reported.
  • scripts/gate.sh classifies nested modules correctly. Go files and go.mod/go.sum under sdk/examples/<name>/ select that module's Go lint and test lanes; before this PR they only selected a JS filter. sdk/go selects lint as well as tests. Fixture-module changes select fixture lint. magefiles selects tagged lint. Bash 3.2 compatibility is kept, and the scripts integration suite covers the new classifications.
  • CI change detection includes nested module manifests. The changes filter now treats nested go.mod/go.sum as backend changes, and the golangci cache key hashes every module manifest.
  • New runbook: docs/runbooks/modern-go.md. It covers the module/Go-version table, a rule → enforcement map for all 54/48 IDs (modernize analyzer, other linter, explicit check, or review-enforced), local commands, gate/CI lane selection, and the consolidated retained-exclusion inventory.

2. Mechanical migrations (all modules)

Every rule below was applied only where the rewrite is exactly equivalent:

  • Sorting:
    • sort.* → slices.Sort / SortFunc / SortStableFunc. Comparators were translated key by key with cmp.Compare and cmp.Or, and stable sorts stay stable.
    • Map-key collection now uses slices.Sorted(maps.Keys(...)). Where the empty result can reach JSON, a DTO, an equality assertion or a nil check, it uses slices.AppendSeq(make(...), maps.Keys(...)) so the result stays non-nil.
  • Errors: errors.As → errors.AsType[T], keeping the same pointer/value target, lazy evaluation order (switch cases became ordered if chains), and typed-nil semantics.
  • Loop variables: redundant x := x copies removed.
  • UUIDs: github.com/google/uuid → stdlib uuid.NewV4().String(), which keeps random v4 and the same canonical format. The dependency is gone from go.mod.
  • Other idioms: new(value) instead of pointer helpers and temporaries (preserving aliasing), strings/bytes.CutLast, CutPrefix, SplitSeq, range-over-int, min/max, slices.Contains/Index/Compact, and maps.Clone/Copy/DeleteFunc. Each is applied only where nil/empty identity and no-match defaults are preserved.
  • Promoted field literals (Go 1.27): keyed literals only. They are never mixed with the embedded field and never go through pointer embedding.

3. Semantic migrations, reviewed by owning layer

  • Test contexts (testing_t_context).
    • About 3,700 test contexts now use t.Context() / b.Context() / tb.Context().
    • The shared helper internal/testutil.Context(t) now inherits the owning test's context, as the issue asked. When it is called during cleanup, after t.Context() has been canceled, it detaches and applies a fresh 45-second bound.
    • Contexts created in a test body and later used inside a t.Cleanup callback would now arrive canceled. An AST audit over the whole merged tree, build-tagged files included, found every such capture. Each one now gets a fresh bounded cleanup context (testutil.Context(t) inside the callback). A reviewer had reproduced the failure before the fix (TestMCPAuthOwnerIsolation, workspacedb TestOpen, TestManagerBusyInput*).
    • Contexts that drive goroutines or processes whose lifetime ends in cleanup keep an independent context, so teardown order doesn't change. Examples: the terminal reaper, MCP server, process-group kill, and ACP process host.
  • sync.WaitGroup.Go / sync.OnceFunc / sync.OnceValue(s) are used only for locally paired equivalents. An Add performed under an admission lock, an Add(n) batch, or a struct-owned lifecycle gate (reset, per-call state, re-panic semantics) is kept.
  • Clone/search/iterator helpers. append([]T(nil), s...) normalizes an empty input to nil, but slices.Clone doesn't. It was only replaced behind existing length guards.
  • Pointer allocation (new(expr)) was only used where the temporary was allocation-only. Behavioral helpers (defaulting, trimming, UTC conversion, deep copy) are kept.

4. JSON (json_omitzero), audited field by field with codegen parity

  • Tag consumers inventoried before any change: encoding/json v1, OpenAPI schema reflection, the TS SDK generator, the Go SDK generator, MCP jsonschema-go, goccy go-yaml (which falls back to json tags), gin binding, mapstructure, and the TOML encoders.
  • What was migrated: 1,238 omitempty options on bool, numeric and pointer fields, which encode identically under omitzero in encoding/json v1. This excludes types with an IsZero method, which omitzero would call. The rewrite was done by an AST tool that resolves named types, aliases and promoted IsZero methods, and touched tag text only.
  • What was kept:
    • omitempty on strings, slices and maps, as the guideline says;
    • types with IsZero, including one promoted through store.EventCorrelation, which the parity probes caught;
    • interfaces (tri-state);
    • struct no-ops whose zero object is on the wire (sdk/go/types.go:136, which now has a justified nolint);
    • Go SDK generator source tags, which are copied verbatim into generated code;
    • all generated files.
  • Parity evidence:
    • make codegen produced no changes to generated artifacts: OpenAPI, the TS/Go SDKs, web types, native tool descriptors, schemas and digests.
    • make codegen-check passes.
    • 1,238 field types were probed in four states (zero, pointer-to-zero, populated, negative), and 592 whole struct shapes were compared old vs new, including JSON and YAML fallback. All produced byte-identical output.

Retained exclusions

Every retained prohibited call has a site-specific //nolint:<linter> // <reason>. Review-enforced patterns are inventoried by guideline ID in docs/runbooks/modern-go.md under "Retained exclusions", each classified as semantic, generated, or justified exclusion. No blanket suppression was added.

How this was produced and reviewed

The work was split into twelve file-disjoint slices, each in its own git worktree: daemon, api, store, cli/config, session/acp/terminal, loop, task/automation, extension/hooks, tools/mcp/skills, platform/testutil, tooling and nested modules, and JSON tags. Each slice was executed under one shared contract, with per-rule policy, ownership boundaries and capped scoped verification. The slices were merged into this branch, followed by one integration pass for cross-slice concerns: the errors.AsType errcheck fix and the cleanup-context sweep. Every slice diff then got an independent adversarial review for behavior changes (comparator translation, nil/empty, context lifetimes, WaitGroup/Once ownership, aliasing, Cut edge cases, scope). Confirmed findings were fixed before this PR was opened.

Final pre-merge review (Codex GPT-6 Astra, xhigh)

Before merge, an independent reviewer (gpt-6-astra, reasoning xhigh, six parallel area sub-reviewers) read every non-tag hunk and every changed test hunk of the full diff. It also re-audited all JSON tag changes with go/types: 1,238 of 1,238 fields are pointers (769) or bool/numeric (469), none has IsZero, and 117 JSON/YAML-fallback/JSON-Schema before/after comparisons showed zero differences. The SDK generator --check reproduced every generated byte.

  • Business logic changed? No unintended production business-rule or public-wire change was found.
  • Bugs introduced? Two, both fixed in this PR and re-verified by the same reviewer on the new head:
    • F1 (major, test-only). Two E2E tests (TestDaemonE2EMCPServeProjectsWorkspaceBoundHostAPI, TestDaemonNativeWorktreeJourneyE2E004) derived their timeout context from t.Context(). That context drives exec.CommandContext for compozy mcp serve clients, which are closed in t.Cleanup. Because t.Context() is canceled before cleanups, the subprocess was killed first (MCP client.Close() error = signal: killed in the E2E runtime lane). Both tests are back to their original context.Background() lifetime (782f514). The reviewer then traced 29 other hosted-MCP client call sites and cleared each one.
    • F2 (minor, tooling). The gate's module and Mage lint lanes could inherit evidence from a narrower cached root lint run. Root evidence is now reused only when the recorded command actually covered ./... (e1f2049), and the gate integration suite has a regression case for it.
  • CI flake. packages/site marketplace-catalog.test.tsx ("Should filter the current catalog…") takes about 4s in jsdom because of accessible-name role queries. That exceeded the 5s default when this broad change invalidated the turbo cache and all workspace suites ran concurrently (on main that run was a cache replay). The test now has the same 15_000 per-test budget the site suite already uses for heavy renders. Its assertions are unchanged (33d65d5).

Verification

  • Per slice: go build ./..., go vet on the slice packages, race tests on every changed package (go test -race, -tags=integration where the slice has integration tests), scoped make go-lint with 0 issues, and Windows cross-vet for terminal/pty and procutil.
  • JSON: make codegen produced no generated diff, make codegen-check passes, the marshal/YAML parity probes passed, and contract, spec, codegen and SDK race suites pass.
  • Tooling: the magefiles (-tags=mage) and scripts (-tags=integration) suites pass, along with SDK/example/fixture build and vet. Probes for each new lint rule fire in every module.
  • Integration branch: the reproduced cleanup failures (TestMCPAuthOwnerIsolation, TestOpen, TestManagerBusyInput*) now pass, plus the touched integration tests.
  • Integration branch, full make go-lint (whole config, every target): 0 issues on root ("" tags), root (integration Modern Go pass), sdk/go, both SDK examples, both fixture modules, and magefiles (mage tag). The fmt lane passed on all 1,479 changed Go files.
  • Full verification (the whole race matrix, E2E, and the make verify-equivalent gates) is delegated to this PR's CI, per the maintainer's direction to keep heavy gates off the local machine. CI therefore stands in for the issue's "one current make gate-full record" criterion.

Acceptance criteria (#482)

  • Every supported Go module and build-tagged Go tooling surface has an explicit Modern Go check.
  • The guideline baseline (Go 1.27.1 root / Go 1.26.4 nested) has no unclassified findings; see the runbook inventory.
  • Safe mechanical migrations are complete, with scoped race-enabled tests.
  • Semantic candidates are either migrated under owning contract tests or retained with a concrete justification.
  • JSON changes preserve HTTP/UDS/CLI/SDK wire behavior and pass codegen parity.
  • Daytona sidecar routing: N/A, the sidecar was removed before this work. The remaining hand-written net/http fixtures were evaluated and kept.
  • scripts/gate.sh classifies nested Go module changes and runs the relevant lint/test lanes.
  • make go-lint reports zero warnings and errors on every target (run locally on the merged branch). make bun-lint (no JS changes) is verified by this PR's CI.
  • Full gate: this PR's CI run on head 33d65d533 (35/35 required checks green: Go lint, all 8 race shards, Windows terminal, Darwin peer, build/boundaries, SDK race, preflight codegen, frontend, desktop, E2E runtime/web/desktop). It replaces the local make gate-full record per maintainer direction.

Compozy impact audit

  • Native tools: no change. compozy__* descriptors, schemas, digests, risk flags and capability gates are byte-identical (make codegen shows no diff).
  • Extensibility and hooks: no change. Hook dispatch order and registry ordering were reviewed as contracts. The extension fixtures and SDK are now covered by the nested-module lint lanes.
  • Workspace data isolation: no data ownership, workspace_id propagation, or cache/event/SSE isolation changes.
  • Official skill (skills/compozy/): unchanged. No public behavior or tool-ID change.
  • Web/Docs: no Web or public wire change. The new developer runbook is docs/runbooks/modern-go.md. No QA scenario changes, since nothing user-visible changed.
  • Config: no config.toml key changes.

🤖 Generated with Claude Code

Apply slices_sort, slices_sort_func, slices_sorted, maps_keys_values_iter, slices_collect, cmp_or, errors_as_type, testing_t_context, new_expression, range_over_int, slices_clone, maps_clone, maps_delete_func, strings_cut_prefix_suffix, strings_bytes_cut_last, and strings_split_seq. Preserve ordering stability, nil/empty identity, error targets, and context lifetimes.
Apply slices_sort, slices_sort_func, slices_sorted, maps_keys_values_iter, errors_as_type, testing_t_context, sync_waitgroup_go, sync_once_func, new_expression, range_over_int, cmp_or, slices_clone, maps_clone, maps_copy, maps_delete_func, slices_compact, strings_split_seq, strings_bytes_cut_last, url_clone, and stdlib_uuid. Preserve stable precedence, nil/empty normalization, cleanup lifetime, descriptor bytes, and UUID v4 semantics.
Apply slices_sort, slices_sort_func, slices_sorted, maps_keys_values_iter, errors_as_type, testing_t_context, sync_waitgroup_go, sync_once_func, new_expression, loopvar_capture, range_over_int, cmp_or, and min_max. Preserve stable ordering, nil/empty identity, lazy error precedence, cleanup lifetimes, and byte-identical OpenAPI output.
Apply testing_t_context, new_expression, slices_sort, slices_sort_func,
cmp_or, sync_waitgroup_go, sync_once_func, loopvar_capture,
range_over_int, min_max, slices_contains, slices_index_func,
slices_clone, bytes_clone, maps_delete_func, maps_keys_values_iter,
slices_collect, and strings_bytes_cut_last.

Preserve cleanup lifetimes, stable ordering, claim/lease tie-breakers,
pointer independence, nil/empty identity, and JSON tags.

Validated scoped race unit and integration suites, build, vet, and lint.
Heavy gates remain with integration CI under the worker contract.
Apply slices_sort, slices_sort_func, maps_keys_values_iter, slices_collect,
cmp_or, errors_as_type, testing_t_context, sync_waitgroup_go,
sync_once_func, new_expression, loopvar_capture, range_over_int,
strings_bytes_cut_last, stdlib_uuid, and strings_split_seq.

Preserve stable ordering, nil versus empty collection identity, UUID v4,
and independent cleanup lifetimes. Keep cleanup-created shared timeout
contexts usable while inheriting test cancellation for test-body work.
Applied guideline IDs: slices_sort, slices_sort_func, slices_sorted, maps_keys_values_iter, cmp_or, errors_as_type, testing_t_context, sync_waitgroup_go, sync_once_func, new_expression, loopvar_capture, range_over_int, strings_bytes_cut_last, generic_methods, promoted_field_literals, slices_clone, slices_contains.

Preserve admission locks, stable transcript ordering, nil/empty identity, cleanup lifetimes and process signaling parity. Validate scoped race suites, real integration journeys, vet, Windows cross-build and zero-finding scoped lint; heavy gates remain PR-CI owned per the worker contract.
Apply slices_sort, slices_sort_func, slices_sorted, slices_clone, cmp_or,
errors_as_type, errors_is, testing_t_context, loopvar_capture, maps_copy,
min_max, strings_split_seq, strings_bytes_cut_last, and new_expression.

Lint all supported Go modules and tagged Mage tooling, preserve fixture SDK
resolution, select nested Go gate lanes, and document per-rule enforcement.
Exclude the matched value of errors.AsType from errcheck while retaining
blank-assignment checks for operation errors.
Apply json_omitzero to omission-equivalent scalar and pointer fields.
Retain IsZero, collection, interface, fixture and generated SDK boundaries.
Verify JSON/YAML marshal parity and unchanged generated contracts.
Apply cmp_or, errors_as_type, generic_methods, loopvar_capture,
maps_clone, maps_delete_func, maps_keys_values_iter, new_expression,
promoted_field_literals, range_over_int, slices_clone, slices_collect,
slices_sort, slices_sort_func, slices_sorted, strings_bytes_cut_last,
sync_once_func, sync_once_value, sync_waitgroup_go, testing_t_context.

Preserve stable ordering, nil/empty collections, error target types,
and cleanup lifetimes. Retain predicate-only As calls pending the
controller-owned errcheck configuration change.

Validate with scoped race tests, integration journeys, go build,
go vet, Modern Go analyzer, scoped lint, and a real CLI JSON run.
Guidelines: slices_sort, slices_sort_func, slices_sorted, maps_keys_values_iter, cmp_or, errors_as_type, testing_t_context, sync_waitgroup_go, sync_once_func, new_expression, loopvar_capture, range_over_int, stdlib_uuid, strings_bytes_cut_last, strings_split_seq, strings_cut_prefix_suffix, promoted_field_literals, generic_methods.
Apply slices_sort, slices_sort_func, slices_sorted, maps_keys_values_iter,
slices_collect, errors_as_type, testing_t_context, sync_waitgroup_go,
sync_once_func, new_expression, loopvar_capture, range_over_int, min_max,
cmp_or, slices_contains, slices_index, slices_clone, maps_clone,
strings_bytes_cut_last, promoted_field_literals, stdlib_uuid, generic_methods.

Preserve stable hook order, registry tie-breakers, nil/empty wire identity,
UUID v4 semantics, pointer ownership, and independent cleanup contexts.

Validate with scoped race tests, focused integration tests, scoped lint,
root build, scoped vet, and a scoped Windows cross-build. Heavy integration
branch gates remain controller/CI-owned per the issue #482 worker contract.
Apply slices_sort, slices_sort_func, slices_sorted, maps_keys_values_iter, slices_collect, errors_as_type, testing_t_context, sync_waitgroup_go, sync_once_func, new_expression, loopvar_capture, range_over_int, cmp_or, strings_bytes_cut_last, slices_contains, maps_clone, bytes_clone, slices_clone, promoted_field_literals, stdlib_uuid, and min_max.
Apply errors_as_type while preserving lazy matching and non-error interfaces.
Repair testing_t_context cleanup lifetimes and preserve ordered teardown.
Classify semantic slices_sort_func, loopvar_capture and json_omitzero exclusions.
Keep loopvar_capture enforcement limited to redundant self-copies.
pedronauck and others added 7 commits October 6, 2026 22:59
Apply testing_t_context with fresh bounded teardown contexts in store,
memory, and attachment test suites. Preserve timer and transaction cleanup
ownership, including named and indirectly invoked cleanup closures.
The new integration-tag Modern Go lint pass covers _integration_test.go
files that were never linted before. Apply its remaining findings
(embedlit, slicescontains, slicesbackward, waitgroupgo), drop the
copyloopvar suppressions that only existed while alias checking was
enabled, format the gate integration test, and tidy go.mod now that
github.com/google/uuid has no direct importers.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Fill the runbook's retained-exclusion inventory from every slice audit
(site-specific lint exceptions plus review-enforced patterns by
guideline ID) and add the #482 entry to the change-impact ledger.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@vercel

vercel Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
compozy-site Ready Ready Preview Oct 7, 2026 7:29am UTC

Request Review

@coderabbitai

coderabbitai Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

Warning

Review details and warnings were omitted to fit the comment limit.

@greptile-apps

greptile-apps Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 5/5

[High risk] Adopts modern Go stdlib across all modules and enforces it in CI.

The changes since the last review appear safe to merge.

Summary

This PR adopts newer Go patterns across modules and expands lint coverage to nested modules, fixtures, and build-tagged tooling.

  • Adds module-aware lint and gate lanes, plus a developer runbook.
  • Updates sorting, error matching, test contexts, and JSON tags while aiming to preserve existing behavior.
  • Since the last review, only one catalog test changed: its timeout increased to 15 seconds. Its assertions remain unchanged.
  • No new actionable findings were identified. No tests were run during this review.
Diagram
%%{init: {'theme': 'neutral'}}%%
flowchart TD
  Entry["make go-lint / CI"] --> Dispatch["Select module and package scopes"]
  Dispatch --> Root["Root: default lint"]
  Dispatch --> Integration["Root: integration-tag Modern Go checks"]
  Dispatch --> SDK["SDK and example modules"]
  Dispatch --> Mage["Mage tooling"]
  Dispatch --> Fixtures["Fixture modules"]
  Fixtures --> Workspace["Temporary workspace with local SDK"]
  Workspace --> FixtureLint["Lint fixtures"]
  FixtureLint --> Cleanup["Remove temporary workspace"]
Loading

Reviews (3) · Last reviewed commit: "test: budget the catalog search test for..." · Reviewed by Greptile

The catalog search test runs accessible-name role queries over the full
catalog, which takes about 4s in jsdom and exceeds the 5s default when a
broad change invalidates the turbo cache and every workspace suite runs
concurrently. Give it the same per-test budget the site suite already
uses for heavy jsdom renders; assertions are unchanged.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

React Doctor found no new issues. 🎉

Reviewed by React Doctor for commit 33d65d5.

@pedronauck
pedronauck merged commit b40b1bf into main Oct 7, 2026
52 checks passed
@pedronauck
pedronauck deleted the modern-go-482 branch October 7, 2026 17:23

This branch was successfully deployed

1 active deployment
Preview — 33d65d53 Deployed Oct 7, 2026 by vercel[bot]
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.

[Refactor] Complete Modern Go adoption across Go 1.26 boundaries

1 participant