Documentation
¶
Overview ¶
Package workflow implements the issue status state machine.
Guards are condition checks that run during status transitions in Advisory and Strict modes. In Liberal mode (default), guards are skipped.
Currently active guards (attached to transitions):
- BlockedGuard: Requires --force to start blocked issues
- DifferentReviewerGuard: Prevents self-approval
Future guards (defined but not yet attached to transitions):
- EpicChildrenGuard: Warns when closing epic with open children
- SelfCloseGuard: Prevents self-closing without exception
- InProgressRequiredGuard: Validates review source status
These future guards require caller modifications to pass necessary context (e.g., open child count, self-close exception reason) and will be wired up when Advisory/Strict modes are enabled by default.
Index ¶
- func AllStatuses() []models.Status
- func GetTransitionsFrom(status models.Status) []models.Status
- func GetTransitionsTo(status models.Status) []models.Status
- func TransitionName(from, to models.Status) string
- type ActionContext
- type BlockedGuard
- type DifferentReviewerGuard
- type EpicChildrenGuard
- type Guard
- type GuardError
- type GuardResult
- type InProgressRequiredGuard
- type SelfCloseGuard
- type StateMachine
- func (sm *StateMachine) CanTransition(ctx *TransitionContext) (bool, []GuardResult)
- func (sm *StateMachine) GetAllTransitions() []*Transition
- func (sm *StateMachine) GetAllowedTransitions(from models.Status) []models.Status
- func (sm *StateMachine) GetTransition(from, to models.Status) *Transition
- func (sm *StateMachine) IsValidTransition(from, to models.Status) bool
- func (sm *StateMachine) Mode() TransitionMode
- func (sm *StateMachine) SetMode(mode TransitionMode)
- func (sm *StateMachine) Validate(ctx *TransitionContext) ([]GuardResult, error)
- type Transition
- type TransitionContext
- type TransitionError
- type TransitionMode
- type ValidationError
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AllStatuses ¶
AllStatuses returns all valid statuses in workflow order
func GetTransitionsFrom ¶
GetTransitionsFrom returns all possible transitions from a given status
func GetTransitionsTo ¶
GetTransitionsTo returns all statuses that can transition to the given status
func TransitionName ¶
TransitionName returns a human-readable name for the transition
Types ¶
type ActionContext ¶
type ActionContext string
ActionContext identifies the source of the transition request. Used by guards to apply context-specific rules (e.g., admin bypass). Currently only ContextAdmin is checked by DifferentReviewerGuard.
const ( // ContextCLI indicates transition from CLI commands ContextCLI ActionContext = "cli" // ContextMonitor indicates transition from TUI monitor ContextMonitor ActionContext = "monitor" // ContextWorkSession indicates transition from work session commands ContextWorkSession ActionContext = "worksession" // ContextAdmin indicates administrative bypass (allows self-approval) ContextAdmin ActionContext = "admin" )
type BlockedGuard ¶
type BlockedGuard struct{}
BlockedGuard warns when starting a blocked issue without --force. Active: Attached to blocked → in_progress transition.
func (*BlockedGuard) Check ¶
func (g *BlockedGuard) Check(ctx *TransitionContext) GuardResult
func (*BlockedGuard) Name ¶
func (g *BlockedGuard) Name() string
type DifferentReviewerGuard ¶
type DifferentReviewerGuard struct{}
DifferentReviewerGuard ensures approvals come from different session than implementer. Active: Attached to in_review → closed transition.
func (*DifferentReviewerGuard) Check ¶
func (g *DifferentReviewerGuard) Check(ctx *TransitionContext) GuardResult
func (*DifferentReviewerGuard) Name ¶
func (g *DifferentReviewerGuard) Name() string
type EpicChildrenGuard ¶
type EpicChildrenGuard struct {
// OpenChildCount is set by caller before validation
OpenChildCount int
}
EpicChildrenGuard warns when closing epic with open children. Future: Not yet attached to transitions. Requires caller to set OpenChildCount.
func (*EpicChildrenGuard) Check ¶
func (g *EpicChildrenGuard) Check(ctx *TransitionContext) GuardResult
func (*EpicChildrenGuard) Name ¶
func (g *EpicChildrenGuard) Name() string
type Guard ¶
type Guard interface {
Name() string
Check(ctx *TransitionContext) GuardResult
}
Guard checks whether a transition should be allowed
type GuardError ¶
GuardError represents an error when a guard check fails
func (*GuardError) Error ¶
func (e *GuardError) Error() string
type GuardResult ¶
GuardResult represents the outcome of a guard check
type InProgressRequiredGuard ¶
type InProgressRequiredGuard struct{}
InProgressRequiredGuard ensures issue is in progress before review. Future: Not yet attached to transitions. Transition definitions already prevent most invalid paths (e.g., blocked → in_review).
func (*InProgressRequiredGuard) Check ¶
func (g *InProgressRequiredGuard) Check(ctx *TransitionContext) GuardResult
func (*InProgressRequiredGuard) Name ¶
func (g *InProgressRequiredGuard) Name() string
type SelfCloseGuard ¶
type SelfCloseGuard struct {
// SelfCloseException is the reason provided for self-close bypass
SelfCloseException string
}
SelfCloseGuard prevents closing issues you implemented without exception. Future: Not yet attached to transitions. Requires caller to set SelfCloseException.
func (*SelfCloseGuard) Check ¶
func (g *SelfCloseGuard) Check(ctx *TransitionContext) GuardResult
func (*SelfCloseGuard) Name ¶
func (g *SelfCloseGuard) Name() string
type StateMachine ¶
type StateMachine struct {
// contains filtered or unexported fields
}
StateMachine manages issue status transitions
func AdvisoryMachine ¶
func AdvisoryMachine() *StateMachine
AdvisoryMachine returns a state machine that warns but allows transitions
func DefaultMachine ¶
func DefaultMachine() *StateMachine
DefaultMachine returns a state machine with liberal mode (existing behavior)
func New ¶
func New(mode TransitionMode) *StateMachine
New creates a new StateMachine with the given mode
func StrictMachine ¶
func StrictMachine() *StateMachine
StrictMachine returns a state machine that blocks invalid transitions
func (*StateMachine) CanTransition ¶
func (sm *StateMachine) CanTransition(ctx *TransitionContext) (bool, []GuardResult)
CanTransition checks if a transition can be performed (convenience method)
func (*StateMachine) GetAllTransitions ¶
func (sm *StateMachine) GetAllTransitions() []*Transition
GetAllTransitions returns all registered transitions
func (*StateMachine) GetAllowedTransitions ¶
func (sm *StateMachine) GetAllowedTransitions(from models.Status) []models.Status
GetAllowedTransitions returns all valid target statuses from a given status
func (*StateMachine) GetTransition ¶
func (sm *StateMachine) GetTransition(from, to models.Status) *Transition
GetTransition returns the transition definition if it exists
func (*StateMachine) IsValidTransition ¶
func (sm *StateMachine) IsValidTransition(from, to models.Status) bool
IsValidTransition checks if a transition exists in the state machine
func (*StateMachine) Mode ¶
func (sm *StateMachine) Mode() TransitionMode
Mode returns the current transition mode
func (*StateMachine) SetMode ¶
func (sm *StateMachine) SetMode(mode TransitionMode)
SetMode changes the transition mode
func (*StateMachine) Validate ¶
func (sm *StateMachine) Validate(ctx *TransitionContext) ([]GuardResult, error)
Validate checks if a transition is allowed and returns any guard results
type Transition ¶
Transition defines a valid status transition with optional guards
func AllTransitions ¶
func AllTransitions() []*Transition
AllTransitions returns all valid status transitions This defines the complete workflow state machine
type TransitionContext ¶
type TransitionContext struct {
Issue *models.Issue
FromStatus models.Status
ToStatus models.Status
SessionID string
Force bool
Minor bool
Context ActionContext
WasInvolved bool // Whether current session was involved with issue
}
TransitionContext provides context for a status transition
type TransitionError ¶
TransitionError represents an error when a transition is not allowed
func (*TransitionError) Error ¶
func (e *TransitionError) Error() string
type TransitionMode ¶
type TransitionMode int
TransitionMode controls how guards are applied
const ( // ModeLiberal disables all guard checks (default, preserves existing behavior) ModeLiberal TransitionMode = iota // ModeAdvisory runs guards but only returns warnings, allows transition ModeAdvisory // ModeStrict blocks transitions when guards fail ModeStrict )
type ValidationError ¶
type ValidationError struct {
Errors []error
}
ValidationError wraps multiple guard failures
func (*ValidationError) Add ¶
func (e *ValidationError) Add(err error)
Add adds an error to the validation error
func (*ValidationError) Error ¶
func (e *ValidationError) Error() string
func (*ValidationError) HasErrors ¶
func (e *ValidationError) HasErrors() bool
HasErrors returns true if there are validation errors