bash-atomic-log-rotation-open-fd-race-recovery
All tests pass. Here's a summary of the diagnosis and the verified solution.
The failure modes that break the "exactly once" invariant are:
copytruncate loses the tail — data appended between the cp completing and the : > truncate is destroyed. Demonstrated: 500 records in, 457 survive (window widened with a sleep for determinism).mv app.log archive/... and creating a fresh app.log, the active path is gone.gzip+rm or cross-filesystem mv unlinks the inode a writer still appends to, orphaning those bytes.rotate.sh makes the only data mutation an atomic rename(2) within one filesystem, wraps it in a death-safe lock (flock, with a portable mkdir fallback), journals the intended archive name before the rename, and runs idempotent recovery that always restores the active path. It never truncates, copies, or unlinks a file an open FD can reach.
Key artifacts written to ~/logrot/solution/:
| File | Purpose |
|---|---|
rotate.sh |
the protocol |
writer.sh |
adversarial producer with one inherited O_APPEND fd |
verify.sh |
exactly-once checker (active + all archives) |
test_buggy.sh |
reproduces the copytruncate loss |
test_exactly_once.sh, test_race.sh |
concurrent writers / simultaneous rotations |
test_crash.sh, test_crash_openfd.sh |
kill at every command boundary via DEBUG+set -T, then recover |
buggy copytruncate: FAIL expected 500, found 457 (loss reproduced)
exactly-once flock/mkdir: OK 3200 records, all unique
rotation race flock/mkdir: OK 1800 records, all unique
crash every boundary: OK every command boundary recovered (flock & mkdir)
open-fd + crashing rotate: OK 300 records, all unique
The adversarial crash test also caught a real bug in the portable mkdir lock (ownerless lock after kill -9 between mkdir and PID write); the final code breaks such a lock after a grace period via an atomic rename.
The full write-up with embedded, directly usable code is in ~/logrot/SOLUTION.md.
# Evidence - Problem class: bash-atomic-log-rotation-open-fd-race-recovery - Model: openrouter/deepseek/deepseek-v4.1-flash - Solved: 2026-10-13T04:09:28.896Z - Verification: solution produced by pi in sandbox; see signatures.json
{"description": "Implement a Bash-driven log rotation protocol that remains correct when writers keep inherited file descriptors open, rotation is interrupted at any command boundary, and multiple rotation requests race. Preserve every byte exactly once across active, archived, and recovered files, using only portable filesystem primitives and validating crash recovery with adversarial process schedules.", "environment": "bash", "language": "shell", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "bash-atomic-log-rotation-open-fd-race-recovery", "provider": "openrouter", "solved_at": "2026-10-13T04:09:28.897Z", "version": "5"}