nmarshall commited on
Commit
ddd93d5
·
1 Parent(s): 3fbdc49

qvm: allocated grenade construction

Browse files
docs/ASSET_PIPELINE_TODO.md CHANGED
@@ -502,3 +502,6 @@ Research progress: RE-606 [report](research/QVM_ENTITY_ALLOCATE.md); remaining n
502
 
503
 
504
  Research progress: RE-607 [report](research/QVM_ALLOCATED_EVENT.md); remaining native/content/runtime/platform scope stays open.
 
 
 
 
502
 
503
 
504
  Research progress: RE-607 [report](research/QVM_ALLOCATED_EVENT.md); remaining native/content/runtime/platform scope stays open.
505
+
506
+
507
+ Research progress: RE-608 [report](research/QVM_ALLOCATED_GRENADE.md); remaining native/content/runtime/platform scope stays open.
docs/FINDINGS.md CHANGED
@@ -860,3 +860,6 @@ Bounded qagame paths recover bomb-plant/inactivity correction requests, direct f
860
 
861
 
862
  **RE-607 — Temporary event with actual entity allocation:** 277695 now composes actual277165/277125 and278138, returning fixed pool slot64 through both reuse and extension paths. [Evidence](research/QVM_ALLOCATED_EVENT.md).
 
 
 
 
860
 
861
 
862
  **RE-607 — Temporary event with actual entity allocation:** 277695 now composes actual277165/277125 and278138, returning fixed pool slot64 through both reuse and extension paths. [Evidence](research/QVM_ALLOCATED_EVENT.md).
863
+
864
+
865
+ **RE-608 — Grenade constructor with actual entity allocation:** 285971 now composes recovered277165/277125 before grenade descriptor and inherited velocity writes, preserving slot identity and in-use fields. [Evidence](research/QVM_ALLOCATED_GRENADE.md).
docs/PROVISIONAL_TODO.md CHANGED
@@ -822,3 +822,6 @@ Research progress: RE-606 [report](research/QVM_ENTITY_ALLOCATE.md); remaining n
822
 
823
 
824
  Research progress: RE-607 [report](research/QVM_ALLOCATED_EVENT.md); remaining native/content/runtime/platform scope stays open.
 
 
 
 
822
 
823
 
824
  Research progress: RE-607 [report](research/QVM_ALLOCATED_EVENT.md); remaining native/content/runtime/platform scope stays open.
825
+
826
+
827
+ Research progress: RE-608 [report](research/QVM_ALLOCATED_GRENADE.md); remaining native/content/runtime/platform scope stays open.
docs/RESEARCH_LEDGER.md CHANGED
@@ -722,3 +722,8 @@ Full-pool retry relaxes the recent-free guard; source count1022 enters diagnosti
722
  ## 2026-10-20 — RE-607 Temporary event with actual entity allocation (separate task commit)
723
 
724
  277695 now composes actual277165/277125 and278138, returning fixed pool slot64 through both reuse and extension paths. Eight fixtures independently reconstruct full event records and verify registration/link call order and preserved stale fields. Full suite: 932 tests pass. Report regenerates byte-identically (717103 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
 
 
 
 
 
 
722
  ## 2026-10-20 — RE-607 Temporary event with actual entity allocation (separate task commit)
723
 
724
  277695 now composes actual277165/277125 and278138, returning fixed pool slot64 through both reuse and extension paths. Eight fixtures independently reconstruct full event records and verify registration/link call order and preserved stale fields. Full suite: 932 tests pass. Report regenerates byte-identically (717103 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
725
+
726
+
727
+ ## 2026-10-20 — RE-608 Grenade constructor with actual entity allocation (separate task commit)
728
+
729
+ 285971 now composes recovered277165/277125 before grenade descriptor and inherited velocity writes, preserving slot identity and in-use fields. Eight mode/reuse/ground-query combinations compare all220 record words to an independent grenade oracle. Existing supplied-allocation reports remain unchanged. Full suite: 935 tests pass. Report regenerates byte-identically (372396 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
docs/REVERSE_ENGINEERING_TODO.md CHANGED
@@ -865,3 +865,6 @@ Purpose: turn the supplied installation into an evidence-backed specification of
865
 
866
 
867
  - [x] RE-607 Temporary event with actual entity allocation ([report](research/QVM_ALLOCATED_EVENT.md)).
 
 
 
 
865
 
866
 
867
  - [x] RE-607 Temporary event with actual entity allocation ([report](research/QVM_ALLOCATED_EVENT.md)).
868
+
869
+
870
+ - [x] RE-608 Grenade constructor with actual entity allocation ([report](research/QVM_ALLOCATED_GRENADE.md)).
docs/research/QVM_ALLOCATED_GRENADE.md ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ # Grenade constructor with actual entity allocation
2
+
3
+ RE-608. Reproduce with `python3 scripts/analyze_qvm_allocated_grenade.py`; check with `python3 scripts/test_qvm_allocated_grenade.py`. The [machine report](qvm-allocated-grenade.json) retains source identity and bounded fixtures.
4
+
5
+ The grenade wrapper accepts an optional recovered allocator; default supplied-pointer behavior stays byte-identical. The new report uses actual277165/277125 for both extension and reuse, then actual source descriptor/direction/velocity writes. All220 final words are independently checked, including slot64/in-use1, owner/callback/fuse and mode-specific speed with optional supplied ground velocity. Allocator−16 registration requests are retained as evidence;276433 remains a supplied response and no engine world query runs. The source does not clear the old client-pointer word520 in this path. Callback223156 and trajectory physics remain pending. The broader firing-chain report still uses its original supplied allocation contract; this composition establishes the narrower constructor path only.
6
+
7
+ No original executable/full QVM/native collision/physics/rendering executes. Native responses and legal input domains are supplied or unverified where stated; full runtime/macOS/Linux Rust/Bevy/Solari gameplay remains open.
docs/research/README.md CHANGED
@@ -423,3 +423,6 @@ The extension collector adds five focused tests for native tail calls, command-r
423
 
424
 
425
  [RE-607: Temporary event with actual entity allocation](QVM_ALLOCATED_EVENT.md). Reproduce with `python3 scripts/analyze_qvm_allocated_event.py`; check with `python3 scripts/test_qvm_allocated_event.py`.
 
 
 
 
423
 
424
 
425
  [RE-607: Temporary event with actual entity allocation](QVM_ALLOCATED_EVENT.md). Reproduce with `python3 scripts/analyze_qvm_allocated_event.py`; check with `python3 scripts/test_qvm_allocated_event.py`.
426
+
427
+
428
+ [RE-608: Grenade constructor with actual entity allocation](QVM_ALLOCATED_GRENADE.md). Reproduce with `python3 scripts/analyze_qvm_allocated_grenade.py`; check with `python3 scripts/test_qvm_allocated_grenade.py`.
docs/research/qvm-allocated-grenade.json ADDED
The diff for this file is too large to render. See raw diff
 
scripts/analyze_qvm_allocated_grenade.py ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Actual grenade construction with recovered source-pool allocation."""
3
+ import itertools
4
+ from pathlib import Path
5
+ from qvm_research_support import source
6
+ from qvm_server_fire_support import BASES,FORWARD
7
+ from analyze_qvm_entity_allocate import allocate
8
+ from analyze_qvm_allocated_event import setup
9
+ from analyze_qvm_grenade_setup import grenade
10
+ from analyze_qvm_acceleration import PS,word
11
+ from analyze_qvm import write_json
12
+
13
+ def main():
14
+ q,raw,h,ins=source();rows=[]
15
+ for reused,mode,query in itertools.product([False,True],[0,1],[False,True]):
16
+ m=setup(raw,h,reused);m[0x90000+192]=7;m[PS+312]=7|(mode<<16);m[PS+68]=8
17
+ for o in range(0,880,4):m[BASES+o]=0
18
+ m[BASES]=8
19
+ for j,v in enumerate((.5,-.25,2)):m[BASES+36+4*j]=word(v)
20
+ for j,v in enumerate((.6,-.25,.8)):m[FORWARD+4*j]=word(v)
21
+ _,r=grenade(ins,m,BASES if query else 0,allocator=allocate);r['reuse']=reused;rows.append(r)
22
+ write_json(Path('docs/research/qvm-allocated-grenade.json'),{'source':q['source'],'sha256':q['sha256'],'probes':rows,'limits':'Actual285971,31691,277165,277125. Supplied math sqrt and276433 query response;−16 registration captured. No trajectory/223156 explosion/native world effects.'})
23
+ if __name__=='__main__':main()
scripts/analyze_qvm_grenade_setup.py CHANGED
@@ -11,12 +11,19 @@ from analyze_qvm_slide_prefix import vec
11
  from analyze_qvm import write_json
12
  LOCAL=0x7f000000
13
 
14
- def grenade(ins,m,query_pointer=0):
15
  initial=state(m);before=record(m);weapons=[m[PS+312+4*j]&0xffffffff for j in range(16)];minus=m[PS+308]&0xffffffff;m[LOCAL+84]=ENTITY;query=[];speeds={str(mode):m[7304+52*mode]&0xffffffff for mode in [0,1]};velocity=vec(m,PS+32);ground_velocity=vec(m,BASES+36)
16
- def allocated(i,m,a,c):return m,c,PROJECTILE,{'supplied_record_pointer':PROJECTILE,'allocator_not_executed':True}
 
 
 
 
 
 
 
17
  def find(i,m,a,c):r={'arguments':a,'supplied_pointer':query_pointer,'entity_id':m.get(query_pointer),'query_not_executed':True};query.append(r);return m,c,query_pointer,r
18
  m,c,r=execute(ins,285972,286471,m,(0,0,0),LOCAL,{31691:lookup,277165:allocated,276433:find});slot=r['children'][0]['effect']['execution']['return'];mode=m[LOCAL+24]
19
- return m,{'initial':initial,'initial_record':before,'weapon_slots':weapons,'slot_minus1_word':minus,'lookup_slot':slot,'mode':mode,'speeds':speeds,'word7224':m[7224]&0xffffffff,'time':m[34992532],'owner_velocity':velocity,'ground_velocity':ground_velocity,'query':query,'execution':r,'final_record':record(m),'final':state(m)}
20
 
21
  def main():
22
  q,raw,h,ins=source();rows=[]
 
11
  from analyze_qvm import write_json
12
  LOCAL=0x7f000000
13
 
14
+ def grenade(ins,m,query_pointer=0,allocator=None):
15
  initial=state(m);before=record(m);weapons=[m[PS+312+4*j]&0xffffffff for j in range(16)];minus=m[PS+308]&0xffffffff;m[LOCAL+84]=ENTITY;query=[];speeds={str(mode):m[7304+52*mode]&0xffffffff for mode in [0,1]};velocity=vec(m,PS+32);ground_velocity=vec(m,BASES+36)
16
+ pointers=[]
17
+ def allocated(i,m,a,c):
18
+ nonlocal before
19
+ if allocator is None:
20
+ pointers.append(PROJECTILE);return m,c,PROJECTILE,{'supplied_record_pointer':PROJECTILE,'allocator_not_executed':True}
21
+ m,r=allocator(i,m);p=r['selected']
22
+ if p is None:raise ValueError('Grenade allocation did not return')
23
+ pointers.append(p);before=record(m,p);return m,c,p,r
24
  def find(i,m,a,c):r={'arguments':a,'supplied_pointer':query_pointer,'entity_id':m.get(query_pointer),'query_not_executed':True};query.append(r);return m,c,query_pointer,r
25
  m,c,r=execute(ins,285972,286471,m,(0,0,0),LOCAL,{31691:lookup,277165:allocated,276433:find});slot=r['children'][0]['effect']['execution']['return'];mode=m[LOCAL+24]
26
+ return m,{'initial':initial,'initial_record':before,'weapon_slots':weapons,'slot_minus1_word':minus,'lookup_slot':slot,'mode':mode,'speeds':speeds,'word7224':m[7224]&0xffffffff,'time':m[34992532],'owner_velocity':velocity,'ground_velocity':ground_velocity,'query':query,'execution':r,'final_record':record(m,pointers[0]),'final':state(m)}
27
 
28
  def main():
29
  q,raw,h,ins=source();rows=[]
scripts/test_qvm_allocated_grenade.py ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json,unittest
2
+ from pathlib import Path
3
+ from test_qvm_grenade_setup import projectile
4
+ class AllocatedGrenadeTests(unittest.TestCase):
5
+ @classmethod
6
+ def setUpClass(cls):cls.r=json.loads(Path('docs/research/qvm-allocated-grenade.json').read_text())
7
+ def test_independent_full_record(self):
8
+ self.assertEqual(len(self.r['probes']),8)
9
+ for p in self.r['probes']:self.assertEqual(p['final_record'],projectile(p));self.assertEqual(p['final_record']['0'],64);self.assertEqual(p['final_record']['532'],1);self.assertEqual(p['final_record']['520'],0x12345678)
10
+ def test_real_allocator_and_registration(self):
11
+ for p in self.r['probes']:
12
+ a=p['execution']['children'][2]['effect'];self.assertEqual(a['selected'],34147688);self.assertEqual(len(a['registrations']),0 if p['reuse'] else 1);self.assertNotIn('allocator_not_executed',a);self.assertEqual([c['target'] for c in p['execution']['calls']],[31691,-107,277165,276433])
13
+ def test_pending_physics_and_query_remain_explicit(self):
14
+ for p in self.r['probes']:self.assertEqual(p['final_record']['648'],223156);self.assertEqual(p['final_record']['644'],7500);self.assertTrue(p['query'][0]['query_not_executed'])
15
+ if __name__=='__main__':unittest.main()