mirror of
https://github.com/Cesarus85/ringfall-mjolnir-vr.git
synced 2026-10-18 07:00:26 +02:00
Land the final Tier B wave: three structural park reopens (+477 meaningful)
The owner-authorized final implementation wave worked only the ten Tier B functions of the research campaign, each a structural defect confirmed by two independent lenses; census first, five evidence-driven shapes at most, stop at allocation, scheduling or x87 ties. Three closed, seven did not. - hud _temporary_hud_draw_reticle: January does a SIGNED `% 16` (`and eax, 0x8000000f; jns; dec; or -16; inc`) where ours did `and eax,0xf`. NUMBEROF yields size_t, so `next_point_index % NUMBEROF(points)` was an unsigned modulo; a signed named count NUMBER_OF_TEMPORARY_HUD_RETICLE_POINTS sizes the array and bounds the loop. It fixes the type, not a cast. The three point stores become one set_real_point3d call (laws_w2 A4). - weapons _weapon_can_be_fired: single-exit form (A3). It writes `result = FALSE` in two arms, which I tested against the identical-fake-branch prohibition: the merged `if (age >= 1.0f || chain)` spelling is residual, while January emits a SEPARATE physical FALSE exit for the age test (`jne; pop edi; xor al,al; pop esi; pop ebp; ret` at 0x35-0x3c) before game_engine_running is ever called. Two distinct rejection blocks is laws_w3 A26's admission criterion, unlike the rejected _bink_query_analog_controller_buttons, whose edges share one block. - rasterizer_transparent_geometry _rasterizer_transparent_geometry_initialize: single exit `success = success && aux_buffer()`. Semantics are unchanged; the error block is the last statement before the call, so the short-circuit sits exactly where the early return did. All three parks removed. Not closed and reported in the wave ledgers: _path_state_traverse, _flag_update, _bitmap_2d_sharpen, _light_volume_render, _actor_stimulus_prop_acknowledged, _stack_memory_pool_allocate, _particle_system_new_particle_jet. Full ninja, parks 268 active / 0 stale / 0 invalid, stable diff vs scratch/opus5-next150-before.json: gained 15 / 9,504 padded, regressions 0; fake_match_scan 0 leads on all three files, matching HEAD. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
6d6529d987
commit
26601453ef
14 files changed
+1230
-86
No files matched your search
@@ -1274,25 +1274,6 @@
|
||||
"objdiff_percent": 84.69773
|
||||
}
|
||||
},
|
||||
{
|
||||
"unit": "source/rasterizer/rasterizer_transparent_geometry",
|
||||
"function": "_rasterizer_transparent_geometry_initialize",
|
||||
"class": "instruction-scheduling",
|
||||
"evidence": "The retained ordinary C is the complete transparent-geometry lifecycle initializer: it allocates the primary 384-group pool, the 384-entry sorted-index array, and the secondary 32-group pool with the January source path and line numbers, clears both group counts, reports the attested silent allocation error, and initializes the Xbox auxiliary buffer. This topology is independently corroborated by the later HCEA implementation, the Stian lift, and the historical b6adf6705 donor. Target and candidate share the 160-byte padded envelope, 51-instruction count, and all 16 logical relocation destinations. The sole fixed point is block placement: January keeps the error block before the auxiliary-buffer call, while VC7 lays out the success call before the error block and uses SETNE for the successful return. Four documented natural result-lifetime/error-path families, public donors, and a 1,571-worktree census produced the same candidate hash or regressed it. No assembly, volatile access, barrier, fake dependency, dead branch, raw address, or optimizer-only carrier is retained. Reopen only for authoritative January source/local records or a natural same-compiler donor that explains this block order.",
|
||||
"measurements": {
|
||||
"target": {
|
||||
"size": 160,
|
||||
"relocation_count": 16,
|
||||
"normalized_sha256": "63251d0d8cc730b0de774a4c06b489f06bd0af5849fa8281705d46e40473e678"
|
||||
},
|
||||
"base": {
|
||||
"size": 160,
|
||||
"relocation_count": 16,
|
||||
"normalized_sha256": "15f6dc8cbb204d551c2c25b60baf4e21ca760125fc43678f40cb24a48fcbdbe4"
|
||||
},
|
||||
"objdiff_percent": 76.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"unit": "source/rasterizer/rasterizer_transparent_geometry",
|
||||
"function": "_rasterizer_sort_external",
|
||||
@@ -1825,25 +1806,6 @@
|
||||
"objdiff_percent": 94.235954
|
||||
}
|
||||
},
|
||||
{
|
||||
"unit": "source/interface/hud",
|
||||
"function": "_temporary_hud_draw_reticle",
|
||||
"class": "instruction-scheduling",
|
||||
"evidence": "Fuzzy-parked under the current house rule with a complete ordinary-C reticle renderer recovered from January disassembly: it constructs sixteen typed world-space points from sine/cosine and the render view transform, then closes the ring through rasterizer_debug_line. January and the retained candidate have the same six relocation identities. The residual is limited to two compiler choices: January schedules the pi/8 x87 add before call-stack cleanup, and retains the generic signed remainder-by-16 sequence, whereas VC7 proves the reconstructed index nonnegative and emits an and 0xf. Natural for-loop, increment-placement, signed long-index, pointer-loop, and declaration-order variants were tested; they either return to this fixed point or perturb more code. No volatile or register forcing, artificial signedness carrier, inline assembly, barrier, raw offset, fake dependency, undefined behavior, or nonsensical control flow is retained. Reopen only for authoritative January source/local-lifetime evidence or a natural same-compiler donor explaining both the x87 and remainder schedules.",
|
||||
"measurements": {
|
||||
"target": {
|
||||
"size": 208,
|
||||
"relocation_count": 6,
|
||||
"normalized_sha256": "34a33fe789d2858840e360558ebc1d2674a329e6a14d59572a3dfb9c1bc2255c"
|
||||
},
|
||||
"base": {
|
||||
"size": 192,
|
||||
"relocation_count": 6,
|
||||
"normalized_sha256": "676b43cbdb66de19263a32f71a6c895b867d638c75f5fcd404e031b808e47afa"
|
||||
},
|
||||
"objdiff_percent": 90.676926
|
||||
}
|
||||
},
|
||||
{
|
||||
"unit": "source/bitmaps/bitmap_utilities",
|
||||
"function": "_bitmap_2d_smooth",
|
||||
@@ -4404,25 +4366,6 @@
|
||||
"objdiff_percent": 81.60833
|
||||
}
|
||||
},
|
||||
{
|
||||
"unit": "source/items/weapons",
|
||||
"function": "_weapon_can_be_fired",
|
||||
"class": "unclassified",
|
||||
"evidence": "Complete typed ordinary-C firing predicate retained after auditing the historically stronger Fable weapons blob 45d791510 and independently corroborating its behavior against January control flow and the HCEA semantic reconstruction. The body rejects fully aged weapons and otherwise applies the authentic game-engine, magazine-capacity, loaded-round, and reserve-round policy through weapon_get, weapon_definition_get, TAG_BLOCK_GET_ELEMENT, project types, and the proper game_engine.h API owner. Target and candidate share the 144-byte padded envelope and five relocation destinations, while ordinary VC7 control-flow placement remains different; objdiff reports 84.69 percent similarity. The historical combined-condition residual is superseded by this target-shaped sequential form. No branch-spelling search, local prototype, raw offset, surrogate layout, volatile/register forcing, barrier, pragma, assembly, fake dependency, or nonsensical branch is retained. Zero exact credit. See docs/object_matching_logs/weapons_obj_historical_packet_reconciliation_20260912.md.",
|
||||
"measurements": {
|
||||
"target": {
|
||||
"size": 144,
|
||||
"relocation_count": 5,
|
||||
"normalized_sha256": "ba8b3806624808498c9815871e5b6e94428c0dac363ca1543591f6530687cedc"
|
||||
},
|
||||
"base": {
|
||||
"size": 144,
|
||||
"relocation_count": 5,
|
||||
"normalized_sha256": "a0706edaa4f925be59bbbd739403e62a5a21407645eaeea1670d7dc4c38ff4e3"
|
||||
},
|
||||
"objdiff_percent": 84.6875
|
||||
}
|
||||
},
|
||||
{
|
||||
"unit": "source/hs/hs_runtime",
|
||||
"function": "_render_debug_trigger_volumes",
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
# `actor_stimulus.obj` — opus5 next-150K lane, final implementation wave, Tier B (B5) (2026-09-16)
|
||||
|
||||
HEAD `6d6529d98`. Scope: `_actor_stimulus_prop_acknowledged` only (parked, `register-allocation`).
|
||||
|
||||
| gate | result |
|
||||
| --- | --- |
|
||||
| baseline real file | `== exact 21 residual 1 unwritten 0`, `_point_from_line3d` guard passes |
|
||||
| final real file (unchanged) | `== exact 21 residual 1 unwritten 0`, guard passes, park drift 0, fake scan 0 leads |
|
||||
|
||||
`git diff --stat -- source/ai/actor_stimulus.c` is empty. No credit is claimed. 0 new landing shapes spent.
|
||||
Worker notes: `scratch/workers/tB_actor_stimulus.md`; artefacts in `scratch/workers/tB_actor_stimulus/`.
|
||||
|
||||
## `_actor_stimulus_prop_acknowledged`: SKIPPED-EXHAUSTED (Tier B lenses do not hold as a source defect)
|
||||
|
||||
Target 800 / 32 / `b66ac2399346e003`, 243 insns, `sub esp,0x38`. Real file 800 / 32 / `0f62d6950730557f`, `sub esp,0x34`.
|
||||
|
||||
### Census
|
||||
|
||||
- **Relocations:** 32 / 32 with an identical multiset by symbolic target. There is no missing or extra call or global.
|
||||
At HEAD the only order difference is the combat ternary (w2 tH fixes it).
|
||||
- **Registers:**
|
||||
- January: ESI=prop, EBX=actor (spilled at its definition), EDI=prop_index, then surprise_level.
|
||||
- Ours: ESI=prop, EDI=actor (never spilled), EBX=prop_index, then surprise_level (spilled at every definition).
|
||||
- **Frame:**
|
||||
- January cells: definition -4, `'<'/'>'` -8, close/far -0xc, shoot -0x10, **combat_status spill -0x14**,
|
||||
**actor spill -0x18**, direction -0x28 (16 B), surprise_names -0x38 (32 B).
|
||||
- Ours: **surprise_level spill -4**, then the same declared objects, each one cell nearer.
|
||||
- Every declared local exists on both sides. Only spill cells differ.
|
||||
- `scratch/research/frame-slot-ranking/frameslot.py` gives `SPILL-MISSING / REGISTER-FAMILY` on the real file and on
|
||||
the tH base.
|
||||
- **Mechanism, from the bytes.** In both builds the printf push sequence borrows EBX as its fourth scratch register:
|
||||
- The web that owns EBX is split-spilled.
|
||||
- Ours keeps actor alive in EDI through that block, so VC7 rematerialises `combat_status` from `[edi+0x6e]`.
|
||||
- January's actor register is clobbered there, so combat_status gets a home.
|
||||
- The +4 frame and the +4 code bytes of the tH base are therefore consequences of the EBX/EDI choice.
|
||||
|
||||
### Lens re-verification
|
||||
|
||||
1. **Frame lens.** The byte fact holds: January stores at +0xBF and reads `cmp word ptr [ebp-0x14],0` at +0x21E. The
|
||||
inference that January has an extra declared local does not hold, because the F3 detector classifies the gap
|
||||
REGISTER-FAMILY.
|
||||
2. **M8 lens.**
|
||||
- **At HEAD.** Re-run confirmed: D=1..7 fix the dot (106 -> 105 differing instructions).
|
||||
- **Where the odd ordinal comes from.** Our `(word)actor_index` cast adds it.
|
||||
- Diagnostic d1 (HEAD plus only w2 tE, `DATUM_INDEX_TO_ABSOLUTE_INDEX(actor_index)`) has January's dot at D=0.
|
||||
January proves tE with `mov ecx,[ebp+8] ... and ecx,0xffff`.
|
||||
- Diagnostic d2 (HEAD plus only the tH ternary polarity) does not.
|
||||
- **On the January-proven tE+tH base.**
|
||||
- The base reproduces w2 exactly: 816/32 `cb3b25a1`.
|
||||
- `mod8.py` gives **NOT-MOD8**, and **D=1 re-breaks the dot**.
|
||||
- M8 therefore refutes adding one genuine local.
|
||||
|
||||
Neither lens supports the implied change ("add January's genuine extra local"). Per the owner's requirements 1 and 3
|
||||
the row was stopped without spending shapes.
|
||||
|
||||
### Residual on the best-evidence base (tH)
|
||||
|
||||
Every differing instruction is one of:
|
||||
- an EBX<->EDI operand;
|
||||
- a frame offset shifted by one cell;
|
||||
- a spill store (ours 4x `mov [ebp-4],ebx`; January `xor eax,eax`, `mov [ebp-0x14],eax`, `mov [ebp-0x18],ebx`);
|
||||
- `cmp word [ebp-0x14],0` vs `cmp word [edi+0x6e],0`;
|
||||
- a relocation displacement.
|
||||
|
||||
There is no control-flow, call, width, literal or x87 difference. The +4 code bytes push the padded size to 816.
|
||||
The 21 siblings stay exact on tH, the guard passes, and parkcheck drifts only the park.
|
||||
|
||||
Classification: REGISTER-ALLOCATION. Research section 2.3 says the REGISTER-FAMILY class has no declaration lever by
|
||||
construction.
|
||||
|
||||
### Evidence consulted
|
||||
|
||||
- January COFF alndiff, tinfo, relocdiff, frameslot and mod8 (all re-run at HEAD).
|
||||
- HCEX.pdb `DIA2Dump -sym`:
|
||||
- params: `actor_index`, `prop_index`, `reappearance`, `expected`;
|
||||
- the only non-enregistered local is `struct direction_specification direction`;
|
||||
- there is no scalar local list, so it gives no evidence of an extra owner.
|
||||
- HCEA `blam/ai/actor_stimulus_prop_acknowledged.c`:
|
||||
- a retail lift with no debug block;
|
||||
- its float `aim_dot`, re-tested at each site, contradicts January's single fcomp into DL, so `boolean flanked` stays.
|
||||
|
||||
### Do not repeat
|
||||
|
||||
- Adding one local to the tE+tH base: refuted by M8, since D=1 breaks the dot.
|
||||
- Treating the combat_status home as a missing declaration: frameslot says REGISTER-FAMILY.
|
||||
- Everything w2 and n2 already record: tA `word`, tB `long`, tG early load, and a local read in the late status
|
||||
test (January reads the field).
|
||||
|
||||
### Correction for the research findings table
|
||||
|
||||
B5 is not a named structural defect:
|
||||
- Lens 1 is a register-family spill cell.
|
||||
- Lens 2's odd ordinal is our `(word)actor_index` cast temp, which the January-proven tE spelling removes.
|
||||
|
||||
Recommend reclassifying B5 to the register-allocation pool. Record tE+tH as the required fidelity base for any
|
||||
future reopen.
|
||||
|
||||
### Reopen criterion
|
||||
|
||||
- The park criterion is unchanged: authoritative January local records, or a natural same-compiler donor that
|
||||
explains the EBX/EDI lifetime choice.
|
||||
- Start from `scratch/workers/tB_actor_stimulus/tH.c` (tE + tH).
|
||||
- Respect the M8 constraint: January's IL count != tH+1 (mod 8).
|
||||
- tE+tH alone are +16 padded, so they can land only together with the allocation fix.
|
||||
@@ -0,0 +1,149 @@
|
||||
# `bitmap_utilities.obj` — next-150K lane, final implementation wave tierB (2026-09-16)
|
||||
|
||||
## Outcome
|
||||
|
||||
Nothing landed. `source/bitmaps/bitmap_utilities.c` is unchanged (`git diff --stat` is empty).
|
||||
|
||||
Baseline and final real-file gate (with the `_point_from_line3d` guard): **exact 43, residual 5, unwritten 0**, the
|
||||
same row for row. The guard passes. `scratch/parkcheck.py` reports 5 parks with 0 drift. The owner census matches
|
||||
`build/base`. The fake-match scan finds 0 leads.
|
||||
|
||||
| function | January padded / meaningful / relocs | status | result |
|
||||
| --- | --- | --- | --- |
|
||||
| `_bitmap_2d_sharpen` (Tier B row B3, the only function in scope) | 1152 / 1151 / 29 | parked | NOT-LANDED: the implied type change is refuted; the loop-form fix removes the width lens; register allocation remains, so the work stopped |
|
||||
| `_bitmap_2d_alpha_bleed`, `_bitmap_2d_smooth`, `_bitmap_3d_smooth`, `_bitmap_sharpen` | — | parked | out of scope for this wave |
|
||||
|
||||
Worker notes, with the census, every measurement and the per-function block: `scratch/workers/tB_bitmap_utilities.md`.
|
||||
Scratch files are in `scratch/workers/tB_bitmap_utilities/`:
|
||||
- `v1.c`, `v2.c` and `v3.c` are the three shapes;
|
||||
- `d1.c` is the keystone diagnostic;
|
||||
- `mk.py` builds a candidate;
|
||||
- `o_*.txt` and `aln_*.txt` hold the disassembly and alignments.
|
||||
|
||||
## Assignment and duplicate prevention
|
||||
|
||||
The orchestrator assigned research-campaign row B3.
|
||||
- **Evidence given:** "F3 DECLARED-TYPE: cells -8/-12/-16 read at 2 and 4 bytes by us, 4 only by January".
|
||||
- **Implied change:** declare `y`, `byte_index` and `row_size`/`next_y` as `long`.
|
||||
- **Second label on the row:** F6 = TIE. That label only means no earlier wave closed the row. It does not identify a defect.
|
||||
|
||||
Read before the census:
|
||||
- all nine `bitmap_utilities_obj_*` ledgers;
|
||||
- the w1 worker notes (s5a/s5f/s5g, the 417-order sweep) and the w3c worker notes (four byte facts, no shape);
|
||||
- laws_w2, laws_w3, and the research campaign (sections 2-5).
|
||||
|
||||
`git log --all` shows 14 commits; the newest is 723ce4dd3. `branch_sweep.py` finds no better blob. The row was still
|
||||
non-exact at baseline: 1184/29, sha `8a988645f8b5734c`.
|
||||
|
||||
## Census (written before any shape)
|
||||
|
||||
- **tinfo.** January is 1152 padded (1151 meaningful, 371 instructions), 29 relocations, sha `38d28fa8cc7ad114`.
|
||||
The HEAD park is 1184/29.
|
||||
- **Frame.** `sub esp,0x3c` on both sides. The slot-by-slot table is in the worker notes. At HEAD, January's cells
|
||||
-8/-0xc/-0x10 hold `previous_row`, `current_row` and a pointer IV, read only as dwords. Ours hold the short
|
||||
`wrapped_left` IV, `y` and `wrapped_right`.
|
||||
- **Relocations by target.** Counts are equal for every target:
|
||||
- calls: `bitmap_verify`, `display_assert` ×4, `system_exit` ×4, `bitmap_get_pixel_data_size`, `debug_malloc`,
|
||||
`bitmap_2d_address` ×3, `bitmap_mipmap_address`, `csmemcpy`, `debug_free`, `error`;
|
||||
- literals: the file string ×6, and each of the four assert/diagnostic strings once.
|
||||
|
||||
No call or global is missing or extra.
|
||||
- **Registers.**
|
||||
- January: EBX holds `bitmap` from entry. ESI holds `negative_table` (private ABI). EDI holds `y` at the row head,
|
||||
then `byte_index`, with `push edi` shrink-wrapped to +0xf1. `temporary_pixels` and every row pointer stay in memory.
|
||||
- HEAD park: EDI holds `bitmap`, then `current_row`. EBX holds `temporary_pixels`, then `previous_row`.
|
||||
|
||||
## Lens re-verification
|
||||
|
||||
The F3 byte fact reproduces: `frameslot.py` on the HEAD object reports cells -8/-12/-16 as DECLARED-TYPE. **The implied
|
||||
change is contradicted by January's own bytes.** January's short variables live in EDI and are provably 16-bit:
|
||||
- `test di,di` at +0x100;
|
||||
- `cmp di,4` at +0x240;
|
||||
- `cmp di,cx` at +0x25a, +0x33a and +0x42a;
|
||||
- `cmp di,word ptr [ebp-0x20]` at +0x415;
|
||||
- `movsx eax,di` at +0x269 and +0x346.
|
||||
|
||||
Shape 1 applied the implied `long` declarations. It reaches size 1152, but it emits 32-bit `test edi,edi` and `cmp ecx,4`
|
||||
and shrinks the frame to 0x38, so the size match is a coincidence.
|
||||
|
||||
The width delta is a symptom. HEAD hoists `short row_size = 4 * bitmap->width`, so `row_size + byte_index` becomes an
|
||||
induction variable homed as a short. January re-reads `bitmap->width` on every iteration: a byte store through
|
||||
`destination_row` may alias it. January's wrapped index is therefore a per-iteration `movsx` temporary homed as a dword.
|
||||
|
||||
## Shapes (3 of 5)
|
||||
|
||||
| # | shape | evidence | size/relocs | aligned target insns | verdict |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| 0 | HEAD park | — | 1184/29 | 154/372 | baseline |
|
||||
| 1 | `long y, next_y, row_size, byte_index` (implied change) | research B3 | 1152/29 sha | 157 | refuted by widths (see above); reverted |
|
||||
| 2 | loop forms from the bytes, HEAD term order kept | see list below | 1200/29 sha | 184 | prologue becomes January's `push ebx; mov ebx,[ebp+8]`; loop forms match; wrapped-term order reversed; reverted |
|
||||
| 3 | shape 2 + natural row-major kernel order | January loop 1 emits `pW cW nW`; the HEAD (HCEA decompiler) order emits `nW cW pW`; w1 measured that row-major reproduces January | 1184/29 sha `7e1a852d964151c9` | 209 | best; scratch only |
|
||||
|
||||
Byte facts behind the loop forms in shape 2:
|
||||
- **Loop 1 has no `row_size` local.** January compiles it as a compare loop that re-reads the width on every
|
||||
iteration (+0x195..+0x247). The source is `for (byte_index = 0; byte_index < 4; byte_index++)` with
|
||||
`short wrapped_left = 4 * bitmap->width + byte_index;`.
|
||||
- **The loop 2 bound is a short local.** January compares it at 16 bits (`cmp di,cx`, +0x25a) and counts the loop with
|
||||
a 16-bit trip count (`movzx ecx,cx`, +0x288). The source is
|
||||
`for (last_byte_index = 4 * bitmap->width - 4; byte_index < last_byte_index; byte_index++)`.
|
||||
- **Loop 3 reuses that bound plus 4.** January adds 4 and stores it back to the same cell (+0x337/+0x33d), and loop 3
|
||||
re-reads the width for `wrapped_right` (+0x370). The source is
|
||||
`for (last_byte_index += 4; byte_index < last_byte_index; byte_index++)` with
|
||||
`short wrapped_right = byte_index - 4 * bitmap->width;`.
|
||||
|
||||
HCEA's `bitmap_2d_sharpen.c` independently shows the `(4*width-4)+4` bound.
|
||||
|
||||
Each shape was gated as a whole TU. All 43 exact rows stayed exact, and parkcheck drift was limited to the target.
|
||||
|
||||
### What remains in shape 3
|
||||
|
||||
Every hunk was read:
|
||||
- The row header computes the same values in the same order.
|
||||
- The loop bodies use January's instruction forms, and loop 1's term order is identical.
|
||||
- On shape 3's object, `frameslot.py` now reports **WIDTH-SELECTION / NOT-A-DECLARATION**: all data widths are equal.
|
||||
The B3 lens is resolved.
|
||||
|
||||
The remaining difference is **which web owns EDI**. In January, EDI holds `y` and then `byte_index`. In ours, EDI holds
|
||||
`temporary_pixels` before and after the loop, `previous_row` across calls 2-3, and the pointer IVs inside the loops.
|
||||
Two consequences follow from that assignment:
|
||||
- `y` is spilled, with an extra rotation `jmp`;
|
||||
- in loops 2 and 3, the IV representative is ours `dest+bi` instead of January's `prev+bi` with a `dest-prev` store
|
||||
offset.
|
||||
|
||||
This is register allocation. Following owner requirement 3, the work stopped. No law in laws_w2/w3 or the research
|
||||
campaign names a source construct that moves callee-saved web ownership:
|
||||
- M8 governs x87 leaves;
|
||||
- H3 governs block-head reload order;
|
||||
- F3 part 0 is a statistical use-count ranking with no source lever.
|
||||
|
||||
HCEX.pdb has no `bitmap_2d_sharpen` (or `bitmap_sharpen`/`bitmap_2d_smooth`) symbol, so there is no local-list evidence.
|
||||
|
||||
## Diagnostic: w3c keystone hypothesis
|
||||
|
||||
w3c proposed that a correct `_bitmap_2d_sharpen` might keep `_bitmap_2d_uncompress_from_mipmap` exact when
|
||||
`_bitmap_2d_smooth` is reopened.
|
||||
|
||||
`d1.c` combines w3c `m4.c` (the 2d_smooth reopen) with the shape-3 sharpen block. It gives 43 exact:
|
||||
`_bitmap_2d_smooth` becomes EXACT and uncompress becomes residual. That is identical to `m4.c` re-measured at this HEAD.
|
||||
**A structurally corrected but non-exact sharpen does not hold the coin.** The hypothesis remains untested only for an
|
||||
exact sharpen body.
|
||||
|
||||
## Corrections for the research campaign ledger
|
||||
|
||||
- **B3 implied change:** `long` types are REFUTED (32-bit ops and a 0x38 frame; January's y/byte_index are provably
|
||||
16-bit).
|
||||
- **B3 mechanism:** HEAD's hoisted `row_size` and the loop forms are the real defect behind the F3 DECLARED-TYPE
|
||||
verdict. Fixing them (shape 3) changes the verdict to NOT-A-DECLARATION and leaves a register-allocation residual.
|
||||
Reclassify the row to Tier C / register-allocation.
|
||||
|
||||
## Reopen criterion
|
||||
|
||||
Either of these would reopen the row:
|
||||
- a measured law, or January-side evidence, that names why `y`/`byte_index` rather than
|
||||
`temporary_pixels`/`previous_row` win EDI in VC7's allocator;
|
||||
- an authoritative local list for this function.
|
||||
|
||||
Start from `scratch/workers/tB_bitmap_utilities/v3.c`. Do not re-spend these:
|
||||
- declared-type (`long`) changes;
|
||||
- kernel term-order sweeps (w1);
|
||||
- `row_size` hoisting variants.
|
||||
@@ -0,0 +1,126 @@
|
||||
# `flags.obj` — next-150K lane, final implementation wave tierB (2026-09-16)
|
||||
|
||||
## Outcome
|
||||
|
||||
Nothing landed. `source/objects/widgets/flags.c` is unchanged (`git diff --stat` is empty). No source shape was cut.
|
||||
|
||||
Baseline and final real-file gate (with the `_point_from_line3d` guard): **exact 14, residual 2, unwritten 0**, the
|
||||
same row for row. The guard passes. `scratch/parkcheck.py` reports 1 park with 0 drift. The fake-match scan finds 0
|
||||
leads.
|
||||
|
||||
| function | January padded / meaningful / relocs | status | result |
|
||||
| --- | --- | --- | --- |
|
||||
| `_flag_update` (Tier B row B2, the only function in scope) | 1184 / 1170 / 26 | parked | SKIPPED-EXHAUSTED: the width lens is refuted at HEAD; only register allocation and slot ranking remain |
|
||||
| `_flag_render_proper` | 2112 / 84 relocs | residual, not parked | out of scope for this wave |
|
||||
|
||||
## Assignment and duplicate-prevention record
|
||||
|
||||
The orchestrator assigned research-campaign Tier B row B2. Its evidence was "F3 DECLARED-TYPE: January reads cell -4 as
|
||||
`word`+`dword` (a `short`); ours reads it via x87/mov". The implied change was to declare the local homed at January's
|
||||
-4 as `short` (A34 value-width fact). The second label on the row is F6 = TIE, a home permutation
|
||||
(`scratch/research/campaign-adjudication/xstudy.txt:55`).
|
||||
|
||||
Read before the census:
|
||||
- all 12 `flags_obj_*` ledgers, including the park ledger `flags_obj_flag_update_credible_fuzzy_park_20260903.md`, w2
|
||||
`flags_obj_opus5_150k_w2_20260914.md` and w3c `flags_obj_opus5_250k_w3c_20260915.md`;
|
||||
- worker notes `scratch/workers/flags.md` and `scratch/workers/w3c_flags.md`;
|
||||
- the parked.json criterion;
|
||||
- laws_w2, laws_w3, and the research campaign findings (LAW I, M8, F3/D/U, H3, LAW C, LAW E, CJ4, and the section 4
|
||||
negative register and retired levers).
|
||||
|
||||
History checks:
|
||||
- `git log --all -- flags.c` shows 17 commits.
|
||||
- `branch_sweep` checked 12 blobs. None carries an exact `_flag_update`.
|
||||
|
||||
## Census (written before any shape)
|
||||
|
||||
**Shape.** Both functions have frame `sub esp,0x300`, 1184 padded bytes and 26 relocations. alndiff aligns 390 January
|
||||
instructions against 393 of ours. The code is identical through 0xa5. The x87 schedule, calls, branches and exits align
|
||||
1:1.
|
||||
|
||||
**Relocations by target.** The 26 targets are identical in symbolic multiset and order. The `__real@` rows differ only in
|
||||
the known literal COMDAT representation, with the same symbolic names. The addresses from 0x2a0 on move by -1/+2
|
||||
because of the three extra instructions. No call or global is missing or extra.
|
||||
|
||||
**Frame.** Every aggregate, array, byte cell and parameter home has the same displacement and access pattern on both
|
||||
sides. Only the scalar pool differs:
|
||||
|
||||
| owner | January | ours | access kinds |
|
||||
| --- | --- | --- | --- |
|
||||
| `short row` (flags.c:521) | -4 | -8 | January: 3 16-bit memory reads + 3 dword stores/loads. Ours: the same 16-bit reads through DX + dword stores/loads |
|
||||
| `fild` conversion temp | -8 | -0x10 | identical |
|
||||
| `short neighbor_count` (flags.c:528) | -8 (shared) | -0xc | identical |
|
||||
| `real wind_scale` (flags.c:533) + neighbor-loop countdown | -0xc | -4 | identical |
|
||||
| `short column` (flags.c:507) | -0x10 | -0x14 | identical (2b:4, 4b:3) |
|
||||
| `real weight_sum` / `inverse_weight` (flags.c:570-571) | -0x14 / -0x14 | -0x10 / -0xc | identical |
|
||||
|
||||
No cell exists on only one side. There is no dead run and no parameter home recycled on only one side.
|
||||
|
||||
## Re-verification of the lenses: refuted as a type defect
|
||||
|
||||
1. **frameslot.py at HEAD.** It still prints `cell -4: January INT data-widths [2, 4] | ours MIX data-widths [4]`. The
|
||||
byte fact reproduces, but cell -4 has **different owners** on the two sides.
|
||||
- January's -4 holds `row`.
|
||||
- Ours holds `wind_scale` and the loop countdown, which is where "MIX" comes from.
|
||||
- Per owner, the access widths are identical. January's `movsx eax,word [ebp-4]`, `add cx,word [ebp-4]` and
|
||||
`movsx eax,word [ebp-4]` match ours' `movsx ecx,dx`, `add cx,dx` and `movsx eax,dx`, all 16-bit.
|
||||
- `row` is **already declared `short`**, so the implied change is already in the source.
|
||||
- No other owner shows a width difference.
|
||||
2. **f4law.py verdict** (independent cross-check) → SOURCE-WIDTH. The instances it cites are `add R16, word ptr [ebp-4]`
|
||||
vs `add R16, R16` and `movsx R32, word ptr [ebp-4]` vs `movsx R32, R16`. Both sides are 16-bit selections, and the
|
||||
operand is memory vs register for the same short `row`.
|
||||
|
||||
Both lenses reduce to the fact that w2 and w3c already recorded, a use-count register web:
|
||||
- Ours keeps `row` in EDX from `point_physics_update` (0x215) to the latch, including `add edx,eax`, a store and a
|
||||
loop-head reload.
|
||||
- January re-reads `[ebp-4]` at every use, and its latch re-enters at the row store (`jmp 0x109`).
|
||||
- As a result, `neighbor_count` takes EDX in January and ESI in ours.
|
||||
- The F3 scalar-pool permutation then follows at equal frame size.
|
||||
|
||||
## Shapes
|
||||
|
||||
None.
|
||||
- The implied source change is already present.
|
||||
- No byte fact names any other type, scope, statement or call defect.
|
||||
- Requirement 3 says to stop once only register allocation, scheduling or x87 ordering remains.
|
||||
- The levers that remain are all retired by the research campaign:
|
||||
- moving a slot by a one-reference gap at equal frame (F3 N10);
|
||||
- block scope for spill cells (F3 N14; w3c f1/f2 measured it negative on this function);
|
||||
- dead or filler declarations (the M8/H3 instrument, never a landing);
|
||||
- H3 numbering (no genuine declaration-census difference is evidenced).
|
||||
|
||||
## Classification and reopen criterion
|
||||
|
||||
**Classification.** Register allocation (the `row` EDX web) plus the downstream F3 scalar stack-home ranking. This is
|
||||
class D, not a declared-type defect. The park is unchanged.
|
||||
|
||||
**Reopen criterion.** The park criterion, sharpened, applies. Reopen only on one of:
|
||||
- January-side source or local evidence of an extra or removed `row` reference in the relaxation path. This is the only
|
||||
change measured to dissolve the EDX web (w2 D1/D3, diagnostics).
|
||||
- A measured VC7 register-pass rule that keeps a short loop index out of an EDX web without changing its IL use count.
|
||||
|
||||
A width/type lens is refuted for this row.
|
||||
|
||||
## Proposals
|
||||
|
||||
None for header or config.
|
||||
|
||||
**Tooling note for the orchestrator.** No change is requested.
|
||||
- frameslot.py's DECLARED-TYPE class compares widths by displacement, not by owner. It fires falsely on an equal-frame
|
||||
permutation when the moved owner is read through a register web on one side.
|
||||
- f4law's SOURCE-WIDTH counts `R16, word [mem]` vs `R16, R16` as a width-selection difference.
|
||||
- B2 should be re-tagged Tier C.
|
||||
|
||||
## Checks
|
||||
|
||||
- Final real-file gate with the guard: exact 14, residual 2, unwritten 0, identical to baseline row for row.
|
||||
- `git diff --stat -- source/objects/widgets/flags.c` is empty.
|
||||
- `scratch/parkcheck.py`: `OK _flag_update 1184 26`, 1 park, 0 drift.
|
||||
- `tools/fake_match_scan.py source/objects/widgets/flags.c`: 0 review leads.
|
||||
- Owner census: there is no source change, so the owner set is unchanged.
|
||||
|
||||
## Scratch
|
||||
|
||||
- Notes: `scratch/workers/tB_flags.md`
|
||||
- Census artifacts: `scratch/workers/tB_flags/v0.c` (== real file), `v0.obj`, `aln_v0.txt`, `aln_v0_full.txt`, `T.txt`,
|
||||
`O.txt`
|
||||
@@ -0,0 +1,103 @@
|
||||
# `hud.obj`, next-150K lane Tier B wave (2026-09-16)
|
||||
|
||||
Scope: one function, research campaign target **B8** `_temporary_hud_draw_reticle` (196 meaningful / 208 padded).
|
||||
It is parked, so only scratch copies were edited. `source/interface/hud.c` is unchanged: `git diff --stat` is empty.
|
||||
Worker notes are in `scratch/workers/tB_hud.md`. All artifacts are in `scratch/workers/tB_hud/`.
|
||||
|
||||
## Outcome
|
||||
|
||||
| function | target | real file (baseline = final) | scratch candidate | status |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `_temporary_hud_draw_reticle` | 208 / 6 / `34a33fe789d28588` | 192 / 6 / `676b43cbdb66de19` | **208 / 6 / `34a33fe789d28588`, strict EXACT** | PARK-REOPEN-PROPOSED |
|
||||
| `_hud_show_action_response` | 1744 / 120 | 1744 / 120 | 1744 / 120 (no drift) | out of scope |
|
||||
|
||||
- Candidate: `scratch/workers/tB_hud/reopen_candidate.c`. It is the current real file plus the reopened body and its TU-local count constant.
|
||||
- Candidate whole-TU gate: exact 20 → **21**, residual 2 → 1. Only the target row changed.
|
||||
- Real file at the end: gate identical to the baseline (20/2/0), guard passed, parkcheck 2 parks / 0 drift.
|
||||
|
||||
## Census (recorded before any shape)
|
||||
|
||||
- **Frame:** January `sub esp,0xc4`, ours the same. Slots on both sides: `radius` at `[ebp-4]`, `points[16]` at `[ebp-0xc4]`, the `angle` parameter reused as the loop accumulator at `[ebp+8]`, and `color` at `[ebp+0xc]`. frameslot.py says FRAME-CLEAN.
|
||||
- **Relocations:** 6 against 6, with the same targets: `__real@3f000000`, `__real@3d800000`, `_render+168`, `_matrix4x3_transform_point`, `__real@3ec90fdb`, `_rasterizer_debug_line`. The literal rows differ only in the systemic symbol-vs-defined literal class.
|
||||
- **Hunks at HEAD** (alndiff 77 vs 66 instructions; f4law STRUCT-COUNT):
|
||||
1. January `call matrix4x3_transform_point; fld [ebp+8]; fadd [pi/8]; add esp,0xc; …; fstp [ebp+8]`. Ours emits the `add esp,0xc` before the `fadd`.
|
||||
2. January `and eax,0x8000000f; jns; dec eax; or eax,-16; inc eax`, a signed `% 16`. Ours emits `and eax,0xf`.
|
||||
- **The two campaign lenses still hold at this HEAD.**
|
||||
- **The campaign's implied source change is refuted.** It said to declare the dividend as a signed type, but `next_point_index` is already `long`. The unsigned remainder comes from the divisor: `NUMBEROF` is `sizeof/sizeof`, a `size_t`, so `long % size_t` is unsigned whatever type the dividend has.
|
||||
|
||||
## Mechanism and evidence
|
||||
|
||||
1. **x87 schedule = laws_w3 A31(a), constructor routing controls the flush.**
|
||||
- Three x87 member stores (`points[i].x = …; .y = …; .z = …;`) flush the deferred cdecl pop early.
|
||||
- Routing the same values through `set_real_point3d(&points[point_index], cosine(angle) * radius, sine(angle) * radius, -0.0625f)` flushes it late, and the bytes before the call stay identical.
|
||||
- A31(a) had been measured on only one function (`_lightning_offset_marker_position`). This is a second function, and it comes with a necessity control.
|
||||
- Same-family precedent: render_debug.c:710-715 and 922-931 build `rasterizer_debug_line` points with `set_real_point3d`. laws_w2 A4 closed the render_debug circle/sphere/point functions with the same routing.
|
||||
2. **Signed remainder = a signed-int named count.**
|
||||
- January's generic signed sequence proves the divisor was a signed `int` constant, not `NUMBEROF`.
|
||||
- The house idiom for a fixed count used as an array extent and a ring modulus is an anonymous enum constant in the TU constants section. There are 301 `NUMBER_OF_/MAXIMUM_ = N` enum constants in `.c` files, against 6 `#define`s.
|
||||
- Same-pattern precedents: `VECTOR_AVOIDANCE_NUMBER_OF_DIRECTIONS` (actor_moving.c:246, used as an array extent and in the `(i + 1) %` ring walk) and `NUMBER_OF_EDITOR_CAMERA_SPEED_STEPS` (editor_flying_camera.c:104-107, `%` ring).
|
||||
- It is not a cast, so the R7 rejection of `% (long)NUMBEROF(points)` does not apply. It also replaces the bare `16` array extent.
|
||||
3. HCEA, Stian, punpckhdq and the hs7 exports have no copy of this function, so there is no cross-build evidence either way.
|
||||
|
||||
Candidate change (all in hud.c):
|
||||
|
||||
```c
|
||||
enum
|
||||
{
|
||||
NUMBER_OF_TEMPORARY_HUD_RETICLE_POINTS = 16
|
||||
};
|
||||
...
|
||||
real_point3d points[NUMBER_OF_TEMPORARY_HUD_RETICLE_POINTS];
|
||||
...
|
||||
for (point_index = 0; point_index < NUMBER_OF_TEMPORARY_HUD_RETICLE_POINTS; point_index++)
|
||||
{
|
||||
set_real_point3d(
|
||||
&points[point_index],
|
||||
cosine(angle) * radius,
|
||||
sine(angle) * radius,
|
||||
-0.0625f);
|
||||
matrix4x3_transform_point(...);
|
||||
angle += _pi / 8.0f;
|
||||
}
|
||||
...
|
||||
line_count = NUMBER_OF_TEMPORARY_HUD_RETICLE_POINTS;
|
||||
...
|
||||
&points[next_point_index % NUMBER_OF_TEMPORARY_HUD_RETICLE_POINTS],
|
||||
```
|
||||
|
||||
## Shapes (4 of the 5 allowed)
|
||||
|
||||
| shape | change | result |
|
||||
| --- | --- | --- |
|
||||
| S1 | A31 `set_real_point3d` routing | 192 [size, sha]. Hunk 1 is gone; only the remainder is left. |
|
||||
| S2 | S1 + the enum count constant | **208/6 strict EXACT**, 21/1 (this is the candidate) |
|
||||
| C1 (control) | enum only, no A31 | 208 [sha]: the fadd/`add esp` hunk returns, so A31 is necessary |
|
||||
| C2 (control) | A31 + `#define … 16` instead of the enum | EXACT: the closure is not a declaration-count (H3) artifact of the added enum |
|
||||
|
||||
## Admission checks on the candidate
|
||||
|
||||
1. Strict EXACT in the whole-TU gate, with the same sha as January.
|
||||
2. Row diff against the baseline `--all` listing: only `_temporary_hud_draw_reticle` changes, residual → EXACT.
|
||||
3. The `_point_from_line3d` guard passed.
|
||||
4. parkcheck: `_hud_show_action_response` OK (1744/120). The target drifts to exact, which is the reopen itself.
|
||||
5. Owner census against `build/base`: the only new owner is `_set_real_point3d`, a select-any COMDAT (selection 2).
|
||||
- This is the accepted systemic real_math.h class: laws_w2 A4 names `_set_real_point3d`, laws_w3 A30 covers it, and 16 base objects already emit it.
|
||||
- Nothing is missing relative to base.
|
||||
6. fake_match_scan: 0 leads, the same as HEAD.
|
||||
7. Authenticity: the programmer builds a 16-point ring in view space with the ordinary point constructor, transforms it to world space, and closes it with a wrap-around index modulo the named point count.
|
||||
8. There are no new private statics.
|
||||
|
||||
## Proposal (orchestrator)
|
||||
|
||||
**PARK-REOPEN `_temporary_hud_draw_reticle`.** Apply `scratch/workers/tB_hud/reopen_candidate.c` and delete the function's `config/parked.json` entry in the same commit. No other park needs re-measuring. There is no header change; the consumers are hud.c only.
|
||||
|
||||
The park's criterion is "authoritative January source/local-lifetime evidence or a natural same-compiler donor explaining both the x87 and remainder schedules". This candidate meets it on both halves:
|
||||
- **x87 schedule:** met by A31(a), a measured same-compiler law, with a necessity control.
|
||||
- **Remainder:** the park's premise ("VC7 proves the index nonnegative") is refuted by the `size_t` divisor. A signed named count, not a cast, reproduces January's sequence.
|
||||
|
||||
Verifier decision point carried over from w3: that worker asked for a ruling on "a `% 16` literal vs a TU-local count define". This candidate uses the house enum-constant idiom, not a literal or a cast.
|
||||
|
||||
## Reopen criteria / do-not-repeat
|
||||
|
||||
- If the verifier rejects the named count constant, the only remaining difference is the signed remainder. A31 alone (S1) closes the x87 schedule. Do not re-spend on loop, increment, pointer or accumulator-local variants (w2 x1-x5, w3 e2/e3/t1/t2).
|
||||
- The campaign's "declare the dividend signed" hypothesis is refuted and must not be retried.
|
||||
@@ -0,0 +1,149 @@
|
||||
# `light_volumes.obj`: next-150K lane, Tier B wave (B4 `_light_volume_render`, 2026-09-16)
|
||||
|
||||
## Result
|
||||
|
||||
Nothing landed. `source/objects/widgets/light_volumes.c` is **unchanged** (`git diff --stat` is empty).
|
||||
|
||||
| gate | result |
|
||||
| --- | --- |
|
||||
| baseline, with the `_point_from_line3d` guard | exact 9 / residual 1 / unwritten 0 |
|
||||
| final, with the guard | the same, row for row |
|
||||
| park drift | 0 |
|
||||
| fake scan | 0 leads |
|
||||
|
||||
**Scope.** One function, `_light_volume_render`. It is parked as `tu-context-optimization`, so any work on it happens only in scratch.
|
||||
|
||||
**Verdict: SKIPPED-EXHAUSTED at census time.**
|
||||
- Zero new source shapes were spent.
|
||||
- After the mandatory census, only x87 register allocation remains: which real value lives on the x87 stack, and whether a phi is kept in memory or on the x87 stack.
|
||||
- Owner requirement 3 says to stop at that point.
|
||||
|
||||
| | padded / relocs / frame / sha16 | instructions |
|
||||
| --- | --- | ---: |
|
||||
| January | 912 / 47 / 0xa4 / `2e43dbc111ad1255` | 291 |
|
||||
| real file (park base) | 928 / 47 / 0xa8 / `a4e273c7939882fc` | 296 |
|
||||
| w2 `lvJ`, re-measured at HEAD | 944 / 48 / 0xac | 302 |
|
||||
|
||||
Worker notes: `scratch/workers/tB_light_volumes.md`. Scratch artifacts: `scratch/workers/tB_light_volumes/`:
|
||||
- `v0.c` and `v0.obj` (the real file);
|
||||
- `lvJ_re.c` and `lvJ_re.obj` (a byte copy of the w2 `lvJ.c`);
|
||||
- `jan.dis`, `ours0.dis` and `lvJ.dis`;
|
||||
- `slots.py`.
|
||||
|
||||
## Duplicate checks
|
||||
|
||||
**Ledgers read:**
|
||||
- `light_volumes_obj_jonas_partial`;
|
||||
- `_jonas_interpolator_recovery_20260826`;
|
||||
- `_jonas_distance_fade_schedule_fixed_point_20260826`;
|
||||
- `_jonas_exhaustive_census_20260830`;
|
||||
- `_credible_fuzzy_closeout_20260831`;
|
||||
- `_opus5_150k_w2_20260914`;
|
||||
- `_opus5_250k_w3d_20260915`;
|
||||
- the research campaign `opus5_next150_research_campaign_20260916` (row B4; xstudy F3=DECLARATION, F6=TIE);
|
||||
- `laws_w2` and `laws_w3`;
|
||||
- both worker briefs.
|
||||
|
||||
**Other checks:**
|
||||
- `git log --all`: last touched in `3cbc29777`.
|
||||
- `branch_sweep`: 15 blobs. None does better than exact 9 / residual 1 (8 fail to compile, 2 are early states).
|
||||
- The park criterion in `config/parked.json` was re-read.
|
||||
|
||||
## Census, recorded before any shape
|
||||
|
||||
**Relocations: 47 == 47, identical multiset.**
|
||||
- Every call count is equal: `_datum_get`, `_tag_get`, `_light_volume_interpolate_frames`, `_object_get_marker_by_name`, `_object_get_function_value`, the four `_rasterizer_widget_*`, `__CIpow` x4, `_rgb_colors_interpolate` and `_real_argb_color_to_pixel32`.
|
||||
- Every global count is equal: `_render+16..36`, `__real@00000000` x11, `__real@3f800000` x11 and `_light_volume_globals+176`.
|
||||
- The gate tag is `[size, sha]`. No statement is missing.
|
||||
|
||||
**Frame: January `sub esp,0xa4` (164) vs ours `0xa8` (168). Ours has one extra dword.**
|
||||
|
||||
| cell | January | ours (real file) |
|
||||
| --- | --- | --- |
|
||||
| marker / color | -0xa4 / -0x38 | -0xa8 / -0x3c |
|
||||
| -0x28, -0x24 | radius; color_fraction (x87 phi, stored at the join) | loop `position` y, z |
|
||||
| -0x20 | `divisor` (fild, fstp, fdiv) | radius |
|
||||
| -0x1c | pow1#1 exponent (integer copy) | pow1#1 exponent (integer copy) |
|
||||
| -0x18..-0x10 | `delta`, **sharing the loop `position` cells** | pow1#2 exponent; pow1#4 memory phi; sprite_index |
|
||||
| -0xc | sprite_index (32-bit shadow) | pow1#3/#4 exponent (fst) |
|
||||
| -0x8 | distance_fade (`mov 1.0f`), then intensity | intensity |
|
||||
| -0x4 | pow1#2/#3/#4 exponent (fst x3) + brightness_fraction | distance_fade + color_fraction memory phi |
|
||||
| [ebp+8] | function_value (`mov 1.0f` at +0xd3), count-1, offset_fraction | parallel_factor, function_value, count-1, offset_fraction |
|
||||
|
||||
`frameslot.py` at HEAD returns MIXED-EXTRA / DECLARATION, identical to the research row.
|
||||
|
||||
## Re-verification of the two lenses
|
||||
|
||||
1. **The frame byte fact holds**, with one correction. The research row reads "frame 164 vs January 168", but January is the **smaller** frame.
|
||||
2. **The F3 DECLARATION slot class holds.**
|
||||
3. **The implied change "one more x87-homed real local in January" is already measured.**
|
||||
- The only real value January homes that ours lacks is `divisor` (w3d defect (a)).
|
||||
- w3d measured it with v7 at 944/47/0xac, and `lvJ` carries the equivalent loop header.
|
||||
- Because January's frame is smaller, no added local can explain the gap.
|
||||
4. **"`lvJ` lost a statement" is refuted.**
|
||||
- `lvJ`'s 48th relocation is one extra `__real@3f800000`.
|
||||
- That is `fld 1.0f`, which keeps distance_fade on the x87 stack instead of January's immediate `mov [ebp-8],0x3f800000`.
|
||||
- All call and global counts are equal.
|
||||
|
||||
## New evidence and corrections
|
||||
|
||||
**(1) `lvJ` already reproduces January's `delta` topology.**
|
||||
- `delta` is homed in memory (`fstp [ebp-0x1c/-0x18/-0x14]`) and shares the loop `position` cells (`lea edx,[ebp-0x1c]` at +0x382).
|
||||
- `lvJ` uses `vector_from_points3d`, `parallel_factor = ABS(dot_product3d(...))` as one statement, and `dot_product3d(&render.camera.forward, &delta)`.
|
||||
- This **corrects w3d finding (f)**, which says `vector_from_points3d` never homes `delta`.
|
||||
- Re-reading `w3d_glow_light_volumes/v3.obj` shows `delta` stays on the x87 stack only when the ABS is written as two statements and distance_fade is homed.
|
||||
- `lvJ`'s loop header (+0x235..+0x25c) is instruction-identical to January's.
|
||||
|
||||
**(2) Every remaining `lvJ` hunk (66 in total) comes from three x87 residency outcomes and their consequences.** The consequences are slot colouring, operand load order, deferred pops and the loop-head alignment nop.
|
||||
|
||||
1. **Pre-loop contest** among the three `delta` webs, `parallel_factor` and `distance_fade`:
|
||||
- January: `delta` and `distance_fade` in memory, `parallel_factor` on x87.
|
||||
- `lvJ`: `delta` and `parallel_factor` in memory, `distance_fade` on x87.
|
||||
- Retained body and w3d v3: `delta` on x87, the other two in memory.
|
||||
2. **Inlined pow1 #1, #3 and #4:**
|
||||
- January uses an x87 phi: an eager `fld value` before the `jnp`, then a store at the join.
|
||||
- Ours uses a memory phi.
|
||||
3. **pow1 #2 exponent:**
|
||||
- January uses `fld; fst [ebp-4]` into a shared home.
|
||||
- Ours uses an integer copy into its own home.
|
||||
|
||||
The two extra `lvJ` frame cells come from outcomes 2 and 3. By F3 law 0, frame layout runs after register allocation. By LAW D, no declared local is missing or extra.
|
||||
|
||||
**(3) `mod8.py` detector run on `lvJ_re.c` (an instrument, never used as source).**
|
||||
- D=0..8 all give 944 B and 142-143 differing instructions; the verdict is INSTRUMENT-PERTURBS.
|
||||
- No IL-local count moves the residency pattern or the size.
|
||||
- So the contest is not M8- or count-keyed, and no genuine local-inventory change can close it.
|
||||
|
||||
**(4) pow1 spelling cannot be the lever (LAW I).**
|
||||
- Re-reading w2 `lvK` (ternary), `lvQ1` (`result = value`) and `lvQ2` (if/else result) shows the same two effects in each:
|
||||
- the exact out-of-line `_pow1` changes (26/25/26 instructions vs January's 28);
|
||||
- render calls `_pow1` out of line (4 `_pow1` relocations, 44 in total).
|
||||
- Either effect would trade an exact row, which is prohibited. So A10 cannot be applied to pow1.
|
||||
|
||||
## Levers checked (no shape spent)
|
||||
|
||||
- **A10 conditional initializer.** January's memory-homed distance_fade already matches ours' default-then-if form. A10 was measured on an integer boolean, not on x87 residency.
|
||||
- **Initializer position and intensity accumulator.**
|
||||
- w2's `lvG` 12-cell grid placed distance_fade and function_value at T/D/P/C; every cell was 944/48.
|
||||
- The `lvB`/`lvC` intensity accumulator hashes the same as `lvA` (web renaming).
|
||||
- **Other research laws.**
|
||||
- H3's only levers are filler declarations.
|
||||
- LAW C, LAW E and CJ4 have no matching construct in this function.
|
||||
- M8 is refuted for residency (3).
|
||||
|
||||
## Reopen criterion
|
||||
|
||||
Reopen only on a measured VC7 law, proven in a micro-TU, that does one of these:
|
||||
- moves x87 residency between overlapping real webs (which of `parallel_factor`, `distance_fade` and `delta` stays on the x87 stack);
|
||||
- turns an inlined `if (c) v = f(v); return v;` helper's memory phi into an x87 phi, **without** changing the helper's out-of-line bytes or its inline decision.
|
||||
|
||||
Then start from `lvJ`, whose `delta` topology and loop header are already January's.
|
||||
|
||||
**Do not repeat:**
|
||||
- pow1 respellings;
|
||||
- the init-position grid;
|
||||
- the intensity accumulator;
|
||||
- dot-product argument order;
|
||||
- declaration or scope permutations;
|
||||
- local-count instruments;
|
||||
- any probe on the w2 or w3d do-not-repeat lists.
|
||||
@@ -0,0 +1,106 @@
|
||||
# `particle_systems.obj` — next-150K lane, final implementation wave, Tier B row B7 (2026-09-16)
|
||||
|
||||
## 1. Scope and provenance
|
||||
|
||||
- Unit `source/effects/particle_systems.c`; target `build/split/source/effects/particle_systems.obj`.
|
||||
- Lane worktree `C:\halo-worktrees\opus5-150k-house-clean-20260914`, HEAD `6d6529d98`. Worker `tB:particle_systems`.
|
||||
- Scope: exactly one function, `_particle_system_new_particle_jet` (research campaign Tier B row **B7**, 365 meaningful).
|
||||
- Nothing under `source/`, `config/`, `tools/` or `build/` was written. No ninja, configure, pytest or git write
|
||||
command was run. `git diff --stat -- source/effects/particle_systems.c` is empty.
|
||||
- Worker log with the full report block: `scratch/workers/tB_particle_systems.md`; evidence in
|
||||
`scratch/workers/tB_particle_systems/`.
|
||||
- Read first: both worker briefs, `opus5_next150_research_campaign_20260916.md`, `scratch/w2/laws_w2.md`,
|
||||
`scratch/w3/laws_w3.md`, and every particle_systems ledger that mentions the function (house_clean 0913, 100K,
|
||||
150K w1, 250K w3c, next150 n4) plus the three worker logs.
|
||||
|
||||
## 2. Baseline and final
|
||||
|
||||
Real-file gate `gate.py source/effects/particle_systems --all --forbid-emitted-symbol _point_from_line3d`:
|
||||
`== exact 21 residual 4 unwritten 0` at start and at finish (identical listing). Guard passed. No parks.
|
||||
|
||||
| row | target padded/meaningful/relocs/sha16 | baseline | final |
|
||||
|---|---|---|---|
|
||||
| `_particle_system_new_particle_jet` | 368/365/11/`322ad2bf7cdffa79` | 368/11 `[sha]` | unchanged (NOT-LANDED) |
|
||||
|
||||
The other three residual rows (`_particle_system_render`, `_particle_system_update`,
|
||||
`_particle_system_update_particle_default`) were out of scope and not touched.
|
||||
|
||||
## 3. Census (written before any shape)
|
||||
|
||||
- **Size / instructions:** 368 = 368; 136 = 136 instructions.
|
||||
- **Frame:** January `sub esp,0x10` = ours. Every slot is identical: `[ebp-0x10..-8]` random direction aggregate
|
||||
(HCEX SHIP name `spread`), `[ebp-4]` `rotates_up`, `[ebp+8]` velocity then spread_scale, `[ebp+0xc]` spread_fraction
|
||||
then directed_scale, `[ebp+0x10]`/`[ebp+0x14]` read-only particle/marker. `frameslot.py`: FRAME-CLEAN.
|
||||
- **Relocations by target:** 11/11, `0 differing row(s)`, every address equal.
|
||||
- **Other detectors:** `inlinerule.py` CONSISTENT (identical call multiset), `f5detect.py` NOT-FAMILY5,
|
||||
`f4law.py` X87-ORDER.
|
||||
- **Difference:** only the fld/fmul operand-load order inside the two inlined `real_math.h` `cross_product3d`
|
||||
copies (17 alndiff lines at +0x11b and +0x136..+0x15b).
|
||||
|
||||
## 4. Lens re-verification
|
||||
|
||||
**Lens 1 — F2 MOD8-REDUCES D=6 (17 → 8): holds.** The research detector re-run at HEAD gives
|
||||
D0 17, D1 17, D2 10, D3 12, D4 12, D5 12, D6 8, D7 10, D8 = D0.
|
||||
|
||||
**Lens 2 — "ours has two surplus IL locals; removing them re-keys cross_product3d": does not hold as a closure.**
|
||||
Per-product orientation (a = the first helper argument's leaf is loaded first; products
|
||||
`a.i*b.j, a.j*b.i, a.k*b.i, a.i*b.k, a.j*b.k, a.k*b.j`):
|
||||
|
||||
| body | copy 1 (velocity × global_up3d) | copy 2 (forward × velocity) |
|
||||
|---|---|---|
|
||||
| January | `aaabba` | `bbabba` |
|
||||
| D0 / D1 | `aaabaa` | `babaab` |
|
||||
| D2 | `aaabaa` | `bbbaab` |
|
||||
| D3 | `aaaaaa` | `bbbaab` |
|
||||
| D4 | `baabaa` | `bbbaab` |
|
||||
| D5 | `aaabaa` | `abbaab` |
|
||||
| D6 | `aaabaa` | `bbbbab` |
|
||||
| D7 | `aaabaa` | `baaaab` |
|
||||
|
||||
January's copy-1 fifth product (`b`) and copy-2 sixth product (`a`) occur at **no** residue. Every genuine change to
|
||||
the local inventory is a uniform ordinal shift (research S2.11), so no local-count change can make this function
|
||||
exact. Independent per-copy shifts cannot either. A brute-force search found no per-leaf additive mod-8 key model
|
||||
(multipliers 1/3/5/7, either direction, either tie default) that fits even our own eight observations. So the
|
||||
cross-product order is not a pure ordinal key, which is consistent with research notes S2.12.
|
||||
|
||||
**A15 "argument roles": refuted by bytes.** Every `fsubp` minuend/subtrahend already matches January, which
|
||||
proves `cross_product3d(&particle->velocity, global_up3d, &particle->axis)` and
|
||||
`cross_product3d(&marker->matrix.forward, &particle->velocity, &particle->axis)`. January's fall-through after
|
||||
`fcomp 0.0; test ah,0x44; jnp` is the velocity × up arm, which proves the `if (rotates_up)` arm order.
|
||||
|
||||
**Surplus-local candidates.** Only `definition` (single use of the `tag_get` macro) is removable (−1 ≡ D7, which
|
||||
measured non-closing). `velocity`, `spread_fraction`, `rotates_up`, `spread_scale`, `directed_scale` and the direction
|
||||
aggregate are byte-proven homed values stored before later calls. HCEA's single `axis_reference` cross product is
|
||||
refuted by January's two distinct inlined copies.
|
||||
|
||||
## 5. Shapes
|
||||
|
||||
None spent. Requirement 3 applies at baseline, because frame, relocations, call multiset and instruction count are
|
||||
already identical and only x87 operand ordering remains. The one count lever the Tier B row named is measured
|
||||
non-closing for all eight residues. The remaining routes are all prohibited:
|
||||
- operand spellings: R3 and the 100K do-not-repeat list;
|
||||
- a hand-expanded cross product: R15;
|
||||
- a TU-local helper copy: R14;
|
||||
- a `real_math.h` body respelling: header scope, and retired as a lottery in campaign §4.4;
|
||||
- pointer aliases: R16.
|
||||
|
||||
## 6. Classification, proposals, reopen criterion
|
||||
|
||||
- **Classification:** x87 commutative operand-load order inside two inlined `cross_product3d` copies. It is NOT an
|
||||
IL-count defect. Recommend moving B7 out of Tier B (to Tier C / retire-pending).
|
||||
- **Proposals:** none.
|
||||
- **Scan fact:** January contains only 12 contiguous inlined cross products. The only one in an exact function
|
||||
(`_object_set_position`) takes a frame-local argument, which is M8-insensitive, so it gives no exemplar.
|
||||
- **Reopen criterion:** a measured VC7 rule for inlined-`cross_product3d` load order that reproduces January's
|
||||
regular pattern here from genuine source. In January, every product loads its k-field leaf first when it has one,
|
||||
and otherwise loads the `particle->velocity` leaf first. A January-side fact changing the leaf provenance of
|
||||
`particle->velocity`, `marker->matrix.forward` or `global_up3d` would also reopen it.
|
||||
|
||||
## 7. Checks
|
||||
|
||||
1. Real-file gate unchanged: 21/4/0, row-identical.
|
||||
2. `_point_from_line3d` guard: passed.
|
||||
3. `scratch/parkcheck.py`: no parks for the unit.
|
||||
4. Owner census: not applicable (nothing landed).
|
||||
5. `tools/fake_match_scan.py`: 0 leads.
|
||||
6. `git diff --stat -- source/effects/particle_systems.c`: empty.
|
||||
@@ -0,0 +1,95 @@
|
||||
# `path.obj` next-150K lane, final implementation wave tierB (B1 `_path_state_traverse`, 2026-09-16)
|
||||
|
||||
Worker `tB_path`. Unit `source/ai/path.c`; target `build/split/source/ai/path.obj` (January 2002 Xbox debug,
|
||||
VC7 13.00.9254). Scope: exactly one function, the research campaign's Tier B row B1 `_path_state_traverse`
|
||||
(2,093 meaningful bytes, PARKED, class unclassified). Notes: `scratch/workers/tB_path.md`; candidates, generators
|
||||
and tools: `scratch/workers/tB_path/`.
|
||||
|
||||
## 1. Outcome
|
||||
|
||||
**Nothing landed. `git diff --stat -- source/ai/path.c` is empty.** The parked body stays locked; no row became
|
||||
strict EXACT, so there is no park-reopen proposal and no header/config proposal.
|
||||
|
||||
Final real-file gate (`gate.py source/ai/path --all --forbid-emitted-symbol _point_from_line3d`):
|
||||
`== exact 28 residual 4 unwritten 0`, guard passed, all 32 rows identical to the baseline listing;
|
||||
`scratch/parkcheck.py`: parks 4 drift 0; `tools/fake_match_scan.py source/ai/path.c`: 0 leads; owner census
|
||||
unchanged (file not edited).
|
||||
|
||||
Best scratch body: `scratch/workers/tB_path/s3.c` (function fragment `frag_s3.c`). It removes every
|
||||
structural difference: frame, byte cells, local inventory, control flow, block layout and register assignment all
|
||||
equal January. What is left is an x87 term-order tie in three blocks plus the strength-reduced edge-cursor bias.
|
||||
Per owner requirement 3 the wave stopped there.
|
||||
|
||||
## 2. Census (owner requirement 1, measured at HEAD 6d6529d98 on the w3c `t1.c` start point)
|
||||
|
||||
- tinfo: January 2096 padded / 65 relocs / sha 3e33ddd8b81a7b51, 652 instructions; t1 663 instructions, 131 alndiff hunks.
|
||||
- Frame: January `sub esp,0x85c` vs ours `0x864`. The full slot table is in the notes. The decisive cells:
|
||||
- January has one address-taken float at `[ebp-0x30]`. It receives the `path_attractor_weight` out-parameter, the MIN result and 0.0f. Ours has two objects, `distance_to_attractor` and `closest_approach_to_attractor`.
|
||||
- January has three byte booleans: `result` at `[ebp-1]`, `passable` at `[ebp-2]` and `reported_cost_overflow` at `[ebp-3]`.
|
||||
- January keeps `new_node_index` in memory `[ebp-0x10]`, a cell it shares with `adjacent_surface_index`, and keeps `heap_location` in BX.
|
||||
- January has no initializer stores for `distance_to_destination` or `new_node_index`.
|
||||
- Relocations by target: 65 = 65. Every call, string and global is equal. The only difference is the literal label class (`symbol:` vs `defined-noncode:`), the csplit artifact present on every exact row.
|
||||
- Both quoted lenses re-verified and HOLD:
|
||||
- **F3 DECLARATION.** 0x85c vs 0x864, byte cell -1, and the address-taken object at -0x30.
|
||||
- **F6 SOURCE-DEFECT-OPEN.** Entry stores `[ebp-1]=1` and `[ebp-3]=0`, and `[ebp-2]=0` behind `jne`. The two dword stores in ours are initializers January lacks.
|
||||
- HCEX.pdb SHIP (`DIA2Dump -sym path_state_traverse`) independently lists `closest_approach_to_attractor` as a stack float and has no `distance_to_attractor`.
|
||||
- Prior art: waveD `b0` (100K lane worktree, read-only) already carried the booleans, the single attractor object, the cost join and the `<=` result tail. Re-gated here it measures 2080/65, 658 instructions, 95 hunks, frame equal. So the implied change alone does not close.
|
||||
|
||||
## 3. Shapes (4 of 5 spent)
|
||||
|
||||
| shape | change (evidence) | result |
|
||||
| --- | --- | --- |
|
||||
| S1 | b0 + exhausted-search test moved to the loop top (January places the exhausted block at the loop exit ahead of the break blocks, with no re-test; HCEA has the same loop-top NONE test) + diameter squared inside the `&&` right operand (January `fadd st0,st0` after the 16.0f compare) + `edge_length` used by both PIN bounds (January stores the fsqrt before the dot; a single-use named sqrt is forwarded) + `new_node_index = node_index` before the heap asserts (January store @0x5c1 between `cmp bx,1` and `jl`) | 2096/65 [sha], 660 insns, 57 hunks; tail and projection block byte-identical, new_node_index in `[ebp-0x10]` |
|
||||
| S2 | S1 + `boolean passable` declared before `adjacent_surface_index` (store order `[ebp-2]` then `[ebp-0x10]`) + post-loop `if (node_index != NONE) {found} else if ... alloc ... overflow` | 2128 [size], 665, 62; store order and block order now January's, but VC7 does not thread the found (break) edge past the post-loop NONE test (+2 insns) |
|
||||
| **S3** | S2 with the probe loop handling both exits in place, found first: `while (TRUE) { node_index = hash[slot]; if (node_index != NONE) { ...found...; break; ... } else { alloc / overflow; break; } }` | **2112 [size], 657, 61; structure = January** (alloc falls into the join, found and overflow deferred after `path_heap_insert`, no re-test); every frame cell equal in width and refs; frameslot `PERMUTATION / NOT-A-DECLARATION`; siblings unchanged; fakescan 0 |
|
||||
| S4 | S3 with the `edge` alias replaced by `edges[edge_index].` (laws_w3 A33) | 2112, frame 0x860 (+4), 661, 106 hunks, bias unchanged: rejected, the alias is genuine |
|
||||
|
||||
Operand-normalized diff of S3 vs January leaves only three items:
|
||||
1. **Edge-cursor bias.** The strength-reduced base is `[ebp-0x840]` (+0x1c) where January has `[ebp-0x844]` (+0x18). It changes displacements only.
|
||||
2. **x87 term order in three blocks.**
|
||||
|
||||
| block | January | ours |
|
||||
| --- | --- | --- |
|
||||
| `magnitude_squared3d` squares | i,k,j | i,j,k |
|
||||
| t numerator dot | k,i,j | k,j,i, plus one extra `fxch` |
|
||||
| `distance3d(&cheapest_node->entry_point, &entry_point)` squares | k,j,i | i,k,j |
|
||||
|
||||
The destination `distance3d` block already matches.
|
||||
3. **Size.** The +2 bytes of the extra `fxch` make one `jne` near and push the probe-loop head into the 1..8 alignment window (`lea esp,[esp]`). That is the entire 2112 vs 2096 padded gap.
|
||||
|
||||
**mod8.py, run last on S3.** Verdict INSTRUMENT-PERTURBS. The per-block census (`x87runs.py` over `mod8_work` d0..d8) shows:
|
||||
- The magnitude block is D-insensitive.
|
||||
- The dot never reaches January's k,i,j.
|
||||
- The two `distance3d` sites move with the same period, so no uniform count fixes both (D=2/4/6 fix the linear site and break the destination site).
|
||||
- The bias is D-insensitive.
|
||||
|
||||
The x87 residual is therefore not a single IL-local count defect. The remaining spellings are helper or argument permutations with no January role evidence (R3/R15, research section 4.4 retired). The wave stopped (owner requirement 3).
|
||||
|
||||
## 4. New measured facts (for laws ledgers)
|
||||
|
||||
- **Loop-top break block ordering.** `while (TRUE) { x = call(); if (x == NONE) { ...; break; } ... }` makes VC7 duplicate the call and test at the bottom (rotation). It places the NONE handler first among the loop's exit blocks, ahead of later `break` blocks, and those blocks skip it. The `while (x != NONE) {...} if (x == NONE && ...)` spelling instead re-tests `cmp bx,-1` on every break path.
|
||||
- **Break edges are not jump-threaded.** VC7 threads a loop exit only on the edge whose last compare decided the value. A `break` from later in the body still passes a post-loop `if (node_index != NONE)` test (S2).
|
||||
- **Block layout follows fall-through.** A block reached only by a forward jcc is deferred to the next hole after an unconditional jmp, in IL order. An if/else arm falls into the statement after the if. An arm that ends in `break` inside a `while (TRUE)` whose body continues in IL order does not fall through (S1 vs S2/S3).
|
||||
- **A named single-use real is forwarded.** VC7 forwards a single-use `real edge_length = square_root(x)` into its use (b0). January's early `fsqrt; fstp [mem]` therefore implies two uses.
|
||||
- **A33 does not generalize.** Indexed access instead of a 20-use struct pointer alias costs a frame cell here (S4).
|
||||
|
||||
## 5. Reopen criterion
|
||||
|
||||
Reopen only with a January-evidenced mechanism for:
|
||||
- the three x87 square/dot term orders (the two `distance3d` expansions must fall into different key classes);
|
||||
- the strength-reduced edge-cursor bias (+0x18, `edge_vector.j`).
|
||||
|
||||
Start from `scratch/workers/tB_path/s3.c`. Its bytes equal January outside these blocks and the alignment pad they cause.
|
||||
|
||||
Do not repeat:
|
||||
- A33 indexed access (S4);
|
||||
- uniform dead-local counts (mod8 D=1..8);
|
||||
- the post-loop `if (node_index != NONE)` dispatch (S2);
|
||||
- b0's NONE-first probe body (S1 layout);
|
||||
- `real diameter` declared before the if;
|
||||
- a single-use `edge_length` plus a `margin` local;
|
||||
- the `distance_to_destination = 0.0f` initializer of the t1 park base (January has no store). S3 keeps `short new_node_index = NONE;`, which emits no store because VC7 threads every NONE path, as January does.
|
||||
|
||||
Review note for any future landing:
|
||||
- **`distance_to_destination` has no initializer.** This is byte-proven. Both reads sit under `state->destination_valid`, which the loop never writes. It is not a runtime uninitialized read, but the reviewer should confirm.
|
||||
- **Repeated expressions are deliberate.** S3 repeats `(pathfinding_radius * 2.0f)` and `pathfinding_radius / edge_length` instead of naming them. That is what the bytes require.
|
||||
+140
@@ -0,0 +1,140 @@
|
||||
# `rasterizer_transparent_geometry.obj`: next-150K lane, Tier B wave (B9)
|
||||
|
||||
Lane `C:\halo-worktrees\opus5-150k-house-clean-20260914`, HEAD `6d6529d98`. Scope: `source/rasterizer/rasterizer_transparent_geometry.c`.
|
||||
The only target was `_rasterizer_transparent_geometry_initialize` (149 meaningful bytes, parked).
|
||||
Worker notes: `scratch/workers/tB_rasterizer_transparent_geometry.md`. Scratch: `scratch/workers/tB_rasterizer_transparent_geometry/`.
|
||||
|
||||
## Result
|
||||
|
||||
**Park reopen proposed. The real file is unchanged.** The parked body stays locked, so `git diff --stat` on the file is empty.
|
||||
|
||||
The scratch candidate `scratch/workers/tB_rasterizer_transparent_geometry/v1.c` is the current real file with only this body replaced.
|
||||
|
||||
| gate (`--all --forbid-emitted-symbol _point_from_line3d`) | exact | residual | unwritten |
|
||||
| --- | ---: | ---: | ---: |
|
||||
| real file (baseline and final) | 17 | 2 | 0 |
|
||||
| scratch candidate v1.c | **18** | 1 | 0 |
|
||||
|
||||
- **Target row:** strict EXACT, 160 bytes, 16 relocations, sha `63251d0d8cc730b0`, identical to January.
|
||||
- **Other rows:** none changed; all 17 exact rows stay exact.
|
||||
- **Guard:** passes.
|
||||
- **Parkcheck:** drift on this park only, to the target hash, as a reopen expects. `_rasterizer_sort_external` is unchanged.
|
||||
- **Owner census (v1.obj against build/base):** identical owner sets.
|
||||
- **fake_match_scan:** 0 leads.
|
||||
- **`CL /Zs /W3`:** the same 12 header-only warnings as HEAD.
|
||||
|
||||
## Census (written before any shape)
|
||||
|
||||
- **tinfo:** 160 bytes, 16 relocations. There are 51 instructions on both sides.
|
||||
- **Frame:** neither side has a frame or any `[ebp±N]` slots. `frameslot.py` reports NO-FRAME / CLEAN.
|
||||
- **Relocations by target:** the multisets are identical: `_debug_malloc` ×3, file literal ×3, error literal, `_error`, `_rasterizer_transparent_geometry_initialize_aux_buffer`, and five `.bss` globals. The only difference is the `.bss` defined-vs-COMMON spelling, which every exact sibling shares.
|
||||
- **Lens 1 (F4 STRUCT-COUNT):** still holds (40 vs 39 instructions).
|
||||
- **Lens 2 (F5 SETCC-DEFECT):** still holds.
|
||||
|
||||
## Why the implied change does not close it
|
||||
|
||||
The implied change was to return TRUE from the success arm. Wave w3c had already measured exactly that as shapes t5 and t6. Those bodies are instruction-identical to January but lay the blocks out as `[aux][error]`, where January has `[error][aux]`. Running F5 on t5 gives DOWNSTREAM.
|
||||
|
||||
So the setcc lens is satisfied. What remains is where the blocks go:
|
||||
- January keeps the error arm as the fall-through of the last null test (`jne 0x89`).
|
||||
- The shared `xor al,al; ret` sits directly after the error call.
|
||||
- The aux block comes after it and branches **backward** into that FALSE exit (`je 0x86`).
|
||||
|
||||
## New evidence
|
||||
|
||||
### Law L-SINGLE-TEST (micro-TU lab, this unit's exact cflags)
|
||||
|
||||
The lab is `scratch/workers/tB_rasterizer_transparent_geometry/lab/lab.py`. It is an instrument only, never source.
|
||||
|
||||
**VC7 keeps an if-arm in place only when a single test selects it.** Here "in place" means the arm is the fall-through, its FALSE exit comes next, and the other path follows after that. When the if-condition is a chain of two or more terms joined by `||` or `&&`, VC7 moves the arm to the function tail.
|
||||
|
||||
The model reproduces our current output exactly. In this table, `A`, `B` and `C` stand for the three allocation pointers, and `err` for the error call.
|
||||
|
||||
| probe | spelling | layout |
|
||||
| --- | --- | --- |
|
||||
| a0 | w3c t5 | ours `[aux][error]` |
|
||||
| a1 | park base | ours: setne, error at the tail |
|
||||
| a2 | a0 with `long` globals | same as a0, so pointer typing is not the cause |
|
||||
| **a3** | **single test `if (!groups2) {err} else if (aux()) return TRUE; return FALSE;`** | **January** |
|
||||
| b3 | two-term chain | error at the tail |
|
||||
| b1 / b2 | `!(A&&B&&C)` / `== NULL` | same as a0 |
|
||||
| v4 / v10 | else-block / result flag with the chain as the condition | error at the tail |
|
||||
| **v1** | **`success = A&&B&&C; if (!success) {err} else if (aux()) return TRUE; return FALSE;`** | **January; every offset identical** |
|
||||
| **w5** | **`success = A&&B&&C; if (!success) err; success = success && aux(); return success;`** | **same as v1** |
|
||||
| **y1** | **`boolean success = TRUE; if (!A\|\|!B\|\|!C) success = FALSE; if (!success) {err} success = success && aux(); return success;`** | **same as v1** |
|
||||
| **y2** | **`boolean success = TRUE; if (!A\|\|!B\|\|!C) { err; success = FALSE; } success = success && aux(); return success;`** | **same as v1** |
|
||||
| w2 / w3 / w4 | returned flag with a FALSE store path | 0 pinned in EBX (w3c fact 1) |
|
||||
| w6 | early returns | setne |
|
||||
| x1 | `return success && aux();` | 32-bit `xor eax,eax` / `mov eax,1` |
|
||||
|
||||
### Same-author donor (strict EXACT)
|
||||
|
||||
`rasterizer_xbox.c` `__rasterizer_initialize` (2352 B) is the January caller of this function and is strict EXACT. It uses the same idiom and the same message family:
|
||||
- `if (!global_d3d_texture_sun_glow_secondary || !global_d3d_surface_sun_glow_secondary) success = FALSE;`
|
||||
- `if (!success) { error(_error_silent, "### ERROR failed to create offscreen surface(s)"); }`
|
||||
- `success = success && rasterizer_memory_pool_initialize() && ... && rasterizer_transparent_geometry_initialize() && ...;`
|
||||
- `return success;`
|
||||
|
||||
Its January bytes at +0x712..+0x74b lay the `if (!success)` error arm in place under one test.
|
||||
|
||||
### Exact corpus instance of the January topology
|
||||
|
||||
ui_widget `_string_has_icons_to_draw` is strict EXACT and shows the same topology:
|
||||
- a single `if (!string)` assert test with `jne` over the in-place failure block;
|
||||
- `xor al,al; pop ebx; ret` directly after the failure block;
|
||||
- a loop `je 0x25` that branches backward into that exit.
|
||||
|
||||
Corpus scans (read-only evidence) are `errscan.py`, `backscan.py`, `orscan.py` and `donorscan.py`, with their `.txt` outputs.
|
||||
|
||||
## Shape (1 of 5 used)
|
||||
|
||||
S1 (`v1.c`) is the y2 spelling:
|
||||
|
||||
```c
|
||||
boolean rasterizer_transparent_geometry_initialize(
|
||||
void)
|
||||
{
|
||||
boolean success = TRUE;
|
||||
|
||||
/* the three debug_malloc allocations and the two count clears, unchanged */
|
||||
|
||||
if (!transparent_geometry_groups ||
|
||||
!transparent_geometry_group_sorted_indices ||
|
||||
!transparent_geometry_groups2)
|
||||
{
|
||||
error(_error_silent, "### ERROR failed to allocate transparent geometry buffer");
|
||||
success = FALSE;
|
||||
}
|
||||
|
||||
success = success && rasterizer_transparent_geometry_initialize_aux_buffer();
|
||||
|
||||
return success;
|
||||
}
|
||||
```
|
||||
|
||||
Result: strict EXACT in the whole-TU gate.
|
||||
|
||||
- **Meaning:** allocate the three group buffers. If any allocation fails, report the silent error and fail. Otherwise initialise the Xbox auxiliary buffer. Return the overall success.
|
||||
- **Idiom:** this is the caller's own success-accumulation idiom.
|
||||
- **Laws applied:** A3 single-exit, with one bottom return of a genuine result flag, and w3c fact 1: a TRUE initializer stays out of the EBX zero pin.
|
||||
- **House rules:**
|
||||
- no casts, filler, dead or redundant stores, carrier, or operand permutation;
|
||||
- `success = FALSE` is read by the `&&`;
|
||||
- declare+initialize together;
|
||||
- an explicit single return.
|
||||
- **Alternative:** y1 is the donor's verbatim split form and is byte-identical in the lab. It was not gated on the whole TU. y2 was preferred because this function has only one failure source before the report.
|
||||
|
||||
## Park-reopen proposal
|
||||
|
||||
- **Unit / function:** `source/rasterizer/rasterizer_transparent_geometry` :: `_rasterizer_transparent_geometry_initialize`, 160 padded / 149 meaningful.
|
||||
- **Candidate:** `scratch/workers/tB_rasterizer_transparent_geometry/v1.c`, which is the real file plus this body only.
|
||||
- **Park criterion:** "Reopen only for authoritative January source/local records or a natural same-compiler donor that explains this block order."
|
||||
- **Why the criterion is met:**
|
||||
- The block order is now explained by a measured law (L-SINGLE-TEST).
|
||||
- A natural, strict-EXACT, same-author, same-subsystem donor uses the spelling that produces it: the function's own January caller, `__rasterizer_initialize`.
|
||||
- The park's premise, that no natural result-lifetime or error-path family reaches it, is refuted: none of the recorded families tested the allocation result through one flag.
|
||||
- **Orchestrator action:** remove the park entry and land the v1.c body in the same commit, then run the full ninja build and the stable-verdict diff.
|
||||
|
||||
## Not in scope
|
||||
|
||||
`_rasterizer_sort_external` (176, parked) was outside this wave's single-function scope. It was not touched, and its park is unchanged.
|
||||
@@ -0,0 +1,114 @@
|
||||
# `stack_memory_pool.obj`: opus5 next-150K lane, final wave tierB (2026-09-16)
|
||||
|
||||
Scope: one Tier B row from the research campaign, B6 `_stack_memory_pool_allocate` (637 meaningful bytes). The
|
||||
"do-not-repeat" tag from laws_w2 D was lifted by the F5 RESULTVAR-DEFECT lens.
|
||||
|
||||
**Outcome: NOT LANDED. Zero strict bytes.** The production source is unchanged
|
||||
(`git diff --stat -- source/memory/stack_memory_pool.c` is empty). One evidence-backed shape (S1) fixed the
|
||||
structural defect that both lenses name. After S1, only register assignment differed, so work stopped under owner
|
||||
requirement 3.
|
||||
|
||||
## Baseline (HEAD 6d6529d98)
|
||||
|
||||
The whole-unit gate gives exact 31, residual 2, unwritten 0. The `_point_from_line3d` guard passes. The unit has no
|
||||
parks.
|
||||
|
||||
| row | January padded / meaningful / relocs / sha16 | real file |
|
||||
| --- | --- | --- |
|
||||
| `_stack_memory_pool_allocate` | 640 / 637 / 36 / `00ddbe408b35e153` | 640 / 36 / `c49ac9850cc6a1eb`, 231 vs 229 instructions |
|
||||
|
||||
## Census
|
||||
|
||||
- **Frame.** Both sides use `sub esp,8` and the same slots:
|
||||
- `[ebp-4]`: `free_space_in_pool_previous`, address-taken.
|
||||
- `[ebp-8]`: the NULL home of `free_space`.
|
||||
- `[ebp+8]`, `[ebp+0xc]`, `[ebp+0x10]`: `pool`, `file`, `line`.
|
||||
- `frameslot.py` reports FRAME-CLEAN.
|
||||
- **Relocations.** 36 vs 36, with the same targets, types, addends and order. There is no missing or extra call or
|
||||
global. Addresses 0x23–0xe8 sit 2–4 bytes early in our build.
|
||||
- **Instructions.** Every difference comes from one register fact:
|
||||
- **January:** EDI holds `pool` and EBX holds `size`. ESI holds X, a NULL value initialised at entry (`xor esi,esi`
|
||||
before `test edi,edi`). X is read exactly once, by `mov eax,esi` on the invalid-size exit, before `pop esi`. So
|
||||
MAXLIVE is 3 and, by LAW Z1, there is no whole-function zero pin. January instead uses `test edi,edi`,
|
||||
`mov eax,[edi+4]; test eax,eax`, a local `xor eax,eax; cmp ebx,eax`, and EAX for both NULL stores and for the
|
||||
FALSE push.
|
||||
- **Ours:** ESI is a whole-function zero pin (MAXLIVE 2) and every NULL return is a literal.
|
||||
- The NONE-failure `je` binds to January's first literal epilogue. That is a downstream effect of the same fact.
|
||||
- **Both lenses re-verified at HEAD.**
|
||||
- `f5detect.py` still reports RESULTVAR-DEFECT (January `pop edi; mov eax,esi; pop esi`, ours
|
||||
`pop edi; pop esi; xor eax,eax`).
|
||||
- The instruction count is still 231 vs 229.
|
||||
|
||||
## Evidence
|
||||
|
||||
- **A42.** An entry `xor` proves a declaration initializer.
|
||||
- **Exact January functions with the same fingerprint.** `scratch/workers/tB_stack_memory_pool/entryzero_scan.py`
|
||||
finds 29 strict-exact January functions with an entry zero that is returned on one exit, and no non-exact ones
|
||||
apart from this target. Examples:
|
||||
- `rasterizer_memory_pool::_rasterizer_memory_alloc`: `pointer = NULL`, whose final `else` arm falls into the
|
||||
shared `return pointer;`.
|
||||
- `stack_memory_pool::_pool_new_pointer`.
|
||||
- `ui_widget::_ui_widget_load_by_name_or_tag`: the NULL-init web (EDI) is returned by the last `else` arm while the
|
||||
success value sits in ESI. This is a split phi.
|
||||
- **Liveness.** January's X is dead once the three size checks pass. So no valid-size path reaches the X-reading
|
||||
return without first redefining the variable:
|
||||
- the find-space and NONE failures return literal NULL;
|
||||
- the X-reading return is reached only by the invalid-size `else` arm and by the success path.
|
||||
- **Why the w2 shape failed.** In w2 `smp_v2` (single bottom return reached by every failure path), the NULL def is
|
||||
live across the whole valid region. It is rematerialised and the zero pin comes back. This explains that shape's
|
||||
identical residual.
|
||||
|
||||
## Shapes
|
||||
|
||||
**S1.** Candidate `scratch/workers/tB_stack_memory_pool/v1.c`, body `s1_body.txt`.
|
||||
|
||||
- **Source changes:**
|
||||
- `struct stack_memory_pool_block *block = NULL;`
|
||||
- a positive size predicate owns the allocation body;
|
||||
- the invalid-size display moves to the final `else` arm, textually last, matching January line 0x3A4;
|
||||
- one bottom `return block;` serves both the success path and the invalid arm;
|
||||
- the find-space and NONE failures keep `return NULL;`.
|
||||
- **Measured:** 640 / 36 / sha `147b10dfc82d9604`, still `[sha]`. The whole-unit gate is 31/2/0 and every row
|
||||
matches the baseline.
|
||||
- **Fixed:**
|
||||
- the zero pin is gone;
|
||||
- the entry region emits January's exact forms;
|
||||
- relocations 0–20 land on January's exact addresses (0x23–0x15a).
|
||||
- **Remaining, all register assignment:**
|
||||
|
||||
| web | ours | January |
|
||||
| --- | --- | --- |
|
||||
| X | EBX | ESI |
|
||||
| `size` / aligned size | ESI, then `lea ebx,[esi+0x20]` | EBX, `add ebx,0x20` in place |
|
||||
| `block` | EBX | EDI |
|
||||
| extra `pool` reload | into ESI | none |
|
||||
| insertion zero | EDI | ESI |
|
||||
|
||||
Our X and `block` share EBX. That is consistent with VC7 merging the NULL def and the success def at the bottom
|
||||
phi, where January keeps them apart.
|
||||
- **Closeness:** aligned-equal instructions fall from 207 (v0) to 168 (v1). S1 is structurally right but further from
|
||||
January in bytes. It is not exact, and the current body is complete, so the fuzzy policy keeps it in scratch.
|
||||
|
||||
After S1 the values reaching the join already match January's: the NULL init arrives through the invalid arm, `block`
|
||||
through the success path, and the failures return literals. By Z4, re-spelling a copy or alias does nothing. No
|
||||
January-side evidence names a different join topology, so no further shape was spent.
|
||||
|
||||
## Verification
|
||||
|
||||
- The final real-file gate (with the guard) is 31/2/0, and its rows match the baseline exactly.
|
||||
- `parkcheck` reports no parks for this unit.
|
||||
- `fake_match_scan` finds 0 leads in both the real file and v1.c.
|
||||
- `branch_sweep` found 24 unique blobs; the best is the current 31/2/0.
|
||||
- The owner census is trivial because the real file is unchanged.
|
||||
|
||||
## Reopen criterion
|
||||
|
||||
Reopen when there is a measured VC7 law that decides whether a result variable's NULL declaration-initializer def
|
||||
keeps its own web or merges with the success def at a shared bottom return:
|
||||
- January keeps them apart: X in ESI, `block` in EDI. The exact donor `_ui_widget_load_by_name_or_tag` shows the
|
||||
split.
|
||||
- S1 merges them: both in EBX.
|
||||
|
||||
Under such a law, re-gate `scratch/workers/tB_stack_memory_pool/v1.c` (sha256 prefix `c9c67e4407a68d8e`). Do not
|
||||
reopen with early-return or literal spellings, or with any form that lets the NULL def reach a valid-size failure
|
||||
exit: w2 `smp_v2` and exp 076 already measure those as non-closing.
|
||||
@@ -0,0 +1,108 @@
|
||||
# weapons.obj — next-150K lane, final implementation wave, Tier B row B10 (2026-09-16)
|
||||
|
||||
Worker scope: `source/items/weapons.c`, TARGET `_weapon_can_be_fired` (Tier B10, PARKED). Nothing else in the unit
|
||||
was in scope. **Real file not modified** (`git diff --stat -- source/items/weapons.c` is empty). Result: a strict-EXACT
|
||||
**park-reopen proposal** built in scratch.
|
||||
|
||||
## Baseline and final real-file gate (HEAD 6d6529d98)
|
||||
|
||||
| gate | result |
|
||||
| --- | --- |
|
||||
| baseline (guard on) | `== exact 74 residual 5 unwritten 0 (of 79)`; guard passed; park drift 0 |
|
||||
| final real file (guard on) | identical rows; guard passed; park drift 0; fake scan 0 leads |
|
||||
| reopen candidate `scratch/workers/tB_weapons/reopen_candidate.c` | `== exact 75 residual 4 unwritten 0`; guard passed; only `_weapon_can_be_fired` changes (residual -> EXACT) |
|
||||
|
||||
## Census (written before any shape)
|
||||
|
||||
- tinfo: January 144 padded / 132 meaningful / 5 relocations / normalized sha16 `ba8b380662480849`
|
||||
(`_object_get_and_verify_type`, `_tag_get`, `__real@3f800000`, `_game_engine_running`, `_tag_block_get_element_with_size`).
|
||||
- alndiff at HEAD: 60 (January) vs 59 (ours). January: age test falls through into an inline FALSE epilogue at +0x37;
|
||||
running/count/max/loaded failures branch FORWARD to the tail TRUE at +0x7e; the rounds_total test `je 0x37` branches
|
||||
BACKWARD to the FALSE epilogue; `mov al,1` epilogue last. Ours: inline TRUE epilogue at +0x46 bound backward by
|
||||
count/max/loaded, `setne al` tail.
|
||||
- Frame: no `sub esp` and no `[ebp-N]` slot on either side (frameslot CLEAN); `[ebp+8]` only.
|
||||
- Relocations by target: identical multiset (the literal is the systemic select-any class, symbolic-equal); only the
|
||||
tag-block call address differs (0x5c vs 0x62) because of our extra inline epilogue.
|
||||
- Both research lenses hold at HEAD: instruction count 60/59, and F5 SETCC-DEFECT (January 0 / ours 1 setcc).
|
||||
|
||||
## Duplicate prevention finding
|
||||
|
||||
The research's implied change ("fold the final guard into the preceding five-term `&&` chain") had already been
|
||||
measured: w3 c1/c3/c5 and 100K wave C Pcbf2 (see weapons_obj_opus5_150k_w3_20260914.md and
|
||||
weapons_obj_opus5_100k_waveC_20260914.md). Re-measured here as v1: the setcc disappears (60/60 instructions), but the
|
||||
unified FALSE exit is hosted after the chain (+0x78, age test `je 0x78` forward) instead of inline after the age test.
|
||||
The F5 lens is therefore real but its named change is not sufficient; the rest of the residual is exit hosting.
|
||||
|
||||
## New evidence
|
||||
|
||||
Same-compiler strict-EXACT donors whose January bytes have this function's topology (a later chain's last test binding
|
||||
BACKWARD into an earlier arm's inline constant exit, falling through into the other constant):
|
||||
|
||||
- `actions::_actor_action_can_stop_conversing` (source/ai/actions.c:1757-1799, read only; Codex-reserved file): flat
|
||||
`if (A1 && B1) result = TRUE; else if (A2 && B2) result = TRUE; else if (A3 && B3) result = TRUE; else result = FALSE;`
|
||||
gives arm 1's `mov al,1` epilogue inline at +0x62 and `jge 0x62` from arms 2 and 3.
|
||||
- `actor_combat::_actor_combat_enable_special_fire_situation` (switch arms `result = A && B;`): case 3's last test
|
||||
`jge 0x40` binds backward into case 1's `mov al,1` epilogue.
|
||||
|
||||
(Located with the sibling B9 worker's read-only scan `scratch/workers/tB_rasterizer_transparent_geometry/backscan.txt`
|
||||
and re-read from the bytes and sources by this worker.)
|
||||
|
||||
## Shapes (5 spent, all scratch; `scratch/workers/tB_weapons/v1..v5.c`)
|
||||
|
||||
| shape | evidence | result |
|
||||
| --- | --- | --- |
|
||||
| v1 F5 implied change: `if (age>=1) return FALSE; if (running && count>0) { magazine; if (max>0 && !loaded && !total) return FALSE; } return TRUE;` | research B10 | 144/5 sha `8d10523e3c79ff0b`; 60/60 insns; FALSE hosted last (= w3 c1) |
|
||||
| v2 last term as a nested single-term guard | HEAD/e12 backward-guard bytes | sha == v1 (VC7 flattens it) |
|
||||
| **v3 flat `if (age>=1) { result = FALSE; } else if (running && count>0 && TAG_BLOCK_GET_ELEMENT(...)->rounds_loaded_maximum>0 && !loaded && !total) { result = FALSE; } else { result = TRUE; } return result;`** | donors above; laws_w2 A3 single exit; laws_w3 A26 | **STRICT EXACT 144/5 `ba8b380662480849`** |
|
||||
| v4 control: v3's flat chain with early returns | lab e13/c1 | sha == v1: the result-variable sibling arms are the lever, not the flat chain |
|
||||
| v5 control: `boolean result = TRUE;` without the final else (house rule 17) | laws_w2 A10 | EBX constant-1 pin, sha `8489bd603b75d8a3`; declare+init is not practical here |
|
||||
|
||||
## Admission checks on the reopen candidate
|
||||
|
||||
- Whole-TU gate: 75 exact / 4 residual; row diff against the HEAD gate changes only `_weapon_can_be_fired`.
|
||||
- Every other code section is byte-identical to the HEAD object (`section_infos_equal` over all 95 code owners).
|
||||
- `_point_from_line3d` guard passed.
|
||||
- `scratch/parkcheck.py`: the only drift is the target itself (144/5/`ba8b380662480849` = January), as a reopen expects;
|
||||
the unit has no other parks.
|
||||
- Owner census vs build/base and build/split: 130/130 owners, no January owner missing, no new code/data/BSS/COMMON
|
||||
owner; only compiler `$L` jump labels renumber. The select-any `__real@3f800000` literal (the 20260831 rejection
|
||||
reason) is already owned by the HEAD body and base; no change.
|
||||
- `tools/fake_match_scan.py`: 0 leads (HEAD 0).
|
||||
- Authenticity: the weapon cannot fire when fully aged, or in a running game engine when magazine 0 of a magazine-using
|
||||
weapon has neither loaded nor reserve rounds; otherwise it can. Two distinct rejection reasons each assign FALSE in
|
||||
sibling arms (the A26-admitted identical-assignment form with distinct conditions), and one result is returned once
|
||||
(A3; the donor's style). Behaviour equals the HEAD body, including short-circuit order (the tag block element is read
|
||||
only when `count > 0`). House rules: typed accessors and `TAG_BLOCK_GET_ELEMENT`, `boolean`, one parameter per line,
|
||||
explicit `return result;`, no casts, no dead locals (the unused `magazine_definition` local is gone).
|
||||
|
||||
## Park-reopen proposal
|
||||
|
||||
- Park: `config/parked.json` entry `source/items/weapons` / `_weapon_can_be_fired` (class unclassified). Its criterion
|
||||
forbids further branch-spelling search "without new original-source or same-compiler evidence"; the w3 reopen
|
||||
criterion asks for "a measured VC7 rule for which duplicate epilogue survives cross-jumping (e.g. proven on another
|
||||
object), or January-side source evidence of the statement structure".
|
||||
- Why it is met: the two exact same-compiler donors above prove, on other objects, which exit copy a chain's last test
|
||||
binds to when identical constant results are assigned in sibling else-if/switch arms. v1/v2/v4 (early-return
|
||||
spellings) and v5 (initializer) are measured controls showing the rule does not apply to them. The research's
|
||||
SETCC reading (F5 V14) independently refutes the park's "control-flow placement tie" premise.
|
||||
- Candidate: `scratch/workers/tB_weapons/reopen_candidate.c` (the current real file with only this body replaced).
|
||||
Apply the body and remove the park entry in one commit. No other park needs a re-measure.
|
||||
|
||||
## Law note for the orchestrator (CJ3 refinement, measured on this row only)
|
||||
|
||||
When the same constant is returned from an early guard and from a later `&&` chain, early-return spellings host the
|
||||
unified exit at the later chain (v1, v2, v4; lab e13/c1). If each arm assigns a result variable in a flat
|
||||
`if / else if / else` and the function returns the variable once, the exit is hosted at the FIRST arm, and the later
|
||||
chain's last test binds backward to it (v3; donors can_stop_conversing and enable_special_fire_situation).
|
||||
Declare-and-initialize (`result = TRUE;` with no else) pins the constant in a callee-saved register instead (v5).
|
||||
Possible consumers (unmeasured here): other F5 SETCC rows whose January bytes show a backward jcc into an earlier
|
||||
inline constant exit, e.g. `_rasterizer_transparent_geometry_initialize` (B9), where w3c t5/t6 used early returns.
|
||||
|
||||
## Do-not-repeat
|
||||
|
||||
- Early-return spellings of the final chain (v1 = w3 c1 = Pcbf2, v2 nested guard, v4 flat chain), and the
|
||||
initializer form v5.
|
||||
|
||||
## Reopen criterion if the proposal is declined
|
||||
|
||||
An owner ruling on the A26 identical-assignment else-if form for this row (the body is otherwise measured closed).
|
||||
+14
-7
@@ -110,6 +110,11 @@ symbols in this file:
|
||||
|
||||
/* ---------- constants */
|
||||
|
||||
enum
|
||||
{
|
||||
NUMBER_OF_TEMPORARY_HUD_RETICLE_POINTS = 16
|
||||
};
|
||||
|
||||
enum player_respawn_failure
|
||||
{
|
||||
_player_respawn_failure_none = 0,
|
||||
@@ -820,7 +825,7 @@ void temporary_hud_draw_reticle(
|
||||
real angle,
|
||||
real_argb_color const *color)
|
||||
{
|
||||
real_point3d points[16];
|
||||
real_point3d points[NUMBER_OF_TEMPORARY_HUD_RETICLE_POINTS];
|
||||
real radius = tangent(angle * 0.5f) * 0.0625f;
|
||||
long point_index;
|
||||
long next_point_index;
|
||||
@@ -828,11 +833,13 @@ void temporary_hud_draw_reticle(
|
||||
real_point3d *point;
|
||||
|
||||
angle = 0.0f;
|
||||
for (point_index = 0; point_index < NUMBEROF(points); point_index++)
|
||||
for (point_index = 0; point_index < NUMBER_OF_TEMPORARY_HUD_RETICLE_POINTS; point_index++)
|
||||
{
|
||||
points[point_index].x = cosine(angle) * radius;
|
||||
points[point_index].y = sine(angle) * radius;
|
||||
points[point_index].z = -0.0625f;
|
||||
set_real_point3d(
|
||||
&points[point_index],
|
||||
cosine(angle) * radius,
|
||||
sine(angle) * radius,
|
||||
-0.0625f);
|
||||
matrix4x3_transform_point(
|
||||
&render.frustum.view_to_world,
|
||||
&points[point_index],
|
||||
@@ -841,13 +848,13 @@ void temporary_hud_draw_reticle(
|
||||
}
|
||||
|
||||
next_point_index = 1;
|
||||
line_count = NUMBEROF(points);
|
||||
line_count = NUMBER_OF_TEMPORARY_HUD_RETICLE_POINTS;
|
||||
point = points;
|
||||
do
|
||||
{
|
||||
rasterizer_debug_line(
|
||||
point,
|
||||
&points[next_point_index % NUMBEROF(points)],
|
||||
&points[next_point_index % NUMBER_OF_TEMPORARY_HUD_RETICLE_POINTS],
|
||||
color);
|
||||
next_point_index++;
|
||||
point++;
|
||||
|
||||
+17
-18
@@ -1312,27 +1312,26 @@ boolean weapon_can_be_fired(
|
||||
{
|
||||
struct weapon_datum *weapon = weapon_get(weapon_index);
|
||||
struct weapon_definition *weapon_definition = weapon_definition_get(weapon->definition_index);
|
||||
struct weapon_magazine_definition *magazine_definition;
|
||||
boolean result;
|
||||
|
||||
if (weapon->weapon.age>=1.0f)
|
||||
return FALSE;
|
||||
if (!game_engine_running())
|
||||
return TRUE;
|
||||
if (weapon_definition->weapon.magazines.count<=0)
|
||||
return TRUE;
|
||||
{
|
||||
result = FALSE;
|
||||
}
|
||||
else if (game_engine_running() &&
|
||||
weapon_definition->weapon.magazines.count>0 &&
|
||||
TAG_BLOCK_GET_ELEMENT(&weapon_definition->weapon.magazines, 0, struct weapon_magazine_definition)->rounds_loaded_maximum>0 &&
|
||||
!weapon->weapon.magazines[0].rounds_loaded &&
|
||||
!weapon->weapon.magazines[0].rounds_total)
|
||||
{
|
||||
result = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = TRUE;
|
||||
}
|
||||
|
||||
magazine_definition = TAG_BLOCK_GET_ELEMENT(
|
||||
&weapon_definition->weapon.magazines,
|
||||
0,
|
||||
struct weapon_magazine_definition);
|
||||
if (magazine_definition->rounds_loaded_maximum<=0)
|
||||
return TRUE;
|
||||
if (weapon->weapon.magazines[0].rounds_loaded)
|
||||
return TRUE;
|
||||
if (weapon->weapon.magazines[0].rounds_total)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
return result;
|
||||
}
|
||||
|
||||
real weapon_compute_movement_penalty(
|
||||
|
||||
@@ -198,6 +198,8 @@ extern struct rasterizer_transparent_geometry_window_parameters global_window_pa
|
||||
boolean rasterizer_transparent_geometry_initialize(
|
||||
void)
|
||||
{
|
||||
boolean success = TRUE;
|
||||
|
||||
transparent_geometry_groups = debug_malloc(
|
||||
RASTERIZER_MAXIMUM_TRANSPARENT_GEOMETRY_GROUPS * sizeof(struct transparent_geometry_group),
|
||||
FALSE, "c:\\halo\\SOURCE\\rasterizer\\rasterizer_transparent_geometry.c", 0x29);
|
||||
@@ -216,13 +218,12 @@ boolean rasterizer_transparent_geometry_initialize(
|
||||
!transparent_geometry_groups2)
|
||||
{
|
||||
error(_error_silent, "### ERROR failed to allocate transparent geometry buffer");
|
||||
return FALSE;
|
||||
success = FALSE;
|
||||
}
|
||||
|
||||
if (!rasterizer_transparent_geometry_initialize_aux_buffer())
|
||||
return FALSE;
|
||||
success = success && rasterizer_transparent_geometry_initialize_aux_buffer();
|
||||
|
||||
return TRUE;
|
||||
return success;
|
||||
}
|
||||
|
||||
void rasterizer_transparent_geometry_begin(
|
||||
|
||||
Reference in new issue
Block a user