Files
passepartout/skills/org-skill-policy.org
Amr Gharbeia 2e8e79a193
Some checks failed
Deploy-Agent-V15-Stdin / JOB-V15-STDIN (push) Failing after 2s
fix(v0.2.0): finalize structural integrity and clean boot
- Fixed memory.org source blocks to ensure persistence functions are tangled.
- Improved extract-tangle-target to handle complex Elisp expressions.
- Corrected opencortex.sh initialization paths to prevent setup loops.
- Reordered variable definitions in policy and standards skills to eliminate forward-reference warnings.
2026-04-27 18:54:18 -04:00

22 KiB

SKILL: System Policy

Overview

The Policy Skill is the constitutional law of OpenCortex. It defines the non-negotiable constraints that every agentic action must satisfy before reaching the actuator layer.

Unlike a passive manifesto, Policy is enforced by the Deterministic Engine. The LLM proposes; Policy verifies. If an action violates an invariant, Policy blocks it and returns an auditable explanation.

Why a Constitutional Approach?**

AIs fail in two ways:

  1. Underconstraint - They do harmful things because no one told them not to
  2. Overconstraint - They refuse to act because every action triggers a warning

OpenCortex solves this with a hierarchy of invariants:

  • Some invariants block absolutely (Transparency, Modularity)
  • Others warn but don't block (Autonomy debt, Sustainability debt)

This allows the agent to be both safe and usable.

The Philosophical Foundation

OpenCortex is not just software—it's a personal operating system designed for the 100-year horizon. The Memex must outlive:

  • Cloud services that get discontinued
  • Programming languages that fall out of fashion
  • Hardware platforms that become obsolete

Therefore, Policy encodes not just rules, but values:

  • Radical Transparency → Auditability is non-negotiable
  • Autonomy → Dependency on proprietary systems is debt, not strength
  • Zero-Bloat → Complexity is cost, not feature
  • Modularity → The kernel must survive even if all skills fail
  • Mentorship → Teaching is the highest form of assistance
  • Sustainability → Offline capability is a feature, not a limitation

Package Context

Every skill executes within its own jailed package namespace, inheriting core harness symbols while maintaining isolation from other skills.

(in-package :opencortex)

Global Policy Configuration

(defvar *policy-invariant-priorities*
  '((:transparency . 500)
    (:autonomy . 400)
    (:bloat . 300)
    (:modularity . 250)
    (:mentorship . 200)
    (:sustainability . 100))
  "Priority alist for policy invariant conflict resolution.
Higher numbers take precedence.

When two invariants conflict, the higher priority wins.
Example: Modularity (250) takes precedence over Mentorship (200),
meaning a change that would fatten the harness is blocked
even if it would be educational.")

(defvar *proprietary-domain-watchlist*
  '("googleapis.com" "api.openai.com" "anthropic.com" "api.groq.com" "openrouter.ai")
  "Domains representing centralized, proprietary control.

  Actions targeting these are logged as autonomy debt, not hard-blocked.
  This is because tactical gateway usage (Telegram, Signal, OpenRouter)
  is permitted under the strategic mandate for autonomy.

  Strategic goal: Replace all proprietary APIs with local alternatives.
  Tactical reality: Use what's available while building toward that goal.")

(defvar *policy-max-skill-size-chars* 50000
  "Maximum recommended size for a skill file tangled from an Org note.

  This is a soft limit—the check warns but does not block.
  A large, well-documented skill is acceptable; a small, poorly-documented
  one that adds unnecessary complexity is not.")

(defvar *modularity-protected-paths*
  '("harness/" "opencortex.asd")
  "Paths that constitute the unbreakable core of the system.

  Any action targeting these paths must include a :modularity-justification
  explaining why the change cannot be implemented as a skill.

  The Thin Harness principle: What belongs in the harness?
  - Core signal processing (Perceive-Reason-Act loop)
  - Memory and persistence primitives
  - Protocol definition and validation
  - Skills register and dispatch

  What belongs in skills?
  - Policy and security
  - LLM integration
  - Domain-specific functionality
  - New actuators")

(defvar *mentorship-required-actions*
  '(:create-skill :eval :modify-file :write-file :replace
    :rename-file :delete-file :shell :create-note)
  "Actions that trigger the Mentorship invariant.

  These are high-impact actions that should come with explanations
  not just for the user, but for future debugging and maintenance.")

(defvar *cloud-only-backends* '(:openrouter :openai :anthropic :groq :gemini-api)
  "Backends requiring internet connection and external infrastructure.

  These are acceptable as fallbacks when local inference is unavailable,
  but should be logged as sustainability debt for tracking purposes.")

The Override Hierarchy

When two invariants conflict, resolution follows a strict priority order. This prevents the agent from freezing on ethical edge cases.

Priority Invariant Philosophy
500 Transparency If you can't explain it, you can't do it
400 Autonomy Independence from proprietary control is the primary goal
300 Zero-Bloat Complexity must be earned, not imported
250 Modularity Complexity belongs at the edges, not the core
200 Mentorship Teaching increases capability; doing removes it
100 Sustainability Offline capability today enables 100-year survival

The Core Invariants

1. Radical Transparency

The maxim: "If you can't explain it, you can't do it."

The agent's Thought Stream must be fully auditable. Hidden reasoning or obfuscated logic violates the system's core purpose: a transparent, comprehensible AI assistant.

At the gate:

  • Every action must be a valid, inspectable data structure
  • Every user-facing action must carry an `:explanation`
  • Log messages must include the triggering invariant
(defun policy-check-transparency (action context)
(defun policy-check-transparency (action context)
  "Ensures the action is inspectable and user-facing actions carry an explanation.

  TRANSPARENCY CHECK:
  1. Action must be a valid plist (not opaque data)
  2. User-facing actions (:cli, :tui, :emacs) must include :explanation
  3. Heartbeat and handshake messages are exempt (they're system status)

  Returns the action if clean, or a blocking LOG event if violated."

  (declare (ignore context))

  ;; Check 1: Action must be a valid plist
  (unless (listp action)
    (return-from policy-check-transparency
      (list :type :LOG
            :payload (list :level :error
                           :text "POLICY [Transparency]: Action is not a valid plist. Rejected."))))

  (let* ((payload (getf action :payload))
         (target (or (getf action :target) (getf action :TARGET)))
         (explanation (or (getf payload :explanation)
                          (getf payload :EXPLANATION)
                          (getf payload :rationale)
                          (getf payload :RATIONALE))))

    ;; Check 2: User-facing actions require explanation
    (when (and (member target '(:cli :tui :emacs :EMACS :CLI :TUI))
               (not explanation)
               (not (member (getf payload :action)
                            '(:handshake :heartbeat :status-update))))
      (return-from policy-check-transparency
        (list :type :LOG
              :payload (list :level :error
                             :text "POLICY [Transparency]: User-facing action missing :explanation. Blocked."))))

    action))

2. Autonomy Above All

The maxim: "Every dependency is debt."

Every action should increase the user's independence from centralized, proprietary platforms. When the system uses a proprietary API, it's logged as "autonomy debt"—acceptable tactically, but flagged for eventual replacement.

(defun policy-scan-proprietary-references (action)
  "Scans ACTION text fields for proprietary domain references.

  Searches in:
  - :text and :TEXT in payload
  - :cmd and :CMD in payload
  - :cmd in args (for shell tool calls)

  Returns the first matched domain, or NIL if clean."

  (let* ((payload (getf action :payload))
         (text (or (getf payload :text) (getf payload :TEXT) ""))
         (cmd (or (getf payload :cmd)
                 (getf payload :CMD)
                 (when (equal (getf payload :tool) "shell")
                   (getf (getf payload :args) :cmd))
                 ""))
         (haystack (concatenate 'string text cmd)))

    (dolist (domain *proprietary-domain-watchlist* nil)
      (when (search domain haystack)
        (return domain)))))

(defun policy-check-autonomy (action context)
  "Flags actions that reference proprietary domains.

  Does NOT block the action—this is a warning, not a veto.
  The agent can use proprietary services tactically, but must
  be aware that each usage is a step away from full autonomy.

  Returns a warning LOG if proprietary reference detected,
  or the original action if clean."

  (declare (ignore context))

  (let ((domain (policy-scan-proprietary-references action)))

    (if domain
        (progn
          (harness-log "POLICY [Autonomy]: Detected proprietary reference '~a'. Flagged for replacement." domain)
          ;; Return a warning log but DO NOT block the action
          (list :type :LOG
                :payload (list :level :warn
                               :text (format nil "Autonomy Debt: Action references proprietary domain '~a'. Consider a local alternative." domain)
                               :original-action action)))

        action)))

3. Zero-Bloat Mandate

The maxim: "Complexity is cost, not feature."

The system harness must remain minimalist. "Just-in-case" code is a security vulnerability. Complexity must be earned through demonstrated need, not anticipation of future use.

(defun policy-check-bloat (action context)
  "Warns if a :create-skill action exceeds the bloat threshold.

  Size alone is not proof of complexity—a 50KB skill that's well-designed
  is better than a 5KB skill that's spaghetti. This check flags for review,
  not automatic rejection.

  Returns a warning LOG if threshold exceeded, or original action if clean."

  (declare (ignore context))

  (let* ((payload (getf action :payload))
         (act (getf payload :action))
         (content (getf payload :content)))

    (when (and (eq act :create-skill)
               (stringp content)
               (> (length content) *policy-max-skill-size-chars*))

      (harness-log "POLICY [Bloat]: Proposed skill is ~a chars. Exceeds ~a char threshold."
                   (length content) *policy-max-skill-size-chars*)

      (return-from policy-check-bloat
        (list :type :LOG
              :payload (list :level :warn
                             :text (format nil "Bloat Warning: Proposed skill (~a chars) exceeds ~a char threshold. Review for earned complexity."
                                          (length content) *policy-max-skill-size-chars*)
                             :original-action action))))

  action))

4. Modularity

The maxim: "The kernel must survive even if all skills fail."

Every system should be decomposed into a minimal, unbreakable core and hot-swappable capabilities. Complexity must live at the edges, never in the kernel.

This is the most important invariant for system stability. If the harness grows fat, it becomes:

  • Harder to verify for security
  • Harder to debug when things go wrong
  • Harder to maintain across versions
(defun policy-check-modularity (action context)
  "Blocks modifications to the system's protected core unless justified.

  MODULARITY CHECK:
  1. If the action targets a protected path
  2. And no :modularity-justification is provided
  3. Then block with an explanation

  The justification should explain WHY the change cannot be a skill.
  Common valid reasons:
  - The change fixes a bug in the harness itself
  - The change adds a primitive that skills cannot implement
  - The change is required for security hardening

  Invalid reasons:
  - 'It's easier to modify the harness'
  - 'Skills are too slow'
  - 'I want to keep it all in one place'"

  (declare (ignore context))

  (let* ((payload (getf action :payload))
         (target-file (or (getf payload :file)
                         (getf payload :filename)))
         (justification (or (getf payload :modularity-justification)
                            (getf payload :MODULARITY-JUSTIFICATION))))

    (when (and target-file
               (some (lambda (path) (search path target-file))
                    *modularity-protected-paths*)
               (not justification))

      (return-from policy-check-modularity
        (list :type :LOG
              :payload (list :level :error
                             :text "POLICY [Modularity]: Modification to protected core path blocked. Provide :modularity-justification explaining why this cannot be a skill."
                             :blocked-path target-file))))

  action))

5. Technical Mastery & Mentorship

The maxim: "Teaching is the highest form of assistance."

The agent's goal is not to "do it for the user," but to "empower the user." Every autonomous action must be explained at a level that increases the user's technical understanding.

(defun policy-check-mentorship (action context)
  "Blocks high-impact actions that lack a mentorship note.

  MENTORSHIP CHECK:
  1. If the action is in *mentorship-required-actions*
  2. Or if the action calls shell/eval/repair-file tools
  3. Then require :mentorship-note explaining what and why

  The mentorship note should be:
  - Concise (1-2 sentences)
  - Educational (explain the principle, not just the action)
  - Actionable (help the user understand the outcome)"

  (declare (ignore context))

  (let* ((payload (getf action :payload))
         (act (or (getf payload :action)
                 (getf action :action)))
         (note (or (getf payload :mentorship-note)
                  (getf payload :MENTORSHIP-NOTE)))
         (target (or (getf action :target)
                    (getf action :TARGET)))
         (tool (when (eq target :tool)
                (getf payload :tool))))

    (when (or (member act *mentorship-required-actions*)
              (member tool '("shell" "eval" "repair-file")))

      (unless note
        (return-from policy-check-mentorship
          (list :type :LOG
                :payload (list :level :error
                               :text "POLICY [Mentorship]: High-impact action missing :mentorship-note. Explain what you are doing and why. Blocked.")))))

  action))

6. Long-Term Sustainability

The maxim: "Build for the 100-year horizon."

The Memex should be functional even when:

  • Internet is unavailable
  • Cloud services are discontinued
  • Hardware platforms change

This means preferring local, energy-efficient architectures over cloud-dependent ones.

(defun policy-check-sustainability (action context)
  "Logs sustainability debt when action relies on cloud-only infrastructure.

  Does NOT block—this is informational, not prohibitive.
  Cloud usage is acceptable tactically (when local models fail),
  but every cloud usage should be a conscious decision, not a default."

  (let* ((payload (getf context :payload))
         (backend (getf payload :backend))
         (provider (getf payload :provider)))

    (when (or (member backend *cloud-only-backends*)
              (member provider *cloud-only-backends*))

      (harness-log "POLICY [Sustainability]: Cloud provider '~a' used. Logged as sustainability debt."
                   (or backend provider))

      (return-from policy-check-sustainability
        (list :type :LOG
              :payload (list :level :warn
                             :text (format nil "Sustainability Debt: Reliance on cloud provider '~a'. Consider Ollama or local inference."
                                          (or backend provider))))))

  action)))

Policy Explanation Engine

When the policy gate blocks or modifies an action, it must tell the user why. This creates an auditable log of every policy decision.

(defun policy-explain (invariant-key message &optional original-action)
  "Formats a policy decision into an auditable explanation plist.

  INVARIANT-KEY is one of:
    :transparency, :autonomy, :bloat, :modularity, :mentorship, :sustainability

  MESSAGE is a human-readable string explaining the decision.

  ORIGINAL-ACTION is the action that was blocked or modified.

  Returns a REQUEST plist addressed to the original source,
  containing the explanation and original action for transparency."

  (list :type :REQUEST
        :target (or (ignore-errors
                    (getf (getf original-action :meta) :source))
                   :cli)
        :payload (list :action :message
                       :text (format nil "[POLICY ~a] ~a" invariant-key message)
                       :explanation (format nil "Invariant: ~a | Rationale: ~a"
                                            invariant-key message)
                       :original-action original-action)))

The Policy Gate

Running Invariant Checks

(defun policy-run-invariant-checks (action context)
  "Runs all invariant checks in priority order.

  Priority order (from *policy-invariant-priorities*):
  1. Transparency (500) - blocks non-transparent actions
  2. Autonomy (400) - warns on proprietary dependencies
  3. Bloat (300) - warns on oversized skills
  4. Modularity (250) - blocks unprotected core modifications
  5. Mentorship (200) - blocks unexplained high-impact actions
  6. Sustainability (100) - warns on cloud dependencies

  Returns:
  - The final action (possibly modified by checks)
  - A blocking LOG event (if any check returned :error level)
  - A warning wrapper (if checks returned :warn level but no blocks)"

  (let ((checks '(policy-check-transparency
                  policy-check-autonomy
                  policy-check-bloat
                  policy-check-modularity
                  policy-check-mentorship
                  policy-check-sustainability)))

    (dolist (check-fn checks action)
      (let ((result (funcall check-fn action context)))

        ;; If the check returned a LOG/EVENT, interpret it
        (when (and (listp result)
                   (member (getf result :type) '(:LOG :EVENT)))

          (let ((level (getf (getf result :payload) :level)))

            (cond
              ;; Hard block: error level stops processing immediately
              ((eq level :error)
               (return-from policy-run-invariant-checks result))

              ;; Soft warning: log but continue with original action
              (t
               (harness-log "~a" (getf (getf result :payload) :text))))))))))
(defun policy-find-engineering-standards-gate ()
  "Searches for the Engineering Standards gate across known jailed package names.

  The standards skill may be in opencortex-contrib submodule,
  so we search multiple possible package names with graceful fallback.

  Returns the function symbol, or NIL if unavailable."

  (dolist (pkg-name '(:opencortex.skills.org-skill-engineering-standards
                      :opencortex.skills.org-skill-engineering
                      :opencortex.skills.engineering-standards)
           nil)

    (let ((pkg (find-package pkg-name)))
      (when pkg
        (let ((sym (find-symbol "ENGINEERING-STANDARDS-GATE" pkg)))
          (when (and sym (fboundp sym))
            (return (symbol-function sym))))))))

Main Policy Gate

(defun policy-deterministic-gate (action context)
  "The main policy gate entry point.

  This function is registered as the deterministic-fn for the policy skill.
  It runs invariant checks, then delegates to engineering standards if loaded.

  IMPORTANT: Never returns NIL silently. Always returns either:
  - An action (possibly modified)
  - A blocking LOG event with explanation
  - A warning wrapper with explanation"

  ;; Step 1: Run invariant checks
  (let ((current-action (policy-run-invariant-checks action context)))

    ;; Step 2: If an invariant blocked the action, stop here
    (when (and (listp current-action)
               (member (getf current-action :type) '(:LOG :EVENT))
               (eq (getf (getf current-action :payload) :level) :error))

      (return-from policy-deterministic-gate current-action))

    ;; Step 3: Delegate to Engineering Standards if loaded
    (let ((eng-gate (policy-find-engineering-standards-gate)))
      (when eng-gate
        (setf current-action (funcall eng-gate current-action context))))

    current-action))

Skill Registration

(defskill :skill-policy
  :priority 500
  :trigger (lambda (ctx) (declare (ignore ctx)) t)
  :probabilistic nil
  :deterministic #'policy-deterministic-gate)

Quick Reference

Invariant Quick Reference

Invariant Blocks? Trigger
Transparency Yes Missing `:explanation` on user-facing actions
Autonomy No Action references proprietary domain
Bloat No Skill file exceeds 50KB
Modularity Yes Modification to `harness/` without justification
Mentorship Yes High-impact action without `:mentorship-note`
Sustainability No Action uses cloud-only provider

Required Fields by Action Type

Action Required Field Purpose
User message `:explanation` Transparency
Core modification `:modularity-justification` Modularity
Skill creation `:mentorship-note` Mentorship
File write `:mentorship-note` Mentorship

See Also