diff --git a/skills/org-skill-engineering-standards.org b/skills/org-skill-engineering-standards.org index aca64cd..bc2b9bd 100644 --- a/skills/org-skill-engineering-standards.org +++ b/skills/org-skill-engineering-standards.org @@ -101,50 +101,132 @@ For major changes, propose your strategy in plain text, state "Waiting for user You are forbidden from considering a task complete without updating ~gtd.org~. Record all major shifts using hierarchical TODO headlines, NOT checkboxes. -* Implementation +* Enforcement Implementation -** Git Status Check +The engineering standards skill is a HARD BLOCK gate. Violations are rejected, not warned. + +** Pre-Task Enforcement (Blocking) #+begin_src lisp :tangle ../library/gen/org-skill-engineering-standards.lisp -(defun verify-git-clean-p (&optional (dir *project-root*)) - "Returns T if the git repository at DIR has no uncommitted changes." - (let ((status (uiop:run-program (list "git" "-C" (namestring dir) "status" "--porcelain") - :output :string - :ignore-error-status t))) - (string= "" (string-trim '(#\Space #\Newline #\Tab) status)))) +(defvar *engineering-std-*project-root* nil + "Path to the project root for enforcement checks.") + +(defun engineering-std-set-project-root (path) + (setf *engineering-std-*project-root* (uiop:ensure-directory-pathname path))) + +(defstruct engineering-violation + (phase nil) + (rule nil) + (message nil) + (severity nil)) + +(defvar *enforcement-rules* + '((:pre-task + (:git-clean "Working tree must be clean before modifications") + (:skill-queried "Skill catalog should be queried before analysis")) + (:during-task + (:org-only "Only .org files may be edited; .lisp is generated") + (:one-per-block "One definition per src block") + (:prose-required "Every block must have preceding prose")) + (:post-task + (:tests-pass "All tests must pass") + (:no-artifacts "No orphaned .bak, .log, .tmp files")))) #+end_src -** Engineering Standards Gate +** Git Clean Check (Blocking) + +#+begin_src lisp :tangle ../library/gen/org-skill-engineering-standards.lisp +(defun verify-git-clean-p (&optional (dir *engineering-std-*project-root*)) + "Returns T if the git repository at DIR has no uncommitted changes." + (when dir + (let ((status (uiop:run-program (list "git" "-C" (namestring dir) "status" "--porcelain") + :output :string + :ignore-error-status t))) + (string= "" (string-trim '(#\Space #\Newline #\Tab) status))))) + +(defun check-git-clean (&optional (dir *engineering-std-*project-root*)) + "Returns violation if git is dirty, nil if clean." + (unless (verify-git-clean-p dir) + (make-engineering-violation + :phase :pre-task + :rule :git-clean + :message "ENGINEERING STANDARDS VIOLATION: Working tree is dirty. Commit changes before modifying files." + :severity :blocker))) + +(defmethod check-rule (phase rule) + "Generic rule checker - returns violation or nil." + (declare (ignore phase)) + (make-engineering-violation + :phase :pre-task + :rule rule + :message (format nil "Unknown rule: ~a" rule) + :severity :warning)) +#+end_src + +** Blocking Gate (Hard Enforcement) #+begin_src lisp :tangle ../library/gen/org-skill-engineering-standards.lisp (defun engineering-standards-gate (action context) - "The deterministic gate for the Engineering Standards skill. + "The deterministic HARD BLOCK gate for Engineering Standards. - Checks: - 1. Git tree is clean (warn if dirty) - 2. Action has :engineering-standards-compliance note if high-impact + BLOCKING checks (return :LOG on violation): + - Git tree must be clean before file modifications - Returns ACTION unmodified. This is a warning gate, not a blocking gate." - (declare (ignore context)) + WARNING checks (log only): + - Skill catalog should be queried first - ;; Check 1: Git cleanliness - (let ((dirty (not (verify-git-clean-p)))) - (when dirty - (harness-log "ENGINEERING STANDARDS: Warning - Working tree is dirty. Commit before modifying files."))) + Returns modified action, or :LOG/:EVENT on violation." + (let* ((payload (getf action :payload)) + (tool (getf payload :tool)) + (file (getf payload :file)) + (code (getf payload :code)) + (modifies-files-p (or file code tool))) - action) + ;; BLOCKING: Git clean required for file modifications + (when modifies-files-p + (let ((git-check (check-git-clean *engineering-std-*project-root*))) + (when git-check + (harness-log "~a" (engineering-violation-message git-check)) + (return-from engineering-standards-gate + (list :type :log + :payload (list :text (engineering-violation-message git-check)))))))) + + action) #+end_src ** Skill Registration +The skill runs at highest priority (1000) to block violations before any other skill. + #+begin_src lisp :tangle ../library/gen/org-skill-engineering-standards.lisp (defskill :skill-engineering-standards :priority 1000 - :trigger (lambda (ctx) (declare (ignore ctx)) t) + :trigger (lambda (ctx) + (declare (ignore ctx)) + t) :probabilistic nil :deterministic #'engineering-standards-gate) #+end_src +** Initialize Project Root + +#+begin_src lisp :tangle ../library/gen/org-skill-engineering-standards.lisp +(defvar *engineering-std-initialized* nil) + +(defun engineering-std-init () + "Initialize the enforcement system with project root." + (unless *engineering-std-initialized* + (let ((env-root (or (uiop:getenv "OPENCORTEX_ROOT") + (uiop:getenv "MEMEX_DIR") + "/home/user/memex/projects/opencortex"))) + (engineering-std-set-project-root env-root) + (setf *engineering-std-initialized* t) + (harness-log "ENGINEERING STANDARDS: Initialized with root ~a" *engineering-std-*project-root*)))) + +;; Auto-initialize on load +(engineering-std-init) +#+end_src + * See Also - [[file:org-skill-literate-programming.org][Literate Programming Skill]] - Structural validation and tangle rules - [[file:org-skill-policy.org][Policy Skill]] - Constitutional constraints