diff --git a/plugins/security-guidance/hooks/hooks.json b/plugins/security-guidance/hooks/hooks.json index 38390d1a..39dbac57 100644 --- a/plugins/security-guidance/hooks/hooks.json +++ b/plugins/security-guidance/hooks/hooks.json @@ -37,7 +37,7 @@ { "type": "command", "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/sg-python.sh\" \"${CLAUDE_PLUGIN_ROOT}/hooks/security_reminder_hook.py\"", - "if": "Bash(git commit:*)|Bash(gt create:*)|Bash(gt modify:*)", + "if": "Bash(git commit:*)", "asyncRewake": true, "rewakeMessage": "Background security review of commit — address or acknowledge the findings below, then continue with the user's original request or continue waiting for their reply:", "rewakeSummary": "Commit security review found issues" @@ -45,7 +45,31 @@ { "type": "command", "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/sg-python.sh\" \"${CLAUDE_PLUGIN_ROOT}/hooks/security_reminder_hook.py\"", - "if": "Bash(git push:*)|Bash(gt submit:*)", + "if": "Bash(git push:*)", + "asyncRewake": true, + "rewakeMessage": "Background security review of pushed commits not yet reviewed — address or acknowledge the findings below, then continue with the user's original request or continue waiting for their reply:", + "rewakeSummary": "Push security review found issues" + }, + { + "type": "command", + "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/sg-python.sh\" \"${CLAUDE_PLUGIN_ROOT}/hooks/security_reminder_hook.py\"", + "if": "Bash(gt create:*)", + "asyncRewake": true, + "rewakeMessage": "Background security review of commit — address or acknowledge the findings below, then continue with the user's original request or continue waiting for their reply:", + "rewakeSummary": "Commit security review found issues" + }, + { + "type": "command", + "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/sg-python.sh\" \"${CLAUDE_PLUGIN_ROOT}/hooks/security_reminder_hook.py\"", + "if": "Bash(gt modify:*)", + "asyncRewake": true, + "rewakeMessage": "Background security review of commit — address or acknowledge the findings below, then continue with the user's original request or continue waiting for their reply:", + "rewakeSummary": "Commit security review found issues" + }, + { + "type": "command", + "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/sg-python.sh\" \"${CLAUDE_PLUGIN_ROOT}/hooks/security_reminder_hook.py\"", + "if": "Bash(gt submit:*)", "asyncRewake": true, "rewakeMessage": "Background security review of pushed commits not yet reviewed — address or acknowledge the findings below, then continue with the user's original request or continue waiting for their reply:", "rewakeSummary": "Push security review found issues" diff --git a/plugins/security-guidance/hooks/security_reminder_hook.py b/plugins/security-guidance/hooks/security_reminder_hook.py index 6d28068f..96f3c7c7 100755 --- a/plugins/security-guidance/hooks/security_reminder_hook.py +++ b/plugins/security-guidance/hooks/security_reminder_hook.py @@ -640,7 +640,15 @@ _COMMIT_SHA_RE = re.compile(r'^\[[^\]]*?\b([0-9a-f]{7,40})\]', re.MULTILINE) # widening for `gt create:*` / `gt modify:*` / `gt submit:*` ships in the # same change set — without that widening this regex change is dead code # because the hook subprocess never spawns for gt invocations. See #2048. -_GIT_COMMIT_RE = re.compile(r'\b(?:git\s+commit|gt\s+(?:create|modify))(?:\s|$)') +_GIT_COMMIT_RE = re.compile( + # `git -C ` and `git -c key=val` global options are allowed between + # `git` and `commit` (mirrors the long-standing tolerance in + # _GIT_PUSH_RE). Without this, `git -C /repo commit` is silently dropped + # by the handler — see #2089's secondary finding. The gt branch has no + # global-option layer to worry about. + r'\bgit(?:\s+-[Cc]\s+\S+|\s+--\S+=\S+)*\s+commit\b' + r'|\bgt\s+(?:create|modify)\b' +) # Match either the `--amend` flag (with the leading whitespace boundary # preserved from the original) OR `gt modify` which is semantically an # amend. The handler treats matches as "find the pre-amend SHA via reflog