nmarshall commited on
Commit
447b0d2
·
1 Parent(s): 54f520a

qvm: compose recovered intermission flow

Browse files
docs/FINDINGS.md CHANGED
@@ -1523,3 +1523,6 @@ RE-813–822 replaces the scoreboard decimal assumption with actual37914 executi
1523
 
1524
 
1525
  **RE-841:** Rust matches 83 original exit-log cases with signed ping clamp, negative/zero/over32 rank counts, ranked filters, optional team score projection and wrapping pending timestamp. Rendering and ordered publication/configstring/log effects remain caller-owned; invalid ranks reject before mutation. [Evidence](research/RUST_EXIT_LOG.md).
 
 
 
 
1523
 
1524
 
1525
  **RE-841:** Rust matches 83 original exit-log cases with signed ping clamp, negative/zero/over32 rank counts, ranked filters, optional team score projection and wrapping pending timestamp. Rendering and ordered publication/configstring/log effects remain caller-owned; invalid ranks reject before mutation. [Evidence](research/RUST_EXIT_LOG.md).
1526
+
1527
+
1528
+ **RE-842:** 150 continuous 7805 fixtures now execute actual tie, readiness, begin-transition and exit-log children on shared world memory with separate child frames. Independent policy and nested ABI checks cover conflicting gates, client mutations and publication intentions. Lower-level next-map/respawn/camera/I/O and allocation still remain captured. [Evidence](research/QVM_INTERMISSION_FLOW.md).
docs/PROVISIONAL_TODO.md CHANGED
@@ -1539,3 +1539,6 @@ RE-840: 83 original 7367 cases recover Exit header, pending now−50, publicatio
1539
 
1540
 
1541
  RE-841: Rust matches 83 original exit-log cases with signed ping clamp, negative/zero/over32 rank counts, ranked filters, optional team score projection and wrapping pending timestamp. Rendering and ordered publication/configstring/log effects remain caller-owned; invalid ranks reject before mutation. Full runtime completion remains open. [Evidence](research/RUST_EXIT_LOG.md).
 
 
 
 
1539
 
1540
 
1541
  RE-841: Rust matches 83 original exit-log cases with signed ping clamp, negative/zero/over32 rank counts, ranked filters, optional team score projection and wrapping pending timestamp. Rendering and ordered publication/configstring/log effects remain caller-owned; invalid ranks reject before mutation. Full runtime completion remains open. [Evidence](research/RUST_EXIT_LOG.md).
1542
+
1543
+
1544
+ RE-842: 150 continuous 7805 fixtures now execute actual tie, readiness, begin-transition and exit-log children on shared world memory with separate child frames. Independent policy and nested ABI checks cover conflicting gates, client mutations and publication intentions. Lower-level next-map/respawn/camera/I/O and allocation still remain captured. Full runtime completion remains open. [Evidence](research/QVM_INTERMISSION_FLOW.md).
docs/RESEARCH_LEDGER.md CHANGED
@@ -1879,3 +1879,8 @@ Rust matches 39 original begin-transition cases, preserving timestamp guard sema
1879
  ## 2026-10-27 — RE-841 Rust exit log ranked projection and pending clock
1880
 
1881
  Rust matches 83 original exit-log cases with signed ping clamp, negative/zero/over32 rank counts, ranked filters, optional team score projection and wrapping pending timestamp. Rendering and ordered publication/configstring/log effects remain caller-owned; invalid ranks reject before mutation. Focused `cargo xtask test-group rust-exit-log` 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.
 
 
 
 
 
 
1879
  ## 2026-10-27 — RE-841 Rust exit log ranked projection and pending clock
1880
 
1881
  Rust matches 83 original exit-log cases with signed ping clamp, negative/zero/over32 rank counts, ranked filters, optional team score projection and wrapping pending timestamp. Rendering and ordered publication/configstring/log effects remain caller-owned; invalid ranks reject before mutation. Focused `cargo xtask test-group rust-exit-log` 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.
1882
+
1883
+
1884
+ ## 2026-10-27 — RE-842 Original exit flow composed with recovered intermission children
1885
+
1886
+ 150 continuous 7805 fixtures now execute actual tie, readiness, begin-transition and exit-log children on shared world memory with separate child frames. Independent policy and nested ABI checks cover conflicting gates, client mutations and publication intentions. Lower-level next-map/respawn/camera/I/O and allocation still remain captured. Focused `cargo xtask test-group intermission-flow` 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
@@ -1576,3 +1576,6 @@ Purpose: turn the supplied installation into an evidence-backed specification of
1576
 
1577
 
1578
  - [x] RE-841 Rust exit log ranked projection and pending clock ([evidence](research/RUST_EXIT_LOG.md)).
 
 
 
 
1576
 
1577
 
1578
  - [x] RE-841 Rust exit log ranked projection and pending clock ([evidence](research/RUST_EXIT_LOG.md)).
1579
+
1580
+
1581
+ - [x] RE-842 Original exit flow composed with recovered intermission children ([evidence](research/QVM_INTERMISSION_FLOW.md)).
docs/research/QVM_INTERMISSION_FLOW.md ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ # Original exit flow composed with recovered intermission children
2
+
3
+ RE-842. Reproduce with `python3 scripts/analyze_qvm_intermission_flow.py`; focused validation: `cargo xtask test-group intermission-flow`. [Machine report](qvm-intermission-flow.json).
4
+
5
+ 150 continuous 7805 fixtures now execute actual tie, readiness, begin-transition and exit-log children on shared world memory with separate child frames. Independent policy and nested ABI checks cover conflicting gates, client mutations and publication intentions. Lower-level next-map/respawn/camera/I/O and allocation still remain captured.
6
+
7
+ Original executable/native runtime and complete Linux/macOS Rust/Bevy/Solari acceptance remain unverified.
docs/research/README.md CHANGED
@@ -1115,3 +1115,6 @@ The extension collector adds five focused tests for native tail calls, command-r
1115
 
1116
 
1117
  [RE-841: Rust exit log ranked projection and pending clock](RUST_EXIT_LOG.md).
 
 
 
 
1115
 
1116
 
1117
  [RE-841: Rust exit log ranked projection and pending clock](RUST_EXIT_LOG.md).
1118
+
1119
+
1120
+ [RE-842: Original exit flow composed with recovered intermission children](QVM_INTERMISSION_FLOW.md).
docs/research/qvm-intermission-flow.json ADDED
The diff for this file is too large to render. See raw diff
 
docs/research/qvm-resumer-audit.json CHANGED
@@ -8672,7 +8672,7 @@
8672
  "calls": [],
8673
  "explicit_result_offsets": null,
8674
  "helper": "qvm_trace_support.resume",
8675
- "line": 26,
8676
  "literal_range": null,
8677
  "path": "scripts/qvm_exit_rules_support.py",
8678
  "repeated_calls_opt_in": true,
 
8672
  "calls": [],
8673
  "explicit_result_offsets": null,
8674
  "helper": "qvm_trace_support.resume",
8675
+ "line": 27,
8676
  "literal_range": null,
8677
  "path": "scripts/qvm_exit_rules_support.py",
8678
  "repeated_calls_opt_in": true,
scripts/analyze_qvm_intermission_flow.py ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ import itertools
3
+ from pathlib import Path
4
+ from qvm_research_support import source
5
+ from qvm_exit_rules_support import run,GLOBALS,FIELDS,CPOOL
6
+ from qvm_intermission_support import seed,execute,E,EXTRA
7
+ from analyze_qvm import write_json
8
+ ALL=FIELDS+EXTRA
9
+
10
+ def cases():
11
+ for blocked,pending,mode,enabled,pair,now in itertools.product([0,1],[0,59000],[0,3,9,11],[0,1],[(2,2),(2,1)],[59999,60000]):
12
+ c=[{'248':pair[j],'308':pair[j],'696':pair[j],'304':1,'3692':1,'3700':123,'300':0xaabbccff,'4324':77,'4036':0,'6156':j} for j in range(2)]
13
+ yield dict(blocked=blocked,pending=pending,mode=mode,enabled=enabled,now=now,playing=2,time_limit=1,score_limit=1,team_limit=1,first_score=pair[0],second_score=pair[1]),c
14
+ for ready,waiting,now in itertools.product([0,1],[0,1],[5999,6000,15999,16000]):yield dict(blocked=1000,waiting=waiting,wait_start=6000,now=now),[{'4036':ready}, {'4036':ready,'entity_flags':8}]
15
+ for mode in [0,9,11]:
16
+ yield dict(mode=mode,playing=2,enabled=0,now=60000,round_limit=1,round_active=1,round_count=1,countdown=64501),[{'696':21},{'696':0}]
17
+ yield dict(mode=mode,pending=59000,now=60000,slow=1),[{'140':9,'6156':1,'4324':4},{}]
18
+
19
+ def main():
20
+ q,raw,h,ins=source();rows=[]
21
+ for a,c in cases():
22
+ m=seed(c,**a);state={k:m[v] for k,v in GLOBALS.items()};state.update({k:a.get(k,d) for k,d in [('enabled',1),('waiting',0),('wait_start',0),('rank_count',len(c))]});state['order']=a.get('order',list(range(len(c))));children=[]
23
+ def child(target,stop,frame,targets,base):
24
+ def call(i,m,args):
25
+ m,p=execute(i,m,target,stop,frame,args,targets,base=base);children.append({'target':target,'arguments':args,'report':p});return m,p['return'] or 0,{'actual_source_child':target}
26
+ return call
27
+ hs={7662:child(7662,7805,28,[],E+0x8000),7525:child(7525,7660,28,[6939],E+0x9000),6825:child(6825,6937,32,[6717,-6,156523,175123,6575,6328],E+0xa000),7367:child(7367,7523,56,[7259,6328,-19],E+0xb000)}
28
+ before=[{str(o):m[CPOOL+6336*j+o]&0xffffffff for o in ALL} for j in range(len(c))]
29
+ m,p=run(ins,m,extra_handlers=hs);p.update(input=state,clients=c,clients_before=before,clients_after=[{str(o):m[CPOOL+6336*j+o]&0xffffffff for o in ALL} for j in range(len(c))],children=children,state_after={k:m[v]&0xffffffff for k,v in {'blocked':34999596,'pending':34999592,'waiting':34999604,'wait_start':34999608}.items()});rows.append(p)
30
+ write_json(Path('docs/research/qvm-intermission-flow.json'),{'source':q['source'],'sha256':q['sha256'],'probes':rows,'limits':'Actual7805 composed with actual7662/33715,7525,6825 and7367 children over150 cases. Separate synthetic child frames preserve caller locals and share world memory. Lower-level children, event allocation and native I/O remain supplied/captured; no complete game runtime claim.'})
31
+ if __name__=='__main__':main()
scripts/qvm_exit_rules_support.py CHANGED
@@ -15,7 +15,7 @@ def seed(clients=(),**a):
15
  m[POOL+880*j]=100+j
16
  return m
17
 
18
- def run(ins,m,start=7806,boundaries=(),predicate=0):
19
  initial=dict(m);requests=[];allocations=[]
20
  def capture(target,value=0):
21
  def child(i,m,a):requests.append({'target':target,'arguments':a});return m,value,{'child_effect_captured':True}
@@ -23,6 +23,7 @@ def run(ins,m,start=7806,boundaries=(),predicate=0):
23
  def event(i,m,a):
24
  ptr=EVENT+880*len(allocations);m[ptr+424]=16;requests.append({'target':277695,'arguments':a});allocations.append(ptr);return m,ptr,{'allocation_supplied':True}
25
  hs={t:capture(t) for t in [7525,6825,7367,-18,7259]};hs[70458]=capture(70458,TEXT);hs[7662]=capture(7662,predicate);hs[277695]=event
 
26
  m,e=resume(ins,start,8416,m,E,handlers=hs,boundaries=boundaries,repeated_calls=True,sync_child_words=True,segment_limit=2048,limit=32768)
27
  changes=[{'address':a,'before':v,'after':m[a]} for a,v in initial.items() if m[a]!=v and not E<=a<E+128]
28
  events=[{'pointer':p,'fields':{str(o):m[p+o]&0xffffffff for o in [140,428,84,424]}} for p in allocations]
 
15
  m[POOL+880*j]=100+j
16
  return m
17
 
18
+ def run(ins,m,start=7806,boundaries=(),predicate=0,extra_handlers=None):
19
  initial=dict(m);requests=[];allocations=[]
20
  def capture(target,value=0):
21
  def child(i,m,a):requests.append({'target':target,'arguments':a});return m,value,{'child_effect_captured':True}
 
23
  def event(i,m,a):
24
  ptr=EVENT+880*len(allocations);m[ptr+424]=16;requests.append({'target':277695,'arguments':a});allocations.append(ptr);return m,ptr,{'allocation_supplied':True}
25
  hs={t:capture(t) for t in [7525,6825,7367,-18,7259]};hs[70458]=capture(70458,TEXT);hs[7662]=capture(7662,predicate);hs[277695]=event
26
+ hs.update(extra_handlers or {})
27
  m,e=resume(ins,start,8416,m,E,handlers=hs,boundaries=boundaries,repeated_calls=True,sync_child_words=True,segment_limit=2048,limit=32768)
28
  changes=[{'address':a,'before':v,'after':m[a]} for a,v in initial.items() if m[a]!=v and not E<=a<E+128]
29
  events=[{'pointer':p,'fields':{str(o):m[p+o]&0xffffffff for o in [140,428,84,424]}} for p in allocations]
scripts/qvm_intermission_support.py CHANGED
@@ -18,12 +18,12 @@ def classify(ins,m,a):
18
  m,e=resume(ins,33716,33740,m,E+0x1000,repeated_calls=True,sync_child_words=True)
19
  return m,e['return'],{'source_child':33715,'return':e['return']}
20
 
21
- def execute(ins,m,start,stop,frame,args=None,targets=(),handlers=None):
22
- for o,v in (args or {}).items():m[E+frame+o]=v
23
  initial=dict(m);requests=[]
24
  hs={t:captured(t,requests) for t in targets};hs[33715]=classify;hs.update(handlers or {})
25
- m,e=resume(ins,start+1,stop,m,E,handlers=hs,repeated_calls=True,sync_child_words=True,segment_limit=4096,limit=32768)
26
- changes=[{'address':a,'before':v&0xffffffff,'after':m[a]&0xffffffff} for a,v in initial.items() if m[a]!=v and not E<=a<E+0x2000]
27
  return m,{'return':e['return'],'requests':requests,'changes':changes,'execution':{k:e[k] for k in ['stop','trace_length','trace_sha256']}}
28
 
29
  def predicate(ins,m,args=None):
 
18
  m,e=resume(ins,33716,33740,m,E+0x1000,repeated_calls=True,sync_child_words=True)
19
  return m,e['return'],{'source_child':33715,'return':e['return']}
20
 
21
+ def execute(ins,m,start,stop,frame,args=None,targets=(),handlers=None,base=E):
22
+ for o,v in (args or {}).items():m[base+frame+o]=v
23
  initial=dict(m);requests=[]
24
  hs={t:captured(t,requests) for t in targets};hs[33715]=classify;hs.update(handlers or {})
25
+ m,e=resume(ins,start+1,stop,m,base,handlers=hs,repeated_calls=True,sync_child_words=True,segment_limit=4096,limit=32768)
26
+ changes=[{'address':a,'before':v&0xffffffff,'after':m[a]&0xffffffff} for a,v in initial.items() if m[a]!=v and not E<=a<E+0x20000]
27
  return m,{'return':e['return'],'requests':requests,'changes':changes,'execution':{k:e[k] for k in ['stop','trace_length','trace_sha256']}}
28
 
29
  def predicate(ins,m,args=None):
scripts/test_qvm_intermission_flow.py ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json,unittest
2
+ from pathlib import Path
3
+ from test_qvm_exit_complete import oracle,signed
4
+ from test_qvm_exit_predicate import expected as tied
5
+ from test_qvm_intermission_ready import policy
6
+ from test_qvm_intermission_begin import requests as begin_requests
7
+ from test_qvm_exit_log import expected as log_requests
8
+
9
+ def expected(p):
10
+ a=dict(p['input']);c=p['clients'];a['predicate']=tied(a,c);pending,req,resets,kind=oracle(a,p['clients_before']);state={k:a[k]&0xffffffff for k in ['blocked','pending','waiting','wait_start']};state['pending']=pending;clients=[dict(v) for v in p['clients_before']]
11
+ if kind=='blocked':
12
+ r=policy(a,c);state.update({k:r[k] for k in ['waiting','wait_start']});targets=[7525]
13
+ elif kind=='transition':
14
+ targets=[6825]
15
+ if not a['blocked']:
16
+ state['blocked']=a['now']&0xffffffff
17
+ for j,v in enumerate(clients[:a['client_count']]):
18
+ if signed(v['468'])==2:
19
+ if signed(v['140'])!=j:v['140']=v['6156']
20
+ v['4324']=0
21
+ elif kind=='wait':targets=[]
22
+ else:
23
+ targets=[] if kind=='class' else [7662]
24
+ if kind in ['class','round','time','client','low_first','low_second','high_first','high_second']:targets.append(7367);state['pending']=(a['now']-50)&0xffffffff
25
+ for j in resets:
26
+ for o in [304,308,3692,3700]:clients[j][str(o)]=0
27
+ clients[j]['300']&=0xffffff00
28
+ return kind,state,clients,targets
29
+ class FlowTests(unittest.TestCase):
30
+ def test_composed_world_state_and_child_priority(self):
31
+ rows=json.loads(Path('docs/research/qvm-intermission-flow.json').read_text())['probes'];self.assertEqual(len(rows),150);kinds=set()
32
+ for p in rows:
33
+ kind,state,c,targets=expected(p);kinds.add(kind);self.assertEqual(p['state_after'],state);self.assertEqual(p['clients_after'],c);self.assertEqual([v['target'] for v in p['children']],targets)
34
+ self.assertTrue({'blocked','wait','transition','class','predicate','round','time','low_first','high_first'}<=kinds)
35
+ def test_nested_children_preserve_external_abi(self):
36
+ for p in json.loads(Path('docs/research/qvm-intermission-flow.json').read_text())['probes']:
37
+ for child in p['children']:
38
+ a=p['input'];c=p['clients'];r=child['report'];t=child['target']
39
+ if t==7662:self.assertEqual(r['return'],tied(a,c));continue
40
+ if t==7525:wanted=[(6939,{})] if policy(a,c)['exit'] else []
41
+ elif t==6825:wanted=begin_requests(a,c)
42
+ else:wanted=log_requests(dict(a,reason=child['arguments']['8']),c)
43
+ self.assertEqual([(v['target'],{int(k):n&0xffffffff for k,n in v['arguments'].items()}) for v in r['requests']],[(t,{k:v&0xffffffff for k,v in a.items()}) for t,a in wanted])
44
+ if __name__=='__main__':unittest.main()
xtask/checks.tsv CHANGED
@@ -2225,3 +2225,7 @@ report scripts/analyze_rust_exit_log.py docs/research/rust-exit-log.json
2225
  edge docs/research/rust-exit-log.json scripts/test_rust_exit_log.py
2226
  group rust-exit-log scripts/analyze_rust_exit_log.py
2227
  edge scripts/analyze_rust_exit_log.py scripts/analyze_qvm_resumer_audit.py
 
 
 
 
 
2225
  edge docs/research/rust-exit-log.json scripts/test_rust_exit_log.py
2226
  group rust-exit-log scripts/analyze_rust_exit_log.py
2227
  edge scripts/analyze_rust_exit_log.py scripts/analyze_qvm_resumer_audit.py
2228
+ report scripts/analyze_qvm_intermission_flow.py docs/research/qvm-intermission-flow.json
2229
+ edge docs/research/qvm-intermission-flow.json scripts/test_qvm_intermission_flow.py
2230
+ group intermission-flow scripts/analyze_qvm_intermission_flow.py
2231
+ edge scripts/analyze_qvm_intermission_flow.py scripts/analyze_qvm_resumer_audit.py