qvm: direction codec
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_DIRECTION_CODEC.md +7 -0
- docs/research/README.md +3 -0
- docs/research/qvm-direction-codec.json +0 -0
- scripts/analyze_qvm_direction_codec.py +33 -0
- scripts/test_qvm_direction_codec.py +29 -0
docs/ASSET_PIPELINE_TODO.md
CHANGED
|
@@ -342,3 +342,6 @@ Research progress: [ordinary air continuation](research/QVM_AIR_MODE.md) complet
|
|
| 342 |
|
| 343 |
|
| 344 |
Research progress: RE-549 [report](research/QVM_MOVE_DIRECTION.md); remaining native/content/runtime/platform scope stays open.
|
|
|
|
|
|
|
|
|
|
|
|
| 342 |
|
| 343 |
|
| 344 |
Research progress: RE-549 [report](research/QVM_MOVE_DIRECTION.md); remaining native/content/runtime/platform scope stays open.
|
| 345 |
+
|
| 346 |
+
|
| 347 |
+
Research progress: RE-550 [report](research/QVM_DIRECTION_CODEC.md); remaining native/content/runtime/platform scope stays open.
|
docs/FINDINGS.md
CHANGED
|
@@ -700,3 +700,6 @@ Bounded qagame paths recover bomb-plant/inactivity correction requests, direct f
|
|
| 700 |
|
| 701 |
|
| 702 |
**RE-549 — Recover40679 movement direction classification:** Signed forward/right input selects all eight direction values; idle rewrites old2 to1 and6 to7, preserving other prior values. [Evidence](research/QVM_MOVE_DIRECTION.md).
|
|
|
|
|
|
|
|
|
|
|
|
| 700 |
|
| 701 |
|
| 702 |
**RE-549 — Recover40679 movement direction classification:** Signed forward/right input selects all eight direction values; idle rewrites old2 to1 and6 to7, preserving other prior values. [Evidence](research/QVM_MOVE_DIRECTION.md).
|
| 703 |
+
|
| 704 |
+
|
| 705 |
+
**RE-550 — Recover162-vector direction codec60317 and60408:** Encoder uses strict-greater positive dot search initialized to score0/index0, so earliest ties survive and null/zero choose0. Decoder copies table entries0..161 or the initialized zero fallback. [Evidence](research/QVM_DIRECTION_CODEC.md).
|
docs/PROVISIONAL_TODO.md
CHANGED
|
@@ -654,3 +654,6 @@ Research progress: [ordinary air continuation](research/QVM_AIR_MODE.md) complet
|
|
| 654 |
|
| 655 |
|
| 656 |
Research progress: RE-549 [report](research/QVM_MOVE_DIRECTION.md); remaining native/content/runtime/platform scope stays open.
|
|
|
|
|
|
|
|
|
|
|
|
| 654 |
|
| 655 |
|
| 656 |
Research progress: RE-549 [report](research/QVM_MOVE_DIRECTION.md); remaining native/content/runtime/platform scope stays open.
|
| 657 |
+
|
| 658 |
+
|
| 659 |
+
Research progress: RE-550 [report](research/QVM_DIRECTION_CODEC.md); remaining native/content/runtime/platform scope stays open.
|
docs/RESEARCH_LEDGER.md
CHANGED
|
@@ -447,3 +447,8 @@ Recovered ordinary air path after actual initial wall guard; unrecovered wall-sp
|
|
| 447 |
## 2026-10-19 — RE-549 Recover40679 movement direction classification (separate task commit)
|
| 448 |
|
| 449 |
Signed forward/right input selects all eight direction values; idle rewrites old2 to1 and6 to7, preserving other prior values. 100 signed-byte/prior-state cases and four independent tests cover octants, idle exceptions, canary and source identity. Full suite: 723 tests pass. Report regenerates byte-identically (69217 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 447 |
## 2026-10-19 — RE-549 Recover40679 movement direction classification (separate task commit)
|
| 448 |
|
| 449 |
Signed forward/right input selects all eight direction values; idle rewrites old2 to1 and6 to7, preserving other prior values. 100 signed-byte/prior-state cases and four independent tests cover octants, idle exceptions, canary and source identity. Full suite: 723 tests pass. Report regenerates byte-identically (69217 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
|
| 450 |
+
|
| 451 |
+
|
| 452 |
+
## 2026-10-19 — RE-550 Recover162-vector direction codec60317 and60408 (separate task commit)
|
| 453 |
+
|
| 454 |
+
Encoder uses strict-greater positive dot search initialized to score0/index0, so earliest ties survive and null/zero choose0. Decoder copies table entries0..161 or the initialized zero fallback. 326 encode inputs,165 decode indices and four independent tests validate exact float32 dots, table provenance, null/zero and invalid bounds. Full suite: 727 tests pass. Report regenerates byte-identically (142623 bytes). Storage/filter, links and whitespace checks pass. No assets/Rust runtime/shared VM evaluator changed; native/reference/legal/full platform scope remains open.
|
docs/REVERSE_ENGINEERING_TODO.md
CHANGED
|
@@ -691,3 +691,6 @@ Purpose: turn the supplied installation into an evidence-backed specification of
|
|
| 691 |
|
| 692 |
|
| 693 |
- [x] RE-549 Recover40679 movement direction classification ([report](research/QVM_MOVE_DIRECTION.md)).
|
|
|
|
|
|
|
|
|
|
|
|
| 691 |
|
| 692 |
|
| 693 |
- [x] RE-549 Recover40679 movement direction classification ([report](research/QVM_MOVE_DIRECTION.md)).
|
| 694 |
+
|
| 695 |
+
|
| 696 |
+
- [x] RE-550 Recover162-vector direction codec60317 and60408 ([report](research/QVM_DIRECTION_CODEC.md)).
|
docs/research/QVM_DIRECTION_CODEC.md
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Recover162-vector direction codec60317 and60408
|
| 2 |
+
|
| 3 |
+
RE-550. Reproduce with `python3 scripts/analyze_qvm_direction_codec.py`; check with `python3 scripts/test_qvm_direction_codec.py`. The [machine report](qvm-direction-codec.json) retains source identity and bounded fixtures.
|
| 4 |
+
|
| 5 |
+
All162 direction vectors are read from source data address21732 with12-byte stride.60317 does not normalize its input: it scans all entries, starting best dot0/index0, replacing only on strict greater. Negative inputs and zero inputs are retained as finite cases; a null pointer returns0 before any scan.60408 accepts signed indices0 through161 and copies the initialized21348 zero vector otherwise.326 encoder cases cover each vector, its negative, zero and null; decoder cases cover every valid index and three invalid controls. This recovers the numeric event-parameter producer needed by the wall-contact path; live table mutation and the event's user-visible meaning remain unverified.
|
| 6 |
+
|
| 7 |
+
No original executable/full QVM/native collision/physics/rendering executes. Native responses and legal input domains are supplied or unverified where stated; full runtime/macOS/Linux Rust/Bevy/Solari gameplay remains open.
|
docs/research/README.md
CHANGED
|
@@ -255,3 +255,6 @@ The extension collector adds five focused tests for native tail calls, command-r
|
|
| 255 |
|
| 256 |
|
| 257 |
[RE-549: Recover40679 movement direction classification](QVM_MOVE_DIRECTION.md). Reproduce with `python3 scripts/analyze_qvm_move_direction.py`; check with `python3 scripts/test_qvm_move_direction.py`.
|
|
|
|
|
|
|
|
|
|
|
|
| 255 |
|
| 256 |
|
| 257 |
[RE-549: Recover40679 movement direction classification](QVM_MOVE_DIRECTION.md). Reproduce with `python3 scripts/analyze_qvm_move_direction.py`; check with `python3 scripts/test_qvm_move_direction.py`.
|
| 258 |
+
|
| 259 |
+
|
| 260 |
+
[RE-550: Recover162-vector direction codec60317 and60408](QVM_DIRECTION_CODEC.md). Reproduce with `python3 scripts/analyze_qvm_direction_codec.py`; check with `python3 scripts/test_qvm_direction_codec.py`.
|
docs/research/qvm-direction-codec.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
scripts/analyze_qvm_direction_codec.py
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""Actual60317/60408 finite direction-table codec."""
|
| 3 |
+
from pathlib import Path
|
| 4 |
+
from qvm_research_support import source,constants
|
| 5 |
+
from analyze_deferred_auth import trace_slice
|
| 6 |
+
from analyze_bsp_references import trace_fields
|
| 7 |
+
from analyze_qvm import write_json
|
| 8 |
+
from analyze_qvm_acceleration import word,number
|
| 9 |
+
|
| 10 |
+
BASE=0x65000000
|
| 11 |
+
VEC=0x51000
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
def table(raw,h):return constants(raw,h,list(range(21732,21732+162*12,4))+[21348,21352,21356])
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
def encode(ins,m,vector):
|
| 18 |
+
m=dict(m)
|
| 19 |
+
if vector is not None:
|
| 20 |
+
for i,v in enumerate(vector):m[VEC+4*i]=v
|
| 21 |
+
t=trace_slice(ins,60318,60406,m,{40:0 if vector is None else VEC},local_base=BASE,halt_on_leave=True,capture_stack=True,limit=20000);return t['memory'],{'vector':vector,'result':t['stack'][-1],'calls':t['calls'],**trace_fields(t,False)}
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
def decode_vector(ins,m,index):
|
| 25 |
+
t=trace_slice(ins,60409,60436,m,{20:index,24:VEC},local_base=BASE+0x1000,limit=128);return {'index':index,'vector':[t['memory'][VEC+4*i]&0xffffffff for i in range(3)],**trace_fields(t,False)}
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
def main():
|
| 29 |
+
q,raw,h,ins=source();m=table(raw,h);vectors=[[m[21732+12*i+4*j] for j in range(3)] for i in range(162)];probes=[encode(ins,m,v)[1] for v in vectors+[[word(-number(x)) for x in v] for v in vectors]+[[0,0,0],None]]
|
| 30 |
+
write_json(Path('docs/research/qvm-direction-codec.json'),{'source':q['source'],'sha256':q['sha256'],'table':vectors,'fallback':[m[a] for a in [21348,21352,21356]],'encodes':probes,'decodes':[decode_vector(ins,m,i) for i in [-1,*range(162),162,2147483647]],'limits':'File-backed162-vector table; actual helpers with finite vector inputs. No normalization is performed. Native/live table mutation and runtime/event consumers remain open.'})
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
if __name__=='__main__':main()
|
scripts/test_qvm_direction_codec.py
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import json,unittest,hashlib
|
| 2 |
+
from pathlib import Path
|
| 3 |
+
from test_qvm_ground import f,n
|
| 4 |
+
|
| 5 |
+
|
| 6 |
+
def best(v,table):
|
| 7 |
+
if v is None:return 0
|
| 8 |
+
a=list(map(n,v));chosen=0;score=0
|
| 9 |
+
for i,b in enumerate(table):
|
| 10 |
+
b=list(map(n,b));d=f(f(f(a[0]*b[0])+f(a[1]*b[1]))+f(a[2]*b[2]))
|
| 11 |
+
if d>score:chosen,score=i,d
|
| 12 |
+
return chosen
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
class DirectionCodecTests(unittest.TestCase):
|
| 16 |
+
@classmethod
|
| 17 |
+
def setUpClass(cls):cls.r=json.loads(Path('docs/research/qvm-direction-codec.json').read_text())
|
| 18 |
+
def test_all326_dot_searches_exact(self):
|
| 19 |
+
self.assertEqual(len(self.r['encodes']),326)
|
| 20 |
+
for p in self.r['encodes']:self.assertEqual(p['result'],best(p['vector'],self.r['table']));self.assertEqual(p['calls'],[])
|
| 21 |
+
def test_null_and_zero_keep_index0(self):self.assertEqual([p['result'] for p in self.r['encodes'][-2:]],[0,0])
|
| 22 |
+
def test_decode_all_indices_and_invalid_fallback(self):
|
| 23 |
+
for p in self.r['decodes']:self.assertEqual(p['vector'],self.r['table'][p['index']] if 0<=p['index']<162 else self.r['fallback'])
|
| 24 |
+
self.assertEqual(self.r['fallback'],[0,0,0])
|
| 25 |
+
def test_all_table_words_file_backed(self):
|
| 26 |
+
from analyze_qvm import decode
|
| 27 |
+
q=json.loads(Path('docs/research/qvm/qagame.json').read_text());raw=Path(q['source']['member']['output']).read_bytes();h,_=decode(raw);self.assertEqual(self.r['sha256'],hashlib.sha256(raw).hexdigest())
|
| 28 |
+
for i,v in enumerate(self.r['table']):
|
| 29 |
+
for j,w in enumerate(v):self.assertEqual(int.from_bytes(raw[h['data_offset']+21732+12*i+4*j:h['data_offset']+21736+12*i+4*j],'little'),w)
|