familia 2.0.0.pre19 → 2.0.0.pre22

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/.talismanrc +5 -1
  8. data/CHANGELOG.rst +220 -112
  9. data/CLAUDE.md +28 -1
  10. data/Gemfile +1 -1
  11. data/Gemfile.lock +20 -17
  12. data/bin/try +16 -0
  13. data/bin/tryouts +16 -0
  14. data/docs/1106-participates_in-bidirectional-solution.md +129 -0
  15. data/docs/guides/encryption.md +486 -0
  16. data/docs/guides/feature-encrypted-fields.md +123 -7
  17. data/docs/guides/feature-expiration.md +161 -117
  18. data/docs/guides/feature-external-identifiers.md +415 -443
  19. data/docs/guides/feature-object-identifiers.md +400 -269
  20. data/docs/guides/feature-quantization.md +120 -6
  21. data/docs/guides/feature-relationships-indexing.md +318 -0
  22. data/docs/guides/feature-relationships-methods.md +146 -604
  23. data/docs/guides/feature-relationships-participation.md +263 -0
  24. data/docs/guides/feature-relationships.md +118 -136
  25. data/docs/guides/feature-system-devs.md +176 -693
  26. data/docs/guides/feature-system.md +119 -6
  27. data/docs/guides/feature-transient-fields.md +81 -0
  28. data/docs/guides/field-system.md +778 -0
  29. data/docs/guides/index.md +32 -15
  30. data/docs/guides/logging.md +187 -0
  31. data/docs/guides/optimized-loading.md +674 -0
  32. data/docs/guides/thread-safety-monitoring.md +61 -0
  33. data/docs/guides/{time-utilities.md → time-literals.md} +12 -12
  34. data/docs/migrating/v2.0.0-pre22.md +241 -0
  35. data/docs/overview.md +7 -9
  36. data/docs/reference/api-technical.md +267 -320
  37. data/examples/autoloader/mega_customer/features/deprecated_fields.rb +2 -0
  38. data/examples/autoloader/mega_customer/safe_dump_fields.rb +2 -0
  39. data/examples/autoloader/mega_customer.rb +2 -0
  40. data/examples/datatype_standalone.rb +4 -3
  41. data/examples/encrypted_fields.rb +2 -1
  42. data/examples/json_usage_patterns.rb +2 -0
  43. data/examples/relationships.rb +3 -0
  44. data/examples/safe_dump.rb +2 -1
  45. data/examples/sampling_demo.rb +53 -0
  46. data/examples/single_connection_transaction_confusions.rb +2 -1
  47. data/familia.gemspec +2 -1
  48. data/lib/familia/base.rb +2 -0
  49. data/lib/familia/connection/behavior.rb +2 -0
  50. data/lib/familia/connection/handlers.rb +2 -0
  51. data/lib/familia/connection/individual_command_proxy.rb +2 -0
  52. data/lib/familia/connection/middleware.rb +34 -24
  53. data/lib/familia/connection/operation_core.rb +3 -2
  54. data/lib/familia/connection/operations.rb +2 -0
  55. data/lib/familia/connection/pipelined_core.rb +3 -3
  56. data/lib/familia/connection/transaction_core.rb +69 -2
  57. data/lib/familia/connection.rb +18 -3
  58. data/lib/familia/data_type/class_methods.rb +3 -1
  59. data/lib/familia/data_type/connection.rb +2 -0
  60. data/lib/familia/data_type/database_commands.rb +2 -0
  61. data/lib/familia/data_type/serialization.rb +79 -52
  62. data/lib/familia/data_type/settings.rb +2 -0
  63. data/lib/familia/data_type/types/counter.rb +2 -0
  64. data/lib/familia/data_type/types/hashkey.rb +7 -5
  65. data/lib/familia/data_type/types/listkey.rb +2 -0
  66. data/lib/familia/data_type/types/lock.rb +2 -0
  67. data/lib/familia/data_type/types/sorted_set.rb +7 -10
  68. data/lib/familia/data_type/types/stringkey.rb +24 -0
  69. data/lib/familia/data_type/types/unsorted_set.rb +2 -0
  70. data/lib/familia/data_type.rb +2 -0
  71. data/lib/familia/encryption/encrypted_data.rb +4 -2
  72. data/lib/familia/encryption/manager.rb +2 -0
  73. data/lib/familia/encryption/provider.rb +2 -0
  74. data/lib/familia/encryption/providers/aes_gcm_provider.rb +2 -0
  75. data/lib/familia/encryption/providers/secure_xchacha20_poly1305_provider.rb +2 -0
  76. data/lib/familia/encryption/providers/xchacha20_poly1305_provider.rb +2 -0
  77. data/lib/familia/encryption/registry.rb +2 -0
  78. data/lib/familia/encryption/request_cache.rb +2 -0
  79. data/lib/familia/encryption.rb +9 -2
  80. data/lib/familia/errors.rb +2 -0
  81. data/lib/familia/features/autoloader.rb +2 -0
  82. data/lib/familia/features/encrypted_fields/concealed_string.rb +2 -0
  83. data/lib/familia/features/encrypted_fields/encrypted_field_type.rb +4 -0
  84. data/lib/familia/features/encrypted_fields.rb +2 -2
  85. data/lib/familia/features/expiration/extensions.rb +3 -1
  86. data/lib/familia/features/expiration.rb +12 -4
  87. data/lib/familia/features/external_identifier.rb +62 -7
  88. data/lib/familia/features/object_identifier.rb +49 -0
  89. data/lib/familia/features/quantization.rb +3 -1
  90. data/lib/familia/features/relationships/README.md +3 -1
  91. data/lib/familia/features/relationships/collection_operations.rb +2 -0
  92. data/lib/familia/features/relationships/indexing/multi_index_generators.rb +138 -9
  93. data/lib/familia/features/relationships/indexing/rebuild_strategies.rb +479 -0
  94. data/lib/familia/features/relationships/indexing/unique_index_generators.rb +97 -21
  95. data/lib/familia/features/relationships/indexing.rb +3 -0
  96. data/lib/familia/features/relationships/indexing_relationship.rb +3 -1
  97. data/lib/familia/features/relationships/participation/participant_methods.rb +131 -14
  98. data/lib/familia/features/relationships/participation/rebuild_strategies.md +41 -0
  99. data/lib/familia/features/relationships/participation/target_methods.rb +6 -6
  100. data/lib/familia/features/relationships/participation.rb +155 -69
  101. data/lib/familia/features/relationships/participation_membership.rb +69 -0
  102. data/lib/familia/features/relationships/participation_relationship.rb +34 -6
  103. data/lib/familia/features/relationships/score_encoding.rb +2 -0
  104. data/lib/familia/features/relationships.rb +5 -3
  105. data/lib/familia/features/safe_dump.rb +2 -0
  106. data/lib/familia/features/transient_fields/redacted_string.rb +2 -0
  107. data/lib/familia/features/transient_fields/single_use_redacted_string.rb +2 -0
  108. data/lib/familia/features/transient_fields/transient_field_type.rb +5 -3
  109. data/lib/familia/features/transient_fields.rb +2 -0
  110. data/lib/familia/features.rb +2 -0
  111. data/lib/familia/field_type.rb +3 -1
  112. data/lib/familia/horreum/connection.rb +17 -1
  113. data/lib/familia/horreum/database_commands.rb +8 -1
  114. data/lib/familia/horreum/definition.rb +16 -6
  115. data/lib/familia/horreum/management.rb +353 -52
  116. data/lib/familia/horreum/persistence.rb +179 -108
  117. data/lib/familia/horreum/related_fields.rb +2 -0
  118. data/lib/familia/horreum/serialization.rb +23 -4
  119. data/lib/familia/horreum/settings.rb +2 -0
  120. data/lib/familia/horreum/utils.rb +2 -0
  121. data/lib/familia/horreum.rb +15 -1
  122. data/lib/familia/identifier_extractor.rb +3 -1
  123. data/lib/familia/instrumentation.rb +156 -0
  124. data/lib/familia/json_serializer.rb +2 -0
  125. data/lib/familia/logging.rb +92 -32
  126. data/lib/familia/refinements/dear_json.rb +2 -0
  127. data/lib/familia/refinements/stylize_words.rb +2 -14
  128. data/lib/familia/refinements/time_literals.rb +2 -0
  129. data/lib/familia/refinements.rb +2 -0
  130. data/lib/familia/secure_identifier.rb +10 -2
  131. data/lib/familia/settings.rb +2 -0
  132. data/lib/familia/thread_safety/instrumented_mutex.rb +166 -0
  133. data/lib/familia/thread_safety/monitor.rb +328 -0
  134. data/lib/familia/utils.rb +13 -0
  135. data/lib/familia/verifiable_identifier.rb +3 -1
  136. data/lib/familia/version.rb +3 -1
  137. data/lib/familia.rb +31 -4
  138. data/lib/middleware/database_command_counter.rb +152 -0
  139. data/lib/middleware/database_logger.rb +295 -170
  140. data/lib/multi_result.rb +61 -31
  141. data/try/edge_cases/empty_identifiers_try.rb +2 -0
  142. data/try/edge_cases/hash_symbolization_try.rb +2 -0
  143. data/try/edge_cases/json_serialization_try.rb +2 -0
  144. data/try/edge_cases/legacy_data_detection/deserialization_edge_cases_try.rb +4 -0
  145. data/try/edge_cases/race_conditions_try.rb +4 -0
  146. data/try/edge_cases/reserved_keywords_try.rb +4 -0
  147. data/try/edge_cases/string_coercion_try.rb +2 -0
  148. data/try/edge_cases/ttl_side_effects_try.rb +4 -0
  149. data/try/features/count_any_edge_cases_try.rb +486 -0
  150. data/try/features/count_any_methods_try.rb +197 -0
  151. data/try/features/encrypted_fields/aad_protection_try.rb +4 -0
  152. data/try/features/encrypted_fields/concealed_string_core_try.rb +4 -0
  153. data/try/features/encrypted_fields/context_isolation_try.rb +4 -0
  154. data/try/features/encrypted_fields/encrypted_fields_core_try.rb +33 -0
  155. data/try/features/encrypted_fields/encrypted_fields_integration_try.rb +4 -0
  156. data/try/features/encrypted_fields/encrypted_fields_no_cache_security_try.rb +4 -0
  157. data/try/features/encrypted_fields/encrypted_fields_security_try.rb +4 -0
  158. data/try/features/encrypted_fields/error_conditions_try.rb +4 -0
  159. data/try/features/encrypted_fields/fresh_key_derivation_try.rb +4 -0
  160. data/try/features/encrypted_fields/fresh_key_try.rb +4 -0
  161. data/try/features/encrypted_fields/key_rotation_try.rb +4 -0
  162. data/try/features/encrypted_fields/memory_security_try.rb +4 -0
  163. data/try/features/encrypted_fields/missing_current_key_version_try.rb +4 -0
  164. data/try/features/encrypted_fields/nonce_uniqueness_try.rb +4 -0
  165. data/try/features/encrypted_fields/secure_by_default_behavior_try.rb +4 -0
  166. data/try/features/encrypted_fields/thread_safety_try.rb +4 -0
  167. data/try/features/encrypted_fields/universal_serialization_safety_try.rb +4 -0
  168. data/try/features/encryption/config_persistence_try.rb +4 -0
  169. data/try/features/encryption/core_try.rb +4 -0
  170. data/try/features/encryption/instance_variable_scope_try.rb +4 -0
  171. data/try/features/encryption/module_loading_try.rb +4 -0
  172. data/try/features/encryption/providers/aes_gcm_provider_try.rb +4 -0
  173. data/try/features/encryption/providers/xchacha20_poly1305_provider_try.rb +4 -0
  174. data/try/features/encryption/roundtrip_validation_try.rb +4 -0
  175. data/try/features/encryption/secure_memory_handling_try.rb +4 -0
  176. data/try/features/expiration/expiration_try.rb +4 -0
  177. data/try/features/external_identifier/external_identifier_try.rb +305 -8
  178. data/try/features/feature_dependencies_try.rb +2 -0
  179. data/try/features/feature_improvements_try.rb +2 -0
  180. data/try/features/field_groups_try.rb +2 -0
  181. data/try/features/object_identifier/object_identifier_integration_try.rb +12 -9
  182. data/try/features/object_identifier/object_identifier_try.rb +140 -0
  183. data/try/features/quantization/quantization_try.rb +4 -0
  184. data/try/features/real_feature_integration_try.rb +2 -0
  185. data/try/features/relationships/indexing_commands_verification_try.rb +2 -0
  186. data/try/features/relationships/indexing_rebuild_try.rb +606 -0
  187. data/try/features/relationships/indexing_try.rb +2 -0
  188. data/try/features/relationships/participation_bidirectional_try.rb +242 -0
  189. data/try/features/relationships/participation_commands_verification_spec.rb +4 -0
  190. data/try/features/relationships/participation_commands_verification_try.rb +2 -0
  191. data/try/features/relationships/participation_performance_improvements_try.rb +11 -9
  192. data/try/features/relationships/participation_reverse_index_try.rb +15 -13
  193. data/try/features/relationships/participation_target_class_resolution_try.rb +209 -0
  194. data/try/features/relationships/participation_unresolved_target_try.rb +109 -0
  195. data/try/features/relationships/relationships_api_changes_try.rb +2 -0
  196. data/try/features/relationships/relationships_edge_cases_try.rb +4 -0
  197. data/try/features/relationships/relationships_performance_minimal_try.rb +4 -0
  198. data/try/features/relationships/relationships_performance_simple_try.rb +4 -0
  199. data/try/features/relationships/relationships_performance_try.rb +4 -0
  200. data/try/features/relationships/relationships_performance_working_try.rb +4 -0
  201. data/try/features/relationships/relationships_try.rb +6 -4
  202. data/try/features/safe_dump/safe_dump_advanced_try.rb +4 -0
  203. data/try/features/safe_dump/safe_dump_try.rb +4 -0
  204. data/try/features/transient_fields/redacted_string_try.rb +2 -0
  205. data/try/features/transient_fields/refresh_reset_try.rb +3 -0
  206. data/try/features/transient_fields/simple_refresh_test.rb +3 -0
  207. data/try/features/transient_fields/single_use_redacted_string_try.rb +2 -0
  208. data/try/features/transient_fields/transient_fields_core_try.rb +4 -0
  209. data/try/features/transient_fields/transient_fields_integration_try.rb +4 -0
  210. data/try/integration/connection/fiber_context_preservation_try.rb +4 -0
  211. data/try/integration/connection/handler_constraints_try.rb +4 -0
  212. data/try/integration/connection/isolated_dbclient_try.rb +4 -0
  213. data/try/integration/connection/middleware_reconnect_try.rb +2 -0
  214. data/try/integration/connection/operation_mode_guards_try.rb +4 -0
  215. data/try/integration/connection/pipeline_fallback_integration_try.rb +3 -0
  216. data/try/integration/connection/pools_try.rb +4 -0
  217. data/try/integration/connection/responsibility_chain_tracking_try.rb +4 -0
  218. data/try/integration/connection/transaction_fallback_integration_try.rb +4 -0
  219. data/try/integration/connection/transaction_mode_permissive_try.rb +4 -0
  220. data/try/integration/connection/transaction_mode_strict_try.rb +4 -0
  221. data/try/integration/connection/transaction_mode_warn_try.rb +4 -0
  222. data/try/integration/connection/transaction_modes_try.rb +4 -0
  223. data/try/integration/conventional_inheritance_try.rb +4 -0
  224. data/try/integration/create_method_try.rb +4 -0
  225. data/try/integration/cross_component_try.rb +4 -0
  226. data/try/integration/data_types/datatype_pipelines_try.rb +9 -3
  227. data/try/integration/data_types/datatype_transactions_try.rb +17 -7
  228. data/try/integration/database_consistency_try.rb +4 -0
  229. data/try/integration/familia_extended_try.rb +4 -0
  230. data/try/integration/familia_members_methods_try.rb +4 -0
  231. data/try/integration/models/customer_safe_dump_try.rb +4 -0
  232. data/try/integration/models/customer_try.rb +7 -3
  233. data/try/integration/models/datatype_base_try.rb +4 -0
  234. data/try/integration/models/familia_object_try.rb +4 -0
  235. data/try/integration/persistence_operations_try.rb +4 -0
  236. data/try/integration/relationships_persistence_round_trip_try.rb +17 -14
  237. data/try/integration/save_methods_consistency_try.rb +241 -0
  238. data/try/integration/scenarios_try.rb +4 -0
  239. data/try/integration/secure_identifier_try.rb +4 -0
  240. data/try/integration/transaction_safety_core_try.rb +176 -0
  241. data/try/integration/transaction_safety_workflow_try.rb +291 -0
  242. data/try/integration/verifiable_identifier_try.rb +4 -0
  243. data/try/investigation/pipeline_routing/README.md +228 -0
  244. data/try/performance/benchmarks_try.rb +4 -0
  245. data/try/performance/transaction_safety_benchmark_try.rb +238 -0
  246. data/try/support/benchmarks/deserialization_benchmark.rb +3 -1
  247. data/try/support/benchmarks/deserialization_correctness_test.rb +3 -1
  248. data/try/support/debugging/cache_behavior_tracer.rb +4 -0
  249. data/try/support/debugging/debug_aad_process.rb +3 -0
  250. data/try/support/debugging/debug_concealed_internal.rb +3 -0
  251. data/try/support/debugging/debug_concealed_reveal.rb +3 -0
  252. data/try/support/debugging/debug_context_aad.rb +3 -0
  253. data/try/support/debugging/debug_context_simple.rb +3 -0
  254. data/try/support/debugging/debug_cross_context.rb +3 -0
  255. data/try/support/debugging/debug_database_load.rb +3 -0
  256. data/try/support/debugging/debug_encrypted_json_check.rb +3 -0
  257. data/try/support/debugging/debug_encrypted_json_step_by_step.rb +3 -0
  258. data/try/support/debugging/debug_exists_lifecycle.rb +3 -0
  259. data/try/support/debugging/debug_field_decrypt.rb +3 -0
  260. data/try/support/debugging/debug_fresh_cross_context.rb +3 -0
  261. data/try/support/debugging/debug_load_path.rb +3 -0
  262. data/try/support/debugging/debug_method_definition.rb +3 -0
  263. data/try/support/debugging/debug_method_resolution.rb +3 -0
  264. data/try/support/debugging/debug_minimal.rb +3 -0
  265. data/try/support/debugging/debug_provider.rb +3 -0
  266. data/try/support/debugging/debug_secure_behavior.rb +3 -0
  267. data/try/support/debugging/debug_string_class.rb +3 -0
  268. data/try/support/debugging/debug_test.rb +3 -0
  269. data/try/support/debugging/debug_test_design.rb +3 -0
  270. data/try/support/debugging/encryption_method_tracer.rb +4 -0
  271. data/try/support/debugging/provider_diagnostics.rb +4 -0
  272. data/try/support/helpers/test_cleanup.rb +4 -0
  273. data/try/support/helpers/test_helpers.rb +5 -0
  274. data/try/support/memory/memory_basic_test.rb +4 -0
  275. data/try/support/memory/memory_detailed_test.rb +4 -0
  276. data/try/support/memory/memory_search_for_string.rb +4 -0
  277. data/try/support/memory/test_actual_redactedstring_protection.rb +4 -0
  278. data/try/support/prototypes/atomic_saves_v1_context_proxy.rb +4 -0
  279. data/try/support/prototypes/atomic_saves_v2_connection_switching.rb +4 -0
  280. data/try/support/prototypes/atomic_saves_v3_connection_pool.rb +4 -0
  281. data/try/support/prototypes/atomic_saves_v4.rb +4 -0
  282. data/try/support/prototypes/lib/atomic_saves_v2_connection_switching_helpers.rb +4 -0
  283. data/try/support/prototypes/lib/atomic_saves_v3_connection_pool_helpers.rb +4 -0
  284. data/try/support/prototypes/pooling/configurable_stress_test.rb +4 -0
  285. data/try/support/prototypes/pooling/lib/atomic_saves_v3_connection_pool_helpers.rb +4 -0
  286. data/try/support/prototypes/pooling/lib/connection_pool_metrics.rb +4 -0
  287. data/try/support/prototypes/pooling/lib/connection_pool_stress_test.rb +4 -0
  288. data/try/support/prototypes/pooling/lib/connection_pool_threading_models.rb +4 -0
  289. data/try/support/prototypes/pooling/lib/visualize_stress_results.rb +4 -2
  290. data/try/support/prototypes/pooling/pool_siege.rb +4 -2
  291. data/try/support/prototypes/pooling/run_stress_tests.rb +4 -2
  292. data/try/thread_safety/README.md +496 -0
  293. data/try/thread_safety/class_connection_chain_race_try.rb +265 -0
  294. data/try/thread_safety/connection_chain_race_try.rb +148 -0
  295. data/try/thread_safety/encryption_manager_cache_race_try.rb +166 -0
  296. data/try/thread_safety/feature_registry_race_try.rb +226 -0
  297. data/try/thread_safety/fiber_pipeline_isolation_try.rb +235 -0
  298. data/try/thread_safety/fiber_transaction_isolation_try.rb +208 -0
  299. data/try/thread_safety/field_registration_race_try.rb +222 -0
  300. data/try/thread_safety/logger_initialization_race_try.rb +170 -0
  301. data/try/thread_safety/middleware_registration_race_try.rb +154 -0
  302. data/try/thread_safety/module_config_race_try.rb +175 -0
  303. data/try/thread_safety/secure_identifier_cache_race_try.rb +226 -0
  304. data/try/unit/core/autoloader_try.rb +4 -0
  305. data/try/unit/core/base_enhancements_try.rb +4 -0
  306. data/try/unit/core/connection_try.rb +4 -0
  307. data/try/unit/core/errors_try.rb +4 -0
  308. data/try/unit/core/extensions_try.rb +4 -0
  309. data/try/unit/core/familia_logger_try.rb +2 -0
  310. data/try/unit/core/familia_try.rb +4 -0
  311. data/try/unit/core/middleware_sampling_try.rb +335 -0
  312. data/try/unit/core/middleware_test_helpers_bug_try.rb +58 -0
  313. data/try/unit/core/middleware_thread_safety_try.rb +245 -0
  314. data/try/unit/core/middleware_try.rb +4 -0
  315. data/try/unit/core/settings_try.rb +4 -0
  316. data/try/unit/core/time_utils_try.rb +4 -0
  317. data/try/unit/core/tools_try.rb +4 -0
  318. data/try/unit/core/utils_try.rb +37 -0
  319. data/try/unit/data_types/boolean_try.rb +39 -22
  320. data/try/unit/data_types/counter_try.rb +4 -0
  321. data/try/unit/data_types/datatype_base_try.rb +4 -0
  322. data/try/unit/data_types/hash_try.rb +6 -2
  323. data/try/unit/data_types/list_try.rb +4 -0
  324. data/try/unit/data_types/lock_try.rb +4 -0
  325. data/try/unit/data_types/serialization_try.rb +386 -0
  326. data/try/unit/data_types/sorted_set_try.rb +4 -0
  327. data/try/unit/data_types/sorted_set_zadd_options_try.rb +4 -0
  328. data/try/unit/data_types/string_try.rb +4 -0
  329. data/try/unit/data_types/unsortedset_try.rb +4 -0
  330. data/try/unit/familia_resolve_class_try.rb +116 -0
  331. data/try/unit/horreum/auto_indexing_on_save_try.rb +5 -1
  332. data/try/unit/horreum/automatic_index_validation_try.rb +2 -0
  333. data/try/unit/horreum/base_try.rb +4 -0
  334. data/try/unit/horreum/class_methods_try.rb +4 -0
  335. data/try/unit/horreum/commands_try.rb +4 -0
  336. data/try/unit/horreum/defensive_initialization_try.rb +4 -0
  337. data/try/unit/horreum/destroy_related_fields_cleanup_try.rb +6 -1
  338. data/try/unit/horreum/enhanced_conflict_handling_try.rb +4 -0
  339. data/try/unit/horreum/field_categories_try.rb +4 -0
  340. data/try/unit/horreum/field_definition_try.rb +4 -0
  341. data/try/unit/horreum/initialization_try.rb +4 -0
  342. data/try/unit/horreum/json_type_preservation_try.rb +2 -0
  343. data/try/unit/horreum/optimized_loading_try.rb +156 -0
  344. data/try/unit/horreum/relations_try.rb +4 -0
  345. data/try/unit/horreum/serialization_persistent_fields_try.rb +4 -0
  346. data/try/unit/horreum/serialization_try.rb +4 -0
  347. data/try/unit/horreum/settings_try.rb +4 -0
  348. data/try/unit/horreum/unique_index_edge_cases_try.rb +4 -0
  349. data/try/unit/horreum/unique_index_guard_validation_try.rb +2 -0
  350. data/try/unit/middleware/database_command_counter_methods_try.rb +139 -0
  351. data/try/unit/middleware/database_logger_methods_try.rb +251 -0
  352. data/try/unit/refinements/dear_json_array_methods_try.rb +4 -0
  353. data/try/unit/refinements/dear_json_hash_methods_try.rb +4 -0
  354. data/try/unit/refinements/time_literals_numeric_methods_try.rb +4 -0
  355. data/try/unit/refinements/time_literals_string_methods_try.rb +4 -0
  356. data/try/unit/thread_safety_monitor_try.rb +149 -0
  357. metadata +69 -17
  358. data/.github/workflows/code-quality.yml +0 -138
  359. data/changelog.d/20251011_012003_delano_159_datatype_transaction_pipeline_support.rst +0 -91
  360. data/changelog.d/20251011_203905_delano_next.rst +0 -30
  361. data/changelog.d/20251011_212633_delano_next.rst +0 -13
  362. data/changelog.d/20251011_221253_delano_next.rst +0 -26
  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
@@ -0,0 +1,197 @@
1
+ require_relative '../support/helpers/test_helpers'
2
+
3
+ # Test class for count/any method testing
4
+ class CountTestCustomer < Familia::Horreum
5
+ identifier_field :custid
6
+ field :custid
7
+ field :name
8
+ end
9
+
10
+ # Setup - clear any existing data
11
+ CountTestCustomer.instances.clear
12
+ CountTestCustomer.all.each(&:destroy!)
13
+
14
+ ## count returns 0 when no instances exist
15
+ CountTestCustomer.count
16
+ #=> 0
17
+
18
+ ## keys_count returns 0 when no instances exist (KEYS command)
19
+ CountTestCustomer.keys_count
20
+ #=> 0
21
+
22
+ ## scan_count returns 0 when no instances exist (SCAN command)
23
+ CountTestCustomer.scan_count
24
+ #=> 0
25
+
26
+ ## count! returns 0 when no instances exist (alias to scan_count)
27
+ CountTestCustomer.count!
28
+ #=> 0
29
+
30
+ ## any? returns false when no instances exist
31
+ CountTestCustomer.any?
32
+ #=> false
33
+
34
+ ## keys_any? returns false when no instances exist (KEYS command)
35
+ CountTestCustomer.keys_any?
36
+ #=> false
37
+
38
+ ## scan_any? returns false when no instances exist (SCAN command)
39
+ CountTestCustomer.scan_any?
40
+ #=> false
41
+
42
+ ## any! returns false when no instances exist (alias to scan_any?)
43
+ CountTestCustomer.any!
44
+ #=> false
45
+
46
+ ## count returns 1 after creating an instance
47
+ @cust1 = CountTestCustomer.create!(custid: 'alice', name: 'Alice')
48
+ CountTestCustomer.count
49
+ #=> 1
50
+
51
+ ## keys_count returns 1 after creating an instance
52
+ CountTestCustomer.keys_count
53
+ #=> 1
54
+
55
+ ## scan_count returns 1 after creating an instance
56
+ CountTestCustomer.scan_count
57
+ #=> 1
58
+
59
+ ## count! returns 1 after creating an instance
60
+ CountTestCustomer.count!
61
+ #=> 1
62
+
63
+ ## any? returns true after creating an instance
64
+ CountTestCustomer.any?
65
+ #=> true
66
+
67
+ ## keys_any? returns true after creating an instance
68
+ CountTestCustomer.keys_any?
69
+ #=> true
70
+
71
+ ## scan_any? returns true after creating an instance
72
+ CountTestCustomer.scan_any?
73
+ #=> true
74
+
75
+ ## any! returns true after creating an instance
76
+ CountTestCustomer.any!
77
+ #=> true
78
+
79
+ ## count increases after creating another instance
80
+ @cust2 = CountTestCustomer.create!(custid: 'bob', name: 'Bob')
81
+ CountTestCustomer.count
82
+ #=> 2
83
+
84
+ ## keys_count also shows 2 instances
85
+ CountTestCustomer.keys_count
86
+ #=> 2
87
+
88
+ ## scan_count also shows 2 instances
89
+ CountTestCustomer.scan_count
90
+ #=> 2
91
+
92
+ ## count! also shows 2 instances
93
+ CountTestCustomer.count!
94
+ #=> 2
95
+
96
+ ## keys_count with filter matches specific patterns
97
+ @cust3 = CountTestCustomer.create!(custid: 'alice2', name: 'Alice2')
98
+ CountTestCustomer.keys_count('alice*')
99
+ #=> 2
100
+
101
+ ## scan_count with filter matches specific patterns
102
+ CountTestCustomer.scan_count('alice*')
103
+ #=> 2
104
+
105
+ ## count! with filter matches specific patterns
106
+ CountTestCustomer.count!('alice*')
107
+ #=> 2
108
+
109
+ ## keys_any? with filter detects matching patterns
110
+ CountTestCustomer.keys_any?('alice*')
111
+ #=> true
112
+
113
+ ## scan_any? with filter detects matching patterns
114
+ CountTestCustomer.scan_any?('alice*')
115
+ #=> true
116
+
117
+ ## any! with filter detects matching patterns
118
+ CountTestCustomer.any!('alice*')
119
+ #=> true
120
+
121
+ ## keys_any? with filter returns false for non-matching patterns
122
+ CountTestCustomer.keys_any?('nonexistent*')
123
+ #=> false
124
+
125
+ ## scan_any? with filter returns false for non-matching patterns
126
+ CountTestCustomer.scan_any?('nonexistent*')
127
+ #=> false
128
+
129
+ ## any! with filter returns false for non-matching patterns
130
+ CountTestCustomer.any!('nonexistent*')
131
+ #=> false
132
+
133
+ ## count reflects deletion when object is destroyed via Familia
134
+ @cust1.destroy!
135
+ CountTestCustomer.count
136
+ #=> 2
137
+
138
+ ## keys_count also reflects the deletion
139
+ CountTestCustomer.keys_count
140
+ #=> 2
141
+
142
+ ## scan_count also reflects the deletion
143
+ CountTestCustomer.scan_count
144
+ #=> 2
145
+
146
+ ## count! also reflects the deletion
147
+ CountTestCustomer.count!
148
+ #=> 2
149
+
150
+ ## count shows stale data when instance deleted outside Familia
151
+ # Delete directly from Redis without going through Familia
152
+ CountTestCustomer.dbclient.del(@cust2.dbkey)
153
+ CountTestCustomer.count
154
+ #=> 2
155
+
156
+ ## keys_count shows authoritative data after direct deletion
157
+ CountTestCustomer.keys_count
158
+ #=> 1
159
+
160
+ ## scan_count shows authoritative data after direct deletion
161
+ CountTestCustomer.scan_count
162
+ #=> 1
163
+
164
+ ## count! shows authoritative data after direct deletion
165
+ CountTestCustomer.count!
166
+ #=> 1
167
+
168
+ ## any? may return true even when all objects deleted outside Familia
169
+ # Instance tracking still has entries
170
+ CountTestCustomer.any?
171
+ #=> true
172
+
173
+ ## keys_any? returns false when no actual keys exist
174
+ CountTestCustomer.dbclient.del(@cust3.dbkey)
175
+ CountTestCustomer.keys_any?
176
+ #=> false
177
+
178
+ ## scan_any? returns false when no actual keys exist
179
+ CountTestCustomer.scan_any?
180
+ #=> false
181
+
182
+ ## any! returns false when no actual keys exist
183
+ CountTestCustomer.any!
184
+ #=> false
185
+
186
+ ## size alias works correctly (aliases to fast count method)
187
+ @cust4 = CountTestCustomer.create!(custid: 'charlie', name: 'Charlie')
188
+ CountTestCustomer.size == CountTestCustomer.count
189
+ #=> true
190
+
191
+ ## length alias works correctly (aliases to fast count method)
192
+ CountTestCustomer.length == CountTestCustomer.count
193
+ #=> true
194
+
195
+ # Cleanup
196
+ CountTestCustomer.instances.clear
197
+ CountTestCustomer.all.each(&:destroy!)
@@ -1,3 +1,7 @@
1
+ # try/features/encrypted_fields/aad_protection_try.rb
2
+ #
3
+ # frozen_string_literal: true
4
+
1
5
  # try/features/encryption_fields/aad_protection_try.rb
2
6
 
3
7
  require 'concurrent'
@@ -1,3 +1,7 @@
1
+ # try/features/encrypted_fields/concealed_string_core_try.rb
2
+ #
3
+ # frozen_string_literal: true
4
+
1
5
  # try/features/encryption_fields/concealed_string_core_try.rb
2
6
 
3
7
  require_relative '../../support/helpers/test_helpers'
@@ -1,3 +1,7 @@
1
+ # try/features/encrypted_fields/context_isolation_try.rb
2
+ #
3
+ # frozen_string_literal: true
4
+
1
5
  # try/features/encryption_fields/context_isolation_try.rb
2
6
 
3
7
  require 'base64'
@@ -1,3 +1,7 @@
1
+ # try/features/encrypted_fields/encrypted_fields_core_try.rb
2
+ #
3
+ # frozen_string_literal: true
4
+
1
5
  # try/features/encrypted_fields_core_try.rb
2
6
 
3
7
  require_relative '../../support/helpers/test_helpers'
@@ -122,4 +126,33 @@ end
122
126
  @user2.api_key.reveal { |decrypted| decrypted }
123
127
  #=> 'secret-key-123'
124
128
 
129
+ ## encrypted_data? returns false when no encrypted fields have values
130
+ class SecureUser6 < Familia::Horreum
131
+ feature :encrypted_fields
132
+ identifier_field :user_id
133
+ field :user_id
134
+ encrypted_field :ssn
135
+ encrypted_field :api_key
136
+ end
137
+
138
+ @user3 = SecureUser6.new(user_id: 'test-user-006')
139
+ @user3.encrypted_data?
140
+ #=> false
141
+
142
+ ## encrypted_data? returns true when at least one encrypted field has a value
143
+ @user3.ssn = '123-45-6789'
144
+ @user3.encrypted_data?
145
+ #=> true
146
+
147
+ ## encrypted_data? returns true with multiple encrypted fields set
148
+ @user3.api_key = 'secret-key-456'
149
+ @user3.encrypted_data?
150
+ #=> true
151
+
152
+ ## encrypted_data? returns false after clearing encrypted fields
153
+ @user3.ssn = nil
154
+ @user3.api_key = nil
155
+ @user3.encrypted_data?
156
+ #=> false
157
+
125
158
  Fiber[:familia_key_cache]&.clear if Fiber[:familia_key_cache]
@@ -1,3 +1,7 @@
1
+ # try/features/encrypted_fields/encrypted_fields_integration_try.rb
2
+ #
3
+ # frozen_string_literal: true
4
+
1
5
  # try/features/encrypted_fields_integration_try.rb
2
6
 
3
7
  # Test constants will be redefined in each test since variables don't persist
@@ -1,3 +1,7 @@
1
+ # try/features/encrypted_fields/encrypted_fields_no_cache_security_try.rb
2
+ #
3
+ # frozen_string_literal: true
4
+
1
5
  # try/features/encrypted_fields_no_cache_security_try.rb
2
6
  #
3
7
  # Security tests for the no-cache encryption strategy
@@ -1,3 +1,7 @@
1
+ # try/features/encrypted_fields/encrypted_fields_security_try.rb
2
+ #
3
+ # frozen_string_literal: true
4
+
1
5
  # try/features/encrypted_fields_security_try.rb
2
6
 
3
7
  require_relative '../../support/helpers/test_helpers'
@@ -1,3 +1,7 @@
1
+ # try/features/encrypted_fields/error_conditions_try.rb
2
+ #
3
+ # frozen_string_literal: true
4
+
1
5
  # try/features/encryption_fields/error_conditions_try.rb
2
6
 
3
7
  require 'base64'
@@ -1,3 +1,7 @@
1
+ # try/features/encrypted_fields/fresh_key_derivation_try.rb
2
+ #
3
+ # frozen_string_literal: true
4
+
1
5
  # try/features/encryption_fields/fresh_key_derivation_try.rb
2
6
 
3
7
  require 'base64'
@@ -1,3 +1,7 @@
1
+ # try/features/encrypted_fields/fresh_key_try.rb
2
+ #
3
+ # frozen_string_literal: true
4
+
1
5
  require_relative '../../support/helpers/test_helpers'
2
6
  require 'base64'
3
7
 
@@ -1,3 +1,7 @@
1
+ # try/features/encrypted_fields/key_rotation_try.rb
2
+ #
3
+ # frozen_string_literal: true
4
+
1
5
  # try/features/encryption_fields/key_rotation_try.rb
2
6
 
3
7
  require 'base64'
@@ -1,3 +1,7 @@
1
+ # try/features/encrypted_fields/memory_security_try.rb
2
+ #
3
+ # frozen_string_literal: true
4
+
1
5
  # try/features/encryption_fields/memory_security_try.rb
2
6
 
3
7
  require 'base64'
@@ -1,3 +1,7 @@
1
+ # try/features/encrypted_fields/missing_current_key_version_try.rb
2
+ #
3
+ # frozen_string_literal: true
4
+
1
5
  # try/features/encryption_fields/missing_current_key_version_try.rb
2
6
 
3
7
  require 'base64'
@@ -1,3 +1,7 @@
1
+ # try/features/encrypted_fields/nonce_uniqueness_try.rb
2
+ #
3
+ # frozen_string_literal: true
4
+
1
5
  # try/features/encryption_fields/nonce_uniqueness_try.rb
2
6
 
3
7
  require 'base64'
@@ -1,3 +1,7 @@
1
+ # try/features/encrypted_fields/secure_by_default_behavior_try.rb
2
+ #
3
+ # frozen_string_literal: true
4
+
1
5
  # try/features/encryption_fields/secure_by_default_behavior_try.rb
2
6
 
3
7
  require_relative '../../support/helpers/test_helpers'
@@ -1,3 +1,7 @@
1
+ # try/features/encrypted_fields/thread_safety_try.rb
2
+ #
3
+ # frozen_string_literal: true
4
+
1
5
  # try/features/encryption_fields/thread_safety_try.rb
2
6
 
3
7
  require 'concurrent'
@@ -1,3 +1,7 @@
1
+ # try/features/encrypted_fields/universal_serialization_safety_try.rb
2
+ #
3
+ # frozen_string_literal: true
4
+
1
5
  # try/features/encryption_fields/universal_serialization_safety_try.rb
2
6
 
3
7
  require_relative '../../support/helpers/test_helpers'
@@ -1,3 +1,7 @@
1
+ # try/features/encryption/config_persistence_try.rb
2
+ #
3
+ # frozen_string_literal: true
4
+
1
5
  # try/encryption/debug2_try.rb
2
6
 
3
7
  # - Tests configuration persistence between test sections
@@ -1,3 +1,7 @@
1
+ # try/features/encryption/core_try.rb
2
+ #
3
+ # frozen_string_literal: true
4
+
1
5
  # try/encryption/encryption_core_try.rb
2
6
 
3
7
  require_relative '../../support/helpers/test_helpers'
@@ -1,3 +1,7 @@
1
+ # try/features/encryption/instance_variable_scope_try.rb
2
+ #
3
+ # frozen_string_literal: true
4
+
1
5
  # try/encryption/debug3_try.rb
2
6
 
3
7
  # - Tests instance variable scoping in tryouts framework
@@ -1,3 +1,7 @@
1
+ # try/features/encryption/module_loading_try.rb
2
+ #
3
+ # frozen_string_literal: true
4
+
1
5
  # try/encryption/debug_try.rb
2
6
 
3
7
  # - Tests that the encryption module loads correctly
@@ -1,3 +1,7 @@
1
+ # try/features/encryption/providers/aes_gcm_provider_try.rb
2
+ #
3
+ # frozen_string_literal: true
4
+
1
5
  # try/encryption/providers/aes_gcm_provider_try.rb
2
6
 
3
7
  require_relative '../../../support/helpers/test_helpers'
@@ -1,3 +1,7 @@
1
+ # try/features/encryption/providers/xchacha20_poly1305_provider_try.rb
2
+ #
3
+ # frozen_string_literal: true
4
+
1
5
  # try/encryption/providers/xchacha20_poly1305_provider_try.rb
2
6
 
3
7
  require_relative '../../../support/helpers/test_helpers'
@@ -1,3 +1,7 @@
1
+ # try/features/encryption/roundtrip_validation_try.rb
2
+ #
3
+ # frozen_string_literal: true
4
+
1
5
  # try/encryption/debug4_try.rb
2
6
 
3
7
  # - Tests full encryption/decryption round trips
@@ -1,3 +1,7 @@
1
+ # try/features/encryption/secure_memory_handling_try.rb
2
+ #
3
+ # frozen_string_literal: true
4
+
1
5
  # try/encryption/secure_memory_handling_try.rb
2
6
 
3
7
  require_relative '../../support/helpers/test_helpers'
@@ -1,3 +1,7 @@
1
+ # try/features/expiration/expiration_try.rb
2
+ #
3
+ # frozen_string_literal: true
4
+
1
5
  # try/features/expiration_try.rb
2
6
 
3
7
  require_relative '../../support/helpers/test_helpers'