qvm: main query state
Browse files- docs/ASSET_PIPELINE_TODO.md +3 -0
- docs/FINDINGS.md +7 -0
- docs/PROVISIONAL_TODO.md +3 -0
- docs/RESEARCH_LEDGER.md +4 -0
- docs/REVERSE_ENGINEERING_TODO.md +6 -0
- docs/research/QVM_CLEARANCE_MODE.md +3 -0
- docs/research/QVM_LOST_ACTION.md +3 -0
- docs/research/QVM_MAIN_QUERY.md +37 -0
- docs/research/QVM_TRAVERSAL_QUERY.md +3 -0
- docs/research/README.md +3 -0
- docs/research/qvm-main-query.json +0 -0
- scripts/analyze_qvm_clearance_mode.py +6 -2
- scripts/analyze_qvm_main_contact.py +12 -4
- scripts/analyze_qvm_main_query.py +57 -0
- scripts/analyze_qvm_traversal_query.py +11 -3
- scripts/test_qvm_main_query.py +109 -0
docs/ASSET_PIPELINE_TODO.md
CHANGED
|
@@ -321,3 +321,6 @@ Research progress: [QVM54981 forward traces/rebase/main routing](research/QVM_AC
|
|
| 321 |
|
| 322 |
|
| 323 |
Research progress: [QVM nested ground-loss action](research/QVM_LOST_ACTION.md) completes bounded RE-529–531: actual54981(1) before sentinel/flags, rebased deep-query priority and distinct later main54981(0) across48 standalone/12 main cases. RE-528/532 retain query/other modes/native/consumers/full runtime/platform work and broad game/rendering milestones.
|
|
|
|
|
|
|
|
|
|
|
|
| 321 |
|
| 322 |
|
| 323 |
Research progress: [QVM nested ground-loss action](research/QVM_LOST_ACTION.md) completes bounded RE-529–531: actual54981(1) before sentinel/flags, rebased deep-query priority and distinct later main54981(0) across48 standalone/12 main cases. RE-528/532 retain query/other modes/native/consumers/full runtime/platform work and broad game/rendering milestones.
|
| 324 |
+
|
| 325 |
+
|
| 326 |
+
Research progress: [QVM shared query/main acquisition event](research/QVM_MAIN_QUERY.md) completes bounded RE-533–535: actual side-clearance child, full query state into main and reached event23 queue across30 standalone/20 main cases. RE-532/536 retain other modes/combined producers/native/consumers/full runtime/platform work and broad game/rendering milestones.
|
docs/FINDINGS.md
CHANGED
|
@@ -667,3 +667,10 @@ Bounded qagame paths recover bomb-plant/inactivity correction requests, direct f
|
|
| 667 |
**F-257 — Deep trace consumes rebase:**clear recursive action can leave origin[101,202,304] for the later64-unit query; flag-producing recursion skips that query/ground-loss animation. Outer46773 still clears plane/walk after helper return. [LOSTACTION-002](research/QVM_LOST_ACTION.md).
|
| 668 |
|
| 669 |
**F-258 — Two actual action call sites:**nested54981(1) runs before main timer, then main54981(0) clears/rebuilds flags and query gating. Twelve reached41768 chains retain actual post-ground landing/timer/event/resource state; native/full main/runtime remain open. [LOSTACTION-003](research/QVM_LOST_ACTION.md).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 667 |
**F-257 — Deep trace consumes rebase:**clear recursive action can leave origin[101,202,304] for the later64-unit query; flag-producing recursion skips that query/ground-loss animation. Outer46773 still clears plane/walk after helper return. [LOSTACTION-002](research/QVM_LOST_ACTION.md).
|
| 668 |
|
| 669 |
**F-258 — Two actual action call sites:**nested54981(1) runs before main timer, then main54981(0) clears/rebuilds flags and query gating. Twelve reached41768 chains retain actual post-ground landing/timer/event/resource state; native/full main/runtime remain open. [LOSTACTION-003](research/QVM_LOST_ACTION.md).
|
| 670 |
+
|
| 671 |
+
|
| 672 |
+
**F-259 — Live side-clearance child:**56639 now evaluates reached56335 with current origin/entity/basis and disjoint frames; first fraction1 skips the second side trace, and both fractions must differ from1 to acquire. All256 PS words are independently checked in30 shared-state query fixtures. Native trace legality/side effects remain supplied or unverified. [MAINQUERY-001](research/QVM_MAIN_QUERY.md).
|
| 673 |
+
|
| 674 |
+
**F-260 — Full query/main state:**20 actual main chains preserve query velocity/anchor/field44/torso and old-state-dependent flags2, replacing isolated return/state-only transfer. Main action suppresses ten queries; routing selects ten evaluated41768, five omitted55465, four omitted43626 and one omitted57312. [MAINQUERY-002](research/QVM_MAIN_QUERY.md).
|
| 675 |
+
|
| 676 |
+
**F-261 — Acquisition event queue:**exactly two new-acquisition main fixtures execute39238(23)/29913 before routing, storing numeric event23/parameter0 and advancing the two-slot queue. Existing-active/exit/failed/gated controls do not emit; event meaning and consumers remain open. [MAINQUERY-003](research/QVM_MAIN_QUERY.md).
|
docs/PROVISIONAL_TODO.md
CHANGED
|
@@ -633,3 +633,6 @@ Research progress: [QVM54981 forward traces/rebase/main routing](research/QVM_AC
|
|
| 633 |
|
| 634 |
|
| 635 |
Research progress: [QVM nested ground-loss action](research/QVM_LOST_ACTION.md) completes bounded RE-529–531: actual54981(1) before sentinel/flags, rebased deep-query priority and distinct later main54981(0) across48 standalone/12 main cases. RE-528/532 retain query/other modes/native/consumers/full runtime/platform work and broad game/rendering milestones.
|
|
|
|
|
|
|
|
|
|
|
|
| 633 |
|
| 634 |
|
| 635 |
Research progress: [QVM nested ground-loss action](research/QVM_LOST_ACTION.md) completes bounded RE-529–531: actual54981(1) before sentinel/flags, rebased deep-query priority and distinct later main54981(0) across48 standalone/12 main cases. RE-528/532 retain query/other modes/native/consumers/full runtime/platform work and broad game/rendering milestones.
|
| 636 |
+
|
| 637 |
+
|
| 638 |
+
Research progress: [QVM shared query/main acquisition event](research/QVM_MAIN_QUERY.md) completes bounded RE-533–535: actual side-clearance child, full query state into main and reached event23 queue across30 standalone/20 main cases. RE-532/536 retain other modes/combined producers/native/consumers/full runtime/platform work and broad game/rendering milestones.
|
docs/RESEARCH_LEDGER.md
CHANGED
|
@@ -415,3 +415,7 @@ Completed bounded RE-525–527 with `analyze_qvm_action_probe.py`:42 standalone5
|
|
| 415 |
## 2026-10-19 — Game-QVM nested ground-loss action and main re-probe ordering
|
| 416 |
|
| 417 |
Completed bounded RE-529–531 with `analyze_qvm_lost_action.py`:48 standalone46527/nested54981 cases and12 actual posture-ground-timer-main-action/movement/post-environment chains. LOSTACTION-001–003/F-256–258 recover actual54981(1) before old-ground sentinel and updated flags rereads, initial flags&12 prepared-child suppression, sentinel-first plane clearing versus new-contact-bit early exit/plane retention, rebased64-unit deep geometry after a clear recursive child and deep-query/animation suppression after flag-producing recursion. Main then executes distinct54981(0), clearing/rebuilding flags/query gating while128 selects41768 in all12 controls; actual first-clear slide/wrapper/gravity/post-ground landing/touch/event/resource states remain shared. Later outer ground landing can store250 after main aging, unlike nested landing's own effects. Optional action callback in lost and optional lost callback in combined ground preserve original defaults/reports. Roots/native records/endpoints/basis/input/state remain supplied; logging/query/alternative modes/other suffix/native consumers/full53418/scheduler/legal collision/platform gameplay remain omitted or unverified. No original executable/full QVM/native collision/physics/rendering executes. Eight independent tests verify all helper/child/caller states, sentinel/flags/rebase/query priority and twelve skipped actions, main entry/two call-site identity/query gates, reached mode/post-ground parent timer states, final queue/resource/animation persistence, source identity and scope. All671 tests pass. Prior ground-callee, combined-ground and action-probe reports regenerate byte-identically; new report reproduces twice byte-identically (1295119 bytes). Storage/filter setup, documentation links and whitespace checks pass. No assets or shared instruction evaluator changed. RE-528 remains open for broader scope; RE-532 tracks actual query/alternative modes/consumers/real producers/native/legal and complete main/scheduler/macOS/Linux Rust/Bevy/Solari gameplay. Broad game/assets/rendering/protocol milestones remain open.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 415 |
## 2026-10-19 — Game-QVM nested ground-loss action and main re-probe ordering
|
| 416 |
|
| 417 |
Completed bounded RE-529–531 with `analyze_qvm_lost_action.py`:48 standalone46527/nested54981 cases and12 actual posture-ground-timer-main-action/movement/post-environment chains. LOSTACTION-001–003/F-256–258 recover actual54981(1) before old-ground sentinel and updated flags rereads, initial flags&12 prepared-child suppression, sentinel-first plane clearing versus new-contact-bit early exit/plane retention, rebased64-unit deep geometry after a clear recursive child and deep-query/animation suppression after flag-producing recursion. Main then executes distinct54981(0), clearing/rebuilding flags/query gating while128 selects41768 in all12 controls; actual first-clear slide/wrapper/gravity/post-ground landing/touch/event/resource states remain shared. Later outer ground landing can store250 after main aging, unlike nested landing's own effects. Optional action callback in lost and optional lost callback in combined ground preserve original defaults/reports. Roots/native records/endpoints/basis/input/state remain supplied; logging/query/alternative modes/other suffix/native consumers/full53418/scheduler/legal collision/platform gameplay remain omitted or unverified. No original executable/full QVM/native collision/physics/rendering executes. Eight independent tests verify all helper/child/caller states, sentinel/flags/rebase/query priority and twelve skipped actions, main entry/two call-site identity/query gates, reached mode/post-ground parent timer states, final queue/resource/animation persistence, source identity and scope. All671 tests pass. Prior ground-callee, combined-ground and action-probe reports regenerate byte-identically; new report reproduces twice byte-identically (1295119 bytes). Storage/filter setup, documentation links and whitespace checks pass. No assets or shared instruction evaluator changed. RE-528 remains open for broader scope; RE-532 tracks actual query/alternative modes/consumers/real producers/native/legal and complete main/scheduler/macOS/Linux Rust/Bevy/Solari gameplay. Broad game/assets/rendering/protocol milestones remain open.
|
| 418 |
+
|
| 419 |
+
## 2026-10-19 — Game-QVM shared query, side-clearance child and main acquisition event
|
| 420 |
+
|
| 421 |
+
Completed bounded RE-533–535 with `analyze_qvm_main_query.py`:30 standalone full-PS query probes and20 actual clock/timer/action/query/main chains. MAINQUERY-001–003/F-259–261 evaluate reached56335 with live memory and disjoint frames, independently verify side roots/geometry/first-clear short circuit and all256 PS words, then carry actual56639 velocity/anchor/field44/torso/state/return into main. Fractional Z300.75 acquires anchor300; release applies the normalized impulse to current velocity and clears anchor/state with field44 floor300. Main old-state snapshot controls flags2 after nonzero return; ten action-produced feet-hit cases suppress query entirely. Ten remaining queries route to ten total evaluated41768 chains; alternative totals are five55465, four43626 and one57312 with omitted effects. Exactly two new-acquisition fixtures execute actual39238(23)/29913 before routing, storing numeric event23/parameter0 and advancing the two-slot queue; event meaning/consumers remain open. Optional shared-memory/query/event/state inputs preserve old defaults. Native roots/fractions/records and initial basis/ground/bounds/state remain supplied; environment/posture/alternative-mode/other suffix/full53418/scheduler/legal collision/platform gameplay remain omitted or unverified in these fixtures. No original executable/full QVM/native collision/physics/rendering executes. Eight independent tests cover transitions/full PS/geometry, skipped children and caller gating, old-state flags2/mode priority, reached event queue and full outputs into movement, independent slide/mode gravity checks, source identity and scope. All679 tests pass. Prior traversal-query, clearance-mode, main-contact and lost-action reports regenerate byte-identically; new report reproduces twice byte-identically (809190 bytes). Storage/filter setup, documentation links and whitespace checks pass. No assets or shared instruction evaluator changed. RE-532 remains open for broader scope; RE-536 tracks other movement bodies/combined producers/native/legal/event-consumer/main/platform work. Broad game/assets/rendering/protocol milestones remain open.
|
docs/REVERSE_ENGINEERING_TODO.md
CHANGED
|
@@ -660,3 +660,9 @@ Purpose: turn the supplied installation into an evidence-backed specification of
|
|
| 660 |
- [x] RE-530 Recover action-produced flag suppression/plane priority and rebased deep-query/animation state with actual caller clearing ([LOSTACTION-002](research/QVM_LOST_ACTION.md)).
|
| 661 |
- [x] RE-531 Compose nested ground action before main timer and distinct main54981(0), reached mode/post-ground/landing/queue/resource state ([LOSTACTION-003](research/QVM_LOST_ACTION.md)).
|
| 662 |
- [ ] RE-532 Recover actual56639/query and alternative55465/41848/other modes, event/PS216/suffix consumers, real basis/input/environment/native collision ABI/legal domains and complete main/scheduler/macOS/Linux Rust/Bevy/Solari gameplay; continue broader game/assets/rendering/protocol work.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 660 |
- [x] RE-530 Recover action-produced flag suppression/plane priority and rebased deep-query/animation state with actual caller clearing ([LOSTACTION-002](research/QVM_LOST_ACTION.md)).
|
| 661 |
- [x] RE-531 Compose nested ground action before main timer and distinct main54981(0), reached mode/post-ground/landing/queue/resource state ([LOSTACTION-003](research/QVM_LOST_ACTION.md)).
|
| 662 |
- [ ] RE-532 Recover actual56639/query and alternative55465/41848/other modes, event/PS216/suffix consumers, real basis/input/environment/native collision ABI/legal domains and complete main/scheduler/macOS/Linux Rust/Bevy/Solari gameplay; continue broader game/assets/rendering/protocol work.
|
| 663 |
+
|
| 664 |
+
|
| 665 |
+
- [x] RE-533 Evaluate reached56335 inside actual56639 with shared memory, exact side geometry/roots/short circuit and full PS preservation checks ([MAINQUERY-001](research/QVM_MAIN_QUERY.md)).
|
| 666 |
+
- [x] RE-534 Carry full query velocity/anchor/field44/torso/state/return into actual main gating, old-state flags2 and mode selection ([MAINQUERY-002](research/QVM_MAIN_QUERY.md)).
|
| 667 |
+
- [x] RE-535 Evaluate reached main39238(23)/29913 acquisition queue effects before routing and verify conditional emission/persistence ([MAINQUERY-003](research/QVM_MAIN_QUERY.md)).
|
| 668 |
+
- [ ] RE-536 Recover57312/55465/41848/43626/42838 movement bodies, combine query with posture/ground/nested-action producers, main prefix/suffix/event/PS216 consumers and real basis/input/environment/native collision ABI/legal domains; complete53418/scheduler/macOS/Linux Rust/Bevy/Solari gameplay and broader game/assets/rendering/protocol work.
|
docs/research/QVM_CLEARANCE_MODE.md
CHANGED
|
@@ -60,3 +60,6 @@ Eight tests independently verify150 side-vector/root/geometry/PS-snapshot result
|
|
| 60 |
RE-464 remains open for native geometry/meaning and broader query state. RE-468 tracks actual60091 collision/velocity/flag effects, native side traces/sqrt/ABI, basis and timer/gravity/flag producers/legal domains, complete side/query/main/mode shared state and runtime/macOS/Linux/Rust/Bevy/Solari validation. Other modes/actions/suffix, contact/resource/playback and packet/entity/player/snapshot/rendering milestones remain open.
|
| 61 |
|
| 62 |
Follow-up: [step/wrapper recovery](QVM_STEP_COLLISION.md) evaluates60091 and59710 inside selected41768 fixtures. Conditional source stores now explain concrete restoration of32 after the mode prefix clears it; underlying57714 slide/native trace effects and full physics remain open (RE-469–472).
|
|
|
|
|
|
|
|
|
|
|
|
| 60 |
RE-464 remains open for native geometry/meaning and broader query state. RE-468 tracks actual60091 collision/velocity/flag effects, native side traces/sqrt/ABI, basis and timer/gravity/flag producers/legal domains, complete side/query/main/mode shared state and runtime/macOS/Linux/Rust/Bevy/Solari validation. Other modes/actions/suffix, contact/resource/playback and packet/entity/player/snapshot/rendering milestones remain open.
|
| 61 |
|
| 62 |
Follow-up: [step/wrapper recovery](QVM_STEP_COLLISION.md) evaluates60091 and59710 inside selected41768 fixtures. Conditional source stores now explain concrete restoration of32 after the mode prefix clears it; underlying57714 slide/native trace effects and full physics remain open (RE-469–472).
|
| 63 |
+
|
| 64 |
+
|
| 65 |
+
Follow-up: [shared query and main acquisition event](QVM_MAIN_QUERY.md) evaluates the reached side-clearance child, transfers full query state into actual main and executes conditional event23. Earlier isolated fixture scope remains unchanged; combined environment/alternative modes/native/full runtime remain open.
|
docs/research/QVM_LOST_ACTION.md
CHANGED
|
@@ -33,3 +33,6 @@ Final contents preserves actual resource, animation, numeric event queue and ext
|
|
| 33 |
Eight tests independently verify all48 nested/helper outcomes, sentinel-versus-new-flag priority and plane retention, rebased deep geometry, twelve skipped prepared actions, actual posture/ground/timer entry handoffs, distinct nested/main argument calls and query gating,12 reached slide/mode/post-ground states and conditional caller250 stores, final event/resource/animation persistence, source identity and supplied-effect limits. Reproducibility/full-suite/storage/link/whitespace results are recorded in the ledger.
|
| 34 |
|
| 35 |
RE-528 remains open for broader query/mode/native/consumer/runtime scope; ground-loss54981 integration is covered by RE-529–531. RE-532 tracks actual56639/query and alternative55465/41848/other movement bodies, remaining event/PS216/suffix consumers, real basis/input/environment/native collision ABI/legal domains and complete main/scheduler/macOS/Linux Rust/Bevy/Solari gameplay. Other game/assets/rendering/protocol milestones remain open.
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
Eight tests independently verify all48 nested/helper outcomes, sentinel-versus-new-flag priority and plane retention, rebased deep geometry, twelve skipped prepared actions, actual posture/ground/timer entry handoffs, distinct nested/main argument calls and query gating,12 reached slide/mode/post-ground states and conditional caller250 stores, final event/resource/animation persistence, source identity and supplied-effect limits. Reproducibility/full-suite/storage/link/whitespace results are recorded in the ledger.
|
| 34 |
|
| 35 |
RE-528 remains open for broader query/mode/native/consumer/runtime scope; ground-loss54981 integration is covered by RE-529–531. RE-532 tracks actual56639/query and alternative55465/41848/other movement bodies, remaining event/PS216/suffix consumers, real basis/input/environment/native collision ABI/legal domains and complete main/scheduler/macOS/Linux Rust/Bevy/Solari gameplay. Other game/assets/rendering/protocol milestones remain open.
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
Follow-up: [shared query and main acquisition event](QVM_MAIN_QUERY.md) evaluates the reached side-clearance child, transfers full query state into actual main and executes conditional event23. Earlier isolated fixture scope remains unchanged; combined environment/alternative modes/native/full runtime remain open.
|
docs/research/QVM_MAIN_QUERY.md
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# QVM shared query, side clearance and main acquisition event
|
| 2 |
+
|
| 3 |
+
This batch completes bounded RE-533–535 / F-259–261. It extends the isolated [query](QVM_TRAVERSAL_QUERY.md), [side clearance](QVM_CLEARANCE_MODE.md) and [main action](QVM_ACTION_PROBE.md) analyses with live memory across the query's child and its actual main caller. No original executable, full QVM, native collision, physics or rendering executes.
|
| 4 |
+
|
| 5 |
+
Reproduce with `python3 scripts/analyze_qvm_main_query.py`; validate with `python3 scripts/test_qvm_main_query.py`. The [machine report](qvm-main-query.json) records source identity, 30 standalone probes with all 256 PS words before/after, and 20 main chains. Roots and native trace fractions remain supplied. The report is 809190 bytes in normal Git; no assets change.
|
| 6 |
+
|
| 7 |
+
## MAINQUERY-001 — Reached side clearance shares the query's memory (RE-533)
|
| 8 |
+
|
| 9 |
+
The ten standalone variants cover acquisition, first trace clear, second trace blocked, either side trace clear, active blocked/clear, release, upper exit and fractional anchor. Each runs with planar basis (1,0), (3,4) and (0,0). Forward and perpendicular right vectors come from the same supplied basis. The query now invokes actual56335 only after its two trace gates reach that request. The child uses the current PS origin, entity and basis, evaluates its own direction helper, and returns the complete memory alongside its actual numeric result. Twelve standalone probes reach this child; prepared side fractions on other paths have no effect.
|
| 10 |
+
|
| 11 |
+
The first side fraction1 short circuits after one trace; otherwise the opposite-side trace is requested. Acceptance requires both fractions to differ from1. The side helper's 12-unit normalized right displacement, raised origin and 20-unit forward endpoints remain exact float-word checks, including zero basis. For these no-native-side-effect fixtures the child's entire 1024-byte PS snapshot stays unchanged. This does not establish native callback immutability or legal collision configurations.
|
| 12 |
+
|
| 13 |
+
The side return replaces the recorded zero in query local160 after STORE57256 and before LOAD57258. The source CALL, caller trace, branch instructions and result-dependent stores still execute. Query and side/direction frames occupy separate synthetic address ranges; all live caller memory survives the child.
|
| 14 |
+
|
| 15 |
+
## MAINQUERY-002 — Full query outputs reach the main caller (RE-534)
|
| 16 |
+
|
| 17 |
+
Optional initial-memory and return-memory paths let56639 consume current flags, ground, origin, height, anchor, field44, timers, torso and velocity rather than reconstructing an isolated PS. Standalone comparisons independently predict every PS word: only the query's state220, anchor200, field44, velocity and torso outputs may change in these fixtures.
|
| 18 |
+
|
| 19 |
+
Acquisition retains horizontal velocity, zeros vertical velocity, stores state bit1024, truncates supplied Z300.75 to anchor300 and requests torso54 (result182 with timer0). Release clears bit1024/anchor, floors field44 at300 and applies the recovered normalized impulse to all three current velocity components. Active first-trace clear requests torso55 (result183). Upper exit returns1 without a trace. These observations retain numeric offsets and identifiers; their full gameplay meanings remain unverified.
|
| 20 |
+
|
| 21 |
+
Twenty actual main slices combine five variants, input flags32/160 and separate no-hit/feet-hit main54981(0) patterns. Actual clock/timer aging and main action run first. Ten feet-hit cases suppress query56639 through the caller flags&12 gate; no prepared query or side child executes there. Ten remaining queries consume the live state and replace main local72 after STORE54314, before the caller reads it. Initial state220 is an explicit optional input; existing default reports retain state0 and remain byte-identical.
|
| 22 |
+
|
| 23 |
+
The caller's old-bit1024 snapshot precedes the query. A nonzero query return with that old bit sets flags2, even if the query has cleared bit1024. Query velocity, anchor, field44 and torso/timer effects survive into routing and the recorded suffix. Across the20 main chains, ten select evaluated41768, five request55465, four request43626 and one requests57312. Alternative movement effects remain omitted. Actual41768 receives the query's full velocity, rather than the former isolated bridge's return/state220-only transfer.
|
| 24 |
+
|
| 25 |
+
## MAINQUERY-003 — Actual main event23 updates the numeric queue (RE-535)
|
| 26 |
+
|
| 27 |
+
When the old bit1024 was clear and the query sets it, main requests39238(23). The optional event callback evaluates that wrapper and29913 before continuing routing. Exactly two main fixtures acquire a new state, one for each input flag variant. Their event queue changes from sequence0/events[700,701]/parameters[800,801] to sequence1/events[23,701]/parameters[0,801]. Release, active exit, failed clearance and caller-gated query cases emit no acquisition event. Queue effects survive the selected movement and supplied-effect suffix.
|
| 28 |
+
|
| 29 |
+
Event23 remains a numeric identifier. This batch does not establish its consumer behavior, sound, animation, networking or user-visible meaning. It verifies the reached source writer and its ordering against the query's state transition.
|
| 30 |
+
|
| 31 |
+
## Validation and next tasks
|
| 32 |
+
|
| 33 |
+
Eight tests independently check query transition formulas, call order and hull geometry; full PS mutation boundaries; side roots, geometry and short circuit; fractional anchor and full release impulse; live main gating, old-state flags2 and mode priority; conditional event wrapper/queue stores; output persistence into mode/suffix; source SHA256 and supplied/omitted-effect limits. Prior query, clearance, main-contact and nested-ground-action reports regenerate byte-identically. The new report reproduces twice byte-identically. Full-suite, storage/filter, link and whitespace results are recorded in the ledger.
|
| 34 |
+
|
| 35 |
+
RE-532 remains open for its broader modes/consumers/native/runtime scope. RE-536 tracks actual57312/55465/41848/43626/42838 movement bodies, query integration with combined posture/ground/nested-action producers, omitted main prefix/suffix and event/PS216 consumers, native trace/content/root ABI and collision-consistent legal domains. Full53418/scheduler and macOS/Linux Rust/Bevy/Solari gameplay remain open, alongside game assets, rendering and protocol work.
|
| 36 |
+
|
| 37 |
+
For the Rust rewrite, preserve the pre-query old-state snapshot, exact float32 arithmetic/truncation, conditional child requests, full state mutation and event queue order. Keep supplied native responses explicit until collision behavior is recovered. These bounded fixtures provide future port comparison cases; no Rust or Bevy/Solari implementation is added here.
|
docs/research/QVM_TRAVERSAL_QUERY.md
CHANGED
|
@@ -69,3 +69,6 @@ Eight tests independently verify direction/root arguments, all348 query outputs/
|
|
| 69 |
RE-460 remains open for broader main/mode/native work. RE-464 tracks helper56335 geometry and side effects, actual native traces/sqrt/ABI and basis producers, state/anchor/field44/flag meanings and legal domains, initial/cooldown/contact/resource interactions, actual54981 and mode/suffix effects, complete query-to-movement shared state, runtime/macOS/Linux/Rust/Bevy/Solari compatibility. Playback/packet/entity/player/snapshot/rendering milestones remain open.
|
| 70 |
|
| 71 |
Follow-up: [56335 side-helper recovery](QVM_CLEARANCE_MODE.md) evaluates its two opposite-offset probes and result at matching origin/basis, replacing the independent Boolean in20 query/main chains. The evaluated body preserves seeded PS; native callback effects, full query state and geometry/legal domains remain open (RE-465–468).
|
|
|
|
|
|
|
|
|
|
|
|
| 69 |
RE-460 remains open for broader main/mode/native work. RE-464 tracks helper56335 geometry and side effects, actual native traces/sqrt/ABI and basis producers, state/anchor/field44/flag meanings and legal domains, initial/cooldown/contact/resource interactions, actual54981 and mode/suffix effects, complete query-to-movement shared state, runtime/macOS/Linux/Rust/Bevy/Solari compatibility. Playback/packet/entity/player/snapshot/rendering milestones remain open.
|
| 70 |
|
| 71 |
Follow-up: [56335 side-helper recovery](QVM_CLEARANCE_MODE.md) evaluates its two opposite-offset probes and result at matching origin/basis, replacing the independent Boolean in20 query/main chains. The evaluated body preserves seeded PS; native callback effects, full query state and geometry/legal domains remain open (RE-465–468).
|
| 72 |
+
|
| 73 |
+
|
| 74 |
+
Follow-up: [shared query and main acquisition event](QVM_MAIN_QUERY.md) evaluates the reached side-clearance child, transfers full query state into actual main and executes conditional event23. Earlier isolated fixture scope remains unchanged; combined environment/alternative modes/native/full runtime remain open.
|
docs/research/README.md
CHANGED
|
@@ -234,3 +234,6 @@ The extension collector adds five focused tests for native tail calls, command-r
|
|
| 234 |
|
| 235 |
|
| 236 |
[QVM ground-loss nested action and main re-probe](QVM_LOST_ACTION.md) adds RE-529–531. Reproduce with `python3 scripts/analyze_qvm_lost_action.py`; check with `python3 scripts/test_qvm_lost_action.py`. Actual nested/main action ordering composes with ground/movement; query/other modes/native/full runtime remain open.
|
|
|
|
|
|
|
|
|
|
|
|
| 234 |
|
| 235 |
|
| 236 |
[QVM ground-loss nested action and main re-probe](QVM_LOST_ACTION.md) adds RE-529–531. Reproduce with `python3 scripts/analyze_qvm_lost_action.py`; check with `python3 scripts/test_qvm_lost_action.py`. Actual nested/main action ordering composes with ground/movement; query/other modes/native/full runtime remain open.
|
| 237 |
+
|
| 238 |
+
|
| 239 |
+
[QVM shared query and main acquisition event](QVM_MAIN_QUERY.md) adds RE-533–535. Reproduce with `python3 scripts/analyze_qvm_main_query.py`; check with `python3 scripts/test_qvm_main_query.py`. Actual side-clearance/query/full state and conditional event23 compose at main; other modes/combined environment/native/full runtime remain open.
|
docs/research/qvm-main-query.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
scripts/analyze_qvm_clearance_mode.py
CHANGED
|
@@ -19,8 +19,10 @@ MODE_LOCAL=0x51000000
|
|
| 19 |
def snapshot(m):return hashlib.sha256(b''.join((m[PS+o]&0xffffffff).to_bytes(4,'little') for o in range(0,1024,4))).hexdigest()
|
| 20 |
|
| 21 |
|
| 22 |
-
def clearance_probe(ins,right=(0,1),forward=(1,0),z=300,fractions=(.5,.5)):
|
| 23 |
m={PS+o:0x5a5a5a5a for o in range(0,1024,4)};m.update({35024032:FRAME,FRAME:PS,FRAME+224:-25,PS+20:word(100),PS+24:word(200),PS+28:word(z),PS+140:7,35023892:word(forward[0]),35023896:word(forward[1]),35023904:word(right[0]),35023908:word(right[1]),35023912:word(777)})
|
|
|
|
|
|
|
| 24 |
for o in range(108,164,4):m[LOCAL+o]=0
|
| 25 |
m[LOCAL+116]=word(fractions[0]);before=snapshot(m);root=root_word([*right,0]);pc=56336;trace=[];calls=[];requests=[];children=[];returned=None
|
| 26 |
while returned is None:
|
|
@@ -31,7 +33,9 @@ def clearance_probe(ins,right=(0,1),forward=(1,0),z=300,fractions=(.5,.5)):
|
|
| 31 |
a=c['args'];requests.append({'instruction':c['instruction'],'args':a,'start_float_words':[m[a[12]+o]&0xffffffff for o in [0,4,8]],'end_float_words':[m[a[24]+o]&0xffffffff for o in [0,4,8]],'mins_float_words':[m[a[16]+o]&0xffffffff for o in [0,4,8]],'maxs_float_words':[m[a[20]+o]&0xffffffff for o in [0,4,8]],'supplied_fraction_float_word':m[LOCAL+116]&0xffffffff})
|
| 32 |
if pc==56597:m[LOCAL+116]=word(fractions[1])
|
| 33 |
if t['trace'] and ins[t['trace'][-1]]['opcode']=='LEAVE':returned=t['stack'][-1]
|
| 34 |
-
|
|
|
|
|
|
|
| 35 |
|
| 36 |
|
| 37 |
def query_chain(ins,query_fractions,side_fractions,walk,z=300):
|
|
|
|
| 19 |
def snapshot(m):return hashlib.sha256(b''.join((m[PS+o]&0xffffffff).to_bytes(4,'little') for o in range(0,1024,4))).hexdigest()
|
| 20 |
|
| 21 |
|
| 22 |
+
def clearance_probe(ins,right=(0,1),forward=(1,0),z=300,fractions=(.5,.5),initial_memory=None,return_memory=False):
|
| 23 |
m={PS+o:0x5a5a5a5a for o in range(0,1024,4)};m.update({35024032:FRAME,FRAME:PS,FRAME+224:-25,PS+20:word(100),PS+24:word(200),PS+28:word(z),PS+140:7,35023892:word(forward[0]),35023896:word(forward[1]),35023904:word(right[0]),35023908:word(right[1]),35023912:word(777)})
|
| 24 |
+
if initial_memory is not None:
|
| 25 |
+
m=dict(initial_memory);right=tuple(number(m[a]) for a in [35023904,35023908]);forward=tuple(number(m[a]) for a in [35023892,35023896]);z=number(m[PS+28])
|
| 26 |
for o in range(108,164,4):m[LOCAL+o]=0
|
| 27 |
m[LOCAL+116]=word(fractions[0]);before=snapshot(m);root=root_word([*right,0]);pc=56336;trace=[];calls=[];requests=[];children=[];returned=None
|
| 28 |
while returned is None:
|
|
|
|
| 33 |
a=c['args'];requests.append({'instruction':c['instruction'],'args':a,'start_float_words':[m[a[12]+o]&0xffffffff for o in [0,4,8]],'end_float_words':[m[a[24]+o]&0xffffffff for o in [0,4,8]],'mins_float_words':[m[a[16]+o]&0xffffffff for o in [0,4,8]],'maxs_float_words':[m[a[20]+o]&0xffffffff for o in [0,4,8]],'supplied_fraction_float_word':m[LOCAL+116]&0xffffffff})
|
| 34 |
if pc==56597:m[LOCAL+116]=word(fractions[1])
|
| 35 |
if t['trace'] and ins[t['trace'][-1]]['opcode']=='LEAVE':returned=t['stack'][-1]
|
| 36 |
+
report={'right_xy_float_words':list(map(word,right)),'forward_xy_float_words':list(map(word,forward)),'ignored_right_z_float_word':m[35023912]&0xffffffff,'z_float_word':word(z),'supplied_fraction_float_words':list(map(word,fractions)),'supplied_right_sqrt_word':root,'right_scaled_float_words':[m[LOCAL+o]&0xffffffff for o in [36,40,44]],'return_word':returned,'ps_snapshot_before_sha256':before,'ps_snapshot_after_sha256':snapshot(m),'trace_requests':requests,'direction_children':children,'calls':calls,**trace_fields({'trace':trace},False)}
|
| 37 |
+
|
| 38 |
+
return (m,report) if return_memory else report
|
| 39 |
|
| 40 |
|
| 41 |
def query_chain(ins,query_fractions,side_fractions,walk,z=300):
|
scripts/analyze_qvm_main_contact.py
CHANGED
|
@@ -15,16 +15,21 @@ from analyze_vm_extensions import verified
|
|
| 15 |
def timer_state(m):return {'flags':m[PS+12]&0xffffffff,'movement':m[PS+16],'leg':m[PS+72],'torso':m[PS+80],'dt':m[35023932]}
|
| 16 |
|
| 17 |
|
| 18 |
-
def probe(ins,requested,timer,flags,pattern,initial_memory=None,environment_effect=None,posture_effect=None,action_effect=None):
|
| 19 |
-
m=seed(flags=flags,timer=timer) if initial_memory is None else dict(initial_memory);m.update({PS:1000,FRAME+4:requested,PS+4:0,PS+72:m.get(PS+72,200),PS+80:m.get(PS+80,17),PS+220:
|
| 20 |
clock=trace_slice(ins,53723,53789,m,{104:FRAME},local_base=MAIN_LOCAL);m=clock['memory'];clock_report={'old_time':1000,'requested':requested,'result_time':m[PS],'elapsed':m[35023932],'ps_elapsed':m[PS+284],'float_dt':m[35023928]&0xffffffff,'origin_snapshot':vec(m,35024004),'velocity_snapshot':vec(m,35024016),**trace_fields(clock,False)}
|
| 21 |
-
pc=54244;calls=[];trace=[];timers=None;mode=None;at_mode=None;environment=[];posture=None;action=None;policy='overlap_solid' if requested==1016 else 'clear'
|
| 22 |
while True:
|
| 23 |
-
t=trace_slice(ins,54244,54473,m,{104:FRAME},resume_at=pc,stop_targets=[s for s in ([54274,54382,54438]+([54247,54260,54441,54444] if environment_effect else [])+([54257] if posture_effect else [])+([54279] if action_effect else [])) if s!=pc],local_base=MAIN_LOCAL,call_results={54313:0},limit=1024);m=t['memory'];calls+=t['calls'];trace+=t['trace'];pc=t['stop']
|
| 24 |
if environment_effect and pc in [54247,54260,54441,54444]:
|
| 25 |
target=47217 if pc in [54247,54444] else 46773;phase='before' if pc<54438 else 'after';m,effect=environment_effect(ins,m,target,phase);environment.append(effect)
|
| 26 |
elif action_effect and pc==54279:m,action=action_effect(ins,m)
|
| 27 |
elif posture_effect and pc==54257:m,posture=posture_effect(ins,m)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 28 |
elif pc==54274:
|
| 29 |
before=timer_state(m);tt=trace_slice(ins,53049,53184,m,{},local_base=TIMER_LOCAL);m=tt['memory'];timers={'before':before,'after':timer_state(m),'calls':tt['calls'],**trace_fields(tt,False)}
|
| 30 |
elif pc==54382:
|
|
@@ -38,6 +43,9 @@ def probe(ins,requested,timer,flags,pattern,initial_memory=None,environment_effe
|
|
| 38 |
if environment_effect:report['environment']=environment
|
| 39 |
if posture_effect:report['posture']=posture
|
| 40 |
if action_effect:report['action']=action
|
|
|
|
|
|
|
|
|
|
| 41 |
return report
|
| 42 |
|
| 43 |
|
|
|
|
| 15 |
def timer_state(m):return {'flags':m[PS+12]&0xffffffff,'movement':m[PS+16],'leg':m[PS+72],'torso':m[PS+80],'dt':m[35023932]}
|
| 16 |
|
| 17 |
|
| 18 |
+
def probe(ins,requested,timer,flags,pattern,initial_memory=None,environment_effect=None,posture_effect=None,action_effect=None,query_effect=None,event_effect=None,state220=0):
|
| 19 |
+
m=seed(flags=flags,timer=timer) if initial_memory is None else dict(initial_memory);m.update({PS:1000,FRAME+4:requested,PS+4:0,PS+72:m.get(PS+72,200),PS+80:m.get(PS+80,17),PS+220:state220,FRAME+212:0,35023936:1,35024000:word(0)});initial=snapshot(m)
|
| 20 |
clock=trace_slice(ins,53723,53789,m,{104:FRAME},local_base=MAIN_LOCAL);m=clock['memory'];clock_report={'old_time':1000,'requested':requested,'result_time':m[PS],'elapsed':m[35023932],'ps_elapsed':m[PS+284],'float_dt':m[35023928]&0xffffffff,'origin_snapshot':vec(m,35024004),'velocity_snapshot':vec(m,35024016),**trace_fields(clock,False)}
|
| 21 |
+
pc=54244;calls=[];trace=[];timers=None;mode=None;at_mode=None;environment=[];posture=None;action=None;query=None;events=[];policy='overlap_solid' if requested==1016 else 'clear'
|
| 22 |
while True:
|
| 23 |
+
t=trace_slice(ins,54244,54473,m,{104:FRAME},resume_at=pc,stop_targets=[s for s in ([54274,54382,54438]+([54247,54260,54441,54444] if environment_effect else [])+([54257] if posture_effect else [])+([54279] if action_effect else [])+([54315] if query_effect else [])+([54369] if event_effect else [])) if s!=pc],local_base=MAIN_LOCAL,call_results={54313:0},limit=1024);m=t['memory'];calls+=t['calls'];trace+=t['trace'];pc=t['stop']
|
| 24 |
if environment_effect and pc in [54247,54260,54441,54444]:
|
| 25 |
target=47217 if pc in [54247,54444] else 46773;phase='before' if pc<54438 else 'after';m,effect=environment_effect(ins,m,target,phase);environment.append(effect)
|
| 26 |
elif action_effect and pc==54279:m,action=action_effect(ins,m)
|
| 27 |
elif posture_effect and pc==54257:m,posture=posture_effect(ins,m)
|
| 28 |
+
elif query_effect and pc==54315:
|
| 29 |
+
m,query=query_effect(ins,m);m[MAIN_LOCAL+72]=query['return_word']
|
| 30 |
+
elif event_effect and pc==54369:
|
| 31 |
+
for c in t['calls']:
|
| 32 |
+
if c['target']==39238:m,e=event_effect(ins,m,c['target'],c['args']);events.append(e)
|
| 33 |
elif pc==54274:
|
| 34 |
before=timer_state(m);tt=trace_slice(ins,53049,53184,m,{},local_base=TIMER_LOCAL);m=tt['memory'];timers={'before':before,'after':timer_state(m),'calls':tt['calls'],**trace_fields(tt,False)}
|
| 35 |
elif pc==54382:
|
|
|
|
| 43 |
if environment_effect:report['environment']=environment
|
| 44 |
if posture_effect:report['posture']=posture
|
| 45 |
if action_effect:report['action']=action
|
| 46 |
+
if query_effect:
|
| 47 |
+
report['query']=query;report['query_final']={str(o):m[PS+o]&0xffffffff for o in [12,20,24,28,32,36,40,44,80,84,108,112,116,120,124,200,220]}
|
| 48 |
+
if event_effect:report['events']=events
|
| 49 |
return report
|
| 50 |
|
| 51 |
|
scripts/analyze_qvm_main_query.py
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""Shared-memory56639/56335 children at the actual main query/event boundary."""
|
| 3 |
+
import itertools,json
|
| 4 |
+
from pathlib import Path
|
| 5 |
+
from analyze_qvm import decode,write_json
|
| 6 |
+
from analyze_qvm_acceleration import PS,FRAME,word
|
| 7 |
+
from analyze_qvm_action_probe import memory,action,PATTERNS
|
| 8 |
+
from analyze_qvm_traversal_query import query_probe
|
| 9 |
+
from analyze_qvm_clearance_mode import clearance_probe
|
| 10 |
+
from analyze_qvm_main_contact import probe
|
| 11 |
+
from analyze_qvm_landing import event
|
| 12 |
+
from analyze_vm_extensions import verified
|
| 13 |
+
|
| 14 |
+
VARIANTS={
|
| 15 |
+
'acquire':{},'first_clear':{'fractions':(1,1)},
|
| 16 |
+
'second_blocked':{'fractions':(.5,.5)},
|
| 17 |
+
'side_first_clear':{'side':(1,.5)},'side_second_clear':{'side':(.5,1)},
|
| 18 |
+
'active_blocked':{'state':1024},
|
| 19 |
+
'active_clear':{'state':1024,'fractions':(1,1)},
|
| 20 |
+
'release':{'state':1024,'forward':0},
|
| 21 |
+
'upper_exit':{'state':1024,'z':351},
|
| 22 |
+
'fractional_anchor':{'z':300.75},
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
def seed(flags,spec,basis):
|
| 27 |
+
m=memory(flags,basis)
|
| 28 |
+
for o in range(0,1024,4):m.setdefault(PS+o,0)
|
| 29 |
+
m.update({PS+20:word(100),PS+24:word(200),PS+28:word(spec.get('z',300)),PS+200:300,PS+44:10,PS+68:1023,PS+220:spec.get('state',0),PS+80:0,PS+84:26,35023904:word(-basis[1]),35023908:word(basis[0]),35023912:word(777)})
|
| 30 |
+
for i,v in enumerate([1,2,3]):m[PS+32+4*i]=word(v)
|
| 31 |
+
return m
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
def coupled(ins,m,spec):
|
| 35 |
+
def side(ins,m):return clearance_probe(ins,fractions=spec.get('side',(.5,.5)),initial_memory=m,return_memory=True)
|
| 36 |
+
return query_probe(ins,forward=spec.get('forward',1),fractions=spec.get('fractions',(.5,1)),initial_memory=m,clearance_effect=side,return_memory=True)
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
def standalone(ins,name,basis):
|
| 40 |
+
spec=VARIANTS[name];m=seed(32,spec,basis);before={str(o):m[PS+o]&0xffffffff for o in range(0,1024,4)};m,r=coupled(ins,m,spec)
|
| 41 |
+
return {'variant':name,'before':before,'query':r,'after':{str(o):m[PS+o]&0xffffffff for o in range(0,1024,4)}}
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
def main_case(ins,name,flags,pattern):
|
| 45 |
+
spec=VARIANTS[name];m=seed(flags,spec,(3,4))
|
| 46 |
+
def query(ins,m):return coupled(ins,m,spec)
|
| 47 |
+
def act(ins,m):return action(ins,m,0,PATTERNS[pattern])
|
| 48 |
+
p=probe(ins,1016,0,flags,'clear',initial_memory=m,action_effect=act,query_effect=query,event_effect=event,state220=m[PS+220]);p.update({'variant':name,'action_pattern':pattern,'input_flags':flags});return p
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
def main():
|
| 52 |
+
q=json.loads(Path('docs/research/qvm/qagame.json').read_text());_,ins=decode(verified(Path(q['source']['member']['output']).read_bytes(),q['sha256']))
|
| 53 |
+
out={'source':q['source'],'sha256':q['sha256'],'probes':[standalone(ins,*v) for v in itertools.product(VARIANTS,[(1,0),(3,4),(0,0)])],'main_chains':[main_case(ins,*v) for v in itertools.product(['acquire','side_second_clear','active_clear','release','upper_exit'],[32,160],['none','feet'])],'limitations':'Bounded finite synthetic shipped-QVM shared-memory query composition; no original executable/full QVM/native collision/physics/rendering executes. Actual56639, reached56335/56214/39338 and requested main39238/29913 event23 execute in disjoint helper frames with all memory returned. Query return replaces the recorded zero after54314 stores local72;56335 return replaces local160 after57256, before either caller reads it. Caller guards and old-state snapshot remain actual instructions. Actual clock/timer/main54981(0), reached41768 contact children and query/event effects compose; initial ground/bounds/basis/state, native roots/fractions/trace records remain supplied. Environment/posture/alternative modes/suffix effects remain omitted in these main fixtures. Event23 numeric meaning/native collision ABI/legal input domains, complete53418/scheduler/macOS/Linux/Rust/Bevy/Solari gameplay remain unverified.'}
|
| 54 |
+
write_json(Path('docs/research/qvm-main-query.json'),out);print('Composed actual query/side-clearance and main acquisition event state')
|
| 55 |
+
|
| 56 |
+
|
| 57 |
+
if __name__=='__main__':main()
|
scripts/analyze_qvm_traversal_query.py
CHANGED
|
@@ -29,12 +29,15 @@ def direction_effect(ins,m,dest):
|
|
| 29 |
def direction_probe(ins,xy):return direction_effect(ins,{35023892:word(xy[0]),35023896:word(xy[1]),35023900:word(777)},DEST)[1]
|
| 30 |
|
| 31 |
|
| 32 |
-
def query_probe(ins,state=0,flags=32,forward=1,z=300,anchor=300,ground=1023,fractions=(.5,1),clearance=1,height=38,basis=(1,0),field44=10,torso_timer=0):
|
| 33 |
m={35024032:FRAME,FRAME:PS,PS+220:state,PS+12:flags,PS+20:word(100),PS+24:word(200),PS+28:word(z),PS+200:anchor,PS+68:ground,PS+164:height,PS+140:7,PS+44:field44,PS+4:0,PS+80:torso_timer,PS+84:26,FRAME+224:-25,35023892:word(basis[0]),35023896:word(basis[1])}
|
| 34 |
for i,v in enumerate([1,2,3]):m[PS+32+i*4]=word(v)
|
| 35 |
for i,v in enumerate([-15,-15,-24,15,15,45]):m[FRAME+184+i*4]=word(v)
|
|
|
|
|
|
|
|
|
|
| 36 |
for o in range(96,152,4):m[LOCAL+o]=0
|
| 37 |
-
m[LOCAL+104]=word(fractions[0]);pc=56640;calls=[];trace=[];directions=[];animations=[];requests=[];returned=None;impulse_root=None
|
| 38 |
while returned is None:
|
| 39 |
if pc==56719:
|
| 40 |
impulse_root=root_word([-number(m[LOCAL+36]),-number(m[LOCAL+40]),number(-1102263091)])
|
|
@@ -44,11 +47,16 @@ def query_probe(ins,state=0,flags=32,forward=1,z=300,anchor=300,ground=1023,frac
|
|
| 44 |
m,child=direction_effect(ins,m,c['args'][8]);directions.append(child)
|
| 45 |
elif c['target']==39338:
|
| 46 |
child=animation_effect(ins,39338,c['args'][8],m);m=child['memory'];animations.append({'request_word':c['args'][8],'result_torso_word':m[PS+84]&0xffffffff,'calls':child['calls'],**trace_fields(child,False)})
|
|
|
|
|
|
|
| 47 |
elif c['target']==-25:
|
| 48 |
args=c['args'];requests.append({'instruction':c['instruction'],'args':args,'start_float_words':[m[args[12]+o]&0xffffffff for o in [0,4,8]],'end_float_words':[m[args[24]+o]&0xffffffff for o in [0,4,8]],'mins_float_words':[m[args[16]+o]&0xffffffff for o in [0,4,8]],'maxs_float_words':[m[args[20]+o]&0xffffffff for o in [0,4,8]],'supplied_fraction_float_word':m[LOCAL+104]&0xffffffff})
|
| 49 |
if pc==57219:m[LOCAL+104]=word(fractions[1])
|
| 50 |
if t['trace'] and ins[t['trace'][-1]]['opcode']=='LEAVE':returned=t['stack'][-1]
|
| 51 |
-
|
|
|
|
|
|
|
|
|
|
| 52 |
|
| 53 |
|
| 54 |
def dispatch_bridge(ins,kwargs,walk):
|
|
|
|
| 29 |
def direction_probe(ins,xy):return direction_effect(ins,{35023892:word(xy[0]),35023896:word(xy[1]),35023900:word(777)},DEST)[1]
|
| 30 |
|
| 31 |
|
| 32 |
+
def query_probe(ins,state=0,flags=32,forward=1,z=300,anchor=300,ground=1023,fractions=(.5,1),clearance=1,height=38,basis=(1,0),field44=10,torso_timer=0,initial_memory=None,clearance_effect=None,return_memory=False):
|
| 33 |
m={35024032:FRAME,FRAME:PS,PS+220:state,PS+12:flags,PS+20:word(100),PS+24:word(200),PS+28:word(z),PS+200:anchor,PS+68:ground,PS+164:height,PS+140:7,PS+44:field44,PS+4:0,PS+80:torso_timer,PS+84:26,FRAME+224:-25,35023892:word(basis[0]),35023896:word(basis[1])}
|
| 34 |
for i,v in enumerate([1,2,3]):m[PS+32+i*4]=word(v)
|
| 35 |
for i,v in enumerate([-15,-15,-24,15,15,45]):m[FRAME+184+i*4]=word(v)
|
| 36 |
+
if initial_memory is not None:
|
| 37 |
+
m=dict(initial_memory);state=m[PS+220];flags=m[PS+12];z=number(m[PS+28]);anchor=m[PS+200];ground=m[PS+68];height=m[PS+164];field44=m[PS+44];torso_timer=m[PS+80];basis=tuple(number(m[a]) for a in [35023892,35023896])
|
| 38 |
+
initial_velocity=[m[PS+32+i*4]&0xffffffff for i in range(3)]
|
| 39 |
for o in range(96,152,4):m[LOCAL+o]=0
|
| 40 |
+
m[LOCAL+104]=word(fractions[0]);pc=56640;calls=[];trace=[];directions=[];animations=[];requests=[];returned=None;impulse_root=None;side=None
|
| 41 |
while returned is None:
|
| 42 |
if pc==56719:
|
| 43 |
impulse_root=root_word([-number(m[LOCAL+36]),-number(m[LOCAL+40]),number(-1102263091)])
|
|
|
|
| 47 |
m,child=direction_effect(ins,m,c['args'][8]);directions.append(child)
|
| 48 |
elif c['target']==39338:
|
| 49 |
child=animation_effect(ins,39338,c['args'][8],m);m=child['memory'];animations.append({'request_word':c['args'][8],'result_torso_word':m[PS+84]&0xffffffff,'calls':child['calls'],**trace_fields(child,False)})
|
| 50 |
+
elif c['target']==56335 and clearance_effect:
|
| 51 |
+
m,side=clearance_effect(ins,m);clearance=side['return_word'];m[LOCAL+160]=clearance
|
| 52 |
elif c['target']==-25:
|
| 53 |
args=c['args'];requests.append({'instruction':c['instruction'],'args':args,'start_float_words':[m[args[12]+o]&0xffffffff for o in [0,4,8]],'end_float_words':[m[args[24]+o]&0xffffffff for o in [0,4,8]],'mins_float_words':[m[args[16]+o]&0xffffffff for o in [0,4,8]],'maxs_float_words':[m[args[20]+o]&0xffffffff for o in [0,4,8]],'supplied_fraction_float_word':m[LOCAL+104]&0xffffffff})
|
| 54 |
if pc==57219:m[LOCAL+104]=word(fractions[1])
|
| 55 |
if t['trace'] and ins[t['trace'][-1]]['opcode']=='LEAVE':returned=t['stack'][-1]
|
| 56 |
+
report={'initial_state220_word':state,'ps_flags_word':flags,'forward_byte':forward&255,'z_float_word':word(z),'initial_anchor_word':anchor,'ground_word':ground,'supplied_fraction_float_words':[word(v) for v in fractions],'supplied_clearance_word':clearance,'height_word':height,'basis_xy_float_words':[word(v) for v in basis],'initial_field44_word':field44,'initial_torso_timer_word':torso_timer,'initial_velocity_float_words':initial_velocity,'return_word':returned,'result_state220_word':m[PS+220]&0xffffffff,'result_anchor_word':m[PS+200],'result_field44_word':m[PS+44],'result_velocity_float_words':[m[PS+32+i*4]&0xffffffff for i in range(3)],'result_torso_word':m[PS+84]&0xffffffff,'result_torso_timer_word':m[PS+80],'supplied_impulse_sqrt_word':impulse_root,'direction_children':directions,'animation_children':animations,'trace_requests':requests,'calls':calls,**trace_fields({'trace':trace},False)}
|
| 57 |
+
|
| 58 |
+
if clearance_effect:report['clearance_child']=side
|
| 59 |
+
return (m,report) if return_memory else report
|
| 60 |
|
| 61 |
|
| 62 |
def dispatch_bridge(ins,kwargs,walk):
|
scripts/test_qvm_main_query.py
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""Independent shared-query state, side geometry and actual caller/event oracles."""
|
| 3 |
+
import hashlib,json
|
| 4 |
+
from pathlib import Path
|
| 5 |
+
import unittest
|
| 6 |
+
from test_qvm_ground import word,n,f
|
| 7 |
+
from test_qvm_slide_repeated import oracle as slide_oracle
|
| 8 |
+
from test_qvm_traversal_query import query_oracle,direction_oracle
|
| 9 |
+
from test_qvm_clearance_mode import clearance_geometry
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
def check_query(test,q):
|
| 13 |
+
expected=query_oracle(q);ret,state,anchor,field,velocity,torso,calls,geometry=expected
|
| 14 |
+
test.assertEqual([q['return_word'],q['result_state220_word'],q['result_anchor_word'],q['result_field44_word'],q['result_velocity_float_words'],q['result_torso_word']],[ret,state,anchor,field,velocity,torso])
|
| 15 |
+
test.assertEqual([c['target'] for c in q['calls']],calls)
|
| 16 |
+
test.assertEqual([(r['start_float_words'],r['end_float_words']) for r in q['trace_requests']],geometry)
|
| 17 |
+
side=q['clearance_child'];test.assertEqual(side is not None,56335 in calls)
|
| 18 |
+
if side is not None:
|
| 19 |
+
test.assertEqual(q['supplied_clearance_word'],int(all(n(v)!=1 for v in side['supplied_fraction_float_words'])))
|
| 20 |
+
test.assertEqual(side['return_word'],q['supplied_clearance_word'])
|
| 21 |
+
test.assertEqual(side['ps_snapshot_before_sha256'],side['ps_snapshot_after_sha256'])
|
| 22 |
+
vectors,root,square,points=clearance_geometry(side)
|
| 23 |
+
test.assertEqual(side['right_scaled_float_words'],list(map(word,vectors)))
|
| 24 |
+
test.assertEqual(side['supplied_right_sqrt_word'],root)
|
| 25 |
+
test.assertEqual(side['calls'][0]['args'],{'8':square})
|
| 26 |
+
test.assertEqual([(r['start_float_words'],r['end_float_words']) for r in side['trace_requests']],points)
|
| 27 |
+
test.assertEqual(len(side['trace_requests']),1 if n(side['supplied_fraction_float_words'][0])==1 else 2)
|
| 28 |
+
for d in q['direction_children']+([] if side is None else side['direction_children']):
|
| 29 |
+
vector,root,square=direction_oracle(d['input_xy_float_words']);test.assertEqual(d['result_direction_float_words'],list(map(word,vector)));test.assertEqual(d['supplied_sqrt_word'],root)
|
| 30 |
+
return expected
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
class QvmMainQueryTests(unittest.TestCase):
|
| 34 |
+
@classmethod
|
| 35 |
+
def setUpClass(cls):cls.r=json.loads(Path('docs/research/qvm-main-query.json').read_text())
|
| 36 |
+
|
| 37 |
+
def test_all_shared_query_words_calls_and_geometry(self):
|
| 38 |
+
self.assertEqual(len(self.r['probes']),30)
|
| 39 |
+
for p in self.r['probes']:check_query(self,p['query'])
|
| 40 |
+
|
| 41 |
+
def test_entire_ps_only_expected_words_change(self):
|
| 42 |
+
for p in self.r['probes']:
|
| 43 |
+
q=p['query'];ret,state,anchor,field,velocity,torso,_,_=query_oracle(q);expected=dict(p['before'])
|
| 44 |
+
for key,o in [('initial_state220_word',220),('ps_flags_word',12),('z_float_word',28),('initial_anchor_word',200),('ground_word',68),('height_word',164),('initial_field44_word',44),('initial_torso_timer_word',80)]:self.assertEqual(q[key],p['before'][str(o)])
|
| 45 |
+
self.assertEqual(q['initial_velocity_float_words'],[p['before'][str(o)] for o in [32,36,40]])
|
| 46 |
+
for o,value in [(220,state),(200,anchor),(44,field),(84,torso)]+list(zip([32,36,40],velocity)):expected[str(o)]=value&0xffffffff
|
| 47 |
+
self.assertEqual(p['after'],expected,p['variant'])
|
| 48 |
+
if q['clearance_child']:
|
| 49 |
+
digest=hashlib.sha256(b''.join(p['before'][str(o)].to_bytes(4,'little') for o in range(0,1024,4))).hexdigest();self.assertEqual(q['clearance_child']['ps_snapshot_before_sha256'],digest)
|
| 50 |
+
|
| 51 |
+
def test_clearance_short_circuit_and_acquisition_fractional_anchor(self):
|
| 52 |
+
rows=self.r['probes']
|
| 53 |
+
for name,count,active in [('side_first_clear',1,False),('side_second_clear',2,False),('acquire',2,True),('fractional_anchor',2,True)]:
|
| 54 |
+
selected=[p for p in rows if p['variant']==name];self.assertEqual(len(selected),3)
|
| 55 |
+
for p in selected:
|
| 56 |
+
q=p['query'];self.assertEqual(len(q['clearance_child']['trace_requests']),count);self.assertEqual(bool(q['result_state220_word']&1024),active)
|
| 57 |
+
if active:self.assertEqual(q['result_anchor_word'],300);self.assertEqual(q['result_velocity_float_words'][2],word(0));self.assertEqual(q['result_torso_word'],182)
|
| 58 |
+
|
| 59 |
+
def test_release_full_velocity_anchor_field_and_torso_propagation(self):
|
| 60 |
+
for p in self.r['probes']:
|
| 61 |
+
q=p['query']
|
| 62 |
+
if p['variant']=='release':self.assertIsNotNone(q['supplied_impulse_sqrt_word']);self.assertEqual(q['result_anchor_word'],0);self.assertEqual(q['result_field44_word'],300);self.assertNotEqual(q['result_velocity_float_words'],q['initial_velocity_float_words'])
|
| 63 |
+
if p['variant']=='active_clear':self.assertEqual(q['result_torso_word'],183);self.assertEqual(q['return_word'],1)
|
| 64 |
+
if p['variant']=='upper_exit':self.assertEqual(q['return_word'],1);self.assertEqual(q['trace_requests'],[])
|
| 65 |
+
|
| 66 |
+
def test_main_query_gate_old_state_flag2_and_actual_mode_priority(self):
|
| 67 |
+
self.assertEqual(len(self.r['main_chains']),20);queried=skipped=0
|
| 68 |
+
for p in self.r['main_chains']:
|
| 69 |
+
flags=p['action']['final']['flags'];q=p['query'];self.assertEqual(q is not None,not bool(flags&12))
|
| 70 |
+
if q is None:skipped+=1;state=p['action']['final']['state220']
|
| 71 |
+
else:
|
| 72 |
+
queried+=1;check_query(self,q);self.assertEqual(q['ps_flags_word'],flags);state=q['result_state220_word']
|
| 73 |
+
if q['initial_state220_word']&1024 and q['return_word']:flags|=2
|
| 74 |
+
mode=41768 if flags&128 else 55465 if flags&12 else 57312 if state&1024 else 43626
|
| 75 |
+
self.assertEqual(p['selected_mode'],mode)
|
| 76 |
+
boundary=p['at_mode'] if mode==41768 else p['after_dispatch'];self.assertEqual(boundary['flags'],flags)
|
| 77 |
+
if q:self.assertEqual(boundary['velocity'],q['result_velocity_float_words'])
|
| 78 |
+
self.assertEqual((queried,skipped),(10,10))
|
| 79 |
+
|
| 80 |
+
def test_event23_only_new_acquisition_numeric_queue_writer(self):
|
| 81 |
+
emitted=0
|
| 82 |
+
for p in self.r['main_chains']:
|
| 83 |
+
q=p['query'];new=bool(q and not q['initial_state220_word']&1024 and q['result_state220_word']&1024)
|
| 84 |
+
self.assertEqual(len(p['events']),int(new));self.assertEqual(any(c['target']==39238 for c in p['calls']),new)
|
| 85 |
+
final=p['query_final'];self.assertEqual(final['108'],int(new));self.assertEqual([final['112'],final['116'],final['120'],final['124']],[23,701,0,801] if new else [700,701,800,801])
|
| 86 |
+
if new:
|
| 87 |
+
emitted+=1;e=p['events'][0];self.assertEqual(e['args'],{'8':23});self.assertEqual(e['after'],{'sequence':1,'events':[23,701],'parameters':[0,801]});self.assertEqual(e['children'][0]['entry'],29913)
|
| 88 |
+
self.assertEqual(emitted,2)
|
| 89 |
+
|
| 90 |
+
def test_query_full_outputs_survive_main_boundary_and_suffix(self):
|
| 91 |
+
for p in self.r['main_chains']:
|
| 92 |
+
q=p['query']
|
| 93 |
+
if q is None:continue
|
| 94 |
+
final=p['query_final']
|
| 95 |
+
for o,value in [(44,q['result_field44_word']),(200,q['result_anchor_word']),(220,q['result_state220_word']),(84,q['result_torso_word']),(80,q['result_torso_timer_word'])]:self.assertEqual(final[str(o)],value&0xffffffff)
|
| 96 |
+
self.assertEqual([final[str(o)] for o in [32,36,40]],p['final']['velocity'])
|
| 97 |
+
if p['mode']:
|
| 98 |
+
mode=p['mode'];self.assertEqual(p['at_mode']['velocity'],q['result_velocity_float_words']);self.assertEqual(mode['initial'],p['at_mode']);w=mode['wrapper'];slide_oracle(self,w['first_slide'],w['before'])
|
| 99 |
+
if w['step']:slide_oracle(self,w['step']['slide'],w['step']['at_slide'])
|
| 100 |
+
expected=dict(w['final']);vz=f(n(expected['velocity'][2])-f(f(800)*n(p['clock']['float_dt'])));expected['velocity']=expected['velocity'][:2]+[word(vz)]
|
| 101 |
+
if vz<0:expected['flags']&=~192;expected['timer']=0
|
| 102 |
+
self.assertEqual(mode['mode_final'],expected);self.assertEqual(p['final'],expected)
|
| 103 |
+
|
| 104 |
+
def test_source_hash_and_explicit_supplied_native_and_omitted_mode_scope(self):
|
| 105 |
+
q=json.loads(Path('docs/research/qvm/qagame.json').read_text());self.assertEqual(self.r['source'],q['source']);self.assertEqual(self.r['sha256'],hashlib.sha256(Path(q['source']['member']['output']).read_bytes()).hexdigest())
|
| 106 |
+
for phrase in ['no original executable/full QVM/native collision/physics/rendering executes','native roots/fractions/trace records remain supplied','alternative modes/suffix effects remain omitted','before either caller reads it','Event23 numeric meaning']:self.assertIn(phrase,self.r['limitations'])
|
| 107 |
+
|
| 108 |
+
|
| 109 |
+
if __name__=='__main__':unittest.main()
|