Why a separate module¶
This page explains why the sign and keys command builders live in their own
module rather than inside go/signing or inside go-tool-base. The short answer
is dependency-cycle avoidance; the longer answer is about keeping a light
library light and letting more than one CLI share one command surface.
The three-way tension¶
Three facts pull against each other:
-
go/signingmust stay tiny. Its whole promise is a framework-free signing/verification library whose module graph is just go-crypto and cockroachdb/errors. Pulling Cobra into it would tax every verify-only consumer with a CLI framework they never invoke. -
More than one binary wants the same commands. go-tool-base exposes
gtb sign/gtb keys; the standalonesigillumCLI wants byte-identical behaviour. Copy-pasting the command code into each host guarantees drift. -
The commands must not drag in go-tool-base. If the builders lived in GTB's
pkg/, thensigillum— and any other tool wanting just the signing commands — would have to import the entire framework. Worse, GTB itself already depends ongo/signing, so co-locating the builders with the logic would knot the graph.
The resolution: a thin command-surface module¶
signing-cli sits in the middle:
go/signing (logic; tiny; no Cobra)
▲
│ imported by
│
signing-cli (Cobra command builders; this module)
▲ ▲
imported │ │ imported by
by │ │
go-tool-base sigillum (host binaries)
- It depends on
go/signing(for the registry and OpenPGP helpers) and Cobra — nothing else heavy. - It is imported by each host binary.
- It never imports go-tool-base.
Because the dependency arrows only ever point up — hosts → signing-cli →
go/signing — there is no cycle. GTB can depend on signing-cli, and
signing-cli never needs to depend back on GTB. The seam that makes the last
point possible is the narrow Logger interface: the builders
name a four-method logging contract instead of GTB's concrete logger type, so
they never have to import GTB to log.
What each layer owns¶
| Layer | Owns | Deliberately does not own |
|---|---|---|
go/signing (+ backends) |
Signing/verification logic, the backend registry, OpenPGP/WKD helpers | Any CLI framework |
signing-cli (this module) |
The sign/keys *cobra.Command surface: flags, help text, arg validation, output wiring |
The crypto logic; any concrete backend; go-tool-base |
Host binary (gtb, sigillum) |
Wiring the commands onto a root; blank-importing the backends it wants compiled in | Re-implementing the command surface |
That last row is why backends are the consumer's job — see Backends are the consumer's responsibility.
See also¶
- The Logger seam — the interface that lets these builders stay GTB-free.
- Backends are the consumer's responsibility — why this module imports no concrete backend.
- Attach the commands to a CLI — wire the builders onto your own root.