Skip to content

source-control:commit: evaluate a PreToolUse exec-bit tier for memory-following commits (deferred from #1579) #1585

Description

@kyle-sexton

Deferred third tier from #1579, which landed the pre-computed probe and the shipped
exec-bit-check.sh but deliberately stopped short of a hook.

What this tier would cover that the landed tiers do not

The probe and the script both require the skill to be invoked. The failure mode that motivated
#1579 was a run of memory-following commits that never invoked the skill at all — exactly the
case neither landed tier reaches. A PreToolUse hook is the only tier that covers it, because it
fires on the tool call regardless of whether any skill is in play.

Mechanism (verified against current docs, fetched 2026-07-26)

From https://code.claude.com/docs/en/hooks:

  • Plugin hooks live at hooks/hooks.json in the plugin root and are auto-discovered — no
    plugin.json declaration needed (https://code.claude.com/docs/en/plugins-reference).
  • A PreToolUse entry with "matcher": "Bash" receives the tool input on stdin as JSON with
    tool_name and tool_input, so the command string is readable via .tool_input.command.
  • Narrower filtering is available per handler via the if field using permission-rule syntax, e.g.
    "if": "Bash(git commit *)".
  • Blocking has two documented forms: exit 2 with the message on stderr, or exit 0 with
    hookSpecificOutput.permissionDecision: "deny" plus permissionDecisionReason (the richer,
    user-visible form).

Why it was NOT landed with #1579

  • source-control ships zero hooks today. Adding one changes the install footprint for every
    consumer of the plugin, not just users of /commit.
  • A Bash-matching hook is evaluated on every Bash tool call. Even with an if filter, this is a
    new always-on surface and belongs behind its own security review per the repo's plugin-acceptance
    process.
  • There is prior art and prior caution to reconcile: the guardrails plugin already ships
    PreToolUse on Bash|PowerShell with block-noncanonical-commit.sh and
    block-convention-violation.sh. That is proof the pattern works in-repo — but it lives in a
    different plugin, so a consumer installing only source-control inherits none of it. Whether
    this check belongs in source-control's own hooks or as an addition to guardrails is the actual
    design question, and it was not settled by source-control:commit: exec-bit check is advisory prose with no deterministic tier #1579.

Open design questions

  1. Which plugin owns it — source-control (cohesive with the skill, but a new hook surface for
    that plugin) or guardrails (already the hook home for git-commit gating, but then the check is
    absent for source-control-only consumers).
  2. Block or warn. An exec-bit miss is a correctness defect, not a safety one. deny may be too
    strong; ask, or a non-blocking warning, may fit better.
  3. Precision. The repo already carries a documented over-fire class for guardrails hooks (guardrails: hooks ship false-positive over-fires with no per-hook fixtures or shared precision convention (6-issue class: diff-scope, quoted-arg, boolean-intent, stdin, path-branch) #547).
    A new hook needs its own fixtures before shipping. Note that during source-control:commit: exec-bit check is advisory prose with no deterministic tier #1579's implementation the
    existing block-noncanonical-commit.sh false-fired on a gh issue create whose body text
    merely mentioned the guarded command — worth folding into the precision work either way.
  4. core.filemode=false interaction. Under the Windows default, staged mode is the only
    meaningful signal; a hook reasoning about worktree bits would be wrong there. See source-control:commit: exec-bit check is advisory prose with no deterministic tier #1579 for the
    verified behavior.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-humanHuman-in-the-loop required; autonomous sessions must not resolve items carrying this.priority: mediumReal value, no hard deadline; normal backlog flow.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions