[GH-ISSUE #4779] [Bug] Apple projection invents application roots from leaf file names #2483

Closed
opened 2026-10-17 21:05:29 +00:00 by bsakaguchi · 1 comment
Owner

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

Before submitting

  • I searched open and closed reports for related application-root/Contents failures.
  • This report contains only authored fixture paths and no credentials.

Area

Evidence, artifacts, or reconstruction

Observed behavior

The built public CLI invents application_roots: ["Fake.app"] from a ZIP whose only member is the regular file Fake.app/Contents. Both inspect-artifact and project-apple-application-graph succeed. Inventory explicitly preserves entry_kind: "file"; the projection treats the leaf name as evidence of a bundle's directory layout.

Reproduction

Executed once using an authored ZIP written by zip.js:

  1. Write Fixture.zip with only Fake.app/Contents, containing ordinary resource as a regular file.
  2. Run node scripts/rea.mjs inspect-artifact Fixture.zip --json.
  3. Save { "inventory_evidence": [<inspection Evidence>] } as projection.json and run node scripts/rea.mjs project-apple-application-graph projection.json --json.
  4. Check normalized_result.application_roots: actual ["Fake.app"], expected [].

The exact built CLI regression is tests/boundary/cli/appleBundleDirectoryCli.test.ts, test Apple CLI does not invent an application from a leaf Contents file (currently local audit work). Its inventory assertion verifies the member's file kind before the failing root assertion.

Expected behavior

A leaf file or symlink does not establish a directory root. Require a known directory or an ancestor implied by deeper members. Preserve the existing explicitly selected .app directory special case. This follows REA's docs/apple-application-analysis.md application-root conventions and Apple's directory-based bundle model: https://developer.apple.com/documentation/bundleresources/placing-content-in-a-bundle

Impact and scope

Observed false application admission for the one authored ZIP. Source review also finds leaf Payload/Fake.app and symlinks entering the same path-only root classifier; those variants are source-derived, not claimed as public CLI reproductions. No execution or mutation authority involved. No claim about real shipped bundles or platform resolver behavior.

REA version

Working tree based on c192c58815, with the #3359 directory-aware layout changes under development. The root-admission code is unchanged from that main revision.

Runtime and platform

Node.js 24.18.0; macOS arm64. No deep analysis provider.

Target and artifact context

Authored harmless ZIP, one regular text member, no target execution.

Interface

CLI

Earliest failure stage

Transport or result projection

Relevant output or evidence

The new built CLI regression fails with expected [], received ["Fake.app"]. Source: applicationRoots in src/domain/apple/appleBundleAnatomy.ts considers path segments without entry kinds. Inventory retains the member as a file.

Typed outcome or recovery expected

Return empty roots/bundles for the fixture while retaining its source inventory. Real explicit and implied application directories, including shallow IPA and macOS layouts, must continue to project normally.

Analysis or suspected cause

Source-derived: root admission precedes the directory index used for bundle anatomy and independently reinterprets raw path names. Proposed fix: derive roots and layout from one directory owner.

Additional context

Found during #3359 / #3505 review. #3359 concerns a real shallow application whose layout is misclassified; this report concerns admission of a nonexistent application. Both can share a structural fix.

Originally created by @morluto on GitHub (Oct 17, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/4779 ### Before submitting - [x] I searched open and closed reports for related application-root/Contents failures. - [x] This report contains only authored fixture paths and no credentials. ### Area Evidence, artifacts, or reconstruction ### Observed behavior The built public CLI invents `application_roots: ["Fake.app"]` from a ZIP whose only member is the regular file `Fake.app/Contents`. Both `inspect-artifact` and `project-apple-application-graph` succeed. Inventory explicitly preserves `entry_kind: "file"`; the projection treats the leaf name as evidence of a bundle's directory layout. ### Reproduction Executed once using an authored ZIP written by zip.js: 1. Write `Fixture.zip` with only `Fake.app/Contents`, containing `ordinary resource` as a regular file. 2. Run `node scripts/rea.mjs inspect-artifact Fixture.zip --json`. 3. Save `{ "inventory_evidence": [<inspection Evidence>] }` as `projection.json` and run `node scripts/rea.mjs project-apple-application-graph projection.json --json`. 4. Check `normalized_result.application_roots`: actual `["Fake.app"]`, expected `[]`. The exact built CLI regression is `tests/boundary/cli/appleBundleDirectoryCli.test.ts`, test `Apple CLI does not invent an application from a leaf Contents file` (currently local audit work). Its inventory assertion verifies the member's file kind before the failing root assertion. ### Expected behavior A leaf file or symlink does not establish a directory root. Require a known directory or an ancestor implied by deeper members. Preserve the existing explicitly selected `.app` directory special case. This follows REA's `docs/apple-application-analysis.md` application-root conventions and Apple's directory-based bundle model: https://developer.apple.com/documentation/bundleresources/placing-content-in-a-bundle ### Impact and scope Observed false application admission for the one authored ZIP. Source review also finds leaf `Payload/Fake.app` and symlinks entering the same path-only root classifier; those variants are source-derived, not claimed as public CLI reproductions. No execution or mutation authority involved. No claim about real shipped bundles or platform resolver behavior. ### REA version Working tree based on c192c58815ddeaf5cf30159e7082c742c0bc36b7, with the #3359 directory-aware layout changes under development. The root-admission code is unchanged from that main revision. ### Runtime and platform Node.js 24.18.0; macOS arm64. No deep analysis provider. ### Target and artifact context Authored harmless ZIP, one regular text member, no target execution. ### Interface CLI ### Earliest failure stage Transport or result projection ### Relevant output or evidence The new built CLI regression fails with expected `[]`, received `["Fake.app"]`. Source: `applicationRoots` in `src/domain/apple/appleBundleAnatomy.ts` considers path segments without entry kinds. Inventory retains the member as a file. ### Typed outcome or recovery expected Return empty roots/bundles for the fixture while retaining its source inventory. Real explicit and implied application directories, including shallow IPA and macOS layouts, must continue to project normally. ### Analysis or suspected cause Source-derived: root admission precedes the directory index used for bundle anatomy and independently reinterprets raw path names. Proposed fix: derive roots and layout from one directory owner. ### Additional context Found during #3359 / #3505 review. #3359 concerns a real shallow application whose layout is misclassified; this report concerns admission of a nonexistent application. Both can share a structural fix.
bsakaguchi 2026-10-17 21:05:29 +00:00
  • closed this issue
  • added the
    triage
    bug
    labels
Author
Owner

@morluto commented on GitHub (Oct 17, 2026):

Fixed on main in 149a0fc06c. Adapted @bnkaiteam's directory-identity proposal and source regressions from #3505, extending the structural fix to metadata-file selection and root admission. This is not a PR merge or readiness attestation.

The owner now indexes directories (explicit and implied) separately from authenticated files. Root discovery, nested bundles, layout, metadata, executable candidates and signing paths consume those facts. Mixed child-name interpretation and later membership repairs were removed. Kind is selected before case preference; original spelling and the explicitly selected .app directory rule remain intact.

Observed validation:

  • Eight new source assertions and three public CLI layout assertions fail before the layout fix. A separate public CLI control reproduces #4779's false Fake.app root before its fix.
  • All 57 focused checks pass after the complete fix, including five built CLI workflows, real inventory, explicit/implied directories, file/symlink roots, metadata/signature shadowing, case collisions, versioned frameworks, unread-file preservation and production MCP projection.
  • Build, check:fast/typecheck/lint, docs:check (five README checks) and pre-push checks pass. Two final read-only reviews found no actionable defects.

30 completed tiny source projection tasks used five genuine authored ZIP inventories. First processes were recorded separately from two alternating repeated processes. Repeated-process medians below are observations, not evidence of a speed improvement. Peak RSS covers the known single Node process family (no children); tokens use cl100k_base estimates for full source replies.

Task Reply tokens Elapsed ms CPU ms Peak MB
shallow-resource 541→549 48.73→48.82 61.68→61.95 75.40→75.67
deep-control 566→566 49.46→49.96 62.40→63.81 75.46→75.42
case-shadow 581→590 48.88→48.55 61.94→61.69 75.24→75.22
versioned-control 829→829 48.76→49.16 61.95→61.73 75.42→75.46
false-root 447→436 49.35→48.61 62.59→61.68 75.25→75.51

Ordinary deep and versioned control replies, including projection IDs, remain byte-identical. Defect-case facts and IDs intentionally change. True-cold, whole agent/catalog, full public-task and large-input costs were not measured. Only harmless authored fixtures were inspected: no target execution, real provider, published npm or heavy profiling claim.

Research: Apple's directory-based bundle model; DeepWiki CoreFoundation layout research used for orientation, with REA's opaque-symlink and inventory rules determining this implementation.

<!-- gh-comment-id:6233575237 --> @morluto commented on GitHub (Oct 17, 2026): Fixed on main in 149a0fc06c3c67ee45624e6da14dfb0754473758. Adapted @bnkaiteam's directory-identity proposal and source regressions from #3505, extending the structural fix to metadata-file selection and root admission. This is not a PR merge or readiness attestation. The owner now indexes directories (explicit and implied) separately from authenticated files. Root discovery, nested bundles, layout, metadata, executable candidates and signing paths consume those facts. Mixed child-name interpretation and later membership repairs were removed. Kind is selected before case preference; original spelling and the explicitly selected `.app` directory rule remain intact. Observed validation: - Eight new source assertions and three public CLI layout assertions fail before the layout fix. A separate public CLI control reproduces #4779's false `Fake.app` root before its fix. - All 57 focused checks pass after the complete fix, including five built CLI workflows, real inventory, explicit/implied directories, file/symlink roots, metadata/signature shadowing, case collisions, versioned frameworks, unread-file preservation and production MCP projection. - Build, check:fast/typecheck/lint, docs:check (five README checks) and pre-push checks pass. Two final read-only reviews found no actionable defects. 30 completed tiny source projection tasks used five genuine authored ZIP inventories. First processes were recorded separately from two alternating repeated processes. Repeated-process medians below are observations, not evidence of a speed improvement. Peak RSS covers the known single Node process family (no children); tokens use cl100k_base estimates for full source replies. | Task | Reply tokens | Elapsed ms | CPU ms | Peak MB | | --- | --- | --- | --- | --- | | shallow-resource | 541→549 | 48.73→48.82 | 61.68→61.95 | 75.40→75.67 | | deep-control | 566→566 | 49.46→49.96 | 62.40→63.81 | 75.46→75.42 | | case-shadow | 581→590 | 48.88→48.55 | 61.94→61.69 | 75.24→75.22 | | versioned-control | 829→829 | 48.76→49.16 | 61.95→61.73 | 75.42→75.46 | | false-root | 447→436 | 49.35→48.61 | 62.59→61.68 | 75.25→75.51 | Ordinary deep and versioned control replies, including projection IDs, remain byte-identical. Defect-case facts and IDs intentionally change. True-cold, whole agent/catalog, full public-task and large-input costs were not measured. Only harmless authored fixtures were inspected: no target execution, real provider, published npm or heavy profiling claim. Research: [Apple's directory-based bundle model](https://developer.apple.com/documentation/bundleresources/placing-content-in-a-bundle); DeepWiki CoreFoundation layout research used for orientation, with REA's opaque-symlink and inventory rules determining this implementation.
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#2483
No description provided.