From eabba11a3355ae895aaf9f42287593d56da2fbbc Mon Sep 17 00:00:00 2001 From: Amr Gharbeia Date: Sun, 26 Apr 2026 11:53:57 -0400 Subject: [PATCH] Restore LP discipline: fix org source, regenerate .lisp - Restored engineering-standards.org from 86eeaab (was missing blocks) - Regenerated .lisp from org (proper literate workflow) - Both org and .lisp now have correct paren balance - System loads, tests pass 9/10 (1 expected failure due to dirty git) Lesson: NEVER edit .lisp directly. Always fix org and regenerate. --- .../gen/org-skill-engineering-standards.lisp | 2 + skills/org-skill-engineering-standards.org | 77 ++++++++++++++++++- 2 files changed, 77 insertions(+), 2 deletions(-) diff --git a/library/gen/org-skill-engineering-standards.lisp b/library/gen/org-skill-engineering-standards.lisp index bfcff96..c492a0e 100644 --- a/library/gen/org-skill-engineering-standards.lisp +++ b/library/gen/org-skill-engineering-standards.lisp @@ -1,5 +1,6 @@ (in-package :opencortex) + (defvar *engineering-std-*project-root* nil "Path to the project root for enforcement checks.") @@ -130,3 +131,4 @@ This detects direct .lisp edits (which violate the LP workflow)." ;; Auto-initialize on load (engineering-std-init) + diff --git a/skills/org-skill-engineering-standards.org b/skills/org-skill-engineering-standards.org index fa0e0c7..8715589 100644 --- a/skills/org-skill-engineering-standards.org +++ b/skills/org-skill-engineering-standards.org @@ -125,7 +125,8 @@ The engineering standards skill is a HARD BLOCK gate. Violations are rejected, n (defvar *enforcement-rules* '((:pre-task (:git-clean "Working tree must be clean before modifications") - (:skill-queried "Skill catalog should be queried before analysis")) + (:skill-queried "Skill catalog should be queried before analysis") + (:tangle-synced "Tangled .lisp files must match Org source")) (:during-task (:org-only "Only .org files may be edited; .lisp is generated") (:one-per-block "One definition per src block") @@ -156,6 +157,43 @@ The engineering standards skill is a HARD BLOCK gate. Violations are rejected, n :severity :blocker))) #+end_src +** Tangle Sync Check (Blocking) + +This check verifies that tangled .lisp files are in sync with their Org source. Violation: edited .lisp directly instead of through Org. + +#+begin_src lisp :tangle ../library/gen/org-skill-engineering-standards.lisp +(defvar *tangle-targets* + '(("skills/org-skill-engineering-standards.org" . "library/gen/org-skill-engineering-standards.lisp") + ("skills/org-skill-literate-programming.org" . "library/gen/org-skill-literate-programming.lisp") + ("harness/memory.org" . "library/memory.lisp") + ("harness/loop.org" . "library/loop.lisp") + ("harness/perceive.org" . "library/perceive.lisp") + ("harness/reason.org" . "library/reason.lisp") + ("harness/act.org" . "library/act.lisp") + ("harness/skills.org" . "library/skills.lisp") + ("harness/communication.org" . "library/communication.lisp"))) + +(defun check-tangle-sync (&optional (root *engineering-std-*project-root*)) + "Returns violation if any tangled .lisp file is newer than its Org source. + +This detects direct .lisp edits (which violate the LP workflow)." + (when root + (dolist (pair *tangle-targets*) + (let* ((org-file (merge-pathnames (car pair) root)) + (lisp-file (merge-pathnames (cdr pair) root)) + (org-time (ignore-errors (file-write-date org-file))) + (lisp-time (ignore-errors (file-write-date lisp-file)))) + (when (and org-time lisp-time (> lisp-time org-time)) + (return-from check-tangle-sync + (make-engineering-violation + :phase :pre-task + :rule :tangle-synced + :message (format nil "ENGINEERING STANDARDS VIOLATION: ~a is newer than ~a. Edit Org source, not .lisp directly." + (file-namestring lisp-file) (file-namestring org-file)) + :severity :blocker)))))) + nil) +#+end_src + ** Test Suite These tests verify the enforcement logic. Run with: @@ -224,6 +262,33 @@ These tests verify the enforcement logic. Run with: (let ((result (opencortex::engineering-standards-gate action nil))) (is (listp result)) (is (eq :request (getf result :type)))))) + +(test tangle-sync-detects-stale-lisp + "check-tangle-sync returns violation when .lisp is newer than .org" + (let ((tmp-org "/tmp/test-skill.org") + (tmp-lisp "/tmp/test-skill.lisp")) + (with-open-file (f tmp-org :direction :output) (write-line "* Test" f)) + (sleep 1) + (with-open-file (f tmp-lisp :direction :output) (write-line "(defun test () t)" f)) + (let* ((root (uiop:ensure-directory-pathname "/tmp/")) + (result (opencortex::check-tangle-sync root))) + (when result + (is (eq :tangle-synced (opencortex::engineering-violation-rule result)))) + (uiop:delete-file-if-exists tmp-org) + (uiop:delete-file-if-exists tmp-lisp))) + +(test tangle-sync-passes-when-synced + "check-tangle-sync returns nil when .org is newer than .lisp" + (let ((tmp-org "/tmp/test-skill2.org") + (tmp-lisp "/tmp/test-skill2.lisp")) + (with-open-file (f tmp-lisp :direction :output) (write-line "(defun test () t)" f)) + (sleep 1) + (with-open-file (f tmp-org :direction :output) (write-line "* Test" f)) + (let* ((root (uiop:ensure-directory-pathname "/tmp/")) + (result (opencortex::check-tangle-sync root))) + (is (null result))) + (uiop:delete-file-if-exists tmp-org) + (uiop:delete-file-if-exists tmp-lisp))) #+end_src ** Blocking Gate (Hard Enforcement) @@ -252,7 +317,15 @@ These tests verify the enforcement logic. Run with: (harness-log "~a" (engineering-violation-message git-check)) (return-from engineering-standards-gate (list :type :log - :payload (list :text (engineering-violation-message git-check))))))) + :payload (list :text (engineering-violation-message git-check)))))) + + ;; BLOCKING: Tangle sync check - .lisp must not be newer than .org + (let ((tangle-check (check-tangle-sync *engineering-std-*project-root*))) + (when tangle-check + (harness-log "~a" (engineering-violation-message tangle-check)) + (return-from engineering-standards-gate + (list :type :log + :payload (list :text (engineering-violation-message tangle-check)))))))) action) #+end_src