#+TITLE: Core: Package Definition (core-package.org) #+AUTHOR: Agent #+FILETAGS: :passepartout:core:defpackage: #+STARTUP: content #+PROPERTY: header-args:lisp :tangle ../lisp/core-package.lisp * Overview: Architectural Intent ~package.lisp~ defines two things: the public API of the ~passepartout~ package (the export list), and the implementation of low-level utility functions and global state that don't belong in a specific pipeline stage or skill. The export list is the contract between the harness and all skills. Every function exported here is accessible to every skill via ~use-package~. Adding a symbol here is an API commitment; removing one is a breaking change. The implementation section includes: - ~plist-get~ — robust plist accessor used everywhere in the pipeline - Logging state (~*log-buffer*~, ~*log-lock*~) — bounded ring buffer for LLM context - Skill registry (~*skill-registry*~, ~defskill~) — all loaded skills live here - Cognitive tool registry (~*cognitive-tool-registry*~, ~def-cognitive-tool~, ~cognitive-tool-prompt~) - Telemetry tracking (~*telemetry-table*~, ~telemetry-track~) — performance metrics per skill - Debugger hook — replaces raw SBCL debugger with a friendly error message * Implementation #+begin_src lisp (defstruct cognitive-tool name description parameters guard body) #+end_src #+begin_src lisp (defmacro def-cognitive-tool (name description parameters &key guard body) "Registers a cognitive tool. PARAMETERS is a list of plists, one per parameter." `(setf (gethash (string-downcase (string ',name)) *cognitive-tool-registry*) (make-cognitive-tool :name (string-downcase (string ',name)) :description ,description :parameters ',parameters :guard ,guard :body ,body))) #+end_src #+begin_src lisp (defun cognitive-tool-prompt () "Serialises all registered tools into a prompt string for the LLM." (let ((descriptions nil)) (maphash (lambda (k tool) (declare (ignore k)) (push (format nil "- ~a: ~a~% Parameters: ~a~%" (cognitive-tool-name tool) (cognitive-tool-description tool) (cognitive-tool-parameters tool)) descriptions)) *cognitive-tool-registry*) (if descriptions (format nil "Available tools:~%~a" (apply #'concatenate 'string (sort descriptions #'string<))) "No tools registered."))) ;; Alias: generate-tool-belt-prompt → cognitive-tool-prompt (defun generate-tool-belt-prompt () (cognitive-tool-prompt)) #+end_src *** Centralized logging (log-message) Thread-safe logging function that writes to both the ring buffer (for LLM context) and stdout (for the user). Bounded by ~*log-limit*~. #+begin_src lisp (defun log-message (msg &rest args) "Centralized, thread-safe logging for the harness." (let ((formatted-msg (apply #'format nil msg args))) (bordeaux-threads:with-lock-held (*log-lock*) (push formatted-msg *log-buffer*) (when (> (length *log-buffer*) *log-limit*) (setq *log-buffer* (subseq *log-buffer* 0 *log-limit*)))) (format t "~a~%" formatted-msg) (finish-output))) #+end_src *** Debugger hook Friendly error handler that replaces the raw SBCL debugger with a diagnostic message. This prevents the agent from entering the debugger on unhandled conditions. #+begin_src lisp (setf *debugger-hook* (lambda (condition hook) "Friendly error handler - shows diagnostic message instead of raw debugger." (declare (ignore hook)) (format t "~%") (format t "┌─────────────────────────────────────────────┐~%") (format t "│ ERROR: ~A~%" (type-of condition)) (format t "│~%") (format t "│ Run: passepartout diagnostics~%") (format t "│ For system diagnostics~%") (format t "└─────────────────────────────────────────────┘~%") (format t "~%") (format t "Details: ~A~%" condition) (format t "Backtrace:~%") (sb-debug:print-backtrace :count 20 :stream *standard-output*) (finish-output) (uiop:quit 1))) #+end_src