#+TITLE: Core: Package Definition (core-defpackage.org) #+AUTHOR: Agent #+FILETAGS: :passepartout:core:defpackage: #+STARTUP: content #+PROPERTY: header-args:lisp :tangle ../lisp/core-defpackage.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 ** Package Definition and Export List The package definition. All public symbols are exported here. #+begin_src lisp (defpackage :passepartout (:use :cl) (:export #:frame-message #:read-framed-message #:PROTO-GET #:proto-get #:*VAULT-MEMORY* #:make-hello-message #:validate-communication-protocol-schema #:start-daemon #:log-message #:main #:diagnostics-run-all #:diagnostics-main #:diagnostics-dependencies-check #:diagnostics-env-check #:register-provider #:provider-openai-request #:provider-config #:run-setup-wizard #:ingest-ast #:memory-object-get #:*memory-store* #:memory-object #:make-memory-object #:memory-object-id #:memory-object-type #:memory-object-attributes #:memory-object-parent-id #:memory-object-children #:memory-object-version #:memory-object-last-sync #:memory-object-vector #:memory-object-content #:memory-object-hash #:memory-object-scope #:snapshot-memory #:rollback-memory #:context-get-system-logs #:context-assemble-global-awareness #:context-awareness-assemble #:context-query #:push-context #:pop-context #:current-context #:current-scope #:context-stack-depth #:context-save #:context-load #:focus-project #:focus-session #:focus-memex #:unfocus #:process-signal #:loop-process #:perceive-gate #:loop-gate-perceive #:act-gate #:loop-gate-act #:reason-gate #:loop-gate-reason #:cognitive-verify #:backend-cascade-call #:register-pre-reason-handler #:inject-stimulus #:stimulus-inject #:hitl-create #:hitl-approve #:hitl-deny #:hitl-handle-message #:dispatcher-check-secret-path #:dispatcher-check-shell-safety #:dispatcher-check-privacy-tags #:dispatcher-check-network-exfil #:dispatcher-gate #:wildcard-match #:actuator-initialize #:action-dispatch #:register-actuator #:load-skill-from-org #:skill-initialize-all #:lisp-syntax-validate #:defskill #:*skill-registry* #:*scope-resolver* #:*embedding-backend* #:*embedding-queue* #:*embedding-provider* #:embed-queue-object #:embed-object #:embed-all-pending #:embedding-backend-hashing #:embedding-backend-native #:embedding-native-load-model #:embedding-native-unload #:embedding-native-ensure-loaded #:embedding-native-get-dim #:embeddings-compute #:mark-vector-stale #:skill #:skill-name #:skill-priority #:skill-dependencies #:skill-trigger-fn #:skill-probabilistic-prompt #:skill-deterministic-fn #:def-cognitive-tool #:*cognitive-tool-registry* #:org-read-file #:org-write-file #:org-headline-add #:org-headline-find-by-id #:literate-tangle-sync-check #:archivist-create-note #:gateway-start #:org-property-set #:org-todo-set #:org-id-generate #:org-id-format #:org-modify #:lisp-validate #:lisp-structural-check #:lisp-syntactic-check #:lisp-semantic-check #:lisp-eval #:lisp-format #:lisp-list-definitions #:lisp-extract #:lisp-inject #:lisp-slurp #:get-oc-config-dir #:get-tool-permission #:set-tool-permission #:check-tool-permission-gate #:permission-get #:permission-set #:cognitive-tool #:cognitive-tool-name #:cognitive-tool-description #:cognitive-tool-parameters #:cognitive-tool-guard #:cognitive-tool-body #:register-probabilistic-backend #:*probabilistic-backends* #:*provider-cascade* #:vault-get #:vault-set #:vault-get-secret #:vault-set-secret #:memory-objects-by-attribute #:gateway-cli-input #:repl-eval #:repl-inspect #:repl-list-vars #:policy-compliance-check #:validator-protocol-check #:archivist-extract-headlines #:archivist-headline-to-filename #:literate-extract-lisp-blocks #:literate-block-balance-check #:gateway-registry-initialize #:messaging-link #:messaging-unlink #:gateway-configured-p)) #+end_src ** Package Implementation The package implementation section defines the low-level utilities and global state that are shared across all harness components and skills. *** Robust plist access (plist-get) Retrieves a value from a plist, checking both upper and lowercase keyword variants. This is needed because different components use different keyword conventions. #+begin_src lisp (in-package :passepartout) (defun plist-get (plist key) "Robust plist accessor — checks both :KEY and :key variants." (let* ((s (string key)) (up (intern (string-upcase s) :keyword)) (dn (intern (string-downcase s) :keyword))) (or (getf plist up) (getf plist dn)))) #+end_src *** Logging state The harness maintains a bounded ring buffer of log messages for inclusion in LLM context. Access is thread-safe via a lock. #+begin_src lisp (defvar *log-buffer* nil) (defvar *log-lock* (bordeaux-threads:make-lock "log-messages-lock")) (defvar *log-limit* 100) #+end_src *** Skill registry The global registry of all loaded skills. This is the authoritative list that the deterministic engine iterates. #+begin_src lisp (defvar *skill-registry* (make-hash-table :test 'equal) "Global registry of all loaded skills.") #+end_src *** Skill telemetry Tracks execution metrics per skill (count, duration, failures) for diagnostics and performance analysis. #+begin_src lisp (defvar *telemetry-table* (make-hash-table :test 'equal)) (defvar *telemetry-lock* (bordeaux-threads:make-lock "harness-telemetry-lock")) (defun telemetry-track (skill-name duration status) "Updates performance metrics for a skill. STATUS is :success or :rejected." (when skill-name (bordeaux-threads:with-lock-held (*telemetry-lock*) (let ((entry (or (gethash skill-name *telemetry-table*) (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 *telemetry-table*) entry))))) #+end_src *** Cognitive tool registry Tools that the LLM can invoke are registered here. Each tool has a name, description, parameters, optional guard, and implementation body. The ~def-cognitive-tool~ macro handles registration. ~cognitive-tool-prompt~ serialises the registry into the LLM's system prompt. #+begin_src lisp (defvar *cognitive-tool-registry* (make-hash-table :test 'equal)) #+end_src #+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