nmarshall commited on
Commit
f525c4a
·
1 Parent(s): 75ffee4

qvm: posed model transform chain

Browse files
docs/ASSET_PIPELINE_TODO.md CHANGED
@@ -682,3 +682,6 @@ Research progress: RE-667 [report](research/QVM_QUERIED_GRENADE.md); remaining n
682
 
683
 
684
  Research progress: RE-668 [report](research/QVM_MODEL_CHILD_SAMPLES.md); remaining native/content/runtime/platform scope stays open.
 
 
 
 
682
 
683
 
684
  Research progress: RE-668 [report](research/QVM_MODEL_CHILD_SAMPLES.md); remaining native/content/runtime/platform scope stays open.
685
+
686
+
687
+ Research progress: RE-670 [report](research/QVM_POSED_MODEL.md); remaining native/content/runtime/platform scope stays open.
docs/FINDINGS.md CHANGED
@@ -1028,3 +1028,6 @@ Bounded qagame paths recover bomb-plant/inactivity correction requests, direct f
1028
 
1029
 
1030
  **RE-668 — Model-child traversal and frame-sample interpolation:** 25341 skips null child entries, selects112-byte frame/child samples and interpolates twelve words as B+(A−B)×fraction before requesting22009. [Evidence](research/QVM_MODEL_CHILD_SAMPLES.md).
 
 
 
 
1028
 
1029
 
1030
  **RE-668 — Model-child traversal and frame-sample interpolation:** 25341 skips null child entries, selects112-byte frame/child samples and interpolates twelve words as B+(A−B)×fraction before requesting22009. [Evidence](research/QVM_MODEL_CHILD_SAMPLES.md).
1031
+
1032
+
1033
+ **RE-670 — Model ray through actual pose and transform construction:** 144766 now executes complete32254 with live target/client pointers and consumes its actual nine angle outputs in all four transform records. [Evidence](research/QVM_POSED_MODEL.md).
docs/PROVISIONAL_TODO.md CHANGED
@@ -1008,3 +1008,6 @@ Research progress: RE-668 [report](research/QVM_MODEL_CHILD_SAMPLES.md); remaini
1008
 
1009
 
1010
  RE-659–668 batch complete: [complete finite pose and lifecycle composition](research/QVM_POSE_LIFECYCLE_BATCH.md). RE-669 tracks continued model/trace/lifecycle recovery; original/native parity and playable Rust/Bevy/Solari integration remain open.
 
 
 
 
1008
 
1009
 
1010
  RE-659–668 batch complete: [complete finite pose and lifecycle composition](research/QVM_POSE_LIFECYCLE_BATCH.md). RE-669 tracks continued model/trace/lifecycle recovery; original/native parity and playable Rust/Bevy/Solari integration remain open.
1011
+
1012
+
1013
+ Research progress: RE-670 [report](research/QVM_POSED_MODEL.md); remaining native/content/runtime/platform scope stays open.
docs/RESEARCH_LEDGER.md CHANGED
@@ -1002,3 +1002,8 @@ Grenade construction now runs actual276433 over an explicit pool and inherits th
1002
  ## 2026-10-20 — RE-668 Model-child traversal and frame-sample interpolation (separate task commit)
1003
 
1004
  25341 skips null child entries, selects112-byte frame/child samples and interpolates twelve words as B+(A−B)×fraction before requesting22009. 47 fixtures independently check traversal/empty boundaries, frame addressing, all twelve interpolated words, extrapolation and exact pending transform arguments. Full suite: 1137 tests pass. Report regenerates byte-identically (68686 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
 
 
 
 
 
 
1002
  ## 2026-10-20 — RE-668 Model-child traversal and frame-sample interpolation (separate task commit)
1003
 
1004
  25341 skips null child entries, selects112-byte frame/child samples and interpolates twelve words as B+(A−B)×fraction before requesting22009. 47 fixtures independently check traversal/empty boundaries, frame addressing, all twelve interpolated words, extrapolation and exact pending transform arguments. Full suite: 1137 tests pass. Report regenerates byte-identically (68686 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
1005
+
1006
+
1007
+ ## 2026-10-21 — RE-670 Model ray through actual pose and transform construction (separate task commit)
1008
+
1009
+ 144766 now executes complete32254 with live target/client pointers and consumes its actual nine angle outputs in all four transform records. 24 fixtures independently check complete pose outputs/state, caller ABI, ray normalization and every word of four88-byte transform records. Full suite: 1141 tests pass. Report regenerates byte-identically (1011044 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
@@ -1051,3 +1051,6 @@ Purpose: turn the supplied installation into an evidence-backed specification of
1051
 
1052
 
1053
  - [ ] RE-669 Compose complete pose into model-hit processing, recover transform/hierarchy/leaf geometry and actual hit records, then continue trace/contact/damage, scheduling and lifecycle parity toward a verified Rust gameplay slice. See the [next ten tasks](research/QVM_POSE_LIFECYCLE_BATCH.md#next-ten-concrete-tasks).
 
 
 
 
1051
 
1052
 
1053
  - [ ] RE-669 Compose complete pose into model-hit processing, recover transform/hierarchy/leaf geometry and actual hit records, then continue trace/contact/damage, scheduling and lifecycle parity toward a verified Rust gameplay slice. See the [next ten tasks](research/QVM_POSE_LIFECYCLE_BATCH.md#next-ten-concrete-tasks).
1054
+
1055
+
1056
+ - [x] RE-670 Model ray through actual pose and transform construction ([report](research/QVM_POSED_MODEL.md)).
docs/research/QVM_POSED_MODEL.md ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ # Model ray through actual pose and transform construction
2
+
3
+ RE-670. Reproduce with `python3 scripts/analyze_qvm_posed_model.py`; check with `python3 scripts/test_qvm_posed_model.py`. The [machine report](qvm-posed-model.json) retains source identity and bounded fixtures.
4
+
5
+ Actual144767–146550 composes ray normalization, complete32254 and transform construction without supplied pose outputs. The pose wrapper now snapshots the four actual argument pointers rather than fixed fixture addresses; its existing report remains byte-identical. Target/client offsets and shooter6176−client0 elapsed are forwarded by source instructions. Independent oracles verify generated angles, external state and full transform buffers. Native finite math and zero fill remain explicit models. The run stops before25341: model tables and timing remain fixtures, and no successful intersection or original native parity is asserted.
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
@@ -609,3 +609,6 @@ The extension collector adds five focused tests for native tail calls, command-r
609
 
610
 
611
  [RE-659–668: Complete finite pose and lifecycle composition](QVM_POSE_LIFECYCLE_BATCH.md), with validation limits and the next ten concrete tasks.
 
 
 
 
609
 
610
 
611
  [RE-659–668: Complete finite pose and lifecycle composition](QVM_POSE_LIFECYCLE_BATCH.md), with validation limits and the next ten concrete tasks.
612
+
613
+
614
+ [RE-670: Model ray through actual pose and transform construction](QVM_POSED_MODEL.md). Reproduce with `python3 scripts/analyze_qvm_posed_model.py`; check with `python3 scripts/test_qvm_posed_model.py`.
docs/research/qvm-posed-model.json ADDED
The diff for this file is too large to render. See raw diff
 
scripts/analyze_qvm_complete_pose.py CHANGED
@@ -13,13 +13,13 @@ from analyze_qvm_slide_prefix import vec
13
  from analyze_qvm import write_json
14
 
15
  def pose(ins,m,args):
16
- m=dict(m);before={'angles':vec(m,args[8]),'velocity':vec(m,args[12]),'state':[m[STATE+4*j]&0xffffffff for j in range(4)]}
17
  for o,v in args.items():m[LOCAL+236+o]=v
18
  def controller(i,m,a,c):m,r=swing(i,m,a);return m,c,0,r
19
  def direction(i,m,a,c):m,r=vector_angles(i,m,a);return m,c,0,r
20
  def blend(i,m,a,c):m,r=angle(i,m,a);return m,c,r['result'],r
21
  m,_,e=execute(ins,32255,33389,m,(0,0,0),LOCAL,{**TRIG,33391:controller,62944:direction,63746:blend})
22
- return m,{'arguments':args,'initial':before,'final_state':[m[STATE+4*j]&0xffffffff for j in range(4)],'output_legs_body_head':[vec(m,args[28]+o) for o in [0,12,24]],'flag':m.get(args[48]),'execution':e}
23
 
24
  def main():
25
  q,raw,h,ins=source();table=constants(raw,h,list(range(20536+22*4,20536+41*4,4))+[21348,21352,21356]);rows=[]
 
13
  from analyze_qvm import write_json
14
 
15
  def pose(ins,m,args):
16
+ m=dict(m);before={'angles':vec(m,args[8]),'velocity':vec(m,args[12]),'state':[m[args[o]]&0xffffffff for o in [32,36,40,44]]}
17
  for o,v in args.items():m[LOCAL+236+o]=v
18
  def controller(i,m,a,c):m,r=swing(i,m,a);return m,c,0,r
19
  def direction(i,m,a,c):m,r=vector_angles(i,m,a);return m,c,0,r
20
  def blend(i,m,a,c):m,r=angle(i,m,a);return m,c,r['result'],r
21
  m,_,e=execute(ins,32255,33389,m,(0,0,0),LOCAL,{**TRIG,33391:controller,62944:direction,63746:blend})
22
+ return m,{'arguments':args,'initial':before,'final_state':[m[args[o]]&0xffffffff for o in [32,36,40,44]],'output_legs_body_head':[vec(m,args[28]+o) for o in [0,12,24]],'flag':m.get(args[48]),'execution':e}
23
 
24
  def main():
25
  q,raw,h,ins=source();table=constants(raw,h,list(range(20536+22*4,20536+41*4,4))+[21348,21352,21356]);rows=[]
scripts/analyze_qvm_posed_model.py ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Actual144766 ray, complete32254 and transform records before25341."""
3
+ import itertools
4
+ from pathlib import Path
5
+ from qvm_research_support import source,execute,constants
6
+ from qvm_shot_math_support import TRIG
7
+ from analyze_qvm_complete_pose import pose
8
+ from analyze_qvm_model_ray_prefix import LOCAL
9
+ from analyze_qvm_model_transforms import BUFFERS,TABLES
10
+ from analyze_qvm_shot_trace_request import fixture,TRACE,END,HIT
11
+ from analyze_qvm_entity_init import POOL,STRIDE
12
+ from analyze_qvm_acceleration import word
13
+ from analyze_qvm_slide_prefix import vec
14
+ from analyze_qvm import write_json
15
+
16
+ def model(ins,m,args):
17
+ m=dict(m)
18
+ for o,v in args.items():m[LOCAL+312+o]=v
19
+ target=POOL+m[args[12]+52]*STRIDE;client=m[target+520];poses=[]
20
+ def child(i,m,a,c):m,r=pose(i,m,a);poses.append(r);return m,c,0,r
21
+ m,_,pre=execute(ins,144767,144985,m,(0,0,0),LOCAL,{32254:child})
22
+ def zero(i,m,a,c):
23
+ assert a[8] in BUFFERS and a[12]==0 and a[16]==88
24
+ for o in range(0,88,4):m[a[8]+o]=0
25
+ return m,c,0,{'bounded_zero_fill':a,'original_native_executed':False}
26
+ m,_,transform=execute(ins,144985,146551,m,(0,0,0),LOCAL,{**TRIG,-101:zero})
27
+ return {'arguments':args,'target':target,'client':client,'pose':poses[0],'direction':vec(m,LOCAL+200),'generated_angles':[vec(m,LOCAL+o) for o in [52,64,76]],'origin':vec(m,target+24),'client_fields':{str(o):m[client+o]&0xffffffff for o in [6196,6204,6212,6248,6256,6264]},'buffers':[[m[p+o]&0xffffffff for o in range(0,88,4)] for p in BUFFERS],'prefix_execution':pre,'transform_execution':transform}
28
+
29
+ def main():
30
+ q,raw,h,ins=source();rows=[];table=constants(raw,h,list(range(20624,20700,4))+[21348,21352,21356])
31
+ for animation,velocity,angles,elapsed in itertools.product([22,23],[(0,0,0),(3,4,12),(-1,-2,0)],[(30,45,10),(-15,-359.5,90)],[0,16]):
32
+ m,a=fixture(raw,h);m.update(table);target=POOL+65*STRIDE;client=m[target+520];m[TRACE+52]=65;m[client+700]=0;m[client+6204]=animation;m[client+6256]=22;m[client+6196]=7;m[client+6212]=word(.5);m[client+6248]=8;m[client+6264]=word(.25)
33
+ for o,v in zip([4380,4384,4388,4392],[10,20,30,40]):m[client+o]=word(v)
34
+ shooter=m[a[8]+520];m[shooter]=200;m[shooter+6176]=200+elapsed
35
+ for p,values in [(target+24,(100,-50,25)),(target+36,velocity),(target+60,angles),(END,(3,4,0)),(END+256,(0,0,0))]:
36
+ for j,v in enumerate(values):m[p+4*j]=word(v)
37
+ for address,pointer in zip(TABLES,BUFFERS):m[address]=pointer
38
+ rows.append(model(ins,m,{8:a[8],12:TRACE,16:END+256,20:END,24:HIT}))
39
+ write_json(Path('docs/research/qvm-posed-model.json'),{'source':q['source'],'sha256':q['sha256'],'probes':rows,'limits':'Actual144767–146550 with complete32254 and finite supplied native math/zero fill. Target pointers, model table and timing inputs are fixtures. Stops before25341; no intersection/native parity.'})
40
+ if __name__=='__main__':main()
scripts/test_qvm_posed_model.py ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json,unittest
2
+ from pathlib import Path
3
+ from test_qvm_complete_pose import expected
4
+ from test_qvm_server_fire_basis import vectors
5
+ from test_qvm_ground import word,n,f
6
+ class PosedModelTests(unittest.TestCase):
7
+ @classmethod
8
+ def setUpClass(cls):cls.rows=json.loads(Path('docs/research/qvm-posed-model.json').read_text())['probes']
9
+ def test_actual_pose_outputs_and_external_state_oracle(self):
10
+ self.assertEqual(len(self.rows),24)
11
+ for p in self.rows:
12
+ state,output,flag=expected(p['pose']);self.assertEqual(p['pose']['final_state'],state);self.assertEqual(p['generated_angles'],output);self.assertEqual(p['pose']['flag'],flag)
13
+ def test_independent_all_transform_words_from_generated_pose(self):
14
+ for p in self.rows:
15
+ rows=[]
16
+ for j,a in enumerate(p['generated_angles']+[p['generated_angles'][2]]):
17
+ fw,right,up=vectors(a);r=[0]*22;r[3:6]=fw;r[7:10]=[word(f(0-n(x))) for x in right];r[11:14]=up;r[18]=word(1)
18
+ if j==0:r[:3]=[p['client_fields'][str(o)] for o in [6196,6204,6212]];r[19:22]=p['origin']
19
+ if j==1:r[:3]=[p['client_fields'][str(o)] for o in [6248,6256,6264]]
20
+ rows.append(r)
21
+ self.assertEqual(p['buffers'],rows)
22
+ def test_actual_target_pointer_and_elapsed_abi(self):
23
+ for p in self.rows:
24
+ a=p['pose']['arguments'];self.assertEqual([a[str(o)] for o in [8,12,32,36,40,44]],[p['target']+60,p['target']+36]+[p['client']+o for o in [4380,4384,4388,4392]]);self.assertIn(a['24'],[0,16]);self.assertEqual(p['direction'],[word(f(3*f(1/5))),word(f(4*f(1/5))),0])
25
+ def test_intersection_still_unexecuted(self):
26
+ for p in self.rows:self.assertEqual([c['target'] for c in p['prefix_execution']['calls']],[-107,32254]);self.assertEqual(len(p['transform_execution']['calls']),22)
27
+ if __name__=='__main__':unittest.main()