[PR #1513] [MERGED] fix: bind identity and coverage to the producing rule #2933

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

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/1513
Author: @morluto
Created: 10/10/2026
Status: ✅ Merged
Merged: 10/10/2026
Merged by: @morluto

Base: main ← Head: cursor/brittleness-cleanup-07c3


📝 Commits (5)

  • c50c2d0 fix: bind identity and coverage to the producing rule
  • 1f7f77c fix: fail unmatched Mach-O slices and keep firmware roots independent
  • 89094ef merge: integrate main into the brittleness cleanup
  • f3feb00 test: cover path identity and runtime families at the projection boundary
  • a7ec8a0 test: expect unread dyld rebase bytes in the Apple dispatch fixture

📊 Changes

48 files changed (+1251 additions, -266 deletions)

View changed files

📝 scripts/verify/apple/dispatch.mjs (+13 -3)
📝 src/application/ReferenceSourceImportEntries.ts (+6 -2)
📝 src/application/javascript/JavaScriptArtifactPathResolution.test.ts (+30 -0)
📝 src/application/javascript/JavaScriptArtifactPathResolution.ts (+6 -6)
📝 src/application/native/NativeUiActionTrace.ts (+17 -5)
📝 src/artifacts/ArtifactPaths.ts (+2 -1)
📝 src/artifacts/inventory/classify.ts (+45 -19)
📝 src/artifacts/inventory/reader.ts (+10 -1)
📝 src/browser/CdpCaptureContextRetention.test.ts (+35 -0)
📝 src/browser/CdpCaptureDocuments.baseUrl.test.ts (+17 -0)
📝 src/browser/CdpCaptureDocuments.ts (+2 -1)
📝 src/browser/CdpCaptureEventHandlers.ts (+10 -2)
📝 src/browser/CdpCaptureEventTypes.ts (+2 -0)
📝 src/browser/CdpCaptureEvents.ts (+2 -4)
📝 src/browser/PlaywrightScenarioBrowser.test.ts (+10 -0)
📝 src/browser/PlaywrightScenarioBrowser.ts (+11 -1)
📝 src/browser/assets/PublishWebScripts.ts (+64 -16)
📝 src/domain/analysisErrorBase.ts (+3 -1)
📝 src/domain/android/androidApplication.ts (+11 -16)
📝 src/domain/apple/appleApplication.test.ts (+77 -0)

...and 28 more files

📄 Description

Summary

Fixes the filed identity and coverage bugs by changing the rule at the layer that owns it: one NFC logical-path normalizer, byte-backed container families, coverage that follows the bytes actually read, path-segment conventions, destination collisions only at the destination, leases keyed by the identity the OS already returned, Mach-O CPU selection, and firmware success returned beside cleanup failure.

Fixes #1485, #1486, #1487, #1488, #1489, #1490, #1491, #1496, #1497, #1498, #1499, #1500, #1501, #1502, #1503.

Problem and expected behavior

Several boundaries treated a nearby spelling, suffix, or later event as if it were the observation:

  • Joins used a private POSIX normalize, so NFC inventory identity and joined logical paths could diverge.
  • A filename suffix could classify a root as DMG, PKG, or ASAR without the matching magic.
  • ZIP inventories with identical entries and different non-entry tails (signing block, comment) could compare as unchanged, and pointer-fixup and Interface Builder traces could report complete coverage when the underlying range or decode was unread or partial.
  • Substring matches treated community and MyApp.framework as runtime families, and Apple anatomy used more than one case policy.
  • Case-distinct web script URL paths were folded before a destination collision was observed.
  • Windows private runtimes, scenario PATH lookup, attached CDP locks, parsed script frames, and repeated DOM attributes could follow a later or folded identity instead of the one already observed.
  • FAT slice selection and lipo -arch could name an architecture the header or lipo did not admit, and a firmware cleanup failure could hide a completed extraction and replay onto the next workspace.

Change and scope

Each fix is at the producing rule. Domain stays free of artifact, browser, and provider imports.

  • logicalPathNfc, normalizeJoinedLogicalPath, and logicalPathEscapesRoot live next to occurrence identity. Inventory joins and artifact path normalization call them. Feature-seed NFKC stays a query fold.
  • Root classification reads ZIP, ASAR, XAR, and koly before the suffix. A misnamed ELF or text file falls through to content classification. ZIP inventories record that non-entry tail bytes are not occurrences, and comparison reports a root-hash change when root_sha256 differs.
  • LC_DYLD_INFO rebase ranges set pointer_fixups to partial or unsupported when unread or unexamined. Interface Builder trace coverage copies the archive-decode facet.
  • Bridge and runtime-family matches are path-segment checks. Bundle anatomy uses one English (en-US) case fold for the fixed vocabulary; reported paths keep the archive spelling.
  • Web script export keeps case-distinct URL paths. A SafeOutputTree destination collision isolates that script under isolated/.
  • Windows runtimes are keyed by volumeSerial and fileId, with exact path match. Scenario executables use the same Windows environment-key canonicalization as the child snapshot. Attached CDP locks use the parsed discovery URL and target_id. A script keeps the frame it was parsed in. Repeated DOM attributes keep the first value.
  • FAT slices are selected from the admitted CPU type table, and 32-bit slices fail as unsupported 32-bit metadata. otool -arch is passed only for a name lipo listed. Firmware returns the completed extraction beside the cleanup error and does not latch that error onto the next root.

Archive case-distinct inventory identity (#1470) and the diverging-segment case-collision record (#1505) are unchanged.

Contract and boundary impact

  • Semantic owner and earliest changed stage: domain identity and conventions, then the artifact, browser, process, native, and firmware adapters that apply them. No new public tool.
  • CLI and MCP/tool-catalog contract: none. Existing results can name a limitation, a partial coverage status, a root-hash change, an isolated script path, or a cleanup error that was previously omitted or overstated.
  • Provider, bridge, target-format, or platform compatibility: FAT selection rejects unsupported 32-bit Mach-O metadata for the requested CPU type. otool is not asked for an architecture lipo did not list.
  • Evidence, artifact, provenance, or reconstruction contract: container family, ZIP-tail coverage, pointer fixups, Interface Builder traces, runtime-family labels, and DOM attributes follow the examined bytes or the first observed value.
  • Process execution, authorization, cleanup, or containment impact: firmware keeps a leaked workspace recorded when teardown fails and allows a later operation to create a new root. Windows runtime close deletes only the file id that was opened.
  • Generated metadata (docs/public/product-catalog.json), package, or installation impact: none.

Evidence and regression coverage

  • Tests added or updated: archive identity and ZIP detection, JavaScript path joins, Apple and Android projection, web script export, Windows runtime, process scenario validation, CDP documents and scenario locks, Mach-O selection and dispatch coverage, Interface Builder trace, and firmware provider.
  • Base reproduction or other evidence: source tests assert the previous fold, suffix, coverage, and lease behaviors fail on the new contracts.
  • User-visible CLI/MCP output (if applicable): limitation and coverage text can change for ZIP tails, pointer fixups, Interface Builder archives, runtime families, and firmware cleanup. No new command or tool.
  • Remaining proof gaps: no real Windows volume, case-insensitive destination volume, attached Chrome, lipo/otool, or firmware image was exercised here. Simulated adapters do not establish those provider behaviors.

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 on the touched domain, application, browser, native, process, and firmware suites — passed before rebase onto main.
  • npm run test:focused on tests/boundary/filesystem/zipDetection.test.ts — passed before rebase onto main.
  • npm run check:fast (pre-push typecheck and lint) — passed on the rebased commit. Rebase onto main, including the diverging-segment case-collision record, applied without conflicts.

Compatibility, safety, and release

  • Breaking changes or migration steps: none. Callers can see partial or unsupported coverage, a root-hash difference, an isolated script path, or a firmware cleanup error that was previously collapsed into a stronger claim.
  • Real Hopper/Ghidra, browser, or OS coverage: not run. Mach-O, CDP, Windows, and firmware checks use local fixtures and fakes.
  • Package or release metadata impact: none.
  • Security, privacy, process, or containment review: firmware no longer deletes an unconfirmed leaked root or replays its cleanup error onto a new workspace. Destination isolation still goes through SafeOutputTree.

Review checklist

  • This PR addresses a concrete problem or an agreed enhancement.
  • 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.
Open in Web Open in Cursor 

🔄 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/1513 **Author:** [@morluto](https://github.com/morluto) **Created:** 10/10/2026 **Status:** ✅ Merged **Merged:** 10/10/2026 **Merged by:** [@morluto](https://github.com/morluto) **Base:** `main` ← **Head:** `cursor/brittleness-cleanup-07c3` --- ### 📝 Commits (5) - [`c50c2d0`](https://github.com/morluto/rea/commit/c50c2d0ca148d5c607521c366ef05e31aced5a7e) fix: bind identity and coverage to the producing rule - [`1f7f77c`](https://github.com/morluto/rea/commit/1f7f77c69f66453a5d0fff7c315b88b9945c3869) fix: fail unmatched Mach-O slices and keep firmware roots independent - [`89094ef`](https://github.com/morluto/rea/commit/89094ef16e93671858698f343727bb80f810dca9) merge: integrate main into the brittleness cleanup - [`f3feb00`](https://github.com/morluto/rea/commit/f3feb0000b271d52a434d5c1179b805811c2591e) test: cover path identity and runtime families at the projection boundary - [`a7ec8a0`](https://github.com/morluto/rea/commit/a7ec8a043d8f9d6eabda11351ec85cc62772d902) test: expect unread dyld rebase bytes in the Apple dispatch fixture ### 📊 Changes **48 files changed** (+1251 additions, -266 deletions) <details> <summary>View changed files</summary> 📝 `scripts/verify/apple/dispatch.mjs` (+13 -3) 📝 `src/application/ReferenceSourceImportEntries.ts` (+6 -2) 📝 `src/application/javascript/JavaScriptArtifactPathResolution.test.ts` (+30 -0) 📝 `src/application/javascript/JavaScriptArtifactPathResolution.ts` (+6 -6) 📝 `src/application/native/NativeUiActionTrace.ts` (+17 -5) 📝 `src/artifacts/ArtifactPaths.ts` (+2 -1) 📝 `src/artifacts/inventory/classify.ts` (+45 -19) 📝 `src/artifacts/inventory/reader.ts` (+10 -1) 📝 `src/browser/CdpCaptureContextRetention.test.ts` (+35 -0) 📝 `src/browser/CdpCaptureDocuments.baseUrl.test.ts` (+17 -0) 📝 `src/browser/CdpCaptureDocuments.ts` (+2 -1) 📝 `src/browser/CdpCaptureEventHandlers.ts` (+10 -2) 📝 `src/browser/CdpCaptureEventTypes.ts` (+2 -0) 📝 `src/browser/CdpCaptureEvents.ts` (+2 -4) 📝 `src/browser/PlaywrightScenarioBrowser.test.ts` (+10 -0) 📝 `src/browser/PlaywrightScenarioBrowser.ts` (+11 -1) 📝 `src/browser/assets/PublishWebScripts.ts` (+64 -16) 📝 `src/domain/analysisErrorBase.ts` (+3 -1) 📝 `src/domain/android/androidApplication.ts` (+11 -16) 📝 `src/domain/apple/appleApplication.test.ts` (+77 -0) _...and 28 more files_ </details> ### 📄 Description <!-- CURSOR_AGENT_PR_BODY_BEGIN --> ## Summary Fixes the filed identity and coverage bugs by changing the rule at the layer that owns it: one NFC logical-path normalizer, byte-backed container families, coverage that follows the bytes actually read, path-segment conventions, destination collisions only at the destination, leases keyed by the identity the OS already returned, Mach-O CPU selection, and firmware success returned beside cleanup failure. Fixes #1485, #1486, #1487, #1488, #1489, #1490, #1491, #1496, #1497, #1498, #1499, #1500, #1501, #1502, #1503. ## Problem and expected behavior Several boundaries treated a nearby spelling, suffix, or later event as if it were the observation: - Joins used a private POSIX normalize, so NFC inventory identity and joined logical paths could diverge. - A filename suffix could classify a root as DMG, PKG, or ASAR without the matching magic. - ZIP inventories with identical entries and different non-entry tails (signing block, comment) could compare as unchanged, and pointer-fixup and Interface Builder traces could report complete coverage when the underlying range or decode was unread or partial. - Substring matches treated `community` and `MyApp.framework` as runtime families, and Apple anatomy used more than one case policy. - Case-distinct web script URL paths were folded before a destination collision was observed. - Windows private runtimes, scenario `PATH` lookup, attached CDP locks, parsed script frames, and repeated DOM attributes could follow a later or folded identity instead of the one already observed. - FAT slice selection and `lipo -arch` could name an architecture the header or lipo did not admit, and a firmware cleanup failure could hide a completed extraction and replay onto the next workspace. ## Change and scope Each fix is at the producing rule. Domain stays free of artifact, browser, and provider imports. - `logicalPathNfc`, `normalizeJoinedLogicalPath`, and `logicalPathEscapesRoot` live next to occurrence identity. Inventory joins and artifact path normalization call them. Feature-seed NFKC stays a query fold. - Root classification reads ZIP, ASAR, XAR, and `koly` before the suffix. A misnamed ELF or text file falls through to content classification. ZIP inventories record that non-entry tail bytes are not occurrences, and comparison reports a root-hash change when `root_sha256` differs. - `LC_DYLD_INFO` rebase ranges set `pointer_fixups` to partial or unsupported when unread or unexamined. Interface Builder trace coverage copies the archive-decode facet. - Bridge and runtime-family matches are path-segment checks. Bundle anatomy uses one English (`en-US`) case fold for the fixed vocabulary; reported paths keep the archive spelling. - Web script export keeps case-distinct URL paths. A `SafeOutputTree` destination collision isolates that script under `isolated/`. - Windows runtimes are keyed by `volumeSerial` and `fileId`, with exact path match. Scenario executables use the same Windows environment-key canonicalization as the child snapshot. Attached CDP locks use the parsed discovery URL and `target_id`. A script keeps the frame it was parsed in. Repeated DOM attributes keep the first value. - FAT slices are selected from the admitted CPU type table, and 32-bit slices fail as unsupported 32-bit metadata. `otool -arch` is passed only for a name lipo listed. Firmware returns the completed extraction beside the cleanup error and does not latch that error onto the next root. Archive case-distinct inventory identity (#1470) and the diverging-segment case-collision record (#1505) are unchanged. ## Contract and boundary impact - Semantic owner and earliest changed stage: domain identity and conventions, then the artifact, browser, process, native, and firmware adapters that apply them. No new public tool. - CLI and MCP/tool-catalog contract: none. Existing results can name a limitation, a partial coverage status, a root-hash change, an isolated script path, or a cleanup error that was previously omitted or overstated. - Provider, bridge, target-format, or platform compatibility: FAT selection rejects unsupported 32-bit Mach-O metadata for the requested CPU type. `otool` is not asked for an architecture lipo did not list. - Evidence, artifact, provenance, or reconstruction contract: container family, ZIP-tail coverage, pointer fixups, Interface Builder traces, runtime-family labels, and DOM attributes follow the examined bytes or the first observed value. - Process execution, authorization, cleanup, or containment impact: firmware keeps a leaked workspace recorded when teardown fails and allows a later operation to create a new root. Windows runtime close deletes only the file id that was opened. - Generated metadata (`docs/public/product-catalog.json`), package, or installation impact: none. ## Evidence and regression coverage - Tests added or updated: archive identity and ZIP detection, JavaScript path joins, Apple and Android projection, web script export, Windows runtime, process scenario validation, CDP documents and scenario locks, Mach-O selection and dispatch coverage, Interface Builder trace, and firmware provider. - Base reproduction or other evidence: source tests assert the previous fold, suffix, coverage, and lease behaviors fail on the new contracts. - User-visible CLI/MCP output (if applicable): limitation and coverage text can change for ZIP tails, pointer fixups, Interface Builder archives, runtime families, and firmware cleanup. No new command or tool. - Remaining proof gaps: no real Windows volume, case-insensitive destination volume, attached Chrome, lipo/otool, or firmware image was exercised here. Simulated adapters do not establish those provider behaviors. 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` on the touched domain, application, browser, native, process, and firmware suites — passed before rebase onto main. - `npm run test:focused` on `tests/boundary/filesystem/zipDetection.test.ts` — passed before rebase onto main. - `npm run check:fast` (pre-push typecheck and lint) — passed on the rebased commit. Rebase onto main, including the diverging-segment case-collision record, applied without conflicts. ## Compatibility, safety, and release - Breaking changes or migration steps: none. Callers can see partial or unsupported coverage, a root-hash difference, an isolated script path, or a firmware cleanup error that was previously collapsed into a stronger claim. - Real Hopper/Ghidra, browser, or OS coverage: not run. Mach-O, CDP, Windows, and firmware checks use local fixtures and fakes. - Package or release metadata impact: none. - Security, privacy, process, or containment review: firmware no longer deletes an unconfirmed leaked root or replays its cleanup error onto a new workspace. Destination isolation still goes through `SafeOutputTree`. ## Review checklist - [x] This PR addresses a concrete problem or an agreed enhancement. - [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. <!-- CURSOR_AGENT_PR_BODY_END --> <div><a href="https://cursor.com/agents/bc-44e94f43-7d92-4380-94b2-c70d5fe807c3?cursor_ref=pr_footer&cursor_cta=open_in_web"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-web-light.png"><img alt="Open in Web" width="114" height="28" src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a>&nbsp;<a href="https://cursor.com/background-agent?bcId=bc-44e94f43-7d92-4380-94b2-c70d5fe807c3&cursor_ref=pr_footer&cursor_cta=open_in_cursor"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-cursor-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-cursor-light.png"><img alt="Open in Cursor" width="131" height="28" src="https://cursor.com/assets/images/open-in-cursor-dark.png"></picture></a>&nbsp;</div> --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-17 21:11:58 +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#2933
No description provided.