os-sdlc lsp-probe daemon socket path exceeds the 108-byte Unix socket limit in git worktrees #619

Closed
opened 2026-09-19 17:39:50 +00:00 by jared · 2 comments
Owner

lsp-probe daemon socket path exceeds sun_path limit in worktrees

Problem

plugins/os-sdlc/lib/os_sdlc/lsp_probe/daemon/paths.rb derives dir as File.join(@root, ".cc-os", "lsp", sha1(root)[0,12]), so the socket path length grows with the root path. In a git worktree the root is long enough to cross the Linux sun_path 108-byte limit; UNIXServer.new raises ENAMETOOLONG in the spawned server, the client sees no socket and raises SpawnTimeout with no clear diagnostic.

Cases

  1. Given a root long enough that the current dir formula exceeds 107 bytes, when lsp-probe spawns the daemon, then it still binds and returns EVIDENCE lines instead of timing out.
  2. Given a 200-byte root, when Paths.new(root).sock_path is read, then its byte length is under 108.
  3. Given a daemon from the main checkout and one from a worktree of the same repo, when both run, then they use distinct sockets (do not share one).

Approach

Derive dir from a short fixed base (XDG_RUNTIME_DIR, falling back to Dir.tmpdir) plus the existing 12-char root hash, keeping sock_path and lock_path co-located under it.

Required work:

  1. Change Paths#dir to File.join(base, "os-sdlc-lsp", sha1(@root)[0,12]) where base is ENV.fetch("XDG_RUNTIME_DIR") { Dir.tmpdir } — check: grep -n "def dir" plugins/os-sdlc/lib/os_sdlc/lsp_probe/daemon/paths.rb
  2. Add a test asserting a 120+ byte root yields a sock_path under 108 bytes
  3. Confirm Stopper/cleanup still find the dir via Paths#dir (no change expected since they key off it) — check existing cleanup tests still pass

Acceptance criteria

  1. Given lsp-probe invoked from a worktree checkout with a long root, when it runs, then it prints EVIDENCE lines instead of raising SpawnTimeout.
  2. Given a 200-byte root passed to Paths.new, when sock_path is read, then its bytesize is less than 108.

Owner sketch

class OsSdlc::LspProbe::Daemon::Paths
  def dir
  end
end

Origin

  • Discoverer: hyperthrive-websites, session 593440fa-69ec-49a3-b2d6-ecb0881dc193, 2026-09-19
  • Where: plugins/os-sdlc/lib/os_sdlc/lsp_probe/daemon/paths.rb
# lsp-probe daemon socket path exceeds sun_path limit in worktrees ## Problem `plugins/os-sdlc/lib/os_sdlc/lsp_probe/daemon/paths.rb` derives `dir` as `File.join(@root, ".cc-os", "lsp", sha1(root)[0,12])`, so the socket path length grows with the root path. In a git worktree the root is long enough to cross the Linux `sun_path` 108-byte limit; `UNIXServer.new` raises `ENAMETOOLONG` in the spawned server, the client sees no socket and raises `SpawnTimeout` with no clear diagnostic. ## Cases 1. Given a root long enough that the current dir formula exceeds 107 bytes, when `lsp-probe` spawns the daemon, then it still binds and returns EVIDENCE lines instead of timing out. 2. Given a 200-byte root, when `Paths.new(root).sock_path` is read, then its byte length is under 108. 3. Given a daemon from the main checkout and one from a worktree of the same repo, when both run, then they use distinct sockets (do not share one). ## Approach Derive `dir` from a short fixed base (`XDG_RUNTIME_DIR`, falling back to `Dir.tmpdir`) plus the existing 12-char root hash, keeping `sock_path` and `lock_path` co-located under it. Required work: 1. Change `Paths#dir` to `File.join(base, "os-sdlc-lsp", sha1(@root)[0,12])` where base is `ENV.fetch("XDG_RUNTIME_DIR") { Dir.tmpdir }` — check: `grep -n "def dir" plugins/os-sdlc/lib/os_sdlc/lsp_probe/daemon/paths.rb` 2. Add a test asserting a 120+ byte root yields a `sock_path` under 108 bytes 3. Confirm Stopper/cleanup still find the dir via `Paths#dir` (no change expected since they key off it) — check existing cleanup tests still pass ## Acceptance criteria 1. Given `lsp-probe` invoked from a worktree checkout with a long root, when it runs, then it prints EVIDENCE lines instead of raising SpawnTimeout. 2. Given a 200-byte root passed to `Paths.new`, when `sock_path` is read, then its `bytesize` is less than 108. ## Owner sketch ```ruby class OsSdlc::LspProbe::Daemon::Paths def dir end end ``` ## Origin - Discoverer: hyperthrive-websites, session 593440fa-69ec-49a3-b2d6-ecb0881dc193, 2026-09-19 - Where: plugins/os-sdlc/lib/os_sdlc/lsp_probe/daemon/paths.rb
Author
Owner

Reproduced deterministically 2026-09-23: worktree name ticket-643-aliases gives a 110-byte daemon socket path (.claude/worktrees/ticket-643-aliases/plugins/os-sdlc/.cc-os/lsp//daemon.sock) and evidence_bin_test fails with SpawnTimeout every run; ticket-643 gives 102 bytes and passes; the same commit checked out at .claude/worktrees/a passes. The 108-byte limit is the live cause, not a flake.

Reproduced deterministically 2026-09-23: worktree name ticket-643-aliases gives a 110-byte daemon socket path (.claude/worktrees/ticket-643-aliases/plugins/os-sdlc/.cc-os/lsp/<hash>/daemon.sock) and evidence_bin_test fails with SpawnTimeout every run; ticket-643 gives 102 bytes and passes; the same commit checked out at .claude/worktrees/a passes. The 108-byte limit is the live cause, not a flake.
Author
Owner

Resolution

Done: Socket path length no longer applies: the lsp-probe daemon registry moved to the procman gem under $XDG_RUNTIME_DIR/procman// (ADR-0219, #712).

Evidence: Commit cd265726 on branch ticket-712: Daemon::Paths deleted, ProcmanKind supplies the endpoint; os-sdlc suite 1423 runs, 0 failures, 33.8s. Branch batch-lsp abandoned unmerged.

Follow-ups: none

## Resolution **Done:** Socket path length no longer applies: the lsp-probe daemon registry moved to the procman gem under $XDG_RUNTIME_DIR/procman/<root-hash>/ (ADR-0219, #712). **Evidence:** Commit cd265726 on branch ticket-712: Daemon::Paths deleted, ProcmanKind supplies the endpoint; os-sdlc suite 1423 runs, 0 failures, 33.8s. Branch batch-lsp abandoned unmerged. **Follow-ups:** none
jared closed this issue 2026-09-25 16:57:50 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
jared/cc-os#619
No description provided.