From ce90fd3e725339fd60575b3e2d8a1bbdb8007482 Mon Sep 17 00:00:00 2001 From: Amr Gharbeia Date: Sun, 3 May 2026 14:21:08 -0400 Subject: [PATCH] fix: HITL functions now properly loaded, define missing proto-get MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Root cause chain: 1. proto-get was used throughout the pipeline but never defined — added to core-communication.org as a keyword-normalizing getf wrapper. 2. security-dispatcher.lisp was loaded by skill-initialize-all into a separate package, making HITL functions invisible to :passepartout. Fixed by adding to ASDF component list and excluding from skill loader. 3. org-id-generate was referenced from hitl-create but lives in an unexported skill package — replaced with uuid:make-v4-uuid. 4. uiop:string-prefix-p was called with :test keyword argument it does not accept — replaced with string-downcase normalization on both sides. Also: - Export hitl-create, hitl-approve, hitl-deny, hitl-handle-message, stimulus-inject from :passepartout for REPL accessibility. --- lisp/core-communication.lisp | 4 ++++ lisp/core-defpackage.lisp | 11 ++++++++--- lisp/core-skills.lisp | 21 +++++++++++---------- lisp/security-dispatcher.fasl | Bin 0 -> 40473 bytes lisp/security-dispatcher.lisp | 14 ++++++++------ org/core-communication.org | 12 ++++++++++++ org/core-defpackage.org | 11 ++++++++--- org/core-skills.org | 21 +++++++++++---------- org/security-dispatcher.org | 18 +++++++++++------- passepartout.asd | 1 + 10 files changed, 74 insertions(+), 39 deletions(-) create mode 100644 lisp/security-dispatcher.fasl diff --git a/lisp/core-communication.lisp b/lisp/core-communication.lisp index 72ba3d3..2f9a58f 100644 --- a/lisp/core-communication.lisp +++ b/lisp/core-communication.lisp @@ -1,5 +1,9 @@ (in-package :passepartout) +(defun proto-get (plist key) + "Look up KEY in PLIST with keyword normalization." + (getf plist (if (keywordp key) key (intern (string-upcase (string key)) :keyword)))) + (defvar *actuator-registry* (make-hash-table :test 'equalp) "Global registry mapping target keywords to their physical actuator functions.") diff --git a/lisp/core-defpackage.lisp b/lisp/core-defpackage.lisp index 0fc589a..0631e8a 100644 --- a/lisp/core-defpackage.lisp +++ b/lisp/core-defpackage.lisp @@ -64,9 +64,14 @@ #:act-gate #:reason-gate #:dispatch-gate - #:register-pre-reason-handler - #:inject-stimulus - #:actuator-initialize + #:register-pre-reason-handler + #:inject-stimulus + #:stimulus-inject + #:hitl-create + #:hitl-approve + #:hitl-deny + #:hitl-handle-message + #:actuator-initialize #:dispatch-action #:register-actuator #:load-skill-from-org diff --git a/lisp/core-skills.lisp b/lisp/core-skills.lisp index 35840bb..dfdd976 100644 --- a/lisp/core-skills.lisp +++ b/lisp/core-skills.lisp @@ -82,16 +82,17 @@ (all-files (append org-files lisp-files)) (files (remove-if (lambda (f) (let ((n (pathname-name f))) - (or (string= n "core-defpackage") - (string= n "core-skills") - (string= n "core-communication") - (string= n "core-memory") - (string= n "core-context") - (string= n "core-loop-perceive") - (string= n "core-loop-reason") - (string= n "core-loop-act") - (string= n "core-loop") - (string= n "core-manifest")))) + (or (string= n "core-defpackage") + (string= n "core-skills") + (string= n "core-communication") + (string= n "core-memory") + (string= n "core-context") + (string= n "core-loop-perceive") + (string= n "core-loop-reason") + (string= n "core-loop-act") + (string= n "core-loop") + (string= n "core-manifest") + (string= n "security-dispatcher")))) all-files)) (adj (make-hash-table :test 'equal)) (name-to-file (make-hash-table :test 'equal)) diff --git a/lisp/security-dispatcher.fasl b/lisp/security-dispatcher.fasl new file mode 100644 index 0000000000000000000000000000000000000000..331e198bde1f75c23e060cd68ae800586bbcb60f GIT binary patch literal 40473 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 (length parts) 1) (second parts)))) (when (and token (hitl-approve token)) (log-message "HITL: Approved via ~a — ~a" (or source :unknown) token) (return-from hitl-handle-message t)))) - (when (or (uiop:string-prefix-p "/deny" text :test #'char-equal) - (uiop:string-prefix-p "deny " text :test #'char-equal)) + (when (or (uiop:string-prefix-p (string-downcase "/deny") (string-downcase text)) + (uiop:string-prefix-p (string-downcase "deny") (string-downcase text))) (let* ((parts (uiop:split-string text :separator '(#\Space #\Tab))) (token (when (> (length parts) 1) (second parts)))) (when (and token (hitl-deny token)) diff --git a/org/core-communication.org b/org/core-communication.org index 5875dca..477dbda 100644 --- a/org/core-communication.org +++ b/org/core-communication.org @@ -36,6 +36,18 @@ The 6-character hex length supports messages up to ~16MB (0xFFFFFF bytes). This (in-package :passepartout) #+end_src +** Protocol Accessor (proto-get) + +Case-insensitive property list accessor used throughout the pipeline. +Returns the value associated with KEY in PLIST by interning a keyword. + +;; REPL-VERIFIED: 2026-05-03T13:00:00 +#+begin_src lisp +(defun proto-get (plist key) + "Look up KEY in PLIST with keyword normalization." + (getf plist (if (keywordp key) key (intern (string-upcase (string key)) :keyword)))) +#+end_src + ** Actuator Registry The global registry mapping target keywords (~:cli~, ~:telegram~, ~:signal~, etc.) to their physical actuator functions. Extensible at runtime — skills can register new actuators via ~register-actuator~. diff --git a/org/core-defpackage.org b/org/core-defpackage.org index 3907118..092fa0b 100644 --- a/org/core-defpackage.org +++ b/org/core-defpackage.org @@ -89,9 +89,14 @@ The package definition. All public symbols are exported here. #:act-gate #:reason-gate #:dispatch-gate - #:register-pre-reason-handler - #:inject-stimulus - #:actuator-initialize + #:register-pre-reason-handler + #:inject-stimulus + #:stimulus-inject + #:hitl-create + #:hitl-approve + #:hitl-deny + #:hitl-handle-message + #:actuator-initialize #:dispatch-action #:register-actuator #:load-skill-from-org diff --git a/org/core-skills.org b/org/core-skills.org index 4741964..73b16db 100644 --- a/org/core-skills.org +++ b/org/core-skills.org @@ -177,16 +177,17 @@ Both ~.org~ and ~.lisp~ files are included. For each skill, the ~.org~ file supp (all-files (append org-files lisp-files)) (files (remove-if (lambda (f) (let ((n (pathname-name f))) - (or (string= n "core-defpackage") - (string= n "core-skills") - (string= n "core-communication") - (string= n "core-memory") - (string= n "core-context") - (string= n "core-loop-perceive") - (string= n "core-loop-reason") - (string= n "core-loop-act") - (string= n "core-loop") - (string= n "core-manifest")))) + (or (string= n "core-defpackage") + (string= n "core-skills") + (string= n "core-communication") + (string= n "core-memory") + (string= n "core-context") + (string= n "core-loop-perceive") + (string= n "core-loop-reason") + (string= n "core-loop-act") + (string= n "core-loop") + (string= n "core-manifest") + (string= n "security-dispatcher")))) all-files)) (adj (make-hash-table :test 'equal)) (name-to-file (make-hash-table :test 'equal)) diff --git a/org/security-dispatcher.org b/org/security-dispatcher.org index 6b62fd7..6a08f45 100644 --- a/org/security-dispatcher.org +++ b/org/security-dispatcher.org @@ -24,7 +24,11 @@ The Bouncer also handles the **Flight Plan** system: when a high-risk action is * Implementation -* Implementation +** Package Context + +#+begin_src lisp +(in-package :passepartout) +#+end_src ** Security Configuration — network whitelist Domains that the Bouncer considers safe for outbound connections. Network calls to unlisted domains are blocked or queued for approval. @@ -432,7 +436,7 @@ privacy tags, privacy text, shell safety, network exfil, high-impact approval." #+begin_src lisp (defun dispatcher-flight-plan-create (blocked-action) "Creates a Flight Plan node for manual approval in Emacs." - (let ((id (org-id-generate))) + (let ((id (remove #\- (princ-to-string (uuid:make-v4-uuid))))) (log-message "BOUNCER: Creating flight plan node '~a'..." id) (list :type :REQUEST :target :emacs :payload (list :action :insert-node :id id @@ -465,7 +469,7 @@ the blocked action is stored for later retrieval by ~hitl-approve~ or (defun hitl-create (blocked-action) "Saves a blocked action for HITL approval. Returns a plist with :token (the correlation ID) and :message (user-facing text)." - (let* ((token (format nil "HITL-~a" (subseq (org-id-generate) 3 11)))) + (let* ((token (format nil "HITL-~a" (subseq (remove #\- (princ-to-string (uuid:make-v4-uuid))) 0 8)))) (setf (gethash token *hitl-pending*) blocked-action) (log-message "HITL: Created pending approval ~a" token) (list :token token @@ -542,15 +546,15 @@ Recognized formats: approve HITL-abc123 deny HITL-abc123" (let ((text (string-trim '(#\Space) (or text "")))) - (when (or (uiop:string-prefix-p "/approve" text :test #'char-equal) - (uiop:string-prefix-p "approve" text :test #'char-equal)) + (when (or (uiop:string-prefix-p (string-downcase "/approve") (string-downcase text)) + (uiop:string-prefix-p (string-downcase "approve") (string-downcase text))) (let* ((parts (uiop:split-string text :separator '(#\Space #\Tab))) (token (when (> (length parts) 1) (second parts)))) (when (and token (hitl-approve token)) (log-message "HITL: Approved via ~a — ~a" (or source :unknown) token) (return-from hitl-handle-message t)))) - (when (or (uiop:string-prefix-p "/deny" text :test #'char-equal) - (uiop:string-prefix-p "deny " text :test #'char-equal)) + (when (or (uiop:string-prefix-p (string-downcase "/deny") (string-downcase text)) + (uiop:string-prefix-p (string-downcase "deny") (string-downcase text))) (let* ((parts (uiop:split-string text :separator '(#\Space #\Tab))) (token (when (> (length parts) 1) (second parts)))) (when (and token (hitl-deny token)) diff --git a/passepartout.asd b/passepartout.asd index 55b1d3f..69cb0e0 100644 --- a/passepartout.asd +++ b/passepartout.asd @@ -11,6 +11,7 @@ (:file "lisp/core-communication") (:file "lisp/core-memory") (:file "lisp/core-context") + (:file "lisp/security-dispatcher") (:file "lisp/core-loop-perceive") (:file "lisp/core-loop-reason") (:file "lisp/core-loop-act")