Repository navigation
[typist] Typist: Go type consistency findings — duplicate types and untyped usage in pkg/ #55753
Closed
Replies: 1 comment
|
This discussion has been marked as outdated by Typist - Go Type Analysis. A newer discussion is available at Discussion #56016. |
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.
🔤 Typist - Go Type Consistency Analysis
Analysis of repository: github/gh-aw
Executive Summary
I scanned all 1,317 non-test
.gofiles underpkg/(1,135 exported/unexported type definitions) for duplicated types and untyped (interface{}/any) usage. The headline finding is good news: this codebase is already disciplined about typing.interface{}is essentially extinct in production code (1 real occurrence, everything else is linter test fixtures), and the team has already built explicit semantic-type conventions (pkg/constants) and a typed replacement for the biggestmap[string]anyoffender (workflow.ToolsConfig). The real opportunities are narrower than a first grep suggests: a handful of genuine same-name type collisions to double-check, one deliberate but shrinkable near-duplicate config family (AWF/SRT/bounded-queries), and a batch of untyped file-path/artifact-name string constants that don't yet follow the semantic-type pattern already established two files away.Full Analysis Report
Duplicated Type Definitions
Summary Statistics
.gofiles underpkg/Cluster 1:
ProgressBar/SpinnerWrapper— false positive, verified cleanType: Same name, different files
Locations:
pkg/console/progress.go:31((go/redacted):build !js && !wasm)pkg/console/progress_wasm.go:9((go/redacted):build js || wasm)pkg/console/spinner.go:92((go/redacted):build !js && !wasm, inferred)pkg/console/spinner_wasm.go:12((go/redacted):build js || wasm)Verdict: Not a duplicate. These are intentional per-platform implementations selected by build tags (native TTY vs. WASM/JS). No action needed — flagging only so the team knows this pattern was checked, not missed.
Cluster 2:
Finding— same name, different conceptsType: Naming collision (not a structural duplicate)
Occurrences: 2
Impact: Low-medium — no functional bug, but the same word means two different things in two packages that both deal with "problems found in a workflow."
Locations:
pkg/scanfindings/scanfindings.go:107— shared scanner finding format (RuleID,Severity,Message,File,Line,Column,Context)pkg/cli/audit_report.go:67— an audit insight (Category,Severity,Title,Description,Impact)Recommendation: Rename the audit-report one to
AuditFinding(or similar) to avoid ambiguity when both packages are imported side by side, e.g. inpkg/cli. Low effort (single type + its constructors), no behavior change.Cluster 3:
ValidationError— good pattern, not a duplicateLocations:
pkg/validationerror/validationerror.go:49— sharedValidationErrorinterface (error+ValidationField/Value/Reason/Suggestion)pkg/parser/validation_error.go:12—parser.ValidationErrorstruct embeddingvalidationerror.Payload, implementing the shared interfaceworkflow.WorkflowValidationErrorfollows the same embedding patternVerdict: This is exactly the "consolidate common behavior, let each package keep its own concrete type" pattern the rest of this report recommends elsewhere. Worth calling out as a positive example other clusters (see below) could follow, not a problem to fix.
Cluster 4: AWF / frontmatter bounded-query config — deliberate near-duplicate, shrinkable
Type: Near duplicate (same fields, different serialization tags)
Impact: Medium — two structs to keep in sync by hand whenever the schema changes
Locations:
pkg/workflow/tools_types.go:414BoundedQueriesConfig/:454BoundedQueryPrivateRepo— YAML frontmatter shape (yaml:"..."tags)pkg/workflow/awf_config.go:111AWFBoundedQueriesConfig/:145AWFBoundedQueryPrivateRepo— AWF config-file JSON shape (json:"..."tags)Both carry the identical field set (
PrivateRepos,Runtime,Timeout,MemoryLimit,Interpreter,MaxInvocations), and the AWF-side doc comments even say things like "A pointer mirrors BoundedQueriesConfig.Timeout so nil-vs-zero semantics stay in sync" — the duplication is already acknowledged in comments as something that has to be kept in sync manually.Recommendation:
yamlandjsontags per field (Go supports multiple tags on one field), orCluster 5: Network/filesystem sandbox config — same package, overlapping responsibility
Locations:
pkg/workflow/awf_config.go:168AWFNetworkConfig(AllowDomains,BlockDomains,Isolation,TopologyAttach) /:188AWFFilesystemConfig(AllowWrite)pkg/workflow/sandbox.go:167SRTNetworkConfig(AllowedDomains,BlockedDomains,AllowUnixSockets,AllowLocalBinding,AllowAllUnixSockets) /:176SRTFilesystemConfig(DenyRead,AllowWrite,DenyWrite)Verdict: These are not structurally identical (SRT has finer-grained unix-socket and read/write-deny controls AWF doesn't), so this is a semantic overlap rather than a copy-paste duplicate — both packages model "what can this sandbox touch on the network/filesystem" for two different sandbox backends (AWF vs. SRT) living in the same
pkg/workflowpackage.Recommendation: Lower priority than Cluster 4. Worth a follow-up design question for the team: do AWF and SRT genuinely need independent shapes, or could a shared
NetworkPolicy/FilesystemPolicybase with backend-specific extension fields serve both? Not urgent — flagging for awareness, not immediate action.Untyped Usages
Summary Statistics
interface{}usages (non-test): 1 in production code (pkg/workflow/behavior_defined_engine.go), 17 more in linter testdata/golden fixtures — effectively already eliminated.anyusages (non-test): ~2,700 across ~450 files, dominated bymap[string]any(~2,715 hits, 448 files, some overlap with plainany).pkg/constants/*.go(90 of the 392).Category 1:
anyusage is mostly legitimate — the codebase already knows thisgh-awcompiles arbitrary YAML/JSON workflow frontmatter, JSON Schema documents, GitHub Actions stepwith:blocks, and MCP registry payloads — domains that are inherently dynamic before validation. Mostmap[string]any/[]anyusage sits in parser/schema/YAML-conversion code (pkg/parser/import_field_extractor.go,pkg/parser/schema_suggestions.go,pkg/parser/mcp.go,pkg/workflow/frontmatter_serialization.go, etc.), where a dynamic container is the correct representation, not a shortcut.The team is already aware of this:
pkg/workflow/tools_types.go:14documentsToolsConfigexplicitly as "a structured alternative to the pervasivemap[string]anypattern", withParseToolsConfig/ToMapbridging functions for legacy callers. That's the right shape for future reductions — I'd extend the same treatment to othermap[string]anybridge points rather than treating the raw count as a problem to zero out.Impact: Low as a whole (working as intended), but worth targeted follow-up on the items below.
Category 2: Concrete, worth-fixing
anyfieldsExample 1:
GitHubReposScopepkg/workflow/tools_types.go:306type GitHubReposScope any // string or []any (YAML-parsed arrays are []any)stringvs[]anyto use this value.UnmarshalYAMLthat normalizes both YAML shapes into[]stringinternally:Example 2:
Raw anyfieldspkg/workflow/tools_types.go:509, 515, 522Raw any \yaml:"-"`` fields.ToolsConfigexists as the typed replacement for the map-based representation, check whether eachRawfield's actual runtime type is narrow enough (e.g., alwaysmap[string]anyfrom a specific parse step) to replace with a concrete struct or a sharedRawToolPayloadtype. This needs a quick audit of assignment sites before committing to a type, so treat as a "look, then fix" task rather than a blind rename.Category 3: Untyped constants — the pattern to fix is right there in the same package
pkg/constantsalready defines and documents semantic string types for exactly this purpose (JobName,StepID,MCPServerID,CommandPrefix,WorkflowID,LineLength), with a comment block explicitly explaining the convention:But in the same files, dozens of related constants are still bare untyped strings, e.g.:
Suggested fix: introduce
ArtifactName,Filename, andFilePathsemantic types alongside the existing ones and retype these constants:Impact: Medium — this isn't introducing a new idea to the codebase, it's finishing one the team already started. It would also make it a compile error to accidentally pass a
Filenamewhere aFilePathorArtifactNamewas expected, which today are all interchangeable bare strings.Estimated effort: 3-4 hours (mostly mechanical retyping + fixing call sites that build paths via string concatenation).
Everywhere else, the 392 untyped constants are spread thinly (1-6 per file) across CLI/parser/workflow code and are mostly one-off sentinel strings or magic numbers local to a single file — lower priority than the concentrated
pkg/constantscluster above.Refactoring Recommendations
Priority 1: Extend the existing semantic-type convention to remaining
pkg/constantsstringsSteps:
ArtifactName,Filename,FilePathtypes topkg/constants/constants.gonext to the existing semantic types.pkg/constants/job_constants.goandconstants.gothat are clearly artifact names, filenames, or paths.stringconversions or comparisons).Estimated effort: 3-4 hours
Impact: Medium — closes a gap in a convention the team already committed to.
Priority 2: Consolidate the AWF/frontmatter bounded-query config duplication (Cluster 4)
Steps:
pkg/workflow/tools_types.goandpkg/workflow/awf_config.goaccordingly.Estimated effort: 2-3 hours
Impact: Medium — removes a manual-sync burden the code comments already flag as fragile.
Priority 3: Rename
cli.Findingto avoid collision withscanfindings.Finding(Cluster 2)Steps:
pkg/cli/audit_report.go.pkg/cli.Estimated effort: <1 hour
Impact: Low — readability only, no functional risk.
Priority 4 (optional, needs an audit first): Type
GitHubReposScopeand review the threeRaw anyfieldsEstimated effort: 2-3 hours (mostly the audit of
Rawcall sites)Impact: Low-medium — removes a handful of type assertions.
Implementation Checklist
ArtifactName/Filename/FilePathsemantic types topkg/constantsand retype existing constantsBoundedQueriesConfig/AWFBoundedQueriesConfigfield definitionscli.Finding→cli.AuditFindingGitHubReposScopea real type with custom YAML unmarshalingRaw anyfields inpkg/workflow/tools_types.gofor narrowingAWFNetworkConfig/SRTNetworkConfigand their filesystem counterparts should share a base typeAnalysis Metadata
pkg/)any/map[string]any, 392 untyped constants across 182 filespkg/constants,pkg/workflowconfig types — over exhaustive per-file review)All reactions