qvm: shot trace request prelude
Browse files- docs/ASSET_PIPELINE_TODO.md +3 -0
- docs/FINDINGS.md +3 -0
- docs/PROVISIONAL_TODO.md +3 -0
- docs/RESEARCH_LEDGER.md +5 -0
- docs/REVERSE_ENGINEERING_TODO.md +3 -0
- docs/research/QVM_SHOT_TRACE_REQUEST.md +7 -0
- docs/research/README.md +3 -0
- docs/research/qvm-shot-trace-request.json +0 -0
- scripts/analyze_qvm_shot_trace_request.py +51 -0
- scripts/test_qvm_shot_trace_request.py +28 -0
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()
|