Initial commit: AetherForge Linux (forge-mesh) v0.1.0-dev
Some checks failed
Test / test (push) Has been cancelled
Some checks failed
Test / test (push) Has been cancelled
This commit is contained in:
105
internal/fleet/clearance.go
Normal file
105
internal/fleet/clearance.go
Normal file
@@ -0,0 +1,105 @@
|
||||
package fleet
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Clearance levels gate remote operator actions (L0–L4).
|
||||
const (
|
||||
ClearanceL0 = 0 // view-only
|
||||
ClearanceL1 = 1 // status queries, fleet list
|
||||
ClearanceL2 = 2 // pause/resume mining
|
||||
ClearanceL3 = 3 // reboot, screenshot
|
||||
ClearanceL4 = 4 // shell exec, court verdicts, crucible batch
|
||||
)
|
||||
|
||||
// Action names used by API and dashboard.
|
||||
const (
|
||||
ActionView = "view"
|
||||
ActionStatus = "status"
|
||||
ActionPause = "pause"
|
||||
ActionResume = "resume"
|
||||
ActionReboot = "reboot"
|
||||
ActionScreenshot = "screenshot"
|
||||
ActionShell = "shell"
|
||||
ActionCourt = "court"
|
||||
ActionCrucible = "crucible"
|
||||
)
|
||||
|
||||
// minClearance maps each action to the minimum operator clearance required.
|
||||
var minClearance = map[string]int{
|
||||
ActionView: ClearanceL0,
|
||||
ActionStatus: ClearanceL1,
|
||||
ActionPause: ClearanceL2,
|
||||
ActionResume: ClearanceL2,
|
||||
ActionReboot: ClearanceL3,
|
||||
ActionScreenshot: ClearanceL3,
|
||||
ActionShell: ClearanceL4,
|
||||
ActionCourt: ClearanceL4,
|
||||
ActionCrucible: ClearanceL4,
|
||||
}
|
||||
|
||||
// RequiredClearance returns the minimum clearance for an action.
|
||||
func RequiredClearance(action string) (int, bool) {
|
||||
level, ok := minClearance[action]
|
||||
return level, ok
|
||||
}
|
||||
|
||||
// RequiredClearanceOrZero returns required level or 0 if unknown.
|
||||
func RequiredClearanceOrZero(action string) int {
|
||||
level, _ := minClearance[action]
|
||||
return level
|
||||
}
|
||||
|
||||
// CanPerform checks whether operator clearance satisfies the action gate.
|
||||
func CanPerform(operatorClearance int, action string) bool {
|
||||
required, ok := minClearance[action]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return operatorClearance >= required
|
||||
}
|
||||
|
||||
// ClearanceError describes a denied action.
|
||||
type ClearanceError struct {
|
||||
Action string
|
||||
Required int
|
||||
OperatorClearance int
|
||||
}
|
||||
|
||||
func (e ClearanceError) Error() string {
|
||||
return fmt.Sprintf("action %q requires clearance L%d (operator has L%d)",
|
||||
e.Action, e.Required, e.OperatorClearance)
|
||||
}
|
||||
|
||||
// CheckAction returns ClearanceError when the operator lacks clearance.
|
||||
func CheckAction(operatorClearance int, action string) error {
|
||||
required, ok := minClearance[action]
|
||||
if !ok {
|
||||
return fmt.Errorf("unknown action %q", action)
|
||||
}
|
||||
if operatorClearance < required {
|
||||
return ClearanceError{
|
||||
Action: action,
|
||||
Required: required,
|
||||
OperatorClearance: operatorClearance,
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ClearanceLabel returns a human-readable label for a level.
|
||||
func ClearanceLabel(level int) string {
|
||||
switch level {
|
||||
case ClearanceL0:
|
||||
return "L0 View"
|
||||
case ClearanceL1:
|
||||
return "L1 Status"
|
||||
case ClearanceL2:
|
||||
return "L2 Control"
|
||||
case ClearanceL3:
|
||||
return "L3 Host Ops"
|
||||
case ClearanceL4:
|
||||
return "L4 Root"
|
||||
default:
|
||||
return fmt.Sprintf("L%d", level)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user