definition

package
v0.1.3 Latest Latest
Warning

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

Go to latest
Published: Aug 30, 2026 License: AGPL-3.0 Imports: 32 Imported by: 0

Documentation

Overview

Package verifier provides the execution machinery for deterministic verifier profiles behind evidence_gate steps. The host ships NO built-in profiles: the catalogue is filled from workspace config ([verifiers] in mivia.toml), so the engine stays project- and language-generic. Workflow files may name a declared profile only; they cannot supply shell or command strings. One exception: an evidence_gate step may declare a sandboxed command (a bare executable name plus argv, never a shell string) that runs inside the same isolation as the declared profiles — a copied worktree without secrets, no network, no host home, and an empty environment.

Package matcher provides closed structural transition matching for workflows. It evaluates attempt status plus exact scalar/enum output fields only. It is not an expression language: no regex, arithmetic, negation, or prose.

Index

Constants

View Source
const (
	PanelFailurePolicyRequireAll   = "require_all"
	PanelFailurePolicyAllowPartial = "allow_partial"
)

Panel failure-policy constants for agent_panel steps.

PanelFailurePolicyRequireAll means any member failure fails the panel attempt.

PanelFailurePolicyAllowPartial means the attempt proceeds to synthesis with the successful members and fails only if ALL members fail.

View Source
const (
	DefaultStackingEnabled             = true
	DefaultStackingMaxChunks           = 12
	DefaultStackingSoftLines           = 200
	DefaultStackingHardLines           = 400
	DefaultStackingMaxFiles            = 5
	DefaultStackingMergePolicy         = "approve"
	DefaultStackingMaxTotalChunks      = 200
	DefaultStackingMaxWaveChunks       = 12
	DefaultStackingMaxConcurrentChunks = 4
	DefaultStackingSplitDeferred       = false
	DefaultStackingSplitMaxChunks      = 4
	DefaultStackingSplitMinLines       = 10
)

Stacking defaults. These are the global defaults every workflow inherits; per-workflow [stacking] values override them.

View Source
const MaxEvidenceBindingBytes = 32 << 10

MaxEvidenceBindingBytes is the maximum bytes of a prior step output bound into a later step context.

View Source
const MaxInputBytes = 1048576

MaxInputBytes is the maximum allowed max_bytes value for a single input definition.

View Source
const MaxSchemaBytes = 65536

MaxSchemaBytes is the maximum allowed size for a single schema file.

View Source
const MaxWorkflowFileBytes = 65536

MaxWorkflowFileBytes is the maximum allowed size for a single workflow TOML file.

View Source
const ProviderGitHub = "github"

ProviderGitHub is the only delivery provider the engine supports. It lives in the schema package, next to the field it constrains, so the compiler (admission) and the delivery package (run probe and delivery-time backstop) share one value instead of drifting literals.

View Source
const UnlimitedIterations = -1

UnlimitedIterations is the sentinel value for MaxIterations indicating no loop bound. Users must explicitly set max_iterations = -1 to opt in; omitting the field (zero) is rejected.

Variables

View Source
var ReservedStepIDs = map[string]bool{
	"success": true,
	"failure": true,
}

ReservedStepIDs are terminal state names that cannot be used as step IDs.

View Source
var ValidStackingMergePolicies = map[string]bool{
	"approve": true,
	"auto":    true,
}

ValidStackingMergePolicies enumerates the allowed merge_policy values.

View Source
var ValidStepKinds = map[string]bool{
	"agent":         true,
	"agent_panel":   true,
	"agent_gate":    true,
	"evidence_gate": true,
	"human_gate":    true,
}

ValidStepKinds enumerates the allowed step kind values.

Functions

func FormatWorkflowExplain

func FormatWorkflowExplain(cw *CompiledWorkflowExplain) string

FormatWorkflowExplain formats a compiled workflow as an explanatory view showing the state graph, loop caps, delivery policy, resolved references, and declared authority. No secret values or transition coverage analysis (deferred to Phase 4 matcher).

func FormatWorkflowList

func FormatWorkflowList(workflows []DiscoveredWorkflow) string

FormatWorkflowList formats a list of discovered workflow names for CLI output.

func FormatWorkflowShow

func FormatWorkflowShow(c *CompiledWorkflow) string

FormatWorkflowShow formats a compiled workflow for detailed CLI display.

func FormatWorkflowValidate

func FormatWorkflowValidate(name string, compiled *CompiledWorkflow, compileErr error) string

FormatWorkflowValidate formats a validation result for a single workflow.

func IsBareProgramName

func IsBareProgramName(program string) bool

IsBareProgramName reports whether program is a safe bare executable name. The generic command verifier and the workflow definition validator share this rule so a TOML-declared command can never name a path or a shell.

func MergeStackingInputs

func MergeStackingInputs(compiled *CompiledWorkflow)

MergeStackingInputs merges the engine-reserved stacking input definitions into a compiled stacking workflow's input contract. Names the workflow already declares are left untouched; a non-stacking workflow (nil Stacking) and a nil compiled workflow are no-ops. The merge is additive and post-compile - it never moves the compile-time digest - and mirrors the reserved set SynthesizeStacking adds to the run graph, so admission and resume validate against the same input contract.

func ParseInputValue

func ParseInputValue(value, typ string) (any, error)

ParseInputValue decodes one workflow input value against the declared type. String inputs pass through verbatim; typed inputs must be single JSON values of the declared type. Both resume surfaces (CLI and local engine) parse admitted input strings through this one function so a typed input resumes with the same Go value on either path.

func SandboxEnabled

func SandboxEnabled() bool

SandboxEnabled reports the current process-wide sandbox toggle.

func SetSandboxEnabled

func SetSandboxEnabled(enabled bool)

SetSandboxEnabled installs the process-wide sandbox toggle, resolved from [harness] sandbox after config load. It is idempotent and safe to call more than once with the same value - newWorkflowController calls it on every controller build within a process, not strictly once at startup - but every call in one process is expected to carry the same resolved config value; it is not a per-run or per-caller override.

func SynthesizedInputs

func SynthesizedInputs(cfg *StackingConfig) map[string]InputDef

SynthesizedInputs returns the reserved stacking inputs admission adds for a stacking run. A missing or disabled config contributes no inputs.

func ValidateAgentReferences

func ValidateAgentReferences(wf *WorkflowFile, workspaceRoot string) []string

ValidateAgentReferences checks that every step with kind "agent" or "agent_gate" references an agent that exists: a file in <workspaceRoot>/.agents/agents/ or a compiled built-in. Returns errors for any referenced agent that is not found.

func ValidateAgentSkillReferences

func ValidateAgentSkillReferences(wf *CompiledWorkflow, agentRegistry *agents.AgentRegistry, skillRegistry *skills.Registry) []string

ValidateAgentSkillReferences checks each selected workflow agent and skill against the resolved agent and skill catalogues. An empty skill is accepted for workflows admitted before explicit skill bindings existed.

func ValidateSchemaReferenceBytes

func ValidateSchemaReferenceBytes(wf *WorkflowFile, schemas map[string][]byte) []string

ValidateSchemaReferenceBytes validates the exact schema bytes selected by a workflow.

func ValidateSchemaReferences

func ValidateSchemaReferences(wf *WorkflowFile, baseDir string) []string

ValidateSchemaReferences checks that every step with a non-empty OutputSchema references a valid JSON Schema file with additionalProperties set to false or a more restrictive schema object. Paths are resolved relative to baseDir.

Types

type AgentPanel

type AgentPanel struct {
	FailurePolicy           string        `toml:"failure_policy" json:"failure_policy,omitempty"`
	RequireDistinctBindings bool          `toml:"require_distinct_bindings" json:"require_distinct_bindings,omitempty"`
	Members                 []PanelMember `toml:"members" json:"members,omitempty"`
}

AgentPanel defines the static members of one agent_panel step.

type Catalogue

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

Catalogue looks up host-owned verifier profiles by name.

func NewCatalogue

func NewCatalogue() *Catalogue

NewCatalogue returns an empty catalogue.

func (*Catalogue) Lookup

func (c *Catalogue) Lookup(name string) (Profile, error)

Lookup returns a registered profile. Unknown names fail closed without dispatching any command.

func (*Catalogue) Names

func (c *Catalogue) Names() []string

Names returns registered profile names in unspecified order.

func (*Catalogue) Register

func (c *Catalogue) Register(p Profile) error

Register adds a profile. Duplicate names fail closed.

type Check

type Check struct {
	Name   string `json:"name"`
	Status string `json:"status"`          // passed | failed | skipped
	Class  string `json:"class,omitempty"` // source | host
	Detail string `json:"detail,omitempty"`
	// Failures is a bounded, language-agnostic list of failing items the gate
	// detected in its output (test names, compile errors, assertion
	// messages). It is complete even when Detail is truncated, so a repair
	// step always learns what must be fixed.
	Failures []string `json:"failures,omitempty"`
}

Check is one named host verification check result.

type CommandProfile

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

CommandProfile runs one sandboxed system command declared by an evidence_gate step. The program is a bare executable name resolved from the trusted system directories; args are argv passed verbatim (never a shell string). The sandbox isolates every run: a copied worktree without secrets, no network, no host home, an empty environment, and a fixed PATH. A workflow file can therefore declare its project's own final gate without widening the host's trust surface.

func (*CommandProfile) Name

func (p *CommandProfile) Name() string

Name identifies the profile in diagnostics and duplicate registration.

func (*CommandProfile) Verify

func (p *CommandProfile) Verify(ctx context.Context, req Request) (Result, error)

Verify runs the declared command in the sandbox and returns schema-valid verification evidence (verification-v1).

type CompiledWorkflow

type CompiledWorkflow struct {
	Name        string
	Description string
	Version     int
	InitialStep string
	Inputs      map[string]InputDef
	Limits      Limits
	Steps       []Step
	Transitions []Transition
	Delivery    *Delivery
	Digest      string

	// Stacking is the resolved stacking configuration when the workflow
	// declares an enabled [stacking] table with explicit plan_step and
	// implement_step keys. Nil otherwise; the run then behaves exactly as a
	// single-PR workflow always did.
	Stacking *StackingConfig

	// Derived sets for O(1) lookups
	StepIDs   map[string]bool
	LoopNames map[string]bool
}

CompiledWorkflow is the immutable result of successful compilation.

func Compile

func Compile(wf *WorkflowFile) (*CompiledWorkflow, error)

Compile validates a workflow definition and returns an immutable compiled workflow. It applies the full admission policy, including the unbounded-cycle check.

func CompileForResume

func CompileForResume(wf *WorkflowFile) (*CompiledWorkflow, error)

CompileForResume compiles a definition that was already admitted in a run snapshot. It skips the unbounded-cycle admission check so an in-flight run admitted under an earlier policy can still resume. All other validators still run, and stacking resolves under the same opt-in rule as admission.

func SynthesizeStacking

func SynthesizeStacking(cw *CompiledWorkflow) (*CompiledWorkflow, error)

SynthesizeStacking returns the run graph for a compiled stacking workflow: the original graph plus the engine-injected decompose and chunk_plan_validate steps, the reserved inputs, and the router edges from the plan step. It never mutates the input; it always returns a copy.

When cw.Stacking is nil, the workflow is not stacked and the input is returned unchanged (the same pointer). The digest is copied unchanged: synthesis is a post-compile admission step and never moves the definition digest.

Synthesis is idempotent: a graph that already carries every engine-reserved stacking artifact (both synthesized steps AND the repair loop) is the run graph itself and is returned unchanged. The runtime build synthesizes once before building step runtimes, and the controller re-synthesizes on direct construction, so both sides must agree on what "already synthesized" means. A workflow that declares only SOME of the reserved identifiers still fails the reserved-identifier check below, exactly as before.

func (*CompiledWorkflow) DeliveryActive

func (c *CompiledWorkflow) DeliveryActive() bool

DeliveryActive reports whether the workflow declares an active pull_request delivery policy: kind "pull_request" with an explicit mode other than "none". Runs with an active policy settle at delivery_pending on their success route instead of moving directly to succeeded.

type CompiledWorkflowExplain

type CompiledWorkflowExplain struct {
	Name                    string
	Description             string
	Version                 int
	Digest                  string
	Steps                   []Step
	Transitions             []Transition
	LoopNames               []string
	Agents                  []string
	References              []string
	InitialStep             string
	Delivery                *Delivery
	MaxStepAttempts         int
	MaxDurationSeconds      int
	MaxOnFailureReentries   int
	MaxTransientStepRetries int
}

CompiledWorkflowExplain holds the data needed for the explain presentation. It avoids exposing the full CompiledWorkflow to the presentation layer.

type ContextBinding

type ContextBinding struct {
	From     string `toml:"from" json:"from,omitempty"`
	As       string `toml:"as" json:"as,omitempty"`
	MaxBytes int    `toml:"max_bytes" json:"max_bytes,omitempty"`
	// Optional is true for a steps.<id>.output binding whose prior output may
	// not exist on the first attempt (for example a reviewer step that has not
	// run yet). When the prior output is absent, the controller resolves the
	// binding to an empty string instead of failing. It has no effect on
	// inputs.<name> bindings, which are always present after admission.
	Optional bool `toml:"optional" json:"optional,omitempty"`
	// EnvelopeOnly is true when the bound prior output must reach the step as a
	// ledger reference envelope (artifact pointer + short note) instead of the
	// full inline payload. The controller resolves envelope-only bindings; a
	// step that needs the full artifact must read it back with workflow_inspect.
	EnvelopeOnly bool `toml:"envelope_only" json:"envelope_only,omitempty"`
}

type Decision

type Decision struct {
	// TransitionIndex is the index of the selected transition in the full
	// workflow transition list (-1 when no single match is selected).
	TransitionIndex int
	ToStepID        string
	Loop            string
	MaxIterations   int
	// PartialTarget is the loop-exhaustion escape declared on the selected
	// transition, forwarded from Transition.
	PartialTarget string
	MatchDigest   string
	// Selected holds the exact status and output field values used for the match.
	Selected map[string]string
	// Outcome is "matched", "zero_match", "multi_match", or "invalid_output".
	Outcome      string
	DecisionJSON []byte
}

Decision is the durable explanation for one selected route.

func Match

func Match(fromStep, status string, output map[string]any, transitions []Transition) (Decision, error)

Match selects exactly one transition for fromStep against status and output. Zero-match and multi-match fail closed. Output leaves must be scalar or enum string values when compared; non-scalar values never match an output key.

type DeclaredCommand

type DeclaredCommand struct {
	Check   string
	Program string
	Args    []string
}

DeclaredCommand is one sandboxed command of a workspace-declared verifier profile. Program is a bare executable name; Args are argv verbatim, never a shell string.

type Delivery

type Delivery struct {
	Kind                  string `toml:"kind" json:"kind,omitempty"`
	Mode                  string `toml:"mode" json:"mode,omitempty"`
	Provider              string `toml:"provider" json:"provider,omitempty"`
	Base                  string `toml:"base" json:"base,omitempty"`
	TitleTemplate         string `toml:"title_template" json:"title_template,omitempty"`
	CommitMessageTemplate string `toml:"commit_message_template" json:"commit_message_template,omitempty"`
	MaxTitleBytes         int    `toml:"max_title_bytes" json:"max_title_bytes,omitempty"`
	MaxCommitMessageBytes int    `toml:"max_commit_message_bytes" json:"max_commit_message_bytes,omitempty"`
	// OnFailure names the step to re-enter when delivery fails for a reason an
	// agent can repair, for example a commit hook that rejects the change.
	//
	// Delivery runs after the success terminal, outside the step graph, so a
	// delivery failure had no route back into the workflow: the run stopped
	// and waited for a person. With this set, the run returns to the named
	// step, the agents fix the cause, the run reaches success again, and
	// delivery runs again.
	//
	// The field names a step, not a reason. Which step repairs which failure
	// is the workflow author's choice, so this stays generic.
	//
	// Empty keeps the old behavior: the run holds for a person.
	OnFailure string `toml:"on_failure" json:"on_failure,omitempty"`
	// PRTitlePolicy is the relative path to the project PR-title policy file.
	// The path is relative to the workflow directory. An empty value selects
	// the default policy at .mivia/policy/pr-title.toml.
	PRTitlePolicy string `toml:"pr_title_policy" json:"pr_title_policy,omitempty"`
	// OnPRMetadataFailure names the step that repairs PR-metadata delivery
	// failures. PR metadata is the pull-request title and summary. An empty
	// value makes the run use OnFailure for PR-metadata failures.
	OnPRMetadataFailure string `toml:"on_pr_metadata_failure" json:"on_pr_metadata_failure,omitempty"`
	// OnDiffSizeFailure names the step that repairs an over-limit delivered
	// diff (a stacking hard_lines rejection). An empty value makes the run use
	// OnFailure for diff-size failures, which keeps pre-existing stacking
	// workflows on their declared generic repair step.
	OnDiffSizeFailure string `toml:"on_diff_size_failure" json:"on_diff_size_failure,omitempty"`
	// MaxRepairs bounds the delivery -> repair -> success -> delivery cycle:
	// how many times a delivery failure may route back into the workflow's
	// repair step before the run settles terminal (delivery_failed) with the
	// last rejection recorded. A rejection the named repair step cannot fix
	// must not cycle until the step cap or the run deadline is spent. Zero
	// selects the delivery package default (delivery.MaxDeliveryRepairs).
	// Negative values are rejected at admission.
	MaxRepairs int `toml:"max_repairs" json:"max_repairs,omitempty"`
	// DeliverPlanRun publishes a stacking plan-mode run's own diff as its own
	// PR after the stack drive. A plan run with a multi-chunk plan settles at
	// delivery_pending (its success terminal is delivery-policy active) and the
	// chunk stack is driven to completion; the chunk PRs carry the work. When
	// false (the default) the plan run is NOT published - the plan and its
	// artifacts stay recorded in the run ledger and the stack task ledger, and
	// the run settles succeeded. Set true to also publish the plan run's PR.
	DeliverPlanRun bool `toml:"deliver_plan_run" json:"deliver_plan_run,omitempty"`
}

type DiscoveredWorkflow

type DiscoveredWorkflow struct {
	Name string
	Path string
	Raw  []byte
}

DiscoveredWorkflow is the result of discovering a workflow file.

func DiscoverWorkflows

func DiscoverWorkflows(workspaceRoot string) ([]DiscoveredWorkflow, error)

DiscoverWorkflows finds all .toml workflow definitions beneath <workspaceRoot>/.mivia/workflows/ using safe file discovery (symlink rejection, files read through a pinned root). Returns an empty slice (not an error) when the workflows directory does not exist.

type GoModuleBaseline

type GoModuleBaseline struct {
	GoMod []byte
	GoSum []byte
}

GoModuleBaseline pins module files before a workflow agent can edit them.

func CaptureGoModuleBaseline

func CaptureGoModuleBaseline(workRoot string) (*GoModuleBaseline, error)

CaptureGoModuleBaseline reads the module inputs before workflow execution.

type InputDef

type InputDef struct {
	Type     string `toml:"type" json:"type,omitempty"`
	Required bool   `toml:"required" json:"required,omitempty"`
	MaxBytes int    `toml:"max_bytes" json:"max_bytes,omitempty"`
}

type Limits

type Limits struct {
	MaxStepAttempts    int `toml:"max_step_attempts" json:"max_step_attempts,omitempty"`
	MaxDurationSeconds int `toml:"max_duration_seconds" json:"max_duration_seconds,omitempty"`
	// MaxOnFailureReentries bounds how many times ONE step may re-enter its
	// declared non-terminal on_failure (repair) target after genuine
	// failures: agent steps, agent_panel steps, and evidence_gate host
	// failures all spend this budget, counted per step. 0 means the
	// controller default (3); negative values are rejected by the compiler.
	// The budget is a safety net, not a tuning dial: the compiler accepts
	// on_failure cycles, so without it a workflow whose author declared a
	// repair cycle would spin to the run deadline.
	MaxOnFailureReentries int `toml:"max_on_failure_reentries" json:"max_on_failure_reentries,omitempty"`
	// MaxTransientStepRetries bounds step-level retries of transient
	// LLM-provider failures (overload, rate limit, upstream 5xx) within one
	// attempt, each retry re-running the whole step with a fresh task
	// identity. 0 means the controller default (3); negative values are
	// rejected by the compiler.
	MaxTransientStepRetries int `toml:"max_transient_step_retries" json:"max_transient_step_retries,omitempty"`
}

func (Limits) IsEmpty

func (l Limits) IsEmpty() bool

IsEmpty reports true when both MaxStepAttempts and MaxDurationSeconds are zero, which is the state when the [limits] TOML section is omitted.

type MatchCriteria

type MatchCriteria struct {
	Status string            `toml:"status" json:"status,omitempty"`
	Output map[string]string `toml:"output" json:"output,omitempty"`
}

type PanelMember

type PanelMember struct {
	ID           string `toml:"id" json:"id,omitempty"`
	Agent        string `toml:"agent" json:"agent,omitempty"`
	Provider     string `toml:"provider" json:"provider,omitempty"`
	Model        string `toml:"model" json:"model,omitempty"`
	Skill        string `toml:"skill" json:"skill,omitempty"`
	Template     string `toml:"template" json:"template,omitempty"`
	OutputSchema string `toml:"output_schema" json:"output_schema,omitempty"`
}

PanelMember defines one statically bound agent in an agent_panel step.

type Profile

type Profile interface {
	Name() string
	Verify(ctx context.Context, req Request) (Result, error)
}

Profile is one registered host verifier implementation.

func NewCommandProfile

func NewCommandProfile(check, program string, args []string, policy ...secretpath.Policy) (Profile, error)

NewCommandProfile creates a generic command verifier profile. policy is optional; when present it excludes matching secret-like files from the sandboxed worktree copy.

func NewDeclaredProfile

func NewDeclaredProfile(name string, commands []DeclaredCommand, policy ...secretpath.Policy) (Profile, error)

NewDeclaredProfile creates a verifier profile from workspace-declared commands. Each program must be a bare executable name; each check name must be non-empty. policy is optional; when present it excludes matching secret-like files from the sandboxed worktree copy.

type Request

type Request struct {
	// WorkDir is the workspace directory for host checks. Empty means cwd.
	WorkDir string
	// StepID is the evidence_gate step identity (for diagnostics only).
	StepID string
	// RunID is the workflow run identity (for diagnostics only).
	RunID string
	// ModuleBaseline pins Go module inputs from workflow admission.
	ModuleBaseline *GoModuleBaseline
}

Request is the fixed host context for one verifier invocation.

type Result

type Result struct {
	Status string  `json:"status"` // passed | failed
	Checks []Check `json:"checks"`
}

Result is schema-shaped verification evidence (verification-v1).

func (Result) Repairable

func (r Result) Repairable() bool

Repairable reports whether all failed checks come from the delivered source.

type Stacking

type Stacking struct {
	// Enabled selects stacking for a workflow that declares this table. nil
	// means enabled (DefaultStackingEnabled); false is a deliberate opt-out.
	Enabled *bool `toml:"enabled" json:"enabled,omitempty"`
	// PlanStep is the id of the workflow's planning step (whose output feeds
	// the decompose step). Required when stacking is enabled.
	PlanStep string `toml:"plan_step" json:"plan_step,omitempty"`
	// ImplementStep is the id where chunk-mode runs start. Required when
	// stacking is enabled.
	ImplementStep string `toml:"implement_step" json:"implement_step,omitempty"`
	// MaxChunks bounds the number of chunks in one plan (0 = global default).
	MaxChunks int `toml:"max_chunks" json:"max_chunks,omitempty"`
	// SoftLines is the preferred per-chunk diff size (0 = global default).
	SoftLines int `toml:"soft_lines" json:"soft_lines,omitempty"`
	// HardLines is the maximum per-chunk diff size; delivery rejects larger
	// actual diffs (0 = global default).
	HardLines int `toml:"hard_lines" json:"hard_lines,omitempty"`
	// MaxFiles bounds the files per chunk (0 = global default).
	MaxFiles int `toml:"max_files" json:"max_files,omitempty"`
	// MergePolicy selects how merged PRs are approved: "approve" (human
	// approves each PR; the default) or "auto" (auto-merge on green with the
	// publish grant as the single human checkpoint).
	MergePolicy string `toml:"merge_policy" json:"merge_policy,omitempty"`
	// Agent names the agent used for the engine-synthesized decompose and
	// chunk-plan-validate steps. Empty selects the plan step's agent, which
	// always exists in the workflow, so agent references stay resolvable in
	// any workspace.
	Agent string `toml:"agent" json:"agent,omitempty"`
	// MaxTotalChunks bounds the number of chunks across all decompose waves
	// of one plan (0 = global default). It is the real ceiling on plan size;
	// MaxWaveChunks bounds only a single decompose call.
	MaxTotalChunks int `toml:"max_total_chunks" json:"max_total_chunks,omitempty"`
	// MaxWaveChunks bounds the number of chunks a single decompose call may
	// emit (0 = global default). Keeps one LLM call reliable; total plan size
	// is bounded by MaxTotalChunks instead.
	MaxWaveChunks int `toml:"max_wave_chunks" json:"max_wave_chunks,omitempty"`
	// MaxConcurrentChunks bounds how many chunk runs the stack driver admits
	// and drives concurrently within one ready wave (0 = global default).
	MaxConcurrentChunks int `toml:"max_concurrent_chunks" json:"max_concurrent_chunks,omitempty"`
	// SplitDeferred enables follow-up PR creation from a repair-produced
	// commit stack (spec-auto-split-oversized-prs.md §5.2-5.3): when a
	// chunk's delivered diff was still oversized despite a good estimate,
	// the diff-size repair step commits the review-sized slice plus one or
	// more additional commits for the deferred scope, and the driver admits
	// those trailing commits as follow-up chunk runs stacked on the first.
	// Opt-in (default false): shipped workflows must enable it explicitly.
	SplitDeferred *bool `toml:"split_deferred" json:"split_deferred,omitempty"`
	// SplitMaxChunks bounds how many follow-up PRs one oversized chunk's
	// repair may produce (0 = global default). Caps stack length; a repair
	// that produces more trailing commits than this allows folds the excess
	// into the last admitted follow-up chunk, logged, never silently dropped.
	SplitMaxChunks int `toml:"split_max_chunks" json:"split_max_chunks,omitempty"`
	// SplitMinLines: a trailing commit at or under this size folds into the
	// previous follow-up chunk instead of becoming its own PR (0 = global
	// default). Avoids a flood of trivial single-line follow-up PRs.
	SplitMinLines int `toml:"split_min_lines" json:"split_min_lines,omitempty"`
}

Stacking enables the generic stacked-small-PR capability for a workflow. A plan-mode run (no stack_mode input) executes the workflow's own planning steps plus an engine-synthesized decompose step and ends with a chunk plan; chunk-mode runs (stack_mode="chunk") start at implement_step and deliver one small PR each; a driver merges the stack incrementally.

Stacking is opt-in: a workflow participates only when it declares a [stacking] table. A declared table is enabled unless it sets enabled = false, and must name plan_step and implement_step explicitly. Every knob is a per-workflow override of a global default.

func (*Stacking) EffectiveStacking

func (s *Stacking) EffectiveStacking(planStep, implementStep string) StackingConfig

EffectiveStacking resolves the stacking configuration for a workflow. planStep and implementStep are the workflow's explicit [stacking] step ids, passed through by the compiler.

func (*Stacking) SplitDeferredEnabled

func (s *Stacking) SplitDeferredEnabled() bool

SplitDeferredEnabled reports whether the repair-produced commit-stack correction path (§5.2-5.3) is enabled for the workflow. An explicit per-workflow value wins; otherwise the global default (off - opt-in).

func (*Stacking) StackingEnabled

func (s *Stacking) StackingEnabled() bool

StackingEnabled reports whether stacking applies to the workflow. Stacking is opt-in: a workflow without a [stacking] table does not participate. A declared table is enabled unless it sets enabled = false.

type StackingConfig

type StackingConfig struct {
	Enabled             bool
	PlanStep            string
	ImplementStep       string
	MaxChunks           int
	SoftLines           int
	HardLines           int
	MaxFiles            int
	MergePolicy         string
	Agent               string
	MaxTotalChunks      int
	MaxWaveChunks       int
	MaxConcurrentChunks int
	SplitDeferred       bool
	SplitMaxChunks      int
	SplitMinLines       int
}

StackingConfig is the resolved stacking configuration: per-workflow values with global defaults filled in for everything unset. PlanStep and ImplementStep are resolved by the compiler (inference needs the step graph) and passed in.

type Step

type Step struct {
	ID    string `toml:"id" json:"id,omitempty"`
	Kind  string `toml:"kind" json:"kind,omitempty"`
	Agent string `toml:"agent" json:"agent,omitempty"`
	// Skill binds an agent step to one named, policy-checked skill.
	// An empty value preserves compatibility with workflows admitted before
	// explicit workflow skill binding.
	Skill        string           `toml:"skill" json:"skill,omitempty"`
	Verifier     string           `toml:"verifier" json:"verifier,omitempty"`
	Command      *StepCommand     `toml:"command" json:"command,omitempty"`
	Template     string           `toml:"template" json:"template,omitempty"`
	OutputSchema string           `toml:"output_schema" json:"output_schema,omitempty"`
	Context      []ContextBinding `toml:"context" json:"context,omitempty"`
	OnFailure    string           `toml:"on_failure" json:"on_failure,omitempty"`
	Panel        *AgentPanel      `toml:"panel" json:"panel,omitempty"`
	// MaxTurns bounds the agent-loop turns each child agent of this step may
	// take. For an agent_panel step it bounds every panel member and the panel
	// synthesis child; for agent and agent_gate steps it bounds the step's own
	// agent loop. 0 means unlimited (the default), matching the agent loop's
	// MaxSteps=0 semantics and the [chat] max_steps config. Negative values
	// are rejected by the compiler.
	MaxTurns int `toml:"max_turns" json:"max_turns,omitempty"`
}

type StepCommand

type StepCommand struct {
	Check   string   `toml:"check" json:"check,omitempty"`
	Program string   `toml:"program" json:"program,omitempty"`
	Args    []string `toml:"args" json:"args,omitempty"`
}

StepCommand declares one sandboxed command for an evidence_gate step that has no named verifier profile. Program must be a bare executable name resolved from the trusted system directories; Args are argv passed verbatim to the program, never a shell string.

type StepDefaults

type StepDefaults struct {
	Kind         string           `toml:"kind" json:"-"`
	Agent        string           `toml:"agent" json:"-"`
	Skill        string           `toml:"skill" json:"-"`
	Template     string           `toml:"template" json:"-"`
	OutputSchema string           `toml:"output_schema" json:"-"`
	OnFailure    string           `toml:"on_failure" json:"-"`
	MaxTurns     int              `toml:"max_turns" json:"-"`
	Context      []ContextBinding `toml:"context" json:"-"`
}

StepDefaults holds shared step field values applied at decode time to every step whose resolved kind is "agent" or "agent_panel" and whose own field is empty (for agent_panel this fills only the step's top-level synthesis fields, never per-member PanelMember entries). Only Kind is considered for the other kinds (agent_gate, evidence_gate, human_gate). See applyStepDefaults.

type Transition

type Transition struct {
	From          string        `toml:"from" json:"from,omitempty"`
	To            string        `toml:"to" json:"to,omitempty"`
	Match         MatchCriteria `toml:"match" json:"match,omitempty"`
	Loop          string        `toml:"loop" json:"loop,omitempty"`
	MaxIterations int           `toml:"max_iterations" json:"max_iterations,omitempty"`
	// PartialTarget is the step a loop routes to when its budget exhausts and
	// the ledger still holds verified (succeeded) step outputs. Without it, an
	// exhausted loop fails the run (with a salvage hint). With it, the verified
	// work survives: the run advances to the target with run.salvage bound as
	// evidence. The target must be a declared step; it usually forwards to
	// success or delivery.
	PartialTarget string `toml:"partial_target" json:"partial_target,omitempty"`
}

type WorkflowFile

type WorkflowFile struct {
	Version     int                 `toml:"version" json:"version,omitempty"`
	Name        string              `toml:"name" json:"name,omitempty"`
	Description string              `toml:"description" json:"description,omitempty"`
	InitialStep string              `toml:"initial_step" json:"initial_step,omitempty"`
	Inputs      map[string]InputDef `toml:"inputs" json:"inputs,omitempty"`
	Limits      Limits              `toml:"limits" json:"limits,omitempty"`
	Steps       []Step              `toml:"steps" json:"steps,omitempty"`
	Transitions []Transition        `toml:"transitions" json:"transitions,omitempty"`
	Delivery    *Delivery           `toml:"delivery" json:"delivery,omitempty"`
	Stacking    *Stacking           `toml:"stacking" json:"stacking,omitempty"`
	// StepDefaults is decode-time sugar: ParseWorkflowTOML copies each
	// non-empty field into every agent/agent_panel step whose own field is
	// empty, then clears this to nil. It never reaches the compiler or the
	// digest - the json:"-" tag keeps a sugared file and its hand-expanded
	// twin byte-identical after json.Marshal, so they compile to the same
	// digest.
	StepDefaults *StepDefaults `toml:"step_defaults" json:"-"`
}

WorkflowFile is the on-disk TOML shape for a workflow definition.

func ParseWorkflowTOML

func ParseWorkflowTOML(data []byte, filename string) (WorkflowFile, string, error)

ParseWorkflowTOML parses a single workflow definition body with unknown-key rejection. filename is the base name (e.g. "feature-delivery.toml").

Jump to

Keyboard shortcuts

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