lifecycle

package
v1.101.0 Latest Latest
Warning

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

Go to latest
Published: May 3, 2026 License: MPL-2.0 Imports: 4 Imported by: 0

Documentation

Index

Constants

View Source
const OutputSchemaVersion = "1.0"

OutputSchemaVersion is the current version of the lifecycle JSON schema.

Variables

This section is empty.

Functions

func CanProceed

func CanProceed(action Action) bool

CanProceed returns true if the action allows lifecycle to continue.

func RenderJSON

func RenderJSON(w io.Writer, result RunResult) error

RenderJSON writes the RunResult as stable, versioned JSON. Schema version is always set to OutputSchemaVersion. Fields are ordered for readability and stability.

func RenderText

func RenderText(w io.Writer, result RunResult) error

RenderText writes a human-readable summary of the RunResult.

func ResolveAuthority

func ResolveAuthority(prior, desired AuthorityState, detection Detection, force bool) (resulting AuthorityState, action Action, err error)

ResolveAuthority determines the resulting authority state given prior state, desired state, and detection observations.

Rules:

  • NFTBAN + PROTECTED/IDLE → owned and healthy, allow operations
  • NFTBAN + DEGRADED → owned but unsafe, proceed with caution
  • NFTBAN + DOWN → owned but failed, recovery before new lifecycle
  • EXTERNAL + any → may observe but MUST NOT seize without force
  • NONE + any → no managed authority, safe for fresh install

func TransitionDescription

func TransitionDescription(prior, resulting AuthorityState, action Action) string

TransitionDescription returns a human-readable description of the authority transition for logging/evidence.

func ValidMode

func ValidMode(m Mode) bool

ValidMode returns true if m is a recognized lifecycle mode.

Types

type Action

type Action string

Action represents a lifecycle recommendation or decision.

const (
	// ActionNoop means no action needed — current state is acceptable.
	ActionNoop Action = "NOOP"

	// ActionTakeAuthority means lifecycle should take firewall ownership.
	ActionTakeAuthority Action = "TAKE_AUTHORITY"

	// ActionPreserveAuthority means keep current NFTBan ownership.
	ActionPreserveAuthority Action = "PRESERVE_AUTHORITY"

	// ActionAbort means lifecycle cannot proceed safely.
	ActionAbort Action = "ABORT"

	// ActionNeedsRecovery means v1.96 recovery must complete first.
	ActionNeedsRecovery Action = "NEEDS_RECOVERY"
)

type AuthorityOwner

type AuthorityOwner string

AuthorityOwner identifies who currently controls the firewall.

const (
	// AuthorityNFTBan means NFTBan owns the firewall authority.
	// This is valid even when health is DEGRADED — ownership and
	// health are independent dimensions (INV-LC-004).
	AuthorityNFTBan AuthorityOwner = "NFTBAN"

	// AuthorityExternal means another firewall (CSF, UFW, firewalld)
	// controls the system. Lifecycle may observe but MUST NOT seize
	// authority without explicit operator instruction.
	AuthorityExternal AuthorityOwner = "EXTERNAL"

	// AuthorityNone means no managed firewall authority exists.
	// Health should normally be DOWN when owner is NONE.
	AuthorityNone AuthorityOwner = "NONE"

	// AuthorityUnknown means the detection layer could not produce a
	// consistent ownership read. Introduced in PR-22B so the bridge
	// between installer and lifecycle can report Ambiguous host state
	// without silently collapsing it to NFTBAN / EXTERNAL / NONE.
	AuthorityUnknown AuthorityOwner = "UNKNOWN"
)

type AuthorityState

type AuthorityState struct {
	Owner  AuthorityOwner  `json:"owner"`
	Health LifecycleHealth `json:"health"`
}

AuthorityState combines ownership and health into a single assessment. These are INDEPENDENT dimensions — NFTBAN + DEGRADED is a valid state meaning "NFTBan owns the firewall but protection is partial."

func (AuthorityState) IsHealthy

func (a AuthorityState) IsHealthy() bool

IsHealthy returns true if health is PROTECTED or IDLE.

func (AuthorityState) IsOwned

func (a AuthorityState) IsOwned() bool

IsOwned returns true if NFTBan has authority (regardless of health).

func (*AuthorityState) NormalizeNone

func (a *AuthorityState) NormalizeNone()

NormalizeNone ensures that Owner=NONE has health=DOWN unless there is a specific reason otherwise. This prevents confusing states like NONE + PROTECTED.

type Detection

type Detection struct {
	// ConflictingFirewall is true if another firewall (CSF/UFW/firewalld) is active.
	ConflictingFirewall bool `json:"conflicting_firewall"`

	// KernelValid is true if nftables kernel state passes structural checks.
	KernelValid bool `json:"kernel_valid"`

	// ValidatorConsistent is true if validator agrees with kernel state.
	ValidatorConsistent bool `json:"validator_consistent"`

	// SSHSafe is true if SSH port is protected and accessible.
	SSHSafe bool `json:"ssh_safe"`
}

Detection captures system observations during the DETECT stage.

type EventType

type EventType string

EventType classifies lifecycle log events.

const (
	EventDetect EventType = "detect"
	EventPlan   EventType = "plan"
	EventResult EventType = "result"
)

type LastOperation

type LastOperation struct {
	// Result is the v1.96 operation result (SUCCESS, FAILED_RECOVERED, etc.)
	Result string `json:"result"`

	// FailureClass is the v1.96 failure classification (if non-success).
	FailureClass string `json:"failure_class"`

	// RecoveryPending is true if a v1.96 recovery marker exists and is not exhausted.
	RecoveryPending bool `json:"recovery_pending"`

	// LastRebuildFailed is true if the most recent rebuild was non-success.
	// This flag exists for dashboard clarity: health=PROTECTED + last_rebuild_failed=true
	// means "healthy now but just recovered from failure."
	LastRebuildFailed bool `json:"last_rebuild_failed"`
}

LastOperation carries v1.96 operation-result truth into lifecycle output. Lifecycle MUST consume these values from rebuild.RecoveryMarker and validator state — it MUST NOT reinterpret or override them (INV-LC-003).

type LifecycleHealth

type LifecycleHealth string

LifecycleHealth represents the health dimension of authority. These values mirror validator.Status but are defined here to avoid import cycles. The lifecycle engine consumes health from the validator and maps it to these values.

const (
	HealthProtected LifecycleHealth = "PROTECTED"
	HealthIdle      LifecycleHealth = "IDLE"
	HealthDegraded  LifecycleHealth = "DEGRADED"
	HealthDown      LifecycleHealth = "DOWN"
)

type LogEvent

type LogEvent struct {
	Timestamp time.Time `json:"timestamp"`
	Event     EventType `json:"event"`
	Mode      Mode      `json:"mode"`
	DryRun    bool      `json:"dry_run"`
	Data      any       `json:"data"`
}

LogEvent is a structured lifecycle log entry.

type Logger

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

Logger writes structured lifecycle events.

func NewLogger

func NewLogger(w io.Writer, mode Mode, dryRun bool) *Logger

NewLogger creates a lifecycle logger.

func (*Logger) LogDetect

func (l *Logger) LogDetect(authority AuthorityState, detection Detection)

LogDetect records the DETECT stage observations.

func (*Logger) LogPlan

func (l *Logger) LogPlan(plan Plan, lastOp LastOperation)

LogPlan records the PLAN stage decisions.

func (*Logger) LogResult

func (l *Logger) LogResult(result RunResult)

LogResult records the final lifecycle outcome. Explicitly marks whether this was a plan-only or real execution.

type Mode

type Mode string

Mode represents the type of lifecycle operation being performed.

const (
	ModeInstall     Mode = "install"
	ModeUpdate      Mode = "update"
	ModeUninstall   Mode = "uninstall"
	ModeMaintenance Mode = "maintenance"
)

type Outcome

type Outcome string

Outcome represents the high-level result of a lifecycle operation.

Lifecycle Outcome is a high-level orchestration result. Detailed failure semantics remain in v1.96 operation result and failure class fields (rebuild.OperationResult, rebuild.FailureClass). Do not conflate lifecycle FAILED with rebuild FAILED_DEGRADED or FAILED_FATAL — those are distinct levels of specificity.

const (
	// OutcomeSuccess means all stages completed and verification passed.
	OutcomeSuccess Outcome = "SUCCESS"

	// OutcomeFailed means execution failed with no recovery.
	// For detailed failure class, see LastOperation.FailureClass.
	OutcomeFailed Outcome = "FAILED"

	// OutcomeFailedRecovered means execution failed but recovery
	// restored a validated prior state. System may be healthy
	// even though the operation did not achieve its goal.
	OutcomeFailedRecovered Outcome = "FAILED_RECOVERED"
)

type Plan

type Plan struct {
	Actions  []Action `json:"actions"`
	Warnings []string `json:"warnings"`
	Errors   []string `json:"errors"`
}

Plan captures the engine's recommended actions, warnings, and errors.

func (Plan) HasAbort

func (p Plan) HasAbort() bool

HasAbort returns true if the plan contains an ABORT action.

func (Plan) HasRecovery

func (p Plan) HasRecovery() bool

HasRecovery returns true if the plan requires v1.96 recovery first.

type RunResult

type RunResult struct {
	// SchemaVersion for output stability.
	SchemaVersion string `json:"schema_version"`

	// Mode that was requested.
	Mode Mode `json:"mode"`

	// DryRun indicates this was a planning-only run.
	DryRun bool `json:"dry_run"`

	// Stage reached during execution/planning.
	Stage Stage `json:"stage"`

	// Outcome of the lifecycle operation.
	Outcome Outcome `json:"outcome"`

	// Authority shows prior, desired, and resulting authority states.
	Authority struct {
		Prior     AuthorityState `json:"prior"`
		Desired   AuthorityState `json:"desired"`
		Resulting AuthorityState `json:"resulting"`
	} `json:"authority"`

	// LastOperation from v1.96 (passed through, not reinterpreted).
	LastOperation LastOperation `json:"last_operation"`

	// Plan contains recommended actions, warnings, and errors.
	Plan Plan `json:"plan"`

	// Detection from the DETECT stage.
	Detection Detection `json:"detection"`

	// Timestamp of when the result was produced.
	Timestamp time.Time `json:"timestamp"`
}

RunResult is the complete output of a lifecycle engine run. It represents a PLAN, not an execution result (in v1.97).

func ParseRunResult

func ParseRunResult(data []byte) (*RunResult, error)

ParseRunResult deserializes a RunResult from JSON.

func Run

func Run(snap Snapshot) RunResult

Run executes the lifecycle state machine against a snapshot. It is a PURE function — no side effects, no system mutation (INV-LC-001). The engine consumes observed state and produces a plan.

type Snapshot

type Snapshot struct {
	// Mode is the requested lifecycle operation.
	Mode Mode `json:"mode"`

	// DryRun is true if this is a planning-only run (INV-LC-001).
	DryRun bool `json:"dry_run"`

	// CurrentAuthority is the observed authority state.
	CurrentAuthority AuthorityState `json:"current_authority"`

	// LastOperation carries v1.96 operation-result ground truth.
	LastOperation LastOperation `json:"last_operation"`

	// Detection carries system observations from the DETECT stage.
	Detection Detection `json:"detection"`
}

Snapshot captures the current system state as input to the lifecycle engine. All fields must be populated from real system observations (validator, recovery marker, service state, conflict detection) — never guessed.

type Stage

type Stage string

Stage represents a phase in the lifecycle execution pipeline. Stages are sequential: DETECT → PLAN → APPLY → VERIFY → FINAL.

const (
	StageDetect Stage = "DETECT"
	StagePlan   Stage = "PLAN"
	StageApply  Stage = "APPLY"
	StageVerify Stage = "VERIFY"
	StageFinal  Stage = "FINAL"
)

Jump to

Keyboard shortcuts

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