(defpackage #:nekod.selfmod (:use #:cl #:nekod) (:export #:generation-loop #:mutate-spec #:evolve #:fitness #:*generation* #:*population*)) (in-package #:nekod.selfmod) ;; Generation loop: rewrite container definitions based on telemetry (defvar *generation* 0) (defvar *population* nil) ; list of container-specs (defun mutate-spec (spec mutation-rate) "Randomly mutate a container spec for evolutionary optimization." (when (< (random 1.0) mutation-rate) (let ((new-spec (copy-structure spec))) ;; Mutate restart policy (setf (container-spec-restart-policy new-spec) (nth (random 3) '(:always :on-failure :never))) new-spec))) (defun fitness (spec telemetry) "Score a container spec based on runtime telemetry. High uptime + low cpu + low memory = high fitness." (declare (ignore spec)) (let ((uptime (getf telemetry :uptime 0.0)) (cpu (getf telemetry :cpu 0.5)) (memory (getf telemetry :memory 0.5))) (- (* 0.6 uptime) (* 0.2 cpu) (* 0.2 memory)))) (defun evolve (population telemetry &optional (mutation-rate 0.1)) "One generation of evolutionary optimization. Returns new population: survivors + mutants." (incf *generation*) (let* ((scored (mapcar (lambda (s) (cons s (fitness s telemetry))) population)) (sorted (sort scored #'> :key #'cdr)) (survivors (mapcar #'car (subseq sorted 0 (ceiling (length sorted) 2)))) (mutants (remove nil (mapcar (lambda (s) (mutate-spec s mutation-rate)) survivors)))) (append survivors mutants))) (defun generation-loop (population telemetry-fn &key (generations 10) (mutation-rate 0.1) (verbose t)) "Run N generations of evolutionary container optimization. POPULATION: initial list of container-specs TELEMETRY-FN: called each generation, returns plist (:uptime f :cpu f :memory f) Returns the final optimized population." (loop repeat generations for pop = population then (evolve pop telemetry mutation-rate) for telemetry = (funcall telemetry-fn) do (when verbose (format t "Gen ~a: ~a containers, best fitness ~,3f~%" *generation* (length pop) (if pop (fitness (first pop) telemetry) 0.0))) finally (return pop)))