Files
passepartout/skills/org-skill-gardener.org
Amr Gharbeia f940861921
Some checks failed
Deploy-Agent-V15-Stdin / JOB-V15-STDIN (push) Failing after 2s
build: dynamically tangle to INSTALL_DIR without copying .org files
- Updated all 150+ :tangle headers across harness/ and skills/ to use elisp (expand-file-name) to target INSTALL_DIR dynamically.
- Cleaned up environment/ directory depth by moving memory-image.lisp to state/.
- Moved test scripts to tests/ and deleted redundant chat scripts.
2026-04-27 12:51:29 -04:00

5.4 KiB

SKILL: Autonomous Gardener (Memex Maintenance)

Overview

The Autonomous Gardener is the metabolic immune system of the Memex. It autonomously audits the knowledge graph for structural decay—broken links, orphaned nodes, and missing metadata—ensuring that the system remains coherent and navigatable over long horizons.

Phase A: Demand (PRD)

1. Purpose

Maintain the structural integrity and "Vibe" of the Memex through autonomous auditing and self-repair proposals.

2. Success Criteria

  • Link Audit: Detect `id:` links that point to non-existent objects.
  • Orphan Detection: Identify headlines that have zero inbound or outbound connections.
  • Reporting: Log structural issues or propose "Flight Plans" for manual repair.

Phase B: Blueprint (PROTOCOL)

1. Architectural Intent

The Gardener runs on a low-priority heartbeat. It performs a "Deep Audit" of the entire `*memory*` graph. Unlike the Scribe, which creates new data, the Gardener focuses on the relationships between existing data.

2. Semantic Interfaces

  • Trigger: `(:sensor :heartbeat)`
  • Action (Repair): `(:type :REQUEST :target :emacs :action :update-node :id "…" :attributes (…))`

Phase D: Build (Implementation)

Package Context

(in-package :opencortex)

State: Maintenance Cycle

We track the last audit time to ensure the Gardener doesn't over-consume resources.

(defvar *gardener-last-audit* 0
  "The universal-time of the last full Memex audit.")

Audit: Broken Links

Scans the content of all objects for `id:` links and verifies the targets exist.

(defun gardener-find-broken-links ()
  "Returns a list of broken ID links found in the Memex."
  (let ((broken nil))
    (maphash (lambda (id obj)
               (let ((content (org-object-content obj)))
                 (when content
                   (cl-ppcre:do-register-groups (target-id) ("id:([A-Za-z0-9-]+)" content)
                     (unless (lookup-object target-id)
                       (push (list :source id :broken-target target-id) broken))))))
             *memory*)
    broken))

Audit: Orphaned Nodes

Identifies nodes that are not linked to and do not link to anything else.

(defun gardener-find-orphans ()
  "Returns a list of IDs for headlines that are structurally isolated."
  (let ((inbound (make-hash-table :test 'equal))
        (outbound (make-hash-table :test 'equal))
        (orphans nil))
    ;; 1. Map all connections
    (maphash (lambda (id obj)
               (let ((content (org-object-content obj)))
                 (when content
                   (cl-ppcre:do-register-groups (target-id) ("id:([A-Za-z0-9-]+)" content)
                     (setf (gethash id outbound) t)
                     (setf (gethash target-id inbound) t)))))
             *memory*)
    ;; 2. Identify nodes with zero connections
    (maphash (lambda (id obj)
               (declare (ignore obj))
               (unless (or (gethash id inbound) (gethash id outbound))
                 (push id orphans)))
             *memory*)
    orphans))

Skill Logic: The Audit Pass

The Gardener's deterministic gate performs the actual analysis and logs the results. In future versions, it will generate probabilistic repair proposals.

(defun gardener-deterministic-gate (action context)
  "Main gate for the Gardener skill. Audits graph integrity."
  (declare (ignore action context))
  (let ((broken (gardener-find-broken-links))
        (orphans (gardener-find-orphans)))
    
    (when (or broken orphans)
      (harness-log "GARDENER: Audit found ~a broken links and ~a orphans." 
                   (length broken) (length orphans))
      
      (dolist (link broken)
        (harness-log "  [BROKEN LINK] Node ~a -> ~a" (getf link :source) (getf link :broken-target)))
      
      (dolist (orphan orphans)
        (harness-log "  [ORPHAN] Node ~a is isolated." orphan)))
    
    (setf *gardener-last-audit* (get-universal-time))
    ;; Return a log to stop the loop
    (list :type :LOG :payload (list :text "Gardener audit complete."))))

Skill Registration

(defskill :skill-gardener
  :priority 40
  :trigger (lambda (ctx)
             (let* ((payload (getf ctx :payload))
                    (sensor (getf payload :sensor)))
               (and (eq sensor :heartbeat)
                    ;; Only audit once per day
                    (> (- (get-universal-time) *gardener-last-audit*) 86400))))
  :probabilistic nil
  :deterministic #'gardener-deterministic-gate)