feat: implement Component III - Memory Archivist (IPFS checkpointing)
This commit is contained in:
154
skills/org-skill-memory-archivist.org
Normal file
154
skills/org-skill-memory-archivist.org
Normal file
@@ -0,0 +1,154 @@
|
||||
:PROPERTIES:
|
||||
:ID: 98923a43-2be0-423c-8509-22592cfe9c9e
|
||||
:CREATED: [2026-04-08 Wed 18:30]
|
||||
:EDITED: [2026-04-09 Thu 15:30]
|
||||
:END:
|
||||
#+TITLE: SKILL: Memory Archivist (Universal Literate Note)
|
||||
#+STARTUP: content
|
||||
#+FILETAGS: :memory:persistence:ipfs:sovereignty:
|
||||
#+DEPENDS_ON: id:e8b500e2-3f26-4c8e-8558-528061e178ca
|
||||
|
||||
* Overview
|
||||
The *Memory Archivist* provides long-term, decentralized, and immutable history for the agent's knowledge graph. It leverages IPFS to achieve "Sovereignty Above All," ensuring that memory state is preserved across space and time.
|
||||
|
||||
* Implementation
|
||||
|
||||
** Package Context
|
||||
#+begin_src lisp
|
||||
(in-package :org-agent)
|
||||
#+end_src
|
||||
|
||||
** Serialization (archivist-serialize-store)
|
||||
Converts the live `*object-store*` into a JSON-compatible list of alists.
|
||||
|
||||
#+begin_src lisp
|
||||
(defun archivist-serialize-store ()
|
||||
"Serializes the entire object-store for archival."
|
||||
(let ((objects nil))
|
||||
(maphash (lambda (id obj)
|
||||
(declare (ignore id))
|
||||
(push `((:id . ,(org-object-id obj))
|
||||
(:type . ,(format nil "~s" (org-object-type obj)))
|
||||
(:attributes . ,(loop for (k v) on (org-object-attributes obj) by #'cddr
|
||||
collect (cons (format nil "~a" k) (format nil "~a" v))))
|
||||
(:content . ,(org-object-content obj))
|
||||
(:parent-id . ,(org-object-parent-id obj))
|
||||
(:children . ,(org-object-children obj))
|
||||
(:version . ,(org-object-version obj))
|
||||
(:last-sync . ,(org-object-last-sync obj))
|
||||
(:hash . ,(org-object-hash obj)))
|
||||
objects))
|
||||
*object-store*)
|
||||
objects))
|
||||
#+end_src
|
||||
|
||||
** IPFS Integration (archivist-push-to-ipfs)
|
||||
Pushes the serialized knowledge graph to the local IPFS daemon.
|
||||
|
||||
#+begin_src lisp
|
||||
(defun archivist-push-to-ipfs ()
|
||||
"Serializes the store and pushes it to IPFS, returning the CID."
|
||||
(let* ((data (archivist-serialize-store))
|
||||
(json-payload (cl-json:encode-json-to-string data))
|
||||
(ipfs-url "http://127.0.0.1:5001/api/v0/add"))
|
||||
(handler-case
|
||||
(let* ((response (dex:post ipfs-url
|
||||
:content `(("file" . ,json-payload))
|
||||
:headers '(("Content-Type" . "multipart/form-data"))))
|
||||
(result (cl-json:decode-json-from-string response))
|
||||
(cid (cdr (assoc :hash result))))
|
||||
(kernel-log "ARCHIVIST - Memory checkpointed to IPFS. CID: ~a" cid)
|
||||
cid)
|
||||
(error (c)
|
||||
(kernel-log "ARCHIVIST ERROR - IPFS push failed: ~a" c)
|
||||
nil))))
|
||||
#+end_src
|
||||
|
||||
** Restoration (archivist-pull-from-ipfs)
|
||||
Fetches a knowledge graph image from IPFS and hydrates the `*object-store*`.
|
||||
|
||||
#+begin_src lisp
|
||||
(defun archivist-pull-from-ipfs (cid)
|
||||
"Fetches data from IPFS by CID and restores the object-store."
|
||||
(let ((ipfs-url (format nil "http://127.0.0.1:5001/api/v0/cat?arg=~a" cid)))
|
||||
(handler-case
|
||||
(let* ((response (dex:post ipfs-url))
|
||||
(data (cl-json:decode-json-from-string response)))
|
||||
(clrhash *object-store*)
|
||||
(dolist (item data)
|
||||
(let* ((id (cdr (assoc :id item)))
|
||||
(obj (make-org-object
|
||||
:id id
|
||||
:type (read-from-string (cdr (assoc :type item)))
|
||||
:attributes (loop for attr in (cdr (assoc :attributes item))
|
||||
append (list (intern (string-upcase (car attr)) :keyword) (cdr attr)))
|
||||
:content (cdr (assoc :content item))
|
||||
:parent-id (cdr (assoc :parent-id item))
|
||||
:children (cdr (assoc :children item))
|
||||
:version (cdr (assoc :version item))
|
||||
:last-sync (cdr (assoc :last-sync item))
|
||||
:hash (cdr (assoc :hash item)))))
|
||||
(setf (gethash id *object-store*) obj)))
|
||||
(kernel-log "ARCHIVIST - Knowledge graph restored from IPFS CID: ~a" cid)
|
||||
t)
|
||||
(error (c)
|
||||
(kernel-log "ARCHIVIST ERROR - Restoration failed: ~a" c)
|
||||
nil))))
|
||||
#+end_src
|
||||
|
||||
** Cognitive Tools
|
||||
Expose archival capabilities to System 1.
|
||||
|
||||
#+begin_src lisp
|
||||
(def-cognitive-tool :ipfs-checkpoint "Creates an immutable snapshot of the current knowledge graph on IPFS."
|
||||
:parameters nil
|
||||
:body (lambda (args)
|
||||
(declare (ignore args))
|
||||
(let ((cid (archivist-push-to-ipfs)))
|
||||
(if cid
|
||||
(format nil "Checkpoint success. CID: ~a" cid)
|
||||
"Checkpoint failed. Ensure IPFS daemon is running."))))
|
||||
|
||||
(def-cognitive-tool :ipfs-restore "Restores the entire knowledge graph from a specific IPFS CID."
|
||||
:parameters ((:cid :type :string :description "The IPFS CID to restore from"))
|
||||
:body (lambda (args)
|
||||
(let ((cid (getf args :cid)))
|
||||
(if (archivist-pull-from-ipfs cid)
|
||||
(format nil "Restoration successful from ~a" cid)
|
||||
"Restoration failed."))))
|
||||
#+end_src
|
||||
|
||||
** Skill Definition
|
||||
#+begin_src lisp
|
||||
(defskill :skill-memory-archivist
|
||||
:priority 80
|
||||
:trigger (lambda (ctx) (eq (getf (getf ctx :payload) :command) :checkpoint-ipfs))
|
||||
:neuro (lambda (ctx) "Propose an IPFS checkpoint if the user wants decentralized persistence.")
|
||||
:symbolic (lambda (action ctx)
|
||||
(let ((cid (archivist-push-to-ipfs)))
|
||||
(if cid
|
||||
`(:target :system :payload (:action :message :text ,(format nil "IPFS Checkpoint: ~a" cid)))
|
||||
`(:target :system :payload (:action :message :text "IPFS Checkpoint failed."))))))
|
||||
#+end_src
|
||||
|
||||
* Phase E: Chaos (Verification)
|
||||
The Memory Archivist must be verified for serialization integrity.
|
||||
|
||||
#+begin_src lisp
|
||||
(defpackage :org-agent-archivist-tests
|
||||
(:use :cl :fiveam :org-agent))
|
||||
(in-package :org-agent-archivist-tests)
|
||||
|
||||
(def-suite archivist-suite :description "Tests for IPFS Archival.")
|
||||
(in-suite archivist-suite)
|
||||
|
||||
(test test-serialization-integrity
|
||||
"Verify that the object-store can be serialized and partially reconstructed."
|
||||
(clrhash org-agent::*object-store*)
|
||||
(ingest-ast '(:type :HEADLINE :properties (:ID "test-id" :TITLE "Test Node") :raw-content "Body Text" :contents nil))
|
||||
(let* ((data (org-agent::archivist-serialize-store))
|
||||
(first-item (first data)))
|
||||
(is (= 1 (length data)))
|
||||
(is (equal "test-id" (cdr (assoc :id first-item))))
|
||||
(is (equal "Body Text" (cdr (assoc :content first-item))))))
|
||||
#+end_src
|
||||
Reference in New Issue
Block a user