From 80faff3e5bf8baa65b0b18e03594e86753a76ac6 Mon Sep 17 00:00:00 2001 From: N0zoM1z0 <1705004398@qq.com> Date: Thu, 16 Jul 2026 15:05:57 +0800 Subject: [PATCH] docs(analysis): define managed-code evidence boundary --- README.md | 5 +- ...ged-code-evidence-and-provider-boundary.md | 397 ++++++++++++++++++ docs/adr/README.md | 1 + docs/managed-code-analysis.md | 298 +++++++++++++ 4 files changed, 699 insertions(+), 2 deletions(-) create mode 100644 docs/adr/0003-managed-code-evidence-and-provider-boundary.md create mode 100644 docs/managed-code-analysis.md diff --git a/README.md b/README.md index e74d6ed78..3ed4c6ba5 100644 --- a/README.md +++ b/README.md @@ -397,7 +397,8 @@ REA is growing into a toolkit for understanding software across static artifacts 1. **Controlled replay conformance growth** — extend the shipped Linux extracted-module sandbox with more source-owned hostile fixtures and cross-kernel conformance; browser or Electron interaction remains a different future authority. 2. **Broader application graph evidence** — extend authenticated cross-layer traces with additional static extractors and separately approved runtime authorities. -3. **Deterministic behavior harnesses** — extend process ownership, protocol fixtures, filesystem observation, reconnects, and cross-version behavioral comparison. +3. **Professional managed-code analysis** — add execution-free PE/CLI metadata and CIL evidence, obfuscation-resistant comparisons, and explicit managed/native composition under the accepted [managed-code boundary](docs/managed-code-analysis.md). +4. **Deterministic behavior harnesses** — extend process ownership, protocol fixtures, filesystem observation, reconnects, and cross-version behavioral comparison. ### Later @@ -407,7 +408,7 @@ REA is growing into a toolkit for understanding software across static artifacts New providers must produce the same evidence and safety metadata as existing capabilities before they become part of the public workflow. Once REA has multiple optional toolchains, setup can become capability-selective; the consent rules for that future work are recorded in the [installation roadmap](docs/roadmap.md). -See the [static-analysis provider evaluation](docs/provider-evaluation.md) for the shipped Ghidra function-analysis boundary, remaining admission gates, and provider comparison matrix; [ADR-0001](docs/adr/0001-provider-selection-and-analysis-profiles.md) for binding, selection, profile, snapshot, and compatibility decisions; and the [controlled replay guide](docs/controlled-javascript-replay.md) plus [ADR-0002](docs/adr/0002-controlled-replay-authority-and-sandbox.md) for the shipped JavaScript replay boundary. +See the [static-analysis provider evaluation](docs/provider-evaluation.md) for the shipped Ghidra function-analysis boundary, remaining admission gates, and provider comparison matrix; [ADR-0001](docs/adr/0001-provider-selection-and-analysis-profiles.md) for binding, selection, profile, snapshot, and compatibility decisions; the [controlled replay guide](docs/controlled-javascript-replay.md) plus [ADR-0002](docs/adr/0002-controlled-replay-authority-and-sandbox.md) for the shipped JavaScript replay boundary; and [ADR-0003](docs/adr/0003-managed-code-evidence-and-provider-boundary.md) for the planned managed-code evidence and provider design. ## Using REA with other agents diff --git a/docs/adr/0003-managed-code-evidence-and-provider-boundary.md b/docs/adr/0003-managed-code-evidence-and-provider-boundary.md new file mode 100644 index 000000000..245e56439 --- /dev/null +++ b/docs/adr/0003-managed-code-evidence-and-provider-boundary.md @@ -0,0 +1,397 @@ +# ADR-0003: Managed-code evidence and provider boundary + +- Status: Accepted +- Date: 2026-07-16 +- Implementation status: Design only. REA does not yet expose managed-code + operations. PRs that implement this decision must retain the shipped 83-tool + inventory until their caller-visible contracts are deliberately admitted. + +## Context + +Professional C# reverse engineering is not one decompiler operation. A file +described as “.NET” can be ordinary Common Intermediate Language (CIL), +ReadyToRun code containing both CIL and native implementations, a single-file +deployment, C++/CLI mixed mode, Unity Mono, Unity IL2CPP, or NativeAOT. Those +forms have different sources of truth and different native-analysis needs. +Choosing a decompiler before classifying the artifact can therefore produce a +plausible but false model. + +The durable static facts in an ordinary managed PE are its PE/CLI headers, +metadata tables, signatures, method bodies, exception regions, and CIL. A C# +decompiler reconstructs source-like control flow and language constructs from +those facts. That reconstruction is valuable, but it is not the original +source and cannot replace the underlying metadata and CIL evidence. Obfuscation +makes names especially weak while tokens remain coordinates in only one build. + +REA already separates one selected deep native provider from disjoint auxiliary +providers under [ADR-0001](0001-provider-selection-and-analysis-profiles.md). +It also separates static evidence, passive observation, process capture, and +controlled replay authorities. Managed analysis must fit those boundaries +without requiring a CLR to inspect an artifact, loading target code into the +REA process, or treating a managed token as a native address. + +The design is informed by exact-build, reflection-free metadata extraction, +hash-locked method manifests, independent behavior models, and managed/native +boundary analysis performed against a local C# application. The application, +its decompiler output, and its runtime observations are research inputs only; +they are not distributable REA fixtures. + +## Decision drivers + +1. Classify the deployment before selecting an analysis route. +2. Make metadata and CIL independently inspectable without a CLR or target + execution. +3. Preserve exact-build provenance while enabling structural comparison across + builds whose MVIDs, tokens, names, and layout differ. +4. Compose managed and native analysis without introducing another ambiguous + deep-provider candidate. +5. Keep decompiled C# useful but epistemically subordinate to canonical bytes. +6. Analyze Linux, macOS, and Windows managed artifacts through the same local + CLI/MCP contracts on REA's supported hosts. +7. Keep setup additive and prevent managed analysis from installing .NET, + ILSpy, an SDK, or another unrelated toolchain. +8. Prove semantics with source-built conformance artifacts and compact, + operator-local real-application checks. + +## Terminology + +- **Managed artifact**: a PE, bundle component, or related metadata artifact + that carries a CLI header, CLI metadata, CIL, or another managed-runtime + commitment. +- **Classification vector**: independently observed container, runtime family, + implementation form, and architecture. It is not one guessed label. +- **Canonical static observation**: a bounded value decoded directly from the + target bytes under a versioned parser contract. +- **Reconstruction**: source-like output, including decompiled C#, derived from + canonical observations. +- **Structural inference**: a relationship or cross-version match derived from + signatures, APIs, constants, control/data-flow shape, or other observations. +- **Validation**: an independently checked proposition, for example a + source-built oracle assertion or a behavior-model corpus result. +- **Runtime observation**: a separately authorized fact obtained by attaching, + loading, debugging, instrumenting, or otherwise executing code. + +## Decision + +### 1. Classify before analyzing + +Managed triage returns a classification vector and the observations supporting +each dimension. Absence of a marker produces `unknown` or `not_applicable`, not +an invented runtime family. + +| Dimension | Initial values | +| ------------------- | ------------------------------------------------------------------------------------------------------------ | +| Container | PE file, single-file bundle, bundle component, Unity metadata pair, native image, malformed, unknown | +| Runtime family | .NET Framework, modern .NET, Unity Mono, Unity IL2CPP, NativeAOT, mixed CLR/native, unknown | +| Implementation form | CIL, CIL plus ReadyToRun, native only, C++/CLI mixed, metadata only, unsupported, unknown | +| Architecture | PE machine plus CLI flags; component-specific architecture for bundles; conflicting or unknown when required | + +Target-framework attributes, assembly references, metadata stream versions, +bundle manifests, ReadyToRun directories, and native headers are observations. +They may support a runtime-family inference, but no single string is treated as +authoritative when the other bytes conflict. + +Classification selects these routes: + +| Observed form | Managed route | Native route and limitation | +| --------------------------------- | ------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------- | +| Ordinary Framework or modern CIL | Full metadata, signatures, method bodies, and CIL | Optional only for declared interop boundaries | +| Obfuscated CIL | Same canonical route; names receive no special trust | Optional for declared interop boundaries | +| Unity Mono assembly | Same canonical route with Unity context retained | Optional for engine/native boundaries | +| ReadyToRun | Metadata/CIL where present; implementation availability is per method | Selected Hopper/Ghidra analyzes native sections; CIL absence is reported per method | +| C++/CLI mixed mode | Metadata/CIL for managed members and explicit mixed-mode boundary observations | Selected Hopper/Ghidra analyzes native bodies; REA never converts tokens directly to native addresses | +| Single-file deployment | Inventory the bundle, then analyze each authenticated managed component | Selected Hopper/Ghidra analyzes the host/native components; unsupported compression remains explicit | +| Unity IL2CPP | Pair and authenticate available Unity metadata; do not claim canonical CIL | Selected Hopper/Ghidra analyzes the generated native binary; semantic recovery is degraded until supported | +| NativeAOT | Report any independently present managed metadata, otherwise no CIL claim | Treat as a native target with NativeAOT provenance; managed source reconstruction is unavailable | +| Malformed or unsupported artifact | Return bounded partial observations and typed unavailable/unknown scopes | Do not silently retry by loading or executing the file | + +Classification is byte-driven and bounded. File extensions, product names, +process names, and an operator's description are hints only. + +### 2. Implement managed static analysis as a disjoint auxiliary provider + +The initial producer is a REA-owned auxiliary provider with ID +`rea-dotnet-static`. It owns a disjoint managed-artifact operation family. It is +not registered as a Hopper/Ghidra deep-provider candidate because it does not +compete for the same operation names and must be able to coexist with the one +selected native provider. + +```text + one opened artifact/session + | + SessionProviderRouter + / \ + rea-dotnet-static auxiliary selected deep binding + PE/CLI metadata and CIL Hopper or Ghidra + \ / + explicit managed/native links + | + Evidence and workflows +``` + +An ordinary managed artifact can therefore remain unbound to a deep native +provider while managed operations work. ReadyToRun, C++/CLI, IL2CPP, NativeAOT, +and interop workflows may additionally require a caller-selected native +binding. Native-provider failure never causes managed evidence to be relabeled, +and managed-parser failure never causes an implicit native fallback. + +Provider mechanics live under a provider directory such as `src/dotnet/`. +Provider-neutral identities, evidence states, and bounded values may live in +the domain/contracts layers. Application code composes results but does not +parse PE headers, metadata tables, signatures, CIL, ReadyToRun headers, or +provider-specific output. + +### 3. Make the production static path byte-only and execution-free + +`rea-dotnet-static` reads approved local bytes and implements the required +PE/CLI metadata and CIL subset in TypeScript. It does not call any reflection +API and does not require the .NET runtime. In particular, static inspection +must never: + +- call `Assembly.Load`, `Assembly.LoadFrom`, `ReflectionOnlyLoad`, or an + equivalent runtime loader; +- resolve target dependencies by executing target-controlled resolver code; +- run module initializers, constructors, entry points, build tasks, plugins, or + generated helpers; +- start the target, attach to a process, contact a service, or inherit target + configuration and credentials; or +- interpret a decompiler, CLR, or native-provider diagnostic as an observation + from the artifact bytes. + +The parser uses checked offsets and additions, explicit endianness, bounded +table/heap/body counts, cycle-safe traversal, and typed partial results. A bad +row, signature, body, resource, or stream does not authorize an unbounded retry +or a CLR load. Complete-coverage claims require every applicable bounded region +to have been admitted; otherwise coverage is partial, unknown, or unavailable +with exact offsets and reasons. + +The input path remains under REA's approved investigation roots. Local artifact +paths, digests, MVIDs, tokens, malformed offsets, and analysis metadata are +actionable diagnostics and are not secrets. Credentials, authorization data, +and genuine secrets remain redacted. + +### 4. Bind every finding to exact artifact and producer identity + +Every managed result carries a commitment with at least: + +```text +artifact: canonical path + byte length + SHA-256 +component: container identity + component path/name + component SHA-256, when applicable +classification: container + runtime family + implementation form + architecture +assembly/module: simple name + version + culture + public-key identity + module name + MVID +producer: provider ID + exact version + parser/profile schema + profile digest +``` + +An assembly-qualified name does not replace the artifact digest or MVID. +Neither an MVID nor an Authenticode signature proves who authored the behavior. +Bundle components retain both their container and component commitments so that +bytes extracted from another host cannot be silently substituted. + +Method observations add: + +```text +declaring type + normalized CLI signature +build-local metadata token +RVA/file extent when present +exact method-body SHA-256 +normalized-CIL schema version + SHA-256 when CIL is valid +max stack + locals signature + exception-region commitment +``` + +The exact body hash commits header bytes, CIL bytes, and admitted extra +sections. Normalized CIL decodes instructions, converts branch operands to +instruction coordinates, and resolves metadata operands to canonical +signatures or literal identities under a versioned algorithm. It preserves +opcode, prefix, constant, local/argument, generic, and exception semantics. It +does not erase differences merely to make two builds match. + +Metadata tokens are reported because they are precise coordinates inside one +module. Cross-version identity never consists of a token alone. A structural +match cites both build commitments, both local tokens, the normalized inputs, +the matching algorithm version, and all competing candidates. + +### 5. Separate five evidence layers + +Managed workflows retain these layers independently: + +| Layer | Examples | Permitted claim | +| ---------------------- | --------------------------------------------------------------------- | --------------------------------------------------------------- | +| Static observation | Metadata row, signature, CIL opcode, literal, exception region | “These bounded bytes decode to this value.” | +| Reconstruction | Decompiled C#, async/iterator source shape, expression simplification | “This is one source-like representation of cited observations.” | +| Structural inference | Likely caller, field flow, behavior slice, cross-build method match | “These cited structures support this relationship.” | +| Independent validation | Synthetic oracle, corpus result, second parser agreement | “This declared proposition passed the named independent check.” | +| Runtime observation | Exact-build attach/load/instrumentation event | “This separately authorized experiment observed this event.” | + +Each layer has its own producer, authority, state, confidence, coverage, and +limitations. A readable C# method is never emitted as original source or exact +semantic proof. A validator does not upgrade unrelated claims. Runtime +agreement does not retroactively turn a static inference into an observation. + +Negative results are scope-qualified. For example, “no declared P/Invoke rows +were found in the admitted metadata tables” does not prove the application has +no native, dynamically resolved, generated, server-side, or protected path. + +### 6. Admit ILSpy only as an optional reconstruction and conformance tool + +REA's canonical static operations do not depend on ILSpy, a .NET SDK/runtime, +dnlib, or Mono.Cecil. The following review was current on the decision date: + +| Tool | Reviewed coordinate | License | Runtime/host observation | Decision | +| ---------------------------- | ------------------- | ------- | --------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | +| `System.Reflection.Metadata` | 10.0.10 | MIT | Library targets .NET Framework 4.6.2, .NET 8/9/10, and .NET Standard 2.0 | Pinned independent metadata oracle for conformance; not shipped or invoked by production parsing | +| `ICSharpCode.Decompiler` | 10.1.1.8388 | MIT | Library targets .NET Standard 2.0; output is reconstruction | Pinned reconstruction/differential oracle candidate | +| `ilspycmd` | 9.1.0.7988 | MIT | Cross-platform .NET 8 tool; newer 10.1.1.8388 requires .NET 10 | Initial optional BYO reconstruction coordinate because it matches the source research baseline | +| dnlib | 4.5.0 | MIT | Cross-platform library; also exposes assembly-writing APIs | Differential test candidate only; its writable model is outside the production trust boundary | +| Mono.Cecil | 0.11.6 | MIT | Cross-platform .NET Framework/.NET Standard library with read/write support | Differential test candidate only; not a production dependency | + +Coordinates and package hashes used by real verification are checked into a +source-owned lock manifest when that verifier is implemented. “Latest” is +never a reproducibility coordinate. A version change requires conformance and +an explicit profile/version change. + +Artifact platform and REA host support are separate. The byte-only parser must +inspect PE/CLI artifacts produced for Windows on a supported Linux or macOS REA +host; that is not a claim that REA itself currently runs on Windows. Managed +library/tool candidates above are cross-platform at their reviewed targets, but +native composition remains limited by the selected Hopper/Ghidra host and +format support. Real verification runs the canonical path on Linux and macOS +and may run pinned oracle checks on Windows without turning that development +check into a public Windows-host claim. + +If a caller-visible C# reconstruction operation is admitted, it is a distinct +optional capability. It accepts only an exact supported BYO `ilspycmd`, records +the tool and decompiler version, runs in an owned bounded process without +loading target code into REA, and links output to the canonical method +observation. Setup and installers do not download or install ILSpy, .NET, an +SDK, or a runtime. Doctor may inspect an explicitly configured executable and +report exact actionable incompatibility. Missing reconstruction never removes +canonical metadata/CIL capabilities. + +This decision does not make a decompiler process a security sandbox. The +initial public path can defer C# reconstruction while canonical contracts and +process isolation are proven. + +### 7. Use source-built conformance and operator-local real targets + +The repository stores source, build descriptions, expected semantic facts, +and tool lock manifests, but not compiled managed binaries. An isolated build +step creates fixtures outside source directories and records their SHA-256 and +MVID before verification. At minimum, the corpus covers: + +- Framework-compatible and modern .NET metadata; +- AnyCPU, x86, and x64 PE/CLI flags; +- generics, nested types, overloaded signatures, properties, events, resources, + attributes, and constants; +- exceptions, filters, prefixes, switch branches, P/Invoke, async and iterator + state machines; +- obfuscated and Unicode names without assigning semantics from names; +- malformed headers, tables, heaps, signatures, bodies, and exception regions; + and +- two semantically related builds with different MVIDs, tokens, layout, and + selected names. + +Expected facts are checked directly and against pinned +`System.Reflection.Metadata`; ILSpy, dnlib, or Mono.Cecil may add differential +coverage but do not vote by majority. Disagreement is a failing or explicitly +unsupported case, not silently normalized output. + +The real-application benchmark is an operator-local, opt-in osu! check derived +from the research workflow. It accepts an explicit path plus a compact +expectation manifest; verifies target SHA-256, MVID, architecture, and expected +assembly identity before analysis; and emits only bounded identities, tokens, +signatures, IL lengths/hashes, match states, and assertion results. It does not +emit full IL, decompiled source, runtime logs, user data, credentials, or +service/account material. No proprietary binary, hash-locked application +manifest, or derived dump is committed to REA. + +### 8. Keep runtime correlation a different, default-disabled authority + +Static managed support grants no permission to attach, load, debug, reflect, +instrument, invoke, or execute. A future runtime capability must distinguish +those effects, remain disabled by default, require explicit administrator and +per-call approval, and bind to the exact artifact SHA-256, MVID, method +signature, and CIL/body shape observed by the static path. + +Runtime admission must additionally validate host OS, CLR family, architecture, +and supported build/tool versions; bound time, threads, outputs, UI and network +effects; avoid real services and accounts; and own all created processes and +artifacts through complete cleanup. Reflection-only loading is still a CLR load +and is not a substitute for the static byte parser. + +Runtime implementation is intentionally outside the initial static PRs and +requires its own threat model and admission decision. + +## Public contract consequences + +- Managed static operations will have CLI and MCP parity and produce the same + Evidence commitments. +- Adding managed operations changes the caller-visible tool inventory and + generated product catalog only in the implementation PR that admits them. +- Partial parsing includes admitted/dropped counts, exact limitations, and + coverage; it never returns a partial list labeled complete. +- Managed addresses distinguish file offsets, RVAs, native virtual addresses, + metadata tokens, and CIL offsets. They are not interchangeable. +- Cache compatibility is exact on artifact/component commitment, parser + profile, normalized-CIL schema, and producer version. +- Provider-neutral workflows may compose canonical managed findings with the + one native binding, but every source operation retains its actual producer. + +## Alternatives rejected + +### Make ILSpy the only managed provider + +This would make canonical metadata/IL inventory depend on a separately +installed CLR and conflate source reconstruction with byte observations. It +would also make tool-version drift part of ordinary inventory. ILSpy remains a +valuable optional reconstruction and conformance tool instead. + +### Use `Assembly.Load` or reflection-only loading + +Both delegate parsing and dependency behavior to a CLR and make static support +runtime-dependent. Ordinary loading can execute target code; reflection-only +loading still establishes a CLR load boundary and is unavailable across modern +runtimes in a uniform way. Neither is required to decode ECMA-335 bytes. + +### Register the managed analyzer as another deep candidate + +That would force callers to choose managed analysis instead of Hopper/Ghidra +for ReadyToRun and mixed-mode artifacts even though both are needed. Disjoint +auxiliary composition represents the real ownership boundary. + +### Treat tokens, names, or decompiler output as durable identity + +Tokens and obfuscated names change across builds, while decompiler output +changes across tools and versions. They remain useful build-local coordinates +or reconstruction labels but are insufficient for exact or structural +cross-version identity. + +### Package a .NET runtime or mutable managed library in REA + +This would expand installer effects, package size, patching obligations, and +the target-parsing attack surface. The initial byte parser keeps canonical +support within REA's existing Node runtime; external managed tools remain BYO +or development-only oracles. + +## Rollout gates + +1. Add read-only triage and identity with malformed-input bounds. +2. Add metadata, signatures, method bodies, normalized CIL, and exact Evidence. +3. Add obfuscation-resistant slices and cross-build match states. +4. Compose explicit managed/native boundaries with Hopper/Ghidra. +5. Add source-built, pinned real-tool, package, CLI, and MCP conformance. +6. Consider separately authorized runtime correlation only after the static + foundation and its authority model are stable. + +Every gate must keep unsupported ReadyToRun, NativeAOT, IL2CPP, mixed-mode, or +bundle cases explicit rather than broadening claims to make a fixture pass. + +## References + +- [ECMA-335: Common Language Infrastructure](https://ecma-international.org/publications-and-standards/standards/ecma-335/) +- [.NET ReadyToRun deployment overview](https://learn.microsoft.com/en-us/dotnet/core/deploying/ready-to-run) +- [.NET Native AOT deployment overview](https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/) +- [.NET single-file deployment overview](https://learn.microsoft.com/en-us/dotnet/core/deploying/single-file/overview) +- [`System.Reflection.Metadata` package](https://www.nuget.org/packages/System.Reflection.Metadata/10.0.10) +- [ILSpy repository and releases](https://github.com/icsharpcode/ILSpy) +- [dnlib repository](https://github.com/0xd4d/dnlib) +- [Mono.Cecil repository](https://github.com/jbevain/cecil) diff --git a/docs/adr/README.md b/docs/adr/README.md index cf242d5d7..c62f57afc 100644 --- a/docs/adr/README.md +++ b/docs/adr/README.md @@ -8,3 +8,4 @@ states its implementation status separately. | ------------------------------------------------------------------------------------------------------------------ | -------- | --------------------------------------------- | | [0001: Provider selection and analysis profiles](0001-provider-selection-and-analysis-profiles.md) | Accepted | Foundation shipped; capability work continues | | [0002: Controlled JavaScript replay authority and sandbox policy](0002-controlled-replay-authority-and-sandbox.md) | Accepted | Linux x86_64 extracted-module replay shipped | +| [0003: Managed-code evidence and provider boundary](0003-managed-code-evidence-and-provider-boundary.md) | Accepted | Design accepted; implementation planned | diff --git a/docs/managed-code-analysis.md b/docs/managed-code-analysis.md new file mode 100644 index 000000000..42c0c63ff --- /dev/null +++ b/docs/managed-code-analysis.md @@ -0,0 +1,298 @@ +# Managed-code analysis plan + +This document turns +[ADR-0003](adr/0003-managed-code-evidence-and-provider-boundary.md) into an +implementation and verification plan. It describes planned behavior, not +shipped tools. The current product inventory remains the one in +[`product-catalog.json`](product-catalog.json). + +## Analysis objective + +REA's managed-code track is intended to answer five different questions without +collapsing them: + +1. What exact artifact and managed deployment form is this? +2. What do its admitted metadata and CIL bytes state? +3. What source-like or behavioral structure can be reconstructed or inferred? +4. Which findings survive an exact-build check or a cross-build structural + comparison? +5. Which remaining questions require native analysis or a separately + authorized runtime experiment? + +The ordinary workflow ends at question four. Static analysis never loads or +executes the target. + +## Classification workflow + +Classification proceeds from the outermost authenticated bytes inward: + +```text +source path + -> canonical path, size, SHA-256 + -> container inventory + -> PE/native header and architecture + -> CLI header and metadata root + -> deployment/runtime markers + -> per-component and per-method implementation availability + -> managed-only, native-only, composed, degraded, or unsupported route +``` + +The result is a vector rather than one label. For example, a single-file modern +.NET deployment can contain a native host, ordinary CIL assemblies, and +ReadyToRun components. Each component receives its own digest, classification, +coverage, and route while retaining the outer bundle commitment. + +| Case | Required positive observations | Claims that remain unavailable or inferred | +| --------------------- | ---------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | +| .NET Framework | Valid CLI metadata plus bounded Framework-specific target/reference evidence | Exact installed CLR and runtime behavior | +| Modern .NET | Valid CLI metadata plus bounded target/reference/runtime-config evidence | Exact runtime selected on another host | +| Unity Mono | Valid managed assembly plus authenticated Unity context when supplied | Engine behavior or native integration not represented by metadata | +| ReadyToRun | Valid managed metadata plus authenticated ReadyToRun header/sections | Native implementation semantics until a selected deep provider analyzes them | +| C++/CLI | Valid CLI metadata plus mixed-mode PE/header evidence | Mapping managed declarations to native implementations without explicit bridge evidence | +| Single-file | Valid authenticated bundle inventory and component extents | Components that are compressed or encoded by an unsupported bundle version | +| Unity IL2CPP | Authenticated native image/metadata pairing and supported metadata version | Canonical CIL and source-equivalent C# | +| NativeAOT | Native image plus bounded NativeAOT evidence | Ordinary CLI metadata/CIL unless independently present | +| Obfuscated assembly | Same positive byte observations as its underlying deployment form | Meaning inferred only from names | +| Malformed/unsupported | Exact admitted regions and failure locations | Completeness, successfully skipped rows, or semantics beyond the admitted parser boundary | + +## Evidence record shape + +Every planned operation returns a provider result and Evidence with four +commitment groups: + +### Artifact commitment + +- canonical local path, byte length, and SHA-256; +- outer-container identity and digest when inspecting a component; +- component name/path, byte extent, and SHA-256; +- observed PE machine, CLI flags, and conflicts; +- classification vector, supporting observations, and unresolved dimensions. + +### Module commitment + +- assembly simple name, version, culture, public-key/token state, flags, and + hash algorithm; +- module name, generation, and MVID; +- target framework and runtime/version strings with their exact metadata + locations; +- parser/provider version, profile schema, limits, and profile digest. + +### Entity commitment + +- table kind and build-local token; +- declaring scope and normalized CLI signature; +- row/heap/body locations expressed as typed file offsets, RVAs, or CIL + offsets; +- exact raw bytes or bounded value digest; +- method body, normalized CIL, locals, exception-region, and generic-context + commitments where applicable. + +### Epistemic commitment + +- authority: static bytes, reconstruction, structural inference, independent + validation, native provider, or separately authorized runtime; +- state: observed, inferred, unknown, or unavailable; +- confidence independent of authority; +- coverage and admitted/dropped counts; +- exact supporting Evidence IDs and actionable limitations. + +A semantic label such as `score_submission_gate` can annotate an entity, but it +is never the entity's identity. The same applies to an obfuscated name, token, +RVA, or decompiler-generated local name. + +## Planned static capabilities + +The caller-visible grouping and exact tool names are decided with the contracts +that implement them. The underlying capability slices are: + +1. **Triage and inventory**: container/component classification, assembly and + module identity, references, files, exported types, resources, attributes, + and runtime markers. +2. **Member inventory**: bounded types, methods, fields, properties, events, + interfaces, nesting, generics, and normalized signatures. +3. **Method inspection**: headers, max stack, locals, CIL instructions, + constants, metadata operands, exception regions, and implementation flags. +4. **Relationships**: declared overrides, interface implementations, member + references, direct CIL callers/callees, field access, construction, and + interop declarations. Dynamic dispatch remains qualified. +5. **Structural search and comparison**: signature/API/constant/flow anchors, + exact and normalized hashes, competing candidates, and explicit + exact/structural/missing/ambiguous states. +6. **Managed/native composition**: P/Invoke, unmanaged exports, COM/mixed-mode + declarations, ReadyToRun/native bodies, single-file hosts, and authenticated + IL2CPP pairs linked to selected Hopper/Ghidra evidence. + +Every list has a deterministic order and hard limits. Search exposes scanned, +matched, returned, and dropped counts. An unresolved indirect call or a failed +signature decode is not silently omitted from a completeness claim. + +## Obfuscation-resistant method slices + +Names are one weak feature among many. A behavior slice records the smallest +bounded set of observations needed to investigate a proposition: + +- normalized declaring/member signatures and inheritance/interface shape; +- framework and application API references; +- exact strings, numeric constants, enum-like values, and serialization keys; +- branch, switch, exception, loop, call, and field-flow shape; +- construction and generic-instantiation sites; +- exact body and normalized-CIL commitments; +- callers, callees, shared fields, and competing candidates; and +- limitations from reflection, dynamic dispatch, generated code, protection, + native transitions, or incomplete coverage. + +The workflow produces separate observation, inference, validation, and unknown +tables. It may say that a method is a strong candidate for a role; it cannot +turn that role into the method's durable identity. + +Cross-version matching is two-stage: + +1. Exact identity requires compatible artifact/module commitments and an exact + entity/body identity. +2. Structural identity compares schema-versioned signatures, normalized CIL, + APIs, constants, and bounded graph context. It reports all candidates at the + winning score and remains ambiguous when the evidence does not distinguish + them. + +Tokens are always remapped through observed structure. A caller cannot carry +`0x06001234` into a new MVID and assume it names the same method. + +## Managed/native boundary rules + +| Boundary | Managed observation | Native observation | Permitted link | +| ----------------------- | ----------------------------------------------------------------------- | ---------------------------------------------------------------------- | -------------------------------------------------------------------- | +| P/Invoke | Module, entry point, charset/calling-convention flags, declaring method | Import/export/symbol/function evidence from the selected deep provider | Exact declared-name/module link or qualified resolution inference | +| COM | Interop attributes, GUIDs, imported interfaces, method signatures | Native registration/vtable evidence when independently available | Identifier/signature inference with explicit environment limitations | +| C++/CLI | Managed declaration and implementation flags | Native body/function evidence | Only a provider-supported bridge observation; never token-as-address | +| ReadyToRun | Component/header and per-method CIL/native availability | Native section/function evidence | Authenticated image mapping with format/profile version | +| Unmanaged export | Export metadata/attribute when present | PE export and native thunk/function | Exact export identity plus provider-qualified address | +| Single-file host | Bundle entry/component identity | Host and native component evidence | Outer bundle plus component digest/extent commitment | +| Unity IL2CPP | Supported metadata entity with authenticated pairing | Generated native function/type evidence | Versioned IL2CPP mapping only; no invented CIL | +| Runtime-resolved native | API/constant/data-flow candidate | Loaded-module/symbol observation only under future runtime authority | Static candidate remains inference until separately observed | + +Declared import inventory supports a bounded positive claim. Its absence does +not exclude dynamic resolution, generated code, protected code, native helpers, +or server-side behavior. + +## Tool and packaging boundary + +The production parser is REA-owned TypeScript and ships with the existing Node +application. It is verified against the ECMA-335 format and independent pinned +oracles but has no runtime dependency on them. + +- `System.Reflection.Metadata` is the primary independent metadata/CIL oracle. +- `ICSharpCode.Decompiler` and `ilspycmd` are reconstruction and differential + oracles. An admitted BYO reconstruction operation records its exact version + and remains non-canonical. +- dnlib and Mono.Cecil may increase differential coverage. Their mutation APIs + are not exposed or included in the production parsing boundary. +- The package contains no .NET runtime, SDK, ILSpy installation, proprietary + assembly, or compiled conformance fixture. +- Setup never installs or upgrades those tools. Doctor may inspect an explicit + optional path without changing it. + +Real-tool downloads used in development or CI require exact package coordinates +and SHA-256 lock entries. They are cached outside the source tree and restored +into isolated directories. Updating any coordinate requires review of license, +runtime, supported host, output contract, and conformance results. + +Target platform is not host support. The canonical parser must inspect +Windows-produced PE/CLI bytes on REA's supported Linux and macOS hosts with the +same result. Pinned Windows oracle jobs may provide additional conformance, but +they do not claim that the REA application itself supports Windows. Native +ReadyToRun, C++/CLI, NativeAOT, or IL2CPP coverage is additionally constrained +by the selected Hopper/Ghidra host and format matrix. + +## Source-built conformance corpus + +Fixture sources are intentionally small and behavior-focused. Build outputs +are generated outside tracked fixture directories and must not remain after +verification or packaging. + +| Corpus slice | Required properties | +| ---------------------- | ------------------------------------------------------------------------------------------ | +| Identity | Assembly/module/version/culture/public key, references, attributes, resources, MVID | +| Signatures | Nested/generic types, arrays, pointers, by-ref, function pointers where supported, varargs | +| CIL | Short/long branches, switch, prefixes, constants, locals, calls, fields, boxing, tokens | +| Exceptions | Catch, finally, fault/filter where the compiler/toolchain supports them | +| Generated structure | Async and iterator state machines, lambdas, closures, properties, events | +| Interop | P/Invoke flags, module/name mapping, managed/unmanaged implementation metadata | +| Architecture | AnyCPU, preferred-32-bit where applicable, x86, x64 | +| Obfuscation resistance | Unicode/meaningless/duplicate-looking names and structure-preserving renames | +| Cross-build comparison | At least two builds with changed MVID/token order/layout and known same/changed behaviors | +| Malformed/adversarial | Truncated/overflowing headers, streams, tables, heaps, signatures, bodies, and EH sections | + +Verification compares semantic facts, not decompiler text. It checks resource +ceilings, deterministic ordering, complete cleanup, CLI/MCP parity, Evidence +commitments, packed-package behavior, and target-free MCP startup. A parser and +an oracle disagreeing on malformed input is investigated explicitly; one tool's +acceptance does not automatically make the bytes valid. + +## Operator-local osu! benchmark + +The optional osu! benchmark accepts only paths and expectations supplied by the +operator. A compact manifest contains: + +```json +{ + "schema_version": 1, + "target": { + "sha256": "", + "mvid": "", + "assembly_name": "", + "architecture": "" + }, + "methods": [ + { + "label": "operator-local semantic label", + "token": "0x06000000", + "signature": "", + "il_length": 0, + "normalized_il_sha256": "" + } + ] +} +``` + +Before evaluating methods, the verifier fails closed on any target commitment +mismatch. Output contains assertion status and compact identities only. It does +not print method bodies, reconstructed C#, application data, runtime telemetry, +account/service details, or full filesystem inventories. The manifest and +target remain outside git. + +The benchmark may prove that REA reproduces selected facts for that exact local +build. It cannot establish general support on its own; source-built conformance +remains the admission requirement. + +## Runtime admission boundary + +The later runtime track is not an extension flag on a static operation. Its +design must expose whether it attaches to an existing process, launches a new +process, loads an assembly, uses reflection, installs a debugger/profiler, or +instruments code. Each effect needs separate approval and exact-build checks. + +At minimum, admission requires target SHA-256, MVID, normalized signature and +body/CIL commitment, CLR family, OS, architecture, tool version, scenario +limits, output policy, and cleanup ownership to match. Any mismatch fails before +the experiment. It must not contact real services/accounts or claim that an +instrumented path represents an ordinary launch unless that proposition is +independently tested. + +Until that capability is separately designed and shipped, runtime questions +remain explicit unknowns with suggested probes; static support does not perform +them. + +## Delivery sequence + +The managed-code track advances as reviewable pull requests: + +1. accepted evidence/provider boundary (this document and ADR); +2. read-only artifact triage and exact identity; +3. bounded metadata, signatures, method bodies, and normalized CIL; +4. obfuscation-resistant slices and cross-version comparison; +5. managed/native composition and truthful deployment degradation; +6. source-built, pinned real-tool, package, CLI, and MCP conformance; and +7. separately authorized runtime correlation. + +Each implementation PR updates generated product facts only for behavior it +actually ships and states which real-tool checks were performed.