qvm: recover early client routing gates
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_CLIENT_ROUTING.md +5 -0
- docs/research/README.md +2 -0
- docs/research/qvm-client-routing.json +355 -0
- docs/research/qvm-resumer-audit.json +14 -3
- scripts/analyze_qvm_client_routing.py +12 -0
- scripts/qvm_client_processing_oracle.py +8 -0
- scripts/qvm_client_processing_support.py +37 -0
- scripts/test_qvm_client_routing.py +12 -0
- xtask/checks.tsv +4 -0
docs/FINDINGS.md
CHANGED
|
@@ -1879,3 +1879,5 @@ RE-971: Rust matches16 whole original timer cases, composing the shared residual
|
|
| 1879 |
RE-972: Ninety-six original154089-prefix cases recover connection-word gating, original command timestamp copies, command-time bounds, signed delta calculation/cap and the word3108==2 exception for nonpositive deltas. Optional8ms rounding occurs after the delta and does not recompute it. Execution stops at154210 or the verified early-return boundary155716; intervening caller processing and dispatch155714 are not skipped or claimed recovered. [Evidence](research/QVM_CLIENT_TIMER_PREPARE.md).
|
| 1880 |
|
| 1881 |
RE-973: Rust matches96 original caller-prefix cases, preserving connection-word gating, pre-clamp timestamp copies, signed wrapping bounds, the nonpositive-delta exception,200ms cap and post-delta8ms rounding. Unit tests cover unchanged disconnected state, retained pre-round delta, negative exception deltas and sequential bounds at signed wrap. The remaining caller body and actual timer dispatch are explicitly unrecovered. [Evidence](research/RUST_CLIENT_TIMER_PREPARE.md).
|
|
|
|
|
|
|
|
|
| 1879 |
RE-972: Ninety-six original154089-prefix cases recover connection-word gating, original command timestamp copies, command-time bounds, signed delta calculation/cap and the word3108==2 exception for nonpositive deltas. Optional8ms rounding occurs after the delta and does not recompute it. Execution stops at154210 or the verified early-return boundary155716; intervening caller processing and dispatch155714 are not skipped or claimed recovered. [Evidence](research/QVM_CLIENT_TIMER_PREPARE.md).
|
| 1880 |
|
| 1881 |
RE-973: Rust matches96 original caller-prefix cases, preserving connection-word gating, pre-clamp timestamp copies, signed wrapping bounds, the nonpositive-delta exception,200ms cap and post-delta8ms rounding. Unit tests cover unchanged disconnected state, retained pre-round delta, negative exception deltas and sequential bounds at signed wrap. The remaining caller body and actual timer dispatch are explicitly unrecovered. [Evidence](research/RUST_CLIENT_TIMER_PREPARE.md).
|
| 1882 |
+
|
| 1883 |
+
RE-974: Sixteen source154210-prefix paths recover intermission precedence, team3/follow gates and spectator-word3 callback suppression. Normal paths stop at154256; routed paths stop at the original early return155716. Callback151133/149671 effects remain captured, with their client/command inputs recorded. Later command and movement processing are outside this first contract. [Evidence](research/QVM_CLIENT_ROUTING.md).
|
docs/PROVISIONAL_TODO.md
CHANGED
|
@@ -1933,3 +1933,5 @@ RE-954–963 completed add/remove wrappers, resolved duration export, full-capac
|
|
| 1933 |
- [x] RE-973 Rust caller timestamp preparation and delta semantics ([evidence](research/RUST_CLIENT_TIMER_PREPARE.md)).
|
| 1934 |
|
| 1935 |
RE-964–973 completed timer deadline/phase/recovery contracts, whole-body composition and caller timing preparation. RE-974 tracks remaining caller paths, damage feedback and native/runtime integration. [Batch and next work](research/QVM_CLIENT_TIMER_BATCH.md).
|
|
|
|
|
|
|
|
|
| 1933 |
- [x] RE-973 Rust caller timestamp preparation and delta semantics ([evidence](research/RUST_CLIENT_TIMER_PREPARE.md)).
|
| 1934 |
|
| 1935 |
RE-964–973 completed timer deadline/phase/recovery contracts, whole-body composition and caller timing preparation. RE-974 tracks remaining caller paths, damage feedback and native/runtime integration. [Batch and next work](research/QVM_CLIENT_TIMER_BATCH.md).
|
| 1936 |
+
|
| 1937 |
+
- [x] RE-974 Original client intermission and spectator routing ([evidence](research/QVM_CLIENT_ROUTING.md)).
|
docs/RESEARCH_LEDGER.md
CHANGED
|
@@ -2565,3 +2565,7 @@ Ninety-six original154089-prefix cases recover connection-word gating, original
|
|
| 2565 |
Rust matches96 original caller-prefix cases, preserving connection-word gating, pre-clamp timestamp copies, signed wrapping bounds, the nonpositive-delta exception,200ms cap and post-delta8ms rounding. Unit tests cover unchanged disconnected state, retained pre-round delta, negative exception deltas and sequential bounds at signed wrap. The remaining caller body and actual timer dispatch are explicitly unrecovered. Focused `cargo xtask test-group rust-client-timer-prepare` passes with deterministic report regeneration, relevant regressions and storage/documentation/whitespace checks. Full suite deferred to the tenth-commit boundary. Original assets unchanged; native IO effects remain captured.
|
| 2566 |
|
| 2567 |
Batch RE-964–973 boundary: the single `cargo xtask test-full --since c1e91e2e` run after commit ten passed with the flake-declared Nix Python: 1,878 Python tests, 270 Rust tests (assets10, gameplay230, xtask30), 106 deterministic report producers, storage policy, 546 documentation files and whitespace guards. No generated report drift. Focused dependency-selection regression covers all five new source/Rust pairs and shared timer/command/loading/lifecycle/native-policy/formatter inputs, including scoped gameplay test-count metadata. Validation notes were amended into task ten; original assets unchanged. See [batch findings and next work](research/QVM_CLIENT_TIMER_BATCH.md).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2565 |
Rust matches96 original caller-prefix cases, preserving connection-word gating, pre-clamp timestamp copies, signed wrapping bounds, the nonpositive-delta exception,200ms cap and post-delta8ms rounding. Unit tests cover unchanged disconnected state, retained pre-round delta, negative exception deltas and sequential bounds at signed wrap. The remaining caller body and actual timer dispatch are explicitly unrecovered. Focused `cargo xtask test-group rust-client-timer-prepare` passes with deterministic report regeneration, relevant regressions and storage/documentation/whitespace checks. Full suite deferred to the tenth-commit boundary. Original assets unchanged; native IO effects remain captured.
|
| 2566 |
|
| 2567 |
Batch RE-964–973 boundary: the single `cargo xtask test-full --since c1e91e2e` run after commit ten passed with the flake-declared Nix Python: 1,878 Python tests, 270 Rust tests (assets10, gameplay230, xtask30), 106 deterministic report producers, storage policy, 546 documentation files and whitespace guards. No generated report drift. Focused dependency-selection regression covers all five new source/Rust pairs and shared timer/command/loading/lifecycle/native-policy/formatter inputs, including scoped gameplay test-count metadata. Validation notes were amended into task ten; original assets unchanged. See [batch findings and next work](research/QVM_CLIENT_TIMER_BATCH.md).
|
| 2568 |
+
|
| 2569 |
+
## 2026-10-28 — RE-974 Original client intermission and spectator routing
|
| 2570 |
+
|
| 2571 |
+
Sixteen source154210-prefix paths recover intermission precedence, team3/follow gates and spectator-word3 callback suppression. Normal paths stop at154256; routed paths stop at the original early return155716. Callback151133/149671 effects remain captured, with their client/command inputs recorded. Later command and movement processing are outside this first contract. Focused `cargo xtask test-group qvm-client-routing` passes with deterministic report regeneration, relevant regressions and storage/documentation/whitespace checks. Full suite deferred to the tenth-commit boundary. Original assets unchanged; native IO effects remain captured.
|
docs/REVERSE_ENGINEERING_TODO.md
CHANGED
|
@@ -1970,3 +1970,5 @@ RE-964–973 recover the complete bounded timer body and its caller timing prefi
|
|
| 1970 |
- [x] RE-973 Rust caller timestamp preparation and delta semantics ([evidence](research/RUST_CLIENT_TIMER_PREPARE.md)).
|
| 1971 |
|
| 1972 |
- [ ] RE-974 Recover the remaining timer caller, damage feedback, initialization/native ownership and full Rust/Bevy/Solari acceptance ([next work](research/QVM_CLIENT_TIMER_BATCH.md)).
|
|
|
|
|
|
|
|
|
| 1970 |
- [x] RE-973 Rust caller timestamp preparation and delta semantics ([evidence](research/RUST_CLIENT_TIMER_PREPARE.md)).
|
| 1971 |
|
| 1972 |
- [ ] RE-974 Recover the remaining timer caller, damage feedback, initialization/native ownership and full Rust/Bevy/Solari acceptance ([next work](research/QVM_CLIENT_TIMER_BATCH.md)).
|
| 1973 |
+
|
| 1974 |
+
- [x] RE-974 Original client intermission and spectator routing ([evidence](research/QVM_CLIENT_ROUTING.md)).
|
docs/research/QVM_CLIENT_ROUTING.md
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Original client intermission and spectator routing
|
| 2 |
+
|
| 3 |
+
RE-974. Focused validation: `cargo xtask test-group qvm-client-routing`. [Machine report](qvm-client-routing.json).
|
| 4 |
+
|
| 5 |
+
Sixteen source154210-prefix paths recover intermission precedence, team3/follow gates and spectator-word3 callback suppression. Normal paths stop at154256; routed paths stop at the original early return155716. Callback151133/149671 effects remain captured, with their client/command inputs recorded. Later command and movement processing are outside this first contract.
|
docs/research/README.md
CHANGED
|
@@ -1505,3 +1505,5 @@ The extension collector adds five focused tests for native tail calls, command-r
|
|
| 1505 |
- [RE-973: Rust caller timestamp preparation and delta semantics](RUST_CLIENT_TIMER_PREPARE.md).
|
| 1506 |
|
| 1507 |
- [RE-964–973 client timer batch and RE-974 next work](QVM_CLIENT_TIMER_BATCH.md).
|
|
|
|
|
|
|
|
|
| 1505 |
- [RE-973: Rust caller timestamp preparation and delta semantics](RUST_CLIENT_TIMER_PREPARE.md).
|
| 1506 |
|
| 1507 |
- [RE-964–973 client timer batch and RE-974 next work](QVM_CLIENT_TIMER_BATCH.md).
|
| 1508 |
+
|
| 1509 |
+
- [RE-974: Original client intermission and spectator routing](QVM_CLIENT_ROUTING.md).
|
docs/research/qvm-client-routing.json
ADDED
|
@@ -0,0 +1,355 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"limits": "16 original154210..154256 paths cover intermission precedence, team3/follow routing and spectator-word3 suppression. Source callbacks151133/149671 are captured; explicit boundaries stop before command rewriting or at original early return155716.",
|
| 3 |
+
"probes": [
|
| 4 |
+
{
|
| 5 |
+
"events": [],
|
| 6 |
+
"execution": {
|
| 7 |
+
"stop": 154256,
|
| 8 |
+
"trace_length": 18,
|
| 9 |
+
"trace_sha256": "8e9022982fa3dd6aa13e253ae059eff18c6e4b1ff81523026d430e48b163cae2"
|
| 10 |
+
},
|
| 11 |
+
"input": {
|
| 12 |
+
"follow": 0,
|
| 13 |
+
"intermission": 0,
|
| 14 |
+
"msec": 50,
|
| 15 |
+
"spectator": 0,
|
| 16 |
+
"team": 0
|
| 17 |
+
},
|
| 18 |
+
"proceed": true
|
| 19 |
+
},
|
| 20 |
+
{
|
| 21 |
+
"events": [],
|
| 22 |
+
"execution": {
|
| 23 |
+
"stop": 154256,
|
| 24 |
+
"trace_length": 18,
|
| 25 |
+
"trace_sha256": "8e9022982fa3dd6aa13e253ae059eff18c6e4b1ff81523026d430e48b163cae2"
|
| 26 |
+
},
|
| 27 |
+
"input": {
|
| 28 |
+
"follow": 0,
|
| 29 |
+
"intermission": 0,
|
| 30 |
+
"msec": 50,
|
| 31 |
+
"spectator": 3,
|
| 32 |
+
"team": 0
|
| 33 |
+
},
|
| 34 |
+
"proceed": true
|
| 35 |
+
},
|
| 36 |
+
{
|
| 37 |
+
"events": [
|
| 38 |
+
{
|
| 39 |
+
"command_time": 12345,
|
| 40 |
+
"op": "spectator",
|
| 41 |
+
"slot": 2
|
| 42 |
+
}
|
| 43 |
+
],
|
| 44 |
+
"execution": {
|
| 45 |
+
"stop": 155716,
|
| 46 |
+
"trace_length": 36,
|
| 47 |
+
"trace_sha256": "b226bba7418f8d3639834da0178c08b0fe7f999ad00b8f4b87cb0f2bd6181491"
|
| 48 |
+
},
|
| 49 |
+
"input": {
|
| 50 |
+
"follow": 1,
|
| 51 |
+
"intermission": 0,
|
| 52 |
+
"msec": 50,
|
| 53 |
+
"spectator": 0,
|
| 54 |
+
"team": 0
|
| 55 |
+
},
|
| 56 |
+
"proceed": false
|
| 57 |
+
},
|
| 58 |
+
{
|
| 59 |
+
"events": [],
|
| 60 |
+
"execution": {
|
| 61 |
+
"stop": 155716,
|
| 62 |
+
"trace_length": 27,
|
| 63 |
+
"trace_sha256": "f703c4f57ae46c84d1db7dd6e8da1ca68c9a6bd950184159933e88b082e8387e"
|
| 64 |
+
},
|
| 65 |
+
"input": {
|
| 66 |
+
"follow": 1,
|
| 67 |
+
"intermission": 0,
|
| 68 |
+
"msec": 50,
|
| 69 |
+
"spectator": 3,
|
| 70 |
+
"team": 0
|
| 71 |
+
},
|
| 72 |
+
"proceed": false
|
| 73 |
+
},
|
| 74 |
+
{
|
| 75 |
+
"events": [
|
| 76 |
+
{
|
| 77 |
+
"command_time": 12345,
|
| 78 |
+
"op": "spectator",
|
| 79 |
+
"slot": 2
|
| 80 |
+
}
|
| 81 |
+
],
|
| 82 |
+
"execution": {
|
| 83 |
+
"stop": 155716,
|
| 84 |
+
"trace_length": 29,
|
| 85 |
+
"trace_sha256": "d8eb4b97d39918d2a78a4d7f3d920eea0bd4cf9a9a1c30a45b9bfe3b08e35476"
|
| 86 |
+
},
|
| 87 |
+
"input": {
|
| 88 |
+
"follow": 0,
|
| 89 |
+
"intermission": 0,
|
| 90 |
+
"msec": 50,
|
| 91 |
+
"spectator": 0,
|
| 92 |
+
"team": 3
|
| 93 |
+
},
|
| 94 |
+
"proceed": false
|
| 95 |
+
},
|
| 96 |
+
{
|
| 97 |
+
"events": [],
|
| 98 |
+
"execution": {
|
| 99 |
+
"stop": 155716,
|
| 100 |
+
"trace_length": 20,
|
| 101 |
+
"trace_sha256": "732bbdfda2cdf56ad02d1e32f7c6604edf0a87b892fba7370cd6d52f69350b69"
|
| 102 |
+
},
|
| 103 |
+
"input": {
|
| 104 |
+
"follow": 0,
|
| 105 |
+
"intermission": 0,
|
| 106 |
+
"msec": 50,
|
| 107 |
+
"spectator": 3,
|
| 108 |
+
"team": 3
|
| 109 |
+
},
|
| 110 |
+
"proceed": false
|
| 111 |
+
},
|
| 112 |
+
{
|
| 113 |
+
"events": [
|
| 114 |
+
{
|
| 115 |
+
"command_time": 12345,
|
| 116 |
+
"op": "spectator",
|
| 117 |
+
"slot": 2
|
| 118 |
+
}
|
| 119 |
+
],
|
| 120 |
+
"execution": {
|
| 121 |
+
"stop": 155716,
|
| 122 |
+
"trace_length": 29,
|
| 123 |
+
"trace_sha256": "d8eb4b97d39918d2a78a4d7f3d920eea0bd4cf9a9a1c30a45b9bfe3b08e35476"
|
| 124 |
+
},
|
| 125 |
+
"input": {
|
| 126 |
+
"follow": 1,
|
| 127 |
+
"intermission": 0,
|
| 128 |
+
"msec": 50,
|
| 129 |
+
"spectator": 0,
|
| 130 |
+
"team": 3
|
| 131 |
+
},
|
| 132 |
+
"proceed": false
|
| 133 |
+
},
|
| 134 |
+
{
|
| 135 |
+
"events": [],
|
| 136 |
+
"execution": {
|
| 137 |
+
"stop": 155716,
|
| 138 |
+
"trace_length": 20,
|
| 139 |
+
"trace_sha256": "732bbdfda2cdf56ad02d1e32f7c6604edf0a87b892fba7370cd6d52f69350b69"
|
| 140 |
+
},
|
| 141 |
+
"input": {
|
| 142 |
+
"follow": 1,
|
| 143 |
+
"intermission": 0,
|
| 144 |
+
"msec": 50,
|
| 145 |
+
"spectator": 3,
|
| 146 |
+
"team": 3
|
| 147 |
+
},
|
| 148 |
+
"proceed": false
|
| 149 |
+
},
|
| 150 |
+
{
|
| 151 |
+
"events": [
|
| 152 |
+
{
|
| 153 |
+
"op": "intermission",
|
| 154 |
+
"slot": 2
|
| 155 |
+
}
|
| 156 |
+
],
|
| 157 |
+
"execution": {
|
| 158 |
+
"stop": 155716,
|
| 159 |
+
"trace_length": 12,
|
| 160 |
+
"trace_sha256": "7e20e5dcf116c97ca51f04063ad22303a8c80ffff614d5a80b92c9fc4bd67d32"
|
| 161 |
+
},
|
| 162 |
+
"input": {
|
| 163 |
+
"follow": 0,
|
| 164 |
+
"intermission": 1,
|
| 165 |
+
"msec": 50,
|
| 166 |
+
"spectator": 0,
|
| 167 |
+
"team": 0
|
| 168 |
+
},
|
| 169 |
+
"proceed": false
|
| 170 |
+
},
|
| 171 |
+
{
|
| 172 |
+
"events": [
|
| 173 |
+
{
|
| 174 |
+
"op": "intermission",
|
| 175 |
+
"slot": 2
|
| 176 |
+
}
|
| 177 |
+
],
|
| 178 |
+
"execution": {
|
| 179 |
+
"stop": 155716,
|
| 180 |
+
"trace_length": 12,
|
| 181 |
+
"trace_sha256": "7e20e5dcf116c97ca51f04063ad22303a8c80ffff614d5a80b92c9fc4bd67d32"
|
| 182 |
+
},
|
| 183 |
+
"input": {
|
| 184 |
+
"follow": 0,
|
| 185 |
+
"intermission": 1,
|
| 186 |
+
"msec": 50,
|
| 187 |
+
"spectator": 3,
|
| 188 |
+
"team": 0
|
| 189 |
+
},
|
| 190 |
+
"proceed": false
|
| 191 |
+
},
|
| 192 |
+
{
|
| 193 |
+
"events": [
|
| 194 |
+
{
|
| 195 |
+
"op": "intermission",
|
| 196 |
+
"slot": 2
|
| 197 |
+
}
|
| 198 |
+
],
|
| 199 |
+
"execution": {
|
| 200 |
+
"stop": 155716,
|
| 201 |
+
"trace_length": 12,
|
| 202 |
+
"trace_sha256": "7e20e5dcf116c97ca51f04063ad22303a8c80ffff614d5a80b92c9fc4bd67d32"
|
| 203 |
+
},
|
| 204 |
+
"input": {
|
| 205 |
+
"follow": 1,
|
| 206 |
+
"intermission": 1,
|
| 207 |
+
"msec": 50,
|
| 208 |
+
"spectator": 0,
|
| 209 |
+
"team": 0
|
| 210 |
+
},
|
| 211 |
+
"proceed": false
|
| 212 |
+
},
|
| 213 |
+
{
|
| 214 |
+
"events": [
|
| 215 |
+
{
|
| 216 |
+
"op": "intermission",
|
| 217 |
+
"slot": 2
|
| 218 |
+
}
|
| 219 |
+
],
|
| 220 |
+
"execution": {
|
| 221 |
+
"stop": 155716,
|
| 222 |
+
"trace_length": 12,
|
| 223 |
+
"trace_sha256": "7e20e5dcf116c97ca51f04063ad22303a8c80ffff614d5a80b92c9fc4bd67d32"
|
| 224 |
+
},
|
| 225 |
+
"input": {
|
| 226 |
+
"follow": 1,
|
| 227 |
+
"intermission": 1,
|
| 228 |
+
"msec": 50,
|
| 229 |
+
"spectator": 3,
|
| 230 |
+
"team": 0
|
| 231 |
+
},
|
| 232 |
+
"proceed": false
|
| 233 |
+
},
|
| 234 |
+
{
|
| 235 |
+
"events": [
|
| 236 |
+
{
|
| 237 |
+
"op": "intermission",
|
| 238 |
+
"slot": 2
|
| 239 |
+
}
|
| 240 |
+
],
|
| 241 |
+
"execution": {
|
| 242 |
+
"stop": 155716,
|
| 243 |
+
"trace_length": 12,
|
| 244 |
+
"trace_sha256": "7e20e5dcf116c97ca51f04063ad22303a8c80ffff614d5a80b92c9fc4bd67d32"
|
| 245 |
+
},
|
| 246 |
+
"input": {
|
| 247 |
+
"follow": 0,
|
| 248 |
+
"intermission": 1,
|
| 249 |
+
"msec": 50,
|
| 250 |
+
"spectator": 0,
|
| 251 |
+
"team": 3
|
| 252 |
+
},
|
| 253 |
+
"proceed": false
|
| 254 |
+
},
|
| 255 |
+
{
|
| 256 |
+
"events": [
|
| 257 |
+
{
|
| 258 |
+
"op": "intermission",
|
| 259 |
+
"slot": 2
|
| 260 |
+
}
|
| 261 |
+
],
|
| 262 |
+
"execution": {
|
| 263 |
+
"stop": 155716,
|
| 264 |
+
"trace_length": 12,
|
| 265 |
+
"trace_sha256": "7e20e5dcf116c97ca51f04063ad22303a8c80ffff614d5a80b92c9fc4bd67d32"
|
| 266 |
+
},
|
| 267 |
+
"input": {
|
| 268 |
+
"follow": 0,
|
| 269 |
+
"intermission": 1,
|
| 270 |
+
"msec": 50,
|
| 271 |
+
"spectator": 3,
|
| 272 |
+
"team": 3
|
| 273 |
+
},
|
| 274 |
+
"proceed": false
|
| 275 |
+
},
|
| 276 |
+
{
|
| 277 |
+
"events": [
|
| 278 |
+
{
|
| 279 |
+
"op": "intermission",
|
| 280 |
+
"slot": 2
|
| 281 |
+
}
|
| 282 |
+
],
|
| 283 |
+
"execution": {
|
| 284 |
+
"stop": 155716,
|
| 285 |
+
"trace_length": 12,
|
| 286 |
+
"trace_sha256": "7e20e5dcf116c97ca51f04063ad22303a8c80ffff614d5a80b92c9fc4bd67d32"
|
| 287 |
+
},
|
| 288 |
+
"input": {
|
| 289 |
+
"follow": 1,
|
| 290 |
+
"intermission": 1,
|
| 291 |
+
"msec": 50,
|
| 292 |
+
"spectator": 0,
|
| 293 |
+
"team": 3
|
| 294 |
+
},
|
| 295 |
+
"proceed": false
|
| 296 |
+
},
|
| 297 |
+
{
|
| 298 |
+
"events": [
|
| 299 |
+
{
|
| 300 |
+
"op": "intermission",
|
| 301 |
+
"slot": 2
|
| 302 |
+
}
|
| 303 |
+
],
|
| 304 |
+
"execution": {
|
| 305 |
+
"stop": 155716,
|
| 306 |
+
"trace_length": 12,
|
| 307 |
+
"trace_sha256": "7e20e5dcf116c97ca51f04063ad22303a8c80ffff614d5a80b92c9fc4bd67d32"
|
| 308 |
+
},
|
| 309 |
+
"input": {
|
| 310 |
+
"follow": 1,
|
| 311 |
+
"intermission": 1,
|
| 312 |
+
"msec": 50,
|
| 313 |
+
"spectator": 3,
|
| 314 |
+
"team": 3
|
| 315 |
+
},
|
| 316 |
+
"proceed": false
|
| 317 |
+
}
|
| 318 |
+
],
|
| 319 |
+
"sha256": "a589351dfe517470a1b121dd2164714987d9e4577bf00c6486e1540035d7a79d",
|
| 320 |
+
"source": {
|
| 321 |
+
"archive": "zUrT43_qvm.pk3",
|
| 322 |
+
"archive_sha256": "b59bf0c5bedf11d50e0edd220da7eade96de40601e98ae14c54c819047df0796",
|
| 323 |
+
"member": {
|
| 324 |
+
"bytes": 983300,
|
| 325 |
+
"comment_hex": "",
|
| 326 |
+
"compressed_bytes": 246560,
|
| 327 |
+
"compression": 8,
|
| 328 |
+
"crc32": "98ea1768",
|
| 329 |
+
"create_system": 0,
|
| 330 |
+
"create_version": 63,
|
| 331 |
+
"date_time": [
|
| 332 |
+
2018,
|
| 333 |
+
6,
|
| 334 |
+
18,
|
| 335 |
+
22,
|
| 336 |
+
11,
|
| 337 |
+
50
|
| 338 |
+
],
|
| 339 |
+
"directory": false,
|
| 340 |
+
"entry_index": 2,
|
| 341 |
+
"external_attr": 32,
|
| 342 |
+
"extra_hex": "0a0020000000000001001800d1e24e974007d40116dcbf962f1fd20116dcbf962f1fd201",
|
| 343 |
+
"extract_version": 20,
|
| 344 |
+
"flags": 0,
|
| 345 |
+
"header_offset": 221309,
|
| 346 |
+
"internal_attr": 0,
|
| 347 |
+
"occurrence": 0,
|
| 348 |
+
"output": "assets/extracted/zUrT43_qvm.pk3/members/000002/vm/qagame.qvm",
|
| 349 |
+
"path": "vm/qagame.qvm",
|
| 350 |
+
"sha256": "a589351dfe517470a1b121dd2164714987d9e4577bf00c6486e1540035d7a79d",
|
| 351 |
+
"type": "member",
|
| 352 |
+
"volume": 0
|
| 353 |
+
}
|
| 354 |
+
}
|
| 355 |
+
}
|
docs/research/qvm-resumer-audit.json
CHANGED
|
@@ -8598,6 +8598,17 @@
|
|
| 8598 |
"repeated_calls_opt_in": true,
|
| 8599 |
"repeated_calls_setting": "literal_true"
|
| 8600 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8601 |
{
|
| 8602 |
"backward_conditional_branches": [],
|
| 8603 |
"calls": [
|
|
@@ -10307,10 +10318,10 @@
|
|
| 10307 |
}
|
| 10308 |
},
|
| 10309 |
"summary": {
|
| 10310 |
-
"call_expressions":
|
| 10311 |
-
"files":
|
| 10312 |
"legacy_expressions": 158,
|
| 10313 |
-
"nonliteral_ranges":
|
| 10314 |
"unresolved_mode_expressions": 3
|
| 10315 |
}
|
| 10316 |
}
|
|
|
|
| 8598 |
"repeated_calls_opt_in": true,
|
| 8599 |
"repeated_calls_setting": "literal_true"
|
| 8600 |
},
|
| 8601 |
+
{
|
| 8602 |
+
"backward_conditional_branches": [],
|
| 8603 |
+
"calls": [],
|
| 8604 |
+
"explicit_result_offsets": null,
|
| 8605 |
+
"helper": "qvm_trace_support.resume",
|
| 8606 |
+
"line": 20,
|
| 8607 |
+
"literal_range": null,
|
| 8608 |
+
"path": "scripts/qvm_client_processing_support.py",
|
| 8609 |
+
"repeated_calls_opt_in": true,
|
| 8610 |
+
"repeated_calls_setting": "literal_true"
|
| 8611 |
+
},
|
| 8612 |
{
|
| 8613 |
"backward_conditional_branches": [],
|
| 8614 |
"calls": [
|
|
|
|
| 10318 |
}
|
| 10319 |
},
|
| 10320 |
"summary": {
|
| 10321 |
+
"call_expressions": 208,
|
| 10322 |
+
"files": 160,
|
| 10323 |
"legacy_expressions": 158,
|
| 10324 |
+
"nonliteral_ranges": 29,
|
| 10325 |
"unresolved_mode_expressions": 3
|
| 10326 |
}
|
| 10327 |
}
|
scripts/analyze_qvm_client_routing.py
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Verified original client-processing source contract."""
|
| 2 |
+
from pathlib import Path
|
| 3 |
+
from analyze_qvm import write_json
|
| 4 |
+
from qvm_research_support import source
|
| 5 |
+
from qvm_client_processing_support import seed,gate,gate_fixtures
|
| 6 |
+
|
| 7 |
+
def main():
|
| 8 |
+
q,raw,h,ins=source();probes=[]
|
| 9 |
+
for a in gate_fixtures():
|
| 10 |
+
m,b=seed(raw,h,a);m,p,b=gate(ins,m,b,a);p['input']=a;probes.append(p)
|
| 11 |
+
write_json(Path('docs/research/qvm-client-routing.json'),dict(source=q['source'],sha256=q['sha256'],probes=probes,limits='16 original154210..154256 paths cover intermission precedence, team3/follow routing and spectator-word3 suppression. Source callbacks151133/149671 are captured; explicit boundaries stop before command rewriting or at original early return155716.'))
|
| 12 |
+
if __name__=='__main__':main()
|
scripts/qvm_client_processing_oracle.py
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Independent client routing, command, inactivity and movement expectations."""
|
| 2 |
+
def signed(v):v&=0xffffffff;return v if v<2**31 else v-2**32
|
| 3 |
+
|
| 4 |
+
def gate(a):
|
| 5 |
+
if a['intermission']:return dict(events=[dict(op='intermission',slot=2)],proceed=False)
|
| 6 |
+
if a['team']==3 or a['follow']:
|
| 7 |
+
return dict(events=[] if a['spectator']==3 else [dict(op='spectator',slot=2,command_time=12345)],proceed=False)
|
| 8 |
+
return dict(events=[],proceed=True)
|
scripts/qvm_client_processing_support.py
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Original client-processing fragments and composed pre-movement paths."""
|
| 2 |
+
from qvm_camera_world_support import B,POOL,run
|
| 3 |
+
from qvm_exit_rules_support import CPOOL
|
| 4 |
+
from qvm_byte_memory_support import write_bytes,read_bytes
|
| 5 |
+
from qvm_string_memory_support import cstring,frame_args
|
| 6 |
+
from qvm_trace_support import resume
|
| 7 |
+
from qvm_filter_loading_support import environment
|
| 8 |
+
ROOT=B+0x3b0000
|
| 9 |
+
ENTITY=POOL+880*2
|
| 10 |
+
CLIENT=CPOOL+6336*2
|
| 11 |
+
CONTROL=ROOT+0x10000
|
| 12 |
+
|
| 13 |
+
def seed(raw,h,a):
|
| 14 |
+
m,b=environment(raw,h,[]);m[ENTITY+520]=CLIENT;m[ROOT+52]=CLIENT;m[ROOT+324]=CLIENT+472;m[ROOT+328]=a.get('msec',50);m[34992496]=CPOOL
|
| 15 |
+
write_bytes(m,b,{p:raw[h['data_offset']+p] for p in range(63148,63380)})
|
| 16 |
+
return m,b
|
| 17 |
+
|
| 18 |
+
def execute(ins,m,b,start,stop,handlers=None,boundaries=()):
|
| 19 |
+
m,b=frame_args(m,b,{ROOT+444:ENTITY})
|
| 20 |
+
m,e=resume(ins,start,stop,m,ROOT,handlers=handlers or {},boundaries=boundaries,byte_inputs=b,repeated_calls=True,sync_child_words=True,coherent_memory=True,byte_handlers=True,capture_byte_memory=True,limit=32768)
|
| 21 |
+
return m,e,e['byte_memory']
|
| 22 |
+
|
| 23 |
+
def gate_fixtures():
|
| 24 |
+
from itertools import product
|
| 25 |
+
return [dict(intermission=i,team=t,follow=f,spectator=s,msec=50) for i,t,f,s in product([0,1],[0,3],[0,1],[0,3])]
|
| 26 |
+
|
| 27 |
+
def gate_handlers(events):
|
| 28 |
+
def intermission(i,m,a,bs):events.append(dict(op='intermission',slot=(a[8]-CPOOL)//6336));return m,0,{'callback151133_captured':True}
|
| 29 |
+
def spectator(i,m,a,bs):events.append(dict(op='spectator',slot=(a[8]-POOL)//880,command_time=m[a[12]]&0xffffffff));return m,0,{'callback149671_captured':True}
|
| 30 |
+
return {151133:intermission,149671:spectator}
|
| 31 |
+
|
| 32 |
+
def gate_seed(m,a):
|
| 33 |
+
m.update({34999596:a['intermission'],CLIENT+3096:a['team'],CLIENT+4324:a['follow'],CLIENT+3108:a['spectator'],CLIENT+472:12345})
|
| 34 |
+
|
| 35 |
+
def gate(ins,m,b,a):
|
| 36 |
+
gate_seed(m,a);events=[];m,e,b=execute(ins,m,b,154210,155717,gate_handlers(events),(154256,155716))
|
| 37 |
+
return m,dict(events=events,proceed=e['stop']==154256,execution={k:e[k] for k in ['stop','trace_length','trace_sha256']}),b
|
scripts/test_qvm_client_routing.py
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import json,unittest
|
| 2 |
+
from pathlib import Path
|
| 3 |
+
from qvm_client_processing_oracle import gate
|
| 4 |
+
class OriginalTests(unittest.TestCase):
|
| 5 |
+
def test_original_contract(self):
|
| 6 |
+
rows=json.loads(Path('docs/research/qvm-client-routing.json').read_text())['probes'];self.assertEqual(len(rows),16)
|
| 7 |
+
for p in rows:
|
| 8 |
+
for k,v in gate(p['input']).items():self.assertEqual(p[k],v)
|
| 9 |
+
def test_fixture_identity_and_trace(self):
|
| 10 |
+
r=json.loads(Path('docs/research/qvm-client-routing.json').read_text());self.assertEqual(len(r['sha256']),64)
|
| 11 |
+
self.assertTrue(all(p['execution']['trace_length']>0 for p in r['probes']))
|
| 12 |
+
if __name__=='__main__':unittest.main()
|
xtask/checks.tsv
CHANGED
|
@@ -3538,3 +3538,7 @@ edge crates/urt-gameplay/src/filter_commands.rs scripts/analyze_rust_client_time
|
|
| 3538 |
edge crates/urt-gameplay/src/bin/urt-filter-commands.rs scripts/analyze_rust_client_timer_prepare.py
|
| 3539 |
edge crates/urt-gameplay/src/client_timer.rs scripts/analyze_rust_client_timer_prepare.py
|
| 3540 |
edge crates/urt-gameplay/src/bin/urt-client-timer.rs scripts/analyze_rust_client_timer_prepare.py
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3538 |
edge crates/urt-gameplay/src/bin/urt-filter-commands.rs scripts/analyze_rust_client_timer_prepare.py
|
| 3539 |
edge crates/urt-gameplay/src/client_timer.rs scripts/analyze_rust_client_timer_prepare.py
|
| 3540 |
edge crates/urt-gameplay/src/bin/urt-client-timer.rs scripts/analyze_rust_client_timer_prepare.py
|
| 3541 |
+
report scripts/analyze_qvm_client_routing.py docs/research/qvm-client-routing.json
|
| 3542 |
+
edge docs/research/qvm-client-routing.json scripts/test_qvm_client_routing.py
|
| 3543 |
+
group qvm-client-routing scripts/analyze_qvm_client_routing.py
|
| 3544 |
+
edge scripts/analyze_qvm_client_routing.py scripts/analyze_qvm_resumer_audit.py
|