Conversation
Co-authored-by: dsyme <7204669+dsyme@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adds a new scheduled agentic workflow to incrementally remove unreachable Go functions using golang.org/x/tools/cmd/deadcode, applying safety checks and opening small PRs with verification.
Changes:
- Introduces a new gh-aw workflow prompt for a “Dead Code Removal Agent” with batching, safety checks, verification, and cache-memory tracking.
- Adds the compiled
.lock.ymlworkflow generated from the markdown source.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| .github/workflows/dead-code-remover.md | Defines the workflow frontmatter and the agent instructions for finding/removing dead Go functions and opening PRs. |
| .github/workflows/dead-code-remover.lock.yml | Generated GitHub Actions workflow implementing the scheduled agent run, safe-outputs handling, and cache-memory persistence. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| ## Phase 2: Check Cache for Previously Processed Functions | ||
|
|
||
| Read `/tmp/gh-aw/cache-memory/dead-code-processed.jsonl` to find functions already processed in previous runs. Each line has the form: | ||
|
|
||
| ```json | ||
| {"function": "FuncName", "file": "pkg/workflow/foo.go", "processed_at": "2026-03-01", "action": "deleted"} | ||
| ``` | ||
|
|
||
| Build a set of `"file:FuncName"` keys to skip — this ensures each function is only processed once. |
There was a problem hiding this comment.
Phase 2 instructs reading /tmp/gh-aw/cache-memory/dead-code-processed.jsonl but doesn’t say what to do when the file is absent (which will be the case on the first run, or after cache misses). Please explicitly handle the “file not found” case (treat as empty / create an empty file) so the agent doesn’t fail early when bootstrapping the cache-memory state.
| ### 4.1 Caller grep | ||
|
|
||
| ```bash | ||
| grep -rn "FunctionName" --include="*.go" . | ||
| ``` | ||
|
|
||
| - Callers **only in `*_test.go` files** → function is dead. Proceed with deletion AND mark its exclusive test functions for removal. | ||
| - Callers in **any non-test file** → **skip** (possible false positive from `deadcode`). |
There was a problem hiding this comment.
The caller check grep -rn "FunctionName" --include="*.go" . will always match the function’s own definition (and can match comments/strings), which makes the “callers only in *_test.go” decision ambiguous and error-prone. Consider tightening this check to search specifically for call sites and/or explicitly ignore the defining func FunctionName line and comment-only matches so the workflow doesn’t mistakenly skip or delete functions based on self-matches.
| Run targeted package tests for every package you modified: | ||
|
|
||
| ```bash | ||
| go test ./pkg/... 2>&1 |
There was a problem hiding this comment.
Phase 6 says to run targeted tests “for every package you modified”, but the command given is go test ./pkg/..., which won’t execute tests for changes in cmd/..., internal/..., or other module directories that may be edited as part of deadcode removals. To match the stated intent, either run go test ./... (simplest) or derive the exact set of modified packages and test those.
| go test ./pkg/... 2>&1 | |
| go test ./... 2>&1 |
| ## Important | ||
|
|
||
| You **MUST** always end by calling exactly one of these safe output tools before finishing: | ||
|
|
||
| - **`create_pull_request`**: When changes were made and the build passes | ||
| - **`noop`**: When no changes were made (nothing to remove, all skipped, or build failure) | ||
|
|
There was a problem hiding this comment.
The “Important” section requires ending with exactly one of create_pull_request or noop, but the compiled workflow also provides missing_tool/missing_data safe outputs (and upstream gh-aw automation expects those to be usable when needed). This restriction could prevent the agent from reporting missing capabilities/data in a structured way. Recommend either allowing those safe outputs in the rule, or removing them from the prompt/tooling so the guidance and available tools stay consistent.
Automates incremental removal of unreachable Go functions via a daily agentic workflow that runs
deadcodestatic analysis, selects a batch of up to 10 dead functions, applies safety checks, and opens a PR with verified removals.Workflow design
daily(fuzzy-scattered) +workflow_dispatch;skip-if-matchprevents stacking when a prior PR is still opengolang.org/x/tools/cmd/deadcodebefore the agent runsSafety checks encoded in the agent prompt
*_test.gofiles call them; exclusive test functions are removed alongsidecmd/gh-aw-wasm/main.gobefore deleting frompkg/workflow/orpkg/console/console_wasm.gostub check for anypkg/console/deletioncompiler_test_helpers.go(containsInNonCommentLines,indexInNonCommentLines,extractJobSection) — shared test infrastructure, never deletedVerification before PR creation
go build ./...→go vet ./...→go vet -tags=integration ./...→make fmt→ targetedgo test ./pkg/.... Reverts and callsnoopon any failure.