docs(milestone): complete v0.2.0 Interactive Refinement
Some checks failed
Deploy-Agent-V15-Stdin / JOB-V15-STDIN (push) Failing after 2s

This commit is contained in:
2026-04-27 20:17:56 -04:00
parent 41e25d091e
commit a717ab1d3a
11 changed files with 775 additions and 561 deletions

View File

@@ -0,0 +1,140 @@
#+TITLE: Skill: Config Manager (org-skill-config-manager.org)
#+AUTHOR: Agent
#+FILETAGS: :skill:setup:config:
#+STARTUP: content
* Overview
The *Config Manager* skill provides the OpenCortex Agent with the capability to manage its own internal settings and LLM provider registry.
* Phase A: Demand (Thinking)
** The Configuration Invariant
A sovereign system must be able to re-configure its own connections. By moving the Setup Wizard and Provider Registry to a skill, we enable the Agent to "self-configure" or assist the user in adding new backends like Ollama or Groq without needing to reboot the kernel.
** Hybrid Security Standard
Secrets are appended to `~/.config/opencortex/.env`, while structural metadata is stored in `~/.config/opencortex/providers.lisp`.
* Phase B: Protocol (Success Criteria)
** Test Suite Context
#+begin_src lisp :tangle (expand-file-name "config-manager-tests.lisp" (concat (or (getenv "INSTALL_DIR") ".") "/tests"))
(defpackage :opencortex-config-manager-tests
(:use :cl :fiveam :opencortex)
(:export #:config-suite))
#+end_src
#+begin_src lisp :tangle (expand-file-name "config-manager-tests.lisp" (concat (or (getenv "INSTALL_DIR") ".") "/tests"))
(in-package :opencortex-config-manager-tests)
#+end_src
#+begin_src lisp :tangle (expand-file-name "config-manager-tests.lisp" (concat (or (getenv "INSTALL_DIR") ".") "/tests"))
(def-suite config-suite :description "Verification of the Config Manager skill")
#+end_src
#+begin_src lisp :tangle (expand-file-name "config-manager-tests.lisp" (concat (or (getenv "INSTALL_DIR") ".") "/tests"))
(in-suite config-suite)
#+end_src
** Registry Tests
#+begin_src lisp :tangle (expand-file-name "config-manager-tests.lisp" (concat (or (getenv "INSTALL_DIR") ".") "/tests"))
(test test-provider-registration
"Verify that multiple providers can be registered and saved."
(let ((opencortex::*providers* nil))
(opencortex:register-provider :ollama '(:url "http://localhost:11434"))
(is (equal "http://localhost:11434" (getf (getf opencortex::*providers* :ollama) :url)))))
#+end_src
* Phase C: Implementation (Build)
** Package Context
#+begin_src lisp :tangle (expand-file-name "org-skill-config-manager.lisp" (concat (or (getenv "INSTALL_DIR") ".") "/skills"))
(in-package :opencortex)
#+end_src
** Skill Metadata
#+begin_src lisp :tangle (expand-file-name "org-skill-config-manager.lisp" (concat (or (getenv "INSTALL_DIR") ".") "/skills"))
(defparameter *skill-config-manager*
'(:name "config-manager"
:description "Manages system settings and LLM provider configurations."
:capabilities (:configure-provider :run-setup-wizard)
:type :deterministic)
"Skill metadata for the Config Manager.")
#+end_src
** Provider Templates
#+begin_src lisp :tangle (expand-file-name "org-skill-config-manager.lisp" (concat (or (getenv "INSTALL_DIR") ".") "/skills"))
(defvar *provider-templates*
'((:ollama . (:name "Ollama (Local)" :fields ((:url :label "URL") (:model :label "Model")) :default-url "http://localhost:11434" :default-model "llama3"))
(:openrouter . (:name "OpenRouter" :fields ((:key :label "API Key" :secret t) (:model :label "Model")) :default-model "anthropic/claude-3-opus-20240229"))
(:openai . (:name "OpenAI" :fields ((:key :label "API Key" :secret t) (:model :label "Model")) :default-model "gpt-4-turbo"))
(:groq . (:name "Groq" :fields ((:key :label "API Key" :secret t) (:model :label "Model")) :default-model "mixtral-8x7b-32768"))
(:gemini . (:name "Google Gemini" :fields ((:key :label "API Key" :secret t) (:model :label "Model")) :default-model "gemini-1.5-pro"))
(:anthropic . (:name "Anthropic" :fields ((:key :label "API Key" :secret t) (:model :label "Model")) :default-model "claude-3-5-sonnet-20240620")))
"Templates for supported LLM providers.")
#+end_src
** Registry Persistence
#+begin_src lisp :tangle (expand-file-name "org-skill-config-manager.lisp" (concat (or (getenv "INSTALL_DIR") ".") "/skills"))
(defvar *providers* nil "Global registry of configured LLM providers.")
#+end_src
#+begin_src lisp :tangle (expand-file-name "org-skill-config-manager.lisp" (concat (or (getenv "INSTALL_DIR") ".") "/skills"))
(defun save-providers ()
"Persist provider configuration to XDG config directory."
(let ((path (merge-pathnames "providers.lisp" (get-oc-config-dir))))
(ensure-directories-exist path)
(with-open-file (s path :direction :output :if-exists :supersede)
(format s ";;; OpenCortex Provider Metadata~%~s~%" *providers*))))
#+end_src
** Registry API
#+begin_src lisp :tangle (expand-file-name "org-skill-config-manager.lisp" (concat (or (getenv "INSTALL_DIR") ".") "/skills"))
(defun register-provider (id config)
"Update the global provider registry."
(setf (getf *providers* id) config))
#+end_src
** Setup Wizard Implementation
#+begin_src lisp :tangle (expand-file-name "org-skill-config-manager.lisp" (concat (or (getenv "INSTALL_DIR") ".") "/skills"))
(defun configure-provider (id)
"Guided configuration for a specific LLM provider template."
(let* ((template (cdr (assoc id *provider-templates*)))
(fields (getf template :fields))
(config nil))
(format t "~%--- Configuring ~a ---~%" (getf template :name))
(dolist (field-spec fields)
(let* ((field (first field-spec))
(label (getf (rest field-spec) :label))
(is-secret (getf (rest field-spec) :secret))
(default-key (intern (format nil "DEFAULT-~a" field) :keyword))
(default (getf template default-key))
(val (prompt-for label default)))
(if is-secret
(save-secret id field val)
(setf (getf config field) val))))
(register-provider id config)
(format t "✓ ~a metadata registered.~%" (getf template :name))))
#+end_src
#+begin_src lisp :tangle (expand-file-name "org-skill-config-manager.lisp" (concat (or (getenv "INSTALL_DIR") ".") "/skills"))
(defun run-setup-wizard ()
"Entry point for the interactive OpenCortex Lisp Setup Wizard."
(format t "=== OpenCortex: Advanced Setup Wizard ===~%")
(let ((user (prompt-for "Your Name" "User"))
(agent (prompt-for "Agent Name" "OpenCortex")))
(format t "Welcome, ~a. I am ~a.~%" user agent))
(format t "~%Available Providers:~%")
(loop for (id . data) in *provider-templates* do (format t " ~a: ~a~%" id (getf data :name)))
(format t "~%Enter provider IDs to configure (comma separated, or 'all'): ")
(finish-output)
(let* ((input (read-line))
(ids (if (string= input "all")
(mapcar #'car *provider-templates*)
(mapcar (lambda (s) (intern (string-upcase (string-trim " " s)) :keyword))
(uiop:split-string input :separator ",")))))
(dolist (id ids)
(when (assoc id *provider-templates*)
(configure-provider id))))
(save-providers)
(format t "~%Setup complete. Running diagnostics...~%")
(doctor-run-all))
#+end_src

View File

@@ -0,0 +1,159 @@
#+TITLE: Skill: Diagnostics (org-skill-diagnostics.org)
#+AUTHOR: Agent
#+FILETAGS: :skill:diagnostic:health:
#+STARTUP: content
* Overview
The *Diagnostics Skill* provides the OpenCortex Agent with the capability to perform self-examinations and environment validation.
By moving this logic from the harness to a skill, we enable the Agent's **Reflection Loop** to autonomously run health checks when a tool fails, transforming the Agent into a self-healing system.
* Phase A: Demand (Thinking)
** The Self-Healing Invariant
In a standard Lisp Machine, the system should be able to reason about its own environment. The `:run-diagnostics` capability ensures the Agent can verify its own dependency chain and XDG directory structure.
** XDG Compliance
The skill strictly validates the POSIX standard paths resolved during bootstrap, ensuring no silent configuration drift occurs.
* Phase B: Protocol (Success Criteria)
** Test Suite Context
#+begin_src lisp :tangle (expand-file-name "diagnostics-tests.lisp" (concat (or (getenv "INSTALL_DIR") ".") "/tests"))
(defpackage :opencortex-diagnostics-tests
(:use :cl :fiveam :opencortex)
(:export #:diagnostics-suite))
#+end_src
#+begin_src lisp :tangle (expand-file-name "diagnostics-tests.lisp" (concat (or (getenv "INSTALL_DIR") ".") "/tests"))
(in-package :opencortex-diagnostics-tests)
#+end_src
#+begin_src lisp :tangle (expand-file-name "diagnostics-tests.lisp" (concat (or (getenv "INSTALL_DIR") ".") "/tests"))
(def-suite diagnostics-suite :description "Verification of the Diagnostics skill")
#+end_src
#+begin_src lisp :tangle (expand-file-name "diagnostics-tests.lisp" (concat (or (getenv "INSTALL_DIR") ".") "/tests"))
(in-suite diagnostics-suite)
#+end_src
** Dependency Tests
#+begin_src lisp :tangle (expand-file-name "diagnostics-tests.lisp" (concat (or (getenv "INSTALL_DIR") ".") "/tests"))
(test test-dependency-check-fail
"Verify that missing binaries are correctly identified as failures."
(let ((opencortex::*doctor-required-binaries* '("non-existent-binary-123")))
(is (null (opencortex:doctor-check-dependencies)))))
#+end_src
* Phase C: Implementation (Build)
** Package Context
#+begin_src lisp :tangle (expand-file-name "org-skill-diagnostics.lisp" (concat (or (getenv "INSTALL_DIR") ".") "/skills"))
(in-package :opencortex)
#+end_src
** Skill Metadata
#+begin_src lisp :tangle (expand-file-name "org-skill-diagnostics.lisp" (concat (or (getenv "INSTALL_DIR") ".") "/skills"))
(defparameter *skill-diagnostics*
'(:name "diagnostics"
:description "Performs system health checks and environment validation."
:capabilities (:run-diagnostics)
:type :deterministic)
"Skill metadata for the Diagnostics component.")
#+end_src
** Global Configuration
#+begin_src lisp :tangle (expand-file-name "org-skill-diagnostics.lisp" (concat (or (getenv "INSTALL_DIR") ".") "/skills"))
(defvar *doctor-required-binaries* '("sbcl" "emacs" "git" "socat" "nc")
"List of external binaries required for full system operation.")
#+end_src
** Dependency Verification
#+begin_src lisp :tangle (expand-file-name "org-skill-diagnostics.lisp" (concat (or (getenv "INSTALL_DIR") ".") "/skills"))
(defun doctor-check-dependencies ()
"Verifies that required external binaries are available in the PATH via a shell probe."
(let ((all-ok t))
(harness-log "DOCTOR: Checking system dependencies...")
(dolist (dep *doctor-required-binaries*)
(let ((path (ignore-errors
(uiop:run-program (list "which" dep)
:output :string :ignore-error-status t))))
(if (and path (> (length path) 0))
(harness-log " [OK] Found ~a" dep)
(progn
(harness-log " [FAIL] Missing binary: ~a" dep)
(setf all-ok nil)))))
all-ok))
#+end_src
** Environment & XDG Validation
#+begin_src lisp :tangle (expand-file-name "org-skill-diagnostics.lisp" (concat (or (getenv "INSTALL_DIR") ".") "/skills"))
(defun doctor-check-env ()
"Validates XDG directories and environment configuration against the POSIX standard."
(harness-log "DOCTOR: Checking XDG environment...")
(let ((all-ok t)
(config-dir (uiop:getenv "OC_CONFIG_DIR"))
(data-dir (uiop:getenv "OC_DATA_DIR"))
(state-dir (uiop:getenv "OC_STATE_DIR"))
(memex-dir (uiop:getenv "MEMEX_DIR")))
(flet ((check-dir (name path critical)
(if (and path (> (length path) 0))
(if (uiop:directory-exists-p path)
(harness-log " [OK] ~a: ~a" name path)
(progn
(harness-log " [FAIL] ~a directory missing: ~a" name path)
(when critical (setf all-ok nil))))
(progn
(harness-log " [FAIL] ~a variable not set." name)
(when critical (setf all-ok nil))))))
(check-dir "Config (OC_CONFIG_DIR)" config-dir t)
(check-dir "Data (OC_DATA_DIR)" data-dir t)
(check-dir "State (OC_STATE_DIR)" state-dir t)
(check-dir "Memex (MEMEX_DIR)" memex-dir t))
all-ok))
#+end_src
** LLM Connectivity
#+begin_src lisp :tangle (expand-file-name "org-skill-diagnostics.lisp" (concat (or (getenv "INSTALL_DIR") ".") "/skills"))
(defun doctor-check-llm ()
"Tests connectivity to primary LLM providers. Non-critical fallback allowed."
(harness-log "DOCTOR: Checking LLM connectivity...")
(let ((openrouter-key (uiop:getenv "OPENROUTER_API_KEY")))
(if (and openrouter-key (> (length openrouter-key) 0))
(progn
(harness-log " [OK] OpenRouter API Key detected.")
t)
(progn
(harness-log " [WARN] No OpenRouter API Key. Falling back to local inference only.")
t))))
#+end_src
** Orchestration
#+begin_src lisp :tangle (expand-file-name "org-skill-diagnostics.lisp" (concat (or (getenv "INSTALL_DIR") ".") "/skills"))
(defun doctor-run-all ()
"Executes the full diagnostic suite and returns T if system is healthy."
(harness-log "==================================================")
(harness-log " OPENCORTEX DOCTOR: Commencing Health Check")
(harness-log "==================================================")
(let ((dep-ok (doctor-check-dependencies))
(env-ok (doctor-check-env))
(llm-ok (doctor-check-llm)))
(harness-log "==================================================")
(if (and dep-ok env-ok)
(progn
(harness-log " ✓ SYSTEM HEALTHY: Ready for ignition.")
t)
(progn
(harness-log " ✗ SYSTEM UNHEALTHY: Fix the errors above.")
nil))))
#+end_src
** CLI Entry Point
#+begin_src lisp :tangle (expand-file-name "org-skill-diagnostics.lisp" (concat (or (getenv "INSTALL_DIR") ".") "/skills"))
(defun doctor-main ()
"Entry point for the 'doctor' CLI command."
(if (doctor-run-all)
(uiop:quit 0)
(uiop:quit 1)))
#+end_src

View File

@@ -0,0 +1,125 @@
#+TITLE: Skill: Gateway Manager (org-skill-gateway-manager.org)
#+AUTHOR: Agent
#+FILETAGS: :skill:setup:gateway:
#+STARTUP: content
* Overview
The *Gateway Manager* skill provides the OpenCortex Agent with the capability to manage its own external communication channels (Gateways).
* Phase A: Demand (Thinking)
** Architectural Invariant: Self-Linking
In a traditional AI wrapper, the user manually edits a config file to add a bot token. In OpenCortex, the Agent should be able to say: "I have verified the Telegram token and successfully linked our connection."
* Phase B: Protocol (Success Criteria)
** Test Suite Context
#+begin_src lisp :tangle (expand-file-name "gateway-manager-tests.lisp" (concat (or (getenv "INSTALL_DIR") ".") "/tests"))
(defpackage :opencortex-gateway-manager-tests
(:use :cl :fiveam :opencortex)
(:export #:gateway-suite))
#+end_src
#+begin_src lisp :tangle (expand-file-name "gateway-manager-tests.lisp" (concat (or (getenv "INSTALL_DIR") ".") "/tests"))
(in-package :opencortex-gateway-manager-tests)
#+end_src
#+begin_src lisp :tangle (expand-file-name "gateway-manager-tests.lisp" (concat (or (getenv "INSTALL_DIR") ".") "/tests"))
(def-suite gateway-suite :description "Verification of the Gateway Manager skill")
#+end_src
#+begin_src lisp :tangle (expand-file-name "gateway-manager-tests.lisp" (concat (or (getenv "INSTALL_DIR") ".") "/tests"))
(in-suite gateway-suite)
#+end_src
** Logic Tests
#+begin_src lisp :tangle (expand-file-name "gateway-manager-tests.lisp" (concat (or (getenv "INSTALL_DIR") ".") "/tests"))
(test test-gateway-registration
"Verify that the skill can register a new gateway metadata block."
(let ((opencortex::*gateways* nil))
(opencortex:skill-gateway-register :telegram '(:status :unverified))
(is (getf (getf opencortex::*gateways* :telegram) :status))))
#+end_src
* Phase C: Implementation (Build)
** Package Context
#+begin_src lisp :tangle (expand-file-name "org-skill-gateway-manager.lisp" (concat (or (getenv "INSTALL_DIR") ".") "/skills"))
(in-package :opencortex)
#+end_src
** Capability Definition
#+begin_src lisp :tangle (expand-file-name "org-skill-gateway-manager.lisp" (concat (or (getenv "INSTALL_DIR") ".") "/skills"))
(defparameter *skill-gateway-manager*
'(:name "gateway-manager"
:description "Manages connections to external chat platforms."
:capabilities (:link-gateway :list-gateways)
:type :deterministic)
"Skill metadata for the Gateway Manager.")
#+end_src
** Registry Persistence
#+begin_src lisp :tangle (expand-file-name "org-skill-gateway-manager.lisp" (concat (or (getenv "INSTALL_DIR") ".") "/skills"))
(defvar *gateways* nil "The internal registry of configured gateways.")
#+end_src
** Persistence Stubs
#+begin_src lisp :tangle (expand-file-name "org-skill-gateway-manager.lisp" (concat (or (getenv "INSTALL_DIR") ".") "/skills"))
(defun save-gateways ()
"Persist gateway metadata to XDG Config directory."
(let ((path (merge-pathnames "gateways.lisp" (get-oc-config-dir))))
(ensure-directories-exist path)
(with-open-file (s path :direction :output :if-exists :supersede)
(format s ";;; OpenCortex Gateway Registry~%~s~%" *gateways*))))
#+end_src
** Registration Logic
#+begin_src lisp :tangle (expand-file-name "org-skill-gateway-manager.lisp" (concat (or (getenv "INSTALL_DIR") ".") "/skills"))
(defun skill-gateway-register (platform metadata)
"Internal function to update the gateway registry."
(setf (getf *gateways* platform) metadata))
#+end_src
** Telegram Verification
#+begin_src lisp :tangle (expand-file-name "org-skill-gateway-manager.lisp" (concat (or (getenv "INSTALL_DIR") ".") "/skills"))
(defun skill-gateway-verify-telegram (token)
"Verifies a Telegram bot token via the getMe API."
(let ((url (format nil "https://api.telegram.org/bot~a/getMe" token)))
(handler-case
(let* ((response (dex:get url))
(data (cl-json:decode-json-from-string response)))
(if (cdr (assoc :ok data))
(let ((result (cdr (assoc :result data))))
(list :status :verified :username (cdr (assoc :username result))))
(list :status :failed :error "Invalid Token")))
(error (c) (list :status :failed :error (format nil "~a" c))))))
#+end_src
** Linkage Command
#+begin_src lisp :tangle (expand-file-name "org-skill-gateway-manager.lisp" (concat (or (getenv "INSTALL_DIR") ".") "/skills"))
(defun skill-gateway-link (platform token)
"Primary capability to link a new platform. Returns status plist."
(harness-log "GATEWAY: Attempting to link ~a..." platform)
(let ((verification (cond
((eq platform :telegram) (skill-gateway-verify-telegram token))
(t (list :status :verified :info "Platform verification pending implementation")))))
(if (eq (getf verification :status) :verified)
(progn
(save-secret platform :token token)
(skill-gateway-register platform verification)
(save-gateways)
(list :status :success :platform platform :info verification))
(list :status :error :reason (getf verification :error)))))
#+end_src
** CLI Main Wrapper
#+begin_src lisp :tangle (expand-file-name "org-skill-gateway-manager.lisp" (concat (or (getenv "INSTALL_DIR") ".") "/skills"))
(defun gateway-manager-main (platform token)
"Main entry point for CLI-driven linkage."
(if (and platform token)
(let ((result (skill-gateway-link (intern (string-upcase platform) :keyword) token)))
(format t "RESULT: ~s~%" result)
(uiop:quit 0))
(progn
(format t "Usage: opencortex link <PLATFORM> <TOKEN>~%")
(uiop:quit 1))))
#+end_src