gameplay: port override command ownership
Browse files- crates/urt-gameplay/src/bin/urt-camera-world.rs +1 -1
- crates/urt-gameplay/src/bin/urt-map-commands.rs +39 -0
- crates/urt-gameplay/src/map_commands.rs +67 -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/README.md +3 -0
- docs/research/RUST_MAP_SELECT.md +7 -0
- docs/research/rust-health-impulse.json +1 -1
- docs/research/rust-map-select.json +0 -0
- scripts/analyze_rust_map_select.py +14 -0
- scripts/test_rust_map_select.py +9 -0
- xtask/checks.tsv +13 -0
crates/urt-gameplay/src/bin/urt-camera-world.rs
CHANGED
|
@@ -312,7 +312,7 @@ fn run() -> Result<String, String> {
|
|
| 312 |
let mut state = w[0];
|
| 313 |
let slot = w[1] as usize;
|
| 314 |
let n = w[2] as usize;
|
| 315 |
-
let
|
| 316 |
origin: w[3..6].try_into().unwrap(),
|
| 317 |
angles: w[6..9].try_into().unwrap(),
|
| 318 |
};
|
|
|
|
| 312 |
let mut state = w[0];
|
| 313 |
let slot = w[1] as usize;
|
| 314 |
let n = w[2] as usize;
|
| 315 |
+
let _fallback = urt_gameplay::transition::View {
|
| 316 |
origin: w[3..6].try_into().unwrap(),
|
| 317 |
angles: w[6..9].try_into().unwrap(),
|
| 318 |
};
|
crates/urt-gameplay/src/bin/urt-map-commands.rs
CHANGED
|
@@ -60,6 +60,25 @@ fn run() -> Result<String, String> {
|
|
| 60 |
rotation_json(&effects)
|
| 61 |
))
|
| 62 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 63 |
_ => Err("unknown command".into()),
|
| 64 |
}
|
| 65 |
}
|
|
@@ -72,3 +91,23 @@ fn main() {
|
|
| 72 |
}
|
| 73 |
}
|
| 74 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 60 |
rotation_json(&effects)
|
| 61 |
))
|
| 62 |
}
|
| 63 |
+
"map" => {
|
| 64 |
+
let mut p = 0;
|
| 65 |
+
let mirror = bytes(&w, &mut p)?;
|
| 66 |
+
let current = bytes(&w, &mut p)?;
|
| 67 |
+
if p + 1 != w.len() {
|
| 68 |
+
return Err("invalid map response input".into());
|
| 69 |
+
}
|
| 70 |
+
let r = select_map(&mirror, ¤t).map_err(|e| format!("{e:?}"))?;
|
| 71 |
+
let cmd = r
|
| 72 |
+
.command
|
| 73 |
+
.as_ref()
|
| 74 |
+
.map(|v| format!("\"{}\"", hex(v)))
|
| 75 |
+
.unwrap_or("null".into());
|
| 76 |
+
Ok(format!(
|
| 77 |
+
"{{\"mirror\":\"{}\",\"command\":{cmd},\"operations\":{}}}",
|
| 78 |
+
hex(&r.mirror),
|
| 79 |
+
map_effects_json(&r.effects)
|
| 80 |
+
))
|
| 81 |
+
}
|
| 82 |
_ => Err("unknown command".into()),
|
| 83 |
}
|
| 84 |
}
|
|
|
|
| 91 |
}
|
| 92 |
}
|
| 93 |
}
|
| 94 |
+
|
| 95 |
+
fn map_effects_json(e: &[MapEffect]) -> String {
|
| 96 |
+
format!(
|
| 97 |
+
"[{}]",
|
| 98 |
+
e.iter()
|
| 99 |
+
.map(|e| match e {
|
| 100 |
+
MapEffect::ReadMap(v) => format!("{{\"op\":\"read-map\",\"text\":\"{}\"}}", hex(v)),
|
| 101 |
+
MapEffect::SetCycle(v) =>
|
| 102 |
+
format!("{{\"op\":\"set-cycle\",\"value\":\"{}\"}}", hex(v)),
|
| 103 |
+
MapEffect::ClearNext => "{\"op\":\"clear-next\"}".into(),
|
| 104 |
+
MapEffect::Command { mode, text } => format!(
|
| 105 |
+
"{{\"op\":\"command\",\"mode\":{mode},\"text\":\"{}\"}}",
|
| 106 |
+
hex(text)
|
| 107 |
+
),
|
| 108 |
+
MapEffect::Fallback => "{\"op\":\"fallback\"}".into(),
|
| 109 |
+
})
|
| 110 |
+
.collect::<Vec<String>>()
|
| 111 |
+
.join(",")
|
| 112 |
+
)
|
| 113 |
+
}
|
crates/urt-gameplay/src/map_commands.rs
CHANGED
|
@@ -94,3 +94,70 @@ mod rotation_tests {
|
|
| 94 |
assert_eq!(s, old);
|
| 95 |
}
|
| 96 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 94 |
assert_eq!(s, old);
|
| 95 |
}
|
| 96 |
}
|
| 97 |
+
|
| 98 |
+
#[derive(Clone, Debug, PartialEq, Eq)]
|
| 99 |
+
pub enum MapEffect {
|
| 100 |
+
ReadMap(Vec<u8>),
|
| 101 |
+
SetCycle(Vec<u8>),
|
| 102 |
+
ClearNext,
|
| 103 |
+
Command { mode: u32, text: Vec<u8> },
|
| 104 |
+
Fallback,
|
| 105 |
+
}
|
| 106 |
+
#[derive(Clone, Debug, PartialEq, Eq)]
|
| 107 |
+
pub struct MapSelection {
|
| 108 |
+
pub mirror: Vec<u8>,
|
| 109 |
+
pub command: Option<Vec<u8>>,
|
| 110 |
+
pub effects: Vec<MapEffect>,
|
| 111 |
+
}
|
| 112 |
+
pub fn select_map(mirror: &[u8], current: &[u8]) -> Result<MapSelection, Error> {
|
| 113 |
+
let old = logical(mirror)?;
|
| 114 |
+
if old.is_empty() {
|
| 115 |
+
return Ok(MapSelection {
|
| 116 |
+
mirror: old,
|
| 117 |
+
command: None,
|
| 118 |
+
effects: vec![MapEffect::Fallback],
|
| 119 |
+
});
|
| 120 |
+
}
|
| 121 |
+
let mut name = logical(current)?;
|
| 122 |
+
name.truncate(127);
|
| 123 |
+
let mut command = b"map ".to_vec();
|
| 124 |
+
command.extend_from_slice(&old[..old.len().min(127)]);
|
| 125 |
+
command.push(b'\n');
|
| 126 |
+
let effects = vec![
|
| 127 |
+
MapEffect::ReadMap(name.clone()),
|
| 128 |
+
MapEffect::SetCycle(name.clone()),
|
| 129 |
+
MapEffect::ClearNext,
|
| 130 |
+
MapEffect::Command {
|
| 131 |
+
mode: 2,
|
| 132 |
+
text: command.clone(),
|
| 133 |
+
},
|
| 134 |
+
];
|
| 135 |
+
Ok(MapSelection {
|
| 136 |
+
mirror: old,
|
| 137 |
+
command: Some(command),
|
| 138 |
+
effects,
|
| 139 |
+
})
|
| 140 |
+
}
|
| 141 |
+
#[cfg(test)]
|
| 142 |
+
mod select_tests {
|
| 143 |
+
use super::*;
|
| 144 |
+
#[test]
|
| 145 |
+
fn mirror_gate_truncation_and_raw_command() {
|
| 146 |
+
let r = select_map(&[255; 128], b"current").unwrap();
|
| 147 |
+
assert_eq!(r.mirror, vec![255; 128]);
|
| 148 |
+
let mut cmd = b"map ".to_vec();
|
| 149 |
+
cmd.extend_from_slice(&[255; 127]);
|
| 150 |
+
cmd.push(b'\n');
|
| 151 |
+
assert_eq!(r.command, Some(cmd));
|
| 152 |
+
assert!(matches!(r.effects[2], MapEffect::ClearNext));
|
| 153 |
+
assert!(matches!(r.effects[3], MapEffect::Command { mode: 2, .. }));
|
| 154 |
+
}
|
| 155 |
+
#[test]
|
| 156 |
+
fn empty_gate_and_logical_nul() {
|
| 157 |
+
let r = select_map(b"\0tail", &[7; 4097]).unwrap();
|
| 158 |
+
assert_eq!(r.effects, vec![MapEffect::Fallback]);
|
| 159 |
+
assert_eq!(r.command, None);
|
| 160 |
+
assert_eq!(select_map(b"cycle", b"x\0tail").unwrap().mirror, b"cycle");
|
| 161 |
+
assert_eq!(select_map(&[1; 4097], b"x"), Err(Error::BytesTooLong));
|
| 162 |
+
}
|
| 163 |
+
}
|
docs/FINDINGS.md
CHANGED
|
@@ -1610,3 +1610,6 @@ RE-813–822 replaces the scoreboard decimal assumption with actual37914 executi
|
|
| 1610 |
|
| 1611 |
|
| 1612 |
**RE-870:** 90 original7188 cases compose actual strlen, bounded-copy wrapper and original formatter. A nonempty override mirror records current engine mapname in g_nextCycleMap, copies the override into a127-byte local command buffer, requests engine g_NextMap clear and emits mode2 map command. VM mirror bytes remain unchanged; engine/native-copy and lower effects remain supplied/captured. [Evidence](research/QVM_MAP_SELECT.md).
|
|
|
|
|
|
|
|
|
|
|
|
| 1610 |
|
| 1611 |
|
| 1612 |
**RE-870:** 90 original7188 cases compose actual strlen, bounded-copy wrapper and original formatter. A nonempty override mirror records current engine mapname in g_nextCycleMap, copies the override into a127-byte local command buffer, requests engine g_NextMap clear and emits mode2 map command. VM mirror bytes remain unchanged; engine/native-copy and lower effects remain supplied/captured. [Evidence](research/QVM_MAP_SELECT.md).
|
| 1613 |
+
|
| 1614 |
+
|
| 1615 |
+
**RE-871:** Rust matches90 original map-selection cases with empty/NUL mirror gates,127-byte engine-mapname truncation, raw non-UTF8 bytes, unchanged VM mirror and exact truncated-override mode2 map command text. The typed effect order matches source cvar/read/command requests. Engine callbacks, native copy and actual command dispatch remain outside the port. [Evidence](research/RUST_MAP_SELECT.md).
|
docs/PROVISIONAL_TODO.md
CHANGED
|
@@ -1635,3 +1635,6 @@ RE-869: Rust matches192 original rotation cases, preserving signed cursor wrap,
|
|
| 1635 |
|
| 1636 |
|
| 1637 |
RE-870: 90 original7188 cases compose actual strlen, bounded-copy wrapper and original formatter. A nonempty override mirror records current engine mapname in g_nextCycleMap, copies the override into a127-byte local command buffer, requests engine g_NextMap clear and emits mode2 map command. VM mirror bytes remain unchanged; engine/native-copy and lower effects remain supplied/captured. Full runtime completion remains open. [Evidence](research/QVM_MAP_SELECT.md).
|
|
|
|
|
|
|
|
|
|
|
|
| 1635 |
|
| 1636 |
|
| 1637 |
RE-870: 90 original7188 cases compose actual strlen, bounded-copy wrapper and original formatter. A nonempty override mirror records current engine mapname in g_nextCycleMap, copies the override into a127-byte local command buffer, requests engine g_NextMap clear and emits mode2 map command. VM mirror bytes remain unchanged; engine/native-copy and lower effects remain supplied/captured. Full runtime completion remains open. [Evidence](research/QVM_MAP_SELECT.md).
|
| 1638 |
+
|
| 1639 |
+
|
| 1640 |
+
RE-871: Rust matches90 original map-selection cases with empty/NUL mirror gates,127-byte engine-mapname truncation, raw non-UTF8 bytes, unchanged VM mirror and exact truncated-override mode2 map command text. The typed effect order matches source cvar/read/command requests. Engine callbacks, native copy and actual command dispatch remain outside the port. Full runtime completion remains open. [Evidence](research/RUST_MAP_SELECT.md).
|
docs/RESEARCH_LEDGER.md
CHANGED
|
@@ -2051,3 +2051,8 @@ Rust matches192 original rotation cases, preserving signed cursor wrap, enable/t
|
|
| 2051 |
## 2026-10-27 — RE-870 Original map command branch with recovered copy and formatter
|
| 2052 |
|
| 2053 |
90 original7188 cases compose actual strlen, bounded-copy wrapper and original formatter. A nonempty override mirror records current engine mapname in g_nextCycleMap, copies the override into a127-byte local command buffer, requests engine g_NextMap clear and emits mode2 map command. VM mirror bytes remain unchanged; engine/native-copy and lower effects remain supplied/captured. Focused `cargo xtask test-group map-select` passes (5 Python tests); selected reports regenerate twice deterministically, with storage, documentation links and whitespace guards. Full suite deferred to task ten. Original assets unchanged; source fixtures do not establish complete native/runtime parity.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2051 |
## 2026-10-27 — RE-870 Original map command branch with recovered copy and formatter
|
| 2052 |
|
| 2053 |
90 original7188 cases compose actual strlen, bounded-copy wrapper and original formatter. A nonempty override mirror records current engine mapname in g_nextCycleMap, copies the override into a127-byte local command buffer, requests engine g_NextMap clear and emits mode2 map command. VM mirror bytes remain unchanged; engine/native-copy and lower effects remain supplied/captured. Focused `cargo xtask test-group map-select` passes (5 Python tests); selected reports regenerate twice deterministically, with storage, documentation links and whitespace guards. Full suite deferred to task ten. Original assets unchanged; source fixtures do not establish complete native/runtime parity.
|
| 2054 |
+
|
| 2055 |
+
|
| 2056 |
+
## 2026-10-27 — RE-871 Rust cycle-mirror map command policy
|
| 2057 |
+
|
| 2058 |
+
Rust matches90 original map-selection cases with empty/NUL mirror gates,127-byte engine-mapname truncation, raw non-UTF8 bytes, unchanged VM mirror and exact truncated-override mode2 map command text. The typed effect order matches source cvar/read/command requests. Engine callbacks, native copy and actual command dispatch remain outside the port. Focused `cargo xtask test-group rust-map-select` passes (9 Python tests); selected reports regenerate twice deterministically, with storage, documentation links and whitespace guards. Full suite deferred to task ten. Original assets unchanged; source fixtures do not establish complete native/runtime parity.
|
docs/REVERSE_ENGINEERING_TODO.md
CHANGED
|
@@ -1672,3 +1672,6 @@ Purpose: turn the supplied installation into an evidence-backed specification of
|
|
| 1672 |
|
| 1673 |
|
| 1674 |
- [x] RE-870 Original map command branch with recovered copy and formatter ([evidence](research/QVM_MAP_SELECT.md)).
|
|
|
|
|
|
|
|
|
|
|
|
| 1672 |
|
| 1673 |
|
| 1674 |
- [x] RE-870 Original map command branch with recovered copy and formatter ([evidence](research/QVM_MAP_SELECT.md)).
|
| 1675 |
+
|
| 1676 |
+
|
| 1677 |
+
- [x] RE-871 Rust cycle-mirror map command policy ([evidence](research/RUST_MAP_SELECT.md)).
|
docs/research/README.md
CHANGED
|
@@ -1208,3 +1208,6 @@ The extension collector adds five focused tests for native tail calls, command-r
|
|
| 1208 |
|
| 1209 |
|
| 1210 |
[RE-870: Original map command branch with recovered copy and formatter](QVM_MAP_SELECT.md).
|
|
|
|
|
|
|
|
|
|
|
|
| 1208 |
|
| 1209 |
|
| 1210 |
[RE-870: Original map command branch with recovered copy and formatter](QVM_MAP_SELECT.md).
|
| 1211 |
+
|
| 1212 |
+
|
| 1213 |
+
[RE-871: Rust cycle-mirror map command policy](RUST_MAP_SELECT.md).
|
docs/research/RUST_MAP_SELECT.md
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Rust cycle-mirror map command policy
|
| 2 |
+
|
| 3 |
+
RE-871. Reproduce with `python3 scripts/analyze_rust_map_select.py`; focused validation: `cargo xtask test-group rust-map-select`. [Machine report](rust-map-select.json).
|
| 4 |
+
|
| 5 |
+
Rust matches90 original map-selection cases with empty/NUL mirror gates,127-byte engine-mapname truncation, raw non-UTF8 bytes, unchanged VM mirror and exact truncated-override mode2 map command text. The typed effect order matches source cvar/read/command requests. Engine callbacks, native copy and actual command dispatch remain outside the port.
|
| 6 |
+
|
| 7 |
+
Original executable/native runtime and complete Linux/macOS Rust/Bevy/Solari acceptance remain unverified.
|
docs/research/rust-health-impulse.json
CHANGED
|
@@ -2985,7 +2985,7 @@
|
|
| 2985 |
"exit_code": 2
|
| 2986 |
}
|
| 2987 |
],
|
| 2988 |
-
"rust_unit_tests":
|
| 2989 |
"source_report": "docs/research/qvm-health-impulse.json",
|
| 2990 |
"source_report_sha256": "625fd8064004ea6dbdf398d51d0af844d9c635ff04c0a0790886dddb6ab81e71"
|
| 2991 |
}
|
|
|
|
| 2985 |
"exit_code": 2
|
| 2986 |
}
|
| 2987 |
],
|
| 2988 |
+
"rust_unit_tests": 127,
|
| 2989 |
"source_report": "docs/research/qvm-health-impulse.json",
|
| 2990 |
"source_report_sha256": "625fd8064004ea6dbdf398d51d0af844d9c635ff04c0a0790886dddb6ab81e71"
|
| 2991 |
}
|
docs/research/rust-map-select.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
scripts/analyze_rust_map_select.py
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
import hashlib,json
|
| 3 |
+
from pathlib import Path
|
| 4 |
+
from rust_map_commands_support import binary,result,invoke
|
| 5 |
+
from analyze_qvm import write_json
|
| 6 |
+
from rust_map_commands_support import blob
|
| 7 |
+
def encode(s):
|
| 8 |
+
a=s['input'];return [*blob(a['mirror']),*blob(a['current']),a['fallback']]
|
| 9 |
+
def project(s):return {k:s[k] for k in ['mirror','command','operations']}
|
| 10 |
+
def main():
|
| 11 |
+
b=binary();p=Path('docs/research/qvm-map-select.json');data=p.read_bytes();rows=[]
|
| 12 |
+
for s in json.loads(data)['probes']:rows.append({'source':project(s),'rust':result(b,'map',encode(s))})
|
| 13 |
+
write_json(Path('docs/research/rust-map-select.json'),{'source_report':str(p),'source_report_sha256':hashlib.sha256(data).hexdigest(),'probes':rows,'limits':'Rust matches90 original map-selection cases with empty/NUL mirror gates,127-byte engine-mapname truncation, raw non-UTF8 bytes, unchanged VM mirror and exact truncated-override mode2 map command text. The typed effect order matches source cvar/read/command requests. Engine callbacks, native copy and actual command dispatch remain outside the port.'})
|
| 14 |
+
if __name__=='__main__':main()
|
scripts/test_rust_map_select.py
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import hashlib,json,unittest
|
| 2 |
+
from pathlib import Path
|
| 3 |
+
class PortTests(unittest.TestCase):
|
| 4 |
+
def test_all_original_cases(self):
|
| 5 |
+
r=json.loads(Path('docs/research/rust-map-select.json').read_text());src=json.loads(Path(r['source_report']).read_text());self.assertEqual(len(r['probes']),len(src['probes']));self.assertGreater(len(r['probes']),20)
|
| 6 |
+
for p in r['probes']:self.assertEqual(p['rust'],p['source'])
|
| 7 |
+
def test_source_identity(self):
|
| 8 |
+
r=json.loads(Path('docs/research/rust-map-select.json').read_text());self.assertEqual(hashlib.sha256(Path(r['source_report']).read_bytes()).hexdigest(),r['source_report_sha256'])
|
| 9 |
+
if __name__=='__main__':unittest.main()
|
xtask/checks.tsv
CHANGED
|
@@ -2484,3 +2484,16 @@ report scripts/analyze_qvm_map_select.py docs/research/qvm-map-select.json
|
|
| 2484 |
edge docs/research/qvm-map-select.json scripts/test_qvm_map_select.py
|
| 2485 |
group map-select scripts/analyze_qvm_map_select.py
|
| 2486 |
edge scripts/analyze_qvm_map_select.py scripts/analyze_qvm_resumer_audit.py
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2484 |
edge docs/research/qvm-map-select.json scripts/test_qvm_map_select.py
|
| 2485 |
group map-select scripts/analyze_qvm_map_select.py
|
| 2486 |
edge scripts/analyze_qvm_map_select.py scripts/analyze_qvm_resumer_audit.py
|
| 2487 |
+
edge Cargo.toml scripts/analyze_rust_map_select.py
|
| 2488 |
+
edge Cargo.lock scripts/analyze_rust_map_select.py
|
| 2489 |
+
edge crates/urt-gameplay/Cargo.toml scripts/analyze_rust_map_select.py
|
| 2490 |
+
edge crates/urt-gameplay/src/lib.rs scripts/analyze_rust_map_select.py
|
| 2491 |
+
edge crates/urt-gameplay/src/map_commands.rs scripts/analyze_rust_map_select.py
|
| 2492 |
+
edge crates/urt-gameplay/src/bin/urt-map-commands.rs scripts/analyze_rust_map_select.py
|
| 2493 |
+
edge docs/research/qvm-map-select.json scripts/analyze_rust_map_select.py
|
| 2494 |
+
group rust-map-select scripts/analyze_rust_health_impulse.py
|
| 2495 |
+
group gameplay scripts/analyze_rust_map_select.py
|
| 2496 |
+
report scripts/analyze_rust_map_select.py docs/research/rust-map-select.json
|
| 2497 |
+
edge docs/research/rust-map-select.json scripts/test_rust_map_select.py
|
| 2498 |
+
group rust-map-select scripts/analyze_rust_map_select.py
|
| 2499 |
+
edge scripts/analyze_rust_map_select.py scripts/analyze_qvm_resumer_audit.py
|