#21155: reply: add cancellable before_reset guard for /new and /reset
size: M
## Summary
- Problem: `/new` and `/reset` are applied immediately; existing hooks are listen-only and cannot block reset.
- Why it matters: in chat-first flows (e.g. Telegram + GSD/subagents), accidental reset can drop active context and unsaved progress.
- What changed: add a cancellable `command:before_reset` guard path and propagate `resetBlocked` through reply pipeline.
- What did NOT change: default reset triggers/config semantics are unchanged unless a hook explicitly blocks reset.
## Change Type
- [x] Bug fix
- [x] Feature
- [x] Security hardening
## Scope
- [x] Gateway / orchestration
- [x] API / contracts
## User-visible / Behavior Changes
- When a `command:before_reset` internal hook sets `event.context.blockReset = true`, `/new` or `/reset` is cancelled.
- User receives guard text (default: `已阻断 /new,请先保存收尾`, or hook-provided message).
- Session is preserved (no reset), and inline command flow is skipped for that turn.
## Security Impact
- New permissions/capabilities? No
- Secrets/tokens handling changed? No
- New/changed network calls? No
- Command/tool execution surface changed? Yes (hook can now cancel reset intentionally)
- Data access scope changed? No
## Repro + Verification
1. Register internal hook `command:before_reset` and set `event.context.blockReset = true`.
2. Send `/new` (or `/reset`) in active session.
3. Verify reset is cancelled and guard message is returned.
## Compatibility
- Backward compatible: Yes
- Config/env migration: No
## Tests
- `pnpm test:fast src/auto-reply/reply/session.test.ts src/auto-reply/reply/reply-flow.test.ts src/hooks/bundled/session-memory/handler.test.ts src/auto-reply/reply/get-reply-run.media-only.test.ts`
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Adds a cancellable `command:before_reset` internal hook that allows blocking `/new` and `/reset` commands to prevent accidental context loss in chat-first workflows. When a hook sets `event.context.blockReset = true`, the reset is cancelled, the session is preserved, and a guard message is returned to the user.
Key changes:
- New internal hook system invoked before reset processing in `session.ts:214-224`
- Reset blocking propagated through `resetBlocked` and `resetBlockMessage` fields across reply pipeline
- Early return in `get-reply-run.ts:165-171` when reset is blocked
- Inline command processing skipped when `ResetBlocked` is set in `get-reply-inline-actions.ts:244-250`
- Comprehensive test coverage for both `/new` and `/reset` blocking scenarios
<h3>Confidence Score: 4/5</h3>
- Safe to merge with minor observation about dual hook systems
- Well-structured implementation with proper type safety, comprehensive tests, and clear propagation of blocking state through the reply pipeline. The internal hook system is correctly awaited and checked. Score is 4 (not 5) due to the observation that plugin hooks have unused `cancel`/`message` fields that create interface confusion, though this doesn't affect functionality.
- No files require special attention
<sub>Last reviewed commit: 03fc3e6</sub>
<!-- greptile_other_comments_section -->
<sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#9782: feat(hooks): implement session:start and session:end lifecycle events
by kentaro · 2026-02-05
77.6%
#6853: fix: fire internal hooks on sessions.reset RPC (TUI/webchat /new)
by hamiltonchua · 2026-02-02
77.6%
#11681: feat(plugins): add cancel support to message_received hook
by PrimeTenet · 2026-02-08
76.0%
#13032: feat(hooks): add unified session:before_end hook event
by TGambit65 · 2026-02-10
74.0%
#14243: fix: fire session-memory hook on auto-resets + topic-aware memory p...
by TheDude135 · 2026-02-11
73.9%
#18103: fix: session-memory hook reads reset file after /new or /reset
by MisterGuy420 · 2026-02-16
73.7%
#11872: Add Pre-Reset Hook
by scomma · 2026-02-08
72.9%
#18004: feat: Add before_message_dispatch hook for blocking inbound messages
by Andy-Haigh · 2026-02-16
72.6%
#16915: fix: await compaction hooks with timeout to prevent cross-session d...
by maximalmargin · 2026-02-15
71.5%
#3392: fix(hooks): remove debug console.log statements from session-memory...
by WinJayX · 2026-01-28
71.2%