qvm: resolve protected child effects
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_PROTECTED_RESOLVED.md +7 -0
- docs/research/README.md +3 -0
- docs/research/qvm-protected-resolved.json +0 -0
- scripts/analyze_qvm_protected_resolved.py +17 -0
- scripts/qvm_lifecycle_support.py +4 -4
- scripts/qvm_resolved_lifecycle_support.py +26 -0
- scripts/test_qvm_protected_resolved.py +21 -0
- xtask/checks.tsv +3 -0
docs/ASSET_PIPELINE_TODO.md
CHANGED
|
@@ -916,3 +916,6 @@ Research progress: RE-750 [report](research/QVM_METHOD_STAT_UPDATES.md); origina
|
|
| 916 |
|
| 917 |
|
| 918 |
Research progress: RE-751 [report](research/QVM_CROSS_CLIENT_CLEAR.md); original assets unchanged.
|
|
|
|
|
|
|
|
|
|
|
|
| 916 |
|
| 917 |
|
| 918 |
Research progress: RE-751 [report](research/QVM_CROSS_CLIENT_CLEAR.md); original assets unchanged.
|
| 919 |
+
|
| 920 |
+
|
| 921 |
+
Research progress: RE-752 [report](research/QVM_PROTECTED_RESOLVED.md); original assets unchanged.
|
docs/FINDINGS.md
CHANGED
|
@@ -1262,3 +1262,6 @@ RE-725–734 batch: [health, contact and Rust impulse findings](research/QVM_HEA
|
|
| 1262 |
|
| 1263 |
|
| 1264 |
**RE-751 — Complete cross client record clearing and inclusive index64:** 285486 clears two words across nonnull client records in64 entity slots; its source gate accepts index64 inclusively. [Evidence](research/QVM_CROSS_CLIENT_CLEAR.md).
|
|
|
|
|
|
|
|
|
|
|
|
| 1262 |
|
| 1263 |
|
| 1264 |
**RE-751 — Complete cross client record clearing and inclusive index64:** 285486 clears two words across nonnull client records in64 entity slots; its source gate accepts index64 inclusively. [Evidence](research/QVM_CROSS_CLIENT_CLEAR.md).
|
| 1265 |
+
|
| 1266 |
+
|
| 1267 |
+
**RE-752 — Protected completion with actual scoring and recipient dispatch:** 152386 completion now executes actual205260 score mutation and6369 connected-recipient dispatch while retaining explicit rank/callback/event boundaries. [Evidence](research/QVM_PROTECTED_RESOLVED.md).
|
docs/PROVISIONAL_TODO.md
CHANGED
|
@@ -1254,3 +1254,6 @@ Research progress: RE-750 [report](research/QVM_METHOD_STAT_UPDATES.md); full na
|
|
| 1254 |
|
| 1255 |
|
| 1256 |
Research progress: RE-751 [report](research/QVM_CROSS_CLIENT_CLEAR.md); full native/platform/game scope remains open.
|
|
|
|
|
|
|
|
|
|
|
|
| 1254 |
|
| 1255 |
|
| 1256 |
Research progress: RE-751 [report](research/QVM_CROSS_CLIENT_CLEAR.md); full native/platform/game scope remains open.
|
| 1257 |
+
|
| 1258 |
+
|
| 1259 |
+
Research progress: RE-752 [report](research/QVM_PROTECTED_RESOLVED.md); full native/platform/game scope remains open.
|
docs/RESEARCH_LEDGER.md
CHANGED
|
@@ -1405,3 +1405,8 @@ Exactly ten task commits follow baseline `e1f7eb5a`. Each task passed focused `c
|
|
| 1405 |
## 2026-10-21 — RE-751 Complete cross client record clearing and inclusive index64
|
| 1406 |
|
| 1407 |
285486 clears two words across nonnull client records in64 entity slots; its source gate accepts index64 inclusively. Focused `cargo xtask test-group record-clear` passes (3 Python tests); selected reports regenerate twice byte-identically, with storage, links and whitespace guards. New report: 137753 bytes. Full-suite validation is deferred to the tenth batch commit. No original assets, Rust runtime or shared VM evaluator changed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1405 |
## 2026-10-21 — RE-751 Complete cross client record clearing and inclusive index64
|
| 1406 |
|
| 1407 |
285486 clears two words across nonnull client records in64 entity slots; its source gate accepts index64 inclusively. Focused `cargo xtask test-group record-clear` passes (3 Python tests); selected reports regenerate twice byte-identically, with storage, links and whitespace guards. New report: 137753 bytes. Full-suite validation is deferred to the tenth batch commit. No original assets, Rust runtime or shared VM evaluator changed.
|
| 1408 |
+
|
| 1409 |
+
|
| 1410 |
+
## 2026-10-21 — RE-752 Protected completion with actual scoring and recipient dispatch
|
| 1411 |
+
|
| 1412 |
+
152386 completion now executes actual205260 score mutation and6369 connected-recipient dispatch while retaining explicit rank/callback/event boundaries. Focused `cargo xtask test-group resolved-protected` passes (3 Python tests); selected reports regenerate twice byte-identically, with storage, links and whitespace guards. New report: 153157 bytes. Full-suite validation is deferred to the tenth batch commit. Optional lifecycle child resolvers added; default source contracts retained. Original assets, Rust runtime and shared VM evaluator unchanged.
|
docs/REVERSE_ENGINEERING_TODO.md
CHANGED
|
@@ -1297,3 +1297,6 @@ Purpose: turn the supplied installation into an evidence-backed specification of
|
|
| 1297 |
|
| 1298 |
|
| 1299 |
- [x] RE-751 Complete cross client record clearing and inclusive index64 ([report](research/QVM_CROSS_CLIENT_CLEAR.md)).
|
|
|
|
|
|
|
|
|
|
|
|
| 1297 |
|
| 1298 |
|
| 1299 |
- [x] RE-751 Complete cross client record clearing and inclusive index64 ([report](research/QVM_CROSS_CLIENT_CLEAR.md)).
|
| 1300 |
+
|
| 1301 |
+
|
| 1302 |
+
- [x] RE-752 Protected completion with actual scoring and recipient dispatch ([report](research/QVM_PROTECTED_RESOLVED.md)).
|
docs/research/QVM_PROTECTED_RESOLVED.md
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Protected completion with actual scoring and recipient dispatch
|
| 2 |
+
|
| 3 |
+
RE-752. Reproduce with `python3 scripts/analyze_qvm_protected_resolved.py`; validate with `cargo xtask test-group resolved-protected`. See the [machine report](qvm-protected-resolved.json).
|
| 4 |
+
|
| 5 |
+
Composed protected completion with actual score and reset-notification loops across25 threshold/flag/mode/paused/in-use fixtures. Exact state oracles verify progress, attacker copy, client/team scores and recipient arguments. Optional lifecycle resolvers preserve prior default fixture behavior. Ranking5864, recipient179736, logging and original event allocation remain unresolved; full health/native/runtime integration remains open.
|
| 6 |
+
|
| 7 |
+
No original executable/full VM/native world collision or rendering runs. Supplied callback/native responses and fixture domains remain explicit; complete macOS/Linux Rust/Bevy/Solari gameplay remains open.
|
docs/research/README.md
CHANGED
|
@@ -852,3 +852,6 @@ The extension collector adds five focused tests for native tail calls, command-r
|
|
| 852 |
|
| 853 |
|
| 854 |
[RE-751: Complete cross client record clearing and inclusive index64](QVM_CROSS_CLIENT_CLEAR.md).
|
|
|
|
|
|
|
|
|
|
|
|
| 852 |
|
| 853 |
|
| 854 |
[RE-751: Complete cross client record clearing and inclusive index64](QVM_CROSS_CLIENT_CLEAR.md).
|
| 855 |
+
|
| 856 |
+
|
| 857 |
+
[RE-752: Protected completion with actual scoring and recipient dispatch](QVM_PROTECTED_RESOLVED.md).
|
docs/research/qvm-protected-resolved.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
scripts/analyze_qvm_protected_resolved.py
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""Actual152386 with actual205260 score and6369 recipient loops."""
|
| 3 |
+
import itertools
|
| 4 |
+
from pathlib import Path
|
| 5 |
+
from qvm_research_support import source
|
| 6 |
+
from qvm_resolved_lifecycle_support import seed,extra,resolvers
|
| 7 |
+
from qvm_lifecycle_support import probe
|
| 8 |
+
from analyze_qvm import write_json
|
| 9 |
+
|
| 10 |
+
def main():
|
| 11 |
+
q,raw,h,ins=source();rows=[]
|
| 12 |
+
cases=[dict(count=c,heat=10.75,flag=f,mode=m,paused=p) for c,f,m,p in itertools.product([31989,31990,32000],[0,1],[3,10],[0,1])]
|
| 13 |
+
cases += [dict(count=31990,heat=10.75,flag=0,mode=10,paused=0,active=0)]
|
| 14 |
+
for a in cases:
|
| 15 |
+
m=seed(raw,h,**a);before=extra(m);m,p=probe(ins,m,152387,152671,True,resolvers());p.update(input=a,extra_initial=before,extra_final=extra(m));rows.append(p)
|
| 16 |
+
write_json(Path('docs/research/qvm-protected-resolved.json'),{'source':q['source'],'sha256':q['sha256'],'probes':rows,'limits':'Actual152386 with actual205260/6369 over25 fixtures. Ranking5864, recipient179736,7259 and original event allocation remain captured/supplied. Nonnull attacker fixtures only; no original binary/native parity.'})
|
| 17 |
+
if __name__=='__main__':main()
|
scripts/qvm_lifecycle_support.py
CHANGED
|
@@ -20,7 +20,7 @@ def seed(raw,h,**a):
|
|
| 20 |
def snapshot(m):
|
| 21 |
return {'client':{str(o):m[CLIENT+o]&0xffffffff for o in FIELDS},'attacker_count':m[A_CLIENT+232]&0xffffffff,'entity':{str(o):m[TARGET+o]&0xffffffff for o in [684,720]},'attacker':{str(o):m[ATTACKER+o]&0xffffffff for o in [764,768]},'team_counts':[m[34999668]&0xffffffff,m[34999672]&0xffffffff]}
|
| 22 |
|
| 23 |
-
def handlers(effects):
|
| 24 |
def event(ins,m,args):
|
| 25 |
p=EVENT+len(effects['events'])*880
|
| 26 |
for o in range(0,880,4):m[p+o]=0
|
|
@@ -32,9 +32,9 @@ def handlers(effects):
|
|
| 32 |
return actual(ins,m,args)
|
| 33 |
def formatting(ins,m,args):
|
| 34 |
effects['requests'].append({'target':70458,'arguments':args,'native_effect_not_executed':True});return m,EVENT+0x10000,{'supplied_string_pointer':EVENT+0x10000}
|
| 35 |
-
hs.update({277695:event,33715:predicate,70458:formatting});return hs
|
| 36 |
|
| 37 |
-
def probe(ins,m,start,stop,protected=False):
|
| 38 |
before=snapshot(m);effects={'events':[],'requests':[]};end=152671 if protected else 207154
|
| 39 |
-
m,e=resume(ins,start,end,m,L,handlers=handlers(effects),boundaries=[] if stop==end else [stop],limit=50000)
|
| 40 |
return m,{'initial':before,'final':snapshot(m),'effects':effects,'events':[{**v,'fields':{str(o):m[v['pointer']+o]&0xffffffff for o in EFIELDS}} for v in effects['events']],'execution':e}
|
|
|
|
| 20 |
def snapshot(m):
|
| 21 |
return {'client':{str(o):m[CLIENT+o]&0xffffffff for o in FIELDS},'attacker_count':m[A_CLIENT+232]&0xffffffff,'entity':{str(o):m[TARGET+o]&0xffffffff for o in [684,720]},'attacker':{str(o):m[ATTACKER+o]&0xffffffff for o in [764,768]},'team_counts':[m[34999668]&0xffffffff,m[34999672]&0xffffffff]}
|
| 22 |
|
| 23 |
+
def handlers(effects,resolvers=None):
|
| 24 |
def event(ins,m,args):
|
| 25 |
p=EVENT+len(effects['events'])*880
|
| 26 |
for o in range(0,880,4):m[p+o]=0
|
|
|
|
| 32 |
return actual(ins,m,args)
|
| 33 |
def formatting(ins,m,args):
|
| 34 |
effects['requests'].append({'target':70458,'arguments':args,'native_effect_not_executed':True});return m,EVENT+0x10000,{'supplied_string_pointer':EVENT+0x10000}
|
| 35 |
+
hs.update({277695:event,33715:predicate,70458:formatting});hs.update(resolvers or {});return hs
|
| 36 |
|
| 37 |
+
def probe(ins,m,start,stop,protected=False,resolvers=None):
|
| 38 |
before=snapshot(m);effects={'events':[],'requests':[]};end=152671 if protected else 207154
|
| 39 |
+
m,e=resume(ins,start,end,m,L,handlers=handlers(effects,resolvers),boundaries=[] if stop==end else [stop],limit=50000)
|
| 40 |
return m,{'initial':before,'final':snapshot(m),'effects':effects,'events':[{**v,'fields':{str(o):m[v['pointer']+o]&0xffffffff for o in EFIELDS}} for v in effects['events']],'execution':e}
|
scripts/qvm_resolved_lifecycle_support.py
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Composable recovered score/recipient/stat/record children; boundaries explicit."""
|
| 2 |
+
from qvm_lifecycle_support import seed as lifecycle_seed,TARGET,ATTACKER,CLIENT,A_CLIENT
|
| 3 |
+
from qvm_score_support import score
|
| 4 |
+
from qvm_notification_support import notify,POOL,CPOOL
|
| 5 |
+
from qvm_stat_update_support import update,OFFSETS
|
| 6 |
+
from qvm_method_stats_support import method_seed
|
| 7 |
+
from qvm_record_clear_support import clear
|
| 8 |
+
from qvm_research_support import constants
|
| 9 |
+
|
| 10 |
+
def seed(raw,h,**a):
|
| 11 |
+
m=lifecycle_seed(raw,h,**a);m.update(method_seed(raw,h));m.update(constants(raw,h,range(31532,31684,4)))
|
| 12 |
+
m.update({TARGET+168:1,ATTACKER+168:2,TARGET+532:a.get('active',1),ATTACKER+532:1,34992512:a.get('paused',0),34081020:0,34992496:CPOOL,34992524:4,CLIENT+248:7,A_CLIENT+248:11,CLIENT+260:1,A_CLIENT+260:2})
|
| 13 |
+
for j in range(4):m[34992552+4*j]=100+j;m[CPOOL+6336*j+468]=[0,2,2,1][j]
|
| 14 |
+
for j in range(64):m[POOL+880*j+520]=CLIENT if j==1 else A_CLIENT if j==2 else 0
|
| 15 |
+
for c in [CLIENT,A_CLIENT]:
|
| 16 |
+
for o in OFFSETS:m[c+o]=5
|
| 17 |
+
for j in range(65):m[c+2520+8*j]=10+j;m[c+2524+8*j]=20+j
|
| 18 |
+
return m
|
| 19 |
+
|
| 20 |
+
def extra(m):
|
| 21 |
+
return {'scores':[m[CLIENT+248]&0xffffffff,m[A_CLIENT+248]&0xffffffff],'team_scores':[m[34992552+4*j]&0xffffffff for j in range(4)],'pair1':[[m[c+2528]&0xffffffff,m[c+2532]&0xffffffff] for c in [CLIENT,A_CLIENT]]}
|
| 22 |
+
|
| 23 |
+
def resolvers():
|
| 24 |
+
def reset(ins,m,args):return notify(ins,m,args)
|
| 25 |
+
def pair(ins,m,args):return notify(ins,m,args,True)
|
| 26 |
+
return {205260:score,6369:reset,6439:pair,278834:update,285486:clear}
|
scripts/test_qvm_protected_resolved.py
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import json,unittest
|
| 2 |
+
from pathlib import Path
|
| 3 |
+
from qvm_notification_support import POOL,TARGET
|
| 4 |
+
class ResolvedProtectedTests(unittest.TestCase):
|
| 5 |
+
@classmethod
|
| 6 |
+
def setUpClass(cls):cls.ps=json.loads(Path('docs/research/qvm-protected-resolved.json').read_text())['probes']
|
| 7 |
+
def test_progress_and_independent_score_mutations(self):
|
| 8 |
+
for p in self.ps:
|
| 9 |
+
a=p['input'];done=a['count']>=31990;n=0 if done else 31999;self.assertEqual(p['final']['client']['232'],n);self.assertEqual(p['final']['attacker_count'],n);self.assertEqual(p['final']['client']['6332'],0)
|
| 10 |
+
add=int(done and not a['flag'] and not a['paused']);r={**p['extra_initial'],'scores':[7+add,11],'team_scores':[100,101+add if a['mode']==3 else 101,102,103]};self.assertEqual(p['extra_final'],r,a)
|
| 11 |
+
def test_actual_children_and_remaining_request_boundaries(self):
|
| 12 |
+
for p in self.ps:
|
| 13 |
+
a=p['input'];children={c['call']['target']:c['effect'] for c in p['execution']['children']}
|
| 14 |
+
if a['count']>=31990 and not a['flag']:
|
| 15 |
+
score=children[205260];self.assertEqual(score['execution']['stop'],205328);self.assertEqual(len(score['requests']),int(not a['paused']))
|
| 16 |
+
reset=children[6369];self.assertEqual(reset['execution']['stop'],6437);self.assertEqual([c['arguments'] for c in reset['requests']],[{'8':TARGET,'12':POOL+880*j} for j in [1,2]] if a.get('active',1) else [])
|
| 17 |
+
self.assertNotIn(205260,[c['target'] for c in p['effects']['requests']]);self.assertNotIn(6369,[c['target'] for c in p['effects']['requests']])
|
| 18 |
+
def test_complete_source_exit_and_fixture_count(self):
|
| 19 |
+
self.assertEqual(len(self.ps),25)
|
| 20 |
+
for p in self.ps:self.assertEqual(p['execution']['stop'],152671)
|
| 21 |
+
if __name__=='__main__':unittest.main()
|
xtask/checks.tsv
CHANGED
|
@@ -1236,3 +1236,6 @@ group stat-updates scripts/analyze_qvm_method_stat_updates.py
|
|
| 1236 |
report scripts/analyze_qvm_cross_client_clear.py docs/research/qvm-cross-client-clear.json
|
| 1237 |
edge docs/research/qvm-cross-client-clear.json scripts/test_qvm_cross_client_clear.py
|
| 1238 |
group record-clear scripts/analyze_qvm_cross_client_clear.py
|
|
|
|
|
|
|
|
|
|
|
|
| 1236 |
report scripts/analyze_qvm_cross_client_clear.py docs/research/qvm-cross-client-clear.json
|
| 1237 |
edge docs/research/qvm-cross-client-clear.json scripts/test_qvm_cross_client_clear.py
|
| 1238 |
group record-clear scripts/analyze_qvm_cross_client_clear.py
|
| 1239 |
+
report scripts/analyze_qvm_protected_resolved.py docs/research/qvm-protected-resolved.json
|
| 1240 |
+
edge docs/research/qvm-protected-resolved.json scripts/test_qvm_protected_resolved.py
|
| 1241 |
+
group resolved-protected scripts/analyze_qvm_protected_resolved.py
|