# Changelog

## Score

- CAI 65 → 70 (+5.5)
- Rubric changed (rubric-2026.09.8 → rubric-2026.09.17) — scores are not directly comparable.

## Lenses

- Code Health 83 → 83 (+0.0)
- Architecture 99 → 84 (-14.6)
- Maturity 70 → 70 (+0.0)
- Readiness 73 → 79 (+6.6)
- Security 51 → 62 (+10.9)
- Performance 100 (new)

## Resolved (2)

- Duplicated block (4–16 lines × 3) (crates/shadowsocks/src/relay/tcprelay/aead.rs)
- Near-duplicate member pair (40 shared lines) (crates/shadowsocks/src/relay/tcprelay/aead.rs)

## New (11)

- Ambiguous constructor variants. `new` takes a generic key `K`, while `with_encoded_key` takes a `str`. It is unclear if `new` expects raw bytes or encoded strings, leading to potential misuse. The existence of `with_encoded_key` suggests `new` might not handle string encoding, but the naming doesn't make this distinction clear.
- Confusingly similar method names with different signatures. `send_to` and `send_to_manager` both send data, but take different target types (`ManagerSocketAddr` vs `ManagerAddr`) and one takes a `Context`. This suggests `send_to_manager` is a higher-level wrapper, but the naming is not distinct enough to prevent confusion.
- Duplicate intent with divergent naming and scope. `ServerType` and `ConfigType` appear to represent the same conceptual enum (Local/Server/Manager/etc.), but are split across two modules with different method signatures. `ServerType` only has `is_local`/`is_server`, while `ConfigType` has `is_manager`/`is_online_config` as well. This forces users to import two different types for similar checks.
- Duplicated block (19 lines × 2) (crates/shadowsocks/src/relay/tcprelay/aead.rs)
- Duplicated block (8 lines × 3) (crates/shadowsocks/src/relay/tcprelay/aead.rs)
- Inconsistent naming for cloning/copying operations. `clone_identity_hash` and `clone_identity_keys` use the verb `clone` for returning owned data, whereas Rust idioms typically use `to_owned()` or just rely on the type system. More importantly, `ServerUser` has `clone_identity_hash` but `ServerConfig` has `clone_identity_keys`. The naming is inconsistent between the two types (`hash` vs `keys`).
- Off the main sequence: shadowsocks
- Redundant accessors for the same underlying data. `key()` and `password()` likely return the same secret material (one as bytes, one as string). `export_password()` is a third variant. This creates confusion about which method to use for serialization vs internal use.
- Redundant methods with unclear distinction. `get_user_by_hash` and `clone_user_by_hash` both return `ServerUser`. In Rust, `get` usually implies borrowing or returning a reference, but here both return owned `ServerUser`. The distinction between 'get' and 'clone' is semantically weak if the return type is identical.
- Split crates/shadowsocks
- Split crates/shadowsocks-service

## Changes since last survey

- 13 commits — 8 feature/other, 5 fixes

## By area

- (root) — 9 commits
- crates/shadowsocks — 2 commits
- crates/shadowsocks-service — 1 commit
- debian/shadowsocks-rust-local@.service — 1 commit

## Notable commits

- fix: fix(local-tun): enable smoltcp "auto-icmp-echo-reply" feature to reply ICMP Echo Request
- fix: fix(relay): pick non-zero AEAD-2022 padding size for empty first payload
- fix: fix(tcprelay): report actual plaintext length when retrying after Pending
- fix: fix: RUSTSEC-2026-0285
- fix: fix: updated chacha20 to v0.10.2, v0.10.1 yanked
- change: chore(deps): update rust crate bloomfilter to v3.0.2
- change: chore(deps): update rust crate cfg-if to v1.0.5
- change: chore(deps): update rust crate clap to v4.6.7
- change: chore(deps): update rust crate rand to v0.10.3
- change: chore(deps): update rust crate sendfd to v0.4.5
- change: chore(deps): update rust crate thiserror to v2.0.21
- change: chore(deps): update rust crate tokio-rustls to v0.26.6
- change: systemd unit improvements (#2187)
