qvm: compose complete exit-rule control flow
Browse files- 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_EXIT_COMPLETE.md +7 -0
- docs/research/README.md +3 -0
- docs/research/qvm-exit-complete.json +0 -0
- scripts/analyze_qvm_exit_complete.py +20 -0
- scripts/test_qvm_exit_complete.py +43 -0
- xtask/checks.tsv +8 -0
docs/FINDINGS.md
CHANGED
|
@@ -1493,3 +1493,6 @@ RE-813–822 replaces the scoreboard decimal assumption with actual37914 executi
|
|
| 1493 |
|
| 1494 |
|
| 1495 |
**RE-831:** Rust matches116 original timer cases, including active-round bypass, signed multiply/clock wrap and exact mode9 client resets. [Evidence](research/RUST_EXIT_TIMERS.md).
|
|
|
|
|
|
|
|
|
|
|
|
| 1493 |
|
| 1494 |
|
| 1495 |
**RE-831:** Rust matches116 original timer cases, including active-round bypass, signed multiply/clock wrap and exact mode9 client resets. [Evidence](research/RUST_EXIT_TIMERS.md).
|
| 1496 |
+
|
| 1497 |
+
|
| 1498 |
+
**RE-832:** Complete7805 execution now composes prefix, class, supplied predicate, round/time and limit policies with shared mutations across438 finite fixtures. [Evidence](research/QVM_EXIT_COMPLETE.md).
|
docs/PROVISIONAL_TODO.md
CHANGED
|
@@ -1506,3 +1506,6 @@ RE-830: The active round gate bypasses time-limit evaluation; expired mode9 time
|
|
| 1506 |
|
| 1507 |
|
| 1508 |
RE-831: Rust matches116 original timer cases, including active-round bypass, signed multiply/clock wrap and exact mode9 client resets. Full runtime completion remains open. [Evidence](research/RUST_EXIT_TIMERS.md).
|
|
|
|
|
|
|
|
|
|
|
|
| 1506 |
|
| 1507 |
|
| 1508 |
RE-831: Rust matches116 original timer cases, including active-round bypass, signed multiply/clock wrap and exact mode9 client resets. Full runtime completion remains open. [Evidence](research/RUST_EXIT_TIMERS.md).
|
| 1509 |
+
|
| 1510 |
+
|
| 1511 |
+
RE-832: Complete7805 execution now composes prefix, class, supplied predicate, round/time and limit policies with shared mutations across438 finite fixtures. Full runtime completion remains open. [Evidence](research/QVM_EXIT_COMPLETE.md).
|
docs/RESEARCH_LEDGER.md
CHANGED
|
@@ -1825,3 +1825,8 @@ The active round gate bypasses time-limit evaluation; expired mode9 time limits
|
|
| 1825 |
## 2026-10-27 — RE-831 Rust exit timer priority and mode9 reset/event intentions
|
| 1826 |
|
| 1827 |
Rust matches116 original timer cases, including active-round bypass, signed multiply/clock wrap and exact mode9 client resets. Focused `cargo xtask test-group rust-exit-timers` 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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1825 |
## 2026-10-27 — RE-831 Rust exit timer priority and mode9 reset/event intentions
|
| 1826 |
|
| 1827 |
Rust matches116 original timer cases, including active-round bypass, signed multiply/clock wrap and exact mode9 client resets. Focused `cargo xtask test-group rust-exit-timers` 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.
|
| 1828 |
+
|
| 1829 |
+
|
| 1830 |
+
## 2026-10-27 — RE-832 Continuous original exit-rule body with all recovered priority branches
|
| 1831 |
+
|
| 1832 |
+
Complete7805 execution now composes prefix, class, supplied predicate, round/time and limit policies with shared mutations across438 finite fixtures. Focused `cargo xtask test-group exit-complete` 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
|
@@ -1543,3 +1543,6 @@ Purpose: turn the supplied installation into an evidence-backed specification of
|
|
| 1543 |
|
| 1544 |
|
| 1545 |
- [x] RE-831 Rust exit timer priority and mode9 reset/event intentions ([evidence](research/RUST_EXIT_TIMERS.md)).
|
|
|
|
|
|
|
|
|
|
|
|
| 1543 |
|
| 1544 |
|
| 1545 |
- [x] RE-831 Rust exit timer priority and mode9 reset/event intentions ([evidence](research/RUST_EXIT_TIMERS.md)).
|
| 1546 |
+
|
| 1547 |
+
|
| 1548 |
+
- [x] RE-832 Continuous original exit-rule body with all recovered priority branches ([evidence](research/QVM_EXIT_COMPLETE.md)).
|
docs/research/QVM_EXIT_COMPLETE.md
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Continuous original exit-rule body with all recovered priority branches
|
| 2 |
+
|
| 3 |
+
RE-832. Reproduce with `python3 scripts/analyze_qvm_exit_complete.py`; focused validation: `cargo xtask test-group exit-complete`. [Machine report](qvm-exit-complete.json).
|
| 4 |
+
|
| 5 |
+
The corpus combines all earlier branch fixtures and eight conflicting-priority cases. An independent composition verifies exact captured request ABI/order, pending clears, mode9 client resets and supplied event-record writes. Transition helpers,7662 predicate effects, actual allocation/log/format/send behavior and native runtime remain open rather than being silently modeled as complete.
|
| 6 |
+
|
| 7 |
+
Original executable/native runtime and complete Linux/macOS Rust/Bevy/Solari acceptance remain unverified.
|
docs/research/README.md
CHANGED
|
@@ -1083,3 +1083,6 @@ The extension collector adds five focused tests for native tail calls, command-r
|
|
| 1083 |
|
| 1084 |
|
| 1085 |
[RE-831: Rust exit timer priority and mode9 reset/event intentions](RUST_EXIT_TIMERS.md).
|
|
|
|
|
|
|
|
|
|
|
|
| 1083 |
|
| 1084 |
|
| 1085 |
[RE-831: Rust exit timer priority and mode9 reset/event intentions](RUST_EXIT_TIMERS.md).
|
| 1086 |
+
|
| 1087 |
+
|
| 1088 |
+
[RE-832: Continuous original exit-rule body with all recovered priority branches](QVM_EXIT_COMPLETE.md).
|
docs/research/qvm-exit-complete.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
scripts/analyze_qvm_exit_complete.py
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
import json
|
| 3 |
+
from pathlib import Path
|
| 4 |
+
from qvm_research_support import source
|
| 5 |
+
from qvm_exit_rules_support import seed,run,GLOBALS,FIELDS,CPOOL
|
| 6 |
+
from analyze_qvm import write_json
|
| 7 |
+
|
| 8 |
+
def main():
|
| 9 |
+
q,raw,h,ins=source();cases=[];rows=[]
|
| 10 |
+
for stem in ['qvm-exit-prefix','qvm-exit-class','qvm-exit-limits','qvm-exit-timers']:
|
| 11 |
+
r=json.loads(Path('docs/research/'+stem+'.json').read_text())
|
| 12 |
+
for p in r['probes']:cases.append(({k:v for k,v in p['input'].items() if k!='clients'},p.get('clients',p['input'].get('clients',r.get('clients',[])))))
|
| 13 |
+
good=[{'468':2,'3096':0,'696':0,'248':20,'3692':1,'304':1,'3700':123,'308':500,'300':0xffffffff}];bad=[{**good[0],'696':21}]
|
| 14 |
+
base=dict(mode=11,playing=2,score_limit=10,team_limit=10,first_score=20,second_score=20,time_limit=1,now=60000)
|
| 15 |
+
cases += [(dict(base,blocked=1,predicate=1),bad),(dict(base,pending=59000),bad),(dict(base,predicate=1),bad),(dict(base,mode=0,predicate=1),good),(dict(base,mode=9,round_limit=1,round_active=1,round_count=1,countdown=64501),good),(dict(base,mode=9),good),(dict(base,mode=0,round_limit=1,round_active=1,round_count=0,countdown=64501),good),(dict(base,mode=11,max_clients=0),bad)]
|
| 16 |
+
for a,clients in cases:
|
| 17 |
+
m=seed(clients,**a);state={k:m[address] for k,address in GLOBALS.items()};state['predicate']=a.get('predicate',0);before=[{str(o):m[CPOOL+6336*j+o]&0xffffffff for o in FIELDS} for j in range(len(clients))]
|
| 18 |
+
m,p=run(ins,m,predicate=state['predicate']);p.update(input=state,clients_before=before,clients_after=[{str(o):m[CPOOL+6336*j+o]&0xffffffff for o in FIELDS} for j in range(len(clients))],pending_after=m[34999592]&0xffffffff);rows.append(p)
|
| 19 |
+
write_json(Path('docs/research/qvm-exit-complete.json'),{'source':q['source'],'sha256':q['sha256'],'probes':rows,'limits':'Continuous complete7805 body to8416 across438 finite source fixtures. All priority branches compose with client/global mutations;7662 return and277695 allocation supplied, other children captured. No actual child transition/log/format/send/world behavior or native/runtime acceptance claim.'})
|
| 20 |
+
if __name__=='__main__':main()
|
scripts/test_qvm_exit_complete.py
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import copy,json,unittest
|
| 2 |
+
from pathlib import Path
|
| 3 |
+
from test_qvm_exit_prefix import expected as prefix
|
| 4 |
+
from test_qvm_exit_limits import decision,requests as limit_requests
|
| 5 |
+
from test_qvm_exit_timers import timer,eligible
|
| 6 |
+
from qvm_exit_rules_support import TEXT
|
| 7 |
+
from qvm_notification_support import CPOOL,POOL
|
| 8 |
+
|
| 9 |
+
def signed(v):return (v+2**31)%2**32-2**31
|
| 10 |
+
|
| 11 |
+
def oracle(a,initial):
|
| 12 |
+
clients=[{k:signed(v) for k,v in c.items()} for c in initial];pending,continuation,calls=prefix(a)
|
| 13 |
+
if calls or continuation=='return_boundary':return pending,[{'target':t,'arguments':{}} for t in calls],[],('blocked' if a['blocked'] else 'transition' if calls else 'wait')
|
| 14 |
+
if a['mode']==11:
|
| 15 |
+
bad=next((j for j,c in enumerate(clients[:a['max_clients']]) if c['468']==2 and c['3096']==0 and c['696']>20),None)
|
| 16 |
+
if bad is not None:return pending,[{'target':7367,'arguments':{'8':34641}},{'target':70458,'arguments':{'8':34618,'12':16,'16':0,'20':CPOOL+6336*bad+504}},{'target':-18,'arguments':{'8':-1,'12':TEXT}}],[],'class'
|
| 17 |
+
req=[{'target':7662,'arguments':{}}]
|
| 18 |
+
if a['predicate']:return pending,req,[],'predicate'
|
| 19 |
+
hit=timer(a);ids=[]
|
| 20 |
+
if hit:
|
| 21 |
+
if hit=='time' and a['mode']==9:
|
| 22 |
+
ids=eligible(clients,a['client_count'])
|
| 23 |
+
for j in ids:
|
| 24 |
+
c=clients[j];id=c['140'];req += [{'target':7259,'arguments':{'8':34540,'12':id,'16':c['3700']}},{'target':70458,'arguments':{'8':34500,'12':CPOOL+6336*j+504}},{'target':-18,'arguments':{'8':-1,'12':TEXT}},{'target':277695,'arguments':{'8':POOL+880*id+24,'12':69}}]
|
| 25 |
+
req += [{'target':-18,'arguments':{'8':-1,'12':34593 if hit=='round' else 34476}},{'target':7367,'arguments':{'8':34577 if hit=='round' else 34461}}];return pending,req,ids,hit
|
| 26 |
+
d=decision(a,clients);return pending,req+limit_requests(d),[],d[0] if d else 'none'
|
| 27 |
+
class CompleteExitTests(unittest.TestCase):
|
| 28 |
+
@classmethod
|
| 29 |
+
def setUpClass(cls):cls.ps=json.loads(Path('docs/research/qvm-exit-complete.json').read_text())['probes']
|
| 30 |
+
def test_continuous_source_priority_and_all_captured_abi_requests(self):
|
| 31 |
+
self.assertEqual(len(self.ps),438);kinds=set()
|
| 32 |
+
for p in self.ps:
|
| 33 |
+
pending,req,ids,kind=oracle(p['input'],p['clients_before']);kinds.add(kind);self.assertEqual(p['requests'],req,p['input']);self.assertEqual(p['pending_after'],pending);self.assertEqual(p['execution']['stop'],8416)
|
| 34 |
+
self.assertEqual(kinds,{'blocked','wait','transition','class','predicate','round','time','none','client','low_first','low_second','high_first','high_second'})
|
| 35 |
+
def test_shared_state_mutations_preserve_untouched_fields(self):
|
| 36 |
+
for p in self.ps:
|
| 37 |
+
_,_,ids,_=oracle(p['input'],p['clients_before']);out=copy.deepcopy(p['clients_before'])
|
| 38 |
+
for j in ids:
|
| 39 |
+
for o in ['304','308','3692','3700']:out[j][o]=0
|
| 40 |
+
out[j]['300']&=0xffffff00
|
| 41 |
+
self.assertEqual(p['clients_after'],out);self.assertEqual(len(p['events']),len(ids))
|
| 42 |
+
for e,j in zip(p['events'],ids):id=p['clients_before'][j]['140'];self.assertEqual(e['fields'],{'140':100+id,'428':100+id,'84':p['input']['now']&0xffffffff,'424':272})
|
| 43 |
+
if __name__=='__main__':unittest.main()
|
xtask/checks.tsv
CHANGED
|
@@ -2128,3 +2128,11 @@ report scripts/analyze_rust_exit_timers.py docs/research/rust-exit-timers.json
|
|
| 2128 |
edge docs/research/rust-exit-timers.json scripts/test_rust_exit_timers.py
|
| 2129 |
group rust-exit-timers scripts/analyze_rust_exit_timers.py
|
| 2130 |
edge scripts/analyze_rust_exit_timers.py scripts/analyze_qvm_resumer_audit.py
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2128 |
edge docs/research/rust-exit-timers.json scripts/test_rust_exit_timers.py
|
| 2129 |
group rust-exit-timers scripts/analyze_rust_exit_timers.py
|
| 2130 |
edge scripts/analyze_rust_exit_timers.py scripts/analyze_qvm_resumer_audit.py
|
| 2131 |
+
edge docs/research/qvm-exit-prefix.json scripts/analyze_qvm_exit_complete.py
|
| 2132 |
+
edge docs/research/qvm-exit-class.json scripts/analyze_qvm_exit_complete.py
|
| 2133 |
+
edge docs/research/qvm-exit-limits.json scripts/analyze_qvm_exit_complete.py
|
| 2134 |
+
edge docs/research/qvm-exit-timers.json scripts/analyze_qvm_exit_complete.py
|
| 2135 |
+
report scripts/analyze_qvm_exit_complete.py docs/research/qvm-exit-complete.json
|
| 2136 |
+
edge docs/research/qvm-exit-complete.json scripts/test_qvm_exit_complete.py
|
| 2137 |
+
group exit-complete scripts/analyze_qvm_exit_complete.py
|
| 2138 |
+
edge scripts/analyze_qvm_exit_complete.py scripts/analyze_qvm_resumer_audit.py
|