qvm: complete leaf hit processing
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_LEAF.md +7 -0
- docs/research/README.md +3 -0
- docs/research/qvm-complete-leaf.json +0 -0
- scripts/analyze_deferred_auth.py +3 -0
- scripts/analyze_qvm_complete_leaf.py +54 -0
- scripts/test_qvm_complete_leaf.py +35 -0
docs/ASSET_PIPELINE_TODO.md
CHANGED
|
@@ -727,3 +727,6 @@ Research progress: RE-684 [report](research/QVM_SURFACE_CATEGORY.md); remaining
|
|
| 727 |
|
| 728 |
|
| 729 |
Research progress: RE-685 [report](research/QVM_LEAF_HIT_PUBLISH.md); remaining native/content/runtime/platform scope stays open.
|
|
|
|
|
|
|
|
|
|
|
|
| 727 |
|
| 728 |
|
| 729 |
Research progress: RE-685 [report](research/QVM_LEAF_HIT_PUBLISH.md); remaining native/content/runtime/platform scope stays open.
|
| 730 |
+
|
| 731 |
+
|
| 732 |
+
Research progress: RE-686 [report](research/QVM_COMPLETE_LEAF.md); remaining native/content/runtime/platform scope stays open.
|
docs/FINDINGS.md
CHANGED
|
@@ -1073,3 +1073,6 @@ Bounded qagame paths recover bomb-plant/inactivity correction requests, direct f
|
|
| 1073 |
|
| 1074 |
|
| 1075 |
**RE-685 — Nearest farthest context updates and bounded hit append:** 23092 updates nearest/farthest point-normal-part independently of category/capacity, then appends nonzero category five-word records only below count10. [Evidence](research/QVM_LEAF_HIT_PUBLISH.md).
|
|
|
|
|
|
|
|
|
|
|
|
| 1073 |
|
| 1074 |
|
| 1075 |
**RE-685 — Nearest farthest context updates and bounded hit append:** 23092 updates nearest/farthest point-normal-part independently of category/capacity, then appends nonzero category five-word records only below count10. [Evidence](research/QVM_LEAF_HIT_PUBLISH.md).
|
| 1076 |
+
|
| 1077 |
+
|
| 1078 |
+
**RE-686 — Complete packed-model leaf geometry and source-produced hit records:** Complete23092 now produces actual geometry-derived context records through packed vertices, ancestry, barycentrics, source normals/points and actual metadata lookup. [Evidence](research/QVM_COMPLETE_LEAF.md).
|
docs/PROVISIONAL_TODO.md
CHANGED
|
@@ -1056,3 +1056,6 @@ Research progress: RE-684 [report](research/QVM_SURFACE_CATEGORY.md); remaining
|
|
| 1056 |
|
| 1057 |
|
| 1058 |
Research progress: RE-685 [report](research/QVM_LEAF_HIT_PUBLISH.md); remaining native/content/runtime/platform scope stays open.
|
|
|
|
|
|
|
|
|
|
|
|
| 1056 |
|
| 1057 |
|
| 1058 |
Research progress: RE-685 [report](research/QVM_LEAF_HIT_PUBLISH.md); remaining native/content/runtime/platform scope stays open.
|
| 1059 |
+
|
| 1060 |
+
|
| 1061 |
+
Research progress: RE-686 [report](research/QVM_COMPLETE_LEAF.md); remaining native/content/runtime/platform scope stays open.
|
docs/RESEARCH_LEDGER.md
CHANGED
|
@@ -1077,3 +1077,8 @@ Actual queried/allocated grenade enters223156, evaluates source trajectory, trun
|
|
| 1077 |
## 2026-10-21 — RE-685 Nearest farthest context updates and bounded hit append (separate task commit)
|
| 1078 |
|
| 1079 |
23092 updates nearest/farthest point-normal-part independently of category/capacity, then appends nonzero category five-word records only below count10. 96 whole-context fixtures independently check negative/equal/large parameters, strict bounds, categories, initialized null-pointer consumption and capacities0/9/10/11. Full suite: 1197 tests pass. Report regenerates byte-identically (350422 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1077 |
## 2026-10-21 — RE-685 Nearest farthest context updates and bounded hit append (separate task commit)
|
| 1078 |
|
| 1079 |
23092 updates nearest/farthest point-normal-part independently of category/capacity, then appends nonzero category five-word records only below count10. 96 whole-context fixtures independently check negative/equal/large parameters, strict bounds, categories, initialized null-pointer consumption and capacities0/9/10/11. Full suite: 1197 tests pass. Report regenerates byte-identically (350422 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
|
| 1080 |
+
|
| 1081 |
+
|
| 1082 |
+
## 2026-10-21 — RE-686 Complete packed-model leaf geometry and source-produced hit records (separate task commit)
|
| 1083 |
+
|
| 1084 |
+
Complete23092 now produces actual geometry-derived context records through packed vertices, ancestry, barycentrics, source normals/points and actual metadata lookup. 36 whole-context compositions check hits/misses/behind-origin/multiple surfaces/twelve triangles/capacity with independent geometry and publication oracles; mixed word/byte copy coherence has a dedicated regression. Full suite: 1202 tests pass. Report regenerates byte-identically (354732 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime changed; shared STORE4 synchronizes active byte memory, with an independent regression; native/reference/legal/full platform scope remains open.
|
docs/REVERSE_ENGINEERING_TODO.md
CHANGED
|
@@ -1099,3 +1099,6 @@ Purpose: turn the supplied installation into an evidence-backed specification of
|
|
| 1099 |
|
| 1100 |
|
| 1101 |
- [x] RE-685 Nearest farthest context updates and bounded hit append ([report](research/QVM_LEAF_HIT_PUBLISH.md)).
|
|
|
|
|
|
|
|
|
|
|
|
| 1099 |
|
| 1100 |
|
| 1101 |
- [x] RE-685 Nearest farthest context updates and bounded hit append ([report](research/QVM_LEAF_HIT_PUBLISH.md)).
|
| 1102 |
+
|
| 1103 |
+
|
| 1104 |
+
- [x] RE-686 Complete packed-model leaf geometry and source-produced hit records ([report](research/QVM_COMPLETE_LEAF.md)).
|
docs/research/QVM_COMPLETE_LEAF.md
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Complete packed-model leaf geometry and source-produced hit records
|
| 2 |
+
|
| 3 |
+
RE-686. Reproduce with `python3 scripts/analyze_qvm_complete_leaf.py`; check with `python3 scripts/test_qvm_complete_leaf.py`. The [machine report](qvm-complete-leaf.json) retains source identity and bounded fixtures.
|
| 4 |
+
|
| 5 |
+
Complete23093–25338 executes all reached primitive loops, actual36038/21493 children and finite sqrt models. Packed model surfaces determine intersection outcomes; no successful hit reply is supplied. Independent full-context oracles check vectors, part indices, five-word records and final nearest/farthest distance stores. A reached evaluator inconsistency was corrected: STORE4 now synchronizes active byte memory so a later BLOCK_COPY observes the just-written word instead of stale bytes. A focused regression checks word→byte→copy coherence. This preserves the source point arithmetic already recovered. Model tables/bounds and initialized unknown-name word4 remain fixture assumptions; original native/domain parity is open.
|
| 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
|
@@ -657,3 +657,6 @@ The extension collector adds five focused tests for native tail calls, command-r
|
|
| 657 |
|
| 658 |
|
| 659 |
[RE-685: Nearest farthest context updates and bounded hit append](QVM_LEAF_HIT_PUBLISH.md). Reproduce with `python3 scripts/analyze_qvm_leaf_hit_publish.py`; check with `python3 scripts/test_qvm_leaf_hit_publish.py`.
|
|
|
|
|
|
|
|
|
|
|
|
| 657 |
|
| 658 |
|
| 659 |
[RE-685: Nearest farthest context updates and bounded hit append](QVM_LEAF_HIT_PUBLISH.md). Reproduce with `python3 scripts/analyze_qvm_leaf_hit_publish.py`; check with `python3 scripts/test_qvm_leaf_hit_publish.py`.
|
| 660 |
+
|
| 661 |
+
|
| 662 |
+
[RE-686: Complete packed-model leaf geometry and source-produced hit records](QVM_COMPLETE_LEAF.md). Reproduce with `python3 scripts/analyze_qvm_complete_leaf.py`; check with `python3 scripts/test_qvm_complete_leaf.py`.
|
docs/research/qvm-complete-leaf.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
scripts/analyze_deferred_auth.py
CHANGED
|
@@ -62,6 +62,9 @@ def trace_slice(instructions, start, stop, memory, locals_map, limit=256, byte_m
|
|
| 62 |
elif op == 'STORE4':
|
| 63 |
value, address = stack.pop(), stack.pop()
|
| 64 |
memory[address] = signed32(value)
|
|
|
|
|
|
|
|
|
|
| 65 |
elif op == 'STORE1':
|
| 66 |
value, address = stack.pop(), stack.pop()
|
| 67 |
byte_writes.append({'address': address, 'value': value & 255})
|
|
|
|
| 62 |
elif op == 'STORE4':
|
| 63 |
value, address = stack.pop(), stack.pop()
|
| 64 |
memory[address] = signed32(value)
|
| 65 |
+
if bytes_map is not None:
|
| 66 |
+
for byte in range(4):
|
| 67 |
+
bytes_map[address+byte] = (value >> (8*byte)) & 255
|
| 68 |
elif op == 'STORE1':
|
| 69 |
value, address = stack.pop(), stack.pop()
|
| 70 |
byte_writes.append({'address': address, 'value': value & 255})
|
scripts/analyze_qvm_complete_leaf.py
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""Complete23092 from explicit packed model surfaces through actual hit records."""
|
| 3 |
+
import math,itertools
|
| 4 |
+
from pathlib import Path
|
| 5 |
+
from qvm_research_support import source
|
| 6 |
+
from qvm_trace_support import resume
|
| 7 |
+
from analyze_qvm_surface_category import support,put_text,classify
|
| 8 |
+
from analyze_qvm_word_strlen import length
|
| 9 |
+
from analyze_qvm_acceleration import word,number
|
| 10 |
+
from analyze_qvm import write_json
|
| 11 |
+
LOCAL=0x78d00000
|
| 12 |
+
NODE=LOCAL+4096
|
| 13 |
+
MODEL=LOCAL+8192
|
| 14 |
+
CONTEXT=LOCAL+0x10000
|
| 15 |
+
ORIGIN=CONTEXT+512
|
| 16 |
+
DIRECTION=ORIGIN+16
|
| 17 |
+
|
| 18 |
+
def words(m,p,count=77):return [m[p+4*j]&0xffffffff for j in range(count)]
|
| 19 |
+
def leaf(ins,m,bs,args,base=LOCAL):
|
| 20 |
+
m=dict(m);before=words(m,args[20])
|
| 21 |
+
for o,v in args.items():m[base+432+o]=v
|
| 22 |
+
def sqrt(i,m,a):v=word(math.sqrt(number(a[8])));return m,v,{'argument':a[8]&0xffffffff,'result':v,'finite_sqrt_model':True}
|
| 23 |
+
def strlen(i,m,a):m,r=length(i,m,a[8]);return m,r['length'],{'length':r['length'],'execution':r['execution']}
|
| 24 |
+
def category(i,m,a):m,r=classify(i,m,bs,a[8],a[12]);return m,r['result_pointer'],{'result_pointer':r['result_pointer'],'category':r['category'],'trace_sha256':r['execution']['trace_sha256'],'trace_length':r['execution']['trace_length']}
|
| 25 |
+
m,e=resume(ins,23093,25339,m,base,handlers={-107:sqrt,36038:strlen,21493:category},byte_inputs=bs,limit=131072)
|
| 26 |
+
return m,{'arguments':args,'before':before,'after':words(m,args[20]),'execution':e}
|
| 27 |
+
|
| 28 |
+
def fixture(raw,h,kind='head',ray='front',count=0):
|
| 29 |
+
m,bs=support(raw,h);m.update({NODE:0,NODE+4:1,NODE+8:word(.5),NODE+88:MODEL,NODE+96:0,MODEL+84:0,MODEL+100:1024});surfaces=[]
|
| 30 |
+
for o in range(12,88,4):m[NODE+o]=0
|
| 31 |
+
for o in [12,32,52,72]:m[NODE+o]=word(1)
|
| 32 |
+
for o in range(0,308,4):m[CONTEXT+o]=0x12340000+o
|
| 33 |
+
m[CONTEXT+64]=count
|
| 34 |
+
names={'empty':[],'head':['h_head'],'torso':['u_torso'],'unknown':['unknown'],'two':['h_head','u_torso'],'twelve':['h_head']}[kind];m[MODEL+84]=len(names)
|
| 35 |
+
for index,name in enumerate(names):
|
| 36 |
+
p=MODEL+1024+1024*index;tri_count=12 if kind=='twelve' else 1;z=32*index;vertices=[[0,0,z],[64,0,z],[0,64,z]];m.update({p+80:3,p+84:tri_count,p+88:128,p+100:512,p+104:1024});put_text(m,bs,p+4,name.encode())
|
| 37 |
+
for tri in range(tri_count):
|
| 38 |
+
for j in range(3):m[p+128+12*tri+4*j]=j
|
| 39 |
+
for frame in range(2):
|
| 40 |
+
for j,v in enumerate(vertices):
|
| 41 |
+
address=p+512+(frame*3+j)*8;data=b''.join(x.to_bytes(2,'little',signed=True) for x in v)+b'\0\0'
|
| 42 |
+
for k,b in enumerate(data):bs[address+k]=b
|
| 43 |
+
surfaces.append({'name':name,'packed_vertices':vertices,'triangles':[[0,1,2]]*tri_count})
|
| 44 |
+
origin=(2,2,1) if ray=='miss' else (.25,.25,1);direction=(0,0,1) if ray=='behind' else (0,0,-1)
|
| 45 |
+
for p,v in [(ORIGIN,origin),(DIRECTION,direction)]:
|
| 46 |
+
for j,x in enumerate(v):m[p+4*j]=word(x)
|
| 47 |
+
return m,bs,{'kind':kind,'surfaces':surfaces,'origin':[word(v) for v in origin],'direction':[word(v) for v in direction],'null_word4':m[4]}
|
| 48 |
+
|
| 49 |
+
def main():
|
| 50 |
+
q,raw,h,ins=source();rows=[]
|
| 51 |
+
for kind,ray,count in itertools.product(['empty','head','torso','unknown','two','twelve'],['front','behind','miss'],[0,9]):
|
| 52 |
+
m,bs,inputs=fixture(raw,h,kind,ray,count);_,r=leaf(ins,m,bs,{8:NODE,12:ORIGIN,16:DIRECTION,20:CONTEXT});r['input']=inputs;rows.append(r)
|
| 53 |
+
write_json(Path('docs/research/qvm-complete-leaf.json'),{'source':q['source'],'sha256':q['sha256'],'probes':rows,'limits':'Complete23092 on explicit packed model surfaces with actual strlen/classifier and finite sqrt models. Actual geometric outcomes, not supplied hit replies. Unknown names retain initialized word4; live data/domain/model ownership parity remains open.'})
|
| 54 |
+
if __name__=='__main__':main()
|
scripts/test_qvm_complete_leaf.py
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import json,unittest
|
| 2 |
+
from pathlib import Path
|
| 3 |
+
from test_qvm_ground import word,n
|
| 4 |
+
from test_qvm_ray_triangle import expected as candidate
|
| 5 |
+
from test_qvm_hit_geometry import expected as geometry
|
| 6 |
+
|
| 7 |
+
def expected(p):
|
| 8 |
+
r=p['before'][:];near=word(1e7);far=word(0);a=p['input']
|
| 9 |
+
for index,s in enumerate(a['surfaces']):
|
| 10 |
+
for triangle in s['triangles']:
|
| 11 |
+
vertices=[[word(v/64) for v in s['packed_vertices'][j]] for j in triangle];c={'vertices':vertices,'origin':a['origin'],'direction':a['direction']};hit,det,u,v,t=candidate(c)
|
| 12 |
+
if not hit:continue
|
| 13 |
+
c.update({'u':u,'v':v,'parameter':t});normal,edges,point=geometry({'candidate':c});category={'h_head':1,'u_torso':3}.get(s['name'],a['null_word4'])
|
| 14 |
+
if n(t)<n(near):near=t;r[3:6]=point;r[9:12]=normal;r[15]=index
|
| 15 |
+
if n(t)>n(far):far=t;r[:3]=point;r[6:9]=normal;r[14]=index
|
| 16 |
+
count=r[16]
|
| 17 |
+
if category and count<10:r[16]=count+1;r[17+5*count:22+5*count]=[category]+point+[t]
|
| 18 |
+
r[12]=far;r[13]=near;return r
|
| 19 |
+
class CompleteLeafTests(unittest.TestCase):
|
| 20 |
+
@classmethod
|
| 21 |
+
def setUpClass(cls):cls.rows=json.loads(Path('docs/research/qvm-complete-leaf.json').read_text())['probes']
|
| 22 |
+
def test_independent_all_context_words_and_actual_geometry(self):
|
| 23 |
+
self.assertEqual(len(self.rows),36)
|
| 24 |
+
for p in self.rows:self.assertEqual(p['after'],expected(p),p['input'])
|
| 25 |
+
def test_capacity_loops_empty_surfaces_and_misses(self):
|
| 26 |
+
self.assertTrue(any(p['after'][16]==10 for p in self.rows))
|
| 27 |
+
for p in self.rows:
|
| 28 |
+
if not p['input']['surfaces'] or p['input']['kind']=='empty':self.assertEqual(p['execution']['calls'],[])
|
| 29 |
+
def test_all_children_source_or_explicit_sqrt(self):
|
| 30 |
+
for p in self.rows:self.assertTrue(set(c['target'] for c in p['execution']['calls'])<={-107,36038,21493});self.assertEqual(p['execution']['stop'],25339)
|
| 31 |
+
def test_word_store_updates_bytes_before_later_copy(self):
|
| 32 |
+
from analyze_deferred_auth import trace_slice
|
| 33 |
+
ops=[('CONST',100),('CONST',0x12345678),('STORE4',None),('CONST',200),('CONST',100),('BLOCK_COPY',4),('CONST',200),('LOAD1',None)];ins=[{'index':j,'opcode':op,'operand':v} for j,(op,v) in enumerate(ops)];r=trace_slice(ins,0,len(ins),{100:0,200:0},{},byte_memory={100+j:0 for j in range(4)},capture_stack=True);self.assertEqual(r['memory'][200],0x12345678);self.assertEqual(r['stack'],[0x78]);self.assertEqual([r['byte_memory'][100+j] for j in range(4)],[0x78,0x56,0x34,0x12])
|
| 34 |
+
def test_negative_parameters_survive_to_nearest_header(self):self.assertTrue(any(n(p['after'][13])<0 and p['after'][16]>p['before'][16] for p in self.rows))
|
| 35 |
+
if __name__=='__main__':unittest.main()
|