qvm: water entry routing
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_WATER_ROUTE.md +7 -0
- docs/research/README.md +3 -0
- docs/research/qvm-water-route.json +0 -0
- scripts/analyze_qvm_water_route.py +33 -0
- scripts/qvm_research_support.py +6 -4
- scripts/test_qvm_water_route.py +38 -0
docs/ASSET_PIPELINE_TODO.md
CHANGED
|
@@ -355,3 +355,6 @@ Research progress: RE-552 [report](research/QVM_WALL_ACTION.md); remaining nativ
|
|
| 355 |
|
| 356 |
|
| 357 |
Research progress: RE-553 [report](research/QVM_WATER_ENTRY.md); remaining native/content/runtime/platform scope stays open.
|
|
|
|
|
|
|
|
|
|
|
|
| 355 |
|
| 356 |
|
| 357 |
Research progress: RE-553 [report](research/QVM_WATER_ENTRY.md); remaining native/content/runtime/platform scope stays open.
|
| 358 |
+
|
| 359 |
+
|
| 360 |
+
Research progress: RE-554 [report](research/QVM_WATER_ROUTE.md); remaining native/content/runtime/platform scope stays open.
|
docs/FINDINGS.md
CHANGED
|
@@ -713,3 +713,6 @@ Bounded qagame paths recover bomb-plant/inactivity correction requests, direct f
|
|
| 713 |
|
| 714 |
|
| 715 |
**RE-553 — Recover41486 water-entry queries and launch state:** With timer0 and level2,41486 probes30 units along normalized planar basis at Z+4 then+20; first contents must contain bit1 and second must equal0. Success uses raw basis times200 for XY, forces Z350, sets128 and timer2000. [Evidence](research/QVM_WATER_ENTRY.md).
|
|
|
|
|
|
|
|
|
|
|
|
| 713 |
|
| 714 |
|
| 715 |
**RE-553 — Recover41486 water-entry queries and launch state:** With timer0 and level2,41486 probes30 units along normalized planar basis at Z+4 then+20; first contents must contain bit1 and second must equal0. Success uses raw basis times200 for XY, forces Z350, sets128 and timer2000. [Evidence](research/QVM_WATER_ENTRY.md).
|
| 716 |
+
|
| 717 |
+
|
| 718 |
+
**RE-554 — Connect41848 entry guard to actual41768 fallback:** Actual41486 return determines whether41848 enters ordinary swimming at41862 or executes41768 with the newly written velocity,128 flag and2000 movement timer before its gravity tail. [Evidence](research/QVM_WATER_ROUTE.md).
|
docs/PROVISIONAL_TODO.md
CHANGED
|
@@ -667,3 +667,6 @@ Research progress: RE-552 [report](research/QVM_WALL_ACTION.md); remaining nativ
|
|
| 667 |
|
| 668 |
|
| 669 |
Research progress: RE-553 [report](research/QVM_WATER_ENTRY.md); remaining native/content/runtime/platform scope stays open.
|
|
|
|
|
|
|
|
|
|
|
|
| 667 |
|
| 668 |
|
| 669 |
Research progress: RE-553 [report](research/QVM_WATER_ENTRY.md); remaining native/content/runtime/platform scope stays open.
|
| 670 |
+
|
| 671 |
+
|
| 672 |
+
Research progress: RE-554 [report](research/QVM_WATER_ROUTE.md); remaining native/content/runtime/platform scope stays open.
|
docs/RESEARCH_LEDGER.md
CHANGED
|
@@ -467,3 +467,8 @@ Successful40966 is followed by counter increment, a second resource check after
|
|
| 467 |
## 2026-10-19 — RE-553 Recover41486 water-entry queries and launch state (separate task commit)
|
| 468 |
|
| 469 |
With timer0 and level2,41486 probes30 units along normalized planar basis at Z+4 then+20; first contents must contain bit1 and second must equal0. Success uses raw basis times200 for XY, forces Z350, sets128 and timer2000. 36 timer/level/contents/basis cases and four independent tests validate exact state, query short circuit, normalized geometry versus raw launch basis and absence of event/resource cost. Full suite: 739 tests pass. Report regenerates byte-identically (108378 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 467 |
## 2026-10-19 — RE-553 Recover41486 water-entry queries and launch state (separate task commit)
|
| 468 |
|
| 469 |
With timer0 and level2,41486 probes30 units along normalized planar basis at Z+4 then+20; first contents must contain bit1 and second must equal0. Success uses raw basis times200 for XY, forces Z350, sets128 and timer2000. 36 timer/level/contents/basis cases and four independent tests validate exact state, query short circuit, normalized geometry versus raw launch basis and absence of event/resource cost. Full suite: 739 tests pass. Report regenerates byte-identically (108378 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
|
| 470 |
+
|
| 471 |
+
|
| 472 |
+
## 2026-10-19 — RE-554 Connect41848 entry guard to actual41768 fallback (separate task commit)
|
| 473 |
+
|
| 474 |
+
Actual41486 return determines whether41848 enters ordinary swimming at41862 or executes41768 with the newly written velocity,128 flag and2000 movement timer before its gravity tail. 36 gate/fraction/contact controls and four independent tests validate helper routing, live launch state, both slide/step branches, wrapper fallback and exact41768 tail outputs. Full suite: 743 tests pass. Report regenerates byte-identically (431168 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
|
@@ -704,3 +704,6 @@ Purpose: turn the supplied installation into an evidence-backed specification of
|
|
| 704 |
|
| 705 |
|
| 706 |
- [x] RE-553 Recover41486 water-entry queries and launch state ([report](research/QVM_WATER_ENTRY.md)).
|
|
|
|
|
|
|
|
|
|
|
|
| 704 |
|
| 705 |
|
| 706 |
- [x] RE-553 Recover41486 water-entry queries and launch state ([report](research/QVM_WATER_ENTRY.md)).
|
| 707 |
+
|
| 708 |
+
|
| 709 |
+
- [x] RE-554 Connect41848 entry guard to actual41768 fallback ([report](research/QVM_WATER_ROUTE.md)).
|
docs/research/QVM_WATER_ROUTE.md
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Connect41848 entry guard to actual41768 fallback
|
| 2 |
+
|
| 3 |
+
RE-554. Reproduce with `python3 scripts/analyze_qvm_water_route.py`; check with `python3 scripts/test_qvm_water_route.py`. The [machine report](qvm-water-route.json) retains source identity and bounded fixtures.
|
| 4 |
+
|
| 5 |
+
The caller stores41486's actual result at local60 before reading it. Failure does not attach any prepared fallback and stops before ordinary swimming friction. Success executes the recovered41768 prefix, gravity-on60091 wrapper, reached slide/step children and mode gravity tail in the same memory. This preserves actual2000 timer/flag/velocity rather than copying isolated scalar outputs. Roots, contents and collision records are supplied; ordinary swimming, main integration and legal native/platform domains remain open for the following task.
|
| 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
|
@@ -268,3 +268,6 @@ The extension collector adds five focused tests for native tail calls, command-r
|
|
| 268 |
|
| 269 |
|
| 270 |
[RE-553: Recover41486 water-entry queries and launch state](QVM_WATER_ENTRY.md). Reproduce with `python3 scripts/analyze_qvm_water_entry.py`; check with `python3 scripts/test_qvm_water_entry.py`.
|
|
|
|
|
|
|
|
|
|
|
|
| 268 |
|
| 269 |
|
| 270 |
[RE-553: Recover41486 water-entry queries and launch state](QVM_WATER_ENTRY.md). Reproduce with `python3 scripts/analyze_qvm_water_entry.py`; check with `python3 scripts/test_qvm_water_entry.py`.
|
| 271 |
+
|
| 272 |
+
|
| 273 |
+
[RE-554: Connect41848 entry guard to actual41768 fallback](QVM_WATER_ROUTE.md). Reproduce with `python3 scripts/analyze_qvm_water_route.py`; check with `python3 scripts/test_qvm_water_route.py`.
|
docs/research/qvm-water-route.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
scripts/analyze_qvm_water_route.py
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""41848 water-entry guard and actual41768 fallback."""
|
| 3 |
+
import itertools
|
| 4 |
+
from pathlib import Path
|
| 5 |
+
from qvm_research_support import source,memory,execute
|
| 6 |
+
from analyze_qvm_acceleration import PS,FRAME
|
| 7 |
+
from analyze_qvm_water_entry import water_entry
|
| 8 |
+
from analyze_qvm_contact_callers import composition
|
| 9 |
+
from analyze_qvm_jump_entry import snapshot
|
| 10 |
+
from analyze_qvm import write_json
|
| 11 |
+
|
| 12 |
+
LOCAL=0x68000000
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
def route(ins,m,cmd=(100,0,0),samples=(1,0),pattern='clear'):
|
| 16 |
+
initial=snapshot(m);entry=None;fallback=None;dt=m[35023928]&0xffffffff
|
| 17 |
+
def jump(i,m,a,c):
|
| 18 |
+
nonlocal entry
|
| 19 |
+
m,entry=water_entry(i,m,c,samples);return m,c,entry['return_word'],entry
|
| 20 |
+
def mode(i,m,a,c):
|
| 21 |
+
nonlocal fallback
|
| 22 |
+
m,fallback=composition(i,pattern,m[PS+16],'clear','clear',initial_memory=m,return_memory=True);return m,c,0,{'selected':41768}
|
| 23 |
+
m,cmd,r=execute(ins,41849,42484,m,cmd,LOCAL,{41486:jump,41768:mode},boundaries=[41862]);return m,{'initial':initial,'entry':entry,'fallback':fallback,'dt':dt,'normal':[m[35023968+4*i]&0xffffffff for i in range(3)],'execution':r,'final':snapshot(m)}
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
def main():
|
| 27 |
+
q,raw,h,ins=source();rows=[]
|
| 28 |
+
for timer,level,samples,pattern in itertools.product([0,1],[1,2,3],[(0,0),(1,0),(1,8)],['clear','contacts']):
|
| 29 |
+
m=memory(raw,h);m.update({PS+16:timer,FRAME+212:level,FRAME+228:-26});rows.append(route(ins,m,samples=samples,pattern=pattern)[1])
|
| 30 |
+
write_json(Path('docs/research/qvm-water-route.json'),{'source':q['source'],'sha256':q['sha256'],'probes':rows,'limits':'Actual41848 prefix/41486/41768 fallback; ordinary swim starts at41862 and is omitted here. Native contents/roots/contact records supplied. No original executable/full QVM/native physics/rendering executes; full main/legal/platform scope remains open.'})
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
if __name__=='__main__':main()
|
scripts/qvm_research_support.py
CHANGED
|
@@ -19,13 +19,13 @@ def memory(raw,h,cmd=(100,0,0),plane=1,flags=0):
|
|
| 19 |
m[0x30000+24]=sum((v&255)<<(8*(i+1)) for i,v in enumerate(cmd));return m
|
| 20 |
|
| 21 |
|
| 22 |
-
def execute(ins,start,stop,m,cmd,base,handlers=None,result_offsets=None):
|
| 23 |
"""Bounded source calls with actual recovered children at empty-stack boundaries."""
|
| 24 |
import math
|
| 25 |
from analyze_deferred_auth import trace_slice
|
| 26 |
from analyze_bsp_references import trace_fields
|
| 27 |
from analyze_qvm_acceleration import FRAME,word,number
|
| 28 |
-
handlers=handlers or {};result_offsets=result_offsets or {};points=[x['index']+2 for x in ins[start:stop] if x['opcode']=='CALL'];pc=start;trace=[];calls=[];children=[];writes=[];ret=None
|
| 29 |
for _ in range(256):
|
| 30 |
t=trace_slice(ins,start,stop,m,{},resume_at=pc,stop_targets=[p for p in points if p!=pc],byte_memory={FRAME+25+i:v&255 for i,v in enumerate(cmd)},local_base=base,halt_on_leave=True,capture_stack=True,limit=8192);m=t['memory'];pc=t['stop'];trace+=t['trace'];calls+=t['calls'];writes+=t['byte_writes'];cmd=[t['byte_memory'][FRAME+25+i] for i in range(3)]
|
| 31 |
for c in t['calls']:
|
|
@@ -39,6 +39,8 @@ def execute(ins,start,stop,m,cmd,base,handlers=None,result_offsets=None):
|
|
| 39 |
m[base+offset]=value
|
| 40 |
children.append({'call':c,'effect':r})
|
| 41 |
if t['trace'] and ins[t['trace'][-1]]['opcode']=='LEAVE':ret=t['stack'][-1];break
|
| 42 |
-
if pc==stop:break
|
| 43 |
else:raise ValueError('Bounded child loop exceeded')
|
| 44 |
-
|
|
|
|
|
|
|
|
|
| 19 |
m[0x30000+24]=sum((v&255)<<(8*(i+1)) for i,v in enumerate(cmd));return m
|
| 20 |
|
| 21 |
|
| 22 |
+
def execute(ins,start,stop,m,cmd,base,handlers=None,result_offsets=None,boundaries=()):
|
| 23 |
"""Bounded source calls with actual recovered children at empty-stack boundaries."""
|
| 24 |
import math
|
| 25 |
from analyze_deferred_auth import trace_slice
|
| 26 |
from analyze_bsp_references import trace_fields
|
| 27 |
from analyze_qvm_acceleration import FRAME,word,number
|
| 28 |
+
handlers=handlers or {};result_offsets=result_offsets or {};points=[x['index']+2 for x in ins[start:stop] if x['opcode']=='CALL']+list(boundaries);pc=start;trace=[];calls=[];children=[];writes=[];ret=None
|
| 29 |
for _ in range(256):
|
| 30 |
t=trace_slice(ins,start,stop,m,{},resume_at=pc,stop_targets=[p for p in points if p!=pc],byte_memory={FRAME+25+i:v&255 for i,v in enumerate(cmd)},local_base=base,halt_on_leave=True,capture_stack=True,limit=8192);m=t['memory'];pc=t['stop'];trace+=t['trace'];calls+=t['calls'];writes+=t['byte_writes'];cmd=[t['byte_memory'][FRAME+25+i] for i in range(3)]
|
| 31 |
for c in t['calls']:
|
|
|
|
| 39 |
m[base+offset]=value
|
| 40 |
children.append({'call':c,'effect':r})
|
| 41 |
if t['trace'] and ins[t['trace'][-1]]['opcode']=='LEAVE':ret=t['stack'][-1];break
|
| 42 |
+
if pc==stop or pc in boundaries:break
|
| 43 |
else:raise ValueError('Bounded child loop exceeded')
|
| 44 |
+
report={'return':ret,'calls':calls,'children':children,'byte_writes':writes,**trace_fields({'trace':trace},False)}
|
| 45 |
+
if boundaries:report['stop']=pc
|
| 46 |
+
return m,cmd,report
|
scripts/test_qvm_water_route.py
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import copy,json,unittest
|
| 2 |
+
from pathlib import Path
|
| 3 |
+
from test_qvm_ground import n,f,word
|
| 4 |
+
from test_qvm_slide_repeated import oracle as slide_oracle
|
| 5 |
+
from test_qvm_contact_callers import expected_step
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
def check_wrapper(test,w,normal):
|
| 9 |
+
first=w['first_slide'];slide_oracle(test,first,{**w['before'],'ground_normal':normal});s=w['step']
|
| 10 |
+
if s:
|
| 11 |
+
slide_oracle(test,s['slide'],{**s['at_slide'],'ground_normal':normal});ret,origin,v,flags=expected_step(s);test.assertEqual([s['return_word'],s['final']['origin'],s['final']['velocity'],s['final']['flags']],[ret,origin,v,flags])
|
| 12 |
+
if not ret:origin=first['final']['origin'];v=first['final']['velocity'];flags|=32
|
| 13 |
+
delta=f(n(origin[2])-n(w['before']['origin'][2]));height=int(delta) if delta>2 else w['before']['height']
|
| 14 |
+
else:origin,v,flags,height=first['final']['origin'],first['final']['velocity'],first['final']['flags'],w['before']['height']
|
| 15 |
+
test.assertEqual([w['final']['origin'],w['final']['velocity'],w['final']['flags'],w['final']['height']],[origin,v,flags,height])
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
class WaterRouteTests(unittest.TestCase):
|
| 19 |
+
@classmethod
|
| 20 |
+
def setUpClass(cls):cls.r=json.loads(Path('docs/research/qvm-water-route.json').read_text())
|
| 21 |
+
def test_all36_route_gates_and_entry_state(self):
|
| 22 |
+
self.assertEqual(len(self.r['probes']),36)
|
| 23 |
+
for p in self.r['probes']:
|
| 24 |
+
e=p['entry'];success=not e['initial']['timer'] and e['level']==2 and e['samples'][0]&1 and e['samples'][1]==0;self.assertEqual(p['fallback'] is not None,bool(success));self.assertEqual(p['execution']['stop'],42484 if success else 41862)
|
| 25 |
+
if not success:self.assertEqual(p['final'],p['initial'])
|
| 26 |
+
def test_fallback_receives_actual2000_timer_and_velocity(self):
|
| 27 |
+
for p in self.r['probes']:
|
| 28 |
+
if p['fallback']:self.assertEqual(p['fallback']['initial']['timer'],2000);self.assertEqual(p['fallback']['initial']['velocity'],p['entry']['final']['velocity']);self.assertTrue(p['fallback']['initial']['flags']&128)
|
| 29 |
+
def test_actual_wrapper_children_and_second_gravity_tail(self):
|
| 30 |
+
for p in self.r['probes']:
|
| 31 |
+
mode=p['fallback']
|
| 32 |
+
if mode:
|
| 33 |
+
check_wrapper(self,mode['wrapper'],p['normal']);s=copy.deepcopy(mode['wrapper']['final']);z=f(n(s['velocity'][2])-f(800*n(p['dt'])));s['velocity'][2]=word(z)
|
| 34 |
+
if z<0:s['flags']&=~192;s['timer']=0
|
| 35 |
+
self.assertEqual(mode['mode_final'],s)
|
| 36 |
+
for k,v in s.items():self.assertEqual(p['final'][k],v)
|
| 37 |
+
def test_call_order_no_prepared_fallback_on_failure(self):
|
| 38 |
+
for p in self.r['probes']:self.assertEqual([c['target'] for c in p['execution']['calls']],[41486,41768] if p['fallback'] else [41486])
|