feat(cmd): S04-B operator subcommands
What
S04-B Plan Step 3 — the operator subcommands registered on the root command:
re-encrypt(--scope,--namespace-id,--phase,--active-key-uri) andretire-key-version(--namespace-id,--version), with the full in-action flag-validation matrix — every usage error renders the subcommand's usage output and exits 1 before any database access, and the root command refuses unknown positionals before building the server.- Per-scope "not yet implemented" stub actions that Steps 4/5/8 replace with the real behavior.
runOperatorAsExitCodernormalization and productiondefaultOperatorDepswiring.
Tests
Per-command flag matrix (missing/unknown --scope/--phase, malformed/missing --namespace-id/--version, missing --active-key-uri with --scope=root, out-of-scope flags), the missing-encryption-block refusal through each command, and the stub-refusal messages. Every branch mutation-killed.
Covers spec AC 11, 12 and the usage-error row of the Error Cases table.
E2E: none — operator commands have no format-client catalog scenario (per the plan).
Notes
Stacked on Step 2 (!1344 (merged)): targets that branch; retargets down to Step 1 / main as the stack merges.
Related to https://gitlab.com/gitlab-org/ops/artifact-registry/-/work_items/496
Size
The diff is ~630 reviewable LOC against its target, over the 500-LOC guideline. The two commands ship together because they share the usage-error helper, the exit-code normalization (runOperatorAsExitCoder), and the ad-hoc-root test harness; splitting them would duplicate that shared surface across two MRs.