[PR #889] [MERGED] fix(dotnet): compare members with undecoded signatures by exact identity #2321

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

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/889
Author: @kaoru0822-kitauji
Created: 10/7/2026
Status: ✅ Merged
Merged: 10/7/2026
Merged by: @kaoru0822-kitauji

Base: main ← Head: fix/managed-comparison-undecoded-signatures


📝 Commits (6)

  • d52af3b fix(dotnet): compare members with undecoded signatures by exact identity
  • 76b7020 fix(dotnet): keep a decoded member unknown beside an undecoded counterpart
  • 767c6c9 Merge remote-tracking branch 'origin/main' into fix/managed-comparison-undecoded-signatures
  • 73370e1 fix(dotnet): treat ambiguous undecoded members as possible counterparts
  • 7714e76 fix(dotnet): name the shared key in exact-signature ambiguities
  • 5574287 chore: merge main and resolve PR #889 conflicts

📊 Changes

10 files changed (+313 additions, -58 deletions)

View changed files

📝 docs/managed-code-analysis.md (+7 -1)
📝 docs/product-catalog.json (+2 -2)
📝 docs/verification/managed-conformance-manifest.json (+2 -2)
📝 skills/reverse-engineer-anything/SKILL.md (+1 -1)
📝 src/contracts/managedWorkflowToolContracts.ts (+1 -1)
📝 src/domain/managedMemberComparisonCoverage.ts (+2 -1)
📝 src/domain/managedMemberComparisonItems.ts (+130 -38)
📝 src/domain/managedMemberComparisonMatch.ts (+21 -11)
📝 src/generatedMcpToolCatalog.ts (+1 -1)
📝 tests/boundary/providers/managed/managedMemberComparisonFromMetadata.test.ts (+146 -0)

📄 Description

Summary

compare_managed_members / rea compare-managed-members built no match key for a method or field whose signature was not decoded (parse_status unsupported or malformed). Generic instantiations (GENERICINST) are one such form. With complete inventories on both sides, every such member became removed on the left and added on the right, even when the two assemblies were byte-identical.

Comparing a real assembly with itself (Microsoft.PowerShell.PSReadLine.dll from VS Code: 300 of 1638 method signatures and 157 of 1047 field signatures are unsupported):

unchanged added removed unknown
main 1305 457 457 68
this PR 1762 0 0 68

Changes:

  • Exact identity without decoding. The raw signature blob is the exact signature, and decoding only feeds the structural shape keys. The method exact-signature key (declared type, name, raw signature SHA-256) no longer requires a decoded signature. Fields get the same exact-signature fallback round. A decoded field with the same raw signature has already met its counterpart in the field-signature round, so in practice the new round only affects undecoded fields. matching.exact_signature now counts method and field items.
  • No false absence. A member whose undecoded signature still finds no counterpart is reported as unknown, with signature-not-decoded: The member's unsupported signature was compared only by exact declared type, name, and raw bytes, so a changed or renamed counterpart could not be sought. It is never added/removed, because no structural round could run for it. This builds on #604, which already kept undecoded signatures out of structural matching.
  • Decoded counterparts stay unknown too. A decoded one-sided member is unknown with counterpart-signature-not-decoded when the other side has an unmatched member with the same declared type and name whose signature was not decoded (for example, int → an unsupported generic instantiation), because that member may be the same one with a changed signature.

Unchanged: structural matching still requires decoded signatures (#604), and names alone never form a match.

Question for review (not changed here): the remaining 68 unknowns in the self-comparison come from the exact rounds' name-blind keys. For example, 5 static string fields of Microsoft.PowerShell.Pager (startAltBuffer, endAltBuffer, …) share one field signature and are reported as one ambiguous item. Those groups never reach the name-including round. does not guess ambiguous field signature matches pins this behaviour, so I left it. Falling through to the exact (type, name, signature) tuple would resolve them without guessing from names alone.

No schema change. The compare_managed_members description now names the exact (declared type, name, raw signature) tier and the undecoded handling, and the generated catalog, SKILL.md, and conformance manifest are regenerated.

Verification

  • New cases in tests/boundary/providers/managed/managedMemberComparisonFromMetadata.test.ts:
    • identical undecoded method and field signatures pair as exact-signature with complete inventories;
    • changed undecoded signatures are unknown with signature-not-decoded, with 0 added and 0 removed.
    • a decoded member beside a same-named undecoded counterpart is unknown on both sides.
      All fail on main.
  • Real assemblies: the self-comparisons above. Pager.dll vs PSReadLine.dll now reports 0 unmatched-by-key items.
  • npm run check:changed (25 files, 216 tests), npm run docs:check, and all managed boundary/acceptance and src/dotnet tests (28 files, 190 tests) pass. verify:managed-conformance needs the .NET SDK, which is not installed on this host, so it was not run.

No Hopper/Ghidra/IDA verification is needed.

🤖 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/889 **Author:** [@kaoru0822-kitauji](https://github.com/kaoru0822-kitauji) **Created:** 10/7/2026 **Status:** ✅ Merged **Merged:** 10/7/2026 **Merged by:** [@kaoru0822-kitauji](https://github.com/kaoru0822-kitauji) **Base:** `main` ← **Head:** `fix/managed-comparison-undecoded-signatures` --- ### 📝 Commits (6) - [`d52af3b`](https://github.com/morluto/rea/commit/d52af3b321a321964598fb302edeb26552c9dffd) fix(dotnet): compare members with undecoded signatures by exact identity - [`76b7020`](https://github.com/morluto/rea/commit/76b70203d941ab85c1772f330407fd832d438c9c) fix(dotnet): keep a decoded member unknown beside an undecoded counterpart - [`767c6c9`](https://github.com/morluto/rea/commit/767c6c9a95de4b7de4ba5aee74170eeae4fa42d8) Merge remote-tracking branch 'origin/main' into fix/managed-comparison-undecoded-signatures - [`73370e1`](https://github.com/morluto/rea/commit/73370e1c064899753988581c9a821e0e7f579561) fix(dotnet): treat ambiguous undecoded members as possible counterparts - [`7714e76`](https://github.com/morluto/rea/commit/7714e763d9ac2e87994068b3dee37ca6c5ffc6f4) fix(dotnet): name the shared key in exact-signature ambiguities - [`5574287`](https://github.com/morluto/rea/commit/5574287101c633ed22497c1dc3b51ba08e76cde2) chore: merge main and resolve PR #889 conflicts ### 📊 Changes **10 files changed** (+313 additions, -58 deletions) <details> <summary>View changed files</summary> 📝 `docs/managed-code-analysis.md` (+7 -1) 📝 `docs/product-catalog.json` (+2 -2) 📝 `docs/verification/managed-conformance-manifest.json` (+2 -2) 📝 `skills/reverse-engineer-anything/SKILL.md` (+1 -1) 📝 `src/contracts/managedWorkflowToolContracts.ts` (+1 -1) 📝 `src/domain/managedMemberComparisonCoverage.ts` (+2 -1) 📝 `src/domain/managedMemberComparisonItems.ts` (+130 -38) 📝 `src/domain/managedMemberComparisonMatch.ts` (+21 -11) 📝 `src/generatedMcpToolCatalog.ts` (+1 -1) 📝 `tests/boundary/providers/managed/managedMemberComparisonFromMetadata.test.ts` (+146 -0) </details> ### 📄 Description ## Summary `compare_managed_members` / `rea compare-managed-members` built no match key for a method or field whose signature was not decoded (`parse_status` `unsupported` or `malformed`). Generic instantiations (`GENERICINST`) are one such form. With complete inventories on both sides, every such member became **`removed`** on the left and **`added`** on the right, even when the two assemblies were byte-identical. Comparing a real assembly with itself (`Microsoft.PowerShell.PSReadLine.dll` from VS Code: 300 of 1638 method signatures and 157 of 1047 field signatures are `unsupported`): | | unchanged | added | removed | unknown | | --- | --- | --- | --- | --- | | `main` | 1305 | **457** | **457** | 68 | | this PR | 1762 | 0 | 0 | 68 | Changes: - **Exact identity without decoding.** The raw signature blob *is* the exact signature, and decoding only feeds the structural shape keys. The method `exact-signature` key (declared type, name, raw signature SHA-256) no longer requires a decoded signature. Fields get the same exact-signature fallback round. A decoded field with the same raw signature has already met its counterpart in the `field-signature` round, so in practice the new round only affects undecoded fields. `matching.exact_signature` now counts method and field items. - **No false absence.** A member whose undecoded signature still finds no counterpart is reported as `unknown`, with `signature-not-decoded: The member's unsupported signature was compared only by exact declared type, name, and raw bytes, so a changed or renamed counterpart could not be sought.` It is never `added`/`removed`, because no structural round could run for it. This builds on #604, which already kept undecoded signatures out of structural matching. - **Decoded counterparts stay unknown too.** A decoded one-sided member is `unknown` with `counterpart-signature-not-decoded` when the other side has an unmatched member with the same declared type and name whose signature was not decoded (for example, `int` → an unsupported generic instantiation), because that member may be the same one with a changed signature. Unchanged: structural matching still requires decoded signatures (#604), and names alone never form a match. **Question for review (not changed here):** the remaining 68 unknowns in the self-comparison come from the exact rounds' name-blind keys. For example, 5 `static string` fields of `Microsoft.PowerShell.Pager` (`startAltBuffer`, `endAltBuffer`, …) share one field signature and are reported as one ambiguous item. Those groups never reach the name-including round. `does not guess ambiguous field signature matches` pins this behaviour, so I left it. Falling through to the exact (type, name, signature) tuple would resolve them without guessing from names alone. No schema change. The `compare_managed_members` description now names the exact (declared type, name, raw signature) tier and the undecoded handling, and the generated catalog, SKILL.md, and conformance manifest are regenerated. ## Verification - New cases in `tests/boundary/providers/managed/managedMemberComparisonFromMetadata.test.ts`: - identical undecoded method and field signatures pair as `exact-signature` with complete inventories; - changed undecoded signatures are `unknown` with `signature-not-decoded`, with 0 added and 0 removed. - a decoded member beside a same-named undecoded counterpart is `unknown` on both sides. All fail on `main`. - Real assemblies: the self-comparisons above. `Pager.dll` vs `PSReadLine.dll` now reports 0 unmatched-by-key items. - `npm run check:changed` (25 files, 216 tests), `npm run docs:check`, and all managed boundary/acceptance and `src/dotnet` tests (28 files, 190 tests) pass. `verify:managed-conformance` needs the .NET SDK, which is not installed on this host, so it was not run. No Hopper/Ghidra/IDA verification is needed. 🤖 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-10-16 21:17:15 +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#2321
No description provided.