9.7 KiB
Phase 4: Delta Patterns & Query Traversal - Implementation Plan
Overview
Phase 4 recognizes that in Rhizome, deltas ARE relationships. Instead of adding a relationship layer on top of deltas, we're creating tools to work with delta patterns more effectively. This phase focuses on formalizing common delta patterns, building query conveniences for traversing these patterns, and creating specialized resolvers that interpret deltas as familiar relational concepts.
Core Insights
- Deltas are relationships: Every delta with pointers already expresses relationships
- Patterns, not structure: We're recognizing patterns in how deltas connect entities
- Perspective-driven: Different views/resolvers can interpret the same deltas differently
- No single truth: Competing deltas are resolved by application-level lossy resolvers
- Time-aware: All queries are inherently temporal, showing different relationships at different times
Current State ✅
- All tests passing: 21/21 suites, 183/183 tests (100%)
- Delta system: Fully functional with pointers expressing relationships
- Negation system: Can invalidate deltas (and thus relationships)
- Query system: Basic traversal of lossless views
- Schema system: Can describe entity structures
- Resolver system: Application-level interpretation of deltas
Implementation Plan
Step 1: Delta Pattern Recognition
Goal: Formalize common patterns of deltas that represent familiar relationships
Tasks:
-
Create
src/patterns/delta-patterns.ts
:- Define patterns for common relationship types
- Create pattern matching utilities
- Document pattern conventions
-
Common patterns to recognize:
// One-to-one: A delta pointing from A to B with unique constraint const AuthorshipPattern = { name: 'authorship', match: (delta) => delta.pointers.some(p => p.targetContext === 'author') && delta.pointers.some(p => p.targetContext === 'post'), interpret: (delta) => ({ post: delta.pointers.find(p => p.targetContext === 'post').target, author: delta.pointers.find(p => p.targetContext === 'author').target }) }; // One-to-many: Multiple deltas pointing from many Bs to one A const PostsByAuthorPattern = { name: 'posts-by-author', query: (authorId) => ({ pointers: { some: { target: authorId, targetContext: 'author' } } }) };
-
Pattern validation:
- Ensure deltas match expected patterns
- Provide clear feedback when patterns are violated
- Allow flexible pattern definitions
Step 2: Query Pattern Traversal
Goal: Make it easy to traverse delta patterns in queries
Tasks:
-
Extend
QueryEngine
with pattern-aware methods:// Find all deltas that establish a certain relationship queryEngine.findRelationships('authorship', { author: 'user-123' }); // Traverse relationships in time queryEngine.findRelationships('authorship', { author: 'user-123', asOf: timestamp // Time-travel query });
-
Create traversal helpers:
// Follow a chain of relationships queryEngine.traverse({ start: 'user-123', follow: [ { pattern: 'authorship', direction: 'from' }, { pattern: 'comments', direction: 'to' } ], includeNegated: false // Perspective choice });
-
Multi-perspective queries:
// Different views of the same deltas queryEngine.query('Post', {}, { perspectives: { published: { includeNegated: false }, draft: { includeNegated: true }, historical: { asOf: timestamp } } });
Step 3: Pattern-Aware Resolvers
Goal: Create resolvers that interpret delta patterns as familiar concepts
Tasks:
-
Create
src/views/resolvers/pattern-resolver.ts
:class PatternResolver { // Interpret deltas matching certain patterns resolveWithPatterns(entityId, patterns) { const deltas = this.lossless.getDeltasForEntity(entityId); return { entity: entityId, relationships: patterns.map(pattern => ({ type: pattern.name, targets: deltas .filter(pattern.match) .map(pattern.interpret) })) }; } }
-
Specialized pattern resolvers:
ReferenceResolver
: Follows pointer patternsTemporalResolver
: Shows relationships over timeCompetingValueResolver
: Handles multiple values for same relationship
-
Resolver composition:
// Stack resolvers for different perspectives const publishedView = new ResolverStack([ new NegationFilter(), new TemporalResolver({ until: now }), new LastWriteWins() ]);
Step 4: Delta Pattern Validation
Goal: Validate that deltas follow expected patterns (without enforcing)
Tasks:
-
Create
src/features/pattern-validation.ts
:// Validate but don't enforce validateDeltaPattern(delta, pattern) { const result = pattern.validate(delta); if (!result.valid) { // Emit warning, but still accept delta this.emit('pattern-warning', { delta, pattern: pattern.name, issues: result.issues }); } return result; }
-
Pattern constraints as guidance:
- Required pointer contexts
- Expected value types
- Cardinality suggestions
- Temporal constraints
-
Missing information detection:
// Detect incomplete patterns detectMissingRelationships(entity, expectedPatterns) { return expectedPatterns.filter(pattern => !this.hasMatchingDelta(entity, pattern) ); }
Step 5: Collection Pattern Helpers
Goal: Make collections work naturally with delta patterns
Tasks:
-
Extend collections with pattern methods:
class PatternAwareCollection extends Collection { // Create deltas that match patterns relate(from, to, pattern) { const delta = pattern.createDelta(from, to); return this.rhizomeNode.acceptDelta(delta); } // Query using patterns findRelated(entity, pattern) { return this.queryEngine.findRelationships(pattern, { [pattern.fromContext]: entity }); } }
-
Pattern-based operations:
- Batch relationship creation
- Relationship negation helpers
- Pattern-based cascades
Step 6: Temporal Pattern Queries
Goal: Leverage time-travel for relationship history
Tasks:
-
Time-aware pattern queries:
// Show relationship changes over time queryEngine.relationshipHistory('authorship', { post: 'post-123', timeRange: { from: t1, to: t2 } }); // Find when relationships were established/negated queryEngine.relationshipTimeline(entityId);
-
Temporal pattern analysis:
- Relationship duration
- Relationship conflicts over time
- Pattern evolution
File Structure
New files to create:
src/
├── patterns/
│ ├── delta-patterns.ts # Pattern definitions
│ ├── pattern-matcher.ts # Pattern matching utilities
│ └── pattern-validators.ts # Pattern validation
├── query/
│ └── pattern-query-engine.ts # Pattern-aware queries
├── views/
│ └── resolvers/
│ ├── pattern-resolver.ts # Pattern interpretation
│ └── temporal-resolver.ts # Time-aware resolution
└── features/
└── pattern-validation.ts # Soft validation
Files to modify:
src/query/query-engine.ts
- Add pattern methodssrc/collections/collection-abstract.ts
- Add pattern helperssrc/node.ts
- Wire up pattern features
Testing Strategy
New test files:
__tests__/delta-patterns.ts
- Pattern definition and matching__tests__/pattern-queries.ts
- Pattern-based traversal__tests__/pattern-validation.ts
- Soft validation behavior__tests__/temporal-patterns.ts
- Time-travel relationship queries__tests__/competing-relationships.ts
- Multiple relationship handling
Test scenarios:
- Define and match delta patterns
- Query relationships using patterns
- Validate deltas against patterns (warnings only)
- Time-travel through relationship history
- Handle competing relationship deltas
- Detect missing relationships
- Test pattern-based cascading negations
Success Criteria
- Delta patterns are well-defined and matchable
- Queries can traverse relationships via delta patterns
- Pattern validation provides guidance without enforcement
- Time-travel queries work with relationships
- Competing relationships are handled gracefully
- Missing relationships are detectable
- Performance scales with pattern complexity
- Developers find patterns intuitive to use
Key Principles to Maintain
- Deltas are relationships - Never create a separate relationship system
- Patterns are recognition - We're recognizing what's already there
- Perspective matters - Same deltas, different interpretations
- No enforcement - Validation guides but doesn't restrict
- Time is first-class - All relationships exist in time
- Conflicts are natural - Multiple truths coexist until resolved by views
Next Session Tasks
- Define core delta patterns in
delta-patterns.ts
- Create pattern matching utilities
- Extend QueryEngine with pattern-aware methods
- Write tests for pattern recognition
- Document the delta-as-relationship philosophy
This approach embraces Rhizome's fundamental architecture where deltas ARE the relationships, making it easier to work with these patterns while respecting the system's perspective-driven, temporal nature.