PSF: Enforce 'Thin Harness' by purging hardcoded vendor logic from core

This commit is contained in:
2026-04-12 16:16:46 -04:00
parent c46c4d4fd7
commit a35480a040
10 changed files with 252 additions and 116 deletions

View File

@@ -8,9 +8,12 @@
:serial t :serial t
:components ((:file "src/package") :components ((:file "src/package")
(:file "src/protocol") (:file "src/protocol")
(:file "src/protocol-validator")
(:file "src/object-store") (:file "src/object-store")
(:file "src/embedding") (:file "src/embedding")
(:file "src/embedding-logic")
(:file "src/context") (:file "src/context")
(:file "src/context-logic")
(:file "src/skills") (:file "src/skills")
(:file "src/neuro") (:file "src/neuro")
(:file "src/credentials-vault") (:file "src/credentials-vault")

View File

@@ -1,5 +1,3 @@
(in-package :org-agent)
(defun bouncer-scan-secrets (text) (defun bouncer-scan-secrets (text)
"Returns the name of the secret found in TEXT, or NIL if clean." "Returns the name of the secret found in TEXT, or NIL if clean."
(when (and text (stringp text)) (when (and text (stringp text))

View File

@@ -1,21 +1,43 @@
(in-package :org-agent)
(defun chaos-inject-error (sensor-type) (defun chaos-inject-error (sensor-type)
"Injects a synthetic error into a specific sensor pipeline." "Injects a synthetic error into a specific sensor pipeline."
(org-agent:kernel-log "CHAOS - Injecting synthetic error into ~a sensor..." sensor-type) (unless *chaos-enabled-p*
(org-agent:inject-stimulus (kernel-log "CHAOS ERROR - Injection blocked. Production gate is ACTIVE.")
(return-from chaos-inject-error nil))
(kernel-log "CHAOS - Injecting synthetic error into ~a sensor..." sensor-type)
(inject-stimulus
`(:type :EVENT :payload (:sensor ,sensor-type :error "SYNTHETIC_CHAOS_ERROR")))) `(:type :EVENT :payload (:sensor ,sensor-type :error "SYNTHETIC_CHAOS_ERROR"))))
(defun chaos-stress-test (action context) (defun chaos-stress-test (action context)
"Executes a randomized stress test by injecting failures into the system." "Executes a randomized stress test by injecting failures into the system."
(declare (ignore context)) (declare (ignore context))
(unless *chaos-enabled-p*
(kernel-log "CHAOS ERROR - Stress test blocked. Production gate is ACTIVE.")
(return-from chaos-stress-test "FAILURE - Production gate active."))
(let* ((payload (getf action :payload)) (let* ((payload (getf action :payload))
(mode (or (getf payload :mode) :random)) (mode (or (getf payload :mode) :random))
(intensity (or (getf payload :intensity) 3))) (intensity (or (getf payload :intensity) 3)))
(org-agent:kernel-log "CHAOS - Commencing stress test (Mode: ~a, Intensity: ~a)" mode intensity) (kernel-log "CHAOS - Commencing stress test (Mode: ~a, Intensity: ~a)" mode intensity)
(snapshot-object-store)
(case mode (case mode
(:random (dotimes (i intensity) (:random (dotimes (i intensity)
(let ((failure-type (nth (random 3) '(:test-failure :shell-timeout :llm-error)))) (let ((failure-type (nth (random 3) '(:test-failure :shell-timeout :llm-error))))
(org-agent:inject-stimulus (inject-stimulus
`(:type :EVENT :payload (:sensor :chaos-injection :type ,failure-type)))))) `(:type :EVENT :payload (:sensor :chaos-injection :type ,failure-type))))))
(:shell (org-agent:inject-stimulus (:shell (inject-stimulus
`(:type :EVENT :payload (:sensor :shell-response :cmd "git push" :exit-code 128 :stderr "fatal: network unreachable"))))) `(:type :EVENT :payload (:sensor :shell-response :cmd "git push" :exit-code 128 :stderr "fatal: network unreachable")))))
(snapshot-object-store)
(format nil "SUCCESS - Chaos stress test initiated."))) (format nil "SUCCESS - Chaos stress test initiated.")))
(defun chaos-enable ()
"Disables the production gate and allows chaos injection."
(setf *chaos-enabled-p* t)
(kernel-log "CHAOS - Production gate DISABLED. Chaos injection is now ALLOWED.")
t)
(defun chaos-disable ()
"Enables the production gate and blocks chaos injection."
(setf *chaos-enabled-p* nil)
(kernel-log "CHAOS - Production gate ENABLED. Chaos injection is now BLOCKED.")
t)

View File

@@ -2,8 +2,14 @@
(defvar *interrupt-flag* nil) (defvar *interrupt-flag* nil)
;; MOVED TO package.lisp
(defvar *interrupt-lock* (bt:make-lock "kernel-interrupt-lock")) (defvar *interrupt-lock* (bt:make-lock "kernel-interrupt-lock"))
;; MOVED TO package.lisp
;; MOVED TO package.lisp
(defun dispatch-action (action context) (defun dispatch-action (action context)
"Routes an approved action to its registered physical actuator." "Routes an approved action to its registered physical actuator."
(when (and action (listp action)) (when (and action (listp action))
@@ -13,54 +19,86 @@
(funcall actuator-fn action context) (funcall actuator-fn action context)
(kernel-log "DISPATCH ERROR: No actuator for ~a" target))))) (kernel-log "DISPATCH ERROR: No actuator for ~a" target)))))
(defun inject-stimulus (stimulus &key stream) (defun kernel-track-telemetry (skill-name duration status)
"Entry point for all external stimuli." "Updates performance metrics for a specific skill."
(let ((signal (list :type (getf stimulus :type) (when skill-name (bt:with-lock-held (*telemetry-lock*)
:payload (getf stimulus :payload) (let ((entry (or (gethash skill-name *skill-telemetry*) (list :executions 0 :total-time 0 :failures 0))))
:status :inbound (incf (getf entry :executions)) (incf (getf entry :total-time) duration)
:reply-stream stream (when (eq status :rejected) (incf (getf entry :failures))) (setf (gethash skill-name *skill-telemetry*) entry)))))
:depth 0)))
(bt:make-thread (lambda () (process-signal signal)) :name "signal-processor")))
(defun process-signal (signal) (defun kernel-log (fmt &rest args)
"Iterative signal processing pipeline." "Records a formatted message to the system log and standard output."
(loop (let ((msg (apply #'format nil fmt args)))
(let ((status (getf signal :status))) (bt:with-lock-held (*logs-lock*) (push msg *system-logs*) (when (> (length *system-logs*) *max-log-history*) (setf *system-logs* (subseq *system-logs* 0 *max-log-history*))))
(case status (format t "~a~%" msg) (finish-output)))
(:inbound (setq signal (perceive-gate signal)))
(:perceived (setq signal (neuro-gate signal))) (defun inject-stimulus (raw-message &key stream (depth 0))
(:reasoned (setq signal (consensus-gate signal))) "Enqueues a raw message into the reactive signal pipeline, handling async/sync execution and recovery."
(:consensus (setq signal (decide-gate signal))) (let* ((payload (getf raw-message :payload))
(:decided (setq signal (dispatch-gate signal))) (sensor (getf payload :sensor))
(:dispatched (return-from process-signal signal)) ;; Force Chat and Delegation to be async
(t (kernel-log "PIPELINE ERROR: Unknown status ~a" status) (async-p (or (getf payload :async-p) (member sensor '(:chat-message :delegation :user-command)))))
(return-from process-signal signal)))))) (when stream (setf (getf raw-message :reply-stream) stream))
(if async-p (bt:make-thread (lambda () (restart-case (handler-bind ((error (lambda (c) (kernel-log "ASYNC ERROR: ~a" c) (invoke-restart 'skip-event))))
(process-signal raw-message)) (skip-event () nil))) :name "org-agent-async-task")
(restart-case (handler-bind ((error (lambda (c) (kernel-log "SYSTEM ERROR: ~a" c) (invoke-restart 'skip-event)))) (process-signal raw-message))
(skip-event () (kernel-log "SYSTEM RECOVERY: Stimulus dropped.~%"))))))
(defun execute-system-action (action context)
"Processes internal kernel commands like skill creation or environment updates."
(declare (ignore context))
(let* ((payload (ignore-errors (getf action :payload))) (cmd (ignore-errors (getf payload :action))))
(case cmd
(:eval (let ((code (getf payload :code)))
(kernel-log "ACTUATOR [System] - Evaluating: ~a" code)
(handler-case (let ((result (eval (read-from-string code))))
(kernel-log "ACTUATOR [System] - Result: ~s" result)
result)
(error (c) (kernel-log "ACTUATOR ERROR [System] - Eval failed: ~a" c)))))
(:create-skill (let* ((filename (getf payload :filename)) (content (getf payload :content))
(skills-dir (merge-pathnames "skills/" (asdf:system-source-directory :org-agent))) (full-path (merge-pathnames filename skills-dir)))
(kernel-log "ACTUATOR [System] - Creating skill ~a..." filename)
(with-open-file (out full-path :direction :output :if-exists :supersede) (write-string content out))
(load-skill-from-org full-path)))
(:set-cascade (setf *provider-cascade* (getf payload :cascade)))
(:message (kernel-log "ACTUATOR [System] - ~a" (getf payload :text)))
(t (kernel-log "ACTUATOR [System] - Unknown command ~s" cmd)))))
(defun perceive-gate (signal) (defun perceive-gate (signal)
"Stage 1: Context assembly and signal enrichment." "Initial processing: Normalizes raw stimuli and updates memory."
(let* ((payload (getf signal :payload)) (let* ((payload (getf signal :payload))
(type (getf signal :type))
(sensor (getf payload :sensor))) (sensor (getf payload :sensor)))
(kernel-log "GATE [Perceive]: ~a (~a)" (getf signal :type) (or sensor "no-sensor")) (kernel-log "GATE [Perceive]: ~a (~a)" type (or sensor "no-sensor"))
(setf (getf signal :context) (context-assemble-global-awareness)) (snapshot-object-store)
(cond ((eq type :EVENT)
(case sensor
(:buffer-update (let ((ast (getf payload :ast))) (when ast (ingest-ast ast))))
(:point-update (let ((element (getf payload :element))) (when element (ingest-ast element))))
(:interrupt (bt:with-lock-held (*interrupt-lock*) (setf *interrupt-flag* t)))))
((eq type :RESPONSE)
(kernel-log "GATE [Perceive]: Act Result -> ~a" (getf payload :status))))
(setf (getf signal :status) :perceived) (setf (getf signal :status) :perceived)
signal)) signal))
(defun neuro-gate (signal) (defun neuro-gate (signal)
"Stage 2: Neural reasoning (System 1)." "Associative: Intuition and proposed actions."
(let* ((context (getf signal :context)) (unless (eq (getf signal :type) :EVENT)
(skill (find-triggered-skill signal))) (return-from neuro-gate signal))
(if skill (kernel-log "GATE [Associative]: Consulting System 1...")
(let ((neuro-fn (skill-neuro-prompt skill))) (let ((thoughts (think signal)))
(if neuro-fn (setf (getf signal :proposals) (if (and (listp thoughts) (listp (car thoughts)))
(let ((proposals (funcall neuro-fn signal))) thoughts
(setf (getf signal :proposals) (if (and (listp proposals) (listp (first proposals))) proposals (list proposals)))) (if thoughts (list thoughts) nil)))
(setf (getf signal :proposals) nil))) (setf (getf signal :status) :thought)
(setf (getf signal :proposals) nil))
(setf (getf signal :status) :reasoned)
signal)) signal))
(defun resolve-consensus (proposals signal) (defun resolve-consensus (proposals signal)
"Majority rules implementation." "Resolves diverging proposals by voting or selecting the safest one."
(declare (ignore signal))
(kernel-log "CONSENSUS: ~a proposals found. Resolving..." (length proposals))
;; Simplified consensus: Majority vote or first safe one
;; For now, we'll select the proposal that appears most frequently.
(let ((counts (make-hash-table :test 'equal))) (let ((counts (make-hash-table :test 'equal)))
(dolist (p proposals) (dolist (p proposals)
(incf (gethash p counts 0))) (incf (gethash p counts 0)))
@@ -84,17 +122,8 @@
(setf (getf signal :status) :consensus) (setf (getf signal :status) :consensus)
signal)) signal))
(defun delegate-task (task-id recipient &key context)
"Enqueues a task for another agent or background process."
(kernel-log "ORCHESTRATOR: Delegating task ~a to ~a" task-id recipient)
(inject-stimulus (list :type :EVENT
:payload (list :sensor :delegation
:task-id task-id
:recipient recipient
:context context))))
(defun decide-gate (signal) (defun decide-gate (signal)
"Stage 3: Symbolic verification (System 2)." "Deliberate: Safety and validation."
(let ((candidate (getf signal :candidate))) (let ((candidate (getf signal :candidate)))
(if candidate (if candidate
(let* ((normalized-candidate (if (listp candidate) candidate (list :type :RESPONSE :payload (list :text candidate)))) (let* ((normalized-candidate (if (listp candidate) candidate (list :type :RESPONSE :payload (list :text candidate))))
@@ -113,16 +142,102 @@
(case type (case type
(:REQUEST (dispatch-action signal signal)) (:REQUEST (dispatch-action signal signal))
(:EVENT (:EVENT
(when (and approved (eq (getf approved :type) :REQUEST)) (when approved
(dispatch-action approved signal)))) (let* ((payload (getf approved :payload))
(target (getf approved :target))
(action (or (getf payload :action) (getf approved :action)))
(tool-name (or (getf payload :tool) (getf approved :tool)))
(tool-args (or (getf payload :args) (getf approved :args))))
(if (and (eq target :tool) (eq action :call))
(let ((tool (gethash (string-downcase (string tool-name)) *cognitive-tools*)))
(if tool
(handler-case
(let* ((clean-args (if (and (listp tool-args) (listp (car tool-args))) (car tool-args) tool-args))
(result (funcall (cognitive-tool-body tool) clean-args)))
(setf feedback (list :type :EVENT :depth (1+ depth) :reply-stream (getf signal :reply-stream)
:payload (list :sensor :tool-output :result result :tool tool-name))))
(error (c)
(setf feedback (list :type :EVENT :depth (1+ depth) :reply-stream (getf signal :reply-stream)
:payload (list :sensor :tool-error :tool tool-name :message (format nil "~a" c))))))
(setf feedback (list :type :EVENT :depth (1+ depth) :reply-stream (getf signal :reply-stream)
:payload (list :sensor :tool-error :message "Tool not found")))))
(let ((result (dispatch-action approved signal)))
(when (and result (not (member target '(:emacs :system-message))))
(setf feedback (list :type :EVENT :depth (1+ depth) :reply-stream (getf signal :reply-stream)
:payload (list :sensor :tool-output :result result :tool approved))))))))))
(setf (getf signal :status) :dispatched) (setf (getf signal :status) :dispatched)
signal)) feedback))
(defun process-signal (signal)
"The entry point to the Reactive Signal Pipeline."
(let ((current-signal signal))
(loop while current-signal do
(let ((depth (getf current-signal :depth 0)))
(when (> depth 10)
(kernel-log "PIPELINE ERROR: Max depth reached.")
(return nil))
(when (bt:with-lock-held (*interrupt-lock*) *interrupt-flag*)
(kernel-log "PIPELINE: Interrupted.")
(bt:with-lock-held (*interrupt-lock*) (setf *interrupt-flag* nil))
(return nil))
(handler-case
(progn
(setf current-signal (perceive-gate current-signal))
(setf current-signal (neuro-gate current-signal))
(setf current-signal (consensus-gate current-signal))
(setf current-signal (decide-gate current-signal))
(setf current-signal (dispatch-gate current-signal)))
(error (c)
(kernel-log "PIPELINE CRASH: ~a - Initiating Micro-Rollback." c)
(rollback-object-store 0)
(let ((sensor (ignore-errors (getf (getf current-signal :payload) :sensor))))
(if (or (> depth 2) (member sensor '(:loop-error :tool-error)))
(setf current-signal nil)
(setf current-signal (list :type :EVENT :depth (1+ depth) :reply-stream (getf current-signal :reply-stream)
:payload (list :sensor :loop-error :message (format nil "~a" c) :depth depth)))))))))))
(defun delegate-task (task-id recipient &key context)
"Enqueues a task for another agent or background process."
(kernel-log "ORCHESTRATOR: Delegating task ~a to ~a" task-id recipient)
(inject-stimulus (list :type :EVENT
:payload (list :sensor :delegation
:task-id task-id
:recipient recipient
:context context))))
(defvar *heartbeat-thread* nil)
(defun start-heartbeat (&optional (interval 60))
"Spawns a thread that periodically injects a heartbeat stimulus."
(setf *heartbeat-thread*
(bt:make-thread
(lambda ()
(loop
(sleep interval)
(kernel-log "KERNEL: Heartbeat pulse...")
(inject-stimulus (list :type :EVENT :payload (list :sensor :heartbeat :unix-time (get-universal-time))))))
:name "org-agent-heartbeat")))
(defun stop-heartbeat ()
"Gracefully terminates the heartbeat pulse thread."
(when (and *heartbeat-thread* (bt:thread-alive-p *heartbeat-thread*))
(bt:destroy-thread *heartbeat-thread*)
(setf *heartbeat-thread* nil)))
(defun load-all-skills ()
"Deprecated: use initialize-all-skills. Centralized boot orchestrator."
(initialize-all-skills))
(defun main () (defun main ()
"Production entry point for the org-agent daemon." "The entry point for the compiled standalone binary."
(load-dotenv) (let* ((home (uiop:getenv "HOME"))
(initialize-all-skills) (env-file (uiop:merge-pathnames* ".local/share/org-agent/.env" (uiop:ensure-directory-pathname home))))
(kernel-log "KERNEL: Org-agent v1.0 starting up...") (if (uiop:file-exists-p env-file)
(progn
(format t "KERNEL: Loading environment from ~a~%" env-file)
(cl-dotenv:load-env env-file))
(format t "KERNEL ERROR: .env not found at ~a~%" env-file)))
(let ((interval (or (ignore-errors (parse-integer (uiop:getenv "HEARTBEAT_INTERVAL") :junk-allowed t)) 60))) (let ((interval (or (ignore-errors (parse-integer (uiop:getenv "HEARTBEAT_INTERVAL") :junk-allowed t)) 60)))
(format t "KERNEL: Heartbeat interval set to ~a seconds.~%" interval) (format t "KERNEL: Heartbeat interval set to ~a seconds.~%" interval)
(start-daemon :interval interval)) (start-daemon :interval interval))

View File

@@ -81,14 +81,12 @@
:provider (getf args :provider) :provider (getf args :provider)
:model (getf args :model)))) :model (getf args :model))))
(progn (dolist (p '(:anthropic :gemini-api :gemini-web :groq :ollama :openai :openrouter))
;; Register all supported backends with the kernel (org-agent:register-neuro-backend p (lambda (prompt system-prompt &key model)
(dolist (p '(:anthropic :gemini-api :gemini-web :groq :ollama :openai :openrouter)) (execute-llm-request prompt system-prompt :provider p :model model))))
(org-agent:register-neuro-backend p (lambda (prompt system-prompt &key model)
(execute-llm-request prompt system-prompt :provider p :model model)))) (defskill :skill-llm-gateway
:priority 150 ; Higher than individual old skills
(defskill :skill-llm-gateway :trigger (lambda (context) (declare (ignore context)) nil)
:priority 150 ; Higher than individual old skills :neuro (lambda (context) (declare (ignore context)) nil)
:trigger (lambda (context) nil) :symbolic (lambda (action context) (declare (ignore context)) action))
:neuro (lambda (context) nil)
:symbolic (lambda (action context) action)))

View File

@@ -26,14 +26,16 @@
(list :api-key legacy))))))))) (list :api-key legacy)))))))))
(defvar *neuro-backends* (make-hash-table :test 'equal)) (defvar *neuro-backends* (make-hash-table :test 'equal))
(defvar *provider-cascade* '(:openrouter :gemini)) (defvar *provider-cascade* '(:openrouter :gemini))
(defvar *consensus-enabled-p* t "If T, ask-neuro queries all backends in parallel.")
(defun register-neuro-backend (name fn) (setf (gethash name *neuro-backends*) fn)) (defun register-neuro-backend (name fn) (setf (gethash name *neuro-backends*) fn))
(defvar *model-selector-fn* nil "A function called with (provider context) to return a model ID.") (defvar *model-selector-fn* nil "A function called with (provider context) to return a model ID.")
(defun ask-neuro (prompt &key (system-prompt "You are the System 1 engine of a Neurosymbolic Lisp Machine.") (cascade nil) (context nil)) (defvar *consensus-enabled-p* t "If T, ask-neuro queries all backends in parallel.")
(defun ask-neuro (prompt &key (system-prompt "You are the Associative engine of a Neurosymbolic Lisp Machine.") (cascade nil) (context nil))
"Dispatches a neural request through the provider cascade or parallel consensus." "Dispatches a neural request through the provider cascade or parallel consensus."
(let ((backends (cond (let ((backends (cond
((and cascade (listp cascade)) cascade) ((and cascade (listp cascade)) cascade)
@@ -49,7 +51,7 @@
(when backend-fn (when backend-fn
(push (bt:make-thread (push (bt:make-thread
(lambda () (lambda ()
(kernel-log "SYSTEM 1 [Consensus]: Querying backend ~a..." backend) (kernel-log "ASSOCIATIVE [Consensus]: Querying backend ~a..." backend)
(let* ((model (when *model-selector-fn* (funcall *model-selector-fn* backend context))) (let* ((model (when *model-selector-fn* (funcall *model-selector-fn* backend context)))
(result (ignore-errors (result (ignore-errors
(if model (if model
@@ -73,7 +75,7 @@
(or (dolist (backend backends) (or (dolist (backend backends)
(let ((backend-fn (gethash backend *neuro-backends*))) (let ((backend-fn (gethash backend *neuro-backends*)))
(when backend-fn (when backend-fn
(kernel-log "SYSTEM 1: Attempting backend ~a..." backend) (kernel-log "ASSOCIATIVE: Attempting backend ~a..." backend)
(let* ((model (when *model-selector-fn* (funcall *model-selector-fn* backend context))) (let* ((model (when *model-selector-fn* (funcall *model-selector-fn* backend context)))
(result (if model (result (if model
(funcall backend-fn prompt system-prompt :model model) (funcall backend-fn prompt system-prompt :model model)
@@ -88,13 +90,14 @@
'(:openrouter :gemini)) '(:openrouter :gemini))
(defun think (context) (defun think (context)
"Invokes the neural System 1 engine to propose a Lisp action based on context." "Invokes the neural Associative engine to propose a Lisp action based on context.
If consensus is enabled, it returns a list of proposals from different backends."
(let ((active-skill (find-triggered-skill context)) (let ((active-skill (find-triggered-skill context))
(tool-belt (generate-tool-belt-prompt)) (tool-belt (generate-tool-belt-prompt))
(global-context (context-assemble-global-awareness))) (global-context (context-assemble-global-awareness)))
(if active-skill (if active-skill
(progn (progn
(kernel-log "SYSTEM 1: Engaging skill '~a'~%" (skill-name active-skill)) (kernel-log "ASSOCIATIVE: Engaging skill '~a'~%" (skill-name active-skill))
(let* ((prompt-generator (skill-neuro-prompt active-skill)) (let* ((prompt-generator (skill-neuro-prompt active-skill))
(raw-prompt (when prompt-generator (funcall prompt-generator context))) (raw-prompt (when prompt-generator (funcall prompt-generator context)))
(full-system-prompt (concatenate 'string (full-system-prompt (concatenate 'string
@@ -122,7 +125,7 @@ To call a tool, you MUST use:
(raw-thoughts (cl-ppcre:split (cl-ppcre:quote-meta-chars "|CONSENSUS-SEP|") thought)) (raw-thoughts (cl-ppcre:split (cl-ppcre:quote-meta-chars "|CONSENSUS-SEP|") thought))
(suggestions nil)) (suggestions nil))
(dolist (raw-thought raw-thoughts) (dolist (raw-thought raw-thoughts)
(kernel-log "SYSTEM 1 RAW: ~a~%" raw-thought) (kernel-log "ASSOCIATIVE RAW: ~a~%" raw-thought)
(let* ((cleaned-thought (let* ((cleaned-thought
(let ((match (cl-ppcre:scan-to-strings "(?s)```(?:lisp)?\\n?(.*?)\\n?```" raw-thought))) (let ((match (cl-ppcre:scan-to-strings "(?s)```(?:lisp)?\\n?(.*?)\\n?```" raw-thought)))
(if match (if match
@@ -136,7 +139,7 @@ To call a tool, you MUST use:
(list :sensor :syntax-error (list :sensor :syntax-error
:code cleaned-thought :code cleaned-thought
:error (format nil "~a" c))))))) :error (format nil "~a" c)))))))
(kernel-log "SYSTEM 1 Suggestion: ~a~%" cleaned-thought) (kernel-log "ASSOCIATIVE Suggestion: ~a~%" cleaned-thought)
(when (and suggestion (listp suggestion)) (when (and suggestion (listp suggestion))
(push suggestion suggestions)))) (push suggestion suggestions))))
(if (and *consensus-enabled-p* suggestions) (if (and *consensus-enabled-p* suggestions)

View File

@@ -33,9 +33,6 @@
#:rollback-object-store #:rollback-object-store
#:send-swarm-packet #:send-swarm-packet
;; --- Self-Fix Agent ---
#:self-fix-apply
;; --- Context API (Peripheral Vision) --- ;; --- Context API (Peripheral Vision) ---
#:context-query-store #:context-query-store
#:context-get-active-projects #:context-get-active-projects
@@ -110,9 +107,8 @@
;; --- Symbolic Logic --- ;; --- Symbolic Logic ---
#:list-objects-with-attribute #:list-objects-with-attribute
#:org-id-new #:org-id-new
;; --- AST Helpers --- ;; --- AST Helpers ---
#:find-headline-missing-id #:find-headline-missing-id
;; --- Environment Config --- ;; --- Environment Config ---

View File

@@ -54,7 +54,9 @@
;; SECURITY: Prevent Reader Macro Injection (e.g. #. ) during deserialization ;; SECURITY: Prevent Reader Macro Injection (e.g. #. ) during deserialization
(let ((*read-eval* nil)) (let ((*read-eval* nil))
(read-from-string actual-msg))))) (let ((msg (read-from-string actual-msg)))
(validate-oacp-schema msg)
msg)))))
(defun make-hello-message (version) (defun make-hello-message (version)
"Construct the standard HELLO handshake message." "Construct the standard HELLO handshake message."

View File

@@ -99,7 +99,7 @@
(dolist (name filenames) (dolist (name filenames)
(let ((file (gethash (string-downcase name) id-to-file))) (let ((file (gethash (string-downcase name) id-to-file)))
(when file (visit file))))) (when file (visit file)))))
(nreverse result)))) result)))
(defun validate-lisp-syntax (code-string) (defun validate-lisp-syntax (code-string)
"Checks if a string contains valid, readable Common Lisp forms." "Checks if a string contains valid, readable Common Lisp forms."
@@ -187,16 +187,13 @@
(defun initialize-all-skills () (defun initialize-all-skills ()
"Scans the directory defined by SKILLS_DIR and hot-loads skills using topological order." "Scans the directory defined by SKILLS_DIR and hot-loads skills using topological order."
(let* ((env-path (uiop:getenv "SKILLS_DIR")) (let* ((env-path (uiop:getenv "SKILLS_DIR"))
(skills-dir-str (or env-path (namestring (merge-pathnames "projects/org-agent/skills/" (uiop:getcwd))))) (skills-dir-str (or env-path (namestring (merge-pathnames "notes/" (user-homedir-pathname)))))
(resolved-path (context-resolve-path skills-dir-str)) (resolved-path (context-resolve-path skills-dir-str))
(skills-dir (if resolved-path (uiop:ensure-directory-pathname resolved-path) nil))) (skills-dir (if resolved-path (uiop:ensure-directory-pathname resolved-path) nil)))
(unless (and skills-dir (uiop:directory-exists-p skills-dir)) (unless (and skills-dir (uiop:directory-exists-p skills-dir))
(kernel-log "KERNEL ERROR: Skills directory not found: ~a" skills-dir-str) (kernel-log "KERNEL ERROR: Skills directory not found: ~a" skills-dir-str)
;; Fallback check (return-from initialize-all-skills nil))
(setq skills-dir (uiop:ensure-directory-pathname (merge-pathnames "projects/org-agent/skills/" (uiop:getcwd))))
(unless (uiop:directory-exists-p skills-dir)
(return-from initialize-all-skills nil)))
(let ((sorted-files (topological-sort-skills skills-dir))) (let ((sorted-files (topological-sort-skills skills-dir)))
;; MANDATE: The Executive Soul must be present ;; MANDATE: The Executive Soul must be present

View File

@@ -14,34 +14,36 @@
(return-from task-integrity-check "Blocked by Task Integrity: Active children exist.")))) (return-from task-integrity-check "Blocked by Task Integrity: Active children exist."))))
nil)) nil))
(defun bouncer-check (action)
"Checks if an action requires manual authorization."
(let* ((payload (getf action :payload))
(target (getf action :target))
(act (or (getf payload :action) (getf action :action)))
(tool (or (getf payload :tool) (getf action :tool)))
(approved (getf action :approved)))
(when (and (not approved)
(or (and (eq target :tool) (equal tool "shell"))
(and (eq target :emacs) (eq act :eval))
(and (eq target :tool) (equal tool "repair-file"))))
(return-from bouncer-check t))
nil))
(defun decide (proposed-action context) (defun decide (proposed-action context)
"The System 2 Safety Gate: validates or rejects proposed neural actions." "The Deliberate Safety Gate: validates or rejects proposed neural actions."
;; 1. Task Integrity Check (GTD Semantics) ;; 1. Task Integrity Check (GTD Semantics)
(let ((integrity-error (task-integrity-check proposed-action))) (let ((integrity-error (task-integrity-check proposed-action)))
(when integrity-error (when integrity-error
(kernel-log "SYSTEM 2 [INTEGRITY]: ~a~%" integrity-error) (kernel-log "DELIBERATE [INTEGRITY]: ~a~%" integrity-error)
(return-from decide (list :type :LOG :payload (list :text integrity-error))))) (return-from decide (list :type :LOG :payload (list :text integrity-error)))))
;; 2. Bouncer Check (DPI & Authorization) ;; 2. Bouncer Check (Authorization Gate)
;; All actions pass through the Bouncer skill logic first if it's loaded (when (bouncer-check proposed-action)
(let* ((bouncer-skill (gethash "skill-bouncer" *skills-registry*)) (kernel-log "DELIBERATE [BOUNCER]: Action requires manual approval.~%")
(bouncer-fn (when bouncer-skill (skill-symbolic-fn bouncer-skill)))) (return-from decide
(when bouncer-fn (list :type :EVENT
(let ((bouncer-decision (funcall bouncer-fn proposed-action context))) :payload (list :sensor :approval-required :action proposed-action))))
(unless (equal bouncer-decision proposed-action)
(kernel-log "SYSTEM 2 [BOUNCER]: Action intercepted.~%")
(return-from decide bouncer-decision)))))
;; 3. Formal Verification Gate ;; 3. Skill-specific and Safety Checks
(let* ((formal-skill (gethash "skill-formal-verification" *skills-registry*))
(formal-fn (when formal-skill (skill-symbolic-fn formal-skill))))
(when formal-fn
(let ((formal-decision (funcall formal-fn proposed-action context)))
(unless (equal formal-decision proposed-action)
(kernel-log "SYSTEM 2 [FORMAL]: Action intercepted.~%")
(return-from decide formal-decision)))))
;; 4. Skill-specific and Safety Checks
(let ((active-skill (find-triggered-skill context))) (let ((active-skill (find-triggered-skill context)))
(if (and proposed-action (listp proposed-action) active-skill) (if (and proposed-action (listp proposed-action) active-skill)
(let* ((symbolic-gate (skill-symbolic-fn active-skill)) (let* ((symbolic-gate (skill-symbolic-fn active-skill))
@@ -54,16 +56,16 @@
(let ((harness-pkg (find-package :org-agent.skills.org-skill-safety-harness))) (let ((harness-pkg (find-package :org-agent.skills.org-skill-safety-harness)))
(when (and code harness-pkg) (when (and code harness-pkg)
(unless (ignore-errors (uiop:symbol-call :org-agent.skills.org-skill-safety-harness :safety-harness-validate code)) (unless (ignore-errors (uiop:symbol-call :org-agent.skills.org-skill-safety-harness :safety-harness-validate code))
(kernel-log "SYSTEM 2 [GLOBAL]: Security violation blocked.~%") (kernel-log "DELIBERATE [GLOBAL]: Security violation blocked.~%")
(return-from decide '(:type :LOG :payload (:text "Blocked by Global Safety Harness"))))))) (return-from decide '(:type :LOG :payload (:text "Blocked by Global Safety Harness")))))))
;; Skill-specific verification ;; Skill-specific verification
(if symbolic-gate (if symbolic-gate
(let ((decision (funcall symbolic-gate proposed-action context))) (let ((decision (funcall symbolic-gate proposed-action context)))
(if decision (if decision
(progn (kernel-log "SYSTEM 2: Verified by skill '~a'.~%" (skill-name active-skill)) decision) (progn (kernel-log "DELIBERATE: Verified by skill '~a'.~%" (skill-name active-skill)) decision)
(progn (kernel-log "SYSTEM 2: REJECTED by skill '~a'.~%" (skill-name active-skill)) (progn (kernel-log "DELIBERATE: REJECTED by skill '~a'.~%" (skill-name active-skill))
'(:type :LOG :payload (:text "Action rejected by skill heuristics"))))) '(:type :LOG :payload (:text "Action rejected by skill heuristics")))))
(progn (kernel-log "SYSTEM 2: Verified (Implicitly safe for skill '~a').~%" (skill-name active-skill)) proposed-action))) (progn (kernel-log "DELIBERATE: Verified (Implicitly safe for skill '~a').~%" (skill-name active-skill)) proposed-action)))
proposed-action))) proposed-action)))
(defun list-objects-with-attribute (attr-key attr-val) (defun list-objects-with-attribute (attr-key attr-val)