Skip to content

refactor: resolve goconst findings via constants and parser unification - #250

Open
kazz187 wants to merge 1 commit into
mainfrom
worktree-g47g42_goconst-172
Open

refactor: resolve goconst findings via constants and parser unification#250
kazz187 wants to merge 1 commit into
mainfrom
worktree-g47g42_goconst-172

Conversation

@kazz187

@kazz187 kazz187 commented Aug 22, 2026

Copy link
Copy Markdown
Owner

Summary

golangci-lint 2.13.1 upgraded goconst 1.8.2 → 1.11.0, which widened repeated-literal counting from file scope to package scope. These are legitimate detections rather than a lapsed config, so they are resolved as a real refactor instead of being suppressed.

  • .golangci.ymlgoconst.ignore-tests: true (test fixture duplication is desirable, and goconst counts across the package so exclusions.rules cannot substitute) plus ignore-string-values: ['^(?:true|false)$'] for the stringly-typed metadata booleans. Thresholds unchanged; ignore-map-keys deliberately not used.
  • internal/claudemd (new) — unifies the four duplicated frontmatter parsers (skill/agent × file/string) behind ParseSkill / ParseAgent. Net −878 lines across the four call sites.
  • internal/eventbus/metadata.go (new) — 19 event metadata keys as shared constants, replacing literals in 16 producer files and 4 reader sites.
  • cmd/taskguild-agent/constants.go (new) — tool names, interaction option values, hook decisions, settings.json keys, task-log metadata keys and content block fields.
  • pkg/clog / internal/template / internal/project — log attribute keys, template entity types, seeded workflow status names and model.

Also folded in two pre-existing duplications flagged during the work: single_command_permission_cache.go now reuses singlecommandpermission.TypeCommand/.TypeRedirect, and the twice-declared startMarker/endMarker block in directive.go is hoisted to package scope.

Results

before after
goconst 221 0
total lint findings 2126 1873 (−253)
linters above baseline none

Notes for review

  • Measure with --uniq-by-line=false. golangci-lint rounds to one finding per line by default, which understated the real count (e.g. prompt.go:125 carries both "type" and "text" but reports one). The true non-test count was 99 across 48 distinct literals, not 90.
  • No string value changed. Every literal→constant substitution was machine-verified by expanding constant identifiers in each added line back to their declared values and comparing against the removed line — 222/222 identical. The metadata keys are a wire contract with the frontend (event-stream.ts, WorktreeList.tsx), so the values are frozen.
  • Deliberately left alone: slog attribute-name literals (different domain from event metadata, and excluded by goconst's default exclude-types: [Call]), task-log metadata maps (full_text / result_type / status_id / source), and display strings such as "**Tool:** `Bash`\n".
  • internal/schedule/server_test.go is an unrelated golangci-lint fmt fix of the pre-existing gofumpt finding.

Behaviour change to check

The string-based agent parser in internal/agentmanager/agent_conflict.go previously used strings.CutPrefix and supported neither block scalars, list-form tools:/disallowedTools:, indented keys, nor context. After unification it handles all of them. This is strictly more correct, and the new package has 31 unit tests covering it — but the ResolveAgentConflict AGENT-choice path has not been exercised against real data.

Test plan

  • go build ./...
  • go test ./... — all packages pass; the 13 existing parser tests in internal/skill / internal/agent pass unchanged, which is the regression guard for the unification
  • go tool golangci-lint run --default=none --enable=goconst --max-issues-per-linter 0 --max-same-issues 0 --uniq-by-line=false ./... → 0 issues
  • Full lint compared against baseline — no linter regressed
  • internal/claudemd lints clean under default: all
  • Exercise agent/skill conflict resolution (AGENT choice) against a real .claude/agents/*.md with block scalars

golangci-lint 2.13.1 upgraded goconst to 1.11.0, which widened repeated-literal
counting from file scope to package scope (221 findings, up from 21). These are
legitimate detections rather than a lapsed config, so resolve them as a real
refactor instead of suppressing them.

- .golangci.yml: ignore-tests (test fixture duplication is desirable) and skip
  "true"/"false", the stringly-typed metadata booleans. Thresholds unchanged.
- internal/claudemd: new package unifying the four duplicated frontmatter
  parsers (skill/agent x file/string). The string-based agent parser now also
  handles block scalars, list-form tools:, and indented keys.
- internal/eventbus/metadata.go: event metadata keys as shared constants. These
  values are a wire contract with the frontend, so they are unchanged.
- cmd/taskguild-agent/constants.go: tool names, interaction option values, hook
  decisions, settings.json keys, metadata keys and content block fields.
- pkg/clog, internal/template, internal/project: log attribute keys, entity
  types and seeded workflow status names.

goconst 221 -> 0; total lint findings 2126 -> 1873 with no linter above
baseline. Every literal-to-constant substitution was verified to resolve back
to the identical string.
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.

1 participant