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 Osterhout

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

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