graph

package
v1.0.5 Latest Latest
Warning

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

Go to latest
Published: Aug 22, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package graph is Fort's deterministic DAG engine (backlog AO-021..025).

A Flow is nodes + conditional edges. Node types: task, gate, check, transform, fanout, fanin. Only task nodes invoke the Runtime (inference); every other node type is deterministic. Flows are resumable: node state is persisted to the store and a paused gate continues after a process restart.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type CheckSpec

type CheckSpec struct {
	// Command is run; exit 0 => pass, non-zero => fail.
	Command []string `yaml:"command" json:"command"`
	// FileExists passes when the named path exists.
	FileExists string `yaml:"file_exists" json:"file_exists"`
}

CheckSpec is a deterministic predicate (AO-022).

type ContextMode added in v0.12.0

type ContextMode string

ContextMode controls how a task prompt is assembled. The zero value keeps the original graph behavior. ContextPlaybook adds the reusable-pipeline context contract without changing ordinary flows.

const (
	ContextDefault  ContextMode = ""
	ContextPlaybook ContextMode = "playbook"
)

type Edge

type Edge struct {
	On Outcome `yaml:"on" json:"on"`
	To string  `yaml:"to" json:"to"`
}

Edge is a conditional transition: take To when the source node's outcome is On.

type Executor

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

Executor runs flows deterministically. Only task nodes invoke the Runtime.

func NewExecutor

func NewExecutor(rt runtime.Runtime, st *store.Store) *Executor

NewExecutor builds an executor.

func (*Executor) Approve

func (e *Executor) Approve(runID, nodeID, edited string) error

Approve records an approve decision on a waiting gate, optionally editing the payload that flows downstream.

func (*Executor) RecoverInterrupted added in v1.0.4

func (e *Executor) RecoverInterrupted(ctx context.Context, f Flow, runID string) (Result, error)

RecoverInterrupted resumes a running flow only while startup owns exclusive execution. It is deliberately separate from Resume: running -> running is not an atomic claim and must never be exposed to ordinary gate actions.

func (*Executor) Reject

func (e *Executor) Reject(runID, nodeID, note string) error

Reject records a reject decision on a waiting gate. The note is the human's redirect note ("" = none); it is recorded in the event log, not the payload.

func (*Executor) Resume

func (e *Executor) Resume(ctx context.Context, f Flow, runID string) (Result, error)

Resume continues a paused flow. It re-walks from the start, replaying already-completed nodes from persisted state (no re-execution) until it reaches the (now-decided) gate or a still-undecided one.

func (*Executor) ResumeAsync added in v0.13.0

func (e *Executor) ResumeAsync(ctx context.Context, f Flow, runID string) error

ResumeAsync validates the durable run before returning, then resumes it once on a detached context. Background errors are written to the existing run.

func (*Executor) Start

func (e *Executor) Start(ctx context.Context, f Flow, runID, payload string) (Result, error)

Start runs a flow from its start node with an initial payload.

func (*Executor) StartAsync added in v0.13.0

func (e *Executor) StartAsync(ctx context.Context, f Flow, runID, payload string) (Result, error)

StartAsync durably creates the flow run, then walks it exactly once on a detached context. It returns only after the run identity is queryable.

func (*Executor) UsePlacer added in v0.12.0

func (e *Executor) UsePlacer(p Placer)

UsePlacer enables deterministic placement for Playbook-context task nodes. Ordinary graph flows intentionally stay local (spec 022); a nil placer keeps the original single-machine behavior.

func (*Executor) Wait added in v0.13.0

func (e *Executor) Wait()

Wait joins every asynchronous walk accepted before the call. Callers use it during shutdown and tests before closing the store that those walks persist to.

type Flow

type Flow struct {
	ID    string `yaml:"id" json:"id"`
	Name  string `yaml:"name" json:"name"`
	Start string `yaml:"start" json:"start"`
	Nodes []Node `yaml:"nodes" json:"nodes"`
}

Flow is a named DAG.

func (Flow) Validate added in v1.0.4

func (f Flow) Validate() error

Validate checks the deterministic graph shape before execution mutates a run.

type Node

type Node struct {
	ID        string         `yaml:"id" json:"id"`
	Type      NodeType       `yaml:"type" json:"type"`
	Profile   string         `yaml:"profile,omitempty" json:"profile,omitempty"`     // task
	Agent     string         `yaml:"agent,omitempty" json:"agent,omitempty"`         // task
	Model     string         `yaml:"model,omitempty" json:"model,omitempty"`         // task
	Prompt    string         `yaml:"prompt,omitempty" json:"prompt,omitempty"`       // task
	Context   ContextMode    `yaml:"context,omitempty" json:"context,omitempty"`     // task
	Memory    bool           `yaml:"memory,omitempty" json:"memory,omitempty"`       // task
	Retry     *Retry         `yaml:"retry,omitempty" json:"retry,omitempty"`         // task
	Check     *CheckSpec     `yaml:"check,omitempty" json:"check,omitempty"`         // check
	Transform *TransformSpec `yaml:"transform,omitempty" json:"transform,omitempty"` // transform
	FaninID   string         `yaml:"fanin,omitempty" json:"fanin,omitempty"`         // fanout -> join node
	Edges     []Edge         `yaml:"edges,omitempty" json:"edges,omitempty"`
}

Node is one DAG node.

type NodeType

type NodeType string

NodeType enumerates the node kinds.

const (
	Task      NodeType = "task"      // invokes the Runtime (the only inference point)
	Gate      NodeType = "gate"      // halts for human approve/edit/reject
	Check     NodeType = "check"     // deterministic predicate -> pass/fail
	Transform NodeType = "transform" // deterministic data step, records hash
	Fanout    NodeType = "fanout"    // splits into parallel branches
	Fanin     NodeType = "fanin"     // joins branches
)

type Outcome

type Outcome string

Outcome is the result label a node produces; edges match on it.

const (
	OutSuccess Outcome = "success"
	OutFail    Outcome = "fail"
	OutPass    Outcome = "pass"
	OutApprove Outcome = "approve"
	OutReject  Outcome = "reject"
	OutAlways  Outcome = "always"
)

type Placer added in v0.12.0

type Placer interface {
	Place(agent, pin string) (machine string, err error)
}

Placer chooses the machine that will run a Playbook task stage (spec 038). Like routing, placement is deterministic and must not invoke a model.

type Result

type Result struct {
	State      string // accepted | completed | failed | paused
	PausedNode string // gate id when paused
}

Result is the outcome of a Start/Resume call.

type Retry

type Retry struct {
	Max int `yaml:"max" json:"max"` // additional attempts after the first
}

Retry configures per-task retry (AO-025).

type TransformSpec

type TransformSpec struct {
	Op  string `yaml:"op" json:"op"`
	Arg string `yaml:"arg" json:"arg"`
}

TransformSpec is a deterministic data step (AO-024). Ops: identity, upper, lower, prefix (Arg prepended), suffix (Arg appended).

Jump to

Keyboard shortcuts

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