248 lines
8.9 KiB
Org Mode
248 lines
8.9 KiB
Org Mode
:PROPERTIES:
|
|
:ID: 0ae190ec-5658-4630-aed8-a5e9ffbbea0e
|
|
:CREATED: [2026-03-30 Mon 21:16]
|
|
:EDITED: [2026-04-07 Tue 13:42]
|
|
:END:
|
|
#+TITLE: SKILL: Shell Actuator Agent (Universal Literate Note)
|
|
#+STARTUP: content
|
|
#+FILETAGS: :shell:actuator:system:psf:
|
|
|
|
* Overview
|
|
The *Shell Actuator Agent* provides the bridge to the host operating system. It enables secure command execution while maintaining a strict security posture through whitelisting and diagnostic feedback loops.
|
|
|
|
* Phase A: Demand (PRD)
|
|
:PROPERTIES:
|
|
:STATUS: FROZEN
|
|
:END:
|
|
|
|
** 1. Purpose
|
|
Define a secure, diagnostic-rich interface for host OS interaction.
|
|
|
|
** 2. User Needs
|
|
- *Secure Actuation:* Strict whitelist of permitted commands.
|
|
- *Diagnostic Feedback:* Capture STDOUT, STDERR, and exit codes.
|
|
- *Loop Closure:* Automatic neural analysis of command results.
|
|
- *Resilience:* Graceful handling of blocked or failed commands.
|
|
|
|
** 3. Success Criteria
|
|
*** TODO Whitelist Enforcement
|
|
*** TODO Diagnostic Capture
|
|
*** TODO Result Analysis Loop
|
|
|
|
* Phase B: Blueprint (PROTOCOL)
|
|
:PROPERTIES:
|
|
:STATUS: SIGNED
|
|
:END:
|
|
|
|
** 1. Architectural Intent
|
|
Interfaces for secure system calls. State is event-driven via the core kernel bus.
|
|
|
|
** 2. Semantic Interfaces
|
|
#+begin_src lisp
|
|
(defun execute-shell-safely (action)
|
|
"Verifies command against whitelist and captures diagnostics.")
|
|
|
|
(defun trigger-skill-shell-actuator (context)
|
|
"Monitors for shell-response events.")
|
|
** 3. Success Criteria
|
|
*** DONE Whitelist Enforcement
|
|
- Verified that only `*allowed-commands*` can be executed.
|
|
- Added a strict `*shell-metacharacters*` check to block command injection.
|
|
*** DONE Diagnostic Capture
|
|
- Verified that STDOUT, STDERR, and Exit Codes are correctly captured and re-injected.
|
|
*** DONE Result Analysis Loop
|
|
- The `:probabilistic` component successfully formats command results for Sovereign review.
|
|
|
|
* Phase B: Blueprint (PROTOCOL)
|
|
:PROPERTIES:
|
|
:STATUS: SIGNED
|
|
:END:
|
|
|
|
** 1. Architectural Intent
|
|
Interfaces for secure system calls. State is event-driven via the core kernel bus.
|
|
|
|
** 2. Semantic Interfaces
|
|
#+begin_src lisp
|
|
(defun execute-shell-safely (action)
|
|
"Verifies command against whitelist and metacharacter blacklist, then captures diagnostics.")
|
|
|
|
(defun trigger-skill-shell-actuator (context)
|
|
"Monitors for shell-response events.")
|
|
|
|
(defun probabilistic-skill-shell-actuator (context)
|
|
"Neural interpretation of command diagnostics.")
|
|
#+end_src
|
|
|
|
* Phase D: Build (Implementation)
|
|
|
|
** Allowed Commands
|
|
Whitelist of permitted host binaries.
|
|
|
|
#+begin_src lisp :tangle ../src/shell-logic.lisp
|
|
(in-package :org-agent)
|
|
(defparameter *allowed-commands* '("ls" "git" "rg" "grep" "date" "echo" "cat" "node" "python3" "sbcl"))
|
|
#+end_src
|
|
|
|
** Shell Metacharacters
|
|
Dangerous characters that are banned to prevent command injection.
|
|
|
|
#+begin_src lisp :tangle ../src/shell-logic.lisp
|
|
(in-package :org-agent)
|
|
(defparameter *shell-metacharacters* '(#\; #\& #\| #\> #\< #\$ #\` #\\ #\!)
|
|
"Characters that are banned in shell commands to prevent injection.")
|
|
#+end_src
|
|
|
|
** Safety Check (shell-command-safe-p)
|
|
Predicate to verify a command string is free of metacharacters.
|
|
|
|
#+begin_src lisp :tangle ../src/shell-logic.lisp
|
|
(in-package :org-agent)
|
|
(defun shell-command-safe-p (cmd-string)
|
|
"Returns T if the command string contains no dangerous metacharacters."
|
|
(not (some (lambda (char) (find char cmd-string)) *shell-metacharacters*)))
|
|
#+end_src
|
|
|
|
** Shell Execution (execute-shell-safely)
|
|
The primary secure actuator for host system calls.
|
|
|
|
#+begin_src lisp :tangle ../src/shell-logic.lisp
|
|
(in-package :org-agent)
|
|
(defun execute-shell-safely (action context)
|
|
(let* ((cmd-string (getf (getf action :payload) :cmd))
|
|
(executable (car (uiop:split-string (string-trim " " cmd-string) :separator '(#\Space)))))
|
|
|
|
(cond
|
|
;; 1. Metacharacter check (Injection prevention)
|
|
((not (shell-command-safe-p cmd-string))
|
|
(org-agent:inject-stimulus
|
|
`(:type :EVENT :payload (:sensor :shell-response :cmd ,cmd-string :stdout "" :stderr "ERROR - Security Violation: Dangerous metacharacters detected." :exit-code 1))
|
|
:stream (getf context :reply-stream)))
|
|
|
|
;; 2. Whitelist check
|
|
((not (member executable *allowed-commands* :test #'string=))
|
|
(org-agent:inject-stimulus
|
|
`(:type :EVENT :payload (:sensor :shell-response :cmd ,cmd-string :stdout "" :stderr "ERROR - Command not in security whitelist." :exit-code 1))
|
|
:stream (getf context :reply-stream)))
|
|
|
|
;; 3. Safe Execution
|
|
(t
|
|
(multiple-value-bind (stdout stderr exit-code)
|
|
(uiop:run-program cmd-string :output :string :error-output :string :ignore-error-status t)
|
|
(org-agent:inject-stimulus
|
|
`(:type :EVENT :payload (:sensor :shell-response :cmd ,cmd-string :stdout ,(or stdout "") :stderr ,(or stderr "") :exit-code ,exit-code))
|
|
:stream (getf context :reply-stream)))))))
|
|
#+end_src
|
|
|
|
** Script Synthesis (execute-sandboxed-script)
|
|
Executes a synthesized script (Python/Lisp/JS) in a controlled directory.
|
|
|
|
#+begin_src lisp :tangle ../src/shell-logic.lisp
|
|
(in-package :org-agent)
|
|
(defun execute-sandboxed-script (action context)
|
|
"Executes a synthesized script (Python/Lisp/JS) in a controlled directory.
|
|
This enables SOTA-level Tool Synthesis and Iterative Fixing."
|
|
(let* ((payload (getf action :payload))
|
|
(language (getf payload :language))
|
|
(content (getf payload :content))
|
|
(sandbox-dir "/tmp/org-agent-sandbox/")
|
|
(filename (format nil "synth-~a.~a" (get-universal-time) (case language (:python "py") (:lisp "lisp") (:js "js") (t "txt"))))
|
|
(full-path (format nil "~a~a" sandbox-dir filename)))
|
|
|
|
(ensure-directories-exist sandbox-dir)
|
|
(with-open-file (out full-path :direction :output :if-exists :supersede)
|
|
(write-string content out))
|
|
|
|
(let ((cmd (case language
|
|
(:python (format nil "python3 ~a" full-path))
|
|
(:lisp (format nil "sbcl --script ~a" full-path))
|
|
(:js (format nil "node ~a" full-path)))))
|
|
(multiple-value-bind (stdout stderr exit-code)
|
|
(uiop:run-program cmd :output :string :error-output :string :ignore-error-status t)
|
|
(org-agent:inject-stimulus
|
|
`(:type :EVENT :payload (:sensor :shell-response :cmd ,cmd :stdout ,(or stdout "") :stderr ,(or stderr "") :exit-code ,exit-code :synthesis-p t))
|
|
:stream (getf context :reply-stream))))))
|
|
#+end_src
|
|
|
|
** Infrastructure: MicroVM Provisioning
|
|
Hardware-Level Isolation for future security evolution.
|
|
|
|
#+begin_src lisp :tangle ../src/shell-logic.lisp
|
|
(in-package :org-agent)
|
|
(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."
|
|
(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
|
|
|
|
** Feedback Perception
|
|
#+begin_src lisp :tangle ../src/shell-logic.lisp
|
|
(in-package :org-agent)
|
|
(defun trigger-skill-shell-actuator (context)
|
|
(let ((type (getf context :type))
|
|
(payload (getf context :payload)))
|
|
(and (eq type :EVENT)
|
|
(eq (getf payload :sensor) :shell-response))))
|
|
#+end_src
|
|
|
|
** Probabilistic-Cognitive Analysis
|
|
#+begin_src lisp :tangle ../src/shell-logic.lisp
|
|
(in-package :org-agent)
|
|
(defun probabilistic-skill-shell-actuator (context)
|
|
(let* ((p (getf context :payload))
|
|
(cmd (getf p :cmd))
|
|
(stdout (getf p :stdout))
|
|
(stderr (getf p :stderr))
|
|
(exit-code (getf p :exit-code))
|
|
(synthesis-p (getf p :synthesis-p)))
|
|
(if synthesis-p
|
|
(format nil "
|
|
TOOL SYNTHESIS RESULT:
|
|
Command: ~a (Exit: ~a)
|
|
STDOUT: ~a
|
|
STDERR: ~a
|
|
|
|
TASK:
|
|
If the command failed (Exit != 0), analyze the STDERR and propose a FIX for the script.
|
|
If it succeeded, use the STDOUT to complete the original goal.
|
|
" cmd exit-code stdout stderr)
|
|
(let ((result-text (format nil "* Shell Command Result
|
|
- Command: ~a
|
|
- Exit Code: ~a
|
|
|
|
** STDOUT
|
|
#+begin_example
|
|
~a
|
|
#+end_example
|
|
|
|
** STDERR
|
|
#+begin_example
|
|
~a
|
|
#+end_example"
|
|
cmd exit-code stdout stderr)))
|
|
`(:type :request :target :emacs :payload (:action :insert-at-end :buffer "*org-agent-chat*" :text ,result-text))))))
|
|
#+end_src
|
|
|
|
* Registration
|
|
|
|
** Registration: Actuator
|
|
Register the shell channel as a physical actuator.
|
|
|
|
#+begin_src lisp :tangle ../src/shell-logic.lisp
|
|
(in-package :org-agent)
|
|
(org-agent:register-actuator :shell #'execute-shell-safely)
|
|
#+end_src
|
|
|
|
** Registration: Skill
|
|
Define the skill entry for the shell actuator.
|
|
|
|
#+begin_src lisp :tangle ../src/shell-logic.lisp
|
|
(in-package :org-agent)
|
|
(defskill :skill-shell-actuator
|
|
:priority 80
|
|
:trigger #'trigger-skill-shell-actuator
|
|
:probabilistic #'probabilistic-skill-shell-actuator
|
|
:deterministic (lambda (action context) (declare (ignore context)) action))
|
|
#+end_src
|