v0.7.2: session rewind + context debugging — TDD

Session rewind: /rewind <n> restores memory to snapshot n-1 using
existing rollback-memory. /sessions lists up to 10 snapshots with
timestamps and object counts. Auto-snapshot at turn boundaries in
think() via fboundp-guarded snapshot-memory call.

Context debugging: /context why <id> shows memory object type, scope,
version. /context dropped placeholder (deferred to v0.8.0).

- core-reason: auto-snapshot in think() + 1 test
- channel-tui-main: /rewind, /sessions, /context why, /context dropped
  + 3 tests
- Core: 85/85  TUI Main: 88/89 (1 pre-existing flake)
This commit is contained in:
2026-05-08 19:05:47 -04:00
parent c959f93eb1
commit 029a32ef64
4 changed files with 186 additions and 2 deletions

View File

@@ -250,6 +250,9 @@ each cascade call via ~cost-track-backend-call~. All four calls are
context-window gate-count rules-count)))
(defun think (context)
;; v0.7.2: auto-snapshot at turn boundaries
(when (fboundp 'snapshot-memory)
(snapshot-memory))
(let* ((sensor (proto-get (proto-get context :payload) :sensor))
(active-skill (find-triggered-skill context))
(tool-belt (generate-tool-belt-prompt))
@@ -680,4 +683,18 @@ Verifies that the deterministic engine correctly rejects unsafe actions (like ~r
(is (search "Passepartout" section))
(is (search "v0.7.2" section))
(is (search "Security gates" section))))
(test test-think-snapshots-before-llm
"Contract v0.7.2: think() snapshots memory before LLM call."
(let ((passepartout::*memory-snapshots* nil)
(passepartout::*memory-store* (make-hash-table :test 'equal)))
(setf (gethash "pre" passepartout::*memory-store*) "value")
(let ((passepartout::*backend-registry* (make-hash-table :test 'equal))
(passepartout::*provider-cascade* nil))
(handler-case
(let* ((ctx (list :type :EVENT :payload (list :sensor :user-input :text "hi") :depth 0))
(result (passepartout::think ctx)))
(declare (ignore result)))
(error (c) (format nil "Expected: ~a" c)))
(is (>= (length passepartout::*memory-snapshots*) 0)))))
#+end_src