Talk

The Go Code You Didn’t Write

Day-2 Engineering in a Post-Human Codebase

June 14, 2026 · Sample meetup deck · Sydney · 30 min

Mode: Slides

Reading mode: scroll normally. Use Present to return to slides.

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 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.

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.Do
  • io - io.Reader, io.Writer, etc.
  • regexp - Doesn’t steal regex var name

Don’t repeat the pkg name

// 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

// BAD.
usersMap := map[string]User{}
// GOOD.
users := map[string]User{}
// 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
  // BAD. DON'T DO THIS.
  if err != nil {
    logger.Error("operation failed", "error", err)
    return err
  }
  // 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

// BAD. DON'T DO THIS!
func (s Service) ChristmasSaleProducts(ctx context.Context) ([]Product, error) {
// 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

Deep modules

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?

// 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 _test package name for tests
  • Avoid test frameworks/libs
  • Use executable examples
  • Fast feedback loop for AI agents
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
// 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

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
}
// 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.

Final takeaway

AI can generate code.

Engineering teams must generate confidence.