Skip to content

feat(hooks): full git-hooks drop-in (lefthook replacement) covering commit-stage and beyond #468

@avihut

Description

@avihut

Goal

Extend daft's hooks system from worktree-lifecycle-only to a full git-hooks drop-in — a lefthook-style replacement that fires on the standard git hook stages (`pre-commit`, `commit-msg`, `pre-push`, `prepare-commit-msg`, etc.) in addition to the existing worktree-lifecycle hooks.

This unifies feature work and docs in a single tracking issue (per "docs and features must enter together"). Supersedes the docs-only #465.

Why

The Hooks pillar's positioning thesis (per the docs IA spec at `docs/superpowers/specs/2026-05-03-docs-ia-restructure-design.md`) is "daft hooks as a local parallel to GitHub Actions, with each code-evolution stage getting its own gate."

Today daft hooks cover only the worktree-lifecycle stage. The lefthook drop-in expands coverage to commit-stage hooks — the "progressive code-replication boundary" where format/lint/fast-tests run before a change is recorded. Together with merge hooks (#330) and worktree hooks (shipped), this completes the boundaries-as-stages picture.

It also opens a clear migration path for users on lefthook today, broadening daft's adoption surface beyond the worktree-only audience.

Feature scope

  • Hook stages supported (initial): `pre-commit`, `commit-msg`, `prepare-commit-msg`, `pre-push`, `post-commit`, `pre-rebase`. Beyond these as future work.
  • Implementation strategy: register daft as the git hook handler (write thin shim scripts under `.git/hooks/` that delegate to daft); preserve any existing user-managed hooks (don't clobber)
  • `daft.yml` schema extension: new top-level keys for commit-stage hook stages, sharing the existing job-orchestration semantics (parallelism, deps, conditions, OS/arch gating, trust)
  • Stage-specific context env vars: `pre-commit` exposes staged files; `commit-msg` exposes message path; `pre-push` exposes ref ranges; etc.
  • Trust model: same trust-on-first-use model as existing hooks (already in place)
  • Bypass: `--no-verify` honored (git's standard); per-hook `skip:` matchers
  • Idempotent install: re-running registration is a no-op; uninstall command restores original `.git/hooks` state
  • Compatibility: detect existing lefthook / pre-commit framework installs and surface a clear migration message (don't silently take over)

Documentation scope (in this PR)

The new IA from #398 must be in place before this lands. This PR adds:

  • `hooks/commit-hooks.md` (Reference) — full reference for every supported commit-stage hook type, daft.yml schema, env var contract, exit-code semantics
  • `hooks/lefthook-migration.md` (How-to) — side-by-side config translation, equivalences, things daft adds, things daft doesn't (yet)
  • Update `hooks/index.md` (pillar Overview) — promote commit hooks from "future" to "shipped"; sharpen the lefthook-replacement framing
  • Update `hooks/roadmap.md` — strike commit hooks from the roadmap
  • Update `about/comparison.md` — expand "vs lefthook" section
  • Cookbook recipes under `cookbook/by-tooling/`:
    • Replacing lefthook with daft hooks
    • Mixing daft hooks with existing pre-commit framework
  • Update agent skill (`SKILL.md`) — commit-stage hooks are now in scope

Depends on

Closing condition

Feature shipped, integration scenarios green, all docs above live, agent skill updated.

Supersedes

Inbound docs references — clean up when this ships

The following docs pages currently describe commit-stage hooks as "on the roadmap" and cite this issue. When this ships, rewrite each to reflect the shipped state:

The cookbook recipes enumerated in the Documentation scope above (lefthook → daft, mixing with pre-commit) are net-new content rather than cross-references.

Metadata

Metadata

Assignees

Labels

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions