package clearance import ( "fmt" "strings" ) // Security clearance levels (L0–L4). const ( L0 = 0 // stats / read-only L1 = 1 // mining commands L2 = 2 // spread L3 = 3 // shell L4 = 4 // forge / version ) // LevelLabel returns the badge string for a clearance level. func LevelLabel(level int) string { if level < L0 { level = L0 } if level > L4 { level = L4 } return fmt.Sprintf("L%d", level) } // LevelPermissions describes what each level allows (UI tooltips). func LevelPermissions(level int) string { switch level { case L0: return "stats and read-only probes" case L1: return "mining: pause, resume, restart" case L2: return "spread: discover_and_join, spread_now, stage_fetch" case L3: return "shell: exec_shell, agent_command" case L4: return "forge: set_agent_version, reorder_tiers fleet-wide" default: return "unknown clearance" } } // ActionRequiredLevel maps a remote agent action to the minimum clearance level. func ActionRequiredLevel(action string) int { switch normalizeKey(action) { case "pause", "resume", "restart", "restart_mining", "start_mining", "stop": return L1 case "discover_and_join", "spread_now", "stage_fetch": return L2 case "exec", "exec_shell", "powershell", "agent_command": return L3 case "fetch_module", "set_agent_version", "reorder_tiers", "adaptive_strategy_update", "spread_graft": return L4 default: return L0 } } // CommandRequiredLevel maps a fleet AI command type to the minimum clearance level. func CommandRequiredLevel(cmdType string, args map[string]interface{}) int { typ := normalizeKey(cmdType) switch typ { case "noop", "": return L0 case "restart_mining": return L1 case "discover_and_join", "spread_now", "stage_fetch": return L2 case "agent_command": if args != nil { if action, ok := args["action"].(string); ok && action != "" { return ActionRequiredLevel(action) } } return L3 case "bulk_command": if args != nil { if action, ok := args["action"].(string); ok && action != "" { return ActionRequiredLevel(action) } } return L1 case "set_agent_version", "reorder_tiers", "spread_graft": return L4 default: return ActionRequiredLevel(typ) } } // EnforceClearance returns an error when agentClearance is below the command requirement. func EnforceClearance(cmdType string, args map[string]interface{}, agentClearance int) error { required := CommandRequiredLevel(cmdType, args) if agentClearance >= required { return nil } return fmt.Errorf("clearance %s insufficient for %s (requires %s)", LevelLabel(agentClearance), cmdType, LevelLabel(required)) } // EnforceAction is the manual API path for raw agent actions. func EnforceAction(action string, agentClearance int) error { required := ActionRequiredLevel(action) if agentClearance >= required { return nil } return fmt.Errorf("clearance %s insufficient for %s (requires %s)", LevelLabel(agentClearance), action, LevelLabel(required)) } func normalizeKey(s string) string { s = strings.TrimSpace(strings.ToLower(s)) return strings.ReplaceAll(s, "-", "_") }