REFAC: Standardize on Cognitive Cycle and harden harness
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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"))
|
||||
|
||||
@@ -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*))
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user