From 0f91a8e0cd0a4b5b351efe407987bb8bb6ab125e Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Thu, 23 Jul 2026 23:55:15 -0500 Subject: fix(inbox-send): write handoffs atomically so a failure leaves no phantom inbox-send wrote straight to the destination path, and write_text truncates on open, so any mid-write failure left a zero-byte .org in another project's inbox. inbox-status counted that phantom as a pending handoff and blocked a turn in the receiving project over a file with no content and no sender. Both send paths now write to a temp sibling and os.replace it into place, so the inbox only ever sees a complete file. A caught failure removes the temp and re-raises, leaving no debris. encoding is pinned to utf-8 on the write and on the roots-config read, which closes the locale-dependent failure that first surfaced this. inbox-status also skips the .inbox-send-* temp, so the brief window before the rename can't read as pending either. The atomicity is only complete once the consumer ignores the in-flight file. --- .ai/scripts/tests/inbox-status.bats | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to '.ai/scripts/tests/inbox-status.bats') diff --git a/.ai/scripts/tests/inbox-status.bats b/.ai/scripts/tests/inbox-status.bats index bc8a734..27a497e 100644 --- a/.ai/scripts/tests/inbox-status.bats +++ b/.ai/scripts/tests/inbox-status.bats @@ -45,6 +45,18 @@ teardown() { [[ "$output" == *"0 pending"* ]] } +@test "inbox-status: ignores an in-flight .inbox-send-* temp file" { + mkdir "$TMP/inbox" + # inbox-send writes to a .inbox-send-* temp then renames it into place; + # during that window the temp must not read as a pending handoff, or a + # concurrent boundary check blocks on a file that's about to become real. + touch "$TMP/inbox/.inbox-send-abc123.org" + cd "$TMP" + run "$SCRIPT" + [ "$status" -eq 0 ] + [[ "$output" == *"0 pending"* ]] +} + @test "inbox-status: -q suppresses the per-item lines" { mkdir "$TMP/inbox" echo body > "$TMP/inbox/handoff.org" -- cgit v1.2.3