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.
- checksums.yaml +4 -4
- data/.github/workflows/claude-code-review.yml +4 -9
- data/.github/workflows/code-smells.yml +64 -3
- data/.pre-commit-config.yaml +8 -6
- data/.reek.yml +10 -9
- data/.rubocop.yml +4 -0
- data/.talismanrc +5 -1
- data/CHANGELOG.rst +220 -112
- data/CLAUDE.md +28 -1
- data/Gemfile +1 -1
- data/Gemfile.lock +20 -17
- data/bin/try +16 -0
- data/bin/tryouts +16 -0
- data/docs/1106-participates_in-bidirectional-solution.md +129 -0
- data/docs/guides/encryption.md +486 -0
- data/docs/guides/feature-encrypted-fields.md +123 -7
- data/docs/guides/feature-expiration.md +161 -117
- data/docs/guides/feature-external-identifiers.md +415 -443
- data/docs/guides/feature-object-identifiers.md +400 -269
- data/docs/guides/feature-quantization.md +120 -6
- data/docs/guides/feature-relationships-indexing.md +318 -0
- data/docs/guides/feature-relationships-methods.md +146 -604
- data/docs/guides/feature-relationships-participation.md +263 -0
- data/docs/guides/feature-relationships.md +118 -136
- data/docs/guides/feature-system-devs.md +176 -693
- data/docs/guides/feature-system.md +119 -6
- data/docs/guides/feature-transient-fields.md +81 -0
- data/docs/guides/field-system.md +778 -0
- data/docs/guides/index.md +32 -15
- data/docs/guides/logging.md +187 -0
- data/docs/guides/optimized-loading.md +674 -0
- data/docs/guides/thread-safety-monitoring.md +61 -0
- data/docs/guides/{time-utilities.md → time-literals.md} +12 -12
- data/docs/migrating/v2.0.0-pre22.md +241 -0
- data/docs/overview.md +7 -9
- data/docs/reference/api-technical.md +267 -320
- data/examples/autoloader/mega_customer/features/deprecated_fields.rb +2 -0
- data/examples/autoloader/mega_customer/safe_dump_fields.rb +2 -0
- data/examples/autoloader/mega_customer.rb +2 -0
- data/examples/datatype_standalone.rb +4 -3
- data/examples/encrypted_fields.rb +2 -1
- data/examples/json_usage_patterns.rb +2 -0
- data/examples/relationships.rb +3 -0
- data/examples/safe_dump.rb +2 -1
- data/examples/sampling_demo.rb +53 -0
- data/examples/single_connection_transaction_confusions.rb +2 -1
- data/familia.gemspec +2 -1
- data/lib/familia/base.rb +2 -0
- data/lib/familia/connection/behavior.rb +2 -0
- data/lib/familia/connection/handlers.rb +2 -0
- data/lib/familia/connection/individual_command_proxy.rb +2 -0
- data/lib/familia/connection/middleware.rb +34 -24
- data/lib/familia/connection/operation_core.rb +3 -2
- data/lib/familia/connection/operations.rb +2 -0
- data/lib/familia/connection/pipelined_core.rb +3 -3
- data/lib/familia/connection/transaction_core.rb +69 -2
- data/lib/familia/connection.rb +18 -3
- data/lib/familia/data_type/class_methods.rb +3 -1
- data/lib/familia/data_type/connection.rb +2 -0
- data/lib/familia/data_type/database_commands.rb +2 -0
- data/lib/familia/data_type/serialization.rb +79 -52
- data/lib/familia/data_type/settings.rb +2 -0
- data/lib/familia/data_type/types/counter.rb +2 -0
- data/lib/familia/data_type/types/hashkey.rb +7 -5
- data/lib/familia/data_type/types/listkey.rb +2 -0
- data/lib/familia/data_type/types/lock.rb +2 -0
- data/lib/familia/data_type/types/sorted_set.rb +7 -10
- data/lib/familia/data_type/types/stringkey.rb +24 -0
- data/lib/familia/data_type/types/unsorted_set.rb +2 -0
- data/lib/familia/data_type.rb +2 -0
- data/lib/familia/encryption/encrypted_data.rb +4 -2
- data/lib/familia/encryption/manager.rb +2 -0
- data/lib/familia/encryption/provider.rb +2 -0
- data/lib/familia/encryption/providers/aes_gcm_provider.rb +2 -0
- data/lib/familia/encryption/providers/secure_xchacha20_poly1305_provider.rb +2 -0
- data/lib/familia/encryption/providers/xchacha20_poly1305_provider.rb +2 -0
- data/lib/familia/encryption/registry.rb +2 -0
- data/lib/familia/encryption/request_cache.rb +2 -0
- data/lib/familia/encryption.rb +9 -2
- data/lib/familia/errors.rb +2 -0
- data/lib/familia/features/autoloader.rb +2 -0
- data/lib/familia/features/encrypted_fields/concealed_string.rb +2 -0
- data/lib/familia/features/encrypted_fields/encrypted_field_type.rb +4 -0
- data/lib/familia/features/encrypted_fields.rb +2 -2
- data/lib/familia/features/expiration/extensions.rb +3 -1
- data/lib/familia/features/expiration.rb +12 -4
- data/lib/familia/features/external_identifier.rb +62 -7
- data/lib/familia/features/object_identifier.rb +49 -0
- data/lib/familia/features/quantization.rb +3 -1
- data/lib/familia/features/relationships/README.md +3 -1
- data/lib/familia/features/relationships/collection_operations.rb +2 -0
- data/lib/familia/features/relationships/indexing/multi_index_generators.rb +138 -9
- data/lib/familia/features/relationships/indexing/rebuild_strategies.rb +479 -0
- data/lib/familia/features/relationships/indexing/unique_index_generators.rb +97 -21
- data/lib/familia/features/relationships/indexing.rb +3 -0
- data/lib/familia/features/relationships/indexing_relationship.rb +3 -1
- data/lib/familia/features/relationships/participation/participant_methods.rb +131 -14
- data/lib/familia/features/relationships/participation/rebuild_strategies.md +41 -0
- data/lib/familia/features/relationships/participation/target_methods.rb +6 -6
- data/lib/familia/features/relationships/participation.rb +155 -69
- data/lib/familia/features/relationships/participation_membership.rb +69 -0
- data/lib/familia/features/relationships/participation_relationship.rb +34 -6
- data/lib/familia/features/relationships/score_encoding.rb +2 -0
- data/lib/familia/features/relationships.rb +5 -3
- data/lib/familia/features/safe_dump.rb +2 -0
- data/lib/familia/features/transient_fields/redacted_string.rb +2 -0
- data/lib/familia/features/transient_fields/single_use_redacted_string.rb +2 -0
- data/lib/familia/features/transient_fields/transient_field_type.rb +5 -3
- data/lib/familia/features/transient_fields.rb +2 -0
- data/lib/familia/features.rb +2 -0
- data/lib/familia/field_type.rb +3 -1
- data/lib/familia/horreum/connection.rb +17 -1
- data/lib/familia/horreum/database_commands.rb +8 -1
- data/lib/familia/horreum/definition.rb +16 -6
- data/lib/familia/horreum/management.rb +353 -52
- data/lib/familia/horreum/persistence.rb +179 -108
- data/lib/familia/horreum/related_fields.rb +2 -0
- data/lib/familia/horreum/serialization.rb +23 -4
- data/lib/familia/horreum/settings.rb +2 -0
- data/lib/familia/horreum/utils.rb +2 -0
- data/lib/familia/horreum.rb +15 -1
- data/lib/familia/identifier_extractor.rb +3 -1
- data/lib/familia/instrumentation.rb +156 -0
- data/lib/familia/json_serializer.rb +2 -0
- data/lib/familia/logging.rb +92 -32
- data/lib/familia/refinements/dear_json.rb +2 -0
- data/lib/familia/refinements/stylize_words.rb +2 -14
- data/lib/familia/refinements/time_literals.rb +2 -0
- data/lib/familia/refinements.rb +2 -0
- data/lib/familia/secure_identifier.rb +10 -2
- data/lib/familia/settings.rb +2 -0
- data/lib/familia/thread_safety/instrumented_mutex.rb +166 -0
- data/lib/familia/thread_safety/monitor.rb +328 -0
- data/lib/familia/utils.rb +13 -0
- data/lib/familia/verifiable_identifier.rb +3 -1
- data/lib/familia/version.rb +3 -1
- data/lib/familia.rb +31 -4
- data/lib/middleware/database_command_counter.rb +152 -0
- data/lib/middleware/database_logger.rb +295 -170
- data/lib/multi_result.rb +61 -31
- data/try/edge_cases/empty_identifiers_try.rb +2 -0
- data/try/edge_cases/hash_symbolization_try.rb +2 -0
- data/try/edge_cases/json_serialization_try.rb +2 -0
- data/try/edge_cases/legacy_data_detection/deserialization_edge_cases_try.rb +4 -0
- data/try/edge_cases/race_conditions_try.rb +4 -0
- data/try/edge_cases/reserved_keywords_try.rb +4 -0
- data/try/edge_cases/string_coercion_try.rb +2 -0
- data/try/edge_cases/ttl_side_effects_try.rb +4 -0
- data/try/features/count_any_edge_cases_try.rb +486 -0
- data/try/features/count_any_methods_try.rb +197 -0
- data/try/features/encrypted_fields/aad_protection_try.rb +4 -0
- data/try/features/encrypted_fields/concealed_string_core_try.rb +4 -0
- data/try/features/encrypted_fields/context_isolation_try.rb +4 -0
- data/try/features/encrypted_fields/encrypted_fields_core_try.rb +33 -0
- data/try/features/encrypted_fields/encrypted_fields_integration_try.rb +4 -0
- data/try/features/encrypted_fields/encrypted_fields_no_cache_security_try.rb +4 -0
- data/try/features/encrypted_fields/encrypted_fields_security_try.rb +4 -0
- data/try/features/encrypted_fields/error_conditions_try.rb +4 -0
- data/try/features/encrypted_fields/fresh_key_derivation_try.rb +4 -0
- data/try/features/encrypted_fields/fresh_key_try.rb +4 -0
- data/try/features/encrypted_fields/key_rotation_try.rb +4 -0
- data/try/features/encrypted_fields/memory_security_try.rb +4 -0
- data/try/features/encrypted_fields/missing_current_key_version_try.rb +4 -0
- data/try/features/encrypted_fields/nonce_uniqueness_try.rb +4 -0
- data/try/features/encrypted_fields/secure_by_default_behavior_try.rb +4 -0
- data/try/features/encrypted_fields/thread_safety_try.rb +4 -0
- data/try/features/encrypted_fields/universal_serialization_safety_try.rb +4 -0
- data/try/features/encryption/config_persistence_try.rb +4 -0
- data/try/features/encryption/core_try.rb +4 -0
- data/try/features/encryption/instance_variable_scope_try.rb +4 -0
- data/try/features/encryption/module_loading_try.rb +4 -0
- data/try/features/encryption/providers/aes_gcm_provider_try.rb +4 -0
- data/try/features/encryption/providers/xchacha20_poly1305_provider_try.rb +4 -0
- data/try/features/encryption/roundtrip_validation_try.rb +4 -0
- data/try/features/encryption/secure_memory_handling_try.rb +4 -0
- data/try/features/expiration/expiration_try.rb +4 -0
- data/try/features/external_identifier/external_identifier_try.rb +305 -8
- data/try/features/feature_dependencies_try.rb +2 -0
- data/try/features/feature_improvements_try.rb +2 -0
- data/try/features/field_groups_try.rb +2 -0
- data/try/features/object_identifier/object_identifier_integration_try.rb +12 -9
- data/try/features/object_identifier/object_identifier_try.rb +140 -0
- data/try/features/quantization/quantization_try.rb +4 -0
- data/try/features/real_feature_integration_try.rb +2 -0
- data/try/features/relationships/indexing_commands_verification_try.rb +2 -0
- data/try/features/relationships/indexing_rebuild_try.rb +606 -0
- data/try/features/relationships/indexing_try.rb +2 -0
- data/try/features/relationships/participation_bidirectional_try.rb +242 -0
- data/try/features/relationships/participation_commands_verification_spec.rb +4 -0
- data/try/features/relationships/participation_commands_verification_try.rb +2 -0
- data/try/features/relationships/participation_performance_improvements_try.rb +11 -9
- data/try/features/relationships/participation_reverse_index_try.rb +15 -13
- data/try/features/relationships/participation_target_class_resolution_try.rb +209 -0
- data/try/features/relationships/participation_unresolved_target_try.rb +109 -0
- data/try/features/relationships/relationships_api_changes_try.rb +2 -0
- data/try/features/relationships/relationships_edge_cases_try.rb +4 -0
- data/try/features/relationships/relationships_performance_minimal_try.rb +4 -0
- data/try/features/relationships/relationships_performance_simple_try.rb +4 -0
- data/try/features/relationships/relationships_performance_try.rb +4 -0
- data/try/features/relationships/relationships_performance_working_try.rb +4 -0
- data/try/features/relationships/relationships_try.rb +6 -4
- data/try/features/safe_dump/safe_dump_advanced_try.rb +4 -0
- data/try/features/safe_dump/safe_dump_try.rb +4 -0
- data/try/features/transient_fields/redacted_string_try.rb +2 -0
- data/try/features/transient_fields/refresh_reset_try.rb +3 -0
- data/try/features/transient_fields/simple_refresh_test.rb +3 -0
- data/try/features/transient_fields/single_use_redacted_string_try.rb +2 -0
- data/try/features/transient_fields/transient_fields_core_try.rb +4 -0
- data/try/features/transient_fields/transient_fields_integration_try.rb +4 -0
- data/try/integration/connection/fiber_context_preservation_try.rb +4 -0
- data/try/integration/connection/handler_constraints_try.rb +4 -0
- data/try/integration/connection/isolated_dbclient_try.rb +4 -0
- data/try/integration/connection/middleware_reconnect_try.rb +2 -0
- data/try/integration/connection/operation_mode_guards_try.rb +4 -0
- data/try/integration/connection/pipeline_fallback_integration_try.rb +3 -0
- data/try/integration/connection/pools_try.rb +4 -0
- data/try/integration/connection/responsibility_chain_tracking_try.rb +4 -0
- data/try/integration/connection/transaction_fallback_integration_try.rb +4 -0
- data/try/integration/connection/transaction_mode_permissive_try.rb +4 -0
- data/try/integration/connection/transaction_mode_strict_try.rb +4 -0
- data/try/integration/connection/transaction_mode_warn_try.rb +4 -0
- data/try/integration/connection/transaction_modes_try.rb +4 -0
- data/try/integration/conventional_inheritance_try.rb +4 -0
- data/try/integration/create_method_try.rb +4 -0
- data/try/integration/cross_component_try.rb +4 -0
- data/try/integration/data_types/datatype_pipelines_try.rb +9 -3
- data/try/integration/data_types/datatype_transactions_try.rb +17 -7
- data/try/integration/database_consistency_try.rb +4 -0
- data/try/integration/familia_extended_try.rb +4 -0
- data/try/integration/familia_members_methods_try.rb +4 -0
- data/try/integration/models/customer_safe_dump_try.rb +4 -0
- data/try/integration/models/customer_try.rb +7 -3
- data/try/integration/models/datatype_base_try.rb +4 -0
- data/try/integration/models/familia_object_try.rb +4 -0
- data/try/integration/persistence_operations_try.rb +4 -0
- data/try/integration/relationships_persistence_round_trip_try.rb +17 -14
- data/try/integration/save_methods_consistency_try.rb +241 -0
- data/try/integration/scenarios_try.rb +4 -0
- data/try/integration/secure_identifier_try.rb +4 -0
- data/try/integration/transaction_safety_core_try.rb +176 -0
- data/try/integration/transaction_safety_workflow_try.rb +291 -0
- data/try/integration/verifiable_identifier_try.rb +4 -0
- data/try/investigation/pipeline_routing/README.md +228 -0
- data/try/performance/benchmarks_try.rb +4 -0
- data/try/performance/transaction_safety_benchmark_try.rb +238 -0
- data/try/support/benchmarks/deserialization_benchmark.rb +3 -1
- data/try/support/benchmarks/deserialization_correctness_test.rb +3 -1
- data/try/support/debugging/cache_behavior_tracer.rb +4 -0
- data/try/support/debugging/debug_aad_process.rb +3 -0
- data/try/support/debugging/debug_concealed_internal.rb +3 -0
- data/try/support/debugging/debug_concealed_reveal.rb +3 -0
- data/try/support/debugging/debug_context_aad.rb +3 -0
- data/try/support/debugging/debug_context_simple.rb +3 -0
- data/try/support/debugging/debug_cross_context.rb +3 -0
- data/try/support/debugging/debug_database_load.rb +3 -0
- data/try/support/debugging/debug_encrypted_json_check.rb +3 -0
- data/try/support/debugging/debug_encrypted_json_step_by_step.rb +3 -0
- data/try/support/debugging/debug_exists_lifecycle.rb +3 -0
- data/try/support/debugging/debug_field_decrypt.rb +3 -0
- data/try/support/debugging/debug_fresh_cross_context.rb +3 -0
- data/try/support/debugging/debug_load_path.rb +3 -0
- data/try/support/debugging/debug_method_definition.rb +3 -0
- data/try/support/debugging/debug_method_resolution.rb +3 -0
- data/try/support/debugging/debug_minimal.rb +3 -0
- data/try/support/debugging/debug_provider.rb +3 -0
- data/try/support/debugging/debug_secure_behavior.rb +3 -0
- data/try/support/debugging/debug_string_class.rb +3 -0
- data/try/support/debugging/debug_test.rb +3 -0
- data/try/support/debugging/debug_test_design.rb +3 -0
- data/try/support/debugging/encryption_method_tracer.rb +4 -0
- data/try/support/debugging/provider_diagnostics.rb +4 -0
- data/try/support/helpers/test_cleanup.rb +4 -0
- data/try/support/helpers/test_helpers.rb +5 -0
- data/try/support/memory/memory_basic_test.rb +4 -0
- data/try/support/memory/memory_detailed_test.rb +4 -0
- data/try/support/memory/memory_search_for_string.rb +4 -0
- data/try/support/memory/test_actual_redactedstring_protection.rb +4 -0
- data/try/support/prototypes/atomic_saves_v1_context_proxy.rb +4 -0
- data/try/support/prototypes/atomic_saves_v2_connection_switching.rb +4 -0
- data/try/support/prototypes/atomic_saves_v3_connection_pool.rb +4 -0
- data/try/support/prototypes/atomic_saves_v4.rb +4 -0
- data/try/support/prototypes/lib/atomic_saves_v2_connection_switching_helpers.rb +4 -0
- data/try/support/prototypes/lib/atomic_saves_v3_connection_pool_helpers.rb +4 -0
- data/try/support/prototypes/pooling/configurable_stress_test.rb +4 -0
- data/try/support/prototypes/pooling/lib/atomic_saves_v3_connection_pool_helpers.rb +4 -0
- data/try/support/prototypes/pooling/lib/connection_pool_metrics.rb +4 -0
- data/try/support/prototypes/pooling/lib/connection_pool_stress_test.rb +4 -0
- data/try/support/prototypes/pooling/lib/connection_pool_threading_models.rb +4 -0
- data/try/support/prototypes/pooling/lib/visualize_stress_results.rb +4 -2
- data/try/support/prototypes/pooling/pool_siege.rb +4 -2
- data/try/support/prototypes/pooling/run_stress_tests.rb +4 -2
- data/try/thread_safety/README.md +496 -0
- data/try/thread_safety/class_connection_chain_race_try.rb +265 -0
- data/try/thread_safety/connection_chain_race_try.rb +148 -0
- data/try/thread_safety/encryption_manager_cache_race_try.rb +166 -0
- data/try/thread_safety/feature_registry_race_try.rb +226 -0
- data/try/thread_safety/fiber_pipeline_isolation_try.rb +235 -0
- data/try/thread_safety/fiber_transaction_isolation_try.rb +208 -0
- data/try/thread_safety/field_registration_race_try.rb +222 -0
- data/try/thread_safety/logger_initialization_race_try.rb +170 -0
- data/try/thread_safety/middleware_registration_race_try.rb +154 -0
- data/try/thread_safety/module_config_race_try.rb +175 -0
- data/try/thread_safety/secure_identifier_cache_race_try.rb +226 -0
- data/try/unit/core/autoloader_try.rb +4 -0
- data/try/unit/core/base_enhancements_try.rb +4 -0
- data/try/unit/core/connection_try.rb +4 -0
- data/try/unit/core/errors_try.rb +4 -0
- data/try/unit/core/extensions_try.rb +4 -0
- data/try/unit/core/familia_logger_try.rb +2 -0
- data/try/unit/core/familia_try.rb +4 -0
- data/try/unit/core/middleware_sampling_try.rb +335 -0
- data/try/unit/core/middleware_test_helpers_bug_try.rb +58 -0
- data/try/unit/core/middleware_thread_safety_try.rb +245 -0
- data/try/unit/core/middleware_try.rb +4 -0
- data/try/unit/core/settings_try.rb +4 -0
- data/try/unit/core/time_utils_try.rb +4 -0
- data/try/unit/core/tools_try.rb +4 -0
- data/try/unit/core/utils_try.rb +37 -0
- data/try/unit/data_types/boolean_try.rb +39 -22
- data/try/unit/data_types/counter_try.rb +4 -0
- data/try/unit/data_types/datatype_base_try.rb +4 -0
- data/try/unit/data_types/hash_try.rb +6 -2
- data/try/unit/data_types/list_try.rb +4 -0
- data/try/unit/data_types/lock_try.rb +4 -0
- data/try/unit/data_types/serialization_try.rb +386 -0
- data/try/unit/data_types/sorted_set_try.rb +4 -0
- data/try/unit/data_types/sorted_set_zadd_options_try.rb +4 -0
- data/try/unit/data_types/string_try.rb +4 -0
- data/try/unit/data_types/unsortedset_try.rb +4 -0
- data/try/unit/familia_resolve_class_try.rb +116 -0
- data/try/unit/horreum/auto_indexing_on_save_try.rb +5 -1
- data/try/unit/horreum/automatic_index_validation_try.rb +2 -0
- data/try/unit/horreum/base_try.rb +4 -0
- data/try/unit/horreum/class_methods_try.rb +4 -0
- data/try/unit/horreum/commands_try.rb +4 -0
- data/try/unit/horreum/defensive_initialization_try.rb +4 -0
- data/try/unit/horreum/destroy_related_fields_cleanup_try.rb +6 -1
- data/try/unit/horreum/enhanced_conflict_handling_try.rb +4 -0
- data/try/unit/horreum/field_categories_try.rb +4 -0
- data/try/unit/horreum/field_definition_try.rb +4 -0
- data/try/unit/horreum/initialization_try.rb +4 -0
- data/try/unit/horreum/json_type_preservation_try.rb +2 -0
- data/try/unit/horreum/optimized_loading_try.rb +156 -0
- data/try/unit/horreum/relations_try.rb +4 -0
- data/try/unit/horreum/serialization_persistent_fields_try.rb +4 -0
- data/try/unit/horreum/serialization_try.rb +4 -0
- data/try/unit/horreum/settings_try.rb +4 -0
- data/try/unit/horreum/unique_index_edge_cases_try.rb +4 -0
- data/try/unit/horreum/unique_index_guard_validation_try.rb +2 -0
- data/try/unit/middleware/database_command_counter_methods_try.rb +139 -0
- data/try/unit/middleware/database_logger_methods_try.rb +251 -0
- data/try/unit/refinements/dear_json_array_methods_try.rb +4 -0
- data/try/unit/refinements/dear_json_hash_methods_try.rb +4 -0
- data/try/unit/refinements/time_literals_numeric_methods_try.rb +4 -0
- data/try/unit/refinements/time_literals_string_methods_try.rb +4 -0
- data/try/unit/thread_safety_monitor_try.rb +149 -0
- metadata +69 -17
- data/.github/workflows/code-quality.yml +0 -138
- data/changelog.d/20251011_012003_delano_159_datatype_transaction_pipeline_support.rst +0 -91
- data/changelog.d/20251011_203905_delano_next.rst +0 -30
- data/changelog.d/20251011_212633_delano_next.rst +0 -13
- data/changelog.d/20251011_221253_delano_next.rst +0 -26
- data/docs/archive/FAMILIA_RELATIONSHIPS.md +0 -210
- data/docs/archive/FAMILIA_TECHNICAL.md +0 -823
- data/docs/archive/FAMILIA_UPDATE.md +0 -226
- data/docs/archive/README.md +0 -64
- data/docs/archive/api-reference.md +0 -333
- data/docs/guides/core-field-system.md +0 -806
- data/docs/guides/implementation.md +0 -276
- data/docs/guides/security-model.md +0 -183
data/CHANGELOG.rst
CHANGED
|
@@ -7,61 +7,222 @@ The format is based on `Keep a Changelog <https://keepachangelog.com/en/1.1.0/>`
|
|
|
7
7
|
|
|
8
8
|
<!--scriv-insert-here-->
|
|
9
9
|
|
|
10
|
-
.. _changelog-2.0.0.
|
|
10
|
+
.. _changelog-2.0.0.pre22:
|
|
11
|
+
|
|
12
|
+
2.0.0.pre22 — 2025-12-03
|
|
13
|
+
========================
|
|
14
|
+
|
|
15
|
+
- **ExternalIdentifier Format Flexibility**: The `external_identifier` feature now supports customizable format templates via the `format` option (e.g., `format: 'cust_%{id}'` or `format: 'api-%{id}'`). Default format remains `'ext_%{id}'`. Provides complete flexibility for various ID formatting needs including different prefixes, separators, URL paths, or no prefix at all.
|
|
11
16
|
|
|
12
|
-
|
|
13
|
-
|
|
17
|
+
- **Participation Relationships with Symbol/String Target Classes**: Fixed four bugs that occurred when calling `participates_in` with Symbol/String target class instead of Class object. Issues included NoMethodError during relationship definition (private method call), failures in `current_participations` (undefined `familia_name`), errors in `target_class_config_name` (undefined `config_name`), and confusing error messages for load order issues. All now properly resolve using `Familia.resolve_class` API with clear error messages for common issues.
|
|
18
|
+
|
|
19
|
+
- **Pipelined Bulk Loading Methods**: New `load_multi` and `load_multi_by_keys` methods enable efficient bulk object loading using Redis pipelining, reducing network round trips from N×2 commands to a single batch (up to 2× performance improvement). Methods maintain nil-return contract for missing objects and preserve input order.
|
|
20
|
+
|
|
21
|
+
- **Optional EXISTS Check Optimization**: The `find_by_dbkey` and `find_by_identifier` methods now accept `check_exists:` parameter (default: `true`) to optionally skip EXISTS check, reducing Redis commands from 2 to 1 per object. Maintains backwards compatibility and same nil-return behavior.
|
|
22
|
+
|
|
23
|
+
- **Parameter Consistency**: The `suffix` parameter in `find_by_identifier` is now a keyword parameter (was optional positional) for consistency with `check_exists`, following Ruby conventions.
|
|
14
24
|
|
|
15
25
|
Added
|
|
16
26
|
-----
|
|
17
27
|
|
|
18
|
-
-
|
|
28
|
+
- Bidirectional reverse collection methods for ``participates_in`` with ``_instances`` suffix (e.g., ``user.project_team_instances``, ``user.project_team_ids``). Supports union behavior for multiple collections and custom naming via ``as:`` parameter. Closes #179.
|
|
29
|
+
|
|
30
|
+
Changed
|
|
31
|
+
-------
|
|
32
|
+
|
|
33
|
+
- All Ruby files now include consistent headers with ``frozen_string_literal: true`` pragma for improved performance and memory efficiency. Headers follow the format: filename comment, blank comment line, frozen string literal pragma. Executable scripts properly place shebang first.
|
|
34
|
+
|
|
35
|
+
- Standardized DataType serialization to use JSON encoding for type preservation, matching Horreum field behavior. All primitive values (Integer, Boolean, String, Float, Hash, Array, nil) are now consistently serialized through JSON, ensuring types are preserved across the Redis storage boundary. Familia object references continue to use identifier extraction. Issue #190.
|
|
36
|
+
|
|
37
|
+
Fixed
|
|
38
|
+
-----
|
|
39
|
+
|
|
40
|
+
- Fixed critical race condition in mutex initialization for connection chain lazy loading. The mutex itself was being lazily initialized with ``||=``, which is not atomic and could result in multiple threads creating different mutex instances, defeating synchronization. Changed to eager initialization via ``Connection.included`` hook. (`lib/familia/horreum/connection.rb`)
|
|
41
|
+
|
|
42
|
+
- Fixed critical race condition in mutex initialization for logger lazy loading. Similar to connection chain issue, the logger mutex was lazily initialized with ``||=``. Changed to eager initialization at module definition time. (`lib/familia/logging.rb`)
|
|
43
|
+
|
|
44
|
+
- Fixed logger assignment atomicity issue where ``Familia.logger=`` set ``DatabaseLogger.logger`` outside the mutex synchronization block, potentially causing ``Familia.logger`` and ``DatabaseLogger.logger`` to be temporarily out of sync during concurrent access. Moved ``DatabaseLogger.logger`` assignment inside the synchronization block. (`lib/familia/logging.rb`)
|
|
45
|
+
|
|
46
|
+
- Added explicit return statement to ``Familia.logger`` method for robustness against future refactoring. (`lib/familia/logging.rb`)
|
|
19
47
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
* Two new connection handlers: ``ParentDelegationHandler`` for owned DataTypes and ``StandaloneConnectionHandler`` for independent DataTypes
|
|
23
|
-
* Enhanced ``direct_access`` method with automatic transaction/pipeline context detection
|
|
24
|
-
* Shared ``Familia::Connection::Behavior`` module extracting common connection functionality
|
|
48
|
+
AI Assistance
|
|
49
|
+
-------------
|
|
25
50
|
|
|
26
|
-
-
|
|
27
|
-
|
|
28
|
-
-
|
|
29
|
-
|
|
51
|
+
- Claude Code (Opus 4, Sonnet 4.5): Implementation of bidirectional participation relationships, external identifier format flexibility, bulk loading optimization with pipelining, race condition fixes in mutex initialization, frozen string literal pragma automation (308 files), and DataType serialization standardization. Comprehensive test coverage and documentation throughout.
|
|
52
|
+
|
|
53
|
+
.. _changelog-2.0.0.pre21:
|
|
54
|
+
|
|
55
|
+
2.0.0.pre21 — 2025-10-21
|
|
56
|
+
========================
|
|
57
|
+
|
|
58
|
+
Added
|
|
59
|
+
-----
|
|
60
|
+
|
|
61
|
+
- 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``.
|
|
30
62
|
|
|
31
63
|
Changed
|
|
32
64
|
-------
|
|
33
65
|
|
|
34
|
-
-
|
|
66
|
+
- **BREAKING**: Duration measurements now use integer microseconds instead of milliseconds. Instrumentation hooks and logging output have changed format:
|
|
67
|
+
|
|
68
|
+
- ``Familia.on_command`` receives ``duration`` in microseconds (was ``duration_ms`` in milliseconds)
|
|
69
|
+
- ``Familia.on_pipeline`` receives ``duration`` in microseconds (was ``duration_ms`` in milliseconds)
|
|
70
|
+
- ``Familia.on_lifecycle`` uses ``duration`` key in microseconds (was ``duration_ms`` in milliseconds)
|
|
71
|
+
- Log messages show ``duration=1234`` (microseconds) instead of ``duration_ms=1.23`` (milliseconds)
|
|
72
|
+
|
|
73
|
+
- Migration: Convert to milliseconds when needed: ``duration / 1000.0``
|
|
74
|
+
|
|
75
|
+
Fixed
|
|
76
|
+
-----
|
|
77
|
+
|
|
78
|
+
- 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.
|
|
79
|
+
|
|
80
|
+
- Thread Safety Test Suite: Corrected test assertions to properly verify thread safety invariants.
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
AI Assistance
|
|
84
|
+
-------------
|
|
85
|
+
|
|
86
|
+
- 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.
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
.. _changelog-2.0.0.pre20:
|
|
91
|
+
|
|
92
|
+
2.0.0.pre20 — 2025-10-20
|
|
93
|
+
========================
|
|
94
|
+
|
|
95
|
+
Added
|
|
96
|
+
-----
|
|
97
|
+
|
|
98
|
+
- **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.
|
|
99
|
+
|
|
100
|
+
- **DatabaseLogger Structured Mode**: Added ``DatabaseLogger.structured_logging`` mode that outputs Redis commands with structured key=value context instead of formatted string output.
|
|
101
|
+
|
|
102
|
+
- **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.
|
|
103
|
+
|
|
104
|
+
- **Lifecycle Logging**: Horreum initialize, save, and destroy operations now log with timing and structured context when ``FAMILIA_DEBUG`` is enabled.
|
|
105
|
+
|
|
106
|
+
- **Operational Logging**: TTL operations and serialization errors now include structured context for better debugging.
|
|
107
|
+
|
|
108
|
+
Changed
|
|
109
|
+
-------
|
|
110
|
+
|
|
111
|
+
- 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).
|
|
112
|
+
|
|
113
|
+
- **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.
|
|
114
|
+
|
|
115
|
+
Removed
|
|
116
|
+
-------
|
|
35
117
|
|
|
36
|
-
-
|
|
37
|
-
- **BREAKING**: Updated ``save_if_not_exists`` to ``save_if_not_exists!`` with optimistic locking and automatic retry logic (up to 3 attempts)
|
|
38
|
-
- Improved ``save`` method to use single atomic transaction encompassing field updates, expiration setting, index updates, and instance collection management
|
|
39
|
-
- Enhanced ``delete!`` methods to work correctly within Redis transactions
|
|
40
|
-
- Updated timestamp fields (``created``, ``updated``) to use float values instead of integers for higher precision
|
|
41
|
-
- Refined log message formatting for better readability and debugging
|
|
42
|
-
- Removed deprecated Connection instance methods for Horreum models in favor of class-level database operations
|
|
43
|
-
- Clarified "pipelined" terminology throughout codebase (renamed from "pipeline" for consistency with Redis documentation)
|
|
118
|
+
- **Internal Methods**: Removed ``Familia.ld`` and ``Familia.le`` internal logging methods. These were never part of the public API.
|
|
44
119
|
|
|
45
120
|
Fixed
|
|
46
121
|
-----
|
|
47
122
|
|
|
48
|
-
-
|
|
49
|
-
|
|
123
|
+
- 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.
|
|
124
|
+
|
|
125
|
+
- 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.
|
|
50
126
|
|
|
51
127
|
Documentation
|
|
52
128
|
-------------
|
|
53
129
|
|
|
54
|
-
-
|
|
130
|
+
- 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.
|
|
55
131
|
|
|
56
132
|
AI Assistance
|
|
57
133
|
-------------
|
|
58
134
|
|
|
59
|
-
|
|
135
|
+
- 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.
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
This implementation was completed with significant AI assistance from Claude (Anthropic), including:
|
|
140
|
+
|
|
141
|
+
- Architecture design for the instrumentation hook system
|
|
142
|
+
- Implementation of structured logging methods with backward-compatible signatures
|
|
143
|
+
- Integration of hooks into DatabaseLogger middleware
|
|
144
|
+
- Bulk replacement of 51 logging method calls across 21 files
|
|
145
|
+
- Comprehensive code review and bug fixes (RedisClient::Config object vs hash handling)
|
|
146
|
+
- Documentation and changelog creation
|
|
147
|
+
|
|
148
|
+
The AI provided discussion, rubber ducking, code generation, testing strategy, and documentation throughout the implementation process.
|
|
149
|
+
|
|
150
|
+
Developer Notes
|
|
151
|
+
---------------
|
|
152
|
+
|
|
153
|
+
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.
|
|
154
|
+
|
|
155
|
+
**Migration**: No action required for external users. Internal development references to ``Familia.ld`` should use ``Familia.debug``, and ``Familia.le`` should use ``Familia.error``.
|
|
156
|
+
|
|
157
|
+
**New Capabilities**: Applications can now register instrumentation hooks for operational observability:
|
|
158
|
+
|
|
159
|
+
.. code-block:: ruby
|
|
160
|
+
|
|
161
|
+
# Enable structured logging with 10% sampling for production
|
|
162
|
+
Familia.logger = Rails.logger
|
|
163
|
+
DatabaseLogger.structured_logging = true
|
|
164
|
+
DatabaseLogger.sample_rate = 0.1 # Log 10% of commands
|
|
165
|
+
|
|
166
|
+
# Register hooks for audit trails
|
|
167
|
+
Familia.on_command do |cmd, duration_ms, context|
|
|
168
|
+
AuditLog.create!(
|
|
169
|
+
event: 'redis_command',
|
|
170
|
+
command: cmd,
|
|
171
|
+
duration_ms: duration_ms,
|
|
172
|
+
user_id: RequestContext.current_user_id
|
|
173
|
+
)
|
|
174
|
+
end
|
|
60
175
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
176
|
+
Familia.on_lifecycle do |event, instance, context|
|
|
177
|
+
case event
|
|
178
|
+
when :save
|
|
179
|
+
AuditLog.create!(event: 'object_saved', object_id: instance.identifier)
|
|
180
|
+
when :destroy
|
|
181
|
+
AuditLog.create!(event: 'object_destroyed', object_id: instance.identifier)
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
.. _changelog-2.0.0.pre19:
|
|
186
|
+
|
|
187
|
+
2.0.0.pre19 — 2025-10-13
|
|
188
|
+
========================
|
|
189
|
+
|
|
190
|
+
Added
|
|
191
|
+
-----
|
|
192
|
+
|
|
193
|
+
- **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>`_
|
|
194
|
+
|
|
195
|
+
* ``transaction`` and ``pipelined`` methods for all DataType classes
|
|
196
|
+
* Connection chain pattern with ``ParentDelegationHandler`` and ``StandaloneConnectionHandler``
|
|
197
|
+
* Enhanced ``direct_access`` method with automatic context detection
|
|
198
|
+
* Shared ``Familia::Connection::Behavior`` module for common functionality
|
|
199
|
+
|
|
200
|
+
- **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
|
|
201
|
+
|
|
202
|
+
Changed
|
|
203
|
+
-------
|
|
204
|
+
|
|
205
|
+
- **Connection Architecture** - Refactored to share ``Familia::Connection::Behavior`` between Horreum and DataType, with cleaner URI construction for logical databases
|
|
206
|
+
|
|
207
|
+
- **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
|
|
208
|
+
|
|
209
|
+
Fixed
|
|
210
|
+
-----
|
|
211
|
+
|
|
212
|
+
- URI formatting for DataType objects with logical database settings
|
|
213
|
+
- Transaction detection and validation flow for unique index operations
|
|
214
|
+
|
|
215
|
+
Documentation
|
|
216
|
+
-------------
|
|
217
|
+
|
|
218
|
+
- Enhanced ``save()`` method documentation with transaction restrictions
|
|
219
|
+
- Updated indexing and relationship cheatsheets with improved terminology
|
|
220
|
+
- Added comprehensive test coverage (48 new tests) for transactions, pipelines, and validation
|
|
221
|
+
|
|
222
|
+
AI Assistance
|
|
223
|
+
-------------
|
|
224
|
+
|
|
225
|
+
This release was implemented with assistance from Claude (Anthropic) for architectural design, test coverage, and systematic refactoring of terminology across the codebase.
|
|
65
226
|
|
|
66
227
|
|
|
67
228
|
.. _changelog-2.0.0.pre18:
|
|
@@ -118,7 +279,7 @@ Documentation
|
|
|
118
279
|
AI Assistance
|
|
119
280
|
-------------
|
|
120
281
|
|
|
121
|
-
- Claude Code (claude-sonnet-4-5) provided implementation guidance, identified the ``initialize_with_keyword_args`` falsy value bug, wrote
|
|
282
|
+
- 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.
|
|
122
283
|
|
|
123
284
|
- Issue analysis, implementation guidance, test verification, and documentation for JSON serialization changes and encrypted field security fix.
|
|
124
285
|
|
|
@@ -132,19 +293,17 @@ AI Assistance
|
|
|
132
293
|
Added
|
|
133
294
|
-----
|
|
134
295
|
|
|
135
|
-
- **SortedSet#add
|
|
296
|
+
- **SortedSet#add** - Full ZADD option support (NX, XX, GT, LT, CH) for atomic conditional operations and accurate change tracking. Closes #135
|
|
136
297
|
|
|
137
298
|
Fixed
|
|
138
299
|
-----
|
|
139
300
|
|
|
140
|
-
- Restored objid provenance tracking when loading objects from Redis
|
|
301
|
+
- Restored objid provenance tracking when loading objects from Redis, enabling dependent features to derive external identifiers. PR #131
|
|
141
302
|
|
|
142
303
|
AI Assistance
|
|
143
304
|
-------------
|
|
144
305
|
|
|
145
|
-
- Claude
|
|
146
|
-
|
|
147
|
-
- 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.
|
|
306
|
+
- Claude (Anthropic) assisted with objid generator inference implementation and ZADD option validation design.
|
|
148
307
|
|
|
149
308
|
.. _changelog-2.0.0.pre16:
|
|
150
309
|
|
|
@@ -154,57 +313,29 @@ AI Assistance
|
|
|
154
313
|
Added
|
|
155
314
|
-----
|
|
156
315
|
|
|
157
|
-
-
|
|
158
|
-
|
|
159
|
-
Example: ``unique_index :badge_number, :badge_index, within: Company`` creates per-company unique badge lookups using HashKey DataType.
|
|
316
|
+
- **Instance-scoped unique indexes** via ``unique_index`` with ``within:`` parameter for per-scope unique lookups. Issue #128
|
|
160
317
|
|
|
161
318
|
Changed
|
|
162
319
|
-------
|
|
163
320
|
|
|
164
|
-
- **BREAKING**: Consolidated relationships API
|
|
165
|
-
- **BREAKING**: Renamed ``context_class`` terminology to ``target_class`` throughout relationships module for clarity
|
|
166
|
-
- **BREAKING**: Removed ``tracking.rb`` and ``membership.rb`` modules, merged functionality into ``participation.rb``
|
|
167
|
-
- **BREAKING**: Updated method names and configuration keys to use ``target`` instead of ``context`` terminology
|
|
168
|
-
- Added ``bidirectional`` parameter to ``participates_in`` to control generation of convenience methods (default: true)
|
|
169
|
-
- Added support for different collection types (sorted_set, set, list) in unified ``participates_in`` API
|
|
170
|
-
- Renamed ``class_tracked_in`` to ``class_participates_in`` for consistency
|
|
171
|
-
|
|
172
|
-
- Renamed DataType classes to avoid Ruby namespace confusion: ``Familia::String`` → ``Familia::StringKey``, ``Familia::List`` → ``Familia::ListKey``
|
|
173
|
-
- Added dual registration for both traditional and explicit method names (``string``/``stringkey``, ``list``/``listkey``)
|
|
174
|
-
- Updated ``Counter`` and ``Lock`` to inherit from ``StringKey`` instead of ``String``
|
|
321
|
+
- **BREAKING**: Consolidated relationships API - replaced ``tracked_in`` and ``member_of`` with unified ``participates_in`` method. PR #110
|
|
175
322
|
|
|
176
|
-
- **BREAKING
|
|
323
|
+
- **BREAKING**: Renamed indexing API methods for clarity. Issue #128
|
|
324
|
+
- ``class_indexed_by`` → ``unique_index``
|
|
325
|
+
- ``indexed_by`` → ``multi_index``
|
|
326
|
+
- Changed ``multi_index`` to use ``UnsortedSet`` instead of ``SortedSet``
|
|
177
327
|
|
|
178
|
-
|
|
179
|
-
- ``indexed_by`` → ``multi_index`` (1:many field-to-objects mapping via UnsortedSet)
|
|
180
|
-
- Parameter ``target:`` → ``within:`` for consistency across both index types
|
|
181
|
-
|
|
182
|
-
- **BREAKING:** Changed ``multi_index`` to use ``UnsortedSet`` instead of ``SortedSet``. Issue #128
|
|
183
|
-
|
|
184
|
-
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)``
|
|
328
|
+
- **DataType class renaming** to avoid Ruby namespace conflicts: ``Familia::String`` → ``Familia::StringKey``, ``Familia::List`` → ``Familia::ListKey``, etc., with dual registration for compatibility
|
|
185
329
|
|
|
186
330
|
Documentation
|
|
187
331
|
-------------
|
|
188
332
|
|
|
189
|
-
- Updated
|
|
190
|
-
- Enhanced examples to demonstrate both traditional and explicit DataType method naming
|
|
191
|
-
|
|
192
|
-
- Updated inline module documentation
|
|
193
|
-
- ``Familia::Features::Relationships::Indexing`` with comprehensive examples, terminology guide, and design philosophy.
|
|
194
|
-
- ``Familia::Features::Relationships::Participation`` to clarify differences from indexing module.
|
|
333
|
+
- Updated indexing and participation module documentation with comprehensive examples and design philosophy
|
|
195
334
|
|
|
196
335
|
AI Assistance
|
|
197
336
|
-------------
|
|
198
337
|
|
|
199
|
-
-
|
|
200
|
-
- Design and implementation of unified ``participates_in`` API integrating both functionalities
|
|
201
|
-
- Systematic refactoring of codebase terminology from context to target
|
|
202
|
-
- Complete test suite updates to verify API consolidation and new functionality
|
|
203
|
-
|
|
204
|
-
- DataType class renaming and dual registration system implementation designed and developed with Claude Code assistance
|
|
205
|
-
- All test updates and documentation enhancements created with AI support
|
|
206
|
-
|
|
207
|
-
- Architecture design, implementation, test updates, and documentation for indexing API refactoring completed with Claude Code assistance. Issue #128
|
|
338
|
+
- Claude (Anthropic) assisted with relationship API consolidation, DataType renaming, and indexing API refactoring.
|
|
208
339
|
|
|
209
340
|
.. _changelog-2.0.0.pre14:
|
|
210
341
|
|
|
@@ -214,19 +345,18 @@ AI Assistance
|
|
|
214
345
|
Changed
|
|
215
346
|
-------
|
|
216
347
|
|
|
217
|
-
- **BREAKING
|
|
348
|
+
- **BREAKING**: Renamed ``TimeUtils`` to ``TimeLiterals`` to better reflect module purpose. PR #100
|
|
218
349
|
|
|
219
350
|
Fixed
|
|
220
351
|
-----
|
|
221
352
|
|
|
222
|
-
- Fixed
|
|
353
|
+
- **CRITICAL**: Fixed Redis connection persistence for standalone DataType objects. PR #107
|
|
354
|
+
- Fixed ExternalIdentifier HashKey cleanup using correct ``remove_field()`` method. PR #100
|
|
223
355
|
|
|
224
356
|
AI Assistance
|
|
225
357
|
-------------
|
|
226
358
|
|
|
227
|
-
- Claude
|
|
228
|
-
- Gemini 2.5 Flash wrote the inline docs for TimeLiterals based on a discussion re: naming rationale.
|
|
229
|
-
- 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.
|
|
359
|
+
- Claude (Anthropic) and Gemini assisted with TimeLiterals refactoring and ExternalIdentifier fixes.
|
|
230
360
|
|
|
231
361
|
.. _changelog-2.0.0.pre13:
|
|
232
362
|
|
|
@@ -236,61 +366,39 @@ AI Assistance
|
|
|
236
366
|
Added
|
|
237
367
|
-----
|
|
238
368
|
|
|
239
|
-
- **Feature Autoloading System
|
|
240
|
-
|
|
241
|
-
- **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.
|
|
242
|
-
|
|
243
|
-
- Added ``PER_MONTH`` constant (2,629,746 seconds = 30.437 days) derived from Gregorian year for consistent month calculations.
|
|
244
|
-
- Added ``months``, ``month``, and ``in_months`` conversion methods to Numeric refinement.
|
|
245
|
-
- Added month unit mappings (``'mo'``, ``'month'``, ``'months'``) to TimeLiterals ``UNIT_METHODS`` hash.
|
|
369
|
+
- **Feature Autoloading System** - Features automatically discover and load extension files from project directories using conventional patterns. PR #97
|
|
246
370
|
|
|
247
|
-
- **
|
|
371
|
+
- **Month calculations** - Added ``PER_MONTH`` constant and month conversion methods to TimeLiterals refinement. Issue #94
|
|
248
372
|
|
|
249
373
|
Changed
|
|
250
374
|
-------
|
|
251
375
|
|
|
252
|
-
-
|
|
253
|
-
-
|
|
254
|
-
-
|
|
255
|
-
|
|
256
|
-
- Updated ``PER_YEAR`` constant to use Gregorian year (31,556,952 seconds = 365.2425 days) for calendar consistency.
|
|
257
|
-
|
|
258
|
-
- **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
|
|
259
|
-
|
|
260
|
-
- **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
|
|
376
|
+
- **Performance** - Replaced stdlib JSON with OJ gem for 2-5x faster operations. PR #97
|
|
377
|
+
- Refactored time/numeric extensions from global monkey patches to Ruby refinements
|
|
378
|
+
- Enhanced encryption serialization safety with improved ConcealedString handling
|
|
261
379
|
|
|
262
380
|
Fixed
|
|
263
381
|
-----
|
|
264
382
|
|
|
265
|
-
- Fixed
|
|
266
|
-
-
|
|
267
|
-
|
|
268
|
-
- 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.
|
|
269
|
-
- 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``.
|
|
383
|
+
- Fixed ``months_old`` and ``years_old`` methods returning raw seconds instead of proper units. Issue #94
|
|
384
|
+
- Fixed byte conversion boundary logic (``size >= 1024`` instead of ``size > 1024``)
|
|
385
|
+
- Fixed calendar consistency where ``12.months != 1.year`` by using Gregorian year
|
|
270
386
|
|
|
271
387
|
Security
|
|
272
388
|
--------
|
|
273
389
|
|
|
274
|
-
-
|
|
390
|
+
- Improved concealed value protection during JSON serialization across all OJ modes. PR #97
|
|
275
391
|
|
|
276
392
|
Documentation
|
|
277
393
|
-------------
|
|
278
394
|
|
|
279
|
-
-
|
|
280
|
-
-
|
|
395
|
+
- Added Feature System Autoloading guide with conventions and usage examples
|
|
396
|
+
- Enhanced YARD documentation for autoloading modules
|
|
281
397
|
|
|
282
398
|
AI Assistance
|
|
283
399
|
-------------
|
|
284
400
|
|
|
285
|
-
-
|
|
286
|
-
- Assisted with refactoring global extensions to proper refinements while maintaining backward compatibility
|
|
287
|
-
- Helped debug and fix the byte conversion boundary condition bug
|
|
288
|
-
|
|
289
|
-
- 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.
|
|
290
|
-
|
|
291
|
-
- 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.
|
|
292
|
-
|
|
293
|
-
- Performance optimization research and OJ gem integration strategy, including compatibility analysis and testing approach for seamless stdlib JSON replacement. PR #97
|
|
401
|
+
- Claude (Anthropic) assisted with refinement refactoring, autoloading system design, and OJ integration.
|
|
294
402
|
|
|
295
403
|
2.0.0.pre12 — 2025-09-04
|
|
296
404
|
========================
|
data/CLAUDE.md
CHANGED
|
@@ -53,7 +53,7 @@ Add changelog fragment with each user-facing or documented change (optional but
|
|
|
53
53
|
### Known Issues & Quirks
|
|
54
54
|
- **Reserved Keywords**: Cannot use `ttl`, `db`, `valkey`, `redis` as field names - use prefixed alternatives
|
|
55
55
|
- **Empty Identifiers**: Cause stack overflow in key generation - validate before operations
|
|
56
|
-
- **Connection
|
|
56
|
+
- **Lazy Initialization Races**: Connection chains and field collections use lazy initialization without synchronization (generally safe due to Ruby GIL, but not guaranteed)
|
|
57
57
|
|
|
58
58
|
### Debugging
|
|
59
59
|
- **Database command logging**: You can request real-time Database command monitoring from the user
|
|
@@ -191,3 +191,30 @@ end
|
|
|
191
191
|
**Memory Efficiency**: Only non-nil values are stored in keystore database to optimize memory usage.
|
|
192
192
|
|
|
193
193
|
**Thread Safety**: Data types are frozen after instantiation to ensure immutability.
|
|
194
|
+
|
|
195
|
+
## Thread Safety Considerations
|
|
196
|
+
|
|
197
|
+
### Current Thread Safety Status (as of 2025-10-21)
|
|
198
|
+
|
|
199
|
+
Familia has **good thread safety** for standard multi-threaded environments:
|
|
200
|
+
|
|
201
|
+
### Testing Thread Safety
|
|
202
|
+
|
|
203
|
+
Thread safety tests are available in `try/thread_safety/`:
|
|
204
|
+
- **100% passing** (56/56 tests)
|
|
205
|
+
- **CyclicBarrier pattern** for maximum contention testing
|
|
206
|
+
- **Test execution**: ~300ms for full suite with 1,000+ concurrent operations
|
|
207
|
+
- **Production monitoring**: 10/10 monitoring tests passing
|
|
208
|
+
|
|
209
|
+
Run thread safety tests:
|
|
210
|
+
```bash
|
|
211
|
+
bundle exec try --agent try/thread_safety/
|
|
212
|
+
bundle exec try --agent try/unit/thread_safety_monitor_try.rb
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Best Practices for Thread-Safe Usage
|
|
216
|
+
|
|
217
|
+
1. **Configure Once at Startup**: Module-level configuration should be set before threads spawn
|
|
218
|
+
2. **Use Immutable DataTypes**: Leverage the fact that DataType instances are frozen
|
|
219
|
+
3. **Test Under Concurrency**: Use the patterns in `try/thread_safety/` to verify thread safety
|
|
220
|
+
4. **Enable Production Monitoring**: Use `Familia.start_monitoring!` to track contention in production
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
familia (2.0.0.
|
|
4
|
+
familia (2.0.0.pre22)
|
|
5
5
|
benchmark (~> 0.4)
|
|
6
|
+
concurrent-ruby (~> 1.3)
|
|
6
7
|
connection_pool (~> 2.5)
|
|
7
8
|
csv (~> 3.3)
|
|
8
9
|
logger (~> 1.7)
|
|
@@ -21,7 +22,7 @@ GEM
|
|
|
21
22
|
concurrent-ruby (1.3.5)
|
|
22
23
|
connection_pool (2.5.3)
|
|
23
24
|
csv (3.3.5)
|
|
24
|
-
date (3.
|
|
25
|
+
date (3.5.0)
|
|
25
26
|
debug (1.11.0)
|
|
26
27
|
irb (~> 1.10)
|
|
27
28
|
reline (>= 0.3.8)
|
|
@@ -55,11 +56,11 @@ GEM
|
|
|
55
56
|
dry-inflector (~> 1.0)
|
|
56
57
|
dry-logic (~> 1.4)
|
|
57
58
|
zeitwerk (~> 2.6)
|
|
58
|
-
erb (5.
|
|
59
|
+
erb (5.1.3)
|
|
59
60
|
ffi (1.17.2)
|
|
60
61
|
ffi (1.17.2-arm64-darwin)
|
|
61
62
|
io-console (0.8.1)
|
|
62
|
-
irb (1.15.
|
|
63
|
+
irb (1.15.3)
|
|
63
64
|
pp (>= 0.6.0)
|
|
64
65
|
rdoc (>= 4.0.0)
|
|
65
66
|
reline (>= 0.4.2)
|
|
@@ -67,7 +68,7 @@ GEM
|
|
|
67
68
|
language_server-protocol (3.17.0.5)
|
|
68
69
|
lint_roller (1.1.0)
|
|
69
70
|
logger (1.7.0)
|
|
70
|
-
minitest (5.
|
|
71
|
+
minitest (5.26.0)
|
|
71
72
|
oj (3.16.11)
|
|
72
73
|
bigdecimal (>= 3.0)
|
|
73
74
|
ostruct (>= 0.2)
|
|
@@ -78,10 +79,10 @@ GEM
|
|
|
78
79
|
racc
|
|
79
80
|
pastel (0.8.0)
|
|
80
81
|
tty-color (~> 0.5)
|
|
81
|
-
pp (0.6.
|
|
82
|
+
pp (0.6.3)
|
|
82
83
|
prettyprint
|
|
83
84
|
prettyprint (0.2.0)
|
|
84
|
-
prism (1.
|
|
85
|
+
prism (1.6.0)
|
|
85
86
|
psych (5.2.6)
|
|
86
87
|
date
|
|
87
88
|
stringio
|
|
@@ -91,9 +92,10 @@ GEM
|
|
|
91
92
|
ffi (~> 1)
|
|
92
93
|
rbs (3.9.5)
|
|
93
94
|
logger
|
|
94
|
-
rdoc (6.
|
|
95
|
+
rdoc (6.15.1)
|
|
95
96
|
erb
|
|
96
97
|
psych (>= 4.0.0)
|
|
98
|
+
tsort
|
|
97
99
|
redcarpet (3.6.1)
|
|
98
100
|
redis (5.4.1)
|
|
99
101
|
redis-client (>= 0.22.0)
|
|
@@ -109,19 +111,19 @@ GEM
|
|
|
109
111
|
reline (0.6.2)
|
|
110
112
|
io-console (~> 0.5)
|
|
111
113
|
rexml (3.4.1)
|
|
112
|
-
rspec (3.13.
|
|
114
|
+
rspec (3.13.2)
|
|
113
115
|
rspec-core (~> 3.13.0)
|
|
114
116
|
rspec-expectations (~> 3.13.0)
|
|
115
117
|
rspec-mocks (~> 3.13.0)
|
|
116
|
-
rspec-core (3.13.
|
|
118
|
+
rspec-core (3.13.6)
|
|
117
119
|
rspec-support (~> 3.13.0)
|
|
118
120
|
rspec-expectations (3.13.5)
|
|
119
121
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
120
122
|
rspec-support (~> 3.13.0)
|
|
121
|
-
rspec-mocks (3.13.
|
|
123
|
+
rspec-mocks (3.13.7)
|
|
122
124
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
123
125
|
rspec-support (~> 3.13.0)
|
|
124
|
-
rspec-support (3.13.
|
|
126
|
+
rspec-support (3.13.6)
|
|
125
127
|
rubocop (1.81.1)
|
|
126
128
|
json (~> 2.3)
|
|
127
129
|
language_server-protocol (~> 3.17.0.2)
|
|
@@ -154,15 +156,16 @@ GEM
|
|
|
154
156
|
stackprof (0.2.27)
|
|
155
157
|
stringio (3.1.7)
|
|
156
158
|
timecop (0.9.10)
|
|
157
|
-
tryouts (3.
|
|
158
|
-
concurrent-ruby (~> 1.0)
|
|
159
|
+
tryouts (3.7.1)
|
|
160
|
+
concurrent-ruby (~> 1.0, < 2)
|
|
159
161
|
irb
|
|
160
162
|
minitest (~> 5.0)
|
|
161
163
|
pastel (~> 0.8)
|
|
162
164
|
prism (~> 1.0)
|
|
163
|
-
rspec (
|
|
165
|
+
rspec (>= 3.0, < 5.0)
|
|
164
166
|
tty-cursor (~> 0.7)
|
|
165
167
|
tty-screen (~> 0.8)
|
|
168
|
+
tsort (0.2.0)
|
|
166
169
|
tty-color (0.6.0)
|
|
167
170
|
tty-cursor (0.7.1)
|
|
168
171
|
tty-screen (0.8.2)
|
|
@@ -192,8 +195,8 @@ DEPENDENCIES
|
|
|
192
195
|
ruby-prof
|
|
193
196
|
stackprof
|
|
194
197
|
timecop
|
|
195
|
-
tryouts (~> 3.
|
|
198
|
+
tryouts (~> 3.7.1)
|
|
196
199
|
yard (~> 0.9)
|
|
197
200
|
|
|
198
201
|
BUNDLED WITH
|
|
199
|
-
2.
|
|
202
|
+
2.7.2
|
data/bin/try
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
#
|
|
5
|
+
# This file was generated by Bundler.
|
|
6
|
+
#
|
|
7
|
+
# The application 'try' is installed as part of a gem, and
|
|
8
|
+
# this file is here to facilitate running it.
|
|
9
|
+
#
|
|
10
|
+
|
|
11
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
|
|
12
|
+
|
|
13
|
+
require "rubygems"
|
|
14
|
+
require "bundler/setup"
|
|
15
|
+
|
|
16
|
+
load Gem.bin_path("tryouts", "try")
|