112 lines
3.8 KiB
Org Mode
112 lines
3.8 KiB
Org Mode
:PROPERTIES:
|
|
:ID: 1063668a-57ab-4d44-8db5-6f6fabb915b9
|
|
:CREATED: [2026-03-30 Mon 21:16]
|
|
:EDITED: [2026-04-07 Tue 13:42]
|
|
:END:
|
|
#+TITLE: SKILL: AST Normalization Agent (Universal Literate Note)
|
|
#+STARTUP: content
|
|
#+FILETAGS: :ast:normalization:integrity:psf:
|
|
|
|
* Overview
|
|
The *AST Normalization Agent* maintains the structural integrity of the Org-mode Abstract Syntax Tree. It ensures all nodes adhere to strict metadata requirements and handles deterministic refactoring.
|
|
|
|
* Phase A: Demand (PRD)
|
|
:PROPERTIES:
|
|
:STATUS: FROZEN
|
|
:END:
|
|
|
|
** 1. Purpose
|
|
Define automated structural enforcement and refactoring for the Org AST.
|
|
|
|
** 2. User Needs
|
|
- *Structural Enforcement:* Mandatory unique IDs for all headlines.
|
|
- *Deterministic Preemption:* Symbolic verification must override neural suggestions if errors exist.
|
|
- *Fidelity:* Preservation of content during metadata normalization.
|
|
|
|
** 3. Success Criteria
|
|
*** TODO ID Injection
|
|
*** TODO Neural Preemption
|
|
*** TODO Subtree Refactoring Verification
|
|
|
|
|
|
* Phase B: Blueprint (PROTOCOL)
|
|
:PROPERTIES:
|
|
:STATUS: SIGNED
|
|
:END:
|
|
|
|
|
|
* Phase D: Build (Implementation)
|
|
|
|
** Normalization Logic
|
|
|
|
#+begin_src lisp
|
|
(defun headline-ensure-id (headline)
|
|
"Checks if a headline node has a unique ID. If not, generates and injects one."
|
|
(let* ((props (getf headline :properties))
|
|
(id (getf props :ID)))
|
|
(if (and id (not (equal id "")))
|
|
headline
|
|
(let* ((new-id (org-agent:org-id-new))
|
|
(new-props (append props (list :ID new-id))))
|
|
(org-agent:kernel-log "AST - Injected new ID ~a into headline '~a'" new-id (getf props :TITLE))
|
|
(setf (getf headline :properties) new-props)
|
|
headline))))
|
|
|
|
(defun ast-normalize-recursive (ast)
|
|
"Recursively ensures all headlines in the AST have unique IDs."
|
|
(let ((type (getf ast :type))
|
|
(contents (getf ast :contents)))
|
|
(when (eq type :HEADLINE)
|
|
(setf ast (headline-ensure-id ast)))
|
|
(when contents
|
|
(setf (getf ast :contents)
|
|
(mapcar (lambda (child)
|
|
(if (listp child)
|
|
(ast-normalize-recursive child)
|
|
child))
|
|
contents)))
|
|
ast))
|
|
|
|
(defun ast-normalize-file (filepath)
|
|
"Reads a file (via Emacs actuator if possible, otherwise local), normalizes it, and returns the AST."
|
|
(let ((ast (org-agent:context-query-store (format nil "file:~a" filepath))))
|
|
(if ast
|
|
(ast-normalize-recursive ast)
|
|
(progn
|
|
(org-agent:kernel-log "AST ERROR - Could not find AST for ~a in store." filepath)
|
|
nil))))
|
|
#+begin_src
|
|
|
|
** Cognitive Tools
|
|
#+begin_src lisp
|
|
(org-agent:def-cognitive-tool :normalize-subtree "Ensures every headline in the current subtree has a unique ID."
|
|
:parameters ((:id :type :string :description "The ID of the root headline to normalize"))
|
|
:body (lambda (args)
|
|
(let* ((id (getf args :id))
|
|
(obj (org-agent:lookup-object id)))
|
|
(if obj
|
|
(progn
|
|
(org-agent:kernel-log "AST - Normalizing subtree starting at ~a" id)
|
|
;; Implementation note: In a real system, we'd reconstruct the AST from the store,
|
|
;; normalize it, and then re-ingest it.
|
|
"SUBTREE NORMALIZATION INITIATED.")
|
|
"ERROR: Node not found."))))
|
|
#+end_src
|
|
|
|
** Skill Definition
|
|
#+begin_src lisp
|
|
(org-agent:defskill :skill-ast-normalization
|
|
:priority 150 ; High priority, keeps the graph clean
|
|
:trigger (lambda (context)
|
|
(let ((payload (getf context :payload)))
|
|
(eq (getf payload :sensor) :buffer-save)))
|
|
:neuro nil
|
|
:symbolic (lambda (action context)
|
|
(let* ((payload (getf context :payload))
|
|
(ast (getf payload :ast)))
|
|
(when ast
|
|
(ast-normalize-recursive ast))
|
|
action)))
|
|
#+end_src
|
|
|