[PR #4551] [CLOSED] fix(native): filter unlocated Swift symbols from dispatch metadata inspection #6302

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

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/4551
Author: @jayinvers
Created: 10/16/2026
Status: ❌ Closed

Base: main ← Head: fix/swift-symbol-empty-address


📝 Commits (3)

  • e09bc0f fix(native): filter unlocated Swift symbols from dispatch metadata inspection
  • cccbf9d ci: retrigger checks
  • 7b6399f ci: verify checks still trigger

📊 Changes

2 files changed (+63 additions, -10 deletions)

View changed files

📝 src/domain/native/objcSwiftMetadata.test.ts (+44 -0)
📝 src/domain/native/objcSwiftMetadata.ts (+19 -10)

📄 Description

Summary

Fixes #4542.

When inspect_native_dispatch_metadata falls back to a provider's list_names inventory, a Swift-mangled symbol with an empty address ("", unlocated) was pushed into swift_symbols unchanged, and the final objcSwiftMetadataSchema.parse threw an unhandled ZodError (too_small: expected string to have >=1 characters at swift_symbols[0].address). The CLI command and the MCP tool lost the whole result, including every ObjC class and method decoded from the same inventory. Unlocated Swift symbols are now omitted, and the inspection returns the remaining valid metadata.

Problem and expected behavior

Smallest trigger: a list_names inventory containing an entry such as { address: "", name: "$s4Test7MyClassC" }. swiftSymbolSchema.address is z.string().min(1), so the projection crashed at the final parse. The application boundary parses list_names output with addressedValue, whose address is a plain z.string(), so an empty address reaches the domain function unfiltered; EnhancedTools and the CLI command funnel into the same inspectNativeDispatch workflow, so no caller rejects it first. Violated invariant: the domain projection must emit schema-conforming records, not crash on parse when a provider reports an unlocated symbol. Expected behavior (per the issue): unlocated Swift symbols are filtered and the operation returns the rest of the decoded ObjcSwiftMetadata.

Change and scope

In inspectNativeDispatchMetadata (src/domain/native/objcSwiftMetadata.ts):

  • Every examined Swift-mangled name (isSwiftMangledSymbolName(name) || name.startsWith("_Tt")) is still counted, but only entries with a non-empty address are recorded in swift_symbols.
  • The swift_declarations coverage facet keeps the honest examined count (located and unlocated), stays partial when Swift names were observed, and reports unlocated_swift_symbols_omitted_and_names_are_not_demangled when any were dropped, so the omission stays visible instead of silent.

Not included: no schema change (swiftSymbolSchema.address stays z.string().min(1); relaxing it would change the published CLI/MCP output contract), and no ObjC-side change (those address fields are nullable and already accept ""). Inventories whose Swift symbols all have addresses produce byte-identical output to before.

Contribution scope: ordinary fix within existing boundaries; not applicable.

Contract and boundary impact

  • Semantic owner and earliest changed stage: domain symbol-name projection (inspectNativeDispatchMetadata in src/domain/native/objcSwiftMetadata.ts).
  • Contribution scope fit and linked maintainer decision: not applicable (bug fix within the existing read-only inspection boundary).
  • CLI and MCP/tool-catalog contract: no schema change. inspect-native-dispatch-metadata and the matching MCP tool now succeed on inventories containing unlocated Swift symbols instead of throwing. New swift_declarations coverage reason value when symbols are omitted; examined now also counts unlocated Swift names (identical to before when every Swift symbol is located).
  • Provider, bridge, target-format, or platform compatibility: none; provider inputs and adapters are unchanged.
  • Evidence, artifact, provenance, or reconstruction contract: unchanged; recorded symbols carry identical evidence, and omitted symbols remain visible through the coverage facet.
  • Target selection, authority, upstream behavior, and cleanup details: not applicable.
  • Generated metadata, package, or installation impact: none.

Expected effects:

  • 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: two cases in src/domain/native/objcSwiftMetadata.test.ts:
    • omits unlocated Swift symbols instead of failing the inspection: empty-address $s4Test7MyClassC (mangling-prefix path) and _TtC4Test7MyClassC (legacy _Tt path) mixed with a valid ObjC class symbol, an ObjC method symbol, and a located Swift symbol; asserts only the located Swift symbol is recorded, the class and method still decode, and swift_declarations coverage reports examined: 3.
    • succeeds with empty swift_symbols when no Swift symbol is located: only unlocated Swift symbols; asserts swift_symbols is empty and coverage stays partial with the omission reason.
  • Base reproduction: on the base revision (4838f444 plus only the new tests) both new tests fail with the reported ZodError: Too small: expected string to have >=1 characters at swift_symbols[0].address / swift_symbols[1].address, while the two pre-existing tests pass; with the fix, all four pass.
  • User-visible CLI/MCP output: not captured; no real provider was run (see gaps).
  • Remaining proof gaps: no end-to-end reproduction against a real provider inventory (e.g. Ghidra or Hopper on a real binary); regression coverage is at the domain unit level, which is where the invariant lives.

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

Node 24.18.0 (.nvmrc), Windows. Branch fix/swift-symbol-empty-address off upstream/main at 4838f444.

  • npm run test:local -- src/domain/native/objcSwiftMetadata.test.ts 鈥?before the fix: 2 new tests failed with the reported ZodError, 2 pre-existing passed; after the fix: 4 passed.
  • npm run check:fast 鈥?typecheck and lint both successful (also re-ran clean as the pre-push hook).
  • npx oxfmt --check src/domain/native/objcSwiftMetadata.ts src/domain/native/objcSwiftMetadata.test.ts 鈥?all matched files use the correct format.

Compatibility, safety, and release

  • Breaking changes or migration steps: none; input that previously crashed now succeeds, and published schemas are unchanged.
  • Real Hopper/Ghidra, browser, or OS coverage: none performed; the change is validated at the domain level.
  • Package or release metadata impact: none.
  • Security, privacy, process, or containment review: not applicable; in-process data projection only.

Author readiness

Human owner: @jayinvers

  • 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/4551 **Author:** [@jayinvers](https://github.com/jayinvers) **Created:** 10/16/2026 **Status:** ❌ Closed **Base:** `main` ← **Head:** `fix/swift-symbol-empty-address` --- ### 📝 Commits (3) - [`e09bc0f`](https://github.com/morluto/rea/commit/e09bc0f8da548b1bd6c77986d49656cbc4814da5) fix(native): filter unlocated Swift symbols from dispatch metadata inspection - [`cccbf9d`](https://github.com/morluto/rea/commit/cccbf9d977e1b985c2b6af41be733235777adfc9) ci: retrigger checks - [`7b6399f`](https://github.com/morluto/rea/commit/7b6399f404bd3329c6fb040b44cd324354c7f21c) ci: verify checks still trigger ### 📊 Changes **2 files changed** (+63 additions, -10 deletions) <details> <summary>View changed files</summary> 📝 `src/domain/native/objcSwiftMetadata.test.ts` (+44 -0) 📝 `src/domain/native/objcSwiftMetadata.ts` (+19 -10) </details> ### 📄 Description ## Summary Fixes #4542. When `inspect_native_dispatch_metadata` falls back to a provider's `list_names` inventory, a Swift-mangled symbol with an empty address (`""`, unlocated) was pushed into `swift_symbols` unchanged, and the final `objcSwiftMetadataSchema.parse` threw an unhandled `ZodError` (`too_small: expected string to have >=1 characters at swift_symbols[0].address`). The CLI command and the MCP tool lost the whole result, including every ObjC class and method decoded from the same inventory. Unlocated Swift symbols are now omitted, and the inspection returns the remaining valid metadata. ## Problem and expected behavior Smallest trigger: a `list_names` inventory containing an entry such as `{ address: "", name: "$s4Test7MyClassC" }`. `swiftSymbolSchema.address` is `z.string().min(1)`, so the projection crashed at the final `parse`. The application boundary parses `list_names` output with `addressedValue`, whose `address` is a plain `z.string()`, so an empty address reaches the domain function unfiltered; `EnhancedTools` and the CLI command funnel into the same `inspectNativeDispatch` workflow, so no caller rejects it first. Violated invariant: the domain projection must emit schema-conforming records, not crash on `parse` when a provider reports an unlocated symbol. Expected behavior (per the issue): unlocated Swift symbols are filtered and the operation returns the rest of the decoded `ObjcSwiftMetadata`. ## Change and scope In `inspectNativeDispatchMetadata` (`src/domain/native/objcSwiftMetadata.ts`): - Every examined Swift-mangled name (`isSwiftMangledSymbolName(name) || name.startsWith("_Tt")`) is still counted, but only entries with a non-empty address are recorded in `swift_symbols`. - The `swift_declarations` coverage facet keeps the honest `examined` count (located and unlocated), stays `partial` when Swift names were observed, and reports `unlocated_swift_symbols_omitted_and_names_are_not_demangled` when any were dropped, so the omission stays visible instead of silent. Not included: no schema change (`swiftSymbolSchema.address` stays `z.string().min(1)`; relaxing it would change the published CLI/MCP output contract), and no ObjC-side change (those address fields are nullable and already accept `""`). Inventories whose Swift symbols all have addresses produce byte-identical output to before. Contribution scope: ordinary fix within existing boundaries; not applicable. ## Contract and boundary impact - Semantic owner and earliest changed stage: domain symbol-name projection (`inspectNativeDispatchMetadata` in `src/domain/native/objcSwiftMetadata.ts`). - Contribution scope fit and linked maintainer decision: not applicable (bug fix within the existing read-only inspection boundary). - CLI and MCP/tool-catalog contract: no schema change. `inspect-native-dispatch-metadata` and the matching MCP tool now succeed on inventories containing unlocated Swift symbols instead of throwing. New `swift_declarations` coverage reason value when symbols are omitted; `examined` now also counts unlocated Swift names (identical to before when every Swift symbol is located). - Provider, bridge, target-format, or platform compatibility: none; provider inputs and adapters are unchanged. - Evidence, artifact, provenance, or reconstruction contract: unchanged; recorded symbols carry identical evidence, and omitted symbols remain visible through the coverage facet. - Target selection, authority, upstream behavior, and cleanup details: not applicable. - Generated metadata, package, or installation impact: none. Expected effects: - [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: two cases in `src/domain/native/objcSwiftMetadata.test.ts`: - `omits unlocated Swift symbols instead of failing the inspection`: empty-address `$s4Test7MyClassC` (mangling-prefix path) and `_TtC4Test7MyClassC` (legacy `_Tt` path) mixed with a valid ObjC class symbol, an ObjC method symbol, and a located Swift symbol; asserts only the located Swift symbol is recorded, the class and method still decode, and `swift_declarations` coverage reports `examined: 3`. - `succeeds with empty swift_symbols when no Swift symbol is located`: only unlocated Swift symbols; asserts `swift_symbols` is empty and coverage stays `partial` with the omission reason. - Base reproduction: on the base revision (4838f444 plus only the new tests) both new tests fail with the reported `ZodError: Too small: expected string to have >=1 characters` at `swift_symbols[0].address` / `swift_symbols[1].address`, while the two pre-existing tests pass; with the fix, all four pass. - User-visible CLI/MCP output: not captured; no real provider was run (see gaps). - Remaining proof gaps: no end-to-end reproduction against a real provider inventory (e.g. Ghidra or Hopper on a real binary); regression coverage is at the domain unit level, which is where the invariant lives. 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 Node 24.18.0 (`.nvmrc`), Windows. Branch `fix/swift-symbol-empty-address` off `upstream/main` at 4838f444. - `npm run test:local -- src/domain/native/objcSwiftMetadata.test.ts` 鈥?before the fix: 2 new tests failed with the reported ZodError, 2 pre-existing passed; after the fix: 4 passed. - `npm run check:fast` 鈥?typecheck and lint both successful (also re-ran clean as the pre-push hook). - `npx oxfmt --check src/domain/native/objcSwiftMetadata.ts src/domain/native/objcSwiftMetadata.test.ts` 鈥?all matched files use the correct format. ## Compatibility, safety, and release - Breaking changes or migration steps: none; input that previously crashed now succeeds, and published schemas are unchanged. - Real Hopper/Ghidra, browser, or OS coverage: none performed; the change is validated at the domain level. - Package or release metadata impact: none. - Security, privacy, process, or containment review: not applicable; in-process data projection only. ## Author readiness Human owner: @jayinvers - [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 - [ ] 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. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-31 01:13:25 +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#6302
No description provided.