feat: strip <system_instruction> tags before DB storage (#1398)

* feat: strip <system_instruction> tags before database storage

Extends the existing tag-stripping mechanism (used for <private> and
<claude-mem-context>) to also filter Conductor-injected system instructions,
preventing them from being persisted in the observation database.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: also strip <system-instruction> (hyphen variant) before DB storage

Conductor uses both <system_instruction> and <system-instruction> tag
formats. This adds the hyphen variant to the same stripping mechanism.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Alex Newman
2026-03-19 12:08:25 -07:00
committed by GitHub
parent b34aff1aa2
commit 9f529a30f5
3 changed files with 68202 additions and 794 deletions
+8 -2
View File
@@ -1,11 +1,13 @@
/**
* Tag Stripping Utilities
*
* Implements the dual-tag system for meta-observation control:
* Implements the tag system for meta-observation control:
* 1. <claude-mem-context> - System-level tag for auto-injected observations
* (prevents recursive storage when context injection is active)
* 2. <private> - User-level tag for manual privacy control
* (allows users to mark content they don't want persisted)
* 3. <system_instruction> / <system-instruction> - Conductor-injected system instructions
* (should not be persisted to memory)
*
* EDGE PROCESSING PATTERN: Filter at hook layer before sending to worker/storage.
* This keeps the worker service simple and follows one-way data stream.
@@ -27,7 +29,9 @@ const MAX_TAG_COUNT = 100;
function countTags(content: string): number {
const privateCount = (content.match(/<private>/g) || []).length;
const contextCount = (content.match(/<claude-mem-context>/g) || []).length;
return privateCount + contextCount;
const systemInstructionCount = (content.match(/<system_instruction>/g) || []).length;
const systemInstructionHyphenCount = (content.match(/<system-instruction>/g) || []).length;
return privateCount + contextCount + systemInstructionCount + systemInstructionHyphenCount;
}
/**
@@ -49,6 +53,8 @@ function stripTagsInternal(content: string): string {
return content
.replace(/<claude-mem-context>[\s\S]*?<\/claude-mem-context>/g, '')
.replace(/<private>[\s\S]*?<\/private>/g, '')
.replace(/<system_instruction>[\s\S]*?<\/system_instruction>/g, '')
.replace(/<system-instruction>[\s\S]*?<\/system-instruction>/g, '')
.trim();
}