Backend Go
Go services, APIs and workers (net/http, database/sql, context, slog) with explicit dependencies, checked errors, owned goroutines and resources, bounded work and evidenced completion. Rule IDs E/A/R/C/G/H/D/S/O/T/V; NEED TO blocks on demonstrated violations.
Set this profile
ccpp cpo profile set backend-goInside Claude Code, prefix the command with ! to run it in the session. Downloading a profile needs a Builder or Team plan; listing them does not.
Policies
63 policies, grouped by what they guard.
Secrets & private data 2
Credentials, keys and personal data stay out of files, logs, commands and the conversation.
go-s02-weak-randomness-for-secretsS02 · The user confirms math/rand used where tokens, keys, passwords or nonces are generated
go-s03-sensitive-loggingS03 · Log calls do not pass passwords, tokens, keys, cookies or authorization headers unredacted
Untrusted input 1
Requests, downloads and tool output are validated before they reach SQL, a shell, eval or a deserializer.
go-d01-sql-interpolationD01 · The user confirms SQL text built with fmt.Sprintf or concatenation of runtime values
Network & TLS 2
Outbound data, verified certificates, destinations taken from requests and services exposed to others.
go-s01-custom-tls-verifierS01 · The user confirms InsecureSkipVerify replaced by a custom VerifyConnection or VerifyPeerCertificate
go-s01-tls-verificationS01 · Production TLS clients verify peers (no InsecureSkipVerify without a replacement verifier)
Weakened checks 3
Suppressions, disabled lint or CI steps and relaxed strictness need a reason or the user's approval.
go-e06-unscoped-suppressionsE06 · A new //nolint, //lint:ignore or
go-e06-weakened-checksE06/V03 · The user confirms lint or CI changes that disable analyzers, add exclusions or drop vet, race or lint steps
go-v03-vet-analyzersV03 · No new go vet finding reported by gopls (lostcancel C04, copylocks G04, waitgroup G05, testinggoroutine T06, printf…)
Type safety 1
No escapes from the type checker (any, unchecked casts, non-null assertions) and explicit contracts.
go-r06-unchecked-type-assertionsR06 · Single-result type assertions are replaced by the comma-ok form unless a type invariant holds
Error handling 6
Failures are propagated or handled, never swallowed or turned into fake success.
go-r01-discarded-errorsR01 · A call whose error result gopls types is not dropped by a bare statement or a blank identifier
go-r03-error-text-matchingR03 · Errors are classified with errors.Is/As, not by matching the text of Error()
go-r04-log-and-returnR04 · A layer logs an error or returns it, not both on the same path
go-r05-panics-in-handlersR05 · Request handlers return errors for expected failures instead of panic or Must helpers on runtime input
go-r07-exit-in-libraryR07 · Library packages return failures instead of os.Exit or fatal loggers (resolved by import or gopls)
go-r08-wrap-loses-causeR08 · fmt.Errorf that formats an error with %v or %s instead of %w is reviewed
Async & concurrency 9
Owned tasks, awaited promises, preserved cancellation and no blocking on event loops.
go-c01-context-firstC01 · A context.Context parameter comes first
go-c01-nil-contextC01 · No call passes a nil context (literal nil to a context.Context parameter, resolved by gopls)
go-c02-context-fieldsC02 · Request operations take contexts as parameters instead of storing them in struct fields
go-c03-detached-contextC03 · Request-scoped work derives from the incoming context (no Background/TODO, no context-free HTTP or SQL calls there)
go-c04-discarded-cancelC04 · The cancel function of context.WithCancel/WithTimeout/WithDeadline is never discarded into _
go-c05-context-key-typesC05 · context.WithValue keys are private comparable types, not built-in strings or numbers
go-c06-dependencies-in-contextC06 · Context values carry request metadata, not databases, clients, loggers or configuration
go-g01-unowned-goroutinesG01 · A launched goroutine has a visible owner that waits for it (WaitGroup, errgroup, a done or result channel)
go-g02-goroutines-in-handlersG02 · Request handlers finish their work synchronously instead of leaving goroutines running after they return
Performance & resource bounds 6
Timeouts, bounded retries and fan-out, reused clients, closed resources, no N+1 queries.
go-d05-pools-per-callD05 · Database pools are opened once at startup, not per request or per loop iteration
go-g03-unbounded-fan-outG03 · Goroutines launched per input item run under a declared bound (errgroup.SetLimit, a semaphore, a worker pool)
go-h01-unbounded-http-callsH01 · Outbound HTTP calls have a finite budget (no http.Get/Post or DefaultClient, which have no timeout or context)
go-h02-clients-per-requestH02 · HTTP clients and transports are built once and reused, not per request or per loop iteration
go-h06-unbounded-request-bodiesH06 · Handlers bound the request body (http.MaxBytesReader) before decoding or buffering it
go-h07-unbounded-shutdownH07 · Server shutdown drains within a bounded context, not context.Background()
Architecture & boundaries 5
Declared layers and dependency directions, no import cycles, small modules, explicit dependencies.
go-a01-import-boundariesA01 · Imports respect the project's declared dependency boundaries (off until importRules is set)
go-a02-transport-types-in-domainA02 · Exported business operations in designated domain packages take and return domain types, not HTTP or SQL ones (off until domainPaths is set)
go-a04-mutable-globalsA04 · Functions do not write package-level variables that drive behavior (outside init and lock-protected registries)
go-a05-init-side-effectsA05 · init functions do not perform fallible I/O or launch goroutines; startup does that explicitly
go-a09-undocumented-exportsA09 · New exported functions, methods and types of library packages carry a doc comment
Language idioms 3
The conventions of the language that keep code predictable for its readers.
go-a10-pointer-to-interfaceA10 · Parameters and fields take interface values, not pointers to interfaces (known interfaces, or gopls types)
go-r02-else-after-returnR02 · An if branch that ends in return, break or continue is not followed by an else
go-v01-gofmtV01 · New Go lines are gofmt-shaped (tab indentation, no trailing spaces) where no raw string or block comment can explain them
HTTP & APIs 3
Request and response contracts, schemas, status codes, error bodies and published API surfaces.
go-h03-unclosed-response-bodiesH03 · A response obtained from Do/Get/Post is closed (resp.Body.Close) unless it is handed to another owner
go-h04-unchecked-statusH04 · A consumer decoding an HTTP response checks its status code first
go-h05-server-timeoutsH05 · Exposed HTTP servers set header and idle budgets (http.Server with ReadHeaderTimeout, no bare ListenAndServe)
Databases & queries 3
Schemas, queries, transactions and the ORM used as intended.
go-d02-rows-lifecycleD02 · Query results are closed when iteration can stop early, and iteration errors are checked with rows.Err()
go-d03-transaction-lifecycleD03 · A started transaction is rolled back on failure paths and its Commit error is checked
go-d04-base-handle-in-transactionD04 · Inside a transaction, statements go through the transaction handle, not the base *sql.DB
Configuration 1
Settings read once at a boundary, validated, with units and without unsafe defaults.
go-a03-environment-outside-configA03 · Operations receive configuration through construction instead of reading the environment themselves
Logging & observability 3
Structured logs, bounded metric labels, no debug prints left in production code.
go-o01-raw-printsO01 · Library and service code logs through the project's structured logger, not fmt.Print or println
go-o02-unbounded-metric-labelsO02 · Metric labels take bounded values (no user, request or session IDs, raw URLs, emails or error texts)
go-o04-metrics-registered-per-callO04 · Metrics are created and registered once, not inside handlers or per call
Dependencies & toolchain 3
Packages change through the package manager, lockfiles stay consistent and the project's tools are used.
go-v05-dependency-additionsV05 · New module requirements name the capability that needs them and keep go.sum consistent
go-v05-go-sum-syncV05 · A turn that adds requirements to a go.mod also updates its go.sum (go mod tidy)
go-v05-module-changesV05 · The user confirms local replace directives and changes to the go or toolchain directive of go.mod
Generated files 1
Build outputs, generated code and tool-owned files are regenerated, never edited by hand.
go-v06-generated-editsV06 · The user confirms hand edits to generated Go files (// Code generated … DO NOT EDIT.)
Tests 7
Tests assert behavior, stay deterministic and are not removed or skipped silently.
go-t01-untested-changesT01 · A turn that changes production Go code either changes tests too or says why none applies (once per stop)
go-t02-assertion-free-testsT02 · A new Test function asserts an observable outcome (t.Error/Fatal, testify, cmp, a helper taking t, or subtests)
go-t04-temp-resourcesT04 · Tests create temporary files and directories with t.TempDir or register their cleanup
go-t05-parallel-global-mutationT05 · t.Setenv and t.Chdir are never used in a parallel test or under a parallel parent (they panic)
go-t06-fatal-in-goroutineT06 · Spawned goroutines in tests report with t.Error, never t.Fatal/FailNow or testify require
go-t07-sleep-in-testsT07 · Concurrent tests synchronize on events or controllable time, not on time.Sleep
go-v04-data-racesV04 · A race detector report in a test or run output is fixed before going on
Completion evidence 4
A turn ends with its checks run and passing; claims of success need proof after the last edit.
go-turn-baselineRecords the work tree when a prompt starts, the baseline of the end-of-turn checks (V02, V05, T01)
go-v02-completion-claimsV02 · A final message claiming a passing build, vet, lint or tests needs a successful go run after Claude's last edit
go-v02-evidence-ledgerV02 · Records, per session, Claude's edits and the go build, vet, test or lint runs that succeeded after them
go-v02-new-compile-errorsV02 · Claude does not end a turn with compiler errors it introduced in Go sources or their importers (gopls)