Use this checklist for a new Google API read surface. Keep the domain unavailable until its scope, client, commands, composition, and tests land together.
Add the narrowest adequate scope and description to internal/app/gro/identity.go. Add it to the non-destructive allowlist in internal/architecture/architecture_test.go. If grw will expose the domain too, add the same scope and description to internal/app/grw/identity.go; TestGrwScopesCoverGroPerService requires per-service coverage.
Create internal/api/<domain> with a concrete Client, NewClient(ctx context.Context), I/O methods taking context first, error wrapping, parsing helpers, and focused unit tests. API code must not import command packages.
Create internal/cmd/<domain> with:
- An exported consumer-owned interface ending in
Client. ClientFactory, defaulting to the API package'sNewClient.- An exported
NewCommand() *cobra.Commandthat registers the domain leaves. - One file per substantial leaf and text output helpers.
- No
--jsonflag on resource leaves.
Use cmd.Context() in handlers and pass it to both ClientFactory and client methods.
Add a function-field mock with a compile-time interface assertion, factory replacement via testutil.WithFactory, success and failure handler tests, and fixtures in internal/testutil only when multiple packages benefit. Add the domain to domainPackages and domainCommands() in internal/architecture/architecture_test.go.
Register the command with the gro root in internal/app/gro/root.go. Register it with grw in internal/app/grw/root.go as well so both binaries expose the read surface. If the domain also needs writes, compose its extended command there instead and follow adding a write surface.
make check
./bin/gro --help
./bin/grw --helpConfirm the new domain appears in both help trees, resource leaves reject --json, and the new scope descriptions appear during setup.