feat(arch): finalize Universal Literate Note transition for all projects and skills
This commit is contained in:
@@ -1,31 +0,0 @@
|
||||
#+TITLE: PRD: Skill - Architect Agent
|
||||
#+STATUS: FROZEN
|
||||
#+AUTHOR: Agent
|
||||
#+CREATED: [2026-03-31 Tue 12:15]
|
||||
|
||||
* 1. Purpose
|
||||
Define the automated architectural behaviors for the PSF Consensus Loop. The Architect skill transforms a FROZEN PRD (Demand) into a rigorous PROTOCOL (Blueprint).
|
||||
|
||||
* 2. User Needs
|
||||
|
||||
** 2.1 PRD Perception
|
||||
As the system orchestrator, I need the Architect to identify when a project is ready for blueprinting.
|
||||
- The Architect MUST monitor `$PROJECTS_DIR` for `PRD.org` files with `#+STATUS: FROZEN`.
|
||||
|
||||
** 2.2 Semantic Translation
|
||||
I need ambiguous requirements translated into executable interfaces.
|
||||
- The Architect MUST generate `PROTOCOL.org` with Lisp-style function signatures for all core requirements.
|
||||
- It MUST define the "Architectural Intent" to maintain long-term system integrity.
|
||||
|
||||
** 2.3 Institutional Memory Integration
|
||||
I need architectural decisions to be grounded in experience.
|
||||
- The Architect MUST reference `notes/institutional-memory.org` when making significant design choices.
|
||||
|
||||
** 2.4 Physical Actuation
|
||||
I need the blueprint to be physically written to the project directory.
|
||||
- The skill must have a symbolic (Lisp) actuator that writes the generated Org content to the disk.
|
||||
|
||||
* 3. Success Criteria
|
||||
- [ ] **Trigger Accuracy:** Architect correctly identifies a `FROZEN` PRD and ignores `DRAFT` PRDs.
|
||||
- [ ] **Protocol Generation:** Architect generates a `PROTOCOL.org` that contains at least one valid Lisp interface signature.
|
||||
- [ ] **File Integrity:** The generated `PROTOCOL.org` is syntactically valid Org-mode and contains the correct front matter (`#+TITLE`, `#+STATUS: DRAFT`).
|
||||
@@ -1,40 +0,0 @@
|
||||
#+TITLE: PROTOCOL: Skill - Architect Agent
|
||||
#+STATUS: DRAFT
|
||||
#+AUTHOR: Architect-Agent
|
||||
#+CREATED: [2026-03-31 Tue 12:20]
|
||||
|
||||
* 1. Architectural Intent
|
||||
This protocol defines the shared Lisp interfaces for the Architect skill. It ensures a rigorous "Consensus Loop" by defining how the Architect perceives requirements and actuates blueprints.
|
||||
|
||||
Following the **Literate Mandate**, the Architect skill's own implementation must be generated from its Org-mode source.
|
||||
|
||||
* 2. Semantic Interfaces
|
||||
|
||||
** 2.1 Requirements Perception
|
||||
#+begin_src lisp
|
||||
(defun architect-perceive-frozen-prd (project-name)
|
||||
"Checks if a project has a FROZEN PRD.
|
||||
Returns a plist: (:status :frozen :path \"path/to/PRD.org\") or NIL."
|
||||
)
|
||||
#+end_src
|
||||
|
||||
** 2.2 Blueprint Actuation
|
||||
#+begin_src lisp
|
||||
(defun architect-actuate-protocol (project-name blueprint-content)
|
||||
"Physically writes the PROTOCOL.org file.
|
||||
Input: project name and generated Org content.
|
||||
Returns a success message or error signal."
|
||||
)
|
||||
#+end_src
|
||||
|
||||
** 2.3 Memory Retrieval
|
||||
#+begin_src lisp
|
||||
(defun architect-query-institutional-memory (context-tags)
|
||||
"Retrieves relevant architectural patterns from notes/institutional-memory.org.
|
||||
Input: tags like :emacs:gtd:psf.
|
||||
Returns a list of relevant patterns/learnings."
|
||||
)
|
||||
#+end_src
|
||||
|
||||
* 3. Integration with PSF Lifecycle
|
||||
The Architect is triggered when a project transitions from `:DEMAND` to `:BLUEPRINT`. Its output (a SIGNED Protocol) is the "Safety Gate" for the **Analyst** phase.
|
||||
75
projects/org-skill-architect/src/architect-logic.lisp
Normal file
75
projects/org-skill-architect/src/architect-logic.lisp
Normal file
@@ -0,0 +1,75 @@
|
||||
;;;; architect-logic.lisp --- Architectural automation for the PSF (Unified).
|
||||
;;;; This file is TANGLED from notes/org-skill-architect.org. DO NOT EDIT MANUALLY.
|
||||
|
||||
(defpackage :org-skill-architect
|
||||
(:use :cl :uiop :local-time)
|
||||
(:export #:architect-perceive-frozen-prd
|
||||
#:architect-scan-all-notes
|
||||
#:trigger-skill-architect
|
||||
#:neuro-skill-architect
|
||||
#:architect-actuate))
|
||||
|
||||
(in-package :org-skill-architect)
|
||||
|
||||
(defun kernel-log (message &rest args)
|
||||
(format t "~&[ARCHITECT] ~?" message args))
|
||||
|
||||
(defun architect-perceive-frozen-prd (note-path)
|
||||
"Checks if a master note has a FROZEN PRD and lacks a Phase B section."
|
||||
(let ((content (uiop:read-file-string note-path)))
|
||||
(when (and (search "* Phase A: Demand (PRD)" content)
|
||||
(search ":STATUS: FROZEN" content)
|
||||
(not (search "* Phase B: Blueprint (PROTOCOL)" content)))
|
||||
`(:note-path ,note-path :content ,content))))
|
||||
|
||||
(defun architect-scan-all-notes ()
|
||||
"Scans all org-skill-*.org notes for demands ready for blueprinting."
|
||||
(let ((notes-dir (or (uiop:getenv "MEMEX_NOTES") "notes/"))
|
||||
(ready-notes '()))
|
||||
(dolist (file (uiop:directory-files notes-dir "org-skill-*.org"))
|
||||
(let ((status (architect-perceive-frozen-prd file)))
|
||||
(when status (push status ready-notes))))
|
||||
ready-notes))
|
||||
|
||||
(defun trigger-skill-architect (context)
|
||||
"Triggers on heartbeat if any master note is in a FROZEN PRD state."
|
||||
(let ((type (getf context :type))
|
||||
(payload (getf context :payload)))
|
||||
(when (and (eq type :EVENT) (eq (getf payload :sensor) :heartbeat))
|
||||
(let ((ready (architect-scan-all-notes)))
|
||||
(when ready
|
||||
(setf (getf (getf context :payload) :ready-notes) ready)
|
||||
t)))))
|
||||
|
||||
(defun neuro-skill-architect (context)
|
||||
(let* ((payload (getf context :payload))
|
||||
(note (car (getf payload :ready-notes)))
|
||||
(note-path (getf note :note-path))
|
||||
(prd-content (getf note :content)))
|
||||
(format nil "
|
||||
You are the PSF Architect.
|
||||
The Master Note '~a' has a FROZEN PRD and needs a PROTOCOL.
|
||||
|
||||
NOTE CONTENT:
|
||||
---
|
||||
~a
|
||||
---
|
||||
|
||||
TASK:
|
||||
Draft the '* Phase B: Blueprint (PROTOCOL)' section.
|
||||
1. Define Architectural Intent.
|
||||
2. Define Semantic Interfaces using Lisp signatures.
|
||||
|
||||
Return a Lisp plist: (:target :architect :action :actuate :path \"~a\" :content \"...blueprint section...\")
|
||||
" note-path prd-content note-path)))
|
||||
|
||||
(defun architect-actuate (action context)
|
||||
(let* ((payload (getf action :payload))
|
||||
(note-path (getf payload :path))
|
||||
(blueprint-content (getf payload :content)))
|
||||
|
||||
(kernel-log "Appending PROTOCOL to ~a" note-path)
|
||||
(with-open-file (out note-path :direction :output :if-exists :append)
|
||||
(format out "~%* Phase B: Blueprint (PROTOCOL)~%:PROPERTIES:~%:STATUS: SIGNED~%:END:~%~%~a"
|
||||
blueprint-content))
|
||||
(format nil "SUCCESS - Architect established PROTOCOL in ~a" note-path)))
|
||||
47
projects/org-skill-architect/tests/simulate_architect.py
Normal file
47
projects/org-skill-architect/tests/simulate_architect.py
Normal file
@@ -0,0 +1,47 @@
|
||||
import os
|
||||
import shutil
|
||||
|
||||
def simulate_perceive(project_name, projects_dir):
|
||||
prd_path = os.path.join(projects_dir, project_name, "PRD.org")
|
||||
protocol_path = os.path.join(projects_dir, project_name, "PROTOCOL.org")
|
||||
|
||||
if not os.path.exists(prd_path):
|
||||
return None
|
||||
|
||||
with open(prd_path, 'r') as f:
|
||||
content = f.read()
|
||||
|
||||
if "#+STATUS: FROZEN" in content and not os.path.exists(protocol_path):
|
||||
return {"project": project_name, "prd_path": prd_path, "content": content}
|
||||
return None
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_dir = "/tmp/architect_test_projects"
|
||||
if os.path.exists(test_dir):
|
||||
shutil.rmtree(test_dir)
|
||||
os.makedirs(os.path.join(test_dir, "test-project"))
|
||||
|
||||
prd_file = os.path.join(test_dir, "test-project", "PRD.org")
|
||||
|
||||
print("--- Test 1: Draft PRD ---")
|
||||
with open(prd_file, "w") as f:
|
||||
f.write("#+TITLE: Test\n#+STATUS: DRAFT\n")
|
||||
res = simulate_perceive("test-project", test_dir)
|
||||
print(f"Result: {res}")
|
||||
status1 = "PASS" if res is None else "FAIL"
|
||||
|
||||
print("\n--- Test 2: Frozen PRD ---")
|
||||
with open(prd_file, "w") as f:
|
||||
f.write("#+TITLE: Test\n#+STATUS: FROZEN\n")
|
||||
res = simulate_perceive("test-project", test_dir)
|
||||
print(f"Result: {res['project'] if res else None}")
|
||||
status2 = "PASS" if res and res['project'] == "test-project" else "FAIL"
|
||||
|
||||
print("\n--- Test 3: Protocol already exists ---")
|
||||
with open(os.path.join(test_dir, "test-project", "PROTOCOL.org"), "w") as f:
|
||||
f.write("exists")
|
||||
res = simulate_perceive("test-project", test_dir)
|
||||
print(f"Result: {res}")
|
||||
status3 = "PASS" if res is None else "FAIL"
|
||||
|
||||
print(f"\nFinal Status: {'PASS' if all(s == 'PASS' for s in [status1, status2, status3]) else 'FAIL'}")
|
||||
Reference in New Issue
Block a user