[typist] Go Type Consistency Analysis Report #25624
Closed
Replies: 1 comment
-
|
This discussion was automatically closed because it expired on 2026-04-11T11:46:35.676Z.
|
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Analysis of repository: github/gh-aw — workflow run §24240983815
This report summarizes findings from a semantic analysis of all non-test Go files in
pkg/(666 files). The codebase has already migrated frominterface{}to the modernanyalias — zerointerface{}usages were found. Type duplication is largely well-managed through the sharedpkg/typespackage. A small set of actionable improvements were identified, primarily aroundany-typed fields that could carry more specific types.Highlights:
interface{}usages — fully modernised toanyany-typed fields identified (2 high priority, 3 medium, 2 low)pkg/types/mcp.go) already in use and working wellFull Analysis Report
Duplicated Type Definitions
Summary Statistics
Apparent Duplicates — All Resolved
All four same-name type pairs were investigated and found to be intentional:
MCPServerConfig— two packages, one shared baseBoth
pkg/parser/mcp.go:35andpkg/workflow/tools_types.go:366defineMCPServerConfig, but both embedtypes.BaseMCPServerConfigfrompkg/types/mcp.go. This is the correct pattern — the shared fields live inpkg/types, and each package adds its own domain-specific fields (JSON tags +Name/Registry/ProxyArgs/Allowedfor the parser; YAML tags +Mode/Toolsets/GuardPolicies/CustomFieldsfor the workflow compiler). No action needed.FileTracker— interface + implementationpkg/workflow/compiler_types.go:65defines a minimal interface:pkg/cli/file_tracker.go:19provides the concrete implementation (with git staging, rollback, etc.) that satisfies it. Standard Go pattern — no action needed.EngineConfig,RepoConfig,WorkflowJob— same name, different domainspkg/clidefinitionpkg/workflowdefinitionEngineConfigRepoConfigaw.jsonrepo settings: maintenance configurationWorkflowJobSafeJobConfiginpkg/workflowis the fuller versionThese share names but serve completely different domains. No action needed.
Untyped Usages
Summary Statistics
interface{}usagesanyusages in pkg/anyanyusagesWell-Justified
anyUsage (No Action Needed)The dominant pattern —
map[string]anyinpkg/parser/(~100 occurrences across 6 files) — is correct and idiomatic. YAML/JSON schema documents are genuinely untyped trees;map[string]anyis the standard Go representation. Similarly:FrontmatterConfig.Engine/Imports/Include/Checkout any— each field accepts either a scalar or a structured value (e.g., engine can be"copilot"or{id: copilot, max-continuations: 2})WorkflowStep.ContinueOnError any— GitHub Actions allowstrue/falseor an expression string like$\{\{ inputs.continue }}rpcRequestPayload/rpcResponsePayload.ID any— JSON-RPC 2.0 specifiesidasstring | number | nullSafeJobConfig.RunsOn / WorkflowJob.RunsOn any— GitHub Actionsruns-onis a string or array of labelsImprovable
anyUsagesPriority 1 (High):
GitHubReposScope any— Named Type Alias Provides No Safetypkg/workflow/tools_types.go:275GitHubToolConfig.AllowedRepos(line 293) andGitHubToolConfig.Repos(line 295)A named type over
anycannot carry methods, cannot be switch-typed without an assertion, and gives callers no additional safety over bareany. The comment itself documents the two valid states (stringor[]any), which is exactly what a union struct + custom unmarshaler would make compile-time-safe:Benefits: Eliminates all type assertions at usage sites; makes invalid states unrepresentable; documents the two valid shapes in the type system.
Priority 1 (High):
AwInfo.RunID / AwInfo.RunNumber any— JSON Number-or-String Polymorphismpkg/cli/logs_models.go:300–301GitHub Actions emits
run_idandrun_numberas either a JSON number or a JSON string depending on context/version. Theanytype forces all consumers to type-assert. Usingjson.Number(whichencoding/jsonunmarshals both forms into correctly) is a targeted, non-breaking fix:json.Numberhas.String(),.Int64(), and.Float64()methods, giving callers type-safe access without runtime panics.Priority 2 (Medium):
SafeJobConfig.Steps []any—WorkflowStepAlready Existspkg/workflow/safe_jobs.go:22WorkflowStepinpkg/workflow/step_types.gowas purpose-built to represent a GitHub Actions step. The safe-job steps are later converted viaMapToStep. Using[]*WorkflowStepdirectly would eliminate this intermediate conversion:Estimated effort: Medium — requires updating YAML parsing at load time and removing
MapToStepcalls.Priority 2 (Medium):
CopilotWorkflowStep.Env map[string]any— Inconsistency with Peer Typepkg/cli/copilot_setup.go:143GitHub Actions
env:map values are always strings. Usingmap[string]anyhere is inconsistent withWorkflowStepand adds unnecessary complexity to consumers.Estimated effort: Low — likely a direct type change with no semantic impact.
Priority 2 (Medium):
DevcontainerFeatures map[string]any— Named Type Aliaspkg/cli/devcontainer.go:39Feature values in devcontainer JSON are genuinely heterogeneous (strings, booleans, objects). The named type is a useful signal of intent, but
map[string]json.RawMessagewould preserve the heterogeneity while enabling structured access:This is a lower-priority change since the type name already communicates intent — but it would enable marshalling round-trips without losing type information.
Priority 3 (Low):
FormField.Value any— Sealed Interface Possiblepkg/console/console_types.go:46The
Valuefield stores a pointer to the result destination (*string,*bool, etc.). A sealedFormValueinterface would make invalid assignments detectable at compile time. However, given the small number of types and the pragmatic nature of interactive form libraries, this is low priority.Priority 3 (Low):
serviceContainerConfig.Ports any— One Unnecessary Level of Assertionpkg/workflow/service_ports.go:50The outer type assertion to
[]anycould be eliminated by declaring the field as[]anydirectly. Each element would still need an inner assertion (string, int, etc.), but the outer check becomes a compile-time guarantee.Untyped Constants
Many package-level constants lack explicit type annotations. The most semantically ambiguous are in
pkg/constants/constants.goandpkg/constants/job_constants.go:Explicit types or a type alias (e.g.,
type Seconds int) would eliminate unit confusion, especially for timeout and rate-limit values. This is a medium-effort, medium-benefit refactor affecting ~30+ constants.Implementation Checklist
GitHubReposScope: Replaceanyalias with union struct + custom YAML unmarshaler (pkg/workflow/tools_types.go:275)AwInfo.RunID/RunNumber: Replaceanywithjson.Number(pkg/cli/logs_models.go:300–301)SafeJobConfig.Steps: Replace[]anywith[]*WorkflowStepand remove intermediate conversion (pkg/workflow/safe_jobs.go:22)CopilotWorkflowStep.Env: Changemap[string]any→map[string]string(pkg/cli/copilot_setup.go:143)DevcontainerFeatures: Considermap[string]json.RawMessageovermap[string]any(pkg/cli/devcontainer.go:39)FormField.Value: Evaluate sealedFormValueinterface (pkg/console/console_types.go:46)serviceContainerConfig.Ports: Changeany→[]any(pkg/workflow/service_ports.go:50)Analysis Metadata
*_test.gointerface{}usagesanyusagesanylocationsBaseMCPServerConfiginpkg/types)References:
Beta Was this translation helpful? Give feedback.
All reactions