Repository navigation
duplicate-holder / lane-end --retire truncate --resume paths containing a space #76
Description
duplicate-holder's and lane-end --retire's --resume argument extraction truncates at the first space, so a recorded directory containing one is never matched
Where
Every place issue #30/#39's process-table reading extracts the --resume value from ps's flattened argv uses the same pattern:
dhp_resume="${dhp_args_lc#*--resume }"; dhp_resume="${dhp_resume%% *}"(lanes-edit.sh's duplicate_holder_pids, both the parent match and each child candidate's match) and
dh_p_resume="${dh_p_args#*--resume }"; dh_p_resume="${dh_p_resume%% *}"(lane-end's pre-kill parent and child rechecks, both copies).
Why it is wrong
ps -o args= (and -o command=) renders a process's argv as ONE flattened, space-joined string — there is no quoting or escaping in that rendering to show where one argument ends and the next begins. ${var%% *} (up to the first remaining space) is therefore only correct when NO argument between --resume and the end of the recorded argv contains a space itself. This repository's own fixtures record directories that do: tests/test_lane_helpers.sh (around lines 5611-5624 as of PR #61) exercises lane-start --dir with a path containing a space, so a real --fork-session --resume "/path with a space/<uuid>.jsonl" is a supported, already-tested shape elsewhere in this suite — just not through this specific extraction.
Effect: a live duplicate holder (or a live fork) resumed from such a path is never discovered (the truncated token never matches */"<uuid>.jsonl"), so duplicate-holder answers "none" for a duplicate that is genuinely there, and lane-end --retire's own pre-kill recheck would similarly read a truncated, non-matching path and treat a real, still-matching process as "argv no longer matched" — withholding a TERM that should be sent.
Why this is filed rather than fixed here
A correct fix needs the actual argv boundaries, not a rendering that has already lost them. Linux offers /proc/<pid>/cmdline (NUL-separated, exact); BSD/macOS has no equivalent procfs, and this file's own extensive comments elsewhere document ps -o pid=,ppid=,args=/ps -o args= as the deliberately-chosen GNU/BSD-portable mechanism for reading a process's command line at all. A real fix is therefore either platform-conditional (an exact read on Linux, with the current best-effort truncated match kept — and documented as a KNOWN LIMIT — on BSD/macOS), or a documented refusal for a recorded directory containing a space on this one surface specifically (paralleling how lane-start --dir already documents and tests the shape it CAN carry). Either shape touches four call sites consistently (both duplicate_holder_pids matches in lanes-edit.sh, both pre-kill rechecks in lane-end) and is worth its own focused pass rather than a guess made piecemeal under this PR's own time budget.
Scope note
This limitation is in code PR #61 itself added (the --resume token extraction was introduced across Copilot rounds 4-5 of that PR, to fix an earlier, worse glob-based match — see that PR's history), not in code that predates it; filed separately because a correct, portable fix is materially larger than a one-line patch and touches multiple call sites that must stay consistent with each other.
Activity
brettheap commentedon Sep 15, 2026
CLAIMED — lane openRepoTools-3, session 4135b2c9-34a6-47e3-a156-5adebb632fae@Eagle, 2026-09-15T03:17:52Z, for #76
Logged in
lanes/log/openRepoTools-3.mdatabaa10d3e03ef11c35ab2a5fe99c736efad78ea9.The three reads (lane-collision-protocol Rule 1):
Copilot rounds 9-10: a sole fenced child was trusted without its own …
Copilot round 11: a substring without an option-token boundary could …
brettheap commentedon Oct 11, 2026
TAKEOVERopenRepoTools-3 — lane openRepoTools-5, session 0d83dca2-c18c-4bb0-99ce-896e6cafea02@Eagle, 2026-10-11T16:56:47Z, for #76
Logged in
lanes/log/openRepoTools-5.mdatc3787209a5dd433a9b8aedf9bb127d678c1be7e5(takeover of the stale claim held by lane openRepoTools-3).The three reads (lane-collision-protocol Rule 1):