diff options
| author | Craig Jennings <c@cjennings.net> | 2026-06-24 05:36:29 -0400 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-06-24 05:36:29 -0400 |
| commit | 1eaec823a9174bb74596a5b008917cdddfc21e6d (patch) | |
| tree | 9929109ffda3090f22d8cf26bc2a0145141386c4 /.ai/scripts/tests/capture-guard.bats | |
| parent | 558624ebdba99e00ffa232421a8d65dd89052eef (diff) | |
| download | rulesets-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.bats | 27 |
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" ] +} |
