[PR #1623] [MERGED] fix(apple): preserve directory requirements in dylib paths #4708

Closed
opened 2026-10-31 00:54:13 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/1623
Author: @evenafterallisaid
Created: 10/10/2026
Status: ✅ Merged
Merged: 10/10/2026
Merged by: @morluto

Base: main ← Head: fix/dylib-directory-components


📝 Commits (1)

  • 8865fc0 fix(apple): preserve directory requirements in dylib paths

📊 Changes

4 files changed (+110 additions, -4 deletions)

View changed files

📝 src/domain/apple/dyldPaths.ts (+7 -2)
📝 src/domain/apple/dylibResolution.test.ts (+43 -0)
📝 src/domain/apple/dylibResolution.ts (+1 -2)
📝 tests/boundary/cli/dylibResolutionCli.test.ts (+59 -0)

📄 Description

summary

prevent trace-dylib-resolution from reporting a regular dylib as resolved when its dependency path requires a directory.

problem and expected behavior

@loader_path/lib.dylib/ and @loader_path/lib.dylib/. incorrectly resolve to the existing regular file lib.dylib. the path tokenizer removes the directory requirement before examining the file. symlink targets have the same problem. additionally, a bare @rpath/ loses its separator during candidate composition and can resolve a file-valued rpath.

these candidates should be absent, with an unresolved edge and required-load-unresolved finding. POSIX pathname resolution requires a trailing slash to name a directory. valid directory dot components and repeated separators should still resolve.

no existing issue is linked: this was reproduced while looking for a contribution, and searches found no matching report or pr.

change and scope

retain dot components until traversal verifies the preceding entry is a directory. represent trailing slashes as a final dot traversal requirement, including in symlink targets. preserve the separator when composing rpath candidates with an empty suffix.

contract and boundary impact

  • semantic owner and earliest changed stage: static dyld candidate composition and tree traversal.
  • CLI and MCP/tool-catalog contract: schemas unchanged; invalid file candidates now report the existing unresolved outcome.
  • provider, bridge, target-format, or platform compatibility: portable static Mach-O path resolution; no engine or bridge change.
  • evidence, artifact, provenance, or reconstruction contract: preserve declared install names and candidate paths; correct derived outcomes and findings.
  • process execution, authorization, cleanup, or containment impact: none.
  • generated metadata, package, or installation impact: none.

evidence and regression coverage

  • public CLI regression uses byte-authored Mach-O files to check loader-path and rpath suffixes, empty rpath suffixes, successful directory dot paths, repeated separators, and findings.

  • domain regression covers symlink targets ending in / or /., with a directory-target control.

  • regressions failed before the fix: invalid paths were returned as resolved.

  • remaining proof gaps: no live macOS dyld oracle was run on this Windows host. the fixtures establish portable static behavior.

  • observed, derived, and inferred claims remain distinguishable.

  • artifact identity, source provenance, and failed attempts remain preserved.

  • unsupported, incomplete, unavailable, or uncertain outcomes remain visible.

validation performed

  • npm run test:local -- src/domain/apple/dylibResolution.test.ts — 84 passed.
  • node node_modules/vitest/vitest.mjs run tests/boundary/cli/dylibResolutionCli.test.ts -t 'traces every|resolves a standalone|reports unparsed|retains directory|reports embedded|retains definitive|distinguishes empty' — 7 passed, 2 excluded.
  • the new CLI regression also passed independently after its final placement change.
  • npm run verify:test-discovery — all 769 test files discovered exactly once.
  • npm run check — passed: typecheck, lint/module boundaries, formatting, knip, metadata, and architecture guards.

the full CLI file had two unchanged Windows failures before the production fix: narrows roots and architecture, and rejects escaping roots returned the wrong classification for an absolute Windows symlink target; reports an unreadable dependency as a permission failure did not fail after POSIX chmod on Windows. those cases were excluded from the portable selection above and remain unchanged.

compatibility, safety, and release

  • breaking changes or migration steps: none.
  • real Hopper/Ghidra, browser, or OS coverage: portable static fixtures on Windows; verify:macos-bundle unavailable on this host.
  • package or release metadata impact: none.
  • security, privacy, process, or containment review: no new target execution, filesystem writes, or authority.

review checklist

  • this pr addresses a concrete problem.
  • the pr has one focused outcome and a conventional title.
  • the reason for not linking an issue is stated above.
  • tests cover changed observable behavior and meaningful failure paths.
  • no owning docs, schemas, or generated metadata need changes.
  • representative CLI outcomes are described above.
  • the final diff contains no secrets, unrelated cleanup, or unsupported claims.

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/1623 **Author:** [@evenafterallisaid](https://github.com/evenafterallisaid) **Created:** 10/10/2026 **Status:** ✅ Merged **Merged:** 10/10/2026 **Merged by:** [@morluto](https://github.com/morluto) **Base:** `main` ← **Head:** `fix/dylib-directory-components` --- ### 📝 Commits (1) - [`8865fc0`](https://github.com/morluto/rea/commit/8865fc079c107c42d977b478d953b73fef406f48) fix(apple): preserve directory requirements in dylib paths ### 📊 Changes **4 files changed** (+110 additions, -4 deletions) <details> <summary>View changed files</summary> 📝 `src/domain/apple/dyldPaths.ts` (+7 -2) 📝 `src/domain/apple/dylibResolution.test.ts` (+43 -0) 📝 `src/domain/apple/dylibResolution.ts` (+1 -2) 📝 `tests/boundary/cli/dylibResolutionCli.test.ts` (+59 -0) </details> ### 📄 Description ## summary prevent `trace-dylib-resolution` from reporting a regular dylib as resolved when its dependency path requires a directory. ## problem and expected behavior `@loader_path/lib.dylib/` and `@loader_path/lib.dylib/.` incorrectly resolve to the existing regular file `lib.dylib`. the path tokenizer removes the directory requirement before examining the file. symlink targets have the same problem. additionally, a bare `@rpath/` loses its separator during candidate composition and can resolve a file-valued rpath. these candidates should be `absent`, with an `unresolved` edge and `required-load-unresolved` finding. [POSIX pathname resolution](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13) requires a trailing slash to name a directory. valid directory dot components and repeated separators should still resolve. no existing issue is linked: this was reproduced while looking for a contribution, and searches found no matching report or pr. ## change and scope retain dot components until traversal verifies the preceding entry is a directory. represent trailing slashes as a final dot traversal requirement, including in symlink targets. preserve the separator when composing rpath candidates with an empty suffix. ## contract and boundary impact - semantic owner and earliest changed stage: static dyld candidate composition and tree traversal. - CLI and MCP/tool-catalog contract: schemas unchanged; invalid file candidates now report the existing unresolved outcome. - provider, bridge, target-format, or platform compatibility: portable static Mach-O path resolution; no engine or bridge change. - evidence, artifact, provenance, or reconstruction contract: preserve declared install names and candidate paths; correct derived outcomes and findings. - process execution, authorization, cleanup, or containment impact: none. - generated metadata, package, or installation impact: none. ## evidence and regression coverage - public CLI regression uses byte-authored Mach-O files to check loader-path and rpath suffixes, empty rpath suffixes, successful directory dot paths, repeated separators, and findings. - domain regression covers symlink targets ending in `/` or `/.`, with a directory-target control. - regressions failed before the fix: invalid paths were returned as resolved. - remaining proof gaps: no live macOS dyld oracle was run on this Windows host. the fixtures establish portable static behavior. - [x] observed, derived, and inferred claims remain distinguishable. - [x] artifact identity, source provenance, and failed attempts remain preserved. - [x] unsupported, incomplete, unavailable, or uncertain outcomes remain visible. ## validation performed - `npm run test:local -- src/domain/apple/dylibResolution.test.ts` — 84 passed. - `node node_modules/vitest/vitest.mjs run tests/boundary/cli/dylibResolutionCli.test.ts -t 'traces every|resolves a standalone|reports unparsed|retains directory|reports embedded|retains definitive|distinguishes empty'` — 7 passed, 2 excluded. - the new CLI regression also passed independently after its final placement change. - `npm run verify:test-discovery` — all 769 test files discovered exactly once. - `npm run check` — passed: typecheck, lint/module boundaries, formatting, knip, metadata, and architecture guards. the full CLI file had two unchanged Windows failures before the production fix: `narrows roots and architecture, and rejects escaping roots` returned the wrong classification for an absolute Windows symlink target; `reports an unreadable dependency as a permission failure` did not fail after POSIX chmod on Windows. those cases were excluded from the portable selection above and remain unchanged. ## compatibility, safety, and release - breaking changes or migration steps: none. - real Hopper/Ghidra, browser, or OS coverage: portable static fixtures on Windows; `verify:macos-bundle` unavailable on this host. - package or release metadata impact: none. - security, privacy, process, or containment review: no new target execution, filesystem writes, or authority. ## review checklist - [x] this pr addresses a concrete problem. - [x] the pr has one focused outcome and a conventional title. - [x] the reason for not linking an issue is stated above. - [x] tests cover changed observable behavior and meaningful failure paths. - [x] no owning docs, schemas, or generated metadata need changes. - [x] representative CLI outcomes are described above. - [x] the final diff contains no secrets, unrelated cleanup, or unsupported claims. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-31 00:54:13 +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
morluto/rea#4708
No description provided.