Refactor PostToolUse hook scaffold to centralize fail-closed policy
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 197
- Forks
- 51
- Avg merge
- 1d 23h
- Merged PRs (30d)
- 94
Description
Why
The PostToolUse handlers in `src/lib/yara-hooks.ts` (Write/Edit, Read/Grep, skill install) and the PreToolUse Bash handler all repeat the same scaffold:
- typeof-narrow `tool_name`
- extract a string field from `tool_input` or `tool_response`
- `recordScan()`
- `await scanAndTriage(...)`
- early-return if no matches
- `highestSeverityMatch` + `recordMatch` + return-or-onTerminate
- an outer `try/catch` that fails closed
Each of the four handlers has its own copy of step 7 — the fail-closed catch block. Three of them call `onTerminate?.()`; the fourth (Write/Edit) used to return `additionalContext` until very recently. The "fail closed on scanner error" invariant is enforced by reviewer discipline, not by a wrapper or a type.
A future handler (e.g. NotebookEdit, MCP tool output) is one easy mistake away from forgetting the fail-closed return entirely — at which point a scanner crash silently lets the violation through with no test or type to catch it.
Proposal
Extract a `withScanHook` higher-order helper:
```ts
function withScanHook(opts: {
extractContent: (input: HookInput) => string | null;
ctx: ScanContext;
llmProvider: LLMProvider | undefined;
onMatches: (matches: ScanMatch[], input: HookInput) => TResponse;
onScannerError: () => TResponse; // fail-closed response, typed
}): (input: HookInput) => Promise;
```
Each hook becomes a small declaration that only describes:
- how to extract content for THIS surface
- what to do when matches survive triage
The fail-closed try/catch lives in one place. The "this is the fail-closed response" decision is forced to be explicit at the type level.
Why this is its own ticket (not bundled with the YARA-X migration)
The refactor crosses every security path in the file. Doing it in the same PR as the warlock migration mixes two reasons to change one file. Better to land warlock first, lock in the test surface, then refactor under green tests.
🤖 Generated with Claude Code
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in src/lib/yara-hooks.ts and read the four PostToolUse and PreToolUse handlers, especially their repeated fail-closed catch blocks and the existing scan flow. Implement the shared withScanHook scaffold after the warlock migration is complete, then verify that each handler declares its content extraction, match response, and typed scanner-error response while the existing tests remain green.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- security
- Issue type
- Refactor
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 55/100