Documentation
¶
Overview ¶
Package op owns the concrete graph data model types shared by the execution engine, Starlark layer, and CLI tools.
Core Types ¶
- Graph: A directed graph of nodes and edges representing work to be done
- Node: A single unit of work with an action to execute
- Edge: A dependency relationship between nodes
Graph Lifecycle ¶
The Graph represents both plans (before execution) and receipts (after execution):
- Before Run(): State is "pending", nodes describe what will happen
- After Run(): State is "executed", nodes describe what happened
- Serialized before execution: "dry-run" or "purchase order"
- Serialized after execution: "receipt"
Index ¶
- Constants
- Variables
- func Announce(p ReceiverFactory)
- func AnnounceResource(desc ResourceDescriptor)
- func AnyToStarlarkValue(v any) starlark.Value
- func Construct[T any](value any) (T, error)
- func FillSlot(node *Node, graph *Graph, slotName string, value starlark.Value) error
- func GenerateNodeID(prefix string, components ...string) string
- func GitStyleChecksum(objectType, basename string, content []byte) string
- func GoToStarlarkValue(v any) (starlark.Value, error)
- func HydrateGraph(g *Graph, reg *ActionRegistry) error
- func InitAll(reg *ActionRegistry, ctx Context)
- func IsStubAction(a Action) bool
- func Marshal(v any) (starlark.Value, error)
- func NoSuchAttrError(receiver, attr string) error
- func RegisterActions(registry *ActionRegistry, factory ReceiverFactory, params MethodParams)
- func RegisterConstructor[T any](fn func(any) (T, error))
- func RegisterReceiverParams(factory ReceiverFactory, params MethodParams)
- func RenderError(format string, args []any, kwargs map[string]any) error
- func StarlarkDictToMap(dict *starlark.Dict) (map[string]any, error)
- func StarlarkListToSlice(list *starlark.List) (any, error)
- func StarlarkValueToGo(v starlark.Value) (any, error)
- func StringSliceToList(s []string) *starlark.List
- func UnmarshalToAny(sv starlark.Value) (any, error)
- type AccessType
- type Action
- type ActionRegistry
- type Attempt
- type BackoffStrategy
- type BindingConfig
- type CallableInput
- type CallableResource
- type Collision
- type CompensableAction
- type Complement
- type Context
- type ContextBase
- type ContextProvider
- type Edge
- type Encoder
- type ExecutingReceiver
- func (r *ExecutingReceiver) Attr(name string) (starlark.Value, error)
- func (r *ExecutingReceiver) AttrNames() []string
- func (r ExecutingReceiver) Freeze()
- func (r ExecutingReceiver) Hash() (uint32, error)
- func (r *ExecutingReceiver) Override(name string, fn builtinFunc)
- func (r *ExecutingReceiver) SetCatalog(c *ResourceCatalog)
- func (r *ExecutingReceiver) SetContext(ctx Context)
- func (r *ExecutingReceiver) SetStack(s *RecoveryStack)
- func (r ExecutingReceiver) String() string
- func (r ExecutingReceiver) Truth() starlark.Bool
- func (r ExecutingReceiver) Type() string
- type ExecutingReceiverFactory
- type FallibleAction
- type FatalError
- type Gather
- type Graph
- type GraphContext
- type GraphState
- type MethodParams
- type NoResult
- type Node
- func (n *Node) ActionName() string
- func (n *Node) GetID() string
- func (n *Node) GetProject() string
- func (n *Node) GetSlot(name string) any
- func (n *Node) MarshalJSON() ([]byte, error)
- func (n *Node) MarshalYAML() (any, error)
- func (n *Node) RequireStringSlot(name string) (string, error)
- func (n *Node) ResolvedSlots(results map[string]any, proxyCtx ...map[string]any) map[string]any
- func (n *Node) SetSlotImmediate(name string, value any)
- func (n *Node) SetSlotPromise(name, nodeRef, slot string)
- func (n *Node) SetSlotProxy(name, gatherRef, field string)
- func (n *Node) UnmarshalJSON(data []byte) error
- func (n *Node) UnmarshalYAML(value *yaml.Node) error
- type NodeStatus
- type Output
- func (o *Output) Attr(name string) (starlark.Value, error)
- func (o *Output) AttrNames() []string
- func (o *Output) DependOn(consumer *Node)
- func (o *Output) FillSlot(consumer *Node, slotName string)
- func (o *Output) Freeze()
- func (o *Output) Graph() *Graph
- func (o *Output) Hash() (uint32, error)
- func (o *Output) Node() *Node
- func (o *Output) Path() string
- func (o *Output) Slot() string
- func (o *Output) String() string
- func (o *Output) Truth() starlark.Bool
- func (o *Output) Type() string
- type PackageManager
- type ParamInfo
- type Path
- type Phase
- type PhaseStatus
- type PlanningReceiver
- func (p *PlanningReceiver) Attr(name string) (starlark.Value, error)
- func (p *PlanningReceiver) AttrNames() []string
- func (r PlanningReceiver) Freeze()
- func (r PlanningReceiver) Hash() (uint32, error)
- func (p *PlanningReceiver) Override(name string, fn builtinFunc)
- func (r PlanningReceiver) String() string
- func (r PlanningReceiver) Truth() starlark.Bool
- func (r PlanningReceiver) Type() string
- type PlanningReceiverFactory
- type Platform
- type PlatformResult
- type ProviderBase
- type ProviderLifetime
- type ReceiverFactory
- type RecoveryEntry
- type RecoverySite
- type RecoveryStack
- func (s *RecoveryStack) Discard()
- func (s *RecoveryStack) Do(invoke func() (undoState any, reconcileState any, err error), ...) error
- func (s *RecoveryStack) Len() int
- func (s *RecoveryStack) Push(compensate func(any) error, reconcile func(any) (bool, error), undoState any, ...)
- func (s *RecoveryStack) PushAction(ctx *Context, action Action, undoState any)
- func (s *RecoveryStack) Unwind() error
- type Resource
- type ResourceBase
- func (b *ResourceBase) Format(v any) string
- func (b *ResourceBase) Fragment() string
- func (b *ResourceBase) Host() string
- func (b *ResourceBase) MarshalStarvalue() (starlark.Value, error)
- func (b *ResourceBase) Opaque() string
- func (b *ResourceBase) Path() string
- func (b *ResourceBase) Resolve(_ Root) error
- func (b *ResourceBase) Scheme() string
- func (b *ResourceBase) SetURI(uri string)
- func (b *ResourceBase) URI() string
- type ResourceCatalog
- func (c *ResourceCatalog) Current(uri string) string
- func (c *ResourceCatalog) DiscoveryURIs() []string
- func (c *ResourceCatalog) Len() int
- func (c *ResourceCatalog) Lookup(id string) (Resource, bool)
- func (c *ResourceCatalog) Resolve(uri string) string
- func (c *ResourceCatalog) Shadow(r Resource, originID string) (string, error)
- type ResourceDescriptor
- type Result
- type RetryPolicy
- type RollbackEntry
- type Root
- type RootReader
- func (b *RootReader) Close() error
- func (b *RootReader) FS() fs.FS
- func (r *RootReader) Lstat(p Path) (fs.FileInfo, error)
- func (r *RootReader) MkdirAll(Path, os.FileMode) error
- func (b *RootReader) Name() string
- func (b *RootReader) NewPath(path string) Path
- func (r *RootReader) Open(p Path) (*os.File, error)
- func (r *RootReader) OpenFile(Path, int, os.FileMode) (*os.File, error)
- func (r *RootReader) ReadFile(p Path) ([]byte, error)
- func (r *RootReader) Readlink(p Path) (string, error)
- func (r *RootReader) Remove(Path) error
- func (r *RootReader) Rename(_, _ Path) error
- func (r *RootReader) Stat(p Path) (fs.FileInfo, error)
- func (r *RootReader) Symlink(_ string, _ Path) error
- func (r *RootReader) WriteFile(Path, []byte, os.FileMode) error
- type RootReaderWriter
- func (b *RootReaderWriter) Close() error
- func (b *RootReaderWriter) FS() fs.FS
- func (r *RootReaderWriter) MkdirAll(p Path, perm os.FileMode) error
- func (b *RootReaderWriter) Name() string
- func (b *RootReaderWriter) NewPath(path string) Path
- func (r *RootReaderWriter) OpenFile(p Path, flag int, perm os.FileMode) (*os.File, error)
- func (r *RootReaderWriter) Remove(p Path) error
- func (r *RootReaderWriter) Rename(oldPath, newPath Path) error
- func (r *RootReaderWriter) Symlink(target string, link Path) error
- func (r *RootReaderWriter) WriteFile(p Path, data []byte, perm os.FileMode) error
- type SearchResult
- type ServiceManager
- type Signature
- type SlotValue
- type StarlarkRuntime
- func (rt *StarlarkRuntime) BuildReceiver(name string) (starlark.Value, bool)
- func (rt *StarlarkRuntime) BuildReceivers() starlark.StringDict
- func (rt *StarlarkRuntime) HasGraphBuilder() bool
- func (rt *StarlarkRuntime) Included(name string) bool
- func (rt *StarlarkRuntime) Initialize(reg *ActionRegistry, ctx ContextBase)
- type Summary
- type Tombstone
- type TombstoneBase
Constants ¶
const ( SchemeAppNet = "appnet" SchemeFile = "file" SchemeGit = "git" SchemeMem = "mem" SchemePackage = "pkg" SchemeService = "svc" )
URI scheme constants.
const GraphFormatVersion = "6"
GraphFormatVersion is the current graph serialization format version.
Variables ¶
var ErrDrifted = errors.New("state has drifted: compensation unsafe")
ErrDrifted indicates that a reconcile check detected external modification, making compensation unsafe. The entry is skipped during Unwind.
var ErrNotCompensable = errors.New("action is not compensable")
ErrNotCompensable signals that an action acknowledges rollback but cannot undo its effect. The executor logs a warning and continues unwinding.
var ErrReadOnly = errors.New("write operation not available in read-only mode")
ErrReadOnly is returned by write operations on a RootReader.
Functions ¶
func Announce ¶
func Announce(p ReceiverFactory)
Announce records a provider descriptor. Called in init(). Does zero initialization — stores the value for later InitAll callback. Duplicate announcements of the same type are deduplicated.
Parameters:
- p: the provider to announce.
func AnnounceResource ¶
func AnnounceResource(desc ResourceDescriptor)
AnnounceResource records a resource descriptor for lazy initialization. Called in generated init() functions. Does zero initialization — stores the descriptor for later lazy Init on first use.
Parameters:
- desc: resource descriptor providing ReceiverName, ProviderType, and Init
func AnyToStarlarkValue ¶
AnyToStarlarkValue converts a Go any that carries a starlark.Value to a starlark.Value. Returns starlark.None if nil.
func Construct ¶
Construct uses the constructor registry to convert value to type T.
Parameters:
- value: the value to convert via the registered constructor.
Returns:
- T: the constructed value.
- error: non-nil if no constructor is registered for T or if it rejects the value.
func FillSlot ¶
FillSlot fills a slot in a node from a Starlark value.
Any slot accepts:
- A promise (Output): creates an edge, value flows at runtime
- A gather (Gather): creates edges from all members (parallel execution)
- An immediate value: stored directly, known at analysis time
Parameters:
- node: the node whose slot to fill.
- graph: the execution graph (for edge creation).
- slotName: the slot to fill.
- value: the Starlark value to assign.
Returns:
- error: non-nil if the value cannot be unmarshaled.
func GenerateNodeID ¶
GenerateNodeID creates a unique node ID with the given prefix and components.
func GitStyleChecksum ¶
GitStyleChecksum computes a git-style checksum. Format: SHA256("<type> <basename> <len>\0<content>") Returns format "sha256:<hex>".
func GoToStarlarkValue ¶
GoToStarlarkValue converts a native Go value to a Starlark value.
func HydrateGraph ¶
func HydrateGraph(g *Graph, reg *ActionRegistry) error
HydrateGraph replaces stub actions on graph nodes with real actions from the registry. This enables loaded/deserialized graphs to be executed. Nodes with no action name (e.g., nodes that were never serialized with an action) are skipped.
func InitAll ¶
func InitAll(reg *ActionRegistry, ctx Context)
InitAll calls Register on every announced provider. Called once by the framework when it is ready to build an ActionRegistry.
Parameters:
- reg: the action registry to populate.
- ctx: the execution context for provider initialization.
func IsStubAction ¶
IsStubAction reports whether an action is a stub (from deserialization).
func Marshal ¶
Marshal converts a Go value to a starlark.Value.
Structs become starlarkstruct.Struct. Primitives, slices, maps, and pointers are handled recursively. Values already implementing starlark.Value pass through unchanged.
Parameters:
- v: the Go value to convert. Nil returns starlark.None.
Returns:
- starlark.Value: the converted Starlark value.
- error: non-nil if v contains an unsupported type (e.g., channels, functions).
func NoSuchAttrError ¶
NoSuchAttrError returns an error for an unknown attribute.
func RegisterActions ¶
func RegisterActions(registry *ActionRegistry, factory ReceiverFactory, params MethodParams)
RegisterActions registers all action methods on a provider. Method return signature determines action type:
- No error return: () or (T) → Action (pure)
- 1 return + error: (error) or (T, error) → FallibleAction
- 2+ returns + error: (T, undo, error) → CompensableAction
Every CompensableAction (3 returns) must have a Compensate<GoName> companion method. Missing pairs panic at registration time.
func RegisterConstructor ¶
RegisterConstructor registers a function that constructs a Go value from a simpler representation (e.g., string → Blob via NewBlob).
Parameters:
- fn: constructor function converting any → (T, error).
func RegisterReceiverParams ¶
func RegisterReceiverParams(factory ReceiverFactory, params MethodParams)
RegisterReceiverParams stores receiver params for a provider type. Called by RegisterActions as a side effect for providers with actions, and directly by immediate-only providers in their Register() callback.
Parameters:
- factory: the ReceiverFactory whose ProviderType is used as the registry key.
- params: maps Go method names to Starlark parameter name lists.
func RenderError ¶
RenderError formats a Go template string with positional args and keyword args, returning the result as an error.
Template data available to the format string:
{{ .key }} — kwargs value
{{ index .Args 0 }} — positional arg by index
If the format string contains no template directives, it passes through as a plain string.
func StarlarkDictToMap ¶
StarlarkDictToMap converts a Starlark dict to a Go map[string]any.
func StarlarkListToSlice ¶
StarlarkListToSlice converts a Starlark list to a Go slice. Returns []string if all elements are strings, []any otherwise.
func StarlarkValueToGo ¶
StarlarkValueToGo converts a Starlark value to a native Go value.
func StringSliceToList ¶
StringSliceToList converts a Go []string to a Starlark list of strings.
func UnmarshalToAny ¶
UnmarshalToAny converts a starlark.Value to a native Go value without a specific target type.
Returns string, int, bool, float64, nil, []any (or []string for homogeneous string lists), or map[string]any.
Parameters:
- sv: the Starlark value to convert.
Returns:
- any: the native Go value.
- error: non-nil if sv contains an unsupported Starlark type.
Types ¶
type AccessType ¶
type AccessType string
AccessType defines when a provider's methods are available.
const ( AccessImmediate AccessType = "immediate" // direct call during plan construction AccessPlanned AccessType = "planned" // graph node only — executed at runtime AccessBoth AccessType = "both" // available in both projections )
Access level constants define when a provider method is available.
type Action ¶
type Action interface {
Name() string
Params() []ParamInfo
Do(ctx *Context, slots map[string]any) (Result, Complement, error)
}
Action is a pure, infallible value transformer. No side effects, cannot fail. Do returns (result, nil, nil).
func StubAction ¶
StubAction creates a named action stub for testing and receipt deserialization. The stub is not executable — the executor replaces stubs via HydrateGraph.
type ActionRegistry ¶
type ActionRegistry struct {
// contains filtered or unexported fields
}
ActionRegistry maps action names to their implementations. Each tool registers its actions before calling GraphExecutor.Run().
func NewActionRegistry ¶
func NewActionRegistry() *ActionRegistry
NewActionRegistry creates an empty action registry.
func (*ActionRegistry) Get ¶
func (r *ActionRegistry) Get(name string) (Action, bool)
Get returns the action registered under the given name.
func (*ActionRegistry) MustGet ¶
func (r *ActionRegistry) MustGet(name string) Action
MustGet returns the action registered under the given name. Panics if the action is not registered (safe: all actions are pre-registered before any builder runs).
func (*ActionRegistry) Names ¶
func (r *ActionRegistry) Names() []string
Names returns all registered action names.
func (*ActionRegistry) Register ¶
func (r *ActionRegistry) Register(action Action)
Register adds an action to the registry. If an action with the same name already exists, it is replaced.
type Attempt ¶
type Attempt struct {
// Number is the 1-based attempt number.
Number int `json:"number" yaml:"number"`
// Status is "completed" or "failed".
Status string `json:"status" yaml:"status"`
// Error is the error message if the attempt failed.
Error string `json:"error,omitempty" yaml:"error,omitempty"`
// Timestamp is when this attempt completed (RFC3339).
Timestamp string `json:"timestamp" yaml:"timestamp"`
}
Attempt records one execution attempt of a phase.
type BackoffStrategy ¶
type BackoffStrategy string
BackoffStrategy defines how delays increase between retries.
const ( // BackoffNone applies no delay between retries. BackoffNone BackoffStrategy = "none" // BackoffLinear increases delay linearly between retries. BackoffLinear BackoffStrategy = "linear" // BackoffExponential doubles the delay between each retry. BackoffExponential BackoffStrategy = "exponential" )
BackoffStrategy constants define the available retry backoff strategies.
type BindingConfig ¶
type BindingConfig struct {
// ProgramName identifies the running tool (e.g., "lore", "writ").
ProgramName string
// Receivers lists the receiver factories to expose as Starlark globals.
Receivers []ReceiverFactory
// GraphBuilder enables the plan.* graph namespace (PlanRoot).
GraphBuilder bool
// Writer is the output destination for immediate receivers (e.g., ui.note).
// Defaults to os.Stderr.
Writer io.Writer
// Color enables ANSI color codes in output.
Color bool
}
BindingConfig holds configuration for constructing Starlark bindings. Use NewBindingConfig to create, then chain With* methods:
cfg := op.NewBindingConfig("lore").
WithGraphBuilder().
WithReceivers(json.receiver, yaml.receiver).
WithColor()
func NewBindingConfig ¶
func NewBindingConfig(programName string) *BindingConfig
NewBindingConfig creates a BindingConfig with the given program name. Writer defaults to os.Stderr.
Parameters:
- programName: the name of the running tool (e.g., "lore", "writ").
Returns:
- *BindingConfig: the initialized config.
func (*BindingConfig) WithColor ¶
func (c *BindingConfig) WithColor() *BindingConfig
WithColor enables ANSI color codes in output.
Returns:
- *BindingConfig: the config for method chaining.
func (*BindingConfig) WithGraphBuilder ¶
func (c *BindingConfig) WithGraphBuilder() *BindingConfig
WithGraphBuilder enables the plan.* graph namespace in the runtime.
Returns:
- *BindingConfig: the config for method chaining.
func (*BindingConfig) WithReceivers ¶
func (c *BindingConfig) WithReceivers(receivers ...ReceiverFactory) *BindingConfig
WithReceivers sets the receiver factories to expose as Starlark globals.
Parameters:
- receivers: the receiver factories to include.
Returns:
- *BindingConfig: the config for method chaining.
func (*BindingConfig) WithWriter ¶
func (c *BindingConfig) WithWriter(w io.Writer) *BindingConfig
WithWriter sets the output destination for immediate receivers.
Parameters:
- w: the output writer.
Returns:
- *BindingConfig: the config for method chaining.
type CallableInput ¶
CallableInput carries the parameters needed for callable extraction. Used as the constructor input for the CallableResource constructor registered by the mem package via AnnounceResource.
type CallableResource ¶
type CallableResource interface {
Resource
Init(thread *starlark.Thread) error
Fn() starlark.Callable
FuncTypeName() string
}
CallableResource is the interface that mem.Callable satisfies. It allows pkg/op to work with callables without importing the mem package.
type Collision ¶
type Collision struct {
Target string `json:"target" yaml:"target"`
Winner string `json:"winner" yaml:"winner"`
WinnerLayer string `json:"winner_layer,omitempty" yaml:"winner_layer,omitempty"`
WinnerSpecificity int `json:"winner_specificity,omitempty" yaml:"winner_specificity,omitempty"`
Loser string `json:"loser" yaml:"loser"`
LoserLayer string `json:"loser_layer,omitempty" yaml:"loser_layer,omitempty"`
LoserSpecificity int `json:"loser_specificity,omitempty" yaml:"loser_specificity,omitempty"`
}
Collision records a source conflict resolved during tree building (writ-specific).
type CompensableAction ¶
type CompensableAction interface {
Action
Undo(ctx *Context, complement Complement) error
}
CompensableAction has side effects, can fail, and can be undone. Do returns (result, complement, error).
type Complement ¶
type Complement = any
Complement is the state captured by Do and passed to Undo during saga rollback. Each action defines its own state shape. Actions with no rollback return nil from Do; their Undo ignores the state parameter.
type Context ¶
type Context struct {
ContextBase
// RecoverySite is the shared recovery service for archiving and restoring resources during compensation.
// Instantiated by the executor from Root.
RecoverySite *RecoverySite
// Catalog is the resource catalog for the current execution session. The action layer uses it to shadow Resource
// results after dispatch. Nil when running without catalog integration (e.g., tests).
Catalog *ResourceCatalog
// Graph is the graph being executed. Flow actions use this to look up phases referenced by their slots (e.g.,
// gather body, choose branch).
Graph *Graph
// NodeID is the ID of the currently executing node. Flow actions use this to identify themselves (e.g., gather uses
// it for proxy context).
NodeID string
// Thread is a Starlark execution thread for callable initialization. Created by the executor at execution time.
// Actions that need to invoke mem.Callable functions call Init(ctx.Thread) before Fn().
Thread *starlark.Thread
// Results holds the accumulated node results from the current execution. Flow actions (choose, gather) use this
// to resolve cross-phase promise references in branch nodes.
Results map[string]any
}
Context provides execution context to actions.
type ContextBase ¶
type ContextBase struct {
context.Context // https://pkg.go.dev/context
// Root provides scoped filesystem operations. All provider I/O goes through this interface.
// Three implementations: confinedRoot (execution), RootReader (planning), RootReaderWriter (testing).
// Created by the executor or test runner; closed after execution completes.
Root Root
// ProgramName identifies the running tool (e.g., "lore", "writ").
ProgramName string
// DryRun prevents filesystem modifications when true.
DryRun bool
// Platform provides platform abstractions (package manager, service manager) to action providers. Nil when running
// in environments where host access is not needed (e.g., pure data transforms).
Platform *Platform
// Writer receives user-facing output messages.
Writer io.Writer
// Data holds tool-provided context: template variables, SOPS config, identities, segment maps, etc. Each tool
// populates this before calling GraphExecutor.Run().
Data map[string]any
}
ContextBase provides the execution environment shared by all contexts: immediate-mode scripting environments and graph execution alike.
func NewContextBase ¶
func NewContextBase(root Root) ContextBase
NewContextBase returns a ContextBase with the Platform auto-detected from the host OS.
Parameters:
- root: the filesystem root for scoped I/O operations.
Returns:
- ContextBase: a context base with platform initialized.
type ContextProvider ¶
type ContextProvider interface {
Context() Context
// contains filtered or unexported methods
}
ContextProvider is an interface for objects that can supply an execution Context.
Actions that need access to the execution environment implement this interface to receive the Context during graph execution. The Context includes execution parameters, platform abstractions, and runtime state.
Types should satisfy this interface by embedding ProviderBase.
type Edge ¶
Edge represents a dependency relationship between two nodes. From must complete before To can begin execution.
type Encoder ¶
Encoder is the interface for graph serialization. Both *json.Encoder and *yaml.Encoder satisfy this interface.
type ExecutingReceiver ¶
type ExecutingReceiver struct {
// contains filtered or unexported fields
}
ExecutingReceiver wraps a Go struct for immediate-mode Starlark use. Exported methods become Starlark builtins; method dispatch, argument unpacking, and return value marshaling are handled by reflection.
Optional catalog and stack fields enable resource management integration. When set, Resource results are shadowed in the catalog after successful dispatch.
func WrapProviderInExecutingReceiver ¶
func WrapProviderInExecutingReceiver(factory ReceiverFactory, provider any) *ExecutingReceiver
WrapProviderInExecutingReceiver wraps a Go struct for immediate-mode Starlark use. Params are looked up from the receiver params registry (populated by RegisterActions during InitAll). Only methods listed in the registered params are exposed. Compensate* methods are excluded.
Parameters:
- name: the receiver name exposed to Starlark.
- provider: the Go struct to wrap (must be a pointer).
Returns:
- *ExecutingReceiver: the wrapped receiver with method bridges.
func (*ExecutingReceiver) Attr ¶
func (r *ExecutingReceiver) Attr(name string) (starlark.Value, error)
Attr implements starlark.HasAttrs.
Parameters:
- name: the attribute name to look up.
Returns:
- starlark.Value: the method builtin.
- error: non-nil if the attribute does not exist.
func (*ExecutingReceiver) AttrNames ¶
func (r *ExecutingReceiver) AttrNames() []string
AttrNames implements starlark.HasAttrs.
Returns:
- []string: sorted list of available method names.
func (ExecutingReceiver) Freeze ¶
func (r ExecutingReceiver) Freeze()
Freeze implements starlark.Value.
func (*ExecutingReceiver) Override ¶
func (r *ExecutingReceiver) Override(name string, fn builtinFunc)
Override replaces a method's auto-generated bridge with a custom one. Used for methods with unusual signatures (Callable params, variadic args, non-zero defaults).
Parameters:
- name: the snake_case method name to override.
- fn: the custom bridge function.
func (*ExecutingReceiver) SetCatalog ¶
func (r *ExecutingReceiver) SetCatalog(c *ResourceCatalog)
SetCatalog sets the resource catalog for immediate-mode dispatch. When set, Resource results are shadowed in the catalog after each successful method call.
Parameters:
- c: the resource catalog to use.
func (*ExecutingReceiver) SetContext ¶
func (r *ExecutingReceiver) SetContext(ctx Context)
SetContext injects the execution Context into the receiver's underlying provider. This allows immediate receivers to access Context-scoped services like RecoverySite.
Parameters:
- ctx: the execution context to inject.
func (*ExecutingReceiver) SetStack ¶
func (r *ExecutingReceiver) SetStack(s *RecoveryStack)
SetStack sets the recovery stack for immediate-mode dispatch.
Parameters:
- s: the recovery stack to use.
func (ExecutingReceiver) String ¶
func (r ExecutingReceiver) String() string
String implements starlark.Value.
type ExecutingReceiverFactory ¶
ExecutingReceiverFactory is optional. Checked via type assertion during InitAll. Providers that contribute an immediate receiver (e.g., file, ui) implement this.
type FallibleAction ¶
type FallibleAction interface {
Action
}
FallibleAction has side effects and can fail. Do returns (result, nil, error).
type FatalError ¶
type FatalError struct {
Message string
}
FatalError signals that the graph must halt immediately. The executor unwinds the recovery stack when it encounters this error.
Defined in pkg/op/ so the executor can check for it via errors.As without importing the flow package.
func (*FatalError) Error ¶
func (e *FatalError) Error() string
type Gather ¶
type Gather struct {
// contains filtered or unexported fields
}
Gather represents a collection of outputs that can run in parallel. When used as a slot input, it creates edges from ALL members to the consumer, enabling parallel execution of the gathered nodes.
Usage in Starlark:
a = plan.file.copy(src1, dst1) b = plan.file.copy(src2, dst2) c = plan.file.copy(src3, dst3) group = plan.gather(a, b, c) d = plan.whatever(group) # d waits for a, b, c (which run in parallel)
func NewGather ¶
NewGather creates a new Gather from multiple outputs.
Parameters:
- graph: the execution graph.
- outputs: the outputs to gather.
Returns:
- *Gather: the new gather handle.
func (*Gather) FillSlot ¶
FillSlot fills a slot in the consumer node with all gathered promises, creating edges from each member. This enables parallel execution.
Parameters:
- consumer: the node receiving the gathered promises.
- slotName: the slot to fill.
func (*Gather) Hash ¶
Hash implements starlark.Value.
Returns:
- uint32: unused, always 0.
- error: always non-nil (Gather is unhashable).
func (*Gather) Outputs ¶
Outputs returns the gathered outputs.
Returns:
- []*Output: the collected output promises.
func (*Gather) String ¶
String implements starlark.Value.
Returns:
- string: human-readable representation.
type Graph ¶
type Graph struct {
// Version is the graph format version.
Version string `json:"version" yaml:"version"`
// Tool identifies which tool created this graph ("writ" or "lore").
Tool string `json:"tool" yaml:"tool"`
// Timestamp is when the graph was created/executed.
Timestamp time.Time `json:"timestamp" yaml:"timestamp"`
// State is the execution state (pending, executed, failed).
State GraphState `json:"state" yaml:"state"`
// Platform records the OS and architecture.
Platform Platform `json:"platform" yaml:"platform"`
// Context contains tool-specific metadata.
Context GraphContext `json:"context" yaml:"context"`
// Nodes are the actions to perform/performed.
Nodes []*Node `json:"nodes" yaml:"nodes"`
// Edges are the dependencies between nodes.
Edges []Edge `json:"edges,omitempty" yaml:"edges,omitempty"`
// Phases defines the ordered lifecycle phases (nil for non-phased graphs).
// When present, the executor uses phase-aware execution with retry and rollback.
// When nil, the executor falls back to flat node execution.
Phases []*Phase `json:"phases,omitempty" yaml:"phases,omitempty"`
// Collisions records source conflicts resolved during tree building (writ-specific).
Collisions []Collision `json:"collisions,omitempty" yaml:"collisions,omitempty"`
// Summary contains execution statistics (populated after Run).
Summary Summary `json:"summary,omitempty" yaml:"summary,omitempty"`
// Rollback records compensating actions executed during rollback (populated on failure).
Rollback []RollbackEntry `json:"rollback,omitempty" yaml:"rollback,omitempty"`
// Checksum is the git-style integrity hash.
Checksum string `json:"checksum,omitempty" yaml:"checksum,omitempty"`
// Signature contains the cryptographic signature (optional).
Signature *Signature `json:"signature,omitempty" yaml:"signature,omitempty"`
// Catalog is the append-only resource catalog for planning.
// One per Graph. Not serialized — planning-only state.
Catalog *ResourceCatalog `json:"-" yaml:"-"`
}
Graph represents an execution graph containing nodes and edges. This is THE graph used by both writ and lore - they differ only in content.
Before Run(): State is "pending", represents the plan After Run(): State is "executed", represents the receipt
func NewGraph ¶
NewGraph creates a Graph with common metadata populated. Tool identifies which tool created the graph ("writ" or "lore"). Callers populate Context and add Nodes/Edges after creation.
func (*Graph) CanonicalContent ¶
CanonicalContent returns the graph serialized as YAML without checksum and signature. This is used for computing checksums and verifying signatures.
func (*Graph) CollectPhaseNodes ¶
CollectPhaseNodes returns the nodes and intra-phase edges for the given phase. Nodes are returned in graph order; edges are filtered to only those between phase-internal nodes.
func (*Graph) ComputeSummary ¶
func (g *Graph) ComputeSummary()
ComputeSummary calculates summary statistics from nodes. For phased graphs, node statuses reflect the phase execution outcome (nodes in rolled-back phases may show as completed from before rollback).
func (*Graph) Filename ¶
Filename returns the standard filename for this graph. Format: "<tool>-<timestamp>.yaml" or "<tool>-<scope>-<timestamp>.yaml" when scoped.
type GraphContext ¶
type GraphContext struct {
// Scope identifies the planning scope for this graph.
// For writ: target scope ("system", "home").
// For lore: package cache scope (package name or names).
Scope string `json:"scope,omitempty" yaml:"scope,omitempty"`
// SourceRoot is the source directory (writ: repo path, lore: registry cache).
SourceRoot string `json:"source_root,omitempty" yaml:"source_root,omitempty"`
// TargetRoot is the target directory (typically $HOME).
TargetRoot string `json:"target_root,omitempty" yaml:"target_root,omitempty"`
// Projects lists the projects included (writ-specific).
Projects []string `json:"projects,omitempty" yaml:"projects,omitempty"`
// Packages lists the packages included (lore-specific).
Packages []string `json:"packages,omitempty" yaml:"packages,omitempty"`
// Segments contains platform segment values (writ-specific).
Segments map[string]string `json:"segments,omitempty" yaml:"segments,omitempty"`
// Layers lists repository layers used (writ-specific).
Layers []string `json:"layers,omitempty" yaml:"layers,omitempty"`
// Platform is the target platform string (lore-specific, e.g., "Darwin", "Linux.Debian").
TargetPlatform string `json:"target_platform,omitempty" yaml:"target_platform,omitempty"`
// Features enabled for package installation (lore-specific).
Features []string `json:"features,omitempty" yaml:"features,omitempty"`
// Settings for package installation (lore-specific).
Settings map[string]string `json:"settings,omitempty" yaml:"settings,omitempty"`
// CommitHashes records the git commit hash for each layer source (writ-specific).
// Keys are layer names ("base", "team", "personal"); values are full commit hashes.
CommitHashes map[string]string `json:"commit_hashes,omitempty" yaml:"commit_hashes,omitempty"`
// DirtyLayers lists layer names that had uncommitted changes at planning time (writ-specific).
// Present only when --allow-dirty was used; empty means all layers were clean.
DirtyLayers []string `json:"dirty_layers,omitempty" yaml:"dirty_layers,omitempty"`
}
GraphContext contains tool-specific metadata stored in the graph. Both writ and lore populate this with their relevant context.
type GraphState ¶
type GraphState string
GraphState represents the execution state of the graph.
const ( // StatePending indicates the graph has not yet been executed. StatePending GraphState = "pending" // StateExecuted indicates the graph executed successfully. StateExecuted GraphState = "executed" // StateFailed indicates the graph failed during execution. StateFailed GraphState = "failed" )
GraphState constants define the possible states of a graph.
type MethodParams ¶
MethodParams maps Go method names (CamelCase) to Starlark parameter name lists. Optional params use the "name?" suffix.
type NoResult ¶
type NoResult struct{}
NoResult signals that a provider method produces no output. Used by CompensableAction methods like Remove and RemoveAll that can be undone but produce no result for downstream nodes. classifyActionReturn maps NoResult to nil Result; classifyReturn maps it to starlark.None.
type Node ¶
type Node struct {
// ID is the unique identifier (typically relative target path or package name).
ID string `json:"id" yaml:"id"`
// Action to perform. Serialized as the action name string; deserialized
// as a stubAction. The executor calls Do directly.
Action Action `json:"-" yaml:"-"`
// Status of this node: pending, completed, skipped, failed.
Status NodeStatus `json:"status" yaml:"status"`
// Timestamp is when this action completed.
Timestamp string `json:"timestamp,omitempty" yaml:"timestamp,omitempty"`
// Slots holds input values for this node. Each slot can be:
// - Immediate: value known at analysis time
// - Promise: reference to another node's output (creates edge)
Slots map[string]SlotValue `json:"slots,omitempty" yaml:"slots,omitempty"`
// Project this node belongs to.
Project string `json:"project,omitempty" yaml:"project,omitempty"`
// Layer is the repository layer (base, team, personal).
Layer string `json:"layer,omitempty" yaml:"layer,omitempty"`
// Error message if status is failed.
Error string `json:"error,omitempty" yaml:"error,omitempty"`
// Retry is the retry policy for this node (nil = no retry).
Retry *RetryPolicy `json:"retry,omitempty" yaml:"retry,omitempty"`
// Annotations holds extensible metadata (serialized to receipts).
Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"`
}
Node represents a single unit of work in an execution graph.
func (*Node) ActionName ¶
ActionName returns the action name. Works for both live nodes (Action set by executor) and deserialized receipt nodes (stubAction).
func (*Node) GetSlot ¶
GetSlot returns the resolved value of a slot. If the slot is a promise, returns nil (must be resolved by executor).
func (*Node) MarshalJSON ¶
MarshalJSON serializes the node with Action as its name string.
func (*Node) MarshalYAML ¶
MarshalYAML serializes the node with Action as its name string. Note: we cannot use the nodeJSONWire embedding pattern here because yaml.v3 panics on unexported concrete types behind interfaces in shadowed embedded fields, and fails to decode embedded fields when names collide (unlike encoding/json which handles both correctly). We round-trip through JSON instead.
func (*Node) RequireStringSlot ¶
RequireStringSlot returns the string value of a required slot. Returns an error if the slot is not set, or holds a non-string value. An empty string is valid — use GetSlot for optional slots where zero value is acceptable.
func (*Node) ResolvedSlots ¶
ResolvedSlots returns all slot values as a flat map. Promise slots are resolved from the results map; immediate slots are returned directly. Proxy slots are resolved from the optional proxyCtx map (used by gather for per-iteration item binding). Pass nil for results when all slots are immediate (e.g., in tests).
func (*Node) SetSlotImmediate ¶
SetSlotImmediate sets a slot to an immediate value.
func (*Node) SetSlotPromise ¶
SetSlotPromise sets a slot to a promise (reference to another node).
func (*Node) SetSlotProxy ¶
SetSlotProxy sets a slot to a gather proxy reference.
func (*Node) UnmarshalJSON ¶
UnmarshalJSON deserializes a node, creating a stubAction from the action name.
type NodeStatus ¶
type NodeStatus string
NodeStatus represents the execution status of a node.
const ( // StatusPending indicates the node has not yet been executed. StatusPending NodeStatus = "pending" // StatusCompleted indicates the node executed successfully. StatusCompleted NodeStatus = "completed" // StatusSkipped indicates the node was skipped. StatusSkipped NodeStatus = "skipped" // StatusFailed indicates the node failed during execution. StatusFailed NodeStatus = "failed" )
NodeStatus constants define the possible statuses of a node.
type Output ¶
type Output struct {
// contains filtered or unexported fields
}
Output represents a promise - a handle to a node's output that can flow through the graph to fill slots in other nodes.
When passed to a plan function's slot, it creates an edge in the graph. The same promise can flow to multiple slots (fan-out).
func NewOutput ¶
NewOutput creates a new Output (promise) representing a node's output.
Parameters:
- node: the producing node.
- graph: the execution graph.
- slot: which output slot this represents (empty for default).
Returns:
- *Output: the new promise handle.
func ResolveInput ¶
ResolveInput extracts an *Output from a Starlark value.
Parameters:
- value: the Starlark value to extract from.
Returns:
- *Output: the extracted output.
- error: non-nil if value is not an Output.
func (*Output) Attr ¶
Attr implements starlark.HasAttrs.
Parameters:
- name: the attribute name to look up.
Returns:
- starlark.Value: the attribute value.
- error: non-nil if the attribute does not exist.
func (*Output) AttrNames ¶
AttrNames implements starlark.HasAttrs.
Returns:
- []string: all available attribute names.
func (*Output) DependOn ¶
DependOn creates an edge making the given node depend on this output's node.
Parameters:
- consumer: the node that should depend on this output's producer.
func (*Output) FillSlot ¶
FillSlot fills a slot in the consumer node with this promise, creating an edge. This is called when a promise is passed to a plan function.
Parameters:
- consumer: the node receiving the promise.
- slotName: the slot to fill.
func (*Output) Graph ¶
Graph returns the execution graph.
Returns:
- *Graph: the graph this output belongs to.
func (*Output) Hash ¶
Hash implements starlark.Value.
Returns:
- uint32: unused, always 0.
- error: always non-nil (Output is unhashable).
func (*Output) Node ¶
Node returns the node that produces this output.
Returns:
- *Node: the producing node.
func (*Output) Path ¶
Path returns a path from the node's slots.
Returns:
- string: the path slot value, or empty string if not present or not a string.
func (*Output) Slot ¶
Slot returns which output slot this represents.
Returns:
- string: the slot identifier.
func (*Output) String ¶
String implements starlark.Value.
Returns:
- string: human-readable representation.
type PackageManager ¶
type PackageManager interface {
Name() string
Installed(name string) bool
Version(name string) string
Available(name string) bool
Search(query string, limit int) []SearchResult
Install(packages ...string) PlatformResult
Remove(name string) PlatformResult
Update() PlatformResult
AddRepo(url, keyURL, name string) PlatformResult
NeedsSudo() bool
}
PackageManager abstracts package manager operations.
type Path ¶
type Path struct {
// contains filtered or unexported fields
}
Path holds both root-relative and absolute forms of a filesystem path. Created through [Root.NewPath] to guarantee both fields are populated. The root field records which root directory Rel is relative to (matching os.Root.Name). Abs is derived as filepath.Join(root, rel) and is not serialized.
func NewPath ¶
NewPath creates a Path from a root directory and a root-relative path. Abs is derived. Intended for tests and deserialization.
Parameters:
- root: Root directory that rel is relative to (matches os.Root.Name)
- rel: Root-relative path
Returns:
- Path: the constructed path
func (Path) Abs ¶
Abs returns the absolute path used for unconfined I/O, URIs, display, and logging.
func (Path) MarshalJSON ¶
MarshalJSON serializes the canonical form {root, rel}. Abs is derived on deserialization.
func (Path) Root ¶
Root returns the root directory path that Rel is relative to. Matches os.Root.Name.
func (*Path) UnmarshalJSON ¶
UnmarshalJSON deserializes {root, rel} and derives Abs.
type Phase ¶
type Phase struct {
// ID is the unique identifier (e.g., "phase.install").
ID string `json:"id" yaml:"id"`
// Name is the phase name (e.g., "install").
Name string `json:"name" yaml:"name"`
// Status of this phase: pending, completed, failed, rolled_back, skipped.
Status PhaseStatus `json:"status" yaml:"status"`
// Retry governs retry behavior when inner nodes fail.
Retry *RetryPolicy `json:"retry,omitempty" yaml:"retry,omitempty"`
// NodeIDs lists the IDs of inner nodes belonging to this phase.
NodeIDs []string `json:"nodes,omitempty" yaml:"nodes,omitempty"`
// Compensate is the ID of the compensating action for rollback.
Compensate string `json:"compensate,omitempty" yaml:"compensate,omitempty"`
// Attempts records retry history (populated during execution).
Attempts []Attempt `json:"attempts,omitempty" yaml:"attempts,omitempty"`
// State holds execution metadata captured during the forward action.
// The compensating action reads this to know what to undo.
State map[string]any `json:"state,omitempty" yaml:"state,omitempty"`
// Branch marks this phase as a conditional branch owned by a choose action.
// Branch phases are not executed directly by the top-level executor; they
// are dispatched by the choose action's Do method.
Branch bool `json:"branch,omitempty" yaml:"branch,omitempty"`
}
Phase represents a lifecycle phase in the execution graph. Each phase owns a set of inner nodes and acts as an error boundary with retry and compensating action support (the Saga Pattern).
type PhaseStatus ¶
type PhaseStatus string
PhaseStatus represents the execution state of a phase.
const ( // PhasePending indicates the phase has not yet been executed. PhasePending PhaseStatus = "pending" // PhaseCompleted indicates the phase executed successfully. PhaseCompleted PhaseStatus = "completed" // PhaseFailed indicates the phase failed during execution. PhaseFailed PhaseStatus = "failed" // PhaseRolledBack indicates the phase was rolled back after failure. PhaseRolledBack PhaseStatus = "rolled_back" // PhaseSkipped indicates the phase was skipped. PhaseSkipped PhaseStatus = "skipped" )
PhaseStatus constants define the possible states of a phase.
type PlanningReceiver ¶
type PlanningReceiver struct {
// contains filtered or unexported fields
}
PlanningReceiver wraps a provider's method signatures for planned-mode Starlark use. Each call creates a graph Node instead of executing the method directly.
func WrapProviderInPlanningReceiver ¶
func WrapProviderInPlanningReceiver( factory ReceiverFactory, graph *Graph, project string, reg *ActionRegistry, params MethodParams, ) *PlanningReceiver
WrapProviderInPlanningReceiver wraps a provider for planned-mode use. Only methods with a corresponding registered action in reg are exposed.
func (*PlanningReceiver) Attr ¶
func (p *PlanningReceiver) Attr(name string) (starlark.Value, error)
Attr implements starlark.HasAttrs.
func (*PlanningReceiver) AttrNames ¶
func (p *PlanningReceiver) AttrNames() []string
AttrNames implements starlark.HasAttrs.
func (PlanningReceiver) Freeze ¶
func (r PlanningReceiver) Freeze()
Freeze implements starlark.Value.
func (*PlanningReceiver) Override ¶
func (p *PlanningReceiver) Override(name string, fn builtinFunc)
Override replaces a method's auto-generated planned bridge with a custom one.
func (PlanningReceiver) String ¶
func (r PlanningReceiver) String() string
String implements starlark.Value.
type PlanningReceiverFactory ¶
type PlanningReceiverFactory interface {
NewPlanning(graph *Graph, project string, reg *ActionRegistry) starlark.Value
}
PlanningReceiverFactory is optional. Checked via type assertion during InitAll.
Providers that contribute a plan sub-namespace (e.g., plan.file) implement this.
type Platform ¶
type Platform struct {
// Serializable info (used by Graph)
OS string `json:"os" yaml:"os"`
Arch string `json:"arch" yaml:"arch"`
Distro string `json:"distro,omitempty" yaml:"distro,omitempty"`
Version string `json:"version,omitempty" yaml:"version,omitempty"`
Hostname string `json:"hostname,omitempty" yaml:"hostname,omitempty"`
// Runtime — not serialized
PackageManager PackageManager `json:"-" yaml:"-"`
PackageManagers map[string]PackageManager `json:"-" yaml:"-"`
ServiceManager ServiceManager `json:"-" yaml:"-"`
}
Platform carries platform info plus runtime package/service managers. Serializable fields are stored in graphs; runtime fields are injected at execution time by NewPlatform().
func NewPlatform ¶
func NewPlatform() *Platform
NewPlatform returns a fully populated Platform for the current OS.
func (*Platform) AllInstalledBy ¶
func (p *Platform) AllInstalledBy(name string) []PackageManager
AllInstalledBy returns all package managers that have the package installed.
func (*Platform) GetPackageManager ¶
func (p *Platform) GetPackageManager(name string) PackageManager
GetPackageManager returns a specific package manager by name. Returns nil if unavailable.
func (*Platform) InstalledBy ¶
func (p *Platform) InstalledBy(name string) PackageManager
InstalledBy returns the package manager that installed the named package. Returns nil if not installed by any known manager.
type PlatformResult ¶
PlatformResult represents a command execution result.
type ProviderBase ¶
type ProviderBase struct {
// contains filtered or unexported fields
}
ProviderBase provides a standardized implementation of the ContextProvider interface.
It must be embedded in all domain-specific providers to ensure they adhere to the execution graph's strictly enforced lifetime.
ProviderBase should only be instantiated by authorized builders using [NewExecuting].
func NewProviderBase ¶
func NewProviderBase(ctx Context) ProviderBase
NewProviderBase returns a new ProviderBase provider instance with the given Context.
func (*ProviderBase) Context ¶
func (p *ProviderBase) Context() Context
Context returns the context associated with this provider's lifetime.
type ProviderLifetime ¶
type ProviderLifetime string
ProviderLifetime declares a provider's lifecycle semantics. The value is set via a "// +devlore:lifetime=" directive on the ReceiverFactory struct and emitted by the code generator into provider descriptor registrations.
const ( LifetimeStateless ProviderLifetime = "stateless" // safe to cache indefinitely and share across threads LifetimePhase ProviderLifetime = "phase" // fresh instance per phase; Close() at phase boundary LifetimeSession ProviderLifetime = "session" // single instance for the session; Close() at session end )
Lifetime constants define caching, sharing, and cleanup behavior.
type ReceiverFactory ¶
type ReceiverFactory interface {
GetOrCreateProvider(ctx Context) ContextProvider
ReceiverName() string
ProviderType() reflect.Type
Register(registry *ActionRegistry, ctx Context)
}
ReceiverFactory is the required interface for all provider descriptors--generated and handwritten alike.
Every provider implements this to announce its name and register its actions with the framework.
func Providers ¶
func Providers() []ReceiverFactory
Providers returns all announced providers (for introspection/debugging).
Returns:
- []ReceiverFactory: a copy of the announced provider list.
type RecoveryEntry ¶
type RecoveryEntry struct {
// contains filtered or unexported fields
}
RecoveryEntry captures a single compensable operation with its undo and reconcile state.
type RecoverySite ¶
type RecoverySite struct {
// contains filtered or unexported fields
}
RecoverySite manages archival and restoration of resources within the authority boundary.
All operations use zero-copy renames for files and byte serialization for data. The recovery directory is .devlore/recovery/ within the op.Root authority boundary. All I/O goes through Context.Root.
func NewRecoverySite ¶
func NewRecoverySite(ctx Context) *RecoverySite
NewRecoverySite creates a RecoverySite with the given Context. The Context must have a non-nil Root.
func (*RecoverySite) ArchiveData ¶
func (s *RecoverySite) ArchiveData(data []byte) (string, error)
ArchiveData writes bytes to a file in the recovery directory.
Parameters:
- data: Bytes to archive
Returns:
- string: opaque recovery ID for tombstone storage
- error: any write error
func (*RecoverySite) ArchiveFile ¶
func (s *RecoverySite) ArchiveFile(p Path) (string, error)
ArchiveFile moves a file to recovery via zero-copy rename.
No data is copied — the file's directory entry is relocated. Takes Path for the user-facing location. Returns an opaque recovery ID for tombstone storage.
Parameters:
- p: Path of the file to archive
Returns:
- string: opaque recovery ID for tombstone storage
- error: any rename error
func (*RecoverySite) RestoreData ¶
func (s *RecoverySite) RestoreData(recoveryID string) ([]byte, error)
RestoreData reads bytes back from a file in the recovery directory.
Parameters:
- recoveryID: Opaque recovery ID returned by ArchiveData
Returns:
- []byte: archived data
- error: any read error
func (*RecoverySite) RestoreFile ¶
func (s *RecoverySite) RestoreFile(original Path, recoveryID string) error
RestoreFile moves a file back from recovery via zero-copy rename.
No data is copied — the directory entry is relocated back. The parent directory of original is recreated if it was pruned after archival.
Parameters:
- original: Path where the file should be restored
- recoveryID: Opaque recovery ID returned by ArchiveFile
Returns:
- error: any rename error
type RecoveryStack ¶
type RecoveryStack struct {
// contains filtered or unexported fields
}
RecoveryStack accumulates compensable operations in LIFO order. On Unwind, each entry is reconciled (if a reconcile function was provided) and then compensated in reverse order.
func NewRecoveryStack ¶
func NewRecoveryStack() *RecoveryStack
NewRecoveryStack creates an empty RecoveryStack.
func (*RecoveryStack) Discard ¶
func (s *RecoveryStack) Discard()
Discard drops all entries without unwinding.
func (*RecoveryStack) Do ¶
func (s *RecoveryStack) Do( invoke func() (undoState any, reconcileState any, err error), compensate func(any) error, reconcile func(any) (bool, error), ) error
Do invokes a closure and, if it succeeds, pushes a recovery entry onto the stack. If invoke returns an error, the stack is unchanged and the error is returned without unwinding.
func (*RecoveryStack) Len ¶
func (s *RecoveryStack) Len() int
Len returns the number of entries on the stack.
func (*RecoveryStack) Push ¶
func (s *RecoveryStack) Push( compensate func(any) error, reconcile func(any) (bool, error), undoState any, reconcileState any, )
Push manually adds a recovery entry to the stack.
func (*RecoveryStack) PushAction ¶
func (s *RecoveryStack) PushAction(ctx *Context, action Action, undoState any)
PushAction pushes a CompensableAction onto the stack. If action does not implement CompensableAction, the call is a no-op. ErrNotCompensable responses are filtered during compensation.
func (*RecoveryStack) Unwind ¶
func (s *RecoveryStack) Unwind() error
Unwind compensates all entries in LIFO order. For each entry:
- If reconcile is non-nil, it is called first. If reconcile returns false (drifted), the entry is skipped and an ErrDrifted is collected.
- If reconcile is nil or returns true (safe), compensate is called.
All entries are attempted regardless of individual failures. Errors are joined via errors.Join.
type Resource ¶
type Resource interface {
URI() string
Resolve(root Root) error
// contains filtered or unexported methods
}
Resource is the interface for all resource types.
Every provider-specific resource (e.g., file.Resource) must embed ResourceBase to satisfy it. The unexported resourceBase method seals the interface to package op. Only types embedding ResourceBase can implement Resource.
URI() returns a cached string computed at construction time. Each concrete type owns its URI construction--there is no shared dispatch. If [Resolve] changes identity-bearing fields (e.g., path canonicalization), the concrete type updates the cached URI via ResourceBase.SetURI.
type ResourceBase ¶
type ResourceBase struct {
// contains filtered or unexported fields
}
ResourceBase holds the identity fields common to all resources.
ReceiverFactory-specific resource types must embed it by value. The uri field is set at construction via NewResourceBase. The id and originID fields are stamped by the ResourceCatalog when the resource is cataloged; they are not a concern of the resource itself.
func NewResourceBase ¶
func NewResourceBase(uri string) ResourceBase
NewResourceBase creates a ResourceBase with the given URI.
func (*ResourceBase) Format ¶
func (b *ResourceBase) Format(v any) string
Format marshals v as compact JSON. Concrete resource types call this from their String() method: func (r Resource) String() string { return r.Format(r) }
func (*ResourceBase) Fragment ¶
func (b *ResourceBase) Fragment() string
Fragment returns the URI fragment by parsing the stored uri. Convenience helper — NOT an interface method.
func (*ResourceBase) Host ¶
func (b *ResourceBase) Host() string
Host returns the URI host by parsing the stored uri.
Non-empty for hierarchical URIs with an authority (e.g., file:///some/path). Empty for opaque URIs. Convenience helper — NOT an interface method.
func (*ResourceBase) MarshalStarvalue ¶
func (b *ResourceBase) MarshalStarvalue() (starlark.Value, error)
MarshalStarvalue implements starvalue.Marshaler. It serializes the private identity fields (uri, id, originID) so they survive the Go → Starlark → Go round-trip used by FillSlot.
func (*ResourceBase) Opaque ¶
func (b *ResourceBase) Opaque() string
Opaque returns the opaque data component of the URI (non-empty for opaque URIs like appnet:, mem:, pkg:, svc:).
For hierarchical URIs (file://), returns empty. Convenience helper--NOT an interface method.
func (*ResourceBase) Path ¶
func (b *ResourceBase) Path() string
Path returns the URI path by parsing the stored uri. Non-empty for hierarchical URIs. Empty for opaque URIs. Convenience helper — NOT an interface method.
func (*ResourceBase) Resolve ¶
func (b *ResourceBase) Resolve(_ Root) error
Resolve populates provider-specific metadata via I/O (e.g., os.Stat for files). The default implementation is a no-op — providers that need resolution (file, git) override it. Callers that need metadata call Resolve then check the result. An unresolved resource reports Exists() == false. When root is non-nil, I/O is scoped through os.Root.
func (*ResourceBase) Scheme ¶
func (b *ResourceBase) Scheme() string
Scheme returns the URI scheme by parsing the stored uri.
Convenience helper--NOT an interface method.
func (*ResourceBase) SetURI ¶
func (b *ResourceBase) SetURI(uri string)
SetURI updates the cached URI. Concrete types call this after Resolve() when identity-bearing fields change (e.g., path canonicalization).
func (*ResourceBase) URI ¶
func (b *ResourceBase) URI() string
URI returns the cached canonical URI of this resource.
type ResourceCatalog ¶
type ResourceCatalog struct {
// contains filtered or unexported fields
}
ResourceCatalog is the append-only catalog of all resources created during a single planning session. One per Graph. It owns the ledger (the log of all resource versions) and the namespace (URI → current resource ID).
func NewResourceCatalog ¶
func NewResourceCatalog() *ResourceCatalog
NewResourceCatalog creates an empty catalog.
func (*ResourceCatalog) Current ¶
func (c *ResourceCatalog) Current(uri string) string
Current returns the current resource ID for a URI, or "".
func (*ResourceCatalog) DiscoveryURIs ¶
func (c *ResourceCatalog) DiscoveryURIs() []string
DiscoveryURIs returns the URIs of catalog entries that were discovered (created by Resolve) but not yet shadowed. These are inputs that should exist on the target machine before execution begins. URIs whose current entry has been superseded by Shadow are excluded.
func (*ResourceCatalog) Len ¶
func (c *ResourceCatalog) Len() int
Len returns the count of resources in the catalog.
func (*ResourceCatalog) Lookup ¶
func (c *ResourceCatalog) Lookup(id string) (Resource, bool)
Lookup returns the resource with the given ID, or false if not found.
func (*ResourceCatalog) Resolve ¶
func (c *ResourceCatalog) Resolve(uri string) string
Resolve returns the current resource ID for a URI. If the URI has never been seen, a discovery entry (ResourceBase with URI only, no origin) is created and cataloged.
func (*ResourceCatalog) Shadow ¶
func (c *ResourceCatalog) Shadow(r Resource, originID string) (string, error)
Shadow catalogs a new resource version, updates the namespace to point to it, and returns the new resource ID. The resource must embed ResourceBase with its URI already set via NewResourceBase.
Write-write conflict detection: if the URI is already shadowed by a different origin (non-empty originID), Shadow returns an error. This catches plan-time conflicts where two nodes target the same output. Discovery entries (originID == "") are silently superseded.
type ResourceDescriptor ¶
type ResourceDescriptor interface {
// Name returns a human-readable name for the resource type (e.g., "file.Resource").
Name() string
// Type returns the reflect.ProviderType of the resource struct (e.g., reflect.TypeOf(file.Resource{})).
Type() reflect.Type
// Init completes registration for this resource type. Called exactly once, lazily, on first use.
// Implementations typically call RegisterConstructor. Errors are cached — Init is never retried.
Init() error
}
ResourceDescriptor describes a resource type for lazy registration. Generated code calls AnnounceResource in init() with a lightweight descriptor. The descriptor's Init method is called exactly once on first use to complete registration (e.g., RegisterConstructor).
type Result ¶
type Result = any
Result is data that flows to downstream nodes via edges (e.g., file content, a rendered template, a query result). The executor stores this keyed by node ID and resolves promise slots from stored Results before calling downstream Do.
type RetryPolicy ¶
type RetryPolicy struct {
// MaxAttempts is the maximum number of retries (0 = no retry, fail immediately).
MaxAttempts int `json:"max_attempts" yaml:"max_attempts"`
// Backoff is the delay strategy: none, linear, exponential.
Backoff BackoffStrategy `json:"backoff" yaml:"backoff"`
// InitialDelay is the delay before the first retry (Go duration string, e.g. "1s").
InitialDelay string `json:"initial_delay,omitempty" yaml:"initial_delay,omitempty"`
// MaxDelay caps the delay between retries (Go duration string, e.g. "30s").
MaxDelay string `json:"max_delay,omitempty" yaml:"max_delay,omitempty"`
}
RetryPolicy configures retry behavior for a phase.
func (RetryPolicy) ComputeDelay ¶
func (r RetryPolicy) ComputeDelay(attempt int) time.Duration
ComputeDelay returns the delay for a given attempt number (0-based).
func (RetryPolicy) ParseInitialDelay ¶
func (r RetryPolicy) ParseInitialDelay() time.Duration
ParseInitialDelay parses the InitialDelay string into a time.Duration. Returns 0 if the string is empty or unparseable.
func (RetryPolicy) ParseMaxDelay ¶
func (r RetryPolicy) ParseMaxDelay() time.Duration
ParseMaxDelay parses the MaxDelay string into a time.Duration. Returns 0 if the string is empty or unparseable.
type RollbackEntry ¶
type RollbackEntry struct {
// Phase is the phase name that was rolled back.
Phase string `json:"phase" yaml:"phase"`
// Compensate is the ID of the compensating action.
Compensate string `json:"compensate" yaml:"compensate"`
// Status is "completed" or "failed".
Status string `json:"status" yaml:"status"`
// Error is the error message if the compensating action failed.
Error string `json:"error,omitempty" yaml:"error,omitempty"`
}
RollbackEntry records a compensating action executed during rollback.
type Root ¶
type Root interface {
Stat(p Path) (fs.FileInfo, error)
Lstat(p Path) (fs.FileInfo, error)
Open(p Path) (*os.File, error)
ReadFile(p Path) ([]byte, error)
Readlink(p Path) (string, error)
FS() fs.FS
OpenFile(p Path, flag int, perm os.FileMode) (*os.File, error)
WriteFile(p Path, data []byte, perm os.FileMode) error
MkdirAll(p Path, perm os.FileMode) error
Remove(p Path) error
Rename(oldPath, newPath Path) error
Symlink(target string, link Path) error
NewPath(path string) Path
Name() string
Close() error
}
Root provides scoped filesystem operations. All path arguments are Path values created through [Root.NewPath]. Three concrete implementations provide different access modes:
- NewConfinedRoot wraps *os.Root for OS-enforced confinement (execution)
- NewRootReader delegates to os.* for unconfined read-only access (planning)
- NewRootReaderWriter delegates to os.* for unconfined read-write access (testing)
func NewConfinedRoot ¶
NewConfinedRoot opens an OS-enforced confined Root at dir.
Parameters:
- dir: Directory to confine all I/O within
Returns:
- Root: confined root backed by *os.Root
- error: any error from os.OpenRoot
func NewRootReader ¶
NewRootReader creates a read-only Root at dir. Write operations return ErrReadOnly.
Parameters:
- dir: Base directory for all path resolution
Returns:
- Root: read-only, unconfined root
func NewRootReaderWriter ¶
NewRootReaderWriter creates a read-write Root at dir without OS-level confinement.
Parameters:
- dir: Base directory for all path resolution
Returns:
- Root: read-write, unconfined root
type RootReader ¶
type RootReader struct {
// contains filtered or unexported fields
}
RootReader provides unconfined, read-only filesystem access. Write operations return ErrReadOnly. Used during planning when providers need to inspect source files without mutation capability.
func (*RootReader) Remove ¶
func (r *RootReader) Remove(Path) error
func (*RootReader) Rename ¶
func (r *RootReader) Rename(_, _ Path) error
type RootReaderWriter ¶
type RootReaderWriter struct {
RootReader
}
RootReaderWriter provides unconfined, read-write filesystem access. Reads are inherited from RootReader. Write operations delegate to os.* without OS-level confinement.
func (*RootReaderWriter) MkdirAll ¶
func (r *RootReaderWriter) MkdirAll(p Path, perm os.FileMode) error
func (*RootReaderWriter) Remove ¶
func (r *RootReaderWriter) Remove(p Path) error
func (*RootReaderWriter) Rename ¶
func (r *RootReaderWriter) Rename(oldPath, newPath Path) error
type SearchResult ¶
SearchResult represents a package found by search.
type ServiceManager ¶
type ServiceManager interface {
Exists(name string) bool
IsRunning(name string) bool
IsEnabled(name string) bool
Status(name string) string
Start(name string) PlatformResult
Stop(name string) PlatformResult
Enable(name string) PlatformResult
Disable(name string) PlatformResult
NeedsSudo() bool
}
ServiceManager abstracts service management operations.
type Signature ¶
type Signature struct {
// Method is the signing method used (gpg, aws_kms, gcp_kms, azure_kv).
Method string `json:"method" yaml:"method"`
// Value is the signature data (base64-encoded).
Value string `json:"value" yaml:"value"`
// KeyID identifies the key used for signing.
// For GPG: fingerprint, for KMS: key ARN/ID/URL.
KeyID string `json:"key_id" yaml:"key_id"`
}
Signature contains the cryptographic signature of a graph.
type SlotValue ¶
type SlotValue struct {
// Immediate is the direct value (any type, known at analysis time).
Immediate any `json:"immediate,omitempty" yaml:"immediate,omitempty"`
// NodeRef is the ID of the node that produces this value (promise).
NodeRef string `json:"node_ref,omitempty" yaml:"node_ref,omitempty"`
// Slot is which output slot of the referenced node (empty = default output).
Slot string `json:"slot,omitempty" yaml:"slot,omitempty"`
// GatherRef is the gather node ID for proxy resolution.
GatherRef string `json:"gather_ref,omitempty" yaml:"gather_ref,omitempty"`
// Field is the field name to access on the proxy item.
Field string `json:"field,omitempty" yaml:"field,omitempty"`
}
SlotValue represents a value that fills a slot in a node. Three variants, mutually exclusive:
- Immediate: value known at analysis time
- Promise: reference to another node's output (NodeRef)
- Proxy: reference to a gather iteration item (GatherRef + Field)
func (SlotValue) IsImmediate ¶
IsImmediate returns true if this slot value is an immediate value.
type StarlarkRuntime ¶
type StarlarkRuntime struct {
// contains filtered or unexported fields
}
StarlarkRuntime manages an immediate-mode Starlark scripting runtime using announced receivers. Receivers listed in BindingConfig.Receivers are constructed as Starlark globals. External consumers (e.g., noblefactor-ops) use this to obtain framework-managed receivers without hand-coding receiver construction.
func NewStarlarkRuntime ¶
func NewStarlarkRuntime(cfg *BindingConfig) *StarlarkRuntime
NewStarlarkRuntime creates a runtime with the given configuration. Receivers listed in cfg.Receivers are included when BuildReceivers is called.
Parameters:
- cfg: configuration specifying which receivers to include.
Returns:
- *StarlarkRuntime: the initialized runtime.
func (*StarlarkRuntime) BuildReceiver ¶
func (rt *StarlarkRuntime) BuildReceiver(name string) (starlark.Value, bool)
BuildReceiver constructs a single immediate receiver by provider name.
Parameters:
- name: the provider name to build.
Returns:
- starlark.Value: the constructed receiver, or nil if not found.
- bool: true if the provider was found and implements ExecutingReceiverFactory.
func (*StarlarkRuntime) BuildReceivers ¶
func (rt *StarlarkRuntime) BuildReceivers() starlark.StringDict
BuildReceivers constructs immediate receivers for factories listed in cfg.Receivers.
Returns:
- starlark.StringDict: receiver map suitable for merging into Starlark globals.
func (*StarlarkRuntime) HasGraphBuilder ¶
func (rt *StarlarkRuntime) HasGraphBuilder() bool
HasGraphBuilder reports whether the plan.* graph namespace is enabled.
Returns:
- bool: true if the graph builder is included.
func (*StarlarkRuntime) Included ¶
func (rt *StarlarkRuntime) Included(name string) bool
Included reports whether the named provider is in the receiver set.
Parameters:
- name: the provider name to check.
Returns:
- bool: true if the provider is included in this runtime's receiver set.
func (*StarlarkRuntime) Initialize ¶
func (rt *StarlarkRuntime) Initialize(reg *ActionRegistry, ctx ContextBase)
Initialize registers all providers' actions with the registry and stores the context for later receiver initialization.
Parameters:
- reg: the action registry to populate.
- ctx: the base execution context for provider initialization.
type Summary ¶
type Summary struct {
TotalFiles int `json:"total_files,omitempty" yaml:"total_files,omitempty"`
Links int `json:"links,omitempty" yaml:"links,omitempty"`
Copies int `json:"copies,omitempty" yaml:"copies,omitempty"`
Templates int `json:"templates,omitempty" yaml:"templates,omitempty"`
Secrets int `json:"secrets,omitempty" yaml:"secrets,omitempty"`
Packages int `json:"packages,omitempty" yaml:"packages,omitempty"`
Skipped int `json:"skipped,omitempty" yaml:"skipped,omitempty"`
Failed int `json:"failed,omitempty" yaml:"failed,omitempty"`
}
Summary contains execution statistics.
type Tombstone ¶
type Tombstone interface {
Resource() Resource
// contains filtered or unexported methods
}
Tombstone is the interface for all compensation state types.
Every provider-specific tombstone (e.g., file.Tombstone) must embed TombstoneBase to satisfy it. The unexported tombstoneBase method seals the interface to types that embed TombstoneBase.
type TombstoneBase ¶
type TombstoneBase struct {
// contains filtered or unexported fields
}
TombstoneBase holds the resource that was affected by a compensable action. ReceiverFactory-specific tombstone types must embed it by value.
The embedded Resource preserves its true identity — its fields are never modified by the recovery system. ReceiverFactory-specific fields on the tombstone (e.g., file.Tombstone.RecoveryID) record where data was temporarily moved during the operation — the recovery location, not the identity.
func NewTombstoneBase ¶
func NewTombstoneBase(resource Resource) TombstoneBase
NewTombstoneBase creates a TombstoneBase anchored to the given resource.
func (TombstoneBase) Resource ¶
func (b TombstoneBase) Resource() Resource
Resource returns the resource affected by the compensable action.
Source Files
¶
- access.go
- action.go
- action_reflect.go
- announce.go
- binding_config.go
- context.go
- convert.go
- fatal.go
- graph.go
- lifetime.go
- nodeid.go
- output.go
- phase.go
- planned_reflect.go
- platform.go
- platform_darwin_panic.go
- platform_helpers.go
- platform_linux.go
- platform_new.go
- platform_windows_panic.go
- provider.go
- receiver.go
- receiver_reflect.go
- recovery.go
- recovery_site.go
- registry.go
- render.go
- resource.go
- resource_catalog.go
- root.go
- starlark_runtime.go
- starvalue_marshal.go
Directories
¶
| Path | Synopsis |
|---|---|
|
provider
|
|
|
appnet
Package appnet provides network actions for the operation graph.
|
Package appnet provides network actions for the operation graph. |
|
archive
Package archive provides archive extraction actions for the operation graph.
|
Package archive provides archive extraction actions for the operation graph. |
|
encryption
Package encryption provides encryption and decryption actions for the operation graph.
|
Package encryption provides encryption and decryption actions for the operation graph. |
|
file/gitignore
Package gitignore provides gitignore-aware file filtering using go-git's gitignore package.
|
Package gitignore provides gitignore-aware file filtering using go-git's gitignore package. |
|
json
Package json provides JSON encoding and decoding for the operation graph.
|
Package json provides JSON encoding and decoding for the operation graph. |
|
pkg
Package pkg provides package management actions for the operation graph.
|
Package pkg provides package management actions for the operation graph. |
|
platform
Package platform provides access to platform information by graph actions and executing receivers.
|
Package platform provides access to platform information by graph actions and executing receivers. |
|
regexp
Package regexp provides regular expression operations for the operation graph.
|
Package regexp provides regular expression operations for the operation graph. |
|
service
Package service provides platform-agnostic service management actions.
|
Package service provides platform-agnostic service management actions. |
|
shell
Package shell provides shell command execution actions for the operation graph.
|
Package shell provides shell command execution actions for the operation graph. |
|
staranalysis
Package staranalysis provides combined analysis of Starlark source files, combining stats, complexity scoring, indexing, and hotspot detection.
|
Package staranalysis provides combined analysis of Starlark source files, combining stats, complexity scoring, indexing, and hotspot detection. |
|
starcode
Package starcode provides Starlark source file capture with glob pattern matching, .gitignore awareness, and optional .bzl file inclusion.
|
Package starcode provides Starlark source file capture with glob pattern matching, .gitignore awareness, and optional .bzl file inclusion. |
|
starcomplexity
Package starcomplexity computes cyclomatic and cognitive complexity metrics for Starlark source files.
|
Package starcomplexity computes cyclomatic and cognitive complexity metrics for Starlark source files. |
|
starindex
Package starindex provides AST-based indexing of Starlark source files, extracting functions, loads, globals, and line statistics.
|
Package starindex provides AST-based indexing of Starlark source files, extracting functions, loads, globals, and line statistics. |
|
starstats
Package starstats computes line and byte statistics for Starlark source files.
|
Package starstats computes line and byte statistics for Starlark source files. |
|
template
Package template provides template expansion actions for the operation graph.
|
Package template provides template expansion actions for the operation graph. |
|
ui
Package ui provides user-facing terminal messaging for the operation graph.
|
Package ui provides user-facing terminal messaging for the operation graph. |
|
yaml
Package yaml provides YAML encoding and decoding for the operation graph.
|
Package yaml provides YAML encoding and decoding for the operation graph. |
|
Package starvalue defines interfaces for custom Starlark value serialization.
|
Package starvalue defines interfaces for custom Starlark value serialization. |