# Changelog

## Score

- CAI 66 → 65 (-0.9)
- Rubric changed (rubric-2026.10.1 → rubric-2026.10.5) — scores are not directly comparable.

## Lenses

- Code Health 100 → 100 (+0.0)
- Architecture 69 → 69 (+0.0)
- Maturity 54 → 52 (-1.9)
- Readiness 74 → 74 (+0.0)
- Security 97 → 97 (+0.0)
- Performance 85 → 85 (+0.0)

## Resolved (5)

- Naming inconsistency in statistical methods. `ips()` returns the iterations per second. `ips_sd()` returns the standard deviation of the IPS. However, `Entry.seconds()` returns total time. `Entry.microseconds` is a property. The method `ips_sd()` is inconsistent with the naming of other statistical methods like `Entry.error_percentage()`. It mixes the metric name (`ips`) with the statistical measure (`sd`). A more consistent naming would be `Entry.ips_standard_deviation()` or `Entry.ips_stddev()`.
- Off-boarding risk: anonymized user #1
- Redundant boolean check vs mutation method. The `compare?` method likely checks if comparison is enabled, while `compare!` enables it. However, the naming convention `?` usually implies a pure predicate, while `!` implies mutation. If `compare?` simply returns the state of a flag that `compare!` sets, this is consistent. However, looking at `hold?` and `hold!`, there is a pattern. The potential inconsistency is subtle: if `compare?` does more than just return the flag (e.g., triggers a lazy evaluation or has side effects), it conflicts with the standard Ruby predicate convention. More critically, `Job.compare?` and `Job.compare!` take an argument in the signature provided (`order`), which is unusual for a predicate `?` method. Predicates typically take no arguments. This suggests `compare?` might be misnamed or overloaded.
- Same naming convention issue as above. `hold?` is a predicate (should take no args) but `hold!` is a mutator. If `hold?` is intended to check if holding is enabled, it should take no arguments. The signature `Job.hold?()` implies no arguments, which is consistent. However, `Job.compare?()` also implies no arguments. The inconsistency lies in the fact that `compare!` takes an `order` argument, while `compare?` does not. This is actually consistent (getter vs setter with args). The real issue is `Job.hold?` vs `Job.hold!`. `hold!` takes a path. `hold?` takes no args. This is consistent. Wait, looking closer at `Job.compare?()` and `Job.compare!(order)`. If `compare?` is a predicate, it shouldn't take args. It doesn't. So this is consistent. Let's look for actual duplicates. `Job.save!(held_path)` and `Job.hold!(held_path)` seem to do similar things (persisting state). `hold!` likely saves to a file for later comparison. `save!` also saves to a file. The difference might be `hold` is for 'holding' results for future runs, while `save` is generic. But `Job.save_held_results` and `Job.load_held_results` exist. `hold!` seems to be a convenience for saving held results. `save!` might be for saving the job config or results? The docs for benchmark-ips show `hold!` saves the current results to a file. `save!` is not a standard method in benchmark-ips core, but here it is listed. If `hold!` and `save!` both save results, they are redundant.
- Workflow token permissions not restricted

## New (3)

- Off-boarding risk: anonymized user #1
- Orphaned file (lib/benchmark/ips/job/entry.rb)
- Workflow token permissions not restricted (.github/workflows/ci.yml)
