feat: Rule subtype for permanent preferences (no decay/prune)#37
Merged
Conversation
Adds a `subtype: 'rule'` semantic on Preference (and any) nodes for permanent constraints — "never X" / "always Y" with no expected sunset. Rule-subtype nodes are exempt from: - Time-based decay (both node confidence and edges touching them) - Low-confidence pruning (defense-in-depth; rules sit at 1.0 anyway) - Orphan pruning (a stranded rule should be reconnected, not deleted) - Edge-weight pruning when either endpoint is a rule The rule's anchor edge (typically Person -[PREFERS]-> Rule) is held at weight 1.0 and exempt from edge decay so the rule never drifts loose. Schema docs (project + universal) updated to describe the subtype. Extractor prompts (dream + graph-capture) updated to recognize hard "never/always" statements and emit them as Rules rather than Preferences. Backward-compatible: all existing nodes have subtype=null and are unaffected by the new filters. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
subtype: 'rule'semantic on Preference (or any) nodes for permanent constraints — "never X" / "always Y" with no expected sunsetWhy
Some user preferences are genuinely permanent constraints, not soft preferences that should fade with time. Letting decay erode them is wrong —
never-edit-domino-odp-fileshas been silently approaching the prune threshold for weeks. A first-class "Rule" semantic keeps these pinned without requiring custom handling everywhere.What changed
src/shared/neo4j-client.ts— Five Cypher filters added:applyDecaynode loop: skipsubtype = 'rule'nodes per typeapplyDecayedge loop: skip edges where either endpoint is a rule (so PREFERS anchor doesn't decay)applyDecayflagged-for-pruning count: skip rulesprunelow-confidence node query: skip rules (defense-in-depth)pruneorphan query: skip rules (stranded rule → reconnect, not delete)pruneedge query: skip edges with rule endpointsGRAPH_SCHEMA.md— Preference row updated to document the rule subtype semantics.prompts/dream-nightly.md+prompts/graph-capture.md— Extractor guidance: hard "never/always" statements → Preference withsubtype: 'rule',confidence: 1.0,PREFERSweight1.0.Backward compatibility
All existing nodes have
subtype = null. The new filters are no-ops for them. No data migration required at deploy time. Other tenants (Jodi) unaffected.Already deployed + validated
Built, deployed via
docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d --force-recreate graph-memory-mcp, healthcheck green. Three Preferences promoted to Rule subtype on the steve tenant for validation:never-edit-domino-odp-files(also mergednever-edit-odp-directlyinto it)no-em-dashes(also mergedpreference-no-em-dashes-in-any-stringsinto it)no-pythonAll three now sit at
confidence: 1.0,subtype: 'rule',PREFERSweight1.0. Pre-migration backup atbackup-2026-05-17T18-35-41-pre-rule-subtype-migration.jsonl.Test plan
npm run buildsucceeds (TypeScript check)graph_statsreturns healthy (no errors)graph_cypher MATCH (n:Preference {subtype:'rule'}) RETURN n.id, n.confidencegraph_prune --dry-runshould NOT list any rule nodes even after weeks of inactivity🤖 Generated with Claude Code