Guide 10 of 12

Conventions and agents

Rails has autoload and method_missing; Go has neither. Nothing exists until it is written down and registered, so every "magic" Rails step has a visible line in a Bogie app, and the six rules below are what keep that visible shape consistent as the app grows.

The six rules

  1. ctx context.Context is the first parameter of anything doing I/O. No context.TODO(). Cancellation, deadlines and tracing travel in it, so a request that is abandoned stops its query instead of finishing work nobody will read.
  2. Interfaces are declared where they are consumed, next to the code that uses them, holding only the methods that code actually calls, never exported from the package that implements them. A controller's store interface lists five methods, not the whole store, which is why a controller test needs no database and there is no mocking library anywhere in a generated app.
  3. app/domain imports nothing third-party. The type and its Validate can be read, and called from a test, without pulling in a database driver or an HTTP framework.
  4. Constructors return (T, error). Only main exits. A bad configuration fails at boot with a message, never with a panic in the middle of a handler.
  5. *gin.Context never travels below app/controllers. A handler converts HTTP into domain values, calls one function, and converts the result back. Everything below that line can be called from a job, a CLI, or a test, not only from a request.
  6. No util/, helpers/ or common/. A package is named for what it provides, which is a required prefix at every call site, so the name has to say something.

The layout is Rails-shaped on purpose

app/controllers, app/services, app/models, db/migrate: a Rails developer finds things where they expect them, and the generators keep it that way deliberately. Do not "fix" this into a more idiomatic Go layout; it is not an oversight, it is the point. There is no spec/ directory, though: Go tests sit beside the code they test, stdlib testing, no factories.

Underscored namespace packages

A Rails namespace (namespace :admin) becomes a Go package, admin_controller, one per namespace. Go style would spell that admincontroller or move it under a different name entirely; .golangci.yml disables the ST1003 naming check for exactly this, and nothing else, so the Rails-shaped name can stand without the linter fighting the layout it was asked to keep.

AGENTS.md and CLAUDE.md, and why generators are the deterministic path

Every generated app ships an AGENTS.md (with CLAUDE.md as the same content) holding the six rules above, every command, and a recipe per generator. It exists because an agent working on a Bogie app has the same problem a new hire does: nothing autoloads, so a controller that is written but not registered compiles, lints clean, and serves nothing. Running bogie g controller instead of writing the file by hand gets the registration right every time, in the same three places, whether the hand on the keyboard is a person's or an agent's; bogie doctor is the check that confirms it actually happened.