Short rules. If it is not here, prefer the smallest change that matches existing code.
- Product (humans / titles): GoDo.
- Identifiers (code, CLI, paths): lowercase
godo— binary,github.com/my-rv/godo,godo.yaml,${godo:args…}. - Do not rename the module or binary to
GoDo/go-do.
- Go, module
github.com/my-rv/godo. cmd/godo/main.gois entrypoint only — no business logic.- Public import is
github.com/my-rv/godo(pkg.gofacade). - Engine lives in
internal/catalog; CLI/expand/exec underinternal/. - Do not import
internal/catalogfrom outside this module.
- Contract in
docs/contract.mdwins over implementation guesses. - In-process expansion only (no host
$VARbind). - Fail closed on bad captures / unexpected args / unknown decorators.
- Commands run with cwd = directory of the resolved
godo.yaml. - Expanded lines go through the host shell — treat catalog + args as trusted input.
- Table or focused cases for errors (
ErrNoMatch, cycle, OOB args, parse rejects). - Do not only test the happy path.
- Dogfood: keep
godo.yamlscripts (test,vet,check,ci) green — project gate is./godo ci, not Make.
- Product docs:
docs/. Contributor/internals:docs/dev/. - README stays short; link out.
- No feature in code without a contract line if it changes CLI or file semantics.
- No new dependency without a clear need (today:
yaml.v3+ stdlib). - Avoid pattern theater: a registry/strategy is fine; extra layers are not.