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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e5bbf0ac2fc6a1243d74f679c7027040be00783af625dd90d376637e32417394
4
- data.tar.gz: 4b354347a0c2403490dc20fdc12f93b3e71b826cf0b2b08638f6fd884a883630
3
+ metadata.gz: 07042bac6b1c1cb48aa4110964f76fcb1bd030b5814d09077e71458528982fc4
4
+ data.tar.gz: 1cc64f41698963091108f48f45a8af7be8e77473aacae2ccd734175be84f2a45
5
5
  SHA512:
6
- metadata.gz: 221116e1aa14bc7114cb51164727587dcb0e8435dd8b85bb7d14618393ef446446376fd7febf6dbc9993098e2c819b3b0aa6f3c8bedce1c965b99ec4c8832a7b
7
- data.tar.gz: 457b0e5bfef1f203c8f2edf934d1ee37915df04c49b0cb8b097ab9732738186ba9e8e92496851699f0952426971d2d3d244e61e594719439672996a0ccde2050
6
+ metadata.gz: 4c2a76ca3e47aff299fcb51ac56fa8b3c6701135921a99228cefe8eb770a8455b0b237849fbd85cb60b8e6bb3d436abe20d7afc384acc6e0e8e7f2ad3ba05d65
7
+ data.tar.gz: 1c3a6b8ccb9479d701eb98f4b00d700c1e05978d29b0247ce83937471c3ab7a8df515ba1b387ceaf1dc7cfd56f7a8cdabee0b6038093eb5595c69babb6670a27
@@ -2,13 +2,8 @@ name: Claude Code Review
2
2
 
3
3
  on:
4
4
  pull_request:
5
- types: [opened, synchronize]
6
- # Optional: Only run on specific file changes
7
- # paths:
8
- # - "src/**/*.ts"
9
- # - "src/**/*.tsx"
10
- # - "src/**/*.js"
11
- # - "src/**/*.jsx"
5
+ types: [opened, synchronize, labeled]
6
+ workflow_dispatch:
12
7
 
13
8
  jobs:
14
9
  claude-review:
@@ -40,7 +35,7 @@ jobs:
40
35
  # Optional: Use sticky comments to make Claude reuse the same comment on subsequent pushes to the same PR
41
36
  use_sticky_comment: true
42
37
 
43
- prompt: |
38
+ direct_prompt: |
44
39
  Please review this pull request and provide feedback on:
45
40
  - Code quality and best practices
46
41
  - Potential bugs or issues
@@ -54,4 +49,4 @@ jobs:
54
49
 
55
50
  # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
56
51
  # or https://docs.anthropic.com/en/docs/claude-code/sdk#command-line for available options
57
- claude_args: '--allowed-tools "Bash(gh issue view:*),Bash(gh search:*),Bash(gh issue list:*),Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh pr list:*)"'
52
+ allowed_tools: "Bash(gh issue view:*),Bash(gh search:*),Bash(gh issue list:*),Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh pr list:*)"
@@ -1,4 +1,4 @@
1
- # ..github/workflows/code-smells.yml
1
+ # .github/workflows/code-smells.yml
2
2
  ---
3
3
  name: Code Smells
4
4
 
@@ -14,7 +14,7 @@ permissions:
14
14
  pull-requests: write # Needed to post comments on PRs
15
15
 
16
16
  jobs:
17
- reek:
17
+ reek-analysis:
18
18
  name: Reek Code Analysis
19
19
  runs-on: ubuntu-24.04
20
20
  timeout-minutes: 5
@@ -52,7 +52,7 @@ jobs:
52
52
  echo "=== Reek analysis complete ==="
53
53
  continue-on-error: true # Don't fail the build on code smells
54
54
 
55
- - name: Generate Reek report (if analysis available)
55
+ - name: Generate Reek report
56
56
  run: |
57
57
  echo "=== Generating detailed Reek report ==="
58
58
 
@@ -83,3 +83,64 @@ jobs:
83
83
  reek-report.html
84
84
  if-no-files-found: ignore
85
85
  retention-days: 30
86
+
87
+ additional-checks:
88
+ name: Additional Quality Checks
89
+ runs-on: ubuntu-24.04
90
+ timeout-minutes: 5
91
+
92
+ steps:
93
+ - name: Checkout code
94
+ uses: actions/checkout@v4
95
+
96
+ - name: Set up Ruby
97
+ uses: ruby/setup-ruby@v1
98
+ with:
99
+ ruby-version: 3.4
100
+ bundler-cache: true
101
+
102
+ - name: Configure Bundler for secure gem installation
103
+ run: |
104
+ bundle config set --local path 'vendor/bundle'
105
+ bundle config set --local deployment 'false'
106
+
107
+ - name: Install dependencies
108
+ run: bundle install --jobs 4 --retry 3
109
+
110
+ - name: Check for TODO/FIXME comments
111
+ run: |
112
+ echo "=== Scanning for TODO/FIXME comments ==="
113
+ echo "This helps track technical debt and action items."
114
+ echo ""
115
+
116
+ # Find TODO/FIXME comments (excluding vendor and tmp directories)
117
+ find . -name "*.rb" -not -path "./vendor/*" -not -path "./tmp/*" | \
118
+ xargs grep -Hn -i -E "(TODO|FIXME|HACK|XXX|NOTE):" 2>/dev/null | \
119
+ head -20 || echo "No TODO/FIXME comments found"
120
+ continue-on-error: true
121
+
122
+ - name: Check Ruby file syntax
123
+ run: |
124
+ echo "=== Checking Ruby syntax ==="
125
+ echo "Validates that all Ruby files have correct syntax."
126
+ echo ""
127
+
128
+ find . -name "*.rb" -not -path "./vendor/*" -not -path "./tmp/*" | \
129
+ while read -r file; do
130
+ if ! ruby -c "$file" > /dev/null 2>&1; then
131
+ echo "Syntax error in: $file"
132
+ ruby -c "$file"
133
+ fi
134
+ done
135
+ continue-on-error: true
136
+
137
+ - name: Check for long lines
138
+ run: |
139
+ echo "=== Checking for long lines (>120 characters) ==="
140
+ echo "Identifies potentially hard-to-read code lines."
141
+ echo ""
142
+
143
+ find . -name "*.rb" -not -path "./vendor/*" -not -path "./tmp/*" | \
144
+ xargs grep -Hn "^.\{121,\}$" | \
145
+ head -10 || echo "No overly long lines found"
146
+ continue-on-error: true
@@ -65,13 +65,15 @@ repos:
65
65
  env:
66
66
  TALISMAN_SCAN_MODE: CI
67
67
 
68
- - repo: https://github.com/avilaton/add-msg-issue-prefix-hook
69
- rev: v0.0.11
68
+ # Commit message issue tracking integration
69
+ - repo: https://github.com/delano/add-msg-issue-prefix-hook
70
+ rev: v0.0.14-fork
70
71
  hooks:
71
72
  - id: add-msg-issue-prefix
72
73
  stages: [prepare-commit-msg]
73
- name: Link commit to Github issue
74
+ description: Automatically prefix commits with issue numbers
74
75
  args:
75
- - "--default="
76
- - "--pattern=[a-zA-Z0-9]{0,10}-?[0-9]{1,5}"
77
- - "--template=[#{}]"
76
+ - '--default='
77
+ - '--exclude-pattern=^(dependabot|renovate|claude)/'
78
+ - '--pattern=(i18n(?=/)|([a-zA-Z0-9]{0,10}-?[0-9]{1,5}))'
79
+ - '--template=[#{}]'
data/.reek.yml CHANGED
@@ -1,10 +1,11 @@
1
1
  # .reek.yml
2
- # Reek configuration for Familia
2
+ #
3
+ # Reek configuration for Rhales
3
4
  #
4
5
  # Basic commands:
5
6
  # bundle exec reek # Analyze all Ruby files
6
7
  # bundle exec reek lib/ # Analyze specific directory
7
- # bundle exec reek lib/familia/horreum.rb # Analyze specific file
8
+ # bundle exec reek lib/rhales.rb # Analyze specific file
8
9
  # bundle exec reek --help # Show all options
9
10
  # bundle exec reek --docs # Open documentation
10
11
  #
@@ -60,16 +61,16 @@ detectors:
60
61
  UncommunicativeParameterName:
61
62
  enabled: true
62
63
  reject:
63
- - '/^.$/' # Single letter names
64
- - '/[0-9]$/' # Names ending in numbers
65
- - '/^_/' # Names starting with underscore (common Ruby pattern)
64
+ - "/^.$/" # Single letter names
65
+ - "/[0-9]$/" # Names ending in numbers
66
+ - "/^_/" # Names starting with underscore (common Ruby pattern)
66
67
  accept: []
67
68
 
68
69
  UncommunicativeVariableName:
69
70
  enabled: true
70
71
  reject:
71
- - '/^.$/' # Single letter names
72
- - '/[0-9]$/' # Names ending in numbers
72
+ - "/^.$/" # Single letter names
73
+ - "/[0-9]$/" # Names ending in numbers
73
74
  accept:
74
75
  - e # Exception variable
75
76
  - id # Common identifier
@@ -80,8 +81,8 @@ detectors:
80
81
  UncommunicativeMethodName:
81
82
  enabled: true
82
83
  reject:
83
- - '/^.$/' # Single letter method names
84
- - '/[0-9]$/' # Methods ending in numbers
84
+ - "/^.$/" # Single letter method names
85
+ - "/[0-9]$/" # Methods ending in numbers
85
86
  accept:
86
87
  - "<<" # Common Ruby operator overload
87
88
 
data/.rubocop.yml CHANGED
@@ -88,6 +88,10 @@ Layout/EndAlignment:
88
88
  Layout/FirstArgumentIndentation:
89
89
  EnforcedStyle: consistent
90
90
 
91
+ Layout/ExtraSpacing:
92
+ Enabled: true
93
+ AllowBeforeTrailingComments: true
94
+
91
95
  Metrics/AbcSize:
92
96
  Enabled: false
93
97
  Max: 20
data/CHANGELOG.rst CHANGED
@@ -1,17 +1,187 @@
1
1
  CHANGELOG.rst
2
2
  =============
3
3
 
4
- All notable changes to Familia are documented here.
5
-
6
- The format is based on `Keep a
7
- Changelog <https://keepachangelog.com/en/1.1.0/>`__, and this project
8
- adheres to `Semantic
9
- Versioning <https://semver.org/spec/v2.0.0.html>`__.
4
+ The format is based on `Keep a Changelog <https://keepachangelog.com/en/1.1.0/>`__, and this project adheres to `Semantic Versioning <https://semver.org/spec/v2.0.0.html>`__.
10
5
 
11
6
  .. raw:: html
12
7
 
13
8
  <!--scriv-insert-here-->
14
9
 
10
+ .. _changelog-2.0.0.pre21:
11
+
12
+ 2.0.0.pre21 — 2025-10-21
13
+ ========================
14
+
15
+ Added
16
+ -----
17
+
18
+ - Pipeline Routing Investigation: Created 7 diagnostic testcases in ``try/investigation/pipeline_routing/`` to investigate suspected middleware routing issue. Investigation revealed single-command pipelines don't have ' | ' separator (expected Array#join behavior), confirming no routing bug exists. Full analysis documented in ``CONCLUSION.md``.
19
+
20
+ Changed
21
+ -------
22
+
23
+ - **BREAKING**: Duration measurements now use integer microseconds instead of milliseconds. Instrumentation hooks and logging output have changed format:
24
+
25
+ - ``Familia.on_command`` receives ``duration`` in microseconds (was ``duration_ms`` in milliseconds)
26
+ - ``Familia.on_pipeline`` receives ``duration`` in microseconds (was ``duration_ms`` in milliseconds)
27
+ - ``Familia.on_lifecycle`` uses ``duration`` key in microseconds (was ``duration_ms`` in milliseconds)
28
+ - Log messages show ``duration=1234`` (microseconds) instead of ``duration_ms=1.23`` (milliseconds)
29
+
30
+ - Migration: Convert to milliseconds when needed: ``duration / 1000.0``
31
+
32
+ Fixed
33
+ -----
34
+
35
+ - Connection Chain Race Condition: Fixed race condition in connection chain initialization where concurrent calls could create multiple instances. Added thread-safe protection to ensure proper singleton behavior.
36
+
37
+ - Thread Safety Test Suite: Corrected test assertions to properly verify thread safety invariants.
38
+
39
+
40
+ AI Assistance
41
+ -------------
42
+
43
+ - Claude Code assisted with analyzing test failures, identifying and fixing the connection chain race condition with Mutex protection, correcting test assertions to verify proper thread safety invariants, and creating diagnostic testcases to investigate pipeline routing behavior.
44
+
45
+
46
+
47
+ .. _changelog-2.0.0.pre20:
48
+
49
+ 2.0.0.pre20 — 2025-10-20
50
+ ========================
51
+
52
+ Added
53
+ -----
54
+
55
+ - **Instrumentation Hooks**: New ``Familia::Instrumentation`` module provides hooks for Redis commands, pipeline operations, lifecycle events, and errors. Applications can now register callbacks for audit trails and performance monitoring.
56
+
57
+ - **DatabaseLogger Structured Mode**: Added ``DatabaseLogger.structured_logging`` mode that outputs Redis commands with structured key=value context instead of formatted string output.
58
+
59
+ - **DatabaseLogger Sampling**: Added ``DatabaseLogger.sample_rate`` for controlling log volume in high-traffic scenarios. Set to 0.1 for 10% sampling, 0.01 for 1% sampling, or nil to disable. Command capture for testing remains unaffected.
60
+
61
+ - **Lifecycle Logging**: Horreum initialize, save, and destroy operations now log with timing and structured context when ``FAMILIA_DEBUG`` is enabled.
62
+
63
+ - **Operational Logging**: TTL operations and serialization errors now include structured context for better debugging.
64
+
65
+ Changed
66
+ -------
67
+
68
+ - Refactored ``save`` and ``save_if_not_exists!`` to use shared helper methods (``prepare_for_save`` and ``persist_to_storage``) to eliminate code duplication and ensure consistency. Both methods now follow the same preparation and persistence logic, differing only in their concurrency control patterns (simple transaction vs. optimistic locking with WATCH).
69
+
70
+ - **Structured Logging**: Replaced internal logging methods (``Familia.ld``, ``Familia.le``) with structured logging methods (``Familia.debug``, ``Familia.info``, ``Familia.error``) that support keyword context for operational observability.
71
+
72
+ Removed
73
+ -------
74
+
75
+ - **Internal Methods**: Removed ``Familia.ld`` and ``Familia.le`` internal logging methods. These were never part of the public API.
76
+
77
+ Fixed
78
+ -----
79
+
80
+ - Fixed ``save_if_not_exists!`` to perform the same operations as ``save`` when creating new objects. Previously, ``save_if_not_exists!`` omitted timestamp updates (``created``/``updated``), unique index validation (``guard_unique_indexes!``), and adding to the instances collection. Now both methods produce identical results when saving a new object, with ``save_if_not_exists`` only differing in its conditional existence check.
81
+
82
+ - Fixed ``save_if_not_exists!`` return value to correctly return ``true`` when successfully saving new objects. Previously returned ``false`` despite successful persistence due to incorrect handling of transaction result.
83
+
84
+ Documentation
85
+ -------------
86
+
87
+ - Streamlined inline documentation for ``save``, ``save_if_not_exists!``, and ``save_if_not_exists`` methods to be more concise, internally consistent, and non-redundant. Each method's documentation now stands on its own with clear, focused descriptions.
88
+
89
+ AI Assistance
90
+ -------------
91
+
92
+ - Claude Code identified the inconsistencies between ``save`` and ``save_if_not_exists!`` methods, implemented the fixes, refactored both methods to extract shared logic into private helper methods (``prepare_for_save`` and ``persist_to_storage``), and updated the documentation to be more concise and internally consistent.
93
+
94
+
95
+
96
+ This implementation was completed with significant AI assistance from Claude (Anthropic), including:
97
+
98
+ - Architecture design for the instrumentation hook system
99
+ - Implementation of structured logging methods with backward-compatible signatures
100
+ - Integration of hooks into DatabaseLogger middleware
101
+ - Bulk replacement of 51 logging method calls across 21 files
102
+ - Comprehensive code review and bug fixes (RedisClient::Config object vs hash handling)
103
+ - Documentation and changelog creation
104
+
105
+ The AI provided discussion, rubber ducking, code generation, testing strategy, and documentation throughout the implementation process.
106
+
107
+ Developer Notes
108
+ ---------------
109
+
110
+ This is a clean break for v2.0 with no deprecation warnings, as the removed methods were internal-only. Applications using the public API are unaffected.
111
+
112
+ **Migration**: No action required for external users. Internal development references to ``Familia.ld`` should use ``Familia.debug``, and ``Familia.le`` should use ``Familia.error``.
113
+
114
+ **New Capabilities**: Applications can now register instrumentation hooks for operational observability:
115
+
116
+ .. code-block:: ruby
117
+
118
+ # Enable structured logging with 10% sampling for production
119
+ Familia.logger = Rails.logger
120
+ DatabaseLogger.structured_logging = true
121
+ DatabaseLogger.sample_rate = 0.1 # Log 10% of commands
122
+
123
+ # Register hooks for audit trails
124
+ Familia.on_command do |cmd, duration_ms, context|
125
+ AuditLog.create!(
126
+ event: 'redis_command',
127
+ command: cmd,
128
+ duration_ms: duration_ms,
129
+ user_id: RequestContext.current_user_id
130
+ )
131
+ end
132
+
133
+ Familia.on_lifecycle do |event, instance, context|
134
+ case event
135
+ when :save
136
+ AuditLog.create!(event: 'object_saved', object_id: instance.identifier)
137
+ when :destroy
138
+ AuditLog.create!(event: 'object_destroyed', object_id: instance.identifier)
139
+ end
140
+ end
141
+
142
+ .. _changelog-2.0.0.pre19:
143
+
144
+ 2.0.0.pre19 — 2025-10-13
145
+ ========================
146
+
147
+ Added
148
+ -----
149
+
150
+ - **DataType Transaction and Pipeline Support** - DataType objects can now initiate transactions and pipelines independently, enabling atomic operations and batch command execution. `PR #159 <https://github.com/familia/familia/pull/159>`_
151
+
152
+ * ``transaction`` and ``pipelined`` methods for all DataType classes
153
+ * Connection chain pattern with ``ParentDelegationHandler`` and ``StandaloneConnectionHandler``
154
+ * Enhanced ``direct_access`` method with automatic context detection
155
+ * Shared ``Familia::Connection::Behavior`` module for common functionality
156
+
157
+ - **Automatic Unique Index Validation** - Instance-scoped unique indexes now validate automatically in ``add_to_*`` methods, with transaction detection to prevent ``save()`` calls within MULTI/EXEC blocks
158
+
159
+ Changed
160
+ -------
161
+
162
+ - **Connection Architecture** - Refactored to share ``Familia::Connection::Behavior`` between Horreum and DataType, with cleaner URI construction for logical databases
163
+
164
+ - **Indexing Terminology** - Renamed internal ``target_class`` to ``scope_class`` throughout to clarify semantic role. Added explicit ``:within`` field to IndexingRelationship for clearer instance-scoped index handling
165
+
166
+ Fixed
167
+ -----
168
+
169
+ - URI formatting for DataType objects with logical database settings
170
+ - Transaction detection and validation flow for unique index operations
171
+
172
+ Documentation
173
+ -------------
174
+
175
+ - Enhanced ``save()`` method documentation with transaction restrictions
176
+ - Updated indexing and relationship cheatsheets with improved terminology
177
+ - Added comprehensive test coverage (48 new tests) for transactions, pipelines, and validation
178
+
179
+ AI Assistance
180
+ -------------
181
+
182
+ This release was implemented with assistance from Claude (Anthropic) for architectural design, test coverage, and systematic refactoring of terminology across the codebase.
183
+
184
+
15
185
  .. _changelog-2.0.0.pre18:
16
186
 
17
187
  2.0.0.pre18 — 2025-10-05
@@ -66,7 +236,7 @@ Documentation
66
236
  AI Assistance
67
237
  -------------
68
238
 
69
- - Claude Code (claude-sonnet-4-5) provided implementation guidance, identified the ``initialize_with_keyword_args`` falsy value bug, wrote comprehensive test suite, and coordinated multi-file changes across serialization, management, and base modules.
239
+ - Claude Code (claude-sonnet-4-5) provided implementation guidance, identified the ``initialize_with_keyword_args`` falsy value bug, wrote test coverage, and coordinated multi-file changes across serialization, management, and base modules.
70
240
 
71
241
  - Issue analysis, implementation guidance, test verification, and documentation for JSON serialization changes and encrypted field security fix.
72
242
 
@@ -80,19 +250,17 @@ AI Assistance
80
250
  Added
81
251
  -----
82
252
 
83
- - **SortedSet#add**: Full ZADD option support (NX, XX, GT, LT, CH) for atomic conditional operations and accurate change tracking. This enables proper index management with timestamp preservation, update-only operations, conditional score updates, and analytics tracking. Closes issue #135.
253
+ - **SortedSet#add** - Full ZADD option support (NX, XX, GT, LT, CH) for atomic conditional operations and accurate change tracking. Closes #135
84
254
 
85
255
  Fixed
86
256
  -----
87
257
 
88
- - Restored objid provenance tracking when loading objects from Redis. The ``ObjectIdentifier`` feature now infers the generator type (:uuid_v7, :uuid_v4, :hex) from the objid format, enabling dependent features like ``ExternalIdentifier`` to derive external identifiers from loaded objects. PR #131
258
+ - Restored objid provenance tracking when loading objects from Redis, enabling dependent features to derive external identifiers. PR #131
89
259
 
90
260
  AI Assistance
91
261
  -------------
92
262
 
93
- - Claude Code assisted with implementing the ``infer_objid_generator`` method and updating the setter logic in ``lib/familia/features/object_identifier.rb``.
94
-
95
- - Claude Code assisted with Redis ZADD option semantics research, mutual exclusivity validation design, comprehensive test case matrix creation (50+ test cases), and YAML documentation examples.
263
+ - Claude (Anthropic) assisted with objid generator inference implementation and ZADD option validation design.
96
264
 
97
265
  .. _changelog-2.0.0.pre16:
98
266
 
@@ -102,57 +270,29 @@ AI Assistance
102
270
  Added
103
271
  -----
104
272
 
105
- - Added support for instance-scoped unique indexes via ``unique_index`` with ``within:`` parameter. Issue #128
106
-
107
- Example: ``unique_index :badge_number, :badge_index, within: Company`` creates per-company unique badge lookups using HashKey DataType.
273
+ - **Instance-scoped unique indexes** via ``unique_index`` with ``within:`` parameter for per-scope unique lookups. Issue #128
108
274
 
109
275
  Changed
110
276
  -------
111
277
 
112
- - **BREAKING**: Consolidated relationships API by replacing ``tracked_in`` and ``member_of`` with unified ``participates_in`` method. PR #110
113
- - **BREAKING**: Renamed ``context_class`` terminology to ``target_class`` throughout relationships module for clarity
114
- - **BREAKING**: Removed ``tracking.rb`` and ``membership.rb`` modules, merged functionality into ``participation.rb``
115
- - **BREAKING**: Updated method names and configuration keys to use ``target`` instead of ``context`` terminology
116
- - Added ``bidirectional`` parameter to ``participates_in`` to control generation of convenience methods (default: true)
117
- - Added support for different collection types (sorted_set, set, list) in unified ``participates_in`` API
118
- - Renamed ``class_tracked_in`` to ``class_participates_in`` for consistency
119
-
120
- - Renamed DataType classes to avoid Ruby namespace confusion: ``Familia::String`` → ``Familia::StringKey``, ``Familia::List`` → ``Familia::ListKey``
121
- - Added dual registration for both traditional and explicit method names (``string``/``stringkey``, ``list``/``listkey``)
122
- - Updated ``Counter`` and ``Lock`` to inherit from ``StringKey`` instead of ``String``
278
+ - **BREAKING**: Consolidated relationships API - replaced ``tracked_in`` and ``member_of`` with unified ``participates_in`` method. PR #110
123
279
 
124
- - **BREAKING:** Renamed indexing API methods for clarity. Issue #128
280
+ - **BREAKING**: Renamed indexing API methods for clarity. Issue #128
281
+ - ``class_indexed_by`` → ``unique_index``
282
+ - ``indexed_by`` → ``multi_index``
283
+ - Changed ``multi_index`` to use ``UnsortedSet`` instead of ``SortedSet``
125
284
 
126
- - ``class_indexed_by`` → ``unique_index`` (1:1 field-to-object mapping via HashKey)
127
- - ``indexed_by`` → ``multi_index`` (1:many field-to-objects mapping via UnsortedSet)
128
- - Parameter ``target:`` → ``within:`` for consistency across both index types
129
-
130
- - **BREAKING:** Changed ``multi_index`` to use ``UnsortedSet`` instead of ``SortedSet``. Issue #128
131
-
132
- Multi-value indexes no longer include temporal scoring. This aligns with the design philosophy that indexing is for finding objects by attribute, not ordering them. Sort results in Ruby when needed: ``employees.sort_by(&:hire_date)``
285
+ - **DataType class renaming** to avoid Ruby namespace conflicts: ``Familia::String`` → ``Familia::StringKey``, ``Familia::List`` ``Familia::ListKey``, etc., with dual registration for compatibility
133
286
 
134
287
  Documentation
135
288
  -------------
136
289
 
137
- - Updated overview documentation to explain dual naming system and namespace safety benefits
138
- - Enhanced examples to demonstrate both traditional and explicit DataType method naming
139
-
140
- - Updated inline module documentation
141
- - ``Familia::Features::Relationships::Indexing`` with comprehensive examples, terminology guide, and design philosophy.
142
- - ``Familia::Features::Relationships::Participation`` to clarify differences from indexing module.
290
+ - Updated indexing and participation module documentation with comprehensive examples and design philosophy
143
291
 
144
292
  AI Assistance
145
293
  -------------
146
294
 
147
- - Comprehensive analysis of existing ``tracked_in`` and ``member_of`` implementations
148
- - Design and implementation of unified ``participates_in`` API integrating both functionalities
149
- - Systematic refactoring of codebase terminology from context to target
150
- - Complete test suite updates to verify API consolidation and new functionality
151
-
152
- - DataType class renaming and dual registration system implementation designed and developed with Claude Code assistance
153
- - All test updates and documentation enhancements created with AI support
154
-
155
- - Architecture design, implementation, test updates, and documentation for indexing API refactoring completed with Claude Code assistance. Issue #128
295
+ - Claude (Anthropic) assisted with relationship API consolidation, DataType renaming, and indexing API refactoring.
156
296
 
157
297
  .. _changelog-2.0.0.pre14:
158
298
 
@@ -162,19 +302,18 @@ AI Assistance
162
302
  Changed
163
303
  -------
164
304
 
165
- - **BREAKING CHANGE**: Renamed ``Familia::Refinements::TimeUtils`` to ``Familia::Refinements::TimeLiterals`` to better reflect the module's primary purpose of enabling numeric and string values to be treated as time unit literals (e.g., ``5.minutes``, ``"30m".in_seconds``). Functionality remains the same - only the module name has changed. Users must update their refinement usage from ``using Familia::Refinements::TimeUtils`` to ``using Familia::Refinements::TimeLiterals``.
305
+ - **BREAKING**: Renamed ``TimeUtils`` to ``TimeLiterals`` to better reflect module purpose. PR #100
166
306
 
167
307
  Fixed
168
308
  -----
169
309
 
170
- - Fixed ExternalIdentifier HashKey method calls by replacing incorrect ``.del()`` calls with ``.remove_field()`` in three critical locations: extid setter (cleanup old mapping when changing value), find_by_extid (cleanup orphaned mapping when object not found), and destroy! (cleanup mapping when object is destroyed). Added comprehensive test coverage for all scenarios to prevent regression. PR #100
310
+ - **CRITICAL**: Fixed Redis connection persistence for standalone DataType objects. PR #107
311
+ - Fixed ExternalIdentifier HashKey cleanup using correct ``remove_field()`` method. PR #100
171
312
 
172
313
  AI Assistance
173
314
  -------------
174
315
 
175
- - Claude Code helped rename TimeUtils to TimeLiterals throughout the codebase, including module name, file path, all usage references, and updating existing documentation.
176
- - Gemini 2.5 Flash wrote the inline docs for TimeLiterals based on a discussion re: naming rationale.
177
- - Claude Code fixed the ExternalIdentifier HashKey method bug, replacing incorrect ``.del()`` calls with proper ``.remove_field()`` calls, and implemented test coverage for the affected scenarios.
316
+ - Claude (Anthropic) and Gemini assisted with TimeLiterals refactoring and ExternalIdentifier fixes.
178
317
 
179
318
  .. _changelog-2.0.0.pre13:
180
319
 
@@ -184,61 +323,39 @@ AI Assistance
184
323
  Added
185
324
  -----
186
325
 
187
- - **Feature Autoloading System**: Features can now automatically discover and load extension files from your project directories. When you include a feature like ``safe_dump``, Familia searches for configuration files using conventional patterns like ``{model_name}/{feature_name}_*.rb``, enabling clean separation between core model definitions and feature-specific configurations. See ``docs/migrating/v2.0.0-pre13.md`` for migration details.
188
-
189
- - **Consolidated autoloader architecture**: Introduced ``Familia::Features::Autoloader`` as a shared utility for consistent file loading patterns across the framework, supporting both general-purpose and feature-specific autoloading scenarios.
190
-
191
- - Added ``PER_MONTH`` constant (2,629,746 seconds = 30.437 days) derived from Gregorian year for consistent month calculations.
192
- - Added ``months``, ``month``, and ``in_months`` conversion methods to Numeric refinement.
193
- - Added month unit mappings (``'mo'``, ``'month'``, ``'months'``) to TimeLiterals ``UNIT_METHODS`` hash.
326
+ - **Feature Autoloading System** - Features automatically discover and load extension files from project directories using conventional patterns. PR #97
194
327
 
195
- - **Error Handling**: Added ``NotSupportedError`` for invalid serialization mode combinations in encryption subsystem. PR #97
328
+ - **Month calculations** - Added ``PER_MONTH`` constant and month conversion methods to TimeLiterals refinement. Issue #94
196
329
 
197
330
  Changed
198
331
  -------
199
332
 
200
- - Refactored time and numeric extensions from global monkey patches to proper Ruby refinements for better encapsulation and reduced global namespace pollution
201
- - Updated all internal classes to use refinements via ``using Familia::Refinements::TimeLiterals`` statements
202
- - Added centralized ``RefinedContext`` module in test helpers to support refinement testing in tryouts files
203
-
204
- - Updated ``PER_YEAR`` constant to use Gregorian year (31,556,952 seconds = 365.2425 days) for calendar consistency.
205
-
206
- - **Performance**: Replaced stdlib JSON with OJ gem for 2-5x faster JSON operations and reduced memory allocation. All existing code remains compatible through mimic_JSON mode. PR #97
207
-
208
- - **Encryption**: Enhanced serialization safety for encrypted fields with improved ConcealedString handling across different JSON processing modes. Strengthened protection against accidental data exposure during serialization. PR #97
333
+ - **Performance** - Replaced stdlib JSON with OJ gem for 2-5x faster operations. PR #97
334
+ - Refactored time/numeric extensions from global monkey patches to Ruby refinements
335
+ - Enhanced encryption serialization safety with improved ConcealedString handling
209
336
 
210
337
  Fixed
211
338
  -----
212
339
 
213
- - Fixed byte conversion logic in ``to_bytes`` method to correctly handle exact 1024-byte boundaries (``size >= 1024`` instead of ``size > 1024``)
214
- - Resolved refinement testing issues in tryouts by implementing ``eval``-based code execution within refined contexts
215
-
216
- - Fixed TimeLiterals refinement ``months_old`` and ``years_old`` methods returning incorrect values (raw seconds instead of months/years). The underlying ``age_in`` method now properly handles ``:months`` and ``:years`` units. Issue #94.
217
- - Fixed calendar consistency issue where ``12.months != 1.year`` by updating ``PER_YEAR`` to use Gregorian year (365.2425 days) and defining ``PER_MONTH`` as ``PER_YEAR / 12``.
340
+ - Fixed ``months_old`` and ``years_old`` methods returning raw seconds instead of proper units. Issue #94
341
+ - Fixed byte conversion boundary logic (``size >= 1024`` instead of ``size > 1024``)
342
+ - Fixed calendar consistency where ``12.months != 1.year`` by using Gregorian year
218
343
 
219
344
  Security
220
345
  --------
221
346
 
222
- - **Encryption**: Improved concealed value protection during JSON serialization, ensuring encrypted data remains properly protected across all OJ serialization modes. PR #97
347
+ - Improved concealed value protection during JSON serialization across all OJ modes. PR #97
223
348
 
224
349
  Documentation
225
350
  -------------
226
351
 
227
- - **Feature System Autoloading Guide**: Added comprehensive guide at ``docs/guides/Feature-System-Autoloading.md`` explaining the new autoloading system, including file naming conventions, directory patterns, and usage examples.
228
- - **Enhanced API documentation**: Added detailed YARD documentation for autoloading modules and methods.
352
+ - Added Feature System Autoloading guide with conventions and usage examples
353
+ - Enhanced YARD documentation for autoloading modules
229
354
 
230
355
  AI Assistance
231
356
  -------------
232
357
 
233
- - Provided comprehensive analysis of Ruby refinement scoping issues and designed the eval-based testing solution
234
- - Assisted with refactoring global extensions to proper refinements while maintaining backward compatibility
235
- - Helped debug and fix the byte conversion boundary condition bug
236
-
237
- - Significant AI assistance in architectural design and implementation of the feature-specific autoloading system, including pattern matching logic, Ruby introspection methods, and comprehensive debugging of edge cases and thread safety considerations.
238
-
239
- - Claude Code assisted with implementing the fix for broken ``months_old`` and ``years_old`` methods in the TimeLiterals refinement, including analysis, implementation, testing, and documentation.
240
-
241
- - Performance optimization research and OJ gem integration strategy, including compatibility analysis and testing approach for seamless stdlib JSON replacement. PR #97
358
+ - Claude (Anthropic) assisted with refinement refactoring, autoloading system design, and OJ integration.
242
359
 
243
360
  2.0.0.pre12 — 2025-09-04
244
361
  ========================