qvm: complete rewind and restore chain
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_COMPLETE_REWIND.md +7 -0
- docs/research/README.md +3 -0
- docs/research/qvm-complete-rewind.json +0 -0
- scripts/analyze_qvm_complete_rewind.py +31 -0
- scripts/test_qvm_complete_rewind.py +27 -0
docs/ASSET_PIPELINE_TODO.md
CHANGED
|
@@ -601,3 +601,6 @@ Research progress: RE-639 [report](research/QVM_HISTORY_ANGLE_LERP.md); remainin
|
|
| 601 |
|
| 602 |
|
| 603 |
Research progress: RE-640 [report](research/QVM_REWIND_HISTORY_APPLY.md); remaining native/content/runtime/platform scope stays open.
|
|
|
|
|
|
|
|
|
|
|
|
| 601 |
|
| 602 |
|
| 603 |
Research progress: RE-640 [report](research/QVM_REWIND_HISTORY_APPLY.md); remaining native/content/runtime/platform scope stays open.
|
| 604 |
+
|
| 605 |
+
|
| 606 |
+
Research progress: RE-641 [report](research/QVM_COMPLETE_REWIND.md); remaining native/content/runtime/platform scope stays open.
|
docs/FINDINGS.md
CHANGED
|
@@ -950,3 +950,6 @@ Bounded qagame paths recover bomb-plant/inactivity correction requests, direct f
|
|
| 950 |
|
| 951 |
|
| 952 |
**RE-640 — History application vector angle and discrete state map:** 143100 blends velocity/position and angles but copies animations and six client fields directly from the lower selected history row. [Evidence](research/QVM_REWIND_HISTORY_APPLY.md).
|
|
|
|
|
|
|
|
|
|
|
|
| 950 |
|
| 951 |
|
| 952 |
**RE-640 — History application vector angle and discrete state map:** 143100 blends velocity/position and angles but copies animations and six client fields directly from the lower selected history row. [Evidence](research/QVM_REWIND_HISTORY_APPLY.md).
|
| 953 |
+
|
| 954 |
+
|
| 955 |
+
**RE-641 — Complete bounded rewind and snapshot restoration round trip:** Whole143100 now executes snapshot, history selection, actual interpolation and link request; recovered144165 restores original live fields with animation byte truncation. [Evidence](research/QVM_COMPLETE_REWIND.md).
|
docs/PROVISIONAL_TODO.md
CHANGED
|
@@ -921,3 +921,6 @@ Research progress: RE-639 [report](research/QVM_HISTORY_ANGLE_LERP.md); remainin
|
|
| 921 |
|
| 922 |
|
| 923 |
Research progress: RE-640 [report](research/QVM_REWIND_HISTORY_APPLY.md); remaining native/content/runtime/platform scope stays open.
|
|
|
|
|
|
|
|
|
|
|
|
| 921 |
|
| 922 |
|
| 923 |
Research progress: RE-640 [report](research/QVM_REWIND_HISTORY_APPLY.md); remaining native/content/runtime/platform scope stays open.
|
| 924 |
+
|
| 925 |
+
|
| 926 |
+
Research progress: RE-641 [report](research/QVM_COMPLETE_REWIND.md); remaining native/content/runtime/platform scope stays open.
|
docs/RESEARCH_LEDGER.md
CHANGED
|
@@ -872,3 +872,8 @@ Whole291641 now follows supplied world/entity traces through retry, ordered reli
|
|
| 872 |
## 2026-10-20 — RE-640 History application vector angle and discrete state map (separate task commit)
|
| 873 |
|
| 874 |
143100 blends velocity/position and angles but copies animations and six client fields directly from the lower selected history row. 12 ordinary/equal-time/extrapolation cases independently reconstruct every entity/client word and actual helper/native request order. Full suite: 1035 tests pass. Report regenerates byte-identically (265042 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 872 |
## 2026-10-20 — RE-640 History application vector angle and discrete state map (separate task commit)
|
| 873 |
|
| 874 |
143100 blends velocity/position and angles but copies animations and six client fields directly from the lower selected history row. 12 ordinary/equal-time/extrapolation cases independently reconstruct every entity/client word and actual helper/native request order. Full suite: 1035 tests pass. Report regenerates byte-identically (265042 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
|
| 875 |
+
|
| 876 |
+
|
| 877 |
+
## 2026-10-20 — RE-641 Complete bounded rewind and snapshot restoration round trip (separate task commit)
|
| 878 |
+
|
| 879 |
+
Whole143100 now executes snapshot, history selection, actual interpolation and link request; recovered144165 restores original live fields with animation byte truncation. Nine complete/null-client cases match a combined independent snapshot/selection/application oracle and full entity restoration. Full suite: 1039 tests pass. Report regenerates byte-identically (520463 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
|
@@ -964,3 +964,6 @@ Purpose: turn the supplied installation into an evidence-backed specification of
|
|
| 964 |
|
| 965 |
|
| 966 |
- [x] RE-640 History application vector angle and discrete state map ([report](research/QVM_REWIND_HISTORY_APPLY.md)).
|
|
|
|
|
|
|
|
|
|
|
|
| 964 |
|
| 965 |
|
| 966 |
- [x] RE-640 History application vector angle and discrete state map ([report](research/QVM_REWIND_HISTORY_APPLY.md)).
|
| 967 |
+
|
| 968 |
+
|
| 969 |
+
- [x] RE-641 Complete bounded rewind and snapshot restoration round trip ([report](research/QVM_COMPLETE_REWIND.md)).
|
docs/research/QVM_COMPLETE_REWIND.md
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Complete bounded rewind and snapshot restoration round trip
|
| 2 |
+
|
| 3 |
+
RE-641. Reproduce with `python3 scripts/analyze_qvm_complete_rewind.py`; check with `python3 scripts/test_qvm_complete_rewind.py`. The [machine report](qvm-complete-rewind.json) retains source identity and bounded fixtures.
|
| 4 |
+
|
| 5 |
+
The bounded driver interprets143101–144079 as one source range with recovered vector/angle children and captured native−31. It retains source snapshot byte writes and merges them into packed word memory before later restoration. Independent pure oracles combine the complete snapshot map, timestamp scan, f32 interpolation and discrete field map for all ordinary records. Actual144165 then restores all original entity words except expected animation high-bit loss, and restores the selected live client fields. Null client exits without history reads or native requests. Supplied histories include equal timestamps, old-target fallback and extrapolation; their live legality/history producer and native engine effects remain unverified.
|
| 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
|
@@ -522,3 +522,6 @@ The extension collector adds five focused tests for native tail calls, command-r
|
|
| 522 |
|
| 523 |
|
| 524 |
[RE-640: History application vector angle and discrete state map](QVM_REWIND_HISTORY_APPLY.md). Reproduce with `python3 scripts/analyze_qvm_rewind_history_apply.py`; check with `python3 scripts/test_qvm_rewind_history_apply.py`.
|
|
|
|
|
|
|
|
|
|
|
|
| 522 |
|
| 523 |
|
| 524 |
[RE-640: History application vector angle and discrete state map](QVM_REWIND_HISTORY_APPLY.md). Reproduce with `python3 scripts/analyze_qvm_rewind_history_apply.py`; check with `python3 scripts/test_qvm_rewind_history_apply.py`.
|
| 525 |
+
|
| 526 |
+
|
| 527 |
+
[RE-641: Complete bounded rewind and snapshot restoration round trip](QVM_COMPLETE_REWIND.md). Reproduce with `python3 scripts/analyze_qvm_complete_rewind.py`; check with `python3 scripts/test_qvm_complete_rewind.py`.
|
docs/research/qvm-complete-rewind.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
scripts/analyze_qvm_complete_rewind.py
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""Whole143100 snapshot→history→interpolation with actual recovered children."""
|
| 3 |
+
from pathlib import Path
|
| 4 |
+
from qvm_research_support import source
|
| 5 |
+
from qvm_trace_support import resume,captured
|
| 6 |
+
from analyze_qvm_rewind_snapshot import LOCAL,client_state
|
| 7 |
+
from analyze_qvm_rewind_history_select import history_fixture
|
| 8 |
+
from analyze_qvm_history_vector_lerp import interpolate
|
| 9 |
+
from analyze_qvm_history_angle_lerp import angle
|
| 10 |
+
from analyze_qvm_rewind_restore import restore_player
|
| 11 |
+
from analyze_qvm_temp_event import record
|
| 12 |
+
from qvm_server_fire_support import ENTITY
|
| 13 |
+
from analyze_qvm import write_json
|
| 14 |
+
|
| 15 |
+
def rewind(ins,m,pointer,time):
|
| 16 |
+
m=dict(m);client=m[pointer+520];before=record(m,pointer);before_client=client_state(m,client) if client else None;rows={str(j):{str(o):m[client+4492+80*j+o]&0xffffffff for o in range(0,80,4)} for j in range(20)} if client else {};m[LOCAL+172]=pointer;m[LOCAL+176]=time;requests=[]
|
| 17 |
+
def vector(i,m,a):m,e=interpolate(i,m,a);return m,0,e
|
| 18 |
+
def angles(i,m,a):m,e=angle(i,m,a);return m,e['result'],e
|
| 19 |
+
bytes_map={client+4492+80*j+36+k:(m[client+4492+80*j+36]>>(8*k))&255 for j in range(20) for k in range(2)} if client else {}
|
| 20 |
+
m,e=resume(ins,143101,144080,m,LOCAL,handlers={143031:vector,63746:angles,-31:captured(-31,requests)},byte_inputs=bytes_map)
|
| 21 |
+
for w in e['byte_writes']:
|
| 22 |
+
a=w['address']&~3;shift=(w['address']&3)*8;m[a]=(m[a]&~(255<<shift))|(w['value']<<shift)
|
| 23 |
+
return m,{'pointer':pointer,'client':client,'time':time,'history':rows,'initial_entity':before,'initial_client':before_client,'final_entity':record(m,pointer),'final_client':client_state(m,client) if client else None,'lower_index':m.get(LOCAL+28),'upper_index':m.get(LOCAL+32),'fraction':m[LOCAL+36]&0xffffffff if client else None,'requests':requests,'execution':e,'status':'void-epilogue'}
|
| 24 |
+
|
| 25 |
+
def main():
|
| 26 |
+
q,raw,h,ins=source();rows=[]
|
| 27 |
+
for times,time in [([2000-50*j for j in range(20)],t) for t in [-100,1050,1475,1950,2000,3000]]+[([1500]*20,t) for t in [1450,1500]]:
|
| 28 |
+
m=history_fixture(raw,h,times);m,r=rewind(ins,m,ENTITY,time);_,restore=restore_player(ins,m,ENTITY);r['restore']=restore;rows.append(r)
|
| 29 |
+
m=history_fixture(raw,h,[1500]*20);m[ENTITY+520]=0;rows.append(rewind(ins,m,ENTITY,1500)[1])
|
| 30 |
+
write_json(Path('docs/research/qvm-complete-rewind.json'),{'source':q['source'],'sha256':q['sha256'],'probes':rows,'limits':'Complete143101–144079 with actual interpolation and captured native link, followed by actual144165 restore where client exists. Supplied finite histories/time values; no original history producer/native linking/collision/legal input domain parity.'})
|
| 31 |
+
if __name__=='__main__':main()
|
scripts/test_qvm_complete_rewind.py
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import json,unittest
|
| 2 |
+
from pathlib import Path
|
| 3 |
+
from test_qvm_rewind_history_select import expected as select_expected
|
| 4 |
+
from test_qvm_rewind_history_apply import expected as apply_expected
|
| 5 |
+
|
| 6 |
+
def expected(p):
|
| 7 |
+
entity=p['initial_entity'];client=dict(p['initial_client']);client['4408']=1
|
| 8 |
+
for dst,src in [(4412,488),(4424,24),(4436,60),(4452,36)]:
|
| 9 |
+
for j in range(3):client[str(dst+4*j)]=entity[str(src+4*j)]
|
| 10 |
+
for dst,src in [(4468,4380),(4464,4384),(4476,4388),(4472,4392),(4484,6204),(4488,6256)]:client[str(dst)]=p['initial_client'][str(src)]
|
| 11 |
+
client['4448']=(client['4448']&0xffff0000)|(entity['200']&255)|((entity['196']&255)<<8);times=[p['history'][str(j)]['68'] for j in range(20)];low,high,fraction,_=select_expected(times,p['time']);fake={**p,'initial_client':client,'selected_rows':p['history']};return apply_expected(fake),(low,high,fraction)
|
| 12 |
+
|
| 13 |
+
class CompleteRewindTests(unittest.TestCase):
|
| 14 |
+
@classmethod
|
| 15 |
+
def setUpClass(cls):cls.r=json.loads(Path('docs/research/qvm-complete-rewind.json').read_text())
|
| 16 |
+
def test_independent_full_snapshot_selection_application(self):
|
| 17 |
+
for p in self.r['probes'][:-1]:
|
| 18 |
+
state,selection=expected(p);self.assertEqual((p['final_entity'],p['final_client']),state);self.assertEqual((p['lower_index'],p['upper_index'],p['fraction']),selection)
|
| 19 |
+
def test_actual_restore_round_trip(self):
|
| 20 |
+
for p in self.r['probes'][:-1]:
|
| 21 |
+
expected=dict(p['initial_entity']);expected['200']&=255;expected['196']&=255;self.assertEqual(p['restore']['final_entity'],expected)
|
| 22 |
+
for o in [4380,4384,4388,4392,6204,6256]:self.assertEqual(p['restore']['final_client'][str(o)],p['initial_client'][str(o)])
|
| 23 |
+
def test_no_unknown_child_or_native_effect(self):
|
| 24 |
+
for p in self.r['probes'][:-1]:self.assertEqual([c['target'] for c in p['execution']['calls']],[143031,143031,63746,63746,63746,-31]);self.assertEqual(p['final_client']['4408'],1);self.assertEqual(p['restore']['final_client']['4408'],0)
|
| 25 |
+
def test_null_client_exits_without_history(self):
|
| 26 |
+
p=self.r['probes'][-1];self.assertEqual(p['initial_entity'],p['final_entity']);self.assertEqual(p['execution']['calls'],[]);self.assertEqual(p['history'],{})
|
| 27 |
+
if __name__=='__main__':unittest.main()
|