diff options
Diffstat (limited to 'scripts')
| -rw-r--r-- | scripts/tests/inbox-boundary-check-hook.bats | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/scripts/tests/inbox-boundary-check-hook.bats b/scripts/tests/inbox-boundary-check-hook.bats new file mode 100644 index 0000000..58668a5 --- /dev/null +++ b/scripts/tests/inbox-boundary-check-hook.bats @@ -0,0 +1,83 @@ +#!/usr/bin/env bats +# hooks/inbox-boundary-check.sh — Stop hook that soft-nudges the agent to +# process pending inbox/ handoffs before yielding. Blocks the stop ONCE (emits +# a block decision + reason) when inbox-status reports pending items; on the +# harness re-entry (stop_hook_active: true) it steps aside so an unprocessable +# item or a mid-task pause never wedges. Self-skips where there's no inbox/ or +# no inbox-status. The real inbox-status is copied into the test project so the +# hook runs against real code, not a stub. + +setup() { + REPO_ROOT="$(cd "$(dirname "$BATS_TEST_FILENAME")/../.." && pwd)" + SCRIPT="$REPO_ROOT/hooks/inbox-boundary-check.sh" + INBOX_STATUS="$REPO_ROOT/claude-templates/.ai/scripts/inbox-status" + TMPDIR_T="$(mktemp -d)" + CWD="$TMPDIR_T/proj" + mkdir -p "$CWD/.ai/scripts" + cp "$INBOX_STATUS" "$CWD/.ai/scripts/inbox-status" + chmod +x "$CWD/.ai/scripts/inbox-status" +} + +teardown() { + rm -rf "$TMPDIR_T" +} + +# Feed Stop-hook JSON on stdin. $1 = stop_hook_active (default false). +run_hook() { + local active="${1:-false}" + printf '{"cwd":"%s","hook_event_name":"Stop","stop_hook_active":%s}' \ + "$CWD" "$active" | bash "$SCRIPT" +} + +@test "pending handoffs block the stop with a count in the reason" { + mkdir -p "$CWD/inbox" + printf 'x\n' >"$CWD/inbox/2026-07-19-from-home-thing.org" + printf 'y\n' >"$CWD/inbox/2026-07-19-from-work-other.org" + run run_hook + [ "$status" -eq 0 ] + # Valid JSON with a block decision. + echo "$output" | jq -e '.decision == "block"' + echo "$output" | jq -e '.reason | test("2 pending")' + echo "$output" | jq -e '.reason | test("inbox.org")' +} + +@test "a clean inbox (only artifacts) emits nothing" { + mkdir -p "$CWD/inbox" + touch "$CWD/inbox/.gitkeep" + printf 'done\n' >"$CWD/inbox/PROCESSED-2026-07-19-old.org" + run run_hook + [ "$status" -eq 0 ] + [ -z "$output" ] +} + +@test "soft-nudge: stop_hook_active=true steps aside even with pending items" { + mkdir -p "$CWD/inbox" + printf 'x\n' >"$CWD/inbox/2026-07-19-from-home-thing.org" + run run_hook true + [ "$status" -eq 0 ] + [ -z "$output" ] +} + +@test "no inbox/ directory is a silent no-op" { + run run_hook + [ "$status" -eq 0 ] + [ -z "$output" ] +} + +@test "inbox-status absent degrades to a silent no-op" { + mkdir -p "$CWD/inbox" + printf 'x\n' >"$CWD/inbox/2026-07-19-from-home-thing.org" + rm -f "$CWD/.ai/scripts/inbox-status" + # Also ensure nothing named inbox-status is on PATH for this run. + run env PATH="/usr/bin:/bin" bash -c ' + printf "{\"cwd\":\"'"$CWD"'\",\"hook_event_name\":\"Stop\"}" | bash "'"$SCRIPT"'"' + [ "$status" -eq 0 ] + [ -z "$output" ] +} + +@test "the emitted reason names the project for context" { + mkdir -p "$CWD/inbox" + printf 'x\n' >"$CWD/inbox/2026-07-19-from-home-thing.org" + run run_hook + echo "$output" | jq -e '.reason | test("proj")' +} |
