Files
org-agent-contrib/skills/org-skill-event-orchestrator.org

7.9 KiB

SKILL: Event Orchestrator (Universal Literate Note)

Overview

The Event Orchestrator is the central nervous system of the OpenCortex. It unifies three previously fragmented domains of system control:

  1. Cron (Temporal Control): Triggering tasks based on time and heartbeats.
  2. Hooks (Lifecycle Control): Enabling event-driven extensibility at specific code points.
  3. Routing (Cognitive Control): Classifying incoming stimuli into complexity tiers for optimal resource allocation.

By consolidating these into a single unit, we ensure that all system automation is auditable, Merkle-integrated, and follows a uniform safety standard.

Phase A: Demand (PRD)

1. Purpose

Provide a unified, high-integrity interface for background automation and stimulus classification.

2. User Needs

  • Predictable Scheduling: Precise execution of tasks based on cron-strings or intervals.
  • Reactive Extensions: Ability to "hook" into system events (save, boot, ingest).
  • Intelligent Dispatch: Automated complexity tiering to prevent wasted compute.
  • Durable Registry: All registered hooks and cron-jobs must be persisted to the Memory.

Phase B: Blueprint (PROTOCOL)

1. Architectural Intent

The orchestrator maintains three internal registries (Hooks, Cron, Routing Rules). It provides a standard API for registration and triggering, using the `LOCAL` persistence adapter to ensure these registries survive reboots.

2. Semantic Interfaces

(defun orchestrator-register-hook (hook-name fn)
  "Adds a function to a system hook.")

(defun orchestrator-schedule-task (task-id schedule fn)
  "Schedules a recurring task.")

(defun orchestrator-classify-stimulus (context)
  "Assigns a complexity tier (:REFLEX, :COGNITION, :REASONING) to a stimulus.")

Phase C: Success (QUALITY)

1. Success Criteria

  • Hook Latency: Triggering a hook with 10 functions must complete in <1ms.
  • Cron Precision: Scheduled tasks must fire within 1s of their target window.
  • Merkle Persistence: Adding a hook or cron-job must increment the Memory version.
  • Classification Accuracy: Routine system events must always be classified as `:REFLEX`.

2. TDD Plan

Tests in `tests/orchestrator-tests.lisp` will verify hook execution order, cron-job triggering via a mocked heartbeat, and the routing classification logic.

Phase D: Build (Implementation)

Package Context

Registry State

We maintain our internal registries in hash-tables, which will be serialized via the State Persistence layer.

(defvar *hook-registry* (make-hash-table :test 'equal)
  "Maps hook-names (symbols) to lists of functions.")

(defvar *cron-registry* (make-hash-table :test 'equal)
  "Maps task-ids to plists containing schedule and function.")

Hook: Registration

Allows external skills to register logic at system lifecycle points.

(defun orchestrator-register-hook (hook-name fn)
  "Registers a function for a named hook. Triggers a Merkle snapshot."
  (pushnew fn (gethash hook-name *hook-registry*))
  (harness-log "ORCHESTRATOR - Registered hook function for ~a" hook-name)
  (snapshot-memory)
  t)

Hook: Triggering

Executes all functions associated with a specific hook.

(defun orchestrator-trigger-hook (hook-name &rest args)
  "Executes all registered functions for the given hook name."
  (let ((functions (gethash hook-name *hook-registry*)))
    (dolist (fn functions)
      (handler-case (apply fn args)
        (error (c) (harness-log "ORCHESTRATOR ERROR - Hook ~a failed: ~a" hook-name c))))))

Cron: Task Scheduling

Registers a recurring task to be executed during heartbeats.

(defun orchestrator-schedule-task (task-id schedule fn)
  "Schedules a task for execution. Schedule can be an interval (integer seconds) or 'heartbeat'."
  (setf (gethash task-id *cron-registry*) (list :schedule schedule :fn fn :last-run 0))
  (harness-log "ORCHESTRATOR - Scheduled task ~a (~a)" task-id schedule)
  (snapshot-memory)
  t)

Cron: Heartbeat Processor

The internal loop that checks the cron-registry during every system pulse.

(defun orchestrator-process-cron ()
  "Checked by the harness on every heartbeat."
  (let ((now (get-universal-time)))
    (maphash (lambda (id task)
               (let ((schedule (getf task :schedule))
                     (last-run (getf task :last-run))
                     (fn (getf task :fn)))
                 (when (or (eq schedule :heartbeat)
                           (and (integerp schedule) (>= (- now last-run) schedule)))
                   (handler-case (funcall fn)
                     (error (c) (harness-log "ORCHESTRATOR ERROR - Cron task ~a failed: ~a" id c)))
                   (setf (getf (gethash id *cron-registry*) :last-run) now))))
             *cron-registry*)))

Router: Complexity Classification

Deterministic logic to classify incoming stimuli into complexity tiers.

(defun orchestrator-classify-complexity (context)
  "Returns the complexity tier (:REFLEX, :COGNITION, :REASONING) for a stimulus."
  (let* ((payload (getf context :payload))
         (sensor (getf payload :sensor))
         (skill (find-triggered-skill context))
         (skill-name (when skill (skill-name skill))))
    (cond
      ;; reasoning: generative or architectural
      ((member skill-name '("skill-architect" "skill-tech-analyst" "skill-scientist" "skill-self-fix") :test #'string-equal) :REASONING)
      ((member sensor '(:user-command)) :REASONING)
      
      ;; cognition: human interaction or semantic data
      ((member sensor '(:chat-message :delegation)) :COGNITION)
      ((member skill-name '("skill-scribe" "skill-web-research") :test #'string-equal) :COGNITION)
      
      ;; reflex: system infrastructure and background automation
      (t :REFLEX))))

Registration

We register the orchestrator as a core skill and hot-patch the harness's routing hook to use our classification logic.

(progn
  ;; Hook into kernel routing
  (setf opencortex::*model-selector-fn* #'orchestrator-classify-complexity)
  
  (defskill :skill-event-orchestrator
    :priority 400 ; Foundational control layer
    :trigger (lambda (ctx) (eq (getf (getf ctx :payload) :sensor) :heartbeat))
    :probabilistic nil
    :deterministic (lambda (action ctx)
                (orchestrator-process-cron)
                action)))

Phase E: Chaos (Verification)

1. Unit Tests (FiveAM)

(defpackage :opencortex-orchestrator-tests
  (:use :cl :fiveam :opencortex))
(in-package :opencortex-orchestrator-tests)

(def-suite orchestrator-suite :description "Tests for Event Orchestrator.")
(in-suite orchestrator-suite)

(test test-hook-execution
  (let ((test-val 0))
    (opencortex:orchestrator-register-hook :test-hook (lambda () (setf test-val 1)))
    (opencortex:orchestrator-trigger-hook :test-hook)
    (is (= 1 test-val))))

(test test-routing-reflex
  (let ((ctx '(:payload (:sensor :heartbeat))))
    (is (eq :REFLEX (opencortex:orchestrator-classify-complexity ctx)))))

2. Chaos Scenarios

  • Scenario A (Infinite Hook Loop): Register two hooks that call each other and verify the orchestrator's recursion limit or handler-case prevents a kernel stack-overflow.
  • Scenario B (Cron Stall): Register a cron-job that performs a long synchronous sleep and verify the `harness-log` identifies the delay in the heartbeat pulse.

Phase F: Memory (RCA)

  • [2026-04-09 Thu]: Consolidated Cron, Hook Manager, and Cognitive Router into a single orchestrator. Fixed the lack of implementation for Cron and Hooks.