[PR #4019] [CLOSED] fix(apple): stop reading a selected UID root as a keyed-archive reference #5993

Closed
opened 2026-10-31 01:11:01 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/4019
Author: @Sriram-PR
Created: 10/15/2026
Status: ❌ Closed

Base: main ← Head: fix/keyed-archive-scalar-uid-root


📝 Commits (2)

  • 0d3542c fix(apple): stop reading a selected UID root as a keyed-archive reference
  • 7fe62ea fix(apple): keep one scan budget across keyed-archive roots

📊 Changes

2 files changed (+66 additions, -6 deletions)

View changed files

📝 src/domain/apple/keyedArchive.test.ts (+49 -0)
📝 src/domain/apple/keyedArchive.ts (+17 -6)

📄 Description

Summary

inspect-keyed-archive --root UID reported a false unresolved reference when the archive's UID root is a plain integer. Selecting one root rebuilds $top as { [root]: value } and the reference scan started from that whole dictionary. With the key UID and a numeric value, the wrapper itself matched the UID marker check (a one-key UID/CF$UID dictionary with a number), so the scan recorded {"source":null,"path":[],"target":1,"status":"unresolved","raw":{"UID":1}}.

Fixes #3913

Problem and expected behavior

Smallest trigger: the fixture from the issue, $top = { UID: 1, ordinary: 7 } and $objects = ["$null"]. With no selector, or with --root ordinary, the archive has no references. With --root UID it reported total_references: 1 with the edge above. Expected: selecting a root only narrows which roots are scanned, so --root UID also reports no references. The uid helper already documents this case ("a $top that holds a root encoded under the key UID"), but the single-root path rebuilt exactly that shape.

Change and scope

  • src/domain/apple/keyedArchive.ts: the root scan now walks each root's value under its key (path: [key]), instead of passing the roots dictionary in as one value. Keys are visited in the same sorted order the scan already used, so references and their paths for real UID roots are unchanged.
  • The object table scan is untouched.
  • Not included: anything about how roots are selected or reported in roots.

Contribution scope: ordinary fix within existing boundaries; no scope decision needed.

Contract and boundary impact

  • Semantic owner and earliest changed stage: projectKeyedArchive in src/domain/apple/keyedArchive.ts, when root references are collected.
  • Contribution scope fit and linked maintainer decision: not applicable (bug fix, #3913).
  • CLI and MCP/tool-catalog contract: no schema change. inspect-keyed-archive / inspect_keyed_archive no longer list a root-level reference for a scalar root named UID (or CF$UID).
  • Provider, bridge, target-format, or platform compatibility: none.
  • Evidence, artifact, provenance, or reconstruction contract: references and total_references drop the false edge; roots and objects are unchanged.
  • Target selection, authority, upstream behavior, and cleanup details: not applicable.
  • Generated metadata, package, or installation impact: none.

Expected effects (check known effects; use documentation-only on its own).
Unchecked items do not establish absence; leave uncertainties visible.

  • Read existing files or captured data.
  • Launch or attach to a process.
  • Inject instrumentation or run scripts/code.
  • Change process memory, registers, files, or configuration.
  • Contact network services.
  • Recover protected code or work around protections.
  • Documentation or usability only; no target interaction.
  • Not sure yet; investigation or maintainer guidance needed.

Evidence and regression coverage

  • Tests added or updated: src/domain/apple/keyedArchive.test.ts adds a root selection block. One test selects the scalar UID root and expects no references (with the all-roots control); the other selects a root that holds a real CF$UID and expects the reference at path ["root"], so real root references still come through.
  • Base reproduction: on the base revision the scalar UID test fails with expected [ { source: null, path: [], ...(3) } ] to deeply equal []; the other test passes on both.
  • User-visible CLI output (inspect-keyed-archive scalar-roots.plist [selector] --json, fixture from the issue, total_references and references):
    selector          base                                                   PR
    --root UID        1 [{"source":null,"path":[],"target":1,"status":"unresolved","raw":{"UID":1}}]   0 []
    --root ordinary   0 []                                                   0 []
    (none)            0 []                                                   0 []
    
  • Remaining proof gaps: XML plist fixture only for the CLI run; the binary plist path goes through the same projection.

For evidence-bearing changes:

  • 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/*.test.ts: 131 passed (the new scalar UID test fails on the base revision)
  • npm run test:focused -- tests/boundary/*/keyedArchive*.test.ts (12 files): 101 passed
  • npm run check:fast: typecheck and lint passed
  • CLI comparison above, built with npm run build:cached on base and on this branch

Compatibility, safety, and release

  • Breaking changes or migration steps: none.
  • Real Hopper/Ghidra, browser, or OS coverage: Linux x64, Node 24.18.0; no provider involved.
  • Package or release metadata impact: none.
  • Security, privacy, process, or containment review: none.

Author readiness

Human owner: @Sriram-PR

  • I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work.
  • I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps.
  • I declare this PR ready for initial maintainer review.

Before merge

  • This PR addresses a concrete problem or an agreed enhancement.
  • Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff.
  • The PR has one focused outcome and the title follows type(scope): outcome.
  • Related issue is linked, or the reason for not linking one is stated above.
  • Tests cover changed observable behavior and meaningful failure paths.
  • Owning docs, contracts, and generated metadata are updated where needed.
  • User-visible CLI/MCP changes include representative output.
  • I checked the final diff for secrets, unrelated cleanup, and 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/4019 **Author:** [@Sriram-PR](https://github.com/Sriram-PR) **Created:** 10/15/2026 **Status:** ❌ Closed **Base:** `main` ← **Head:** `fix/keyed-archive-scalar-uid-root` --- ### 📝 Commits (2) - [`0d3542c`](https://github.com/morluto/rea/commit/0d3542cd3e9e393680d0555ad7004c6cef0a8aa6) fix(apple): stop reading a selected UID root as a keyed-archive reference - [`7fe62ea`](https://github.com/morluto/rea/commit/7fe62ea1b7270ca1e6688cb79913e9bb3224e120) fix(apple): keep one scan budget across keyed-archive roots ### 📊 Changes **2 files changed** (+66 additions, -6 deletions) <details> <summary>View changed files</summary> 📝 `src/domain/apple/keyedArchive.test.ts` (+49 -0) 📝 `src/domain/apple/keyedArchive.ts` (+17 -6) </details> ### 📄 Description ## Summary `inspect-keyed-archive --root UID` reported a false unresolved reference when the archive's `UID` root is a plain integer. Selecting one root rebuilds `$top` as `{ [root]: value }` and the reference scan started from that whole dictionary. With the key `UID` and a numeric value, the wrapper itself matched the UID marker check (a one-key `UID`/`CF$UID` dictionary with a number), so the scan recorded `{"source":null,"path":[],"target":1,"status":"unresolved","raw":{"UID":1}}`. Fixes #3913 ## Problem and expected behavior Smallest trigger: the fixture from the issue, `$top = { UID: 1, ordinary: 7 }` and `$objects = ["$null"]`. With no selector, or with `--root ordinary`, the archive has no references. With `--root UID` it reported `total_references: 1` with the edge above. Expected: selecting a root only narrows which roots are scanned, so `--root UID` also reports no references. The `uid` helper already documents this case ("a `$top` that holds a root encoded under the key `UID`"), but the single-root path rebuilt exactly that shape. ## Change and scope - `src/domain/apple/keyedArchive.ts`: the root scan now walks each root's value under its key (`path: [key]`), instead of passing the roots dictionary in as one value. Keys are visited in the same sorted order the scan already used, so references and their paths for real UID roots are unchanged. - The object table scan is untouched. - Not included: anything about how roots are selected or reported in `roots`. Contribution scope: ordinary fix within existing boundaries; no scope decision needed. ## Contract and boundary impact - Semantic owner and earliest changed stage: `projectKeyedArchive` in `src/domain/apple/keyedArchive.ts`, when root references are collected. - Contribution scope fit and linked maintainer decision: not applicable (bug fix, #3913). - CLI and MCP/tool-catalog contract: no schema change. `inspect-keyed-archive` / `inspect_keyed_archive` no longer list a root-level reference for a scalar root named `UID` (or `CF$UID`). - Provider, bridge, target-format, or platform compatibility: none. - Evidence, artifact, provenance, or reconstruction contract: `references` and `total_references` drop the false edge; `roots` and `objects` are unchanged. - Target selection, authority, upstream behavior, and cleanup details: not applicable. - Generated metadata, package, or installation impact: none. Expected effects (check known effects; use documentation-only on its own). Unchecked items do not establish absence; leave uncertainties visible. - [x] Read existing files or captured data. - [ ] Launch or attach to a process. - [ ] Inject instrumentation or run scripts/code. - [ ] Change process memory, registers, files, or configuration. - [ ] Contact network services. - [ ] Recover protected code or work around protections. - [ ] Documentation or usability only; no target interaction. - [ ] Not sure yet; investigation or maintainer guidance needed. ## Evidence and regression coverage - Tests added or updated: `src/domain/apple/keyedArchive.test.ts` adds a root selection block. One test selects the scalar `UID` root and expects no references (with the all-roots control); the other selects a root that holds a real `CF$UID` and expects the reference at path `["root"]`, so real root references still come through. - Base reproduction: on the base revision the scalar `UID` test fails with `expected [ { source: null, path: [], ...(3) } ] to deeply equal []`; the other test passes on both. - User-visible CLI output (`inspect-keyed-archive scalar-roots.plist [selector] --json`, fixture from the issue, `total_references` and `references`): ``` selector base PR --root UID 1 [{"source":null,"path":[],"target":1,"status":"unresolved","raw":{"UID":1}}] 0 [] --root ordinary 0 [] 0 [] (none) 0 [] 0 [] ``` - Remaining proof gaps: XML plist fixture only for the CLI run; the binary plist path goes through the same projection. For evidence-bearing changes: - [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/*.test.ts`: 131 passed (the new scalar `UID` test fails on the base revision) - `npm run test:focused -- tests/boundary/*/keyedArchive*.test.ts` (12 files): 101 passed - `npm run check:fast`: typecheck and lint passed - CLI comparison above, built with `npm run build:cached` on base and on this branch ## Compatibility, safety, and release - Breaking changes or migration steps: none. - Real Hopper/Ghidra, browser, or OS coverage: Linux x64, Node 24.18.0; no provider involved. - Package or release metadata impact: none. - Security, privacy, process, or containment review: none. ## Author readiness Human owner: @Sriram-PR - [x] I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work. - [x] I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps. - [x] I declare this PR ready for initial maintainer review. ## Before merge - [x] This PR addresses a concrete problem or an agreed enhancement. - [x] Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff. - [x] The PR has one focused outcome and the title follows `type(scope): outcome`. - [x] Related issue is linked, or the reason for not linking one is stated above. - [x] Tests cover changed observable behavior and meaningful failure paths. - [x] Owning docs, contracts, and generated metadata are updated where needed. - [x] User-visible CLI/MCP changes include representative output. - [x] I checked the final diff for secrets, unrelated cleanup, and 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 01:11:01 +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#5993
No description provided.