re: the ind_call damage is bounded - no corpus claim was contaminated

The protective sweep after last commit's refutation. The question was which
existing claims the ind_call cross product voids. Answer: none of the ones the
corpus makes.

Every caller-count claim in the corpus verifies against call edges, with zero
ind_call contamination:

  title-crash-stl-tree      sub_82457780  "one caller"     call=1   ind_call=0
  isl-trigger-queue         sub_8226EAB8  "16 callers"     call=16  ind_call=0
  isl-coroutine-spawner     sub_822737C8  "seven callers"  call=7   ind_call=0
  challenge-mission-gate    0x82175110    "22 callers"     call=22  ind_call=0

4 of 4 exact, and not one of the four carries a single ind_call edge.

There is a structural reason for that rather than luck. Partitioning the two
target populations: 1710 targets have ind_call edges, 12170 have call edges, 103
have BOTH, 1607 are ind_call-only, 12067 are call-only. And all 1710 ind_call
targets are vtable entries - 1710 of 1710, zero partials - against a control
where only 273 of the 12170 call targets are. So ind_call fires only on virtual
methods, and 1607 of them have no direct caller at all, which is exactly why the
two EX_ screens came back empty on call and flooded on ind_call.

The residual risk is narrow and nameable: the 103 targets carrying both kinds,
where a caller count taken without a kind filter would be inflated by about 633.
Everywhere else the two populations are disjoint, so a call-based count is safe
and an ind_call-based one is meaningless.

Rule for future work: always filter kind='call'; and when a function has no call
edges, that is a fact about it - it is a virtual method - not a gap to be filled
from ind_call.

All seventeen artefacts byte-identical.
This commit is contained in:
Sylpheed RE agent
2026-08-28 11:24:14 +00:00
parent 6736786b66
commit e23eea36f7
2 changed files with 68 additions and 0 deletions

View File

@@ -184,3 +184,46 @@ structural difference rather than a coincidence.
graph are exhausted for it. A route with actual power would be the RTTI class
behind `ANON_Class_271D5F25` / `_CAA8AD62`, or a runtime watch on the field —
not another static offset search.
### ✅ How far the `ind_call` damage reaches — bounded, and the corpus is clean
The refutation above is corpus-wide in principle, so the next question is which
existing claims it voids. Answer: **none of the ones the corpus makes.**
**Every caller-count claim in the corpus checks out against `call` edges, with
zero `ind_call` contamination:**
| doc | claim | `call` | `ind_call` |
|---|---|---|---|
| `title-crash-stl-tree` | `sub_82457780` "one caller" | **1** | 0 |
| `isl-trigger-queue` | `sub_8226EAB8` "16 callers" | **16** | 0 |
| `isl-coroutine-spawner` | `sub_822737C8` "seven callers" | **7** | 0 |
| `challenge-mission-gate` | `0x82175110` "22 callers" | **22** | 0 |
4 of 4 exact, and none of the four has a single `ind_call` edge.
**And there is a structural reason, not luck.** Partitioning the two target
populations:
| | count |
|---|---|
| targets with `ind_call` edges | 1 710 |
| targets with `call` edges | 12 170 |
| **both** | 103 |
| `ind_call` only | 1 607 |
| `call` only | 12 067 |
🔑 **All 1 710 `ind_call` targets are vtable entries — 1 710 of 1 710, zero
partials.** (Against a control: only 273 of the 12 170 `call` targets are.) So
`ind_call` fires *only* on virtual methods, and **1 607 of them have no direct
caller at all** — which is exactly why the two `EX_` screens came back empty on
`call` and flooded on `ind_call`.
⚠️ **The residual risk, named precisely:** the **103** targets carrying *both*
kinds. There a caller count taken without a `kind` filter would be inflated by
~633. Everywhere else the two populations are disjoint, so a `call`-based count
is safe and an `ind_call`-based one is meaningless.
**Rule for future work:** always filter `kind='call'`; and when a function has no
`call` edges, that is a *fact about it* — it is a virtual method — not a gap to
be filled from `ind_call`.