Skip to content

test(pstack): resolve the temp folder before the statechart launcher's relative symlink - #997

Open
VDrozd-Cyclis wants to merge 1 commit into
cursor:mainfrom
VDrozd-Cyclis:fix/statechart-launcher-symlink-tmpdir
Open

VDrozd-Cyclis wants to merge 1 commit into
cursor:mainfrom
VDrozd-Cyclis:fix/statechart-launcher-symlink-tmpdir

Conversation

@VDrozd-Cyclis

Copy link
Copy Markdown

Why

On macOS, node --test pstack/skills/*/scripts/test/*.test.ts fails one statechart test, even with TLC installed:

✖ the launcher reached through an absolute and a relative symlink writes the committed chart on this Node
  AssertionError: undefined !== ''

linkedLauncher() makes b/statechart a relative symlink to the launcher, with path.relative(second, launcher), where second is under os.tmpdir(). On macOS os.tmpdir() is /var/folders/..., and /var links to /private/var. The kernel resolves a relative link from the real folder, which is one level deeper, so the .. steps land one folder too high and the link points at a file that does not exist. spawnSync then fails before the launcher runs, so stderr is undefined. The launcher handles both kinds of symlink correctly; only the test's link is wrong.

What changed

  • pstack/skills/statechart/scripts/test/cli.test.ts: linkedLauncher() resolves its temp folder with fs.realpathSync before it builds the relative link.
  • harness/pstack/claude-code/: regenerated with node scripts/generate-pstack-harness-trees.mjs.

#924 fixed the same macOS TMPDIR symlink problem in the old statechart.test.mjs, before #977 replaced it with the TypeScript tests.

Validation

The full CI test command, node --disable-warning=ExperimentalWarning --test pstack/skills/*/scripts/test/*.test.ts, with TLC 1.7.4 and Temurin 25 set in TLA2TOOLS and JAVA:

Setup main This PR
macOS, Node 24.22.1, default TMPDIR 366 pass, 1 fail 367 pass

The two launcher tests in node:22-bookworm, Node 22.23.4:

TMPDIR main This PR
default /tmp 2 pass 2 pass
/linktmp, a symlink to /private/tmp 1 pass, 1 fail 2 pass

A symlinked TMPDIR only breaks the test when the link changes the path depth. A link to a folder at the same depth, such as /linktmp to /real, passes on main too.

node scripts/validate-plugins.mjs, node scripts/generate-pstack-harness-trees.mjs --check, and git diff --check pass.

…s relative symlink

The launcher test links b/statechart to the launcher with path.relative
from a folder under os.tmpdir(). When TMPDIR goes through a symlink
that changes the path depth, such as macOS's /var -> /private/var, the
kernel resolves the relative link from the real folder, one level
deeper, so the link points at a missing file and spawnSync fails with
no stderr. Resolve the folder with realpathSync first.
@deanrie

deanrie commented Oct 29, 2026

Copy link
Copy Markdown

Hey @VDrozd-Cyclis, reproduced the premise and the fix on macOS 15 (Node 22, TMPDIR under /var/folders, no TLC installed): on main (23ab063) node --test test/cli.test.ts in pstack/skills/statechart/scripts is 125 pass, 1 fail, the failing case being exactly "the launcher reached through an absolute and a relative symlink writes the committed chart on this Node" with undefined !== ''; with #997 merged onto main it is 126 pass, 0 fail. The same /var -> /private/var cause is what #923 reports for the old .mjs suite and what oesni's #924 fixed there before #977 replaced that file, so this is the surviving fix for the TypeScript suite. It also bites a new test in #1017 (tool-paths.test.ts builds its expected classpath from os.tmpdir() without realpathSync), noted there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants