Skip to content

[Refactor] Complete Modern Go adoption across Go 1.26 boundaries #482

Closed

Description

@pedronauck

Problem

Compozy targets Go 1.26.4 and already uses many current standard-library idioms, but Modern Go compliance is uneven and is not enforced across every checked-in Go boundary.

The root .golangci.yml enables modernize, yet the default root ./... scope does not enter nested modules. Build-tagged magefiles, SDK examples, and extension fixture modules also lack equivalent lint coverage. As a result, a clean root lint does not establish repository-wide compliance.

This issue should complete the migration without treating syntax changes as behavior-neutral. Error target shape, goroutine ownership, stable ordering, nil/empty collections, JSON omission, cancellation lifetime, and route precedence are contracts that must be preserved.

Evidence

  • The repository contains six Go modules, all declaring Go 1.26.4: the root module, sdk/go, two SDK examples, and two extension fixture modules.
  • Production code already has broad modern adoption (errors.Join, typed atomics, slices/maps, iterator APIs, time.Since/time.Until, and modern benchmarks).
  • A production-only collection survey found 121 legacy sort calls, concentrated in internal/loop, internal/cli, internal/config, internal/modelcatalog, and internal/task.
  • Verified mechanical candidates include legacy errors.As, ordinary ordered sorts, deterministic map-key collection, at least nine redundant loop-variable copies, and a small number of local WaitGroup.Go/sync.OnceFunc conversions.
  • internal/testutil/testutil.go creates timeout contexts from context.Background() instead of inheriting the owning test context.
  • internal/sandbox/daytona/cmd/compozy-daytona-sidecar/server.go manually dispatches HTTP methods and parses path suffixes; it is a candidate for method-aware http.ServeMux patterns and Request.PathValue.
  • scripts/gate.sh tests sdk/go but does not give it an equivalent lint lane, and Go changes under SDK examples can be classified into JavaScript-oriented filters.

Scope

1. Establish an authoritative baseline

  • Run the Modern Go Guidelines CLI for all 48 rules resolved for Go 1.26.4 across:
    • root module;
    • sdk/go;
    • sdk/examples/notes-commands;
    • sdk/examples/clarify-tool;
    • both internal/extension/testdata/*-fixture-go modules;
    • build-tagged magefiles.
  • Record each residual finding as mechanical, semantic, generated, or a justified exclusion.
  • Document which guideline IDs are enforced by modernize and which need another explicit check.

2. Apply behavior-preserving mechanical migrations

  • Convert verified errors.As calls to errors.AsType only when pointer/value target semantics remain identical.
  • Replace ordinary ordered sorts with slices.Sort and direct map-key collection plus sorting with slices.Sorted(maps.Keys(...)).
  • Remove verified redundant loop-variable self-copies.
  • Make shared test timeout helpers inherit t.Context().
  • Use WaitGroup.Go and sync.OnceFunc only for clear, locally owned equivalents.

3. Review semantic migrations by owning layer

  • Stable sorts: preserve tie ordering and comparator behavior.
  • Clone/search/iterator helpers: preserve nil versus empty identity, shallow/deep ownership, no-match defaults, and required materialization.
  • Context and WaitGroup changes: preserve cancellation, admission locking, completion, and goroutine ownership.
  • Pointer allocation: preserve aliasing and normalization behavior.
  • JSON tags: audit field-by-field before adopting omitzero; preserve empty collection and tri-state wire behavior.
  • HTTP routing: modernize the Daytona sidecar only with route, status, malformed-path, and websocket-upgrade parity.

4. Make compliance continuous

  • Add Modern Go lint/check coverage for all supported nested modules and build-tagged Go tooling.
  • Correct gate classification for Go files under SDK examples and fixture modules.
  • Keep generated outputs excluded from direct edits while checking their authoritative sources and codegen drift.
  • Make a new Modern Go regression fail the appropriate repository gate regardless of module boundary.

Guardrails

  • Do not perform blanket replacements for errors.As, WaitGroup, context.Background, omitempty, clone helpers, stable sorts, tickers, or generated files.
  • Before changing a test, name the invariant, owning layer, and canonical suite; extend that suite instead of duplicating the invariant.
  • JSON/OpenAPI changes must use the contract codegen workflow and co-ship generated SDK/runtime artifacts.
  • A failed test is a production regression to fix, not a reason to weaken the assertion.
  • No compatibility bridge is needed: this is a behavior-preserving modernization of the greenfield codebase.

Acceptance Criteria

  • Every supported Go module and build-tagged Go tooling surface has an explicit Modern Go check.
  • The Go 1.26.4 guideline baseline contains no unclassified findings.
  • Safe mechanical migrations are complete with scoped race-enabled tests.
  • Semantic candidates are either migrated with owning contract tests or retained with a concrete justification.
  • JSON changes preserve HTTP/UDS/CLI/SDK wire behavior and pass codegen parity checks.
  • Daytona sidecar routing preserves route precedence, methods, status codes, malformed-path behavior, and websocket upgrades.
  • scripts/gate.sh correctly classifies nested Go module changes and runs the relevant lint/test lanes.
  • make lint and make bun-lint report zero warnings and zero errors.
  • One current make gate-full record exists at workstream close.

Web/Docs Impact

No direct web UI or documentation behavior is expected. If a JSON, HTTP, CLI, UDS, or SDK contract changes during the work, update generated references and public docs in the same change and reset the owning QA scenario to untested before verification.

Extensibility, Agent Manageability, and Config Lifecycle

The intended work is a behavior-preserving Go refactor. No new extension surface, hook, capability, registry, native tool, CLI verb, HTTP/UDS operation, or config.toml key is expected. Verify contract parity across agent-manageable CLI/HTTP/UDS/SDK surfaces when touching JSON or routing code. If parity cannot be preserved, split the behavior change into a separate spec.

Compozy Impact Audit

  • Native tools: no intended change; verify existing compozy__* descriptors, schemas, digests, risk flags, and capability gates remain byte-for-byte or semantically unchanged when shared contracts are regenerated.
  • Extensibility and hooks: no intended change; check extension fixtures, tool/resource registries, bridge SDKs, hooks, and config lifecycle through the new nested-module gates.
  • Workspace data isolation: no new or changed data ownership; verify any touched HTTP/UDS/store path keeps existing workspace_id propagation and cache/event/SSE isolation.
  • Official Compozy skill: no intended public behavior or tool-ID change, so skills/compozy/ should remain unchanged; update it only if the implementation reveals an unavoidable public contract change.

Activity

  1. added
    needs-planRoadmap item that still needs an implementation plan
    on Aug 25, 2026
  2. changed the title [-]refactor: complete Modern Go adoption across Go 1.26 boundaries[/-] [+][Refactor] Complete Modern Go adoption across Go 1.26 boundaries[/+] on Aug 25, 2026
  3. added theissue type on Aug 26, 2026
  4. changed the issue type fromtoon Aug 26, 2026
  5. changed the issue type fromtoon Aug 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-planRoadmap item that still needs an implementation plan

    Type

    Fields

    No fields configured for Task.

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions