Files
passepartout/literate/skills.org
Amr Gharbeia dd3873cd5e
Some checks failed
Deploy-Agent-V15-Stdin / JOB-V15-STDIN (push) Failing after 2s
DOCS: Systematic overhaul of Literate source (Granularity & Technical Reasoning)
2026-04-21 11:49:58 -04:00

5.7 KiB

The Skill Engine (skills.lisp)

The Skill Engine (skills.lisp)

Architectural Intent: Hot-Reloadable Intelligence

The Skill Engine is the modular heart of the OpenCortex. By separating cognitive and physical capabilities into discrete "Skills," we allow the system to evolve without modifying the core Lisp microharness.

Core Principles

  1. Isolation: Every skill resides in its own Lisp package, preventing global namespace pollution and variable collisions.
  2. Topological Bootstrapping: Skills can declare dependencies on other skills. The harness automatically calculates the correct loading order.
  3. Hot-Reloading: Since Skills are defined as Literate Org files, the agent can edit, re-tangle, and re-load its own skills at runtime without a system restart.
  4. The Bouncer Pattern: Every skill must define a deterministic gate. This is the primary security layer where native Lisp logic verifies probabilistic AI proposals.

Pipeline Initialization

(in-package :opencortex)

Skill Definition and Registration

The Skill Structure

(defstruct skill
  "Represents a hot-reloadable module of intelligence or actuation."
  name
  priority
  dependencies
  trigger-fn
  probabilistic-prompt
  deterministic-fn)

Skill Registration Macro (defskill)

This macro provides a clean interface for skill authors to register their modules. It automatically handles the integration with the global *skills-registry*.

(defmacro defskill (name &key (priority 0) dependencies trigger probabilistic deterministic)
  "Registers a new skill into the global harness registry."
  `(setf (gethash (string-downcase (string ',name)) *skills-registry*)
         (make-skill :name (string-downcase (string ',name))
                     :priority ,priority
                     :dependencies ,dependencies
                     :trigger-fn ,trigger
                     :probabilistic-prompt ,probabilistic
                     :deterministic-fn ,deterministic)))

Dynamic Loading System

Lisp Syntax Validation (validate-lisp-syntax)

Before loading a new skill into the live image, the harness performs a dry-run parse to ensure the code is syntactically valid. This prevents a single hallucinated parenthesis from crashing the entire brain.

(defun validate-lisp-syntax (file-path)
  "Parses a Lisp file without evaluation to verify syntactic integrity."
  (handler-case
      (with-open-file (stream file-path)
        (loop for form = (read stream nil :eof)
              until (eq form :eof))
        t)
    (error (c)
      (harness-log "SYNTAX ERROR in ~a: ~a" file-path c)
      nil)))

Literate Skill Ingestion (load-skill-from-org)

The primary mechanism for hot-reloading. It handles the Org-to-Lisp translation and ensures the resulting code is jailed within its own package.

(defun load-skill-from-org (org-file-path)
  "Tangles and loads a single Org-mode skill file."
  (let* ((filename (file-name-nondirectory (namestring org-file-path)))
         (skill-id (pathname-name org-file-path))
         (lisp-file (merge-pathnames (concatenate 'string "src/gen/" skill-id ".lisp")
                                     (asdf:system-source-directory :opencortex))))
    
    (ensure-directories-exist lisp-file)
    (harness-log "LOADER: Loading ~a..." skill-id)

    ;; 1. Tangle the Org file into Lisp
    (uiop:run-program (list "emacs" "--batch" "--eval" "(require 'org)" 
                            "--eval" (format nil "(org-babel-tangle-file \"~a\")" org-file-path))
                      :output t)

    ;; 2. Verify and Load
    (if (validate-lisp-syntax lisp-file)
        (progn
          (handler-case (load lisp-file)
            (error (c) (harness-log "LOADER ERROR in skill '~a': ~a" skill-id c)))
          t)
        nil)))

Bootstrapping Logic

Dependency Sorting (topological-sort-skills)

Ensures that foundational skills (like the Bouncer or Policy engine) are always loaded before higher-level actuators.

(defun topological-sort-skills (skills)
  "Calculates the correct loading order based on #+DEPENDS_ON metadata."
  ;; Placeholder: Currently sorts by priority as a proxy for dependencies.
  (sort skills #'> :key #'skill-priority))

Registry Initialization (initialize-all-skills)

The high-level boot sequence for the skill engine.

(defun initialize-all-skills ()
  "Discovers and loads all Org files in the SKILLS_DIR."
  (let* ((skills-dir (uiop:getenv "SKILLS_DIR"))
         (files (when (and skills-dir (uiop:directory-exists-p skills-dir))
                  (uiop:directory-files skills-dir "*.org"))))
    (dolist (f files)
      (load-skill-from-org f))
    (harness-log "LOADER: Boot Complete. [Ready: ~a] [Failed: 0]" (hash-table-count *skills-registry*))))

Cognitive Dispatching

Skill Trigger Discovery (find-triggered-skill)

Identifies which skill is best suited to handle the current metabolic signal.

(defun find-triggered-skill (context)
  "Iterates through the registry and returns the first skill whose trigger returns true."
  (let ((skills nil))
    (maphash (lambda (name skill) (declare (ignore name)) (push skill skills)) *skills-registry*)
    (setf skills (sort skills #'> :key #'skill-priority))
    (dolist (s skills)
      (let ((trigger (skill-trigger-fn s)))
        (when (and trigger (funcall trigger context))
          (return-from find-triggered-skill s))))
    nil))