familia 2.0.0.pre5 → 2.0.0.pre7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/claude-code-review.yml +57 -0
  3. data/.github/workflows/claude.yml +71 -0
  4. data/.gitignore +5 -1
  5. data/.rubocop.yml +3 -0
  6. data/CLAUDE.md +32 -10
  7. data/Gemfile +2 -2
  8. data/Gemfile.lock +4 -3
  9. data/docs/wiki/API-Reference.md +95 -18
  10. data/docs/wiki/Connection-Pooling-Guide.md +437 -0
  11. data/docs/wiki/Encrypted-Fields-Overview.md +40 -3
  12. data/docs/wiki/Expiration-Feature-Guide.md +596 -0
  13. data/docs/wiki/Feature-System-Guide.md +631 -0
  14. data/docs/wiki/Features-System-Developer-Guide.md +892 -0
  15. data/docs/wiki/Field-System-Guide.md +784 -0
  16. data/docs/wiki/Home.md +82 -15
  17. data/docs/wiki/Implementation-Guide.md +126 -33
  18. data/docs/wiki/Quantization-Feature-Guide.md +721 -0
  19. data/docs/wiki/Relationships-Guide.md +684 -0
  20. data/docs/wiki/Security-Model.md +65 -25
  21. data/docs/wiki/Transient-Fields-Guide.md +280 -0
  22. data/examples/bit_encoding_integration.rb +237 -0
  23. data/examples/redis_command_validation_example.rb +231 -0
  24. data/examples/relationships_basic.rb +273 -0
  25. data/lib/familia/base.rb +1 -1
  26. data/lib/familia/connection.rb +3 -3
  27. data/lib/familia/data_type/types/counter.rb +38 -0
  28. data/lib/familia/data_type/types/hashkey.rb +18 -0
  29. data/lib/familia/data_type/types/lock.rb +43 -0
  30. data/lib/familia/data_type/types/string.rb +9 -2
  31. data/lib/familia/data_type.rb +9 -6
  32. data/lib/familia/encryption/encrypted_data.rb +137 -0
  33. data/lib/familia/encryption/manager.rb +21 -4
  34. data/lib/familia/encryption/providers/aes_gcm_provider.rb +20 -0
  35. data/lib/familia/encryption/providers/xchacha20_poly1305_provider.rb +20 -0
  36. data/lib/familia/encryption.rb +1 -1
  37. data/lib/familia/errors.rb +17 -3
  38. data/lib/familia/features/encrypted_fields/concealed_string.rb +293 -0
  39. data/lib/familia/features/encrypted_fields/encrypted_field_type.rb +94 -26
  40. data/lib/familia/features/encrypted_fields.rb +413 -4
  41. data/lib/familia/features/expiration.rb +319 -33
  42. data/lib/familia/features/quantization.rb +385 -44
  43. data/lib/familia/features/relationships/cascading.rb +438 -0
  44. data/lib/familia/features/relationships/indexing.rb +370 -0
  45. data/lib/familia/features/relationships/membership.rb +503 -0
  46. data/lib/familia/features/relationships/permission_management.rb +264 -0
  47. data/lib/familia/features/relationships/querying.rb +620 -0
  48. data/lib/familia/features/relationships/redis_operations.rb +274 -0
  49. data/lib/familia/features/relationships/score_encoding.rb +442 -0
  50. data/lib/familia/features/relationships/tracking.rb +379 -0
  51. data/lib/familia/features/relationships.rb +466 -0
  52. data/lib/familia/features/safe_dump.rb +1 -1
  53. data/lib/familia/features/transient_fields/redacted_string.rb +1 -1
  54. data/lib/familia/features/transient_fields.rb +192 -10
  55. data/lib/familia/features.rb +2 -1
  56. data/lib/familia/field_type.rb +5 -2
  57. data/lib/familia/horreum/{connection.rb → core/connection.rb} +2 -8
  58. data/lib/familia/horreum/{database_commands.rb → core/database_commands.rb} +14 -3
  59. data/lib/familia/horreum/core/serialization.rb +535 -0
  60. data/lib/familia/horreum/{utils.rb → core/utils.rb} +0 -2
  61. data/lib/familia/horreum/core.rb +21 -0
  62. data/lib/familia/horreum/{settings.rb → shared/settings.rb} +0 -2
  63. data/lib/familia/horreum/{definition_methods.rb → subclass/definition.rb} +45 -29
  64. data/lib/familia/horreum/{management_methods.rb → subclass/management.rb} +9 -8
  65. data/lib/familia/horreum/{related_fields_management.rb → subclass/related_fields_management.rb} +15 -10
  66. data/lib/familia/horreum.rb +17 -17
  67. data/lib/familia/validation/command_recorder.rb +336 -0
  68. data/lib/familia/validation/expectations.rb +519 -0
  69. data/lib/familia/validation/test_helpers.rb +443 -0
  70. data/lib/familia/validation/validator.rb +412 -0
  71. data/lib/familia/validation.rb +140 -0
  72. data/lib/familia/version.rb +1 -1
  73. data/lib/familia.rb +1 -1
  74. data/try/core/create_method_try.rb +240 -0
  75. data/try/core/database_consistency_try.rb +299 -0
  76. data/try/core/errors_try.rb +25 -4
  77. data/try/core/familia_try.rb +1 -1
  78. data/try/core/persistence_operations_try.rb +297 -0
  79. data/try/data_types/counter_try.rb +93 -0
  80. data/try/data_types/lock_try.rb +133 -0
  81. data/try/debugging/debug_aad_process.rb +82 -0
  82. data/try/debugging/debug_concealed_internal.rb +59 -0
  83. data/try/debugging/debug_concealed_reveal.rb +61 -0
  84. data/try/debugging/debug_context_aad.rb +68 -0
  85. data/try/debugging/debug_context_simple.rb +80 -0
  86. data/try/debugging/debug_cross_context.rb +62 -0
  87. data/try/debugging/debug_database_load.rb +64 -0
  88. data/try/debugging/debug_encrypted_json_check.rb +53 -0
  89. data/try/debugging/debug_encrypted_json_step_by_step.rb +62 -0
  90. data/try/debugging/debug_exists_lifecycle.rb +54 -0
  91. data/try/debugging/debug_field_decrypt.rb +74 -0
  92. data/try/debugging/debug_fresh_cross_context.rb +73 -0
  93. data/try/debugging/debug_load_path.rb +66 -0
  94. data/try/debugging/debug_method_definition.rb +46 -0
  95. data/try/debugging/debug_method_resolution.rb +41 -0
  96. data/try/debugging/debug_minimal.rb +24 -0
  97. data/try/debugging/debug_provider.rb +68 -0
  98. data/try/debugging/debug_secure_behavior.rb +73 -0
  99. data/try/debugging/debug_string_class.rb +46 -0
  100. data/try/debugging/debug_test.rb +46 -0
  101. data/try/debugging/debug_test_design.rb +80 -0
  102. data/try/edge_cases/hash_symbolization_try.rb +1 -0
  103. data/try/edge_cases/reserved_keywords_try.rb +1 -0
  104. data/try/edge_cases/string_coercion_try.rb +2 -0
  105. data/try/encryption/encryption_core_try.rb +6 -4
  106. data/try/features/categorical_permissions_try.rb +515 -0
  107. data/try/features/encrypted_fields_core_try.rb +19 -11
  108. data/try/features/encrypted_fields_integration_try.rb +66 -70
  109. data/try/features/encrypted_fields_no_cache_security_try.rb +22 -8
  110. data/try/features/encrypted_fields_security_try.rb +151 -144
  111. data/try/features/encryption_fields/aad_protection_try.rb +108 -23
  112. data/try/features/encryption_fields/concealed_string_core_try.rb +253 -0
  113. data/try/features/encryption_fields/context_isolation_try.rb +30 -8
  114. data/try/features/encryption_fields/error_conditions_try.rb +6 -6
  115. data/try/features/encryption_fields/fresh_key_derivation_try.rb +20 -14
  116. data/try/features/encryption_fields/fresh_key_try.rb +27 -22
  117. data/try/features/encryption_fields/key_rotation_try.rb +16 -10
  118. data/try/features/encryption_fields/nonce_uniqueness_try.rb +15 -13
  119. data/try/features/encryption_fields/secure_by_default_behavior_try.rb +310 -0
  120. data/try/features/encryption_fields/thread_safety_try.rb +6 -6
  121. data/try/features/encryption_fields/universal_serialization_safety_try.rb +174 -0
  122. data/try/features/feature_dependencies_try.rb +3 -3
  123. data/try/features/relationships_edge_cases_try.rb +145 -0
  124. data/try/features/relationships_performance_minimal_try.rb +132 -0
  125. data/try/features/relationships_performance_simple_try.rb +155 -0
  126. data/try/features/relationships_performance_try.rb +420 -0
  127. data/try/features/relationships_performance_working_try.rb +144 -0
  128. data/try/features/relationships_try.rb +237 -0
  129. data/try/features/safe_dump_try.rb +3 -0
  130. data/try/features/transient_fields/redacted_string_try.rb +2 -0
  131. data/try/features/transient_fields/single_use_redacted_string_try.rb +2 -0
  132. data/try/features/transient_fields_core_try.rb +1 -1
  133. data/try/features/transient_fields_integration_try.rb +1 -1
  134. data/try/helpers/test_helpers.rb +26 -1
  135. data/try/horreum/base_try.rb +14 -8
  136. data/try/horreum/enhanced_conflict_handling_try.rb +3 -1
  137. data/try/horreum/initialization_try.rb +1 -1
  138. data/try/horreum/relations_try.rb +2 -2
  139. data/try/horreum/serialization_persistent_fields_try.rb +8 -8
  140. data/try/horreum/serialization_try.rb +39 -4
  141. data/try/models/customer_safe_dump_try.rb +1 -1
  142. data/try/models/customer_try.rb +1 -1
  143. data/try/validation/atomic_operations_try.rb.disabled +320 -0
  144. data/try/validation/command_validation_try.rb.disabled +207 -0
  145. data/try/validation/performance_validation_try.rb.disabled +324 -0
  146. data/try/validation/real_world_scenarios_try.rb.disabled +390 -0
  147. metadata +81 -12
  148. data/TEST_COVERAGE.md +0 -40
  149. data/lib/familia/features/relatable_objects.rb +0 -125
  150. data/lib/familia/horreum/serialization.rb +0 -473
  151. data/try/features/relatable_objects_try.rb +0 -220
data/docs/wiki/Home.md CHANGED
@@ -1,46 +1,113 @@
1
- # Familia Encrypted Fields Documentation
1
+ # Familia v2.0 Documentation
2
2
 
3
- Welcome to the Familia encrypted fields feature documentation. This Wiki provides comprehensive guides for implementing field-level encryption in your Familia-based applications.
3
+ Welcome to the comprehensive documentation for Familia v2.0. This wiki covers all major features including security, connection management, architecture, and object relationships.
4
4
 
5
5
  ## 📚 Documentation Structure
6
6
 
7
- ### Essential Reading (Start Here)
7
+ ### 🔐 Security & Data Protection
8
8
 
9
- 1. **[Encrypted Fields Overview](Encrypted-Fields-Overview.md)** - Quick introduction and basic usage
9
+ 1. **[Encrypted Fields Overview](Encrypted-Fields-Overview.md)** - Persistent encrypted storage with modular providers
10
+ 2. **[Transient Fields Guide](Transient-Fields-Guide.md)** - Non-persistent secure data handling with RedactedString
11
+ 3. **[Security Model](Security-Model.md)** - Cryptographic design and Ruby memory limitations
10
12
 
11
- 2. **[Implementation Guide](Implementation-Guide.md)** - Configuration details and advanced usage
13
+ ### 🏗️ Architecture & System Design
12
14
 
13
- 3. **[API Reference](API-Reference.md)** - Class and method documentation
15
+ 4. **[Feature System Guide](Feature-System-Guide.md)** - Modular architecture with dependencies and conflict resolution _(new!)_
16
+ 5. **[Connection Pooling Guide](Connection-Pooling-Guide.md)** - Provider pattern for efficient Redis/Valkey pooling _(new!)_
17
+ 6. **[Relationships Guide](Relationships-Guide.md)** - Object relationships and membership system _(new!)_
14
18
 
15
- ### Deep Dives
19
+ ### 🛠️ Implementation & Usage
16
20
 
17
- 4. **[Security Model](Security-Model.md)** - Cryptographic design and Protected vs unprotected scenarios
21
+ 7. **[Implementation Guide](Implementation-Guide.md)** - Configuration, providers, and advanced usage
22
+ 8. **[API Reference](API-Reference.md)** - Complete class and method documentation
18
23
 
19
- ### Operations (As Needed)
24
+ ### 🚀 Operations (As Needed)
20
25
 
21
- 5. **[Migration Guide](Migration-Guide.md)** - Upgrading existing fields _(coming soon)_
22
- 6. **[Key Management](Key-Management.md)** - Rotation and best practices _(coming soon)_
26
+ 9. **[Migration Guide](Migration-Guide.md)** - Upgrading existing fields _(coming soon)_
27
+ 10. **[Key Management](Key-Management.md)** - Rotation and best practices _(coming soon)_
23
28
 
24
- ## 🚀 Quick Start
29
+ ## 🚀 Quick Start Examples
25
30
 
31
+ ### Encrypted Fields (Persistent)
26
32
  ```ruby
27
- # 1. Add encrypted field to your model
28
33
  class User < Familia::Horreum
34
+ feature :encrypted_fields
29
35
  encrypted_field :secret_recipe
30
36
  end
31
37
 
32
- # 2. Configure encryption key
38
+ # Configure encryption
33
39
  Familia.configure do |config|
34
40
  config.encryption_keys = { v1: ENV['FAMILIA_ENCRYPTION_KEY'] }
35
41
  config.current_key_version = :v1
36
42
  end
37
43
 
38
- # 3. Use like any other field
39
44
  user = User.new(secret_recipe: "donna's cookies")
40
45
  user.save
41
46
  user.secret_recipe # => "donna's cookies" (automatically decrypted)
42
47
  ```
43
48
 
49
+ ### Feature System (Modular)
50
+ ```ruby
51
+ class Customer < Familia::Horreum
52
+ feature :safe_dump # API-safe serialization
53
+ feature :expiration # TTL support
54
+ feature :encrypted_fields # Secure storage
55
+
56
+ field :name, :email
57
+ encrypted_field :api_key
58
+ default_expiration 24.hours
59
+ safe_dump_fields :name, :email
60
+ end
61
+ ```
62
+
63
+ ### Connection Pooling (Performance)
64
+ ```ruby
65
+ # Configure connection provider for multi-database pooling
66
+ Familia.connection_provider = lambda do |uri|
67
+ parsed = URI.parse(uri)
68
+ pool_key = "#{parsed.host}:#{parsed.port}/#{parsed.db || 0}"
69
+
70
+ @pools[pool_key] ||= ConnectionPool.new(size: 10) do
71
+ Redis.new(host: parsed.host, port: parsed.port, db: parsed.db || 0)
72
+ end
73
+
74
+ @pools[pool_key].with { |conn| conn }
75
+ end
76
+ ```
77
+
78
+ ### Object Relationships
79
+ ```ruby
80
+ class Customer < Familia::Horreum
81
+ feature :relationships
82
+ identifier_field :custid
83
+ field :custid, :name, :email
84
+
85
+ # Customer collections
86
+ set :domains
87
+ end
88
+
89
+ class Domain < Familia::Horreum
90
+ feature :relationships
91
+ identifier_field :domain_id
92
+ field :domain_id, :name, :dns_zone
93
+
94
+ # Declare membership in customer collections
95
+ member_of Customer, :domains, type: :set
96
+ end
97
+
98
+ # Create objects and establish relationships
99
+ customer = Customer.new(custid: "cust123", name: "Acme Corp")
100
+ domain = Domain.new(domain_id: "dom456", name: "acme.com")
101
+
102
+ # Establish bidirectional relationship
103
+ domain.add_to_customer_domains(customer.custid)
104
+ customer.domains.add(domain.identifier)
105
+
106
+ # Query relationships
107
+ domain.in_customer_domains?(customer.custid) # => true
108
+ customer.domains.member?(domain.identifier) # => true
109
+ ```
110
+
44
111
 
45
112
  ## Related Resources
46
113
 
@@ -2,48 +2,88 @@
2
2
 
3
3
  ## Architecture Overview
4
4
 
5
- The encrypted fields feature extends Familia's existing field system with transformation hooks:
5
+ The encrypted fields feature uses a modular provider system with field transformation hooks:
6
6
 
7
7
  ```
8
- User Input → Field Setter → Serialize Transform → Encryption → Redis
9
- Redis → DecryptionDeserialize Transform → Field Getter → User Output
8
+ User Input → Field Setter → Provider Selection → Encryption → Redis/Valkey
9
+ Redis/ValkeyAlgorithm Detection Decryption → Field Getter → User Output
10
+ ```
11
+
12
+ ### Provider Architecture
13
+
14
+ ```
15
+ ┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
16
+ │ Manager │ │ Registry │ │ Providers │
17
+ │ │ │ │ │ │
18
+ │ - encrypt() │───→│ - get() │───→│ XChaCha20Poly │
19
+ │ - decrypt() │ │ - register() │ │ AES-GCM │
20
+ │ - derive_key() │ │ - priority │ │ (Future: More) │
21
+ └─────────────────┘ └──────────────────┘ └─────────────────┘
10
22
  ```
11
23
 
12
24
  ## Core Components
13
25
 
14
- ### 1. Transform Hooks
26
+ ### 1. Registry System
27
+
28
+ The Registry manages available encryption providers and selects the best one:
29
+
30
+ ```ruby
31
+ module Familia::Encryption::Registry
32
+ # Auto-register available providers by priority
33
+ def self.setup!
34
+
35
+ # Get provider instance by algorithm
36
+ def self.get(algorithm)
37
+
38
+ # Get highest-priority available provider
39
+ def self.default_provider
40
+ end
41
+ ```
42
+
43
+ ### 2. Manager Class
15
44
 
16
- Fields now support transform callbacks:
45
+ The Manager handles encryption/decryption operations with provider delegation:
17
46
 
18
47
  ```ruby
19
- FieldDefinition = Data.define(
20
- :field_name,
21
- :method_name,
22
- :serialize_transform, # Called before storage
23
- :deserialize_transform # Called after retrieval
24
- )
48
+ class Familia::Encryption::Manager
49
+ # Use specific algorithm or auto-select best
50
+ def initialize(algorithm: nil)
51
+
52
+ # Encrypt with context-specific key derivation
53
+ def encrypt(plaintext, context:, additional_data: nil)
54
+
55
+ # Decrypt with automatic algorithm detection
56
+ def decrypt(encrypted_json, context:, additional_data: nil)
57
+ end
25
58
  ```
26
59
 
27
- ### 2. Encryption Module
60
+ ### 3. Provider Interface
28
61
 
29
- Handles the cryptographic operations:
62
+ All providers implement a common interface:
30
63
 
31
64
  ```ruby
32
- module Familia::Encryption
33
- # Encrypts with field-specific derived key
34
- def self.encrypt(plaintext, context:, additional_data: nil)
65
+ class Provider
66
+ ALGORITHM = 'algorithm-name'
35
67
 
36
- # Decrypts and verifies authenticity
37
- def self.decrypt(ciphertext, context:, additional_data: nil)
68
+ def self.available? # Check if dependencies are met
69
+ def self.priority # Higher = preferred (XChaCha20: 100, AES: 50)
70
+
71
+ def encrypt(plaintext, key, additional_data)
72
+ def decrypt(ciphertext, key, nonce, auth_tag, additional_data)
73
+ def derive_key(master_key, context)
74
+ def generate_nonce
38
75
  end
39
76
  ```
40
77
 
41
- ### 3. Key Derivation
78
+ ### 4. Key Derivation
42
79
 
43
- Each field gets a unique encryption key:
80
+ Each field gets a unique encryption key using provider-specific methods:
44
81
 
45
82
  ```
46
- Master Key + Field Context → HKDF/BLAKE2b → Field-Specific Key
83
+ Master Key + Field Context → Provider KDF → Field-Specific Key
84
+
85
+ XChaCha20-Poly1305: BLAKE2b with personalization
86
+ AES-256-GCM: HKDF-SHA256
47
87
  ```
48
88
 
49
89
  ## Implementation Steps
@@ -79,14 +119,28 @@ Familia::Encryption.validate_configuration!
79
119
  ### Step 3: Generate Keys
80
120
 
81
121
  ```bash
82
- # Generate a secure key
83
- $ familia encryption:generate_key --bits 256
122
+ # Generate a secure 256-bit key (32 bytes)
123
+ $ openssl rand -base64 32
84
124
  # => base64_encoded_key_here
85
125
 
86
126
  # Add to environment
87
127
  $ echo "FAMILIA_ENCRYPTION_KEY_V1=base64_encoded_key_here" >> .env
88
128
  ```
89
129
 
130
+ ### Step 4: Install Optional Dependencies
131
+
132
+ For best security and performance, install RbNaCl:
133
+
134
+ ```bash
135
+ # Add to Gemfile
136
+ gem 'rbnacl', '~> 7.1', '>= 7.1.1'
137
+
138
+ # Install
139
+ $ bundle install
140
+ ```
141
+
142
+ Without RbNaCl, Familia falls back to OpenSSL AES-256-GCM (still secure but lower priority).
143
+
90
144
  ## Advanced Usage
91
145
 
92
146
  ### Custom Field Names
@@ -118,24 +172,63 @@ customers = Customer.batch_create([
118
172
  ])
119
173
  ```
120
174
 
175
+ ## Provider-Specific Features
176
+
177
+ ### XChaCha20-Poly1305 Provider (Recommended)
178
+
179
+ ```ruby
180
+ # Enable with RbNaCl gem
181
+ gem 'rbnacl', '~> 7.1'
182
+
183
+ # Benefits:
184
+ # - Extended nonce (192 bits vs 96 bits)
185
+ # - Better resistance to nonce reuse
186
+ # - BLAKE2b key derivation with personalization
187
+ # - Priority: 100 (highest)
188
+ ```
189
+
190
+ ### AES-256-GCM Provider (Fallback)
191
+
192
+ ```ruby
193
+ # Always available with OpenSSL
194
+ # - 256-bit keys, 96-bit nonces
195
+ # - HKDF-SHA256 key derivation
196
+ # - Priority: 50
197
+ # - Good compatibility, proven security
198
+ ```
199
+
121
200
  ## Performance Optimization
122
201
 
123
- ### Request-Scoped Key Caching
202
+ ### Provider Benchmarking
124
203
 
125
204
  ```ruby
126
- # Automatically enabled in web frameworks
127
- # Manual control for other contexts:
128
- Familia::Encryption.with_key_cache do
129
- # All operations here share derived keys
130
- Customer.find_each { |c| c.process }
131
- end
205
+ # Compare provider performance
206
+ results = Familia::Encryption.benchmark(iterations: 1000)
207
+ puts results
208
+ # => {
209
+ # "xchacha20poly1305" => { time: 0.45, ops_per_sec: 4444, priority: 100 },
210
+ # "aes-256-gcm" => { time: 0.52, ops_per_sec: 3846, priority: 50 }
211
+ # }
212
+ ```
213
+
214
+ ### Key Derivation Monitoring
215
+
216
+ ```ruby
217
+ # Monitor key derivations (should increment with each operation)
218
+ puts Familia::Encryption.derivation_count.value
219
+ # => 42
220
+
221
+ # Reset counter for testing
222
+ Familia::Encryption.reset_derivation_count!
132
223
  ```
133
224
 
134
225
  ### Memory Management
135
226
 
136
- With libsodium installed:
137
- - Keys are automatically wiped from memory
138
- - Plaintext values cleared after use
227
+ **⚠️ Important**: Ruby provides no memory safety guarantees. See security warnings in provider files.
228
+
229
+ - Keys are cleared from variables after use (best effort)
230
+ - No protection against memory dumps or GC copying
231
+ - Plaintext exists in Ruby strings during processing
139
232
 
140
233
  ## Testing
141
234