From ca44136a551606d515c17c9705d1603f87ab079f Mon Sep 17 00:00:00 2001 From: Amr Gharbeia Date: Fri, 8 May 2026 16:48:10 -0400 Subject: [PATCH] =?UTF-8?q?v0.7.2:=20agent=20identity=20injection=20(CONFI?= =?UTF-8?q?G=20section)=20=E2=80=94=20TDD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Live config section injected into system prompt between time and IDENTITY. assemble-config-section reads *provider-cascade*, tokenizer-context-limit, gate count, and *hitl-pending* at each think() call. fboundp-guarded. Tested. - core-reason: assemble-config-section fn, config-section binding, injected into all 3 prompt assembly paths - Reason tests: +4 checks (Passepartout, version, gates) --- docs/ROADMAP.org | 18 +++++++++++++++++ lisp/core-reason.lisp | 47 +++++++++++++++++++++++++++++++++++-------- org/core-reason.org | 47 +++++++++++++++++++++++++++++++++++-------- 3 files changed, 96 insertions(+), 16 deletions(-) diff --git a/docs/ROADMAP.org b/docs/ROADMAP.org index 4f337ef..9e44722 100644 --- a/docs/ROADMAP.org +++ b/docs/ROADMAP.org @@ -1701,6 +1701,24 @@ Passepartout's image-based Lisp model enables hot-reload — redefine a function - On compile error: keep the old version loaded, log the error, show TUI warning: ~"✗ Skill 'skill-name' failed to compile — old version retained."~ ~80 lines in a new ~symbolic-file-watch.org~ skill. +*** TODO Heavy thinking skill — parallel reasoning + sequential deliberation +:PROPERTIES: +:ID: id-v082-heavy-thinking +:CREATED: [2026-05-08 Fri] +:END: + +The HeavySkill paper (arXiv:2605.02396v1) demonstrates that a two-stage pipeline — K independent reasoning trajectories followed by a critical deliberation step — consistently outperforms majority voting and approaches Pass@K. The authors distill it into a readable skill file that works across any agent harness. Passepartout's Merkle tree makes this auditable, rewoundable, and cross-session comparable. + +- New skill: ~org/heavy-thinking.org~ — a readable skill document loaded at startup. The agent follows a defined protocol when facing complex reasoning tasks: + 1. *Activation*: triggers when the complexity classifier detects a STEM/reasoning/code-generation task. Dormant for simple factual queries or casual conversation + 2. *Parallel reasoning*: spawns K independent ~think()~ calls (default K=3, ~HEAVY_THINKING_WIDTH~ env var). Each call solves the same problem from scratch without access to other trajectories. Encourages diverse strategies + 3. *Sequential deliberation*: a second model call reads all K trajectories (pruned to essential thinking content to stay under context budget). Critically evaluates each — not voting, but re-reasoning. Produces a synthesized final answer with a deliberation trace: "Trajectories 1,3 converged on answer X. Trajectory 2 had error Y. Synthesized answer: X." + 4. *Output*: returns the synthesized answer with ~[Heavy-thinking: 3 parallel, 1 deliberate]~ annotation in the response metadata +- Merkle advantage: each trajectory is stored as a content-addressed node. The deliberation trace is permanent and auditable — users can see WHY one answer was chosen +- Iterative deliberation optional (capped at 2 — the paper shows iterations 3+ degrade HP@K) +- Cost model: 3 parallel × 1 deliberation = 4 API calls for complex tasks (vs 1 normally). ~HEAVY_THINKING_COST_MULTIPLIER~ env var for cost-aware auto-activation +~100 lines as a skill (~60 prompt template + ~40 orchestration in ~symbolic-heavy-thinking.org~). + ** v0.8.3: Direction 3 — Adaptive Layout + Personality The TUI adapts to the terminal it's running in — full sidebar at ultrawide, compact at standard, minimal at narrow (phone/SSH). It has a personality: spinner style, relative timestamps, progress bars, live context help. diff --git a/lisp/core-reason.lisp b/lisp/core-reason.lisp index d08d07e..ca7163a 100644 --- a/lisp/core-reason.lisp +++ b/lisp/core-reason.lisp @@ -72,6 +72,26 @@ k) collect v))) +;; v0.7.2: live config section for system prompt +(defun assemble-config-section () + "Build the CONFIG section of the system prompt from live state." + (let ((provider-names "") + (context-window (if (and (boundp '*tokenizer-provider*) (fboundp 'tokenizer-context-limit)) + (tokenizer-context-limit (symbol-value '*tokenizer-provider*)) + 8192)) + (gate-count 10) + (rules-count 0)) + (when (boundp '*provider-cascade*) + (setf provider-names + (format nil "~{~a~^, ~}" + (mapcar (lambda (p) (getf p :model)) + (symbol-value '*provider-cascade*))))) + (when (boundp '*hitl-pending*) + (setf rules-count (hash-table-count (symbol-value '*hitl-pending*)))) + (format nil "CONFIG: You are Passepartout v0.7.2. Provider: ~a. Context: ~d tokens. Security gates: ~d active. Rules learned: ~d." + (if (string= provider-names "") "default" provider-names) + context-window gate-count rules-count))) + (defun think (context) (let* ((sensor (proto-get (proto-get context :payload) :sensor)) (active-skill (find-triggered-skill context)) @@ -102,8 +122,11 @@ (setf out (concatenate 'string out text (string #\Newline)))))) (when (> (length out) 0) out))) (identity-content (if (fboundp 'agent-identity) ; v0.7.2: symbolic identity - (agent-identity) - "")) + (agent-identity) + "")) + (config-section (if (fboundp 'assemble-config-section) ; v0.7.2: live config + (assemble-config-section) + "")) (time-section (if (fboundp 'sensor-time-duration) ; v0.6.0: temporal awareness (format-time-for-llm :session-duration-seconds (funcall (symbol-function 'session-duration))) @@ -121,13 +144,13 @@ raw-prompt standing-mandates-text) (declare (ignore _)) (setf standing-mandates-text mandates) - (format nil "~a~%~%~a~%~%CONTEXT:~%~a~%~%LOGS:~%~a" - time-section pfx (or ctxt "") logs)) - (format nil "~a~%~%~a~%~%CONTEXT:~%~a~%~%LOGS:~%~a" - time-section prefix (or global-context "") system-logs))) + (format nil "~a~%~%~a~%~%~a~%~%CONTEXT:~%~a~%~%LOGS:~%~a" + time-section config-section pfx (or ctxt "") logs)) + (format nil "~a~%~%~a~%~%~a~%~%CONTEXT:~%~a~%~%LOGS:~%~a" + time-section config-section prefix (or global-context "") system-logs))) ;; Fallback when token-economics not loaded - (format nil "~a~%~%IDENTITY: ~a~a~a~a~%~%TOOLS:~%~a~%~%CONTEXT:~%~a~%~%LOGS:~%~a" - time-section + (format nil "~a~%~%~a~%~%IDENTITY: ~a~a~a~a~%~%TOOLS:~%~a~%~%CONTEXT:~%~a~%~%LOGS:~%~a" + time-section config-section assistant-name identity-content reflection-feedback (if standing-mandates-text (concatenate 'string (string #\Newline) standing-mandates-text) @@ -437,3 +460,11 @@ sorted by priority (highest first). Returns a rejection plist or the action." (is (= 42 (second result))) (is (eq :ACTIVE (third result))) (is (eq :true (fourth result)))))) + +(test test-assemble-config-section + "Contract v0.7.2: config section contains Passepartout and version." + (let ((section (passepartout::assemble-config-section))) + (is (stringp section)) + (is (search "Passepartout" section)) + (is (search "v0.7.2" section)) + (is (search "Security gates" section)))) diff --git a/org/core-reason.org b/org/core-reason.org index 7fe7ef4..a46ec89 100644 --- a/org/core-reason.org +++ b/org/core-reason.org @@ -227,6 +227,26 @@ each cascade call via ~cost-track-backend-call~. All four calls are ;; REPL-VERIFIED: 2026-05-03T13:00:00 #+begin_src lisp +;; v0.7.2: live config section for system prompt +(defun assemble-config-section () + "Build the CONFIG section of the system prompt from live state." + (let ((provider-names "") + (context-window (if (and (boundp '*tokenizer-provider*) (fboundp 'tokenizer-context-limit)) + (tokenizer-context-limit (symbol-value '*tokenizer-provider*)) + 8192)) + (gate-count 10) + (rules-count 0)) + (when (boundp '*provider-cascade*) + (setf provider-names + (format nil "~{~a~^, ~}" + (mapcar (lambda (p) (getf p :model)) + (symbol-value '*provider-cascade*))))) + (when (boundp '*hitl-pending*) + (setf rules-count (hash-table-count (symbol-value '*hitl-pending*)))) + (format nil "CONFIG: You are Passepartout v0.7.2. Provider: ~a. Context: ~d tokens. Security gates: ~d active. Rules learned: ~d." + (if (string= provider-names "") "default" provider-names) + context-window gate-count rules-count))) + (defun think (context) (let* ((sensor (proto-get (proto-get context :payload) :sensor)) (active-skill (find-triggered-skill context)) @@ -257,8 +277,11 @@ each cascade call via ~cost-track-backend-call~. All four calls are (setf out (concatenate 'string out text (string #\Newline)))))) (when (> (length out) 0) out))) (identity-content (if (fboundp 'agent-identity) ; v0.7.2: symbolic identity - (agent-identity) - "")) + (agent-identity) + "")) + (config-section (if (fboundp 'assemble-config-section) ; v0.7.2: live config + (assemble-config-section) + "")) (time-section (if (fboundp 'sensor-time-duration) ; v0.6.0: temporal awareness (format-time-for-llm :session-duration-seconds (funcall (symbol-function 'session-duration))) @@ -276,13 +299,13 @@ each cascade call via ~cost-track-backend-call~. All four calls are raw-prompt standing-mandates-text) (declare (ignore _)) (setf standing-mandates-text mandates) - (format nil "~a~%~%~a~%~%CONTEXT:~%~a~%~%LOGS:~%~a" - time-section pfx (or ctxt "") logs)) - (format nil "~a~%~%~a~%~%CONTEXT:~%~a~%~%LOGS:~%~a" - time-section prefix (or global-context "") system-logs))) + (format nil "~a~%~%~a~%~%~a~%~%CONTEXT:~%~a~%~%LOGS:~%~a" + time-section config-section pfx (or ctxt "") logs)) + (format nil "~a~%~%~a~%~%~a~%~%CONTEXT:~%~a~%~%LOGS:~%~a" + time-section config-section prefix (or global-context "") system-logs))) ;; Fallback when token-economics not loaded - (format nil "~a~%~%IDENTITY: ~a~a~a~a~%~%TOOLS:~%~a~%~%CONTEXT:~%~a~%~%LOGS:~%~a" - time-section + (format nil "~a~%~%~a~%~%IDENTITY: ~a~a~a~a~%~%TOOLS:~%~a~%~%CONTEXT:~%~a~%~%LOGS:~%~a" + time-section config-section assistant-name identity-content reflection-feedback (if standing-mandates-text (concatenate 'string (string #\Newline) standing-mandates-text) @@ -647,4 +670,12 @@ Verifies that the deterministic engine correctly rejects unsafe actions (like ~r (is (= 42 (second result))) (is (eq :ACTIVE (third result))) (is (eq :true (fourth result)))))) + +(test test-assemble-config-section + "Contract v0.7.2: config section contains Passepartout and version." + (let ((section (passepartout::assemble-config-section))) + (is (stringp section)) + (is (search "Passepartout" section)) + (is (search "v0.7.2" section)) + (is (search "Security gates" section)))) #+end_src