Skip to content

hook-manager: add a pre-commit adapter #1820

Open

Description

@potiuk

The hook-manager contract (#1819) defines how the secure agent setup integrates a git-hook manager: where its install puts the hook, how its home is split between sandboxed and host runs, and how the setup detects that a repository uses it.
prek is the only adapter so far.
This issue adds pre-commit (Python).

What the source says (pre-commit v4.7.0)

  • Install target. pre-commit install always writes $(git rev-parse --git-common-dir)/hooks/<type> (commands/install_uninstall.py:47-53, git.py:86-93), but refuses when git config core.hooksPath returns anything (git.py:180-182):
    Cowardly refusing to install hooks with core.hooksPath set. (install_uninstall.py:123-127).
    Under the whole-user setup the global core.hooksPath is always set, so a plain install always fails.
    There is no --git-dir flag (main.py:273-293).
  • Fix. GIT_CONFIG_GLOBAL=/dev/null pre-commit install hides the global value from that check, and the install lands in the common dir.
    Do not use GIT_CONFIG_COUNT to override core.hooksPath: any non-empty value is refused, and git treats an empty value as set (hooks then resolve against /).
    Do not use pre-commit init-templatedir as a workaround: it forces overwrite=True, which moves a foreign hook to .legacy and then deletes it.
  • Home. PRE_COMMIT_HOME, else $XDG_CACHE_HOME/pre-commit, else ~/.cache/pre-commit (store.py:32-36).
    Hook runs execute the repositories cloned and the environments built there (repository.py:177,196), so it needs the same sandbox/host split as prek.
    PRE_COMMIT_HOME does not expand ~ (only os.path.realpath), so the committed settings cannot spell the sandbox home as ~/.cache/pre-commit-sandbox; it would become <cwd>/~/.cache/....
  • Generated hook. It hardcodes the install-time Python (INSTALL_PYTHON=...) with a fallback to pre-commit on PATH, and passes --hook-dir "$(dirname "$0")", which is used only to find <type>.legacy (hook_impl.py:36-46).
    The dispatcher execs it by its real path, so that works.
  • Detection. Config .pre-commit-config.yaml (or a custom --config path written into the hook); no nested configs.
    Hook marker: the generated hook names pre-commit.

What to do

  1. Add a hide-global-config install strategy to tools/agent-isolation/hook-manager-shim.sh (run the install with GIT_CONFIG_GLOBAL=/dev/null) and to STRATEGIES in tools/dev/sync-hook-managers.py, with a shim test.
  2. Decide how a home that does not expand ~ gets a per-user sandbox value.
    The contract requires expands_tilde: true today.
    One option: sandbox-add-project-root.sh writes the absolute PRE_COMMIT_HOME into the per-user .claude/settings.local.json, and sandbox-lint accepts it there.
    Write the choice into the contract's Home section.
  3. Add the pre-commit adapter to tools/hook-manager/registry.json (detect.config_files: [".pre-commit-config.yaml", ".pre-commit-config.yml"], nested: false, hook_marker: "pre-commit") and run tools/dev/sync-hook-managers.py.
  4. The two YAML names are shared with prek, so a repository with either uses both managers as far as detection goes; check that both homes are set for it and nothing breaks.
  5. Update the adapter table in the contract, and docs/setup/sandbox-troubleshooting.md for the "Cowardly refusing" error.

Acceptance

  • pre-commit install through ~/.claude/bin/pre-commit succeeds under a global core.hooksPath and writes to the common dir, including in a linked worktree.
  • A hook run outside the sandbox gets a host-only PRE_COMMIT_HOME; a sandboxed run gets the sandbox home; a repository without a pre-commit config gets neither.
  • prek run --all-files --skip workspace-pytest and the agent-isolation, sandbox-lint and dev tests pass.

Activity

  1. added
    contract:hook-managerTool capability: git-hook managers under the secure setup (install target, sandbox / host homes)
    on Oct 25, 2026
  2. ninglinLiu commented on Oct 25, 2026

    @ninglinLiu

    I'd like to work on this one: add the hide-global-config install strategy to hook-manager-shim.sh and STRATEGIES, the pre-commit registry entry (with the non-expanding PRE_COMMIT_HOME handled explicitly), regenerate with tools/dev/sync-hook-managers.py, and add shim tests for the new strategy. Could a maintainer assign it to me? I'll wait for the assignment before opening a PR.

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

    contract:hook-managerTool capability: git-hook managers under the secure setup (install target, sandbox / host homes)family:setupsetup-* skillsgood first issueGood for newcomers

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions