nmarshall commited on
Commit
2aca128
·
1 Parent(s): fd1c739

qvm: shot trace request prelude

Browse files
docs/ASSET_PIPELINE_TODO.md CHANGED
@@ -538,3 +538,6 @@ Research progress: RE-618 [report](research/QVM_COMPLETE_AIM.md); remaining nati
538
 
539
 
540
  Research progress: RE-619 [report](research/QVM_SHARED_SHOT_AIM.md); remaining native/content/runtime/platform scope stays open.
 
 
 
 
538
 
539
 
540
  Research progress: RE-619 [report](research/QVM_SHARED_SHOT_AIM.md); remaining native/content/runtime/platform scope stays open.
541
+
542
+
543
+ Research progress: RE-620 [report](research/QVM_SHOT_TRACE_REQUEST.md); remaining native/content/runtime/platform scope stays open.
docs/FINDINGS.md CHANGED
@@ -893,3 +893,6 @@ Bounded qagame paths recover bomb-plant/inactivity correction requests, direct f
893
 
894
 
895
  **RE-619 — Shared firing handler through complete aim and trace handoff:** Actual293732 now calls recovered290493 with its local forward/global muzzle, then prepares291641 without fabricating a trace result. [Evidence](research/QVM_SHARED_SHOT_AIM.md).
 
 
 
 
893
 
894
 
895
  **RE-619 — Shared firing handler through complete aim and trace handoff:** Actual293732 now calls recovered290493 with its local forward/global muzzle, then prepares291641 without fabricating a trace result. [Evidence](research/QVM_SHARED_SHOT_AIM.md).
896
+
897
+
898
+ **RE-620 — Shot trace prelude candidate bounds and native request:** 291641 unlinks the shooter, may request unrecovered rewind/setup helpers, widens eligible candidate bounds and issues native−25 with mask100663297. [Evidence](research/QVM_SHOT_TRACE_REQUEST.md).
docs/PROVISIONAL_TODO.md CHANGED
@@ -858,3 +858,6 @@ Research progress: RE-618 [report](research/QVM_COMPLETE_AIM.md); remaining nati
858
 
859
 
860
  Research progress: RE-619 [report](research/QVM_SHARED_SHOT_AIM.md); remaining native/content/runtime/platform scope stays open.
 
 
 
 
858
 
859
 
860
  Research progress: RE-619 [report](research/QVM_SHARED_SHOT_AIM.md); remaining native/content/runtime/platform scope stays open.
861
+
862
+
863
+ Research progress: RE-620 [report](research/QVM_SHOT_TRACE_REQUEST.md); remaining native/content/runtime/platform scope stays open.
docs/RESEARCH_LEDGER.md CHANGED
@@ -777,3 +777,8 @@ A single bounded source interpreter now follows every branch and call through290
777
  ## 2026-10-20 — RE-619 Shared firing handler through complete aim and trace handoff (separate task commit)
778
 
779
  Actual293732 now calls recovered290493 with its local forward/global muzzle, then prepares291641 without fabricating a trace result. 13 compositions check independent endpoint math, source caller ABI, current-slot versus lookup-ID distinction and no resume after zero-seed exhaustion. Full suite: 969 tests pass. Report regenerates byte-identically (569253 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
 
 
 
 
 
 
777
  ## 2026-10-20 — RE-619 Shared firing handler through complete aim and trace handoff (separate task commit)
778
 
779
  Actual293732 now calls recovered290493 with its local forward/global muzzle, then prepares291641 without fabricating a trace result. 13 compositions check independent endpoint math, source caller ABI, current-slot versus lookup-ID distinction and no resume after zero-seed exhaustion. Full suite: 969 tests pass. Report regenerates byte-identically (569253 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
780
+
781
+
782
+ ## 2026-10-20 — RE-620 Shot trace prelude candidate bounds and native request (separate task commit)
783
+
784
+ 291641 unlinks the shooter, may request unrecovered rewind/setup helpers, widens eligible candidate bounds and issues native−25 with mask100663297. Four branch fixtures and six player records check every candidate word, skip gates, native ABI and unchanged trace buffer. Full suite: 973 tests pass. Report regenerates byte-identically (297738 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
@@ -901,3 +901,6 @@ Purpose: turn the supplied installation into an evidence-backed specification of
901
 
902
 
903
  - [x] RE-619 Shared firing handler through complete aim and trace handoff ([report](research/QVM_SHARED_SHOT_AIM.md)).
 
 
 
 
901
 
902
 
903
  - [x] RE-619 Shared firing handler through complete aim and trace handoff ([report](research/QVM_SHARED_SHOT_AIM.md)).
904
+
905
+
906
+ - [x] RE-620 Shot trace prelude candidate bounds and native request ([report](research/QVM_SHOT_TRACE_REQUEST.md)).
docs/research/QVM_SHOT_TRACE_REQUEST.md ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ # Shot trace prelude candidate bounds and native request
2
+
3
+ RE-620. Reproduce with `python3 scripts/analyze_qvm_shot_trace_request.py`; check with `python3 scripts/test_qvm_shot_trace_request.py`. The [machine report](qvm-shot-trace-request.json) retains source identity and bounded fixtures.
4
+
5
+ Actual291642–291919 first issues native−32 for the shooter. Depending on client/record424 bit8/mode1 it suspends before144082(delta=PS6176−PS716,entity), or configured global34082500 suspends before144493(entity). Neither opaque helper is bypassed. When those gates permit continuation, the source scans34992592 indices for count34992580, skips self and clients with3096==3,4324!=0 or3740!=0, then edits bounding fields. Tests compare all220 words for six candidate records, including untouched minimumZ. Native−25 receives(trace,start,0,0,end,shooterID,100663297). Native unlink/trace effects are captured only: the trace buffer remains canaries, with no invented hit response. Bound restoration, relinking, rewind effects and post-trace classification remain unresolved. Synthetic records exercise the source gates without establishing legal world states.
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
@@ -459,3 +459,6 @@ The extension collector adds five focused tests for native tail calls, command-r
459
 
460
 
461
  [RE-619: Shared firing handler through complete aim and trace handoff](QVM_SHARED_SHOT_AIM.md). Reproduce with `python3 scripts/analyze_qvm_shared_shot_aim.py`; check with `python3 scripts/test_qvm_shared_shot_aim.py`.
 
 
 
 
459
 
460
 
461
  [RE-619: Shared firing handler through complete aim and trace handoff](QVM_SHARED_SHOT_AIM.md). Reproduce with `python3 scripts/analyze_qvm_shared_shot_aim.py`; check with `python3 scripts/test_qvm_shared_shot_aim.py`.
462
+
463
+
464
+ [RE-620: Shot trace prelude candidate bounds and native request](QVM_SHOT_TRACE_REQUEST.md). Reproduce with `python3 scripts/analyze_qvm_shot_trace_request.py`; check with `python3 scripts/test_qvm_shot_trace_request.py`.
docs/research/qvm-shot-trace-request.json ADDED
The diff for this file is too large to render. See raw diff
 
scripts/analyze_qvm_shot_trace_request.py ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """291641 prelude, player bound edits and first native trace request only."""
3
+ from pathlib import Path
4
+ from qvm_research_support import source,execute
5
+ from qvm_server_fire_support import seed,ENTITY,MUZZLE
6
+ from analyze_qvm_entity_init import POOL,STRIDE
7
+ from analyze_qvm_temp_event import record
8
+ from analyze_qvm_acceleration import PS,word
9
+ from analyze_qvm_slide_prefix import vec
10
+ from analyze_qvm import write_json
11
+ LOCAL=0x79700000
12
+ TRACE=LOCAL+0x2000
13
+ END=LOCAL+0x2100
14
+ HIT=LOCAL+0x2200
15
+
16
+ def first_trace(ins,m,args):
17
+ m=dict(m)
18
+ for o,v in args.items():m[LOCAL+144+o]=v
19
+ candidates=[POOL+m[34992592+4*j]*STRIDE for j in range(m[34992580])];initial={str(p):record(m,p) for p in candidates};requests=[]
20
+ def unlink(i,m,a,c):r={'target':-32,'arguments':a,'native_effect_not_executed':True};requests.append(r);return m,c,0,r
21
+ m,_,pre=execute(ins,291642,291898,m,(0,0,0),LOCAL,{-32:unlink},boundaries=[291701,291714]);stop=pre['stop'];call=None;execution=None
22
+ if stop==291701:status='rewind-child-pending';call={'target':144082,'arguments':{8:m[LOCAL+104],12:args[8]}}
23
+ elif stop==291714:status='configured-child-pending';call={'target':144493,'arguments':{8:args[8]}}
24
+ else:
25
+ status='native-trace-request-captured'
26
+ def trace(i,m,a,c):r={'target':-25,'arguments':a,'start':vec(m,a[12]),'end':vec(m,a[24]),'native_effect_not_executed':True};requests.append(r);return m,c,0,r
27
+ m,_,execution=execute(ins,291898,291920,m,(0,0,0),LOCAL,{-25:trace})
28
+ return m,{'arguments':args,'initial_candidates':initial,'final_candidates':{str(p):record(m,p) for p in candidates},'prelude':pre,'trace_execution':execution,'requests':requests,'status':status,'pending_call':call}
29
+
30
+ def fixture(raw,h,mode=1,flag=8,configured=0):
31
+ m=seed(raw,h);shooter=POOL+64*STRIDE
32
+ for o in range(0,STRIDE,4):m[shooter+o]=m[ENTITY+o]
33
+ m[shooter]=64;m[shooter+424]=flag;m[PS+6176]=1234;m[PS+716]=34;m[34082500]=configured;m[34992580]=6
34
+ for j,index in enumerate(range(64,70)):
35
+ p=POOL+index*STRIDE;client=PS if index==64 else 0x200000+index*0x2000;m[34992592+4*j]=index
36
+ for o in range(0,STRIDE,4):m.setdefault(p+o,0x12345678)
37
+ m[p+520]=client
38
+ for o in [3096,4324,3740]:m[client+o]=0
39
+ if index in [66,67,68]:m[client+{66:3096,67:4324,68:3740}[index]]=3 if index==66 else 1
40
+ for o in [436,440,444,448,452,456,464,468,472,476,480,484]:m[p+o]=word(float(o-450))
41
+ for o in range(0,56,4):m[TRACE+o]=0x12345678
42
+ for j,v in enumerate((123.5,-456.25,789)):m[END+4*j]=word(v)
43
+ args={8:shooter,12:TRACE,16:MUZZLE,20:END,24:word(1),28:HIT,32:mode}
44
+ return m,args
45
+
46
+ def main():
47
+ q,raw,h,ins=source();rows=[]
48
+ for mode,flag,configured in [(0,0,0),(1,8,0),(1,0,0),(1,8,1)]:
49
+ m,a=fixture(raw,h,mode,flag,configured);before=[m[TRACE+o] for o in range(0,56,4)];m,r=first_trace(ins,m,a);r['fixture']={'mode':mode,'flag':flag,'configured':configured};r['trace_buffer_before']=before;r['trace_buffer_after']=[m[TRACE+o] for o in range(0,56,4)];rows.append(r)
50
+ write_json(Path('docs/research/qvm-shot-trace-request.json'),{'source':q['source'],'sha256':q['sha256'],'probes':rows,'limits':'Actual291642–291919 with captured−32/−25 only; stops before144082/144493 when reached. Six synthetic player slots; no engine broadphase/link/rewind/collision or supplied hit response. Temporary candidate bound restoration remains later source scope.'})
51
+ if __name__=='__main__':main()
scripts/test_qvm_shot_trace_request.py ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json,unittest
2
+ from pathlib import Path
3
+ from test_qvm_ground import word,n,f
4
+
5
+ def widened(r):
6
+ r=dict(r)
7
+ for o in [476,480,484]:r[str(o)]=word(f(n(r[str(o)])+n(1103626240)))
8
+ for o in [464,468]:r[str(o)]=word(f(n(r[str(o)])-n(1103626240)))
9
+ for o in [448,452]:r[str(o)]=1105723392
10
+ r['456']=word(f(n(r['456'])+n(1097859072)))
11
+ for o in [436,440]:r[str(o)]=(-1041760256)&0xffffffff
12
+ return r
13
+ class ShotTraceRequestTests(unittest.TestCase):
14
+ @classmethod
15
+ def setUpClass(cls):cls.r=json.loads(Path('docs/research/qvm-shot-trace-request.json').read_text())
16
+ def test_independent_complete_candidate_records(self):
17
+ for p in self.r['probes']:
18
+ for address,r in p['initial_candidates'].items():
19
+ index=(int(address)-34091368)//880;change=p['status']=='native-trace-request-captured' and index in [65,69];self.assertEqual(p['final_candidates'][address],widened(r) if change else r)
20
+ def test_first_native_trace_abi_and_no_hit_write(self):
21
+ for p in self.r['probes'][:2]:
22
+ a=p['arguments'];self.assertEqual(p['requests'][-1]['arguments'],{'8':a['12'],'12':a['16'],'16':0,'20':0,'24':a['20'],'28':64,'32':100663297});self.assertEqual([c['target'] for c in p['trace_execution']['calls']],[-25]);self.assertEqual(p['trace_buffer_before'],p['trace_buffer_after'])
23
+ def test_unlink_and_pending_rewind_configuration(self):
24
+ for p in self.r['probes']:self.assertEqual(p['requests'][0],{'target':-32,'arguments':{'8':34091368+64*880},'native_effect_not_executed':True})
25
+ self.assertEqual(self.r['probes'][2]['pending_call'],{'target':144082,'arguments':{'8':1200,'12':34091368+64*880}});self.assertEqual(self.r['probes'][3]['pending_call'],{'target':144493,'arguments':{'8':34091368+64*880}})
26
+ def test_no_candidate_work_before_pending_children(self):
27
+ for p in self.r['probes'][2:]:self.assertIsNone(p['trace_execution']);self.assertEqual(p['initial_candidates'],p['final_candidates'])
28
+ if __name__=='__main__':unittest.main()