qvm: resolve defuse completion score and counters
Browse files- docs/FINDINGS.md +2 -0
- docs/PROVISIONAL_TODO.md +2 -0
- docs/RESEARCH_LEDGER.md +4 -0
- docs/REVERSE_ENGINEERING_TODO.md +2 -0
- docs/research/QVM_EFFECT_DEFUSE_FINISH.md +5 -0
- docs/research/README.md +2 -0
- docs/research/qvm-effect-defuse-finish.json +0 -0
- docs/research/qvm-resumer-audit.json +14 -3
- scripts/analyze_qvm_effect_defuse_finish.py +12 -0
- scripts/qvm_effect_feedback_oracle.py +35 -0
- scripts/qvm_effect_feedback_support.py +56 -0
- scripts/test_qvm_effect_defuse_finish.py +13 -0
- xtask/checks.tsv +4 -0
docs/FINDINGS.md
CHANGED
|
@@ -1995,3 +1995,5 @@ RE-1025: Rust implements caller-indexed wrapping counter increments across12 sou
|
|
| 1995 |
RE-1026: Thirty-four original-QVM scenarios recover193620 with actual mode classifier33715. Live non-following non-spectator sender obtains supplied location text, then sends rsay sender/-1/type/text to connected same-team recipients in team modes or mode9. Mode11 and signed negative modes do not route. Sender marker84 becomes tick+3500 and marker204 becomes1 only when a command is sent. Empty/quoted payloads, failed text lookup, zero/64 counts and wrap are covered. Native sending and location lookup remain boundaries; fixed formatter is modeled. [Evidence](research/QVM_EFFECT_RADIO.md).
|
| 1996 |
|
| 1997 |
RE-1027: Rust matches34 source team-radio scenarios, including the mode9 exception, mode11/signed exclusions, failed location text, raw quote preservation and64-recipient tables. Only actual sends update an existing marker; empty routing leaves it unchanged. Tests cover connected same-team routing, wrapped marker deadlines and invalid payload atomicity. Text location and native network sends remain boundaries. [Evidence](research/RUST_EFFECT_RADIO.md).
|
|
|
|
|
|
|
|
|
| 1995 |
RE-1026: Thirty-four original-QVM scenarios recover193620 with actual mode classifier33715. Live non-following non-spectator sender obtains supplied location text, then sends rsay sender/-1/type/text to connected same-team recipients in team modes or mode9. Mode11 and signed negative modes do not route. Sender marker84 becomes tick+3500 and marker204 becomes1 only when a command is sent. Empty/quoted payloads, failed text lookup, zero/64 counts and wrap are covered. Native sending and location lookup remain boundaries; fixed formatter is modeled. [Evidence](research/QVM_EFFECT_RADIO.md).
|
| 1996 |
|
| 1997 |
RE-1027: Rust matches34 source team-radio scenarios, including the mode9 exception, mode11/signed exclusions, failed location text, raw quote preservation and64-recipient tables. Only actual sends update an existing marker; empty routing leaves it unchanged. Tests cover connected same-team routing, wrapped marker deadlines and invalid payload atomicity. Text location and native network sends remain boundaries. [Evidence](research/RUST_EFFECT_RADIO.md).
|
| 1998 |
+
|
| 1999 |
+
RE-1028: Sixty-four source probes execute defuse completion with actual205260 and283463. Ready completion adds one player score point and requests ranking unless paused, then increments counter index5 by1 regardless of pause. Both score and counter wrap independently. Waiting does neither. Corrected ordered requests are log, allocate, score, optional rank, counter; allocation/log/ranking remain boundaries. This replaces the earlier misleading teleport/five-point labels with actual state feedback. [Evidence](research/QVM_EFFECT_DEFUSE_FINISH.md).
|
docs/PROVISIONAL_TODO.md
CHANGED
|
@@ -2055,3 +2055,5 @@ RE-974–983 completed routing, command rewrite, inactivity, movement-parameter
|
|
| 2055 |
- [x] RE-1026 Recover team radio routing and marker state ([evidence](research/QVM_EFFECT_RADIO.md)).
|
| 2056 |
|
| 2057 |
- [x] RE-1027 Port team radio command planning and marker feedback ([evidence](research/RUST_EFFECT_RADIO.md)).
|
|
|
|
|
|
|
|
|
| 2055 |
- [x] RE-1026 Recover team radio routing and marker state ([evidence](research/QVM_EFFECT_RADIO.md)).
|
| 2056 |
|
| 2057 |
- [x] RE-1027 Port team radio command planning and marker feedback ([evidence](research/RUST_EFFECT_RADIO.md)).
|
| 2058 |
+
|
| 2059 |
+
- [x] RE-1028 Resolve defuse completion score and objective counter ([evidence](research/QVM_EFFECT_DEFUSE_FINISH.md)).
|
docs/RESEARCH_LEDGER.md
CHANGED
|
@@ -2783,3 +2783,7 @@ Thirty-four original-QVM scenarios recover193620 with actual mode classifier3371
|
|
| 2783 |
## 2026-10-29 — RE-1027 Port team radio command planning and marker feedback
|
| 2784 |
|
| 2785 |
Rust matches34 source team-radio scenarios, including the mode9 exception, mode11/signed exclusions, failed location text, raw quote preservation and64-recipient tables. Only actual sends update an existing marker; empty routing leaves it unchanged. Tests cover connected same-team routing, wrapped marker deadlines and invalid payload atomicity. Text location and native network sends remain boundaries. Focused `cargo xtask test-group rust-effect-radio` passes with deterministic report regeneration and selected regressions. Full suite deferred to task ten. Original assets unchanged; Python uses the flake-declared Nix runtime.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2783 |
## 2026-10-29 — RE-1027 Port team radio command planning and marker feedback
|
| 2784 |
|
| 2785 |
Rust matches34 source team-radio scenarios, including the mode9 exception, mode11/signed exclusions, failed location text, raw quote preservation and64-recipient tables. Only actual sends update an existing marker; empty routing leaves it unchanged. Tests cover connected same-team routing, wrapped marker deadlines and invalid payload atomicity. Text location and native network sends remain boundaries. Focused `cargo xtask test-group rust-effect-radio` passes with deterministic report regeneration and selected regressions. Full suite deferred to task ten. Original assets unchanged; Python uses the flake-declared Nix runtime.
|
| 2786 |
+
|
| 2787 |
+
## 2026-10-29 — RE-1028 Resolve defuse completion score and objective counter
|
| 2788 |
+
|
| 2789 |
+
Sixty-four source probes execute defuse completion with actual205260 and283463. Ready completion adds one player score point and requests ranking unless paused, then increments counter index5 by1 regardless of pause. Both score and counter wrap independently. Waiting does neither. Corrected ordered requests are log, allocate, score, optional rank, counter; allocation/log/ranking remain boundaries. This replaces the earlier misleading teleport/five-point labels with actual state feedback. Focused `cargo xtask test-group qvm-effect-defuse-finish` passes with deterministic report regeneration and selected regressions. Full suite deferred to task ten. Original assets unchanged; Python uses the flake-declared Nix runtime.
|
docs/REVERSE_ENGINEERING_TODO.md
CHANGED
|
@@ -2092,3 +2092,5 @@ RE-974–983 recover routing, command rewriting, inactivity and composed setup t
|
|
| 2092 |
- [x] RE-1026 Recover team radio routing and marker state ([evidence](research/QVM_EFFECT_RADIO.md)).
|
| 2093 |
|
| 2094 |
- [x] RE-1027 Port team radio command planning and marker feedback ([evidence](research/RUST_EFFECT_RADIO.md)).
|
|
|
|
|
|
|
|
|
| 2092 |
- [x] RE-1026 Recover team radio routing and marker state ([evidence](research/QVM_EFFECT_RADIO.md)).
|
| 2093 |
|
| 2094 |
- [x] RE-1027 Port team radio command planning and marker feedback ([evidence](research/RUST_EFFECT_RADIO.md)).
|
| 2095 |
+
|
| 2096 |
+
- [x] RE-1028 Resolve defuse completion score and objective counter ([evidence](research/QVM_EFFECT_DEFUSE_FINISH.md)).
|
docs/research/QVM_EFFECT_DEFUSE_FINISH.md
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Resolve defuse completion score and objective counter
|
| 2 |
+
|
| 3 |
+
RE-1028. Focused validation: `cargo xtask test-group qvm-effect-defuse-finish`. [Machine report](qvm-effect-defuse-finish.json).
|
| 4 |
+
|
| 5 |
+
Sixty-four source probes execute defuse completion with actual205260 and283463. Ready completion adds one player score point and requests ranking unless paused, then increments counter index5 by1 regardless of pause. Both score and counter wrap independently. Waiting does neither. Corrected ordered requests are log, allocate, score, optional rank, counter; allocation/log/ranking remain boundaries. This replaces the earlier misleading teleport/five-point labels with actual state feedback.
|
docs/research/README.md
CHANGED
|
@@ -1623,3 +1623,5 @@ The extension collector adds five focused tests for native tail calls, command-r
|
|
| 1623 |
- [RE-1026: Recover team radio routing and marker state](QVM_EFFECT_RADIO.md).
|
| 1624 |
|
| 1625 |
- [RE-1027: Port team radio command planning and marker feedback](RUST_EFFECT_RADIO.md).
|
|
|
|
|
|
|
|
|
| 1623 |
- [RE-1026: Recover team radio routing and marker state](QVM_EFFECT_RADIO.md).
|
| 1624 |
|
| 1625 |
- [RE-1027: Port team radio command planning and marker feedback](RUST_EFFECT_RADIO.md).
|
| 1626 |
+
|
| 1627 |
+
- [RE-1028: Resolve defuse completion score and objective counter](QVM_EFFECT_DEFUSE_FINISH.md).
|
docs/research/qvm-effect-defuse-finish.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
docs/research/qvm-resumer-audit.json
CHANGED
|
@@ -9033,6 +9033,17 @@
|
|
| 9033 |
"repeated_calls_opt_in": true,
|
| 9034 |
"repeated_calls_setting": "literal_true"
|
| 9035 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9036 |
{
|
| 9037 |
"backward_conditional_branches": [],
|
| 9038 |
"calls": [],
|
|
@@ -10640,10 +10651,10 @@
|
|
| 10640 |
}
|
| 10641 |
},
|
| 10642 |
"summary": {
|
| 10643 |
-
"call_expressions":
|
| 10644 |
-
"files":
|
| 10645 |
"legacy_expressions": 158,
|
| 10646 |
-
"nonliteral_ranges":
|
| 10647 |
"unresolved_mode_expressions": 3
|
| 10648 |
}
|
| 10649 |
}
|
|
|
|
| 9033 |
"repeated_calls_opt_in": true,
|
| 9034 |
"repeated_calls_setting": "literal_true"
|
| 9035 |
},
|
| 9036 |
+
{
|
| 9037 |
+
"backward_conditional_branches": [],
|
| 9038 |
+
"calls": [],
|
| 9039 |
+
"explicit_result_offsets": null,
|
| 9040 |
+
"helper": "qvm_trace_support.resume",
|
| 9041 |
+
"line": 118,
|
| 9042 |
+
"literal_range": null,
|
| 9043 |
+
"path": "scripts/qvm_effect_feedback_support.py",
|
| 9044 |
+
"repeated_calls_opt_in": true,
|
| 9045 |
+
"repeated_calls_setting": "literal_true"
|
| 9046 |
+
},
|
| 9047 |
{
|
| 9048 |
"backward_conditional_branches": [],
|
| 9049 |
"calls": [],
|
|
|
|
| 10651 |
}
|
| 10652 |
},
|
| 10653 |
"summary": {
|
| 10654 |
+
"call_expressions": 215,
|
| 10655 |
+
"files": 164,
|
| 10656 |
"legacy_expressions": 158,
|
| 10657 |
+
"nonliteral_ranges": 32,
|
| 10658 |
"unresolved_mode_expressions": 3
|
| 10659 |
}
|
| 10660 |
}
|
scripts/analyze_qvm_effect_defuse_finish.py
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Verified original movement-context source contract."""
|
| 2 |
+
from pathlib import Path
|
| 3 |
+
from analyze_qvm import write_json
|
| 4 |
+
from qvm_research_support import source
|
| 5 |
+
from qvm_effect_feedback_support import seed,finish,finish_fixtures
|
| 6 |
+
|
| 7 |
+
def main():
|
| 8 |
+
q,raw,h,ins=source();probes=[]
|
| 9 |
+
for a in finish_fixtures():
|
| 10 |
+
m,b=seed(raw,h,a);m,p,b=finish(ins,m,b,a);p['input']=a;probes.append(p)
|
| 11 |
+
write_json(Path('docs/research/qvm-effect-defuse-finish.json'),dict(source=q['source'],sha256=q['sha256'],probes=probes,limits='Active defuse153644 with actual205260 score and283463 counter bodies. Ranking5864/log captured and event allocation supplied. Pause affects score only; no teleport execution occurs.'))
|
| 12 |
+
if __name__=='__main__':main()
|
scripts/qvm_effect_feedback_oracle.py
CHANGED
|
@@ -16,3 +16,38 @@ def radio(a):
|
|
| 16 |
if j==2:team=a['team']
|
| 17 |
if connection==2 and (team_mode or mode==9) and team==a['team']:commands.append(dict(slot=j,text=text))
|
| 18 |
return dict(commands=commands,getter_calls=int(active),marker=[(a['tick']+3500)&0xffffffff,1] if commands and a['marker'] else [17,18])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 16 |
if j==2:team=a['team']
|
| 17 |
if connection==2 and (team_mode or mode==9) and team==a['team']:commands.append(dict(slot=j,text=text))
|
| 18 |
return dict(commands=commands,getter_calls=int(active),marker=[(a['tick']+3500)&0xffffffff,1] if commands and a['marker'] else [17,18])
|
| 19 |
+
|
| 20 |
+
def resolve(a,parent):
|
| 21 |
+
import copy
|
| 22 |
+
out=copy.deepcopy(parent);events=[];radios=[];score=0xffffffff;counters=[100+j for j in range(15)];counters[5]=0xffffffff;marker=[17,18];record=None
|
| 23 |
+
for e in parent['events']:
|
| 24 |
+
op=e['op']
|
| 25 |
+
if op=='teleport':
|
| 26 |
+
events.append(dict(op='score',delta=1))
|
| 27 |
+
if not a['paused']:score=0;events.append(dict(op='rank'))
|
| 28 |
+
elif op=='award':counters[5]=0;events.append(dict(op='counter',index=5))
|
| 29 |
+
elif op=='sound':
|
| 30 |
+
events.append(dict(op='radio',code=7))
|
| 31 |
+
if 'selector' in a:
|
| 32 |
+
selected=2 if a['selector']==1 else 1;team=a['team'] or selected
|
| 33 |
+
clients=[[2,selected] for _ in range(max(3,a['count']))];clients[a['busy_slot']]=[a['other_connection'],a['other_team'] or selected];clients[2]=[a['connection'],team]
|
| 34 |
+
else:team=1;clients=[[2,1],[2,2],[2,1],[1,2]]
|
| 35 |
+
payload=bytes.fromhex(a['payload']) if a['success'] else b'';text=(b'rsay 2 -1 7 "'+payload+b'"').hex()
|
| 36 |
+
commands=[dict(slot=j,text=text) for j,c in enumerate(clients[:a.get('count',4)]) if c[0]==2 and c[1]==team]
|
| 37 |
+
if commands and a['marker']:marker=[(a['tick']+3500)&0xffffffff,1]
|
| 38 |
+
radios.append(dict(commands=commands,getter_calls=1,marker=list(marker)))
|
| 39 |
+
else:
|
| 40 |
+
events.append(e)
|
| 41 |
+
if op=='allocate' and a['constructed']:
|
| 42 |
+
from analyze_qvm_acceleration import word
|
| 43 |
+
origin=a['origin'];snap=[word(float(int(v))) for v in origin];init=0x13579bdf
|
| 44 |
+
record={str(o):init for o in [4,12,16,20,24,28,32,36,40,44,84,140,400,424,488,492,496,536,540,568,572]}
|
| 45 |
+
record.update({'4':e['event']+19,'12':0,'16':0,'20':0,'36':0,'40':0,'44':0,'424':out['event'][1],'536':97191,'540':662184166,'568':a['tick'],'572':1})
|
| 46 |
+
for j,v in enumerate(snap):record[str(24+4*j)]=v;record[str(488+4*j)]=v
|
| 47 |
+
events.append(dict(op='link'))
|
| 48 |
+
out.update(events=events,score=score,teams=[100,101,102,103],counters=counters,radio=radios,marker=marker,event_record=record)
|
| 49 |
+
return out
|
| 50 |
+
|
| 51 |
+
def finish(a):
|
| 52 |
+
from qvm_defuse_oracle import finish
|
| 53 |
+
return resolve(a,finish(a))
|
scripts/qvm_effect_feedback_support.py
CHANGED
|
@@ -62,3 +62,59 @@ def radio_run(ins,m,b,code,payload,success):
|
|
| 62 |
return m,dict(commands=commands,getter_calls=len(getters),marker=[m[MARK+84]&0xffffffff,m[MARK+204]&0xffffffff],execution=p['execution']),b
|
| 63 |
|
| 64 |
def radio(ins,m,b,a):radio_seed(m,b,a);return radio_run(ins,m,b,a['code'],bytes.fromhex(a['payload']),a['success'])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 62 |
return m,dict(commands=commands,getter_calls=len(getters),marker=[m[MARK+84]&0xffffffff,m[MARK+204]&0xffffffff],execution=p['execution']),b
|
| 63 |
|
| 64 |
def radio(ins,m,b,a):radio_seed(m,b,a);return radio_run(ins,m,b,a['code'],bytes.fromhex(a['payload']),a['success'])
|
| 65 |
+
|
| 66 |
+
EVENT_FIELDS=[4,12,16,20,24,28,32,36,40,44,84,140,400,424,488,492,496,536,540,568,572]
|
| 67 |
+
|
| 68 |
+
def finish_fixtures():
|
| 69 |
+
from qvm_defuse_support import finish_fixtures as fixtures
|
| 70 |
+
return [dict(a,paused=paused,constructed=0,marker=1,success=1,payload=b'Bomb site'.hex(),origin=[1.9,-1.9,-0.]) for a in fixtures() for paused in [0,1]]
|
| 71 |
+
|
| 72 |
+
def feedback_seed(m,b,a,full=False):
|
| 73 |
+
for o in range(0,880,4):m.setdefault(ALLOC+o,0x13579bdf)
|
| 74 |
+
m.update({CLIENT+248:0xffffffff,CLIENT+260:1,34992512:a['paused'],34090788:8,34081020:0,CLIENT+6168:MARK if a['marker'] else 0,MARK+84:17,MARK+204:18})
|
| 75 |
+
for j in range(4):m[34992552+4*j]=100+j
|
| 76 |
+
for j in range(15):m[CLIENT+3036+4*j]=100+j
|
| 77 |
+
m[CLIENT+3056]=0xffffffff
|
| 78 |
+
if not full:
|
| 79 |
+
m.update({CLIENT+208:1,CLIENT+4324:0,CLIENT+3096:1,34992524:4})
|
| 80 |
+
for j in range(4):m[POOL+880*j+520]=CPOOL+6336*j;m[CPOOL+6336*j+468]=2 if j!=3 else 1;m[CPOOL+6336*j+3096]=1 if j%2==0 else 2
|
| 81 |
+
for j,v in enumerate(a['origin']):m[BOMB+24+4*j]=word(v)
|
| 82 |
+
write_bytes(m,b,{RADIO+32+j:77 for j in range(156)})
|
| 83 |
+
|
| 84 |
+
def resolved_handlers(events,radios,a):
|
| 85 |
+
def log(i,m,args,bs):events.append(dict(op='log',format=cstring(m,bs,args[8]).hex(),slot=args[12]));return m,0,{'captured_log':7259}
|
| 86 |
+
def score(i,m,args,bs):
|
| 87 |
+
assert args[8]==ENTITY and args[12]==ENTITY+488 and args[16]==1
|
| 88 |
+
events.append(dict(op='score',delta=1))
|
| 89 |
+
def rank(i,m,args,b):events.append(dict(op='rank'));return m,0,{'ranking_captured':5864}
|
| 90 |
+
m,v,p,b=run(i,m,205260,205328,16,args,dict(bs),{5864:rank},base=ROOT+0x190000)
|
| 91 |
+
return m,0,{'actual_source_child':205260}
|
| 92 |
+
def counter_(i,m,args,bs):
|
| 93 |
+
assert args[8]==ENTITY and args[12]==5
|
| 94 |
+
m,v,p,b=run(i,m,283463,283486,12,args,dict(bs),base=ROOT+0x1a0000);events.append(dict(op='counter',index=5))
|
| 95 |
+
return m,0,{'actual_source_child':283463}
|
| 96 |
+
def radio_(i,m,args,bs):
|
| 97 |
+
assert args[8]==7 and args[12]==ENTITY
|
| 98 |
+
events.append(dict(op='radio',code=7));m,p,b=radio_run(i,m,dict(bs),7,bytes.fromhex(a['payload']),a['success']);radios.append(p)
|
| 99 |
+
return m,0,{'actual_source_child':193620}
|
| 100 |
+
def allocate(i,m,args,bs):
|
| 101 |
+
events.append(dict(op='allocate',event=args[12]))
|
| 102 |
+
if not a['constructed']:return m,ALLOC,{'supplied_event_entity':True}
|
| 103 |
+
def alloc(i,m,args,b):return m,ALLOC,{'allocator277165_supplied':True}
|
| 104 |
+
def origin(i,m,args,b):
|
| 105 |
+
m,v,p,b=run(i,m,278138,278199,16,args,dict(b),base=ROOT+0x1b0000);return m,0,{'actual_source_child':278138}
|
| 106 |
+
def link(i,m,args,b):events.append(dict(op='link'));return m,0,{'native_link_captured':True}
|
| 107 |
+
m,v,p,b=run(i,m,277695,277777,36,args,dict(bs),{277165:alloc,278138:origin,-31:link},base=ROOT+0x1c0000)
|
| 108 |
+
return m,v,{'actual_source_child':277695}
|
| 109 |
+
return {7259:log,205260:score,283463:counter_,193620:radio_,277695:allocate}
|
| 110 |
+
|
| 111 |
+
def feedback_view(m,radios,a,events):
|
| 112 |
+
return dict(events=events,score=m[CLIENT+248]&0xffffffff,teams=[m[34992552+4*j]&0xffffffff for j in range(4)],counters=[m[CLIENT+3036+4*j]&0xffffffff for j in range(15)],radio=[{k:p[k] for k in ['commands','getter_calls','marker']} for p in radios],marker=[m[MARK+84]&0xffffffff,m[MARK+204]&0xffffffff],event_record={str(o):m[ALLOC+o]&0xffffffff for o in EVENT_FIELDS} if a['constructed'] and any(e['op']=='allocate' for e in events) else None)
|
| 113 |
+
|
| 114 |
+
def resolved_fragment(ins,m,b,a,start):
|
| 115 |
+
from qvm_defuse_support import state_seed
|
| 116 |
+
from qvm_trace_support import resume
|
| 117 |
+
state_seed(m,a);feedback_seed(m,b,a);m,b=frame_args(m,b,{DEFUSE_BASE+28:CLIENT,DEFUSE_BASE+32:BOMB,DEFUSE_BASE+100:ENTITY});events=[];radios=[]
|
| 118 |
+
m,p=resume(ins,start,154088,m,DEFUSE_BASE,boundaries=(154087,),handlers=resolved_handlers(events,radios,a),byte_inputs=b,repeated_calls=True,sync_child_words=True,coherent_memory=True,byte_handlers=True,capture_byte_memory=True,limit=32768)
|
| 119 |
+
return m,dict(**defuse_view(m,a),**feedback_view(m,radios,a,events),execution={k:p[k] for k in ['stop','trace_length','trace_sha256']}),p['byte_memory']
|
| 120 |
+
def finish(ins,m,b,a):return resolved_fragment(ins,m,b,a,153644)
|
scripts/test_qvm_effect_defuse_finish.py
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import json,unittest
|
| 2 |
+
from pathlib import Path
|
| 3 |
+
from qvm_effect_feedback_oracle import finish
|
| 4 |
+
class OriginalTests(unittest.TestCase):
|
| 5 |
+
def test_original_contract(self):
|
| 6 |
+
rows=json.loads(Path('docs/research/qvm-effect-defuse-finish.json').read_text())['probes'];self.assertEqual(len(rows),64)
|
| 7 |
+
for p in rows:
|
| 8 |
+
with self.subTest(input=p['input']):
|
| 9 |
+
for k,v in finish(p['input']).items():self.assertEqual(p[k],v,k)
|
| 10 |
+
def test_fixture_identity_and_trace(self):
|
| 11 |
+
r=json.loads(Path('docs/research/qvm-effect-defuse-finish.json').read_text());self.assertEqual(len(r['sha256']),64)
|
| 12 |
+
self.assertTrue(all(p['execution']['trace_length']>0 for p in r['probes']))
|
| 13 |
+
if __name__=='__main__':unittest.main()
|
xtask/checks.tsv
CHANGED
|
@@ -4396,3 +4396,7 @@ edge crates/urt-gameplay/src/effect_feedback.rs scripts/analyze_rust_effect_radi
|
|
| 4396 |
edge crates/urt-gameplay/src/bin/urt-effect-feedback.rs scripts/analyze_rust_effect_radio.py
|
| 4397 |
edge crates/urt-gameplay/src/score.rs scripts/analyze_rust_effect_radio.py
|
| 4398 |
edge crates/urt-gameplay/src/transition.rs scripts/analyze_rust_effect_radio.py
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4396 |
edge crates/urt-gameplay/src/bin/urt-effect-feedback.rs scripts/analyze_rust_effect_radio.py
|
| 4397 |
edge crates/urt-gameplay/src/score.rs scripts/analyze_rust_effect_radio.py
|
| 4398 |
edge crates/urt-gameplay/src/transition.rs scripts/analyze_rust_effect_radio.py
|
| 4399 |
+
report scripts/analyze_qvm_effect_defuse_finish.py docs/research/qvm-effect-defuse-finish.json
|
| 4400 |
+
edge docs/research/qvm-effect-defuse-finish.json scripts/test_qvm_effect_defuse_finish.py
|
| 4401 |
+
group qvm-effect-defuse-finish scripts/analyze_qvm_effect_defuse_finish.py
|
| 4402 |
+
edge scripts/analyze_qvm_effect_defuse_finish.py scripts/analyze_qvm_resumer_audit.py
|