[PR #5575] [CLOSED] fix(swift): keep nested types with undecoded identifiers unclassified #6974

Closed
opened 2026-11-01 21:44:25 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/5575
Author: @kaoru0822-kitauji
Created: 10/20/2026
Status: ❌ Closed

Base: main ← Head: fix/swift-nested-punycode-classification


📝 Commits (1)

  • 106f260 fix(swift): keep nested types with undecoded identifiers unclassified

📊 Changes

2 files changed (+20 additions, -1 deletions)

View changed files

📝 src/domain/swiftSymbolClassification.ts (+6 -1)
📝 src/domain/symbolAnalysis.test.ts (+14 -0)

📄 Description

Summary

Fixes #5553. analyze_swift_types filed procedures of nested types with non-ASCII (punycode) names under the enclosing struct's category, so a nested enum's describe() and a nested class's initializer and metadata accessor were reported as structs. A classes filter then dropped them from both classes and unclassified. These symbols are now unresolved (category_not_decoded), so they appear in other and, under any category filter, in unclassified.

Problem and expected behavior

classifySwiftSymbol walks <identifier><nominal-kind> pairs and breaks when identifierEnd cannot decode the next identifier, keeping the last decoded category. For _$s6Nested8EnvelopeV007IhuqBAbO8describeSSyF, the identifier after EnvelopeV is punycode (00…), so the loop stopped with structs. The module's contract (swiftSymbolClassification.ts: "Substitutions, generic contexts, and other encodings remain unknown") and the analyze_swift_types description (unresolved observations retained under category filters) require unknown instead.

Change and scope

  • When the undecodable component is an identifier (0…, i.e. word-substituted or punycode), the category becomes null. Suffixes after a decoded nominal (methods, Ma, Mp, E, …) are unaffected.
  • Not included: decoding punycode/word substitutions (not required by the contract). Open PR #4319 edits the same end === undefined branch for A… substitutions; the two changes compose, but whichever merges second needs a trivial rebase.

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

Contract and boundary impact

  • Semantic owner and earliest changed stage: src/domain/swiftSymbolClassification.ts (Swift category decoder).

  • Contribution scope fit and linked maintainer decision: ordinary fix; not applicable.

  • CLI and MCP/tool-catalog contract: no schema change; affected observations move from a wrong category to other / unclassified.

  • Provider, bridge, target-format, or platform compatibility: provider-neutral (procedure names from any provider).

  • Evidence, artifact, provenance, or reconstruction contract: categories become less specific only where they were unsupported.

  • Target selection, authority, upstream behavior, and cleanup details: not applicable.

  • Generated metadata, package, or installation impact: none.

  • 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: src/domain/symbolAnalysis.test.ts. The issue's three nested-type symbols are added to the existing "retained unresolved under category filters" case (structs filter), plus a new classes-filter case for the nested class metadata accessor.

  • Base reproduction: with the classifier change stashed, both cases fail.

  • Real symbols: the issue's Nested.swift compiled with swiftc -O -g -parse-as-library (Apple Swift, macOS arm64). Its 100 _$s6Nested… symbols from nm were classified with base and fixed code:

    • Base: 63 structs, of which 57 belong to Envelope.状態 (enum), Envelope.中身 or Envelope.部品 (class).
    • Fixed: 6 structs, all Envelope's own (metadata, descriptor, init); every nested-type symbol is unresolved.
  • Remaining proof gaps: the issue's Hopper + MCP session was not rerun; the classifier is provider-neutral and the MCP Swift-types boundary test passes. Nested ASCII types are unaffected unless their identifier is word-substituted.

  • 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:focused -- src/domain/symbolAnalysis.test.ts tests/boundary/mcp/enhancedTools.swiftTypes.test.ts: 26 passed
  • npm run test:local -- src/domain/symbolAnalysis.test.ts with the classifier change stashed: 2 failed, 15 passed
  • npm run check:fast: passed
  • Base vs fixed classification of the compiled fixture's real symbols (above)

Compatibility, safety, and release

  • Breaking changes or migration steps: none; misattributed nested-type procedures become unresolved.
  • Real Hopper/Ghidra, browser, or OS coverage: real swiftc symbols on macOS arm64; Hopper not run.
  • Package or release metadata impact: none.
  • Security, privacy, process, or containment review: no new reads, processes or side effects.

Author readiness

Human owner:

  • 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.

🤖 Generated with Claude Code


🔄 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/5575 **Author:** [@kaoru0822-kitauji](https://github.com/kaoru0822-kitauji) **Created:** 10/20/2026 **Status:** ❌ Closed **Base:** `main` ← **Head:** `fix/swift-nested-punycode-classification` --- ### 📝 Commits (1) - [`106f260`](https://github.com/morluto/rea/commit/106f260d18983b560e90737e81be2747ac943ff3) fix(swift): keep nested types with undecoded identifiers unclassified ### 📊 Changes **2 files changed** (+20 additions, -1 deletions) <details> <summary>View changed files</summary> 📝 `src/domain/swiftSymbolClassification.ts` (+6 -1) 📝 `src/domain/symbolAnalysis.test.ts` (+14 -0) </details> ### 📄 Description ## Summary Fixes #5553. `analyze_swift_types` filed procedures of nested types with non-ASCII (punycode) names under the enclosing struct's category, so a nested enum's `describe()` and a nested class's initializer and metadata accessor were reported as `structs`. A `classes` filter then dropped them from both `classes` and `unclassified`. These symbols are now unresolved (`category_not_decoded`), so they appear in `other` and, under any category filter, in `unclassified`. ## Problem and expected behavior `classifySwiftSymbol` walks `<identifier><nominal-kind>` pairs and breaks when `identifierEnd` cannot decode the next identifier, keeping the last decoded category. For `_$s6Nested8EnvelopeV007IhuqBAbO8describeSSyF`, the identifier after `EnvelopeV` is punycode (`00…`), so the loop stopped with `structs`. The module's contract (`swiftSymbolClassification.ts`: "Substitutions, generic contexts, and other encodings remain unknown") and the `analyze_swift_types` description (unresolved observations retained under category filters) require unknown instead. ## Change and scope - When the undecodable component is an identifier (`0…`, i.e. word-substituted or punycode), the category becomes `null`. Suffixes after a decoded nominal (methods, `Ma`, `Mp`, `E`, …) are unaffected. - Not included: decoding punycode/word substitutions (not required by the contract). Open PR #4319 edits the same `end === undefined` branch for `A…` substitutions; the two changes compose, but whichever merges second needs a trivial rebase. Contribution scope: ordinary fix within existing boundaries; maintainer scope decision not applicable. ## Contract and boundary impact - Semantic owner and earliest changed stage: `src/domain/swiftSymbolClassification.ts` (Swift category decoder). - Contribution scope fit and linked maintainer decision: ordinary fix; not applicable. - CLI and MCP/tool-catalog contract: no schema change; affected observations move from a wrong category to `other` / `unclassified`. - Provider, bridge, target-format, or platform compatibility: provider-neutral (procedure names from any provider). - Evidence, artifact, provenance, or reconstruction contract: categories become less specific only where they were unsupported. - Target selection, authority, upstream behavior, and cleanup details: not applicable. - Generated metadata, package, or installation impact: none. - [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: `src/domain/symbolAnalysis.test.ts`. The issue's three nested-type symbols are added to the existing "retained unresolved under category filters" case (structs filter), plus a new `classes`-filter case for the nested class metadata accessor. - Base reproduction: with the classifier change stashed, both cases fail. - Real symbols: the issue's `Nested.swift` compiled with `swiftc -O -g -parse-as-library` (Apple Swift, macOS arm64). Its 100 `_$s6Nested…` symbols from `nm` were classified with base and fixed code: - Base: 63 `structs`, of which 57 belong to `Envelope.状態` (enum), `Envelope.中身` or `Envelope.部品` (class). - Fixed: 6 `structs`, all `Envelope`'s own (metadata, descriptor, init); every nested-type symbol is unresolved. - Remaining proof gaps: the issue's Hopper + MCP session was not rerun; the classifier is provider-neutral and the MCP Swift-types boundary test passes. Nested ASCII types are unaffected unless their identifier is word-substituted. - [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:focused -- src/domain/symbolAnalysis.test.ts tests/boundary/mcp/enhancedTools.swiftTypes.test.ts`: 26 passed - `npm run test:local -- src/domain/symbolAnalysis.test.ts` with the classifier change stashed: 2 failed, 15 passed - `npm run check:fast`: passed - Base vs fixed classification of the compiled fixture's real symbols (above) ## Compatibility, safety, and release - Breaking changes or migration steps: none; misattributed nested-type procedures become unresolved. - Real Hopper/Ghidra, browser, or OS coverage: real `swiftc` symbols on macOS arm64; Hopper not run. - Package or release metadata impact: none. - Security, privacy, process, or containment review: no new reads, processes or side effects. ## Author readiness Human owner: <!-- @GitHub-handle --> - [ ] 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. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-11-01 21:44: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#6974
No description provided.