Documentation
¶
Overview ¶
Package mission provides multi-feature parallel execution for hawk. This file adds a watchdog for stall detection in worker goroutines.
Index ¶
- Variables
- type AgentCapability
- type AgentMessage
- type AgentStatus
- type ApprovalRequest
- type BusStats
- type Config
- type Fact
- type Feature
- type FeatureStatus
- type FixFunc
- type Handoff
- type HandoffMessage
- type HandoffProtocol
- func (hp *HandoffProtocol) BuildHandoffContext(from, to string, task string) *HandoffMessage
- func (hp *HandoffProtocol) CanHandle(agentName, task string) bool
- func (hp *HandoffProtocol) EscalateToHuman(reason string) *HandoffMessage
- func (hp *HandoffProtocol) FormatHandoffHistory() string
- func (hp *HandoffProtocol) GetActiveAgent() *AgentCapability
- func (hp *HandoffProtocol) Handoff(msg HandoffMessage) error
- func (hp *HandoffProtocol) RegisterAgent(cap AgentCapability)
- func (hp *HandoffProtocol) SelectBestAgent(task string) string
- type Ledger
- type LedgerOrchestrator
- func (lo *LedgerOrchestrator) AddFact(content, source string, confidence float64)
- func (lo *LedgerOrchestrator) AddPlanItem(description string, deps []string)
- func (lo *LedgerOrchestrator) AssignNext() (*PlanItem, string)
- func (lo *LedgerOrchestrator) DetectStall() bool
- func (lo *LedgerOrchestrator) FormatLedger() string
- func (lo *LedgerOrchestrator) Reassign(itemID string) string
- func (lo *LedgerOrchestrator) RegisterAgent(name string)
- func (lo *LedgerOrchestrator) ReportProgress(agentName string, itemID string, status string)
- func (lo *LedgerOrchestrator) UpdatePlan(newItems []PlanItem)
- type MemEntry
- type MessageBus
- func (mb *MessageBus) AcquireLock(resource, owner string, ttl time.Duration) error
- func (mb *MessageBus) Broadcast(from, topic, content string)
- func (mb *MessageBus) BuildContextFromMessages(agentID string, maxTokens int) string
- func (mb *MessageBus) CleanupExpiredLocks()
- func (mb *MessageBus) GetHistory(topic string, limit int) []AgentMessage
- func (mb *MessageBus) IsLocked(resource string) bool
- func (mb *MessageBus) Register(agentID string) <-chan AgentMessage
- func (mb *MessageBus) ReleaseLock(resource, owner string) error
- func (mb *MessageBus) ReportConflict(from string, files []string, description string)
- func (mb *MessageBus) ReportDiscovery(from, discovery string)
- func (mb *MessageBus) ReportProgress(from string, pct float64, status string)
- func (mb *MessageBus) RequestHelp(from, description string) string
- func (mb *MessageBus) Send(msg AgentMessage) error
- func (mb *MessageBus) Stats() BusStats
- func (mb *MessageBus) Subscribe(agentID, topic string)
- func (mb *MessageBus) TryLockFiles(from string, files []string, ttl time.Duration) []string
- func (mb *MessageBus) Unregister(agentID string)
- func (mb *MessageBus) WaitForLock(resource, owner string, timeout time.Duration) error
- func (mb *MessageBus) WaitForResponse(messageID string, timeout time.Duration) (*AgentMessage, error)
- type Mission
- func (m *Mission) Fix(ctx context.Context, fixFn FixFunc) error
- func (m *Mission) GeneratePRD(ctx context.Context, prdFn PRDFunc) error
- func (m *Mission) Plan(ctx context.Context, planFn PlanFunc) error
- func (m *Mission) Run(ctx context.Context, workerFn WorkerFunc) error
- func (m *Mission) RunStaged(ctx context.Context, workerFn WorkerFunc, opts ...StagedOption) error
- func (m *Mission) Summary() string
- func (m *Mission) Verify(ctx context.Context, verifyFn VerifyFunc) error
- type MissionApprovalGate
- type PRDFunc
- type PlanFunc
- type PlanItem
- type RequestResponse
- type ResourceLock
- type Responder
- type SharedMemory
- func (sm *SharedMemory) Clear()
- func (sm *SharedMemory) Delete(key string, owner string) error
- func (sm *SharedMemory) Diff(since time.Time) []MemEntry
- func (sm *SharedMemory) FormatState() string
- func (sm *SharedMemory) Get(key string) (interface{}, bool)
- func (sm *SharedMemory) GetBool(key string) bool
- func (sm *SharedMemory) GetInt(key string) int
- func (sm *SharedMemory) GetString(key string) string
- func (sm *SharedMemory) List(namespace string) []MemEntry
- func (sm *SharedMemory) Restore(snapshot map[string]interface{})
- func (sm *SharedMemory) Set(key string, value interface{}, owner string)
- func (sm *SharedMemory) SetNamespace(key, namespace string)
- func (sm *SharedMemory) Snapshot() map[string]interface{}
- func (sm *SharedMemory) Watch(key string) <-chan *MemEntry
- type StagedOption
- type Status
- type StepDef
- type StepFunc
- type StepStatus
- type VerifyFunc
- type Watchdog
- type WatchdogConfig
- type WorkerFunc
- type Workflow
- func (w *Workflow) Approve(name string) error
- func (w *Workflow) Done() bool
- func (w *Workflow) LastCompletedStep() string
- func (w *Workflow) Reject(name string) error
- func (w *Workflow) Resume(ctx context.Context) error
- func (w *Workflow) Run(ctx context.Context) error
- func (w *Workflow) SetValue(key, val string)
- func (w *Workflow) State() *WorkflowState
- type WorkflowState
- type WorkflowStep
Constants ¶
This section is empty.
Variables ¶
var ErrApprovalTimeout = errors.New("approval request timed out: context cancelled")
ErrApprovalTimeout is returned when the context expires before the operator calls Respond().
var ErrAwaitingApproval = errors.New("workflow halted: awaiting human approval at checkpoint gate")
ErrAwaitingApproval is returned by Workflow.Run when execution halts at a human-in-the-loop checkpoint gate. The workflow state is durable at this point: a later Resume after Approve/Reject continues from the gate.
var ErrToolRejected = errors.New("tool call rejected by human approval gate")
ErrToolRejected is returned from the gate check when the operator rejects a tool call.
Functions ¶
This section is empty.
Types ¶
type AgentCapability ¶
type AgentCapability struct {
Name string
Expertise []string
Tools []string
MaxComplexity int
Model string
}
AgentCapability describes a specialized agent's capabilities.
type AgentMessage ¶
type AgentMessage struct {
ID string `json:"id"`
From string `json:"from"`
To string `json:"to,omitempty"`
Topic string `json:"topic"`
Content string `json:"content"`
Priority int `json:"priority"`
Timestamp time.Time `json:"timestamp"`
RequiresResponse bool `json:"requires_response,omitempty"`
ResponseTo string `json:"response_to,omitempty"`
}
AgentMessage represents a message exchanged between agents during a mission.
type AgentStatus ¶
type AgentStatus struct {
Name string
Busy bool
TaskCount int
SuccessRate float64
LastActive time.Time
}
AgentStatus tracks the state and performance of a registered agent.
type ApprovalRequest ¶
type ApprovalRequest struct {
// ToolName is the canonical name of the tool being called.
ToolName string
// Args are the tool call arguments as a map.
Args map[string]interface{}
// Summary is a one-line human-readable description of the action.
Summary string
// Category is the risk category matched by the gate classifier.
Category string
// contains filtered or unexported fields
}
ApprovalRequest describes a tool call that is pending human approval. The caller receives this via MissionApprovalGate.OnRequest and must call Respond() to unblock the waiting mission worker.
func (*ApprovalRequest) Await ¶
func (r *ApprovalRequest) Await(ctx context.Context) (RequestResponse, error)
Await blocks until Respond() is called or ctx is cancelled. Returns ErrApprovalTimeout when ctx expires before the operator responds.
func (*ApprovalRequest) Respond ¶
func (r *ApprovalRequest) Respond(resp RequestResponse) error
Respond sends a decision to the waiting Await() call. It is safe to call from any goroutine. Subsequent Respond() calls after the first are no-ops.
type BusStats ¶
type BusStats struct {
// Dropped is the cumulative number of messages that could not be
// delivered to a registered agent because its channel was full.
// Includes both broadcast and direct-send drops.
Dropped int64
// Agents is the number of currently registered agents.
Agents int
// Locks is the number of currently held resource locks.
Locks int
// HistorySz is the number of messages retained in history.
HistorySz int
}
BusStats is a snapshot of MessageBus runtime counters.
type Config ¶
type Config struct {
MaxWorkers int `json:"max_workers"`
WorkerModel string `json:"worker_model"`
ValidatorModel string `json:"validator_model"`
RepoDir string `json:"repo_dir"`
BaseBranch string `json:"base_branch"`
AutonomyLevel int `json:"autonomy_level"`
SkipValidation bool `json:"skip_validation"`
PerWorkerTimeout time.Duration `json:"per_worker_timeout,omitempty"`
MaxRetriesPerFeat int `json:"max_retries_per_feat,omitempty"`
// Staged pipeline configuration (oh-my-claudecode-style team workflow).
PRDModel string `json:"prd_model,omitempty"`
FixModel string `json:"fix_model,omitempty"`
MaxFixAttempts int `json:"max_fix_attempts,omitempty"` // default 3
EnablePRDPhase bool `json:"enable_prd_phase,omitempty"`
EnableVerifyPhase bool `json:"enable_verify_phase,omitempty"`
}
Config controls mission orchestration behavior.
type Feature ¶
type Feature struct {
ID string `json:"id"`
Description string `json:"description"`
ExpectedBehavior string `json:"expected_behavior"`
Branch string `json:"branch"`
WorkerSessionID string `json:"worker_session_id,omitempty"`
Status FeatureStatus `json:"status"`
Handoff *Handoff `json:"handoff,omitempty"`
StartedAt time.Time `json:"started_at,omitempty"`
CompletedAt time.Time `json:"completed_at,omitempty"`
PRD string `json:"prd,omitempty"` // generated product requirements
VerificationResult string `json:"verification_result,omitempty"` // verify-phase outcome
FixAttempts int `json:"fix_attempts,omitempty"` // number of fix passes applied
}
Feature is a discrete unit of work assigned to a worker.
type FeatureStatus ¶
type FeatureStatus string
FeatureStatus tracks individual feature progress.
const ( FeaturePending FeatureStatus = "pending" FeatureInProgress FeatureStatus = "in_progress" FeatureCompleted FeatureStatus = "completed" FeatureFailed FeatureStatus = "failed" )
type FixFunc ¶
type FixFunc func(ctx context.Context, feature *Feature, verificationResult string, handoff *Handoff) (*Handoff, error)
FixFunc attempts to fix a feature that failed verification.
type Handoff ¶
type Handoff struct {
CommitID string `json:"commit_id,omitempty"`
RepoPath string `json:"repo_path,omitempty"`
Summary string `json:"summary"`
FilesChanged []string `json:"files_changed,omitempty"`
TestsPassed bool `json:"tests_passed"`
}
Handoff is the structured report a worker produces upon completion.
type HandoffMessage ¶
type HandoffMessage struct {
FromAgent string
ToAgent string
Reason string
Context string
Task string
Priority int
State map[string]interface{}
Timestamp time.Time
}
HandoffMessage represents a control transfer message between agents.
type HandoffProtocol ¶
type HandoffProtocol struct {
Agents map[string]*AgentCapability
ActiveAgent string
History []HandoffMessage
// contains filtered or unexported fields
}
HandoffProtocol manages typed message-based control transfer between specialized agents.
func NewHandoffProtocol ¶
func NewHandoffProtocol() *HandoffProtocol
NewHandoffProtocol creates a new HandoffProtocol with initialized fields.
func (*HandoffProtocol) BuildHandoffContext ¶
func (hp *HandoffProtocol) BuildHandoffContext(from, to string, task string) *HandoffMessage
BuildHandoffContext automatically builds a HandoffMessage with relevant state for transferring control from one agent to another.
func (*HandoffProtocol) CanHandle ¶
func (hp *HandoffProtocol) CanHandle(agentName, task string) bool
CanHandle checks whether a given agent can handle a task by matching task keywords against the agent's expertise.
func (*HandoffProtocol) EscalateToHuman ¶
func (hp *HandoffProtocol) EscalateToHuman(reason string) *HandoffMessage
EscalateToHuman creates a special handoff message that signals human intervention is needed.
func (*HandoffProtocol) FormatHandoffHistory ¶
func (hp *HandoffProtocol) FormatHandoffHistory() string
FormatHandoffHistory returns a formatted string representation of the handoff history.
func (*HandoffProtocol) GetActiveAgent ¶
func (hp *HandoffProtocol) GetActiveAgent() *AgentCapability
GetActiveAgent returns the currently active agent's capability, or nil if no agent is active.
func (*HandoffProtocol) Handoff ¶
func (hp *HandoffProtocol) Handoff(msg HandoffMessage) error
Handoff transfers control from one agent to another. It validates the target agent exists, transfers context and task, records the handoff in history, and sets the new active agent.
func (*HandoffProtocol) RegisterAgent ¶
func (hp *HandoffProtocol) RegisterAgent(cap AgentCapability)
RegisterAgent adds an agent capability to the protocol.
func (*HandoffProtocol) SelectBestAgent ¶
func (hp *HandoffProtocol) SelectBestAgent(task string) string
SelectBestAgent picks the best agent for a given task by matching task keywords against agent expertise and considering complexity.
type Ledger ¶
type Ledger struct {
Facts []Fact
Plan []PlanItem
Agents map[string]*AgentStatus
CurrentAssignment string
StallCount int
// contains filtered or unexported fields
}
Ledger maintains the shared state of facts, plan, and agents for orchestration.
type LedgerOrchestrator ¶
type LedgerOrchestrator struct {
Ledger *Ledger
MaxStalls int
ReassignThreshold time.Duration
// contains filtered or unexported fields
}
LedgerOrchestrator coordinates multi-agent work using a task ledger, dynamically reassigning work based on progress — inspired by MagenticOne.
func NewLedgerOrchestrator ¶
func NewLedgerOrchestrator() *LedgerOrchestrator
NewLedgerOrchestrator creates a new orchestrator with sensible defaults.
func (*LedgerOrchestrator) AddFact ¶
func (lo *LedgerOrchestrator) AddFact(content, source string, confidence float64)
AddFact records a new discovered fact into the ledger.
func (*LedgerOrchestrator) AddPlanItem ¶
func (lo *LedgerOrchestrator) AddPlanItem(description string, deps []string)
AddPlanItem appends a new plan item with the given description and dependencies.
func (*LedgerOrchestrator) AssignNext ¶
func (lo *LedgerOrchestrator) AssignNext() (*PlanItem, string)
AssignNext finds the next unblocked pending plan item and assigns it to the best available agent. Returns nil, "" if no assignment can be made.
func (*LedgerOrchestrator) DetectStall ¶
func (lo *LedgerOrchestrator) DetectStall() bool
DetectStall checks if any active item has exceeded the ReassignThreshold without progress. Returns true if a stall is detected.
func (*LedgerOrchestrator) FormatLedger ¶
func (lo *LedgerOrchestrator) FormatLedger() string
FormatLedger returns a human-readable summary of the ledger state.
func (*LedgerOrchestrator) Reassign ¶
func (lo *LedgerOrchestrator) Reassign(itemID string) string
Reassign moves a stalled item to a different agent and records a fact. Returns the name of the new agent, or "" if no reassignment is possible.
func (*LedgerOrchestrator) RegisterAgent ¶
func (lo *LedgerOrchestrator) RegisterAgent(name string)
RegisterAgent adds a new agent to the orchestrator's pool.
func (*LedgerOrchestrator) ReportProgress ¶
func (lo *LedgerOrchestrator) ReportProgress(agentName string, itemID string, status string)
ReportProgress updates the status of a plan item and the agent's stats.
func (*LedgerOrchestrator) UpdatePlan ¶
func (lo *LedgerOrchestrator) UpdatePlan(newItems []PlanItem)
UpdatePlan replaces or merges plan items dynamically. Items with matching IDs are updated; new items are appended.
type MemEntry ¶
type MemEntry struct {
Key string `json:"key"`
Value interface{} `json:"value"`
Type string `json:"type"` // "string", "int", "bool", "json", "list"
Owner string `json:"owner"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Version int `json:"version"`
Readers []string `json:"readers,omitempty"`
}
MemEntry represents a single entry in shared memory.
type MessageBus ¶
type MessageBus struct {
// contains filtered or unexported fields
}
MessageBus coordinates inter-agent communication during mission execution.
func NewMessageBus ¶
func NewMessageBus() *MessageBus
NewMessageBus creates and returns an initialized MessageBus.
func (*MessageBus) AcquireLock ¶
func (mb *MessageBus) AcquireLock(resource, owner string, ttl time.Duration) error
AcquireLock attempts to acquire an exclusive lock on a resource. Returns nil on success, or an error if the resource is held by another agent. A lock held by the same owner is refreshed (re-entrant). Expired locks are reclaimed.
func (*MessageBus) Broadcast ¶
func (mb *MessageBus) Broadcast(from, topic, content string)
Broadcast sends a message from one agent to all others. Broadcasts never fail: agents with full buffers are silently skipped.
func (*MessageBus) BuildContextFromMessages ¶
func (mb *MessageBus) BuildContextFromMessages(agentID string, maxTokens int) string
BuildContextFromMessages formats recent relevant messages for injection into an agent's context. It returns a human-readable summary of team communication limited to approximately maxTokens characters.
func (*MessageBus) CleanupExpiredLocks ¶
func (mb *MessageBus) CleanupExpiredLocks()
CleanupExpiredLocks removes all locks whose expiry time has passed.
func (*MessageBus) GetHistory ¶
func (mb *MessageBus) GetHistory(topic string, limit int) []AgentMessage
GetHistory returns messages filtered by topic (or all if topic is empty), limited to the most recent `limit` entries.
func (*MessageBus) IsLocked ¶
func (mb *MessageBus) IsLocked(resource string) bool
IsLocked reports whether a resource is currently locked by any agent. Expired locks are treated as unlocked.
func (*MessageBus) Register ¶
func (mb *MessageBus) Register(agentID string) <-chan AgentMessage
Register creates a channel for the given agent to receive messages. Returns a read-only channel the agent can listen on.
func (*MessageBus) ReleaseLock ¶
func (mb *MessageBus) ReleaseLock(resource, owner string) error
ReleaseLock releases a lock on a resource, verifying ownership.
func (*MessageBus) ReportConflict ¶
func (mb *MessageBus) ReportConflict(from string, files []string, description string)
ReportConflict notifies all agents about a file conflict so they can coordinate.
func (*MessageBus) ReportDiscovery ¶
func (mb *MessageBus) ReportDiscovery(from, discovery string)
ReportDiscovery shares a useful finding with all agents.
func (*MessageBus) ReportProgress ¶
func (mb *MessageBus) ReportProgress(from string, pct float64, status string)
ReportProgress sends a progress update for coordination.
func (*MessageBus) RequestHelp ¶
func (mb *MessageBus) RequestHelp(from, description string) string
RequestHelp broadcasts a help request and returns the message ID for tracking responses.
func (*MessageBus) Send ¶
func (mb *MessageBus) Send(msg AgentMessage) error
Send delivers a message to a specific agent or broadcasts to all. If msg.To is set, delivers to that specific agent. If msg.To is empty, broadcasts to all registered agents (except sender).
The dropped-message WARN log is performed after mb.mu is released (see M8): a slow slog handler should not serialize bus operations. We snapshot the (from, to, topic) of each drop into a local slice while still holding the lock, then iterate the slice after the inner function returns and the lock has been released.
func (*MessageBus) Stats ¶
func (mb *MessageBus) Stats() BusStats
Stats returns a snapshot of MessageBus counters. Safe for concurrent use.
func (*MessageBus) Subscribe ¶
func (mb *MessageBus) Subscribe(agentID, topic string)
Subscribe registers an agent to receive messages for a given topic.
func (*MessageBus) TryLockFiles ¶
TryLockFiles attempts to acquire locks on a set of files for an agent. Returns the list of files that could NOT be locked (held by others). On any contention, it also reports a conflict via the message bus.
func (*MessageBus) Unregister ¶
func (mb *MessageBus) Unregister(agentID string)
Unregister removes an agent from the message bus and closes its channel.
func (*MessageBus) WaitForLock ¶
func (mb *MessageBus) WaitForLock(resource, owner string, timeout time.Duration) error
WaitForLock blocks until a resource lock can be acquired or the timeout elapses.
Implementation: push-based via a per-call done channel. The caller registers as a waiter; ReleaseLock() closes the done channel when the lock is freed. This replaces the previous 20ms busy-poll.
Once ReleaseLock closes our done channel, the channel stays closed for the lifetime of the waiter. The previous implementation re-entered the select after each signal, which (a) busy-spinned calling AcquireLock on the same closed-channel signal under contention and (b) raced the timer.C case: both `<-w.done` and `<-timer.C` are ready, and select picks randomly — so the timeout could be missed or the function could loop indefinitely waiting on the second signal from a ReleaseLock that never re-fires. (See M7 in the code review.)
Fix: use a one-shot select. On the first signal (w.done or timer), try AcquireLock exactly once. If it succeeds, return nil; if the timer fired, return a timeout error. There is no second loop, so no busy-spin and no select race.
func (*MessageBus) WaitForResponse ¶
func (mb *MessageBus) WaitForResponse(messageID string, timeout time.Duration) (*AgentMessage, error)
WaitForResponse blocks until a response to the given messageID arrives or timeout elapses.
Implementation: push-based via a per-call done channel. The caller registers as a waiter; Send() closes the done channel when a matching response is appended to history. This replaces the previous 10ms busy-poll (which missed sub-tick responses and burned CPU under load).
Race: a response may have been appended to history just before the waiter registers. The fast path below checks history first, so a late-arriving WaitForResponse still finds the answer.
type Mission ¶
type Mission struct {
ID string `json:"id"`
Prompt string `json:"prompt"`
Dir string `json:"dir"`
Features []Feature `json:"features"`
Status Status `json:"status"`
StartedAt time.Time `json:"started_at"`
CompletedAt time.Time `json:"completed_at,omitempty"`
Config Config `json:"config"`
// ApprovalGate is an optional typed human-in-the-loop gate that intercepts
// tool calls matching a flagged risk category before they execute.
// When nil the gate is a no-op and all tool calls proceed automatically.
ApprovalGate *MissionApprovalGate `json:"-"`
// contains filtered or unexported fields
}
Mission represents a multi-agent orchestration run.
func (*Mission) Fix ¶
Fix runs the fix loop: for each failed feature with a recorded verification result, attempts up to MaxFixAttempts fixes, re-marking the feature completed on success.
func (*Mission) GeneratePRD ¶
GeneratePRD runs the PRD phase: generates a requirements doc for each feature.
func (*Mission) Run ¶
func (m *Mission) Run(ctx context.Context, workerFn WorkerFunc) error
Run executes all features in parallel using workerFn.
func (*Mission) RunStaged ¶
func (m *Mission) RunStaged(ctx context.Context, workerFn WorkerFunc, opts ...StagedOption) error
RunStaged orchestrates the full team pipeline:
team-plan (already done via Plan) -> team-prd -> team-exec -> team-verify -> team-fix loop
PRD and verify phases run only when enabled in Config. The fix loop runs when a fix function is provided and the verify phase is enabled.
type MissionApprovalGate ¶
type MissionApprovalGate struct {
// OnRequest is called synchronously in the worker goroutine before the tool
// runs. The implementation must not call Await() itself — it should hand the
// *ApprovalRequest to an operator UI and return immediately.
OnRequest func(req *ApprovalRequest)
// contains filtered or unexported fields
}
MissionApprovalGate wraps a mission's tool-call dispatch with the typed channel-based gate. When OnRequest is non-nil and a tool call matches a flagged category, OnRequest is invoked with an *ApprovalRequest; the worker goroutine blocks on Await() until the operator calls Respond(). If OnRequest is nil the gate is a no-op (auto-approve everything).
SessionApproved tracks tools approved for the entire session via ResponseApproveForSession; subsequent calls to those tools skip the gate.
func NewMissionApprovalGate ¶
func NewMissionApprovalGate(onRequest func(req *ApprovalRequest)) *MissionApprovalGate
NewMissionApprovalGate creates a gate with the given OnRequest handler. Pass nil to create a no-op gate.
func (*MissionApprovalGate) Check ¶
func (g *MissionApprovalGate) Check(ctx context.Context, toolName string, args map[string]interface{}) error
Check consults the gate for a pending tool call. If the gate is enabled and the tool matches a risky category, it calls OnRequest and blocks until the operator responds. Returns an error if the call is rejected or the context expires; nil means proceed.
type PlanFunc ¶
Plan decomposes the mission prompt into features. planFn is called with the prompt and should return a list of features.
type PlanItem ¶
type PlanItem struct {
ID string
Description string
Status string // "pending", "active", "done", "stalled"
AssignedTo string
Dependencies []string
Order int
}
PlanItem represents a single unit of work in the orchestration plan.
type RequestResponse ¶
type RequestResponse int
RequestResponse is the operator's decision for an approval request.
const ( // ResponseApprove allows the tool call once. ResponseApprove RequestResponse = iota // ResponseApproveForSession auto-approves subsequent calls to the same tool. ResponseApproveForSession // ResponseReject denies the tool call and causes an error event. ResponseReject )
type ResourceLock ¶
type ResourceLock struct {
Resource string `json:"resource"`
Owner string `json:"owner"`
AcquiredAt time.Time `json:"acquired_at"`
ExpiresAt time.Time `json:"expires_at"`
Priority int `json:"priority"`
}
ResourceLock represents an exclusive lock on a shared resource (e.g. a file). Prevents conflicting operations when multiple agents work in parallel.
type Responder ¶
type Responder interface {
Respond(RequestResponse) error
}
Responder is implemented by anything that can resolve an ApprovalRequest.
type SharedMemory ¶
type SharedMemory struct {
// contains filtered or unexported fields
}
SharedMemory provides a concurrent-safe key-value store for multi-agent workflows, allowing agents to read and write common state without message passing.
func NewSharedMemory ¶
func NewSharedMemory() *SharedMemory
NewSharedMemory creates and returns an initialized SharedMemory instance.
func (*SharedMemory) Clear ¶
func (sm *SharedMemory) Clear()
Clear resets all entries, namespaces, and watchers.
func (*SharedMemory) Delete ¶
func (sm *SharedMemory) Delete(key string, owner string) error
Delete removes an entry from shared memory. Only the owner who wrote the entry is permitted to delete it; otherwise an error is returned.
func (*SharedMemory) Diff ¶
func (sm *SharedMemory) Diff(since time.Time) []MemEntry
Diff returns all entries that have been modified since the given timestamp.
func (*SharedMemory) FormatState ¶
func (sm *SharedMemory) FormatState() string
FormatState returns a human-readable representation of all entries in shared memory, formatted for display in agent context.
func (*SharedMemory) Get ¶
func (sm *SharedMemory) Get(key string) (interface{}, bool)
Get retrieves a value from shared memory by key. Returns the value and a boolean indicating whether the key was found.
func (*SharedMemory) GetBool ¶
func (sm *SharedMemory) GetBool(key string) bool
GetBool retrieves a value as a bool. Returns false if the key does not exist or the value cannot be interpreted as a boolean.
func (*SharedMemory) GetInt ¶
func (sm *SharedMemory) GetInt(key string) int
GetInt retrieves a value as an int. Returns 0 if the key does not exist or the value cannot be interpreted as an integer.
func (*SharedMemory) GetString ¶
func (sm *SharedMemory) GetString(key string) string
GetString retrieves a value as a string. Returns empty string if the key does not exist or the value cannot be converted to a string.
func (*SharedMemory) List ¶
func (sm *SharedMemory) List(namespace string) []MemEntry
List returns all entries belonging to a given namespace.
func (*SharedMemory) Restore ¶
func (sm *SharedMemory) Restore(snapshot map[string]interface{})
Restore populates shared memory from a previously captured snapshot. Existing entries are cleared and replaced with the snapshot contents. All restored entries are assigned owner "snapshot" and version 1.
func (*SharedMemory) Set ¶
func (sm *SharedMemory) Set(key string, value interface{}, owner string)
Set writes a value into shared memory. If the key already exists, the version is incremented and the UpdatedAt timestamp is refreshed. The owner is recorded as the agent that last wrote the entry.
func (*SharedMemory) SetNamespace ¶
func (sm *SharedMemory) SetNamespace(key, namespace string)
SetNamespace assigns a key to a namespace for organizational grouping. A key can belong to multiple namespaces.
func (*SharedMemory) Snapshot ¶
func (sm *SharedMemory) Snapshot() map[string]interface{}
Snapshot returns a shallow copy of all key-value pairs currently in shared memory.
func (*SharedMemory) Watch ¶
func (sm *SharedMemory) Watch(key string) <-chan *MemEntry
Watch returns a channel that receives notifications whenever the specified key is updated. The channel is buffered (size 16) and non-blocking on send.
type StagedOption ¶
type StagedOption func(*stagedConfig)
StagedOption configures RunStaged behavior.
func WithFix ¶
func WithFix(fn FixFunc) StagedOption
WithFix supplies the fix function for the staged pipeline.
func WithPRD ¶
func WithPRD(fn PRDFunc) StagedOption
WithPRD supplies the PRD generation function for the staged pipeline.
func WithVerify ¶
func WithVerify(fn VerifyFunc) StagedOption
WithVerify supplies the verification function for the staged pipeline.
type Status ¶
type Status string
Status represents the mission lifecycle.
const ( StatusPlanning Status = "planning" StatusPlanningPRD Status = "planning_prd" StatusRunning Status = "running" StatusExecuting Status = "executing" StatusVerifying Status = "verifying" StatusFixing Status = "fixing" StatusValidating Status = "validating" StatusCompleted Status = "completed" StatusFailed Status = "failed" StatusPartial Status = "partial" )
type StepDef ¶
NewWorkflow creates a durable workflow with the given name and ordered step definitions. Each definition contributes a named step and its executor. dir is where workflow.json is persisted; if empty, persistence is skipped.
type StepFunc ¶
type StepFunc func(ctx context.Context, state *WorkflowState) (output json.RawMessage, err error)
StepFunc executes a single workflow step. The returned bytes (may be nil) are persisted as the step's durable Output.
type StepStatus ¶
type StepStatus string
StepStatus tracks the lifecycle of a single workflow step.
const ( StepPending StepStatus = "pending" StepRunning StepStatus = "running" StepCompleted StepStatus = "completed" StepFailed StepStatus = "failed" StepAwaitingApprov StepStatus = "awaiting_approval" StepRejected StepStatus = "rejected" )
type VerifyFunc ¶
type VerifyFunc func(ctx context.Context, feature *Feature, handoff *Handoff) (passed bool, result string, err error)
VerifyFunc validates a completed feature's implementation. Returns passed=true if the implementation satisfies the feature's expected behavior.
type Watchdog ¶
type Watchdog struct {
// contains filtered or unexported fields
}
Watchdog monitors worker progress and triggers fallback on stalls.
func NewWatchdog ¶
func NewWatchdog(cfg WatchdogConfig, onStall func(string)) *Watchdog
NewWatchdog creates a new watchdog with the given config and stall callback.
func (*Watchdog) ActiveCount ¶
ActiveCount returns the number of currently monitored features.
func (*Watchdog) Touch ¶
Touch updates the last-activity timestamp for a feature. Call this when a worker produces output.
func (*Watchdog) Unregister ¶
Unregister removes a feature from monitoring (call on completion).
type WatchdogConfig ¶
type WatchdogConfig struct {
StallTimeout time.Duration // default 90s — no output for this long = stall
CheckInterval time.Duration // default 10s — how often to check
}
WatchdogConfig configures the stall-detection watchdog.
type WorkerFunc ¶
type WorkerFunc func(ctx context.Context, feature *Feature, missionDir string, cfg Config) (*Handoff, error)
WorkerFunc is the function type that the orchestrator calls for each feature. It receives the feature and mission dir, and returns a handoff or error.
func EngineWorker ¶
func EngineWorker(provider, model, systemPrompt string) WorkerFunc
EngineWorker returns a WorkerFunc that runs an actual engine session in an isolated git worktree for each feature.
func ReadOnlyValidationWorker ¶
func ReadOnlyValidationWorker(provider, model, systemPrompt string) WorkerFunc
ReadOnlyValidationWorker returns a WorkerFunc that reviews an already-produced implementation without modifying it. It runs in the same worktree the implementation worker committed to (passed via cfg.RepoDir / the handed-off branch) using a read-only tool registry, and returns its verdict as the Handoff.Summary. It never commits and reports no FilesChanged of its own.
This is the validation half of the implement-then-validate pair: pipeline an EngineWorker (implementation) into a ReadOnlyValidationWorker (validation) so the agent that writes the code is never the agent that signs off on it.
type Workflow ¶
type Workflow struct {
// contains filtered or unexported fields
}
Workflow is a durable, resumable sequence of named steps.
func LoadWorkflow ¶
LoadWorkflow reads a previously persisted workflow from dir and rebinds the supplied step executors by name. Steps whose names are not present in defs are left without an executor (Resume will error if it needs to run them).
func NewWorkflow ¶
NewWorkflow constructs a Workflow from ordered step definitions.
func (*Workflow) Approve ¶
Approve records human approval for the named gate step, making the decision durable, so a subsequent Resume proceeds past the gate.
func (*Workflow) LastCompletedStep ¶
LastCompletedStep returns the name of the most recently completed step, or "" if none have completed yet. Useful for reporting resume points.
func (*Workflow) Reject ¶
Reject records a human rejection for the named gate step. A rejected gate halts the workflow on the next Run/Resume.
func (*Workflow) Resume ¶
Resume continues a workflow from the last completed step. It is identical to Run; the name documents intent at call sites after a restart.
func (*Workflow) Run ¶
Run executes steps from the first non-completed step to the end. It persists after every step transition so a crash leaves a resumable state. When it reaches an un-approved human gate it persists StepAwaitingApprov and returns ErrAwaitingApproval. Resume is an alias for Run after Approve.
func (*Workflow) SetValue ¶
SetValue stores a shared value visible to subsequent steps and across restarts.
func (*Workflow) State ¶
func (w *Workflow) State() *WorkflowState
State returns a snapshot pointer to the workflow's durable state.
type WorkflowState ¶
type WorkflowState struct {
ID string `json:"id"`
Name string `json:"name"`
Steps []WorkflowStep `json:"steps"`
Values map[string]string `json:"values,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Dir string `json:"-"`
}
WorkflowState is the durable, serializable state of a Workflow. The bag of shared values (Values) lets steps pass data forward across restarts.
type WorkflowStep ¶
type WorkflowStep struct {
Name string `json:"name"`
Status StepStatus `json:"status"`
HumanGate bool `json:"human_gate,omitempty"` // requires Approve before running
Approved bool `json:"approved,omitempty"`
StartedAt time.Time `json:"started_at,omitempty"`
CompletedAt time.Time `json:"completed_at,omitempty"`
Attempts int `json:"attempts,omitempty"`
Error string `json:"error,omitempty"`
// Output is an opaque, JSON-serializable result the step produced. It is
// persisted so resumed runs can read prior step output without re-running.
Output json.RawMessage `json:"output,omitempty"`
}
WorkflowStep is a durable, named unit of work in a Workflow.