Scheduled-loop infra: lockfile guard + release + fire log

- scripts/loop-guard.sh — atomic claim with 30-min staleness overtake,
  appends NDJSON event to .loop-logs/<lang>.ndjson. Exit 0 = go ahead,
  exit 1 = another run is live, skip.
- scripts/loop-release.sh — clear lock, log release with exit status.

Intended for 7 per-language /schedule routines firing every 15 minutes.
Lock detects overlap so tight cadences are safe; stale lock (>30 min)
overtaken automatically if an agent dies mid-run.
This commit is contained in:
2026-04-24 16:39:17 +00:00
parent 99753580b4
commit e67852ca96
3 changed files with 44 additions and 0 deletions

4
.gitignore vendored
View File

@@ -29,3 +29,7 @@ test-case-define.txt
test_all.js
test_final.js
test_interactive.js
# Loop lock/log state
.loop-locks/
.loop-logs/

27
scripts/loop-guard.sh Executable file
View File

@@ -0,0 +1,27 @@
#!/usr/bin/env bash
set -euo pipefail
LANG=${1:?usage: loop-guard.sh <lang>}
ROOT=$(cd "$(dirname "$0")/.." && pwd)
cd "$ROOT"
mkdir -p .loop-locks .loop-logs
LOCK=".loop-locks/$LANG.claim"
LOG=".loop-logs/$LANG.ndjson"
NOW=$(date +%s)
ISO=$(date -Iseconds)
STALE_SEC=${LOOP_STALE_SEC:-1800}
if [ -f "$LOCK" ]; then
LAST=$(cat "$LOCK" 2>/dev/null || echo 0)
AGE=$((NOW - LAST))
if [ "$AGE" -lt "$STALE_SEC" ]; then
printf '{"ts":"%s","lang":"%s","status":"skip","age":%d}\n' "$ISO" "$LANG" "$AGE" >> "$LOG"
echo "SKIP: $LANG claimed ${AGE}s ago (stale threshold ${STALE_SEC}s)"
exit 1
fi
echo "INFO: $LANG lock was ${AGE}s old, overtaking"
fi
echo "$NOW" > "$LOCK"
printf '{"ts":"%s","lang":"%s","status":"claimed"}\n' "$ISO" "$LANG" >> "$LOG"
echo "OK: $LANG claimed at $ISO"

13
scripts/loop-release.sh Executable file
View File

@@ -0,0 +1,13 @@
#!/usr/bin/env bash
set -euo pipefail
LANG=${1:?usage: loop-release.sh <lang>}
STATUS=${2:-done}
ROOT=$(cd "$(dirname "$0")/.." && pwd)
cd "$ROOT"
LOCK=".loop-locks/$LANG.claim"
LOG=".loop-logs/$LANG.ndjson"
ISO=$(date -Iseconds)
rm -f "$LOCK"
printf '{"ts":"%s","lang":"%s","status":"released","exit":"%s"}\n' "$ISO" "$LANG" "$STATUS" >> "$LOG"
echo "OK: $LANG released ($STATUS)"