aboutsummaryrefslogtreecommitdiff
path: root/.ai/scripts/tests/capture-guard.bats
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-06-24 05:36:29 -0400
committerCraig Jennings <c@cjennings.net>2026-06-24 05:36:29 -0400
commit1eaec823a9174bb74596a5b008917cdddfc21e6d (patch)
tree9929109ffda3090f22d8cf26bc2a0145141386c4 /.ai/scripts/tests/capture-guard.bats
parent558624ebdba99e00ffa232421a8d65dd89052eef (diff)
downloadrulesets-1eaec823a9174bb74596a5b008917cdddfc21e6d.tar.gz
rulesets-1eaec823a9174bb74596a5b008917cdddfc21e6d.zip
feat(inbox): poll-and-retry the capture-guard instead of bouncing
When a roam edit hits a live org-capture, the guard used to bounce the caller right away (surface to the user, or skip the cycle) even though the capture is usually a few seconds of mid-finalize that clears on its own. capture-guard gets a --wait poll mode: it re-checks every ~10s up to a budget (default 30s, each sleep capped so a short --wait never overshoots), returns the instant the capture clears, and reports blocked only at the deadline. The no-capture common case still returns instantly without sleeping. Roam mode now uses --wait on every write, and the per-caller fallback fires only after the wait: an interactive run surfaces, the auto /loop defers to the next cycle (the loop cadence is the retry), wrap-up skips and self-heals. Surfaced live this session: a transient capture blocked a roam reconcile and had cleared a minute later. Covered by three new bats cases (instant-when-safe, timeout-when-blocked, target-after-flag). Claude-Session: https://claude.ai/code/session_017PtX1nt1rtYVATuzmzBS4f
Diffstat (limited to '.ai/scripts/tests/capture-guard.bats')
-rw-r--r--.ai/scripts/tests/capture-guard.bats27
1 files changed, 27 insertions, 0 deletions
diff --git a/.ai/scripts/tests/capture-guard.bats b/.ai/scripts/tests/capture-guard.bats
index 2bfee61..31632a4 100644
--- a/.ai/scripts/tests/capture-guard.bats
+++ b/.ai/scripts/tests/capture-guard.bats
@@ -101,3 +101,30 @@ teardown() {
[ "$status" -eq 0 ]
[ -z "$output" ]
}
+
+# ---- --wait poll mode -----------------------------------------------
+
+@test "capture-guard --wait: returns 0 instantly when already safe (no sleep)" {
+ SECONDS=0
+ run env PATH="$STUB_DIR:$PATH" STUB_REACHABLE=1 STUB_BUFS='""' \
+ "$BASH_BIN" "$SCRIPT" --wait
+ [ "$status" -eq 0 ]
+ [ -z "$output" ]
+ [ "$SECONDS" -lt 2 ] # didn't poll-sleep
+}
+
+@test "capture-guard --wait=1: times out to exit 1 when persistently blocked" {
+ # Stub always reports the buffer, so it never clears — the short budget
+ # forces a timeout. Capped sleep keeps this near 1s.
+ run env PATH="$STUB_DIR:$PATH" STUB_REACHABLE=1 STUB_BUFS='"CAPTURE-inbox.org"' \
+ "$BASH_BIN" "$SCRIPT" --wait=1
+ [ "$status" -eq 1 ]
+ [[ "$output" == *"CAPTURE-inbox.org"* ]]
+}
+
+@test "capture-guard --wait=N accepts a target after the flag" {
+ run env PATH="$STUB_DIR:$PATH" STUB_REACHABLE=1 STUB_BUFS='""' \
+ "$BASH_BIN" "$SCRIPT" --wait=1 "$TEST_DIR/some-other-inbox.org"
+ [ "$status" -eq 0 ]
+ [ -z "$output" ]
+}