From f6139d4ed3d6003bc22656ccd25ceffd89b0edbe Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 27 Jul 2026 22:24:34 +0000 Subject: [PATCH] Add the Claude Code web SessionStart hook and bump the drift pin to v5 PythonTap was one of three repos in the family without the canonical SessionStart hook. Fresh Claude Code web containers clone bare -- no submodules, no pre-commit hook -- so agent commits could bypass the local format layer entirely and fail the clang-format gate on code a local clone would have fixed at commit time. The hook initializes source/min-api recursively, installs the pinned pre-commit hook, and warms its clang-format. The drift pin moves v4 -> v5 in the same commit because that is what makes the hook guarded rather than merely present: v4 does not carry .claude/hooks/session-start.sh, so the drift job's conditional guard would skip it silently. At v5 the guard becomes active. Verified this cannot break the gate: v4 and v5 carry byte-identical .clang-format, .clang-tidy, STYLE.md, .pre-commit-config.yaml and scripts/tidy.sh -- the tags differ only by the addition of the hook -- and every file the v5 drift job will compare here matches its canonical blob exactly, including the new hook at b7c2a49. .claude/settings.json is the canonical copy, created because none existed; it stays unguarded by design. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01JhhQ93r2E1QTnCx46YfX8j --- .claude/hooks/session-start.sh | 36 ++++++++++++++++++++++++++++++++++ .claude/settings.json | 14 +++++++++++++ .github/workflows/style.yml | 4 ++-- 3 files changed, 52 insertions(+), 2 deletions(-) create mode 100755 .claude/hooks/session-start.sh create mode 100644 .claude/settings.json diff --git a/.claude/hooks/session-start.sh b/.claude/hooks/session-start.sh new file mode 100755 index 0000000..b7c2a49 --- /dev/null +++ b/.claude/hooks/session-start.sh @@ -0,0 +1,36 @@ +#!/bin/bash +# Canonical Tap House SessionStart hook for Claude Code on the web. +# +# Fresh web-session containers clone the repo bare: no submodules, no +# pre-commit hook installed — so `git commit` runs unformatted and the +# clang-format CI gate fails on code a local clone would have fixed at commit +# time. This hook closes that gap at session start: +# +# 1. init submodules recursively (kernels, SDKs, vendored test harnesses) +# 2. install pre-commit and register the repo's canonical hook +# (.pre-commit-config.yaml — the Tap-wide pinned clang-format) +# 3. warm the pinned clang-format binary so the first commit doesn't +# pay the download (the container snapshot caches it) +# +# Canonical copy: taphouse (distributed by scripts/sync.sh alongside +# .clang-format / .clang-tidy / .pre-commit-config.yaml; drift-guarded where +# present). Web-only; local clones are untouched. +set -euo pipefail + +if [ "${CLAUDE_CODE_REMOTE:-}" != "true" ]; then + exit 0 +fi + +cd "$CLAUDE_PROJECT_DIR" + +echo "session-start: initializing submodules ..." +git submodule update --init --recursive + +echo "session-start: installing pre-commit ..." +if ! python3 -m pre_commit --version >/dev/null 2>&1; then + python3 -m pip install --quiet pre-commit +fi +python3 -m pre_commit install +python3 -m pre_commit install-hooks + +echo "session-start: done." diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 0000000..e06b033 --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,14 @@ +{ + "hooks": { + "SessionStart": [ + { + "hooks": [ + { + "type": "command", + "command": "$CLAUDE_PROJECT_DIR/.claude/hooks/session-start.sh" + } + ] + } + ] + } +} diff --git a/.github/workflows/style.yml b/.github/workflows/style.yml index eef1254..eee6777 100644 --- a/.github/workflows/style.yml +++ b/.github/workflows/style.yml @@ -14,9 +14,9 @@ on: [push, pull_request] jobs: drift: - uses: tap/taphouse/.github/workflows/drift-check.yml@v4 + uses: tap/taphouse/.github/workflows/drift-check.yml@v5 with: - ref: v4 + ref: v5 clang-format: runs-on: ubuntu-latest