;;;; analyst-logic.lisp --- TDD automation for the PSF (Unified). ;;;; This file is TANGLED from notes/org-skill-tech-analyst.org. DO NOT EDIT MANUALLY. (defpackage :org-skill-tech-analyst (:use :cl :uiop :local-time) (:export #:tech-analyst-perceive-signed-protocol #:tech-analyst-scan-all-notes #:trigger-skill-tech-analyst #:neuro-skill-tech-analyst #:tech-analyst-actuate)) (in-package :org-skill-tech-analyst) (defun kernel-log (message &rest args) (format t "~&[ANALYST] ~?" message args)) (defun tech-analyst-perceive-signed-protocol (note-path) "Checks if a master note has a SIGNED PROTOCOL and lacks a TDD suite in the material project." (let* ((content (uiop:read-file-string note-path)) (filename (pathname-name note-path)) (project-name (subseq filename 10)) ; Extract 'name' from 'org-skill-name' (projects-dir (or (uiop:getenv "PROJECTS_DIR") "projects/")) (test-path (format nil "~aorg-skill-~a/tests/test-suite.lisp" projects-dir project-name))) (when (and (search "* Phase B: Blueprint (PROTOCOL)" content) (search ":STATUS: SIGNED" content) (not (uiop:file-exists-p test-path))) `(:project-name ,project-name :note-path ,note-path :content ,content)))) (defun tech-analyst-scan-all-notes () "Scans all org-skill-*.org notes for blueprints ready for testing." (let ((notes-dir (or (uiop:getenv "MEMEX_NOTES") "notes/")) (ready-notes '())) (dolist (file (uiop:directory-files notes-dir "org-skill-*.org")) (let ((status (tech-analyst-perceive-signed-protocol file))) (when status (push status ready-notes)))) ready-notes)) (defun trigger-skill-tech-analyst (context) "Triggers on heartbeat if any master note is in a SIGNED PROTOCOL state." (let ((type (getf context :type)) (payload (getf context :payload))) (when (and (eq type :EVENT) (eq (getf payload :sensor) :heartbeat)) (let ((ready (tech-analyst-scan-all-notes))) (when ready (setf (getf (getf context :payload) :ready-blueprints) ready) t))))) (defun neuro-skill-tech-analyst (context) (let* ((payload (getf context :payload)) (note (car (getf payload :ready-blueprints))) (name (getf note :project-name)) (protocol-content (getf note :content))) (format nil " You are the PSF Technical Analyst. The Master Note for project '~a' has a SIGNED PROTOCOL and needs a TDD Suite. PROTOCOL CONTENT: --- ~a --- TASK: Generate a comprehensive Common Lisp test suite (failing/RED). 1. Use FiveAM for testing. 2. Match function signatures exactly as defined in the PROTOCOL. Return a Lisp plist: (:target :analyst :action :actuate :name \"~a\" :content \"...test code...\") " name protocol-content name))) (defun tech-analyst-actuate (action context) (let* ((payload (getf action :payload)) (project-name (getf payload :name)) (test-content (getf payload :content)) (projects-dir (or (uiop:getenv "PROJECTS_DIR") "projects/")) (project-dir (format nil "~aorg-skill-~a/" projects-dir project-name)) (test-dir (format nil "~atests/" project-dir)) (test-path (format nil "~atests/test-suite.lisp" project-dir))) (kernel-log "Actuating TDD Suite for ~a" project-name) (ensure-directories-exist test-dir) (with-open-file (out test-path :direction :output :if-exists :supersede) (format out ";;; TDD Suite for ~a~%~a" project-name test-content)) (format nil "SUCCESS - Technical Analyst established TDD Suite for ~a" project-name)))