fix: dev-loop instance guards -- concurrent-start refusal + per-rebuild reap (BACKLOG Standing #8) - #52
Merged
Merged
Conversation
…ld reap (BACKLOG Standing #8) Two mechanical fixes for the owner-hit THREE-concurrent-mill.dev.app incident (real crash risk on a 16GB machine): (a) Per-rebuild reap: build/config.yml's dev_mode.executes gains a `type: blocking` pkill step right before the `primary` `wails3 task run` step. Blocking steps re-run on every reload cycle (confirmed directly against the vendored github.com/atterpac/refresh engine source), backstopping refresh's own kill-then-restart regardless of whether it actually reaps the previous instance -- a live task dev session was caught, mid-investigation, with two concurrent mill.dev.app processes, one orphaned into a foreign process group refresh's own tracking never caught. Root cause not fully pinned to one line since it's inside a vendored third-party dependency; this reap is an independent, pattern-based backstop rather than a patch to code this repo doesn't own. (b) Concurrent-start guard: internal/devguard (a real Go package, unit-tested) runs as the first step of Taskfile.yml's `dev:` task, checks for an already-running `wails3 dev` process for this exact repo, and exits non-zero naming the conflicting PID before the existing destructive sweep steps can run -- which would otherwise silently kill a genuinely live first session's own vite/app instead of refusing to start. Verified live against a real running session (correctly detected and refused, naming the actual PID). Manual-only registry entry added (.claude/skills/run-mill/SKILL.md) for what CI structurally can't prove: real per-rebuild-orphan prevention across several live Go-triggered rebuilds, and a genuine second-terminal task dev invocation actually refusing to start. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018pkViCNAuZp2vBv2K9AbUh
alicoding
enabled auto-merge (squash)
August 13, 2026 06:08
alicoding
added a commit
that referenced
this pull request
Aug 15, 2026
…ld reap (BACKLOG Standing #8) (#52) Two mechanical fixes for the owner-hit THREE-concurrent-mill.dev.app incident (real crash risk on a 16GB machine): (a) Per-rebuild reap: build/config.yml's dev_mode.executes gains a `type: blocking` pkill step right before the `primary` `wails3 task run` step. Blocking steps re-run on every reload cycle (confirmed directly against the vendored github.com/atterpac/refresh engine source), backstopping refresh's own kill-then-restart regardless of whether it actually reaps the previous instance -- a live task dev session was caught, mid-investigation, with two concurrent mill.dev.app processes, one orphaned into a foreign process group refresh's own tracking never caught. Root cause not fully pinned to one line since it's inside a vendored third-party dependency; this reap is an independent, pattern-based backstop rather than a patch to code this repo doesn't own. (b) Concurrent-start guard: internal/devguard (a real Go package, unit-tested) runs as the first step of Taskfile.yml's `dev:` task, checks for an already-running `wails3 dev` process for this exact repo, and exits non-zero naming the conflicting PID before the existing destructive sweep steps can run -- which would otherwise silently kill a genuinely live first session's own vite/app instead of refusing to start. Verified live against a real running session (correctly detected and refused, naming the actual PID). Manual-only registry entry added (.claude/skills/run-mill/SKILL.md) for what CI structurally can't prove: real per-rebuild-orphan prevention across several live Go-triggered rebuilds, and a genuine second-terminal task dev invocation actually refusing to start. Claude-Session: https://claude.ai/code/session_018pkViCNAuZp2vBv2K9AbUh Co-authored-by: Claude Fable 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.
Summary
build/config.yml'sdev_mode.executesgains atype: blockingpkillstep right before theprimarywails3 task runstep. Blocking steps re-run every reload cycle (confirmed against the vendoredgithub.com/atterpac/refreshengine source), backstopping refresh's own kill-then-restart -- a livetask devsession was caught mid-investigation with two concurrentmill.dev.appprocesses, one orphaned into a foreign process group refresh's own tracking never reaped. Root cause not fully pinned to one line in a vendored dependency this repo doesn't own; this is an independent, pattern-based backstop.internal/devguard(real Go package, unit-tested) runs as the first step ofTaskfile.yml'sdev:task, detects an already-runningwails3 devprocess for this exact repo, and exits non-zero naming the conflicting PID -- verified live against a genuinely running session (correctly refused, naming the real PID)..claude/skills/run-mill/SKILL.md) for what CI structurally can't prove (real multi-rebuild orphan prevention, a genuine second-terminal refusal).Test plan
go vet . ./internal/...golangci-lint run . ./internal/...(0 issues, two justified//nolint:gosec,noctxon one-shot CLI subprocess calls)go test . ./internal/... -race -cover(all green,internal/devguard74.1% coverage)go build -o /dev/null .andgo build -tags server -o /dev/null .scripts/check-loc.shinternal/devguardagainst a real runningtask devsession (correctly detected + refused, naming the actual PID)🤖 Generated with Claude Code
https://claude.ai/code/session_018pkViCNAuZp2vBv2K9AbUh