Skip to content

fix: humanization injection — responsive, glitch-free, all-mouse-compatible#7

Merged
ramseymcgrath merged 17 commits into
mainfrom
fix/humanization-injection
Jun 2, 2026
Merged

fix: humanization injection — responsive, glitch-free, all-mouse-compatible#7
ramseymcgrath merged 17 commits into
mainfrom
fix/humanization-injection

Conversation

@ramseymcgrath

Copy link
Copy Markdown
Contributor

Summary

Fixes injected-movement degradation from the always-on humanization filter.

  • In-frame delivery — removed the 40%/frame velocity drain that smeared each command over ~10 ms. Injection now lands the same frame; noise + sub-pixel dither + 127 cap + timing jitter are kept for Tier-1 realism, with zero added latency.
  • One report per frame — injection rides real-mouse reports while the mouse is active; a standalone synth report is emitted only during mouse silence and at most once per ms. Stops the empty-report flood that was competing with / overwriting real-mouse reports at the 1 kHz endpoint (the "glitchy with simultaneous movement" symptom).
  • Field-clip carry (humanize_return) — injected motion the report's delta field can't carry is returned to the filter and redelivered as headroom opens. 8-bit-delta mice are now lossless, and split X/Y report-ID mice no longer drop an axis. Real-mouse motion always keeps priority.

Tunable via km.human(level) (default on, level 2).

Test plan

  • Host unit tests pass (make test): conservation, idle gate, 127 cap, anti-quantization, in-frame delivery, field-clip carry.
  • Both firmware builds clean (make, make PROTOCOL=ferrum).
  • Hardware: injected movement responsive; injection during real mouse movement is smooth.
  • Optional: 8-bit-delta mouse under real+injected saturation (field-clip carry edge).

ramseymcgrath and others added 17 commits June 2, 2026 00:06
Spec for moving humanization from an opt-in trajectory generator (smooth.c,
MOVE_SMOOTH only) to an always-on signal-level output filter that humanizes
every report. Captures the Tier-1/Tier-2 detection threat model, the
filter-not-generator decision, and the integration model grounded in rn-mouse
(host already does WindMouse/Kalman; device must be a downstream bounded filter).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ault-on km.human

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…dither + cap)

Implements the real always-on humanization filter in src/humanize.c:
- Displacement-conserving 1st-order exponential drain (owed accumulator,
  carry-on-cap so no motion is dropped even on a 30 000-count injection)
- Correlated perpendicular micro-noise via EWMA-smoothed SFC32 output
- Sub-pixel dither residual tracked separately from owed
- Idle gate: zero-in, settled state -> zero-out (no tremor on still cursor)
- Human per-frame cap (127 counts) with proper signal_cut carry-back
- Four levels (0=off, 1-3 increasing humanization strength)
- Builds both host (-DHUMANIZE_HOSTTEST, system gcc) and firmware (imxrt.h)
- All five test CHECKs pass: scaffold, conservation, idle gate, cap+carry, anti-quantization

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…lta telemetry

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ter to one advance per frame

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…rved

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…gle path

- l_mouse_move_smooth now calls act_move(..., false) so MOVE_SMOOTH frames
  go through the normal raw injection path; humanize.c filters everything
- act_move smooth branch removed; always calls kmbox_inject_mouse directly
- apply_mouse_result smooth branch removed; always accumulates into inject dx/dy
- kmbox_inject_smooth function deleted; smooth_set_max_per_frame setup block
  deleted from kmbox_cache_endpoints; smooth_init call deleted from kmbox_init
- #include "smooth.h" removed from actions.c and kmbox.c
- kmbox_inject_smooth declaration removed from kmbox.h
- src/smooth.c, src/smooth.h, src/smooth_config.h deleted
- Makefile: src/smooth.c removed from SRC, src/smooth.o removed from HOT_SRC
- CLAUDE.md Key Files updated: smooth.c line replaced with humanize.c description
act_move, kmbox_inject_mouse, and apply_mouse_result all had a bool
smooth/use_smooth parameter that was always passed as false after the
smooth.c retirement. Remove it entirely from all declarations, definitions,
and call sites across actions.c/h, hurra.c, ferrum.c, kmbox.c/h.
…on, field-clip carry

The always-on humanization filter degraded injected movement: a 40%/frame
drain smeared each command over ~10 ms, and the synth path flooded the 1 kHz
endpoint with empty reports that competed with real-mouse reports.

- Deliver injected motion in-frame (drop the cross-frame velocity drain); keep
  noise + sub-pixel dither + 127 cap + timing jitter for Tier-1 realism.
- Inject onto real-mouse reports while the mouse is active; synthesize a
  standalone report only during mouse silence, at most once per ms — so the two
  paths never both emit in the same frame.
- Return field-clamped injected overflow to the filter (humanize_return) so
  8-bit-delta mice are lossless and split X/Y report-ID mice don't drop an axis;
  real-mouse motion always keeps priority.

Host tests cover in-frame delivery and field-clip carry; both protocols build.
Copilot AI review requested due to automatic review settings June 2, 2026 05:36

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot reviewed 18 out of 18 changed files in this pull request and generated no comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@ramseymcgrath
ramseymcgrath merged commit dbc9fd7 into main Jun 2, 2026
3 checks passed
@ramseymcgrath
ramseymcgrath deleted the fix/humanization-injection branch June 2, 2026 05:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants