nmarshall commited on
Commit
bdf3988
·
1 Parent(s): d8e6444

qvm: recover entity field string search

Browse files
docs/FINDINGS.md CHANGED
@@ -1565,3 +1565,6 @@ RE-813–822 replaces the scoreboard decimal assumption with actual37914 executi
1565
 
1566
 
1567
  **RE-855:** Rust matches 80 original class-hash search cases, including inactive/null class filtering, collisions, nonzero signed active values and cursors beyond the scan count. Bounded safe entity slices reject invalid cursors/counts; class text is intentionally not compared because the source does not compare it. [Evidence](research/RUST_ENTITY_HASH.md).
 
 
 
 
1565
 
1566
 
1567
  **RE-855:** Rust matches 80 original class-hash search cases, including inactive/null class filtering, collisions, nonzero signed active values and cursors beyond the scan count. Bounded safe entity slices reject invalid cursors/counts; class text is intentionally not compared because the source does not compare it. [Evidence](research/RUST_ENTITY_HASH.md).
1568
+
1569
+
1570
+ **RE-856:** 150 original 276505 searches and 256 actual 69386 comparisons recover cursor/active/null-field filtering, ASCII folding, signed high-byte ordering, embedded NUL, nullable pointer order and zero-count behavior. Source calls the comparator with99999. Safe finite strings only; raw invalid pointers and runtime integration remain open. [Evidence](research/QVM_ENTITY_FIELD.md).
docs/PROVISIONAL_TODO.md CHANGED
@@ -1587,3 +1587,6 @@ RE-854: 80 original 276433 cases recover nonzero active/class-pointer filtering,
1587
 
1588
 
1589
  RE-855: Rust matches 80 original class-hash search cases, including inactive/null class filtering, collisions, nonzero signed active values and cursors beyond the scan count. Bounded safe entity slices reject invalid cursors/counts; class text is intentionally not compared because the source does not compare it. Full runtime completion remains open. [Evidence](research/RUST_ENTITY_HASH.md).
 
 
 
 
1587
 
1588
 
1589
  RE-855: Rust matches 80 original class-hash search cases, including inactive/null class filtering, collisions, nonzero signed active values and cursors beyond the scan count. Bounded safe entity slices reject invalid cursors/counts; class text is intentionally not compared because the source does not compare it. Full runtime completion remains open. [Evidence](research/RUST_ENTITY_HASH.md).
1590
+
1591
+
1592
+ RE-856: 150 original 276505 searches and 256 actual 69386 comparisons recover cursor/active/null-field filtering, ASCII folding, signed high-byte ordering, embedded NUL, nullable pointer order and zero-count behavior. Source calls the comparator with99999. Safe finite strings only; raw invalid pointers and runtime integration remain open. Full runtime completion remains open. [Evidence](research/QVM_ENTITY_FIELD.md).
docs/RESEARCH_LEDGER.md CHANGED
@@ -1957,3 +1957,8 @@ Batch RE-844–853 boundary: the single `cargo xtask test-full --since 15d7fcac`
1957
  ## 2026-10-27 — RE-855 Rust entity class-hash search
1958
 
1959
  Rust matches 80 original class-hash search cases, including inactive/null class filtering, collisions, nonzero signed active values and cursors beyond the scan count. Bounded safe entity slices reject invalid cursors/counts; class text is intentionally not compared because the source does not compare it. Focused `cargo xtask test-group rust-entity-hash` passes (9 Python tests); selected reports regenerate twice deterministically, with storage, documentation links and whitespace guards. Full suite deferred to task ten. Original assets unchanged; source fixtures do not establish complete native/runtime parity.
 
 
 
 
 
 
1957
  ## 2026-10-27 — RE-855 Rust entity class-hash search
1958
 
1959
  Rust matches 80 original class-hash search cases, including inactive/null class filtering, collisions, nonzero signed active values and cursors beyond the scan count. Bounded safe entity slices reject invalid cursors/counts; class text is intentionally not compared because the source does not compare it. Focused `cargo xtask test-group rust-entity-hash` passes (9 Python tests); selected reports regenerate twice deterministically, with storage, documentation links and whitespace guards. Full suite deferred to task ten. Original assets unchanged; source fixtures do not establish complete native/runtime parity.
1960
+
1961
+
1962
+ ## 2026-10-27 — RE-856 Original field-string entity search with actual comparator
1963
+
1964
+ 150 original 276505 searches and 256 actual 69386 comparisons recover cursor/active/null-field filtering, ASCII folding, signed high-byte ordering, embedded NUL, nullable pointer order and zero-count behavior. Source calls the comparator with99999. Safe finite strings only; raw invalid pointers and runtime integration remain open. Focused `cargo xtask test-group entity-field` passes (5 Python tests); selected reports regenerate twice deterministically, with storage, documentation links and whitespace guards. Full suite deferred to task ten. Original assets unchanged; source fixtures do not establish complete native/runtime parity.
docs/REVERSE_ENGINEERING_TODO.md CHANGED
@@ -1624,3 +1624,6 @@ Purpose: turn the supplied installation into an evidence-backed specification of
1624
 
1625
 
1626
  - [x] RE-855 Rust entity class-hash search ([evidence](research/RUST_ENTITY_HASH.md)).
 
 
 
 
1624
 
1625
 
1626
  - [x] RE-855 Rust entity class-hash search ([evidence](research/RUST_ENTITY_HASH.md)).
1627
+
1628
+
1629
+ - [x] RE-856 Original field-string entity search with actual comparator ([evidence](research/QVM_ENTITY_FIELD.md)).
docs/research/QVM_ENTITY_FIELD.md ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ # Original field-string entity search with actual comparator
2
+
3
+ RE-856. Reproduce with `python3 scripts/analyze_qvm_entity_field.py`; focused validation: `cargo xtask test-group entity-field`. [Machine report](qvm-entity-field.json).
4
+
5
+ 150 original 276505 searches and 256 actual 69386 comparisons recover cursor/active/null-field filtering, ASCII folding, signed high-byte ordering, embedded NUL, nullable pointer order and zero-count behavior. Source calls the comparator with99999. Safe finite strings only; raw invalid pointers and runtime integration remain open.
6
+
7
+ Original executable/native runtime and complete Linux/macOS Rust/Bevy/Solari acceptance remain unverified.
docs/research/README.md CHANGED
@@ -1161,3 +1161,6 @@ The extension collector adds five focused tests for native tail calls, command-r
1161
 
1162
 
1163
  [RE-855: Rust entity class-hash search](RUST_ENTITY_HASH.md).
 
 
 
 
1161
 
1162
 
1163
  [RE-855: Rust entity class-hash search](RUST_ENTITY_HASH.md).
1164
+
1165
+
1166
+ [RE-856: Original field-string entity search with actual comparator](QVM_ENTITY_FIELD.md).
docs/research/qvm-entity-field.json ADDED
The diff for this file is too large to render. See raw diff
 
scripts/analyze_qvm_entity_field.py ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ import itertools
3
+ from pathlib import Path
4
+ from qvm_research_support import source
5
+ from qvm_camera_world_support import casecmp,find_field,string,POOL,S
6
+ from analyze_qvm import write_json
7
+ ENTITIES=[{'active':0,'text':b'node'},{'active':1,'text':None},{'active':1,'text':b'Node'},{'active':2,'text':b'noDE'},{'active':-1,'text':b'\xff'},{'active':1,'text':b'other'},{'active':1,'text':b'node\0suffix'},{'active':1,'text':b''}]
8
+ TEXTS=[None,b'',b'a',b'A',b'ab',b'aB\0x',b'\xff',b'\x80A']
9
+ def main():
10
+ q,raw,h,ins=source();rows=[];comparisons=[]
11
+ for count,after,needle,field in itertools.product([0,4,8],[-1,0,2,3,7],[b'NODE',b'other',b'\xff',b'',None],[608,700]):
12
+ m={34992508:count};b={}
13
+ for j,e in enumerate(ENTITIES):
14
+ m[POOL+880*j+532]=e['active'];m[POOL+880*j+field]=0 if e['text'] is None else S+j*256
15
+ if e['text'] is not None:string(m,b,S+j*256,e['text'])
16
+ if needle is not None:string(m,b,S+0x2000,needle)
17
+ m,value,p,b=find_field(ins,m,{8:0 if after<0 else POOL+880*after,12:field,16:0 if needle is None else S+0x2000},b);rows.append({'input':dict(count=count,after=after,needle=None if needle is None else needle.hex(),field=field),'result':-1 if value==0 else (value-POOL)//880,**p})
18
+ for left,right,count in itertools.product(TEXTS,TEXTS,[0,1,2,99999]):
19
+ m={};b={}
20
+ if left is not None:string(m,b,S,left)
21
+ if right is not None:string(m,b,S+256,right)
22
+ m,value,p,b=casecmp(ins,m,{8:0 if left is None else S,12:0 if right is None else S+256,16:count},b);comparisons.append({'left':None if left is None else left.hex(),'right':None if right is None else right.hex(),'count':count,'result':value,**p})
23
+ write_json(Path('docs/research/qvm-entity-field.json'),{'source':q['source'],'sha256':q['sha256'],'entities':[{'active':e['active'],'text':None if e['text'] is None else e['text'].hex()} for e in ENTITIES],'probes':rows,'comparisons':comparisons,'limits':'Actual276505 with actual69386 over150 field searches plus256 comparator cases. ASCII case fold and signed-byte ordering, nullable pointers, embedded NUL and zero count are explicit. Logical safe strings only; arbitrary offsets/pointers and runtime integration unverified.'})
24
+ if __name__=='__main__':main()
scripts/qvm_camera_world_support.py CHANGED
@@ -14,3 +14,10 @@ def run(ins,m,start,stop,frame,args=None,b=None,handlers=None,base=B):
14
  def string(m,b,address,data):write_bytes(m,b,{address+j:v for j,v in enumerate(bytes(data)+b'\0')})
15
 
16
  def find_class(ins,m,args,b=None,base=B):return run(ins,m,276433,276503,12,args,b,base=base)
 
 
 
 
 
 
 
 
14
  def string(m,b,address,data):write_bytes(m,b,{address+j:v for j,v in enumerate(bytes(data)+b'\0')})
15
 
16
  def find_class(ins,m,args,b=None,base=B):return run(ins,m,276433,276503,12,args,b,base=base)
17
+
18
+ def casecmp(ins,m,args,b=None,base=B+0x2000):return run(ins,m,69386,69523,40,args,b,base=base)
19
+ def find_field(ins,m,args,b=None,base=B+0x1000):
20
+ comparisons=[]
21
+ def compare(i,m,a,bs):
22
+ m,value,p,b=casecmp(i,m,a,bs);comparisons.append({'arguments':a,'result':value,'trace_sha256':p['execution']['trace_sha256']});return m,value,{'actual_source_child':69386}
23
+ m,value,p,b=run(ins,m,276505,276584,28,args,b,{69386:compare},base=base);p['comparisons']=comparisons;return m,value,p,b
scripts/test_qvm_entity_field.py ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json,unittest
2
+ from pathlib import Path
3
+
4
+ def compare(left,right,count=99999):
5
+ if left is None:return 0 if right is None else -1
6
+ if right is None:return 1
7
+ for j in range(min(count,max(len(left),len(right))+1)):
8
+ a=left[j] if j<len(left) else 0;b=right[j] if j<len(right) else 0;a=a-32 if 97<=a<=122 else a;b=b-32 if 97<=b<=122 else b;a=a if a<128 else a-256;b=b if b<128 else b-256
9
+ if a!=b:return -1 if a<b else 1
10
+ if a==0:return 0
11
+ return 0
12
+ class FieldTests(unittest.TestCase):
13
+ def test_actual_comparator_nullable_signed_bytes_and_count(self):
14
+ r=json.loads(Path('docs/research/qvm-entity-field.json').read_text());self.assertEqual(len(r['comparisons']),256)
15
+ for p in r['comparisons']:self.assertEqual(p['result'],compare(None if p['left'] is None else bytes.fromhex(p['left']),None if p['right'] is None else bytes.fromhex(p['right']),p['count']));self.assertEqual(p['changes'],[])
16
+ def test_first_eligible_field_match_and_read_only_world(self):
17
+ r=json.loads(Path('docs/research/qvm-entity-field.json').read_text());self.assertEqual(len(r['probes']),150)
18
+ for p in r['probes']:
19
+ a=p['input'];needle=None if a['needle'] is None else bytes.fromhex(a['needle']);ids=[j for j,e in enumerate(r['entities'][:a['count']]) if j>a['after'] and e['active'] and e['text'] is not None and compare(bytes.fromhex(e['text']),needle)==0];self.assertEqual(p['result'],ids[0] if ids else -1);self.assertEqual(p['changes'],[])
20
+ for c in p['comparisons']:self.assertEqual(c['arguments']['16'],99999)
21
+ if __name__=='__main__':unittest.main()
xtask/checks.tsv CHANGED
@@ -2353,3 +2353,7 @@ edge docs/research/rust-entity-hash.json scripts/test_rust_entity_hash.py
2353
  group rust-entity-hash scripts/analyze_rust_entity_hash.py
2354
  edge scripts/analyze_rust_entity_hash.py scripts/analyze_qvm_resumer_audit.py
2355
  edge scripts/rust_camera_world_support.py scripts/analyze_qvm_resumer_audit.py
 
 
 
 
 
2353
  group rust-entity-hash scripts/analyze_rust_entity_hash.py
2354
  edge scripts/analyze_rust_entity_hash.py scripts/analyze_qvm_resumer_audit.py
2355
  edge scripts/rust_camera_world_support.py scripts/analyze_qvm_resumer_audit.py
2356
+ report scripts/analyze_qvm_entity_field.py docs/research/qvm-entity-field.json
2357
+ edge docs/research/qvm-entity-field.json scripts/test_qvm_entity_field.py
2358
+ group entity-field scripts/analyze_qvm_entity_field.py
2359
+ edge scripts/analyze_qvm_entity_field.py scripts/analyze_qvm_resumer_audit.py