nmarshall commited on
Commit
be29204
·
1 Parent(s): f1ba0d2

qvm: no target statistic bookkeeping

Browse files
docs/ASSET_PIPELINE_TODO.md CHANGED
@@ -613,3 +613,6 @@ Research progress: RE-643 [report](research/QVM_REWOUND_TRACE.md); remaining nat
613
 
614
 
615
  Research progress: RE-644 [report](research/QVM_TWENTY_PELLETS.md); remaining native/content/runtime/platform scope stays open.
 
 
 
 
613
 
614
 
615
  Research progress: RE-644 [report](research/QVM_TWENTY_PELLETS.md); remaining native/content/runtime/platform scope stays open.
616
+
617
+
618
+ Research progress: RE-645 [report](research/QVM_NO_TARGET_STATS.md); remaining native/content/runtime/platform scope stays open.
docs/FINDINGS.md CHANGED
@@ -962,3 +962,6 @@ Bounded qagame paths recover bomb-plant/inactivity correction requests, direct f
962
 
963
 
964
  **RE-644 — Twenty pellet source loop signed seed carry and no-target handoff:** 295018 now executes all20 pellet iterations with actual rotation, signed seed carry and recovered trace return0, then reaches no-target bookkeeping. [Evidence](research/QVM_TWENTY_PELLETS.md).
 
 
 
 
962
 
963
 
964
  **RE-644 — Twenty pellet source loop signed seed carry and no-target handoff:** 295018 now executes all20 pellet iterations with actual rotation, signed seed carry and recovered trace return0, then reaches no-target bookkeeping. [Evidence](research/QVM_TWENTY_PELLETS.md).
965
+
966
+
967
+ **RE-645 — Statistic category maps and complete no-target bookkeeping:** 279820 maps weapon/location categories, increments attempts/misses for no-target IDs, and recomputes percentage; zero total after wrap resets percentage without division. [Evidence](research/QVM_NO_TARGET_STATS.md).
docs/PROVISIONAL_TODO.md CHANGED
@@ -933,3 +933,6 @@ Research progress: RE-643 [report](research/QVM_REWOUND_TRACE.md); remaining nat
933
 
934
 
935
  Research progress: RE-644 [report](research/QVM_TWENTY_PELLETS.md); remaining native/content/runtime/platform scope stays open.
 
 
 
 
933
 
934
 
935
  Research progress: RE-644 [report](research/QVM_TWENTY_PELLETS.md); remaining native/content/runtime/platform scope stays open.
936
+
937
+
938
+ Research progress: RE-645 [report](research/QVM_NO_TARGET_STATS.md); remaining native/content/runtime/platform scope stays open.
docs/RESEARCH_LEDGER.md CHANGED
@@ -892,3 +892,8 @@ Whole291641 now executes recovered rewind/configured/restore children before and
892
  ## 2026-10-20 — RE-644 Twenty pellet source loop signed seed carry and no-target handoff (separate task commit)
893
 
894
  295018 now executes all20 pellet iterations with actual rotation, signed seed carry and recovered trace return0, then reaches no-target bookkeeping. Four20-pellet compositions plus a zero-direction boundary check every endpoint, signed seed, indexed rotation geometry, trace count and pending bookkeeping ABI. Full suite: 1051 tests pass. Report regenerates byte-identically (1035109 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
 
 
 
 
 
 
892
  ## 2026-10-20 — RE-644 Twenty pellet source loop signed seed carry and no-target handoff (separate task commit)
893
 
894
  295018 now executes all20 pellet iterations with actual rotation, signed seed carry and recovered trace return0, then reaches no-target bookkeeping. Four20-pellet compositions plus a zero-direction boundary check every endpoint, signed seed, indexed rotation geometry, trace count and pending bookkeeping ABI. Full suite: 1051 tests pass. Report regenerates byte-identically (1035109 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
895
+
896
+
897
+ ## 2026-10-20 — RE-645 Statistic category maps and complete no-target bookkeeping (separate task commit)
898
+
899
+ 279820 maps weapon/location categories, increments attempts/misses for no-target IDs, and recomputes percentage; zero total after wrap resets percentage without division. 49 category probes and28 no-target/counter/invalid-attacker cases independently check table-derived categories, all20 stats rows, call order and overflow handling. Full suite: 1055 tests pass. Report regenerates byte-identically (520179 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
@@ -976,3 +976,6 @@ Purpose: turn the supplied installation into an evidence-backed specification of
976
 
977
 
978
  - [x] RE-644 Twenty pellet source loop signed seed carry and no-target handoff ([report](research/QVM_TWENTY_PELLETS.md)).
 
 
 
 
976
 
977
 
978
  - [x] RE-644 Twenty pellet source loop signed seed carry and no-target handoff ([report](research/QVM_TWENTY_PELLETS.md)).
979
+
980
+
981
+ - [x] RE-645 Statistic category maps and complete no-target bookkeeping ([report](research/QVM_NO_TARGET_STATS.md)).
docs/research/QVM_NO_TARGET_STATS.md ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ # Statistic category maps and complete no-target bookkeeping
2
+
3
+ RE-645. Reproduce with `python3 scripts/analyze_qvm_no_target_stats.py`; check with `python3 scripts/test_qvm_no_target_stats.py`. The [machine report](qvm-no-target-stats.json) retains source identity and bounded fixtures.
4
+
5
+ Actual278587/278692 use file-backed jump tables to map weapon and location IDs, returning−1 outside supported categories. Actual279820 no-target paths accept target−1 or≥64, force location category−1, increment category row offsets0/4 and set row56 to100−misses/attempts×100 in source f32 order. A total wrapping to0 resets row56 to0. Attacker−1 bypasses work; invalid weapon category exits after both actual map calls. All20×76-byte rows are independently compared, including preserved canaries. Victim/team/hit branch33715 and damage semantics remain unrecovered; explicit counter fixtures are not legal-runtime claims.
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
@@ -534,3 +534,6 @@ The extension collector adds five focused tests for native tail calls, command-r
534
 
535
 
536
  [RE-644: Twenty pellet source loop signed seed carry and no-target handoff](QVM_TWENTY_PELLETS.md). Reproduce with `python3 scripts/analyze_qvm_twenty_pellets.py`; check with `python3 scripts/test_qvm_twenty_pellets.py`.
 
 
 
 
534
 
535
 
536
  [RE-644: Twenty pellet source loop signed seed carry and no-target handoff](QVM_TWENTY_PELLETS.md). Reproduce with `python3 scripts/analyze_qvm_twenty_pellets.py`; check with `python3 scripts/test_qvm_twenty_pellets.py`.
537
+
538
+
539
+ [RE-645: Statistic category maps and complete no-target bookkeeping](QVM_NO_TARGET_STATS.md). Reproduce with `python3 scripts/analyze_qvm_no_target_stats.py`; check with `python3 scripts/test_qvm_no_target_stats.py`.
docs/research/qvm-no-target-stats.json ADDED
The diff for this file is too large to render. See raw diff
 
scripts/analyze_qvm_no_target_stats.py ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Source statistic category maps and complete279820 no-target bookkeeping."""
3
+ import itertools
4
+ from pathlib import Path
5
+ from qvm_research_support import source,execute,constants
6
+ from qvm_server_fire_support import seed,ENTITY
7
+ from analyze_qvm_entity_init import POOL,STRIDE
8
+ from analyze_qvm_acceleration import PS,word
9
+ from analyze_qvm import write_json
10
+ LOCAL=0x79f10000
11
+ MAP_LOCAL=0x79f00000
12
+
13
+ def category(ins,m,target,value):
14
+ base=MAP_LOCAL+(0x1000 if target==278692 else 0);m=dict(m);m[base+20]=value;start,stop=(278588,278690) if target==278587 else (278693,278731);m,_,e=execute(ins,start,stop,m,(0,0,0),base);return m,{'target':target,'input':value,'result':e['return'],'execution':e}
15
+
16
+ def stats_state(m,client=PS):return {str(j):{str(o):m[client+856+76*j+o]&0xffffffff for o in range(0,76,4)} for j in range(20)}
17
+
18
+ def prepare(raw,h,m=None):
19
+ m=seed(raw,h,4) if m is None else dict(m);m.update(constants(raw,h,range(31236,31404,4)))
20
+ for o in range(0,880,4):m[POOL+7*STRIDE+o]=m[ENTITY+o]
21
+ return m
22
+
23
+ def no_target_stats(ins,m,args):
24
+ m=dict(m);before=stats_state(m)
25
+ for o,v in args.items():m[LOCAL+80+o]=v
26
+ def mapper(target):
27
+ def call(i,m,a,c):m,e=category(i,m,target,a[8]);return m,c,e['result'],e
28
+ return call
29
+ m,_,e=execute(ins,279821,280296,m,(0,0,0),LOCAL,{278587:mapper(278587),278692:mapper(278692)})
30
+ return m,{'arguments':args,'initial':before,'final':stats_state(m),'weapon_category':m.get(LOCAL+12),'execution':e,'status':'void-epilogue'}
31
+
32
+ def main():
33
+ q,raw,h,ins=source();m=prepare(raw,h);maps=[category(ins,m,target,value)[1] for target,values in [(278587,range(-1,30)),(278692,range(-1,17))] for value in values];rows=[]
34
+ cases=list(itertools.product([4,27,1],[-1,64,1023],[0,10,0xffffffff]))
35
+ for ident,target,count in cases+[(4,1023,0)]:
36
+ m=prepare(raw,h)
37
+ for j in range(20):
38
+ for o in range(0,76,4):m[PS+856+76*j+o]=0
39
+ m[PS+856+76*j]=count;m[PS+856+76*j+4]=min(count,7);m[PS+856+76*j+56]=word(9.5)
40
+ args={8:-1 if len(rows)==len(cases) else 7,12:ident,16:1,20:target,24:word(73.5)};rows.append(no_target_stats(ins,m,args)[1])
41
+ write_json(Path('docs/research/qvm-no-target-stats.json'),{'source':q['source'],'sha256':q['sha256'],'jump_words':{str(a):v for a,v in constants(raw,h,range(31236,31404,4)).items()},'category_probes':maps,'probes':rows,'limits':'Actual category278587/278692 and complete279820 for attacker−1 or no-target IDs−1/≥64. No victim/team/hit33715 branch or damage; explicit counter wrap fixtures do not establish legal runtime statistics domains.'})
42
+ if __name__=='__main__':main()
scripts/test_qvm_no_target_stats.py ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json,copy,unittest
2
+ from pathlib import Path
3
+ from test_qvm_ground import word,f
4
+ class NoTargetStatsTests(unittest.TestCase):
5
+ @classmethod
6
+ def setUpClass(cls):cls.r=json.loads(Path('docs/research/qvm-no-target-stats.json').read_text());cls.maps={(p['target'],p['input']):p['result'] for p in cls.r['category_probes']}
7
+ def test_independent_file_jump_table_category_results(self):
8
+ for p in self.r['category_probes']:
9
+ value=p['input'];target=p['target'];valid=2<=value<=27 if target==278587 else 1<=value<=14;expected=-1
10
+ if valid:
11
+ address=(31236 if target==278587 else 31344)+4*value;destination=self.r['jump_words'][str(address)];expected=(destination-278608)//4 if target==278587 and destination!=278688 else ((destination-278713)//4 if target==278692 and destination!=278729 else -1)
12
+ self.assertEqual(p['result'],expected);self.assertEqual(p['execution']['calls'],[])
13
+ def test_independent_entire_stats_rows(self):
14
+ for p in self.r['probes']:
15
+ expected=copy.deepcopy(p['initial']);a=p['arguments'];category=self.maps.get((278587,a['12']),-1)
16
+ if a['8']!=-1 and category!=-1:
17
+ row=expected[str(category)];row['0']=(row['0']+1)&0xffffffff;row['4']=(row['4']+1)&0xffffffff;row['56']=word(f(100-f(f(float(row['4'])/float(row['0']))*100))) if row['0'] else 0
18
+ self.assertEqual(p['final'],expected)
19
+ def test_only_actual_category_children_on_no_target_paths(self):
20
+ for p in self.r['probes']:self.assertEqual([c['target'] for c in p['execution']['calls']],[] if p['arguments']['8']==-1 else [278587,278692])
21
+ def test_overflow_zero_total_avoids_division_and_resets_percentage(self):
22
+ for p in self.r['probes']:
23
+ c=self.maps[(278587,p['arguments']['12'])]
24
+ if c!=-1 and p['initial'][str(c)]['0']==0xffffffff:self.assertEqual(p['final'][str(c)]['0'],0);self.assertEqual(p['final'][str(c)]['56'],0)
25
+ if __name__=='__main__':unittest.main()