The Go Code You Didn’t Write
Day-2 Engineering in a Post-Human Codebase
Imagine working on a project where
- 100% of code is generated by AI
- you have paying customers
- you are responsible about new features
- you are responsible about production incidents
AI agents are everywhere
- Code generation
- Docs generation
- Testing
- Troubleshooting
- Automation
- Research
## Many companies want even more AI
- Teams organize token usage competitions
- Others delegate code reviews to AI agents to ship even faster
- Some even try to handle production incidents with AI agents
- Worst of all - AI generated postmortems
Using AI for the sake of using AI makes little sense.
AI helps us move fast
- Lead time from idea to PR is reduced
- The number of PRs is skyrocketing
- The size of the PRs is also increasing
Speed Has a Price
- Complexity
- Tech debt
- Spaghetti code
- (Lack of) readability
- Cognitive load
Delegate all the things

## AI Writes It. You Sign It.
- You can delegate the writing of the code
- You can **NOT** delegate the **ownership**
---
## Faster Writing, Slower Reading
- Writing code is no longer the bottleneck
- Reading (and understanding) it is
---
## AI generates code that works
It doesn't address complexity, tech debt and readability.
{ .fragment }
---
## Focus on code readability
- Every layer of abstraction is a layer of obscurity
- Simple code is readable code
- Readable code is easier to change
---
## How to improve readability?
- choose names carefully
- holistic thinking
- deep modules (packages, types)
- design your interfaces
- line of sight
- stick to the stdlib
- write table-driven tests (compare full objects)
---
## Carefully name things
- the shorter the scope, the shorter the name
- name packages after what they do, not what they contain
- do not repeat package name in funcs/types
- do not repeat type in var names
- think how your users would use it
Example pkg names
sync/once-once.Doio-io.Reader,io.Writer, etc.regexp- Doesn’t stealregexvar name
## Don't repeat the pkg name
```go
// BAD. This reads as `chubby.ChubbyFile` from outside.
package chubby
type ChubbyFile struct {}
```
// GOOD. This reads as `chubby.File` from the outside world.
package chubby
type File struct {}
## Don't repeat the type in the name
```go {.fragment}
// BAD.
usersMap := map[string]User{}
```
```go {.fragment}
// GOOD.
users := map[string]User{}
```
```go {.fragment}
// BETTER.
exists := map[string]User{}
if _, ok := exists[u.ID]; ok {
```
Think about the scope
// BAD.
var customerInvoiceResult billing.Invoice
// GOOD.
var invoice billing.Invoice
// BETTER.
var inv billing.Invoice
## Use consistent names
- For example, in testing - `args`, `got`, `want`, `tt`.
- Common variables - `svc`, `srv`, `db`, `req`, `resp`, `opts`
---
## Systems thinking
- think of your project as a system of components
- define your domain types in the root of your repo (library)
- design your architecture before writing any code
- think about failure modes
- identify business rules
Imagine you have to design and build an e-commerce app
- Should be accessible on web, tablet, phone, voice and MCP.
- Allow users to navigate products, add to cart, checkout.
- Allow admin to add products, categories, sale events.
## Domain types
- Define in the lib root `Product`, `Collection`, `Order`, etc.
- Should not have external dependencies
- Should not "know" where they are coming from
Don’t skip design phase
- Design helps you avoid complexity
- Design decisions live in your repo
## Think about your failure modes
- Each failure mode is an error
- Expect it
- Handle it
- Don't log AND return an error
Example - Product out of stock
- User 1 adds last item to the cart
- User 2 also adds last item to the cart
- User 1 checks out
- User 2 - no availability
```go
// BAD. DON'T DO THIS.
if err != nil {
logger.Error("operation failed", "error", err)
return err
}
```
```go {.fragment}
// GOOD.
if err != nil {
return fmt.Errorf("operation failed: %w", err)
}
```
Business rules
- This is where most of your bugs are
- Spaghetti code is also here
- Move it to a separate service if possible
## Handling (Christmas) Sale Events
```go {.fragment}
// BAD. DON'T DO THIS!
func (s Service) ChristmasSaleProducts(ctx context.Context) ([]Product, error) {
```
```go {.fragment}
// BAD. DON'T DO THIS!
func (s Service) BlackFridaySaleProducts(ctx context.Context) ([]Product, error) {
```
Engineers shouldn’t be involved in new sales events ideally 🤔
Deep modules
from Philosophy of Software Design by John Ousterhout

Best practices
- Carefully design the public API
- Think from the users’ PoV
- Hide implementation details
## Design public API
- API surface - the (complexity) cost you pay
- Implementation - the value you get
How can we get maximum value for minimum cost?
- Minimal API surface (narrow interface)
- General implementation (maximum benefit)
## Q: What is common between
- Men's shoes
- Kids t-shirts
- Christmas sale
- Related products
- Recommended for you
A: All of these are collections of products
## What good looks instead?
```go {.fragment}
// GOOD. (ctx skipped for brevity)
type ProductService interface {
Product(id ProductID) (*Product, error)
Products(id CollectionID, po PageOpts) ([]Product, error)
}
```
What if requirements change?
Imagine this e-commerce app becomes multi-tenanted. Instead of one shop - there needs to be many shop owners.
Product interface still doesn’t need any refactoring.
Cover your features with tests
- Code covered with tests gives confidence
- Use table driven tests
- Compare full objects (use
cmp.Diff) - Use
_testpackage name for tests - Avoid test frameworks/libs
- Use executable examples
- Fast feedback loop for AI agents
```go {hl_lines=["7-11"]}
func TestService_Product(t *testing.T) {
type test struct{}
tests := []test{}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
svc := products.NewService(tt.db)
got, err := svc.Product(t.Context(), tt.id)
// handle error
if diff := cmp.Diff(tt.want, got); diff != "" {
t.Errorf("Product(%v), res (+got,-want)\n%s\n", tt.id, diff)
}
}
}
}
```
---
## Design your interfaces
- Make your interfaces as generic as possible
- With API surface as narrow as possible
- Defining your interface is faster than typing your prompt
---
## Line of sight
- avoid unnecessary indentation
- every indented code is error handling
- avoid `else` keyword
- prefer `switch` to many `else if` statements
- happy path is last
// BAD.
if authorizationHeader != "" {
if len(bearerToken) != 2 {
// nested happy path
}
// error handling here
}
// error handling here
```go
// GOOD.
if authorizationHeader == "" {
return errors.New("missing header")
}
if len(bearerToken) == 2 {
return errors.New("invalid token")
}
// Core logic follows here at minimum indentation
return nil
```
Else statement - avoid it
In the Go libraries, you’ll find that when an if statement doesn’t flow into the next statement—that is, the body ends in break, continue, goto, or return—the unnecessary else is omitted.
Effective Go
(Avoid) Dependencies
- Best code = no code. Best dep = no dep.
- A dependency is only imported from 1 package.
- More dependencies = increased cognitive load + more tokens
## For each dependency
- Ask - can the stdlib do that
- If yes - delete the dep
Some dependencies are good
- Only ever import them from one package
- Don’t leak dependency types outside of that package
## Example - feature toggle
```go
package feature
type Client struct {
// fields
}
func (c *Client) Enabled(ctx Context, name string, def bool) bool {
//impl
}
```
Usage
Interface is declared by the consumer.
type FeatureToggle interface {
Enabled(ctx context.Context, feature string, def bool) bool
}
```go
// GOOD. Feature toggle provider isolated.
func MyFunc(ctx context.Context, ft FeatureToggle) {
if ft.Enabled(ctx, "new-feature", false) {
// new implementation
return
}
// old implementation
}
```
---
### Go review checklist for generated code
- Is the code readable
- Does it increase complexity
- Is there room for refactoring (shallow -> deep module)
---
## Managing tech debt
- Bad code compounds (so does good one)
- Ensure regular refactoring sessions
- Pay tech debt, before it grows out of the context window
---
## AI is a multiplier
- ... when used correctly
- Unfortunately, same applies when used incorrectly
---
## (Go) Engineering Fundamentals have never been more relevant.
- Effective Go - https://go.dev/doc/effective_go
- Code Review Comments - https://go.dev/wiki/CodeReviewComments
- Test Comments - https://go.dev/wiki/TestComments
---
## Final takeaway
AI _can_ generate code.
Engineering teams **must** generate confidence.
