familia 2.0.0.pre18 → 2.0.0.pre21

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 (370) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/claude-code-review.yml +4 -9
  3. data/.github/workflows/code-smells.yml +64 -3
  4. data/.pre-commit-config.yaml +8 -6
  5. data/.reek.yml +10 -9
  6. data/.rubocop.yml +4 -0
  7. data/CHANGELOG.rst +205 -88
  8. data/CLAUDE.md +62 -10
  9. data/Gemfile +3 -3
  10. data/Gemfile.lock +27 -62
  11. data/README.md +39 -0
  12. data/bin/try +16 -0
  13. data/bin/tryouts +16 -0
  14. data/changelog.d/20251105_flexible_external_identifier_format.rst +66 -0
  15. data/changelog.d/20251107_112554_delano_179_participation_asymmetry.rst +44 -0
  16. data/changelog.d/20251107_213121_delano_fix_thread_safety_races_011CUumCP492Twxm4NLt2FvL.rst +20 -0
  17. data/changelog.d/20251107_fix_participates_in_symbol_resolution.rst +91 -0
  18. data/changelog.d/20251107_optimized_redis_exists_checks.rst +94 -0
  19. data/changelog.d/20251108_frozen_string_literal_pragma.rst +44 -0
  20. data/docs/1106-participates_in-bidirectional-solution.md +129 -0
  21. data/docs/guides/encryption.md +486 -0
  22. data/docs/guides/feature-encrypted-fields.md +123 -7
  23. data/docs/guides/feature-expiration.md +177 -133
  24. data/docs/guides/feature-external-identifiers.md +415 -443
  25. data/docs/guides/feature-object-identifiers.md +400 -269
  26. data/docs/guides/feature-quantization.md +120 -6
  27. data/docs/guides/feature-relationships-indexing.md +318 -0
  28. data/docs/guides/feature-relationships-methods.md +146 -604
  29. data/docs/guides/feature-relationships-participation.md +263 -0
  30. data/docs/guides/feature-relationships.md +118 -136
  31. data/docs/guides/feature-system-devs.md +176 -693
  32. data/docs/guides/feature-system.md +119 -6
  33. data/docs/guides/feature-transient-fields.md +81 -0
  34. data/docs/guides/field-system.md +778 -0
  35. data/docs/guides/index.md +32 -15
  36. data/docs/guides/logging.md +187 -0
  37. data/docs/guides/optimized-loading.md +674 -0
  38. data/docs/guides/thread-safety-monitoring.md +61 -0
  39. data/docs/guides/{time-utilities.md → time-literals.md} +12 -12
  40. data/docs/migrating/v2.0.0-pre19.md +197 -0
  41. data/docs/migrating/v2.0.0-pre22.md +241 -0
  42. data/docs/overview.md +7 -9
  43. data/docs/reference/api-technical.md +267 -320
  44. data/examples/autoloader/mega_customer/features/deprecated_fields.rb +2 -0
  45. data/examples/autoloader/mega_customer/safe_dump_fields.rb +2 -0
  46. data/examples/autoloader/mega_customer.rb +2 -0
  47. data/examples/datatype_standalone.rb +282 -0
  48. data/examples/encrypted_fields.rb +2 -1
  49. data/examples/json_usage_patterns.rb +2 -0
  50. data/examples/relationships.rb +3 -0
  51. data/examples/safe_dump.rb +2 -1
  52. data/examples/sampling_demo.rb +53 -0
  53. data/examples/single_connection_transaction_confusions.rb +2 -1
  54. data/familia.gemspec +2 -1
  55. data/lib/familia/base.rb +2 -0
  56. data/lib/familia/connection/behavior.rb +254 -0
  57. data/lib/familia/connection/handlers.rb +97 -0
  58. data/lib/familia/connection/individual_command_proxy.rb +2 -0
  59. data/lib/familia/connection/middleware.rb +34 -24
  60. data/lib/familia/connection/operation_core.rb +3 -1
  61. data/lib/familia/connection/operations.rb +2 -0
  62. data/lib/familia/connection/{pipeline_core.rb → pipelined_core.rb} +4 -2
  63. data/lib/familia/connection/transaction_core.rb +75 -9
  64. data/lib/familia/connection.rb +21 -5
  65. data/lib/familia/data_type/class_methods.rb +3 -1
  66. data/lib/familia/data_type/connection.rb +153 -7
  67. data/lib/familia/data_type/database_commands.rb +9 -4
  68. data/lib/familia/data_type/serialization.rb +10 -4
  69. data/lib/familia/data_type/settings.rb +2 -0
  70. data/lib/familia/data_type/types/counter.rb +2 -0
  71. data/lib/familia/data_type/types/hashkey.rb +8 -6
  72. data/lib/familia/data_type/types/listkey.rb +2 -0
  73. data/lib/familia/data_type/types/lock.rb +2 -0
  74. data/lib/familia/data_type/types/sorted_set.rb +2 -0
  75. data/lib/familia/data_type/types/stringkey.rb +2 -0
  76. data/lib/familia/data_type/types/unsorted_set.rb +2 -0
  77. data/lib/familia/data_type.rb +2 -0
  78. data/lib/familia/encryption/encrypted_data.rb +4 -2
  79. data/lib/familia/encryption/manager.rb +2 -0
  80. data/lib/familia/encryption/provider.rb +2 -0
  81. data/lib/familia/encryption/providers/aes_gcm_provider.rb +2 -0
  82. data/lib/familia/encryption/providers/secure_xchacha20_poly1305_provider.rb +2 -0
  83. data/lib/familia/encryption/providers/xchacha20_poly1305_provider.rb +2 -0
  84. data/lib/familia/encryption/registry.rb +2 -0
  85. data/lib/familia/encryption/request_cache.rb +2 -0
  86. data/lib/familia/encryption.rb +9 -2
  87. data/lib/familia/errors.rb +53 -14
  88. data/lib/familia/features/autoloader.rb +2 -0
  89. data/lib/familia/features/encrypted_fields/concealed_string.rb +2 -0
  90. data/lib/familia/features/encrypted_fields/encrypted_field_type.rb +4 -0
  91. data/lib/familia/features/encrypted_fields.rb +2 -2
  92. data/lib/familia/features/expiration/extensions.rb +11 -11
  93. data/lib/familia/features/expiration.rb +29 -21
  94. data/lib/familia/features/external_identifier.rb +33 -7
  95. data/lib/familia/features/object_identifier.rb +2 -0
  96. data/lib/familia/features/quantization.rb +3 -1
  97. data/lib/familia/features/relationships/README.md +3 -1
  98. data/lib/familia/features/relationships/collection_operations.rb +2 -0
  99. data/lib/familia/features/relationships/indexing/multi_index_generators.rb +177 -47
  100. data/lib/familia/features/relationships/indexing/rebuild_strategies.rb +479 -0
  101. data/lib/familia/features/relationships/indexing/unique_index_generators.rb +203 -63
  102. data/lib/familia/features/relationships/indexing.rb +40 -42
  103. data/lib/familia/features/relationships/indexing_relationship.rb +17 -5
  104. data/lib/familia/features/relationships/participation/participant_methods.rb +131 -14
  105. data/lib/familia/features/relationships/participation/rebuild_strategies.md +41 -0
  106. data/lib/familia/features/relationships/participation/target_methods.rb +6 -6
  107. data/lib/familia/features/relationships/participation.rb +155 -69
  108. data/lib/familia/features/relationships/participation_membership.rb +69 -0
  109. data/lib/familia/features/relationships/participation_relationship.rb +34 -6
  110. data/lib/familia/features/relationships/score_encoding.rb +2 -0
  111. data/lib/familia/features/relationships.rb +5 -3
  112. data/lib/familia/features/safe_dump.rb +2 -0
  113. data/lib/familia/features/transient_fields/redacted_string.rb +2 -0
  114. data/lib/familia/features/transient_fields/single_use_redacted_string.rb +2 -0
  115. data/lib/familia/features/transient_fields/transient_field_type.rb +5 -3
  116. data/lib/familia/features/transient_fields.rb +2 -0
  117. data/lib/familia/features.rb +2 -0
  118. data/lib/familia/field_type.rb +5 -2
  119. data/lib/familia/horreum/connection.rb +28 -36
  120. data/lib/familia/horreum/database_commands.rb +131 -10
  121. data/lib/familia/horreum/definition.rb +18 -7
  122. data/lib/familia/horreum/management.rb +233 -57
  123. data/lib/familia/horreum/persistence.rb +314 -122
  124. data/lib/familia/horreum/related_fields.rb +2 -0
  125. data/lib/familia/horreum/serialization.rb +26 -4
  126. data/lib/familia/horreum/settings.rb +2 -0
  127. data/lib/familia/horreum/utils.rb +2 -8
  128. data/lib/familia/horreum.rb +46 -13
  129. data/lib/familia/identifier_extractor.rb +2 -0
  130. data/lib/familia/instrumentation.rb +156 -0
  131. data/lib/familia/json_serializer.rb +2 -0
  132. data/lib/familia/logging.rb +94 -37
  133. data/lib/familia/refinements/dear_json.rb +2 -0
  134. data/lib/familia/refinements/stylize_words.rb +2 -14
  135. data/lib/familia/refinements/time_literals.rb +2 -0
  136. data/lib/familia/refinements.rb +2 -0
  137. data/lib/familia/secure_identifier.rb +10 -2
  138. data/lib/familia/settings.rb +9 -7
  139. data/lib/familia/thread_safety/instrumented_mutex.rb +166 -0
  140. data/lib/familia/thread_safety/monitor.rb +328 -0
  141. data/lib/familia/utils.rb +13 -0
  142. data/lib/familia/verifiable_identifier.rb +3 -1
  143. data/lib/familia/version.rb +3 -1
  144. data/lib/familia.rb +31 -4
  145. data/lib/middleware/database_command_counter.rb +152 -0
  146. data/lib/middleware/database_logger.rb +325 -129
  147. data/lib/multi_result.rb +2 -0
  148. data/try/edge_cases/empty_identifiers_try.rb +2 -0
  149. data/try/edge_cases/hash_symbolization_try.rb +2 -0
  150. data/try/edge_cases/json_serialization_try.rb +2 -0
  151. data/try/edge_cases/legacy_data_detection/deserialization_edge_cases_try.rb +4 -0
  152. data/try/edge_cases/race_conditions_try.rb +4 -0
  153. data/try/edge_cases/reserved_keywords_try.rb +4 -0
  154. data/try/edge_cases/string_coercion_try.rb +6 -4
  155. data/try/edge_cases/ttl_side_effects_try.rb +4 -0
  156. data/try/features/encrypted_fields/aad_protection_try.rb +4 -0
  157. data/try/features/encrypted_fields/concealed_string_core_try.rb +4 -0
  158. data/try/features/encrypted_fields/context_isolation_try.rb +4 -0
  159. data/try/features/encrypted_fields/encrypted_fields_core_try.rb +33 -0
  160. data/try/features/encrypted_fields/encrypted_fields_integration_try.rb +4 -0
  161. data/try/features/encrypted_fields/encrypted_fields_no_cache_security_try.rb +4 -0
  162. data/try/features/encrypted_fields/encrypted_fields_security_try.rb +4 -0
  163. data/try/features/encrypted_fields/error_conditions_try.rb +4 -0
  164. data/try/features/encrypted_fields/fresh_key_derivation_try.rb +4 -0
  165. data/try/features/encrypted_fields/fresh_key_try.rb +4 -0
  166. data/try/features/encrypted_fields/key_rotation_try.rb +4 -0
  167. data/try/features/encrypted_fields/memory_security_try.rb +4 -0
  168. data/try/features/encrypted_fields/missing_current_key_version_try.rb +4 -0
  169. data/try/features/encrypted_fields/nonce_uniqueness_try.rb +4 -0
  170. data/try/features/encrypted_fields/secure_by_default_behavior_try.rb +4 -0
  171. data/try/features/encrypted_fields/thread_safety_try.rb +4 -0
  172. data/try/features/encrypted_fields/universal_serialization_safety_try.rb +4 -0
  173. data/try/features/encryption/config_persistence_try.rb +4 -0
  174. data/try/features/encryption/core_try.rb +4 -0
  175. data/try/features/encryption/instance_variable_scope_try.rb +4 -0
  176. data/try/features/encryption/module_loading_try.rb +4 -0
  177. data/try/features/encryption/providers/aes_gcm_provider_try.rb +4 -0
  178. data/try/features/encryption/providers/xchacha20_poly1305_provider_try.rb +4 -0
  179. data/try/features/encryption/roundtrip_validation_try.rb +4 -0
  180. data/try/features/encryption/secure_memory_handling_try.rb +4 -0
  181. data/try/features/expiration/expiration_try.rb +5 -1
  182. data/try/features/external_identifier/external_identifier_try.rb +171 -8
  183. data/try/features/feature_dependencies_try.rb +2 -0
  184. data/try/features/feature_improvements_try.rb +2 -0
  185. data/try/features/field_groups_try.rb +2 -0
  186. data/try/features/object_identifier/object_identifier_integration_try.rb +12 -9
  187. data/try/features/object_identifier/object_identifier_try.rb +2 -0
  188. data/try/features/quantization/quantization_try.rb +4 -0
  189. data/try/features/real_feature_integration_try.rb +2 -0
  190. data/try/features/relationships/indexing_commands_verification_try.rb +2 -0
  191. data/try/features/relationships/indexing_rebuild_try.rb +600 -0
  192. data/try/features/relationships/indexing_try.rb +30 -4
  193. data/try/features/relationships/participation_bidirectional_try.rb +242 -0
  194. data/try/features/relationships/participation_commands_verification_spec.rb +4 -0
  195. data/try/features/relationships/participation_commands_verification_try.rb +2 -0
  196. data/try/features/relationships/participation_performance_improvements_try.rb +11 -9
  197. data/try/features/relationships/participation_reverse_index_try.rb +15 -13
  198. data/try/features/relationships/participation_target_class_resolution_try.rb +209 -0
  199. data/try/features/relationships/participation_unresolved_target_try.rb +109 -0
  200. data/try/features/relationships/relationships_api_changes_try.rb +6 -4
  201. data/try/features/relationships/relationships_edge_cases_try.rb +4 -0
  202. data/try/features/relationships/relationships_performance_minimal_try.rb +4 -0
  203. data/try/features/relationships/relationships_performance_simple_try.rb +4 -0
  204. data/try/features/relationships/relationships_performance_try.rb +4 -0
  205. data/try/features/relationships/relationships_performance_working_try.rb +4 -0
  206. data/try/features/relationships/relationships_try.rb +6 -4
  207. data/try/features/safe_dump/safe_dump_advanced_try.rb +4 -0
  208. data/try/features/safe_dump/safe_dump_try.rb +4 -0
  209. data/try/features/transient_fields/redacted_string_try.rb +2 -0
  210. data/try/features/transient_fields/refresh_reset_try.rb +3 -0
  211. data/try/features/transient_fields/simple_refresh_test.rb +3 -0
  212. data/try/features/transient_fields/single_use_redacted_string_try.rb +2 -0
  213. data/try/features/transient_fields/transient_fields_core_try.rb +4 -0
  214. data/try/features/transient_fields/transient_fields_integration_try.rb +4 -0
  215. data/try/integration/connection/fiber_context_preservation_try.rb +7 -3
  216. data/try/integration/connection/handler_constraints_try.rb +4 -0
  217. data/try/integration/connection/isolated_dbclient_try.rb +4 -0
  218. data/try/integration/connection/middleware_reconnect_try.rb +2 -0
  219. data/try/integration/connection/operation_mode_guards_try.rb +5 -1
  220. data/try/integration/connection/pipeline_fallback_integration_try.rb +15 -12
  221. data/try/integration/connection/pools_try.rb +4 -0
  222. data/try/integration/connection/responsibility_chain_tracking_try.rb +4 -0
  223. data/try/integration/connection/transaction_fallback_integration_try.rb +4 -0
  224. data/try/integration/connection/transaction_mode_permissive_try.rb +4 -0
  225. data/try/integration/connection/transaction_mode_strict_try.rb +4 -0
  226. data/try/integration/connection/transaction_mode_warn_try.rb +4 -0
  227. data/try/integration/connection/transaction_modes_try.rb +4 -0
  228. data/try/integration/conventional_inheritance_try.rb +4 -0
  229. data/try/integration/create_method_try.rb +26 -22
  230. data/try/integration/cross_component_try.rb +4 -0
  231. data/try/integration/data_types/datatype_pipelines_try.rb +108 -0
  232. data/try/integration/data_types/datatype_transactions_try.rb +251 -0
  233. data/try/integration/database_consistency_try.rb +4 -0
  234. data/try/integration/familia_extended_try.rb +4 -0
  235. data/try/integration/familia_members_methods_try.rb +4 -0
  236. data/try/integration/models/customer_safe_dump_try.rb +9 -1
  237. data/try/integration/models/customer_try.rb +4 -0
  238. data/try/integration/models/datatype_base_try.rb +4 -0
  239. data/try/integration/models/familia_object_try.rb +5 -1
  240. data/try/integration/persistence_operations_try.rb +166 -10
  241. data/try/integration/relationships_persistence_round_trip_try.rb +17 -14
  242. data/try/integration/save_methods_consistency_try.rb +241 -0
  243. data/try/integration/scenarios_try.rb +4 -0
  244. data/try/integration/secure_identifier_try.rb +4 -0
  245. data/try/integration/transaction_safety_core_try.rb +176 -0
  246. data/try/integration/transaction_safety_workflow_try.rb +291 -0
  247. data/try/integration/verifiable_identifier_try.rb +4 -0
  248. data/try/investigation/pipeline_routing/README.md +228 -0
  249. data/try/performance/benchmarks_try.rb +4 -0
  250. data/try/performance/transaction_safety_benchmark_try.rb +238 -0
  251. data/try/support/benchmarks/deserialization_benchmark.rb +3 -1
  252. data/try/support/benchmarks/deserialization_correctness_test.rb +3 -1
  253. data/try/support/debugging/cache_behavior_tracer.rb +4 -0
  254. data/try/support/debugging/debug_aad_process.rb +3 -0
  255. data/try/support/debugging/debug_concealed_internal.rb +3 -0
  256. data/try/support/debugging/debug_concealed_reveal.rb +3 -0
  257. data/try/support/debugging/debug_context_aad.rb +3 -0
  258. data/try/support/debugging/debug_context_simple.rb +3 -0
  259. data/try/support/debugging/debug_cross_context.rb +3 -0
  260. data/try/support/debugging/debug_database_load.rb +3 -0
  261. data/try/support/debugging/debug_encrypted_json_check.rb +3 -0
  262. data/try/support/debugging/debug_encrypted_json_step_by_step.rb +3 -0
  263. data/try/support/debugging/debug_exists_lifecycle.rb +3 -0
  264. data/try/support/debugging/debug_field_decrypt.rb +3 -0
  265. data/try/support/debugging/debug_fresh_cross_context.rb +3 -0
  266. data/try/support/debugging/debug_load_path.rb +3 -0
  267. data/try/support/debugging/debug_method_definition.rb +3 -0
  268. data/try/support/debugging/debug_method_resolution.rb +3 -0
  269. data/try/support/debugging/debug_minimal.rb +3 -0
  270. data/try/support/debugging/debug_provider.rb +3 -0
  271. data/try/support/debugging/debug_secure_behavior.rb +3 -0
  272. data/try/support/debugging/debug_string_class.rb +3 -0
  273. data/try/support/debugging/debug_test.rb +3 -0
  274. data/try/support/debugging/debug_test_design.rb +3 -0
  275. data/try/support/debugging/encryption_method_tracer.rb +4 -0
  276. data/try/support/debugging/provider_diagnostics.rb +4 -0
  277. data/try/support/helpers/test_cleanup.rb +4 -0
  278. data/try/support/helpers/test_helpers.rb +5 -0
  279. data/try/support/memory/memory_basic_test.rb +4 -0
  280. data/try/support/memory/memory_detailed_test.rb +4 -0
  281. data/try/support/memory/memory_search_for_string.rb +4 -0
  282. data/try/support/memory/test_actual_redactedstring_protection.rb +4 -0
  283. data/try/support/prototypes/atomic_saves_v1_context_proxy.rb +4 -0
  284. data/try/support/prototypes/atomic_saves_v2_connection_switching.rb +4 -0
  285. data/try/support/prototypes/atomic_saves_v3_connection_pool.rb +4 -0
  286. data/try/support/prototypes/atomic_saves_v4.rb +4 -0
  287. data/try/support/prototypes/lib/atomic_saves_v2_connection_switching_helpers.rb +4 -0
  288. data/try/support/prototypes/lib/atomic_saves_v3_connection_pool_helpers.rb +4 -0
  289. data/try/support/prototypes/pooling/configurable_stress_test.rb +4 -0
  290. data/try/support/prototypes/pooling/lib/atomic_saves_v3_connection_pool_helpers.rb +4 -0
  291. data/try/support/prototypes/pooling/lib/connection_pool_metrics.rb +4 -0
  292. data/try/support/prototypes/pooling/lib/connection_pool_stress_test.rb +4 -0
  293. data/try/support/prototypes/pooling/lib/connection_pool_threading_models.rb +4 -0
  294. data/try/support/prototypes/pooling/lib/visualize_stress_results.rb +4 -2
  295. data/try/support/prototypes/pooling/pool_siege.rb +4 -2
  296. data/try/support/prototypes/pooling/run_stress_tests.rb +4 -2
  297. data/try/thread_safety/README.md +496 -0
  298. data/try/thread_safety/class_connection_chain_race_try.rb +265 -0
  299. data/try/thread_safety/connection_chain_race_try.rb +148 -0
  300. data/try/thread_safety/encryption_manager_cache_race_try.rb +166 -0
  301. data/try/thread_safety/feature_registry_race_try.rb +226 -0
  302. data/try/thread_safety/fiber_pipeline_isolation_try.rb +235 -0
  303. data/try/thread_safety/fiber_transaction_isolation_try.rb +208 -0
  304. data/try/thread_safety/field_registration_race_try.rb +222 -0
  305. data/try/thread_safety/logger_initialization_race_try.rb +170 -0
  306. data/try/thread_safety/middleware_registration_race_try.rb +154 -0
  307. data/try/thread_safety/module_config_race_try.rb +175 -0
  308. data/try/thread_safety/secure_identifier_cache_race_try.rb +226 -0
  309. data/try/unit/core/autoloader_try.rb +4 -0
  310. data/try/unit/core/base_enhancements_try.rb +4 -0
  311. data/try/unit/core/connection_try.rb +4 -0
  312. data/try/unit/core/errors_try.rb +4 -0
  313. data/try/unit/core/extensions_try.rb +4 -0
  314. data/try/unit/core/familia_logger_try.rb +2 -0
  315. data/try/unit/core/familia_try.rb +4 -0
  316. data/try/unit/core/middleware_sampling_try.rb +335 -0
  317. data/try/unit/core/middleware_test_helpers_bug_try.rb +58 -0
  318. data/try/unit/core/middleware_thread_safety_try.rb +245 -0
  319. data/try/unit/core/middleware_try.rb +4 -0
  320. data/try/unit/core/settings_try.rb +4 -0
  321. data/try/unit/core/time_utils_try.rb +4 -0
  322. data/try/unit/core/tools_try.rb +4 -0
  323. data/try/unit/core/utils_try.rb +37 -0
  324. data/try/unit/data_types/boolean_try.rb +5 -1
  325. data/try/unit/data_types/counter_try.rb +4 -0
  326. data/try/unit/data_types/datatype_base_try.rb +4 -0
  327. data/try/unit/data_types/hash_try.rb +4 -0
  328. data/try/unit/data_types/list_try.rb +4 -0
  329. data/try/unit/data_types/lock_try.rb +4 -0
  330. data/try/unit/data_types/sorted_set_try.rb +4 -0
  331. data/try/unit/data_types/sorted_set_zadd_options_try.rb +4 -0
  332. data/try/unit/data_types/string_try.rb +5 -1
  333. data/try/unit/data_types/unsortedset_try.rb +4 -0
  334. data/try/unit/familia_resolve_class_try.rb +116 -0
  335. data/try/unit/horreum/auto_indexing_on_save_try.rb +36 -16
  336. data/try/unit/horreum/automatic_index_validation_try.rb +255 -0
  337. data/try/unit/horreum/base_try.rb +5 -1
  338. data/try/unit/horreum/class_methods_try.rb +6 -2
  339. data/try/unit/horreum/commands_try.rb +4 -0
  340. data/try/unit/horreum/defensive_initialization_try.rb +4 -0
  341. data/try/unit/horreum/destroy_related_fields_cleanup_try.rb +4 -0
  342. data/try/unit/horreum/enhanced_conflict_handling_try.rb +4 -0
  343. data/try/unit/horreum/field_categories_try.rb +4 -0
  344. data/try/unit/horreum/field_definition_try.rb +4 -0
  345. data/try/unit/horreum/initialization_try.rb +5 -1
  346. data/try/unit/horreum/json_type_preservation_try.rb +2 -0
  347. data/try/unit/horreum/optimized_loading_try.rb +156 -0
  348. data/try/unit/horreum/relations_try.rb +8 -4
  349. data/try/unit/horreum/serialization_persistent_fields_try.rb +4 -0
  350. data/try/unit/horreum/serialization_try.rb +6 -2
  351. data/try/unit/horreum/settings_try.rb +4 -0
  352. data/try/unit/horreum/unique_index_edge_cases_try.rb +380 -0
  353. data/try/unit/horreum/unique_index_guard_validation_try.rb +283 -0
  354. data/try/unit/middleware/database_command_counter_methods_try.rb +139 -0
  355. data/try/unit/middleware/database_logger_methods_try.rb +251 -0
  356. data/try/unit/refinements/dear_json_array_methods_try.rb +4 -0
  357. data/try/unit/refinements/dear_json_hash_methods_try.rb +4 -0
  358. data/try/unit/refinements/time_literals_numeric_methods_try.rb +4 -0
  359. data/try/unit/refinements/time_literals_string_methods_try.rb +4 -0
  360. data/try/unit/thread_safety_monitor_try.rb +149 -0
  361. metadata +81 -14
  362. data/.github/workflows/code-quality.yml +0 -138
  363. data/docs/archive/FAMILIA_RELATIONSHIPS.md +0 -210
  364. data/docs/archive/FAMILIA_TECHNICAL.md +0 -823
  365. data/docs/archive/FAMILIA_UPDATE.md +0 -226
  366. data/docs/archive/README.md +0 -64
  367. data/docs/archive/api-reference.md +0 -333
  368. data/docs/guides/core-field-system.md +0 -806
  369. data/docs/guides/implementation.md +0 -276
  370. data/docs/guides/security-model.md +0 -183
@@ -1,226 +0,0 @@
1
- # Familia v2.0.0-pre Series Update Overview
2
-
3
- **Familia** is a Ruby ORM for Redis/Valkey that provides object mapping and persistence capabilities. This document summarizes the major updates from v2.0.0-pre through v2.0.0-pre7, representing a significant evolution with new features, security enhancements, and architectural improvements.
4
-
5
- ## Version Summary
6
-
7
- | Version | Focus | Key Features |
8
- |---------|-------|-------------|
9
- | v2.0.0-pre | Foundation | Modern API, Valkey support, connection pooling |
10
- | v2.0.0-pre5 | Security | Encrypted fields, transient fields, RedactedString |
11
- | v2.0.0-pre6 | Architecture | Horreum reorganization, enhanced persistence |
12
- | v2.0.0-pre7 | Relationships | Comprehensive relationship system, permissions |
13
-
14
- ---
15
-
16
- ## v2.0.0-pre - Foundation Release
17
-
18
- ### Major API Modernization
19
- - **Complete API redesign** for clarity and modern Ruby conventions
20
- - **Valkey compatibility** alongside traditional Valkey/Redis support
21
- - **Ruby 3.4+ modernization** with fiber and thread safety improvements
22
- - **Connection pooling foundation** with provider pattern architecture
23
-
24
- ### Security & Dependency Management
25
- - **Critical security fixes** in Ruby workflow vulnerabilities
26
- - **Systematic dependency resolution** via multi-constraint optimization
27
- - **GitHub Actions security hardening** with matrix optimization
28
-
29
- ### Documentation Infrastructure
30
- - **YARD documentation workflow** with automated GitHub Pages deployment
31
- - **Comprehensive wiki system** with structured documentation
32
- - **Developer-focused guides** for implementation and usage
33
-
34
- ---
35
-
36
- ## v2.0.0-pre5 - Security Enhancement Release
37
-
38
- ### Encrypted Fields System
39
- - **Field-level encryption** with transparent access patterns
40
- - **Multiple encryption providers**:
41
- - XChaCha20-Poly1305 (preferred, requires rbnacl)
42
- - AES-256-GCM (fallback, OpenSSL-based)
43
- - **Field-specific key derivation** for cryptographic domain separation
44
- - **Configurable key versioning** supporting key rotation
45
-
46
- ```ruby
47
- class Vault < Familia::Horreum
48
- feature :encrypted_fields
49
-
50
- field :name # Plaintext
51
- encrypted_field :secret_key # Encrypted at rest
52
- encrypted_field :api_token # Transparent access
53
- end
54
- ```
55
-
56
- ### Transient Fields & RedactedString
57
- - **Non-persistent field storage** for sensitive runtime data
58
- - **RedactedString wrapper** preventing accidental logging/serialization
59
- - **Memory-safe handling** of sensitive data in Ruby objects
60
- - **API-safe serialization** excluding transient fields
61
-
62
- ```ruby
63
- class User < Familia::Horreum
64
- feature :transient_fields
65
-
66
- field :email
67
- transient_field :password # Never persisted
68
- transient_field :session_token # Runtime only
69
- end
70
- ```
71
-
72
- ### Connection Pooling Enhancement
73
- - **Connection provider pattern** for flexible pooling strategies
74
- - **Multi-database support** with intelligent pool management
75
- - **Thread-safe connection handling** for concurrent applications
76
- - **Configurable pool sizing** and timeout management
77
-
78
- ---
79
-
80
- ## v2.0.0-pre6 - Architecture Enhancement Release
81
-
82
- ### Horreum Architecture Reorganization
83
- - **Modular class structure** with cleaner separation of concerns
84
- - **Enhanced feature system** with dependency management
85
- - **Improved inheritance patterns** for better code organization
86
- - **Streamlined base class functionality**
87
-
88
- ### Enhanced Persistence Operations
89
- - **New `save_if_not_exists` method** for conditional persistence
90
- - **Atomic persistence operations** with transaction support
91
- - **Enhanced error handling** for persistence failures
92
- - **Improved data consistency** guarantees
93
-
94
- ### Security Improvements
95
- - **Encryption field security hardening** with additional validation
96
- - **Enhanced memory protection** for sensitive data handling
97
- - **Improved key management** patterns and best practices
98
- - **Security test suite expansion** with comprehensive coverage
99
-
100
- ---
101
-
102
- ## v2.0.0-pre7 - Relationships & Permissions Release
103
-
104
- ### Comprehensive Relationships System
105
- - **Three relationship types** optimized for different use cases:
106
- - `participates_in` - Multi-presence tracking with score encoding
107
- - `indexed_by` - O(1) hash-based lookups
108
- - `member_of` - Bidirectional membership with collision-free naming
109
-
110
- ```ruby
111
- class Customer < Familia::Horreum
112
- feature :relationships
113
-
114
- identifier_field :custid
115
- field :custid, :name, :email
116
-
117
- # Define collections
118
- set :domains
119
- participates_in :active_users, type: :sorted_set
120
- end
121
-
122
- class Domain < Familia::Horreum
123
- feature :relationships
124
-
125
- identifier_field :domain_id
126
- field :domain_id, :name
127
-
128
- # Bidirectional relationship
129
- member_of Customer, :domains, type: :set
130
- end
131
- ```
132
-
133
- ### Categorical Permission System
134
- - **Bit-encoded permissions** for efficient storage and querying
135
- - **Time-based permission scoring** for temporal access control
136
- - **Permission tier hierarchies** with inheritance patterns
137
- - **Scalable permission management** for large object collections
138
-
139
- ### Advanced Relationship Features
140
- - **Score-based sorting** with custom scoring functions
141
- - **Permission-aware queries** filtering by access levels
142
- - **Relationship validation framework** ensuring data integrity
143
- - **Performance optimizations** for large-scale relationship operations
144
-
145
- ---
146
-
147
- ## Breaking Changes & Migration
148
-
149
- ### v2.0.0-pre Series
150
- - **API method renaming** for consistency and clarity
151
- - **Configuration changes** in connection management
152
- - **Feature activation syntax** updates for the new system
153
- - **Identifier field declaration** syntax modernization
154
-
155
- ### Security Considerations
156
- - **Encryption key configuration** required for encrypted fields
157
- - **Memory handling changes** for sensitive data protection
158
- - **Permission system migration** for existing relationship data
159
-
160
- ---
161
-
162
- ## Performance Improvements
163
-
164
- ### Connection Management
165
- - **Pool-based connections** reducing connection overhead
166
- - **Intelligent connection reuse** across operations
167
- - **Concurrent operation support** with thread-safe pooling
168
-
169
- ### Relationship Operations
170
- - **O(1) indexed lookups** for field-based queries
171
- - **Optimized sorted set operations** for scored relationships
172
- - **Batch relationship operations** for bulk updates
173
- - **Memory-efficient bit encoding** for permission storage
174
-
175
- ### Feature System
176
- - **Lazy feature loading** reducing memory footprint
177
- - **Dependency-aware activation** preventing conflicts
178
- - **Optimized method dispatch** for feature methods
179
-
180
- ---
181
-
182
- ## Migrating Guide Summary
183
-
184
- ### From v1.x to v2.0.0-pre
185
- 1. **Update connection configuration** to use new pooling system
186
- 2. **Migrate identifier declarations** to new syntax
187
- 3. **Update feature activations** to use `feature :name` syntax
188
- 4. **Review method calls** for renamed API methods
189
-
190
- ### Security Feature Adoption
191
- 1. **Configure encryption keys** for encrypted fields
192
- 2. **Identify sensitive fields** for encryption/transient marking
193
- 3. **Update serialization code** to handle RedactedString
194
- 4. **Implement key rotation procedures** for production systems
195
-
196
- ### Relationship System Migration
197
- 1. **Analyze existing relationships** for optimization opportunities
198
- 2. **Choose appropriate relationship types** based on usage patterns
199
- 3. **Implement permission systems** for access-controlled relationships
200
- 4. **Update queries** to use new relationship methods
201
-
202
- ---
203
-
204
- ## Next Steps & Roadmap
205
-
206
- ### Immediate (v2.0.0 Final)
207
- - **Production stability** testing and bug fixes
208
- - **Performance benchmarking** and optimization
209
- - **Documentation completion** for all features
210
- - **Migration tooling** for existing applications
211
-
212
- ### Future Releases
213
- - **Advanced encryption features** with hardware security modules
214
- - **Extended relationship types** for specialized use cases
215
- - **Performance analytics** and monitoring integration
216
- - **Cloud-native deployment** patterns and examples
217
-
218
- ---
219
-
220
- ## Resources
221
-
222
- - [GitHub Repository](https://github.com/delano/familia)
223
- - [Wiki Documentation](https://github.com/delano/familia/wiki)
224
- - [API Reference](docs/wiki/API-Reference.md)
225
- - [Implementation Guide](docs/wiki/Implementation-Guide.md)
226
- - [Security Model](docs/wiki/Security-Model.md)
@@ -1,64 +0,0 @@
1
- # Archived Documentation
2
-
3
- This directory contains original documentation files that have either been migrated to the new Scriv-based changelog system or incorporated into other documents.
4
-
5
- ## Migration Date
6
- **Sept 22, 1015** - Deprecated api-reference.md, to reduce surface area for stale documentation to hide.
7
- **Sept 1, 2025** - As part of implementing [Issue #84: Scriv-based changelog system](https://github.com/delano/familia/issues/84)
8
-
9
- ## Archived Files
10
-
11
- ### FAMILIA_UPDATE.md
12
- **Original Purpose:** Version summary table and detailed release notes for v2.0.0-pre series
13
-
14
- **Migrating Destinations:**
15
- - **Changelog entries** → Extracted to Scriv fragments, aggregated into `CHANGELOG.md`
16
- - **Migrating guides** → Reorganized into `docs/migrating/v2.0.0-pre*.md`
17
- - **Feature descriptions** → Cross-referenced with existing feature guides in `docs/guides/`
18
-
19
- ### FAMILIA_RELATIONSHIPS.md
20
- **Original Purpose:** Auto-generated relationship methods reference
21
-
22
- **Migration Destination:**
23
- - **Complete content** → Moved to `docs/guides/relationships-methods.md`
24
- - **Cross-referenced** with existing `docs/guides/Relationships-Guide.md`
25
-
26
- ### FAMILIA_TECHNICAL.md
27
- **Original Purpose:** Technical API reference for v2.0.0-pre series classes and methods
28
-
29
- **Migration Destination:**
30
- - **Core technical content** → Moved to `docs/reference/api-technical.md`
31
- - **Cross-referenced** with existing `docs/guides/API-Reference.md`
32
-
33
- ## New Documentation Structure
34
-
35
- ```
36
- docs/
37
- ├── migrating/ # Version-specific migrating guides
38
- │ ├── v2.0.0-pre.md
39
- │ ├── v2.0.0-pre5.md # Security features
40
- │ ├── v2.0.0-pre6.md # Architecture improvements
41
- │ └── v2.0.0-pre7.md # Relationships system
42
-
43
- ├── guides/ # Feature-specific guides (moved from wiki/)
44
- │ ├── relationships.md # From FAMILIA_RELATIONSHIPS.md
45
- │ └── [other guides...]
46
-
47
- ├── reference/ # Technical reference
48
- │ └── api-technical.md
49
-
50
- └── archive/ # This directory
51
- ```
52
-
53
- ## Finding Migrated Content
54
-
55
- - **Version changes** → Check `CHANGELOG.md` (generated from fragments)
56
- - **How to upgrade** → See `docs/migration/` for version-specific guides
57
- - **Feature usage** → See `docs/guides/` for implementation examples
58
- - **API reference** → See `docs/reference/` for technical details
59
-
60
- ## References
61
-
62
- - [Issue #84](https://github.com/delano/familia/issues/84) - Original migration plan
63
- - [Scriv Documentation](https://scriv.readthedocs.io/) - Changelog management tool
64
- - [Keep a Changelog](https://keepachangelog.com/) - Changelog format standard
@@ -1,333 +0,0 @@
1
- # API Reference
2
-
3
- > [!NOTE]
4
- > This document is deprecated. For comprehensive encryption API documentation, see [`docs/reference/api-technical.md`](../reference/api-technical.md) which contains complete implementation details and examples.
5
-
6
- ## Class Methods
7
-
8
- ### encrypted_field
9
-
10
- Defines an encrypted field on a Familia::Horreum class.
11
-
12
- ```ruby
13
- encrypted_field(name, aad_fields: [], **options)
14
- ```
15
-
16
- **Parameters:**
17
- - `name` (Symbol) - Field name
18
- - `aad_fields` (Array<Symbol>) - Additional fields to include in authentication
19
- - `**options` (Hash) - Standard field options
20
-
21
- **Example:**
22
- ```ruby
23
- class User < Familia::Horreum
24
- feature :encrypted_fields
25
-
26
- encrypted_field :favorite_snack
27
- encrypted_field :api_key
28
- encrypted_field :notes, aad_fields: [:user_id, :email] # With tamper protection
29
- end
30
- ```
31
-
32
- ### encrypted_fields
33
-
34
- Returns list of encrypted field names.
35
-
36
- ```ruby
37
- User.encrypted_fields # => [:favorite_snack, :api_key]
38
- ```
39
-
40
- ## Instance Methods
41
-
42
- ### Field Accessors
43
-
44
- Encrypted fields provide standard accessors that return ConcealedString objects:
45
-
46
- ```ruby
47
- user.favorite_snack # Returns ConcealedString (safe for logging)
48
- user.favorite_snack.reveal # Get actual decrypted value
49
- user.favorite_snack = value # Set and encrypt value
50
- user.favorite_snack! # Fast write (still encrypted)
51
- ```
52
-
53
- **ConcealedString Methods:**
54
- ```ruby
55
- concealed = user.favorite_snack
56
- concealed.to_s # => "[CONCEALED]" (safe for logging)
57
- concealed.reveal # => "actual value"
58
- concealed.clear! # Clear from memory
59
- concealed.cleared? # Check if cleared
60
- ```
61
-
62
- ## Familia::Encryption Module
63
-
64
- ### with_request_cache
65
-
66
- Enables key derivation caching for performance optimization:
67
-
68
- ```ruby
69
- Familia::Encryption.with_request_cache do
70
- # Multiple encryption operations reuse derived keys
71
- user.secret_one = "value1"
72
- user.secret_two = "value2"
73
- user.save
74
- end
75
- ```
76
-
77
- ### clear_request_cache!
78
-
79
- Manually clears the request-level key cache:
80
-
81
- ```ruby
82
- Familia::Encryption.clear_request_cache!
83
- ```
84
-
85
- ### encrypt / decrypt
86
-
87
- Low-level encryption methods (typically used internally):
88
-
89
- ```ruby
90
- # Encrypt with context for key derivation
91
- encrypted = Familia::Encryption.encrypt(plaintext,
92
- context: "User:favorite_snack:user123",
93
- additional_data: nil
94
- )
95
-
96
- # Decrypt (auto-detects algorithm from JSON)
97
- decrypted = Familia::Encryption.decrypt(encrypted_json,
98
- context: "User:favorite_snack:user123",
99
- additional_data: nil
100
- )
101
- ```
102
-
103
- ### status
104
-
105
- Returns current encryption configuration and available providers.
106
-
107
- ```ruby
108
- Familia::Encryption.status
109
- # => {
110
- # default_algorithm: "xchacha20poly1305",
111
- # available_algorithms: ["xchacha20poly1305", "aes-256-gcm"],
112
- # preferred_available: "Familia::Encryption::Providers::XChaCha20Poly1305Provider",
113
- # using_hardware: false,
114
- # key_versions: [:v1],
115
- # current_version: :v1
116
- # }
117
- ```
118
-
119
- ### benchmark
120
-
121
- Benchmarks available providers.
122
-
123
- ```ruby
124
- Familia::Encryption.benchmark(iterations: 1000)
125
- # => {
126
- # "xchacha20poly1305" => { time: 0.45, ops_per_sec: 4444, priority: 100 },
127
- # "aes-256-gcm" => { time: 0.52, ops_per_sec: 3846, priority: 50 }
128
- # }
129
- ```
130
-
131
- ### validate_configuration!
132
-
133
- Validates encryption configuration at startup.
134
-
135
- ```ruby
136
- Familia::Encryption.validate_configuration!
137
- # Raises Familia::EncryptionError if configuration invalid
138
- ```
139
-
140
- ### derivation_count / reset_derivation_count!
141
-
142
- Monitors key derivation operations (for testing and debugging).
143
-
144
- ```ruby
145
- # Check how many key derivations have occurred
146
- count = Familia::Encryption.derivation_count.value
147
- # => 42
148
-
149
- # Reset counter
150
- Familia::Encryption.reset_derivation_count!
151
- ```
152
-
153
- ## Familia::Encryption::Manager
154
-
155
- Low-level manager class for direct provider control.
156
-
157
- ### initialize
158
-
159
- ```ruby
160
- # Use default provider
161
- manager = Familia::Encryption::Manager.new
162
-
163
- # Use specific algorithm
164
- manager = Familia::Encryption::Manager.new(algorithm: 'aes-256-gcm')
165
- ```
166
-
167
- ### encrypt / decrypt
168
-
169
- Same interface as module-level methods but tied to specific provider.
170
-
171
- ## Familia::Encryption::Registry
172
-
173
- Provider management system.
174
-
175
- ### setup!
176
-
177
- Registers all available providers.
178
-
179
- ### get
180
-
181
- Returns provider instance by algorithm name.
182
-
183
- ### default_provider
184
-
185
- Returns highest-priority available provider instance.
186
-
187
- ### available_algorithms
188
-
189
- Returns array of available algorithm names.
190
-
191
- ## Configuration
192
-
193
- ### Familia.configure
194
-
195
- ```ruby
196
- Familia.configure do |config|
197
- # Single key configuration
198
- config.encryption_keys = {
199
- v1: ENV['FAMILIA_ENCRYPTION_KEY']
200
- }
201
- config.current_key_version = :v1
202
-
203
- # Multi-version configuration for key rotation
204
- config.encryption_keys = {
205
- v1_2024: ENV['OLD_KEY'],
206
- v2_2025: ENV['NEW_KEY']
207
- }
208
- config.current_key_version = :v2_2025
209
-
210
- # Optional personalization (XChaCha20-Poly1305 only)
211
- config.encryption_personalization = 'MyApp-2024'
212
- end
213
-
214
- # Always validate configuration
215
- Familia::Encryption.validate_configuration!
216
- ```
217
-
218
- ## Data Types
219
-
220
- ### EncryptedData
221
-
222
- Internal data structure for encrypted values.
223
-
224
- ```ruby
225
- EncryptedData = Data.define(
226
- :library, # "libsodium" or "openssl"
227
- :algorithm, # "xchacha20poly1305" or "aes-256-gcm"
228
- :nonce, # Base64-encoded nonce/IV
229
- :ciphertext, # Base64-encoded ciphertext
230
- :key_version # Key version identifier
231
- )
232
- ```
233
-
234
- ### ConcealedString
235
-
236
- String-like object that conceals sensitive data in output and provides memory safety.
237
-
238
- ```ruby
239
- class ConcealedString
240
- def reveal
241
- # Returns actual decrypted string value
242
- end
243
-
244
- def to_s
245
- '[CONCEALED]'
246
- end
247
-
248
- def inspect
249
- '[CONCEALED]'
250
- end
251
-
252
- def clear!
253
- # Best-effort memory wiping
254
- end
255
-
256
- def cleared?
257
- # Returns true if cleared from memory
258
- end
259
- end
260
- ```
261
-
262
- ## Exceptions
263
-
264
- ### Familia::EncryptionError
265
-
266
- Raised for encryption/decryption failures.
267
-
268
- ```ruby
269
- begin
270
- user.decrypt_field(:favorite_snack)
271
- rescue Familia::EncryptionError => e
272
- case e.message
273
- when /key version/
274
- # Handle key version mismatch
275
- when /authentication/
276
- # Handle tampering
277
- else
278
- # Handle other errors
279
- end
280
- end
281
- ```
282
-
283
- ## Instance Methods
284
-
285
- ### encrypted_data?
286
-
287
- Check if any encrypted fields have values:
288
-
289
- ```ruby
290
- user.encrypted_data? # => true if any encrypted fields have values
291
- ```
292
-
293
- ### clear_encrypted_fields!
294
-
295
- Clear all encrypted field values from memory:
296
-
297
- ```ruby
298
- user.clear_encrypted_fields! # Clear all ConcealedString values
299
- ```
300
-
301
- ### encrypted_fields_cleared?
302
-
303
- Check if all encrypted fields have been cleared:
304
-
305
- ```ruby
306
- user.encrypted_fields_cleared? # => true if all cleared
307
- ```
308
-
309
- ### re_encrypt_fields!
310
-
311
- Re-encrypt all encrypted fields with current key version:
312
-
313
- ```ruby
314
- user.re_encrypt_fields! # Uses current_key_version
315
- user.save
316
- ```
317
-
318
- ### encrypted_fields_status
319
-
320
- Get encryption status for debugging:
321
-
322
- ```ruby
323
- user.encrypted_fields_status
324
- # => {
325
- # ssn: { encrypted: true, cleared: false },
326
- # credit_card: { encrypted: true, cleared: true }
327
- # }
328
- ```
329
-
330
- ---
331
-
332
- > [!IMPORTANT]
333
- > For complete implementation details, configuration examples, and advanced usage patterns, see the comprehensive documentation in [`docs/reference/api-technical.md`](../reference/api-technical.md).