workflow

package
v0.28.1 Latest Latest
Warning

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

Go to latest
Published: Feb 1, 2026 License: MIT Imports: 2 Imported by: 0

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

Constants

This section is empty.

Variables

This section is empty.

Functions

func AllStatuses

func AllStatuses() []models.Status

AllStatuses returns all valid statuses in workflow order

func GetTransitionsFrom

func GetTransitionsFrom(status models.Status) []models.Status

GetTransitionsFrom returns all possible transitions from a given status

func GetTransitionsTo

func GetTransitionsTo(status models.Status) []models.Status

GetTransitionsTo returns all statuses that can transition to the given status

func TransitionName

func TransitionName(from, to models.Status) string

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 (*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 (*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 (*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

type GuardError struct {
	GuardName string
	Reason    string
	IssueID   string
}

GuardError represents an error when a guard check fails

func (*GuardError) Error

func (e *GuardError) Error() string

type GuardResult

type GuardResult struct {
	Passed  bool
	Message string
	Guard   string
}

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 (*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 (*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

type Transition struct {
	From   models.Status
	To     models.Status
	Guards []Guard
}

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

type TransitionError struct {
	From    models.Status
	To      models.Status
	Reason  string
	IssueID string
}

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

Jump to

Keyboard shortcuts

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