qvm: complete original model contacts
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_CONTACT_COMPLETE.md +7 -0
- docs/research/README.md +3 -0
- docs/research/qvm-contact-complete.json +0 -0
- scripts/analyze_qvm_contact_complete.py +24 -0
- scripts/test_qvm_contact_complete.py +62 -0
docs/ASSET_PIPELINE_TODO.md
CHANGED
|
@@ -826,3 +826,6 @@ Research progress: RE-719 [report](research/QVM_CONTACT_FEEDBACK.md); remaining
|
|
| 826 |
|
| 827 |
|
| 828 |
Research progress: RE-720 [report](research/QVM_CONTACT_IMPACT.md); remaining native/content/runtime/platform scope stays open.
|
|
|
|
|
|
|
|
|
|
|
|
| 826 |
|
| 827 |
|
| 828 |
Research progress: RE-720 [report](research/QVM_CONTACT_IMPACT.md); remaining native/content/runtime/platform scope stays open.
|
| 829 |
+
|
| 830 |
+
|
| 831 |
+
Research progress: RE-721 [report](research/QVM_CONTACT_COMPLETE.md); remaining native/content/runtime/platform scope stays open.
|
docs/FINDINGS.md
CHANGED
|
@@ -1172,3 +1172,6 @@ RE-703–712 batch complete: [damage factor and contact dispatch](research/QVM_D
|
|
| 1172 |
|
| 1173 |
|
| 1174 |
**RE-720 — Complete impact-only contact branch:** Impact-only contacts return0 and emit event109 for weapon30 or63 otherwise only with nonzero flag and clear trace surface bit32; weapon27 copies exact muzzle. [Evidence](research/QVM_CONTACT_IMPACT.md).
|
|
|
|
|
|
|
|
|
|
|
|
| 1172 |
|
| 1173 |
|
| 1174 |
**RE-720 — Complete impact-only contact branch:** Impact-only contacts return0 and emit event109 for weapon30 or63 otherwise only with nonzero flag and clear trace surface bit32; weapon27 copies exact muzzle. [Evidence](research/QVM_CONTACT_IMPACT.md).
|
| 1175 |
+
|
| 1176 |
+
|
| 1177 |
+
**RE-721 — Complete contact on original-model contexts:** Complete292545 now composes eligibility, ordinary/special factors, event/impact branches, actual feedback, direction basis, health request and return using original-model contexts. [Evidence](research/QVM_CONTACT_COMPLETE.md).
|
docs/PROVISIONAL_TODO.md
CHANGED
|
@@ -1161,3 +1161,6 @@ Research progress: RE-719 [report](research/QVM_CONTACT_FEEDBACK.md); remaining
|
|
| 1161 |
|
| 1162 |
|
| 1163 |
Research progress: RE-720 [report](research/QVM_CONTACT_IMPACT.md); remaining native/content/runtime/platform scope stays open.
|
|
|
|
|
|
|
|
|
|
|
|
| 1161 |
|
| 1162 |
|
| 1163 |
Research progress: RE-720 [report](research/QVM_CONTACT_IMPACT.md); remaining native/content/runtime/platform scope stays open.
|
| 1164 |
+
|
| 1165 |
+
|
| 1166 |
+
Research progress: RE-721 [report](research/QVM_CONTACT_COMPLETE.md); remaining native/content/runtime/platform scope stays open.
|
docs/RESEARCH_LEDGER.md
CHANGED
|
@@ -1240,3 +1240,8 @@ Contact event104 receives truncated global forward×500 or exact muzzle for weap
|
|
| 1240 |
## 2026-10-21 — RE-720 Complete impact-only contact branch (separate task commit)
|
| 1241 |
|
| 1242 |
Impact-only contacts return0 and emit event109 for weapon30 or63 otherwise only with nonzero flag and clear trace surface bit32; weapon27 copies exact muzzle. 48 weapon/flag/surface/normal combinations check every event word, actual child order, early suppression and numeric return. Full suite: 1328 tests pass. Report regenerates byte-identically (490508 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1240 |
## 2026-10-21 — RE-720 Complete impact-only contact branch (separate task commit)
|
| 1241 |
|
| 1242 |
Impact-only contacts return0 and emit event109 for weapon30 or63 otherwise only with nonzero flag and clear trace surface bit32; weapon27 copies exact muzzle. 48 weapon/flag/surface/normal combinations check every event word, actual child order, early suppression and numeric return. Full suite: 1328 tests pass. Report regenerates byte-identically (490508 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
|
| 1243 |
+
|
| 1244 |
+
|
| 1245 |
+
## 2026-10-21 — RE-721 Complete contact on original-model contexts (separate task commit)
|
| 1246 |
+
|
| 1247 |
+
Complete292545 now composes eligibility, ordinary/special factors, event/impact branches, actual feedback, direction basis, health request and return using original-model contexts. 35 complete-call fixtures verify independent branch/float32/event-record/ABI oracles and exact original hit/miss context identity. Full suite: 1333 tests pass. Report regenerates byte-identically (997739 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
|
@@ -1204,3 +1204,6 @@ Purpose: turn the supplied installation into an evidence-backed specification of
|
|
| 1204 |
|
| 1205 |
|
| 1206 |
- [x] RE-720 Complete impact-only contact branch ([report](research/QVM_CONTACT_IMPACT.md)).
|
|
|
|
|
|
|
|
|
|
|
|
| 1204 |
|
| 1205 |
|
| 1206 |
- [x] RE-720 Complete impact-only contact branch ([report](research/QVM_CONTACT_IMPACT.md)).
|
| 1207 |
+
|
| 1208 |
+
|
| 1209 |
+
- [x] RE-721 Complete contact on original-model contexts ([report](research/QVM_CONTACT_COMPLETE.md)).
|
docs/research/QVM_CONTACT_COMPLETE.md
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Complete contact on original-model contexts
|
| 2 |
+
|
| 3 |
+
RE-721. Reproduce with `python3 scripts/analyze_qvm_contact_complete.py`; check with `python3 scripts/test_qvm_contact_complete.py`. The [machine report](qvm-contact-complete.json) retains source identity and bounded fixtures.
|
| 4 |
+
|
| 5 |
+
Complete292545 executes292546–293729 through every numeric return with actual289594,32155/32117,33715,277695/278138,60317 and285142 children. Original context rows are copied verbatim into separate memory; nearest point and normal words supply the trace. Ordinary/special/impact/nonclient, empty/null context, same-team/friendly-fire, protection and mode9 cases are included. An independent source-order oracle composes complete factor results, caller scalar rules, all220 event words and211239 request arguments. Native trig/sqrt are modeled; allocation is supplied; native link, formatted announcements/protection notifications and health damage are captured. Geometry is cached original-model output, not recomputed or live world collision. These boundaries remain open despite the complete caller control flow.
|
| 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
|
@@ -762,3 +762,6 @@ The extension collector adds five focused tests for native tail calls, command-r
|
|
| 762 |
|
| 763 |
|
| 764 |
[RE-720: Complete impact-only contact branch](QVM_CONTACT_IMPACT.md). Reproduce with `python3 scripts/analyze_qvm_contact_impact.py`; check with `python3 scripts/test_qvm_contact_impact.py`.
|
|
|
|
|
|
|
|
|
|
|
|
| 762 |
|
| 763 |
|
| 764 |
[RE-720: Complete impact-only contact branch](QVM_CONTACT_IMPACT.md). Reproduce with `python3 scripts/analyze_qvm_contact_impact.py`; check with `python3 scripts/test_qvm_contact_impact.py`.
|
| 765 |
+
|
| 766 |
+
|
| 767 |
+
[RE-721: Complete contact on original-model contexts](QVM_CONTACT_COMPLETE.md). Reproduce with `python3 scripts/analyze_qvm_contact_complete.py`; check with `python3 scripts/test_qvm_contact_complete.py`.
|
docs/research/qvm-contact-complete.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
scripts/analyze_qvm_contact_complete.py
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""Complete292545 with original hit/miss contexts and recovered bounded children."""
|
| 3 |
+
import hashlib,itertools,json
|
| 4 |
+
from pathlib import Path
|
| 5 |
+
from qvm_research_support import source
|
| 6 |
+
from qvm_contact_support import seed,run,L,CONTEXT,TRACE,EXTRA,V_CLIENT,A_CLIENT
|
| 7 |
+
from analyze_qvm_acceleration import number
|
| 8 |
+
from analyze_qvm import write_json
|
| 9 |
+
|
| 10 |
+
def main():
|
| 11 |
+
q,raw,h,ins=source();path=Path('docs/research/md3-original-model-hit.json');data=path.read_bytes();contexts=json.loads(data)['probes'];rows=[]
|
| 12 |
+
cases=[dict(context_row=i,weapon=w,flag=flag,announce=1,vest_slot=0,helmet_slot=15) for i,(w,flag) in itertools.product([1,2,4,5],[(3,0),(3,1),(4,0),(4,1),(27,1),(30,1)])]
|
| 13 |
+
cases += [dict(context_row=1,**changes) for changes in [dict(damageable=0,flag=0),dict(damageable=0,flag=1),dict(damageable=0,weapon=4,flag=1),dict(client=False,flag=1),dict(null_context=True),dict(same_team=True),dict(same_team=True,friendly_fire=1,flag=1),dict(now=3999,flag=1),dict(mode=9,flag=1),dict(entity_flags=16,flag=1)]]
|
| 14 |
+
cases += [dict(context_row=0,flag=1)]
|
| 15 |
+
for supplied in cases:
|
| 16 |
+
a=dict(supplied);a.setdefault('weapon',3);context=contexts[a['context_row']]['context'];a.update(location=context[17],distance=number(context[21]),count=context[16]);m=seed(raw,h,**a)
|
| 17 |
+
for j,v in enumerate(context):m[CONTEXT+4*j]=v
|
| 18 |
+
for p,values in [(TRACE+12,context[3:6]),(TRACE+24,context[9:12])]:
|
| 19 |
+
for j,v in enumerate(values):m[p+4*j]=v
|
| 20 |
+
if a.get('null_context'):m[L+144]=0
|
| 21 |
+
weapon=a.get('weapon',3);fixture={'input':a,'initial':{'extra':m[EXTRA]&0xffffffff,'client':{str(o):m[V_CLIENT+o]&0xffffffff for o in [192,220,4300,4304,4312,4316,6304]}},'descriptor_words':{str(loc):[m[4068+432*weapon+8*loc],m[4072+432*weapon+8*loc]] for loc in range(15)},'range_integer':m[4188+432*weapon]}
|
| 22 |
+
base_factor=m[4068+432*weapon];method=m[4200+432*weapon];m,p=run(ins,m,292546,293730,include_event=True);p.update(input=a,factor_fixture=fixture,base_factor_word=base_factor,method_word=method,context_words=context,feedback_pair=[m[A_CLIENT+2520+8*64],m[A_CLIENT+2524+8*64]]);rows.append(p)
|
| 23 |
+
write_json(Path('docs/research/qvm-contact-complete.json'),{'source':q['source'],'sha256':q['sha256'],'context_report':str(path),'context_report_sha256':hashlib.sha256(data).hexdigest(),'probes':rows,'limits':'Complete292545 with actual289594/inventory/mode/constructor/codec/285142 and modeled native trig/sqrt. Original context bytes copied verbatim. Allocation supplied; native link, announcements, protection notifications and211239 health effects captured. Geometry is cached original-model output, not recomputed/live world collision.'})
|
| 24 |
+
if __name__=='__main__':main()
|
scripts/test_qvm_contact_complete.py
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import hashlib,json,math,unittest
|
| 2 |
+
from pathlib import Path
|
| 3 |
+
from test_qvm_ground import word,n,f
|
| 4 |
+
from test_qvm_damage_complete import expected as factor_expected
|
| 5 |
+
from test_qvm_temp_event import event_record
|
| 6 |
+
from test_qvm_direction_codec import best
|
| 7 |
+
from test_qvm_contact_event_value import normalized
|
| 8 |
+
from qvm_contact_support import ATTACKER,TARGET,TRACE
|
| 9 |
+
from analyze_qvm_contact_dispatch import FORWARD
|
| 10 |
+
|
| 11 |
+
def expected(p):
|
| 12 |
+
a=p['input'];w=a.get('weapon',3);flag=a.get('flag',0);special=w==4 and flag!=0;impact=not a.get('damageable',1) and not special
|
| 13 |
+
if impact:return 0,0,bool(flag),'impact',False
|
| 14 |
+
if not a.get('client',True):return word(f(n(p['base_factor_word'])*100)),0,False,'nonclient',False
|
| 15 |
+
mode=a.get('mode',3);enabled=mode>=3 and mode not in (9,11)
|
| 16 |
+
if a.get('null_context') or not a['count'] or (enabled and a.get('same_team',False) and not a.get('friendly_fire',0)):return 0,0,False,'rejected',False
|
| 17 |
+
if special:
|
| 18 |
+
loc=a['location']
|
| 19 |
+
if loc in (1,2):loc=2 if a.get('helmet_slot',-1)>=0 else 1
|
| 20 |
+
if loc in (3,4):loc=4 if a.get('vest_slot',-1)>=0 else 3
|
| 21 |
+
return word(1),loc,bool(flag),'special',False
|
| 22 |
+
v,loc,*_=factor_expected(p['factor_fixture'])
|
| 23 |
+
if mode==9 or a.get('now',5000)<4000:loc=0
|
| 24 |
+
scalar=word(0 if loc==0 else f(n(v)*100));return scalar,loc,bool(flag and n(scalar)!=0),'ordinary',n(scalar)!=0
|
| 25 |
+
|
| 26 |
+
class CompleteContactTests(unittest.TestCase):
|
| 27 |
+
@classmethod
|
| 28 |
+
def setUpClass(cls):cls.r=json.loads(Path('docs/research/qvm-contact-complete.json').read_text());cls.ps=cls.r['probes'];cls.table=json.loads(Path('docs/research/qvm-direction-codec.json').read_text())['table']
|
| 29 |
+
def test_independent_complete_return_and_branch_outcomes(self):
|
| 30 |
+
for p in self.ps:
|
| 31 |
+
v,loc,event,kind,damage=expected(p);self.assertEqual(p['execution']['return']&0xffffffff,v,p['input']);self.assertEqual(len(p['effects']['events']),int(event),p['input'])
|
| 32 |
+
if kind in ('ordinary','special','nonclient'):self.assertEqual(p['location'],loc)
|
| 33 |
+
if kind=='nonclient':damage=n(v)!=0
|
| 34 |
+
self.assertEqual(len(p['effects']['damage']),int(damage),p['input'])
|
| 35 |
+
def test_all_event_words_composed_independently(self):
|
| 36 |
+
for p in self.ps:
|
| 37 |
+
a=p['input'];scalar,loc,event,kind,_=expected(p);w=a.get('weapon',3)
|
| 38 |
+
if not event:self.assertTrue(all(v==0 for v in p['event_record'].values()));continue
|
| 39 |
+
e=p['effects']['events'][0];self.assertEqual(e['input_origin'],p['context_words'][3:6]);r=event_record(e);normal=p['context_words'][9:12]
|
| 40 |
+
if kind=='impact':r.update({'184':best(normal,self.table),'192':w,'88':99,'140':7,'204':1})
|
| 41 |
+
else:
|
| 42 |
+
encoded=math.trunc(n(scalar)) if w!=4 else min(100,math.trunc(f(n(p['extra_word'])*100)))
|
| 43 |
+
r.update({'424':32,'184':best(normal,self.table),'140':7,'144':65,'88':loc,'84':p['context_words'][15],'200':int(f(100-n(scalar))<=0),'204':encoded&0xffffffff,'196':w})
|
| 44 |
+
for j,v in enumerate(p['context_words'][3:6]):r[str(24+4*j)]=v
|
| 45 |
+
for j,v in enumerate(normalized((3,4,0),(0,0,0))):r[str(36+4*j)]=v
|
| 46 |
+
for j,v in enumerate([0.3333,-0.002,1]):r[str(104+4*j)]=word(float(math.trunc(f(f(v)*500))))
|
| 47 |
+
if w==27:
|
| 48 |
+
for j,v in enumerate([1.25,-2.5,3.75]):r[str(104+4*j)]=word(v)
|
| 49 |
+
self.assertEqual(p['event_record'],r,a)
|
| 50 |
+
def test_health_request_arguments_and_unapplied_effects(self):
|
| 51 |
+
for p in self.ps:
|
| 52 |
+
scalar,loc,*_=expected(p)
|
| 53 |
+
for c in p['effects']['damage']:self.assertEqual(c['arguments'],{'8':TARGET,'12':ATTACKER,'16':ATTACKER,'20':FORWARD,'24':TRACE+12,'28':math.trunc(n(scalar)),'32':0,'36':p['method_word'],'40':loc})
|
| 54 |
+
self.assertEqual(p['target_health'],100);self.assertEqual(p['feedback_pair'],[0,0])
|
| 55 |
+
def test_exact_original_context_identity(self):
|
| 56 |
+
data=Path(self.r['context_report']).read_bytes();self.assertEqual(hashlib.sha256(data).hexdigest(),self.r['context_report_sha256']);rows=json.loads(data)['probes']
|
| 57 |
+
for p in self.ps:self.assertEqual(p['context_words'],rows[p['input']['context_row']]['context'])
|
| 58 |
+
def test_expected_actual_call_families_and_count(self):
|
| 59 |
+
self.assertEqual(len(self.ps),35)
|
| 60 |
+
allowed={33715,289594,32155,7259,277695,60317,-107,-104,-105,285142,211239}
|
| 61 |
+
for p in self.ps:self.assertTrue(all(c['target'] in allowed for c in p['execution']['calls']))
|
| 62 |
+
if __name__=='__main__':unittest.main()
|