[PR #1159] [MERGED] fix(apple): report unusable dylib-resolution roots as invalid input #2693

Closed
opened 2026-10-17 21:09:08 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/1159
Author: @kaoru0822-kitauji
Created: 10/9/2026
Status: ✅ Merged
Merged: 10/9/2026
Merged by: @kaoru0822-kitauji

Base: main ← Head: fix/dylib-resolution-root-input-errors


📝 Commits (1)

  • 24a30fd fix(apple): report unusable dylib-resolution roots as invalid input

📊 Changes

4 files changed (+132 additions, -28 deletions)

View changed files

📝 src/artifacts/apple/DylibResolutionReader.ts (+28 -14)
📝 src/domain/apple/dylibResolution.ts (+7 -1)
📝 tests/boundary/cli/dylibResolutionCli.test.ts (+46 -12)
📝 tests/boundary/mcp/dylibResolutionMcp.test.ts (+51 -1)

📄 Description

Problem

trace_dylib_resolution reports the caller's roots selection as a fault in the artifact. I reproduced this on main with /Applications/Transmission.app:

--root Before
Contents/MacOS/Nope (missing) or Contents/Resources (directory) artifact_operation_failed / path: "Artifact contains an unsafe or conflicting internal path… correct the artifact before retrying."
Contents/Info.plist (not Mach-O) artifact_operation_failed / format: "Artifact is invalid or has changed. Get a fresh copy and try again."
a symlink leading outside the bundle same "unsafe internal path… correct the artifact"
../Other.app/x (not normalized) "roots must be normalized paths relative to the analyzed root", reported the same way

Every schema failure took that last path, including an invalid architecture, so the reported constraint could be the wrong one.

This is the same misclassification #1070 fixed for inspect_keyed_archive, where ArtifactProvider already passes AnalysisInputError through.

Change

  • A root the caller selected that is outside the bundle, not a regular file, or not a Mach-O becomes an invalid_request issue on ["roots", i], with the failed constraint as its message.
  • Roots REA derives itself (the bundle's executables, or the active target) keep reporting artifact failures, because a failure there isn't the caller's input.
  • Schema failures are projected through their real Zod issues (projectInputIssues). The normalized-path rule now has a readable message: "Use a normalized path relative to the analyzed root, without a leading or trailing '/', '//', or '.' and '..' segments". The advertised JSON Schema is unchanged; I checked it with z.toJSONSchema.

Sanitized result for --root Contents/Info.plist:

{"code":"invalid_request","category":"invalid_input","details":{"operation":"trace_dylib_resolution","issues":[{"path":["roots",0],"reason":"invalid_value","message":"Root Contents/Info.plist is not a Mach-O image"}]}}

Verification

  • tests/boundary/mcp/dylibResolutionMcp.test.ts gains a new case for missing, directory, non-Mach-O and escaping-symlink roots.
  • tests/boundary/cli/dylibResolutionCli.test.ts already rejected three roots but checked only for a generic failure; it now asserts the issue path, reason and message for each. Both fail on main.
  • All 13 test files that reference dylib resolution or ArtifactProvider: 251 passed.
  • npm run check:fast, npm run jscpd (2.49%)
  • Ran the CLI against /Applications/Transmission.app with the roots in the table. A valid trace is unchanged.

No real Hopper or Ghidra verification was run, because this change does not touch those providers.

🤖 Generated with Claude Code


🔄 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/1159 **Author:** [@kaoru0822-kitauji](https://github.com/kaoru0822-kitauji) **Created:** 10/9/2026 **Status:** ✅ Merged **Merged:** 10/9/2026 **Merged by:** [@kaoru0822-kitauji](https://github.com/kaoru0822-kitauji) **Base:** `main` ← **Head:** `fix/dylib-resolution-root-input-errors` --- ### 📝 Commits (1) - [`24a30fd`](https://github.com/morluto/rea/commit/24a30fd91c144b7f2533e5f5de8c91268773519c) fix(apple): report unusable dylib-resolution roots as invalid input ### 📊 Changes **4 files changed** (+132 additions, -28 deletions) <details> <summary>View changed files</summary> 📝 `src/artifacts/apple/DylibResolutionReader.ts` (+28 -14) 📝 `src/domain/apple/dylibResolution.ts` (+7 -1) 📝 `tests/boundary/cli/dylibResolutionCli.test.ts` (+46 -12) 📝 `tests/boundary/mcp/dylibResolutionMcp.test.ts` (+51 -1) </details> ### 📄 Description ## Problem `trace_dylib_resolution` reports the caller's `roots` selection as a fault in the artifact. I reproduced this on `main` with `/Applications/Transmission.app`: | `--root` | Before | |---|---| | `Contents/MacOS/Nope` (missing) or `Contents/Resources` (directory) | `artifact_operation_failed` / `path`: "Artifact contains an unsafe or conflicting internal path… correct the artifact before retrying." | | `Contents/Info.plist` (not Mach-O) | `artifact_operation_failed` / `format`: "Artifact is invalid or has changed. Get a fresh copy and try again." | | a symlink leading outside the bundle | same "unsafe internal path… correct the artifact" | | `../Other.app/x` (not normalized) | "roots must be normalized paths relative to the analyzed root", reported the same way | Every schema failure took that last path, including an invalid `architecture`, so the reported constraint could be the wrong one. This is the same misclassification #1070 fixed for `inspect_keyed_archive`, where `ArtifactProvider` already passes `AnalysisInputError` through. ## Change - A root the caller selected that is outside the bundle, not a regular file, or not a Mach-O becomes an `invalid_request` issue on `["roots", i]`, with the failed constraint as its message. - Roots REA derives itself (the bundle's executables, or the active target) keep reporting artifact failures, because a failure there isn't the caller's input. - Schema failures are projected through their real Zod issues (`projectInputIssues`). The normalized-path rule now has a readable message: "Use a normalized path relative to the analyzed root, without a leading or trailing '/', '//', or '.' and '..' segments". The advertised JSON Schema is unchanged; I checked it with `z.toJSONSchema`. Sanitized result for `--root Contents/Info.plist`: ```json {"code":"invalid_request","category":"invalid_input","details":{"operation":"trace_dylib_resolution","issues":[{"path":["roots",0],"reason":"invalid_value","message":"Root Contents/Info.plist is not a Mach-O image"}]}} ``` ## Verification - `tests/boundary/mcp/dylibResolutionMcp.test.ts` gains a new case for missing, directory, non-Mach-O and escaping-symlink roots. - `tests/boundary/cli/dylibResolutionCli.test.ts` already rejected three roots but checked only for a generic failure; it now asserts the issue path, reason and message for each. Both fail on `main`. - All 13 test files that reference dylib resolution or `ArtifactProvider`: 251 passed. - `npm run check:fast`, `npm run jscpd` (2.49%) - Ran the CLI against `/Applications/Transmission.app` with the roots in the table. A valid trace is unchanged. No real Hopper or Ghidra verification was run, because this change does not touch those providers. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-17 21:09:08 +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#2693
No description provided.