Commit Check - xsyetopz/claudetto GitHub Wiki

Commit Check

This page describes how claudetto makes sure that a commit or a pull request of Claude has the attribution lines. It is for a user who wants to know what /claudetto:setup writes, and how to turn the check off. The harness only makes sure that Claude follows the guidelines of the settings. The user can turn each part off.

What It Does

Claude Code adds the attribution lines when it follows a reminder in the context. The attribution slice sends the same reminder, and it adds three checks for the git commands that Claude runs. A command that the user types in a terminal has no check.

Part When Result
Reminder Before a prompt, and in the task of a subagent Claude knows the commit line and the pull request line.
commit-msg hook On each git commit of Claude Git rejects a message that does not end with the commit line.
Bypass deny Before a git commit that skips the hook The call is denied with the reason.
Pull request check After gh pr create or gh pr edit, and before a GitHub MCP write Claude gets a note, or the call is denied, when the body lacks the pull request line.

The Commit Hook

/claudetto:setup writes the env keys GIT_CONFIG_COUNT, GIT_CONFIG_KEY_<n>, and GIT_CONFIG_VALUE_<n> to the settings. They define a config-based hook of git: hook.claudetto-attribution.event is commit-msg, and hook.claudetto-attribution.command is the script. Two more pairs set hook.claudetto-attribution.enabled and hook.commit-msg.enabled to true. The env keys are in the command scope of git, which wins over the config of a repository. So a repository that sets one of the enabled keys to false, or sets another command or event, does not remove the check. A setup from an earlier version has two pairs, and a new run adds the two enabled pairs after them. The setup adds the keys after the GIT_CONFIG_* keys of the user, keeps those keys, and changes nothing on a second run. The hook runs next to the hooks of the repository, so it does not replace them.

The attribution hooks write the commit line of each model of the session to a file in ~/.claudetto/attribution/<session id>/. The script reads the files of the session in CLAUDE_CODE_SESSION_ID. The script accepts a message when the last line, after git removes the comments, is a recorded line. It also accepts a message where a recorded line is a whole line of the trailers, such as before a Signed-off-by line. A rejected commit prints a note with the lines, and Claude adds the line and commits again. A commit with no session id, or with no recorded line, passes. The pre-push hook of the AI policy checks only a push from a Bash call of Claude, which CLAUDETTO_AGENT_CALL marks. The commit hook does not read that name.

Turn It Off

Set attribution.commit to an empty string in the settings. The next prompt empties the record files, so the hook passes. Set attribution.pr to an empty string to turn off the pull request check. Remove the four pairs of GIT_CONFIG_KEY_<n> and GIT_CONFIG_VALUE_<n> of claudetto from env, and lower GIT_CONFIG_COUNT, to remove the hook itself.

Git Version

The config-based hooks need git 2.54 or later. An older git ignores the keys, so the check passes with no output. /claudetto:setup runs git --version and says so when git is older than 2.54 or is missing. The note names the commit-msg and pre-push checks, which do not run. The reminder and the bypass deny work with each version of git.

Bypass Deny

When the commit line is on, the slice denies these forms of a git commit of Claude:

  • --no-verify, -n, and a cluster such as -nm.
  • -c core.hooksPath=..., -c hook.<name>..., or --config-env of such a key on the commit.
  • An assignment of GIT_CONFIG_COUNT, GIT_CONFIG_KEY_<n>, GIT_CONFIG_VALUE_<n>, GIT_CONFIG_PARAMETERS, GIT_CONFIG_GLOBAL, GIT_CONFIG_SYSTEM, or GIT_CONFIG_NOSYSTEM in a command with a commit.
  • An export, declare, typeset, readonly, local, or unset of one of those names in a command with a commit.
  • env -u <name>, env -i, or env --ignore-environment before git in a command with a commit.
  • git commit-tree, which writes a commit and runs no hook.

The Bash tool of Claude Code does not keep the env of one call for the next call, so a change of the env is a bypass only in the call that commits.

The check reads the command with the shell reader of the kernel, so a message that holds -n is not a bypass.

Pull Request Check

After a gh pr create or gh pr edit call, the slice runs gh pr view --json body. When the body does not end with the pull request line, Claude gets a note to fix it with gh pr edit --body-file. The GitHub MCP tools create_pull_request and update_pull_request are denied before the call when the body lacks the line. The check after the call fails open: a missing gh, no network, or an unreadable body adds no note.

Related Pages

⚠️ **GitHub.com Fallback** ⚠️