Cha
1.13.0 - 2026-04-30
v1.13.0
Apr 30 2026 at 09:05 UTC
Added
primitive_representationdetector (roadmap S8.2). Flags function parameters whose name carries a domain concept (user_id,email,status_code,api_url,password,language, …) but whose type is a raw scalar primitive (String,i32,bool,char, …). Signals an opportunity to introduce a newtype / value object to preserve the invariant. Per-parameter detection groups all offending params of one function into a single hint. Complements the existingprimitive_obsession(which looks at per-function ratio): this fires on even a single param when it's clearly a business concept.- Business-token and noise-token vocabularies are deliberately narrow to keep signal-to-noise high. Substring matches are ruled out (tokens must be standalone words —
widget_identifierdoes not trigger onid). - Parameters already typed with project-local newtypes (e.g.
id: UserIdwhereUserIdisTypeOrigin::Local) are skipped — the author already did the right thing. - Container types (
Path,PathBuf,Vec,Arc,Box,HashMap, …) are treated as domain-carrying and excluded; wrappingpath: &Pathin a newtype would destroy the abstraction. - Only runs on
is_exportedfunctions — private helpers are noise for a design signal aimed at public API hygiene. - Cha self-analyze: 14 findings (all genuine —
rel_path/env_hash/language/key/hashas raw types). lvglsrc/baseline: 53 findings (TTFplatformID/encodingID/languageID/nameID: int, file-explorerpath/dir: charpointers, …).
- Business-token and noise-token vocabularies are deliberately narrow to keep signal-to-noise high. Substring matches are ruled out (tokens must be standalone words —
stringly_typed_dispatchdetector (roadmap S8.8). Flags functions whoseswitch/matchbody dispatches on ≥ 3 string or ≥ 3 integer literal arms — classic "the arm values should have been an enum" smell. Char-literal arms (C tokenisers) skipped. Enum-variant / structural-pattern arms classify asOtherand never contribute to the threshold, somatch event { Event::Click => …, Event::Scroll => …, _ => … }stays quiet whilematch s { "click" => …, "scroll" => …, "submit" => … }fires. SeverityHint. Complements S8.2primitive_representation(signature side) with the body-side dispatch signal.- New
cha_core::ArmValueenum (Str / Int / Char / Other) +FunctionInfo.switch_arm_values+FunctionSymbol.switch_arm_values. Populated by every parser via a new sharedcha-parser/src/switch_arms.rshelper — language-specific arm-node kinds funnel through one classifier. - Cha self-baseline: 20 findings (all node-kind dispatchers in the 6 language parsers — valid detections, users can add
// cha:ignore stringly_typed_dispatchif the dispatch shape is forced by tree-sitter). lvglsrc/baseline: 23 findings (PNG/JPEG/QR error-code dispatchers, color-format size tables, TTF bytecode interpreter).
- New
cross_boundary_chaindetector (roadmap S8.U4). Flags functions wherechain_depth ≥ 3and the chain's root parameter is externally-typed (TypeOrigin::External(crate)) — the function is reaching into a third-party library's internal field layout, not just over-chaining local data. Companion to the existingmessage_chain(which fires on depth regardless of source):cross_boundary_chainis narrower but a stronger abstraction-leak signal. SeverityHint.- Workspace crates are auto-whitelisted (same mechanism
leaky_public_signatureuses), so siblingcha_core::Findingtraversals inside this repo don't fire. Cha self-baseline: 4 findings, all genuinetree_sitter::Nodetraversals incha-parser. lvglsrc/baseline: 0 (C project, fewExternalorigins by design). - Zero parser changes — reuses
chain_depth,parameter_types(with origin),parameter_names,external_refs. Pure post-pass onProjectIndex.
- Workspace crates are auto-whitelisted (same mechanism
FunctionInfo.parameter_names+FunctionSymbol.parameter_names(cha-core). Parallel toparameter_types: identifier names in declaration order. All six parsers (Rust / TS / Python / Go / C / C++) extract these;self/ C++thispositions skipped to stay length-aligned withparameter_types. Enables name-semantic analyses likeprimitive_representation, future LSP hover with full signatures, futurecha summary.- New helpers
cha_parser::rust_imports::rust_param_namesandcha_parser::cpp::c_param_nameextract identifier names from their language's declarator chains; reused across all C/C++ function-definition sites.