ARCH: Finalize semantic reorganization, skill jailing, and unified CLI
Some checks failed
Deploy-Agent-V15-Stdin / JOB-V15-STDIN (push) Failing after 4s

This commit is contained in:
2026-04-22 11:38:13 -04:00
parent 60f2c152e0
commit 6c333af7aa
51 changed files with 974 additions and 717 deletions

View File

@@ -0,0 +1,109 @@
(in-package :opencortex)
(defun bouncer-scan-secrets (text)
"Returns the name of the secret found in TEXT, or NIL if clean."
(when (and text (stringp text))
(let ((found-secret nil))
(maphash (lambda (key val)
(when (and val (stringp val) (> (length val) 5))
(when (search val text)
(setf found-secret key))))
opencortex::*vault-memory*)
found-secret)))
(defun bouncer-check-network-exfil (cmd)
"Returns T if the command appears to target an unwhitelisted external host."
(when (and cmd (stringp cmd))
;; Basic check for common data exfiltration tools being used with IPs/URLs
(let ((network-whitelist '("api.telegram.org" "matrix.org" "googleapis.com" "openai.com" "anthropic.com")))
(when (cl-ppcre:scan "(http|https|ftp)://([\\w\\.-]+)" cmd)
(multiple-value-bind (match regs)
(cl-ppcre:scan-to-strings "(http|https|ftp)://([\\w\\.-]+)" cmd)
(declare (ignore match))
(let ((domain (aref regs 1)))
(not (some (lambda (safe) (search safe domain)) network-whitelist))))))))
(defun bouncer-check (action context)
"The 5-Vector security gate. Blocks or queues actions based on risk."
(let* ((target (getf action :target))
(payload (getf action :payload))
(text (or (getf payload :text) (getf action :text)))
;; Extract cmd from direct shell or tool-mediated shell call
(cmd (or (getf payload :cmd)
(when (and (eq target :tool) (equal (getf payload :tool) "shell"))
(getf (getf payload :args) :cmd))))
(approved (getf action :approved)))
(cond
;; 0. Bypass for already approved actions
(approved action)
;; 1. Secret Exposure Vector (Hard Block)
((and text (bouncer-scan-secrets text))
(let ((secret-name (bouncer-scan-secrets text)))
(harness-log "SECURITY VIOLATION: Blocked leak of secret ~a" secret-name)
`(:type :log :payload (:level :error :text ,(format nil "Action blocked: Potential exposure of ~a" secret-name)))))
;; 2. Network Exfiltration Vector (Authorization Required)
((and (or (eq target :shell)
(and (eq target :tool) (equal (getf payload :tool) "shell")))
(bouncer-check-network-exfil cmd))
(harness-log "SECURITY WARNING: External network call detected. Queuing for approval.")
`(:type :EVENT :payload (:sensor :approval-required :action ,action)))
;; 3. High-Impact Target Vector (Authorization Required)
((or (member target '(:shell))
(and (eq target :tool) (member (getf payload :tool) '("shell" "repair-file") :test #'string=))
(and (eq target :EMACS) (eq (getf payload :action) :eval)))
(harness-log "SECURITY: High-impact action ~a requires approval." (or (getf payload :tool) target))
`(:type :EVENT :payload (:sensor :approval-required :action ,action)))
;; 4. Default Pass
(t action))))
(defun bouncer-process-approvals ()
"Scans the object store for APPROVED flight plans and re-injects their actions."
(let ((approved-nodes (list-objects-with-attribute :TODO "APPROVED"))
(found-any nil))
(dolist (node approved-nodes)
(let* ((tags (getf (org-object-attributes node) :TAGS))
(action-str (getf (org-object-attributes node) :ACTION)))
(when (and (member "FLIGHT_PLAN" tags :test #'string-equal) action-str)
(harness-log "BOUNCER: Found approved flight plan ~a. Re-injecting..." (org-object-id node))
(let ((action (ignore-errors (read-from-string action-str))))
(when action
;; Mark as approved to bypass the gate
(setf (getf action :approved) t)
(inject-stimulus action)
;; Mark as DONE
(setf (getf (org-object-attributes node) :TODO) "DONE")
(setq found-any t))))))
found-any))
(defun bouncer-deterministic-gate (action context)
"Main gate for the bouncer skill."
(let* ((payload (getf context :payload))
(sensor (getf payload :sensor)))
(case sensor
(:approval-required
(let* ((blocked-action (getf payload :action))
(id (org-id-new)))
(harness-log "BOUNCER: Creating flight plan node...")
;; Create the node in Emacs (or inbox)
(list :type :REQUEST :target :EMACS :action :insert-node
:id id :attributes `(:TITLE "Flight Plan: High-Risk Action"
:TODO "PLAN"
:TAGS ("FLIGHT_PLAN")
:ACTION ,(format nil "~s" blocked-action)))))
(:heartbeat
;; Periodically check for approvals
(bouncer-process-approvals)
(if action (bouncer-check action context) action))
(otherwise
(if action (bouncer-check action context) action)))))
(defskill :skill-bouncer
:priority 150
:trigger (lambda (ctx) t) ;; Bouncer evaluates all actions deterministically
:probabilistic nil
:deterministic #'bouncer-deterministic-gate)

View File

@@ -0,0 +1,81 @@
(defvar *cli-port* 9105)
(defvar *cli-server-socket* nil)
(defvar *cli-server-thread* nil)
(defun execute-cli-action (action context)
"Sends a framed message back to the connected CLI client."
(let* ((payload (proto-get action :PAYLOAD))
(meta (getf context :meta))
(stream (getf meta :reply-stream)))
(handler-case
(if (and stream (open-stream-p stream))
(progn
(format stream "~a" (frame-message action))
(finish-output stream)
(format stream "~a" (frame-message '(:TYPE :STATUS :SCRIBE :IDLE :GARDENER :SLEEPING)))
(finish-output stream))
(harness-log "CLI ERROR: No active or open reply stream for signal."))
(error (c) (harness-log "CLI ACTUATOR ERROR: ~a" c)))))
(defun handle-cli-slash-command (cmd stream)
(cond
((string= cmd "/exit") (return-from handle-cli-slash-command :exit))
(t (format stream "~a" (frame-message (list :TYPE :REQUEST :PAYLOAD (list :ACTION :MESSAGE :TEXT (format nil "Unknown command: ~a" cmd))))))))
(defun handle-cli-client (stream)
"Reads framed messages from a CLI client and injects them as stimuli."
(harness-log "CLI: Client connected.")
(handler-case
(progn
;; 1. Send Handshake
(format stream "~a" (frame-message (make-hello-message "0.1.0")))
(finish-output stream)
(format stream "~a" (frame-message '(:TYPE :STATUS :SCRIBE :IDLE :GARDENER :SLEEPING)))
(finish-output stream)
;; 2. Communication Loop
(loop
(let ((msg (read-framed-message stream)))
(cond ((eq msg :eof) (return))
((eq msg :error) (return))
(t (let* ((payload (proto-get msg :payload))
(text (proto-get payload :text))
(meta (proto-get msg :meta)))
(if (and text (stringp text) (char= (char text 0) #\/))
(when (eq (handle-cli-slash-command text stream) :exit) (return))
(progn
;; Default meta if missing
(unless meta
(setf (getf msg :meta) (list :SOURCE :CLI :SESSION-ID "default")))
(harness-log "CLI: Received input -> ~s" msg)
(inject-stimulus msg :stream stream)))))))))
(error (c) (harness-log "CLI CLIENT DISCONNECT: ~a" c)))
(harness-log "CLI: Client disconnected."))
(defun start-cli-gateway (&optional (port *cli-port*))
"Starts the TCP listener for local CLI clients."
(setf *cli-server-socket* (usocket:socket-listen "0.0.0.0" port :reuse-address t))
(setf *cli-server-thread*
(bt:make-thread
(lambda ()
(unwind-protect
(loop
(let* ((socket (usocket:socket-accept *cli-server-socket*))
(stream (usocket:socket-stream socket)))
(bt:make-thread (lambda ()
(unwind-protect (handle-cli-client stream)
(usocket:socket-close socket)))
:name "opencortex-cli-client-handler")))
(usocket:socket-close *cli-server-socket*)))
:name "opencortex-cli-gateway"))
(harness-log "CLI: Gateway listening on port ~a" port))
(register-actuator :CLI #'execute-cli-action)
(defskill :skill-gateway-cli
:priority 200
:trigger (lambda (ctx) (declare (ignore ctx)) nil)
:probabilistic nil
:deterministic (lambda (action ctx) (declare (ignore ctx)) action))
(start-cli-gateway)

View File

@@ -0,0 +1,82 @@
(defun vault-get-secret (provider &key type)
"Retrieves a secret (api-key or session) for a provider.")
(defun vault-set-secret (provider secret &key type)
"Securely stores a secret and triggers a Merkle snapshot.")
(defvar opencortex::*vault-memory* (make-hash-table :test 'equal)
"In-memory cache of sensitive credentials.")
(defun vault-mask-string (str)
"Returns a masked version of a sensitive string."
(if (and str (> (length str) 8))
(format nil "~a...~a" (subseq str 0 4) (subseq str (- (length str) 4)))
"[REDACTED]"))
(defun vault-get-secret (provider &key (type :api-key))
"Retrieves a credential. Type can be :api-key or :session."
(let* ((key (format nil "~a-~a" provider type))
(val (gethash key opencortex::*vault-memory*)))
(if val
val
;; Fallback to environment
(let ((env-var (case provider
((:gemini :gemini-api) "GEMINI_API_KEY")
(:openai "OPENAI_API_KEY")
(:anthropic "ANTHROPIC_API_KEY")
(:groq "GROQ_API_KEY")
(:openrouter "OPENROUTER_API_KEY")
(:telegram "TELEGRAM_BOT_TOKEN")
(:signal "SIGNAL_ACCOUNT_NUMBER")
(:matrix-homeserver "MATRIX_HOMESERVER")
(:matrix-token "MATRIX_ACCESS_TOKEN")
(t nil))))
(when (and env-var (eq type :api-key))
(uiop:getenv env-var))))))
(defun vault-set-secret (provider secret &key (type :api-key))
"Securely stores a secret and triggers a Merkle snapshot."
(let ((key (format nil "~a-~a" provider type)))
(setf (gethash key opencortex::*vault-memory*) secret)
(harness-log "VAULT - Updated ~a for ~a. Triggering Merkle snapshot..." type provider)
(snapshot-memory)
t))
(defun vault-onboard-gemini-web ()
"Instructions for the Autonomous Cookie Handshake."
(harness-log "--- GEMINI WEB ONBOARDING ---")
(harness-log "1. Visit gemini.google.com")
(harness-log "2. Run the 'Get Gemini Cookies' Bookmarklet.")
(harness-log " CODE: javascript:(function(){const c=document.cookie.split('; ').reduce((r,v)=>{const [n,val]=v.split('=');r[n]=val;return r},{});const target=['__Secure-1PSID','__Secure-1PSIDTS'];const out=target.map(n=>({name:n,value:c[n]}));prompt('Copy JSON:',JSON.stringify(out));})();")
(harness-log "PLATFORM GUIDE: Chrome/Firefox/Safari all support Bookmarklets via 'Add Page' or 'New Bookmark'.")
t)
(progn
(defskill :skill-credentials-vault
:priority 200 ; High priority, foundational
:trigger (lambda (ctx) (eq (getf (getf ctx :payload) :sensor) :onboarding-request))
:probabilistic nil
:deterministic (lambda (action ctx)
(vault-onboard-gemini-web)
action)))
#|
(defpackage :opencortex-vault-tests
(:use :cl :fiveam :opencortex))
(in-package :opencortex-vault-tests)
(def-suite vault-suite :description "Tests for the Credentials Vault.")
(in-suite vault-suite)
(test test-masking
(is (equal "sk-t...-key" (opencortex::vault-mask-string "sk-test-key")))
(is (equal "[REDACTED]" (opencortex::vault-mask-string "short"))))
(test test-vault-persistence
"Verify that setting a secret triggers a snapshot (mock check)."
(let ((old-version (opencortex::org-object-version (gethash "root" *memory*))))
(opencortex:vault-set-secret :test "secret-val")
(is (> (opencortex::org-object-version (gethash "root" *memory*)) old-version))))
|#

View File

@@ -0,0 +1,68 @@
(in-package :opencortex)
(defvar *gardener-last-audit* 0
"The universal-time of the last full Memex audit.")
(defun gardener-find-broken-links ()
"Returns a list of broken ID links found in the Memex."
(let ((broken nil))
(maphash (lambda (id obj)
(let ((content (org-object-content obj)))
(when content
(cl-ppcre:do-register-groups (target-id) ("id:([A-Za-z0-9-]+)" content)
(unless (lookup-object target-id)
(push (list :source id :broken-target target-id) broken))))))
*memory*)
broken))
(defun gardener-find-orphans ()
"Returns a list of IDs for headlines that are structurally isolated."
(let ((inbound (make-hash-table :test 'equal))
(outbound (make-hash-table :test 'equal))
(orphans nil))
;; 1. Map all connections
(maphash (lambda (id obj)
(let ((content (org-object-content obj)))
(when content
(cl-ppcre:do-register-groups (target-id) ("id:([A-Za-z0-9-]+)" content)
(setf (gethash id outbound) t)
(setf (gethash target-id inbound) t)))))
*memory*)
;; 2. Identify nodes with zero connections
(maphash (lambda (id obj)
(declare (ignore obj))
(unless (or (gethash id inbound) (gethash id outbound))
(push id orphans)))
*memory*)
orphans))
(defun gardener-deterministic-gate (action context)
"Main gate for the Gardener skill. Audits graph integrity."
(declare (ignore action context))
(let ((broken (gardener-find-broken-links))
(orphans (gardener-find-orphans)))
(when (or broken orphans)
(harness-log "GARDENER: Audit found ~a broken links and ~a orphans."
(length broken) (length orphans))
(dolist (link broken)
(harness-log " [BROKEN LINK] Node ~a -> ~a" (getf link :source) (getf link :broken-target)))
(dolist (orphan orphans)
(harness-log " [ORPHAN] Node ~a is isolated." orphan)))
(setf *gardener-last-audit* (get-universal-time))
;; Return a log to stop the loop
(list :type :LOG :payload (list :text "Gardener audit complete."))))
(defskill :skill-gardener
:priority 40
:trigger (lambda (ctx)
(let* ((payload (getf ctx :payload))
(sensor (getf payload :sensor)))
(and (eq sensor :heartbeat)
;; Only audit once per day
(> (- (get-universal-time) *gardener-last-audit*) 86400))))
:probabilistic nil
:deterministic #'gardener-deterministic-gate)

View File

@@ -0,0 +1,28 @@
(defun memory-org-to-json (source)
"Converts Org-mode source to JSON AST."
(declare (ignore source))
"")
(defun memory-json-to-org (ast)
"Converts JSON AST back to Org-mode text."
(declare (ignore ast))
"")
(defun memory-normalize-ast (ast)
"Recursively ensures ID uniqueness across the AST."
(declare (ignore ast))
nil)
(defun make-memory-node (headline &key content properties children)
"Constructor for a normalized Org node alist."
(declare (ignore headline))
(list :TYPE :HEADLINE
:PROPERTIES (or properties nil)
:CONTENT content
:CONTENTS children))
(defskill :skill-homoiconic-memory
:priority 100
:trigger (lambda (ctx) (declare (ignore ctx)) nil)
:probabilistic nil
:deterministic (lambda (action ctx) (declare (ignore ctx)) action))

View File

@@ -0,0 +1,33 @@
(in-package :opencortex)
(defun llama-inference (prompt system-prompt &key (model "local-model"))
"Sends a completion request to the local llama.cpp server."
(let ((endpoint (uiop:getenv "LLAMACPP_ENDPOINT")))
(unless endpoint
(harness-log "LLAMA ERROR: LLAMACPP_ENDPOINT not set in environment.")
(return-from llama-inference (list :error "LLAMACPP_ENDPOINT_MISSING")))
(handler-case
(let* ((full-prompt (format nil "System: ~a~%User: ~a~%Assistant:" system-prompt prompt))
(payload (cl-json:encode-json-to-string
`((:prompt . ,full-prompt)
(:n_predict . 1024)
(:stop . ("User:" "System:")))))
(response (dex:post (format nil "~a/completion" endpoint)
:content payload
:headers '(("Content-Type" . "application/json"))))
(data (cl-json:decode-json-from-string response)))
(cdr (assoc :content data)))
(error (c)
(harness-log "LLAMA ERROR: Connection failed -> ~a" c)
(list :error (format nil "~a" c))))))
(progn
(register-probabilistic-backend :llama #'llama-inference)
(harness-log "LLAMA: Local backend registered and active."))
(defskill :skill-llama-backend
:priority 50
:trigger (lambda (ctx) (declare (ignore ctx)) nil) ; Pure infrastructure skill
:probabilistic nil
:deterministic (lambda (action ctx) (declare (ignore ctx)) action))

View File

@@ -0,0 +1,110 @@
(defun get-nested (alist &rest keys)
"Recursively extracts nested values from an alist, handling both objects and arrays."
(let ((val alist))
(dolist (k keys)
;; Descend into arrays (cl-json style: ((key . val)) or ( ( (key . val) ) ))
(loop while (and (listp val) (listp (car val)) (not (keywordp (caar val))))
do (setf val (car val)))
(let ((pair (or (assoc k val)
(assoc (intern (string-upcase (string k)) :keyword) val)
(assoc (intern (string-downcase (string k)) :keyword) val))))
(if pair
(setf val (cdr pair))
(return-from get-nested nil))))
val))
(defun execute-llm-request (prompt system-prompt &key provider model)
"Unified entry point for all LLM providers. Respects the global cascade."
(let* ((active-provider (or provider (car opencortex::*provider-cascade*) :openrouter))
(api-key (vault-get-secret active-provider :type :api-key))
(full-prompt (format nil "~a~%~%Prompt: ~a" system-prompt prompt)))
(harness-log "PROBABILISTIC ENGINE: Requesting ~a (Model: ~s)"
active-provider (or model "default"))
;; If the specifically requested provider has no key, try falling back to the cascade
(when (or (null api-key) (string= api-key ""))
(harness-log "GATEWAY: Provider ~a has no key. Cascade fallback would trigger here." active-provider)
(return-from execute-llm-request (list :status :error :message "API Key missing.")))
(case active-provider
(:gemini-web
(let ((res (uiop:symbol-call :opencortex.skills.org-skill-web-research :ask-gemini-web full-prompt)))
(if res (list :status :success :content res) (list :status :error :message "Web Research Failure"))))
(:ollama
(let* ((host (or (uiop:getenv "OLLAMA_HOST") "localhost:11434"))
(url (format nil "http://~a/api/generate" host))
(body (cl-json:encode-json-to-string `((model . ,(or model "llama3")) (prompt . ,full-prompt) (stream . :false)))))
(handler-case
(progn
(harness-log "LLM DEBUG: Requesting Ollama...")
(let* ((response (dex:post url :headers '(("Content-Type" . "application/json")) :content body :connect-timeout 5 :read-timeout 60))
(json (cl-json:decode-json-from-string response)))
(list :status :success :content (cdr (assoc :response json)))))
(error (c) (list :status :error :message (format nil "Ollama Failure: ~a" c))))))
(t ;; Cloud Providers (Anthropic, Gemini API, Groq, OpenAI, OpenRouter)
(let* ((endpoint (case active-provider
(:anthropic "https://api.anthropic.com/v1/messages")
(:gemini-api (format nil "https://generativelanguage.googleapis.com/v1/models/~a:generateContent" (or model "gemini-1.5-flash-latest")))
(:groq "https://api.groq.com/openai/v1/chat/completions")
(:openai "https://api.openai.com/v1/chat/completions")
(:openrouter "https://openrouter.ai/api/v1/chat/completions")))
(headers (case active-provider
(:anthropic `(("Content-Type" . "application/json") ("x-api-key" . ,api-key) ("anthropic-version" . "2023-06-01")))
(:gemini-api `(("Content-Type" . "application/json") ("x-goog-api-key" . ,api-key)))
(:openrouter `(("Content-Type" . "application/json") ("Authorization" . ,(format nil "Bearer ~a" api-key))
("HTTP-Referer" . "https://github.com/amr/opencortex") ("X-Title" . "opencortex Autonomous Kernel")))
(t `(("Content-Type" . "application/json") ("Authorization" . ,(format nil "Bearer ~a" api-key))))))
(body (case active-provider
(:anthropic (cl-json:encode-json-to-string `((model . ,(or model "claude-3-5-sonnet-20240620")) (max_tokens . 4096) (system . ,system-prompt) (messages . (( (role . "user") (content . ,prompt) ))))))
(:gemini-api (cl-json:encode-json-to-string `((contents . (((parts . (((text . ,full-prompt))))))))))
(t (cl-json:encode-json-to-string `((model . ,(or model (case active-provider (:groq "llama-3.3-70b-versatile") (t "google/gemini-2.0-flash-001"))))
(messages . (( (role . "system") (content . ,system-prompt) ) ( (role . "user") (content . ,prompt) )))))))))
(handler-case
(progn
(harness-log "LLM DEBUG: Requesting ~a..." active-provider)
(let* ((response (dex:post endpoint :headers headers :content body :connect-timeout 10 :read-timeout 30))
(json (cl-json:decode-json-from-string response)))
(let ((content (case active-provider
(:anthropic (get-nested json :content :text))
(:gemini-api (get-nested json :candidates :parts :text))
(t (get-nested json :choices :message :content)))))
(if content
(list :status :success :content content)
(list :status :error :message (format nil "Failed to parse ~a response structure." active-provider))))))
(error (c) (list :status :error :message (format nil "LLM Gateway Failure (~a): ~a" active-provider c)))))))))
;; Initialize Cascade
(let* ((env-cascade (uiop:getenv "PROVIDER_CASCADE"))
(default-list '(:openrouter :openai :anthropic :groq :gemini-api :ollama))
(final-list (if (and env-cascade (not (string= env-cascade "")))
(mapcar (lambda (s) (intern (string-upcase (string-trim '(#\Space) s)) :keyword))
(uiop:split-string env-cascade :separator '(#\,)))
default-list)))
(setf opencortex::*provider-cascade* final-list)
(opencortex:harness-log "PROBABILISTIC: Neural Cascade Initialized -> ~a" final-list))
;; Register Providers
(dolist (p '(:anthropic :gemini-api :gemini-web :groq :ollama :openrouter :openai))
(opencortex:register-probabilistic-backend p (lambda (prompt system-prompt &key model)
(execute-llm-request prompt system-prompt :provider p :model model))))
(def-cognitive-tool :ask-llm
"Queries an LLM provider via the unified gateway."
((:prompt :type :string :description "The user prompt.")
(:system-prompt :type :string :description "The system instructions.")
(:provider :type :keyword :description "Optional specific provider.")
(:model :type :string :description "Optional specific model ID."))
:body (lambda (args)
(execute-llm-request (getf args :prompt)
(or (getf args :system-prompt) "You are a helpful assistant.")
:provider (getf args :provider)
:model (getf args :model))))
(defskill :skill-llm-gateway
:priority 150
:trigger (lambda (context) (declare (ignore context)) nil)
:probabilistic (lambda (context) (declare (ignore context)) nil)
:deterministic (lambda (action context) (declare (ignore context)) action))

View File

@@ -0,0 +1,76 @@
(defun context-render-to-org (obj &key depth foveal-id semantic-threshold foveal-vector)
"Recursively renders an org-object with foveal-peripheral pruning.")
(defun context-assemble-global-awareness (&optional signal)
"Assembles the full context block for a neural request.")
(defun context-render-to-org (obj &key (depth 1) (foveal-id nil) (semantic-threshold 0.75) (foveal-vector nil))
"Recursively renders an org-object and its children to an Org string using a Foveal-Peripheral Hybrid model."
(let* ((id (org-object-id obj))
(is-foveal (equal id foveal-id))
(title (or (getf (org-object-attributes obj) :TITLE) "Untitled"))
(content (org-object-content obj))
(children (org-object-children obj))
(stars (make-string depth :initial-element #\*))
(obj-vector (org-object-vector obj))
(similarity (if (and foveal-vector obj-vector (not is-foveal))
(cosine-similarity foveal-vector obj-vector)
0.0))
(is-semantically-relevant (>= similarity semantic-threshold))
;; We always render depth 1 and 2 (Projects and main tasks).
;; We always render the foveal node and its immediate children.
;; We render deeper nodes ONLY if they are semantically relevant.
(should-render (or (<= depth 2) is-foveal is-semantically-relevant))
(output ""))
(when should-render
(setf output (format nil "~a ~a~%:PROPERTIES:~%:ID: ~a~%" stars title id))
(when (and is-semantically-relevant (> similarity 0))
(setf output (concatenate 'string output (format nil ":SEMANTIC_SCORE: ~,2f~%" similarity))))
(setf output (concatenate 'string output (format nil ":END:~%")))
;; Only include full body content if this is the Foveal focus or highly relevant
(when (and content (or is-foveal is-semantically-relevant))
(setf output (concatenate 'string output content (string #\Newline))))
;; Recursively render children
(dolist (child-id children)
(let ((child-obj (lookup-object child-id)))
(when child-obj
;; If the current node is Foveal, its children should be rendered (depth effectively resets)
(let ((next-foveal (if is-foveal child-id foveal-id)))
(setf output (concatenate 'string output
(context-render-to-org child-obj
:depth (1+ depth)
:foveal-id next-foveal
:semantic-threshold semantic-threshold
:foveal-vector foveal-vector))))))))
output))
(defun context-assemble-global-awareness (&optional signal)
"Produces a high-level skeletal outline of the current Memory for the LLM."
(let* ((payload (when signal (getf signal :payload)))
(foveal-id (when payload (getf payload :target-id)))
(foveal-vector (when foveal-id (org-object-vector (lookup-object foveal-id))))
(projects (context-get-active-projects))
(output "GLOBAL MEMEX AWARENESS (Peripheral Vision):
"))
(if projects
(dolist (project projects)
(setf output (concatenate 'string output
(context-render-to-org project
:foveal-id foveal-id
:foveal-vector foveal-vector))))
(setf output (concatenate 'string output "No active projects found.~%")))
output))
(defskill :skill-peripheral-vision
:priority 90
:dependencies ("org-skill-embedding")
:trigger (lambda (ctx) (member (getf (getf ctx :payload) :sensor) '(:perceive :context-refresh)))
:probabilistic nil
:deterministic (lambda (action ctx)
(declare (ignore action ctx))
;; This skill primarily provides the context-assemble-global-awareness function
;; used by the probabilistic-gate, rather than handling specific actions.
nil))

View File

@@ -0,0 +1,25 @@
(in-package :opencortex)
(defun policy-check-autonomy (action context)
"Ensures the action does not violate the Autonomy invariant."
(declare (ignore context))
;; Implementation placeholder: currently permits all actions.
;; Future: Scan for non-autonomous domain names or proprietary API endpoints.
action)
(defun policy-deterministic-gate (action context)
"The main policy gate. Sub-calls engineering standards if available."
(let ((current-action (policy-check-autonomy action context)))
(when current-action
(let ((eng-pkg (find-package :opencortex.skills.org-skill-engineering-standards)))
(when eng-pkg
(let ((eng-gate (find-symbol "ENGINEERING-STANDARDS-GATE" eng-pkg)))
(when (and eng-gate (fboundp eng-gate))
(setf current-action (funcall (symbol-function eng-gate) current-action context)))))))
current-action))
(defskill :skill-policy
:priority 100
:trigger (lambda (ctx) t)
:probabilistic nil
:deterministic #'policy-deterministic-gate)

View File

@@ -0,0 +1,39 @@
(in-package :opencortex)
(defun validate-communication-protocol-schema (msg)
"Strict structural validation for incoming communication protocol messages."
(unless (listp msg)
(error "Communication Protocol Schema Error: Message must be a property list (got ~s)" (type-of msg)))
(let ((type (let ((raw (proto-get msg :type))) (if (keywordp raw) (intern (string-upcase (string raw)) :keyword) raw))))
(unless (member type '(:REQUEST :EVENT :RESPONSE :LOG :STATUS :CHAT))
(progn (harness-log "REJECTED MSG: ~s" msg) (error "Communication Protocol Schema Error: Invalid message type '~a'" type)))
(case type
(:REQUEST
(unless (proto-get msg :target)
(error "Communication Protocol Schema Error: REQUEST missing mandatory :target"))
(unless (proto-get msg :payload)
(error "Communication Protocol Schema Error: REQUEST missing mandatory :payload")))
(:EVENT
(let ((payload (proto-get msg :payload)))
(unless (and payload (listp payload))
(error "Communication Protocol Schema Error: EVENT missing or invalid :payload"))
(unless (or (proto-get payload :action) (proto-get payload :sensor))
(error "Communication Protocol Schema Error: EVENT payload must contain :action or :sensor"))))
(:RESPONSE
(unless (proto-get msg :payload)
(error "Communication Protocol Schema Error: RESPONSE missing mandatory :payload"))))
t))
(defskill :skill-communication-protocol-validator
:priority 95
:trigger (lambda (ctx) (member (getf (getf ctx :payload) :sensor) '(:protocol-received)))
:probabilistic nil
:deterministic (lambda (action ctx)
(declare (ignore ctx))
(validate-communication-protocol-schema action)
action))

View File

@@ -0,0 +1,108 @@
(in-package :opencortex)
(defvar *scribe-last-checkpoint* 0
"The universal-time of the last successful distillation run.")
(defun scribe-load-state ()
"Loads the scribe checkpoint from the state directory."
(let ((state-file (uiop:merge-pathnames* "state/scribe-checkpoint.lisp" (asdf:system-source-directory :opencortex))))
(if (uiop:file-exists-p state-file)
(setf *scribe-last-checkpoint* (read-from-string (uiop:read-file-string state-file)))
(setf *scribe-last-checkpoint* 0))))
(defun scribe-save-state ()
"Saves the current universal-time as the new checkpoint."
(let ((state-file (uiop:merge-pathnames* "state/scribe-checkpoint.lisp" (asdf:system-source-directory :opencortex))))
(ensure-directories-exist state-file)
(with-open-file (out state-file :direction :output :if-exists :supersede)
(format out "~a" (get-universal-time)))))
(defun scribe-get-distillable-nodes ()
"Returns a list of org-objects from the daily/ folder that require distillation."
(let ((results nil))
(maphash (lambda (id obj)
(declare (ignore id))
(let* ((attrs (org-object-attributes obj))
(tags (getf attrs :TAGS))
(type (org-object-type obj))
(version (org-object-version obj)))
(when (and (eq type :HEADLINE)
(> version *scribe-last-checkpoint*)
(not (member "@personal" tags :test #'string-equal)))
(push obj results))))
*memory*)
results))
(defun probabilistic-skill-scribe (context)
"Generates the extraction prompt for the Scribe."
(let* ((payload (getf context :payload))
(nodes (scribe-get-distillable-nodes)))
(if nodes
(let ((text-to-process ""))
(dolist (node nodes)
(setf text-to-process (concatenate 'string text-to-process
(format nil "ID: ~a~%TITLE: ~a~%CONTENT: ~a~%---~%"
(org-object-id node)
(getf (org-object-attributes node) :TITLE)
(org-object-content node)))))
(format nil "DISTILLATION TASK:
Below are raw chronological logs from my daily journal.
Extract ATOMIC EVERGREEN NOTES from this text.
RULES:
1. One note per distinct concept.
2. Output a list of Lisp plists: ((:title \"...\" :content \"...\" :source-id \"...\") ...)
3. The content should be in Org-mode format.
4. Keep titles descriptive and snake_case.
TEXT:
~a" text-to-process))
nil)))
(defun scribe-commit-notes (proposals)
"Writes proposed atomic notes to the notes/ directory. Appends if the note exists."
(let ((notes-dir (uiop:merge-pathnames* "notes/" (asdf:system-source-directory :opencortex))))
(ensure-directories-exist notes-dir)
(dolist (note proposals)
(let* ((title (getf note :title))
(content (getf note :content))
(source-id (getf note :source-id))
(filename (format nil "~a.org" (string-downcase (cl-ppcre:regex-replace-all " " title "_"))))
(path (merge-pathnames filename notes-dir)))
(if (uiop:file-exists-p path)
(with-open-file (out path :direction :output :if-exists :append)
(format out "~%~%* Appended insight from ~a~%~a" source-id content))
(with-open-file (out path :direction :output :if-exists :supersede)
(format out ":PROPERTIES:~%:ID: ~a~%:SOURCE_ID: ~a~%:END:~%#+TITLE: ~a~%~%~a"
(org-id-new) source-id title content)))
(harness-log "SCRIBE: Processed evergreen note ~a" filename)))))
(defun verify-skill-scribe (action context)
"Executes the note creation and marks source nodes as distilled."
(declare (ignore context))
(let ((data (cond ((and (listp action) (eq (getf action :type) :REQUEST))
(getf (getf action :payload) :payload))
((and (listp action) (not (member (getf action :type) '(:LOG :EVENT))))
action)
(t nil))))
(when data
(harness-log "SCRIBE: Committing ~a atomic notes..." (length data))
(scribe-commit-notes data)
(scribe-save-state)
(harness-log "SCRIBE: Distillation complete.")
;; Return a log event to stop the loop
(list :type :LOG :payload (list :text "Distillation successful.")))))
(defskill :skill-scribe
:priority 50
:trigger (lambda (ctx)
(let* ((payload (getf ctx :payload))
(sensor (getf payload :sensor)))
(and (eq sensor :heartbeat)
;; Only run once per hour to check if we need to distill
(> (- (get-universal-time) *scribe-last-checkpoint*) 3600)
(scribe-get-distillable-nodes))))
:probabilistic #'probabilistic-skill-scribe
:deterministic #'verify-skill-scribe)
(scribe-load-state)

View File

@@ -0,0 +1,56 @@
(defparameter *allowed-commands* '("ls" "git" "rg" "grep" "date" "echo" "cat" "node" "python3" "sbcl"))
(defparameter *shell-metacharacters* '(#\; #\& #\| #\> #\< #\$ #\` #\\ #\!))
(defun shell-command-safe-p (cmd-string)
"Returns T if the command string contains no dangerous metacharacters."
(not (some (lambda (char) (find char cmd-string)) *shell-metacharacters*)))
(defun execute-shell-safely (action context)
(let* ((payload (getf action :PAYLOAD))
(cmd-string (getf payload :cmd))
(executable (car (uiop:split-string (string-trim " " cmd-string) :separator '(#\Space)))))
(cond
((not (shell-command-safe-p cmd-string))
(opencortex:inject-stimulus
`(:TYPE :EVENT :PAYLOAD (:SENSOR :shell-response :cmd ,cmd-string :stdout "" :stderr "ERROR - Security Violation: Dangerous metacharacters detected." :exit-code 1))
:stream (getf context :reply-stream)))
((not (member executable *allowed-commands* :test #'string=))
(opencortex:inject-stimulus
`(:TYPE :EVENT :PAYLOAD (:SENSOR :shell-response :cmd ,cmd-string :stdout "" :stderr "ERROR - Command not in security whitelist." :exit-code 1))
:stream (getf context :reply-stream)))
(t
(multiple-value-bind (stdout stderr exit-code)
(uiop:run-program cmd-string :output :string :error-output :string :ignore-error-status t)
(opencortex:inject-stimulus
`(:TYPE :EVENT :PAYLOAD (:SENSOR :shell-response :cmd ,cmd-string :stdout ,(or stdout "") :stderr ,(or stderr "") :exit-code ,exit-code))
:stream (getf context :reply-stream)))))))
(defun trigger-skill-shell-actuator (context)
(let ((type (getf context :TYPE))
(payload (getf context :PAYLOAD)))
(and (eq type :EVENT)
(eq (getf payload :SENSOR) :shell-response))))
(defun probabilistic-skill-shell-actuator (context)
(let* ((p (getf context :PAYLOAD))
(cmd (getf p :cmd))
(stdout (getf p :stdout))
(stderr (getf p :stderr))
(exit-code (getf p :exit-code)))
(format nil "SHELL COMMAND RESULT:
Command: ~a
Exit Code: ~a
STDOUT: ~a
STDERR: ~a" cmd exit-code stdout stderr)))
(opencortex:register-actuator :shell #'execute-shell-safely)
(defskill :skill-shell-actuator
:priority 80
:trigger #'trigger-skill-shell-actuator
:probabilistic #'probabilistic-skill-shell-actuator
:deterministic (lambda (action context) (declare (ignore context)) action))