Documentation
¶
Overview ¶
Package specverb is the runtime engine of the spec-driven verb design: it builds a guarded cli tree from a Guardfile + spec. See docs/specverb.md.
Index ¶
- func Build(cfg Config) (*cli.Command, error)
- func Descriptors(cfg DescriptorConfig) ([]opcore.Descriptor, opcore.RuntimeConfig, error)
- func Mount(root *cli.Command, cfg Config) error
- func NegativeControls(ctx context.Context, gf *guardfile.Guardfile, spec []byte) ([]negcontrol.Control, error)
- func Prune(spec []byte, gf *guardfile.Guardfile) ([]byte, error)
- type ActionCallInfo
- type ActionCollectInfo
- type ActionDefaultInfo
- type ActionInfo
- type AuthInfo
- type Config
- type DenyInfo
- type DescriptorConfig
- type FetchEnvInfo
- type FetchHeaderInfo
- type FetchInfo
- type FetchWhenInfo
- type ParamInfo
- type Provider
- type RestrictionInfo
- type Surface
- type VerbInfo
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Build ¶
Build assembles the guarded command tree and returns the Guardfile group's leaf command (e.g. `forgejo`). Fails closed: an unresolvable grant is an error.
func Descriptors ¶
func Descriptors(cfg DescriptorConfig) ([]opcore.Descriptor, opcore.RuntimeConfig, error)
Descriptors resolves a spec-driven Guardfile into the pair ParseInline returns. Deny is absence and the cli-only nodes fail closed: specverb-descriptors.md.
func Mount ¶
Mount builds the guarded group and grafts it onto root, generating the intermediate path groups the Guardfile names. See docs/specverb.md.
func NegativeControls ¶
func NegativeControls(ctx context.Context, gf *guardfile.Guardfile, spec []byte) ([]negcontrol.Control, error)
NegativeControls invokes every `never`/`cannot` grant in gf, sending and resolving nothing, then again with each removed. See docs/negative-controls.md.
Types ¶
type ActionCallInfo ¶
type ActionCallInfo struct {
Method string `json:"method"`
Path string `json:"path"`
Grant string `json:"grant"`
As string `json:"as,omitempty"`
}
ActionCallInfo is one step of a multi-call action for the describe surface.
type ActionCollectInfo ¶
type ActionCollectInfo struct {
Method string `json:"method"`
Path string `json:"path"`
Grant string `json:"grant"`
PageParam string `json:"page_param"`
LimitParam string `json:"limit_param"`
DefaultLimit int `json:"default_limit"`
As string `json:"as"`
// Cache is the on-disk TTL (e.g. "10m") when the action declares a
// `cache "<ttl>"` modifier; empty when the collect does not cache.
Cache string `json:"cache,omitempty"`
}
ActionCollectInfo is the resolved auto-pagination leaf for the describe surface.
type ActionDefaultInfo ¶
ActionDefaultInfo is one input `default` pre-flight binding for the describe surface: the input it resolves and the JMESPath evaluated against the poll leaf.
type ActionInfo ¶
type ActionInfo struct {
Name string `json:"name"` // envelope audit name, e.g. ward.ops.forgejo.action.ci-watch
Leaf string `json:"leaf"` // CLI leaf, e.g. ci-watch
Describe string `json:"describe,omitempty"` // optional human note
Method string `json:"method"` // the polled leaf's HTTP method
Path string `json:"path"` // the polled leaf's path template
Grant string `json:"grant"` // the grant that authorizes the polled leaf
Every string `json:"every"` // sample interval
Timeout string `json:"timeout"` // wall-clock bound
Until string `json:"until"` // loop-ending JMESPath
FailWhen string `json:"fail_when,omitempty"` // non-zero-exit JMESPath
// Defaults is the pre-flight input bindings: each absent input resolved from
// the polled leaf before the loop starts. Empty when the action declares none.
Defaults []ActionDefaultInfo `json:"defaults,omitempty"`
// MountVerb/MountResource: set when the action shadows a leaf path (mounts at
// `<resource> <verb>`, not the `action` noun). Empty for a named action.
MountVerb string `json:"mount_verb,omitempty"`
MountResource string `json:"mount_resource,omitempty"`
// Calls is the resolved step sequence for a multi-call action; empty for a poll.
Calls []ActionCallInfo `json:"calls,omitempty"`
// Collect describes an auto-pagination action; nil for poll/call actions.
Collect *ActionCollectInfo `json:"collect,omitempty"`
}
ActionInfo is one mounted complex action for the describe surface: its envelope name, the polled leaf, the bounds, and the conditions.
type AuthInfo ¶
type AuthInfo struct {
Scheme string `json:"scheme"`
Header string `json:"header"`
Source string `json:"source"` // value source (provider + address), not the secret
}
AuthInfo is the auth scope a describe consumer sees: scheme, header, and the value source (provider + address). The secret value itself never appears here.
type Config ¶
type Config struct {
// Guardfile is the parsed L2 policy: the command path, auth, and grants.
Guardfile *guardfile.Guardfile
// Spec is the raw Swagger 2.0 document bytes (embedded by the consumer).
Spec []byte
// Wrap adapts a verb.Spec into a guarded cli.ActionFunc (the audit + argv
// pipeline). nil mounts the bare action, for doc rendering only.
Wrap func(verb.Spec) cli.ActionFunc
// Providers registers the value resolvers a `value <provider>` source names;
// umbra merges its built-ins (env, file, literal). See specverb-policy.md.
Providers map[string]Provider
// HTTPClient fires the live request. nil uses http.DefaultClient.
HTTPClient *http.Client
// BaseURL overrides the Guardfile base-url. "" uses the Guardfile value.
BaseURL string
// contains filtered or unexported fields
}
Config is everything the engine needs to build a command tree.
type DenyInfo ¶
type DenyInfo struct {
Name string `json:"name"` // dotted audit name, e.g. ward.ops.forgejo.orgs.create
Group string `json:"group"` // CLI noun, e.g. orgs
Leaf string `json:"leaf"` // CLI verb, e.g. create
Message string `json:"message"` // the teaching error
}
DenyInfo is one blocked (verb,resource) class for the describe surface: its CLI placement and the teaching message an operator sees when they reach for it.
type DescriptorConfig ¶
type DescriptorConfig struct {
// Guardfile is the parsed L2 policy. Use ParseFile to flatten inherit first.
Guardfile *guardfile.Guardfile
// Spec is the raw Swagger 2.0 / OpenAPI 3.x document bytes, decompressed.
Spec []byte
// Providers registers the resolvers a `value <provider>` source names.
Providers map[string]Provider
// HTTPClient fires the live request. nil uses http.DefaultClient.
HTTPClient *http.Client
// BaseURL overrides the Guardfile base-url. "" uses the Guardfile value.
BaseURL string
}
DescriptorConfig is what resolution needs and nothing more. It names no cli type, so a non-cli consumer never reaches for a projection it will not use.
type FetchEnvInfo ¶
FetchEnvInfo is one fetch env source, rendered as the value chain rather than the resolved secret.
type FetchHeaderInfo ¶
FetchHeaderInfo is one fetch header, rendered with its template intact.
type FetchInfo ¶
type FetchInfo struct {
Name string `json:"name"` // dotted audit name, e.g. ward.ops.forgejo.fetch.actions-logs
Leaf string `json:"leaf"` // CLI leaf, e.g. actions-logs
Title string `json:"title"` // author-supplied fetch label
Describe string `json:"describe,omitempty"` // optional human note
Method string `json:"method"` // HTTP method
Path string `json:"path"` // path template
Output string `json:"output"` // raw
Params []ParamInfo `json:"params,omitempty"` // positional path args, in order
Env []FetchEnvInfo `json:"env,omitempty"` // env value sources, never resolved values
Headers []FetchHeaderInfo `json:"headers,omitempty"` // literal headers with env templates
Whens []FetchWhenInfo `json:"whens,omitempty"` // glob guards on the positional inputs
}
FetchInfo is one mounted HTTP overlay: the fixed method/path, output mode, env-backed headers, and the positional guards that gate invocation.
type FetchWhenInfo ¶
FetchWhenInfo is one fetch guard clause.
type ParamInfo ¶
type ParamInfo struct {
Name string `json:"name"`
UpstreamName string `json:"upstream_name,omitempty"` // aliased outgoing query parameter
Kind string `json:"kind"` // "path" | "query" | "body" | "form"
Type string `json:"type"` // swagger type, arrays render as []elem
Required bool `json:"required"` // path params and required-schema fields
Desc string `json:"desc,omitempty"` // upstream spec description, often blank
}
ParamInfo is one input to a verb, tagged by kind so help can always show the structure the engine knows even where the upstream spec carries no description.
type Provider ¶
type Provider = valuesource.Provider
Provider resolves the value at address for one named value source: the shared valuesource.Provider, so the consumer's one registry drives both engines.
type RestrictionInfo ¶
RestrictionInfo is one wrap-level restrict clause for the describe surface: the path param it gates and the globs an argument must match.
type Surface ¶
type Surface struct {
Group []string `json:"group"` // command path, e.g. ["ward","ops","forgejo"]
Description string `json:"description,omitempty"` // the guardfile's top-level `description` prose, "" when none
BaseURL string `json:"base_url"` // resolved request base, scheme defaulted
Auth AuthInfo `json:"auth"` // how the engine authenticates
Verbs []VerbInfo `json:"verbs"` // every mounted leaf, in mount order
Fetches []FetchInfo `json:"fetches,omitempty"` // HTTP fetch overlays, in declaration order
Actions []ActionInfo `json:"actions,omitempty"` // complex actions, in declaration order
Denied []DenyInfo `json:"denied,omitempty"` // blocked classes, in declaration order
Restrict []RestrictionInfo `json:"restrict,omitempty"` // wrap-level scope allowlists
}
Surface is the in-engine model of a mounted command surface: the structural truth shared by help, the describe verb, and (later) completions and the skill.
type VerbInfo ¶
type VerbInfo struct {
Name string `json:"name"` // dotted audit name, e.g. ward.ops.forgejo.repo.create
Group string `json:"group"` // CLI noun, e.g. repo
Leaf string `json:"leaf"` // CLI verb, e.g. create
Method string `json:"method"` // HTTP method
Path string `json:"path"` // path template
Destructive bool `json:"destructive"` // mutates irreversibly
Grant string `json:"grant"` // authorizing grant sentence
Describe string `json:"describe,omitempty"` // Guardfile describe "..." note
Params []ParamInfo `json:"params,omitempty"` // path/query/body params, in invocation order
FixedBody map[string]any `json:"fixed_body,omitempty"` // exact body a state-toggle leaf sends
}
VerbInfo is one mounted leaf: its CLI placement, the HTTP op it drives, its destructive flag, the grant that authorized it, and the optional human note.