[GH-ISSUE #8100] [Bug] Apple graph reports a null Info.plist for flattened macOS frameworks #4673

Closed
opened 2026-10-31 00:52:18 +00:00 by bsakaguchi · 0 comments
Owner

Originally created by @kaoru0822-kitauji on GitHub (Oct 30, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/8100

Originally assigned to: @kaoru0822-kitauji on GitHub.

Before submitting

  • I searched the open and closed issues for a related report.
  • I removed credentials, tokens, private paths, and sensitive target data.

Area

Evidence, artifacts, or reconstruction

Observed behavior

project_apple_application_graph reports info_plist_path: null for a macOS framework that has no Versions/ directory and keeps its Info.plist in Resources/. The projection still says coverage.status: "complete-within-inventory", and the result has no limitation explaining the null.

{
  "path": "Contents/Frameworks/Core.framework",
  "layout": "shallow",
  "role": "framework",
  "info_plist_path": null,
  "executable_candidates": ["Contents/Frameworks/Core.framework/Core"],
  "signing_paths": ["Contents/Frameworks/Core.framework/_CodeSignature/CodeResources"]
}

Real apps ship this layout. On this Mac, 5 frameworks in three installed third-party apps (one Electron app and two Gecko-based browsers) have it: _CodeSignature/, the binary, and Resources/Info.plist sit directly in the .framework, with no Versions/. All 5 projected as above, with info_plist_path: null. The four in the browsers were under complete-within-inventory coverage. The Electron app's projection was partial for an unrelated reason: it was inspected with --integrity-policy record-and-continue.

Reproduction

At origin/main 317bf3fe2, with the runtime built:

R=$(mktemp -d)
F="$R/Sample.app/Contents/Frameworks/Core.framework"
mkdir -p "$R/Sample.app/Contents/MacOS" "$F/Resources" "$F/_CodeSignature"
cp /usr/bin/true "$R/Sample.app/Contents/MacOS/Sample"
cp /usr/bin/true "$F/Core"
printf '<?xml version="1.0"?><plist version="1.0"><dict><key>CFBundleExecutable</key><string>Sample</string></dict></plist>' > "$R/Sample.app/Contents/Info.plist"
printf '<?xml version="1.0"?><plist version="1.0"><dict><key>CFBundleExecutable</key><string>Core</string></dict></plist>' > "$F/Resources/Info.plist"
printf '<plist version="1.0"><dict/></plist>' > "$F/_CodeSignature/CodeResources"
node scripts/rea.mjs inspect-artifact "$R/Sample.app" --format json > "$R/inspection.json"
python3 -c 'import json,sys; json.dump({"inventory_evidence":[json.load(open(sys.argv[1]))]}, open(sys.argv[2],"w"))' "$R/inspection.json" "$R/request.json"
node scripts/rea.mjs project-apple-application-graph "$R/request.json" --format json

It reproduced on every run (3 of 3), and also through the real apps described above.

Expected behavior

info_plist_path should be Contents/Frameworks/Core.framework/Resources/Info.plist. This is the layout CoreFoundation calls a version-0 ("Resources") bundle. Each Versions/<version>/ directory already uses it, and the projection resolves that case. A flattened framework is that same version directory without the Versions/ wrapper. A shallow iOS-style bundle with a root Info.plist should keep reporting the root plist.

Impact and scope

When this happens, info_plist_path is wrong under complete coverage. The tool's own guidance says to read info_plist_path with inspect_plist for CFBundleExecutable and identifiers, so agents have no plist to read for these frameworks. On this Mac that covers the main Electron runtime framework of one app and the update/channel frameworks of two browsers. Other projection fields (executable_candidates, signing_paths, roles) were correct for these bundles. I did not measure how common the layout is outside this Mac.

REA version

6.8.0 (source origin/main 317bf3fe2)

Runtime and platform

Node.js v26.5.0, macOS 26.7.1, arm64

Target and artifact context

macOS .app directory inventory (inspect-artifact), projected with project-apple-application-graph

Interface

CLI

Earliest failure stage

Transport or result projection

Relevant output or evidence

The JSON above comes from the reproduction script. The source behind it: infoPlistPath in src/domain/apple/appleBundleAnatomy.ts looks for Info.plist only at the bundle root for shallow layouts. It looks in Resources/ only for versioned-framework version directories.

Typed outcome or recovery expected

info_plist_path should be the existing Resources/Info.plist, with no change to coverage.

Analysis or suspected cause

This is source-derived. bundleLayout classifies a bundle with neither Contents/ nor Versions/ as shallow, and infoPlistPath then reads only <bundle>/Info.plist. The proposed fix keeps root-first precedence, falls back to Resources/Info.plist for shallow bundles, and keeps the ios platform rule tied to a root-level Info.plist.

Additional context

Related but distinct: #5727 and #3359 (bundle plist paths), and #4310 (opening nested bundles as targets).

Originally created by @kaoru0822-kitauji on GitHub (Oct 30, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/8100 Originally assigned to: @kaoru0822-kitauji on GitHub. ### Before submitting - [x] I searched the open and closed issues for a related report. - [x] I removed credentials, tokens, private paths, and sensitive target data. ### Area Evidence, artifacts, or reconstruction ### Observed behavior `project_apple_application_graph` reports `info_plist_path: null` for a macOS framework that has no `Versions/` directory and keeps its `Info.plist` in `Resources/`. The projection still says `coverage.status: "complete-within-inventory"`, and the result has no limitation explaining the null. ```json { "path": "Contents/Frameworks/Core.framework", "layout": "shallow", "role": "framework", "info_plist_path": null, "executable_candidates": ["Contents/Frameworks/Core.framework/Core"], "signing_paths": ["Contents/Frameworks/Core.framework/_CodeSignature/CodeResources"] } ``` Real apps ship this layout. On this Mac, 5 frameworks in three installed third-party apps (one Electron app and two Gecko-based browsers) have it: `_CodeSignature/`, the binary, and `Resources/Info.plist` sit directly in the `.framework`, with no `Versions/`. All 5 projected as above, with `info_plist_path: null`. The four in the browsers were under `complete-within-inventory` coverage. The Electron app's projection was `partial` for an unrelated reason: it was inspected with `--integrity-policy record-and-continue`. ### Reproduction At `origin/main` 317bf3fe2, with the runtime built: ```sh R=$(mktemp -d) F="$R/Sample.app/Contents/Frameworks/Core.framework" mkdir -p "$R/Sample.app/Contents/MacOS" "$F/Resources" "$F/_CodeSignature" cp /usr/bin/true "$R/Sample.app/Contents/MacOS/Sample" cp /usr/bin/true "$F/Core" printf '<?xml version="1.0"?><plist version="1.0"><dict><key>CFBundleExecutable</key><string>Sample</string></dict></plist>' > "$R/Sample.app/Contents/Info.plist" printf '<?xml version="1.0"?><plist version="1.0"><dict><key>CFBundleExecutable</key><string>Core</string></dict></plist>' > "$F/Resources/Info.plist" printf '<plist version="1.0"><dict/></plist>' > "$F/_CodeSignature/CodeResources" node scripts/rea.mjs inspect-artifact "$R/Sample.app" --format json > "$R/inspection.json" python3 -c 'import json,sys; json.dump({"inventory_evidence":[json.load(open(sys.argv[1]))]}, open(sys.argv[2],"w"))' "$R/inspection.json" "$R/request.json" node scripts/rea.mjs project-apple-application-graph "$R/request.json" --format json ``` It reproduced on every run (3 of 3), and also through the real apps described above. ### Expected behavior `info_plist_path` should be `Contents/Frameworks/Core.framework/Resources/Info.plist`. This is the layout CoreFoundation calls a version-0 ("Resources") bundle. Each `Versions/<version>/` directory already uses it, and the projection resolves that case. A flattened framework is that same version directory without the `Versions/` wrapper. A shallow iOS-style bundle with a root `Info.plist` should keep reporting the root plist. ### Impact and scope When this happens, `info_plist_path` is wrong under complete coverage. The tool's own guidance says to read `info_plist_path` with `inspect_plist` for `CFBundleExecutable` and identifiers, so agents have no plist to read for these frameworks. On this Mac that covers the main Electron runtime framework of one app and the update/channel frameworks of two browsers. Other projection fields (`executable_candidates`, `signing_paths`, roles) were correct for these bundles. I did not measure how common the layout is outside this Mac. ### REA version 6.8.0 (source `origin/main` 317bf3fe2) ### Runtime and platform Node.js v26.5.0, macOS 26.7.1, arm64 ### Target and artifact context macOS `.app` directory inventory (`inspect-artifact`), projected with `project-apple-application-graph` ### Interface CLI ### Earliest failure stage Transport or result projection ### Relevant output or evidence The JSON above comes from the reproduction script. The source behind it: `infoPlistPath` in `src/domain/apple/appleBundleAnatomy.ts` looks for `Info.plist` only at the bundle root for `shallow` layouts. It looks in `Resources/` only for `versioned-framework` version directories. ### Typed outcome or recovery expected `info_plist_path` should be the existing `Resources/Info.plist`, with no change to coverage. ### Analysis or suspected cause This is source-derived. `bundleLayout` classifies a bundle with neither `Contents/` nor `Versions/` as `shallow`, and `infoPlistPath` then reads only `<bundle>/Info.plist`. The proposed fix keeps root-first precedence, falls back to `Resources/Info.plist` for shallow bundles, and keeps the `ios` platform rule tied to a root-level `Info.plist`. ### Additional context Related but distinct: #5727 and #3359 (bundle plist paths), and #4310 (opening nested bundles as targets).
bsakaguchi 2026-10-31 00:52:18 +00:00
  • closed this issue
  • added the
    bug
    label
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#4673
No description provided.