Help us shape the future of Go! Take the 2026 Go Developer Survey

guardfile

package
v0.263.0 Latest Latest
Warning

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

Go to latest
Published: Nov 1, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Package guardfile parses a KDL Guardfile, the human authoring layer (L2) of the specverb engine, into a typed model. KDL is parsed, never evaluated.

Index

Constants

View Source
const AuthSchemeNone = "none"

AuthSchemeNone marks a deliberately credential-free upstream. Distinct from an unset scheme, which is a spec that forgot. See docs/specverb-policy.md.

View Source
const DescriptionNode = "description"

DescriptionNode is the top-level `description "..."` node every dialect parser reads beside `wrap`. Parse sites name it through this constant.

Variables

View Source
var ErrNotGuardfile = errors.New("guardfile: not a guardfile")

ErrNotGuardfile marks a YAML or TOML file that is not a guardfile, which project discovery skips as unrelated (KDL without `wrap` is skipped alike).

Functions

func Flatten

func Flatten(path string) ([]byte, error)

Flatten resolves every `inherit` in the guardfile at path into one self-contained KDL document's bytes (no `inherit` => source verbatim). docs/specverb-policy.md.

func IsFormatExtension

func IsFormatExtension(path string) bool

IsFormatExtension reports whether path names a YAML or TOML guardfile.

func Lower

func Lower(path string, src []byte) ([]byte, error)

Lower returns KDL source for the guardfile at path. KDL and any unrecognised extension come back verbatim, and .yaml, .yml, and .toml are decoded and lowered.

func LowerForDiscovery

func LowerForDiscovery(path string, src []byte) ([]byte, error)

LowerForDiscovery is Lower for a project walk: a member is a top-level `wrap` mapping naming its `command`, other files yield ErrNotGuardfile, malformed ones fail.

func ParseAllowMetaNode

func ParseAllowMetaNode(n *kdl.Node) ([]string, error)

ParseAllowMetaNode parses one `allow-metacharacters` KDL node into its param names, the entry the inline dialect shares with the guardfile dialect.

func SiblingNodes added in v0.249.0

func SiblingNodes() []string

SiblingNodes returns, sorted, the top-level names umbra reads beside `wrap` or `mcp-upstream`, so a consumer tells an umbra node from an unread one.

Types

type Action

type Action struct {
	Name     string
	Describe string
	Inputs   []Input
	Poll     *Poll
	Calls    []Call // ordered multi-call sequence; mutually exclusive with Poll
	Collect  *Collect
	FailWhen string // JMESPath over the bindings; truthy => non-zero exit

	// RejectEmpty refuses an action that answered with nothing. Exec dialect
	// only, refused at build time over http. See docs/execverb-occlusion.md.
	RejectEmpty bool

	// MountVerb/MountResource: the two-arg `action <verb> <resource>` mount form
	// shadows that leaf path. Empty for `action <name>`. See specverb-actions.md.
	MountVerb     string
	MountResource string
}

Action is a named composite verb: exactly one of Poll, Calls, or Collect, plus an optional FailWhen exit. See specverb-actions.md.

func ParseActionNode

func ParseActionNode(n *kdl.Node) (Action, error)

ParseActionNode parses one `action` KDL node into an Action: the entry the exec dialect shares, so both dialects speak one action grammar.

func (Action) IsMount

func (a Action) IsMount() bool

IsMount reports whether the action shadows a leaf path (two-arg form).

type ArgBind

type ArgBind struct {
	Name  string
	Value string // `$input` reference or a literal
}

ArgBind is one `args { <name> <value> }` binding for the polled leaf. A `$input` value references an Input; else it is a literal. See specverb-actions.md.

type Auth

type Auth struct {
	Scheme string
	Header string
	Prefix string // trailing space is significant, e.g. "token "
	Value  ValueChain

	// Params are the query-param scheme's ordered secrets, each injected as a
	// query parameter (Trello's ?key=&token=). Empty for the header schemes.
	Params []QueryAuthParam
}

Auth describes how the engine authenticates to the target API. Four schemes: header-token, bearer, query-param (dual-secret), none. See docs/specverb.md.

func ParseAuthNode

func ParseAuthNode(n *kdl.Node) (Auth, error)

ParseAuthNode parses one `auth` KDL node into an Auth: the entry the opcore inline source shares, so both sources speak one auth grammar.

type Call

type Call struct {
	Verb     string
	Resource string
	Args     []ArgBind
	As       string // binding name for this call's response
}

Call is one step of a multi-call action: fires a granted leaf with Args, binds the response to As for `$As.field` data-flow. See specverb-actions.md.

type Collect

type Collect struct {
	Verb         string
	Resource     string
	Args         []ArgBind
	PageParam    string
	LimitParam   string
	Limit        string
	DefaultLimit string
	As           string
	// Cache, when set, is the TTL string (e.g. "10m") serving the accumulated
	// array from the on-disk ttl cache. Collect-only (see docs/specverb-actions.md).
	Cache string
}

Collect walks a paginated granted leaf, incrementing PageParam and appending each array response until the page returns fewer than Limit (specverb-actions.md).

type Fetch

type Fetch struct {
	Name     string
	Leaf     string
	Describe string
	Method   string
	Path     string
	Output   string
	Env      []FetchEnv
	Headers  []FetchHeader
	Whens    []FetchWhen
}

Fetch is one HTTP overlay leaf: a fixed method/path pair plus env-backed headers and simple glob guards on the positional path inputs.

type FetchEnv

type FetchEnv struct {
	Name  string
	Value ValueChain
}

FetchEnv is one named value source used to fill fetch header templates.

type FetchHeader

type FetchHeader struct {
	Name  string
	Value string
}

FetchHeader is one literal header name plus a template value.

type FetchWhen

type FetchWhen struct {
	Selector string
	Globs    []string
}

FetchWhen is one positional guard: the selector and globs it must match.

type Grant

type Grant struct {
	Modal      string
	Verb       string
	Resource   string
	Qualifiers []string

	// Props are KDL key=value node properties: structured scoping constraints
	// like `org=acme`. Positional bareword qualifiers stay in Qualifiers.
	Props map[string]string

	// Op is the spec operationId (grant-body `op "..."`). Optional: an empty Op is
	// resolved by convention (specverb.resolveOp); set it to override. Deny ignores it.
	Op string

	// OpMethod and OpPath address an operation by method+path, for a spec whose
	// operations carry no operationId. See docs/specverb-resolution.md.
	OpMethod string
	OpPath   string

	// FixedBody is the grant-body `body key=value...` map: a state-toggle leaf that
	// always sends this exact JSON and mounts no body flags. Keeps KDL-native types.
	FixedBody map[string]any

	// Message is the grant-body `message "..."` shown when a deny blocks an
	// invocation - the teaching error. Only meaningful on cannot/never.
	Message string

	// Describe is the optional grant-body `describe "..."` note that enriches
	// the thin upstream spec; it flows into help and the describe verb.
	Describe string

	// Wildcard is set when the resource was authored as the `"*"` sentinel: the
	// engine expands it to one concrete grant per spec resource exposing the verb.
	Wildcard bool

	// Override is set for an `override can <verb> <resource>` grant: the sole
	// construct that crosses an inherited `never`. It carries Modal "can".
	Override bool
}

Grant is one policy sentence: modal verb resource [qualifiers...] [key=value...]. Resource is the CLI group, Verb the leaf, Op the operationId. See docs/specverb.md.

type Guardfile

type Guardfile struct {
	// Description is the optional top-level `description "..."` prose (sibling of
	// `wrap`): standing context in describe + the ref doc. See docs/value-providers.md.
	Description string

	Group   []string // command path, e.g. ["ward", "ops", "forgejo"]
	Spec    string
	BaseURL string
	// BaseURLValue resolves the base-url at request time (block form
	// `base-url { value ... }`), exclusive with BaseURL. See specverb-policy.md.
	BaseURLValue ValueChain
	Auth         Auth
	Grants       []Grant
	Restrict     []Restriction
	Actions      []Action
	Fetches      []Fetch

	// AllowMeta names the path params opted out of the shell-metacharacter
	// gate by `allow-metacharacters <param>...`. See docs/specverb-request.md.
	AllowMeta []string

	// Providers are consumer-declared value resolvers: `provider <name> { exec ... }`.
	// umbra ships no store SDK, so a store-backed source is an exec contract.
	ProviderDecls []ProviderDecl
}

Guardfile is the parsed form of one wrap block.

func Parse

func Parse(src []byte) (*Guardfile, error)

Parse turns Guardfile source into a Guardfile. It fails closed: an unknown node, a missing required field, or a malformed sentence is an error.

func ParseFile

func ParseFile(path string) (*Guardfile, error)

ParseFile flattens the guardfile at path (resolving inherit) and parses the merged result into a typed Guardfile.

func (*Guardfile) Providers

func (gf *Guardfile) Providers() []string

Providers returns the distinct provider names every value source in gf names, so a consumer (or the codegen) can wire exactly the resolvers in use.

type Input

type Input struct {
	Name       string
	Positional bool   // true: a positional arg; false: a --flag
	Required   bool   // enforced at invocation
	Help       string // one-line help, "" if none
	// Default is a JMESPath pre-flight binding for an absent input (poll actions
	// only); mutually exclusive with Required. See specverb-actions.md.
	Default string
	// Array makes the input repeatable, projected as a JSON array coerced to the
	// element type the bound leaf field declares. Flags only. See specverb-actions.md.
	Array bool
	// Matches constrains the bound value: on an `array` each entry demands at
	// least one matching element. See specverb-actions.md.
	Matches []InputMatch
}

Input is one parameter an Action declares (a positional arg or a flag). Its name doubles as the JMESPath `$name` variable in `until`/`fail-when`.

type InputMatch

type InputMatch struct {
	Globs   []string
	Message string
}

InputMatch is one `matches "<glob...>" message="<why>"` constraint on an Input. Globs are alternatives; Message names what is missing, "" taking a generated one.

type Poll

type Poll struct {
	Verb     string
	Resource string
	Args     []ArgBind
	Until    string // JMESPath; truthy ends the loop
	Every    string // sample interval, e.g. "10s" (quoted: KDL rejects bare 10s)
	Timeout  string // wall-clock bound, e.g. "30m"
	As       string // binding name for the final response
}

Poll re-fires a granted leaf (Verb+Resource) until Until settles or Timeout elapses, sampling Every; the last response binds to As. See specverb-actions.md.

type ProviderDecl

type ProviderDecl struct {
	Name string
	Exec []string
}

ProviderDecl is one `provider <name> { exec <argv...> }` declaration. The address being resolved is appended to Exec as the final argument.

func ParseProviderNode

func ParseProviderNode(n *kdl.Node) (ProviderDecl, error)

ParseProviderNode exposes the provider grammar to the exec dialect, so both dialects declare store-backed resolvers the same way.

type QueryAuthParam

type QueryAuthParam struct {
	Name  string
	Value ValueChain
}

QueryAuthParam is one secret of the query-param scheme: a query parameter Name whose value is read from the named value source.

type Restriction

type Restriction struct {
	Param string
	Globs []string
}

Restriction is a wrap-level `restrict <param> matches "<glob>"...` allowlist: a {Param}-carrying leaf must match a Glob or fail closed. See docs/specverb.md.

func ParseRestrictNode

func ParseRestrictNode(n *kdl.Node) (Restriction, error)

ParseRestrictNode parses one `restrict` KDL node into a Restriction, shared with the opcore inline source so both sources speak one restrict grammar.

type ValueChain

type ValueChain []ValueSource

ValueChain is an ordered fallback list of value sources: resolution takes the first yielding a non-empty value. See value-providers.md.

func ParseBaseURL

func ParseBaseURL(n *kdl.Node) (raw string, chain ValueChain, err error)

ParseBaseURL reads a base-url node: a bare string (raw) or a `{ value ... }` block (chain). Exactly one is non-zero. Shared with the opcore inline source.

func ParseValueBlock

func ParseValueBlock(n *kdl.Node, node string) (ValueChain, error)

ParseValueBlock reads a `{ value ... }` block off a node that carries one, so a new wrap node can take a credential chain without restating the shape.

func (ValueChain) IsZero

func (c ValueChain) IsZero() bool

IsZero reports whether the chain names no source.

func (ValueChain) String

func (c ValueChain) String() string

String renders the chain as `provider address` sources joined by " | " (the symbolic form describe/--dry-run show; "" when zero, never a resolved value).

type ValueSource

type ValueSource struct {
	Provider string
	Address  string
}

ValueSource names where a config value is read at request time: a Provider (ssm, tailscale, env, ...) and the Address it interprets. See specverb-policy.md.

func (ValueSource) IsZero

func (v ValueSource) IsZero() bool

IsZero reports whether the source is unset (no provider named).

Jump to

Keyboard shortcuts

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