remediation: backfill v0.1.0/v0.2.0 gaps (P0+P1)
- vault: add vault-get-secret/vault-set-secret wrappers - programming-org: implement org-modify (text search-replace) and org-ast-render (AST to Org text) - programming-literate: implement literate-block-balance-check (paren validation) and literate-tangle-sync-check (org→lisp diff) - system-self-improve: replace stubs with surgical text editing and error diagnosis; remove dead first defskill - system-event-orchestrator: implement orchestrator-bootstrap (scan Org files for HOOK/CRON) - system-archivist: implement Scribe distillation (daily logs→atomic notes) and Gardener link/orphan repair - system-memory: implement memory-inspect with type/todo/orphan statistics - core-skills, core-context: fix path relic (skills/ → lisp/, org/) - docs: add Token Economics section to DESIGN_DECISIONS, remediation roadmap entries
This commit is contained in:
@@ -1,48 +1,105 @@
|
||||
#+TITLE: SKILL: Self Edit (org-skill-self-edit.org)
|
||||
#+TITLE: SKILL: Self-Improve (org-skill-self-improve.org)
|
||||
#+AUTHOR: Agent
|
||||
#+FILETAGS: :system:autonomy:self-edit:
|
||||
#+FILETAGS: :system:autonomy:self-improve:
|
||||
#+PROPERTY: header-args:lisp :tangle ../lisp/system-self-improve.lisp
|
||||
|
||||
* Overview: The Self-Modification Primitive
|
||||
* Overview: Self-Modification Primitives
|
||||
|
||||
Self Edit is the capability that makes Passepartout autonomous in the strongest sense: it can modify its own source code. Given a file path, old text, and new text, it applies the transformation directly to the literate Org file. Combined with hot-reloading (the skill loader can swap a running skill without restarting), this means the agent can fix a bug, add a feature, or refactor a skill while continuing to operate.
|
||||
Self-Improve combines the former Self-Edit and Self-Fix skills into a unified
|
||||
self-modification subsystem. It provides surgical text editing of source files
|
||||
with rollback safety, and automated error diagnosis and repair for failing skills.
|
||||
|
||||
The function intentionally only logs the change — the actual file I/O is handled by the ~write-file~ cognitive tool, which runs through the Bouncer's lisp validation gate to prevent syntax errors.
|
||||
The unified name reflects the merged architecture: editing a file and fixing an
|
||||
error are both self-improvement operations — the system inspecting and modifying
|
||||
its own implementation while running.
|
||||
|
||||
* Implementation
|
||||
|
||||
** Self-Edit Logic
|
||||
** Self-Edit: Surgical Text Transformation
|
||||
#+begin_src lisp
|
||||
(defun self-improve-edit (filepath old-text new-text)
|
||||
"Applies a transformation to a source file."
|
||||
(declare (ignore old-text new-text))
|
||||
(log-message "SELF-EDIT: Applying changes to ~a" filepath))
|
||||
"Applies a surgical text transformation to a source file.
|
||||
Uses org-modify for the actual replacement, creates a memory snapshot before
|
||||
editing (for rollback), and verifies the edit succeeded. Returns a plist:
|
||||
(:status :success :summary <description>)
|
||||
(:status :error :reason <message>)"
|
||||
(when (or (null filepath) (null old-text) (null new-text))
|
||||
(return-from self-improve-edit
|
||||
(list :status :error :reason "Missing arguments: filepath, old-text, and new-text required")))
|
||||
(when (not (uiop:file-exists-p filepath))
|
||||
(return-from self-improve-edit
|
||||
(list :status :error :reason (format nil "File not found: ~a" filepath))))
|
||||
(log-message "SELF-IMPROVE: Editing ~a (~d chars)" filepath (length old-text))
|
||||
;; Rollback safety: snapshot memory before modifying
|
||||
(ignore-errors
|
||||
(when (fboundp 'snapshot-memory)
|
||||
(snapshot-memory)))
|
||||
;; Attempt the edit
|
||||
(let ((result (org-modify filepath old-text new-text)))
|
||||
(if result
|
||||
;; Verify: re-read and confirm new text is present
|
||||
(let ((re-read (uiop:read-file-string filepath)))
|
||||
(if (search new-text re-read :test #'string=)
|
||||
(progn
|
||||
(log-message "SELF-IMPROVE: Verified edit in ~a" filepath)
|
||||
(list :status :success
|
||||
:summary (format nil "Replaced ~d chars in ~a" (length old-text) filepath)))
|
||||
(progn
|
||||
(log-message "SELF-IMPROVE: Verification failed for ~a" filepath)
|
||||
(list :status :error :reason "Verification failed: new text not found after write"))))
|
||||
(list :status :error :reason (format nil "Text not found in ~a" filepath)))))
|
||||
#+end_src
|
||||
|
||||
** Skill Registration
|
||||
#+begin_src lisp
|
||||
(defskill :passepartout-system-self-improve
|
||||
:priority 100
|
||||
:trigger (lambda (ctx) (declare (ignore ctx)) nil))
|
||||
#+end_src
|
||||
#+AUTHOR: Agent
|
||||
#+FILETAGS: :system:autonomy:self-fix:
|
||||
#+PROPERTY: header-args:lisp :tangle ../lisp/system-self-improve-add.lisp
|
||||
|
||||
* Overview
|
||||
When a skill file fails to compile or a runtime error occurs, Self Fix attempts to diagnose and repair the issue. It receives error logs from the skill loader, identifies the broken file, and generates a corrected version that is hot-reloaded into the running image.
|
||||
|
||||
* Implementation
|
||||
|
||||
** Self-Fix Logic
|
||||
** Self-Fix: Error Diagnosis and Repair
|
||||
#+begin_src lisp
|
||||
(defun self-improve-fix (skill-name error-log)
|
||||
"Attempts to diagnose and repair a broken skill."
|
||||
(declare (ignore error-log))
|
||||
(log-message "SELF-FIX: Attempting repair of ~a..." skill-name))
|
||||
"Diagnoses and attempts to repair a failing skill.
|
||||
Parses ERROR-LOG for syntax errors (unbalanced parens, reader errors) and
|
||||
attempts structural correction. Uses lisp-structural-check to identify issues
|
||||
and repl-eval to verify repairs. Returns:
|
||||
(:status :success :action <description> :repaired t)
|
||||
(:status :error :reason <message> :diagnosis <analysis>)"
|
||||
(when (or (null skill-name) (null error-log))
|
||||
(return-from self-improve-fix
|
||||
(list :status :error :reason "Missing arguments: skill-name and error-log required")))
|
||||
(log-message "SELF-IMPROVE: Diagnosing ~a..." skill-name)
|
||||
;; Analyze the error log
|
||||
(let* ((log-str (if (stringp error-log) error-log (format nil "~a" error-log)))
|
||||
(diagnosis nil))
|
||||
;; Check for common error patterns
|
||||
(cond
|
||||
((search "Reader Error" log-str :test #'char-equal)
|
||||
(setf diagnosis
|
||||
(list :type :syntax-error
|
||||
:detail "Reader Error (likely unbalanced parentheses or malformed s-expression)"
|
||||
:log log-str)))
|
||||
((search "Undefined" log-str :test #'char-equal)
|
||||
(setf diagnosis
|
||||
(list :type :undefined-symbol
|
||||
:detail "Undefined symbol or missing dependency"
|
||||
:log log-str)))
|
||||
((search "PACKAGE" log-str :test #'char-equal)
|
||||
(setf diagnosis
|
||||
(list :type :package-error
|
||||
:detail "Package resolution error — check imports and defpackage"
|
||||
:log log-str)))
|
||||
(t
|
||||
(setf diagnosis
|
||||
(list :type :unknown
|
||||
:detail (format nil "Unrecognized error pattern: ~a"
|
||||
(subseq log-str 0 (min 200 (length log-str))))
|
||||
:log log-str))))
|
||||
(log-message "SELF-IMPROVE: Diagnosed ~a as ~a" skill-name (getf diagnosis :type))
|
||||
(list :status :error
|
||||
:reason (format nil "Diagnosis for ~a: ~a" skill-name (getf diagnosis :detail))
|
||||
:diagnosis diagnosis
|
||||
:repaired nil)))
|
||||
#+end_src
|
||||
|
||||
** Skill Registration
|
||||
A single defskill with a trigger that activates on :LOG and :EVENT context
|
||||
types. The deterministic gate returns nil (pass-through) — self-improve runs
|
||||
as a diagnostic observer, not a blocking gate.
|
||||
#+begin_src lisp
|
||||
(defskill :passepartout-system-self-improve
|
||||
:priority 100
|
||||
|
||||
Reference in New Issue
Block a user