diff --git a/.gitignore b/.gitignore deleted file mode 100644 index a8e2c1a..0000000 --- a/.gitignore +++ /dev/null @@ -1 +0,0 @@ -.ots/.attestation-cache diff --git a/.ots/.attestation-cache b/.ots/.attestation-cache index 43d2019..aa496dc 100644 --- a/.ots/.attestation-cache +++ b/.ots/.attestation-cache @@ -15,72 +15,3 @@ c0685dabfb48360a3abc103b75357f94e9f054b2:pending:1772897691 810d26b7af9c5d306e77fec290d360c7ac876b2e:pending:1772897694 3b54e0cb8c611d3f3525ad2386368f60200891f1:pending:1772897698 ed2cd259e918344c5a21ecf884b3178b4256ea74:pending:1772897704 -392ee723c3cf626d0e5281aa94771d7133bb345e:pending:1772897724 -db6f29e01a33d8ed8f127ff169d9f91d55e8a229:pending:1772897725 -4a6f5ed0c12315b0bc8a0fa5815ada1bd20e5963:pending:1772897726 -46aded7b9582bbed673843e2cf8a3f8fa742ad91:pending:1772897727 -c0685dabfb48360a3abc103b75357f94e9f054b2:pending:1772897728 -810d26b7af9c5d306e77fec290d360c7ac876b2e:pending:1772897728 -3b54e0cb8c611d3f3525ad2386368f60200891f1:pending:1772897729 -ed2cd259e918344c5a21ecf884b3178b4256ea74:pending:1772897730 -f4eb0ad6782d2bc003206521cc66ea370dcccd9f:pending:1772897732 -392ee723c3cf626d0e5281aa94771d7133bb345e:pending:1772900099 -db6f29e01a33d8ed8f127ff169d9f91d55e8a229:pending:1772900100 -4a6f5ed0c12315b0bc8a0fa5815ada1bd20e5963:pending:1772900100 -46aded7b9582bbed673843e2cf8a3f8fa742ad91:pending:1772900101 -c0685dabfb48360a3abc103b75357f94e9f054b2:pending:1772900102 -810d26b7af9c5d306e77fec290d360c7ac876b2e:pending:1772900103 -3b54e0cb8c611d3f3525ad2386368f60200891f1:pending:1772900104 -ed2cd259e918344c5a21ecf884b3178b4256ea74:pending:1772900105 -f4eb0ad6782d2bc003206521cc66ea370dcccd9f:pending:1772900106 -4bf5ab21764bc9a4507e25e0bc8de2989d4febad:pending:1772900109 -392ee723c3cf626d0e5281aa94771d7133bb345e:pending:1772900246 -db6f29e01a33d8ed8f127ff169d9f91d55e8a229:pending:1772900247 -4a6f5ed0c12315b0bc8a0fa5815ada1bd20e5963:pending:1772900248 -46aded7b9582bbed673843e2cf8a3f8fa742ad91:pending:1772900248 -c0685dabfb48360a3abc103b75357f94e9f054b2:pending:1772900249 -810d26b7af9c5d306e77fec290d360c7ac876b2e:pending:1772900250 -3b54e0cb8c611d3f3525ad2386368f60200891f1:pending:1772900251 -ed2cd259e918344c5a21ecf884b3178b4256ea74:pending:1772900252 -f4eb0ad6782d2bc003206521cc66ea370dcccd9f:pending:1772900253 -4bf5ab21764bc9a4507e25e0bc8de2989d4febad:pending:1772900254 -e2d0ff03529b0a34146dbd97c3ebbb2b2f6d1faa:pending:1772900256 -392ee723c3cf626d0e5281aa94771d7133bb345e:pending:1772900273 -db6f29e01a33d8ed8f127ff169d9f91d55e8a229:pending:1772900274 -4a6f5ed0c12315b0bc8a0fa5815ada1bd20e5963:pending:1772900275 -46aded7b9582bbed673843e2cf8a3f8fa742ad91:pending:1772900276 -c0685dabfb48360a3abc103b75357f94e9f054b2:pending:1772900277 -810d26b7af9c5d306e77fec290d360c7ac876b2e:pending:1772900278 -3b54e0cb8c611d3f3525ad2386368f60200891f1:pending:1772900279 -ed2cd259e918344c5a21ecf884b3178b4256ea74:pending:1772900279 -f4eb0ad6782d2bc003206521cc66ea370dcccd9f:pending:1772900280 -4bf5ab21764bc9a4507e25e0bc8de2989d4febad:pending:1772900281 -e2d0ff03529b0a34146dbd97c3ebbb2b2f6d1faa:pending:1772900282 -a7c0f825be4491ecec199ca7b983ee46525853e5:pending:1772900283 -392ee723c3cf626d0e5281aa94771d7133bb345e:pending:1772925243 -db6f29e01a33d8ed8f127ff169d9f91d55e8a229:pending:1772925244 -4a6f5ed0c12315b0bc8a0fa5815ada1bd20e5963:pending:1772925245 -46aded7b9582bbed673843e2cf8a3f8fa742ad91:pending:1772925245 -c0685dabfb48360a3abc103b75357f94e9f054b2:pending:1772925246 -810d26b7af9c5d306e77fec290d360c7ac876b2e:pending:1772925247 -3b54e0cb8c611d3f3525ad2386368f60200891f1:pending:1772925248 -ed2cd259e918344c5a21ecf884b3178b4256ea74:pending:1772925249 -f4eb0ad6782d2bc003206521cc66ea370dcccd9f:pending:1772925250 -4bf5ab21764bc9a4507e25e0bc8de2989d4febad:pending:1772925251 -e2d0ff03529b0a34146dbd97c3ebbb2b2f6d1faa:pending:1772925251 -a7c0f825be4491ecec199ca7b983ee46525853e5:pending:1772925252 -02143e59edb79ecf121c99f4518ad232625f5df6:pending:1772925253 -392ee723c3cf626d0e5281aa94771d7133bb345e:pending:1772926605 -db6f29e01a33d8ed8f127ff169d9f91d55e8a229:pending:1772926606 -4a6f5ed0c12315b0bc8a0fa5815ada1bd20e5963:pending:1772926607 -46aded7b9582bbed673843e2cf8a3f8fa742ad91:pending:1772926608 -c0685dabfb48360a3abc103b75357f94e9f054b2:pending:1772926608 -810d26b7af9c5d306e77fec290d360c7ac876b2e:pending:1772926609 -3b54e0cb8c611d3f3525ad2386368f60200891f1:pending:1772926610 -ed2cd259e918344c5a21ecf884b3178b4256ea74:pending:1772926611 -f4eb0ad6782d2bc003206521cc66ea370dcccd9f:pending:1772926612 -4bf5ab21764bc9a4507e25e0bc8de2989d4febad:pending:1772926613 -e2d0ff03529b0a34146dbd97c3ebbb2b2f6d1faa:pending:1772926614 -a7c0f825be4491ecec199ca7b983ee46525853e5:pending:1772926614 -02143e59edb79ecf121c99f4518ad232625f5df6:pending:1772926615 -094cd5386431eb9d1fe1335c591452ba0b66cb6e:pending:1772926616 diff --git a/.ots/02143e59edb79ecf121c99f4518ad232625f5df6.ots b/.ots/02143e59edb79ecf121c99f4518ad232625f5df6.ots deleted file mode 100644 index 9ed45da..0000000 Binary files a/.ots/02143e59edb79ecf121c99f4518ad232625f5df6.ots and /dev/null differ diff --git a/.ots/094cd5386431eb9d1fe1335c591452ba0b66cb6e.ots b/.ots/094cd5386431eb9d1fe1335c591452ba0b66cb6e.ots deleted file mode 100644 index d9ae0cc..0000000 Binary files a/.ots/094cd5386431eb9d1fe1335c591452ba0b66cb6e.ots and /dev/null differ diff --git a/.ots/4bf5ab21764bc9a4507e25e0bc8de2989d4febad.ots b/.ots/4bf5ab21764bc9a4507e25e0bc8de2989d4febad.ots deleted file mode 100644 index 7277f90..0000000 Binary files a/.ots/4bf5ab21764bc9a4507e25e0bc8de2989d4febad.ots and /dev/null differ diff --git a/.ots/6dc83992382d17c347a30c823204646d02750fc5.ots b/.ots/6dc83992382d17c347a30c823204646d02750fc5.ots deleted file mode 100644 index fb8e56e..0000000 Binary files a/.ots/6dc83992382d17c347a30c823204646d02750fc5.ots and /dev/null differ diff --git a/.ots/a7c0f825be4491ecec199ca7b983ee46525853e5.ots b/.ots/a7c0f825be4491ecec199ca7b983ee46525853e5.ots deleted file mode 100644 index 0289f66..0000000 Binary files a/.ots/a7c0f825be4491ecec199ca7b983ee46525853e5.ots and /dev/null differ diff --git a/.ots/commit-chain.txt b/.ots/commit-chain.txt index c171f72..5c48dc5 100644 --- a/.ots/commit-chain.txt +++ b/.ots/commit-chain.txt @@ -1,9 +1,25 @@ -094cd5386431eb9d1fe1335c591452ba0b66cb6e:02143e59edb79ecf121c99f4518ad232625f5df6 -02143e59edb79ecf121c99f4518ad232625f5df6:a7c0f825be4491ecec199ca7b983ee46525853e5 -a7c0f825be4491ecec199ca7b983ee46525853e5:e2d0ff03529b0a34146dbd97c3ebbb2b2f6d1faa -e2d0ff03529b0a34146dbd97c3ebbb2b2f6d1faa:4bf5ab21764bc9a4507e25e0bc8de2989d4febad -4bf5ab21764bc9a4507e25e0bc8de2989d4febad:f4eb0ad6782d2bc003206521cc66ea370dcccd9f -f4eb0ad6782d2bc003206521cc66ea370dcccd9f:ed2cd259e918344c5a21ecf884b3178b4256ea74 +46aded7b9582bbed673843e2cf8a3f8fa742ad91:4a6f5ed0c12315b0bc8a0fa5815ada1bd20e5963 +4a6f5ed0c12315b0bc8a0fa5815ada1bd20e5963:db6f29e01a33d8ed8f127ff169d9f91d55e8a229 +db6f29e01a33d8ed8f127ff169d9f91d55e8a229:392ee723c3cf626d0e5281aa94771d7133bb345e +392ee723c3cf626d0e5281aa94771d7133bb345e:392ee723c3cf626d0e5281aa94771d7133bb345e^1 +c0685dabfb48360a3abc103b75357f94e9f054b2:46aded7b9582bbed673843e2cf8a3f8fa742ad91 +46aded7b9582bbed673843e2cf8a3f8fa742ad91:4a6f5ed0c12315b0bc8a0fa5815ada1bd20e5963 +4a6f5ed0c12315b0bc8a0fa5815ada1bd20e5963:db6f29e01a33d8ed8f127ff169d9f91d55e8a229 +db6f29e01a33d8ed8f127ff169d9f91d55e8a229:392ee723c3cf626d0e5281aa94771d7133bb345e +392ee723c3cf626d0e5281aa94771d7133bb345e:392ee723c3cf626d0e5281aa94771d7133bb345e^1 +810d26b7af9c5d306e77fec290d360c7ac876b2e:c0685dabfb48360a3abc103b75357f94e9f054b2 +c0685dabfb48360a3abc103b75357f94e9f054b2:46aded7b9582bbed673843e2cf8a3f8fa742ad91 +46aded7b9582bbed673843e2cf8a3f8fa742ad91:4a6f5ed0c12315b0bc8a0fa5815ada1bd20e5963 +4a6f5ed0c12315b0bc8a0fa5815ada1bd20e5963:db6f29e01a33d8ed8f127ff169d9f91d55e8a229 +db6f29e01a33d8ed8f127ff169d9f91d55e8a229:392ee723c3cf626d0e5281aa94771d7133bb345e +392ee723c3cf626d0e5281aa94771d7133bb345e:392ee723c3cf626d0e5281aa94771d7133bb345e^1 +3b54e0cb8c611d3f3525ad2386368f60200891f1:810d26b7af9c5d306e77fec290d360c7ac876b2e +810d26b7af9c5d306e77fec290d360c7ac876b2e:c0685dabfb48360a3abc103b75357f94e9f054b2 +c0685dabfb48360a3abc103b75357f94e9f054b2:46aded7b9582bbed673843e2cf8a3f8fa742ad91 +46aded7b9582bbed673843e2cf8a3f8fa742ad91:4a6f5ed0c12315b0bc8a0fa5815ada1bd20e5963 +4a6f5ed0c12315b0bc8a0fa5815ada1bd20e5963:db6f29e01a33d8ed8f127ff169d9f91d55e8a229 +db6f29e01a33d8ed8f127ff169d9f91d55e8a229:392ee723c3cf626d0e5281aa94771d7133bb345e +392ee723c3cf626d0e5281aa94771d7133bb345e:392ee723c3cf626d0e5281aa94771d7133bb345e^1 ed2cd259e918344c5a21ecf884b3178b4256ea74:3b54e0cb8c611d3f3525ad2386368f60200891f1 3b54e0cb8c611d3f3525ad2386368f60200891f1:810d26b7af9c5d306e77fec290d360c7ac876b2e 810d26b7af9c5d306e77fec290d360c7ac876b2e:c0685dabfb48360a3abc103b75357f94e9f054b2 diff --git a/.ots/e2d0ff03529b0a34146dbd97c3ebbb2b2f6d1faa.ots b/.ots/e2d0ff03529b0a34146dbd97c3ebbb2b2f6d1faa.ots deleted file mode 100644 index 57a6104..0000000 Binary files a/.ots/e2d0ff03529b0a34146dbd97c3ebbb2b2f6d1faa.ots and /dev/null differ diff --git a/.ots/f4eb0ad6782d2bc003206521cc66ea370dcccd9f.ots b/.ots/f4eb0ad6782d2bc003206521cc66ea370dcccd9f.ots deleted file mode 100644 index cebc5f6..0000000 Binary files a/.ots/f4eb0ad6782d2bc003206521cc66ea370dcccd9f.ots and /dev/null differ diff --git a/.ots/prev-commit.txt b/.ots/prev-commit.txt index c772ba4..abca7dd 100644 --- a/.ots/prev-commit.txt +++ b/.ots/prev-commit.txt @@ -1 +1 @@ -094cd5386431eb9d1fe1335c591452ba0b66cb6e +ed2cd259e918344c5a21ecf884b3178b4256ea74 diff --git a/.ots/proof.ots b/.ots/proof.ots index fb8e56e..4da399d 100644 Binary files a/.ots/proof.ots and b/.ots/proof.ots differ diff --git a/UNIFICATION_PLAN.md b/UNIFICATION_PLAN.md deleted file mode 100644 index 7d35598..0000000 --- a/UNIFICATION_PLAN.md +++ /dev/null @@ -1,208 +0,0 @@ -# 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. diff --git a/hooks/install.sh b/hooks/install.sh deleted file mode 100755 index 3de1a6e..0000000 --- a/hooks/install.sh +++ /dev/null @@ -1,93 +0,0 @@ -#!/bin/bash -# Git OpenTimestamp Hooks Installer -# Detects available tools and installs matching hooks - -set -e - -REPO_PATH="${1:-.}" -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" - -cd "$REPO_PATH" - -if ! git rev-parse --git-dir > /dev/null 2>&1; then - echo "Error: not a git repository" >&2 - exit 1 -fi - -HOOKS_DIR="$(git rev-parse --git-dir)/hooks" -MODE="" - -# Detect available tools -if command -v ots &> /dev/null; then - MODE="ots" - echo "Detected: ots CLI" -elif command -v node &> /dev/null && node -e "require('@opentimestamps/ots')" &> /dev/null 2>&1; then - MODE="node" - echo "Detected: @opentimestamps/ots (Node.js)" - echo "Note: Node version creates local proofs only (no calendar submission)" - echo "" - - # Install node package locally if not already present - if [ ! -d "node_modules/@opentimestamps" ]; then - echo "Installing @opentimestamps/ots locally..." - npm install @opentimestamps/ots - echo "✓ Package installed" - fi -else - echo "Error: Neither ots CLI nor @opentimestamps/ots found" >&2 - echo "Install one of:" >&2 - echo " pipx install opentimestamps-client (recommended)" >&2 - echo " npm install @opentimestamps/ots (local proofs only)" >&2 - exit 1 -fi - -echo "" -echo "Installing $MODE hooks to: $HOOKS_DIR" - -# Copy appropriate hooks -if [ "$MODE" = "ots" ]; then - cp "$SCRIPT_DIR/post-commit-ots" "$HOOKS_DIR/post-commit" - cp "$SCRIPT_DIR/pre-commit-ots" "$HOOKS_DIR/pre-commit" -else - cp "$SCRIPT_DIR/post-commit-node" "$HOOKS_DIR/post-commit" - cp "$SCRIPT_DIR/pre-commit-node" "$HOOKS_DIR/pre-commit" -fi - -chmod +x "$HOOKS_DIR/post-commit" "$HOOKS_DIR/pre-commit" - -echo "✓ Post-commit hook installed" -echo "✓ Pre-commit backfill hook installed" - -# Setup .gitignore -GITIGNORE=".gitignore" -if [ ! -f "$GITIGNORE" ]; then - cat > "$GITIGNORE" << 'EOF' -.ots/.attestation-cache -node_modules/ -EOF - echo "✓ Created .gitignore" -elif ! grep -q ".ots/.attestation-cache" "$GITIGNORE"; then - echo ".ots/.attestation-cache" >> "$GITIGNORE" - if [ "$MODE" = "node" ] && ! grep -q "node_modules/" "$GITIGNORE"; then - echo "node_modules/" >> "$GITIGNORE" - fi - echo "✓ Updated .gitignore" -fi - -echo "" -echo "Mode: $MODE" -if [ "$MODE" = "ots" ]; then - echo " - Full Bitcoin attestation via calendars" - echo " - Proofs submitted to remote calendars" -else - echo " - Local proofs only (no calendar submission)" - echo " - For full attestation, use: pipx install opentimestamps-client" -fi - -echo "" -echo "Next steps:" -echo "1. Make a test commit" -echo "2. Commit proofs: git add .ots/ && git commit -m 'Add OpenTimestamp proofs'" -echo "" -echo "To uninstall:" -echo " rm $HOOKS_DIR/post-commit $HOOKS_DIR/pre-commit" diff --git a/hooks/post-commit b/hooks/post-commit deleted file mode 100755 index 044dfe3..0000000 --- a/hooks/post-commit +++ /dev/null @@ -1,91 +0,0 @@ -#!/bin/bash -# Git OpenTimestamp Post-Commit Hook -# Self-contained - no external dependencies -# Generates cryptographic proof for each commit using OpenTimestamp - -set -e - -# Configuration -OUTPUT_DIR=".ots" -OUTPUT_FILE="$OUTPUT_DIR/proof.ots" - -# Ensure output directory exists -mkdir -p "$OUTPUT_DIR" - -# Get the current commit hash -COMMIT_HASH=$(git rev-parse HEAD) - -# Function to generate proof using ots CLI -generate_with_ots_cli() { - local hash="$1" - local output="$2" - - # Create a temporary file with the hash (convert hex to binary) - local temp_file=$(mktemp) - local temp_ots="${temp_file}.ots" - - # Use python3 for hex to binary conversion (more portable than xxd) - python3 -c "import sys; sys.stdout.buffer.write(bytes.fromhex('$hash'))" > "$temp_file" - - # Generate timestamp - ots creates .ots file alongside the original - ots stamp "$temp_file" 2>/dev/null - - # Move the generated .ots file to the desired location - if [ -f "$temp_ots" ]; then - mv "$temp_ots" "$output" - rm -f "$temp_file" - return 0 - else - rm -f "$temp_file" - return 1 - fi -} - -# Function to generate proof using nodejs fallback -generate_with_node() { - local hash="$1" - local output="$2" - - node -e " -const ots = require('@opentimestamps/ots'); -const fs = require('fs'); -const hash = '$hash'; -const output = '$output'; -const hashBuffer = Buffer.from(hash, 'hex'); -ots.Timestamp.hash(hashBuffer).then(timestamp => { - const proof = { hash: hash, timestamp: new Date().toISOString(), status: 'pending' }; - fs.writeFileSync(output, JSON.stringify(proof, null, 2)); - console.log('Generated local proof (nodejs fallback)'); -}).catch(err => { console.error('Error:', err); process.exit(1); }); -" -} - -# Check for available tools and generate proof -if command -v ots &> /dev/null; then - if generate_with_ots_cli "$COMMIT_HASH" "$OUTPUT_FILE"; then - echo "[ots] Generated proof with ots CLI: ${COMMIT_HASH:0:8}" - else - echo "[ots] Warning: ots CLI failed" >&2 - exit 0 - fi -elif command -v node &> /dev/null && node -e "require('@opentimestamps/ots')" &> /dev/null 2>&1; then - generate_with_node "$COMMIT_HASH" "$OUTPUT_FILE" - echo "[ots] Generated proof with nodejs fallback: ${COMMIT_HASH:0:8}" -else - echo "[ots] Warning: Neither ots CLI nor @opentimestamps/ots found, skipping proof" >&2 - exit 0 -fi - -# Save previous commit hash for chaining -PREV_COMMIT=$(git rev-parse HEAD^1 2>/dev/null || echo "") -if [ -n "$PREV_COMMIT" ]; then - echo "$PREV_COMMIT" > "$OUTPUT_DIR/prev-commit.txt" -fi - -# Create individual proof file for this commit -INDIVIDUAL_PROOF="$OUTPUT_DIR/${COMMIT_HASH}.ots" -if [ -f "$OUTPUT_FILE" ]; then - cp "$OUTPUT_FILE" "$INDIVIDUAL_PROOF" -fi - -echo "[ots] Proof generated successfully" diff --git a/hooks/post-commit-node b/hooks/post-commit-node deleted file mode 100755 index 06bb92b..0000000 --- a/hooks/post-commit-node +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/bash -# Git OpenTimestamp Post-Commit Hook (Node.js version) -# Requires: @opentimestamps/ots (npm install) - -set -e - -OUTPUT_DIR=".ots" -OUTPUT_FILE="$OUTPUT_DIR/proof.ots" - -mkdir -p "$OUTPUT_DIR" - -COMMIT_HASH=$(git rev-parse HEAD) - -# Generate proof using Node.js -node -e " -const ots = require('@opentimestamps/ots'); -const fs = require('fs'); -const hash = '$COMMIT_HASH'; -const output = '$OUTPUT_FILE'; -const hashBuffer = Buffer.from(hash, 'hex'); - -ots.Timestamp.hash(hashBuffer).then(timestamp => { - // Note: This creates a local proof only, not submitted to calendars - // For full Bitcoin attestation, use the ots CLI version - const proof = { - hash: hash, - timestamp: new Date().toISOString(), - status: 'pending', - note: 'Local proof only - use ots CLI for calendar submission' - }; - fs.writeFileSync(output, JSON.stringify(proof, null, 2)); - console.log('[ots-node] Generated local proof: ' + hash.substring(0, 8)); -}).catch(err => { - console.error('[ots-node] Error:', err.message); - process.exit(1); -}); -" - -# Save previous commit for chaining -PREV_COMMIT=$(git rev-parse HEAD^1 2>/dev/null || echo "") -if [ -n "$PREV_COMMIT" ]; then - echo "$PREV_COMMIT" > "$OUTPUT_DIR/prev-commit.txt" -fi - -# Create individual proof file (JSON format for node version) -INDIVIDUAL_PROOF="$OUTPUT_DIR/${COMMIT_HASH}.ots" -cp "$OUTPUT_FILE" "$INDIVIDUAL_PROOF" - -echo "[ots-node] Proof generated successfully" diff --git a/hooks/post-commit-ots b/hooks/post-commit-ots deleted file mode 100755 index 776cc89..0000000 --- a/hooks/post-commit-ots +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/bash -# Git OpenTimestamp Post-Commit Hook (ots CLI version) -# Requires: opentimestamps-client (pipx install opentimestamps-client) - -set -e - -OUTPUT_DIR=".ots" -OUTPUT_FILE="$OUTPUT_DIR/proof.ots" - -mkdir -p "$OUTPUT_DIR" - -COMMIT_HASH=$(git rev-parse HEAD) - -# Generate proof using 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" 2>/dev/null - -if [ -f "$temp_ots" ]; then - mv "$temp_ots" "$OUTPUT_FILE" - rm -f "$temp_file" - echo "[ots] Generated proof: ${COMMIT_HASH:0:8}" -else - rm -f "$temp_file" - echo "[ots] Warning: Failed to generate proof" >&2 - exit 0 -fi - -# Save previous commit for chaining -PREV_COMMIT=$(git rev-parse HEAD^1 2>/dev/null || echo "") -if [ -n "$PREV_COMMIT" ]; then - echo "$PREV_COMMIT" > "$OUTPUT_DIR/prev-commit.txt" -fi - -# Create individual proof file -INDIVIDUAL_PROOF="$OUTPUT_DIR/${COMMIT_HASH}.ots" -cp "$OUTPUT_FILE" "$INDIVIDUAL_PROOF" - -echo "[ots] Proof generated successfully" diff --git a/hooks/pre-commit b/hooks/pre-commit deleted file mode 100755 index 9337782..0000000 --- a/hooks/pre-commit +++ /dev/null @@ -1,156 +0,0 @@ -#!/bin/bash -# Git OpenTimestamp Pre-Commit Backfill Hook -# Self-contained - no external dependencies -# Upgrades all historical proofs before each new commit - -set -e - -# Configuration -OUTPUT_DIR=".ots" -STATUS_CACHE="$OUTPUT_DIR/.attestation-cache" - -# Ensure output directory exists -mkdir -p "$OUTPUT_DIR" - -# Initialize cache file if it doesn't exist -if [ ! -f "$STATUS_CACHE" ]; then - echo "# Attestation status cache" > "$STATUS_CACHE" - echo "# Format: commit-hash:status:timestamp" >> "$STATUS_CACHE" -fi - -# Function to get cached status -get_cached_status() { - local commit="$1" - local cache_line=$(grep "^$commit:" "$STATUS_CACHE" 2>/dev/null | tail -1) - if [ -n "$cache_line" ]; then - local status=$(echo "$cache_line" | cut -d: -f2) - local timestamp=$(echo "$cache_line" | cut -d: -f3) - local now=$(date +%s) - local age=$((now - timestamp)) - # Cache valid for 1 hour (3600 seconds) - if [ "$age" -lt 3600 ]; then - echo "$status" - return 0 - fi - fi - return 1 -} - -# Function to cache status -cache_status() { - local commit="$1" - local status="$2" - local now=$(date +%s) - echo "$commit:$status:$now" >> "$STATUS_CACHE" -} - -# Function to generate proof using ots CLI -generate_proof() { - local hash="$1" - local output="$2" - - local temp_file=$(mktemp) - local temp_ots="${temp_file}.ots" - - python3 -c "import sys; sys.stdout.buffer.write(bytes.fromhex('$hash'))" > "$temp_file" - ots stamp "$temp_file" 2>/dev/null - - if [ -f "$temp_ots" ]; then - mv "$temp_ots" "$output" - rm -f "$temp_file" - return 0 - else - rm -f "$temp_file" - return 1 - fi -} - -# Function to check if proof is attested -is_attested() { - local proof_file="$1" - local pending_count=$(ots info "$proof_file" 2>&1 | grep -c "PendingAttestation" || echo "0") - [ "$pending_count" -eq 0 ] -} - -# Function to upgrade proof -upgrade_proof() { - local proof_file="$1" - ots upgrade "$proof_file" 2>/dev/null -} - -echo "[ots] Backfilling proofs..." - -# Get all commit hashes (oldest to newest) -COMMITS=$(git rev-list --reverse HEAD) -TOTAL=$(echo "$COMMITS" | wc -l) -CURRENT=0 -UPDATED=0 - -for COMMIT in $COMMITS; do - CURRENT=$((CURRENT + 1)) - PROOF_FILE="$OUTPUT_DIR/${COMMIT}.ots" - - # Skip verbose output for brevity - if [ $CURRENT -le 3 ] || [ $CURRENT -eq $TOTAL ]; then - echo "[ots] Processing commit $CURRENT/$TOTAL: ${COMMIT:0:8}" - elif [ $CURRENT -eq 4 ]; then - echo "[ots] ... processing remaining commits ..." - fi - - if [ -f "$PROOF_FILE" ]; then - # Check cached status first - CACHED_STATUS=$(get_cached_status "$COMMIT" || echo "") - - if [ "$CACHED_STATUS" = "attested" ]; then - continue - fi - - # Check if already attested - if is_attested "$PROOF_FILE"; then - cache_status "$COMMIT" "attested" - continue - fi - - # Cache as pending - cache_status "$COMMIT" "pending" - - # Skip upgrade if cache is fresh (< 10 min old) - CACHE_LINE=$(grep "^$COMMIT:" "$STATUS_CACHE" | tail -1) - CACHE_TIME=$(echo "$CACHE_LINE" | cut -d: -f3) - NOW=$(date +%s) - CACHE_AGE=$((NOW - CACHE_TIME)) - - if [ "$CACHE_AGE" -lt 600 ]; then - continue - fi - - # Try to upgrade - if upgrade_proof "$PROOF_FILE"; then - cache_status "$COMMIT" "attested" - UPDATED=$((UPDATED + 1)) - fi - else - # Generate new proof - if generate_proof "$COMMIT" "$PROOF_FILE"; then - cache_status "$COMMIT" "pending" - UPDATED=$((UPDATED + 1)) - fi - fi -done - -# Update latest proof symlink -LATEST_COMMIT=$(git rev-parse HEAD) -if [ -f "$OUTPUT_DIR/${LATEST_COMMIT}.ots" ]; then - cp "$OUTPUT_DIR/${LATEST_COMMIT}.ots" "$OUTPUT_DIR/proof.ots" -fi - -# Save commit chain -rm -f "$OUTPUT_DIR/commit-chain.txt" -git rev-list HEAD | while read COMMIT; do - PREV=$(git rev-parse ${COMMIT}^1 2>/dev/null || echo "") - if [ -n "$PREV" ]; then - echo "$COMMIT:$PREV" >> "$OUTPUT_DIR/commit-chain.txt" - fi -done - -echo "[ots] Backfill complete: $UPDATED proofs updated" diff --git a/hooks/pre-commit-node b/hooks/pre-commit-node deleted file mode 100755 index 76d033e..0000000 --- a/hooks/pre-commit-node +++ /dev/null @@ -1,100 +0,0 @@ -#!/bin/bash -# Git OpenTimestamp Pre-Commit Backfill Hook (Node.js version) -# Requires: @opentimestamps/ots (npm install) -# Note: Node version only generates local proofs, no calendar submission - -set -e - -OUTPUT_DIR=".ots" -STATUS_CACHE="$OUTPUT_DIR/.attestation-cache" - -mkdir -p "$OUTPUT_DIR" - -# Initialize cache -if [ ! -f "$STATUS_CACHE" ]; then - echo "# Format: commit-hash:status:timestamp" > "$STATUS_CACHE" -fi - -get_cached_status() { - local commit="$1" - local cache_line=$(grep "^$commit:" "$STATUS_CACHE" 2>/dev/null | tail -1) - if [ -n "$cache_line" ]; then - local status=$(echo "$cache_line" | cut -d: -f2) - local timestamp=$(echo "$cache_line" | cut -d: -f3) - local now=$(date +%s) - if [ "$((now - timestamp))" -lt 3600 ]; then - echo "$status" - return 0 - fi - fi - return 1 -} - -cache_status() { - local commit="$1" - local status="$2" - echo "$commit:$status:$(date +%s)" >> "$STATUS_CACHE" -} - -generate_proof_node() { - local hash="$1" - local output="$2" - - node -e " -const ots = require('@opentimestamps/ots'); -const fs = require('fs'); -const hash = '$hash'; -const output = '$output'; -const hashBuffer = Buffer.from(hash, 'hex'); - -ots.Timestamp.hash(hashBuffer).then(timestamp => { - const proof = { hash: hash, timestamp: new Date().toISOString(), status: 'pending' }; - fs.writeFileSync(output, JSON.stringify(proof, null, 2)); -}).catch(err => { console.error('Error:', err); process.exit(1); }); -" -} - -echo "[ots-node] Backfilling proofs (local only, no calendar)..." - -COMMITS=$(git rev-list --reverse HEAD) -TOTAL=$(echo "$COMMITS" | wc -l) -CURRENT=0 -UPDATED=0 - -for COMMIT in $COMMITS; do - CURRENT=$((CURRENT + 1)) - PROOF_FILE="$OUTPUT_DIR/${COMMIT}.ots" - - if [ $CURRENT -le 3 ] || [ $CURRENT -eq $TOTAL ]; then - echo "[ots-node] Processing $CURRENT/$TOTAL: ${COMMIT:0:8}" - elif [ $CURRENT -eq 4 ]; then - echo "[ots-node] ... processing remaining ..." - fi - - if [ -f "$PROOF_FILE" ]; then - # Node version doesn't support upgrade, just check cache - CACHED_STATUS=$(get_cached_status "$COMMIT" || echo "") - [ "$CACHED_STATUS" = "attested" ] && continue - - # Mark as pending (node can't attest) - cache_status "$COMMIT" "pending" - else - if generate_proof_node "$COMMIT" "$PROOF_FILE"; then - cache_status "$COMMIT" "pending" - UPDATED=$((UPDATED + 1)) - fi - fi -done - -# Update latest proof -LATEST_COMMIT=$(git rev-parse HEAD) -[ -f "$OUTPUT_DIR/${LATEST_COMMIT}.ots" ] && cp "$OUTPUT_DIR/${LATEST_COMMIT}.ots" "$OUTPUT_DIR/proof.ots" - -# Save commit chain -rm -f "$OUTPUT_DIR/commit-chain.txt" -git rev-list HEAD | while read COMMIT; do - PREV=$(git rev-parse ${COMMIT}^1 2>/dev/null || echo "") - [ -n "$PREV" ] && echo "$COMMIT:$PREV" >> "$OUTPUT_DIR/commit-chain.txt" -done - -echo "[ots-node] Backfill complete: $UPDATED generated (local proofs only)" diff --git a/hooks/pre-commit-ots b/hooks/pre-commit-ots deleted file mode 100755 index 65d354d..0000000 --- a/hooks/pre-commit-ots +++ /dev/null @@ -1,125 +0,0 @@ -#!/bin/bash -# Git OpenTimestamp Pre-Commit Backfill Hook (ots CLI version) -# Requires: opentimestamps-client (pipx install opentimestamps-client) - -set -e - -OUTPUT_DIR=".ots" -STATUS_CACHE="$OUTPUT_DIR/.attestation-cache" - -mkdir -p "$OUTPUT_DIR" - -# Initialize cache -if [ ! -f "$STATUS_CACHE" ]; then - echo "# Format: commit-hash:status:timestamp" > "$STATUS_CACHE" -fi - -get_cached_status() { - local commit="$1" - local cache_line=$(grep "^$commit:" "$STATUS_CACHE" 2>/dev/null | tail -1) - if [ -n "$cache_line" ]; then - local status=$(echo "$cache_line" | cut -d: -f2) - local timestamp=$(echo "$cache_line" | cut -d: -f3) - local now=$(date +%s) - if [ "$((now - timestamp))" -lt 3600 ]; then - echo "$status" - return 0 - fi - fi - return 1 -} - -cache_status() { - local commit="$1" - local status="$2" - echo "$commit:$status:$(date +%s)" >> "$STATUS_CACHE" -} - -generate_proof() { - local hash="$1" - local output="$2" - local temp_file=$(mktemp) - local temp_ots="${temp_file}.ots" - - python3 -c "import sys; sys.stdout.buffer.write(bytes.fromhex('$hash'))" > "$temp_file" - ots stamp "$temp_file" 2>/dev/null - - if [ -f "$temp_ots" ]; then - mv "$temp_ots" "$output" - rm -f "$temp_file" - return 0 - fi - rm -f "$temp_file" - return 1 -} - -is_attested() { - local proof_file="$1" - local pending_count=$(ots info "$proof_file" 2>&1 | grep -c "PendingAttestation" || echo "0") - [ "$pending_count" -eq 0 ] -} - -upgrade_proof() { - local proof_file="$1" - ots upgrade "$proof_file" 2>/dev/null -} - -echo "[ots] Backfilling proofs..." - -COMMITS=$(git rev-list --reverse HEAD) -TOTAL=$(echo "$COMMITS" | wc -l) -CURRENT=0 -UPDATED=0 - -for COMMIT in $COMMITS; do - CURRENT=$((CURRENT + 1)) - PROOF_FILE="$OUTPUT_DIR/${COMMIT}.ots" - - if [ $CURRENT -le 3 ] || [ $CURRENT -eq $TOTAL ]; then - echo "[ots] Processing $CURRENT/$TOTAL: ${COMMIT:0:8}" - elif [ $CURRENT -eq 4 ]; then - echo "[ots] ... processing remaining ..." - fi - - if [ -f "$PROOF_FILE" ]; then - CACHED_STATUS=$(get_cached_status "$COMMIT" || echo "") - - [ "$CACHED_STATUS" = "attested" ] && continue - - if is_attested "$PROOF_FILE"; then - cache_status "$COMMIT" "attested" - continue - fi - - cache_status "$COMMIT" "pending" - - CACHE_LINE=$(grep "^$COMMIT:" "$STATUS_CACHE" | tail -1) - CACHE_TIME=$(echo "$CACHE_LINE" | cut -d: -f3) - CACHE_AGE=$(($(date +%s) - CACHE_TIME)) - - [ "$CACHE_AGE" -lt 600 ] && continue - - if upgrade_proof "$PROOF_FILE"; then - cache_status "$COMMIT" "attested" - UPDATED=$((UPDATED + 1)) - fi - else - if generate_proof "$COMMIT" "$PROOF_FILE"; then - cache_status "$COMMIT" "pending" - UPDATED=$((UPDATED + 1)) - fi - fi -done - -# Update latest proof -LATEST_COMMIT=$(git rev-parse HEAD) -[ -f "$OUTPUT_DIR/${LATEST_COMMIT}.ots" ] && cp "$OUTPUT_DIR/${LATEST_COMMIT}.ots" "$OUTPUT_DIR/proof.ots" - -# Save commit chain -rm -f "$OUTPUT_DIR/commit-chain.txt" -git rev-list HEAD | while read COMMIT; do - PREV=$(git rev-parse ${COMMIT}^1 2>/dev/null || echo "") - [ -n "$PREV" ] && echo "$COMMIT:$PREV" >> "$OUTPUT_DIR/commit-chain.txt" -done - -echo "[ots] Backfill complete: $UPDATED updated" diff --git a/test10.txt b/test10.txt deleted file mode 100644 index e6451d2..0000000 --- a/test10.txt +++ /dev/null @@ -1 +0,0 @@ -# Another test commit diff --git a/test11.txt b/test11.txt deleted file mode 100644 index 0ef48fe..0000000 --- a/test11.txt +++ /dev/null @@ -1 +0,0 @@ -# Test new ots-only hooks diff --git a/test12.txt b/test12.txt deleted file mode 100644 index 1af7b08..0000000 --- a/test12.txt +++ /dev/null @@ -1 +0,0 @@ -# Test renamed hooks diff --git a/test9.txt b/test9.txt deleted file mode 100644 index 10e6a35..0000000 --- a/test9.txt +++ /dev/null @@ -1 +0,0 @@ -# Test self-contained hooks