If go-stack.sh fails (non-zero exit or "status":"error" in its JSON) print ⚠️ <error.message> and stop. Other failing commands are findings — report and continue.
Steps
- Run
.agents/skills/pflow-golang/scripts/go-stack.sh→{go_version, toolchain, cli, rpc, testing[], other[], golangci_config, task_runner, lib_references[]}. - Read the topic references that match the task (table below) and every file in
lib_references. Skip the rest. - Write or review the code. Apply modern-Go rules only up to
go_versionfrom step 1; each rule inmodernize.mdnames its minimum version. - Before finishing, run the project's own gate when
task_runnerhas one (task check,make lint, …); otherwisegofmt -l .,go vet ./..., andgolangci-lint run ./...whengolangci_configis set.
| Task | Read |
|---|---|
| Any new or changed code | style-naming.md, errors-safety.md |
| Types, constructors, APIs | structs-interfaces.md, patterns.md |
| Goroutines, channels, ctx, timeouts | concurrency-context.md |
| Slices, maps, strings, allocations | slices-maps.md, performance.md (only when a hot path is named) |
| Tests, mocks, fixtures | testing.md |
| Old code, deprecations, upgrade | modernize.md |
| Input, files, crypto, secrets, exec | security.md |
| Code review | style-naming.md, errors-safety.md, security.md, then the task-specific files |
Paths are relative to this skill: .agents/skills/pflow-golang/references/.
Iron rules
- Handle every error once: wrap with
%wand context, or handle it — never both, never_. - Accept interfaces, return structs. Define interfaces where they are consumed, keep them 1–3 methods.
context.Contextis the first parameter, never a struct field. Every goroutine has an owner that knows when it stops.- Make the zero value useful; no
init(), no package-level mutable state. - Follow the project's conventions (AGENTS.md, existing packages) over these rules when they conflict — and say so.
- Prefer stdlib (
slices,maps,cmp,log/slog,errors) over a dependency that does the same.