Skip to content

fix(ui): keep saved trails inside the project - #1667

Open
danusha2345 wants to merge 8 commits into
colbymchenry:mainfrom
danusha2345:fix/ui-review-findings
Open

danusha2345 wants to merge 8 commits into
colbymchenry:mainfrom
danusha2345:fix/ui-review-findings

Conversation

@danusha2345

@danusha2345 danusha2345 commented Sep 1, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Rebased onto v1.6.2 (6560052). The wall-clock replacement for the busiest-symbol test that this PR used to carry is dropped: #2208 did it on main. Changelog lines live in docs/viewer-launch-changelog.md.

  • reject not-yet-created paths when their nearest existing ancestor is a symlink outside the project
  • validate every listed trail through the project-root chokepoint and open it with O_NOFOLLOW | O_NONBLOCK
  • revalidate the trail directory after creation and use a random, exclusive 0600 temp file for atomic writes
  • cache saved-trail authors per real project root and reject declared unknown trail format versions
  • move the test workspace to Vitest 4 test.projects, align the Vite toolchain, and preserve Node >=25 contributor testing
  • update the dev dependency graph (the one remaining npm audit finding, devalue, is the same version as on main)

Reproductions fixed

  • .codegraph/ui -> outside with missing trails/ previously created outside/trails/<id>.json; the write is now refused.

  • .codegraph/ui/trails/leak.json -> outside/secret.json previously exposed a trail-shaped external JSON through the list endpoint; it is now skipped.

  • two repositories with different local Git user names in one process previously reused the first author; they now resolve independently.

  • a FIFO with no writer in .codegraph/ui/trails/ (a regression of the O_NOFOLLOW open in this PR, caught in review) blocked the synchronous open, and with it the whole UI server, on every list or read; it is now skipped like any other non-regular entry.

Positive controls keep projects opened through a safe root symlink and ordinary unversioned hand-written v1 trails working.

Verification

  • npm ci, npm run build, npx tsc --noEmit -p .
  • focused security / UI / trails suites, ui-package in the ui project, child-process-windows-hide: 1,034 passed, 4 skipped
  • full suite (Linux, Node 22, Vitest 4): everything passes except the two bundle-launcher Windows-archive listings, which hit Vitest's 5 s default timeout on this machine; the other timeouts seen under a loaded machine pass when re-run
  • compiled read/write/author reproductions all refuse or separate state as expected

🤖 Generated with Claude Code

@danusha2345

Copy link
Copy Markdown
Contributor Author

Merged current main (3adf067, post-#1770) into this branch: head afa27e2. The only conflict was the CHANGELOG entry; no source conflict. tsc clean, the branch's tests pass.

@danusha2345

Copy link
Copy Markdown
Contributor Author

Merged current main (43271f3) into this branch: head 0187193. The only conflict was the CHANGELOG entry; no source conflict. tsc clean, the branch's tests pass.

@danusha2345

Copy link
Copy Markdown
Contributor Author

Merged current main (85550eb) into this branch: head 7dad42e. The only conflict was the CHANGELOG entry; no source conflict. tsc clean, the branch's tests pass.

@danusha2345

Copy link
Copy Markdown
Contributor Author

Merged current main (8733c28) into this branch: head e6c1530. The only conflict was the CHANGELOG entry; no source conflict. tsc clean, the branch's tests pass.

@danusha2345

Copy link
Copy Markdown
Contributor Author

Merged current main (8c04734) into this branch: head 0a77a4b. The only conflict was the CHANGELOG entry; no source conflict. tsc clean, the branch's tests pass.

@danusha2345

Copy link
Copy Markdown
Contributor Author

Merged current main (ee83636) into this branch: head d0dbae3. The only conflict was the CHANGELOG entry; no source conflict. tsc clean, the branch's tests pass.

@danusha2345

Copy link
Copy Markdown
Contributor Author

Merged current main (e720f6c) into this branch: head b4dd834. The only conflict was the CHANGELOG entry; no source conflict. tsc clean, the branch's tests pass.

@danusha2345

Copy link
Copy Markdown
Contributor Author

Merged current main (de5adba) into this branch: head 10288d9. The only conflict was the CHANGELOG entry; no source conflict. tsc clean, the branch's tests pass.

@danusha2345

Copy link
Copy Markdown
Contributor Author

Merged current main (cece072) into this branch: head f2ebce7. The only conflict was the CHANGELOG entry; no source conflict. tsc clean, the branch's tests pass.

@danusha2345

Copy link
Copy Markdown
Contributor Author

Merged current main (040ba38) into this branch: head 50ceafc. The only conflict was the CHANGELOG entry; no source conflict. tsc clean, the branch's tests pass.

@danusha2345

Copy link
Copy Markdown
Contributor Author

Merged current main (374b3b4) into this branch: head 704ef5c. The only conflict was the CHANGELOG entry; no source conflict. tsc clean, the branch's tests pass.

@danusha2345

Copy link
Copy Markdown
Contributor Author

Merged current main (71d049c) into this branch: head c2f90ab. The only conflict was the CHANGELOG entry; no source conflict. tsc clean, the branch's tests pass.

@danusha2345

Copy link
Copy Markdown
Contributor Author

Merged current main (9181dd1) into this branch: head 0988b8f. The only conflict was the CHANGELOG entry; no source conflict. tsc clean, the branch's tests pass.

@danusha2345

Copy link
Copy Markdown
Contributor Author

Merged current main (64bd45c) into this branch: head e3e6e3c. The only conflict was the CHANGELOG entry; no source conflict. tsc clean, the branch's tests pass.

@danusha2345

Copy link
Copy Markdown
Contributor Author

Merged current main (748311f) into this branch: head 06f19d7. The only conflict was the CHANGELOG entry; no source conflict. tsc clean, the branch's tests pass.

@danusha2345

Copy link
Copy Markdown
Contributor Author

Merged main (8f80819) and adapted one test the Vitest 4 bump breaks: __tests__/git-index-currency.test.ts (from #1878) injects failures with vi.spyOn on a module it already vi.mocks. Under Vitest 4 that spy IS the mock's vi.fn, so the captured "real" function recursed into itself (Maximum call stack size exceeded) and, since restoreAllMocks no longer resets a vi.fn, the injection leaked into the six following tests — 7 of 13 red on a clean main checkout run with Vitest 4, 13/13 with Vitest 2. The rewrite routes the injections through the mocks' own vi.fns and reinstates the real functions explicitly; 13/13 under both 2.1.9 and 4.1.11. Full suite otherwise unchanged.

@danusha2345

Copy link
Copy Markdown
Contributor Author

One more Vitest 4 adaptation: #1883 passes --liftoff-only to pool workers through poolOptions.forks.execArgv, which Vitest 4 no longer reads, so on this branch the #1779 worker death (Fatal process out of memory: Zone in the turboshaft wasm tier-up) came back in a full run. Vitest 4's option is test.execArgv; a probe confirms the fork's process.execArgv now carries the flag and the 655-test extraction file passes. If #1883 lands first, this branch carries the Vitest 4 form of the same line.

danusha2345 pushed a commit to danusha2345/codegraph that referenced this pull request Sep 27, 2026
danusha2345 pushed a commit to danusha2345/codegraph that referenced this pull request Sep 27, 2026
@danusha2345

Copy link
Copy Markdown
Contributor Author

Merged current main (34ede4d) into this branch. The only conflict was __tests__/ui-server-api.test.ts with #2208. #2208 now times the engine's busiest symbol as the best of five warmed requests inside the regular test, which is what this branch's isolated median gate (npm run test:perf) was for, so I took main's file and dropped the gate together with the test:perf script; the branch no longer touches that test. What remains: the trail-path fixes (trail-store, trails, utils, trail-codec) with their tests, and the Vitest 4 migration they were written against. tsc clean; git-index-currency, ui-trails, ui-server-api, security, ui-package, viewer-gate and cli-ui-command pass under Vitest 4.1.11 (195 passed, 3 skipped: two Windows-only cases and the own-index test, which needs a local .codegraph/).

🤖 Generated with Claude Code

danusha2345 and others added 8 commits October 3, 2026 11:20
devEngines and the ui package's engines keep their Node 22.12 floor for the
Vite 7 toolchain under Vitest 4, but drop the upper bound: it would stop npm
itself on a newer Node, where contributors are meant to be able to run the
suite (the test config sets CODEGRAPH_ALLOW_UNSAFE_NODE, colbymchenry#478).

This commit used to add an isolated median timing gate for the viewer's
busiest symbol, and a test:perf script to run it. On this base the regular
test already times that request as the best of five (colbymchenry#2208), so both are
left out.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The O_NOFOLLOW open introduced in 746e774 runs before the isFile() check
that used to reject non-regular entries. A named pipe with no writer in
.codegraph/ui/trails/ therefore parked the synchronous open, and with it
the whole UI server, on every list or read. Open with O_NONBLOCK as well:
a regular file ignores it, a FIFO returns at once and fstat skips it as
before.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…uiltin

Under Vitest 4 `vi.spyOn(cp, 'execFileSync')` on the module this file
already mocks returns the same `vi.fn`, so the "real" function a test
captured is the spy itself and the injected implementation recurses until
the stack overflows; `vi.restoreAllMocks()` also stops resetting a
`vi.fn`'s implementation, so the injection leaked into the six tests that
follow. Route both injections through the module mocks' own `vi.fn`s, fall
through to `vi.importActual`, and reinstate the real functions explicitly.
13/13 under Vitest 2.1.9 and 4.1.11.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The Vitest 4 bump in this branch drops `poolOptions`, so the
`poolOptions.forks.execArgv` fix from colbymchenry#1883 is silently ignored here and a
pool worker still compiles tree-sitter grammars on the turboshaft tier —
the `Fatal process out of memory: Zone` worker death from colbymchenry#1779 came back
in a full run on this branch. Vitest 4 reads `test.execArgv`; the engine
project inherits it through `extends`. A probe test confirms the fork's
`process.execArgv` now carries `--liftoff-only`, and the 655-test
extraction file passes where it died before.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@danusha2345
danusha2345 force-pushed the fix/ui-review-findings branch from e35c791 to 111bfa4 Compare October 3, 2026 09:04

This branch has not been deployed

No deployments
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.

1 participant