[PR #2163] [MERGED] feat(managed): name the declaring type of call and field targets #5068

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

📋 Pull Request Information

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

Base: main ← Head: feat/managed-call-target-types


📝 Commits (10+)

  • 8c1cc90 feat(managed): name the declaring type of call and field targets
  • ace5cd0 fix(managed): validate spec blobs and member kinds before naming targets
  • 02bad95 fix(managed): validate MethodSpec arity and report unsupported spec blobs
  • 6fef3ea fix(managed): reject non-method signature headers and invalid TypeRef scopes
  • 35eaa30 fix(managed): hold member rows to MethodDefSig and FieldSig headers
  • 613ba0c fix(managed): accept MethodSpec arity only from a fully decoded signature
  • 9b76dd0 perf(managed): decode each MethodSpec target signature once
  • e59217c fix(managed): validate spec type operands and transitive reference scopes
  • a78f3b4 fix(managed): retain readable names when a scope row is unreadable
  • 2cc6fee test(managed): pin owner-scoped spec operand and scope-chain checks

📊 Changes

9 files changed (+1060 additions, -108 deletions)

View changed files

📝 docs/managed-code-analysis.md (+22 -0)
📝 src/domain/managed/managedArtifact.ts (+18 -1)
📝 src/dotnet/ManagedMemberInspector.test.ts (+376 -18)
📝 src/dotnet/ManagedMemberInspector.ts (+14 -4)
📝 src/dotnet/ManagedMemberInspectorCore.ts (+186 -44)
📝 src/dotnet/ManagedMemberRows.ts (+78 -35)
➕ src/dotnet/ManagedMethodSpecs.ts (+154 -0)
📝 src/dotnet/ManagedPe.fixture.ts (+75 -6)
➕ src/dotnet/ManagedTypeNames.ts (+137 -0)

📄 Description

Note

🤖 Claude Opus 5.5 responding on behalf of Nick

Summary

Fixes #2160.

Call edges named external targets by member name alone, method-spec edges had no name, and field accesses through MemberRefs had no name either. This names the declaring type of every edge target and of each MemberRef parent. Callers can now tell UnityEngine.JsonUtility.ToJson from Newtonsoft.Json.JsonConvert.ToJson, and find every use of a type, without a decompiler.

Problem and expected behavior

Smallest trigger: any call to a MemberRef. target_name is Join, and member_refs[].parent_token points at a TypeRef that no output names. A call to a MethodSpec reports target_name: null. An ldsfld of a MemberRef field reports field_name: null, because the field path only consulted FieldDef rows.

Expected:

  • Each target carries its declaring type in the namespace-qualified form TypeDef full_name already uses.
  • Unknown stays null.
  • Malformed rows stay visible as partial coverage.

Change and scope

  • Type naming: new src/dotnet/ManagedTypeNames.ts. typeNameLookup names a TypeDef from the existing ranges, a TypeRef from its row, and a GENERICINST TypeSpec by its generic type, once per token. TypeSpec blobs are decoded whole with the existing signature grammar through a new specSignature. A GENERICINST base must be a TypeDef or TypeRef (ECMA-335 II.23.2.12), so naming never recurses. Malformed or unsupported blobs and out-of-range rows are reported against their row. TypeRef ResolutionScope chains are checked transitively with cycle detection (morluto, e59217c and a78f3b4). An invalid or cyclic scope is reported as invalid-row and the readable name is kept. A null scope is valid. Type operands inside spec blobs, including nested arguments and custom modifiers, are validated against the metadata tables, and a failure is reported under the owning TypeSpec or MethodSpec row. Other well-formed TypeSpec forms stay null without an issue.
  • Member refs: parseMemberRefs records parent_name and uses it as the MemberRef's declaring type, with its decoded signature kind.
  • One lookup: MethodCore, FieldCore and MemberRefCore were three shapes of the same fact. They merge into one MemberCore with a declaring type and a kind. edgeTargets indexes fields, member refs and methods by token, then adds each MethodSpec an inspected body calls under the generic method it instantiates. MethodSpec reading lives in src/dotnet/ManagedMethodSpecs.ts. It validates the Method column and the Instantiation blob, and checks that the method's signature decodes completely as a generic method with as many parameters as the instantiation supplies. The arity comes from the signature the target's owner already decoded (MemberCore.genericArity for MemberRefs and selected MethodDefs). Only a target nothing decoded, such as a MethodDef outside a --type selection, falls back to a transient raw decode, cached per target method. A readable Method keeps its name beside a malformed instantiation or an arity mismatch, with partial coverage. edges resolves every target through that single map instead of methodCore ?? refCore and a separate field map.
  • Signature headers: every method signature goes through readMethodSignatureHeader, which now checks the header against its context. MethodDef and MemberRef rows accept only MethodDefSig/MethodRefSig headers (ECMA-335 II.23.2.1-2): DEFAULT, VARARG, or GENERIC with DEFAULT, plus HASTHIS/EXPLICITTHIS. FNPTR keeps the unmanaged C, STDCALL, THISCALL, FASTCALL and UNMANAGED conventions that compilers emit. A field signature must be exactly FIELD (II.23.2.4). Any other header is malformed. That includes PROPERTY, LOCAL_SIG, GENERICINST, a flagged FIELD, the reserved bit, and EXPLICITTHIS without HASTHIS. Such a member never passes the MethodSpec arity check and never names a field.
  • Kind guard: a field operand is named only by a field or a field-signature MemberRef. A call operand is named by a method, or by a MemberRef whose signature does not decode, which keeps the previous call-edge behavior. For example, a call on a FieldDef token and an ldsfld on a method MemberRef stay unnamed.
  • Schema: member_refs[].parent_name, call_edges[].target_declaring_type and field_accesses[].field_declaring_type are added as nullable().default(null), so older Evidence reads them as unknown.
  • Fixture: gains optional TypeSpec rows, MethodSpec rows and a MemberRef name. Default fixture bytes are unchanged.

Not included:

  • Cross-assembly resolution. AssemblyRef scopes are not followed.
  • Type-forwarder resolution.
  • Names for ModuleRef or MethodDef MemberRef parents.
  • Array or other non-generic TypeSpec names.
  • Any change to nested type naming. Bare nested names stay, matching TypeDef full_name.

Contract and boundary impact

  • Semantic owner and earliest changed stage: src/dotnet. Type naming has one owner, typeNameLookup, and edge target resolution has one owner, edgeTargets.
  • CLI and MCP/tool-catalog contract: three additive output fields on inspect_managed_members. For method-spec edges, target_name changes from always null to the generic method's name when the MethodSpec row resolves. A member signature whose header is neither an exact FIELD nor a MethodDefSig/MethodRefSig header, such as PROPERTY, C, or a flagged FIELD, now reports kind: unknown and parse_status: malformed instead of decoding as a method or field.
  • Provider, bridge, target-format, or platform compatibility: none.
  • Evidence, artifact, provenance, or reconstruction contract: additive and nullable. Older Evidence parses with the new fields null. Tokens, anchors and digests are unchanged.
  • Process execution, authorization, cleanup, or containment impact: none. Static parsing only.
  • Generated metadata, package, or installation impact: none committed.

Evidence and regression coverage

  • Tests added or updated, all in src/dotnet/ManagedMemberInspector.test.ts:

    • The existing end-to-end test now asserts parent_name, target_declaring_type and field_declaring_type.
    • MethodSpec calls are named after their MemberRef and MethodDef generic methods.
    • A generic TypeSpec parent names its generic type. An SZARRAY TypeSpec stays null with complete coverage.
    • Four malformed generic TypeSpecs give partial coverage and a null name: a TypeSpec base, a missing argument count, and out-of-range TypeRef and TypeDef rows.
    • A malformed MethodSpec instantiation keeps its method's name with partial coverage. An invalid Method coded index is reported and unnamed.
    • A MethodSpec on a non-generic method, with the wrong argument count, or on a field reference is reported as invalid-row.
    • Unsupported TypeSpec and MethodSpec forms raise unsupported-signature instead of reading as unknown.
    • A MethodSpec on a PROPERTY-header, C-convention, or truncated generic MemberRef signature is reported as invalid-row. Member signatures with a PROPERTY, C, or GENERIC|VARARG header, or with EXPLICITTHIS but no HASTHIS, are malformed.
    • A MemberRef with a flagged FIELD header stays unnamed under ldsfld, with partial coverage.
    • A TypeRef with an out-of-range ResolutionScope keeps its name, with an invalid-row issue and partial coverage.
    • A MethodSpec over a field-signature MemberRef stays unnamed under both ldsfld and call.
    • A field-signature MemberRef is named under ldsfld. A method-signature MemberRef under ldsfld, and a call with a FieldDef operand, stay unnamed.
    • Legacy Evidence without the fields parses them as null.
  • Base reproduction: on main, PEAK's Peak.Quicksave (Unity Mono Assembly-CSharp.dll, --type Peak.Quicksave) shows SaveNow -> ToJson, WriteAllText and LoadSaveData -> ReadAllText, plus method-spec 0x2b0002a5 null.

  • User-visible CLI output, same command on this branch, with complete coverage:

    get_SavePath -> UnityEngine.Application.get_persistentDataPath  [member-ref]
    get_SavePath -> System.IO.Path.Join                             [member-ref]
    SaveNow      -> UnityEngine.JsonUtility.ToJson                  [member-ref]
    SaveNow      -> System.IO.File.WriteAllText                     [member-ref]
    LoadSaveData -> System.IO.File.ReadAllText                      [member-ref]
    LoadSaveData -> UnityEngine.JsonUtility.FromJson                [method-spec]
    

    3,830 of 3,841 member refs get a parent_name, and every field access in the class is named, for example Zorro.Core.BuildVersion.MinorVersion. The other 11 have multidimensional-array TypeSpec parents, which stay null by design.

  • Remaining proof gaps: no real-provider lane applies. Fixtures are source-built. The PEAK assembly is a third-party game binary and is not committed.

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

All runs used Node 24.18.0 and npm 11.16.0, per .nvmrc and packageManager.

  • npm run check: passed, including architecture guards. Lint has no new warnings against main. Existing size and complexity warnings in touched files moved by a few lines, and ManagedMemberInspectorCore.ts got shorter.
  • npm run docs:check: passed.
  • npm run verify:test-discovery: passed.
  • npm run test:focused -- on the same 26 managed test files as the sibling PR: 322 passed.
  • Built CLI across real assemblies (a whole 247 KB Unity Assembly-CSharp.dll, PEAK and Valheim type selections, Mono mscorlib.dll List1, Unity.InputSystem.dll): complete coverage, with all 247 method-spec` edges named and arity-checked.
  • Built CLI against PEAK Assembly-CSharp.dll with --type Peak.Quicksave: complete coverage, output above.
  • Type selections whose MethodSpec edges target MethodDefs outside the selection stay complete, and every method-spec edge is named. Mono mscorlib with List`1 and Array selected has at least 16 such edges out of 56. Valheim with Player and ZNet has at least 22 of 137. PEAK Peak.Quicksave has 1 of 2.
  • Signature header check: decoded every FieldDef, MethodDef and MemberRef signature in seven real assemblies (Mono mscorlib, System.Xml, UnityEngine.CoreModule, Unity.InputSystem, and three game assemblies). That is 170,725 signatures: 61,620 fields and 109,105 methods and member references. The header checks reject none of them, and every one still decodes. Member headers seen were only 0x00, 0x05, 0x10, 0x20, 0x30 and exactly 0x06.

Compatibility, safety, and release

  • Breaking changes or migration steps: none. Fields are additive and nullable. method-spec target_name goes from null to a value when resolvable.
  • Real Hopper/Ghidra, browser, or OS coverage: not applicable. Linux x64 only.
  • Package or release metadata impact: none.
  • Security, privacy, process, or containment review: names come from the caller's artifact metadata. Nothing is executed. TypeRef rows read through metadataRowCursor are charged to the existing budget, and each type is named once.

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.

#2162 is a sibling PR that touches the same schema, fixture and docs section. Whichever merges second will need a small rebase.

🤖 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/2163 **Author:** [@Nelglor](https://github.com/Nelglor) **Created:** 10/12/2026 **Status:** ✅ Merged **Merged:** 10/13/2026 **Merged by:** [@morluto](https://github.com/morluto) **Base:** `main` ← **Head:** `feat/managed-call-target-types` --- ### 📝 Commits (10+) - [`8c1cc90`](https://github.com/morluto/rea/commit/8c1cc9055b8698d25e5a3d890dcfa4d3066b374b) feat(managed): name the declaring type of call and field targets - [`ace5cd0`](https://github.com/morluto/rea/commit/ace5cd00bee36d2c562523b2b2f785ce880af4da) fix(managed): validate spec blobs and member kinds before naming targets - [`02bad95`](https://github.com/morluto/rea/commit/02bad95bee91720fb43003548e6ceb12b6e90cb8) fix(managed): validate MethodSpec arity and report unsupported spec blobs - [`6fef3ea`](https://github.com/morluto/rea/commit/6fef3eaabe4147a2c883db90025631d687b5b31d) fix(managed): reject non-method signature headers and invalid TypeRef scopes - [`35eaa30`](https://github.com/morluto/rea/commit/35eaa3062d7e333f780240cf8704651142d89b00) fix(managed): hold member rows to MethodDefSig and FieldSig headers - [`613ba0c`](https://github.com/morluto/rea/commit/613ba0cd6289ff375d376c66b96e8d02259c84e5) fix(managed): accept MethodSpec arity only from a fully decoded signature - [`9b76dd0`](https://github.com/morluto/rea/commit/9b76dd0cf924a721bd5b7522c6a8f56feb3ff3e1) perf(managed): decode each MethodSpec target signature once - [`e59217c`](https://github.com/morluto/rea/commit/e59217c83488bc37d6743c2b59300d901d9982fa) fix(managed): validate spec type operands and transitive reference scopes - [`a78f3b4`](https://github.com/morluto/rea/commit/a78f3b4903dbe78b6230d11899de9002e5524cfe) fix(managed): retain readable names when a scope row is unreadable - [`2cc6fee`](https://github.com/morluto/rea/commit/2cc6feeddb205a1d0d16e1bc126b1656de010533) test(managed): pin owner-scoped spec operand and scope-chain checks ### 📊 Changes **9 files changed** (+1060 additions, -108 deletions) <details> <summary>View changed files</summary> 📝 `docs/managed-code-analysis.md` (+22 -0) 📝 `src/domain/managed/managedArtifact.ts` (+18 -1) 📝 `src/dotnet/ManagedMemberInspector.test.ts` (+376 -18) 📝 `src/dotnet/ManagedMemberInspector.ts` (+14 -4) 📝 `src/dotnet/ManagedMemberInspectorCore.ts` (+186 -44) 📝 `src/dotnet/ManagedMemberRows.ts` (+78 -35) ➕ `src/dotnet/ManagedMethodSpecs.ts` (+154 -0) 📝 `src/dotnet/ManagedPe.fixture.ts` (+75 -6) ➕ `src/dotnet/ManagedTypeNames.ts` (+137 -0) </details> ### 📄 Description > [!NOTE] > 🤖 **Claude Opus 5.5 responding on behalf of Nick** ## Summary Fixes #2160. Call edges named external targets by member name alone, method-spec edges had no name, and field accesses through MemberRefs had no name either. This names the declaring type of every edge target and of each MemberRef parent. Callers can now tell `UnityEngine.JsonUtility.ToJson` from `Newtonsoft.Json.JsonConvert.ToJson`, and find every use of a type, without a decompiler. ## Problem and expected behavior Smallest trigger: any `call` to a MemberRef. `target_name` is `Join`, and `member_refs[].parent_token` points at a TypeRef that no output names. A `call` to a MethodSpec reports `target_name: null`. An `ldsfld` of a MemberRef field reports `field_name: null`, because the field path only consulted FieldDef rows. Expected: - Each target carries its declaring type in the namespace-qualified form TypeDef `full_name` already uses. - Unknown stays `null`. - Malformed rows stay visible as partial coverage. ## Change and scope - **Type naming:** new `src/dotnet/ManagedTypeNames.ts`. `typeNameLookup` names a TypeDef from the existing ranges, a TypeRef from its row, and a GENERICINST TypeSpec by its generic type, once per token. TypeSpec blobs are decoded whole with the existing signature grammar through a new `specSignature`. A GENERICINST base must be a TypeDef or TypeRef (ECMA-335 II.23.2.12), so naming never recurses. Malformed or unsupported blobs and out-of-range rows are reported against their row. TypeRef ResolutionScope chains are checked transitively with cycle detection (morluto, e59217c and a78f3b4). An invalid or cyclic scope is reported as `invalid-row` and the readable name is kept. A null scope is valid. Type operands inside spec blobs, including nested arguments and custom modifiers, are validated against the metadata tables, and a failure is reported under the owning TypeSpec or MethodSpec row. Other well-formed TypeSpec forms stay `null` without an issue. - **Member refs:** `parseMemberRefs` records `parent_name` and uses it as the MemberRef's declaring type, with its decoded signature kind. - **One lookup:** `MethodCore`, `FieldCore` and `MemberRefCore` were three shapes of the same fact. They merge into one `MemberCore` with a declaring type and a kind. `edgeTargets` indexes fields, member refs and methods by token, then adds each MethodSpec an inspected body calls under the generic method it instantiates. MethodSpec reading lives in `src/dotnet/ManagedMethodSpecs.ts`. It validates the Method column and the Instantiation blob, and checks that the method's signature decodes completely as a generic method with as many parameters as the instantiation supplies. The arity comes from the signature the target's owner already decoded (`MemberCore.genericArity` for MemberRefs and selected MethodDefs). Only a target nothing decoded, such as a MethodDef outside a `--type` selection, falls back to a transient raw decode, cached per target method. A readable Method keeps its name beside a malformed instantiation or an arity mismatch, with partial coverage. `edges` resolves every target through that single map instead of `methodCore ?? refCore` and a separate field map. - **Signature headers:** every method signature goes through `readMethodSignatureHeader`, which now checks the header against its context. MethodDef and MemberRef rows accept only MethodDefSig/MethodRefSig headers (ECMA-335 II.23.2.1-2): DEFAULT, VARARG, or GENERIC with DEFAULT, plus HASTHIS/EXPLICITTHIS. FNPTR keeps the unmanaged C, STDCALL, THISCALL, FASTCALL and UNMANAGED conventions that compilers emit. A field signature must be exactly FIELD (II.23.2.4). Any other header is malformed. That includes PROPERTY, LOCAL_SIG, GENERICINST, a flagged FIELD, the reserved bit, and EXPLICITTHIS without HASTHIS. Such a member never passes the MethodSpec arity check and never names a field. - **Kind guard:** a field operand is named only by a field or a field-signature MemberRef. A call operand is named by a method, or by a MemberRef whose signature does not decode, which keeps the previous call-edge behavior. For example, a call on a FieldDef token and an `ldsfld` on a method MemberRef stay unnamed. - **Schema:** `member_refs[].parent_name`, `call_edges[].target_declaring_type` and `field_accesses[].field_declaring_type` are added as `nullable().default(null)`, so older Evidence reads them as unknown. - **Fixture:** gains optional TypeSpec rows, MethodSpec rows and a MemberRef name. Default fixture bytes are unchanged. Not included: - Cross-assembly resolution. AssemblyRef scopes are not followed. - Type-forwarder resolution. - Names for ModuleRef or MethodDef MemberRef parents. - Array or other non-generic TypeSpec names. - Any change to nested type naming. Bare nested names stay, matching TypeDef `full_name`. ## Contract and boundary impact - Semantic owner and earliest changed stage: `src/dotnet`. Type naming has one owner, `typeNameLookup`, and edge target resolution has one owner, `edgeTargets`. - CLI and MCP/tool-catalog contract: three additive output fields on `inspect_managed_members`. For `method-spec` edges, `target_name` changes from always `null` to the generic method's name when the MethodSpec row resolves. A member signature whose header is neither an exact FIELD nor a MethodDefSig/MethodRefSig header, such as PROPERTY, C, or a flagged FIELD, now reports `kind: unknown` and `parse_status: malformed` instead of decoding as a method or field. - Provider, bridge, target-format, or platform compatibility: none. - Evidence, artifact, provenance, or reconstruction contract: additive and nullable. Older Evidence parses with the new fields `null`. Tokens, anchors and digests are unchanged. - Process execution, authorization, cleanup, or containment impact: none. Static parsing only. - Generated metadata, package, or installation impact: none committed. ## Evidence and regression coverage - Tests added or updated, all in `src/dotnet/ManagedMemberInspector.test.ts`: - The existing end-to-end test now asserts `parent_name`, `target_declaring_type` and `field_declaring_type`. - MethodSpec calls are named after their MemberRef and MethodDef generic methods. - A generic TypeSpec parent names its generic type. An SZARRAY TypeSpec stays `null` with complete coverage. - Four malformed generic TypeSpecs give partial coverage and a `null` name: a TypeSpec base, a missing argument count, and out-of-range TypeRef and TypeDef rows. - A malformed MethodSpec instantiation keeps its method's name with partial coverage. An invalid Method coded index is reported and unnamed. - A MethodSpec on a non-generic method, with the wrong argument count, or on a field reference is reported as `invalid-row`. - Unsupported TypeSpec and MethodSpec forms raise `unsupported-signature` instead of reading as unknown. - A MethodSpec on a PROPERTY-header, C-convention, or truncated generic MemberRef signature is reported as `invalid-row`. Member signatures with a PROPERTY, C, or GENERIC|VARARG header, or with EXPLICITTHIS but no HASTHIS, are malformed. - A MemberRef with a flagged FIELD header stays unnamed under `ldsfld`, with partial coverage. - A TypeRef with an out-of-range ResolutionScope keeps its name, with an `invalid-row` issue and partial coverage. - A MethodSpec over a field-signature MemberRef stays unnamed under both `ldsfld` and `call`. - A field-signature MemberRef is named under `ldsfld`. A method-signature MemberRef under `ldsfld`, and a call with a FieldDef operand, stay unnamed. - Legacy Evidence without the fields parses them as `null`. - Base reproduction: on `main`, PEAK's `Peak.Quicksave` (Unity Mono `Assembly-CSharp.dll`, `--type Peak.Quicksave`) shows `SaveNow -> ToJson`, `WriteAllText` and `LoadSaveData -> ReadAllText`, plus `method-spec 0x2b0002a5 null`. - User-visible CLI output, same command on this branch, with complete coverage: ```text get_SavePath -> UnityEngine.Application.get_persistentDataPath [member-ref] get_SavePath -> System.IO.Path.Join [member-ref] SaveNow -> UnityEngine.JsonUtility.ToJson [member-ref] SaveNow -> System.IO.File.WriteAllText [member-ref] LoadSaveData -> System.IO.File.ReadAllText [member-ref] LoadSaveData -> UnityEngine.JsonUtility.FromJson [method-spec] ``` 3,830 of 3,841 member refs get a `parent_name`, and every field access in the class is named, for example `Zorro.Core.BuildVersion.MinorVersion`. The other 11 have multidimensional-array TypeSpec parents, which stay `null` by design. - Remaining proof gaps: no real-provider lane applies. Fixtures are source-built. The PEAK assembly is a third-party game binary and is not committed. 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 All runs used Node 24.18.0 and npm 11.16.0, per `.nvmrc` and `packageManager`. - `npm run check`: passed, including architecture guards. Lint has no new warnings against `main`. Existing size and complexity warnings in touched files moved by a few lines, and `ManagedMemberInspectorCore.ts` got shorter. - `npm run docs:check`: passed. - `npm run verify:test-discovery`: passed. - `npm run test:focused --` on the same 26 managed test files as the sibling PR: 322 passed. - Built CLI across real assemblies (a whole 247 KB Unity `Assembly-CSharp.dll`, PEAK and Valheim type selections, Mono `mscorlib.dll` `List`1`, `Unity.InputSystem.dll`): complete coverage, with all 247 `method-spec` edges named and arity-checked. - Built CLI against PEAK `Assembly-CSharp.dll` with `--type Peak.Quicksave`: complete coverage, output above. - Type selections whose MethodSpec edges target MethodDefs outside the selection stay complete, and every `method-spec` edge is named. Mono `mscorlib` with ``List`1`` and `Array` selected has at least 16 such edges out of 56. Valheim with `Player` and `ZNet` has at least 22 of 137. PEAK `Peak.Quicksave` has 1 of 2. - Signature header check: decoded every FieldDef, MethodDef and MemberRef signature in seven real assemblies (Mono `mscorlib`, `System.Xml`, `UnityEngine.CoreModule`, `Unity.InputSystem`, and three game assemblies). That is 170,725 signatures: 61,620 fields and 109,105 methods and member references. The header checks reject none of them, and every one still decodes. Member headers seen were only 0x00, 0x05, 0x10, 0x20, 0x30 and exactly 0x06. ## Compatibility, safety, and release - Breaking changes or migration steps: none. Fields are additive and nullable. `method-spec` `target_name` goes from `null` to a value when resolvable. - Real Hopper/Ghidra, browser, or OS coverage: not applicable. Linux x64 only. - Package or release metadata impact: none. - Security, privacy, process, or containment review: names come from the caller's artifact metadata. Nothing is executed. TypeRef rows read through `metadataRowCursor` are charged to the existing budget, and each type is named once. ## 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. #2162 is a sibling PR that touches the same schema, fixture and docs section. Whichever merges second will need a small rebase. 🤖 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-31 01:02:20 +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#5068
No description provided.