Compare commits

..

7 Commits

Author SHA1 Message Date
ce17336acd build: embed org-agent-test.el inside emacs-bridge skill 2026-04-27 13:19:19 -04:00
abda622145 build: embed Python bridge inside web-research skill
- In accordance with the strict literate programming mandate, the standalone browser-bridge.py script has been embedded as a :tangle block directly inside the org-skill-web-research.org file.
- It dynamically tangles to the INSTALL_DIR's skills directory alongside its parent Lisp logic.
2026-04-27 13:16:14 -04:00
6335b0c0c4 refactor: standardize skill API keywords to :probabilistic/:deterministic 2026-04-27 12:19:34 -04:00
5f2b7e8d16 Fix gateway skills: minor cleanup in matrix/signal/telegram org blocks 2026-04-25 18:44:41 -04:00
2db53fae17 Remove lisp-repair - moved to core skills
Consolidated into opencortex/skills/org-skill-lisp-utils.org
2026-04-23 07:22:51 -04:00
2b1f0f1b35 docs: Add test-first methodology and org-thinking mandates
- Rule 10: Test-first - design tests before coding, run chaos testing
- Rule 11: Org as thinking medium - document investigations in prose
- Rule 12: Engineering decision audit trail - document root cause, tradeoffs

These mandates ensure rigorous verification and capture institutional knowledge.
2026-04-23 06:47:24 -04:00
5b6f4c18d1 fix(audit): Ensure Chat Skill is Merkle-compliant and secure (Component IV) 2026-04-17 16:30:41 -04:00
22 changed files with 212 additions and 127 deletions

View File

@@ -131,6 +131,6 @@ Interfaces for blueprint actuation and requirement perception. Source of truth i
(defskill :skill-architect (defskill :skill-architect
:priority 110 ; Higher priority to lead the loop :priority 110 ; Higher priority to lead the loop
:trigger #'trigger-skill-architect :trigger #'trigger-skill-architect
:neuro #'neuro-skill-architect :probabilistic #'neuro-skill-architect
:symbolic #'architect-actuate) :deterministic #'architect-actuate)
#+end_src #+end_src

View File

@@ -154,8 +154,8 @@ The *Chaos Gauntlet* skill is designed to be non-invasive, running primarily in
(defskill :skill-chaos (defskill :skill-chaos
:priority 10 ; Lower priority, used for background testing :priority 10 ; Lower priority, used for background testing
:trigger (lambda (context) (eq (getf (getf context :payload) :sensor) :chaos-trigger)) :trigger (lambda (context) (eq (getf (getf context :payload) :sensor) :chaos-trigger))
:neuro (lambda (context) :probabilistic (lambda (context)
(let ((p (getf context :payload))) (let ((p (getf context :payload)))
(format nil "A chaos trigger was received (~a). Should I run a stress test?" (getf p :mode)))) (format nil "A chaos trigger was received (~a). Should I run a stress test?" (getf p :mode))))
:symbolic #'chaos-stress-test) :deterministic #'chaos-stress-test)
#+end_src #+end_src

View File

@@ -51,8 +51,8 @@ Enable visual communication of plans and system states.
(defskill :skill-diagrammer (defskill :skill-diagrammer
:priority 60 :priority 60
:trigger (lambda (context) (eq (getf (getf context :payload) :sensor) :visualize)) :trigger (lambda (context) (eq (getf (getf context :payload) :sensor) :visualize))
:neuro #'neuro-skill-diagrammer :probabilistic #'neuro-skill-diagrammer
:symbolic (lambda (action context) action)) :deterministic (lambda (action context) action))
#+end_src #+end_src

View File

@@ -99,6 +99,83 @@ Interfaces for TCP I/O and protocol framing. Source of truth is the Harness Comm
(defskill :skill-emacs-bridge (defskill :skill-emacs-bridge
:priority 100 :priority 100
:trigger (lambda (context) nil) :trigger (lambda (context) nil)
:neuro (lambda (context) nil) :probabilistic (lambda (context) nil)
:symbolic (lambda (action context) action)) :deterministic (lambda (action context) action))
#+end_src
* Emacs Bridge Test Suite
#+begin_src elisp :tangle (expand-file-name "tests/org-agent-test.el" (concat (or (getenv "INSTALL_DIR") ".") "/skills"))
;;; opencortex-test.el --- Tests for the opencortex Emacs stub
(require 'ert)
(require 'cl-lib)
(require 'opencortex "/home/amr/.openclaw/workspace/memex/5_projects/opencortex/src/opencortex.el")
(ert-deftest test-opencortex-framing ()
"Verify that opencortex-send correctly frames a plist."
(let ((captured-framed nil))
(cl-letf (((symbol-function 'process-send-string)
(lambda (proc string) (setq captured-framed string)))
((symbol-function 'process-live-p) (lambda (proc) t))
(opencortex--process t))
(opencortex-send '(:type :EVENT :id 1))
(should (string= "000014(:type :EVENT :id 1)" captured-framed)))))
(ert-deftest test-opencortex-parsing ()
"Verify that the filter correctly parses communication protocol framed messages."
(let ((mock-buffer (generate-new-buffer " *opencortex-test*"))
(received-plist nil))
(cl-letf (((symbol-function 'opencortex--handle-message)
(lambda (proc plist) (setq received-plist plist))))
(with-current-buffer mock-buffer
(insert "000014(:type :EVENT :id 1)")
(opencortex--process-buffer mock-buffer)
(should (equal '(:type :EVENT :id 1) received-plist))
(should (= (buffer-size) 0))))))
(ert-deftest test-opencortex-actuator-message ()
"Verify that the :message actuator works."
(let ((opencortex--process nil)
(captured-response nil))
(cl-letf (((symbol-function 'opencortex-send)
(lambda (plist) (setq captured-response plist))))
(opencortex--execute-request nil 101 '(:action :message :text "Hello from Daemon"))
;; Check that we sent a success response back
(should (eq :RESPONSE (plist-get captured-response :type)))
(should (eq :success (plist-get (plist-get captured-response :payload) :status))))))
(ert-deftest test-opencortex-run-command ()
"Verify that opencortex-run-command sends the correct event."
(let ((captured-framed nil))
(cl-letf (((symbol-function 'process-send-string)
(lambda (proc string) (setq captured-framed string)))
((symbol-function 'process-live-p) (lambda (proc) t))
(opencortex--process t))
(opencortex-run-command :test-cmd)
(should (string-match-p ":sensor :user-command" captured-framed))
(should (string-match-p ":command :test-cmd" captured-framed)))))
(ert-deftest test-opencortex-ast-cleaning ()
"Verify that opencortex--clean-element produces a pure plist."
(let* ((org-text "* Hello\nWorld")
(ast (with-temp-buffer
(org-mode)
(insert org-text)
(org-element-parse-buffer)))
(cleaned (opencortex--clean-element ast)))
(should (plist-get cleaned :type))
(should (eq 'org-data (plist-get cleaned :type)))
;; Check that children exist
(should (plist-get (car (plist-get cleaned :contents)) :type))
;; Check that we didn't leak buffer objects
(should-not (plist-get (plist-get cleaned :properties) :buffer))))
(ert-deftest test-opencortex-actuator-eval ()
"Verify that the :eval actuator can execute elisp."
(let ((opencortex--process nil)
(captured-response nil))
(cl-letf (((symbol-function 'opencortex-send)
(lambda (plist) (setq captured-response plist))))
(opencortex--execute-request nil 102 '(:action :eval :code "(+ 1 2)"))
(should (equal "3" (plist-get (plist-get captured-response :payload) :result))))))
#+end_src #+end_src

View File

@@ -41,8 +41,8 @@ Unify the system's diverse information silos into a single, navigable graph.
(defskill :skill-hyper-graph (defskill :skill-hyper-graph
:priority 70 :priority 70
:trigger (lambda (context) (eq (getf (getf context :payload) :sensor) :deep-trace)) :trigger (lambda (context) (eq (getf (getf context :payload) :sensor) :deep-trace))
:neuro (lambda (context) "Synthesize a lineage report for the target ID.") :probabilistic (lambda (context) "Synthesize a lineage report for the target ID.")
:symbolic (lambda (action context) action)) :deterministic (lambda (action context) action))
#+end_src #+end_src

View File

@@ -84,6 +84,6 @@ RULES:
(defskill :skill-inbox-processor (defskill :skill-inbox-processor
:priority 100 :priority 100
:trigger (lambda (context) (eq (getf (getf context :payload) :sensor) :heartbeat)) :trigger (lambda (context) (eq (getf (getf context :payload) :sensor) :heartbeat))
:neuro #'neuro-skill-inbox-processor :probabilistic #'neuro-skill-inbox-processor
:symbolic #'inbox-process-logic) :deterministic #'inbox-process-logic)
#+end_src #+end_src

View File

@@ -73,7 +73,7 @@ Hooks into the `:heartbeat` sensor.
(setf *last-reflection-time* now) (setf *last-reflection-time* now)
t) t)
nil))) nil)))
:neuro (lambda (ctx) :probabilistic (lambda (ctx)
(declare (ignore ctx)) (declare (ignore ctx))
(let* ((memories (sample-random-memories 3)) (let* ((memories (sample-random-memories 3))
(context-string "LATENT REFLECTION CANDIDATES:\n")) (context-string "LATENT REFLECTION CANDIDATES:\n"))
@@ -94,7 +94,7 @@ Find hidden connections, suggest new tags, or propose a new insight that bridges
MANDATE: Output EXACTLY ONE Common Lisp property list starting with (:type :REQUEST). MANDATE: Output EXACTLY ONE Common Lisp property list starting with (:type :REQUEST).
Use the :emacs target and :insert-at-end action to write your reflection into the \"*opencortex-chat*\" buffer." Use the :emacs target and :insert-at-end action to write your reflection into the \"*opencortex-chat*\" buffer."
context-string))) context-string)))
:symbolic (lambda (action ctx) :deterministic (lambda (action ctx)
(declare (ignore ctx)) (declare (ignore ctx))
;; Approve any safe request ;; Approve any safe request
action)) action))

View File

@@ -34,8 +34,8 @@ Automate the "Easy Apply" process on LinkedIn to sustain revenue streams.
(defskill :skill-linkedin (defskill :skill-linkedin
:priority 50 :priority 50
:trigger (lambda (context) (eq (getf (getf context :payload) :sensor) :revenue-pulse)) :trigger (lambda (context) (eq (getf (getf context :payload) :sensor) :revenue-pulse))
:neuro (lambda (context) nil) :probabilistic (lambda (context) nil)
:symbolic (lambda (action context) action)) :deterministic (lambda (action context) action))
#+end_src #+end_src

View File

@@ -91,6 +91,6 @@ Register the high-fidelity browsing tool with the harness.
(defskill :skill-playwright (defskill :skill-playwright
:priority 150 :priority 150
:trigger (lambda (ctx) (declare (ignore ctx)) nil) ; Passive tool provider :trigger (lambda (ctx) (declare (ignore ctx)) nil) ; Passive tool provider
:neuro nil :probabilistic nil
:symbolic (lambda (action ctx) (declare (ignore ctx)) action)) :deterministic (lambda (action ctx) (declare (ignore ctx)) action))
#+end_src #+end_src

View File

@@ -55,8 +55,8 @@ Eliminate speculative debugging through rigorous scientific methodology.
(defskill :skill-scientist (defskill :skill-scientist
:priority 90 :priority 90
:trigger (lambda (context) (eq (getf (getf context :payload) :sensor) :test-failure)) :trigger (lambda (context) (eq (getf (getf context :payload) :sensor) :test-failure))
:neuro #'scientist-hypothesis :probabilistic #'scientist-hypothesis
:symbolic #'scientist-propose-fix) :deterministic #'scientist-propose-fix)
#+end_src #+end_src
* Phase B: Blueprint (PROTOCOL) * Phase B: Blueprint (PROTOCOL)

View File

@@ -52,8 +52,8 @@ Automate the extraction of root causes and architectural learnings into the Meme
(defskill :skill-scribe-rca (defskill :skill-scribe-rca
:priority 90 :priority 90
:trigger (lambda (context) (search "SYSTEM ERROR" (format nil "~a" (getf (getf context :payload) :text)))) :trigger (lambda (context) (search "SYSTEM ERROR" (format nil "~a" (getf (getf context :payload) :text))))
:neuro #'scribe-rca-draft :probabilistic #'scribe-rca-draft
:symbolic (lambda (action context) action)) :deterministic (lambda (action context) action))
#+end_src #+end_src
* Phase B: Blueprint (PROTOCOL) * Phase B: Blueprint (PROTOCOL)

View File

@@ -99,6 +99,6 @@ RULES:
(defskill :skill-scribe (defskill :skill-scribe
:priority 60 :priority 60
:trigger #'trigger-skill-scribe :trigger #'trigger-skill-scribe
:neuro #'neuro-skill-scribe-enrich :probabilistic #'neuro-skill-scribe-enrich
:symbolic #'scribe-get-changed-dailies) :deterministic #'scribe-get-changed-dailies)
#+end_src #+end_src

View File

@@ -72,8 +72,8 @@ Interfaces for background verification and kernel alerting. Source of truth is t
:trigger (lambda (context) :trigger (lambda (context)
(let ((sensor (getf (getf context :payload) :sensor))) (let ((sensor (getf (getf context :payload) :sensor)))
(or (eq sensor :buffer-update) (eq sensor :file-saved)))) (or (eq sensor :buffer-update) (eq sensor :file-saved))))
:neuro (lambda (context) nil) :probabilistic (lambda (context) nil)
:symbolic (lambda (action context) :deterministic (lambda (action context)
(let ((file (getf (getf context :payload) :file))) (let ((file (getf (getf context :payload) :file)))
(when (and file (search "projects/" file)) (when (and file (search "projects/" file))
(let ((parts (uiop:split-string file :separator '(#\/)))) (let ((parts (uiop:split-string file :separator '(#\/))))

View File

@@ -128,6 +128,6 @@ Interfaces for TDD suite actuation and protocol perception. Source of truth is t
(defskill :skill-tech-analyst (defskill :skill-tech-analyst
:priority 120 :priority 120
:trigger #'trigger-skill-tech-analyst :trigger #'trigger-skill-tech-analyst
:neuro #'neuro-skill-tech-analyst :probabilistic #'neuro-skill-tech-analyst
:symbolic #'tech-analyst-actuate) :deterministic #'tech-analyst-actuate)
#+end_src #+end_src

View File

@@ -84,8 +84,8 @@ Maintain a state-aware provider cascade that routes around "pain" (failures) and
:trigger (lambda (context) :trigger (lambda (context)
(let ((sensor (getf (getf context :payload) :sensor))) (let ((sensor (getf (getf context :payload) :sensor)))
(or (eq sensor :tool-error) (eq sensor :cost-audit)))) (or (eq sensor :tool-error) (eq sensor :cost-audit))))
:neuro (lambda (context) nil) :probabilistic (lambda (context) nil)
:symbolic (lambda (action context) :deterministic (lambda (action context)
(let ((p (getf (getf context :payload) :provider))) (let ((p (getf (getf context :payload) :provider)))
(when p (token-accountant-record-pain p)) (when p (token-accountant-record-pain p))
action)))) action))))

View File

@@ -127,6 +127,64 @@ loginGemini().catch(err => {
(defskill :skill-web-research (defskill :skill-web-research
:priority 60 :priority 60
:trigger (lambda (context) (eq (getf (getf context :payload) :sensor) :web-search)) :trigger (lambda (context) (eq (getf (getf context :payload) :sensor) :web-search))
:neuro (lambda (context) nil) :probabilistic (lambda (context) nil)
:symbolic (lambda (action context) (ask-gemini-web (getf (getf action :payload) :prompt)))) :deterministic (lambda (action context) (ask-gemini-web (getf (getf action :payload) :prompt))))
#+end_src
*** Headless Data Extraction Bridge
#+begin_src python :tangle (expand-file-name "browser-bridge.py" (concat (or (getenv "INSTALL_DIR") ".") "/skills"))
#!/usr/bin/env python3
import sys
import json
import base64
from playwright.sync_api import sync_playwright
def run_bridge():
# Read command from stdin
try:
raw_input = sys.stdin.read()
if not raw_input:
print(json.dumps({"status": "error", "message": "No input provided"}))
return
args = json.loads(raw_input)
except Exception as e:
print(json.dumps({"status": "error", "message": f"Invalid JSON input: {str(e)}"}))
return
url = args.get("url")
action = args.get("action", "extract_text")
selector = args.get("selector", "body")
if not url:
print(json.dumps({"status": "error", "message": "No URL provided"}))
return
try:
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page()
# Navigate and wait for network to be idle
page.goto(url, wait_until="networkidle")
result = {"status": "success", "url": url}
if action == "extract_text":
result["content"] = page.inner_text(selector)
elif action == "screenshot":
screenshot_bytes = page.screenshot()
result["screenshot_base64"] = base64.b64encode(screenshot_bytes).decode("utf-8")
else:
result["status"] = "error"
result["message"] = f"Unknown action: {action}"
browser.close()
print(json.dumps(result))
except Exception as e:
print(json.dumps({"status": "error", "message": f"Playwright Error: {str(e)}"}))
if __name__ == "__main__":
run_bridge()
#+end_src #+end_src

View File

@@ -54,14 +54,18 @@ Interfaces for conversational event handling and UI integration. Source of truth
(defun chat-archive-message (text &key (role :user) channel chat-id) (defun chat-archive-message (text &key (role :user) channel chat-id)
"Archives a chat message into the persistent Memory and triggers a snapshot." "Archives a chat message into the persistent Memory and triggers a snapshot."
(let* ((msg-id (org-id-new)) (let* ((msg-id (org-id-new))
(attributes `(:role ,role :channel ,channel :chat-id ,chat-id :timestamp ,(get-universal-time)))
(hash (compute-merkle-hash msg-id :CHAT-MESSAGE attributes text nil))
(obj (make-org-object (obj (make-org-object
:id msg-id :id msg-id
:type :CHAT-MESSAGE :type :CHAT-MESSAGE
:attributes `(:role ,role :channel ,channel :chat-id ,chat-id :timestamp ,(get-universal-time)) :attributes attributes
:content text :content text
:hash hash
:version (get-universal-time)))) :version (get-universal-time))))
(setf (gethash hash *history-store*) obj)
(setf (gethash msg-id *memory*) obj) (setf (gethash msg-id *memory*) obj)
(harness-log "CHAT - Message archived: ~a (~a)" msg-id role) (harness-log "CHAT - Message archived: ~a (~a) [Hash: ~a]" msg-id role (subseq hash 0 8))
(snapshot-memory) (snapshot-memory)
msg-id)) msg-id))

View File

@@ -39,6 +39,27 @@ Source code MUST be strictly free of hardcoded configuration values (e.g., ports
** 9. Literate-Only Modification (The Tangle Mandate) ** 9. Literate-Only Modification (The Tangle Mandate)
You are strictly forbidden from modifying generated source code files (e.g., `.lisp`, `.py`, `.el`) directly. All changes MUST be made within the corresponding Literate Org file and then tangled to the source. Direct modification of source code is only permitted with explicit user authorization. You are strictly forbidden from modifying generated source code files (e.g., `.lisp`, `.py`, `.el`) directly. All changes MUST be made within the corresponding Literate Org file and then tangled to the source. Direct modification of source code is only permitted with explicit user authorization.
** 10. Test-First Methodology (Design Before Code)
Before implementing any fix or feature, you MUST:
1. Design the test/success criteria first - define what "works" means
2. Run chaos/edge-case testing - try to break the design
3. Only then implement the solution
This prevents debugging-by-trial-and-error and ensures rigorous verification.
** 11. Org as Thinking Medium (Investigation in Prose)
When debugging or analyzing issues:
1. Document your investigation in the relevant org file BEFORE implementing a fix
2. Record: root cause hypothesis, evidence found, tradeoffs considered
3. This makes the reasoning auditable and captures institutional knowledge
The org file IS the design document - code is just the implementation.
** 12. Engineering Decision Audit Trail
Every significant fix or architectural decision MUST be documented in the relevant org file with:
- Root cause analysis
- Options considered and tradeoffs
- Why this solution was chosen
This creates a searchable, literate history of engineering decisions.
* Phase B: Blueprint (PROTOCOL) * Phase B: Blueprint (PROTOCOL)
:PROPERTIES: :PROPERTIES:
:STATUS: SIGNED :STATUS: SIGNED

View File

@@ -32,8 +32,8 @@ Integrate the OpenCortex into the Matrix federation for secure, distributed chat
Autonomous background polling of the Matrix homeserver. Uses `dexador` for HTTP and `cl-json` for parsing. Autonomous background polling of the Matrix homeserver. Uses `dexador` for HTTP and `cl-json` for parsing.
** 2. Semantic Interfaces ** 2. Semantic Interfaces
- `(:sensor :chat-message :channel :matrix ...)` - `(:type :EVENT :meta (:source :matrix :room-id "...") :payload (:sensor :user-input :text "..."))`
- `(:type :REQUEST :target :matrix :room-id "..." :text "...")` - `(:type :REQUEST :target :matrix :payload (:action :message :text "..."))`
* Phase D: Build (Implementation) * Phase D: Build (Implementation)
@@ -73,7 +73,8 @@ Sends an `m.room.message` to a Matrix room.
"Sends a message via Matrix Client API." "Sends a message via Matrix Client API."
(declare (ignore context)) (declare (ignore context))
(let* ((payload (getf action :payload)) (let* ((payload (getf action :payload))
(room-id (or (getf payload :room-id) (getf action :room-id))) (meta (getf action :meta))
(room-id (or (getf meta :room-id) (getf payload :room-id) (getf action :room-id)))
(text (or (getf payload :text) (getf action :text))) (text (or (getf payload :text) (getf action :text)))
(hs (get-matrix-homeserver)) (hs (get-matrix-homeserver))
(token (get-matrix-token)) (token (get-matrix-token))
@@ -126,10 +127,8 @@ Polls the `/sync` endpoint and processes timeline events.
(harness-log "MATRIX: Received message from ~a in ~a" sender room-id) (harness-log "MATRIX: Received message from ~a in ~a" sender room-id)
(inject-stimulus (inject-stimulus
(list :type :EVENT (list :type :EVENT
:payload (list :sensor :chat-message :meta (list :source :matrix :room-id room-id :sender sender)
:channel :matrix :payload (list :sensor :user-input
:room-id room-id
:sender sender
:text body))))))))) :text body)))))))))
(error (c) (harness-log "MATRIX SYNC ERROR: ~a" c)))))) (error (c) (harness-log "MATRIX SYNC ERROR: ~a" c))))))
#+end_src #+end_src

View File

@@ -32,8 +32,8 @@ Enable secure Signal communication for the OpenCortex.
Wraps the `signal-cli` binary. Polling is done in a background thread to prevent blocking the harness. Wraps the `signal-cli` binary. Polling is done in a background thread to prevent blocking the harness.
** 2. Semantic Interfaces ** 2. Semantic Interfaces
- `(:sensor :chat-message :channel :signal ...)` - `(:type :EVENT :meta (:source :signal :chat-id "+1...") :payload (:sensor :user-input :text "..."))`
- `(:type :REQUEST :target :signal :chat-id "+1..." :text "...")` - `(:type :REQUEST :target :signal :payload (:action :message :text "..."))`
* Phase D: Build (Implementation) * Phase D: Build (Implementation)
@@ -63,7 +63,8 @@ Executes the `signal-cli send` command.
"Sends a message via signal-cli." "Sends a message via signal-cli."
(declare (ignore context)) (declare (ignore context))
(let* ((payload (getf action :payload)) (let* ((payload (getf action :payload))
(chat-id (or (getf payload :chat-id) (getf action :chat-id))) (meta (getf action :meta))
(chat-id (or (getf meta :chat-id) (getf payload :chat-id) (getf action :chat-id)))
(text (or (getf payload :text) (getf action :text))) (text (or (getf payload :text) (getf action :text)))
(account (get-signal-account))) (account (get-signal-account)))
(when (and account chat-id text) (when (and account chat-id text)
@@ -97,9 +98,8 @@ Polls for new messages and injects them into the harness.
(harness-log "SIGNAL: Received message from ~a" source) (harness-log "SIGNAL: Received message from ~a" source)
(inject-stimulus (inject-stimulus
(list :type :EVENT (list :type :EVENT
:payload (list :sensor :chat-message :meta (list :source :signal :chat-id source)
:channel :signal :payload (list :sensor :user-input
:chat-id source
:text text)))))))) :text text))))))))
(error (c) (harness-log "SIGNAL POLL ERROR: ~a" c)))))) (error (c) (harness-log "SIGNAL POLL ERROR: ~a" c))))))
#+end_src #+end_src

View File

@@ -32,8 +32,8 @@ Enable mobile/remote access to the OpenCortex via a secure Telegram bot.
The gateway operates as an autonomous background service. It uses `dexador` for HTTP polling and `cl-json` for payload processing. Authentication is enforced via a whitelist of authorized `chat_id`s. The gateway operates as an autonomous background service. It uses `dexador` for HTTP polling and `cl-json` for payload processing. Authentication is enforced via a whitelist of authorized `chat_id`s.
** 2. Semantic Interfaces ** 2. Semantic Interfaces
- `(:sensor :chat-message :channel :telegram ...)` - `(:type :EVENT :meta (:source :telegram :chat-id "...") :payload (:sensor :user-input :text "..."))`
- `(:type :REQUEST :target :telegram :chat-id "..." :text "...")` - `(:type :REQUEST :target :telegram :payload (:action :message :text "..."))`
* Phase D: Build (Implementation) * Phase D: Build (Implementation)
@@ -76,7 +76,8 @@ Fetches the Bot API token from the secure vault.
"Sends a message back to Telegram." "Sends a message back to Telegram."
(declare (ignore context)) (declare (ignore context))
(let* ((payload (getf action :payload)) (let* ((payload (getf action :payload))
(chat-id (or (getf payload :chat-id) (getf action :chat-id))) (meta (getf action :meta))
(chat-id (or (getf meta :chat-id) (getf payload :chat-id) (getf action :chat-id)))
(text (or (getf payload :text) (getf action :text))) (text (or (getf payload :text) (getf action :text)))
(token (get-telegram-token)) (token (get-telegram-token))
(url (format nil "https://api.telegram.org/bot~a/sendMessage" token))) (url (format nil "https://api.telegram.org/bot~a/sendMessage" token)))
@@ -113,9 +114,8 @@ Fetches the Bot API token from the secure vault.
(harness-log "TELEGRAM: Received message from ~a" chat-id) (harness-log "TELEGRAM: Received message from ~a" chat-id)
(inject-stimulus (inject-stimulus
(list :type :EVENT (list :type :EVENT
:payload (list :sensor :chat-message :meta (list :source :telegram :chat-id (format nil "~a" chat-id))
:channel :telegram :payload (list :sensor :user-input
:chat-id (format nil "~a" chat-id)
:text text))))))) :text text)))))))
(error (c) (harness-log "TELEGRAM POLL ERROR: ~a" c)))))) (error (c) (harness-log "TELEGRAM POLL ERROR: ~a" c))))))
#+end_src #+end_src

View File

@@ -1,74 +0,0 @@
:PROPERTIES:
:ID: 1e5a2c30-d3a9-4674-8db7-b08e7e1f44d1
:CREATED: [2026-04-11 Sat 14:40]
:END:
#+TITLE: SKILL: Lisp Repair Syntax Gate
#+STARTUP: content
#+FILETAGS: :system:repair:syntax:lisp:autonomy:
* Overview
The *Lisp Repair Syntax Gate* asynchronously intercepts `:syntax-error` events emitted by the harness when Probabilistic Engine (LLM) proposals fail to parse. It performs deterministic or neural repairs and re-injects the corrected action into the pipeline.
* Implementation
** Core Repair Logic
#+begin_src lisp
(defun count-char (char string)
(let ((count 0))
(loop for c across string
when (char= c char)
do (incf count))
count))
(defun deterministic-repair (code)
"Attempts instant fixes on broken Lisp code (e.g. balancing parens)."
(let* ((open-parens (count-char #\( code))
(close-parens (count-char #\) code))
(diff (- open-parens close-parens)))
(if (> diff 0)
(concatenate 'string code (make-string diff :initial-element #\)))
code)))
(defun neural-repair (code error-message)
"Uses Probabilistic Engine to deeply repair the syntax structure."
(let ((prompt (format nil "The following Lisp code failed to parse.
ERROR: ~a
CODE: ~a
MANDATE: Output EXACTLY ONE valid Common Lisp list. Do not explain. Do not use markdown blocks."
error-message code))
(system-prompt "You are a Lisp Syntax Repair Actuator. Return only valid, balanced Lisp code."))
(let ((repaired (ask-probabilistic prompt :system-prompt system-prompt)))
(string-trim '(#\Space #\Newline #\Tab) repaired))))
#+end_src
** Skill Definition
Reacts to syntax error events and transforms them into repaired requests.
#+begin_src lisp
(defskill :skill-lisp-repair
:priority 90
:trigger (lambda (ctx) (eq (getf (getf ctx :payload) :sensor) :syntax-error))
:probabilistic nil ;; Handled deterministically in deterministic or manually via ask-probabilistic
:deterministic (lambda (action context)
(declare (ignore action))
(let* ((payload (getf context :payload))
(code (getf payload :code))
(error-msg (getf payload :error)))
(harness-log "SYNTAX GATE: Reacting to broken Lisp stimulus...")
(let ((fast-fix (deterministic-repair code)))
(handler-case
(let ((repaired (read-from-string fast-fix)))
(harness-log "SYNTAX GATE: Deterministic repair SUCCESS.")
repaired)
(error ()
(harness-log "SYNTAX GATE: Deterministic repair failed. Escalating...")
(let ((deep-fix (neural-repair code error-msg)))
(handler-case
(let ((repaired (read-from-string deep-fix)))
(harness-log "SYNTAX GATE: Neural repair SUCCESS.")
repaired)
(error ()
(harness-log "SYNTAX GATE: Neural repair failed.")
(list :type :LOG :payload (list :text "Lisp Repair Failed.")))))))))))
#+end_src