2.4 KiB
Root Cause Analysis: Asynchronous Lisp Repair Syntax Gate
- Executive Summary
- 1. Issue: Core Bloat & Synchronous Coupling
- 2. Side-Issue: Nested Signal Payloads
- 3. PSF Mandate Alignment
- 4. Permanent Learnings
Executive Summary
Reimplemented the `org-skill-lisp-repair` to align with the "Sovereign Boundary" mandate. The previously synchronous, core-blocking repair logic has been replaced with an asynchronous, event-driven architecture using the Reactive Signal Pipeline.
1. Issue: Core Bloat & Synchronous Coupling
Symptoms
The initial implementation of the Lisp Repair gate placed a `handler-case` and a dynamic function call (`repair-lisp-syntax`) directly inside the core `think` function (`neuro.lisp`). This forced the core to wait for repairs and made it "aware" of specific repair logic.
Root Cause
Architectural shortcutting. By placing repair logic in the core execution path, we violated the microkernel principle which mandates that the core should be a "dumb" signal processor.
Resolution
- Refactored Core: `think` now only emits a `:syntax-error` stimulus if parsing fails. It no longer attempts to repair.
- Asynchronous Skill: `skill-lisp-repair` now triggers on the `:syntax-error` event. It performs the repair and returns the corrected action, which is then dispatched by the pipeline.
2. Side-Issue: Nested Signal Payloads
Symptoms
`TYPE-ERROR` during testing when extracting the broken code from the stimulus.
Root Cause
Mismatched expectations of signal nesting. The skill expected the code at `(getf context :payload)`, but in the `decide-gate`, `context` is the full signal, and the error details were nested inside the `:candidate` field of that signal.
Resolution
Updated the symbolic logic to correctly traverse the nested signal structure: `(getf (getf context :candidate) :payload)`.
3. PSF Mandate Alignment
Sovereign Boundary
The core is now strictly a parser. Repair is an optional, user-space service.
Reactive Signal Pipeline
Leveraged the pipeline's ability to re-inject `EVENT` signals to flatten the recursion of the repair loop.
4. Permanent Learnings
- Emit, Don't Call: In a microkernel, if a non-fatal error occurs, always emit a signal rather than calling a recovery function. This allows the system to remain asynchronous and modular.
- Signal Inspection: When writing symbolic gates, always verify the exact shape of the `context` signal being passed by the kernel to avoid nesting errors.