garm

package module
v0.14.1 Latest Latest
Warning

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

Go to latest
Published: Sep 28, 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/tool/v1/ The tool annotations — verb, clearance, compartments, tool sets, effects, guidance, approval, audit
proto/garm/agent/v1/ The agent manifest — mode, principal, model, bounds, prompts, the tool allowlist and its guards
cmd/garm/ The CLI
internal/compiler/ 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 catalogue build     build the artifact garmd loads
garm catalogue publish   put it, and the prompts it pins, on an object store
garm catalogue diff      what changed between two catalogues

The binary also contains protoc-gen-garm-go, invoked by buf as a local plugin (a Python generator is not written; see KNOWN-GAPS). One install, not two — 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 vendored into each tool repository by garm init; they are not yet published as a buf module (see KNOWN-GAPS).

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

Shipped: init, gen, lint, catalogue build|diff|publish, claims check, plugin, version. Thirty-one tool lint rules (the L series) and five agent rules (A1–A5), with twelve conformance cases. What is still missing is in KNOWN-GAPS.md.

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 VendoredAgentAnnotationsPath = "third_party/proto/garm/agent/v1/agent.proto"

VendoredAgentAnnotationsPath is where AgentAnnotationsProto belongs in a consumer's tree.

The same third_party module as the tool annotations, for the same reason: every module in a buf v2 workspace is an input, so annotations under proto/ would have Go generated for them, and two packages registering one proto file panic at init. The tail of the path is part of the contract — an import of "garm/agent/v1/agent.proto" has to resolve.

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 AgentAnnotationsProto []byte

AgentAnnotationsProto is proto/garm/agent/v1/agent.proto, exactly as published.

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.
grant
Package grant computes what a human approved.
Package grant computes what a human approved.
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
claimscheck
Package claimscheck reads the vocabulary a claims policy references — the compartments and tool sets its roles grant — so a CI gate can compare that vocabulary against what a tool catalogue declares.
Package claimscheck reads the vocabulary a claims policy references — the compartments and tool sets its roles grant — so a CI gate can compare that vocabulary against what a tool catalogue declares.
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.
policydiff
Package policydiff reports what changed about POLICY between two catalogues, and which direction it moved.
Package policydiff reports what changed about POLICY between two catalogues, and which direction it moved.
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