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

protocol

package
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Oct 24, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package protocol defines the wire format and schema model shared between Orchard and its providers.

Providers communicate with Orchard over JSON Lines on stdio: one JSON object per line, with request/response matched by id. The same types that describe the wire format also describe in-process providers, so builtin and external providers share a single schema model.

The on-disk authoring format is HCL (see ParseHCLSchema); the on-wire format is JSON. Both round-trip through the same ProviderSchema struct.

Index

Constants

View Source
const (
	MethodDescribe  = "describe"
	MethodConfigure = "configure"
	MethodExecute   = "execute"
	MethodShutdown  = "shutdown"
)

Method names understood by the provider protocol.

The describe/configure split mirrors Terraform's two-phase handshake: a provider must be able to advertise its schema before it has been configured, because callers like `orchard plan` need schemas to type-check scenarios without opening connections to target systems. Bundling both into a single "initialize" would force every plan invocation to supply real credentials.

View Source
const (
	ErrCodeInvalidRequest = "invalid_request"
	ErrCodeUnknownMethod  = "unknown_method"
	ErrCodeUnknownAction  = "unknown_action"
	ErrCodeValidation     = "validation_failed"
	ErrCodeConfigure      = "configure_failed"
	ErrCodeExecute        = "execute_failed"
	ErrCodeInternal       = "internal_error"
)

Well-known error codes. Providers are free to define additional codes, but these cover the conditions the engine reasons about directly.

View Source
const ProtocolVersion = "1"

ProtocolVersion is the wire protocol version the engine speaks. Providers advertise their own supported version in ProviderSchema.Protocol during initialize; a mismatch is a hard error at handshake time.

Variables

This section is empty.

Functions

func MarshalAttrs

func MarshalAttrs(attrs map[string]cty.Value) (map[string]json.RawMessage, error)

MarshalAttrs is the common-case helper for encoding a map of attribute values as it would appear in ExecuteParams.Attrs or ExecuteResult.Outputs. Each value is encoded against its own type, matching the per-attribute schema model.

func MarshalValue

func MarshalValue(v cty.Value) (json.RawMessage, error)

MarshalValue encodes a cty.Value as a JSON payload suitable for embedding in a protocol message. The type is derived from the value itself; callers with a declared schema type should use MarshalValueAs to pin the on-wire shape.

func MarshalValueAs

func MarshalValueAs(v cty.Value, t cty.Type) (json.RawMessage, error)

MarshalValueAs encodes v against an explicit target type. This is the form the engine should prefer when a schema is available — it forces type conformance up front and produces a canonical shape (e.g. objects always carry all declared attributes).

func ReadMessage

func ReadMessage(r *bufio.Reader, v any) error

ReadMessage reads one '\n'-terminated JSON frame from r and decodes it into v. Returns io.EOF when the stream is closed cleanly between frames; a partial frame followed by EOF is reported as io.ErrUnexpectedEOF.

func UnmarshalAttrs

func UnmarshalAttrs(raw map[string]json.RawMessage, types map[string]cty.Type) (map[string]cty.Value, error)

UnmarshalAttrs decodes a map of JSON-encoded values against a per-attribute type map. Attributes present in raw but absent from types are decoded as cty.DynamicPseudoType, preserving their shape for providers that accept free-form input.

func UnmarshalValue

func UnmarshalValue(raw json.RawMessage, t cty.Type) (cty.Value, error)

UnmarshalValue decodes a JSON payload into a cty.Value of the given type. A null input decodes to cty.NullVal(t). An empty or missing payload is an error — callers that want "optional" semantics should check for that themselves before calling.

When t is cty.DynamicPseudoType, the payload's cty type is inferred from the JSON structure. This is the fallback that lets providers declare free-form outputs without losing ergonomics on the wire.

func WriteMessage

func WriteMessage(w io.Writer, v any) error

WriteMessage encodes v as a single JSON Lines frame: compact JSON followed by a newline. The newline terminator is required — readers on the other end split on '\n'.

Types

type ActionSchema

type ActionSchema struct {
	Description string                `json:"description,omitempty"`
	Notes       string                `json:"notes,omitempty"`
	Attrs       map[string]AttrSchema `json:"attrs"`
	Outputs     *AttrSchema           `json:"outputs,omitempty"`
	Examples    []Example             `json:"examples,omitempty"`
}

ActionSchema describes one action type offered by a provider.

type AttrSchema

type AttrSchema struct {
	Type        string          `json:"type"`
	Required    bool            `json:"required,omitempty"`
	Default     json.RawMessage `json:"default,omitempty"`
	Description string          `json:"description,omitempty"`
	// Path marks a string provider config attribute as a file path. A
	// relative value is resolved against the scenario file's directory
	// before Configure, the same as action `file` attributes and exec:
	// sources, so a scenario works from any working directory. Values
	// starting with ':' (special names like SQLite's :memory:) pass
	// through unchanged.
	Path bool `json:"path,omitempty"`
}

AttrSchema describes a single attribute or an output shape.

Type is a cty type expression in textual form ("string", "list(number)", "object({id=number, name=string})", "any"). It is parsed by CtyType.

Default is optional. When present, it carries a JSON-encoded cty value compatible with Type; the engine applies it when the attribute is omitted from an action body.

func (AttrSchema) CtyType

func (a AttrSchema) CtyType() (cty.Type, error)

CtyType parses the schema's textual cty type expression and returns the corresponding cty.Type. An empty Type string is treated as cty.DynamicPseudoType so providers can declare free-form outputs.

type ConfigureParams

type ConfigureParams struct {
	Config map[string]json.RawMessage `json:"config,omitempty"`
}

ConfigureParams carries the evaluated `provider "name" {}` block from the scenario, encoded as JSON-serialized cty values keyed by attribute name. Decoding back to cty values is the caller's responsibility using the type information from ProviderSchema.Config.

type ConfigureResult

type ConfigureResult struct{}

ConfigureResult is the successful response to a configure call. Empty today; kept as a named type so providers can grow the response shape (observability hints, capability advertisements) without breaking the protocol.

type DescribeParams

type DescribeParams struct{}

DescribeParams is the payload of a describe request. Empty today; the named type reserves room for future additions (capability negotiation, requested-schema filters) without bumping the protocol version.

type DescribeResult

type DescribeResult struct {
	Schema ProviderSchema `json:"schema"`
}

DescribeResult returns the provider's full schema. Callers use it to validate action bodies and type-check output references.

type Error

type Error struct {
	Code    string `json:"code"`
	Message string `json:"message"`
	Detail  string `json:"detail,omitempty"`
}

Error is a structured failure returned by a provider.

func (*Error) Error

func (e *Error) Error() string

type Example

type Example struct {
	Description string `json:"description,omitempty"`
	Code        string `json:"code"`
}

Example is a worked HCL snippet attached to a provider or action. It is carried in the schema so tooling — docs generation in particular — can render authoritative, schema-adjacent examples without a separate templates tree.

Code is the raw HCL as it should appear in documentation. Description is an optional one-line caption rendered above the snippet.

type ExecuteParams

type ExecuteParams struct {
	Action string                     `json:"action"`
	Attrs  map[string]json.RawMessage `json:"attrs"`
	Undo   *UndoOptions               `json:"undo,omitempty"`
}

ExecuteParams is the payload of an execute request.

Attrs values are JSON-encoded cty values. The engine has already evaluated the HCL action body against the scenario's eval context, so attribute values are fully resolved.

Undo is set when Orchard will record an undo for this action: it has no `lifecycle { teardown { } }` block and doesn't opt out with `managed_teardown = false`. A provider that knows how to reverse the action returns ExecuteResult.Undo; one that doesn't ignores it.

type ExecuteResult

type ExecuteResult struct {
	Outputs map[string]json.RawMessage `json:"outputs"`
	Undo    *Invocation                `json:"undo,omitempty"`
}

ExecuteResult is the payload of an execute response.

Outputs values are JSON-encoded cty values. They are made available to downstream nodes as `action.<provider>.<name>.<output>` references.

Undo, returned only when the request carried ExecuteParams.Undo, is the call that reverses this action. Orchard stores it in the run record and `orchard teardown` executes it.

type Invocation added in v0.3.0

type Invocation struct {
	Action string                     `json:"action"`
	Attrs  map[string]json.RawMessage `json:"attrs"`
}

Invocation is an action call to make later: one of the provider's own action types and its attributes, encoded as in ExecuteParams.

type ProviderSchema

type ProviderSchema struct {
	Name        string                  `json:"name"`
	Version     string                  `json:"version"`
	Protocol    string                  `json:"protocol"`
	Description string                  `json:"description,omitempty"`
	Notes       string                  `json:"notes,omitempty"`
	Config      map[string]AttrSchema   `json:"config,omitempty"`
	Actions     map[string]ActionSchema `json:"actions"`
	Examples    []Example               `json:"examples,omitempty"`
}

ProviderSchema is the self-description a provider returns during initialize. It is also the parse target for schema.hcl files.

Description is rendered immediately after the page header and carries the provider's intro prose. Notes is rendered at the bottom of the page — the field exists so end-of-page caveats (runtime behaviour, limitations, migration notes) have a natural home without being tucked into the intro.

func MustParseHCL

func MustParseHCL(src []byte) ProviderSchema

MustParseHCL is the panic-on-error form of ParseHCLSchema, suitable for embedded schema files loaded at provider init.

func ParseHCLSchema

func ParseHCLSchema(src []byte, filename string) (ProviderSchema, error)

ParseHCLSchema parses a provider schema file (schema.hcl) into a ProviderSchema. The filename is used only for diagnostic source locations and may be empty.

The HCL authoring form expects a single top-level provider block:

provider "name" {
  version  = "1"
  protocol = "1"

  config {
    attribute "dsn" { type = string, required = true }
  }

  action "sql" {
    attribute "query" { type = string, required = true }
    output { type = any }
  }
}

Type fields hold HCL type expressions (bare identifiers like `string` or compound forms like `object({id=number})`), not string literals. Default values are full HCL expressions evaluated against the attribute's declared type at parse time.

func (ProviderSchema) ActionNames

func (s ProviderSchema) ActionNames() []string

ActionNames returns the action type names in sorted order. Useful for deterministic error messages and plan output.

func (ProviderSchema) Validate

func (s ProviderSchema) Validate() error

Validate checks that the schema is self-consistent: required fields are set, every declared type parses, and the protocol version matches what this build of Orchard speaks. It does not touch defaults — those need a cty.Type to decode, so the engine validates them as part of its own per-attribute checks.

type Request

type Request struct {
	ID     int64           `json:"id"`
	Method string          `json:"method"`
	Params json.RawMessage `json:"params,omitempty"`
}

Request is a single message from Orchard to a provider.

Params is held as a raw JSON payload so that callers can unmarshal it into a method-specific struct (InitializeParams, ExecuteParams, ...) without the envelope needing to know about every method.

type Response

type Response struct {
	ID     int64           `json:"id"`
	Result json.RawMessage `json:"result,omitempty"`
	Error  *Error          `json:"error,omitempty"`
}

Response is a single message from a provider back to Orchard. Exactly one of Result or Error is populated.

type ShutdownParams

type ShutdownParams struct{}

ShutdownParams is the payload of a shutdown request. Empty today but named so fields (drain timeouts, final flush flags) can be added without a protocol version bump.

type ShutdownResult

type ShutdownResult struct{}

ShutdownResult is the payload of a shutdown response.

type UndoOptions added in v0.3.0

type UndoOptions struct {
	// Requested is true when the action sets
	// `lifecycle { managed_teardown = true }`: return an undo even where
	// the provider wouldn't by default.
	Requested bool `json:"requested,omitempty"`
}

UndoOptions carries the scenario's say in automatic teardown.

Jump to

Keyboard shortcuts

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