qvm: recover timer countdown and recovery flags
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_TIMER_RECOVERY.md +5 -0
- docs/research/README.md +2 -0
- docs/research/qvm-client-timer-recovery.json +0 -0
- scripts/analyze_qvm_client_timer_recovery.py +12 -0
- scripts/qvm_client_timer_support.py +4 -0
- scripts/test_qvm_client_timer_recovery.py +12 -0
- xtask/checks.tsv +4 -0
docs/FINDINGS.md
CHANGED
|
@@ -1867,3 +1867,5 @@ RE-965: Rust matches144 original terminal-fragment cases, preserving wrapping co
|
|
| 1867 |
RE-966: A288-case source loop contract covers signed residual thresholds, wrapping phase increments and signed remainder with rates0/1/2/5. Rate0 reads preceding word1120403456 instead of a zero divisor. Flag256 plus positive supplied health and phase0 request damage1, means23 and caller weapon/owner pointers. Damage effects remain captured and flag512 is disabled in this stage; health mutation and other branches remain open. [Evidence](research/QVM_CLIENT_TIMER_TICKS.md).
|
| 1868 |
|
| 1869 |
RE-967: Rust matches288 original tick-loop cases with signed residual/remainder and wrapping phase behavior. Rate0 retains the preceding-word divisor1120403456. Typed damage requests retain all source arguments without mutating supplied health. Unit tests cover alias behavior, signed wrap, exact request ABI and atomic invalid-rate rejection. Flag512 is deliberately outside this first loop subset; the residual budget bounds execution. [Evidence](research/RUST_CLIENT_TIMER_TICKS.md).
|
|
|
|
|
|
|
|
|
| 1867 |
RE-966: A288-case source loop contract covers signed residual thresholds, wrapping phase increments and signed remainder with rates0/1/2/5. Rate0 reads preceding word1120403456 instead of a zero divisor. Flag256 plus positive supplied health and phase0 request damage1, means23 and caller weapon/owner pointers. Damage effects remain captured and flag512 is disabled in this stage; health mutation and other branches remain open. [Evidence](research/QVM_CLIENT_TIMER_TICKS.md).
|
| 1868 |
|
| 1869 |
RE-967: Rust matches288 original tick-loop cases with signed residual/remainder and wrapping phase behavior. Rate0 retains the preceding-word divisor1120403456. Typed damage requests retain all source arguments without mutating supplied health. Unit tests cover alias behavior, signed wrap, exact request ABI and atomic invalid-rate rejection. Flag512 is deliberately outside this first loop subset; the residual budget bounds execution. [Evidence](research/RUST_CLIENT_TIMER_TICKS.md).
|
| 1870 |
+
|
| 1871 |
+
RE-968: A216-case source contract extends the tick loop through flags512/256/128 and f32 subtraction of0.1. Crossing zero resets flag256/rate/timer but delays secondary flag128/status cleanup until a later tick; initially nonpositive timers can clear immediately. Reset rate0 changes later modulo through the preceding-word alias. Damage stays captured and health supplied; nonfinite/unsafe table domains remain open. [Evidence](research/QVM_CLIENT_TIMER_RECOVERY.md).
|
docs/PROVISIONAL_TODO.md
CHANGED
|
@@ -1919,3 +1919,5 @@ RE-954–963 completed add/remove wrappers, resolved duration export, full-capac
|
|
| 1919 |
- [x] RE-966 Original100ms timer phase loop and damage-request ABI ([evidence](research/QVM_CLIENT_TIMER_TICKS.md)).
|
| 1920 |
|
| 1921 |
- [x] RE-967 Rust100ms phase loop and captured damage requests ([evidence](research/RUST_CLIENT_TIMER_TICKS.md)).
|
|
|
|
|
|
|
|
|
| 1919 |
- [x] RE-966 Original100ms timer phase loop and damage-request ABI ([evidence](research/QVM_CLIENT_TIMER_TICKS.md)).
|
| 1920 |
|
| 1921 |
- [x] RE-967 Rust100ms phase loop and captured damage requests ([evidence](research/RUST_CLIENT_TIMER_TICKS.md)).
|
| 1922 |
+
|
| 1923 |
+
- [x] RE-968 Original float countdown and flag-recovery loop ([evidence](research/QVM_CLIENT_TIMER_RECOVERY.md)).
|
docs/RESEARCH_LEDGER.md
CHANGED
|
@@ -2539,3 +2539,7 @@ A288-case source loop contract covers signed residual thresholds, wrapping phase
|
|
| 2539 |
## 2026-10-28 — RE-967 Rust100ms phase loop and captured damage requests
|
| 2540 |
|
| 2541 |
Rust matches288 original tick-loop cases with signed residual/remainder and wrapping phase behavior. Rate0 retains the preceding-word divisor1120403456. Typed damage requests retain all source arguments without mutating supplied health. Unit tests cover alias behavior, signed wrap, exact request ABI and atomic invalid-rate rejection. Flag512 is deliberately outside this first loop subset; the residual budget bounds execution. Focused `cargo xtask test-group rust-client-timer-ticks` 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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2539 |
## 2026-10-28 — RE-967 Rust100ms phase loop and captured damage requests
|
| 2540 |
|
| 2541 |
Rust matches288 original tick-loop cases with signed residual/remainder and wrapping phase behavior. Rate0 retains the preceding-word divisor1120403456. Typed damage requests retain all source arguments without mutating supplied health. Unit tests cover alias behavior, signed wrap, exact request ABI and atomic invalid-rate rejection. Flag512 is deliberately outside this first loop subset; the residual budget bounds execution. Focused `cargo xtask test-group rust-client-timer-ticks` 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.
|
| 2542 |
+
|
| 2543 |
+
## 2026-10-28 — RE-968 Original float countdown and flag-recovery loop
|
| 2544 |
+
|
| 2545 |
+
A216-case source contract extends the tick loop through flags512/256/128 and f32 subtraction of0.1. Crossing zero resets flag256/rate/timer but delays secondary flag128/status cleanup until a later tick; initially nonpositive timers can clear immediately. Reset rate0 changes later modulo through the preceding-word alias. Damage stays captured and health supplied; nonfinite/unsafe table domains remain open. Focused `cargo xtask test-group qvm-client-timer-recovery` 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
|
@@ -1956,3 +1956,5 @@ RE-954–963 recover bounded command wrappers, resolved duration export, full-ca
|
|
| 1956 |
- [x] RE-966 Original100ms timer phase loop and damage-request ABI ([evidence](research/QVM_CLIENT_TIMER_TICKS.md)).
|
| 1957 |
|
| 1958 |
- [x] RE-967 Rust100ms phase loop and captured damage requests ([evidence](research/RUST_CLIENT_TIMER_TICKS.md)).
|
|
|
|
|
|
|
|
|
| 1956 |
- [x] RE-966 Original100ms timer phase loop and damage-request ABI ([evidence](research/QVM_CLIENT_TIMER_TICKS.md)).
|
| 1957 |
|
| 1958 |
- [x] RE-967 Rust100ms phase loop and captured damage requests ([evidence](research/RUST_CLIENT_TIMER_TICKS.md)).
|
| 1959 |
+
|
| 1960 |
+
- [x] RE-968 Original float countdown and flag-recovery loop ([evidence](research/QVM_CLIENT_TIMER_RECOVERY.md)).
|
docs/research/QVM_CLIENT_TIMER_RECOVERY.md
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Original float countdown and flag-recovery loop
|
| 2 |
+
|
| 3 |
+
RE-968. Focused validation: `cargo xtask test-group qvm-client-timer-recovery`. [Machine report](qvm-client-timer-recovery.json).
|
| 4 |
+
|
| 5 |
+
A216-case source contract extends the tick loop through flags512/256/128 and f32 subtraction of0.1. Crossing zero resets flag256/rate/timer but delays secondary flag128/status cleanup until a later tick; initially nonpositive timers can clear immediately. Reset rate0 changes later modulo through the preceding-word alias. Damage stays captured and health supplied; nonfinite/unsafe table domains remain open.
|
docs/research/README.md
CHANGED
|
@@ -1491,3 +1491,5 @@ The extension collector adds five focused tests for native tail calls, command-r
|
|
| 1491 |
- [RE-966: Original100ms timer phase loop and damage-request ABI](QVM_CLIENT_TIMER_TICKS.md).
|
| 1492 |
|
| 1493 |
- [RE-967: Rust100ms phase loop and captured damage requests](RUST_CLIENT_TIMER_TICKS.md).
|
|
|
|
|
|
|
|
|
| 1491 |
- [RE-966: Original100ms timer phase loop and damage-request ABI](QVM_CLIENT_TIMER_TICKS.md).
|
| 1492 |
|
| 1493 |
- [RE-967: Rust100ms phase loop and captured damage requests](RUST_CLIENT_TIMER_TICKS.md).
|
| 1494 |
+
|
| 1495 |
+
- [RE-968: Original float countdown and flag-recovery loop](QVM_CLIENT_TIMER_RECOVERY.md).
|
docs/research/qvm-client-timer-recovery.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
scripts/analyze_qvm_client_timer_recovery.py
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Original full tick loop with float countdown and flag512 recovery paths."""
|
| 2 |
+
from pathlib import Path
|
| 3 |
+
from analyze_qvm import write_json
|
| 4 |
+
from qvm_research_support import source
|
| 5 |
+
from qvm_client_timer_support import seed,seed_loop,tick_loop,recovery_fixtures
|
| 6 |
+
|
| 7 |
+
def main():
|
| 8 |
+
q,raw,h,ins=source();probes=[]
|
| 9 |
+
for a in recovery_fixtures():
|
| 10 |
+
m,b=seed(raw,h,a);seed_loop(m,a);m,p,b=tick_loop(ins,m,b,a);p['input']=a;probes.append(p)
|
| 11 |
+
write_json(Path('docs/research/qvm-client-timer-recovery.json'),dict(source=q['source'],sha256=q['sha256'],range=[150810,151085],probes=probes,limits='216 original loop cases recover flag512/256/128 gates, repeated f32 subtraction of0.1, rate/float resets and status-bit clearing. Positive countdown crossing zero skips flag128 cleanup until a later iteration; nonpositive initial timer can clean immediately. Rate reset0 changes subsequent modulo through the preceding-word alias. Damage callbacks captured, finite float/rate domains only.'))
|
| 12 |
+
if __name__=='__main__':main()
|
scripts/qvm_client_timer_support.py
CHANGED
|
@@ -40,3 +40,7 @@ def tick_loop(ins,m,b,a):
|
|
| 40 |
def tick_fixtures():
|
| 41 |
from itertools import product
|
| 42 |
return [dict(residual=residual,rate=rate,flags=flags,health=health,phase=phase,status=3,timer=0.0,weapon=7) for residual,rate,flags,health,phase in product([-1,99,100,250,500,1000],[0,1,2,5],[0,256],[0,1],[0,3,0x7fffffff])]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 40 |
def tick_fixtures():
|
| 41 |
from itertools import product
|
| 42 |
return [dict(residual=residual,rate=rate,flags=flags,health=health,phase=phase,status=3,timer=0.0,weapon=7) for residual,rate,flags,health,phase in product([-1,99,100,250,500,1000],[0,1,2,5],[0,256],[0,1],[0,3,0x7fffffff])]
|
| 43 |
+
|
| 44 |
+
def recovery_fixtures():
|
| 45 |
+
from itertools import product
|
| 46 |
+
return [dict(flags=flags,timer=timer,rate=rate,residual=residual,health=health,phase=3,status=3,weapon=7) for flags,timer,rate,residual,health in product([512,768,896],[0.0,0.05,0.1,0.2,1.0,-0.1],[0,2],[100,250,550],[0,1])]
|
scripts/test_qvm_client_timer_recovery.py
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import json,unittest
|
| 2 |
+
from pathlib import Path
|
| 3 |
+
from qvm_client_timer_oracle import ticks
|
| 4 |
+
class RecoveryTests(unittest.TestCase):
|
| 5 |
+
def test_original_full_loop(self):
|
| 6 |
+
rows=json.loads(Path('docs/research/qvm-client-timer-recovery.json').read_text())['probes'];self.assertEqual(len(rows),216)
|
| 7 |
+
for p in rows:
|
| 8 |
+
for k,v in ticks(p['input']).items():self.assertEqual(p[k],v)
|
| 9 |
+
def test_zero_crossing_delays_secondary_cleanup(self):
|
| 10 |
+
a=dict(flags=896,status=3,rate=2,phase=3,timer=0.05,residual=100,health=1,weapon=7);p=ticks(a);self.assertEqual(p['state'][0],640);self.assertEqual(p['state'][1],3);self.assertEqual(p['state'][2],0);self.assertEqual(len(p['damage']),1)
|
| 11 |
+
a['residual']=250;p=ticks(a);self.assertEqual(p['state'][0],512);self.assertEqual(p['state'][1],2);self.assertEqual(p['state'][3],1)
|
| 12 |
+
if __name__=='__main__':unittest.main()
|
xtask/checks.tsv
CHANGED
|
@@ -3466,3 +3466,7 @@ edge crates/urt-gameplay/src/filter_commands.rs scripts/analyze_rust_client_time
|
|
| 3466 |
edge crates/urt-gameplay/src/bin/urt-filter-commands.rs scripts/analyze_rust_client_timer_ticks.py
|
| 3467 |
edge crates/urt-gameplay/src/client_timer.rs scripts/analyze_rust_client_timer_ticks.py
|
| 3468 |
edge crates/urt-gameplay/src/bin/urt-client-timer.rs scripts/analyze_rust_client_timer_ticks.py
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3466 |
edge crates/urt-gameplay/src/bin/urt-filter-commands.rs scripts/analyze_rust_client_timer_ticks.py
|
| 3467 |
edge crates/urt-gameplay/src/client_timer.rs scripts/analyze_rust_client_timer_ticks.py
|
| 3468 |
edge crates/urt-gameplay/src/bin/urt-client-timer.rs scripts/analyze_rust_client_timer_ticks.py
|
| 3469 |
+
report scripts/analyze_qvm_client_timer_recovery.py docs/research/qvm-client-timer-recovery.json
|
| 3470 |
+
edge docs/research/qvm-client-timer-recovery.json scripts/test_qvm_client_timer_recovery.py
|
| 3471 |
+
group qvm-client-timer-recovery scripts/analyze_qvm_client_timer_recovery.py
|
| 3472 |
+
edge scripts/analyze_qvm_client_timer_recovery.py scripts/analyze_qvm_resumer_audit.py
|