runledger

package
v0.7.0 Latest Latest
Warning

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

Go to latest
Published: Apr 13, 2026 License: MIT Imports: 27 Imported by: 0

Documentation

Index

Constants

View Source
const DefaultMaxRetries = 2

DefaultMaxRetries is the default number of retries before escalation.

View Source
const SystemCallerName = "system"

SystemCallerName is the explicit identity for trusted internal callers.

Variables

View Source
var (
	ErrRunNotFound  = errors.New("run not found")
	ErrRunNotPaused = errors.New("run is not paused")
	ErrStepNotFound = errors.New("step not found")
	ErrAccessDenied = errors.New("access denied")
	ErrRunCompleted = errors.New("run already completed")
)

Sentinel errors for the RunLedger package.

View Source
var (
	// ErrInvalidPlanJSON is returned when the planner output is not valid JSON.
	ErrInvalidPlanJSON = fmt.Errorf("invalid plan JSON")
	// ErrPlanValidation is returned when the plan fails schema validation.
	ErrPlanValidation = fmt.Errorf("plan validation failed")
)

Functions

func ApplyTail

func ApplyTail(snap *RunSnapshot, events []JournalEvent) error

ApplyTail applies only events after the snapshot's LastJournalSeq.

func BuildTools

func BuildTools(store RunLedgerStore, pev *PEVEngine) []*agent.Tool

BuildTools creates all run_* tools with access control.

func ConvertPlanToRunData

func ConvertPlanToRunData(plan *PlannerOutput) ([]Step, []AcceptanceCriterion)

ConvertPlanToRunData converts a validated PlannerOutput into Steps and AcceptanceCriteria suitable for journal storage.

func DefaultValidators

func DefaultValidators() map[ValidatorType]Validator

DefaultValidators returns the standard validator set.

func DetectResumeIntent

func DetectResumeIntent(message string) bool

DetectResumeIntent checks if the user's message contains resume keywords.

func NeedsIsolation

func NeedsIsolation(step *Step) bool

NeedsIsolation returns true if the step requires workspace isolation based on its validator type.

func ReplayWorkflowProjection

func ReplayWorkflowProjection(
	ctx context.Context,
	ledger RunLedgerStore,
	projection WorkflowProjectionStore,
	runID string,
	wf *workflow.Workflow,
) error

ReplayWorkflowProjection rebuilds the workflow projection from the RunLedger snapshot.

func ToolProfileGuard

func ToolProfileGuard(store RunLedgerStore) toolchain.Middleware

ToolProfileGuard returns a middleware that narrows execution tools according to the active step's ToolProfile for workflow/background sessions.

func ValidatePlanSchema

func ValidatePlanSchema(plan *PlannerOutput, validAgents []string) error

ValidatePlanSchema checks the parsed plan against structural and semantic rules.

func WithSnapshotCache

func WithSnapshotCache(ctx context.Context) context.Context

WithSnapshotCache seeds a per-turn snapshot cache into the context.

Types

type AcceptanceCriteriaInput

type AcceptanceCriteriaInput struct {
	Description string        `json:"description"`
	Validator   ValidatorSpec `json:"validator"`
}

AcceptanceCriteriaInput is the planner's acceptance criterion format.

type AcceptanceCriterion

type AcceptanceCriterion struct {
	Description string        `json:"description"`
	Validator   ValidatorSpec `json:"validator"`
	Met         bool          `json:"met"`
	MetAt       *time.Time    `json:"met_at,omitempty"`
}

AcceptanceCriterion describes a requirement for Run completion.

type AppendHookSetter

type AppendHookSetter interface {
	SetAppendHook(func(JournalEvent))
}

AppendHookSetter is implemented by concrete store types that support post-construction hook registration. Not part of RunLedgerStore.

type ArtifactExistsValidator

type ArtifactExistsValidator struct{}

ArtifactExistsValidator verifies that a file exists at the target path.

func (*ArtifactExistsValidator) Validate

type BackgroundWriteThrough

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

BackgroundWriteThrough creates canonical task IDs in RunLedger and mirrors background task lifecycle transitions into the ledger.

func NewBackgroundWriteThrough

func NewBackgroundWriteThrough(ledger RunLedgerStore, cfg RolloutConfig) *BackgroundWriteThrough

NewBackgroundWriteThrough creates a background projection adapter backed by RunLedger.

func (*BackgroundWriteThrough) PrepareTask

func (b *BackgroundWriteThrough) PrepareTask(
	ctx context.Context,
	prompt string,
	origin background.Origin,
) (string, error)

func (*BackgroundWriteThrough) SyncTask

func (*BackgroundWriteThrough) WithMaxHistory

func (b *BackgroundWriteThrough) WithMaxHistory(maxKeep int) *BackgroundWriteThrough

WithMaxHistory configures pruning of old terminal runs after completion.

type BuildPassValidator

type BuildPassValidator struct{}

BuildPassValidator verifies that `go build <target>` succeeds.

func (*BuildPassValidator) Validate

type CommandPassValidator

type CommandPassValidator struct{}

CommandPassValidator runs an arbitrary command and checks the exit code.

func (*CommandPassValidator) Validate

type CriterionMetPayload

type CriterionMetPayload struct {
	Index       int    `json:"index"`
	Description string `json:"description"`
}

CriterionMetPayload is the payload for EventCriterionMet.

type EntStore

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

EntStore persists RunLedger journal events and cached projections in Ent.

func NewEntStore

func NewEntStore(client *ent.Client, opts ...StoreOption) *EntStore

NewEntStore creates a new Ent-backed RunLedger store.

func (*EntStore) AppendJournalEvent

func (s *EntStore) AppendJournalEvent(ctx context.Context, event JournalEvent) error

func (*EntStore) GetCachedSnapshot

func (s *EntStore) GetCachedSnapshot(ctx context.Context, runID string) (*RunSnapshot, int64, error)

func (*EntStore) GetJournalEvents

func (s *EntStore) GetJournalEvents(ctx context.Context, runID string) ([]JournalEvent, error)

func (*EntStore) GetJournalEventsSince

func (s *EntStore) GetJournalEventsSince(ctx context.Context, runID string, afterSeq int64) ([]JournalEvent, error)

func (*EntStore) GetRunSnapshot

func (s *EntStore) GetRunSnapshot(ctx context.Context, runID string) (*RunSnapshot, error)

func (*EntStore) ListRunSummariesBySession

func (s *EntStore) ListRunSummariesBySession(ctx context.Context, sessionKey string, limit int) ([]RunSummary, error)

func (*EntStore) ListRuns

func (s *EntStore) ListRuns(ctx context.Context, limit int) ([]RunSummary, error)

func (*EntStore) MaterializeRunSnapshot

func (s *EntStore) MaterializeRunSnapshot(ctx context.Context, runID string) (*RunSnapshot, error)

func (*EntStore) MaxJournalSeqForSession

func (s *EntStore) MaxJournalSeqForSession(ctx context.Context, sessionKey string) (int64, error)

func (*EntStore) PruneOldRuns

func (s *EntStore) PruneOldRuns(ctx context.Context, maxKeep int) error

func (*EntStore) RecordValidationResult

func (s *EntStore) RecordValidationResult(ctx context.Context, runID, stepID string, result ValidationResult) error

func (*EntStore) SetAppendHook

func (s *EntStore) SetAppendHook(h func(JournalEvent))

SetAppendHook adds an append hook, chaining with any existing hook. Must be called before concurrent AppendJournalEvent calls (e.g., during app boot).

func (*EntStore) UpdateCachedSnapshot

func (s *EntStore) UpdateCachedSnapshot(ctx context.Context, snapshot *RunSnapshot) error

type Evidence

type Evidence struct {
	Type    string `json:"type"`
	Content string `json:"content"`
}

Evidence is a piece of proof attached to a step result proposal.

type FileChangedValidator

type FileChangedValidator struct{}

FileChangedValidator verifies that files matching target pattern appear in git diff.

func (*FileChangedValidator) Validate

type JournalEvent

type JournalEvent struct {
	ID        string           `json:"id"`
	RunID     string           `json:"run_id"`
	Seq       int64            `json:"seq"`
	Type      JournalEventType `json:"type"`
	Timestamp time.Time        `json:"timestamp"`
	Payload   json.RawMessage  `json:"payload"`
}

JournalEvent is a single append-only record in the RunLedger journal. The journal is the sole source of truth — all other state is derived from it.

type JournalEventType

type JournalEventType string

JournalEventType identifies the kind of journal event.

const (
	EventRunCreated            JournalEventType = "run_created"
	EventPlanAttached          JournalEventType = "plan_attached"
	EventStepStarted           JournalEventType = "step_started"
	EventStepResultProposed    JournalEventType = "step_result_proposed"
	EventStepValidationPassed  JournalEventType = "step_validation_passed"
	EventStepValidationFailed  JournalEventType = "step_validation_failed"
	EventPolicyDecisionApplied JournalEventType = "policy_decision_applied"
	EventNoteWritten           JournalEventType = "note_written"
	EventRunPaused             JournalEventType = "run_paused"
	EventRunResumed            JournalEventType = "run_resumed"
	EventRunCompleted          JournalEventType = "run_completed"
	EventRunFailed             JournalEventType = "run_failed"
	EventProjectionSynced      JournalEventType = "projection_synced"
	EventCriterionMet          JournalEventType = "criterion_met"
)

type MemoryStore

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

MemoryStore is an in-memory implementation of RunLedgerStore for testing and for the initial shadow phase.

func NewMemoryStore

func NewMemoryStore(opts ...StoreOption) *MemoryStore

NewMemoryStore creates a new in-memory RunLedgerStore.

func (*MemoryStore) AppendJournalEvent

func (m *MemoryStore) AppendJournalEvent(_ context.Context, event JournalEvent) error

func (*MemoryStore) GetCachedSnapshot

func (m *MemoryStore) GetCachedSnapshot(_ context.Context, runID string) (*RunSnapshot, int64, error)

func (*MemoryStore) GetJournalEvents

func (m *MemoryStore) GetJournalEvents(_ context.Context, runID string) ([]JournalEvent, error)

func (*MemoryStore) GetJournalEventsSince

func (m *MemoryStore) GetJournalEventsSince(_ context.Context, runID string, afterSeq int64) ([]JournalEvent, error)

func (*MemoryStore) GetRunSnapshot

func (m *MemoryStore) GetRunSnapshot(ctx context.Context, runID string) (*RunSnapshot, error)

func (*MemoryStore) ListRunSummariesBySession

func (m *MemoryStore) ListRunSummariesBySession(ctx context.Context, sessionKey string, limit int) ([]RunSummary, error)

func (*MemoryStore) ListRuns

func (m *MemoryStore) ListRuns(_ context.Context, limit int) ([]RunSummary, error)

func (*MemoryStore) MaterializeRunSnapshot

func (m *MemoryStore) MaterializeRunSnapshot(ctx context.Context, runID string) (*RunSnapshot, error)

func (*MemoryStore) MaxJournalSeqForSession

func (m *MemoryStore) MaxJournalSeqForSession(_ context.Context, sessionKey string) (int64, error)

func (*MemoryStore) PruneOldRuns

func (m *MemoryStore) PruneOldRuns(_ context.Context, maxKeep int) error

func (*MemoryStore) RecordValidationResult

func (m *MemoryStore) RecordValidationResult(ctx context.Context, runID, stepID string, result ValidationResult) error

func (*MemoryStore) SetAppendHook

func (m *MemoryStore) SetAppendHook(h func(JournalEvent))

SetAppendHook adds an append hook, chaining with any existing hook. Must be called before concurrent AppendJournalEvent calls (e.g., during app boot).

func (*MemoryStore) UpdateCachedSnapshot

func (m *MemoryStore) UpdateCachedSnapshot(_ context.Context, snapshot *RunSnapshot) error

type NoteWrittenPayload

type NoteWrittenPayload struct {
	Key   string `json:"key"`
	Value string `json:"value"`
}

NoteWrittenPayload is the payload for EventNoteWritten.

type OrchestratorApprovalValidator

type OrchestratorApprovalValidator struct{}

OrchestratorApprovalValidator never auto-passes. It returns a failed result that triggers a PolicyRequest, which the orchestrator must explicitly approve via run_approve_step.

func (*OrchestratorApprovalValidator) Validate

type PEVEngine

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

PEVEngine is the Propose-Evidence-Verify engine. It runs typed validators against step results and records outcomes in the journal. It never modifies step status directly.

func NewPEVEngine

func NewPEVEngine(ledger RunLedgerStore, validators map[ValidatorType]Validator) *PEVEngine

NewPEVEngine creates a PEV engine with the provided store and validators.

func (*PEVEngine) Verify

func (e *PEVEngine) Verify(ctx context.Context, runID string, step *Step) (*PolicyRequest, error)

Verify runs the step's validator and records the result in the journal. Returns a PolicyRequest if validation fails, nil if it passes.

func (*PEVEngine) VerifyAcceptanceCriteria

func (e *PEVEngine) VerifyAcceptanceCriteria(
	ctx context.Context,
	criteria []AcceptanceCriterion,
) ([]AcceptanceCriterion, []AcceptanceCriterion, error)

VerifyAcceptanceCriteria checks all acceptance criteria against the current state. It returns both unmet criteria and a fully evaluated copy.

func (*PEVEngine) WithMaxRunHistory

func (e *PEVEngine) WithMaxRunHistory(maxHistory int) *PEVEngine

WithMaxRunHistory configures how many runs should be retained in the store.

func (*PEVEngine) WithTimeout

func (e *PEVEngine) WithTimeout(timeout time.Duration) *PEVEngine

WithTimeout configures a validator execution deadline.

func (*PEVEngine) WithWorkspace

func (e *PEVEngine) WithWorkspace(ws *WorkspaceManager) *PEVEngine

WithWorkspace enables workspace isolation for coding steps. Phase 1 default is nil (no isolation). Phase 3 activates with:

pev.WithWorkspace(NewWorkspaceManager())

func (*PEVEngine) WorkspaceEnabled

func (e *PEVEngine) WorkspaceEnabled() bool

WorkspaceEnabled reports whether runtime workspace isolation is wired in.

type PlanAttachedPayload

type PlanAttachedPayload struct {
	Steps              []Step                `json:"steps"`
	AcceptanceCriteria []AcceptanceCriterion `json:"acceptance_criteria"`
}

PlanAttachedPayload is the payload for EventPlanAttached.

type PlannerOutput

type PlannerOutput struct {
	Goal               string                    `json:"goal"`
	AcceptanceCriteria []AcceptanceCriteriaInput `json:"acceptance_criteria"`
	Steps              []StepInput               `json:"steps"`
}

PlannerOutput is the deserialized JSON returned by the Planner agent.

func ParsePlannerOutput

func ParsePlannerOutput(raw string) (*PlannerOutput, error)

ParsePlannerOutput extracts and deserializes the planner's JSON output. It accepts either a raw JSON object or a JSON block inside markdown fences.

type PolicyAction

type PolicyAction string

PolicyAction identifies the orchestrator's response to a step failure.

const (
	PolicyRetry           PolicyAction = "retry"
	PolicyDecompose       PolicyAction = "decompose"
	PolicyChangeAgent     PolicyAction = "change_agent"
	PolicyChangeValidator PolicyAction = "change_validator"
	PolicySkip            PolicyAction = "skip"
	PolicyAbort           PolicyAction = "abort"
	PolicyEscalate        PolicyAction = "escalate"
)

type PolicyDecision

type PolicyDecision struct {
	Action       PolicyAction   `json:"action"`
	NewSteps     []Step         `json:"new_steps,omitempty"`
	NewValidator *ValidatorSpec `json:"new_validator,omitempty"`
	NewAgent     string         `json:"new_agent,omitempty"`
	Reason       string         `json:"reason,omitempty"`
}

PolicyDecision is the orchestrator's action in response to a PolicyRequest.

type PolicyDecisionAppliedPayload

type PolicyDecisionAppliedPayload struct {
	StepID   string         `json:"step_id"`
	Decision PolicyDecision `json:"decision"`
}

PolicyDecisionAppliedPayload is the payload for EventPolicyDecisionApplied.

type PolicyRequest

type PolicyRequest struct {
	RunID      string            `json:"run_id"`
	StepID     string            `json:"step_id"`
	StepGoal   string            `json:"step_goal"`
	Failure    *ValidationResult `json:"failure"`
	RetryCount int               `json:"retry_count"`
	MaxRetries int               `json:"max_retries"`
}

PolicyRequest is generated when a step fails validation. The orchestrator must respond with a PolicyDecision.

type ProjectionDrift

type ProjectionDrift struct {
	RunID  string
	Target string
	Reason string
}

ProjectionDrift describes a mismatch between RunLedger and a projection target.

func DetectWorkflowProjectionDrift

func DetectWorkflowProjectionDrift(
	ctx context.Context,
	ledger RunLedgerStore,
	projection WorkflowProjectionStore,
	runID string,
) (*ProjectionDrift, error)

DetectWorkflowProjectionDrift compares a RunLedger snapshot against the workflow projection store and reports the first mismatch found.

type ProjectionSyncPayload

type ProjectionSyncPayload struct {
	Target string `json:"target"`
	Status string `json:"status"`
	Error  string `json:"error,omitempty"`
}

ProjectionSyncPayload describes the result of syncing a projection target.

type ResumeCandidate

type ResumeCandidate struct {
	RunID       string    `json:"run_id"`
	Goal        string    `json:"goal"`
	Status      RunStatus `json:"status"`
	LastUpdated time.Time `json:"last_updated"`
	StepSummary string    `json:"step_summary"`
}

ResumeCandidate represents a run that can be resumed.

type ResumeManager

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

ResumeManager handles detection and execution of run resumption. Resume is always opt-in — no automatic revival.

func NewResumeManager

func NewResumeManager(store RunLedgerStore, staleTTL time.Duration) *ResumeManager

NewResumeManager creates a new ResumeManager.

func (*ResumeManager) FindCandidates

func (m *ResumeManager) FindCandidates(ctx context.Context, sessionKey string) ([]ResumeCandidate, error)

FindCandidates returns runs that can be resumed for the given session.

func (*ResumeManager) Resume

func (m *ResumeManager) Resume(ctx context.Context, runID, resumedBy string) (*RunSnapshot, error)

Resume re-opens a paused run by appending a run_resumed event.

type RolloutConfig

type RolloutConfig struct {
	Stage RolloutStage
}

RolloutConfig holds the current rollout stage configuration.

func (RolloutConfig) IsAuthoritativeRead

func (c RolloutConfig) IsAuthoritativeRead() bool

IsAuthoritativeRead returns true if reads should come from ledger.

func (RolloutConfig) IsShadow

func (c RolloutConfig) IsShadow() bool

IsShadow returns true if only shadow journaling is active.

func (RolloutConfig) IsWriteThrough

func (c RolloutConfig) IsWriteThrough() bool

IsWriteThrough returns true if write-through is active.

type RolloutStage

type RolloutStage int

RolloutStage controls how deeply the RunLedger is integrated.

const (
	// StageShadow: journal records only, existing systems unaffected.
	StageShadow RolloutStage = iota
	// StageWriteThrough: all creates/updates go through ledger first, then mirror to projections.
	StageWriteThrough
	// StageAuthoritativeRead: state reads come from ledger snapshots only.
	StageAuthoritativeRead
	// StageProjectionRetired: legacy direct writes removed.
	StageProjectionRetired
)

type RunCompletedPayload

type RunCompletedPayload struct {
	Summary string `json:"summary"`
}

RunCompletedPayload is the payload for EventRunCompleted.

type RunCreatedPayload

type RunCreatedPayload struct {
	SessionKey       string          `json:"session_key"`
	OriginalRequest  string          `json:"original_request"`
	Goal             string          `json:"goal"`
	SourceKind       string          `json:"source_kind,omitempty"`       // "workflow" | "background" | ""
	SourceDescriptor json.RawMessage `json:"source_descriptor,omitempty"` // original workflow/origin JSON
}

RunCreatedPayload is the payload for EventRunCreated.

type RunFailedPayload

type RunFailedPayload struct {
	Reason string `json:"reason"`
}

RunFailedPayload is the payload for EventRunFailed.

type RunLedgerStore

type RunLedgerStore interface {
	// AppendJournalEvent appends an event to the journal. Seq is auto-assigned.
	AppendJournalEvent(ctx context.Context, event JournalEvent) error

	// GetJournalEvents returns all events for a run, ordered by seq.
	GetJournalEvents(ctx context.Context, runID string) ([]JournalEvent, error)

	// GetJournalEventsSince returns events with seq > afterSeq.
	GetJournalEventsSince(ctx context.Context, runID string, afterSeq int64) ([]JournalEvent, error)

	// MaterializeRunSnapshot replays the full journal to build a snapshot.
	MaterializeRunSnapshot(ctx context.Context, runID string) (*RunSnapshot, error)

	// RecordValidationResult appends a step_validation_passed or step_validation_failed event.
	RecordValidationResult(ctx context.Context, runID, stepID string, result ValidationResult) error

	// GetCachedSnapshot returns the last cached snapshot and its seq, or nil if uncached.
	GetCachedSnapshot(ctx context.Context, runID string) (*RunSnapshot, int64, error)

	// UpdateCachedSnapshot stores/updates the snapshot cache.
	UpdateCachedSnapshot(ctx context.Context, snapshot *RunSnapshot) error

	// ListRuns returns run IDs with their current status, ordered by creation time desc.
	ListRuns(ctx context.Context, limit int) ([]RunSummary, error)

	// GetRunSnapshot returns the most up-to-date snapshot, using cache + tail replay.
	GetRunSnapshot(ctx context.Context, runID string) (*RunSnapshot, error)

	// ListRunSummariesBySession returns recent run summaries for a session.
	ListRunSummariesBySession(ctx context.Context, sessionKey string, limit int) ([]RunSummary, error)

	// MaxJournalSeqForSession returns the highest last_journal_seq across the
	// session's runs, or 0 when the session has no runs.
	MaxJournalSeqForSession(ctx context.Context, sessionKey string) (int64, error)

	// PruneOldRuns removes the oldest terminal runs until at most maxKeep remain.
	PruneOldRuns(ctx context.Context, maxKeep int) error
}

RunLedgerStore is the persistence interface for the RunLedger. The journal is the single source of truth; snapshots are cached projections.

type RunPausedPayload

type RunPausedPayload struct {
	Reason string `json:"reason"`
}

RunPausedPayload is the payload for EventRunPaused.

type RunResumedPayload

type RunResumedPayload struct {
	ResumedBy string `json:"resumed_by"`
}

RunResumedPayload is the payload for EventRunResumed.

type RunSnapshot

type RunSnapshot struct {
	RunID            string                `json:"run_id"`
	SessionKey       string                `json:"session_key"`
	OriginalRequest  string                `json:"original_request"`
	Goal             string                `json:"goal"`
	Status           RunStatus             `json:"status"`
	CurrentStepID    string                `json:"current_step_id,omitempty"`
	CurrentBlocker   string                `json:"current_blocker,omitempty"`
	AcceptanceState  []AcceptanceCriterion `json:"acceptance_state"`
	Steps            []Step                `json:"steps"`
	Notes            map[string]string     `json:"notes"`
	SourceKind       string                `json:"source_kind,omitempty"`
	SourceDescriptor json.RawMessage       `json:"source_descriptor,omitempty"`
	LastJournalSeq   int64                 `json:"last_journal_seq"`
	UpdatedAt        time.Time             `json:"updated_at"`
	// contains filtered or unexported fields
}

RunSnapshot is a materialized view derived entirely from the journal. It is a read cache — never the source of truth.

func MaterializeFromJournal

func MaterializeFromJournal(events []JournalEvent) (*RunSnapshot, error)

MaterializeFromJournal builds a RunSnapshot from scratch by replaying all journal events in sequence order.

func (*RunSnapshot) AllCriteriaMet

func (s *RunSnapshot) AllCriteriaMet() bool

AllCriteriaMet returns true if every acceptance criterion is met.

func (*RunSnapshot) AllStepsSuccessful

func (s *RunSnapshot) AllStepsSuccessful() bool

AllStepsSuccessful returns true if every step is completed. Unlike AllStepsTerminal, failed/interrupted steps make this return false.

func (*RunSnapshot) AllStepsTerminal

func (s *RunSnapshot) AllStepsTerminal() bool

AllStepsTerminal returns true if every step is completed, failed, or interrupted.

func (*RunSnapshot) CompletedSteps

func (s *RunSnapshot) CompletedSteps() int

CompletedSteps counts how many steps have StepStatusCompleted.

func (*RunSnapshot) DeepCopy

func (s *RunSnapshot) DeepCopy() *RunSnapshot

DeepCopy returns a fully independent copy of the snapshot.

func (*RunSnapshot) FindStep

func (s *RunSnapshot) FindStep(stepID string) *Step

FindStep returns the step with the given ID, or nil.

func (*RunSnapshot) NextExecutableStep

func (s *RunSnapshot) NextExecutableStep() *Step

NextExecutableStep returns the first step that is pending and has all dependencies completed, or nil if no step is ready.

func (*RunSnapshot) ToSummary

func (s *RunSnapshot) ToSummary() RunSummary

ToSummary produces a compact RunSummary for context injection.

type RunStatus

type RunStatus string

RunStatus is the lifecycle status of a Run.

const (
	RunStatusPlanning  RunStatus = "planning"
	RunStatusRunning   RunStatus = "running"
	RunStatusPaused    RunStatus = "paused"
	RunStatusCompleted RunStatus = "completed"
	RunStatusFailed    RunStatus = "failed"
)

type RunSummary

type RunSummary struct {
	RunID              string    `json:"run_id"`
	Goal               string    `json:"goal"`
	Status             RunStatus `json:"status"`
	TotalSteps         int       `json:"total_steps"`
	CompletedSteps     int       `json:"completed_steps"`
	CurrentStepGoal    string    `json:"current_step_goal,omitempty"`
	CurrentStepStatus  string    `json:"current_step_status,omitempty"`
	CurrentBlocker     string    `json:"current_blocker,omitempty"`
	UnmetCriteria      []string  `json:"unmet_criteria,omitempty"`
	LastVerifiedResult string    `json:"last_verified_result,omitempty"`
}

RunSummary is a compressed representation of a Run for context injection.

type Step

type Step struct {
	StepID      string        `json:"step_id"`
	Index       int           `json:"index"`
	Goal        string        `json:"goal"`
	OwnerAgent  string        `json:"owner_agent"`
	Status      StepStatus    `json:"status"`
	Evidence    []Evidence    `json:"evidence,omitempty"`
	Validator   ValidatorSpec `json:"validator"`
	ToolProfile []string      `json:"tool_profile,omitempty"`
	RetryCount  int           `json:"retry_count"`
	MaxRetries  int           `json:"max_retries"`
	ResumeFrom  string        `json:"resume_from,omitempty"`
	Result      string        `json:"result,omitempty"`
	DependsOn   []string      `json:"depends_on,omitempty"`
}

Step represents a discrete unit of work within a Run.

type StepInput

type StepInput struct {
	ID          string        `json:"id"`
	Goal        string        `json:"goal"`
	OwnerAgent  string        `json:"owner_agent"`
	Validator   ValidatorSpec `json:"validator"`
	ToolProfile []string      `json:"tool_profile,omitempty"`
	DependsOn   []string      `json:"depends_on,omitempty"`
}

StepInput is the planner's step format.

type StepResultProposedPayload

type StepResultProposedPayload struct {
	StepID   string     `json:"step_id"`
	Result   string     `json:"result"`
	Evidence []Evidence `json:"evidence,omitempty"`
}

StepResultProposedPayload is the payload for EventStepResultProposed.

type StepStartedPayload

type StepStartedPayload struct {
	StepID     string `json:"step_id"`
	OwnerAgent string `json:"owner_agent"`
}

StepStartedPayload is the payload for EventStepStarted.

type StepStatus

type StepStatus string

StepStatus is the lifecycle status of a Step.

const (
	StepStatusPending       StepStatus = "pending"
	StepStatusInProgress    StepStatus = "in_progress"
	StepStatusVerifyPending StepStatus = "verify_pending"
	StepStatusCompleted     StepStatus = "completed"
	StepStatusFailed        StepStatus = "failed"
	StepStatusInterrupted   StepStatus = "interrupted"
)

type StepValidationFailedPayload

type StepValidationFailedPayload struct {
	StepID string           `json:"step_id"`
	Result ValidationResult `json:"result"`
}

StepValidationFailedPayload is the payload for EventStepValidationFailed.

type StepValidationPassedPayload

type StepValidationPassedPayload struct {
	StepID string           `json:"step_id"`
	Result ValidationResult `json:"result"`
}

StepValidationPassedPayload is the payload for EventStepValidationPassed.

type StoreOption

type StoreOption func(*StoreOptions)

StoreOption configures a RunLedger store.

func WithAppendHook

func WithAppendHook(h func(JournalEvent)) StoreOption

WithAppendHook registers a callback invoked after each successful journal append. This enables decoupled consumers (e.g., provenance checkpoint creation) to react to journal events without modifying the RunLedgerStore interface.

type StoreOptions

type StoreOptions struct {
	// AppendHook is called after a journal event is successfully appended.
	// The hook is invoked synchronously — keep it lightweight.
	AppendHook func(JournalEvent)
}

StoreOptions holds optional configuration for RunLedger store implementations.

type TestPassValidator

type TestPassValidator struct{}

TestPassValidator verifies that `go test <target>` succeeds.

func (*TestPassValidator) Validate

type ToolProfile

type ToolProfile string

ToolProfile defines which tools are accessible during a step.

const (
	ToolProfileCoding     ToolProfile = "coding"
	ToolProfileBrowser    ToolProfile = "browser"
	ToolProfileKnowledge  ToolProfile = "knowledge"
	ToolProfileSupervisor ToolProfile = "supervisor"
)

type ValidationResult

type ValidationResult struct {
	Passed  bool              `json:"passed"`
	Reason  string            `json:"reason"`
	Details map[string]string `json:"details,omitempty"`
	Missing []string          `json:"missing,omitempty"`
}

ValidationResult is the output of a Validator execution.

type Validator

type Validator interface {
	Validate(ctx context.Context, spec ValidatorSpec, evidence []Evidence) (*ValidationResult, error)
}

Validator executes a specific validation strategy against step evidence.

type ValidatorSpec

type ValidatorSpec struct {
	Type    ValidatorType     `json:"type"`
	Target  string            `json:"target,omitempty"`
	Params  map[string]string `json:"params,omitempty"`
	WorkDir string            `json:"work_dir,omitempty"` // set at runtime by workspace manager
}

ValidatorSpec specifies how a step or acceptance criterion is validated.

type ValidatorType

type ValidatorType string

ValidatorType identifies a built-in validation strategy. Custom validators are intentionally not supported — no auto-pass allowed.

const (
	ValidatorBuildPass            ValidatorType = "build_pass"
	ValidatorTestPass             ValidatorType = "test_pass"
	ValidatorFileChanged          ValidatorType = "file_changed"
	ValidatorArtifactExists       ValidatorType = "artifact_exists"
	ValidatorCommandPass          ValidatorType = "command_pass"
	ValidatorOrchestratorApproval ValidatorType = "orchestrator_approval"
)

type WorkflowProjectionStore

type WorkflowProjectionStore interface {
	CreateRun(ctx context.Context, w *workflow.Workflow) (string, error)
	CreateRunWithID(ctx context.Context, runID string, w *workflow.Workflow) error
	UpdateRunStatus(ctx context.Context, runID string, status string) error
	CompleteRun(ctx context.Context, runID string, status string, errMsg string) error
	CreateStepRun(ctx context.Context, runID string, step workflow.Step, renderedPrompt string) error
	UpdateStepStatus(ctx context.Context, runID string, stepID string, status string, result string, errMsg string) error
	GetRunStatus(ctx context.Context, runID string) (*workflow.RunStatus, error)
	GetStepResults(ctx context.Context, runID string) (map[string]string, error)
	ListRuns(ctx context.Context, limit int) ([]workflow.RunStatus, error)
}

WorkflowProjectionStore is the subset of workflow state persistence that RunLedger write-through needs to mirror workflow state.

type WorkflowWriteThrough

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

WorkflowWriteThrough creates canonical run IDs in RunLedger and mirrors state to the legacy workflow projection store.

func NewWorkflowWriteThrough

func NewWorkflowWriteThrough(
	ledger RunLedgerStore,
	original WorkflowProjectionStore,
	cfg RolloutConfig,
) *WorkflowWriteThrough

NewWorkflowWriteThrough creates a workflow projection adapter backed by RunLedger.

func (*WorkflowWriteThrough) CompleteRun

func (w *WorkflowWriteThrough) CompleteRun(ctx context.Context, runID string, status string, errMsg string) error

func (*WorkflowWriteThrough) CreateRun

func (w *WorkflowWriteThrough) CreateRun(ctx context.Context, wf *workflow.Workflow) (string, error)

func (*WorkflowWriteThrough) CreateStepRun

func (w *WorkflowWriteThrough) CreateStepRun(ctx context.Context, runID string, step workflow.Step, renderedPrompt string) error

func (*WorkflowWriteThrough) GetRunStatus

func (w *WorkflowWriteThrough) GetRunStatus(ctx context.Context, runID string) (*workflow.RunStatus, error)

func (*WorkflowWriteThrough) GetStepResults

func (w *WorkflowWriteThrough) GetStepResults(ctx context.Context, runID string) (map[string]string, error)

func (*WorkflowWriteThrough) ListRuns

func (w *WorkflowWriteThrough) ListRuns(ctx context.Context, limit int) ([]workflow.RunStatus, error)

func (*WorkflowWriteThrough) UpdateRunStatus

func (w *WorkflowWriteThrough) UpdateRunStatus(ctx context.Context, runID string, status string) error

func (*WorkflowWriteThrough) UpdateStepStatus

func (w *WorkflowWriteThrough) UpdateStepStatus(
	ctx context.Context,
	runID string,
	stepID string,
	status string,
	result string,
	errMsg string,
) error

func (*WorkflowWriteThrough) WithMaxHistory

func (w *WorkflowWriteThrough) WithMaxHistory(maxKeep int) *WorkflowWriteThrough

WithMaxHistory configures pruning of old terminal runs after completion.

type WorkspaceManager

type WorkspaceManager struct{}

WorkspaceManager handles git worktree isolation for coding steps. Coding-only, fail-closed: if worktree creation fails, the step is not executed.

func NewWorkspaceManager

func NewWorkspaceManager() *WorkspaceManager

NewWorkspaceManager creates a new WorkspaceManager.

func (*WorkspaceManager) ApplyPatch

func (m *WorkspaceManager) ApplyPatch(patchPath string) error

ApplyPatch applies a patch to the main tree using git am.

func (*WorkspaceManager) CheckDirtyTree

func (m *WorkspaceManager) CheckDirtyTree() error

CheckDirtyTree returns an error if the git working tree has uncommitted changes.

func (*WorkspaceManager) CreateWorktree

func (m *WorkspaceManager) CreateWorktree(path, branch string) error

CreateWorktree creates a git worktree at the given path for isolated execution.

func (*WorkspaceManager) DeleteBranch

func (m *WorkspaceManager) DeleteBranch(branch string) error

DeleteBranch deletes a worktree branch after cleanup.

func (*WorkspaceManager) ExportPatch

func (m *WorkspaceManager) ExportPatch(worktreePath, outputPath string) error

ExportPatch generates a patch file from a worktree using git format-patch. Auto-merge is intentionally forbidden — only git am is allowed.

func (*WorkspaceManager) PrepareStepWorkspace

func (m *WorkspaceManager) PrepareStepWorkspace(step *Step, runID string) (cleanup func(), err error)

PrepareStepWorkspace handles the full workspace lifecycle for a coding step: 1. Check if isolation needed (based on validator type) 2. If not needed, return (WorkDir stays empty = current dir) 3. Check dirty tree -> fail if dirty 4. Create worktree -> set step.Validator.WorkDir Returns a cleanup function that must be deferred.

func (*WorkspaceManager) RemoveWorktree

func (m *WorkspaceManager) RemoveWorktree(path string) error

RemoveWorktree removes a git worktree.

Jump to

Keyboard shortcuts

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