#!/usr/bin/env bash # # D001 — runtime write-path guard. # # Proves the deployment invariant: after running a scan, `git status` shows # NO tracked file modified by the scan — every runtime write lands in a # gitignored location (data/, reports/, *.db). This is what makes `git pull` # conflict-free on a server where scans keep running. # # If this fails, a scan wrote into a git-tracked path and `git pull` on the # server can conflict. Investigate the printed files before deploying. # # Usage: # deploy/check_runtime_git.sh [--live] # --live additionally run a real scan first (requires log sources) and # then assert the tree is still clean. Without --live it only # verifies that whatever runtime files already exist are untracked. set -euo pipefail cd "$(dirname "$0")/.." if [[ "${1:-}" == "--live" ]]; then echo "== Running a real scan to exercise every write path ==" python app.py scan --quiet --dry-run || true fi echo "== Checking that runtime data is gitignored / untracked ==" # Paths a scan writes to. Any of these being tracked OR showing as (non-ignored) # untracked means the invariant is broken and a git pull could conflict. RUNTIME_PATHS=( "app/data" "app/reports" "app/data/ids.db" "app/data/ids.db-wal" "app/data/ids.db-shm" ) fail=0 # 1) No runtime path may be TRACKED, except the single allowed read-only # PaloAlto seed. `git ls-files` reflects the index (including staged # changes), so unborn commits don't cause false failures. allowed="app/data/paloalto/scanner-ips.txt" tracked=$(git ls-files app/data app/reports) problem=$(printf '%s\n' "$tracked" | grep -xvF "$allowed" || true) if [[ -n "$problem" ]]; then echo "FAIL: unexpected tracked files under runtime dirs:" >&2 echo "$problem" >&2 fail=1 fi # 2) Nothing may show as untracked-but-not-ignored under the runtime dirs, i.e. # a scan wrote a file git would happily add (and later conflict on). for p in "${RUNTIME_PATHS[@]}"; do dirty=$(git status --porcelain --untracked-files=all -- "$p" 2>/dev/null || true) if [[ -n "$dirty" ]]; then echo "FAIL: runtime path has changes git cares about:" >&2 echo "$dirty" >&2 fail=1 fi done if [[ "$fail" -eq 0 ]]; then echo "OK: no tracked runtime data; git pull will not conflict with scan writes." else echo "BROKEN: a scan wrote into git-tracked paths — fix before deploying." >&2 exit 1 fi