# Changelog

## Score

- CAI 67 → 63 (-3.6)
- Rubric changed (rubric-2026.10.1 → rubric-2026.10.5) — scores are not directly comparable.

## Lenses

- Code Health 98 → 75 (-23.4)
- Architecture 86 → 86 (+0.0)
- Maturity 51 → 48 (-2.6)
- Readiness 75 → 75 (+0.0)
- Security 85 → 82 (-2.7)

## Resolved (4)

- Inconsistent command initialization pattern. While all commands use `initialize(argv)`, some commands (like `ConfigDump`) have additional methods like `validate!()` with a bang, while `Show` has `validate()` without a bang. This inconsistency in validation method naming (`validate!` vs `validate`) across command types suggests a lack of standardized lifecycle for command execution.
- Inconsistent equality comparison semantics. `Project` defines both `==` and `eql?`, which in Ruby typically implies different equality contracts (value vs identity/hash-key), but `AbstractObject` (the base for most project elements) only defines `==` and `<=>` (comparison), lacking `eql?`. This creates an inconsistent API surface where some objects support `eql?` and others do not, confusing users expecting uniform behavior across the object graph.
- Redundant method names with unclear distinction. `merge!` and `merge` are present on `Config`. In Ruby, `!` usually denotes mutation, while the non-`!` version returns a new instance. However, without seeing the return types, it is ambiguous if `merge` returns a new `Config` or the same one. If `merge` returns a new instance, it is consistent with Ruby conventions, but having both on a configuration object that is often mutated in-place can be confusing. More critically, `ConfigDump` has `extract_common_settings!` which mutates, while `Project` has `mark_dirty!` which is a side-effect marker. The inconsistency lies in the usage of `!` for mutation vs side-effects across the library.
- Workflow token permissions not restricted

## New (42)

- Ambiguous distinction between `merge!` and `merge`. In Ruby, `merge!` typically mutates the receiver while `merge` returns a new object. However, both signatures accept a single argument and the return type isn't explicitly clear from the signature alone. If `merge` returns a new Config object, it's consistent with Ruby Hash behavior. If `merge` also mutates, it's a violation of convention. Assuming standard Ruby semantics, this is likely consistent, but the presence of both suggests potential confusion if `merge` doesn't return a new instance.
- Documentation: no usage examples (README.md)
- Inconsistent equality comparison methods. `Project` defines `==` and `eql?`, while `AbstractObject` defines `==` and `<=>` (spaceship operator). `eql?` is typically used for hash key equality, while `<=>` is for sorting. `Project` lacks `<=>`, and `AbstractObject` lacks `eql?`. This inconsistency makes it unclear how to compare these objects for sorting vs. hash lookup.
- Orphaned file (lib/xcodeproj/command/config_dump.rb)
- Orphaned file (lib/xcodeproj/config.rb)
- Orphaned file (lib/xcodeproj/differ.rb)
- Orphaned file (lib/xcodeproj/plist.rb)
- Orphaned file (lib/xcodeproj/project/case_converter.rb)
- Orphaned file (lib/xcodeproj/project/object.rb)
- Orphaned file (lib/xcodeproj/project/object/build_configuration.rb)
- Orphaned file (lib/xcodeproj/project/object/build_file.rb)
- Orphaned file (lib/xcodeproj/project/object/build_phase.rb)
- Orphaned file (lib/xcodeproj/project/object/build_rule.rb)
- Orphaned file (lib/xcodeproj/project/object/configuration_list.rb)
- Orphaned file (lib/xcodeproj/project/object/container_item_proxy.rb)
- Orphaned file (lib/xcodeproj/project/object/file_reference.rb)
- Orphaned file (lib/xcodeproj/project/object/group.rb)
- Orphaned file (lib/xcodeproj/project/object/helpers/file_references_factory.rb)
- Orphaned file (lib/xcodeproj/project/object/helpers/groupable_helper.rb)
- Orphaned file (lib/xcodeproj/project/object/root_object.rb)
- …and 22 more

## Architecture

- 0 containers · 1 bounded contexts · 0 dependency edges (baseline)
