#!/bin/bash # Pre-commit hook for Foxhunt HFT system # Lightweight checks only — compilation is validated by agents before commit set -e echo "🔍 Running pre-commit quality checks..." echo "" # Check for common issues in staged files echo "🔎 Checking for common issues..." STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep "\.rs$" || true) if [ -n "$STAGED_FILES" ]; then # Check for unwrap() usage UNWRAP_FILES=$(echo "$STAGED_FILES" | xargs grep -l "\.unwrap()" 2>/dev/null || true) if [ -n "$UNWRAP_FILES" ]; then echo "⚠️ Warning: Found .unwrap() in staged files:" echo "$UNWRAP_FILES" | sed 's/^/ /' echo " Consider using ? operator or proper error handling" echo "" fi # Check for expect() with generic messages EXPECT_FILES=$(echo "$STAGED_FILES" | xargs grep -l "\.expect(\"\")" 2>/dev/null || true) if [ -n "$EXPECT_FILES" ]; then echo "⚠️ Warning: Found .expect() with empty message in:" echo "$EXPECT_FILES" | sed 's/^/ /' echo " Provide descriptive error messages" echo "" fi # Check for TODO/FIXME comments TODO_COUNT=$(echo "$STAGED_FILES" | xargs grep -c "TODO\|FIXME" 2>/dev/null | awk -F: '{sum+=$2} END {print sum}' || echo "0") if [ "$TODO_COUNT" -gt 0 ]; then echo "ℹ️ Info: Found $TODO_COUNT TODO/FIXME comments in staged files" echo "" fi # Check for stub patterns in src/ files SRC_FILES=$(echo "$STAGED_FILES" | grep "/src/" || true) if [ -n "$SRC_FILES" ]; then STUB_RETURNS=$(echo "$SRC_FILES" | xargs grep -n 'return 0\.0\b\|return 100\.0\|return 1\.0\b\|return vec!\[\]' 2>/dev/null | grep -v '// ok:' | grep -v '// legitimate' || true) if [ -n "$STUB_RETURNS" ]; then echo "⚠️ Warning: Possible stub return values in staged files:" echo "$STUB_RETURNS" | head -5 | sed 's/^/ /' echo " Add '// ok: ' comment to suppress if intentional" echo "" fi STUB_MARKERS=$(echo "$SRC_FILES" | xargs grep -n '"placeholder"\|"stub"\|"fake"\|"hardcoded"\|"dummy"' 2>/dev/null | grep -v '// ok:' || true) if [ -n "$STUB_MARKERS" ]; then echo "⚠️ Warning: Stub marker strings in production code:" echo "$STUB_MARKERS" | head -5 | sed 's/^/ /' echo "" fi fi fi # GPU hot-path leak detection echo "🔎 Checking for GPU→CPU leaks in hot paths..." SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" if [ -x "$SCRIPT_DIR/gpu-hotpath-guard.sh" ]; then if ! "$SCRIPT_DIR/gpu-hotpath-guard.sh" --staged; then echo "⛔ GPU hot-path leak detected — fix or suppress with // gpu-ok: " exit 1 fi echo " No GPU→CPU leaks in hot paths" echo "" fi # DQN v2 Invariant 7 enforcement: component-adding commits must update audit docs. check_audit_doc_updates() { local staged=$(git diff --cached --name-only) # Detect "component-adding" commits: new .rs or .cu files, or modifications to # files that define ISV slots (gpu_dqn_trainer.rs), kernels (cuda_pipeline/*.cu), # or state layout (state_layout.cuh). local component_changes=$(echo "$staged" | grep -E '(^crates/ml/src/(cuda_pipeline|trainers/dqn)/|^crates/ml/src/cuda_pipeline/state_layout\.cuh$)') if [ -z "$component_changes" ]; then return 0; fi local audit_docs_touched=$(echo "$staged" | grep -E '^docs/(dqn-wire-up-audit|isv-slots|dqn-gpu-hot-path-audit|dqn-named-dims|ml-supervised-to-dqn-concept-audit)\.md$') if [ -z "$audit_docs_touched" ]; then echo "❌ Invariant 7 violation: component changes without audit-doc update" echo " Changed components:" echo "$component_changes" | sed 's/^/ /' echo " You must update one of:" echo " docs/dqn-wire-up-audit.md" echo " docs/isv-slots.md" echo " docs/dqn-gpu-hot-path-audit.md" echo " docs/dqn-named-dims.md" echo " docs/ml-supervised-to-dqn-concept-audit.md" return 1 fi } # DQN v2 Invariant 9 enforcement: reject TODO/FIXME/XXX/HACK/TBD markers in added code. check_no_todo_fixme() { local added_lines=$(git diff --cached --diff-filter=AM -U0 -- '*.rs' '*.cu' '*.cuh' \ | grep -E '^\+' | grep -vE '^\+\+\+') local bad=$(echo "$added_lines" | grep -E '(TODO|FIXME|\bXXX\b|\bHACK\b|\bTBD\b|unimplemented!|todo!\()') if [ -n "$bad" ]; then echo "❌ Invariant 9 violation: deferred-work markers found in staged code" echo "$bad" | sed 's/^/ /' return 1 fi } # DQN v2 Invariant (spec §4.A.2): no ISV migration functions allowed. # The layout fingerprint is fail-fast only; no migration path exists. check_no_isv_migrations() { local bad=$(git diff --cached -U0 -- crates/ml/src/cuda_pipeline/gpu_dqn_trainer.rs \ crates/ml/src/trainers/dqn/trainer/ 2>/dev/null | \ grep -E '^\+.*fn\s+(migrate|upgrade)_isv' || true) if [ -n "$bad" ]; then echo "❌ Spec §4.A.2 violation: ISV migration functions are forbidden" echo " (layout fingerprint is fail-fast only; no migration path exists)" echo "$bad" | sed 's/^/ /' return 1 fi } check_audit_doc_updates || exit 1 check_no_todo_fixme || exit 1 check_no_isv_migrations || exit 1 echo "✅ All pre-commit checks passed!" echo "" echo "Summary:" echo " - Code quality checks: ✅" echo " - GPU hot-path guard: ✅" echo "" exit 0