# Git Hooks Unification Plan ## Goal Consolidate the current multi-script architecture into standard, self-contained git hook files that can be installed directly without external dependencies. ## Current Architecture ``` scripts/ ├── generate-proof.sh # Core proof generation logic ├── backfill-proofs.sh # History scanning + upgrade ├── install-ots-hook.sh # Installer script ├── pre-commit-backfill # Pre-commit hook wrapper ├── check-attestation.sh # Status checker └── setup-gitignore.sh # Gitignore helper ``` **Problems:** - Hooks depend on external scripts in repo root or global paths - Multiple files to manage and copy - Path resolution logic is fragile - Hard to install manually ## Target Architecture ``` hooks/ ├── post-commit # Self-contained post-commit hook ├── pre-commit # Self-contained pre-commit backfill hook └── install.sh # Simple installer (copies hooks) ``` Each hook file contains all necessary logic inline - no external dependencies. ## Implementation Plan ### Phase 1: Create Self-Contained Hooks #### `hooks/post-commit` Inline the entire `generate-proof.sh` logic: ```bash #!/bin/bash # Self-contained post-commit hook set -e COMMIT_HASH=$(git rev-parse HEAD) OUTPUT_FILE=".ots/proof.ots" mkdir -p "$(dirname "$OUTPUT_FILE")" # Inline: generate_with_ots_cli() temp_file=$(mktemp) temp_ots="${temp_file}.ots" python3 -c "import sys; sys.stdout.buffer.write(bytes.fromhex('$COMMIT_HASH'))" > "$temp_file" ots stamp "$temp_file" if [ -f "$temp_ots" ]; then mv "$temp_ots" "$OUTPUT_FILE" rm -f "$temp_file" fi # Inline: get previous commit PREV_COMMIT=$(git rev-parse HEAD^1 2>/dev/null || echo "") if [ -n "$PREV_COMMIT" ]; then echo "$PREV_COMMIT" > ".ots/prev-commit.txt" fi echo "[ots] Proof generated: ${COMMIT_HASH:0:8}" ``` #### `hooks/pre-commit` Inline the entire `backfill-proofs.sh` logic: ```bash #!/bin/bash # Self-contained pre-commit backfill hook set -e # Inline: cache functions get_cached_status() { ... } cache_status() { ... } # Inline: main loop COMMITS=$(git rev-list --reverse HEAD) for COMMIT in $COMMITS; do PROOF_FILE=".ots/${COMMIT}.ots" if [ -f "$PROOF_FILE" ]; then # Check cache, skip if attested # Upgrade if pending and cache expired else # Generate proof inline fi done ``` ### Phase 2: Simplify Installer #### `hooks/install.sh` ```bash #!/bin/bash # Simple installer - just copies hooks REPO_PATH="${1:-.}" HOOKS_DIR="$(cd "$REPO_PATH" && git rev-parse --git-dir)/hooks" echo "Installing OTS hooks to: $HOOKS_DIR" cp "$(dirname "$0")/post-commit" "$HOOKS_DIR/post-commit" cp "$(dirname "$0")/pre-commit" "$HOOKS_DIR/pre-commit" chmod +x "$HOOKS_DIR/post-commit" "$HOOKS_DIR/pre-commit" echo "✓ Hooks installed" ``` ### Phase 3: Migration Path 1. **Keep current scripts** in `scripts/` for backward compatibility 2. **Add new `hooks/`** directory with unified hooks 3. **Update SKILL.md** to recommend new hooks 4. **Deprecate old scripts** (add deprecation warnings) 5. **Eventually remove** old scripts in next major version ## Benefits | Aspect | Before | After | |--------|--------|-------| | Files to install | 6 scripts | 2 hooks + installer | | External dependencies | Yes (scripts in root) | No (self-contained) | | Manual installation | Complex (path resolution) | Simple (copy 2 files) | | Debugging | Hard (multiple files) | Easy (single file per hook) | | Portability | Low (path-dependent) | High (drop-in) | ## Trade-offs **Pros:** - Simpler installation - No path resolution logic - Easier to understand (single file = single responsibility) - Better for manual installation **Cons:** - Code duplication (generate-proof logic in both hooks) - Larger hook files (~200-300 lines each) - Harder to update (must update multiple files) ## Mitigation - Extract shared functions into a sourced library: `hooks/.ots-lib.sh` - Hooks source the library: `source "$(dirname "$0")/.ots-lib.sh"` - Library is installed alongside hooks ## Revised Architecture (with Library) ``` hooks/ ├── .ots-lib.sh # Shared functions (generate_proof, check_attested, etc.) ├── post-commit # Sources library, calls generate_proof() ├── pre-commit # Sources library, calls backfill_history() └── install.sh # Copies all files ``` ## Next Steps 1. [ ] Create `hooks/.ots-lib.sh` with extracted functions 2. [ ] Create `hooks/post-commit` using library 3. [ ] Create `hooks/pre-commit` using library 4. [ ] Create `hooks/install.sh` 5. [ ] Test on git-timestamps-test repo 6. [ ] Update documentation 7. [ ] Deprecate old `scripts/` directory ## Timeline - Phase 1 (Library + Hooks): 1-2 hours - Phase 2 (Testing): 30 min - Phase 3 (Documentation): 30 min - **Total**: ~3 hours --- **Branch**: `git-scripts` **Created**: 2026-03-07 **Status**: ✅ Complete ## Implementation Complete Created self-contained hooks without shared library: ``` hooks/ ├── post-commit # 2.8KB - Full proof generation inline ├── pre-commit # 4.3KB - Full backfill logic inline └── install.sh # 1.3KB - Simple copier ``` **Test results:** - Commit time: ~14s (11 commits, cached status) - All proofs generated/upgraded correctly - No external script dependencies - Single-file installation **Next:** Copy to skill directory and update documentation.