# Changelog

## Score

- CAI 61 → 68 (+7.4)
- Rubric changed (rubric-2026.09.9 → rubric-2026.09.17) — scores are not directly comparable.

## Lenses

- Code Health 82 → 82 (+0.1)
- Architecture 99 → 92 (-6.6)
- Maturity 50 → 65 (+15.1)
- Readiness 62 → 64 (+1.5)
- Security 65 → 69 (+4.3)
- Event Sourcing 100 → 100 (+0.0)
- Performance 100 (new)

## Resolved (29)

- Boundary-crossing change coupling: assistant.rs ↔ sugarloaf.rs (frontends/rioterm/src/router/routes/assistant.rs)
- Change coupling: atlas.rs ↔ sugarloaf.rs (sugarloaf/src/renderer/image_cache/atlas.rs)
- Duplicated block (12–14 lines × 3) (frontends/rioterm/src/context/title.rs)
- Duplicated block (12–15 lines × 2) (frontends/rioterm/src/application.rs)
- Duplicated block (15–18 lines × 2) (frontends/rioterm/src/context/title.rs)
- Duplicated block (26 lines × 2) (frontends/rioterm/src/context/mod.rs)
- Hotspot: corcovado/src/poll.rs (corcovado/src/poll.rs)
- Hotspot: frontends/rioterm/src/context/title.rs (frontends/rioterm/src/context/title.rs)
- Hotspot: frontends/rioterm/src/global_hotkey.rs (frontends/rioterm/src/global_hotkey.rs)
- Hotspot: frontends/rioterm/src/hints.rs (frontends/rioterm/src/hints.rs)
- Hotspot: frontends/rioterm/src/layout/mod.rs (frontends/rioterm/src/layout/mod.rs)
- Hotspot: frontends/rioterm/src/renderer/trail_cursor.rs (frontends/rioterm/src/renderer/trail_cursor.rs)
- Hotspot: librio-wasm/src/lib.rs (librio-wasm/src/lib.rs)
- Hotspot: rio-graphics/src/lib.rs (rio-graphics/src/lib.rs)
- Hotspot: rio-unicode/src/grapheme.rs (rio-unicode/src/grapheme.rs)
- Hotspot: rio-vt/src/ansi/glyph_protocol.rs (rio-vt/src/ansi/glyph_protocol.rs)
- Hotspot: rio-vt/src/config/colors/mod.rs (rio-vt/src/config/colors/mod.rs)
- Hotspot: rio-vt/src/crosswords/pos.rs (rio-vt/src/crosswords/pos.rs)
- Hotspot: rio-vt/src/crosswords/vi_mode.rs (rio-vt/src/crosswords/vi_mode.rs)
- Hotspot: rio-vt/src/performer/parser/mod.rs (rio-vt/src/performer/parser/mod.rs)
- …and 9 more

## New (39)

- Ambiguous naming for interruptible behavior. While `poll_interruptible` is descriptive, the existence of two `poll` variants with different blocking behaviors (one potentially blocking indefinitely or on signal, one explicitly interruptible) can be confusing. However, this is a common pattern in async I/O.
- Duplicate accessors for the same property. `readiness()` and `kind()` both return the `Ready` state of an event.
- Duplicate deregistration logic. Both types expose `deregister` with identical intent but different parameter structures (one takes the poll, one takes the handle), causing confusion about ownership and lifecycle management.
- Duplicate method signatures with different return types or overloads? The list shows two entries for `to_rio_window_colorspace` with identical signatures but potentially different contexts or return types (one returns `Colorspace`, the other is ambiguous). If they are truly identical, it's a duplicate.
- Duplicate registration logic across types. `Evented` is a trait/interface that requires implementing `register`, while `Poll` is the concrete implementation that also exposes `register`. This creates a confusing API surface where users might call `poll.register()` directly or `evented.register(poll, ...)` depending on context, with identical signatures.
- Duplicate registration update logic. Similar to `register`, both `Evented` and `Poll` expose `reregister` with identical signatures, leading to ambiguity about which method performs the actual I/O or state update.
- Duplicated block (12–14 lines × 3) (frontends/rioterm/src/context/title.rs)
- Duplicated block (13–16 lines × 2) (frontends/rioterm/src/application.rs)
- Duplicated block (27 lines × 2) (frontends/rioterm/src/context/mod.rs)
- Duplicated block (6 lines × 2) (frontends/rioterm/src/application.rs)
- End-of-life runtime: Rust 1.96
- Inconsistent constructor naming. `new2` is a non-descriptive name compared to `new`, suggesting a legacy or overloaded constructor without clear semantic distinction in the name.
- Inconsistent error handling patterns. `load()` likely panics or returns a default on error, while `try_load()` returns a `Result`. This is a common pattern but can be confusing if the behavior of `load()` is not explicitly documented as infallible or panic-on-error.
- Low cohesion: Graphics (LCOM4 4) (rio-vt/src/ansi/graphics.rs)
- Low cohesion: Poll (LCOM4 4) (corcovado/src/poll.rs)
- Machine::pty_read (cyclomatic 19) (rio-vt/src/performer/mod.rs)
- Machine::run (cognitive 50) (rio-vt/src/performer/mod.rs)
- Machine::run (cyclomatic 23) (rio-vt/src/performer/mod.rs)
- Members sharing a duplicated core (4 members, 50+ identical tokens) (frontends/rioterm/src/layout/mod.rs)
- Members sharing a duplicated core (6 members, 50+ identical tokens) (frontends/rioterm/src/renderer/assistant.rs)
- …and 19 more

## Changes since last survey

- 5 commits — 3 feature/other, 2 fixes

## By area

- frontends/rioterm — 4 commits
- (root) — 1 commit

## Notable commits

- fix: fix: harden PTY quit delivery and lifecycle locking (#1942)
- fix: fix: preserve Unix PTY lifecycle and final output (#1930)
- change: Automatic shell integration for zsh, fish and PowerShell (#1923)
- change: Surface terminal bells on tabs, with a font-free indicator (#1922)
- change: prepare v0.5.28
