Commit Graph
420 Commits
Author SHA1 Message Date
Jonas Volman 6bfd956737 Reconcile approved Halo fidelity packets and bounded data credit
Recover transparent geometry submit (+1,285 meaningful code, zero exact losses); reconcile COMMON ownership and Q10 85+EXT1 credit, actions/main data, and separately disclosed denominator corrections. Preserve canonical-only repairs and all held research. C09 is ordinary disclosed cleanup, not a claim of proven scaffolding intent. Clean rebuild, 1,663 tests, parks, audits, provider links and independent EXT1 check pass. Local reconciliation only.
2026-09-29 13:52:37 -07:00
Jonas Volman f3aadeab98 Reconcile five Halo functions and approved declaration batches
Integrate coherent B3, P2/K17 prerequisites, completed K1-K16 + S, and the independent profile/effects rulings. Five gains and two explicitly approved B3 debits: net +3 strict functions, +2770 meaningful/+2800 padded bytes (+2774 progress credit). No additional losses; Halo objects 394 to 396 and data unchanged.

Clean rebuild, identical 8252-row stable sweep, 68 valid parks, admission/provider checks, 467-unit warning comparison, unchanged fake scan, and 1318 tests passed. Preserve canonical helper recoveries and unrelated work. Full evidence and disclosures in docs/object_matching_logs/astra_five_function_reconciliation_20260928.md.
2026-09-28 23:17:10 -07:00
Jonas Volman 51cd4d8b67 Reconcile exact AI actor talk-weight chain (+904 bytes) 2026-09-28 13:41:27 -07:00
Jonas Volman 709bfc3a3c Reconcile approved frontier ownership and admission packets
Import only independently reviewed production changes. Preserve canonical physics and virtual-keyboard repairs; keep B3 and all unresolved holds out.

Record exactly four approved canary debits (6987 meaningful bytes), six Halo admissions and two revocations. Keep vendor ioinit/storage work separate. Full build, 8252-row sweep, 1318 tests, park/admission/fake audits and 621-object binding pass within approved debit bounds.

Do not publish donor research dumps or private assets. README and unrelated user research remain untouched. See frontier_publication_reconciliation_20260927.md for complete evidence limits and accounting.
2026-09-27 17:12:48 -07:00
Jonas Volman ebd24ae1e7 Recover source-backed vector avoidance timer statement without exact credit 2026-09-27 11:44:36 -07:00
Jonas Volman 59757f4263 Reconcile approved type ownership, static locals and source disclosures
Independently gate storage + K, OQ-4 P-a/P-b1, four static-local packets and comment-only disclosures. Preserve all 7641 exact owner rows, 71 valid parks and 1161 passing tests; code/data credit unchanged. G and game_engine admission remain held because current canonical loses populate_statistic_buffer. Existing collision static-local repair is not duplicated. No donor tree, held candidate, scorer or private asset imported.
2026-09-27 05:17:27 -07:00
Jonas Volman a8b2512d63 Admit path_obstacle_avoidance after independent ownership audit 2026-09-27 04:32:47 -07:00
Jonas VolmanandClaude Opus 5.5 9c9118d1b5 ai: reconcile exact actor path refresh decision flag
Independently verified donor 9ed00bf758887d22ee67f9d1e8add23f317b2fc1. Restore the later first-party-attested live build_path flag, with January exact code and all 52 relocations. No new helper or storage owner. Whole-board batch sweep gains only the two reviewed functions and loses none; tests and warnings pass. The donor and all holds remain untouched.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 15:18:17 -07:00
Jonas Volman 7c0af5f029 Reconcile approved compiler-application code, data and owner repairs 2026-09-26 12:02:50 -07:00
Jonas Volman a885494045 ai: reconcile actor destination helper recovery and batch proofs
Independently reconcile the +968-byte landing from 455dffad. All seven target-only view casts strip without changing runtime sections; both new helper copies match January and link with selected providers in both orders. Batch: +3 functions, +4208 canonical credited code bytes, +4224 padded, zero regressions; 1161 tests pass. No whole-object or data credit changes.
2026-09-26 00:38:14 -07:00
Jonas VolmanandClaude Opus 5.5 3ee32a5cb5 R3 batch 2: owner rulings 1, 4, 7 - five objects complete
Owner rulings 2026-09-24:
- Q1 YES (04, not 04b): _actor_aim_grenade in its natural /Od body (no goto),
  keeping the BUG comment on January's vehicle-path read of the unassigned
  aim_vector. Header-inline helpers replace the TU redirects and the NODUP
  cross_product2d hand copy; the new COMDATs are identical to January's.
  Unlocks collision_features, real_math and path_smoothing (config 03A) and
  retires the stale collision_features rejection (04). The decals rejection,
  path_structure_bsp and path_obstacle_avoidance are untouched.
- Q4 YES (A2): _first_person_weapon_update without the two NULL guards,
  VALID_INDEX at all five /Od-attested sites, and the three magnitude
  redirects removed. The weapon-switch invariant is documented in source.
- Q7 YES: _uncompress_int32_to_real_vector3d stages the conversion through a
  real temp with a declaration-time initialiser (debug exact; verbatim in
  Oct-2001 2276P and the Sept-2001 cache.exe).

Full gate: 383 -> 388 / 468 Halo objects, +3 functions (+2,211 meaningful
code), 0 regressions, parks 82 -> 80, admission 0 contradicted / 0 revoked,
fake-match leads 26, pytest 1,161 passed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 00:04:10 -07:00
Jonas VolmanandClaude Opus 5.5 6f531fdd0b R3 batch 1: _ai_communication_finished exact via the /Od statement structure
The residual earlier lanes classified as an unreachable cross-jump closes once
the /Od 0x492e80 statement structure is restored:
- a positive outer preselected test;
- per-case reply resolution in /Od case order (target/friend/enemy), each with
  its /Od block-scoped local (reviewer amendment 01a adds the attested
  target_unit local; byte-identical);
- the play_reply dispatch.
Ablations show three load-bearing factors. The rest is byte-inert /Od
fidelity. January's .rdata literal order flips to January's exactly when the
dispatch is restored (an independent structure check). Park retired.

Gate (full ninja, objdiff 3.3.1): Halo functions 7,445 -> 7,446, meaningful
code +1,583 (1,584 padded); stable diff +1, 0 regressions; parks 82/0/0;
admission 11/0/2/0; fake scan 26; pytest 1161; diff --check clean.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 18:56:58 -07:00
Jonas VolmanandClaude Opus 5.5 4f236e9f2c R3 prerequisites: HCEX allegiance incident enum owner; zero-count authentic real_math.h content
Zero credit; both packets passed adversarial review and are byte-inert on
their complete consumer lists.
- game_allegiance.h owns the allegiance incident constants in HCEX's form
  (unnamed enum, no count); game_allegiance.c's private enum with the
  unattested tag and count is removed. 12 consumers are raw-identical apart
  from C1 $L jump-table label renumbering in 5 objects (not scored).
- real_math.h P1a:
  - seven assert macro families recovered from January string literals and
    validated by converting hand expansions at 16 January sites;
  - the nonuniform_cubic_spline body is replaced by the January-exact glow.c
    body (this removes an uninitialised read);
  - path_obstacle_avoidance loses its TU-local duplicate macro.
  The complete 273-consumer list shows 0 changed rows. The count-selected
  transport_endpoint.h hunk is held for the owner (review_real_math_h_real_math_P1).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 18:56:58 -07:00
Jonas Volman 193a68682a Reconcile Claude fifty-object round two 2026-09-24 17:10:07 -07:00
Jonas VolmanandClaude Opus 5.5 b993052102 R2 batch 3: first-party function names and storage from the completeness-critic routes
Zero credit; every packet was independently adversarially reviewed (22/22 approved).
- critic_3: 72 renames of placeholder/invented static function names across 20
  objects to first-party names. Each rename has Sept-2001 linker-map alignment
  (cachebeta xbe / retail cache exe, several also Aug-2001), relocation-masked
  body identity and matching callers; cachebeta publics show every row was a
  January static. hs's radiosity_hack_{start,save,find_point}_evaluate pairing
  is proven by the Sept .rdata hs_function_definition pointers; players'
  create_weapon also matches HCEX.pdb. Objects: ai_debug (reviewer-amended: a
  dead stub removed, its comment re-attached), transport_endpoint_winsock,
  transport_endpoint_set_winsock (+ parked.json key renames), profile,
  progress_bar, network_connection, saved_game_files, rasterizer_xbox_profile,
  xbox_sound_cache, game_engine_king, players, hs, hs_runtime, main, decals,
  rasterizer_lights, rasterizer_xbox_dynavobgeom,
  rasterizer_xbox_environment_fog, rasterizer_xbox_hardware_bitmaps,
  render_cameras.
- hs_compile: whitespace_characters, eol_characters and hs_type_primitive_parsers
  are external (cachebeta publics, HCEX DataIsGlobal); hs_compile_finish is
  static with a TU-local prototype (no public; HCEX static function).
- bink_playback: bink_playback_idle -> bink_playback_update__internal
  (first-party). The bink_decompress_audio_frame rename is NOT landed: it needs
  an added call whose position is unattested, the same class canonical held for
  hardware_geometry in 4d1ebf17.

Gate (full ninja, objdiff 3.3.1): objects 383, code 1,577,237, data 2,586,915
(all unchanged); stable diff 0 regressions; parks 83/0/0; admission 11/0/2/0;
fake scan 26; pytest 1161 passed; diff --check clean.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 16:59:40 -07:00
Jonas VolmanandClaude Opus 5.5 fcbc6c48cb R2 batch 1b: admit hardware_geometry and actors; render_debug_trigger_volumes exact
- rasterizer_xbox_hardware_geometry (admission): the no-op MoveResourceMemory
  wrapper pair is spelled D3DVertexBuffer_MoveResourceMemory, as the first-party
  2001-09-25 linker maps (atlas 6455066470 / 7eacac85) name it with January's
  exact spacing. This settles the round-1 owner pick A vs B without a ruling. The
  six hand-written placeholder stubs become their XDK names, 13 wrapper rows go
  static, and the call's argument/position are disclosed as byte-inert and
  unattested.
- actors (new code): _actor_input_update (2384) and _actors_spawn_from_unit (672)
  exact in the complete /Od named-local shape and declaration order; parks
  retired.
- hs_runtime: _render_debug_trigger_volumes (1088) exact in the /Od helper form,
  with the reviewer-amended /Od declaration order (matrix first; escape-law block
  for center/ray/result); park retired. 12 typecast converters are static per
  cachebeta publics (provider link FAIL(12) -> PASS). The object stays blocked by
  the retired begin_random tie.

Gate (full ninja, objdiff 3.3.1): Halo objects 381 -> 384; stable diff +3 strict /
4,144 padded, 0 regressions; parks 83/0/0; admission 9/0/2/0; fake scan 26;
pytest 1159 passed; diff --check clean.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 15:12:09 -07:00
Jonas VolmanandClaude Opus 5.5 0525558489 R2 batch 1b: admit hardware_geometry and actors; render_debug_trigger_volumes exact
- rasterizer_xbox_hardware_geometry (admission): the no-op MoveResourceMemory
  wrapper pair is spelled D3DVertexBuffer_MoveResourceMemory, as the first-party
  2001-09-25 linker maps (atlas 6455066470 / 7eacac85) name it with January's
  exact spacing. This settles the round-1 owner pick A vs B without a ruling. The
  six hand-written placeholder stubs become their XDK names, 13 wrapper rows go
  static, and the call's argument/position are disclosed as byte-inert and
  unattested.
- actors (new code): _actor_input_update (2384) and _actors_spawn_from_unit (672)
  exact in the complete /Od named-local shape and declaration order; parks
  retired.
- hs_runtime: _render_debug_trigger_volumes (1088) exact in the /Od helper form,
  with the reviewer-amended /Od declaration order (matrix first; escape-law block
  for center/ray/result); park retired. 12 typecast converters are static per
  cachebeta publics (provider link FAIL(12) -> PASS). The object stays blocked by
  the retired begin_random tie.

Gate (full ninja, objdiff 3.3.1): Halo objects 381 -> 384; stable diff +3 strict /
4,144 padded, 0 regressions; parks 83/0/0; admission 9/0/2/0; fake scan 26;
pytest 1159 passed; diff --check clean.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 09:25:03 -07:00
Jonas Volman f6d00a8c1d Reconcile Claude fifty-object lane with canonical
Merge verified source, data and owner corrections from 4e84c212. Resolve overlapping HS/path symbols against canonical, retain the dynavobgeom ownership rejection, document Layer 2/P7 source-shape decisions, and preserve held research. Verified 14 exact functions, 17 new Halo objects, zero regressions under objdiff 3.3.1.
2026-09-24 07:20:01 -07:00
Jonas VolmanandClaude Opus 5.5 b9a8d587a0 Batch 3: admit twelve objects; four exact functions; verified storage and data fixes
Objects admitted (Halo 363 -> 375), each with an independent adversarial review:
units (first-party names incl. the reviewer-corrected unit_vectors_are_valid, 49
static flags, '$'-defect data entry), collision_debug (/Od helper calls),
render_objects (b807f9f6 provider packet), editor_flying_camera
(_editor_camera_set_position_and_roll 432, storage + grouped entry re-pin),
rasterizer_xbox_shadows (shadow_model_draw 688), cache_files_windows
(open_cache_files 752), light_volumes (light_volume_render 912, reviewer-amended
/Od declaration order), actor_firing_position, path, biped_limp_noodle (HCEX file
statics), leaf_map and model_animations (/Od helper calls replace hand expansions).

Zero-credit/data: path_structure_bsp HCEX tables (+200 data), hud_nav_points
storage, first_person_weapons patch A (park re-baselined).

Gate (full ninja, objdiff 3.3.1): stable diff +4 strict / 2,784 padded, 0
regressions; parks 89/0/0; admission 11/0/5/0; fake scan 26 (new lead is the
/Od-attested empty then-arm in the still-parked fpw update); pytest 1157 passed;
diff --check clean. Ledger: docs/object_matching_logs/claude_fifty_objects_20260925.md
(adds the Layer 2 owner-ruling disclosure, tallies and held items).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-23 23:53:28 -07:00
Jonas VolmanandClaude Opus 5.5 b807f9f61d Header prerequisites: objects.h __FILE__ provider packet and path.h HCEX field
objects.h: both bounding-sphere inline assertions report OBJECTS_H_FILE, which
defaults to January's relative "..\objects\objects.h". object_lights defines the
absolute spelling first, as January's string census shows. action_vehicle loses
its NODUP hand copy of object_get_bounding_sphere, so the header inline is the only
definition. render_objects' lighting_storage becomes the static local of
object_get_cached_render_lighting (symbols.json).

path.h: the opaque __unknown140A0[0x5C] span is HCEX's `struct path_result
result`, and path.c stores through the field instead of a punning cast.

Consumer sweep (full ninja, objdiff 3.3.1): stable diff shows 0 regressions and no
moved rows beyond the batch-1/Layer-2 gains. Parks 93/0/0, admission 15/0/7/0,
pytest 1157 passed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-23 23:42:16 -07:00
Jonas VolmanandClaude Opus 5.5 931ed8dc2b Layer 2: /Od-attested real_math.h helper bodies and provider hand-copy removal
Shared-header prerequisite packet:
- real_math.h: distance2d/distance3d become square_root(distance_squared*(a,b))
  (/Od build, no local); project_point2d takes short mapping locals and a
  single ?: store (/Od-attested, equal to January's selected copy);
  lock/unlock_global_random_seed move from the 2026-09-04 reconstruction
  header random_math.h into real_math.h's existing RANDOM_MATH.C prototype
  section (main.c calls them without random_math.h).
- action_vehicle, path_obstacles, decals drop their '#define x x_inline'
  renames and hand-written NODUP helper copies; the header inlines now emit
  byte-identical copies of January's selected sections.
- object_lights and players adopt the /Od caller spellings (0x5d0d50).
Full ninja + rename-stable 8,245-function diff: +2 exact
(_player_set_action_result, _convex_hull2d_perimeter; park retired),
0 regressions. _ai_test_line_of_sight park remeasured (size/relocations
unchanged, fuzzy 97.98 -> 97.92).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-23 20:46:43 -07:00
Jonas VolmanandClaude Opus 5.5 bf937aac0f Batch 1: admit files_windows and objects; five exact functions
- files_windows: _file_get_size strict exact from the /Od single-exit
  result and file_error's named GetLastError() local; park retired.
- objects: Layer 1 helper-provider repair (action_charge, player_control,
  bored_camera, path_obstacles, decals use the genuine real_math.h
  inlines instead of hand-written NODUP copies; every provider row
  unchanged, emitted COMDATs byte-identical to January's selected copies,
  pair links pass both orders) plus the pinned objects_update data entry.
- Exact functions: _dead_camera_new, _actor_perception_refresh_danger_zone,
  _actor_look_idle_find_prop, _texture_cache_steal_memory.
- Zero-credit PDB/HCEX ownership corrections: profile, transport endpoint,
  actor_firing_position, game_engine, real_math, model_animations.

Halo objects 361 -> 363, code +2,769 meaningful bytes, data +1,530,
stable diff +5 functions / 0 regressions, parks 94/0/0, pytest green.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-23 20:42:50 -07:00
Jonas Volman e208c87ba6 ai: restore attested quantized pathfinding tables 2026-09-23 18:44:52 -07:00
Jonas VolmanandClaude Opus 5.5 e942f3385c Own realcmp in real_math.h and match convex_hull2d (770 meaningful bytes)
realcmp appears in January's own assert strings in four objects
(actors, actor_moving, matrix_math, biped_limp_noodle), so it is a
shared Bungie math macro. Define it once in real_math.h's macros
section, using an existing blank line so no header line number moves.
Blank the four identical TU-local copies in actors.c, actor_looking.c
(with its now-stale comment), matrix_math.c and biped_limp_noodle.c.
They are blanked, not deleted, so no __LINE__ moves.
realcmp_epsilon is untouched.

_convex_hull2d returns to direct points[index] indexing. The /Od build
(0x6b9250) reads the parameter array at every site ([eax+edx*8+4]),
with no pointer locals. It uses realcmp at the two degeneracy tests.
The function is now strict exact: 784 padded / 770 meaningful bytes,
25 relocations, normalized sha256
49124afa1d48d20fe6b36cd5c98861de7d27d9ec0109cf7d8dba8812c5464e77. With
the plain fabs(...) < _real_epsilon spelling it is not exact, so the
genuine macro is load-bearing. No new view cast, no new helper
definitions (nothing to link). _convex_polygon2d_clip_to_plane is not
pursued.

The now-stale _convex_hull2d park is retired with
tools.campaign.unpark --write (1 removed, 102 retained).

Verification: full ninja; all 273 real_math.h consumers rebuilt with
no C4005/C4013; stable diff vs frozen 8,245-function baseline
+2 (_collision_debug_render 4,192, _convex_hull2d 784 padded) and 0
regressions; parks 102/0/0; admission audit 13/0/7/0; fake-match scan
unchanged on all six files; python -m pytest -q tools 1154 passed;
git diff --check clean. objdiff 3.3.1 as canonical.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-23 15:58:34 -07:00
Jonas VolmanandClaude Opus 5.5 2535f91a79 Close five objects after correcting January symbol ownership
Each of actor_types, recorded_animation_definitions,
model_animation_definitions, sound_classes and object_types had strict
exact functions and a .data section byte-identical to January's: same
payload, flags and resolved relocation destinations. But each also had
private symbols whose storage disagreed with January. cachebeta.pdb
publics are the independent truth: none of the corrected symbols is
public, and no other January object references them.

- actor_types: the address-named accessor and table become
  actor_type_definition_get and actor_type_definitions, both static.
  January's own assert strings name the table, and the Halo CE atlas
  names the accessor at the same 0x140-byte span.
- recorded_animation_definitions: byte_swap_recording is static.
- model_animation_definitions: the seven *_animation_list_entries
  arrays are static beside their public animation_list wrappers.
- sound_classes: _code_001b84c0 is sound_class_datum_get (static). The
  atlas mapping is anchored on six exact sound_classes names.
- object_types: bss_00456e98 is processed_bsp_flags (static), the
  object's only file static in HCEX.pdb.
- items: drop the hand-written NODUP valid_real_matrix4x3 and
  valid_real_vector3d_axes3 copies (bodies identical to real_math.h).
  items genuinely uses them, and all 18 items rows are unchanged. This
  lets object_types' candidate-only copies pair-link. All eight
  object_types helper COMDATs are byte-identical to January's selected
  copies.

Five pinned entries in config/semantic_data_matches.json.
- Canonical scorer (objdiff 3.3.1): credits 6,656 data bytes and clears
  5 more revoked admission rows (9 -> 4).
- Pinned objdiff 3.6.0: already fully matched (verified no-ops).
- No code bytes, no config status change.

Verification: full ninja; stable diff vs frozen 8,245-function
baseline 0 gained / 0 regressions; parks 103/0/0; whole-object audit
PASS, PDB-storage 0 disagreements and provider links PASS for all five;
fake-match scan unchanged (0 -> 0) on all six changed sources; pytest
1154 passed; git diff --check clean.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-23 14:42:52 -07:00
Jonas Volman b0992d0ebe Admit nine verified Halo object closures 2026-09-23 14:25:38 -07:00
Jonas VolmanandClaude Opus 5.5 59925575f1 Match action_vehicle_find_destination and admit action_vehicle
Wave 2 of the limited object-closure lane. New code: 1 function,
1,232 padded / 1,225 meaningful bytes; action_vehicle closes at 17/17.

find_destination now uses the genuine real_math.h helpers the /Od build
(halo_cache_symbols.exe 0x4422a0) calls: distance3d, MAX, a pointer-
selected target copy, vector_from_points2d x4, dot_product2d,
point_from_line2d x2, magnitude_squared2d/3d, perpendicular2d,
negate_vector2d, normalize2d, vector_from_points3d, square_root,
point_from_line3d x3, scale_vector3d, and a single success flag. Local
names come from the /Od RTC descriptor. The statement list is Lane B's
diag_inline.c donor.

- Drop the REAL_MATH_EXTERNAL_POINT_FROM_LINE3D guard for this TU.
  January's action_vehicle holds an UNDEF reference to
  _point_from_line3d, so this is within owner ruling 1. The emitted
  COMDAT is section-identical to January's action_charge copy.
- _scale_vector3d is a new all-inlined COMDAT (ruling 5). Its caller is
  strict exact and the section is identical to January's copy.
- Drop the hand-written NODUP point_from_line2d and its rename. The
  header inline now supplies the exact, January-owned _point_from_line2d,
  and no object on the board defines it NODUP.
- 18 view casts, admitted under ruling 6. Each is attested at its own
  /Od call site (quoted in the ledger). The strip test is byte-inert:
  with all 18 removed the function is still EXACT and section-identical.

Verification: full ninja; stable diff gained 1 / 1,232 bytes,
regressions 0; parks 103/0/0; admission audit 39 candidates,
0 contradicted, 0 revoked; object audit PASS; selected-provider link
PASS (both orders, 21 surplus symbols); pytest 1154 passed;
halobetacache linked files 335 -> 336. Ledger:
docs/object_matching_logs/claude_object_closure_20260924.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-23 11:58:45 -07:00
Jonas VolmanandClaude Opus 5.5 f04103c28f Admit action_flee, action_guard and aim_assist objects
Whole-object admission of three objects whose functions were already
strict exact (13/13, 15/15, 16/16). No new code bytes are credited.

Symbol ownership (January cachebeta.pdb publics, no cross-TU refs):
- symbols.json marks _action_flee_find_flee_position,
  _action_flee_current_position_exposed, _action_flee_at_flee_position
  and _action_guard_speak_post_combat static, matching January's
  storage class.
- aim_assist.c: compute_composite_attenuation is public in January, so
  drop `static` from its prototype and definition.

Genuine helper-provider repairs (selected-provider LNK2005 fixes):
- actor_moving.c drops its hand-written NODUP arccosine and the
  arccosine_inline rename; the one acos site becomes
  arccosine(facing_dot). The /Od build (halo_cache_symbols.exe) calls
  an actor_moving-local arccosine COMDAT at exactly this site
  (0x465510 -> 0x46d330), and January's actor_moving owns _arccosine.
  All 36 actor_moving rows are unchanged, including the 2,752-byte
  _actor_move_calculate_movement and _arccosine.
- path_obstacles.c drops its hand-written NODUP set_real_point2d and
  rename; its project_point3d copy now calls set_real_point2d as the
  real_math.h inline does. All 16 rows unchanged.
After both, no object on the board defines _arccosine or
_set_real_point2d NODUP.

Verification: full ninja; stable diff gained 0 / regressions 0;
parks 103 active / 0 stale / 0 invalid; admission audit 39 candidates,
0 contradicted, 0 revoked; object audit PASS and selected-provider link
PASS (both orders) for all three; fake scan and castcheck unchanged;
pytest 1154 passed; halobetacache linked files 332 -> 335.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-23 11:58:39 -07:00
Jonas Volman 63e8dd7a3b Close eleven Halo objects with verified source and data ownership 2026-09-23 11:55:28 -07:00
Jonas Volman 5e81dabff0 Close five Halo objects with verified shared-helper ownership 2026-09-23 10:38:14 -07:00
Jonas VolmanandClaude Opus 5.5 c789bec003 Correct ai_debug actor rendering scopes and vision-cone trig
Structural lane batch 5: zero-credit fuzzy improvement to
_ai_debug_render_actor (24,976 B, still residual); zero regressions.

- Fixes a real defect: the headspace vision cone used the vertical sine
  and cosine arrays swapped (January computes i/j from the cosine and k
  from the sine).
- Buffer types and scopes follow the debug build's RTC records and
  January's slots: textbuffer[1024], tempbuf[80], shared ring/height
  loop indices, and one block-scoped offset_point in the paths block.
- Exact-equal instructions rise from 6,181 to 6,472 of 6,662. Frame,
  slot set and relocation multiset now all match January. What remains
  is x87 operand staging and one tail merge.

Gate: ninja PASS, stable diff 0 gained / 0 regressions, parks 112/0/0,
pytest 1152 passed / 5 skipped / 26 subtests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-23 05:31:57 -07:00
Jonas VolmanandClaude Opus 5.5 6eb9cb7626 Match aim projectile, obstacle avoidance and six HUD/AI functions
Structural lane batch 1: +8,512 padded / +8,459 meaningful bytes strict
exact (8 functions), zero stable-verdict regressions.

- aim_assist.c: _player_aim_projectile (Lane B body). The debug build
  calls set_real_point3d with the three x+i sums; the pin_normal_to_cone3d
  prototype now comes from the focused real_math_cones.h. The object stops
  emitting _add_vectors3d and _distance3d and emits only the coalescing
  _set_real_point3d, byte-identical to January's copy.
- path_obstacle_avoidance.c: _path_avoid_obstacles single-exit body
  (Lane B). Its only blocker, the _debug_path/_debug_obstacles static
  relabel, landed canonically in 4f4c8502.
- actor_perception.c: _actor_perception_friend_prop_is_attacking
  (single exit, /Od 0x472cb0) and _actor_situation_update (/Od statement
  order at 0x478d33).
- ui_widget.c: _display_error (/Od 0x65f2e0 shape) and
  _widget_instance_text_box_is_focused (/Od 0x66c190 list arm).
- hud_weapon.c: _render_grenade_hud (parent index in its own local,
  /Od 0x639128).
- hud_messaging.c: _hud_messaging_update from /Od 0x62cb90 (wchar_t[256]
  buffer gives the 0x2a0 frame), plus two relocs.json retargets of a
  one-before alias to _button_mappings-18.
- parked.json: unpark the three newly exact parked functions.
- docs: machine-readable manifest and the owner-decision packet.

Gate: ninja PASS, parks 121/0/0, admission 0 contradicted/0 revoked,
selected-provider link PASS on every touched unit, punning casts and
fake-scan leads unchanged, pytest 1152 passed / 5 skipped / 26 subtests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-23 04:19:08 -07:00
Jonas Volman a01115aaf5 Integrate verified Claude Lane B campaign
# Conflicts:
#	config/parked.json
2026-09-21 20:20:30 -07:00
Jonas VolmanandClaude Fable 5.1 ccf3b4125d Lane B wave 3: path.c complete - three strict-exact functions (+2,783 meaningful / +2,800 padded)
New strict exact (function board for ai/path is now 32/32):
  ai/path :: _path_state_traverse             2096
  ai/path :: _path_state_estimated_distance    496
  ai/path :: _closest_point_to_attractor       208

This is the owner's all-inlined COMDAT admission (2026-09-21: "admit the class
... genuine shared-header __inline, byte-identical COMDAT, strict-exact caller,
full ownership/build sweep, zero regressions. No hand expansions.") doing what
it was for: path.c HAND-EXPANDED point_from_line3d at three sites because the
old emission guard forbade the real helper, and those sites were the whole
residue. The three hand expansions are replaced by the REAL
point_from_line3d(...) call. path.obj therefore newly emits _point_from_line3d
(48 B, math/real_math.h, byte-identical to January's single folded copy credited
to ai/action_charge); all three callers are strict exact. admit_check.py: PASS.

Other source changes, each read from the first-party /Od build first and then
confirmed in January's bytes:
- _path_state_estimated_distance: a genuine reconstruction BUG. After the first
  walk /Od does `current_node_index = child_node_index;` (0x4c657e) and the
  second walk tests and advances current_node_index, as does the `?:`. We
  iterated child_node_index. With the copy, January's spilled result byte web and
  its EDI/ESI/EBX assignment appear - every row of the previous ledger. Exact on
  the first compile.
- _path_state_traverse: `closest_distance < 4.0f` (was distance_to_destination;
  /Od 0x4c76ee compares closest_distance); the second collision_bsp pointer is a
  block-scoped local; and the local below.

DISCLOSURE for owner awareness - a local that is written once and never read:
    struct path_node previous_node_values;  ...  previous_node_values = *new_node;
It is a first-party debugging snapshot, NOT an invention: the /Od RTC descriptor
NAMES it (`previous_node_values`, size 68 = sizeof(struct path_node), [ebp-0x8ec])
and /Od does the `rep movsd` right after path_get_node. VC7 deletes the copy in
the optimised build (no rep movs, frame 0x85c unchanged), but the extra IL local
is what yields January's x87 ordering at 0x2cc-0x2d8; January also shows a
constant +1 assert-line drift across this span, consistent with extra source
lines here. Strip test on the final file: without it the function is [sha].
Same class as `jet_marker_count` in 01e16607. Revert on request.

No new representation-punning casts (castcheck real=1 landing=1). Byte-inert
/Od restructurings the worker found were deliberately NOT applied (not
confirmable in January's bytes).

Config: config/parked.json - the three path entries removed (now exact).
Parks 168 / 0 / 0.

Verification: full ninja all_source progress semantic_progress pass (Code
1456768 -> 1459551, 7312 -> 7315). stable_verdicts vs the FROZEN baseline:
gained 24 / 15744 bytes, regressions 0. All 11,060 function and 1,706 section
report rows: 0 lost 100%, 0 missing. Fake scan 0 leads, line endings preserved,
git diff --check clean.
Reviewer: the wave was stopped on the owner's token budget before a reviewer
agent ran, so the ORCHESTRATOR reviewed this packet itself: re-gated from
scratch, read the full 22-line diff, re-derived the RTC attestation from its own
/Od dump, and ran admit_check / castcheck / fake scan / unitcheck.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 12:17:02 -07:00
Jonas VolmanandClaude Fable 5.1 3ba2eb9106 Lane B: three exact functions under the owner's per-site rule-24 admission (+2,802 meaningful / +2,816 padded)
New strict exact:
  ai/path_structure_bsp :: _structure_test_line2d     1104  (object now 6/6)
  ai/action_obey        :: _action_obey_control         992  (object now 27/27)
  ai/actions            :: _actor_action_try_to_dive    720

OWNER ADMISSION (2026-09-21), quoted: "Admit only with per-site /Od attestation,
byte-inert cast, compatible prefix layout, strict exactness, and ledger
disclosure. Land the three; keep the fighter held."

DISCLOSURE - every NEW 3D->2D view cast in this commit, with the first-party
/Od + /RTC build (halo_cache_symbols.exe) instructions that attest the SAME
punned object at the SAME site. The punning is Bungie's: C cannot pass or copy a
3D object as a 2D one without it.

1. _actor_action_try_to_dive - ONE cast:
     dot_product2d(&left_animation_alignment, (real_vector2d const *)&actor->input.facing_vector)
   /Od fn 0x42c1f0:  0042c3e6 mov edx,[ebp-8]      ; actor
                     0042c3e9 add edx,0x140        ; &actor->input.facing_vector (real_vector3d)
                     0042c3ef push edx
                     0042c3f0 call -> fn 0x42dd30
   and fn 0x42dd30 is dot_product2d: a[0]*b[0] + a[1]*b[1], two components only.
   Byte-inert: with the cast deleted the TU compiles (C4133) and the function is
   STILL strict exact 720.
2. _structure_test_line2d - FOUR casts, (real_point2d const *)&vertexN->point:
     vector_from_points2d(v0, v1, &e0e1); (v0, p1, &e0p1); (p0, v0, &p0e0); (p0, v1, &p0e1)
   /Od fn 0x4cee00, call sites 0x4cefb6 / 0x4cefca / 0x4cefe1 / 0x4ceff8: the
   vertex pointer locals [ebp-0x5c] and [ebp-0x60] (results of
   tag_block_get_element; the 3D point is at offset 0) are pushed DIRECTLY as the
   2D point arguments, in exactly that argument order, to fn 0x42e350 =
   vector_from_points2d (two 2-component subtractions).
   Byte-inert: with the five casts deleted (operands kept) the function is STILL
   strict exact 1104.
3. _action_obey_control - ONE cast, an aggregate COPY rather than an argument:
     alignment_vector = *(real_vector2d const *)&actor->input.facing_vector;
   /Od fn 0x43c2d0:  0043c7c7 mov eax,[ebp-8]        ; actor
                     0043c7ca mov ecx,[eax+0x140]
                     0043c7d0 mov edx,[eax+0x144]
                     0043c7d6 mov [ebp-0x2c],ecx
                     0043c7d9 mov [ebp-0x28],edx
                     0043c7dc lea eax,[ebp-0x2c] / push eax / call normalize2d
   Integer mov pairs = an 8-byte STRUCT ASSIGNMENT out of the 3D vector straight
   into the one 2D local that is then normalised (member-wise real copies compile
   to movss at /Od, and there is no intermediate temp). This replaces our
   member-wise copy through a `facing` temporary.
   Byte-inertness caveat, stated plainly: this cast cannot be strip-tested - C
   rejects an aggregate assignment across types outright - so the showing here is
   the /Od aggregate copy plus the fact that a pointer cast emits no code. The
   reviewer measured every undecorated alternative (.i/.j, .j/.i,
   set_real_vector2d, bound 3D pointer member-wise) as residual.
Compatible prefix layout (math/real_math.h): real_vector2d is `real n[2]`,
real_vector3d `real n[3]`; real_point2d `real n[2]`, real_point3d `real n[3]` -
each 2D union is exactly the first 8 bytes of its 3D counterpart.
The idiom already appears 72 times in 21 canonical files, incl. math/real_math.c.

Other source evidence:
- _structure_test_line2d: both loop heads are `mov 1 / test / je` in /Od
  (while (TRUE)); the inner break lands on the outer back-jump so the tail sits
  inside the inner loop; two blocked copies. Depends on the assert-spacing
  relocation identity taken from the data lane in 7583df5d.
- _actor_action_try_to_dive: the /Od RTC descriptor lists an extra 8-byte
  aggregate `left_animation_alignment` built by set_real_vector2d(-facing.j,
  facing.i) and fed to a real dot_product2d call; without it the body is residual.

STILL HELD: _update_alien_fighter_physics_new (1,088, exact in scratch): its
cross_product2d view-cast site has not been /Od-attested; owner: keep it held.

Config: config/parked.json - _structure_test_line2d and
_actor_action_try_to_dive entries removed (now exact). Parks 171 / 0 / 0.

Verification: full ninja all_source progress semantic_progress pass (Code
1453966 -> 1456768, 7309 -> 7312). stable_verdicts vs the FROZEN baseline:
gained 21 / 12944 bytes, regressions 0. All 11,060 function and 1,706 section
report rows: 0 lost 100%, 0 missing. Guard, ownership, fake scan, line endings
clean. git diff --check clean.
Reviewer: independent adversarial agents confirmed all three EXACT and credible
and held them ONLY on rule 24, which the owner has now ruled on per site; the
orchestrator re-derived every /Od attestation above from its own dumps.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 11:33:18 -07:00
Jonas VolmanandClaude Fable 5.1 f0b191bc68 Lane B: three exact functions under the owner's all-inlined COMDAT admission (+2,545 meaningful / +2,560 padded)
New strict exact:
  ai/actor_type_flood :: _actor_type_flood_desire_shamble  1296  (object now 2/2)
  units/vehicles      :: _update_human_plane_physics        928
  ai/path_smoothing   :: _find_tangent_point                336  (object now 6/6)

OWNER ADMISSION (2026-09-21), quoted: "Sufficient: admit the class. Require a
genuine shared-header __inline, byte-identical COMDAT, strict-exact caller, full
ownership/build sweep, and zero regressions. No hand expansions."
Each landing newly emits ONE header-inline COMDAT that January's split credits
to another object. Conditions verified per landing by scratch/orch/admit_check.py:
  _real_random_range   32 B  math/real_math.h  January owner ai/action_alert      byte-identical
  _interpolate_scalar  64 B  math/real_math.h  January owner game/player_control  byte-identical
  _set_real_point2d    32 B  math/real_math.h  January owner ai/path_obstacles    byte-identical
All three callers are strict exact; no hand expansion is used anywhere in them.

The evidence the owner accepted:
 (1) Compiler (scratch/orch/inline_lab.py): VC7 13.00.9254 with the campaign's
     real flags (/O2 /Oy- /DDEBUG /Dxbox) emits the out-of-line COMDAT for a
     non-static __inline whose EVERY call site inlined, and emits nothing when
     the inline is unused - so emission implies use in that TU.
 (2) January's own image (scratch/orch/inline_owner_census.py): of 104
     header-inline COMDATs, 65 are owned - per January's PDB section
     contributions - by an object that holds ZERO references to them (e.g.
     _cross_product2d in actor_combat.obj). Owners cluster at the earliest
     link-order TUs, as "folded survivor = first emitter" predicts. The split's
     single definition is therefore a link-fold artifact, not evidence that the
     other TUs did not emit the COMDAT.

Source evidence (all read from the first-party /Od build first, then confirmed
in January's bytes):
- _actor_type_flood_desire_shamble: result/switching flags zeroed at the top, all
  six `result = FALSE` arms, chain-assigned counters, `--timer == 0`, per-arm
  two-argument helper calls, MAX with double evaluation; `< 15.0f` confirmed by
  January's `test ah,5`. real_random_range is byte-REQUIRED (a hand expansion
  measures 1280 != 1296; January shows the inlined parameter temporaries).
- _update_human_plane_physics: uses the real interpolate_scalar helper.
- _find_tangent_point: every call is a real real_math.h helper including
  set_real_point2d; store-by-store spellings are residual and worse than baseline.

Held alongside (NOT landed): _update_alien_fighter_physics_new (1,088, exact in
scratch) - needs a NEW 3D->2D view cast whose site is not /Od-attested; owner:
"keep the fighter held".

Config: config/parked.json - _actor_type_flood_desire_shamble entry removed
(now exact). Parks 173 / 0 / 0. No header, symbols.json, flag or tool change.

Verification: full ninja all_source progress semantic_progress pass (Code
1451421 -> 1453966, 7306 -> 7309). stable_verdicts vs the FROZEN baseline:
gained 18 / 10128 bytes, regressions 0. All 11,060 function and 1,706 section
report rows: 0 lost 100%, 0 missing. Guard, fake scan, line endings and the
new-punning-cast screen clean. git diff --check clean.
Reviewer: independent adversarial agents confirmed each body EXACT and credible
and held them ONLY on the ownership question the owner has now ruled on.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 11:27:15 -07:00
Jonas VolmanandClaude Fable 5.1 74c9cb2a02 Lane B wave 2: zero-credit fuzzy source corrections (path, collisions, action_charge)
ZERO exact credit. Better-evidenced bodies retained per house rule 11. No new
representation-punning casts (screened), no ownership change, no new
fake_match_scan lead, line endings preserved.

- physics/collisions.c _collision_move_point (4,752 B, not parked): reviewer byte
  compare with relocation sites zeroed - differing bytes 3,847 -> 6. Size
  4752 == 4752 and relocations 226 == 226. The remaining six bytes (0x595-0x597,
  0x59b-0x59d) are ONE transposition of two independent instructions, so the body
  is semantically January on every path. Each hunk was strip-tested alone and is
  byte-bearing (position block scope, post-increment placement, ...). The owner's
  collisions[-1] ban is respected; line 1572 is untouched.
- ai/path.c (both PARKED, entries refreshed in this commit):
  _path_state_traverse (2,096 B): rewritten statement-for-statement from the /Od
  build (fn 0x4c6a70) with each fact confirmed in January's bytes. Frame and
  return count are now January's; differing regions 132 -> 61; objdiff
  64.6% -> 98.6%. Padded size is now 2112 vs 2096. Residue is confined to
  0x10b-0x4cc, at the hand-expanded point_from_line3d sites forced by the
  emission guard (path.obj is in the owner's still-guarded all-inlined class).
  _path_state_estimated_distance (496 B): size now equal (was 528), 191 == 191
  instructions, objdiff 77.5% -> 95.5%; residue is a three-register cycle.
- ai/action_charge.c _action_charge_perform (3,248 B, not parked): three hunks
  accepted - melee arm first, the `!ranged || underwater` arm, and the two-store
  unreachable test - each a pure block move or an equivalent rewrite with the
  same evaluation order. NOT landed: the worker's `__inline` added to eleven
  baseline-exact local math helpers (flips their COMDAT selection for zero
  credit; two earlier lanes declined the same lever; needs a helper-linkage
  ruling). action_charge still emits the January-owned _point_from_line3d.

Config: config/parked.json - the two path entries re-measured in place by line
surgery (base size / sha / objdiff percent) with a dated evidence note each.
Parks 174 active / 0 stale / 0 invalid.

Verification: see the preceding strict commit (same build): 0 exact regressions,
0 report rows lost. Reviewer: independent adversarial agent per unit,
ACCEPT_FUZZY_ZERO_CREDIT; partial files built by the reviewers and re-gated by
the orchestrator.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 11:10:49 -07:00
Jonas VolmanandClaude Fable 5.1 d57ba30c0d Lane B wave 2: nine strict-exact functions (+4,715 meaningful / +4,784 padded)
New strict exact (unit :: function, padded bytes):
  game/player_control     :: _player_control_modify_desired_angles  1584
  ai/actor_combat         :: _actor_aim_projectile                   720
  memory/stack_memory_pool:: _stack_memory_pool_allocate             640
  memory/stack_memory_pool:: _stack_memory_pool_resize_block         192
  ai/action_vehicle       :: _action_vehicle_setup_impromptu         464
  scenario/wind           :: _wind_variance_initialize               384
  ai/actions              :: _actors_searching_same_position         320
  ai/action_converse      :: _action_converse_perform                256
  game/game_engine_race   :: _race_engine_get_score                  224
Function boards now complete: action_converse 9/9, wind 9/9, stack_memory_pool
33/33, game_engine_race 36/36, player_control 49/49 (objects NOT marked Matching:
whole-object data/ownership audit not done; player_control .rdata is owner-held).

Method. Every closure started from the SOURCE SHAPE read out of the first-party
unoptimised /Od + /RTC build (halo_cache_symbols.exe, scratch/orch/odbuild.py)
and was then confirmed against January's own bytes before it was relied on
(double attestation); none is a spelling search.
- _player_control_modify_desired_angles: both autolevel products are
  `error * K * magnitude3d(v)`; three lines, no local, cast or parenthesis.
- _actor_aim_projectile: weapon_vector is scoped to its own inner block, the dot
  product is tested directly (no `alignment` local), and the three debug-info
  stores follow January's order (flag first). Reviewer strip tests: block alone,
  order alone and alignment-drop alone are each residual; only the combination
  is exact.
- _stack_memory_pool_allocate: result zeroed before the 0x342 assert, ONE return,
  positive guard with the assert in the else, in-place size arithmetic. The
  worker's unattested `last_block` pointer local was REMOVED by the reviewer; the
  /Od arm spelling lands instead.
- _stack_memory_pool_resize_block: body untouched. The static helper
  stack_memory_pool_dispose_block takes (pool, reference), as /Od pushes them and
  as the callee forwards them to valid_block(pool, reference).
- _action_vehicle_setup_impromptu: passes state_data->attempt_distance /
  ->continue_distance (the fields just stored) instead of the parameters.
- _wind_variance_initialize: block-local `word control_point_indices[4]` assigned
  inside the innermost axis loop; name and size from the /Od RTC descriptor.
- _actors_searching_same_position: four pointer locals, result = FALSE after the
  four calls, if / else-if arms assigning result, one return. Requires
  actor_get_pursuit_location (baseline exact, STILL exact 64) to read
  uncover.pursuit_location through its own union member in a second arm, as /Od
  has it. The evade-direction enum gains its two real middle constants; values
  are unchanged (_actor_evade_random is still 4).
- _action_converse_perform: REMOVES a pre-existing `true_value` dummy local from
  production. `in_range = TRUE` is assigned in two arms (if / else-if): /Od has two
  distinct stores, impossible from one `||` statement, and January has
  `mov ebx,1` with two bl stores each with two in-edges. One return.
- _race_engine_get_score: a `score` accumulator assigned on both arms with ONE
  return (single-exit law); team_index/laps/flags_touched are block locals of
  the non-team arm.

Orchestrator overrides of reviewer-approved text (not landed, zero credit lost
beyond what is listed under HELD):
- action_vehicle: the reviewer's landing.c also rewrote _find_destination with 16
  NEW 3D->2D view casts. Owner ruling 2026-09-21 keeps rule 24 strict for new
  representation-punning casts, so only the two-line exact closure lands.
- actions: _actor_action_try_to_dive (720, exact in scratch) needs ONE new view
  cast -> HELD. _actor_action_handle_vehicle_entry's fuzzy rewrite introduced an
  empty `if` arm holding only a `//` comment (new fake_match_scan lead the
  reviewer missed) -> reverted to production.

Config: config/parked.json - six entries REMOVED (now exact):
_action_converse_perform, _wind_variance_initialize, _actor_aim_projectile,
_actors_searching_same_position, _player_control_modify_desired_angles,
_race_engine_get_score. No header, symbols.json, flag or tool change.

Verification (tip of the following fuzzy commit): full ninja all_source progress
semantic_progress pass, Code 1446706 -> 1451421, 7297 -> 7306 functions.
stable_verdicts vs the FROZEN baseline: gained 15 / 7568 bytes, regressions 0.
All 11,060 function and 1,706 section report rows: 0 lost 100%, 0 missing.
Parks 174 active / 0 stale / 0 invalid. Admission audit 23 / 0 / 8 / 0.
Guard, ownership, fake scan, line endings, new-punning-cast screen: clean on
every landed file. git diff --check clean.
Reviewer: independent adversarial agent per unit, ACCEPT_EXACT for all nine;
orchestrator re-gated every file through scratch/orch/land.py.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 11:10:49 -07:00
Jonas VolmanandClaude Fable 5.1 479341043f Lane B wave 1: zero-credit fuzzy source corrections (infection, bipeds, physics)
ZERO exact credit. Better-evidenced source retained per house rule 11; none of
these functions is parked, so no park entry moves.

- ai/actor_type_infection.c _infection_swarm_control (3,616 B): partial rewrite
  from January's bytes. Baseline was 256 bytes short with a wrong frame and a
  wrong constant multiset (missing 1.0f, -1/15, (double)1e-4f, +/-pi/2; an extra
  _normalize3d call). Now residual [sha] ONLY: size 3616 == 3616 and relocations
  104 == 104. Side effect: the unit's .rdata section (228 B) now matches January
  (data +228, not counted as Lane B code credit). Adds the include of
  ai_scenario_definitions.h for the _ai_atom_move_facing_* enum the recovered
  obey-facing switch needs (no header edited).
- units/bipeds.c _biped_update_moving (4,080 B): four in-function corrections,
  each read from January: `0.01f` not the double `0.01` (January's constant is
  __real@3f847ae140000000 = (double)0.01f); `!(fabs(dyaw) < _real_epsilon)`;
  the two ground_tangential_* stores in January's order; no (short) cast on
  actor_index. The reviewer measured the worker's file-scope `realcmp` macro as
  byte-inert and it was DROPPED (strip test). Still residual [size, sha].
- physics/physics.c _physics_update_old (5,168 B): rotation_axis is assigned
  immediately before normalize3d, after object_translate - a store cannot cross
  a call, so its position relative to the call IS January's statement order.
  The reviewer REJECTED the rest of the physics candidate (21
  PHYSICS_POINT_FROM_LINE3D macro sites and body rewrites) pending an owner
  ruling; only this two-line change lands.

Verification: same full build and sweeps as the preceding strict commit -
0 exact regressions, 0 report rows lost, parks 180 / 0 / 0.
Reviewer: independent adversarial agent, ACCEPT_FUZZY_ZERO_CREDIT for each;
partial-landing files produced by the reviewers and re-verified by the
orchestrator (unitcheck NO LOSS, guard, ownership, fake scan, line endings).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 07:26:50 -07:00
Jonas VolmanandClaude Fable 5.1 7583df5d62 Lane B prerequisite: take the data lane's hunks in six Lane B files
Identical text to claude/data-section-credit-20260920 for these six files
(git diff against that branch is empty), so the two branches merge cleanly.
ZERO Lane B credit is claimed: the five data sections belong to the data lane.

Taken deliberately because three of the hunks change relocation IDENTITIES
that Lane B code residuals need before they can ever gate exact:
  action_vehicle.c        0.1225f -> 0.35f*0.35f  (__real@3dfae147, January's
                          folded product) - _action_vehicle_find_destination
  collision_debug.c       assert text count<=14   - _collision_debug_render
  path_structure_bsp.c    assert spacing          - _structure_test_line2d
and three are the .bss layout law (= 0 / = FALSE on debug globals):
  player_control.c, collisions.c, bipeds.c

Units/functions: none change verdict. Strict meaningful +0, padded +0.
Fuzzy: none. Data: +489 B (116+300+43+26+4), credited to the data lane.
Stable regression: scratch/lane_b_before.json -> lane_b_w0.json, 0 regressions,
0 gains. Lane inventory row-diff: 0 losses, 0 moves. Parks 0 stale / 0 invalid.
Full ninja all_source progress semantic_progress: pass
(Code 1443979 / 1770166, 7291 / 7574; Data 2360994 -> 2361483).
Config/header changes: none. Reviewer: data lane's own verification; re-verified
here by full build and row diff.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-21 02:27:48 -07:00
Jonas VolmanandClaude Opus 5 f910bd2754 encounters.obj CLOSED 61/61: _encounter_create EXACT (+752), switch at one site
Owner ruling 2026-09-20: admit at the single byte-proven site only; document the
threading-law evidence; leave the byte-invisible site natural.

The random-leader case now tests the marine type with a single-case switch,
switch (actor_type) { case _actor_marine: ... break; }, instead of an if. The
normal-leader site keeps its natural if. No source comment is added; the
evidence is recorded here and in the lane ledger.

WHY THIS SITE. January re-tests actor_type on the fall-through from the normal
case into the random case - mov ecx,[ebp-0x14] at 0x223, cmp cx,7 at 0x226 -
and that test is semantically redundant, because the dominating normal-case test
has already established actor_type == _actor_marine on that path. The redundant
test physically survives in January's bytes at the random-case site, which makes
that site the byte-proven one.

THE THREADING LAW (decoded, VC7 13.00.9254). The jump threader carries branch
knowledge from if compares but not from switch case edges, and it does not
thread an edge into a switch-dispatch test. With an if at both sites our build
threads the fall-through past the random test (jmp over it); about 25 if-based
spellings all stay threaded. A single-case switch at the random site is exactly
the shape that keeps January's re-test. The same law reproduces in a standalone
repro TU. The normal site's form is invisible in the bytes - a switch there also
matches - so it stays an if, per the ruling.

Measurement note: objdiff's fuzzy figure reads 94.19%, not 100, because of
recorded trap #2/#4 - January's jump table relocates onto _encounter_create+0x2c0
and ours onto an internal $L label, the same seven bytes spelled differently. The
strict comparator reports 38/38 relocations with 0 differing rows and the build
credits the function.

Verified: full ninja green; code 1,463,135 -> 1,463,880 (7,305 -> 7,306
functions); encounters 60/1 -> 61/0; 11,060 function rows and 1,706 section rows
diffed board-wide, 0 worse; no symbol added or removed; parks 179 / 0 / 0; forbid
guard exit 0; fake_match_scan 0 findings.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-21 02:06:29 -07:00
Jonas VolmanandClaude Opus 5 3ad3622623 props.obj CLOSED 17/17: _prop_get_active_by_unit_index EXACT (+144)
Owner ruling 2026-09-20: admit as proposed - the iterator and single-exit result
are natural; document the load-bearing declaration order in the ledger, not with
an intrusive source comment. No source comment is added.

The loop is rewritten with prop_iterator, this file's own idiom: both props.c
siblings that walk props use it (prop_get_base_by_unit_index,
prop_new_unacknowledged), January inlines it in both - there are no
_prop_iterator_* relocations - and January's prop_get_base bytes show the same
inlined header, cmp ecx,-1 then index := next then je, as this function. The
match predicate and the single-exit result follow the sibling. No new symbol is
defined.

LEDGER - THE LOAD-BEARING DECLARATION ORDER. The one fact that decides the match
is not visible in January's bytes: the single-exit initialiser long result =
NONE must EXECUTE AFTER the target-actor selection, so it is the last
declaration. Its web and the -1 constant then sit in the pre-loop join block that
initialises the cursor, lifting the cursor web's priority from 36 to 40 - a tie
with the state web that the [W+0x44] position tie-break awards to the cursor, so
it takes ecx, which is January's colouring. Declaring result first, as the
sibling does, is measured residual. Both the result web and the constant vanish
from the final code, which is why more than fifty earlier spellings - all without
a result variable, or with it initialised first - never reached it. The decoded
allocator's force-test confirms the threshold exactly (state <= 36 or cursor >= 40).

This reverses recorded conclusions R16 ("closed class-C colouring tie"), the
wave-I oracle's "UNREACHABLE by natural source", and props_obj.md's "do not
repeat" on the combined predicate, which does fail inside the plain loop but is
exact inside the iterator loop.

Verified: full ninja green; code 1,462,991 -> 1,463,135 (7,304 -> 7,305
functions); props 16/1 -> 17/0 with .text at 100%; 11,060 function rows and
1,706 section rows diffed board-wide, 0 worse; parks 179 / 0 / 0; forbid guard
exit 0; fake_match_scan 0 findings.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-21 02:05:12 -07:00
Jonas VolmanandClaude Opus 5 ba612bffb7 _actor_customize_unit EXACT (+640) under the narrow _random_range exception
Owner ruling 2026-09-20: allow the narrow _random_range COMDAT exception and land
+640. Do not extend it to _point_from_line3d; its explicit guard remains.

One line. The grenade count is computed with the header's __inline helper,
random_range(lower, upper + 1), instead of spelling out
seed_random_range(get_global_random_seed_address(), lower, upper + 1). This is
exactly how the already-exact _ai_scripting_renew in ai_script.c computes the
same grenade count from the same fields.

The decoded allocator predicts why it matters: the helper's two inlined
parameters raise the grenade block's pressure from 3 to 5, lifting
actor_variant_definition's web from 53 to 65 - one point above change_colors at
64 - so it takes ebx and change_colors spills, which is January's allocation. The
same form also fixes the push order at 0x18e. One source fact resolves both
halves of what had been classed as "allocator decision plus a separate
difference".

THE EXCEPTION, and its limits. The change newly defines exactly one symbol,
_random_range, a COMDAT byte-identical to January's single copy, which the split
credits to action_obey.obj. That emission is admitted by the ruling above and by
nothing broader; ai_script.obj and encounters.obj already emit the same COMDAT.
The _point_from_line3d guard still exits 0 on this unit.

The function was parked; its entry is removed by brace-depth line surgery.

Verified: full ninja green; code 1,462,353 -> 1,462,991 (7,303 -> 7,304
functions); actors 73/3 -> 74/2; 11,060 function rows and 1,706 section rows
diffed board-wide, 0 worse; newly defined symbols: _random_range only; parks
180 -> 179 active, 0 stale, 0 invalid; fake_match_scan 0 findings.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-21 02:04:23 -07:00
Jonas VolmanandClaude Opus 5 a0343465fc _actor_create_for_unit EXACT (+624): one return statement instead of five
The residual was one source fact. January's actor_create_for_unit has a single
exit - long actor_index = NONE; if (unit_index != NONE &&
actor_variant_definition_index != NONE) { ... } return actor_index; - with no
inner returns. Ours had five return statements.

This is the recorded single-exit law, and the shape is attested in this very
file: actor_new opens with the same long actor_index = NONE guard and returns
once. With one return VC7 splits the bottom return per incoming edge, which gives
the NONE initialiser its own web coloured esi; the -1 constant is then rescued
into esi by copy preference - January's pin - and the guard-fail exit becomes a
separate epilogue that does not pop ebx, so push ebx sinks below the guards.
Every piece of the recorded "-1 pin plus fifth epilogue" residual follows.

The biped rejection now clears a boolean valid flag, the attested carrier for
this idiom (actor_firing_position.c, ai_communication.c and action_charge.c use
the same spelling). It is not what buys the bytes: VC7 threads it away entirely,
leaving no register, slot or instruction, and four different spellings of it
compile to identical bytes. Restoring any single early return breaks the match.

The function was parked (class register-allocation); its entry is removed by
brace-depth line surgery, never re-serialized, and parks go 181 -> 180.

Verified: full ninja green; code 1,461,731 -> 1,462,353 (7,302 -> 7,303
functions); actors 72/4 -> 73/3; 11,060 function rows and 1,706 section rows
diffed board-wide, 0 worse; parks 180 active / 0 stale / 0 invalid; forbid guard
exit 0; fake_match_scan 0 findings.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-21 01:54:10 -07:00
Jonas VolmanandClaude Opus 5 3fdad47e67 _ai_communication_event: evidenced corrections, relocations now equal - ZERO bytes
Owner ruling 2026-09-20: land the package minus the invented flag and the
unproven actor-arm polarity change; keep all evidenced corrections, document it
as fuzzy, grant zero credit. The function stays residual and this is not
scoreboard movement.

Result: relocations 335 -> 336, equal to January with an identical multiset;
the frame now matches January's 0x126c (was 0x1268); REAL regions 339 -> 253.
Padded size moves from 16 short to 64 over - accepted because relocation
identity outranks padded size in the lane's ordered key, and on this function
size is dominated by the non-local branch-width noise wave H measured.

THE BEHAVIOUR FIX, proven by a controlled experiment rather than taken on
trust. The encounter arm of enemy_status[5] read !subject_encounter->enemy_alive.
Flipping ONLY that negation, with nothing else changed, turns exactly one
instruction - the je after the byte load at [esi+0x44] - into jne, and January
has jne at that site. So January's source tested enemy_alive; ours was wrong.

WHAT WAS DELIBERATELY LEFT OUT, per the ruling:
- the invented negative-sense protagonist_invalid flag. It moved padded size
  only (the frame matches January without it), the same profile as the
  steering rejected in _actor_look_update.
- the matching flip in the ACTOR arm. On the floor that flip is byte-inert, so
  January's bytes cannot decide it; it stays !target_really_alive. For the
  record, within this package it is not inert - 8,096 bytes with it against
  8,128 without, but REAL regions favour the other way (265 against 253) - so
  the signals conflict and nothing proves either polarity.

Other evidenced corrections kept: the 2.0f literal at the player-rating
assignment, value-identical to the real const it replaces, where January
references that global once and we did twice; char locals for the two %c debug
codes, which January computes at 8 bits; statement orders recovered from store
positions relative to calls. Disclosed per the verifier: play_type now lives in
candidate scope, so a reply candidate stores _unit_play_speech_none instead of a
stale value - dead data, since play_type is read only on the non-reply path.

Verified: full ninja green; 11,060 function rows and 1,706 section rows diffed
board-wide, 0 worse; ai_communication 45/3 unchanged; its .rdata stays 100%; no
symbol added or removed; parks 181 active / 0 stale / 0 invalid; forbid guard
exit 0; fake_match_scan 0 findings.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-20 23:47:02 -07:00
Jonas VolmanandClaude Opus 5 0269a75997 _ai_debug_render_actor: fix seven January-proven defects - ZERO bytes banked
A source-correctness landing under the standing "correct source beats a
misleading byte score" ruling. The function stays residual and this is not
scoreboard movement - though here every key improves as well: padded size
25024 -> 25008 against 24976, REAL regions 529 -> 340, and the frame now
matches January exactly, sub esp,0x80c -> 0x810.

Each defect was confirmed by its own January byte window becoming register-blind
identical, and by leave-one-out (dropping any one raises the blind region count).

V1  a real UNINITIALISED READ. January passes lea [ebp-8] and lea [ebp-4] as the
    full and partial vision-distance out-pointers and reads [ebp+edx-8] in the
    second loop nest: it is ONE real[2] array. Our full_distance_reference[1] was
    never written. Fixing it is what brings the frame to 0x810.
P2  an UNREACHABLE ARM. January's je 0x5c5f from both the render_paths_current
    test and the has-path test lands on the "following path" status text, so it
    sits outside that block; our "no current path" else could never run.
N1  normalize2d writes straight into desired_facing's own cells before the > 0
    test, spelled as at actor_combat.c:2304 and eight other AI sites.
X   four cross blocks read p0.x, not p1.x (fld [ebp-0x18]): p0.x = p0.x - 0.2f.
P1  the paths block indexes steps by the short local, not the char field.
SR1 the avoidance-objects loop addresses through an element pointer, as at
    actor_moving.c:903.
FA2 the flying-axes blocks use the existing __inline helpers scale_vector3d and
    point_from_line3d in January's term-major order. These are ordinary calls to
    existing helpers, which house rule 13 permits; nothing is written out.

Disclosure the verifier required: FA2 adds twelve (real_point3d *) casts on the
point_from_line3d arguments. All twelve are strip-test inert - the section is
byte-identical with them removed - and the cast is the tree-wide idiom.

Verified: full ninja green; 11,060 function rows and 1,706 section rows diffed
board-wide, 0 worse; ai_debug 59/1 unchanged; no symbol added or removed; the
pre-existing _point_from_line3d guard finding stays at exactly one; parks 181
active / 0 stale / 0 invalid; fake_match_scan 0 findings.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-20 23:39:00 -07:00
Jonas VolmanandClaude Opus 5 fd57245a6e _actor_move_vector_avoidance: 96 bytes short -> 16 - ZERO bytes banked
The function stays residual; this is not scoreboard movement. Padded size goes
4048 -> 4128 against January's 4144, relocations stay at 135/135, and REAL
regions go 180 -> 170. This recovers most of the size an earlier landing traded
away to get the relocation count exact.

THE PERPENDICULAR SITE is written as a two-axis accumulation - rotation starts
from *global_zero_vector3d and takes only the left and up terms - instead of a
call to actor_move_transform_avoidance_vector. This is a reconstruction of
January's own code, not the helper body written out: January's bytes at
0xe73-0xf02 contain no forward-axis term at all, no load of avoidance_data.forward
and no multiply by __real@00000000. VC7 13.00.9254 never folds x*0.0f; with the
helper genuinely inlined at this very site it leaves three fmul by zero. So
January's source computed only two axes, in its own text. A comment at the site
says so.

The remaining hunks are statement reorders fixed by store positions relative to
calls, and a declaration moved to where January's frame puts it.

The verifier found a dead store, perpendicular.i = 0.f, never read once the
forward term is gone. It is byte-inert - the function's bytes are identical with
and without it - so by the strip test the plain spelling is the admissible one,
and it is removed. No diagnostic-only dummy locals are present.

Verified: full ninja green; 11,060 function rows and 1,706 section rows diffed
board-wide, 0 worse; actor_moving 31/5 unchanged; newly defined symbols versus
the floor: none; parks 181 active / 0 stale / 0 invalid; forbid guard exit 0;
fake_match_scan 0 findings.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-20 23:37:11 -07:00
Jonas VolmanandClaude Opus 5 2ee8bfefe8 _actor_move_update: fix a proven allow_jump defect - ZERO bytes banked
The function stays residual at [sha]; this is not scoreboard movement. REAL
regions 57 -> 53 with size, relocations and real code end all unchanged.

THE DEFECT, verified from January's bytes before landing. Our source set
allow_jump only when BOTH vehicle->vehicle.hover < 0.7f AND up.k < 0.8f.
January tests hover (fcomp __real@3f333333 at 0x54e, jp 0x5fa), then executes
mov byte ptr [ebp-3], 1 at 0x562 - allow_jump = TRUE - and only then tests
up.k (fcomp __real@3f4ccccd at 0x566, jp 0x5fa). So January sets allow_jump
whenever hover < 0.7, and falls through when up.k >= 0.8. Our source had a
real behaviour difference; the if is now nested accordingly. The escape
direction, crouch and break stay inside the up.k test.

Also: rotation is scaled with the existing scale_vector3d helper instead of
three *= statements.

WHAT WAS NOT LANDED. The wave's primary variant PA also rewrote a negation with
negate_vector3d, which makes actor_moving.obj newly define a _negate_vector3d
COMDAT. January's actor_moving.obj does not define that symbol, so under the
2026-09-20 ownership ruling it cannot be emitted; PA_noNG, landed here, adds no
new symbol. A further variant PB is byte-worse on padded size (+16) and its extra
levers are neutral respellings rather than fixes, so it stays held.

Verified: full ninja green; 11,060 function rows and 1,706 section rows diffed
board-wide, 0 worse; actor_moving 31/5 unchanged; newly defined symbols versus
the floor: none; parks 181 active / 0 stale / 0 invalid; forbid guard exit 0;
fake_match_scan 0 findings.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-20 23:36:04 -07:00
Jonas VolmanandClaude Opus 5 5dddede52e _ai_test_line_of_sight: take HCEX-attested local names - byte-identical, ZERO bytes
Renames the function's parameters and locals to the names HCEX.pdb records:
point0 -> p0, cluster0 -> p0_cluster_index, point1 -> p1, cluster1 ->
p1_cluster_index, collision_fraction -> collision_t, and the expand-source /
expand-target corners to p0a/p0b and p1a/p1b/p1c. Per the house rule on real
names. All 128 non-debug sections of ai.obj are byte-identical before and
after, so the parked entry stays valid and nothing is scoreboard movement.

WHAT WAVE H ESTABLISHED ABOUT THIS FUNCTION - recorded because it overturns a
committed "proof". R11, R25 and res7 said no shape closes its 12-byte frame gap.
Every probe behind that kept four separate objects and only changed scopes.

The ledger now closes to the byte: 34 real bytes = the 7-byte collision_t
initialiser (the correct behaviour we keep, since January's bytes prove it reads
an uninitialised slot on the heavy-fog path) + 27 bytes from ONE surplus 12-byte
frame cell - 24 bytes of disp8 -> disp32 lea widening because our frame crosses
0x80, and 3 bytes for a cross-jump January can take and we cannot.

The mechanism: ai.c's TU-private REAL_MATH_EXTERNAL_NORMALIZE3D and
REAL_MATH_EXTERNAL_POINT_FROM_LINE3D defines make perpendicular address-exposed,
which blocks liveness packing and forces the interleaved struct copy. With the
helper bodies visible, the separate-locals source HCEX attests reproduces
January's frame, slot census and copy order exactly; size, 50 relocations and
331 instructions all match, and 37 ModRM bytes plus one esi/edi decision remain.

That route is dead under the 2026-09-20 ownership ruling: visible bodies make
ai.obj emit a _point_from_line3d COMDAT that January's split does not attribute
to it. So the function stays residual, now for a stated reason rather than a
false impossibility proof.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-20 23:34:45 -07:00
Jonas VolmanandClaude Opus 5 f5698ba245 _actor_look_update: land owner-admitted (a)+(b) only - ZERO bytes banked
Owner ruling 2026-09-20: admit (a) and (b) only; reject (c) as semantically
inert steering; keep the function fuzzy at zero credit and audit the helper's
COMDAT ownership. It stays residual at [size 4704!=4720, sha] and this is not
scoreboard movement.

(a) valid_real_normal2d's definition takes the __inline specifier. Its sibling
    valid_real_normal3d is __inline in real_math.h, and four January objects
    reference this function. The call stays out of line.
(b) the aiming-speed tail is two separate tests rather than one disjunction;
    HCEX's line table puts them on separate lines, 1740 and 1745.
Both carry in-file disclosure comments, which were checked to leave the
function's bytes identical to the measured candidate.

What was NOT landed, and why:
- (c) can_look = TRUE on the asleep path - rejected by the ruling.
- the copy of desired_aiming into desired_looking moved after update_facing.
  It was paired with (c). Without it, the asleep path has already set both
  vectors from desired_facing, so the move adds only a redundant store of an
  equal value - the same inert steering (c) was rejected as.
- the plain-source edits (the minor_valid flag, the 2D struct copies and dot
  order). Ablated one subset at a time: without (c) they push padded size from
  4704 to 4688 and instructions away from January's 1,439, so under the lane's
  ordered key they are WORSE and stay out.
(a)+(b) alone ties every higher key - size 4704, relocations, 1,439
instructions, real code end 4690 - and improves REAL regions 120 -> 119.

COMDAT OWNERSHIP AUDIT, as directed: CLEAN. In both builds actor_looking.obj is
the only definer of _valid_real_normal2d and actors, actor_moving and units are
its only referencers. The one difference is the COMDAT selection flag, now
select-any against the split's no-duplicates - but csplit writes no-duplicates
for all 8,223 function COMDATs and never records select-any, even for helpers
that were certainly __inline in January such as valid_real_normal3d and
dot_product3d. The flag carries no evidence, and our build already differs this
way on 162 functions including that sibling.

Verified: full ninja green; 11,060 function rows and 1,706 section rows diffed
board-wide, 0 worse; actor_moving 31/5, actors 72/4 and units 189/189
unchanged; parks 181 active / 0 stale / 0 invalid; forbid guard exit 0;
fake_match_scan 0 findings.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-20 23:32:09 -07:00