Repository navigation
fix: cross-instance store locking, prompt size preflight, windows graceful stop - #157
Merged
Merged
Conversation
The token, workspace and settings stores merge the file before replacing it, but two bodek instances could still interleave between the read and the rename and drop each other's update (a test lost half of 80 tokens). A new internal/filelock takes an advisory lock on <path>.lock around the cycle — best-effort, released by the OS if the holder dies, and skipped after 2s so persistence never hangs the TUI. Saves also wrote the staged file over a symlinked store, replacing a dotfile-managed link with a regular file; they now write through it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An oversized prompt was committed (transcript card, busy state, staged files cleared) before the client refused the frame, and its errMsg never drained the queue. Submit, queue sends and drains now preflight the frame size with client.CheckPromptSize and leave everything in place behind an explaining note. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
AGENTS.md promised ^U clears the draft over an approval card; the code, README and tests have ^U page the transcript there. Document the real path (Backspace / ^W) and the find/drawer-editor swallow rule. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Process.Signal(os.Interrupt) is unsupported on windows, so every quit waited out the 12s grace and force-killed odek mid-cleanup. The child now starts in its own console process group and gets CTRL_BREAK, which Go delivers as os.Interrupt. The new group also hides console Ctrl+C from odek, and windows has no re-exec watchdog, so the child is placed in a kill-on-close Job Object whose only handle bodek holds: a bodek that dies for any reason takes odek with it. CI's windows leg now runs these process tests and the filelock suite. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
bodek | c1c3410 | Commit Preview URL Branch Preview URL |
Oct 17 2026, 03:03 PM |
tryLock treated every error as a busy peer, so a mount without locking (NFS nolocks, some SMB/FUSE) stalled each save — workspace persists run on the update loop — by the full 2s. Only EWOULDBLOCK / lock violation retries now. Lock also creates the store directory (the first write ran unlocked) and keys on the resolved path, so two links to one store share its lock. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The drain runs after every idle event, so an oversized queue head was re-encoded and re-noted on each heartbeat. The refusal is remembered until the head or the staged files change, /unattach re-drains at once, and the note says when the text alone is too long. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
guardChild opened the child by pid after the reaper's Wait could have released the handle, so a child that exited at once risked a recycled pid landing in the kill-on-close job. It now runs first. The CI step that runs the windows process and filelock tests was also missing from the previous commit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #156: this closes the issues that round left open.
Cross-instance store writes.
internal/filelockadds an advisory lock on<path>.lock(flock on unix, LockFileEx on windows). It wraps the read-merge-write cycle in the token, workspace and settings stores.Symlinked stores. Saves used to replace a dotfile-managed symlink with a regular file. They now write through the link.
Oversized prompts.
client.CheckPromptSize). Everything stays in place behind a note explaining why the prompt was not sent.Windows graceful stop.
os.Interrupt. Before, every quit waited 12s and then force-killed.Docs. AGENTS.md now describes the approval bare-key fallback as implemented: Backspace or
^Wempties the draft. Before, it wrongly said^Udoes.Adversarial review follow-ups.
/unattachdrains it right away.Checks:
make fmt,make vet,make lint(0 issues) andmake test(race) pass on macOS. Onwindows-latestCI, the filelock suite and the Windows process tests pass: CTRL_BREAK reaches the child asos.Interrupt, and closing the job kills the child.🤖 Generated with Claude Code