REFAC: Standardize on Cognitive Cycle and harden harness

This commit is contained in:
2026-04-16 12:00:12 -04:00
parent 2d4a6d1586
commit 53eee06225
39 changed files with 236 additions and 2725 deletions

View File

@@ -101,15 +101,18 @@ The final stage of the metabolic loop. It performs a "last-mile" safety check be
(type (getf signal :type))
(feedback nil))
;; 1. Last-Mile Safety Check (The Bouncer)
;; 1. Last-Mile Safety Check (The Bouncer & Deterministic Gates)
(when approved
(let ((verified (decide approved signal)))
(if (and (listp verified) (member (getf verified :type) '(:LOG :EVENT)))
(let ((verified (deterministic-verify approved signal)))
(if (and (listp verified) (member (getf verified :type) '(:LOG :EVENT :log :event)))
(progn
(harness-log "ACT BLOCKED: Action failed last-mile deterministic check.")
(setf (getf signal :approved-action) nil)
(setf approved nil)
(setf feedback verified))
(setf approved verified))))
(progn
(setf (getf signal :approved-action) verified)
(setf approved verified)))))
;; 2. Actuation Logic
(case type

View File

@@ -36,7 +36,7 @@ This system defines the core "Thin Harness." It includes the protocol, the objec
:version "0.1.0"
:license "AGPLv3"
:description "The Probabilistic-Deterministic Lisp Machine Harness"
:depends-on (:usocket ::bordeaux-threads :dexador :uiop :cl-dotenv :cl-ppcre :hunchentoot :ironclad :str :cl-json)
:depends-on (:usocket :bordeaux-threads :dexador :uiop :cl-dotenv :cl-ppcre :hunchentoot :ironclad :str :cl-json :uuid)
:serial t
:components ((:file "src/package")
(:file "src/skills")
@@ -46,7 +46,9 @@ This system defines the core "Thin Harness." It includes the protocol, the objec
(:file "src/memory")
(:file "src/context")
(:file "src/probabilistic")
(:file "src/deterministic")
(:file "src/perceive")
(:file "src/reason")
(:file "src/act")
(:file "src/loop"))
:build-operation "program-op"
:build-pathname "opencortex-server"
@@ -61,6 +63,7 @@ This system contains the empirical tests required by the Engineering Standards.
:depends-on (:opencortex :fiveam)
:components ((:file "tests/communication-tests")
(:file "tests/pipeline-tests")
(:file "tests/act-tests")
(:file "tests/boot-sequence-tests")
(:file "tests/memory-tests")
(:file "tests/immune-system-tests"))

View File

@@ -148,6 +148,10 @@ Restores the state of the Memex from one of the previous snapshots.
Basic functions for retrieving objects by ID or type.
#+begin_src lisp :tangle ../src/memory.lisp
(defun org-id-new ()
"Generates a new UUID string for Org-mode identification."
(string-downcase (format nil "~a" (uuid:make-v4-uuid))))
(defun lookup-object (id)
"Retrieves an object from the store by its unique ID."
(gethash id *memory*))

View File

@@ -38,6 +38,7 @@ flowchart TD
#:ingest-ast
#:lookup-object
#:list-objects-by-type
#:org-id-new
#:*memory*
#:*history-store*
#:org-object
@@ -72,7 +73,9 @@ flowchart TD
#:perceive-gate
#:probabilistic-gate
#:consensus-gate
#:decide-gate
#:act-gate
#:reason-gate
#:perceive-gate
#:dispatch-gate
#:inject-stimulus
#:initialize-actuators
@@ -117,9 +120,13 @@ flowchart TD
#:distill-prompt
#:*provider-cascade*
;; --- Security Vault ---
#:vault-get-secret
#:vault-set-secret
;; --- Deterministic Logic ---
#:list-objects-with-attribute
#:decide
#:deterministic-verify
;; --- AST Helpers ---
#:find-headline-missing-id))

View File

@@ -88,14 +88,16 @@ Once a proposal is generated, it MUST pass through the deterministic gates. Ever
(maphash (lambda (name skill) (declare (ignore name)) (when (skill-deterministic-fn skill) (push skill skills))) *skills-registry*)
(setf skills (sort skills #'> :key #'skill-priority))
;; 2. Execute gates sequentially
;; 2. Execute gates sequentially if their trigger allows
(dolist (skill skills)
(let ((gate (skill-deterministic-fn skill)))
(setf current-action (funcall gate current-action context))
;; If any gate returns a LOG or EVENT, it has intercepted the action.
(when (and (listp current-action) (member (getf current-action :type) '(:LOG :EVENT)))
(harness-log "DETERMINISTIC: Intercepted by skill '~a'" (skill-name skill))
(return-from deterministic-verify current-action))))
(let ((trigger (skill-trigger-fn skill))
(gate (skill-deterministic-fn skill)))
(when (or (null trigger) (ignore-errors (funcall trigger context)))
(setf current-action (funcall gate current-action context))
;; If any gate returns a LOG or EVENT, it has intercepted the action.
(when (and (listp current-action) (member (getf current-action :type) '(:LOG :EVENT :log :event)))
(harness-log "DETERMINISTIC: Intercepted by skill '~a'" (skill-name skill))
(return-from deterministic-verify current-action)))))
current-action))
#+end_src

View File

@@ -11,7 +11,18 @@ A static, hardcoded architecture is inherently fragile. To build a autonomous ag
Skills unify the **"Why"** (Literate Org documentation) and the **"How"** (Functional Lisp implementation). This allows the harness to "learn" new behaviors without a full system restart, enabling a continuous evolutionary loop where the agent can eventually inspect and improve its own code.
*** The True Microkernel (Decoupled Core Skills)
Historically, "core" skills (like State Persistence or Gateways) were statically compiled into the harness for performance. We have fundamentally decoupled this. Now, *all* behavioral skills are pure user-space dynamic modules. They do not tangle to `src/` and are not listed in `opencortex.asd`. The harness simply boots, scans the `skills/` directory, and evaluates the code inside a jailed package. If a user wishes to swap the IPFS persistence skill for an AWS S3 one, they simply swap the `.org` file; no kernel recompilation is required.
Historically, "core" skills (like State Persistence or Gateways) were statically compiled into the harness for performance. We have fundamentally decoupled this. Now, *all* behavioral skills are pure user-space dynamic modules.
**** MANDATE: Dynamic Loading (No Tangling)
Skills are defined as single-file Literate Org notes. Unlike the core harness, **Skills MUST NOT use :tangle headers.**
Instead of being compiled into static source files, skills are:
1. **Discovered:** The harness scans the `skills/` directory for `.org` files.
2. **Parsed:** The harness extracts Lisp code blocks directly from the Org AST.
3. **Jailed:** Each skill is evaluated inside its own temporary, isolated package namespace.
4. **Hot-Loaded:** Skills can be added, modified, or removed at runtime without restarting the Lisp image.
This ensures the agent can safely read, write, and repair its own capabilities without breaking the physical file structure. If a user wishes to swap the IPFS persistence skill for an AWS S3 one, they simply swap the `.org` file; no kernel recompilation is required.
*** Dormant Verification (Tests)
Because skills are no longer statically compiled into the core `opencortex` ASDF system, their associated `FiveAM` test blocks are currently dormant during a standard static build. The tests still exist within the literate `.org` files as verifiable documentation, but executing them requires either dynamic evaluation at runtime or a dedicated test-loader skill.
@@ -322,30 +333,30 @@ The `initialize-all-skills` function is the unified orchestrator for the system
'("org-skill-policy" "org-skill-bouncer"))))
(dolist (req mandatory-skills)
(unless (member req sorted-files :key #'pathname-name :test #'string-equal)
(error "BOOT FAILURE: Mandatory skill '~a' not found in skills directory." req))))
(error "BOOT FAILURE: Mandatory skill '~a' not found in skills directory." req)))
(harness-log "==================================================")
(harness-log " LOADER: Initializing ~a skills..." (length sorted-files))
(dolist (file sorted-files)
(let* ((skill-name (pathname-name file))
(is-mandatory (member skill-name mandatory-skills :test #'string-equal)))
(harness-log " LOADER: Loading ~a..." skill-name)
(let ((status (load-skill-with-timeout file 5)))
(unless (eq status :success)
(if is-mandatory
(error "BOOT FAILURE: Mandatory skill '~a' failed to load (Status: ~a)." skill-name status)
(harness-log "LOADER WARNING: Skill '~a' failed to load." skill-name))))))
;; Final Summary
(let ((ready 0) (failed 0))
(maphash (lambda (k v)
(declare (ignore k))
(if (eq (skill-entry-status v) :ready) (incf ready) (incf failed)))
*skill-catalog*)
(harness-log " LOADER: Boot Complete. [Ready: ~a] [Failed: ~a]" ready failed)
(harness-log "==================================================")
(values ready failed)))))
(harness-log " LOADER: Initializing ~a skills..." (length sorted-files))
(dolist (file sorted-files)
(let* ((skill-name (pathname-name file))
(is-mandatory (member skill-name mandatory-skills :test #'string-equal)))
(harness-log " LOADER: Loading ~a..." skill-name)
(let ((status (load-skill-with-timeout file 5)))
(unless (eq status :success)
(if is-mandatory
(error "BOOT FAILURE: Mandatory skill '~a' failed to load (Status: ~a)." skill-name status)
(harness-log "LOADER WARNING: Skill '~a' failed to load." skill-name))))))
;; Final Summary
(let ((ready 0) (failed 0))
(maphash (lambda (k v)
(declare (ignore k))
(if (eq (skill-entry-status v) :ready) (incf ready) (incf failed)))
*skill-catalog*)
(harness-log " LOADER: Boot Complete. [Ready: ~a] [Failed: ~a]" ready failed)
(harness-log "==================================================")
(values ready failed))))))
#+end_src
** Toolbelt Prompt Generation (generate-tool-belt-prompt)