// Package model defines the domain value types shared across the // orchestrator: Host, Run, Stage, SubStep, Measurement, and SpecDiff. // These are plain structs with no behaviour beyond state classification. package model import "time" // Host is a registered hardware node in the vetting cluster. type Host struct { ID int64 Name string MAC string WoLBroadcastIP string WoLPort int ExpectedSpecYAML string PDUConfigJSON string IPMIConfigJSON string Notes string CreatedAt time.Time UpdatedAt time.Time LastSeenAt *time.Time // host-mode agent heartbeat; nil = never seen } // RunState is the current position of a run in the state machine. type RunState string const ( StateRegistered RunState = "Registered" StateQueued RunState = "Queued" StateWaitingWoL RunState = "WaitingWoL" StateWaitingReboot RunState = "WaitingReboot" StateBooting RunState = "Booting" StateInventoryCheck RunState = "InventoryCheck" StateFirmware RunState = "Firmware" StateSpecValidate RunState = "SpecValidate" StateSMART RunState = "SMART" StateCPUStress RunState = "CPUStress" StateStorage RunState = "Storage" StateNetwork RunState = "Network" StateBurn RunState = "Burn" StateGPU RunState = "GPU" StatePSU RunState = "PSU" StateReporting RunState = "Reporting" StateCompleted RunState = "Completed" StateFailed RunState = "Failed" StateFailedHolding RunState = "FailedHolding" StateReleased RunState = "Released" StateCancelled RunState = "Cancelled" ) func (s RunState) IsTerminal() bool { switch s { case StateCompleted, StateFailed, StateFailedHolding, StateReleased, StateCancelled: return true } return false } // Run is a single vetting pass on a host, walking through the stage pipeline. type Run struct { ID int64 HostID int64 State RunState Result string FailedStage string NextBootTarget string AgentTokenHash string StartedAt time.Time CompletedAt *time.Time ReportPath string HoldIP string OverrideFlagsJSON string NonDestructive bool Profile string // quick|deep|soak; empty is treated as "quick" } // StageState tracks whether a stage is pending, running, passed, failed, or skipped. type StageState string const ( StagePending StageState = "pending" StageRunning StageState = "running" StagePassed StageState = "passed" StageFailed StageState = "failed" StageSkipped StageState = "skipped" ) // Stage is a single test step within a run (e.g. SMART, CPUStress, Storage). type Stage struct { ID int64 RunID int64 Name string Ordinal int State StageState StartedAt *time.Time CompletedAt *time.Time SummaryJSON string } // SubStep is a finer-grained unit within a Stage, authored by the agent. // Not every stage has sub-steps; those that do (CPUStress, SMART per-disk, // Storage per-disk, GPU per-device) surface them so the UI can render a // GitHub-Actions-style collapsible list. Sub-steps share the StageState // enum with Stage; Ordinal is 0-based within StageName for a given RunID // and is how the UI and SSE events key each row. type SubStep struct { ID int64 RunID int64 StageName string Ordinal int Name string State StageState StartedAt *time.Time CompletedAt *time.Time SummaryJSON string } // Measurement is a single time-series sample from the thermal sidecar or a stage executor. type Measurement struct { ID int64 RunID int64 StageID *int64 TS time.Time Kind string Key string Value float64 Unit string } // SpecDiff records a single expected-vs-actual hardware divergence from SpecValidate. type SpecDiff struct { ID int64 RunID int64 Field string Expected string Actual string Severity string // critical|warning|info Ignored bool }