#22293: Hooks: add message-filter bundled hook with inbound message pre-filter
size: L
## Summary
- Add `InboundMessageHookContext` type and `InboundMessageHookEvent` type to `internal-hooks.ts`, enabling mutable pre-processing hooks that can veto inbound messages before model work
- Wire `message:inbound` hook trigger into `dispatch-from-config.ts` (between dedup check and model invocation), with early return when `skip=true`
- Add bundled `message-filter` hook: opt-in regex-based filter that silently drops automated/junk messages (OTP codes, marketing, appointment reminders, fitness notifications, delivery updates, banking alerts)
- Features: command bypass (`/` prefix never filtered), allowed/blocked sender lists, SMS shortcode detection, custom regex patterns, per-category enable/disable, safe logging (digits redacted)
## Motivation
Messaging channels (iMessage, SMS, Telegram) receive many automated messages that waste tokens and produce confusing agent responses. This hook lets operators opt in to filtering them at zero latency and zero token cost, using only regex pattern matching.
The `InboundMessageHookContext` with mutable `skip`/`skipReason` fields provides a generic pre-filter mechanism that other hooks can also use.
## Test plan
- [x] 22 new tests in `handler.test.ts` covering all 6 categories, command bypass, allowed/blocked senders, shortcode detection, custom patterns, disabled categories, invalid patterns, and real-world message examples
- [x] All 142 existing hooks tests still pass (`pnpm vitest --run src/hooks/`)
- [x] `pnpm build` succeeds, HOOK.md copied to dist
- [x] `pnpm format:check` passes
- [x] Only pre-existing upstream TS error (`discord/send.components.test.ts`) remains
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Added a pre-processing hook system for filtering automated inbound messages before they reach the model. The implementation includes:
- New `InboundMessageHookContext` and `InboundMessageHookEvent` types in `internal-hooks.ts` for mutable pre-filter hooks
- Integration point in `dispatch-from-config.ts` between dedup check and model invocation with early return on `skip=true`
- Bundled `message-filter` hook with 6 built-in categories (OTP, marketing, appointments, fitness, delivery, banking)
- Opt-in design with command bypass, allowlist/blocklist, shortcode detection, and custom patterns
- Comprehensive test coverage with 22 new tests covering all categories and edge cases
The hook correctly runs after deduplication and before any model work, achieving zero-latency and zero-token-cost filtering as intended. The implementation follows existing hook patterns and includes proper type guards, error handling, and safe logging with digit redaction.
<h3>Confidence Score: 5/5</h3>
- Safe to merge - well-tested opt-in feature with defensive design
- High confidence due to comprehensive test coverage (22 tests), opt-in design that won't affect existing systems, proper integration at correct lifecycle point, defensive patterns (command bypass, allowlist support), and safe handling of sensitive data (digit redaction). Only minor documentation inconsistency found regarding shortcode digit count.
- No files require special attention
<sub>Last reviewed commit: 8a1d249</sub>
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#11597: feat(hooks): implement message:received hook
by gnufoo · 2026-02-08
80.3%
#7545: feat(hooks): add message:received hook for pre-turn automation
by wangtian24 · 2026-02-02
79.7%
#10706: feat(hooks): add message:received internal hook for Telegram
by thebtf · 2026-02-06
78.9%
#19922: feat(hooks): add message:received and message:sent hook events
by NOVA-Openclaw · 2026-02-18
78.4%
#9906: feat: wire message_sending hook in outbound delivery
by teempai · 2026-02-05
78.0%
#18004: feat: Add before_message_dispatch hook for blocking inbound messages
by Andy-Haigh · 2026-02-16
77.4%
#8084: fix(plugins): wire up message_sending hook in outbound delivery
by lailoo · 2026-02-03
77.4%
#7580: feat: add message:received internal hook with prompt injection
by rodrigoschott · 2026-02-03
77.2%
#16618: feat: bridge message lifecycle hooks to workspace hook system
by DarlingtonDeveloper · 2026-02-14
77.0%
#20859: fix(hooks): wire message_sent hook into reply dispatcher for all ch...
by davidrudduck · 2026-02-19
76.3%