Skip to content

feat: add modifies_hooks support for extension hook overrides#2209

Closed
dango85 wants to merge 1 commit intogithub:mainfrom
dango85:feat/extension-hook-overrides
Closed

feat: add modifies_hooks support for extension hook overrides#2209
dango85 wants to merge 1 commit intogithub:mainfrom
dango85:feat/extension-hook-overrides

Conversation

@dango85
Copy link
Copy Markdown
Contributor

@dango85 dango85 commented Apr 13, 2026

Summary

  • Extensions can now declare a modifies_hooks section in extension.yml to disable or set_optional hooks from other installed extensions during specify extension add
  • Solves the conflict where extensions like spec-kit-worktree-parallel need to disable the git extension's before_specify -> speckit.git.feature hook (which forces branch switching, breaking the worktree-first workflow)

Related Issues

This PR addresses a common pain point across many open issues — the inability for extensions to coordinate hook behavior, especially around git branch creation:

Issue Title Impact
#654 Rethink the branch thing 142 upvotes — widespread frustration with forced branching; modifies_hooks lets extension authors provide alternatives
#61 Spawn worktree when creating new branch 36+ upvotes — worktree extensions need to disable branch-first hooks
#1476 Native git worktree support for parallel agents Parallel agents need stable checkout; this PR is the extension-level answer
#1680 Support using existing branch (without auto branch creation) Extensions can now disable git.feature to stay on the current branch
#1921 Make branch creation configurable modifies_hooks provides the mechanism for conditional branch behavior
#2047 Configurable branching strategy without command forking Extensions declare modifies_hooks instead of forking the specify command
#2168 Make git extension opt-in at 1.0.0 modifies_hooks provides a granular alternative: keep git for commits, disable branch creation
#2167 Deprecate --no-git flag Eliminates the need for --no-git as a blunt instrument — extensions surgically disable specific hooks
#343 Add hook system for workflow automation Extends the hook system with inter-extension coordination
#1850 Preset system: hook system for post-install automation modifies_hooks is the install-time hook automation mechanism
#1016 Allow branching to be optional in git repos modifies_hooks: action: disable on the branch hook is exactly this
#377 Multi agent in one project Parallel agents need worktree isolation, which needs the branch hook disabled
#537 Remove all git functionality Extreme version of the same frustration — modifies_hooks lets people disable git hooks selectively

Safety Model

Guardrail Behavior
Explicit consent Interactive Y/N prompt before applying any modifications
CI / non-TTY Defaults to NO (fail-closed)
Granular targeting Requires hook + extension + command triple
Limited actions Only disable and set_optional (no removal, no arbitrary mutation)
Mandatory reason reason field required and shown in consent prompt
Community warning Extra warning when modifying non-bundled extension hooks
Reversible Original state restored on specify extension remove
Audit trail Applied modifications stored in registry _modified_hooks

Schema

modifies_hooks:
  - hook: before_specify
    extension: git
    command: speckit.git.feature
    action: disable
    reason: "Worktree-parallel keeps primary checkout stable; branch creation happens via git worktree add -b"

Consent UX

Extension 'worktrees' requests the following hook modifications:

  Hook                   Target Extension   Command                      Action       Reason
  -----------------------------------------------------------------------------------------------------------------------
  before_specify         git                speckit.git.feature          disable      Worktree-parallel keeps primary...

Apply these modifications? [Y/n]:

Test plan

  • 9 new tests added covering: consent accepted, consent declined, non-TTY, uninstall restore, validation (missing fields, bad action), target not found, already-disabled no-op
  • All 165 existing extension tests pass (zero regressions)

Extensions can now declare a `modifies_hooks` section in extension.yml
to disable or set_optional hooks from other extensions during installation.

This solves conflicts like the worktree-parallel extension needing to
disable the git extension's `before_specify -> speckit.git.feature` hook,
which forces branch switching and breaks the worktree-first workflow.

Safety model:
- Requires explicit user consent (Y/N prompt) before applying modifications
- Non-TTY (CI) defaults to NO (fail-closed)
- Granular targeting: hook + extension + command triple required
- Limited actions: only disable and set_optional (no removal)
- Reason field is mandatory and shown in consent prompt
- Extra warning when modifying community (non-bundled) extension hooks
- Fully reversible: original state restored on extension removal
- Audit trail in registry via _modified_hooks metadata

Schema:
  modifies_hooks:
    - hook: before_specify
      extension: git
      command: speckit.git.feature
      action: disable
      reason: "Worktree-parallel keeps primary checkout stable"

Closes: related to github#61, github#1476
Made-with: Cursor
@dango85 dango85 requested a review from mnriem as a code owner April 13, 2026 22:41
dango85 pushed a commit to dango85/spec-kit-worktree-parallel that referenced this pull request Apr 13, 2026
Declares modifies_hooks in extension.yml so that installing this extension
automatically disables the git extension's before_specify -> speckit.git.feature
hook (with explicit user consent). This keeps the primary checkout on a stable
branch while worktrees handle feature branch isolation.

Requires: github/spec-kit#2209 (modifies_hooks support)
Made-with: Cursor
@mnriem
Copy link
Copy Markdown
Collaborator

mnriem commented Apr 13, 2026

Are you aware that you can disable an extension?

@dango85
Copy link
Copy Markdown
Contributor Author

dango85 commented Apr 13, 2026

Thanks for the feedback @mnriem!

Yes — though specify extension disable git turns off all git hooks (including speckit.git.commit, speckit.git.initialize, etc.). For the worktree-parallel case, we only need to skip the before_specify → speckit.git.feature hook while keeping everything else working.

Today there's no per-hook granularity at the CLI level, so the only option is manually editing extensions.yml. modifies_hooks lets extension authors declare that intent so users don't have to discover and fix the conflict themselves.

Happy to adjust the approach if there's a preferred direction — e.g., a specify extension disable-hook git before_specify command could work just as well.

@mnriem mnriem self-assigned this Apr 13, 2026
dango85 pushed a commit to dango85/spec-kit-worktree-parallel that referenced this pull request Apr 14, 2026
Re-adds modifies_hooks to disable git before_specify on install with consent.
Bumps extension to 1.2.2. Supersedes the 1.2.1 revert for users who want automatic hook coordination.

Requires: github/spec-kit#2209
Made-with: Cursor
@mnriem
Copy link
Copy Markdown
Collaborator

mnriem commented Apr 14, 2026

I am very hesitant to allow one extension to change the configuration of another. It creates a whole sleuth of other potentital problems with dependencies.

I think the best approach here is to use a preset that overrides just the commands (either core command or extension command) you need to behave differently.

That way you are in control of what happens. As otherwise any change to the Git extension could very easily break you?

Note at 1.0.0 time the Git extension becomes an opt-in so you cannot rely on the fact it will be auto enabled then

@dango85
Copy link
Copy Markdown
Contributor Author

dango85 commented Apr 14, 2026

Thanks for the clear guidance — I agree.

I won’t merge or pursue cross-extension configuration (one extension changing another’s hooks/config on install). It’s too easy to break when the Git extension changes, and it doesn’t fit Git becoming opt-in at 1.0.0.

For parallel worktrees, the fix is explicit user control: e.g. set enabled: false on the Git extension’s before_specify → speckit.git.feature entry in .specify/extensions.yml when you need a stable primary checkout, and use git worktree add -b so feature branches don’t require git checkout on the shared root.

I’ll treat any stronger “do X before specify” workflow as a preset that overrides only the commands that need to differ.

I’m closing this PR; follow-up is documentation (and a separate preset repo/zip if useful), not more hook-override machinery in core.

@dango85 dango85 closed this Apr 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants