docs: global terminology update from kernel/core to harness
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
Welcome to ~org-agent~, the "Executive Soul" of your personal OS. This guide will help you set up and interact with your first neurosymbolic agent.
|
||||
|
||||
* 2. Prerequisites
|
||||
Before launching the kernel, ensure your host environment has:
|
||||
Before launching the harness, ensure your host environment has:
|
||||
- **Docker & Docker Compose**: The primary enclosure for the Lisp Machine.
|
||||
- **LLM API Keys**: At least one key for Gemini, Anthropic, or OpenAI.
|
||||
- **Emacs (Optional)**: For the full literate experience via ~org-agent.el~.
|
||||
@@ -33,7 +33,7 @@ docker-compose up --build -d
|
||||
#+end_src
|
||||
|
||||
* 4. Interaction Gateways
|
||||
Once the kernel is "Ready", you can interact with it via multiple sensors.
|
||||
Once the harness is "Ready", you can interact with it via multiple sensors.
|
||||
|
||||
** Gateway A: Emacs (OACP)
|
||||
If you have configured the ~org-agent~ package in Emacs:
|
||||
@@ -44,7 +44,7 @@ If you have configured the ~org-agent~ package in Emacs:
|
||||
If you enabled Signal or Telegram in ~.env~, send a message directly to your bot.
|
||||
|
||||
* 5. Verification (The Chaos Check)
|
||||
To ensure the kernel is fully healthy, check the logs for the Micro-Loader summary:
|
||||
To ensure the harness is fully healthy, check the logs for the Micro-Loader summary:
|
||||
#+begin_src bash
|
||||
docker-compose logs -f org-agent
|
||||
#+end_src
|
||||
@@ -52,4 +52,4 @@ Look for: ~LOADER: Boot Complete. [Ready: 34] [Failed: 0]~
|
||||
|
||||
* 6. Next Steps
|
||||
- **Extend the Brain**: Read the [[file:skill-creation.org][Skill Creation Guide]] to add custom Lisp skills.
|
||||
- **Deep Dive**: Explore the [[file:../literate/][literate/]] directory to understand the kernel's architecture.
|
||||
- **Deep Dive**: Explore the [[file:../literate/][literate/]] directory to understand the harness's architecture.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#+FILETAGS: :rca:boot:loader:topological-sort:psf:
|
||||
|
||||
* Executive Summary
|
||||
Refactored the arbitrary skill loading mechanism into a robust **Micro-Loader**. The system now calculates a deterministic boot sequence based on `#+DEPENDS_ON:` tags and protects the kernel from malformed or hanging skills via package-based jailing and execution timeouts.
|
||||
Refactored the arbitrary skill loading mechanism into a robust **Micro-Loader**. The system now calculates a deterministic boot sequence based on `#+DEPENDS_ON:` tags and protects the harness from malformed or hanging skills via package-based jailing and execution timeouts.
|
||||
|
||||
* 1. Issue: Fragile Load Order
|
||||
** Symptoms
|
||||
|
||||
@@ -12,7 +12,7 @@ System 1 proposals involving `shell` or `eval` were executed immediately upon pa
|
||||
Architecture gap. The system lacked an authorization state between "Safe" and "Executed".
|
||||
** Resolution
|
||||
1. **Interceptor:** Added `bouncer-check` to `symbolic.lisp`. It flags high-risk actions that lack the `:approved t` property.
|
||||
2. **Asynchronous Event:** If flagged, the kernel emits an `:approval-required` event.
|
||||
2. **Asynchronous Event:** If flagged, the harness emits an `:approval-required` event.
|
||||
3. **Flight Plan Skill:** Created `org-skill-bouncer.org` to:
|
||||
- Catch the event and create a serialized Org node with state `PLAN`.
|
||||
- Monitor the Object Store for `APPROVED` states.
|
||||
@@ -30,4 +30,4 @@ Ensures that the agent's "Flight Plans" are first-class citizens in the Memex, a
|
||||
|
||||
* 3. Permanent Learnings
|
||||
- **Serial Bypass:** Always include a specific bypass flag (e.g., `:approved t`) when re-injecting intercepted actions to prevent infinite interception loops.
|
||||
- **Heartbeat Listeners:** Periodic scanning of the Object Store for state transitions is an effective way to implement asynchronous authorization gates without blocking the kernel.
|
||||
- **Heartbeat Listeners:** Periodic scanning of the Object Store for state transitions is an effective way to implement asynchronous authorization gates without blocking the harness.
|
||||
|
||||
@@ -7,9 +7,9 @@ Successfully implemented the first external communication channel (Telegram) and
|
||||
|
||||
* 1. Issue: Undefined Foundational Functions
|
||||
** Symptoms
|
||||
During compilation, `gateway-telegram.lisp` failed with `UNDEFINED-FUNCTION` for `register-actuator` and `kernel-log`.
|
||||
During compilation, `gateway-telegram.lisp` failed with `UNDEFINED-FUNCTION` for `register-actuator` and `harness-log`.
|
||||
** Root Cause
|
||||
Poorly scoped foundational functions. These were defined in `core.lisp` (the loop orchestrator), which was loaded *after* the gateways in `org-agent.asd`. This created a "Circular Intention" where the gateways needed the kernel to exist before the kernel could load the gateways.
|
||||
Poorly scoped foundational functions. These were defined in `core.lisp` (the loop orchestrator), which was loaded *after* the gateways in `org-agent.asd`. This created a "Circular Intention" where the gateways needed the harness to exist before the harness could load the gateways.
|
||||
** Resolution
|
||||
1. **Relocation:** Moved `*actuator-registry*` and `register-actuator` to `protocol.lisp` (the foundation).
|
||||
2. **Reordering:** Adjusted `org-agent.asd` to load `core.lisp` (containing the stimulus loop) immediately after the symbolic gates but before the physical sensors (gateways).
|
||||
|
||||
@@ -30,4 +30,4 @@ Leveraged the pipeline's ability to re-inject `EVENT` signals to flatten the rec
|
||||
|
||||
* 4. Permanent Learnings
|
||||
- **Emit, Don't Call:** In a microkernel, if a non-fatal error occurs, always emit a signal rather than calling a recovery function. This allows the system to remain asynchronous and modular.
|
||||
- **Signal Inspection:** When writing symbolic gates, always verify the exact shape of the `context` signal being passed by the kernel to avoid nesting errors.
|
||||
- **Signal Inspection:** When writing symbolic gates, always verify the exact shape of the `context` signal being passed by the harness to avoid nesting errors.
|
||||
|
||||
@@ -19,7 +19,7 @@ The `execute-shell-safely` function only checked the first space-delimited word
|
||||
** Symptoms
|
||||
`UNDEFINED-FUNCTION EXECUTE-SHELL-SAFELY` during unit tests.
|
||||
** Root Cause
|
||||
`src/shell-logic.lisp` was missing an `(in-package :org-agent)` declaration, causing symbols to be defined in the default `COMMON-LISP-USER` package instead of the kernel package.
|
||||
`src/shell-logic.lisp` was missing an `(in-package :org-agent)` declaration, causing symbols to be defined in the default `COMMON-LISP-USER` package instead of the harness package.
|
||||
** Resolution
|
||||
Added the `in-package` header to `shell-logic.lisp`.
|
||||
|
||||
|
||||
@@ -80,11 +80,11 @@ Reads the raw literate source of a specific skill. This is crucial for "System 2
|
||||
#+end_src
|
||||
|
||||
** Kernel Logs (context-get-system-logs)
|
||||
Retrieves the most recent lines from the kernel's internal log.
|
||||
Retrieves the most recent lines from the harness's internal log.
|
||||
|
||||
#+begin_src lisp :tangle ../src/context.lisp
|
||||
(defun context-get-system-logs (&optional (limit 20))
|
||||
"Retrieves the most recent lines from the kernel's internal log."
|
||||
"Retrieves the most recent lines from the harness's internal log."
|
||||
(bt:with-lock-held (*logs-lock*)
|
||||
(let ((count (min limit (length *system-logs*)))) (subseq *system-logs* 0 count))))
|
||||
#+end_src
|
||||
|
||||
@@ -101,7 +101,7 @@ sequenceDiagram
|
||||
(when backend-fn
|
||||
(push (bt:make-thread
|
||||
(lambda ()
|
||||
(kernel-log "ASSOCIATIVE [Consensus]: Querying backend ~a..." backend)
|
||||
(harness-log "ASSOCIATIVE [Consensus]: Querying backend ~a..." backend)
|
||||
(let* ((model (when *model-selector-fn* (funcall *model-selector-fn* backend context)))
|
||||
(result (ignore-errors
|
||||
(if model
|
||||
@@ -125,7 +125,7 @@ sequenceDiagram
|
||||
(or (dolist (backend backends)
|
||||
(let ((backend-fn (gethash backend *neuro-backends*)))
|
||||
(when backend-fn
|
||||
(kernel-log "ASSOCIATIVE: Attempting backend ~a..." backend)
|
||||
(harness-log "ASSOCIATIVE: Attempting backend ~a..." backend)
|
||||
(let* ((model (when *model-selector-fn* (funcall *model-selector-fn* backend context)))
|
||||
(result (if model
|
||||
(funcall backend-fn prompt system-prompt :model model)
|
||||
@@ -149,7 +149,7 @@ Crucially, it mandates that the output be a Common Lisp property list, forcing t
|
||||
(global-context (context-assemble-global-awareness)))
|
||||
(if active-skill
|
||||
(progn
|
||||
(kernel-log "ASSOCIATIVE: Engaging skill '~a'~%" (skill-name active-skill))
|
||||
(harness-log "ASSOCIATIVE: Engaging skill '~a'~%" (skill-name active-skill))
|
||||
(let* ((prompt-generator (skill-neuro-prompt active-skill))
|
||||
(raw-prompt (when prompt-generator (funcall prompt-generator context)))
|
||||
(full-system-prompt (concatenate 'string
|
||||
@@ -177,7 +177,7 @@ To call a tool, you MUST use:
|
||||
(raw-thoughts (cl-ppcre:split (cl-ppcre:quote-meta-chars "|CONSENSUS-SEP|") thought))
|
||||
(suggestions nil))
|
||||
(dolist (raw-thought raw-thoughts)
|
||||
(kernel-log "ASSOCIATIVE RAW: ~a~%" raw-thought)
|
||||
(harness-log "ASSOCIATIVE RAW: ~a~%" raw-thought)
|
||||
(let* ((cleaned-thought
|
||||
(let ((match (cl-ppcre:scan-to-strings "(?s)```(?:lisp)?\\n?(.*?)\\n?```" raw-thought)))
|
||||
(if match
|
||||
@@ -191,7 +191,7 @@ To call a tool, you MUST use:
|
||||
(list :sensor :syntax-error
|
||||
:code cleaned-thought
|
||||
:error (format nil "~a" c)))))))
|
||||
(kernel-log "ASSOCIATIVE Suggestion: ~a~%" cleaned-thought)
|
||||
(harness-log "ASSOCIATIVE Suggestion: ~a~%" cleaned-thought)
|
||||
(when (and suggestion (listp suggestion))
|
||||
(push suggestion suggestions))))
|
||||
(if (and *consensus-enabled-p* suggestions)
|
||||
@@ -261,7 +261,7 @@ flowchart LR
|
||||
;; If any gate returns a LOG or EVENT (blocking/intercepting), stop and return it.
|
||||
(when (and (listp current-action)
|
||||
(member (getf current-action :type) '(:LOG :EVENT :log :event)))
|
||||
(kernel-log "DELIBERATE: Intercepted by skill '~a'~%" (skill-name skill))
|
||||
(harness-log "DELIBERATE: Intercepted by skill '~a'~%" (skill-name skill))
|
||||
(return-from decide current-action))))
|
||||
|
||||
current-action))
|
||||
|
||||
@@ -126,7 +126,7 @@ Because objects are stored immutably in the `*history-store*`, a snapshot is no
|
||||
(push (list :timestamp (get-universal-time) :data snapshot) *object-store-snapshots*)
|
||||
(when (> (length *object-store-snapshots*) 20)
|
||||
(setf *object-store-snapshots* (subseq *object-store-snapshots* 0 20)))
|
||||
(kernel-log "MEMORY - CoW Object Store snapshot created.")))
|
||||
(harness-log "MEMORY - CoW Object Store snapshot created.")))
|
||||
#+end_src
|
||||
|
||||
** Memory Rollback (rollback-object-store)
|
||||
@@ -138,8 +138,8 @@ Restores the state of the Memex from one of the previous snapshots.
|
||||
(let ((snapshot (nth index *object-store-snapshots*)))
|
||||
(if snapshot
|
||||
(progn (setf *object-store* (copy-hash-table (getf snapshot :data)))
|
||||
(kernel-log "MEMORY - Object Store rolled back to snapshot ~a" index))
|
||||
(kernel-log "MEMORY ERROR - Snapshot ~a not found." index))))
|
||||
(harness-log "MEMORY - Object Store rolled back to snapshot ~a" index))
|
||||
(harness-log "MEMORY ERROR - Snapshot ~a not found." index))))
|
||||
#+end_src
|
||||
|
||||
** Lookup Utilities
|
||||
|
||||
@@ -18,7 +18,7 @@ The `package.lisp` file defines the public API of the `org-agent` kernel. It exp
|
||||
;; --- Daemon Lifecycle ---
|
||||
#:start-daemon
|
||||
#:stop-daemon
|
||||
#:kernel-log
|
||||
#:harness-log
|
||||
#:main
|
||||
|
||||
;; --- Object Store (CLOSOS) ---
|
||||
@@ -133,7 +133,7 @@ The `package.lisp` file defines the public API of the `org-agent` kernel. It exp
|
||||
** Kernel Logging State
|
||||
#+begin_src lisp :tangle ../src/package.lisp
|
||||
(defvar *system-logs* nil)
|
||||
(defvar *logs-lock* (bt:make-lock "kernel-logs-lock"))
|
||||
(defvar *logs-lock* (bt:make-lock "harness-logs-lock"))
|
||||
(defvar *max-log-history* 100)
|
||||
#+end_src
|
||||
|
||||
@@ -171,8 +171,8 @@ The `package.lisp` file defines the public API of the `org-agent` kernel. It exp
|
||||
|
||||
** Kernel Logging Implementation
|
||||
#+begin_src lisp :tangle ../src/package.lisp
|
||||
(defun kernel-log (msg &rest args)
|
||||
"Centralized logging for the kernel."
|
||||
(defun harness-log (msg &rest args)
|
||||
"Centralized logging for the harness."
|
||||
(let ((formatted-msg (apply #'format nil msg args)))
|
||||
(bt:with-lock-held (*logs-lock*)
|
||||
(push formatted-msg *system-logs*)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
** Deep Reasoning: Why Hex-Length Framing?
|
||||
Streaming raw JSON over a socket is fragile. If a 5MB Org AST is fragmented by the OS network stack, a standard parser will crash or desynchronize.
|
||||
- **Physical Boundary:** By prefixing every message with a 6-character hex length, we create a deterministic physical boundary.
|
||||
- **Actuator-Agnosticism:** This protocol makes the kernel a "Dumb Terminal" host. Any program (Bash, Python, WebSockets) that can calculate a length and send bytes can now become an agentic interface.
|
||||
- **Actuator-Agnosticism:** This protocol makes the harness a "Dumb Terminal" host. Any program (Bash, Python, WebSockets) that can calculate a length and send bytes can now become an agentic interface.
|
||||
|
||||
** Package Context
|
||||
We begin by ensuring we are in the correct package.
|
||||
@@ -98,7 +98,7 @@ Parsing is the inverse of framing. This function performs three critical safety
|
||||
#+end_src
|
||||
|
||||
** Handshaking (make-hello-message)
|
||||
Every OACP connection begins with a `HELLO` handshake. This function constructs the standard response that the kernel sends to a client to announce its capabilities and version.
|
||||
Every OACP connection begins with a `HELLO` handshake. This function constructs the standard response that the harness sends to a client to announce its capabilities and version.
|
||||
|
||||
#+begin_src lisp :tangle ../src/protocol.lisp
|
||||
(defun make-hello-message (version)
|
||||
|
||||
@@ -167,7 +167,7 @@ Calculates the correct load order for a directory of skill filepaths, detecting
|
||||
The core "hot-loading" mechanism. It extracts Lisp blocks from an Org file and evaluates them within a dedicated package ("Jail").
|
||||
|
||||
*** Phase A: Demand
|
||||
- *Need:* Safely load skills from `.org` files without evaluating docstrings or kernel-level tangled blocks as logic.
|
||||
- *Need:* Safely load skills from `.org` files without evaluating docstrings or harness-level tangled blocks as logic.
|
||||
- *Success:* Exclude `#+begin_src lisp :tangle` blocks and ignore `:PROPERTIES:` and `:END:` drawers embedded within src blocks.
|
||||
|
||||
*** Phase B: Blueprint
|
||||
@@ -211,7 +211,7 @@ The loader must actively scan block arguments and filter out those containing `:
|
||||
(unless valid-p
|
||||
(error "Syntax Error: ~a" err)))
|
||||
|
||||
(kernel-log "KERNEL: Jailing skill '~a' in package ~a" skill-base-name pkg-name)
|
||||
(harness-log "HARNESS: Jailing skill '~a' in package ~a" skill-base-name pkg-name)
|
||||
(unless (find-package pkg-name)
|
||||
(let ((new-pkg (make-package pkg-name :use '(:cl))))
|
||||
(do-external-symbols (sym (find-package :org-agent)) (shadowing-import sym new-pkg))))
|
||||
@@ -223,7 +223,7 @@ The loader must actively scan block arguments and filter out those containing `:
|
||||
t)))
|
||||
(error (c)
|
||||
(let ((msg (format nil "~a" c)))
|
||||
(kernel-log "LOADER ERROR in skill '~a': ~a" skill-base-name msg)
|
||||
(harness-log "LOADER ERROR in skill '~a': ~a" skill-base-name msg)
|
||||
(setf (skill-entry-status entry) :failed)
|
||||
(setf (skill-entry-error-log entry) msg)
|
||||
nil)))))
|
||||
@@ -248,7 +248,7 @@ Wraps the skill loader in a thread with a hard timeout to prevent a single malfo
|
||||
(when (eq finished :error) (return :error))
|
||||
(unless (bt:thread-alive-p thread) (return :error))
|
||||
(when (> (- (get-internal-real-time) start-time) timeout-units)
|
||||
(kernel-log "KERNEL: Timing out skill ~a..." (pathname-name filepath))
|
||||
(harness-log "HARNESS: Timing out skill ~a..." (pathname-name filepath))
|
||||
#+sbcl (sb-thread:terminate-thread thread)
|
||||
#-sbcl (bt:destroy-thread thread)
|
||||
(return :timeout))
|
||||
@@ -256,7 +256,7 @@ Wraps the skill loader in a thread with a hard timeout to prevent a single malfo
|
||||
#+end_src
|
||||
|
||||
** Initializing All Skills (initialize-all-skills)
|
||||
The unified orchestrator for the kernel boot sequence. It scans the environment, calculates dependencies, and loads the system brain.
|
||||
The unified orchestrator for the harness boot sequence. It scans the environment, calculates dependencies, and loads the system brain.
|
||||
|
||||
#+begin_src lisp :tangle ../src/skills.lisp
|
||||
(defun initialize-all-skills ()
|
||||
@@ -267,7 +267,7 @@ The unified orchestrator for the kernel boot sequence. It scans the environment,
|
||||
(skills-dir (if resolved-path (uiop:ensure-directory-pathname resolved-path) nil)))
|
||||
|
||||
(unless (and skills-dir (uiop:directory-exists-p skills-dir))
|
||||
(kernel-log "KERNEL ERROR: Skills directory not found: ~a" skills-dir-str)
|
||||
(harness-log "HARNESS ERROR: Skills directory not found: ~a" skills-dir-str)
|
||||
(return-from initialize-all-skills nil))
|
||||
|
||||
(let ((sorted-files (topological-sort-skills skills-dir)))
|
||||
@@ -275,12 +275,12 @@ The unified orchestrator for the kernel boot sequence. It scans the environment,
|
||||
(unless (member "org-skill-agent" sorted-files :key #'pathname-name :test #'string-equal)
|
||||
(error "BOOT FAILURE: org-skill-agent.org not found in skills directory."))
|
||||
|
||||
(kernel-log "==================================================")
|
||||
(kernel-log " LOADER: Initializing ~a skills..." (length sorted-files))
|
||||
(harness-log "==================================================")
|
||||
(harness-log " LOADER: Initializing ~a skills..." (length sorted-files))
|
||||
|
||||
(dolist (file sorted-files)
|
||||
(let ((skill-name (pathname-name file)))
|
||||
(kernel-log " LOADER: Loading ~a..." skill-name)
|
||||
(harness-log " LOADER: Loading ~a..." skill-name)
|
||||
(load-skill-with-timeout file 5)))
|
||||
|
||||
;; Final Summary
|
||||
@@ -289,8 +289,8 @@ The unified orchestrator for the kernel boot sequence. It scans the environment,
|
||||
(declare (ignore k))
|
||||
(if (eq (skill-entry-status v) :ready) (incf ready) (incf failed)))
|
||||
*skill-catalog*)
|
||||
(kernel-log " LOADER: Boot Complete. [Ready: ~a] [Failed: ~a]" ready failed)
|
||||
(kernel-log "==================================================")
|
||||
(harness-log " LOADER: Boot Complete. [Ready: ~a] [Failed: ~a]" ready failed)
|
||||
(harness-log "==================================================")
|
||||
(values ready failed)))))
|
||||
#+end_src
|
||||
|
||||
@@ -325,7 +325,7 @@ We register a set of standard cognitive tools that all skills can use.
|
||||
|
||||
*** The Eval Tool
|
||||
#+begin_src lisp :tangle ../src/skills.lisp
|
||||
(def-cognitive-tool :eval "Evaluates raw Common Lisp code in the kernel image. Use this for complex calculations or internal state inspection."
|
||||
(def-cognitive-tool :eval "Evaluates raw Common Lisp code in the harness image. Use this for complex calculations or internal state inspection."
|
||||
((:code :type :string :description "The Lisp code to evaluate"))
|
||||
:guard (lambda (args context)
|
||||
(declare (ignore context))
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
(:file "src/lisp-repair")
|
||||
(:file "src/bouncer")
|
||||
(:file "src/verification-logic")
|
||||
(:file "src/core")
|
||||
(:file "src/loop")
|
||||
(:file "src/gateway-telegram")
|
||||
(:file "src/gateway-signal")
|
||||
(:file "src/gateway-matrix")
|
||||
|
||||
@@ -49,7 +49,7 @@ Define the core functional and security requirements for the neurosymbolic daemo
|
||||
- *Homoiconic Memory:* Use Org-mode AST as the primary data structure for both human and machine.
|
||||
- *Deterministic Reasoning:* Common Lisp (SBCL) for high-performance, threaded symbolic logic.
|
||||
- *Cognitive Loop:* A strict four-stage pipeline: Perceive -> Think (Associative) -> Decide (Deliberate) -> Act.
|
||||
- *Minimalist Core:* The kernel handles only the loop, object-store, and communication; all else is a skill.
|
||||
- *Minimalist Core:* the harness handles only the loop, object-store, and communication; all else is a skill.
|
||||
- *Security by Default:* Reader safety (*read-eval* disabled) and package-based skill jailing.
|
||||
|
||||
** 3. Success Criteria
|
||||
@@ -64,7 +64,7 @@ Define the core functional and security requirements for the neurosymbolic daemo
|
||||
:END:
|
||||
|
||||
** 1. Architectural Intent
|
||||
The kernel is transport-agnostic and business-logic-agnostic. It communicates with external actuators (Emacs, Web, Signal) via the Org-Agent Communication Protocol (OACP).
|
||||
the harness is transport-agnostic and business-logic-agnostic. It communicates with external actuators (Emacs, Web, Signal) via the Org-Agent Communication Protocol (OACP).
|
||||
|
||||
** 2. Semantic Interfaces
|
||||
#+begin_src lisp
|
||||
@@ -139,7 +139,7 @@ Follow the Core Invariants:
|
||||
(let ((payload (getf action :payload)))
|
||||
(if (and payload (search "proprietary" (format nil "~s" payload)))
|
||||
(progn
|
||||
(org-agent:kernel-log "DELIBERATE [Agent]: Sovereignty violation suspected. Blocking action.")
|
||||
(org-agent:harness-log "DELIBERATE [Agent]: Sovereignty violation suspected. Blocking action.")
|
||||
nil)
|
||||
action))))
|
||||
#+end_src
|
||||
|
||||
@@ -78,21 +78,21 @@ The primary entry point for all high-impact actions.
|
||||
;; 1. Secret Exposure Vector (Hard Block)
|
||||
((and text (bouncer-scan-secrets text))
|
||||
(let ((secret-name (bouncer-scan-secrets text)))
|
||||
(kernel-log "SECURITY VIOLATION: Blocked leak of secret ~a" secret-name)
|
||||
(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))
|
||||
(kernel-log "SECURITY WARNING: External network call detected. Queuing for approval.")
|
||||
(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)))
|
||||
(kernel-log "SECURITY: High-impact action ~a requires approval." (or (getf payload :tool) target))
|
||||
(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
|
||||
@@ -110,7 +110,7 @@ The primary entry point for all high-impact actions.
|
||||
(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)
|
||||
(kernel-log "BOUNCER: Found approved flight plan ~a. Re-injecting..." (org-object-id node))
|
||||
(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
|
||||
@@ -139,7 +139,7 @@ The primary entry point for all high-impact actions.
|
||||
(:approval-required
|
||||
(let* ((blocked-action (getf payload :action))
|
||||
(id (org-id-new)))
|
||||
(kernel-log "BOUNCER: Creating flight plan node...")
|
||||
(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"
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#+DEPENDS_ON: skill-shell-actuator skill-tdd-runner
|
||||
|
||||
* Overview
|
||||
The *Chaos Gauntlet* is an adversarial testing skill designed to ensure the system's resilience. It simulates environmental failures, malformed LLM responses, and network disruptions, forcing the kernel and its skills to handle "Byzantine" conditions gracefully.
|
||||
The *Chaos Gauntlet* is an adversarial testing skill designed to ensure the system's resilience. It simulates environmental failures, malformed LLM responses, and network disruptions, forcing the harness and its skills to handle "Byzantine" conditions gracefully.
|
||||
|
||||
* Phase A: Demand (PRD)
|
||||
:PROPERTIES:
|
||||
@@ -23,7 +23,7 @@ Verify the system's stability and error-handling capabilities under stress.
|
||||
- *Failure Simulation:* Ability to inject artificial delays or errors into the OACP bus.
|
||||
- *Byzantine Response Testing:* Test how System 2 handles nonsensical or malicious System 1 proposals.
|
||||
- *Network Resilience:* Simulate Gitea or LLM provider timeouts.
|
||||
- *Recovery Verification:* Ensure the kernel can recover from a "skip-event" restart.
|
||||
- *Recovery Verification:* Ensure the harness can recover from a "skip-event" restart.
|
||||
|
||||
* Phase D: Build (Implementation)
|
||||
:PROPERTIES:
|
||||
@@ -37,9 +37,9 @@ Verify the system's stability and error-handling capabilities under stress.
|
||||
(defun chaos-inject-error (sensor-type)
|
||||
"Injects a synthetic error into a specific sensor pipeline."
|
||||
(unless *chaos-enabled-p*
|
||||
(kernel-log "CHAOS ERROR - Injection blocked. Production gate is ACTIVE.")
|
||||
(harness-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)
|
||||
(harness-log "CHAOS - Injecting synthetic error into ~a sensor..." sensor-type)
|
||||
(inject-stimulus
|
||||
`(:type :EVENT :payload (:sensor ,sensor-type :error "SYNTHETIC_CHAOS_ERROR"))))
|
||||
|
||||
@@ -47,12 +47,12 @@ Verify the system's stability and error-handling capabilities under stress.
|
||||
"Executes a randomized stress test by injecting failures into the system."
|
||||
(declare (ignore context))
|
||||
(unless *chaos-enabled-p*
|
||||
(kernel-log "CHAOS ERROR - Stress test blocked. Production gate is ACTIVE.")
|
||||
(harness-log "CHAOS ERROR - Stress test blocked. Production gate is ACTIVE.")
|
||||
(return-from chaos-stress-test "FAILURE - Production gate active."))
|
||||
(let* ((payload (getf action :payload))
|
||||
(mode (or (getf payload :mode) :random))
|
||||
(intensity (or (getf payload :intensity) 3)))
|
||||
(kernel-log "CHAOS - Commencing stress test (Mode: ~a, Intensity: ~a)" mode intensity)
|
||||
(harness-log "CHAOS - Commencing stress test (Mode: ~a, Intensity: ~a)" mode intensity)
|
||||
(snapshot-object-store)
|
||||
(case mode
|
||||
(:random (dotimes (i intensity)
|
||||
@@ -67,13 +67,13 @@ Verify the system's stability and error-handling capabilities under stress.
|
||||
(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.")
|
||||
(harness-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.")
|
||||
(harness-log "CHAOS - Production gate ENABLED. Chaos injection is now BLOCKED.")
|
||||
t)
|
||||
#+end_src
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ Interfaces for conversational event handling and UI integration. Source of truth
|
||||
:content text
|
||||
:version (get-universal-time))))
|
||||
(setf (gethash msg-id *object-store*) obj)
|
||||
(kernel-log "CHAT - Message archived: ~a (~a)" msg-id role)
|
||||
(harness-log "CHAT - Message archived: ~a (~a)" msg-id role)
|
||||
(snapshot-object-store)
|
||||
msg-id))
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ Securely manage all authentication tokens required for the PSF to operate.
|
||||
|
||||
** 2. User Needs
|
||||
- *Unified Storage:* Single interface for API keys and Session Cookies.
|
||||
- *Masked Logging:* Ensure credentials never appear in plaintext in `kernel-log`.
|
||||
- *Masked Logging:* Ensure credentials never appear in plaintext in `harness-log`.
|
||||
- *Guided Onboarding:* Retain and improve the Google/Gemini cookie handshake.
|
||||
- *Persistence:* Securely save credentials to the Object Store via Merkle-Tree snapshots.
|
||||
|
||||
@@ -118,7 +118,7 @@ When a secret is updated, we immediately snapshot the Object Store to ensure the
|
||||
"Securely stores a secret and triggers a Merkle snapshot."
|
||||
(let ((key (format nil "~a-~a" provider type)))
|
||||
(setf (gethash key *vault-memory*) secret)
|
||||
(kernel-log "VAULT - Updated ~a for ~a. Triggering Merkle snapshot..." type provider)
|
||||
(harness-log "VAULT - Updated ~a for ~a. Triggering Merkle snapshot..." type provider)
|
||||
(snapshot-object-store)
|
||||
t))
|
||||
#+end_src
|
||||
@@ -129,11 +129,11 @@ Retained from the legacy Google skill, this provides the instructions for the so
|
||||
#+begin_src lisp :tangle ../src/credentials-vault.lisp
|
||||
(defun vault-onboard-gemini-web ()
|
||||
"Instructions for the Sovereign Cookie Handshake."
|
||||
(kernel-log "--- GEMINI WEB ONBOARDING ---")
|
||||
(kernel-log "1. Visit gemini.google.com")
|
||||
(kernel-log "2. Run the 'Get Gemini Cookies' Bookmarklet.")
|
||||
(kernel-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));})();")
|
||||
(kernel-log "PLATFORM GUIDE: Chrome/Firefox/Safari all support Bookmarklets via 'Add Page' or 'New Bookmark'.")
|
||||
(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)
|
||||
#+end_src
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ Move heavy neural and mathematical logic out of `core.lisp` and `neuro.lisp` int
|
||||
(api-key (getf auth :api-key))
|
||||
(endpoint "https://generativelanguage.googleapis.com/v1beta/models/text-embedding-004:embedContent"))
|
||||
(unless api-key
|
||||
(kernel-log "EMBEDDING ERROR: No API key for :gemini")
|
||||
(harness-log "EMBEDDING ERROR: No API key for :gemini")
|
||||
(return-from get-embedding nil))
|
||||
(let* ((url (format nil "~a?key=~a" endpoint api-key))
|
||||
(headers `(("Content-Type" . "application/json")))
|
||||
@@ -73,7 +73,7 @@ Move heavy neural and mathematical logic out of `core.lisp` and `neuro.lisp` int
|
||||
(embedding (getf (getf json :embedding) :values)))
|
||||
embedding)
|
||||
(error (c)
|
||||
(kernel-log "EMBEDDING FAILURE: ~a" c)
|
||||
(harness-log "EMBEDDING FAILURE: ~a" c)
|
||||
nil)))))
|
||||
|
||||
(defun dot-product (v1 v2)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#+FILETAGS: :system:config:sovereignty:psf:
|
||||
|
||||
* Overview
|
||||
The *Environment Configuration Manager* is the source of truth for user preferences. It persists settings (like LLM Model Fleets) into the kernel's Object Store, allowing for dynamic runtime reconfiguration without environment variable bloat.
|
||||
The *Environment Configuration Manager* is the source of truth for user preferences. It persists settings (like LLM Model Fleets) into the harness's Object Store, allowing for dynamic runtime reconfiguration without environment variable bloat.
|
||||
|
||||
* Phase A: Demand (PRD)
|
||||
:PROPERTIES:
|
||||
@@ -47,7 +47,7 @@ Define a standardized `CONFIG` object type in the Object Store. Provide getter/s
|
||||
:content (format nil "Fleet preference for ~a set to ~a" provider model-id)
|
||||
:version (get-universal-time))))
|
||||
(setf (gethash config-id *object-store*) obj)
|
||||
(kernel-log "CONFIG - Fleet updated: ~a -> ~a" provider model-id)
|
||||
(harness-log "CONFIG - Fleet updated: ~a -> ~a" provider model-id)
|
||||
t)))
|
||||
|
||||
(defun get-llm-model (provider &optional default)
|
||||
|
||||
@@ -88,7 +88,7 @@ Allows external skills to register logic at system lifecycle points.
|
||||
(defun orchestrator-register-hook (hook-name fn)
|
||||
"Registers a function for a named hook. Triggers a Merkle snapshot."
|
||||
(pushnew fn (gethash hook-name *hook-registry*))
|
||||
(kernel-log "ORCHESTRATOR - Registered hook function for ~a" hook-name)
|
||||
(harness-log "ORCHESTRATOR - Registered hook function for ~a" hook-name)
|
||||
(snapshot-object-store)
|
||||
t)
|
||||
#+end_src
|
||||
@@ -102,7 +102,7 @@ Executes all functions associated with a specific hook.
|
||||
(let ((functions (gethash hook-name *hook-registry*)))
|
||||
(dolist (fn functions)
|
||||
(handler-case (apply fn args)
|
||||
(error (c) (kernel-log "ORCHESTRATOR ERROR - Hook ~a failed: ~a" hook-name c))))))
|
||||
(error (c) (harness-log "ORCHESTRATOR ERROR - Hook ~a failed: ~a" hook-name c))))))
|
||||
#+end_src
|
||||
|
||||
** Cron: Task Scheduling
|
||||
@@ -112,7 +112,7 @@ Registers a recurring task to be executed during heartbeats.
|
||||
(defun orchestrator-schedule-task (task-id schedule fn)
|
||||
"Schedules a task for execution. Schedule can be an interval (integer seconds) or 'heartbeat'."
|
||||
(setf (gethash task-id *cron-registry*) (list :schedule schedule :fn fn :last-run 0))
|
||||
(kernel-log "ORCHESTRATOR - Scheduled task ~a (~a)" task-id schedule)
|
||||
(harness-log "ORCHESTRATOR - Scheduled task ~a (~a)" task-id schedule)
|
||||
(snapshot-object-store)
|
||||
t)
|
||||
#+end_src
|
||||
@@ -122,7 +122,7 @@ The internal loop that checks the cron-registry during every system pulse.
|
||||
|
||||
#+begin_src lisp :tangle ../src/event-orchestrator.lisp
|
||||
(defun orchestrator-process-cron ()
|
||||
"Checked by the kernel on every heartbeat."
|
||||
"Checked by the harness on every heartbeat."
|
||||
(let ((now (get-universal-time)))
|
||||
(maphash (lambda (id task)
|
||||
(let ((schedule (getf task :schedule))
|
||||
@@ -131,7 +131,7 @@ The internal loop that checks the cron-registry during every system pulse.
|
||||
(when (or (eq schedule :heartbeat)
|
||||
(and (integerp schedule) (>= (- now last-run) schedule)))
|
||||
(handler-case (funcall fn)
|
||||
(error (c) (kernel-log "ORCHESTRATOR ERROR - Cron task ~a failed: ~a" id c)))
|
||||
(error (c) (harness-log "ORCHESTRATOR ERROR - Cron task ~a failed: ~a" id c)))
|
||||
(setf (getf (gethash id *cron-registry*) :last-run) now))))
|
||||
*cron-registry*)))
|
||||
#+end_src
|
||||
@@ -160,7 +160,7 @@ Deterministic logic to classify incoming stimuli into complexity tiers.
|
||||
#+end_src
|
||||
|
||||
** Registration
|
||||
We register the orchestrator as a core skill and hot-patch the kernel's routing hook to use our classification logic.
|
||||
We register the orchestrator as a core skill and hot-patch the harness's routing hook to use our classification logic.
|
||||
|
||||
#+begin_src lisp :tangle ../src/event-orchestrator.lisp
|
||||
(progn
|
||||
@@ -200,7 +200,7 @@ We register the orchestrator as a core skill and hot-patch the kernel's routing
|
||||
|
||||
** 2. Chaos Scenarios
|
||||
- *Scenario A (Infinite Hook Loop):* Register two hooks that call each other and verify the orchestrator's recursion limit or handler-case prevents a kernel stack-overflow.
|
||||
- *Scenario B (Cron Stall):* Register a cron-job that performs a long synchronous sleep and verify the `kernel-log` identifies the delay in the heartbeat pulse.
|
||||
- *Scenario B (Cron Stall):* Register a cron-job that performs a long synchronous sleep and verify the `harness-log` identifies the delay in the heartbeat pulse.
|
||||
|
||||
* Phase F: Memory (RCA)
|
||||
- *[2026-04-09 Thu]:* Consolidated Cron, Hook Manager, and Cognitive Router into a single orchestrator. Fixed the lack of implementation for Cron and Hooks.
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#+FILETAGS: :security:logic:formal-methods:psf:
|
||||
|
||||
* Overview
|
||||
The *Formal Verification Gate* replaces heuristic whitelisting with symbolic logic proofs. It ensures that every action proposed by System 1 is *provably safe* against the kernel's core security invariants using a Lisp-native symbolic prover.
|
||||
The *Formal Verification Gate* replaces heuristic whitelisting with symbolic logic proofs. It ensures that every action proposed by System 1 is *provably safe* against the harness's core security invariants using a Lisp-native symbolic prover.
|
||||
|
||||
** Deep Reasoning: The Sandbox of Intent
|
||||
This gate is the first line of defense against both "Inside Threats" (maliciously modified skill files) and "Hallucination Threats" (LLMs generating unsafe commands).
|
||||
@@ -130,7 +130,7 @@ The core prover that applies all relevant invariants to an action.
|
||||
(eq inv-type action-target)
|
||||
(eq inv-type action-type))
|
||||
(unless (funcall inv-logic action context)
|
||||
(kernel-log "FORMAL FAILURE: Action ~s violated invariant ~a" action inv-name)
|
||||
(harness-log "FORMAL FAILURE: Action ~s violated invariant ~a" action inv-name)
|
||||
(setf all-passed nil)))))
|
||||
*formal-invariants*)
|
||||
all-passed))
|
||||
|
||||
@@ -19,7 +19,7 @@ The *Matrix Gateway* provides bi-directional communication via the Matrix Client
|
||||
Integrate the Org-Agent into the Matrix federation for secure, distributed chat.
|
||||
|
||||
** 2. Success Criteria
|
||||
- [ ] *Inbound:* Messages from Matrix rooms are normalized and injected into the Kernel Bus.
|
||||
- [ ] *Inbound:* Messages from Matrix rooms are normalized and injected into the harness Bus.
|
||||
- [ ] *Outbound:* The `:matrix` target correctly routes messages to specific room IDs.
|
||||
- [ ] *State:* The `since` token is maintained during a session to prevent message loops.
|
||||
|
||||
@@ -81,14 +81,14 @@ Sends an `m.room.message` to a Matrix room.
|
||||
(txn-id (get-universal-time))
|
||||
(url (format nil "~a/_matrix/client/v3/rooms/~a/send/m.room.message/~a" hs room-id txn-id)))
|
||||
(when (and hs token room-id text)
|
||||
(kernel-log "MATRIX: Sending message to ~a..." room-id)
|
||||
(harness-log "MATRIX: Sending message to ~a..." room-id)
|
||||
(handler-case
|
||||
(dex:put url
|
||||
:headers `(("Authorization" . ,(format nil "Bearer ~a" token))
|
||||
("Content-Type" . "application/json"))
|
||||
:content (cl-json:encode-json-to-string
|
||||
`((msgtype . "m.text") (body . ,text))))
|
||||
(error (c) (kernel-log "MATRIX ERROR: ~a" c))))))
|
||||
(error (c) (harness-log "MATRIX ERROR: ~a" c))))))
|
||||
#+end_src
|
||||
|
||||
** Sensor: Sync loop & Injection
|
||||
@@ -124,7 +124,7 @@ Polls the `/sync` endpoint and processes timeline events.
|
||||
(sender (cdr (assoc :sender event)))
|
||||
(body (cdr (assoc :body content))))
|
||||
(when (and (string= type "m.room.message") body)
|
||||
(kernel-log "MATRIX: Received message from ~a in ~a" sender room-id)
|
||||
(harness-log "MATRIX: Received message from ~a in ~a" sender room-id)
|
||||
(inject-stimulus
|
||||
(list :type :EVENT
|
||||
:payload (list :sensor :chat-message
|
||||
@@ -132,7 +132,7 @@ Polls the `/sync` endpoint and processes timeline events.
|
||||
:room-id room-id
|
||||
:sender sender
|
||||
:text body)))))))))
|
||||
(error (c) (kernel-log "MATRIX SYNC ERROR: ~a" c))))))
|
||||
(error (c) (harness-log "MATRIX SYNC ERROR: ~a" c))))))
|
||||
#+end_src
|
||||
|
||||
** Start Polling
|
||||
@@ -149,7 +149,7 @@ Initializes the Matrix background thread.
|
||||
(matrix-process-sync)
|
||||
(sleep 2)))
|
||||
:name "org-agent-matrix-gateway"))
|
||||
(kernel-log "MATRIX: Gateway sync active.")))
|
||||
(harness-log "MATRIX: Gateway sync active.")))
|
||||
#+end_src
|
||||
|
||||
** Stop Polling
|
||||
|
||||
@@ -19,7 +19,7 @@ The *Signal Gateway* provides bi-directional communication between the Sovereign
|
||||
Enable secure Signal communication for the Org-Agent.
|
||||
|
||||
** 2. Success Criteria
|
||||
- [ ] *Inbound:* Messages received via `signal-cli receive` are injected into the Kernel Bus.
|
||||
- [ ] *Inbound:* Messages received via `signal-cli receive` are injected into the harness Bus.
|
||||
- [ ] *Outbound:* The `:signal` target correctly routes messages via `signal-cli send`.
|
||||
- [ ] *Robustness:* Handles JSON output from `signal-cli` and filters system messages.
|
||||
|
||||
@@ -29,7 +29,7 @@ Enable secure Signal communication for the Org-Agent.
|
||||
:END:
|
||||
|
||||
** 1. Architectural Intent
|
||||
Wraps the `signal-cli` binary. Polling is done in a background thread to prevent blocking the kernel.
|
||||
Wraps the `signal-cli` binary. Polling is done in a background thread to prevent blocking the harness.
|
||||
|
||||
** 2. Semantic Interfaces
|
||||
- `(:sensor :chat-message :channel :signal ...)`
|
||||
@@ -68,19 +68,19 @@ Executes the `signal-cli send` command.
|
||||
(text (or (getf payload :text) (getf action :text)))
|
||||
(account (get-signal-account)))
|
||||
(when (and account chat-id text)
|
||||
(kernel-log "SIGNAL: Sending message to ~a..." chat-id)
|
||||
(harness-log "SIGNAL: Sending message to ~a..." chat-id)
|
||||
(handler-case
|
||||
(uiop:run-program (list "signal-cli" "-u" account "send" "-m" text chat-id)
|
||||
:output :string :error-output :string)
|
||||
(error (c) (kernel-log "SIGNAL ERROR: ~a" c))))))
|
||||
(error (c) (harness-log "SIGNAL ERROR: ~a" c))))))
|
||||
#+end_src
|
||||
|
||||
** Sensor: receive & Injection
|
||||
Polls for new messages and injects them into the kernel.
|
||||
Polls for new messages and injects them into the harness.
|
||||
|
||||
#+begin_src lisp :tangle ../src/gateway-signal.lisp
|
||||
(defun signal-process-updates ()
|
||||
"Polls for new messages via signal-cli and injects them into the kernel."
|
||||
"Polls for new messages via signal-cli and injects them into the harness."
|
||||
(let ((account (get-signal-account)))
|
||||
(when account
|
||||
(handler-case
|
||||
@@ -95,14 +95,14 @@ Polls for new messages and injects them into the kernel.
|
||||
(data-message (cdr (assoc :data-message envelope)))
|
||||
(text (cdr (assoc :message data-message))))
|
||||
(when (and source text)
|
||||
(kernel-log "SIGNAL: Received message from ~a" source)
|
||||
(harness-log "SIGNAL: Received message from ~a" source)
|
||||
(inject-stimulus
|
||||
(list :type :EVENT
|
||||
:payload (list :sensor :chat-message
|
||||
:channel :signal
|
||||
:chat-id source
|
||||
:text text))))))))
|
||||
(error (c) (kernel-log "SIGNAL POLL ERROR: ~a" c))))))
|
||||
(error (c) (harness-log "SIGNAL POLL ERROR: ~a" c))))))
|
||||
#+end_src
|
||||
|
||||
** Start Polling
|
||||
@@ -119,7 +119,7 @@ Initializes the Signal background thread.
|
||||
(signal-process-updates)
|
||||
(sleep 5)))
|
||||
:name "org-agent-signal-gateway"))
|
||||
(kernel-log "SIGNAL: Gateway polling active.")))
|
||||
(harness-log "SIGNAL: Gateway polling active.")))
|
||||
#+end_src
|
||||
|
||||
** Stop Polling
|
||||
|
||||
@@ -19,7 +19,7 @@ The *Telegram Gateway* provides bi-directional communication between the Soverei
|
||||
Enable mobile/remote access to the Org-Agent via a secure Telegram bot.
|
||||
|
||||
** 2. Success Criteria
|
||||
- [ ] *Inbound:* Messages from authorized Telegram IDs are injected into the Kernel Bus.
|
||||
- [ ] *Inbound:* Messages from authorized Telegram IDs are injected into the harness Bus.
|
||||
- [ ] *Outbound:* The `:telegram` target correctly routes messages to the Bot API.
|
||||
- [ ] *Persistence:* The polling offset is maintained to prevent duplicate processing.
|
||||
|
||||
@@ -82,19 +82,19 @@ Fetches the Bot API token from the secure vault.
|
||||
(token (get-telegram-token))
|
||||
(url (format nil "https://api.telegram.org/bot~a/sendMessage" token)))
|
||||
(when (and token chat-id text)
|
||||
(kernel-log "TELEGRAM: Sending message to ~a..." chat-id)
|
||||
(harness-log "TELEGRAM: Sending message to ~a..." chat-id)
|
||||
(handler-case
|
||||
(dex:post url
|
||||
:headers '(("Content-Type" . "application/json"))
|
||||
:content (cl-json:encode-json-to-string
|
||||
`((chat_id . ,chat-id) (text . ,text))))
|
||||
(error (c) (kernel-log "TELEGRAM ERROR: ~a" c))))))
|
||||
(error (c) (harness-log "TELEGRAM ERROR: ~a" c))))))
|
||||
#+end_src
|
||||
|
||||
** Sensor: getUpdates & Injection
|
||||
#+begin_src lisp :tangle ../src/gateway-telegram.lisp
|
||||
(defun telegram-process-updates ()
|
||||
"Polls for new messages and injects them into the kernel."
|
||||
"Polls for new messages and injects them into the harness."
|
||||
(let* ((token (get-telegram-token))
|
||||
(url (format nil "https://api.telegram.org/bot~a/getUpdates?offset=~a"
|
||||
token (1+ *telegram-last-update-id*))))
|
||||
@@ -111,14 +111,14 @@ Fetches the Bot API token from the secure vault.
|
||||
(text (cdr (assoc :text message))))
|
||||
(setf *telegram-last-update-id* update-id)
|
||||
(when (and text chat-id)
|
||||
(kernel-log "TELEGRAM: Received message from ~a" chat-id)
|
||||
(harness-log "TELEGRAM: Received message from ~a" chat-id)
|
||||
(inject-stimulus
|
||||
(list :type :EVENT
|
||||
:payload (list :sensor :chat-message
|
||||
:channel :telegram
|
||||
:chat-id (format nil "~a" chat-id)
|
||||
:text text)))))))
|
||||
(error (c) (kernel-log "TELEGRAM POLL ERROR: ~a" c))))))
|
||||
(error (c) (harness-log "TELEGRAM POLL ERROR: ~a" c))))))
|
||||
#+end_src
|
||||
|
||||
** Start Polling
|
||||
@@ -135,7 +135,7 @@ Initializes the Telegram background thread.
|
||||
(telegram-process-updates)
|
||||
(sleep 3)))
|
||||
:name "org-agent-telegram-gateway"))
|
||||
(kernel-log "TELEGRAM: Gateway polling active.")))
|
||||
(harness-log "TELEGRAM: Gateway polling active.")))
|
||||
#+end_src
|
||||
|
||||
** Stop Polling
|
||||
|
||||
@@ -65,7 +65,7 @@ Tests in `tests/memory-suite-tests.lisp` will verify the round-trip conversion a
|
||||
#+end_src
|
||||
|
||||
** Node Structure Definition
|
||||
We define the standard `org-node` structure used throughout the kernel.
|
||||
We define the standard `org-node` structure used throughout the harness.
|
||||
|
||||
#+begin_src lisp :tangle ../src/homoiconic-memory.lisp
|
||||
(defun make-memory-node (headline &key content properties children)
|
||||
@@ -97,7 +97,7 @@ Ensures every headline has a unique ID property using the system standard `org-i
|
||||
node
|
||||
(let ((new-id (org-agent:org-id-get-create)))
|
||||
(setf (getf node :properties) (append props (list :ID new-id)))
|
||||
(kernel-log "MEMORY - Injected standard ID ~a" new-id)
|
||||
(harness-log "MEMORY - Injected standard ID ~a" new-id)
|
||||
node))))
|
||||
#+end_src
|
||||
|
||||
@@ -128,7 +128,7 @@ Utilizes the Emacs bridge (or local parser) to convert text to JSON.
|
||||
(defun memory-org-to-json (source-path)
|
||||
"Routes to the Emacs-based Org-JSON bridge."
|
||||
;; Future implementation will use the org-json-convert CLI tool
|
||||
(kernel-log "MEMORY - Parsing ~a to JSON..." source-path)
|
||||
(harness-log "MEMORY - Parsing ~a to JSON..." source-path)
|
||||
nil)
|
||||
#+end_src
|
||||
|
||||
@@ -139,7 +139,7 @@ Converts a structured AST back into Org-mode text.
|
||||
(defun memory-json-to-org (ast)
|
||||
"Materializes a JSON AST into Org-mode text."
|
||||
;; Placeholder for org-element-interpret-data equivalent
|
||||
(kernel-log "MEMORY - Rendering AST to text...")
|
||||
(harness-log "MEMORY - Rendering AST to text...")
|
||||
"")
|
||||
#+end_src
|
||||
|
||||
@@ -175,7 +175,7 @@ Converts a structured AST back into Org-mode text.
|
||||
|
||||
** 2. Chaos Scenarios
|
||||
- *Scenario A (Duplicate IDs):* Intentionally inject two nodes with the same ID and verify the normalizer detects the collision and re-generates one.
|
||||
- *Scenario B (Broken AST):* Pass a malformed list to `memory-normalize-ast` and verify it fails gracefully with a log entry rather than crashing the kernel.
|
||||
- *Scenario B (Broken AST):* Pass a malformed list to `memory-normalize-ast` and verify it fails gracefully with a log entry rather than crashing the harness.
|
||||
|
||||
* Phase F: Memory (RCA)
|
||||
- *[2026-04-09 Thu]:* Consolidated `org-mode`, `org-json-bridge`, and `ast-normalization` into this single skill. Standardized the recursive normalization path.
|
||||
|
||||
@@ -21,14 +21,14 @@ Define a secure and extensible ingress for external communication channels.
|
||||
** 2. User Needs
|
||||
- *Multi-Channel Ingress:* Support Signal (via signal-cli), Telegram (via Bot API), and generic Webhooks.
|
||||
- *Payload Normalization:* Convert platform-specific JSON into standard Lisp plists.
|
||||
- *Security & Authentication:* Verify sender identity before injecting stimuli into the kernel.
|
||||
- *Security & Authentication:* Verify sender identity before injecting stimuli into the harness.
|
||||
- *Asynchronous Reception:* Non-blocking monitoring of inbound message queues.
|
||||
|
||||
** 3. Success Criteria
|
||||
*** TODO Signal-cli message reception and parsing
|
||||
*** TODO Telegram Bot API webhook normalization
|
||||
*** TODO Sender verification logic (Whitelisting)
|
||||
*** TODO Autonomous stimulus injection into the Kernel Bus
|
||||
*** TODO Autonomous stimulus injection into the harness Bus
|
||||
|
||||
|
||||
* Phase B: Blueprint (PROTOCOL)
|
||||
@@ -95,6 +95,6 @@ Error handling and logging will be crucial for observability and maintainability
|
||||
2. The raw message is passed to `inbound-message-handler` with `channel` = `:signal`.
|
||||
3. `inbound-message-handler` calls `normalize-message` to convert the Signal payload to a standard plist.
|
||||
4. `inbound-message-handler` calls `authenticate-sender` to verify the sender's identity.
|
||||
5. If authentication succeeds, `inbound-message-handler` calls `inject-stimulus` to inject the message into the Kernel.
|
||||
5. If authentication succeeds, `inbound-message-handler` calls `inject-stimulus` to inject the message into the harness.
|
||||
6. Error handling and logging are performed at each step.
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ RULES:
|
||||
(when (eq sensor :heartbeat)
|
||||
(let* ((base-dir (or (uiop:getenv "MEMEX_DIR") "/home/user/memex/"))
|
||||
(inbox-path (merge-pathnames "inbox.org" base-dir)))
|
||||
(org-agent:kernel-log "INBOX - Scanning ~a for migration..." (uiop:native-namestring inbox-path))
|
||||
(org-agent:harness-log "INBOX - Scanning ~a for migration..." (uiop:native-namestring inbox-path))
|
||||
;; Physical move logic would go here using Org AST parsing
|
||||
'(:target :system :payload (:action :message :text "Inbox processing complete (Simulation)."))))))
|
||||
#+end_src
|
||||
|
||||
@@ -69,7 +69,7 @@ Hooks into the `:heartbeat` sensor.
|
||||
(if (and (eq sensor :heartbeat)
|
||||
(> (- now *last-reflection-time*) *reflection-interval*))
|
||||
(progn
|
||||
(kernel-log "GARDENER - Initiating Latent Reflection...")
|
||||
(harness-log "GARDENER - Initiating Latent Reflection...")
|
||||
(setf *last-reflection-time* now)
|
||||
t)
|
||||
nil)))
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#+FILETAGS: :system:repair:syntax:lisp:psf:
|
||||
|
||||
* Overview
|
||||
The *Lisp Repair Syntax Gate* asynchronously intercepts `:syntax-error` events emitted by the kernel when System 1 (LLM) proposals fail to parse. It performs deterministic or neural repairs and re-injects the corrected action into the pipeline.
|
||||
The *Lisp Repair Syntax Gate* asynchronously intercepts `:syntax-error` events emitted by the harness when System 1 (LLM) proposals fail to parse. It performs deterministic or neural repairs and re-injects the corrected action into the pipeline.
|
||||
|
||||
* Implementation
|
||||
|
||||
@@ -56,20 +56,20 @@ Reacts to syntax error events and transforms them into repaired requests.
|
||||
(let* ((payload (getf context :payload))
|
||||
(code (getf payload :code))
|
||||
(error-msg (getf payload :error)))
|
||||
(kernel-log "SYNTAX GATE: Reacting to broken Lisp stimulus...")
|
||||
(harness-log "SYNTAX GATE: Reacting to broken Lisp stimulus...")
|
||||
(let ((fast-fix (deterministic-repair code)))
|
||||
(handler-case
|
||||
(let ((repaired (read-from-string fast-fix)))
|
||||
(kernel-log "SYNTAX GATE: Deterministic repair SUCCESS.")
|
||||
(harness-log "SYNTAX GATE: Deterministic repair SUCCESS.")
|
||||
repaired)
|
||||
(error ()
|
||||
(kernel-log "SYNTAX GATE: Deterministic repair failed. Escalating...")
|
||||
(harness-log "SYNTAX GATE: Deterministic repair failed. Escalating...")
|
||||
(let ((deep-fix (neural-repair code error-msg)))
|
||||
(handler-case
|
||||
(let ((repaired (read-from-string deep-fix)))
|
||||
(kernel-log "SYNTAX GATE: Neural repair SUCCESS.")
|
||||
(harness-log "SYNTAX GATE: Neural repair SUCCESS.")
|
||||
repaired)
|
||||
(error ()
|
||||
(kernel-log "SYNTAX GATE: Neural repair failed.")
|
||||
(harness-log "SYNTAX GATE: Neural repair failed.")
|
||||
(list :type :LOG :payload (list :text "Lisp Repair Failed.")))))))))))
|
||||
#+end_src
|
||||
|
||||
@@ -31,7 +31,7 @@ Provide a secure, non-redundant interface for multi-provider LLM interaction.
|
||||
:END:
|
||||
|
||||
** 1. Architectural Intent
|
||||
The gateway utilizes a functional dispatch pattern. A single entry point, `execute-llm-request`, resolves the provider-specific nuances (URLs, headers, JSON structures) while exposing a uniform interface to the kernel.
|
||||
The gateway utilizes a functional dispatch pattern. A single entry point, `execute-llm-request`, resolves the provider-specific nuances (URLs, headers, JSON structures) while exposing a uniform interface to the harness.
|
||||
|
||||
** 2. Semantic Interfaces
|
||||
#+begin_src lisp
|
||||
@@ -88,7 +88,7 @@ This is the primary actuator for neural reasoning. It handles the specific JSON
|
||||
(let ((api-key (vault-get-secret provider :type :api-key))
|
||||
(full-prompt (format nil "~a~%~%Prompt: ~a" system-prompt prompt)))
|
||||
|
||||
(kernel-log "SYSTEM 1: Requesting ~a (Model: ~a) [Key: ~a]"
|
||||
(harness-log "SYSTEM 1: Requesting ~a (Model: ~a) [Key: ~a]"
|
||||
provider (or model "default") (vault-mask-string api-key))
|
||||
|
||||
(case provider
|
||||
@@ -157,7 +157,7 @@ Register the unified gateway as a cognitive tool.
|
||||
:provider (getf args :provider)
|
||||
:model (getf args :model))))
|
||||
#+end_src
|
||||
Register each supported provider with the kernel's neural registry.
|
||||
Register each supported provider with the harness's neural registry.
|
||||
|
||||
#+begin_src lisp :tangle ../src/llm-gateway.lisp
|
||||
(dolist (p '(:anthropic :gemini-api :gemini-web :groq :ollama :openai :openrouter))
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#+FILETAGS: :protocol:oacp:security:validation:psf:
|
||||
|
||||
* Overview
|
||||
The *OACP Schema Validator* skill provides deep structural validation for all messages entering the org-agent kernel. It ensures that every property list adheres to a strict schema, preventing malformed data from causing kernel-level errors.
|
||||
The *OACP Schema Validator* skill provides deep structural validation for all messages entering the org-agent kernel. It ensures that every property list adheres to a strict schema, preventing malformed data from causing harness-level errors.
|
||||
|
||||
* Phase A: Demand (PRD)
|
||||
:PROPERTIES:
|
||||
|
||||
@@ -67,4 +67,4 @@ The Onboarding Protocol aims for a modular, extensible, and interactive configur
|
||||
Generates the `.env` file from a template, populating it with the configuration data gathered from the other calibration functions. Returns `T` on success, `NIL` on failure.
|
||||
|
||||
*** `validate-env-variables -> plist`
|
||||
Validates .env variables are set and functional for the kernel, actuators, and models. Returns a plist `(:kernel t :actuators t :models t)`. This is the main test before boot.
|
||||
Validates .env variables are set and functional for the harness, actuators, and models. Returns a plist `(:kernel t :actuators t :models t)`. This is the main test before boot.
|
||||
|
||||
@@ -69,7 +69,7 @@ Invokes the Python bridge and parses its JSON output.
|
||||
#+end_src
|
||||
|
||||
** Cognitive Tool: Browser
|
||||
Register the high-fidelity browsing tool with the kernel.
|
||||
Register the high-fidelity browsing tool with the harness.
|
||||
|
||||
#+begin_src lisp :tangle ../src/playwright.lisp
|
||||
(def-cognitive-tool :browser
|
||||
|
||||
@@ -53,7 +53,7 @@ Define a high-integrity, recursive security sandbox for Lisp execution.
|
||||
;; Strings
|
||||
format concatenate string-downcase string-upcase search
|
||||
;; Kernel specifics
|
||||
org-agent::kernel-log
|
||||
org-agent::harness-log
|
||||
org-agent::snapshot-object-store
|
||||
org-agent::rollback-object-store
|
||||
org-agent::lookup-object
|
||||
@@ -91,7 +91,7 @@ We allow other skills to register safe symbols for the harness.
|
||||
(defun safety-harness-register (symbols)
|
||||
"Adds symbols to the global safety registry."
|
||||
(setf *safety-registry* (append *safety-registry* (if (listp symbols) symbols (list symbols))))
|
||||
(kernel-log "SAFETY HARNESS: Registered ~a new safe symbols." (length (if (listp symbols) symbols (list symbols)))))
|
||||
(harness-log "SAFETY HARNESS: Registered ~a new safe symbols." (length (if (listp symbols) symbols (list symbols)))))
|
||||
|
||||
(defun safety-harness-is-safe (symbol)
|
||||
"Checks if a symbol is in the static whitelist or the dynamic registry."
|
||||
@@ -119,7 +119,7 @@ We allow other skills to register safe symbols for the harness.
|
||||
((safety-harness-is-safe head)
|
||||
(every #'safety-harness-ast-walk (cdr form)))
|
||||
(t
|
||||
(kernel-log "SAFETY HARNESS: Blocked call to non-whitelisted function ~a" head)
|
||||
(harness-log "SAFETY HARNESS: Blocked call to non-whitelisted function ~a" head)
|
||||
nil))))
|
||||
(t nil)))
|
||||
#+end_src
|
||||
@@ -153,7 +153,7 @@ We allow other skills to register safe symbols for the harness.
|
||||
:symbolic (lambda (action context)
|
||||
;; The decide-gate already calls safety-harness-validate via global logic,
|
||||
;; but this skill can provide additional context or logging.
|
||||
(kernel-log "SYSTEM 2 [Safety]: Intercepted critical action for validation.")
|
||||
(harness-log "SYSTEM 2 [Safety]: Intercepted critical action for validation.")
|
||||
action))
|
||||
#+end_src
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ The *Self-Fix Agent* is the system's "Repair Mechanism." It takes failure hypoth
|
||||
(search "skills/" (namestring target-file)))))
|
||||
|
||||
(org-agent:snapshot-object-store)
|
||||
(org-agent:kernel-log "SELF-FIX - Attempting surgical fix on ~a..." target-file)
|
||||
(org-agent:harness-log "SELF-FIX - Attempting surgical fix on ~a..." target-file)
|
||||
|
||||
(handler-case
|
||||
(if (uiop:file-exists-p target-file)
|
||||
@@ -41,24 +41,24 @@ The *Self-Fix Agent* is the system's "Repair Mechanism." It takes failure hypoth
|
||||
|
||||
(if is-skill
|
||||
(progn
|
||||
(org-agent:kernel-log "SELF-FIX - Reloading modified skill ~a..." target-file)
|
||||
(org-agent:harness-log "SELF-FIX - Reloading modified skill ~a..." target-file)
|
||||
(if (org-agent:load-skill-from-org target-file)
|
||||
(progn
|
||||
(org-agent:kernel-log "SELF-FIX SUCCESS - Applied and reloaded.")
|
||||
(org-agent:harness-log "SELF-FIX SUCCESS - Applied and reloaded.")
|
||||
t)
|
||||
(progn
|
||||
(org-agent:kernel-log "SELF-FIX FAILURE - Skill reload failed. Rolling back.")
|
||||
(org-agent:harness-log "SELF-FIX FAILURE - Skill reload failed. Rolling back.")
|
||||
(with-open-file (out target-file :direction :output :if-exists :supersede)
|
||||
(write-string content out))
|
||||
(org-agent:rollback-object-store 0)
|
||||
nil)))
|
||||
(progn
|
||||
(org-agent:kernel-log "SELF-FIX SUCCESS - Applied fix to file.")
|
||||
(org-agent:harness-log "SELF-FIX SUCCESS - Applied fix to file.")
|
||||
t)))
|
||||
(progn (org-agent:kernel-log "SELF-FIX FAILURE - Pattern not found.") nil)))
|
||||
(progn (org-agent:kernel-log "SELF-FIX FAILURE - File not found.") nil))
|
||||
(progn (org-agent:harness-log "SELF-FIX FAILURE - Pattern not found.") nil)))
|
||||
(progn (org-agent:harness-log "SELF-FIX FAILURE - File not found.") nil))
|
||||
(error (c)
|
||||
(org-agent:kernel-log "SELF-FIX CRASH - ~a. Rolling back." c)
|
||||
(org-agent:harness-log "SELF-FIX CRASH - ~a. Rolling back." c)
|
||||
(org-agent:rollback-object-store 0)
|
||||
nil))))
|
||||
#+end_src
|
||||
|
||||
@@ -171,7 +171,7 @@ Hardware-Level Isolation for future security evolution.
|
||||
(defun provision-microvm (id &key (cpu 1) (ram 512))
|
||||
"Hardware-Level Isolation: Provisions an ephemeral Firecracker MicroVM.
|
||||
This is the high-security evolution of directory-based sandboxing."
|
||||
(kernel-log "SECURITY [Hardware] - Provisioning MicroVM ~a (CPU: ~a, RAM: ~aMB)..." id cpu ram)
|
||||
(harness-log "SECURITY [Hardware] - Provisioning MicroVM ~a (CPU: ~a, RAM: ~aMB)..." id cpu ram)
|
||||
;; Future implementation: Wraps 'fcvm' or 'firecracker' CLI calls.
|
||||
(format nil "vm-~a-provisioned" id))
|
||||
#+end_src
|
||||
|
||||
@@ -13,8 +13,8 @@ The *State Persistence Layer* ensures the durability and sovereignty of the agen
|
||||
While the *Prover* and *Bouncer* protect against internal skill failures, the Merkle-Tree architecture within the State Layer protects against **External Threats** (e.g., a hacker or virus modifying your `.org` files directly on disk).
|
||||
|
||||
1. **Skill Hashing:** Every code block and headline in a skill file has a unique Merkle hash recorded in the Object Store.
|
||||
2. **Integrity Verification:** Upon loading or reloading a skill, the Kernel re-calculates the hash and compares it against the "known good" state in the Merkle Tree.
|
||||
3. **Automatic Lockdown:** If a file has been tampered with externally, the hash mismatch triggers an immediate lockdown. The Kernel refuses to execute the skill and alerts the Sovereign via Signal/Telegram.
|
||||
2. **Integrity Verification:** Upon loading or reloading a skill, the harness re-calculates the hash and compares it against the "known good" state in the Merkle Tree.
|
||||
3. **Automatic Lockdown:** If a file has been tampered with externally, the hash mismatch triggers an immediate lockdown. the harness refuses to execute the skill and alerts the Sovereign via Signal/Telegram.
|
||||
|
||||
* Phase A: Demand (PRD)
|
||||
:PROPERTIES:
|
||||
@@ -88,7 +88,7 @@ Serializes the Merkle history and current pointers to a Lisp file.
|
||||
"Serializes the entire history store and current pointers to a local Lisp image."
|
||||
(let ((image-file (persistence-get-local-path)))
|
||||
(ensure-directories-exist image-file)
|
||||
(kernel-log "PERSISTENCE - Dumping local image to ~a..." (uiop:native-namestring image-file))
|
||||
(harness-log "PERSISTENCE - Dumping local image to ~a..." (uiop:native-namestring image-file))
|
||||
(with-open-file (out image-file :direction :output :if-exists :supersede)
|
||||
(format out "(in-package :org-agent)~%")
|
||||
;; 1. Dump all immutable objects in the history store
|
||||
@@ -111,11 +111,11 @@ Restores the state from the local disk.
|
||||
(let ((image-file (persistence-get-local-path)))
|
||||
(if (uiop:file-exists-p image-file)
|
||||
(progn
|
||||
(kernel-log "PERSISTENCE - Loading local image...")
|
||||
(harness-log "PERSISTENCE - Loading local image...")
|
||||
(load image-file)
|
||||
t)
|
||||
(progn
|
||||
(kernel-log "PERSISTENCE ERROR - Local image not found.")
|
||||
(harness-log "PERSISTENCE ERROR - Local image not found.")
|
||||
nil))))
|
||||
#+end_src
|
||||
|
||||
@@ -158,10 +158,10 @@ Pushes the serialized knowledge graph to the decentralized network.
|
||||
:headers '(("Content-Type" . "multipart/form-data"))))
|
||||
(result (cl-json:decode-json-from-string response))
|
||||
(cid (cdr (assoc :hash result))))
|
||||
(kernel-log "PERSISTENCE - Checkpoint to IPFS successful. CID: ~a" cid)
|
||||
(harness-log "PERSISTENCE - Checkpoint to IPFS successful. CID: ~a" cid)
|
||||
cid)
|
||||
(error (c)
|
||||
(kernel-log "PERSISTENCE ERROR - IPFS push failed: ~a" c)
|
||||
(harness-log "PERSISTENCE ERROR - IPFS push failed: ~a" c)
|
||||
nil))))
|
||||
#+end_src
|
||||
|
||||
@@ -190,10 +190,10 @@ Restores the graph from IPFS, using a safe parser to prevent injection.
|
||||
:last-sync (cdr (assoc :last-sync item))
|
||||
:hash (cdr (assoc :hash item)))))
|
||||
(setf (gethash id *object-store*) obj)))
|
||||
(kernel-log "PERSISTENCE - Restored from IPFS: ~a" cid)
|
||||
(harness-log "PERSISTENCE - Restored from IPFS: ~a" cid)
|
||||
t)
|
||||
(error (c)
|
||||
(kernel-log "PERSISTENCE ERROR - IPFS restoration failed: ~a" c)
|
||||
(harness-log "PERSISTENCE ERROR - IPFS restoration failed: ~a" c)
|
||||
nil))))
|
||||
#+end_src
|
||||
|
||||
@@ -254,7 +254,7 @@ Expose persistence capabilities to the neural System 1.
|
||||
#+end_src
|
||||
|
||||
** 2. Chaos Scenarios
|
||||
- *Scenario A (IPFS Daemon Down):* Kill the IPFS daemon and verify `persistence-push-ipfs` returns a standardized error instead of hanging the kernel.
|
||||
- *Scenario A (IPFS Daemon Down):* Kill the IPFS daemon and verify `persistence-push-ipfs` returns a standardized error instead of hanging the harness.
|
||||
- *Scenario B (Corrupt Image):* Intentionally mangle the `memory-image.lisp` file and verify the loader catches the error during `load` and falls back to a clean state.
|
||||
|
||||
* Phase F: Memory (RCA)
|
||||
|
||||
@@ -38,7 +38,7 @@ Maintain a state-aware provider cascade that routes around "pain" (failures) and
|
||||
(defun token-accountant-record-pain (provider)
|
||||
"Marks a provider as 'pained' (failed). It will be de-prioritized."
|
||||
(setf (gethash provider *provider-pain-table*) (+ (get-universal-time) 600)) ; 10 min penalty
|
||||
(kernel-log "ACCOUNTANT - Provider ~a de-prioritized due to failure." provider))
|
||||
(harness-log "ACCOUNTANT - Provider ~a de-prioritized due to failure." provider))
|
||||
|
||||
(defun token-accountant-get-cascade (context)
|
||||
"Returns a dynamic list of providers, routing around pained ones. Uses standardized gateway keywords."
|
||||
@@ -70,7 +70,7 @@ Maintain a state-aware provider cascade that routes around "pain" (failures) and
|
||||
(t nil))))
|
||||
|
||||
(defun token-accountant-patch-kernel ()
|
||||
"Hot-patches the kernel's cascade and model selector to use our dynamic logic."
|
||||
"Hot-patches the harness's cascade and model selector to use our dynamic logic."
|
||||
(setf org-agent:*provider-cascade* #'token-accountant-get-cascade)
|
||||
(setf org-agent::*model-selector-fn* #'token-accountant-get-model-for-provider))
|
||||
#+end_src
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
(defun token-accountant-record-pain (provider)
|
||||
"Marks a provider as 'pained' (failed). It will be de-prioritized."
|
||||
(setf (gethash provider *provider-pain-table*) (+ (get-universal-time) 600)) ; 10 min penalty
|
||||
(kernel-log "ACCOUNTANT - Provider ~a de-prioritized due to failure." provider))
|
||||
(harness-log "ACCOUNTANT - Provider ~a de-prioritized due to failure." provider))
|
||||
|
||||
(defun token-accountant-get-cascade (context)
|
||||
"Returns a dynamic list of providers, routing around pained ones. Uses standardized gateway keywords."
|
||||
@@ -37,6 +37,6 @@
|
||||
(t nil))))
|
||||
|
||||
(defun token-accountant-patch-kernel ()
|
||||
"Hot-patches the kernel's cascade and model selector to use our dynamic logic."
|
||||
"Hot-patches the harness's cascade and model selector to use our dynamic logic."
|
||||
(setf org-agent:*provider-cascade* #'token-accountant-get-cascade)
|
||||
(setf org-agent::*model-selector-fn* #'token-accountant-get-model-for-provider))
|
||||
|
||||
@@ -42,21 +42,21 @@
|
||||
;; 1. Secret Exposure Vector (Hard Block)
|
||||
((and text (bouncer-scan-secrets text))
|
||||
(let ((secret-name (bouncer-scan-secrets text)))
|
||||
(kernel-log "SECURITY VIOLATION: Blocked leak of secret ~a" secret-name)
|
||||
(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))
|
||||
(kernel-log "SECURITY WARNING: External network call detected. Queuing for approval.")
|
||||
(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)))
|
||||
(kernel-log "SECURITY: High-impact action ~a requires approval." (or (getf payload :tool) target))
|
||||
(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
|
||||
@@ -71,7 +71,7 @@
|
||||
(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)
|
||||
(kernel-log "BOUNCER: Found approved flight plan ~a. Re-injecting..." (org-object-id node))
|
||||
(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
|
||||
@@ -97,7 +97,7 @@
|
||||
(:approval-required
|
||||
(let* ((blocked-action (getf payload :action))
|
||||
(id (org-id-new)))
|
||||
(kernel-log "BOUNCER: Creating flight plan node...")
|
||||
(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"
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
(defun chaos-inject-error (sensor-type)
|
||||
"Injects a synthetic error into a specific sensor pipeline."
|
||||
(unless *chaos-enabled-p*
|
||||
(kernel-log "CHAOS ERROR - Injection blocked. Production gate is ACTIVE.")
|
||||
(harness-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)
|
||||
(harness-log "CHAOS - Injecting synthetic error into ~a sensor..." sensor-type)
|
||||
(inject-stimulus
|
||||
`(:type :EVENT :payload (:sensor ,sensor-type :error "SYNTHETIC_CHAOS_ERROR"))))
|
||||
|
||||
@@ -13,12 +13,12 @@
|
||||
"Executes a randomized stress test by injecting failures into the system."
|
||||
(declare (ignore context))
|
||||
(unless *chaos-enabled-p*
|
||||
(kernel-log "CHAOS ERROR - Stress test blocked. Production gate is ACTIVE.")
|
||||
(harness-log "CHAOS ERROR - Stress test blocked. Production gate is ACTIVE.")
|
||||
(return-from chaos-stress-test "FAILURE - Production gate active."))
|
||||
(let* ((payload (getf action :payload))
|
||||
(mode (or (getf payload :mode) :random))
|
||||
(intensity (or (getf payload :intensity) 3)))
|
||||
(kernel-log "CHAOS - Commencing stress test (Mode: ~a, Intensity: ~a)" mode intensity)
|
||||
(harness-log "CHAOS - Commencing stress test (Mode: ~a, Intensity: ~a)" mode intensity)
|
||||
(snapshot-object-store)
|
||||
(case mode
|
||||
(:random (dotimes (i intensity)
|
||||
@@ -33,11 +33,11 @@
|
||||
(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.")
|
||||
(harness-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.")
|
||||
(harness-log "CHAOS - Production gate ENABLED. Chaos injection is now BLOCKED.")
|
||||
t)
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
:content text
|
||||
:version (get-universal-time))))
|
||||
(setf (gethash msg-id *object-store*) obj)
|
||||
(kernel-log "CHAT - Message archived: ~a (~a)" msg-id role)
|
||||
(harness-log "CHAT - Message archived: ~a (~a)" msg-id role)
|
||||
(snapshot-object-store)
|
||||
msg-id))
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
:content (format nil "Fleet preference for ~a set to ~a" provider model-id)
|
||||
:version (get-universal-time))))
|
||||
(setf (gethash config-id *object-store*) obj)
|
||||
(kernel-log "CONFIG - Fleet updated: ~a -> ~a" provider model-id)
|
||||
(harness-log "CONFIG - Fleet updated: ~a -> ~a" provider model-id)
|
||||
t)))
|
||||
|
||||
(defun get-llm-model (provider &optional default)
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
(if (uiop:file-exists-p full-path) (uiop:read-file-string full-path) nil)))
|
||||
|
||||
(defun context-get-system-logs (&optional (limit 20))
|
||||
"Retrieves the most recent lines from the kernel's internal log."
|
||||
"Retrieves the most recent lines from the harness's internal log."
|
||||
(bt:with-lock-held (*logs-lock*)
|
||||
(let ((count (min limit (length *system-logs*)))) (subseq *system-logs* 0 count))))
|
||||
|
||||
|
||||
244
src/core.lisp
244
src/core.lisp
@@ -1,244 +0,0 @@
|
||||
(in-package :org-agent)
|
||||
|
||||
(defvar *interrupt-flag* nil)
|
||||
|
||||
;; MOVED TO package.lisp
|
||||
|
||||
(defvar *interrupt-lock* (bt:make-lock "kernel-interrupt-lock"))
|
||||
|
||||
;; MOVED TO package.lisp
|
||||
|
||||
;; MOVED TO package.lisp
|
||||
|
||||
(defun dispatch-action (action context)
|
||||
"Routes an approved action to its registered physical actuator."
|
||||
(when (and action (listp action))
|
||||
(let* ((target (or (ignore-errors (getf action :target)) :emacs))
|
||||
(actuator-fn (gethash target *actuator-registry*)))
|
||||
(if actuator-fn
|
||||
(funcall actuator-fn action context)
|
||||
(kernel-log "DISPATCH ERROR: No actuator for ~a" target)))))
|
||||
|
||||
(defun kernel-track-telemetry (skill-name duration status)
|
||||
"Updates performance metrics for a specific skill."
|
||||
(when skill-name (bt:with-lock-held (*telemetry-lock*)
|
||||
(let ((entry (or (gethash skill-name *skill-telemetry*) (list :executions 0 :total-time 0 :failures 0))))
|
||||
(incf (getf entry :executions)) (incf (getf entry :total-time) duration)
|
||||
(when (eq status :rejected) (incf (getf entry :failures))) (setf (gethash skill-name *skill-telemetry*) entry)))))
|
||||
|
||||
(defun kernel-log (fmt &rest args)
|
||||
"Records a formatted message to the system log and standard output."
|
||||
(let ((msg (apply #'format nil fmt args)))
|
||||
(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*))))
|
||||
(format t "~a~%" msg) (finish-output)))
|
||||
|
||||
(defun inject-stimulus (raw-message &key stream (depth 0))
|
||||
"Enqueues a raw message into the reactive signal pipeline, handling async/sync execution and recovery."
|
||||
(let* ((payload (getf raw-message :payload))
|
||||
(sensor (getf payload :sensor))
|
||||
;; Force Chat and Delegation to be async
|
||||
(async-p (or (getf payload :async-p) (member sensor '(:chat-message :delegation :user-command)))))
|
||||
(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)
|
||||
"Initial processing: Normalizes raw stimuli and updates memory."
|
||||
(let* ((payload (getf signal :payload))
|
||||
(type (getf signal :type))
|
||||
(sensor (getf payload :sensor)))
|
||||
(kernel-log "GATE [Perceive]: ~a (~a)" type (or sensor "no-sensor"))
|
||||
(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)
|
||||
signal))
|
||||
|
||||
(defun neuro-gate (signal)
|
||||
"Associative: Intuition and proposed actions."
|
||||
(unless (eq (getf signal :type) :EVENT)
|
||||
(return-from neuro-gate signal))
|
||||
(kernel-log "GATE [Associative]: Consulting System 1...")
|
||||
(let ((thoughts (think signal)))
|
||||
(setf (getf signal :proposals) (if (and (listp thoughts) (listp (car thoughts)))
|
||||
thoughts
|
||||
(if thoughts (list thoughts) nil)))
|
||||
(setf (getf signal :status) :thought)
|
||||
signal))
|
||||
|
||||
(defun resolve-consensus (proposals signal)
|
||||
"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)))
|
||||
(dolist (p proposals)
|
||||
(incf (gethash p counts 0)))
|
||||
(let ((winner (first proposals))
|
||||
(max-count 0))
|
||||
(maphash (lambda (p count)
|
||||
(when (> count max-count)
|
||||
(setq max-count count
|
||||
winner p)))
|
||||
counts)
|
||||
(kernel-log "CONSENSUS: Winner selected with ~a votes." max-count)
|
||||
winner)))
|
||||
|
||||
(defun consensus-gate (signal)
|
||||
"Resolves multiple proposals into a single candidate action."
|
||||
(let ((proposals (getf signal :proposals)))
|
||||
(if (and proposals (cdr proposals))
|
||||
(let ((winner (resolve-consensus proposals signal)))
|
||||
(setf (getf signal :candidate) winner))
|
||||
(setf (getf signal :candidate) (first proposals)))
|
||||
(setf (getf signal :status) :consensus)
|
||||
signal))
|
||||
|
||||
(defun decide-gate (signal)
|
||||
"Deliberate: Safety and validation."
|
||||
(let ((candidate (getf signal :candidate)))
|
||||
(if candidate
|
||||
(let* ((normalized-candidate (if (listp candidate) candidate (list :type :RESPONSE :payload (list :text candidate))))
|
||||
(decision (decide normalized-candidate signal)))
|
||||
(setf (getf signal :approved-action) decision))
|
||||
(setf (getf signal :approved-action) nil))
|
||||
(setf (getf signal :status) :decided)
|
||||
signal))
|
||||
|
||||
(defun dispatch-gate (signal)
|
||||
"Final Stage: Actuation and feedback generation."
|
||||
(let* ((approved (getf signal :approved-action))
|
||||
(type (getf signal :type))
|
||||
(depth (getf signal :depth 0))
|
||||
(feedback nil))
|
||||
(case type
|
||||
(:REQUEST (dispatch-action signal signal))
|
||||
(:EVENT
|
||||
(when approved
|
||||
(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)
|
||||
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 ()
|
||||
"The entry point for the compiled standalone binary."
|
||||
(let* ((home (uiop:getenv "HOME"))
|
||||
(env-file (uiop:merge-pathnames* ".local/share/org-agent/.env" (uiop:ensure-directory-pathname home))))
|
||||
(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)))
|
||||
(format t "KERNEL: Heartbeat interval set to ~a seconds.~%" interval)
|
||||
(start-daemon :interval interval))
|
||||
(loop (sleep 3600)))
|
||||
@@ -34,17 +34,17 @@
|
||||
"Securely stores a secret and triggers a Merkle snapshot."
|
||||
(let ((key (format nil "~a-~a" provider type)))
|
||||
(setf (gethash key *vault-memory*) secret)
|
||||
(kernel-log "VAULT - Updated ~a for ~a. Triggering Merkle snapshot..." type provider)
|
||||
(harness-log "VAULT - Updated ~a for ~a. Triggering Merkle snapshot..." type provider)
|
||||
(snapshot-object-store)
|
||||
t))
|
||||
|
||||
(defun vault-onboard-gemini-web ()
|
||||
"Instructions for the Sovereign Cookie Handshake."
|
||||
(kernel-log "--- GEMINI WEB ONBOARDING ---")
|
||||
(kernel-log "1. Visit gemini.google.com")
|
||||
(kernel-log "2. Run the 'Get Gemini Cookies' Bookmarklet.")
|
||||
(kernel-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));})();")
|
||||
(kernel-log "PLATFORM GUIDE: Chrome/Firefox/Safari all support Bookmarklets via 'Add Page' or 'New Bookmark'.")
|
||||
(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
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
(api-key (getf auth :api-key))
|
||||
(endpoint "https://generativelanguage.googleapis.com/v1beta/models/text-embedding-004:embedContent"))
|
||||
(unless api-key
|
||||
(kernel-log "EMBEDDING ERROR: No API key for :gemini")
|
||||
(harness-log "EMBEDDING ERROR: No API key for :gemini")
|
||||
(return-from get-embedding nil))
|
||||
(let* ((url (format nil "~a?key=~a" endpoint api-key))
|
||||
(headers `(("Content-Type" . "application/json")))
|
||||
@@ -19,7 +19,7 @@
|
||||
(embedding (getf (getf json :embedding) :values)))
|
||||
embedding)
|
||||
(error (c)
|
||||
(kernel-log "EMBEDDING FAILURE: ~a" c)
|
||||
(harness-log "EMBEDDING FAILURE: ~a" c)
|
||||
nil)))))
|
||||
|
||||
(defun dot-product (v1 v2)
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
(handler-case (let* ((response (dex:post url :headers headers :content body))
|
||||
(json (cl-json:decode-json-from-string response)))
|
||||
(cdr (assoc :values (cdr (assoc :embedding json)))))
|
||||
(error (c) (kernel-log "EMBEDDING FAILURE: ~a" c) nil)))))
|
||||
(error (c) (harness-log "EMBEDDING FAILURE: ~a" c) nil)))))
|
||||
|
||||
(defun dot-product (v1 v2)
|
||||
"Calculates the dot product of two numerical vectors."
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
(defun orchestrator-register-hook (hook-name fn)
|
||||
"Registers a function for a named hook. Triggers a Merkle snapshot."
|
||||
(pushnew fn (gethash hook-name *hook-registry*))
|
||||
(kernel-log "ORCHESTRATOR - Registered hook function for ~a" hook-name)
|
||||
(harness-log "ORCHESTRATOR - Registered hook function for ~a" hook-name)
|
||||
(snapshot-object-store)
|
||||
t)
|
||||
|
||||
@@ -18,17 +18,17 @@
|
||||
(let ((functions (gethash hook-name *hook-registry*)))
|
||||
(dolist (fn functions)
|
||||
(handler-case (apply fn args)
|
||||
(error (c) (kernel-log "ORCHESTRATOR ERROR - Hook ~a failed: ~a" hook-name c))))))
|
||||
(error (c) (harness-log "ORCHESTRATOR ERROR - Hook ~a failed: ~a" hook-name c))))))
|
||||
|
||||
(defun orchestrator-schedule-task (task-id schedule fn)
|
||||
"Schedules a task for execution. Schedule can be an interval (integer seconds) or 'heartbeat'."
|
||||
(setf (gethash task-id *cron-registry*) (list :schedule schedule :fn fn :last-run 0))
|
||||
(kernel-log "ORCHESTRATOR - Scheduled task ~a (~a)" task-id schedule)
|
||||
(harness-log "ORCHESTRATOR - Scheduled task ~a (~a)" task-id schedule)
|
||||
(snapshot-object-store)
|
||||
t)
|
||||
|
||||
(defun orchestrator-process-cron ()
|
||||
"Checked by the kernel on every heartbeat."
|
||||
"Checked by the harness on every heartbeat."
|
||||
(let ((now (get-universal-time)))
|
||||
(maphash (lambda (id task)
|
||||
(let ((schedule (getf task :schedule))
|
||||
@@ -37,7 +37,7 @@
|
||||
(when (or (eq schedule :heartbeat)
|
||||
(and (integerp schedule) (>= (- now last-run) schedule)))
|
||||
(handler-case (funcall fn)
|
||||
(error (c) (kernel-log "ORCHESTRATOR ERROR - Cron task ~a failed: ~a" id c)))
|
||||
(error (c) (harness-log "ORCHESTRATOR ERROR - Cron task ~a failed: ~a" id c)))
|
||||
(setf (getf (gethash id *cron-registry*) :last-run) now))))
|
||||
*cron-registry*)))
|
||||
|
||||
|
||||
@@ -19,14 +19,14 @@
|
||||
(txn-id (get-universal-time))
|
||||
(url (format nil "~a/_matrix/client/v3/rooms/~a/send/m.room.message/~a" hs room-id txn-id)))
|
||||
(when (and hs token room-id text)
|
||||
(kernel-log "MATRIX: Sending message to ~a..." room-id)
|
||||
(harness-log "MATRIX: Sending message to ~a..." room-id)
|
||||
(handler-case
|
||||
(dex:put url
|
||||
:headers `(("Authorization" . ,(format nil "Bearer ~a" token))
|
||||
("Content-Type" . "application/json"))
|
||||
:content (cl-json:encode-json-to-string
|
||||
`((msgtype . "m.text") (body . ,text))))
|
||||
(error (c) (kernel-log "MATRIX ERROR: ~a" c))))))
|
||||
(error (c) (harness-log "MATRIX ERROR: ~a" c))))))
|
||||
|
||||
(defun matrix-process-sync ()
|
||||
"Calls Matrix sync and injects new messages."
|
||||
@@ -57,7 +57,7 @@
|
||||
(sender (cdr (assoc :sender event)))
|
||||
(body (cdr (assoc :body content))))
|
||||
(when (and (string= type "m.room.message") body)
|
||||
(kernel-log "MATRIX: Received message from ~a in ~a" sender room-id)
|
||||
(harness-log "MATRIX: Received message from ~a in ~a" sender room-id)
|
||||
(inject-stimulus
|
||||
(list :type :EVENT
|
||||
:payload (list :sensor :chat-message
|
||||
@@ -65,7 +65,7 @@
|
||||
:room-id room-id
|
||||
:sender sender
|
||||
:text body)))))))))
|
||||
(error (c) (kernel-log "MATRIX SYNC ERROR: ~a" c))))))
|
||||
(error (c) (harness-log "MATRIX SYNC ERROR: ~a" c))))))
|
||||
|
||||
(defun start-matrix-gateway ()
|
||||
"Initializes the Matrix background thread."
|
||||
@@ -77,7 +77,7 @@
|
||||
(matrix-process-sync)
|
||||
(sleep 2)))
|
||||
:name "org-agent-matrix-gateway"))
|
||||
(kernel-log "MATRIX: Gateway sync active.")))
|
||||
(harness-log "MATRIX: Gateway sync active.")))
|
||||
|
||||
(defun stop-matrix-gateway ()
|
||||
(when (and *matrix-polling-thread* (bt:thread-alive-p *matrix-polling-thread*))
|
||||
|
||||
@@ -12,14 +12,14 @@
|
||||
(text (or (getf payload :text) (getf action :text)))
|
||||
(account (get-signal-account)))
|
||||
(when (and account chat-id text)
|
||||
(kernel-log "SIGNAL: Sending message to ~a..." chat-id)
|
||||
(harness-log "SIGNAL: Sending message to ~a..." chat-id)
|
||||
(handler-case
|
||||
(uiop:run-program (list "signal-cli" "-u" account "send" "-m" text chat-id)
|
||||
:output :string :error-output :string)
|
||||
(error (c) (kernel-log "SIGNAL ERROR: ~a" c))))))
|
||||
(error (c) (harness-log "SIGNAL ERROR: ~a" c))))))
|
||||
|
||||
(defun signal-process-updates ()
|
||||
"Polls for new messages via signal-cli and injects them into the kernel."
|
||||
"Polls for new messages via signal-cli and injects them into the harness."
|
||||
(let ((account (get-signal-account)))
|
||||
(when account
|
||||
(handler-case
|
||||
@@ -34,14 +34,14 @@
|
||||
(data-message (cdr (assoc :data-message envelope)))
|
||||
(text (cdr (assoc :message data-message))))
|
||||
(when (and source text)
|
||||
(kernel-log "SIGNAL: Received message from ~a" source)
|
||||
(harness-log "SIGNAL: Received message from ~a" source)
|
||||
(inject-stimulus
|
||||
(list :type :EVENT
|
||||
:payload (list :sensor :chat-message
|
||||
:channel :signal
|
||||
:chat-id source
|
||||
:text text))))))))
|
||||
(error (c) (kernel-log "SIGNAL POLL ERROR: ~a" c))))))
|
||||
(error (c) (harness-log "SIGNAL POLL ERROR: ~a" c))))))
|
||||
|
||||
(defun start-signal-gateway ()
|
||||
"Initializes the Signal background thread."
|
||||
@@ -53,7 +53,7 @@
|
||||
(signal-process-updates)
|
||||
(sleep 5)))
|
||||
:name "org-agent-signal-gateway"))
|
||||
(kernel-log "SIGNAL: Gateway polling active.")))
|
||||
(harness-log "SIGNAL: Gateway polling active.")))
|
||||
|
||||
(defun stop-signal-gateway ()
|
||||
(when (and *signal-polling-thread* (bt:thread-alive-p *signal-polling-thread*))
|
||||
|
||||
@@ -18,16 +18,16 @@
|
||||
(token (get-telegram-token))
|
||||
(url (format nil "https://api.telegram.org/bot~a/sendMessage" token)))
|
||||
(when (and token chat-id text)
|
||||
(kernel-log "TELEGRAM: Sending message to ~a..." chat-id)
|
||||
(harness-log "TELEGRAM: Sending message to ~a..." chat-id)
|
||||
(handler-case
|
||||
(dex:post url
|
||||
:headers '(("Content-Type" . "application/json"))
|
||||
:content (cl-json:encode-json-to-string
|
||||
`((chat_id . ,chat-id) (text . ,text))))
|
||||
(error (c) (kernel-log "TELEGRAM ERROR: ~a" c))))))
|
||||
(error (c) (harness-log "TELEGRAM ERROR: ~a" c))))))
|
||||
|
||||
(defun telegram-process-updates ()
|
||||
"Polls for new messages and injects them into the kernel."
|
||||
"Polls for new messages and injects them into the harness."
|
||||
(let* ((token (get-telegram-token))
|
||||
(url (format nil "https://api.telegram.org/bot~a/getUpdates?offset=~a"
|
||||
token (1+ *telegram-last-update-id*))))
|
||||
@@ -44,14 +44,14 @@
|
||||
(text (cdr (assoc :text message))))
|
||||
(setf *telegram-last-update-id* update-id)
|
||||
(when (and text chat-id)
|
||||
(kernel-log "TELEGRAM: Received message from ~a" chat-id)
|
||||
(harness-log "TELEGRAM: Received message from ~a" chat-id)
|
||||
(inject-stimulus
|
||||
(list :type :EVENT
|
||||
:payload (list :sensor :chat-message
|
||||
:channel :telegram
|
||||
:chat-id (format nil "~a" chat-id)
|
||||
:text text)))))))
|
||||
(error (c) (kernel-log "TELEGRAM POLL ERROR: ~a" c))))))
|
||||
(error (c) (harness-log "TELEGRAM POLL ERROR: ~a" c))))))
|
||||
|
||||
(defun start-telegram-gateway ()
|
||||
"Initializes the Telegram background thread."
|
||||
@@ -63,7 +63,7 @@
|
||||
(telegram-process-updates)
|
||||
(sleep 3)))
|
||||
:name "org-agent-telegram-gateway"))
|
||||
(kernel-log "TELEGRAM: Gateway polling active.")))
|
||||
(harness-log "TELEGRAM: Gateway polling active.")))
|
||||
|
||||
(defun stop-telegram-gateway ()
|
||||
(when (and *telegram-polling-thread* (bt:thread-alive-p *telegram-polling-thread*))
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
node
|
||||
(let ((new-id (org-agent:org-id-get-create)))
|
||||
(setf (getf node :properties) (append props (list :ID new-id)))
|
||||
(kernel-log "MEMORY - Injected standard ID ~a" new-id)
|
||||
(harness-log "MEMORY - Injected standard ID ~a" new-id)
|
||||
node))))
|
||||
|
||||
(defun memory-normalize-ast (ast)
|
||||
@@ -40,13 +40,13 @@
|
||||
(defun memory-org-to-json (source-path)
|
||||
"Routes to the Emacs-based Org-JSON bridge."
|
||||
;; Future implementation will use the org-json-convert CLI tool
|
||||
(kernel-log "MEMORY - Parsing ~a to JSON..." source-path)
|
||||
(harness-log "MEMORY - Parsing ~a to JSON..." source-path)
|
||||
nil)
|
||||
|
||||
(defun memory-json-to-org (ast)
|
||||
"Materializes a JSON AST into Org-mode text."
|
||||
;; Placeholder for org-element-interpret-data equivalent
|
||||
(kernel-log "MEMORY - Rendering AST to text...")
|
||||
(harness-log "MEMORY - Rendering AST to text...")
|
||||
"")
|
||||
|
||||
(progn
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
(if (and (eq sensor :heartbeat)
|
||||
(> (- now *last-reflection-time*) *reflection-interval*))
|
||||
(progn
|
||||
(kernel-log "GARDENER - Initiating Latent Reflection...")
|
||||
(harness-log "GARDENER - Initiating Latent Reflection...")
|
||||
(setf *last-reflection-time* now)
|
||||
t)
|
||||
nil)))
|
||||
|
||||
@@ -36,19 +36,19 @@ MANDATE: Output EXACTLY ONE valid Common Lisp list. Do not explain. Do not use m
|
||||
(let* ((payload (getf context :payload))
|
||||
(code (getf payload :code))
|
||||
(error-msg (getf payload :error)))
|
||||
(kernel-log "SYNTAX GATE: Reacting to broken Lisp stimulus...")
|
||||
(harness-log "SYNTAX GATE: Reacting to broken Lisp stimulus...")
|
||||
(let ((fast-fix (deterministic-repair code)))
|
||||
(handler-case
|
||||
(let ((repaired (read-from-string fast-fix)))
|
||||
(kernel-log "SYNTAX GATE: Deterministic repair SUCCESS.")
|
||||
(harness-log "SYNTAX GATE: Deterministic repair SUCCESS.")
|
||||
repaired)
|
||||
(error ()
|
||||
(kernel-log "SYNTAX GATE: Deterministic repair failed. Escalating...")
|
||||
(harness-log "SYNTAX GATE: Deterministic repair failed. Escalating...")
|
||||
(let ((deep-fix (neural-repair code error-msg)))
|
||||
(handler-case
|
||||
(let ((repaired (read-from-string deep-fix)))
|
||||
(kernel-log "SYNTAX GATE: Neural repair SUCCESS.")
|
||||
(harness-log "SYNTAX GATE: Neural repair SUCCESS.")
|
||||
repaired)
|
||||
(error ()
|
||||
(kernel-log "SYNTAX GATE: Neural repair failed.")
|
||||
(harness-log "SYNTAX GATE: Neural repair failed.")
|
||||
(list :type :LOG :payload (list :text "Lisp Repair Failed.")))))))))))
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
(let ((api-key (vault-get-secret provider :type :api-key))
|
||||
(full-prompt (format nil "~a~%~%Prompt: ~a" system-prompt prompt)))
|
||||
|
||||
(kernel-log "SYSTEM 1: Requesting ~a (Model: ~a) [Key: ~a]"
|
||||
(harness-log "SYSTEM 1: Requesting ~a (Model: ~a) [Key: ~a]"
|
||||
provider (or model "default") (vault-mask-string api-key))
|
||||
|
||||
(case provider
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
(when backend-fn
|
||||
(push (bt:make-thread
|
||||
(lambda ()
|
||||
(kernel-log "ASSOCIATIVE [Consensus]: Querying backend ~a..." backend)
|
||||
(harness-log "ASSOCIATIVE [Consensus]: Querying backend ~a..." backend)
|
||||
(let* ((model (when *model-selector-fn* (funcall *model-selector-fn* backend context)))
|
||||
(result (ignore-errors
|
||||
(if model
|
||||
@@ -50,7 +50,7 @@
|
||||
(or (dolist (backend backends)
|
||||
(let ((backend-fn (gethash backend *neuro-backends*)))
|
||||
(when backend-fn
|
||||
(kernel-log "ASSOCIATIVE: Attempting backend ~a..." backend)
|
||||
(harness-log "ASSOCIATIVE: Attempting backend ~a..." backend)
|
||||
(let* ((model (when *model-selector-fn* (funcall *model-selector-fn* backend context)))
|
||||
(result (if model
|
||||
(funcall backend-fn prompt system-prompt :model model)
|
||||
@@ -67,7 +67,7 @@
|
||||
(global-context (context-assemble-global-awareness)))
|
||||
(if active-skill
|
||||
(progn
|
||||
(kernel-log "ASSOCIATIVE: Engaging skill '~a'~%" (skill-name active-skill))
|
||||
(harness-log "ASSOCIATIVE: Engaging skill '~a'~%" (skill-name active-skill))
|
||||
(let* ((prompt-generator (skill-neuro-prompt active-skill))
|
||||
(raw-prompt (when prompt-generator (funcall prompt-generator context)))
|
||||
(full-system-prompt (concatenate 'string
|
||||
@@ -95,7 +95,7 @@ To call a tool, you MUST use:
|
||||
(raw-thoughts (cl-ppcre:split (cl-ppcre:quote-meta-chars "|CONSENSUS-SEP|") thought))
|
||||
(suggestions nil))
|
||||
(dolist (raw-thought raw-thoughts)
|
||||
(kernel-log "ASSOCIATIVE RAW: ~a~%" raw-thought)
|
||||
(harness-log "ASSOCIATIVE RAW: ~a~%" raw-thought)
|
||||
(let* ((cleaned-thought
|
||||
(let ((match (cl-ppcre:scan-to-strings "(?s)```(?:lisp)?\\n?(.*?)\\n?```" raw-thought)))
|
||||
(if match
|
||||
@@ -109,7 +109,7 @@ To call a tool, you MUST use:
|
||||
(list :sensor :syntax-error
|
||||
:code cleaned-thought
|
||||
:error (format nil "~a" c)))))))
|
||||
(kernel-log "ASSOCIATIVE Suggestion: ~a~%" cleaned-thought)
|
||||
(harness-log "ASSOCIATIVE Suggestion: ~a~%" cleaned-thought)
|
||||
(when (and suggestion (listp suggestion))
|
||||
(push suggestion suggestions))))
|
||||
(if (and *consensus-enabled-p* suggestions)
|
||||
|
||||
@@ -69,15 +69,15 @@
|
||||
(push (list :timestamp (get-universal-time) :data snapshot) *object-store-snapshots*)
|
||||
(when (> (length *object-store-snapshots*) 20)
|
||||
(setf *object-store-snapshots* (subseq *object-store-snapshots* 0 20)))
|
||||
(kernel-log "MEMORY - CoW Object Store snapshot created.")))
|
||||
(harness-log "MEMORY - CoW Object Store snapshot created.")))
|
||||
|
||||
(defun rollback-object-store (&optional (index 0))
|
||||
"Restores the Object Store to a previously captured snapshot using immutable history pointers."
|
||||
(let ((snapshot (nth index *object-store-snapshots*)))
|
||||
(if snapshot
|
||||
(progn (setf *object-store* (copy-hash-table (getf snapshot :data)))
|
||||
(kernel-log "MEMORY - Object Store rolled back to snapshot ~a" index))
|
||||
(kernel-log "MEMORY ERROR - Snapshot ~a not found." index))))
|
||||
(harness-log "MEMORY - Object Store rolled back to snapshot ~a" index))
|
||||
(harness-log "MEMORY ERROR - Snapshot ~a not found." index))))
|
||||
|
||||
(defun lookup-object (id)
|
||||
"Retrieves an object from the store by its unique ID."
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
;; --- Daemon Lifecycle ---
|
||||
#:start-daemon
|
||||
#:stop-daemon
|
||||
#:kernel-log
|
||||
#:harness-log
|
||||
#:main
|
||||
|
||||
;; --- Object Store (CLOSOS) ---
|
||||
@@ -118,7 +118,7 @@
|
||||
(in-package :org-agent)
|
||||
|
||||
(defvar *system-logs* nil)
|
||||
(defvar *logs-lock* (bt:make-lock "kernel-logs-lock"))
|
||||
(defvar *logs-lock* (bt:make-lock "harness-logs-lock"))
|
||||
(defvar *max-log-history* 100)
|
||||
|
||||
(defvar *skills-registry* (make-hash-table :test 'equal)
|
||||
@@ -144,8 +144,8 @@
|
||||
:guard ,guard
|
||||
:body ,body)))
|
||||
|
||||
(defun kernel-log (msg &rest args)
|
||||
"Centralized logging for the kernel."
|
||||
(defun harness-log (msg &rest args)
|
||||
"Centralized logging for the harness."
|
||||
(let ((formatted-msg (apply #'format nil msg args)))
|
||||
(bt:with-lock-held (*logs-lock*)
|
||||
(push formatted-msg *system-logs*)
|
||||
|
||||
@@ -28,6 +28,6 @@ RULES:
|
||||
(when (eq sensor :heartbeat)
|
||||
(let* ((base-dir (or (uiop:getenv "MEMEX_DIR") "/home/user/memex/"))
|
||||
(inbox-path (merge-pathnames "inbox.org" base-dir)))
|
||||
(org-agent:kernel-log "INBOX - Scanning ~a for migration..." (uiop:native-namestring inbox-path))
|
||||
(org-agent:harness-log "INBOX - Scanning ~a for migration..." (uiop:native-namestring inbox-path))
|
||||
;; Physical move logic would go here using Org AST parsing
|
||||
'(:target :system :payload (:action :message :text "Inbox processing complete (Simulation)."))))))
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
;; Strings
|
||||
format concatenate string-downcase string-upcase search
|
||||
;; Kernel specifics
|
||||
org-agent::kernel-log
|
||||
org-agent::harness-log
|
||||
org-agent::snapshot-object-store
|
||||
org-agent::rollback-object-store
|
||||
org-agent::lookup-object
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
(search "skills/" (namestring target-file)))))
|
||||
|
||||
(org-agent:snapshot-object-store)
|
||||
(org-agent:kernel-log "SELF-FIX - Attempting surgical fix on ~a..." target-file)
|
||||
(org-agent:harness-log "SELF-FIX - Attempting surgical fix on ~a..." target-file)
|
||||
|
||||
(handler-case
|
||||
(if (uiop:file-exists-p target-file)
|
||||
@@ -23,24 +23,24 @@
|
||||
|
||||
(if is-skill
|
||||
(progn
|
||||
(org-agent:kernel-log "SELF-FIX - Reloading modified skill ~a..." target-file)
|
||||
(org-agent:harness-log "SELF-FIX - Reloading modified skill ~a..." target-file)
|
||||
(if (org-agent:load-skill-from-org target-file)
|
||||
(progn
|
||||
(org-agent:kernel-log "SELF-FIX SUCCESS - Applied and reloaded.")
|
||||
(org-agent:harness-log "SELF-FIX SUCCESS - Applied and reloaded.")
|
||||
t)
|
||||
(progn
|
||||
(org-agent:kernel-log "SELF-FIX FAILURE - Skill reload failed. Rolling back.")
|
||||
(org-agent:harness-log "SELF-FIX FAILURE - Skill reload failed. Rolling back.")
|
||||
(with-open-file (out target-file :direction :output :if-exists :supersede)
|
||||
(write-string content out))
|
||||
(org-agent:rollback-object-store 0)
|
||||
nil)))
|
||||
(progn
|
||||
(org-agent:kernel-log "SELF-FIX SUCCESS - Applied fix to file.")
|
||||
(org-agent:harness-log "SELF-FIX SUCCESS - Applied fix to file.")
|
||||
t)))
|
||||
(progn (org-agent:kernel-log "SELF-FIX FAILURE - Pattern not found.") nil)))
|
||||
(progn (org-agent:kernel-log "SELF-FIX FAILURE - File not found.") nil))
|
||||
(progn (org-agent:harness-log "SELF-FIX FAILURE - Pattern not found.") nil)))
|
||||
(progn (org-agent:harness-log "SELF-FIX FAILURE - File not found.") nil))
|
||||
(error (c)
|
||||
(org-agent:kernel-log "SELF-FIX CRASH - ~a. Rolling back." c)
|
||||
(org-agent:harness-log "SELF-FIX CRASH - ~a. Rolling back." c)
|
||||
(org-agent:rollback-object-store 0)
|
||||
nil))))
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
(defun provision-microvm (id &key (cpu 1) (ram 512))
|
||||
"Hardware-Level Isolation: Provisions an ephemeral Firecracker MicroVM.
|
||||
This is the high-security evolution of directory-based sandboxing."
|
||||
(kernel-log "SECURITY [Hardware] - Provisioning MicroVM ~a (CPU: ~a, RAM: ~aMB)..." id cpu ram)
|
||||
(harness-log "SECURITY [Hardware] - Provisioning MicroVM ~a (CPU: ~a, RAM: ~aMB)..." id cpu ram)
|
||||
;; Future implementation: Wraps 'fcvm' or 'firecracker' CLI calls.
|
||||
(format nil "vm-~a-provisioned" id))
|
||||
|
||||
|
||||
@@ -146,7 +146,7 @@
|
||||
(unless valid-p
|
||||
(error "Syntax Error: ~a" err)))
|
||||
|
||||
(kernel-log "KERNEL: Jailing skill '~a' in package ~a" skill-base-name pkg-name)
|
||||
(harness-log "HARNESS: Jailing skill '~a' in package ~a" skill-base-name pkg-name)
|
||||
(unless (find-package pkg-name)
|
||||
(let ((new-pkg (make-package pkg-name :use '(:cl))))
|
||||
(do-external-symbols (sym (find-package :org-agent)) (shadowing-import sym new-pkg))))
|
||||
@@ -158,7 +158,7 @@
|
||||
t)))
|
||||
(error (c)
|
||||
(let ((msg (format nil "~a" c)))
|
||||
(kernel-log "LOADER ERROR in skill '~a': ~a" skill-base-name msg)
|
||||
(harness-log "LOADER ERROR in skill '~a': ~a" skill-base-name msg)
|
||||
(setf (skill-entry-status entry) :failed)
|
||||
(setf (skill-entry-error-log entry) msg)
|
||||
nil)))))
|
||||
@@ -178,7 +178,7 @@
|
||||
(when (eq finished :error) (return :error))
|
||||
(unless (bt:thread-alive-p thread) (return :error))
|
||||
(when (> (- (get-internal-real-time) start-time) timeout-units)
|
||||
(kernel-log "KERNEL: Timing out skill ~a..." (pathname-name filepath))
|
||||
(harness-log "HARNESS: Timing out skill ~a..." (pathname-name filepath))
|
||||
#+sbcl (sb-thread:terminate-thread thread)
|
||||
#-sbcl (bt:destroy-thread thread)
|
||||
(return :timeout))
|
||||
@@ -192,7 +192,7 @@
|
||||
(skills-dir (if resolved-path (uiop:ensure-directory-pathname resolved-path) nil)))
|
||||
|
||||
(unless (and skills-dir (uiop:directory-exists-p skills-dir))
|
||||
(kernel-log "KERNEL ERROR: Skills directory not found: ~a" skills-dir-str)
|
||||
(harness-log "HARNESS ERROR: Skills directory not found: ~a" skills-dir-str)
|
||||
(return-from initialize-all-skills nil))
|
||||
|
||||
(let ((sorted-files (topological-sort-skills skills-dir)))
|
||||
@@ -200,12 +200,12 @@
|
||||
(unless (member "org-skill-agent" sorted-files :key #'pathname-name :test #'string-equal)
|
||||
(error "BOOT FAILURE: org-skill-agent.org not found in skills directory."))
|
||||
|
||||
(kernel-log "==================================================")
|
||||
(kernel-log " LOADER: Initializing ~a skills..." (length sorted-files))
|
||||
(harness-log "==================================================")
|
||||
(harness-log " LOADER: Initializing ~a skills..." (length sorted-files))
|
||||
|
||||
(dolist (file sorted-files)
|
||||
(let ((skill-name (pathname-name file)))
|
||||
(kernel-log " LOADER: Loading ~a..." skill-name)
|
||||
(harness-log " LOADER: Loading ~a..." skill-name)
|
||||
(load-skill-with-timeout file 5)))
|
||||
|
||||
;; Final Summary
|
||||
@@ -214,8 +214,8 @@
|
||||
(declare (ignore k))
|
||||
(if (eq (skill-entry-status v) :ready) (incf ready) (incf failed)))
|
||||
*skill-catalog*)
|
||||
(kernel-log " LOADER: Boot Complete. [Ready: ~a] [Failed: ~a]" ready failed)
|
||||
(kernel-log "==================================================")
|
||||
(harness-log " LOADER: Boot Complete. [Ready: ~a] [Failed: ~a]" ready failed)
|
||||
(harness-log "==================================================")
|
||||
(values ready failed)))))
|
||||
|
||||
(defun generate-tool-belt-prompt ()
|
||||
@@ -239,7 +239,7 @@ EXAMPLES:
|
||||
*cognitive-tools*)
|
||||
output))
|
||||
|
||||
(def-cognitive-tool :eval "Evaluates raw Common Lisp code in the kernel image. Use this for complex calculations or internal state inspection."
|
||||
(def-cognitive-tool :eval "Evaluates raw Common Lisp code in the harness image. Use this for complex calculations or internal state inspection."
|
||||
((:code :type :string :description "The Lisp code to evaluate"))
|
||||
:guard (lambda (args context)
|
||||
(declare (ignore context))
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"Serializes the entire history store and current pointers to a local Lisp image."
|
||||
(let ((image-file (persistence-get-local-path)))
|
||||
(ensure-directories-exist image-file)
|
||||
(kernel-log "PERSISTENCE - Dumping local image to ~a..." (uiop:native-namestring image-file))
|
||||
(harness-log "PERSISTENCE - Dumping local image to ~a..." (uiop:native-namestring image-file))
|
||||
(with-open-file (out image-file :direction :output :if-exists :supersede)
|
||||
(format out "(in-package :org-agent)~%")
|
||||
;; 1. Dump all immutable objects in the history store
|
||||
@@ -27,11 +27,11 @@
|
||||
(let ((image-file (persistence-get-local-path)))
|
||||
(if (uiop:file-exists-p image-file)
|
||||
(progn
|
||||
(kernel-log "PERSISTENCE - Loading local image...")
|
||||
(harness-log "PERSISTENCE - Loading local image...")
|
||||
(load image-file)
|
||||
t)
|
||||
(progn
|
||||
(kernel-log "PERSISTENCE ERROR - Local image not found.")
|
||||
(harness-log "PERSISTENCE ERROR - Local image not found.")
|
||||
nil))))
|
||||
|
||||
(defun persistence-serialize-for-archival ()
|
||||
@@ -64,10 +64,10 @@
|
||||
:headers '(("Content-Type" . "multipart/form-data"))))
|
||||
(result (cl-json:decode-json-from-string response))
|
||||
(cid (cdr (assoc :hash result))))
|
||||
(kernel-log "PERSISTENCE - Checkpoint to IPFS successful. CID: ~a" cid)
|
||||
(harness-log "PERSISTENCE - Checkpoint to IPFS successful. CID: ~a" cid)
|
||||
cid)
|
||||
(error (c)
|
||||
(kernel-log "PERSISTENCE ERROR - IPFS push failed: ~a" c)
|
||||
(harness-log "PERSISTENCE ERROR - IPFS push failed: ~a" c)
|
||||
nil))))
|
||||
|
||||
(defun persistence-restore-ipfs (cid)
|
||||
@@ -91,10 +91,10 @@
|
||||
:last-sync (cdr (assoc :last-sync item))
|
||||
:hash (cdr (assoc :hash item)))))
|
||||
(setf (gethash id *object-store*) obj)))
|
||||
(kernel-log "PERSISTENCE - Restored from IPFS: ~a" cid)
|
||||
(harness-log "PERSISTENCE - Restored from IPFS: ~a" cid)
|
||||
t)
|
||||
(error (c)
|
||||
(kernel-log "PERSISTENCE ERROR - IPFS restoration failed: ~a" c)
|
||||
(harness-log "PERSISTENCE ERROR - IPFS restoration failed: ~a" c)
|
||||
nil))))
|
||||
|
||||
(progn
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
;; If any gate returns a LOG or EVENT (blocking/intercepting), stop and return it.
|
||||
(when (and (listp current-action)
|
||||
(member (getf current-action :type) '(:LOG :EVENT :log :event)))
|
||||
(kernel-log "DELIBERATE: Intercepted by skill '~a'~%" (skill-name skill))
|
||||
(harness-log "DELIBERATE: Intercepted by skill '~a'~%" (skill-name skill))
|
||||
(return-from decide current-action))))
|
||||
|
||||
current-action))
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
(eq inv-type action-target)
|
||||
(eq inv-type action-type))
|
||||
(unless (funcall inv-logic action context)
|
||||
(kernel-log "FORMAL FAILURE: Action ~s violated invariant ~a" action inv-name)
|
||||
(harness-log "FORMAL FAILURE: Action ~s violated invariant ~a" action inv-name)
|
||||
(setf all-passed nil)))))
|
||||
*formal-invariants*)
|
||||
all-passed))
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
(in-suite chaos-suite)
|
||||
|
||||
(test malformed-ast-injection
|
||||
"Verify that injecting a non-list AST doesn't crash the kernel."
|
||||
(kernel-log "CHAOS: Injecting string as AST")
|
||||
"Verify that injecting a non-list AST doesn't crash the harness."
|
||||
(harness-log "CHAOS: Injecting string as AST")
|
||||
;; This should be caught by handler-case in cognitive-loop or perceive
|
||||
(let ((malformed-stimulus '(:type :EVENT :payload (:sensor :buffer-update :ast "NOT A LIST"))))
|
||||
(finishes (ignore-errors (perceive-gate malformed-stimulus)))
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
(test deep-recursion-stimulus
|
||||
"Verify that deep recursion is halted by the recursion breaker."
|
||||
(kernel-log "CHAOS: Injecting deep recursion stimulus")
|
||||
(harness-log "CHAOS: Injecting deep recursion stimulus")
|
||||
(clrhash org-agent::*skills-registry*)
|
||||
;; Skill that always triggers another instance of itself
|
||||
(org-agent::defskill :infinite-skill
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
(test missing-actuator-dispatch
|
||||
"Verify that dispatching to a non-existent actuator is handled."
|
||||
(kernel-log "CHAOS: Dispatching to missing actuator")
|
||||
(harness-log "CHAOS: Dispatching to missing actuator")
|
||||
(let ((action '(:type :REQUEST :target :ghost-actuator :payload (:action :boo))))
|
||||
(finishes (org-agent:dispatch-action action nil))))
|
||||
|
||||
|
||||
@@ -30,8 +30,8 @@
|
||||
|
||||
;; Since cognitive-loop is recursive and our core hooks inject a NEW stimulus,
|
||||
;; we can't easily capture it in a single synchronous call without mocking cognitive-loop.
|
||||
;; However, we can check if kernel-log received the "SYSTEM ERROR" message.
|
||||
(kernel-log "CLEAN LOG")
|
||||
;; However, we can check if harness-log received the "SYSTEM ERROR" message.
|
||||
(harness-log "CLEAN LOG")
|
||||
(org-agent:process-signal stimulus)
|
||||
(let ((logs (context-get-system-logs 20)))
|
||||
;; We expect the pipeline to at least acknowledge the tool error
|
||||
@@ -46,7 +46,7 @@
|
||||
:neuro (lambda (ctx) (error "CRITICAL BRAIN FAILURE"))
|
||||
:symbolic nil)
|
||||
|
||||
(kernel-log "CLEAN LOG")
|
||||
(harness-log "CLEAN LOG")
|
||||
(org-agent:process-signal '(:type :EVENT :payload (:sensor :test)))
|
||||
(let ((logs (context-get-system-logs 20)))
|
||||
;; Check for the PIPELINE CRASH log
|
||||
|
||||
@@ -85,8 +85,8 @@
|
||||
(is (member "mock-dependent" deps :test #'string-equal))))
|
||||
|
||||
(test test-log-buffering
|
||||
"Verify that kernel-log correctly populates the system logs."
|
||||
(kernel-log "PSF TEST LOG")
|
||||
"Verify that harness-log correctly populates the system logs."
|
||||
(harness-log "PSF TEST LOG")
|
||||
(let ((logs (context-get-system-logs 5)))
|
||||
(is (cl:some (lambda (line) (search "PSF TEST LOG" line)) logs))))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user