feat: memory scope segmentation — wire context scope into perceive gate
Some checks failed
Deploy (Gitea) / deploy (push) Has been cancelled
Some checks failed
Deploy (Gitea) / deploy (push) Has been cancelled
Adds *scope-resolver* hook in core-loop-perceive that the context-manager skill sets at load time. The perceive gate now passes the active scope to ingest-ast, tagging all ingested objects with the current context scope. Implementation: - core-loop-perceive: *scope-resolver* defvar (default nil → :memex), two ingest-ast calls now pass (if *scope-resolver* (funcall it) :memex) - core-defpackage: export *scope-resolver* and context-query - system-context-manager: auto-init sets *scope-resolver* to #'current-scope This completes the Memory Scope Segmentation feature: all three scopes (:memex, :session, :project) are supported, scope-aware retrieval (context-query :scope / context-scoped-query) was already implemented, and ingested objects now correctly carry the active scope.
This commit is contained in:
@@ -56,6 +56,7 @@
|
|||||||
#:context-get-skill-telemetry
|
#:context-get-skill-telemetry
|
||||||
#:telemetry-track
|
#:telemetry-track
|
||||||
#:context-assemble-global-awareness
|
#:context-assemble-global-awareness
|
||||||
|
#:context-query
|
||||||
#:process-signal
|
#:process-signal
|
||||||
#:loop-process
|
#:loop-process
|
||||||
#:perceive-gate
|
#:perceive-gate
|
||||||
@@ -81,6 +82,7 @@
|
|||||||
#:validate-lisp-syntax
|
#:validate-lisp-syntax
|
||||||
#:defskill
|
#:defskill
|
||||||
#:*skill-registry*
|
#:*skill-registry*
|
||||||
|
#:*scope-resolver*
|
||||||
#:skill
|
#:skill
|
||||||
#:skill-name
|
#:skill-name
|
||||||
#:skill-priority
|
#:skill-priority
|
||||||
|
|||||||
@@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
(defvar *loop-interrupt* nil)
|
(defvar *loop-interrupt* nil)
|
||||||
|
|
||||||
|
(defvar *scope-resolver* nil
|
||||||
|
"If set, function returning current scope keyword. Used by perceive gate.")
|
||||||
|
|
||||||
(defvar *loop-async-sensors* '(:chat-message :delegation :user-command)
|
(defvar *loop-async-sensors* '(:chat-message :delegation :user-command)
|
||||||
"Sensors that are processed in dedicated threads.")
|
"Sensors that are processed in dedicated threads.")
|
||||||
|
|
||||||
@@ -79,13 +82,13 @@ FN receives (signal) and returns T if consumed, nil to continue."
|
|||||||
(let ((ast (getf payload :ast)))
|
(let ((ast (getf payload :ast)))
|
||||||
(when ast
|
(when ast
|
||||||
(snapshot-memory)
|
(snapshot-memory)
|
||||||
(ingest-ast ast))))
|
(ingest-ast ast :scope (if *scope-resolver* (funcall *scope-resolver*) :memex)))))
|
||||||
(:point-update
|
(:point-update
|
||||||
(let ((element (getf payload :element)))
|
(let ((element (getf payload :element)))
|
||||||
(when element
|
(when element
|
||||||
(snapshot-memory)
|
(snapshot-memory)
|
||||||
(setf *loop-focus-id* (getf element :id))
|
(setf *loop-focus-id* (getf element :id))
|
||||||
(ingest-ast element))))
|
(ingest-ast element :scope (if *scope-resolver* (funcall *scope-resolver*) :memex)))))
|
||||||
(:interrupt
|
(:interrupt
|
||||||
(setf *loop-interrupt* t))
|
(setf *loop-interrupt* t))
|
||||||
;; HITL: re-injected approved action from dispatcher-approvals-process
|
;; HITL: re-injected approved action from dispatcher-approvals-process
|
||||||
|
|||||||
@@ -116,3 +116,6 @@ until stack is empty or :memex context is reached."
|
|||||||
(when (> (context-stack-depth) 0)
|
(when (> (context-stack-depth) 0)
|
||||||
nil))
|
nil))
|
||||||
nil))
|
nil))
|
||||||
|
|
||||||
|
(when (boundp '*scope-resolver*)
|
||||||
|
(setf *scope-resolver* #'current-scope))
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ The package definition. All public symbols are exported here.
|
|||||||
#:context-get-skill-telemetry
|
#:context-get-skill-telemetry
|
||||||
#:telemetry-track
|
#:telemetry-track
|
||||||
#:context-assemble-global-awareness
|
#:context-assemble-global-awareness
|
||||||
|
#:context-query
|
||||||
#:process-signal
|
#:process-signal
|
||||||
#:loop-process
|
#:loop-process
|
||||||
#:perceive-gate
|
#:perceive-gate
|
||||||
@@ -106,6 +107,7 @@ The package definition. All public symbols are exported here.
|
|||||||
#:validate-lisp-syntax
|
#:validate-lisp-syntax
|
||||||
#:defskill
|
#:defskill
|
||||||
#:*skill-registry*
|
#:*skill-registry*
|
||||||
|
#:*scope-resolver*
|
||||||
#:skill
|
#:skill
|
||||||
#:skill-name
|
#:skill-name
|
||||||
#:skill-priority
|
#:skill-priority
|
||||||
|
|||||||
@@ -43,6 +43,19 @@ A global interrupt flag that can be set by any signal. When set, the metabolic l
|
|||||||
(defvar *loop-interrupt* nil)
|
(defvar *loop-interrupt* nil)
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
** Scope Resolver
|
||||||
|
|
||||||
|
A hook for the context-manager skill to register its ~current-scope~
|
||||||
|
function. When set, the perceive gate passes the current context scope
|
||||||
|
to ~ingest-ast~ so ingested objects are tagged and queryable by scope.
|
||||||
|
Defaults to ~nil~ meaning all objects are ingested as ~:memex~.
|
||||||
|
|
||||||
|
;; REPL-VERIFIED: 2026-05-03T14:00:00
|
||||||
|
#+begin_src lisp
|
||||||
|
(defvar *scope-resolver* nil
|
||||||
|
"If set, function returning current scope keyword. Used by perceive gate.")
|
||||||
|
#+end_src
|
||||||
|
|
||||||
** Sensor Configuration
|
** Sensor Configuration
|
||||||
|
|
||||||
~*loop-async-sensors*~ lists the sensor types that should be processed in their own threads. Currently, ~:chat-message~, ~:delegation~, and ~:user-command~ are async because they don't block the main reasoning loop — the agent can process a Telegram message while waiting for the user's next input.
|
~*loop-async-sensors*~ lists the sensor types that should be processed in their own threads. Currently, ~:chat-message~, ~:delegation~, and ~:user-command~ are async because they don't block the main reasoning loop — the agent can process a Telegram message while waiting for the user's next input.
|
||||||
@@ -186,13 +199,13 @@ The main perceive pipeline stage.
|
|||||||
(let ((ast (getf payload :ast)))
|
(let ((ast (getf payload :ast)))
|
||||||
(when ast
|
(when ast
|
||||||
(snapshot-memory)
|
(snapshot-memory)
|
||||||
(ingest-ast ast))))
|
(ingest-ast ast :scope (if *scope-resolver* (funcall *scope-resolver*) :memex)))))
|
||||||
(:point-update
|
(:point-update
|
||||||
(let ((element (getf payload :element)))
|
(let ((element (getf payload :element)))
|
||||||
(when element
|
(when element
|
||||||
(snapshot-memory)
|
(snapshot-memory)
|
||||||
(setf *loop-focus-id* (getf element :id))
|
(setf *loop-focus-id* (getf element :id))
|
||||||
(ingest-ast element))))
|
(ingest-ast element :scope (if *scope-resolver* (funcall *scope-resolver*) :memex)))))
|
||||||
(:interrupt
|
(:interrupt
|
||||||
(setf *loop-interrupt* t))
|
(setf *loop-interrupt* t))
|
||||||
;; HITL: re-injected approved action from dispatcher-approvals-process
|
;; HITL: re-injected approved action from dispatcher-approvals-process
|
||||||
|
|||||||
@@ -223,3 +223,13 @@ until stack is empty or :memex context is reached."
|
|||||||
nil))
|
nil))
|
||||||
nil))
|
nil))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
** Auto-Init: Wire Scope Resolver
|
||||||
|
|
||||||
|
Registers ~current-scope~ into the core ~*scope-resolver*~ hook so the
|
||||||
|
perceive gate tags ingested objects with the active context scope.
|
||||||
|
|
||||||
|
#+begin_src lisp
|
||||||
|
(when (boundp '*scope-resolver*)
|
||||||
|
(setf *scope-resolver* #'current-scope))
|
||||||
|
#+end_src
|
||||||
Reference in New Issue
Block a user