#+TITLE: SKILL: Homoiconic Memory (org-skill-homoiconic-memory.org) #+AUTHOR: Agent #+FILETAGS: :harness:memory:homoiconic: #+PROPERTY: header-args:lisp :tangle ../lisp/symbolic-memory.lisp * Overview Because Lisp is homoiconic (code is data), memory objects can be read as executable forms. This skill provides the bridge between the org-object store and live Lisp evaluation — it can serialize an org-object into an s-expression, evaluate it to reconstruct state, and store the result back as a new object. This is the foundation of the agent's ability to save, restore, and inspect its own cognitive state at runtime. * Implementation ** Memory Inspection ;; REPL-VERIFIED: 2026-05-03T13:00:00 #+begin_src lisp (in-package :passepartout) (defun memory-inspect (&key (type-filter nil) (todo-filter nil) (limit 10)) "Returns a structured report of memory state. Optional filters: TYPE-FILTER (keyword), TODO-FILTER (string). Returns a plist: (:total :by-type :by-todo :recent :snapshots :orphans )." (let* ((store (if (boundp '*memory-store*) (symbol-value '*memory-store*) (return-from memory-inspect (list :total 0 :reason "Memory store not available")))) (total 0) (type-counts (make-hash-table :test 'eq)) (todo-counts (make-hash-table :test 'equal)) (recent nil) (all-ids (make-hash-table :test 'equal)) (orphans 0)) (maphash (lambda (id obj) (setf (gethash id all-ids) t) (let ((obj-type (memory-object-type obj)) (attrs (memory-object-attributes obj)) (v (memory-object-version obj))) (unless (and type-filter (not (eq obj-type type-filter))) (let ((todo (getf attrs :TODO-STATE))) (when (and todo-filter (not (string-equal todo todo-filter))) (return nil))) (incf total) (incf (gethash obj-type type-counts 0)) (let ((todo (getf attrs :TODO-STATE))) (when todo (incf (gethash todo todo-counts 0)))) (push (list :id id :type t :todo (getf attrs :TODO-STATE) :title (getf attrs :TITLE) :version v) recent)))) store) ;; Sort recent by version desc and take LIMIT (setf recent (subseq (sort recent #'> :key (lambda (r) (or (getf r :version) 0))) 0 (min limit (length recent)))) ;; Count orphans (maphash (lambda (id obj) (let ((parent (memory-object-parent-id obj))) (when (and parent (not (gethash parent all-ids))) (incf orphans)))) store) ;; Build output (let ((types (loop for k being the hash-keys of type-counts using (hash-value v) collect (cons k v))) (todos (loop for k being the hash-keys of todo-counts using (hash-value v) collect (cons k v))) (snapshots (if (boundp '*memory-snapshots*) (length (symbol-value '*memory-snapshots*)) 0))) (list :total total :by-type (sort types #'> :key #'cdr) :by-todo (sort todos #'> :key #'cdr) :recent recent :snapshots snapshots :orphans orphans)))) #+end_src ** Skill Registration #+begin_src lisp (defskill :passepartout-symbolic-memory :priority 100 :trigger (lambda (ctx) (eq (getf (getf ctx :payload) :sensor) :introspection)) :deterministic (lambda (action ctx) (declare (ignore action ctx)) (ignore-errors (memory-inspect)) nil)) #+end_src