[GH-ISSUE #4304] [Feature] Inspect privacy manifests and cross-check required-reason API imports per bundle #1708

Open
opened 2026-10-16 21:09:18 +00:00 by bsakaguchi · 0 comments
Owner

Originally created by @coygeek on GitHub (Oct 16, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/4304

Before submitting

  • I searched the open and closed issues and pull requests for a related proposal.
  • I understand the contribution scope must be reviewed before integration; open questions are welcome here.
  • This request does not include credentials, private samples, or sensitive target data.

Area

Native analysis or decompilation

Current limitation

Add an execution-free Apple operation that finds every PrivacyInfo.xcprivacy in an app by bundle location, validates it against Apple's closed value sets and validity rules, and cross-checks each Mach-O's imported required-reason API symbols against the manifest of the bundle that contains it, reporting matches, missing declarations, and unknowns, qualified by platform.

An analyst examining an iOS or macOS app wants to know what each component declares about tracking, collected data, and required-reason APIs, whether those declarations are valid, and whether each bundle's code imports covered APIs its manifest does not declare. REA cannot answer any part of this.

At release rea-agents-6.5.0 (commit 3b79af28e80785afce9f5998d8f03289402a1847), git grep -i for xcprivacy, NSPrivacy, PrivacyInfo, and privacy manifest finds nothing, and current main adds nothing. The reachable pieces do not interpret the file:

Observed on macOS 27.0.1 (26A434) arm64, Xcode 27.0 (27A266a), npx -y rea-agents@6.5.0 (--version prints 6.5.0): a self-built iOS-family ./fixture/Fixture.app whose executable imports _stat, _statfs, and _mach_absolute_time has a root manifest with NSPrivacyTracking true and empty NSPrivacyTrackingDomains, the data type NSPrivacyCollectedDataTypePhotosOrVideos (Apple spells it PhotosorVideos), and the DiskSpace reason 85F4.1 under NSPrivacyAccessedAPICategoryFileTimestamp. rea inspect-plist ./fixture/Fixture.app --relative-path PrivacyInfo.xcprivacy returned the dictionary unchanged with "limitations":[] and no verdict on any of the three invalid values; rea inspect-macho ./fixture/Fixture.app listed the imports with no sign that _statfs (DiskSpace) is undeclared.

Use cases

No response

Desired outcome and success criteria

A new operation or a mode of an existing Apple tool (maintainers' choice), on CLI and MCP, accepts an app directory or IPA and returns one Evidence record with coverage, limitations, and provenance:

  • Bundles and manifests. For the app and each nested code bundle REA already recognizes (frameworks, app extensions, XPC services, plug-ins), report the path, kind, platform from Mach-O build metadata, the expected manifest location per Apple's location table (bundle root on iOS-family platforms, Contents/Resources/ for macOS apps, Versions/<current>/Resources/ for macOS frameworks), and whether a manifest is there (path, SHA-256) or absent. A PrivacyInfo.xcprivacy anywhere else is listed as unattributed.
  • Validation. Per finding: key path, observed value, verdict, and the Apple rule applied. Rules: top-level types; NSPrivacyTracking and NSPrivacyTrackingDomains consistency; domain shape; accessed-API dictionaries with exactly two keys, a known category, and a non-empty reasons array valid for that category; collected-data dictionaries with exactly four keys, a known data type, Boolean Linked and Tracking, and known purposes. Matching is exact and case-sensitive (NSPrivacyCollectedDataTypePhotosorVideos is valid; PhotosOrVideos is not). Because Apple updates its lists, an unknown value is reported as "not in the documented value set" with the table's source and date. A file that does not decode as a property list is an invalid property list with no per-key verdicts.
  • Required-reason cross-check. For each Mach-O slice, map imported C symbols to categories (normalizing variants such as the x86_64 $INODE64 suffix, observed with Xcode 27 clang) and compare them with the manifest of the containing bundle; a loose dylib is covered by the bundle that contains it. Each hit is declared, missing, category_ambiguous, or not_established. getattrlist, fgetattrlist, and getattrlistat belong to both FileTimestamp and DiskSpace, so a hit lists both: missing when neither is declared, category_ambiguous when only one is. A declared category with no matching import is "declared, no import observed", not an error.
  • Unknowns stay unknown. Property-level Swift and Objective-C APIs in Apple's lists (UserDefaults, creationDate, systemUptime, activeInputModes, volume-capacity URL keys) cannot be established from imports. They are not_established; an indicative reference may appear as a hint, never as declared or missing.
  • Platform qualification. Required-reason results carry applicability: required for iOS, iPadOS, tvOS, visionOS, and watchOS; not_required for macOS, with a limitation quoting Apple's platform list; unknown for absent or conflicting build metadata and for Mac Catalyst, which Apple's list does not name. Validity and collected-data results apply on every platform.
  • Stated limitations. Imports are not exhaustive (no dlsym lookups, inline system calls, or stripped metadata), and statically linked SDK code merges into its containing executable, so a hit cannot be attributed to the SDK.

Acceptance criteria

Fixture, built with stock Xcode tools (dyld_info -imports confirms each import):

xcrun --sdk iphoneos clang -target arm64-apple-ios17.0 -o ./fixture/Fixture.app/Fixture main.c   # calls stat, statfs, mach_absolute_time
xcrun --sdk iphoneos clang -target arm64-apple-ios17.0 -dynamiclib -o ./fixture/Fixture.app/Frameworks/Lib.framework/Lib lib.c   # calls getattrlist; no manifest
clang -target arm64-apple-macos14 -o ./fixture/Mac.app/Contents/MacOS/Mac main.c   # no manifest
  • On ./fixture/Fixture.app, the app's manifest is found at the root and Lib.framework's is absent. Moving the app's manifest to Fixture.app/Resources/ makes it absent and lists the moved file as unattributed.
  • With the manifest from Current limitation, three invalid findings appear with key path, value, and rule: tracking true with empty domains (TN3181), NSPrivacyCollectedDataTypePhotosOrVideos outside the documented set, and 85F4.1 invalid for FileTimestamp. Changing the data type to NSPrivacyCollectedDataTypePhotosorVideos clears only that finding.
  • A third key in an accessed-API dictionary, a collected-data dictionary without NSPrivacyCollectedDataTypeTracking, and an empty reasons array each produce one finding citing TN3183, TN3184, or TN3181 respectively.
  • For Fixture, _mach_absolute_time is declared (SystemBootTime), _stat is declared (FileTimestamp, with that entry's invalid-reason finding linked), and _statfs is missing (DiskSpace). For Lib, _getattrlist is missing with candidates FileTimestamp and DiskSpace. After a root manifest declaring only FileTimestamp C617.1 is added to Lib.framework, _getattrlist becomes category_ambiguous.
  • Declaring NSPrivacyAccessedAPICategoryUserDefaults with CA92.1 yields "declared, no import observed" with a not_established limitation and no error.
  • For ./fixture/Mac.app, the same imports are reported with applicability not_required and a limitation naming the iOS-family platforms; a manifest at Contents/Resources/PrivacyInfo.xcprivacy is found and validated.
  • Rebuilding Mac with -target x86_64-apple-macos11 (imports _stat$INODE64 and _statfs$INODE64) yields the same category mapping as the arm64 build.
  • A manifest replaced with non-plist bytes yields one invalid-property-list finding and no per-key verdicts; other bundles are still reported.
  • Every result names the value-set source and date and states the import-coverage and static-linking limitations.

Expected interaction with targets

Read existing files or captured data

Target and scope details (optional)

Affected area

Apple static analysis on the MCP and CLI surfaces: Mach-O import and build-metadata reading, nested-bundle discovery, and a new typed privacy-manifest Evidence result. Validation and the import cross-check stay one issue because both rest on the same per-bundle manifest attribution and Evidence record, and the cross-check links each declared hit to that entry's validation findings.

Non-goals

  • Interpreting general Info.plist keys, including NS*UsageDescription privacy strings.
  • Accepting nested bundle directories as direct targets of the existing single-file tools, and flagging Mach-O code outside documented bundle code locations.
  • App Store policy judgments beyond the documented validity rules, such as whether a declared reason truthfully describes use, SDK signature requirements, or ITMS submission outcomes.
  • Identifying third-party SDKs or applying Apple's list of SDKs that need a manifest.
  • XCFramework distribution bundles, Swift package source trees, and Xcode's privacy report.
  • Observing API calls at runtime or launching the target.

Verification available so far

I can suggest a sample or manual check

Verification details (optional)

No response

Alternatives considered

  • Run inspect_plist on each manifest path and inspect_macho on each Mach-O, then compare by hand. The analyst must apply Apple's location table, value sets, and reason codes per bundle, and nothing records the result as Evidence.
  • Use Xcode's Generate Privacy Report. It aggregates manifests from an Xcode archive in the Organizer, which an analyst of a shipped bundle usually lacks, and it does not compare manifests with imported symbols.

Possible direction

No response

References

  • Privacy manifest files: PrivacyInfo.xcprivacy "is the required file name for bundled privacy manifests"; collected data types are required "on all platforms" and required reasons APIs "on iOS, iPadOS, tvOS, visionOS, and watchOS".
  • Adding a privacy manifest to your app or third-party SDK: iOS-family apps and frameworks place it "at the root", macOS and Mac Catalyst apps in Contents/Resources/, macOS frameworks in Versions/A/Resources/; "All privacy manifest files in your app must be valid, containing only the expected keys and values."
  • Describing use of required reason API: "For each executable or dynamic library in an app that uses a required reason API, the bundle that includes the executable or dynamic library needs to include a privacy manifest file that reports the API." Apple "will update this article from time to time."
  • Placing content in a bundle: its privacy manifest row gives Contents/Resources/, Versions/A/Resources/, and / for macOS, macOS framework, and iOS-family bundles.
  • NSPrivacyAccessedAPIType and NSPrivacyAccessedAPITypeReasons: five categories and seventeen reason codes. FileTimestamp covers getattrlist, getattrlistbulk, fgetattrlist, getattrlistat, stat, fstat, fstatat, lstat; DiskSpace covers statfs, statvfs, fstatfs, fstatvfs, getattrlist, fgetattrlist, getattrlistat; SystemBootTime covers systemUptime and mach_absolute_time().
  • NSPrivacyCollectedDataType and NSPrivacyCollectedDataTypePurposes: 35 data types, including NSPrivacyCollectedDataTypePhotosorVideos, and six purposes.
  • TN3181: invalid means "invalid keys or values" or "an improperly formatted property list file"; it gives the tracking and domain consistency rules (a domain "Contains no path and query components" and "Contains no trailing slash") and the empty and mismatched reasons rules.
  • TN3183: the accessed-API dictionary "contains exactly two keys". TN3184: the collected-data dictionary "contains exactly four keys".
  • REA already recognizes nested bundle extensions by path (appleBundleAnatomy.ts#L8-L9).
  • Related: #3289 asks broadly for iOS application support; this is one concrete static capability for both iOS and macOS bundles. GitHub search finds no issue or PR about privacy manifests, xcprivacy, or required-reason APIs.
Originally created by @coygeek on GitHub (Oct 16, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/4304 ### Before submitting - [X] I searched the open and closed issues and pull requests for a related proposal. - [X] I understand the [contribution scope](https://github.com/morluto/rea/blob/main/CONTRIBUTING.md#contribution-scope) must be reviewed before integration; open questions are welcome here. - [X] This request does not include credentials, private samples, or sensitive target data. ### Area Native analysis or decompilation ### Current limitation Add an execution-free Apple operation that finds every `PrivacyInfo.xcprivacy` in an app by bundle location, validates it against Apple's closed value sets and validity rules, and cross-checks each Mach-O's imported required-reason API symbols against the manifest of the bundle that contains it, reporting matches, missing declarations, and unknowns, qualified by platform. An analyst examining an iOS or macOS app wants to know what each component declares about tracking, collected data, and required-reason APIs, whether those declarations are valid, and whether each bundle's code imports covered APIs its manifest does not declare. REA cannot answer any part of this. At release `rea-agents-6.5.0` (commit `3b79af28e80785afce9f5998d8f03289402a1847`), `git grep -i` for `xcprivacy`, `NSPrivacy`, `PrivacyInfo`, and `privacy manifest` finds nothing, and current `main` adds nothing. The reachable pieces do not interpret the file: - `inspect_plist` parses a manifest when the caller passes its path, but it returns the decoded value verbatim and only projects five `CFBundle*` keys ([NativeMacOSProvider.ts#L819-L834](https://github.com/morluto/rea/blob/3b79af28e80785afce9f5998d8f03289402a1847/src/native/NativeMacOSProvider.ts#L819-L834), [plist.ts#L252-L266](https://github.com/morluto/rea/blob/3b79af28e80785afce9f5998d8f03289402a1847/src/native/parsers/plist.ts#L252-L266)). - Artifact inventory classifies a `.xcprivacy` file as a generic `resource` ([ArtifactGraphConstruction.ts#L463-L466](https://github.com/morluto/rea/blob/3b79af28e80785afce9f5998d8f03289402a1847/src/artifacts/inventory/ArtifactGraphConstruction.ts#L463-L466)), or as `framework` when its path lies inside a `.framework/` directory ([L456-L457](https://github.com/morluto/rea/blob/3b79af28e80785afce9f5998d8f03289402a1847/src/artifacts/inventory/ArtifactGraphConstruction.ts#L456-L457)), and the Apple application graph states that it "reports only exact paths and hashes" ([appleApplication.ts#L449](https://github.com/morluto/rea/blob/3b79af28e80785afce9f5998d8f03289402a1847/src/domain/apple/appleApplication.ts#L449)). - `inspect_macho` lists imports, marked `exhaustive: false` ([NativeMachoInspection.ts#L279-L281](https://github.com/morluto/rea/blob/3b79af28e80785afce9f5998d8f03289402a1847/src/native/NativeMachoInspection.ts#L279-L281)), but nothing relates them to a manifest. Observed on macOS 27.0.1 (26A434) arm64, Xcode 27.0 (27A266a), `npx -y rea-agents@6.5.0` (`--version` prints `6.5.0`): a self-built iOS-family `./fixture/Fixture.app` whose executable imports `_stat`, `_statfs`, and `_mach_absolute_time` has a root manifest with `NSPrivacyTracking` `true` and empty `NSPrivacyTrackingDomains`, the data type `NSPrivacyCollectedDataTypePhotosOrVideos` (Apple spells it `PhotosorVideos`), and the DiskSpace reason `85F4.1` under `NSPrivacyAccessedAPICategoryFileTimestamp`. `rea inspect-plist ./fixture/Fixture.app --relative-path PrivacyInfo.xcprivacy` returned the dictionary unchanged with `"limitations":[]` and no verdict on any of the three invalid values; `rea inspect-macho ./fixture/Fixture.app` listed the imports with no sign that `_statfs` (DiskSpace) is undeclared. ### Use cases _No response_ ### Desired outcome and success criteria A new operation or a mode of an existing Apple tool (maintainers' choice), on CLI and MCP, accepts an app directory or IPA and returns one Evidence record with coverage, limitations, and provenance: - **Bundles and manifests.** For the app and each nested code bundle REA already recognizes (frameworks, app extensions, XPC services, plug-ins), report the path, kind, platform from Mach-O build metadata, the expected manifest location per Apple's location table (bundle root on iOS-family platforms, `Contents/Resources/` for macOS apps, `Versions/<current>/Resources/` for macOS frameworks), and whether a manifest is there (path, SHA-256) or absent. A `PrivacyInfo.xcprivacy` anywhere else is listed as unattributed. - **Validation.** Per finding: key path, observed value, verdict, and the Apple rule applied. Rules: top-level types; `NSPrivacyTracking` and `NSPrivacyTrackingDomains` consistency; domain shape; accessed-API dictionaries with exactly two keys, a known category, and a non-empty reasons array valid for that category; collected-data dictionaries with exactly four keys, a known data type, Boolean `Linked` and `Tracking`, and known purposes. Matching is exact and case-sensitive (`NSPrivacyCollectedDataTypePhotosorVideos` is valid; `PhotosOrVideos` is not). Because Apple updates its lists, an unknown value is reported as "not in the documented value set" with the table's source and date. A file that does not decode as a property list is an invalid property list with no per-key verdicts. - **Required-reason cross-check.** For each Mach-O slice, map imported C symbols to categories (normalizing variants such as the x86_64 `$INODE64` suffix, observed with Xcode 27 clang) and compare them with the manifest of the containing bundle; a loose dylib is covered by the bundle that contains it. Each hit is `declared`, `missing`, `category_ambiguous`, or `not_established`. `getattrlist`, `fgetattrlist`, and `getattrlistat` belong to both FileTimestamp and DiskSpace, so a hit lists both: `missing` when neither is declared, `category_ambiguous` when only one is. A declared category with no matching import is "declared, no import observed", not an error. - **Unknowns stay unknown.** Property-level Swift and Objective-C APIs in Apple's lists (`UserDefaults`, `creationDate`, `systemUptime`, `activeInputModes`, volume-capacity URL keys) cannot be established from imports. They are `not_established`; an indicative reference may appear as a hint, never as `declared` or `missing`. - **Platform qualification.** Required-reason results carry applicability: `required` for iOS, iPadOS, tvOS, visionOS, and watchOS; `not_required` for macOS, with a limitation quoting Apple's platform list; `unknown` for absent or conflicting build metadata and for Mac Catalyst, which Apple's list does not name. Validity and collected-data results apply on every platform. - **Stated limitations.** Imports are not exhaustive (no `dlsym` lookups, inline system calls, or stripped metadata), and statically linked SDK code merges into its containing executable, so a hit cannot be attributed to the SDK. **Acceptance criteria** Fixture, built with stock Xcode tools (`dyld_info -imports` confirms each import): ```sh xcrun --sdk iphoneos clang -target arm64-apple-ios17.0 -o ./fixture/Fixture.app/Fixture main.c # calls stat, statfs, mach_absolute_time xcrun --sdk iphoneos clang -target arm64-apple-ios17.0 -dynamiclib -o ./fixture/Fixture.app/Frameworks/Lib.framework/Lib lib.c # calls getattrlist; no manifest clang -target arm64-apple-macos14 -o ./fixture/Mac.app/Contents/MacOS/Mac main.c # no manifest ``` - [ ] On `./fixture/Fixture.app`, the app's manifest is found at the root and `Lib.framework`'s is absent. Moving the app's manifest to `Fixture.app/Resources/` makes it absent and lists the moved file as unattributed. - [ ] With the manifest from Current limitation, three invalid findings appear with key path, value, and rule: tracking `true` with empty domains (TN3181), `NSPrivacyCollectedDataTypePhotosOrVideos` outside the documented set, and `85F4.1` invalid for FileTimestamp. Changing the data type to `NSPrivacyCollectedDataTypePhotosorVideos` clears only that finding. - [ ] A third key in an accessed-API dictionary, a collected-data dictionary without `NSPrivacyCollectedDataTypeTracking`, and an empty reasons array each produce one finding citing TN3183, TN3184, or TN3181 respectively. - [ ] For `Fixture`, `_mach_absolute_time` is `declared` (SystemBootTime), `_stat` is `declared` (FileTimestamp, with that entry's invalid-reason finding linked), and `_statfs` is `missing` (DiskSpace). For `Lib`, `_getattrlist` is `missing` with candidates FileTimestamp and DiskSpace. After a root manifest declaring only FileTimestamp `C617.1` is added to `Lib.framework`, `_getattrlist` becomes `category_ambiguous`. - [ ] Declaring `NSPrivacyAccessedAPICategoryUserDefaults` with `CA92.1` yields "declared, no import observed" with a `not_established` limitation and no error. - [ ] For `./fixture/Mac.app`, the same imports are reported with applicability `not_required` and a limitation naming the iOS-family platforms; a manifest at `Contents/Resources/PrivacyInfo.xcprivacy` is found and validated. - [ ] Rebuilding `Mac` with `-target x86_64-apple-macos11` (imports `_stat$INODE64` and `_statfs$INODE64`) yields the same category mapping as the arm64 build. - [ ] A manifest replaced with non-plist bytes yields one invalid-property-list finding and no per-key verdicts; other bundles are still reported. - [ ] Every result names the value-set source and date and states the import-coverage and static-linking limitations. ### Expected interaction with targets Read existing files or captured data ### Target and scope details (optional) **Affected area** Apple static analysis on the MCP and CLI surfaces: Mach-O import and build-metadata reading, nested-bundle discovery, and a new typed privacy-manifest Evidence result. Validation and the import cross-check stay one issue because both rest on the same per-bundle manifest attribution and Evidence record, and the cross-check links each `declared` hit to that entry's validation findings. **Non-goals** - Interpreting general `Info.plist` keys, including `NS*UsageDescription` privacy strings. - Accepting nested bundle directories as direct targets of the existing single-file tools, and flagging Mach-O code outside documented bundle code locations. - App Store policy judgments beyond the documented validity rules, such as whether a declared reason truthfully describes use, SDK signature requirements, or ITMS submission outcomes. - Identifying third-party SDKs or applying Apple's list of SDKs that need a manifest. - XCFramework distribution bundles, Swift package source trees, and Xcode's privacy report. - Observing API calls at runtime or launching the target. ### Verification available so far I can suggest a sample or manual check ### Verification details (optional) _No response_ ### Alternatives considered - Run `inspect_plist` on each manifest path and `inspect_macho` on each Mach-O, then compare by hand. The analyst must apply Apple's location table, value sets, and reason codes per bundle, and nothing records the result as Evidence. - Use Xcode's Generate Privacy Report. It aggregates manifests from an Xcode archive in the Organizer, which an analyst of a shipped bundle usually lacks, and it does not compare manifests with imported symbols. ### Possible direction _No response_ ### References - [Privacy manifest files](https://developer.apple.com/documentation/bundleresources/privacy-manifest-files): `PrivacyInfo.xcprivacy` "is the required file name for bundled privacy manifests"; collected data types are required "on all platforms" and required reasons APIs "on iOS, iPadOS, tvOS, visionOS, and watchOS". - [Adding a privacy manifest to your app or third-party SDK](https://developer.apple.com/documentation/bundleresources/adding-a-privacy-manifest-to-your-app-or-third-party-sdk): iOS-family apps and frameworks place it "at the root", macOS and Mac Catalyst apps in `Contents/Resources/`, macOS frameworks in `Versions/A/Resources/`; "All privacy manifest files in your app must be valid, containing only the expected keys and values." - [Describing use of required reason API](https://developer.apple.com/documentation/bundleresources/describing-use-of-required-reason-api): "For each executable or dynamic library in an app that uses a required reason API, the bundle that includes the executable or dynamic library needs to include a privacy manifest file that reports the API." Apple "will update this article from time to time." - [Placing content in a bundle](https://developer.apple.com/documentation/bundleresources/placing-content-in-a-bundle): its privacy manifest row gives `Contents/Resources/`, `Versions/A/Resources/`, and `/` for macOS, macOS framework, and iOS-family bundles. - [NSPrivacyAccessedAPIType](https://developer.apple.com/documentation/bundleresources/app-privacy-configuration/nsprivacyaccessedapitypes/nsprivacyaccessedapitype) and [NSPrivacyAccessedAPITypeReasons](https://developer.apple.com/documentation/bundleresources/app-privacy-configuration/nsprivacyaccessedapitypes/nsprivacyaccessedapitypereasons): five categories and seventeen reason codes. FileTimestamp covers `getattrlist`, `getattrlistbulk`, `fgetattrlist`, `getattrlistat`, `stat`, `fstat`, `fstatat`, `lstat`; DiskSpace covers `statfs`, `statvfs`, `fstatfs`, `fstatvfs`, `getattrlist`, `fgetattrlist`, `getattrlistat`; SystemBootTime covers `systemUptime` and `mach_absolute_time()`. - [NSPrivacyCollectedDataType](https://developer.apple.com/documentation/bundleresources/app-privacy-configuration/nsprivacycollecteddatatypes/nsprivacycollecteddatatype) and [NSPrivacyCollectedDataTypePurposes](https://developer.apple.com/documentation/bundleresources/app-privacy-configuration/nsprivacycollecteddatatypes/nsprivacycollecteddatatypepurposes): 35 data types, including `NSPrivacyCollectedDataTypePhotosorVideos`, and six purposes. - [TN3181](https://developer.apple.com/documentation/technotes/tn3181-debugging-invalid-privacy-manifest): invalid means "invalid keys or values" or "an improperly formatted property list file"; it gives the tracking and domain consistency rules (a domain "Contains no path and query components" and "Contains no trailing slash") and the empty and mismatched reasons rules. - [TN3183](https://developer.apple.com/documentation/technotes/tn3183-adding-required-reason-api-entries-to-your-privacy-manifest): the accessed-API dictionary "contains exactly two keys". [TN3184](https://developer.apple.com/documentation/technotes/tn3184-adding-data-collection-details-to-your-privacy-manifest): the collected-data dictionary "contains exactly four keys". - REA already recognizes nested bundle extensions by path ([appleBundleAnatomy.ts#L8-L9](https://github.com/morluto/rea/blob/3b79af28e80785afce9f5998d8f03289402a1847/src/domain/apple/appleBundleAnatomy.ts#L8-L9)). - Related: #3289 asks broadly for iOS application support; this is one concrete static capability for both iOS and macOS bundles. GitHub search finds no issue or PR about privacy manifests, `xcprivacy`, or required-reason APIs.
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#1708
No description provided.