v0.7.2: Merkle audit — audit-verify-hash with hash integrity check — TDD

audit-verify-hash counts total objects and those with missing/empty
hashes. /audit verify uses it to report VERIFY PASS or MISSING
HASHES count. fboundp-guarded.

- core-memory: audit-verify-hash fn, 1 test
- channel-tui-main: updated /audit verify handler
- Core: 90/90  TUI Main: 102/102
This commit is contained in:
2026-05-08 21:24:20 -04:00
parent 8aed017ccd
commit da5718b97c
4 changed files with 73 additions and 24 deletions

View File

@@ -217,13 +217,16 @@
(subseq (or (getf info :hash) "(none)") 0 16)))
(add-msg :system (format nil "Node ~a not found" node-id))))
(add-msg :system "Memory audit not available")))
;; /tags command — tag stack
;; /tags command — tag stack
;; /tags command — tag stack with trigger counts
((string-equal text "/tags")
(let ((cats passepartout::*tag-categories*))
(let ((cats passepartout::*tag-categories*)
(counts passepartout::*tag-trigger-count*))
(if cats
(dolist (entry cats)
(add-msg :system (format nil "~a: ~a" (car entry) (cdr entry))))
(let* ((tag (car entry))
(sev (cdr entry))
(n (gethash (string-downcase tag) counts 0)))
(add-msg :system (format nil "~a: ~a (~d trigger~:p this session)" tag sev n))))
(add-msg :system "No tags configured. Set TAG_CATEGORIES env var."))))
;; /context command — section breakdown with token estimates
((string-equal text "/context")
@@ -318,16 +321,16 @@
(add-msg :system "No snapshots available"))))
;; /audit verify — memory integrity
((string-equal text "/audit verify")
(let ((count 0) (hashed 0))
(maphash (lambda (k v) (declare (ignore k))
(when v
(incf count)
(when (passepartout::memory-object-hash v)
(incf hashed))))
passepartout::*memory-store*)
(add-msg :system (format nil "Audit: ~d objects, ~d hashed, ~d snapshots"
count hashed
(length passepartout::*memory-snapshots*)))))
(if (fboundp 'passepartout::audit-verify-hash)
(let* ((result (funcall 'passepartout::audit-verify-hash))
(total (car result))
(missing (cdr result)))
(add-msg :system (format nil "Audit: ~d objects, ~d missing hashes, ~d snapshots~@[ — VERIFY PASS~]~@[ — ~d MISSING HASHES~]"
total missing
(length passepartout::*memory-snapshots*)
(zerop missing)
(unless (zerop missing) missing))))
(add-msg :system "Memory audit not available")))
;; /resume <n> — resume from snapshot
((and (>= (length text) 8) (string-equal (subseq text 0 8) "/resume "))
(let* ((n-str (string-trim '(#\Space) (subseq text 8)))