9012d5ddc6
Remove the legacy/ Rust tree (Cargo manifests, .rs sources, desktop entry), drop Rust-specific .gitignore blocks and README note, and strip now-dangling "ported from Rust" comments from the Go sources. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
116 lines
5.0 KiB
Go
116 lines
5.0 KiB
Go
// Package statemachine holds the pure runtime and commitment transition
|
|
// functions. No I/O, no shared state.
|
|
package statemachine
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"antidrift/internal/domain"
|
|
)
|
|
|
|
// RuntimeAction enumerates runtime transitions. Activate's policy acceptance
|
|
// and admin-override exit targets are flattened into distinct actions so the
|
|
// action type stays a simple value.
|
|
type RuntimeAction string
|
|
|
|
const (
|
|
EnterPlanning RuntimeAction = "enter_planning"
|
|
CancelOrTimeout RuntimeAction = "cancel_or_timeout"
|
|
ActivateAccepted RuntimeAction = "activate_accepted"
|
|
ActivateRejected RuntimeAction = "activate_rejected"
|
|
StartTransition RuntimeAction = "start_transition"
|
|
CompleteForReview RuntimeAction = "complete_for_review"
|
|
SevereViolation RuntimeAction = "severe_violation"
|
|
ReturnToActive RuntimeAction = "return_to_active"
|
|
SwitchTask RuntimeAction = "switch_task"
|
|
EndTransitionForReview RuntimeAction = "end_transition_for_review"
|
|
ContinuePlanning RuntimeAction = "continue_planning"
|
|
EndWorkPeriod RuntimeAction = "end_work_period"
|
|
EnterAdminOverride RuntimeAction = "enter_admin_override"
|
|
ExitAdminOverrideToLocked RuntimeAction = "exit_admin_override_to_locked"
|
|
ExitAdminOverrideToPlanning RuntimeAction = "exit_admin_override_to_planning"
|
|
)
|
|
|
|
type CommitmentAction string
|
|
|
|
const (
|
|
CommitmentActivate CommitmentAction = "activate"
|
|
PauseForTransition CommitmentAction = "pause_for_transition"
|
|
ReturnFromPause CommitmentAction = "return_from_pause"
|
|
Complete CommitmentAction = "complete"
|
|
Abandon CommitmentAction = "abandon"
|
|
Violate CommitmentAction = "violate"
|
|
RecoverExplicitly CommitmentAction = "recover_explicitly"
|
|
)
|
|
|
|
// IllegalTransitionError reports a rejected transition.
|
|
type IllegalTransitionError struct {
|
|
From string
|
|
Action string
|
|
}
|
|
|
|
func (e IllegalTransitionError) Error() string {
|
|
return fmt.Sprintf("illegal transition from %s via %s", e.From, e.Action)
|
|
}
|
|
|
|
// PolicyRejectedError reports an activation attempted with an unaccepted policy.
|
|
type PolicyRejectedError struct{}
|
|
|
|
func (PolicyRejectedError) Error() string { return "policy was rejected" }
|
|
|
|
func TransitionRuntime(current domain.RuntimeState, action RuntimeAction) (domain.RuntimeState, error) {
|
|
type key struct {
|
|
s domain.RuntimeState
|
|
a RuntimeAction
|
|
}
|
|
table := map[key]domain.RuntimeState{
|
|
{domain.RuntimeLocked, EnterPlanning}: domain.RuntimePlanning,
|
|
{domain.RuntimePlanning, ActivateAccepted}: domain.RuntimeActive,
|
|
{domain.RuntimePlanning, CancelOrTimeout}: domain.RuntimeLocked,
|
|
{domain.RuntimeActive, StartTransition}: domain.RuntimeTransition,
|
|
{domain.RuntimeActive, CompleteForReview}: domain.RuntimeReview,
|
|
{domain.RuntimeActive, SevereViolation}: domain.RuntimeLocked,
|
|
{domain.RuntimeTransition, ReturnToActive}: domain.RuntimeActive,
|
|
{domain.RuntimeTransition, SwitchTask}: domain.RuntimePlanning,
|
|
{domain.RuntimeTransition, EndTransitionForReview}: domain.RuntimeReview,
|
|
{domain.RuntimeTransition, CancelOrTimeout}: domain.RuntimeLocked,
|
|
{domain.RuntimeReview, ContinuePlanning}: domain.RuntimePlanning,
|
|
{domain.RuntimeReview, EndWorkPeriod}: domain.RuntimeLocked,
|
|
{domain.RuntimeAdminOverride, ExitAdminOverrideToLocked}: domain.RuntimeLocked,
|
|
{domain.RuntimeAdminOverride, ExitAdminOverrideToPlanning}: domain.RuntimePlanning,
|
|
}
|
|
|
|
if action == ActivateRejected && current == domain.RuntimePlanning {
|
|
return current, PolicyRejectedError{}
|
|
}
|
|
if action == EnterAdminOverride {
|
|
return domain.RuntimeAdminOverride, nil
|
|
}
|
|
if next, ok := table[key{current, action}]; ok {
|
|
return next, nil
|
|
}
|
|
return current, IllegalTransitionError{From: string(current), Action: string(action)}
|
|
}
|
|
|
|
func TransitionCommitment(current domain.CommitmentState, action CommitmentAction) (domain.CommitmentState, error) {
|
|
type key struct {
|
|
s domain.CommitmentState
|
|
a CommitmentAction
|
|
}
|
|
table := map[key]domain.CommitmentState{
|
|
{domain.CommitmentDraft, CommitmentActivate}: domain.CommitmentActive,
|
|
{domain.CommitmentActive, PauseForTransition}: domain.CommitmentPaused,
|
|
{domain.CommitmentPaused, ReturnFromPause}: domain.CommitmentActive,
|
|
{domain.CommitmentActive, Complete}: domain.CommitmentCompleted,
|
|
{domain.CommitmentActive, Abandon}: domain.CommitmentAbandoned,
|
|
{domain.CommitmentActive, Violate}: domain.CommitmentViolated,
|
|
{domain.CommitmentPaused, Abandon}: domain.CommitmentAbandoned,
|
|
{domain.CommitmentViolated, RecoverExplicitly}: domain.CommitmentActive,
|
|
{domain.CommitmentViolated, Abandon}: domain.CommitmentAbandoned,
|
|
}
|
|
if next, ok := table[key{current, action}]; ok {
|
|
return next, nil
|
|
}
|
|
return current, IllegalTransitionError{From: string(current), Action: string(action)}
|
|
}
|