skill

package module
v0.3.0-alpha.1 Latest Latest
Warning

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

Go to latest
Published: Aug 26, 2026 License: MIT Imports: 20 Imported by: 0

README

Note: This skill primitive borrows the SKILL.md filename and progressive-disclosure model from Anthropic Agent Skills. It is a distinct primitive and makes no interop claim with the Anthropic runtime.

gokit/skill

skill owns kit.skill.yaml manifests, progressive-disclosure loading, in-process skill providers, signature verification seams, and activation envelope helpers.

Architecture

flowchart TD
    Skill[skill]
    Manifest[manifest + prompt refs]
    Loader[loader + verifier]
    Registry[registry]
    Activation[activation + effective policy]
    Tool[tool references]
    MCP[mcp skill adapter]
    Agent[agent capability bundles]
    Authz[authz]
    Security[security]
    Obs[observability]

    Skill --> Manifest
    Skill --> Loader
    Skill --> Registry
    Skill --> Activation
    Manifest --> Tool
    Loader --> Security
    Activation --> Authz
    Registry --> Obs
    MCP --> Registry
    Agent --> Registry

Documentation

Overview

Package skill provides SDK-free skill manifests, loading, registry, and activation helpers.

Index

Constants

View Source
const (
	// MaxBodyBytes bounds the SKILL.md body size.
	MaxBodyBytes = 4 << 20 // 4 MiB
	// MaxAssetBytes bounds a single inert asset size.
	MaxAssetBytes = 16 << 20 // 16 MiB
	// MaxAssetTotalBytes bounds the aggregate size of all inert assets.
	MaxAssetTotalBytes = 64 << 20 // 64 MiB
)

Size limits for untrusted skill-pack files. Reads fail closed once exceeded.

View Source
const ManifestFileName = "kit.skill.yaml"
View Source
const MaxManifestBytes = 1 << 20 // 1 MiB

MaxManifestBytes bounds the manifest file size accepted at load time.

View Source
const SkillMarkdownFileName = "SKILL.md"

Variables

View Source
var (
	// ErrManifestInvalid marks a manifest that failed schema validation.
	ErrManifestInvalid = errors.New("skill: invalid manifest")
	// ErrParseManifest marks a manifest that could not be decoded.
	ErrParseManifest = errors.New("skill: manifest parse failed")
	// ErrFileTooLarge marks a pack file that exceeds its size limit.
	ErrFileTooLarge = errors.New("skill: file exceeds size limit")
	// ErrAssetsTooLarge marks a pack whose aggregate assets exceed the limit.
	ErrAssetsTooLarge = errors.New("skill: assets exceed total size limit")
	// ErrInvalidUTF8 marks a text pack file that is not valid UTF-8.
	ErrInvalidUTF8 = errors.New("skill: file is not valid UTF-8")
	// ErrInvalidPackFile marks a pack path that is not an accepted regular file
	// or directory (symlink, escaping path, wrong type).
	ErrInvalidPackFile = errors.New("skill: invalid pack file")
	// ErrVerificationDenied marks a manifest rejected by the verifier.
	ErrVerificationDenied = errors.New("skill: verification denied")
	// ErrAlreadyRegistered marks a duplicate registration.
	ErrAlreadyRegistered = errors.New("skill: already registered")
)

Sentinel errors for classifiable skill manifest, loading, verification, and registry failures. Policy rejections (invalid manifest, parse/size/UTF-8/path violations, verification denial, duplicate registration) wrap one of these so callers can match with errors.Is; low-level IO failures (missing or unreadable files) are returned as-is.

Functions

func EffectiveSafety

func EffectiveSafety(m Manifest, lookup func(toolName string) tool.Safety) tool.Safety

func Validate

func Validate(m *Manifest) error

Validate checks a manifest's required fields and structural invariants. Every failure wraps ErrManifestInvalid.

Types

type ActivationDecision

type ActivationDecision struct {
	SkillName       string          `json:"skill_name"`
	Allowed         bool            `json:"allowed"`
	Reason          string          `json:"reason,omitempty"`
	EffectiveSafety tool.Safety     `json:"effective_safety"`
	Tools           []EffectiveTool `json:"tools"`
}

func Activate

func Activate(m Manifest, principalGrants, operatorCeiling []string, toolEnvelopes map[string]tool.Envelope) ActivationDecision

Activate composes the effective safety and per-tool envelopes for a skill into an ActivationDecision. The skill is Allowed only when every referenced tool resolves to a present envelope whose required scopes survive intersection with the principal grants and operator ceiling; otherwise the decision fails closed and Reason names the first blocking tool.

type Asset

type Asset struct {
	Path   string `json:"path"`
	SHA256 string `json:"sha256"`
}

type Budgets

type Budgets struct {
	MaxTokens int     `yaml:"max_tokens,omitempty" json:"max_tokens,omitempty"`
	MaxCalls  int     `yaml:"max_calls,omitempty" json:"max_calls,omitempty"`
	MaxCost   MaxCost `yaml:"max_cost,omitempty" json:"max_cost,omitempty"`
	WallClock string  `yaml:"wall_clock,omitempty" json:"wall_clock,omitempty"`
}

type DenyVerifier

type DenyVerifier struct{}

DenyVerifier is the canonical operator-deny verifier: it rejects every manifest unconditionally. Use it as a safe default until a real signature verifier (e.g., Sigstore/cosign) is wired in.

func (DenyVerifier) Verify

Verify always denies.

type EffectiveTool

type EffectiveTool struct {
	Name     string        `json:"name"`
	Envelope tool.Envelope `json:"envelope"`
	Allowed  bool          `json:"allowed"`
	Reason   string        `json:"reason,omitempty"`
}

func EffectiveEnvelope

func EffectiveEnvelope(m Manifest, principalGrants, operatorCeiling []string, toolEnvelopes map[string]tool.Envelope) []EffectiveTool

type HumanApproval

type HumanApproval struct {
	Step      string `yaml:"step" json:"step"`
	When      string `yaml:"when" json:"when"`
	Rationale string `yaml:"rationale" json:"rationale"`
}

type Limits

type Limits struct {
	// Manifest bounds the manifest file size.
	Manifest int64
	// Body bounds the SKILL.md body size.
	Body int64
	// Asset bounds a single inert asset size.
	Asset int64
	// AssetTotal bounds the aggregate size of all inert assets.
	AssetTotal int64
}

Limits bounds the sizes of untrusted skill-pack files read at load time. Reads fail closed once a bound is exceeded. The zero value is not usable; obtain defaults from DefaultLimits or inject via WithLimits, which fills any non-positive field with its default.

func DefaultLimits

func DefaultLimits() Limits

DefaultLimits returns the production size limits.

type Loader

type Loader struct {
	// contains filtered or unexported fields
}

Loader loads and activates skill packs from the filesystem, enforcing size limits, rejecting symlinks and escaping paths, and running an injected verifier before a pack is returned.

func NewLoader

func NewLoader(opts ...LoaderOption) *Loader

NewLoader builds a Loader. Without options it verifies with WarnOnlyVerifier and enforces DefaultLimits.

func (*Loader) Load

func (l *Loader) Load(root string) (*Pack, error)

Load activates a skill pack: it loads verified metadata, the SKILL.md body, and the inert reference and script asset inventory. Every path is anchored to the canonical pack root.

func (*Loader) LoadMetadata

func (l *Loader) LoadMetadata(root string) (*Manifest, []string, error)

LoadMetadata parses, validates, and verifies only the manifest. It returns the manifest and any non-fatal verification warnings, and fails closed when verification is denied.

type LoaderOption

type LoaderOption func(*Loader)

LoaderOption configures a Loader.

func WithLimits

func WithLimits(limits Limits) LoaderOption

WithLimits injects the size limits enforced on untrusted pack files. Any non-positive field falls back to its DefaultLimits value.

func WithLogger

func WithLogger(logger *slog.Logger) LoaderOption

WithLogger injects the logger used to surface non-fatal verification warnings.

func WithVerifier

func WithVerifier(v Verifier) LoaderOption

WithVerifier injects the manifest verifier consulted at load time. When omitted the loader uses WarnOnlyVerifier.

type Manifest

type Manifest struct {
	SchemaVersion         string                `yaml:"schema_version" json:"schema_version"`
	Name                  string                `yaml:"name" json:"name"`
	Version               string                `yaml:"version" json:"version"`
	Description           string                `yaml:"description" json:"description"`
	License               string                `yaml:"license,omitempty" json:"license,omitempty"`
	Authors               []string              `yaml:"authors,omitempty" json:"authors,omitempty"`
	References            References            `yaml:"references" json:"references"`
	Requires              Requires              `yaml:"requires,omitempty" json:"requires,omitempty"`
	HumanApproval         []HumanApproval       `yaml:"human_approval" json:"human_approval"`
	Budgets               Budgets               `yaml:"budgets,omitempty" json:"budgets,omitempty"`
	ModelHints            ModelHints            `yaml:"model_hints,omitempty" json:"model_hints,omitempty"`
	ProgressiveDisclosure ProgressiveDisclosure `yaml:"progressive_disclosure,omitempty" json:"progressive_disclosure,omitempty"`
	Scripts               []Script              `yaml:"scripts,omitempty" json:"scripts,omitempty"`
	Signature             *Signature            `yaml:"signature,omitempty" json:"signature,omitempty"`
	Safety                Safety                `yaml:"safety,omitempty" json:"safety,omitempty"`
}

func LoadManifest

func LoadManifest(path string) (*Manifest, error)

LoadManifest reads and parses a manifest file, enforcing MaxManifestBytes and rejecting symlinks before reading.

func ParseManifest

func ParseManifest(data []byte) (*Manifest, error)

ParseManifest decodes and validates a manifest from raw YAML bytes. Unknown fields are rejected and the result is validated, so it fails closed on malformed or untrusted input.

type MaxCost

type MaxCost struct {
	Amount   float64 `yaml:"amount" json:"amount"`
	Currency string  `yaml:"currency" json:"currency"`
}

type MemoryRegistry

type MemoryRegistry struct {
	// contains filtered or unexported fields
}

func NewRegistry

func NewRegistry() *MemoryRegistry

func (*MemoryRegistry) Get

func (r *MemoryRegistry) Get(name string) (Provider, bool)

func (*MemoryRegistry) List

func (r *MemoryRegistry) List() []Manifest

func (*MemoryRegistry) Register

func (r *MemoryRegistry) Register(provider Provider) error

type ModelHints

type ModelHints struct {
	Preferred []string `yaml:"preferred,omitempty" json:"preferred,omitempty"`
	Reject    []string `yaml:"reject,omitempty" json:"reject,omitempty"`
}

type Pack

type Pack struct {
	Root                 string
	Manifest             Manifest
	SkillBody            string
	References           []Asset
	Scripts              []Asset
	VerificationWarnings []string
	// contains filtered or unexported fields
}

func (*Pack) ListScripts

func (p *Pack) ListScripts() []Asset

func (*Pack) LoadReferenceDoc

func (p *Pack) LoadReferenceDoc(name string) ([]byte, error)

type ProgressiveDisclosure

type ProgressiveDisclosure struct {
	Summary string `yaml:"summary,omitempty" json:"summary,omitempty"`
	Detail  string `yaml:"detail,omitempty" json:"detail,omitempty"`
}

type PromptReference

type PromptReference struct {
	Name    string `yaml:"name" json:"name"`
	Version string `yaml:"version" json:"version"`
}

type PromptTemplate

type PromptTemplate = prompt.Template

PromptTemplate aliases the canonical prompt template type for providers that bundle local prompt assets with a skill pack.

type Provider

type Provider interface {
	Manifest() Manifest
	OpenAsset(name string) (io.ReadCloser, error)
}

type References

type References struct {
	Tools      []string          `yaml:"tools" json:"tools"`
	Prompts    []PromptReference `yaml:"prompts" json:"prompts"`
	Resources  []string          `yaml:"resources" json:"resources"`
	MCPServers []string          `yaml:"mcp_servers" json:"mcp_servers"`
}

type Registry

type Registry interface {
	Register(provider Provider) error
	Get(name string) (Provider, bool)
	List() []Manifest
}

type Requires

type Requires struct {
	Scopes       []string `yaml:"scopes,omitempty" json:"scopes,omitempty"`
	Capabilities []string `yaml:"capabilities,omitempty" json:"capabilities,omitempty"`
}

type Safety

type Safety string
const (
	SafetyReadOnly    Safety = "read-only"
	SafetyMutating    Safety = "mutating"
	SafetyDestructive Safety = "destructive"
)

type Script

type Script struct {
	Path        string `yaml:"path" json:"path"`
	Description string `yaml:"description" json:"description"`
}

type Signature

type Signature struct {
	Algorithm string `yaml:"algorithm" json:"algorithm"`
	Value     string `yaml:"value" json:"value"`
	KeyID     string `yaml:"key_id" json:"key_id"`
}

func (*Signature) IsPresent

func (s *Signature) IsPresent() bool

IsPresent reports whether the signature carries the fields required to identify a signature scheme and payload. An empty or placeholder object (e.g. `signature: {}` or a blank value) is not present.

type VerificationOutcome

type VerificationOutcome struct {
	Status   VerificationStatus
	Warnings []string
	Reason   string
}

VerificationOutcome is the result of verifying a manifest at load time.

func Denied

func Denied(reason string) VerificationOutcome

Denied reports a rejected verification with a human-readable reason.

func Verified

func Verified() VerificationOutcome

Verified reports a passing verification with no warnings.

func Warning

func Warning(messages ...string) VerificationOutcome

Warning reports a passing verification carrying non-fatal warnings.

type VerificationStatus

type VerificationStatus int

VerificationStatus is the outcome kind of a manifest verification.

const (
	// VerificationVerified indicates the manifest passed verification.
	VerificationVerified VerificationStatus = iota
	// VerificationWarning indicates verification succeeded with non-fatal warnings.
	VerificationWarning
	// VerificationDenied indicates verification rejected the manifest.
	VerificationDenied
)

type Verifier

type Verifier interface {
	Verify(manifest *Manifest, root string) (VerificationOutcome, error)
}

Verifier verifies a skill manifest at load time. The loader consults it after parsing and validation: Denied fails the load, Warning is surfaced on the pack, and Verified proceeds silently.

Implementations MUST be safe for concurrent use.

type WarnOnlyVerifier

type WarnOnlyVerifier struct{}

WarnOnlyVerifier permits unsigned manifests with a warning and treats any signed manifest as verified. Suitable for development and tests; operators SHOULD pair it with DenyVerifier or a real signature verifier in production.

func (WarnOnlyVerifier) Verify

func (WarnOnlyVerifier) Verify(manifest *Manifest, _ string) (VerificationOutcome, error)

Verify returns Verified for signed manifests and a Warning otherwise.

Jump to

Keyboard shortcuts

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