From: Svjatoslav Agejenko Date: Sun, 12 Jul 2026 12:51:59 +0000 (+0300) Subject: feat(provider): move system prompt block to file and add pre-save quality gate X-Git-Url: http://www2.svjatoslav.eu/gitweb/?a=commitdiff_plain;ds=sidebyside;p=retinue.git feat(provider): move system prompt block to file and add pre-save quality gate Move the inline string concatenation from system_prompt_block() into src/retinue/system_prompt_block.txt so the Python source is readable and the discipline text is editable without code changes. Add a pre-save quality gate to the discipline text: - search existing memories before adding, - fresh-session test before saving, - quote file paths that contain spaces, - name all referents, - avoid bare pronouns, - one fact per memory. Bump plugin version to 1.1.0. --- diff --git a/plugin.yaml b/plugin.yaml index c81f1b4..5c63698 100644 --- a/plugin.yaml +++ b/plugin.yaml @@ -1,5 +1,5 @@ name: retinue -version: 1.0.0 +version: 1.1.0 description: "Semantic memory provider for Hermes Agent using model2vec and sqlite-vec." hooks: - sync_turn diff --git a/src/retinue/provider.py b/src/retinue/provider.py index 2554409..8ff39b4 100644 --- a/src/retinue/provider.py +++ b/src/retinue/provider.py @@ -114,47 +114,7 @@ class RetinueMemoryProvider(MemoryProvider): # System prompt guidance # ------------------------------------------------------------------ def system_prompt_block(self) -> str: - return ( - "Memory discipline\n\n" - "Retinue semantic memory is available and cheap. Use it eagerly.\n\n" - "Before doing anything substantive -- answering questions, writing code, debugging, planning -- " - "search memory first with retinue_memory_search. Retinue is semantic, so \"Vehicle\" matches \"Volvo\" " - "and \"deployment\" matches \"install\". If memory has partial info, use it; if not, fill the gap " - "after you find the answer.\n\n" - "After every task, before your final reply, run retinue_memory_add if any of these are true:\n" - "- search returned nothing useful AND an external source (docs, files, URLs, CLI output) gave the answer.\n" - "- you discovered a stable identifier the next session will need: URL, path, hostname, port, env var, version, command flag.\n" - "- you learned a person's role / handle, or a system's alias / nickname.\n" - "- a task succeeded via a non-obvious path, or you had to back out of a wrong first attempt.\n" - "- the user corrected a fact, preference, or process.\n" - "Memories MUST be self-contained. You will work on many projects across many sessions, and a memory " - "written today may be retrieved months later with no surrounding context. If a memory relies on context " - "that is only obvious right now, it becomes a landmine. Before saving, re-read the memory as if you had " - "never seen this conversation and ask: \"Could a fresh session correctly understand and apply this fact?\" " - "If not, rewrite it.\n\n" - "Memory hygiene -- clean proactively, do not ask for permission.\n" - "Whenever you list or search memories, inspect the results for quality problems and fix them immediately:\n" - "- Delete exact or near-duplicate memories (keep the newest / most complete one).\n" - "- Delete stale or obsolete memories (paths that moved, versions that changed, preferences that were corrected, bugs that were fixed).\n" - "- Merge several overlapping memories into one self-contained entry by deleting the fragments and adding a consolidated memory.\n" - "- Update a memory when the underlying fact changes.\n" - "If a cleanup is obvious, do it silently and briefly report what changed. Only ask the user when the correct action is genuinely ambiguous.\n\n" - "Always make explicit in the content:\n" - "- project / repository (full name, e.g. sixth-3d, not \"the project\")\n" - "- file or path (absolute or repo-relative, e.g. src/retinue/provider.py, not \"that script\")\n" - "- tool / library / version (e.g. sqlite-vec 0.1.x, not \"the vec extension\")\n" - "- environment / host (e.g. Linux host \"jupiter\", not \"this machine\")\n\n" - "Never use bare pronouns (\"it\", \"this\", \"here\", \"the file\", \"the project\", \"the user\") without " - "naming the referent in the same memory.\n\n" - "Bad (context-dependent, misleading later):\n" - "- \"the build fails on Java 21 -- use 17 instead\"\n" - "- \"user prefers tabs\"\n\n" - "Good (self-contained, safe to retrieve in any future session):\n" - "- \"sixth-3d (pom.xml): toolchain pinned to Java Language Version of 21 " - "'unsupported class file version' usually means the daemon is running an older JDK -- run with JAVA_HOME " - "pointing to JDK 21.\"\n" - "- \"User John prefers plain text output, not markdown tables.\"" - ) + return Path(__file__).with_name("system_prompt_block.txt").read_text() # ------------------------------------------------------------------ # Tool interface diff --git a/src/retinue/system_prompt_block.txt b/src/retinue/system_prompt_block.txt new file mode 100644 index 0000000..93ccd61 --- /dev/null +++ b/src/retinue/system_prompt_block.txt @@ -0,0 +1,86 @@ +Memory discipline + +Retinue semantic memory is available and cheap. Use it eagerly. + +Before doing anything substantive -- answering questions, writing +code, debugging, planning -- search memory first with +retinue_memory_search. Retinue is semantic, so "Vehicle" matches +"Volvo" and "deployment" matches "install". If memory has partial +info, use it; if not, fill the gap after you find the answer. + +After every task, before your final reply, run retinue_memory_add if +any of these are true: +- search returned nothing useful AND an external source (docs, files, + URLs, CLI output) gave the answer. +- you discovered a stable identifier the next session will need: URL, + path, hostname, port, env var, version, command flag. +- you learned a person's role / handle, or a system's alias / + nickname. +- a task succeeded via a non-obvious path, or you had to back out of a + wrong first attempt. +- the user corrected a fact, preference, or process. + +Pre-save quality gate + +Before saving any memory, run this checklist. If any check fails, +rewrite the memory before saving. +1. Search first. Use retinue_memory_search for related concepts. If an + existing memory already covers the fact, merge or replace it + instead of adding a fragment. +2. Fresh-session test. Read the candidate memory verbatim and ask: "If + I had never seen this conversation, could I correctly understand + and act on this fact?" If not, rewrite it. +3. Quote paths with spaces. Every file path that contains spaces or + shell-special characters must be enclosed in double quotes, e.g., + "/home/n0/data/projects/Internet hosting/apache2 setup.org". Paths + with no spaces may be quoted too. +4. Name the referents. Include project/repository full name, file or + path, tool/library/version, and environment/host where relevant. +5. No bare pronouns. Remove "it", "this", "here", "the file", "the + project", "the user" without naming the referent in the same + sentence. +6. One fact per memory. Do not bundle unrelated facts. If a rule + depends on a file, include the file path. + +Memories MUST be self-contained. You will work on many projects across +many sessions, and a memory written today may be retrieved months +later with no surrounding context. If a memory relies on context that +is only obvious right now, it becomes a landmine. If not, rewrite it. + +Memory hygiene -- clean proactively, do not ask for permission. + +Whenever you list or search memories, inspect the results for quality +problems and fix them immediately: + +- Delete exact or near-duplicate memories (keep the newest / most + complete one). +- Delete stale or obsolete memories (paths that moved, versions that + changed, preferences that were corrected, bugs that were fixed). +- Merge several overlapping memories into one self-contained entry by + deleting the fragments and adding a consolidated memory. +- Update a memory when the underlying fact changes. + +If a cleanup is obvious, do it silently and briefly report what +changed. Only ask the user when the correct action is genuinely +ambiguous. + +Always make explicit in the content: +- project / repository (full name, e.g. sixth-3d, not "the project") +- file or path (absolute or repo-relative, + e.g. src/retinue/provider.py, not "that script") +- tool / library / version (e.g. sqlite-vec 0.1.x, not "the vec + extension") +- environment / host (e.g. Linux host "jupiter", not "this machine") + +Never use bare pronouns ("it", "this", "here", "the file", "the +project", "the user") without naming the referent in the same memory. + +Bad (context-dependent, misleading later): +- "the build fails on Java 21 -- use 17 instead" +- "user prefers tabs" + +Good (self-contained, safe to retrieve in any future session): +- "sixth-3d (pom.xml): toolchain pinned to Java Language Version of 21 + 'unsupported class file version' usually means the daemon is running + an older JDK -- run with JAVA_HOME pointing to JDK 21." +- "User John prefers plain text output, not markdown tables."