garm

package module
v0.9.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 25, 2026 License: MIT Imports: 1 Imported by: 0

README

garm

The command line tool, and the contract language it speaks.

garm is what a person types. It scaffolds a proto tree, compiles governed tool declarations, refuses the bad ones, and builds the catalogue a runtime will serve. It runs for half a second and exits.

It is not the server. That is garmd.

What is here

proto/garm/v1/ The annotations — verb, clearance, compartments, tool sets, effects, guidance, approval, audit
cmd/garm/ The CLI
internal/toolgen/ The reader, the emitter, and the lint rules
conformance/ Golden proto sets and the errors they must produce

What you type

garm init                scaffold a proto tree, annotations vendored in
garm gen                 run the code generators
garm lint                check your tool declarations
garm new toolservice     scaffold a service
garm catalogue build     build the artifact garmd loads
garm catalogue check     will this load on garmd v2.1?

The binary also contains protoc-gen-garm-go and protoc-gen-garm-python, invoked by buf as local plugins. One install, not three — and the annotations and the generator that reads them cannot drift apart, because they are the same artifact.

The catalogue

garm catalogue build compiles a proto tree into the artifact a daemon loads at boot, so adding a tool is a catalogue rebuild rather than a release of the governance binary. Two builds of identical source produce identical bytes, because the digest is the catalogue's identity.

About 384 bytes per tool on disk and 9.3 KB retained, linear to at least 10,000 tools — mise run bench measures it, and docs/catalogue.md explains what it means for where a catalogue should be sized.

Why the annotations live with the CLI

They have the same consumers, the same release cadence, and no build edge between them. A new annotation and the code generation that reads it are one change; split across two repositories they become a release dance with a window in which the annotation exists and nothing can compile it.

The annotations are additionally published as a buf module, for anyone with a pipeline that prefers a registry to a vendored tree. Both paths, same source.

Nothing here depends on the server

That is the property this repository exists to hold. An engineer authoring a tool schema compiles it, lints it and generates from it without running, installing or cloning garmd. Enforcement at authoring time must not require the thing that enforces at run time.

What is deliberately not here

  • The governance chain. Declaring that a tool requires clearance is this repository's business; enforcing it is garmd's.
  • Any taxonomy. Compartments are an organisation's data-classification policy. This ships the mechanism — that compartments exist, that clearance compares, that a tool declares what it requires — never the vocabulary.
  • Commands that need the product. manifest, agent and tool index depend on packages that live in garmd today. They arrive here when their dependencies do, and not before — dragging the product across to keep a command would defeat the boundary above.

Status

Not yet seeded. Intent recorded; the first cut is init, gen, lint, new and the generator subcommands.

Documentation

Overview

Package garm embeds the contract this repository publishes.

The annotations are vendored into a consumer's tree by `garm init` rather than fetched from a registry. That is deliberate: a registry is one more thing an enterprise build has to be allowed to reach, and the annotations are small, stable, and worth reading by the people writing tool schemas against them.

The bytes here are the same bytes `garm init` writes, verbatim and with no added header, so a later drift check is a byte comparison rather than a parse.

Index

Constants

View Source
const AnnotationSchemaVersion = 1

AnnotationSchemaVersion is the version of the garm.tool.v1 vocabulary this build speaks, stamped into every catalogue it produces.

A daemon reads the current version and the two previous and refuses anything outside that window at boot. It is an integer rather than a semver because the only question asked of it is "can this binary read that catalogue", and a range check wants a number.

Bump it when a change to the annotations means an older daemon would misread a declaration — not when a field is added that an older daemon can safely ignore.

View Source
const VendoredAnnotationsPath = "third_party/proto/garm/tool/v1/tool.proto"

VendoredAnnotationsPath is where AnnotationsProto belongs in a consumer's tree.

Under third_party rather than beside your own protos, and that is not cosmetic: every module in a buf v2 workspace is an input, so annotations living under proto/ get Go generated for them — output that is never usable, because the real one is in this module's contracts package and two packages registering one proto file panic at init.

The tail of the path is part of the contract: an import of "garm/tool/v1/tool.proto" has to resolve, so only the root is a choice.

Variables

View Source
var AnnotationsProto []byte

AnnotationsProto is proto/garm/tool/v1/tool.proto, exactly as published.

Functions

This section is empty.

Types

This section is empty.

Directories

Path Synopsis
cmd
garm command
Command garm is the garm command line tool: it scaffolds a proto tree, compiles governed tool declarations, and refuses the bad ones.
Command garm is the garm command line tool: it scaffolds a proto tree, compiles governed tool declarations, and refuses the bad ones.
protoc-gen-garm-go command
Command protoc-gen-garm-go is the garm tool generator for Go, in the shape protoc and buf expect to find it: a standalone binary named protoc-gen-<name>, discoverable on PATH.
Command protoc-gen-garm-go is the garm tool generator for Go, in the shape protoc and buf expect to find it: a standalone binary named protoc-gen-<name>, discoverable on PATH.
Package contracts is the root of garm's generated tool contracts.
Package contracts is the root of garm's generated tool contracts.
audit
Package audit is the durable, separately-retained half of the record.
Package audit is the durable, separately-retained half of the record.
callctx
Package callctx encodes the InvocationContext for the NATS hop.
Package callctx encodes the InvocationContext for the NATS hop.
ledger
Package ledger is the shape of a governed call's record.
Package ledger is the shape of a governed call's record.
wire
Package wire is how a route becomes a NATS address.
Package wire is how a route becomes a NATS address.
internal
cli
Package cli holds the cobra conventions every garm binary shares.
Package cli holds the cobra conventions every garm binary shares.
compile
Package compile turns proto source into descriptors, in process.
Package compile turns proto source into descriptors, in process.
compiler
Package toolgen reads garm tool annotations off descriptors and validates them.
Package toolgen reads garm tool annotations off descriptors and validates them.
plugin
Package plugin is the protoc plugin that emits garm tool bindings and fails the build on any error-level lint diagnostic.
Package plugin is the protoc plugin that emits garm tool bindings and fails the build on any error-level lint diagnostic.
Package toolpolicy resolves what a principal may see, from annotations on the schema.
Package toolpolicy resolves what a principal may see, from annotations on the schema.
redact
Package redact turns a denied field value into what the caller may see.
Package redact turns a denied field value into what the caller may see.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL