# Changelog

## Score

- CAI 61 → 62 (+1.3)

## Lenses

- Code Health 89 → 89 (+0.0)
- Architecture 92 → 90 (-1.2)
- Maturity 50 → 53 (+2.6)
- Readiness 63 → 63 (+0.2)
- Security 68 → 68 (+0.3)

## Resolved (11)

- Duplicate functionality with inconsistent entry points. `PythonSpy.get_stack_traces()` is a high-level method on the spy object, while `stack_trace.get_stack_traces(...)` is a low-level free function that requires passing addresses and process handles directly. The low-level function duplicates the logic that `PythonSpy` likely encapsulates, exposing internal implementation details unnecessarily.
- Inconsistent output/dumping API surface. There are two distinct modules (`PythonCoreDump` and `dump`) handling trace output. `PythonCoreDump` has `print_traces` (plural, takes traces), while `dump` has `print_traces` (plural, takes pid/config) and `print_trace` (singular, takes a single trace). The naming `print_traces` is overloaded with different signatures and responsibilities (one processes a core dump file, the other seems to be a general utility).
- Inconsistent symbol/address resolution API. `PythonProcessInfo` exposes a high-level `get_symbol` method, but the underlying binary parsing is done via a free function `binary_parser.parse_binary` which takes raw addresses and sizes. It is unclear if `get_symbol` uses `parse_binary` internally or a different mechanism. If `parse_binary` is the general-purpose parser, it should likely be a method on `BinaryInfo` or a static method on a `BinaryParser` struct, not a free function in the module root, especially when `BinaryInfo` already exists to hold binary metadata.
- Low cohesion: _PyInterpreterFrame (LCOM4 6) (src/python_bindings/v3_11_0.rs)
- Medium advisory (unsound): RUSTSEC-2026-0190 (Cargo.lock)
- Members sharing a duplicated core (17 members, 50+ identical tokens) (src/python_bindings/v3_10_0.rs)
- Off-boarding risk: anonymized user #1
- Outdated: anyhow
- Outdated: goblin
- Outdated: remoteprocess
- Redundant containment check logic. `BinaryInfo` has a `contains` method, while a separate trait/type `ContainsAddr` exists with `contains_addr`. Given `BinaryInfo` likely implements `ContainsAddr` or serves the same purpose for address ranges, having both a method on the struct and a separate trait with a slightly different name (`contains` vs `contains_addr`) is inconsistent.

## New (5)

- Hotspot: ci/update_python_test_versions.py (ci/update_python_test_versions.py)
- Hotspot: src/stack_trace.rs (src/stack_trace.rs)
- Members sharing a duplicated core (17 members, 50+ identical tokens) (src/python_bindings/v3_10_0.rs)
- Off-boarding risk: anonymized user #1
- Orphaned file (src/chrometrace.rs)

## Changes since last survey

- 10 commits — 7 feature/other, 3 fixes

## By area

- .github/workflows — 4 commits
- (root) — 2 commits
- src/python_bindings — 1 commit
- src/python_data_access.rs — 1 commit
- src/python_interpreters.rs — 1 commit
- tests/scripts — 1 commit

## Notable commits

- fix: Fix getting thread names and copying PyLongObject on 32-bit arm (#888)
- fix: Fix line number at compact line table entry boundaries (#883)
- fix: Minor fixes for python 3.15 (#886)
- change: Add thread name lookup tests, lookup again after 1 second if not matched at first (#880)
- change: Classify 3.12+ frames by owner and mask stackref tag bits (#884)
- change: Drop unused pull-requests: write from build workflow (#893)
- change: Reduce GHA ci matrix size (#889)
- change: Update remoteprocess dependency to 0.5.5 (#895)
- change: Update tested python versions (#894)
- change: update remoteprocess/proc-maps dependencies (#887)
