# Changelog

## Score

- CAI 73 → 73 (+0.9)
- Rubric changed (rubric-2026.09.8 → rubric-2026.09.16) — scores are not directly comparable.

## Lenses

- Code Health 90 → 91 (+0.8)
- Architecture 92 → 92 (-0.2)
- Maturity 71 → 71 (+0.0)
- Readiness 68 → 66 (-1.7)
- Security 69 → 79 (+10.2)
- Event Sourcing 100 → 100 (+0.0)
- Performance 100 (new)

## Resolved (88)

- AppView::render (cognitive 20) (crates/openlogi-desktop/src/app.rs)
- Change coupling: add_device.rs ↔ appearance.rs (crates/openlogi-desktop/src/windows/add_device.rs)
- Change coupling: appearance.rs ↔ permissions.rs (crates/openlogi-desktop/src/windows/settings/appearance.rs)
- Change coupling: device.rs ↔ dpi.rs (crates/openlogi-desktop/src/features/lighting/device.rs)
- Change coupling: dpi.rs ↔ smartshift.rs (crates/openlogi-desktop/src/features/pointer/dpi.rs)
- Change coupling: hook.rs ↔ bindings.rs (crates/openlogi-agent-core/src/runtime/hook.rs)
- Change coupling: host_switch.rs ↔ lib.rs (crates/openlogi-device/src/session/host_switch.rs)
- Change coupling: lib.rs ↔ transport.rs (crates/openlogi-device/src/lib.rs)
- ClassTooLong: Config (crates/openlogi-core/src/config.rs)
- Config::migrate_owner_locked_gestures (cognitive 24) (crates/openlogi-core/src/config.rs)
- Config::migrate_thumbwheel_native_direction (cognitive 18) (crates/openlogi-core/src/config.rs)
- Dependency source pinned to a moving git ref
- Documentation: no installation or build instructions (README.md)
- Documentation: no installation or build instructions (docs/README.de.md)
- Documentation: no installation or build instructions (docs/README.fr.md)
- Documentation: no installation or build instructions (docs/README.ja.md)
- Documentation: no installation or build instructions (docs/README.ko.md)
- Documentation: no usage examples (docs/USAGE.md)
- Duplicated block (10 lines × 2) (crates/openlogi-agent-core/src/runtime/button.rs)
- Duplicated block (10 lines × 2) (crates/openlogi-desktop/src/features/action_ring.rs)
- …and 68 more

## New (63)

- ActionExecutor::dispatch_to (cognitive 23) (crates/openlogi-agent-core/src/runtime.rs)
- ActionExecutor::dispatch_to (cyclomatic 16) (crates/openlogi-agent-core/src/runtime.rs)
- Ambiguous duplication: Two methods with nearly identical names suggest different return types or behaviors (e.g., parsed vs raw bytes), but the signatures are identical (`Result`). Without documentation, it is unclear if one is deprecated, if they return different types, or if one is a mistake.
- Ambiguous duplication: `latest_frame` and `take_frame` likely differ in semantics (e.g., non-blocking peek vs. blocking/consuming), but the identical signatures and similar naming create confusion about which to use for non-blocking reads.
- AppView::render_content (cognitive 20) (crates/openlogi-desktop/src/app.rs)
- CaptureAccum::on_event (cognitive 35) (crates/openlogi-device/src/session/gesture/accum.rs)
- CaptureAccum::on_event (cyclomatic 21) (crates/openlogi-device/src/session/gesture/accum.rs)
- Change coupling: binding_editor.rs ↔ view.rs (crates/openlogi-desktop/src/features/binding_editor.rs)
- Change coupling: function_row.rs ↔ view.rs (crates/openlogi-desktop/src/features/keyboard/function_row.rs)
- Change coupling: route.rs ↔ pairing.rs (crates/openlogi-device/src/channel/route.rs)
- Change coupling: tests.rs ↔ keyboard.rs (crates/openlogi-device/src/session/gesture/tests.rs)
- Config::migrate_owner_locked_gestures (cognitive 24) (crates/openlogi-core/src/config/migrate.rs)
- Config::migrate_thumbwheel_native_direction (cognitive 18) (crates/openlogi-core/src/config/migrate.rs)
- Dependency hygiene PARTLY measured — Cargo dependencies read, dependency currency not (crates.io unreachable)
- Duplicate intent across types: Both `Config` and `ConfigFile` expose `load_or_default`. It is unclear if `ConfigFile` is a lower-level utility and `Config` is the high-level facade, or if they are redundant entry points for the same operation.
- Duplicate intent across types: Same as above, `load_from_path` exists on both `Config` and `ConfigFile` with identical signatures.
- Duplicated block (10 lines × 2) (crates/openlogi-agent-core/src/runtime/button/worker.rs)
- Duplicated block (10 lines × 2) (crates/openlogi-device/src/inventory/probe/bolt.rs)
- Duplicated block (10 lines × 2) (crates/openlogi-hid/src/transport.rs)
- Duplicated block (11–12 lines × 2) (crates/openlogi-inject/src/inject/macos.rs)
- …and 43 more

## Changes since last survey

- 269 commits — 214 feature/other, 55 fixes

## By area

- crates/openlogi-desktop — 81 commits
- crates/openlogi-device — 47 commits
- crates/openlogi-agent-core — 26 commits
- crates/openlogi-core — 13 commits
- .ast-grep/rules — 12 commits
- (root) — 11 commits
- crates/openlogi-hidpp — 11 commits
- crates/openlogi-cli — 10 commits
- crates/openlogi-hook — 10 commits
- xtask/src — 10 commits
- crates/openlogi-agent — 9 commits
- crates/openlogi-ui — 7 commits
- .agents/rules — 4 commits
- crates/openlogi-ipc — 4 commits
- crates/openlogi-overlay — 4 commits
- .agents/skills — 3 commits
- crates/openlogi-inject — 3 commits
- crates/openlogi-camera — 1 commit
- crates/openlogi-device-registry — 1 commit
- crates/openlogi-fixture — 1 commit

## Notable commits

- fix: fix(agent): divert a single-bound gesture button (#1569)
- fix: fix(agent): honor per-app overrides for hidpp gestures
- fix: fix(agent): log a DPI or SmartShift write only once one is scheduled
- fix: fix(agent): say why a background write was skipped
- fix: fix(agent): start the HID++ watchers through one named worker shell
- fix: fix(camera): refuse a camera another application is streaming
- fix: fix(camera): require a stored frame before reporting startup
- fix: fix(cli): select rgb devices through receiver routes
- fix: fix(cli): stop naming the agent lock file outside its owner
- fix: fix(cli): stop telling users Unifying receivers are not surfaced
- fix: fix(cli): tell a timed-out profile capture what to do next
- fix: fix(core): preserve existing middle click gestures
- fix: fix(deps): update rustls to address RUSTSEC-2026-0285
- fix: fix(gui): clamp camera control values through the ordered range
- fix: fix(gui): correct thumb-wheel volume preset labels (#1436)
- fix: fix(gui): declare the alignment bespoke buttons relied on
- fix: fix(gui): hold a config reload until the agent connects
- fix: fix(gui): keep a snapped sync off a slider mid-drag
- fix: fix(gui): keep the relaunch notice ahead of the unreachable one
- fix: fix(gui): keep update consent buttons visible
- …and 249 more
