# AGENTS.md — cmd/kettle The binary's entry point, and all of it: ```go func main() { os.Exit(cmd.Main(os.Args[1:])) } ``` One file, `main.go`, holding a package comment and that line. The sibling [`cmd/release`](../release/AGENTS.md) is the module's other binary — build infrastructure, deliberately not a `kettle` verb. ## Why it is empty Everything a `main` usually accumulates — flag parsing, dispatch, usage text, error formatting, exit codes — is in [`internal/cmd`](../../internal/cmd/AGENTS.md), where it is **testable**. A `main` package cannot be imported, so anything written here can only be exercised by running the binary; the command tree is instead a library with one caller, and its tests run it as a subprocess *and* call into it directly where that is cheaper. The exit status is the only thing this layer owns, and it owns it because `os.Exit` skips deferred functions: it has to happen after everything else is finished, at the outermost frame, and nowhere else in the tree may call it. The version a build reports is **not** stamped here either. `-ldflags -X` names `internal/cmd.Version`, because that is where the `version` command reads it and where a test can build with the flag and read the answer back — a `-X` whose symbol path is one character wrong is silently ignored, and the binary goes on saying `dev`. ## Adding a command Nothing here changes. A new command is a `register(&Command{…})` in an `init()` over in [`internal/cmd`](../../internal/cmd/AGENTS.md) — that is the whole point of a registry. ## Keeping this file true - **Scope:** `main.go`, and the reason it stays this short. - **Update it when** this package grows a second file or a line that does anything but delegate — which should be treated as a design change and argued for, not documented after the fact. - **Do not** describe commands, flags or exit codes here.