AI Skill Report Card
Reviewing Go Backend Production Readiness
Quick Start13 / 15
Run this as a single, ordered pass. Do not modify code. Every finding needs file:line, severity, problem, why-it-matters, minimal fix.
1. Read docs (in exact precedence order) → build mental model of intended behavior
2. Inventory repo (git status/log, find, module map)
3. Trace architecture: domain → application → handler → infra/adapter → db
4. Review DB/adapters → domain/app logic → handlers/routes → auth/tenant → concurrency → tests
5. Run quality gates (make check, make test, go vet, go test -race, golangci-lint)
6. Cross-check docs vs code
7. Emit findings in the mandated Final Output structure
Recommendation▾
The 27-step workflow is highly specific to one codebase's conventions (e.g., 'module.go/provider.go/routes.go', booking/layout domains) — consider generalizing or clearly marking domain-specific steps as conditional to improve portability across different Go services.
Workflow15 / 15
Progress:
- Step 1: Read
.ai/rules.md(single source of truth), thendocs/README.md, then all relevantdocs/*.md, then.claude/CLAUDE.md/.github/copilot-instructions.md - Step 2: Inventory repo — entrypoints, modules, layers, migrations, DI wiring, tests, CI
- Step 3: Verify clean architecture boundaries (domain never imports infra/gin/sqlc; cross-module DB access only via
internal/database/adapters/) - Step 4: Verify DI/module composition (module.go/provider.go/routes.go; 3-phase registration: infra → modules → routes)
- Step 5: Review Go code quality (errors, context, concurrency primitives, complexity ≤15)
- Step 6: Review every HTTP handler for parse→validate→service→response flow, correct response/error wrappers
- Step 7: Verify Swagger annotations match runtime behavior and repo conventions (
{object}, not{array}) - Step 8: Audit DB layer — tenant scoping, N+1, indexes, pagination, migrations
- Step 9: Audit transactions — begin/commit/rollback correctness, idempotency, locking
- Step 10: Audit multi-tenancy as a CRITICAL boundary — tenant ID must come from auth context only
- Step 11: Audit authn/authz/RBAC — resource-level checks, not just middleware presence
- Step 12: Audit input validation/security (injection, IDOR, mass assignment, log/secret leakage)
- Step 13: Audit concurrency — races, double-booking, check-then-act, atomicity guarantees
- Step 14: Audit booking/domain invariants (overlap boundaries, timezones, status transitions) if applicable
- Step 15: Audit batch/layout editor logic (temp-ID mapping, transaction atomicity) if applicable
- Step 16: Audit error handling (wrapping, swallowed errors, leaked internals)
- Step 17: Audit observability (secrets in logs, timeouts, graceful shutdown) — only if materially impacts ops
- Step 18: Audit performance — N+1, unbounded queries, missing indexes
- Step 19: Audit test suite for real coverage vs false-confidence tests
- Step 20: Audit configuration/deployment (secrets, insecure defaults)
- Step 21: Audit dependencies (go.mod/go.sum) for demonstrable risk only
- Step 22: Identify dead code/cleanup opportunities
- Step 23: Cross-check docs vs code, format each mismatch as Says/Does/Fix
- Step 24: Run
make check,make test,go vet ./...,go test -race ./...,golangci-lint run; classify failures as introduced vs pre-existing - Step 25: Assign severities (CRITICAL/HIGH/MEDIUM/LOW/NIT) without inflation
- Step 26: Deduplicate — one systemic finding with representative locations, not 30 copies
- Step 27: Emit final structured output exactly as specified
Recommendation▾
Examples are good but all three show only bad outcomes (findings) — add at least one example of a clean pass or a NIT-level finding to demonstrate severity calibration across the full spectrum.
Examples16 / 20
Example 1:
Input: Handler reads tenant_id from request JSON body and passes it to the repository query.
Output:
HIGH
- `internal/booking/handler.go:142` — Handler accepts `tenant_id` from the
request body instead of deriving it from authenticated context. A caller
can operate on another tenant's data. Derive tenant ID from auth context;
ignore/reject client-supplied tenant IDs.
Example 2:
Input: Batch layout save loop calls repo.UpdateElement(ctx, el) once per element inside for _, el := range elements.
Output:
HIGH
- `internal/layout/service.go:88` — UPDATE executed inside a loop over
`elements` (N+1 writes) instead of a bulk operation. On layouts with
hundreds of elements this causes excessive round trips and non-atomic
partial-failure risk. Wrap in a single transaction and use a bulk
upsert/batch query.
Example 3:
Input: docs/booking.md states cancellations require status CONFIRMED, but code allows canceling from any status.
Output:
Docs/Code Mismatch
- `internal/booking/service.go:210` — Documentation
(`docs/booking.md:34`) says cancellation is only valid from `CONFIRMED`;
code permits cancellation from any status. Authoritative behavior per
docs precedence is the documented rule. Add a status guard before
transition to `CANCELLED`.
Recommendation▾
The Final Output structure is referenced repeatedly ('Emit final structured output exactly as specified') but never actually defined in the skill — include the literal template/schema for the mandated output format.
Best Practices
- Docs precedence is absolute:
docs/*.md→DATABASE_SCHEMA.md→ runtime code. Never assume code is correct when it conflicts with docs — report the mismatch. - Every finding must be traceable to an exact
file:line; no finding without a citation. - Treat multi-tenancy, auth/authz, data integrity, and concurrency as the highest-priority risk categories — review them exhaustively even if it takes longer than other sections.
- For concurrency-sensitive domains (bookings, layouts, availability), mentally test boundary intervals (
start==existing_end,start==end, overlaps, adjacency, DST) and concurrent request scenarios. - Verify DB-level enforcement (constraints, unique indexes, transactions) for any correctness property that "looks" handled only in application code.
- When the same root cause recurs, report it once systemically with a few representative locations — do not spam duplicate findings.
- Quality gate results are mandatory evidence, not optional — always attempt to run them and report exact pass/fail, classifying failures as introduced vs pre-existing.
- Use the exact severity definitions given; do not escalate or downplay based on personal preference.
Common Pitfalls
- Do not review only changed files — this is a full-codebase audit.
- Do not recommend refactors for style/preference reasons; only report violations of documented rules or real correctness/security/performance risks.
- Do not claim a vulnerability without showing a concrete, realistic attack path from the actual code.
- Do not stop after the first few findings — the mandate is complete coverage across all 29 review dimensions.
- Do not modify any files during the review, even to demonstrate a fix — output findings only.
- Do not treat middleware presence as proof of authorization — verify resource/ownership-level checks explicitly.
- Do not skip running the mandated commands (
make check,make test) or silently substitute other checks for them. - Do not report missing test coverage as a finding unless the untested behavior carries realistic regression risk.