From c1a5c736ec329967a6c063eddd94b0accd8d9773 Mon Sep 17 00:00:00 2001 From: Markus Fritsche Date: Wed, 13 May 2026 04:52:42 +0000 Subject: [PATCH] context: [background] memory injection block (Phase 4 commit #2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase 4 commit #2 per docs/PHASE4.md §5/§12. ctx.memory_items (array of {kind, content, ...}) loaded by repl.lua at startup from history.load_memory(). When non-empty AND ctx not in Norris mode, to_messages() appends a [background] block to the system prompt: [background] (memory.jsonl; manage via :memory) - (fact) User prefers terse responses - (context) Project: aish (LuaJIT REPL) Suppression under Norris (R-C1): when ctx.norris_active is true the [background] block is omitted. Norris already anchors via its NORRIS suffix carrying the goal; a 2KB background block per planning iteration would add ~16K tokens of redundant input over an 8-step run. Suffix composition order is now: 1. DEFAULT_SYSTEM_PROMPT (Phase 0 + Phase 2 MCP, statically embedded) 2. [background] block — when memory_items non-empty AND NOT norris_active 3. NORRIS MODE block — when norris_active repl.lua wiring (memory_items population at startup, :memory meta cmds, :remember shortcut, :memory inject for live refresh) lands in commit #3. Verified composition order with 4 cases: default-only → 697 chars, no background, no norris memory_items only → 824 chars, background YES, no norris memory + norris → 1451 chars, background NO, norris YES (suppressed) norris only → 1451 chars, background NO, norris YES Co-Authored-By: Claude Opus 4.7 (1M context) --- context.lua | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/context.lua b/context.lua index 00222a1..01ea1ee 100644 --- a/context.lua +++ b/context.lua @@ -136,6 +136,22 @@ end -- model (user → assistant → user → assistant), no strict-template breakage. -- -- The system prompt is NOT stored in self.turns per §6. +-- Phase 4: [background] block composer. Memory items from memory.jsonl +-- are stored on self.memory_items (loaded by repl.lua at startup) and +-- rendered as a dim-styled suffix on the system prompt. Suppressed when +-- norris_active to avoid stacking large background contexts in +-- per-iteration broker calls (R-C1 review fold-in). Cap honored via +-- inject_max_chars argument from the caller (already truncated by repl). +local function compose_background(items) + if not items or #items == 0 then return "" end + local lines = { "", "", "[background] (memory.jsonl; manage via :memory)" } + for _, it in ipairs(items) do + lines[#lines + 1] = + ("- (%s) %s"):format(it.kind or "?", (it.content or ""):gsub("\n", " ")) + end + return table.concat(lines, "\n") +end + -- Phase 3: NORRIS MODE suffix appended to the system prompt when -- self.norris_active. Carries self.norris_goal so eviction of the -- user's "[norris] goal: ..." turn doesn't lose the anchor. @@ -165,6 +181,12 @@ message if they declined.]] function Context:to_messages() local sys_content = self.system_prompt + -- Phase 4 [background] memory block. Suppressed during Norris (R-C1 + -- — avoid ~16K of redundant tokens per planning iteration). + if not self.norris_active then + sys_content = sys_content .. compose_background(self.memory_items) + end + -- Phase 3 NORRIS MODE suffix. Last block so its instructions dominate. if self.norris_active and self.norris_goal then sys_content = sys_content .. string.format(NORRIS_SUFFIX_TEMPLATE, self.norris_goal)