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
- Variables
- func Flatten(path string) ([]byte, error)
- func IsFormatExtension(path string) bool
- func Lower(path string, src []byte) ([]byte, error)
- func LowerForDiscovery(path string, src []byte) ([]byte, error)
- func ParseAllowMetaNode(n *kdl.Node) ([]string, error)
- func SiblingNodes() []string
- type Action
- type ArgBind
- type Auth
- type Call
- type Collect
- type Fetch
- type FetchEnv
- type FetchHeader
- type FetchWhen
- type Grant
- type Guardfile
- type Input
- type InputMatch
- type Poll
- type ProviderDecl
- type QueryAuthParam
- type Restriction
- type ValueChain
- type ValueSource
Constants ¶
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.
const DescriptionNode = "description"
DescriptionNode is the top-level `description "..."` node every dialect parser reads beside `wrap`. Parse sites name it through this constant.
Variables ¶
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 ¶
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 ¶
IsFormatExtension reports whether path names a YAML or TOML guardfile.
func Lower ¶
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 ¶
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 ¶
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 ¶
ParseActionNode parses one `action` KDL node into an Action: the entry the exec dialect shares, so both dialects speak one action grammar.
type ArgBind ¶
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.
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 ¶
FetchHeader is one literal header name plus a template value.
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 ¶
Parse turns Guardfile source into a Guardfile. It fails closed: an unknown node, a missing required field, or a malformed sentence is an error.
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 ¶
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 ¶
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 ¶
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 ¶
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).