Improve keyboard comfort and usability with advanced customization
This report summarizes scanner evidence for jtroo/kanata, a Rust project with 8,056 GitHub stars. SynthScan examined 71,499 lines of code across 218 source files, recording 133 pattern matches distributed across 4 syntactic categories. The legacy adjusted pattern signal is 1.9 (Low pattern signal); it is not an authorship estimate.
Use the findings to ask whether maintainers can explain intent, verify dependencies, simplify unnecessary scaffolding, and focus review effort. Risk Payload v1 adds ownership, supply-chain, over-engineering, and review-effort vectors when available. These are prompts for human verification, not probabilities, security findings, or measured maintenance costs.
Use each vector to guide manual verification of the underlying findings.
Payload schema: 1.0.0 · Engine: 2.0.0 · Scoring: heuristic-density-v1 · Scan date: 2026-10-31.
Can maintainers explain intent, assumptions, and trade-offs? 124 finding(s).
Are imports declared and package/API names verified? 9 finding(s).
Are wrappers, guards, and repeated structures necessary? 0 finding(s).
Which changes need focused human review? 133 finding(s).
This chart tracks the legacy adjusted pattern score across scan runs. Changes can reflect source changes, scan coverage, or detector/scoring versions; they do not measure AI adoption or prove that a team refactored code. Compare runs only when their scoring versions are compatible. The dashed line tracks the raw pattern-hit count.
Groups findings by configured severity weight. Severity is not a confidence estimate, security rating, or proof that a package is missing. Verify imports against the project's manifests and inspect each finding in its local design context.
This horizontal bar chart shows where configured pattern scores accumulate across directories. Treat the bars as locations to inspect, not as evidence of authorship or code quality. Use the file-level findings to decide whether a directory needs a focused ownership, dependency, complexity, or review check.
The scanner identified 133 distinct pattern matches across 4 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a detector match to inspect in context. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.
Reading the findings table: The Severity column indicates the configured finding weight (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — legacy comment-context matches receive a ×1.5 score weight. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier under the legacy scoring model.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | windows_key_tester/src/windows/interception.rs | 141 | ScanCode::F20 => OsCode::KEY_F20, | COMMENT |
| LOW | keyberon/src/action.rs | 61 | /// not used in the flow of typing, like escape for example. If | COMMENT |
| LOW | keyberon/src/action.rs | 81 | /// | COMMENT |
| LOW | keyberon/src/action.rs | 141 | /// If the key is held more than `timeout` ticks (usually | COMMENT |
| LOW | keyberon/src/action.rs | 161 | pub hold: Action<'a, T>, | COMMENT |
| LOW | keyberon/src/action.rs | 181 | /// | COMMENT |
| LOW | keyberon/src/action.rs | 201 | /// Action to activate until timeout expires or exactly one non-one-shot key is activated. | COMMENT |
| LOW | keyberon/src/action.rs | 361 | /// Action to release either a keycode state or a layer state. | COMMENT |
| LOW | keyberon/src/action.rs | 381 | /// key will hold space until either another key is pressed or the timeout occurs, which will | COMMENT |
| LOW | keyberon/src/action.rs | 401 | Chords(&'a ChordsGroup<'a, T>), | COMMENT |
| LOW | keyberon/src/layout.rs | 1 | //! Layout management. | COMMENT |
| LOW | keyberon/src/layout.rs | 61 | COMMENT | |
| LOW | keyberon/src/layout.rs | 121 | pub historical_keys: History<KeyCode>, | COMMENT |
| LOW | keyberon/src/layout.rs | 921 | // | COMMENT |
| LOW | keyberon/src/layout.rs | 1021 | /// of items in array-based stack implementations. | COMMENT |
| LOW | keyberon/src/layout.rs | 1041 | /// Used to keep track of already-pressed keys for the release variants. | COMMENT |
| LOW | keyberon/src/layout.rs | 1961 | // is immediately re-added again. This means the release is never observed.. | COMMENT |
| LOW | keyberon/src/layout.rs | 2021 | // of `do_action`. | COMMENT |
| LOW | keyberon/src/chord.rs | 121 | // Like a layout, this should be destroyed and recreated on a live reload. | COMMENT |
| LOW | keyberon/src/tap_hold_tracker.rs | 1 | //! Tracks tap-hold activation events for external consumers (e.g. TCP broadcast). | COMMENT |
| LOW | keyberon/src/action/switch.rs | 1 | //! Handle processing of the switch action for Keyberon. | COMMENT |
| LOW | docs/config-stylesheet.css | 121 | b.button::after{content:"]";padding:0 2px 0 3px} | COMMENT |
| LOW | docs/config-stylesheet.css | 141 | #toc{border-bottom:1px solid #e7e7e9;padding-bottom:.5em} | COMMENT |
| LOW | docs/config-stylesheet.css | 161 | #toc.toc2{width:20em} | COMMENT |
| LOW | parser/src/subset.rs | 1 | //! Collection where keys are slices of a type, and supports a get operation to check if the key | COMMENT |
| LOW | parser/src/subset.rs | 21 | // larger than 1, the point at which an `Arc` would be better would need to be measured. | COMMENT |
| LOW | parser/src/gamepad/analog.rs | 1 | //! Analog values and the transformations that turn them into digital edges | COMMENT |
| LOW | parser/src/gamepad/analog.rs | 281 | /// Overshoot past the rim clamps, which is also what stops a stick at a | COMMENT |
| LOW | parser/src/gamepad/mod.rs | 1 | //! Game controller support: the control vocabulary and the configuration tree | COMMENT |
| LOW | parser/src/gamepad/mod.rs | 341 | /// whatever glyph the vendor printed on it, so one configuration works across | COMMENT |
| LOW | parser/src/gamepad/mod.rs | 601 | /// A diagonal presses two cardinal controls, the way holding two keys | COMMENT |
| LOW | parser/src/gamepad/mod.rs | 621 | #[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] | COMMENT |
| LOW | parser/src/gamepad/mod.rs | 641 | pub struct Digital { | COMMENT |
| LOW | parser/src/gamepad/project.rs | 1 | //! Projection: controller readings in, the set of held controls out. | COMMENT |
| LOW | parser/src/gamepad/project.rs | 181 | config: GamepadConfig, | COMMENT |
| LOW | parser/src/cfg/deftemplate.rs | 1 | //! This file is responsible for template expansion. | COMMENT |
| LOW | parser/src/cfg/sequence.rs | 181 | COMMENT | |
| LOW | parser/src/cfg/mod.rs | 1 | //! This parses the configuration language to create a `kanata_keyberon::layout::Layout` as well as | COMMENT |
| LOW | parser/src/cfg/mod.rs | 21 | //! | COMMENT |
| LOW | parser/src/cfg/mod.rs | 301 | /// walking the layout, so it does not depend on where the action ends up. macOS uses this to | COMMENT |
| LOW | parser/src/cfg/alloc.rs | 1 | //! This module contains a helper struct for generating 'static lifetime allocations while still | COMMENT |
| LOW | parser/src/cfg/defgamepad.rs | 1 | //! Parsing for the `defgamepad` declaration, which says what physical | COMMENT |
| LOW | parser/src/cfg/deflocalkeys.rs | 61 | // Trying to convert a number to OsCode is OS-dependent and is fallible. | COMMENT |
| LOW | parser/src/cfg/zippychord.rs | 1 | //! Zipchord-like parsing. Probably not 100% compatible. | COMMENT |
| LOW | parser/src/cfg/zippychord.rs | 21 | //! "r df => recipient" | COMMENT |
| LOW | parser/src/cfg/zippychord.rs | 141 | /// | COMMENT |
| LOW | parser/src/cfg/zippychord.rs | 221 | #[derive(Debug)] | COMMENT |
| LOW | parser/src/keys/macos.rs | 701 | code: 0x29F, | COMMENT |
| LOW | parser/src/keys/mod.rs | 1261 | KEY_762 = 762, | COMMENT |
| LOW | parser/src/keys/mod.rs | 1361 | ) | COMMENT |
| LOW | simulated_passthru/src/log_win.rs | 1 | //! A logger that prints to OutputDebugString (Windows only) | COMMENT |
| LOW | key-sort-add/src/main.rs | 1 | //! one: | COMMENT |
| LOW | src/main_lib/args.rs | 1 | use clap::Parser; | COMMENT |
| LOW | src/main_lib/args.rs | 81 | COMMENT | |
| LOW | src/main_lib/args.rs | 101 | /// option to false. Useful if you are experimenting with a new | COMMENT |
| LOW | src/main_lib/args.rs | 121 | /// users get an unmodified keyboard. Off by default to preserve the | COMMENT |
| LOW | src/oskbd/macos.rs | 41 | COMMENT | |
| LOW | src/oskbd/macos.rs | 61 | /// Per-button cursor position captured at button press in `button_action`. | COMMENT |
| LOW | src/oskbd/macos.rs | 101 | /// later live reload without needing the original `event_loop` context. | COMMENT |
| LOW | src/oskbd/macos.rs | 121 | /// event. The Arc points to the same `parking_lot::Mutex` that the live-reload | COMMENT |
| 62 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | keyberon/src/layout.rs | 2407 | for fake_key in self.states.clone().iter() { | CODE |
| LOW | keyberon/src/layout.rs | 2408 | if let FakeKey { keycode } = *fake_key { | CODE |
| LOW⚡ | parser/src/cfg/mod.rs | 77 | mod fake_key; | CODE |
| LOW⚡ | parser/src/cfg/mod.rs | 78 | use fake_key::*; | CODE |
| LOW⚡ | parser/src/cfg/mod.rs | 80 | pub use fake_key::{FAKE_KEY_ROW, NORMAL_KEY_ROW}; | CODE |
| LOW | src/tcp_server.rs | 349 | "tcp server fake-key action: {name},{action:?}" | CODE |
| LOW | src/tcp_server.rs | 415 | "fake-key-names".to_string(), | CODE |
| LOW | src/tcp_server.rs | 421 | "fake-key".to_string(), | CODE |
| LOW | src/main_lib/args.rs | 218 | Args::try_parse_from(["kanata", "msg", "-p", "9999", "act-on-fake-key", "fk"]).unwrap(); | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | parser/src/keys/mod.rs | 487 | /// I've added the Copy trait and I'll be able | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | scripts/test_linux_list_devices.sh | 94 | # Check if it's a permission issue | COMMENT |