CHORE: Prepare for lisp-repair implementation
This commit is contained in:
80
tests/self-fix-tests.lisp
Normal file
80
tests/self-fix-tests.lisp
Normal file
@@ -0,0 +1,80 @@
|
||||
(defpackage :org-agent-self-fix-tests
|
||||
(:use :cl :fiveam :org-agent)
|
||||
(:export #:self-fix-suite))
|
||||
(in-package :org-agent-self-fix-tests)
|
||||
|
||||
(def-suite self-fix-suite :description "Verification of the Autonomous Self-Fix Loop.")
|
||||
(in-suite self-fix-suite)
|
||||
|
||||
(defun create-broken-skill (path)
|
||||
"Programmatically generates a broken skill with a type error."
|
||||
(with-open-file (out path :direction :output :if-exists :supersede)
|
||||
(format out ":PROPERTIES:
|
||||
:ID: skill-broken-math
|
||||
:CREATED: [2026-04-11 Sat]
|
||||
:END:
|
||||
#+TITLE: SKILL: Broken Math (Temporary for Self-Fix Test)
|
||||
|
||||
* Implementation
|
||||
#+begin_src lisp
|
||||
(org-agent:defskill :skill-broken-math
|
||||
:priority 50
|
||||
:trigger (lambda (ctx) (eq (getf (getf ctx :payload) :sensor) :broken-trigger))
|
||||
:neuro nil
|
||||
:symbolic (lambda (action context)
|
||||
(declare (ignore action context))
|
||||
(+ 1 \"two\"))) ; DELIBERATE BUG
|
||||
#+end_src
|
||||
")))
|
||||
|
||||
(test test-autonomous-self-fix-loop
|
||||
"Verifies that a crash in a skill triggers the self-fix agent to patch the code."
|
||||
(let* ((skills-dir (merge-pathnames "skills/" (asdf:system-source-directory :org-agent)))
|
||||
(broken-skill-path (merge-pathnames "org-skill-broken-math.org" skills-dir))
|
||||
(original-content nil))
|
||||
|
||||
(unwind-protect
|
||||
(progn
|
||||
;; 1. Setup the broken skill
|
||||
(create-broken-skill broken-skill-path)
|
||||
(is (org-agent:load-skill-from-org broken-skill-path))
|
||||
(setf original-content (uiop:read-file-string broken-skill-path))
|
||||
(is (search "(+ 1 \"two\")" original-content))
|
||||
|
||||
;; 2. Trigger the crash
|
||||
(let ((crash-stimulus '(:type :EVENT :payload (:sensor :broken-trigger))))
|
||||
(org-agent:process-signal crash-stimulus))
|
||||
|
||||
;; 3. Mock the repair proposal and trigger the fix
|
||||
;; We manually simulate what the LLM would do: propose a fix via repair-file.
|
||||
(let* ((repair-action '(:type :REQUEST :target :tool :action :call :tool "repair-file"
|
||||
:args (:file "org-skill-broken-math.org"
|
||||
:old "(+ 1 \"two\")"
|
||||
:new "(+ 1 2)")))
|
||||
;; We need to provide the full path to the skill file for self-fix-apply
|
||||
(full-repair-action (list :type :REQUEST :target :tool :action :call :tool "repair-file"
|
||||
:payload (list :file broken-skill-path
|
||||
:old "(+ 1 \"two\")"
|
||||
:new "(+ 1 2)"))))
|
||||
|
||||
;; Execute the repair
|
||||
(is (org-agent::self-fix-apply full-repair-action nil)))
|
||||
|
||||
;; 4. Verify the fix
|
||||
(let ((patched-content (uiop:read-file-string broken-skill-path)))
|
||||
(is (not (search "(+ 1 \"two\")" patched-content)))
|
||||
(is (search "(+ 1 2)" patched-content))
|
||||
|
||||
;; Verify that the skill is reloaded and working (no longer crashes)
|
||||
(let ((working-stimulus '(:type :EVENT :payload (:sensor :broken-trigger))))
|
||||
(handler-case
|
||||
(progn
|
||||
(org-agent:process-signal working-stimulus)
|
||||
(pass "Skill successfully repaired and reloaded."))
|
||||
(error (c)
|
||||
(fail (format nil "Skill still broken after repair: ~a" c)))))))
|
||||
|
||||
;; 5. Cleanup
|
||||
(uiop:delete-file-if-exists broken-skill-path)
|
||||
(clrhash org-agent::*skills-registry*)
|
||||
(org-agent:initialize-all-skills))))
|
||||
34
tests/task-orchestrator-tests.lisp
Normal file
34
tests/task-orchestrator-tests.lisp
Normal file
@@ -0,0 +1,34 @@
|
||||
(defpackage :org-agent-task-orchestrator-tests
|
||||
(:use :cl :fiveam :org-agent)
|
||||
(:export #:task-orchestrator-suite))
|
||||
(in-package :org-agent-task-orchestrator-tests)
|
||||
|
||||
(def-suite task-orchestrator-suite :description "Tests for Consolidation VI: Task Orchestrator.")
|
||||
(in-suite task-orchestrator-suite)
|
||||
|
||||
(test test-consensus-gate-divergence
|
||||
"Verify that consensus-gate handles diverging proposals by selecting the safest one."
|
||||
(let* ((proposals '((:type :REQUEST :target :tool :action :call :tool "shell" :args (:cmd "rm -rf /"))
|
||||
(:type :REQUEST :target :tool :action :call :tool "grep-search" :args (:pattern "sovereignty"))
|
||||
(:type :REQUEST :target :tool :action :call :tool "grep-search" :args (:pattern "sovereignty"))))
|
||||
(signal `(:type :EVENT :status :thought :proposals ,proposals))
|
||||
(result (org-agent:consensus-gate signal)))
|
||||
;; The judge should reject the 'rm -rf' and select the matching grep-search
|
||||
(is (equal (getf (getf result :candidate) :tool) "grep-search"))
|
||||
(is (eq :consensus (getf result :status)))))
|
||||
|
||||
(test test-task-integrity-parent-child
|
||||
"Verify that task-integrity-check rejects closing a parent with active children."
|
||||
;; Mocking some objects in the store
|
||||
(clrhash org-agent::*object-store*)
|
||||
(setf (gethash "parent-1" org-agent::*object-store*)
|
||||
(org-agent::make-org-object :id "parent-1" :attributes '(:TITLE "Parent Task" :TODO "TODO")))
|
||||
(setf (gethash "child-1" org-agent::*object-store*)
|
||||
(org-agent::make-org-object :id "child-1" :attributes '(:TITLE "Child Task" :TODO "TODO" :PARENT "parent-1")))
|
||||
|
||||
(let* ((action '(:type :REQUEST :target :emacs :action :update-node :id "parent-1" :attributes (:TODO "DONE")))
|
||||
(signal `(:type :EVENT :payload (:sensor :test) :candidate ,action))
|
||||
(result (org-agent:decide-gate signal)))
|
||||
;; Should be blocked by Task Integrity
|
||||
(let ((approved (getf result :approved-action)))
|
||||
(is (equal (getf (getf approved :payload) :text) "Blocked by Task Integrity: Active children exist.")))))
|
||||
Reference in New Issue
Block a user