nmarshall commited on
Commit
cef895c
·
1 Parent(s): 517cec8

gameplay: port userinfo lookup ownership

Browse files
crates/urt-gameplay/src/bin/urt-native-policy.rs CHANGED
@@ -341,6 +341,22 @@ fn run() -> Result<String, String> {
341
  rotation_ops(&out.normal.rotation)
342
  ))
343
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
344
  _ => Err("unknown command".into()),
345
  }
346
  }
@@ -505,3 +521,21 @@ fn clients_json(c: &[urt_gameplay::transition::MapClient]) -> String {
505
  .join(",")
506
  )
507
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
341
  rotation_ops(&out.normal.rotation)
342
  ))
343
  }
344
+ "info" => {
345
+ let mut p = 1;
346
+ let mut ring = *w.first().ok_or("missing selector")?;
347
+ let text = input_blob(&w, &mut p)?;
348
+ let key = input_blob(&w, &mut p)?;
349
+ if p != w.len() {
350
+ return Err("trailing info words".into());
351
+ }
352
+ let out = info_lookup(text.as_deref(), key.as_deref(), &mut ring)
353
+ .map_err(|e| format!("{e:?}"))?;
354
+ Ok(format!(
355
+ "{{\"found\":{},\"value\":\"{}\",\"ring\":{ring}}}",
356
+ out.found,
357
+ hex(&out.value)
358
+ ))
359
+ }
360
  _ => Err("unknown command".into()),
361
  }
362
  }
 
521
  .join(",")
522
  )
523
  }
524
+
525
+ fn input_blob(w: &[u32], p: &mut usize) -> Result<Option<Vec<u8>>, String> {
526
+ let n = *w.get(*p).ok_or("missing byte count")?;
527
+ *p += 1;
528
+ if n == u32::MAX {
529
+ return Ok(None);
530
+ }
531
+ let n = n as usize;
532
+ if n > 8192 || n > w.len() - *p {
533
+ return Err("invalid byte count".into());
534
+ }
535
+ let v = w[*p..*p + n]
536
+ .iter()
537
+ .map(|v| u8::try_from(*v).map_err(|_| "invalid byte".to_string()))
538
+ .collect::<Result<Vec<_>, _>>()?;
539
+ *p += n;
540
+ Ok(Some(v))
541
+ }
crates/urt-gameplay/src/native_policy.rs CHANGED
@@ -691,3 +691,76 @@ mod normal_session_tests {
691
  assert_eq!(sessions, s);
692
  }
693
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
691
  assert_eq!(sessions, s);
692
  }
693
  }
694
+
695
+ #[derive(Clone, Debug, PartialEq, Eq)]
696
+ pub struct InfoValue {
697
+ pub found: bool,
698
+ pub value: Vec<u8>,
699
+ }
700
+ /// Actual70503 logical-string subset. Non-null requests alternate buffers even
701
+ /// when absent; explicit null arguments preserve the selector.
702
+ pub fn info_lookup(
703
+ text: Option<&[u8]>,
704
+ key: Option<&[u8]>,
705
+ ring: &mut u32,
706
+ ) -> Result<InfoValue, Error> {
707
+ if *ring > 1 {
708
+ return Err(Error::InvalidInput);
709
+ }
710
+ let (Some(text), Some(key)) = (text, key) else {
711
+ return Ok(InfoValue {
712
+ found: false,
713
+ value: vec![],
714
+ });
715
+ };
716
+ let text = text.split(|v| *v == 0).next().unwrap_or_default();
717
+ let key = key.split(|v| *v == 0).next().unwrap_or_default();
718
+ if text.len() >= 8192 || key.len() >= 8192 {
719
+ return Err(Error::InvalidInput);
720
+ }
721
+ let text = text.strip_prefix(b"\\").unwrap_or(text);
722
+ let mut parts = text.split(|v| *v == b'\\');
723
+ let mut out = InfoValue {
724
+ found: false,
725
+ value: vec![],
726
+ };
727
+ while let (Some(k), Some(v)) = (parts.next(), parts.next()) {
728
+ if k.eq_ignore_ascii_case(key) {
729
+ out = InfoValue {
730
+ found: true,
731
+ value: v.to_vec(),
732
+ };
733
+ break;
734
+ }
735
+ }
736
+ *ring ^= 1;
737
+ Ok(out)
738
+ }
739
+ #[cfg(test)]
740
+ mod info_tests {
741
+ use super::*;
742
+ #[test]
743
+ fn first_match_empty_value_and_null_ownership() {
744
+ let mut r = 0;
745
+ let v = info_lookup(
746
+ Some(b"\\CL_GUID\\\\cl_guid\\second"),
747
+ Some(b"cl_guid"),
748
+ &mut r,
749
+ )
750
+ .unwrap();
751
+ assert!(v.found);
752
+ assert!(v.value.is_empty());
753
+ assert_eq!(r, 1);
754
+ assert!(!info_lookup(None, Some(b"x"), &mut r).unwrap().found);
755
+ assert_eq!(r, 1);
756
+ }
757
+ #[test]
758
+ fn oversized_input_preserves_selector() {
759
+ let mut r = 1;
760
+ assert_eq!(
761
+ info_lookup(Some(&vec![b'a'; 8192]), Some(b"x"), &mut r),
762
+ Err(Error::InvalidInput)
763
+ );
764
+ assert_eq!(r, 1);
765
+ }
766
+ }
docs/FINDINGS.md CHANGED
@@ -1682,3 +1682,6 @@ RE-813–822 replaces the scoreboard decimal assumption with actual37914 executi
1682
 
1683
 
1684
  **RE-894:** 96 actual70503 cases execute actual36038/69386, recovering optional leading separator, case-insensitive first-match keys, incomplete-pair rejection, empty values, embedded NUL and null-pointer early exits. Non-null calls XOR the two-buffer selector even on misses; null arguments preserve it. Oversized info fatal/aliasing/native userinfo retrieval remain open. [Evidence](research/QVM_INFO_LOOKUP.md).
 
 
 
 
1682
 
1683
 
1684
  **RE-894:** 96 actual70503 cases execute actual36038/69386, recovering optional leading separator, case-insensitive first-match keys, incomplete-pair rejection, empty values, embedded NUL and null-pointer early exits. Non-null calls XOR the two-buffer selector even on misses; null arguments preserve it. Oversized info fatal/aliasing/native userinfo retrieval remain open. [Evidence](research/QVM_INFO_LOOKUP.md).
1685
+
1686
+
1687
+ **RE-895:** Rust matches96 original70503 key/value and selector cases, preserving first-match case folding, incomplete-pair rejection, empty values, embedded NUL and null early exits. Oversized logical inputs reject without changing the selector. Native userinfo retrieval, raw pointer aliases and fatal semantics remain open. [Evidence](research/RUST_INFO_LOOKUP.md).
docs/PROVISIONAL_TODO.md CHANGED
@@ -1716,3 +1716,6 @@ RE-884–893 completed bounded queried spawn/camera and map persistence composit
1716
 
1717
 
1718
  RE-894: 96 actual70503 cases execute actual36038/69386, recovering optional leading separator, case-insensitive first-match keys, incomplete-pair rejection, empty values, embedded NUL and null-pointer early exits. Non-null calls XOR the two-buffer selector even on misses; null arguments preserve it. Oversized info fatal/aliasing/native userinfo retrieval remain open. Full runtime completion remains open. [Evidence](research/QVM_INFO_LOOKUP.md).
 
 
 
 
1716
 
1717
 
1718
  RE-894: 96 actual70503 cases execute actual36038/69386, recovering optional leading separator, case-insensitive first-match keys, incomplete-pair rejection, empty values, embedded NUL and null-pointer early exits. Non-null calls XOR the two-buffer selector even on misses; null arguments preserve it. Oversized info fatal/aliasing/native userinfo retrieval remain open. Full runtime completion remains open. [Evidence](research/QVM_INFO_LOOKUP.md).
1719
+
1720
+
1721
+ RE-895: Rust matches96 original70503 key/value and selector cases, preserving first-match case folding, incomplete-pair rejection, empty values, embedded NUL and null early exits. Oversized logical inputs reject without changing the selector. Native userinfo retrieval, raw pointer aliases and fatal semantics remain open. Full runtime completion remains open. [Evidence](research/RUST_INFO_LOOKUP.md).
docs/RESEARCH_LEDGER.md CHANGED
@@ -2185,3 +2185,8 @@ After the tenth commit, `cargo xtask test-full --since b9a94452` passed with the
2185
  ## 2026-10-28 — RE-894 Original userinfo key lookup and alternating buffers
2186
 
2187
  96 actual70503 cases execute actual36038/69386, recovering optional leading separator, case-insensitive first-match keys, incomplete-pair rejection, empty values, embedded NUL and null-pointer early exits. Non-null calls XOR the two-buffer selector even on misses; null arguments preserve it. Oversized info fatal/aliasing/native userinfo retrieval remain open. Focused `cargo xtask test-group qvm-info-lookup` passes (4 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.
 
 
 
 
 
 
2185
  ## 2026-10-28 — RE-894 Original userinfo key lookup and alternating buffers
2186
 
2187
  96 actual70503 cases execute actual36038/69386, recovering optional leading separator, case-insensitive first-match keys, incomplete-pair rejection, empty values, embedded NUL and null-pointer early exits. Non-null calls XOR the two-buffer selector even on misses; null arguments preserve it. Oversized info fatal/aliasing/native userinfo retrieval remain open. Focused `cargo xtask test-group qvm-info-lookup` passes (4 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.
2188
+
2189
+
2190
+ ## 2026-10-28 — RE-895 Rust userinfo lookup and buffer ownership
2191
+
2192
+ Rust matches96 original70503 key/value and selector cases, preserving first-match case folding, incomplete-pair rejection, empty values, embedded NUL and null early exits. Oversized logical inputs reject without changing the selector. Native userinfo retrieval, raw pointer aliases and fatal semantics remain open. Focused `cargo xtask test-group rust-info-lookup` 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
@@ -1753,3 +1753,6 @@ Purpose: turn the supplied installation into an evidence-backed specification of
1753
 
1754
 
1755
  - [x] RE-894 Original userinfo key lookup and alternating buffers ([evidence](research/QVM_INFO_LOOKUP.md)).
 
 
 
 
1753
 
1754
 
1755
  - [x] RE-894 Original userinfo key lookup and alternating buffers ([evidence](research/QVM_INFO_LOOKUP.md)).
1756
+
1757
+
1758
+ - [x] RE-895 Rust userinfo lookup and buffer ownership ([evidence](research/RUST_INFO_LOOKUP.md)).
docs/research/README.md CHANGED
@@ -1288,3 +1288,6 @@ The extension collector adds five focused tests for native tail calls, command-r
1288
 
1289
 
1290
  [RE-894: Original userinfo key lookup and alternating buffers](QVM_INFO_LOOKUP.md).
 
 
 
 
1288
 
1289
 
1290
  [RE-894: Original userinfo key lookup and alternating buffers](QVM_INFO_LOOKUP.md).
1291
+
1292
+
1293
+ [RE-895: Rust userinfo lookup and buffer ownership](RUST_INFO_LOOKUP.md).
docs/research/RUST_INFO_LOOKUP.md ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ # Rust userinfo lookup and buffer ownership
2
+
3
+ RE-895. Reproduce with `python3 scripts/analyze_rust_info_lookup.py`; focused validation: `cargo xtask test-group rust-info-lookup`. [Machine report](rust-info-lookup.json).
4
+
5
+ Rust matches96 original70503 key/value and selector cases, preserving first-match case folding, incomplete-pair rejection, empty values, embedded NUL and null early exits. Oversized logical inputs reject without changing the selector. Native userinfo retrieval, raw pointer aliases and fatal semantics remain open.
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": 148,
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": 150,
2989
  "source_report": "docs/research/qvm-health-impulse.json",
2990
  "source_report_sha256": "625fd8064004ea6dbdf398d51d0af844d9c635ff04c0a0790886dddb6ab81e71"
2991
  }
docs/research/rust-info-lookup.json ADDED
@@ -0,0 +1,1159 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "limits": "Rust matches96 original70503 key/value and selector cases, preserving first-match case folding, incomplete-pair rejection, empty values, embedded NUL and null early exits. Oversized logical inputs reject without changing the selector. Native userinfo retrieval, raw pointer aliases and fatal semantics remain open.",
3
+ "probes": [
4
+ {
5
+ "rust": {
6
+ "found": false,
7
+ "ring": 0,
8
+ "value": ""
9
+ },
10
+ "source": {
11
+ "found": false,
12
+ "ring": 0,
13
+ "value": ""
14
+ }
15
+ },
16
+ {
17
+ "rust": {
18
+ "found": false,
19
+ "ring": 1,
20
+ "value": ""
21
+ },
22
+ "source": {
23
+ "found": false,
24
+ "ring": 1,
25
+ "value": ""
26
+ }
27
+ },
28
+ {
29
+ "rust": {
30
+ "found": false,
31
+ "ring": 0,
32
+ "value": ""
33
+ },
34
+ "source": {
35
+ "found": false,
36
+ "ring": 0,
37
+ "value": ""
38
+ }
39
+ },
40
+ {
41
+ "rust": {
42
+ "found": false,
43
+ "ring": 1,
44
+ "value": ""
45
+ },
46
+ "source": {
47
+ "found": false,
48
+ "ring": 1,
49
+ "value": ""
50
+ }
51
+ },
52
+ {
53
+ "rust": {
54
+ "found": false,
55
+ "ring": 0,
56
+ "value": ""
57
+ },
58
+ "source": {
59
+ "found": false,
60
+ "ring": 0,
61
+ "value": ""
62
+ }
63
+ },
64
+ {
65
+ "rust": {
66
+ "found": false,
67
+ "ring": 1,
68
+ "value": ""
69
+ },
70
+ "source": {
71
+ "found": false,
72
+ "ring": 1,
73
+ "value": ""
74
+ }
75
+ },
76
+ {
77
+ "rust": {
78
+ "found": false,
79
+ "ring": 0,
80
+ "value": ""
81
+ },
82
+ "source": {
83
+ "found": false,
84
+ "ring": 0,
85
+ "value": ""
86
+ }
87
+ },
88
+ {
89
+ "rust": {
90
+ "found": false,
91
+ "ring": 1,
92
+ "value": ""
93
+ },
94
+ "source": {
95
+ "found": false,
96
+ "ring": 1,
97
+ "value": ""
98
+ }
99
+ },
100
+ {
101
+ "rust": {
102
+ "found": false,
103
+ "ring": 0,
104
+ "value": ""
105
+ },
106
+ "source": {
107
+ "found": false,
108
+ "ring": 0,
109
+ "value": ""
110
+ }
111
+ },
112
+ {
113
+ "rust": {
114
+ "found": false,
115
+ "ring": 1,
116
+ "value": ""
117
+ },
118
+ "source": {
119
+ "found": false,
120
+ "ring": 1,
121
+ "value": ""
122
+ }
123
+ },
124
+ {
125
+ "rust": {
126
+ "found": false,
127
+ "ring": 0,
128
+ "value": ""
129
+ },
130
+ "source": {
131
+ "found": false,
132
+ "ring": 0,
133
+ "value": ""
134
+ }
135
+ },
136
+ {
137
+ "rust": {
138
+ "found": false,
139
+ "ring": 1,
140
+ "value": ""
141
+ },
142
+ "source": {
143
+ "found": false,
144
+ "ring": 1,
145
+ "value": ""
146
+ }
147
+ },
148
+ {
149
+ "rust": {
150
+ "found": false,
151
+ "ring": 0,
152
+ "value": ""
153
+ },
154
+ "source": {
155
+ "found": false,
156
+ "ring": 0,
157
+ "value": ""
158
+ }
159
+ },
160
+ {
161
+ "rust": {
162
+ "found": false,
163
+ "ring": 1,
164
+ "value": ""
165
+ },
166
+ "source": {
167
+ "found": false,
168
+ "ring": 1,
169
+ "value": ""
170
+ }
171
+ },
172
+ {
173
+ "rust": {
174
+ "found": false,
175
+ "ring": 1,
176
+ "value": ""
177
+ },
178
+ "source": {
179
+ "found": false,
180
+ "ring": 1,
181
+ "value": ""
182
+ }
183
+ },
184
+ {
185
+ "rust": {
186
+ "found": false,
187
+ "ring": 0,
188
+ "value": ""
189
+ },
190
+ "source": {
191
+ "found": false,
192
+ "ring": 0,
193
+ "value": ""
194
+ }
195
+ },
196
+ {
197
+ "rust": {
198
+ "found": false,
199
+ "ring": 1,
200
+ "value": ""
201
+ },
202
+ "source": {
203
+ "found": false,
204
+ "ring": 1,
205
+ "value": ""
206
+ }
207
+ },
208
+ {
209
+ "rust": {
210
+ "found": false,
211
+ "ring": 0,
212
+ "value": ""
213
+ },
214
+ "source": {
215
+ "found": false,
216
+ "ring": 0,
217
+ "value": ""
218
+ }
219
+ },
220
+ {
221
+ "rust": {
222
+ "found": false,
223
+ "ring": 1,
224
+ "value": ""
225
+ },
226
+ "source": {
227
+ "found": false,
228
+ "ring": 1,
229
+ "value": ""
230
+ }
231
+ },
232
+ {
233
+ "rust": {
234
+ "found": false,
235
+ "ring": 0,
236
+ "value": ""
237
+ },
238
+ "source": {
239
+ "found": false,
240
+ "ring": 0,
241
+ "value": ""
242
+ }
243
+ },
244
+ {
245
+ "rust": {
246
+ "found": false,
247
+ "ring": 1,
248
+ "value": ""
249
+ },
250
+ "source": {
251
+ "found": false,
252
+ "ring": 1,
253
+ "value": ""
254
+ }
255
+ },
256
+ {
257
+ "rust": {
258
+ "found": false,
259
+ "ring": 0,
260
+ "value": ""
261
+ },
262
+ "source": {
263
+ "found": false,
264
+ "ring": 0,
265
+ "value": ""
266
+ }
267
+ },
268
+ {
269
+ "rust": {
270
+ "found": false,
271
+ "ring": 1,
272
+ "value": ""
273
+ },
274
+ "source": {
275
+ "found": false,
276
+ "ring": 1,
277
+ "value": ""
278
+ }
279
+ },
280
+ {
281
+ "rust": {
282
+ "found": false,
283
+ "ring": 0,
284
+ "value": ""
285
+ },
286
+ "source": {
287
+ "found": false,
288
+ "ring": 0,
289
+ "value": ""
290
+ }
291
+ },
292
+ {
293
+ "rust": {
294
+ "found": false,
295
+ "ring": 0,
296
+ "value": ""
297
+ },
298
+ "source": {
299
+ "found": false,
300
+ "ring": 0,
301
+ "value": ""
302
+ }
303
+ },
304
+ {
305
+ "rust": {
306
+ "found": false,
307
+ "ring": 1,
308
+ "value": ""
309
+ },
310
+ "source": {
311
+ "found": false,
312
+ "ring": 1,
313
+ "value": ""
314
+ }
315
+ },
316
+ {
317
+ "rust": {
318
+ "found": false,
319
+ "ring": 1,
320
+ "value": ""
321
+ },
322
+ "source": {
323
+ "found": false,
324
+ "ring": 1,
325
+ "value": ""
326
+ }
327
+ },
328
+ {
329
+ "rust": {
330
+ "found": false,
331
+ "ring": 0,
332
+ "value": ""
333
+ },
334
+ "source": {
335
+ "found": false,
336
+ "ring": 0,
337
+ "value": ""
338
+ }
339
+ },
340
+ {
341
+ "rust": {
342
+ "found": true,
343
+ "ring": 1,
344
+ "value": "616263"
345
+ },
346
+ "source": {
347
+ "found": true,
348
+ "ring": 1,
349
+ "value": "616263"
350
+ }
351
+ },
352
+ {
353
+ "rust": {
354
+ "found": true,
355
+ "ring": 0,
356
+ "value": "616263"
357
+ },
358
+ "source": {
359
+ "found": true,
360
+ "ring": 0,
361
+ "value": "616263"
362
+ }
363
+ },
364
+ {
365
+ "rust": {
366
+ "found": true,
367
+ "ring": 1,
368
+ "value": "616263"
369
+ },
370
+ "source": {
371
+ "found": true,
372
+ "ring": 1,
373
+ "value": "616263"
374
+ }
375
+ },
376
+ {
377
+ "rust": {
378
+ "found": true,
379
+ "ring": 0,
380
+ "value": "616263"
381
+ },
382
+ "source": {
383
+ "found": true,
384
+ "ring": 0,
385
+ "value": "616263"
386
+ }
387
+ },
388
+ {
389
+ "rust": {
390
+ "found": false,
391
+ "ring": 1,
392
+ "value": ""
393
+ },
394
+ "source": {
395
+ "found": false,
396
+ "ring": 1,
397
+ "value": ""
398
+ }
399
+ },
400
+ {
401
+ "rust": {
402
+ "found": false,
403
+ "ring": 0,
404
+ "value": ""
405
+ },
406
+ "source": {
407
+ "found": false,
408
+ "ring": 0,
409
+ "value": ""
410
+ }
411
+ },
412
+ {
413
+ "rust": {
414
+ "found": false,
415
+ "ring": 1,
416
+ "value": ""
417
+ },
418
+ "source": {
419
+ "found": false,
420
+ "ring": 1,
421
+ "value": ""
422
+ }
423
+ },
424
+ {
425
+ "rust": {
426
+ "found": false,
427
+ "ring": 0,
428
+ "value": ""
429
+ },
430
+ "source": {
431
+ "found": false,
432
+ "ring": 0,
433
+ "value": ""
434
+ }
435
+ },
436
+ {
437
+ "rust": {
438
+ "found": false,
439
+ "ring": 0,
440
+ "value": ""
441
+ },
442
+ "source": {
443
+ "found": false,
444
+ "ring": 0,
445
+ "value": ""
446
+ }
447
+ },
448
+ {
449
+ "rust": {
450
+ "found": false,
451
+ "ring": 1,
452
+ "value": ""
453
+ },
454
+ "source": {
455
+ "found": false,
456
+ "ring": 1,
457
+ "value": ""
458
+ }
459
+ },
460
+ {
461
+ "rust": {
462
+ "found": false,
463
+ "ring": 1,
464
+ "value": ""
465
+ },
466
+ "source": {
467
+ "found": false,
468
+ "ring": 1,
469
+ "value": ""
470
+ }
471
+ },
472
+ {
473
+ "rust": {
474
+ "found": false,
475
+ "ring": 0,
476
+ "value": ""
477
+ },
478
+ "source": {
479
+ "found": false,
480
+ "ring": 0,
481
+ "value": ""
482
+ }
483
+ },
484
+ {
485
+ "rust": {
486
+ "found": true,
487
+ "ring": 1,
488
+ "value": "6669727374"
489
+ },
490
+ "source": {
491
+ "found": true,
492
+ "ring": 1,
493
+ "value": "6669727374"
494
+ }
495
+ },
496
+ {
497
+ "rust": {
498
+ "found": true,
499
+ "ring": 0,
500
+ "value": "6669727374"
501
+ },
502
+ "source": {
503
+ "found": true,
504
+ "ring": 0,
505
+ "value": "6669727374"
506
+ }
507
+ },
508
+ {
509
+ "rust": {
510
+ "found": true,
511
+ "ring": 1,
512
+ "value": "6669727374"
513
+ },
514
+ "source": {
515
+ "found": true,
516
+ "ring": 1,
517
+ "value": "6669727374"
518
+ }
519
+ },
520
+ {
521
+ "rust": {
522
+ "found": true,
523
+ "ring": 0,
524
+ "value": "6669727374"
525
+ },
526
+ "source": {
527
+ "found": true,
528
+ "ring": 0,
529
+ "value": "6669727374"
530
+ }
531
+ },
532
+ {
533
+ "rust": {
534
+ "found": false,
535
+ "ring": 1,
536
+ "value": ""
537
+ },
538
+ "source": {
539
+ "found": false,
540
+ "ring": 1,
541
+ "value": ""
542
+ }
543
+ },
544
+ {
545
+ "rust": {
546
+ "found": false,
547
+ "ring": 0,
548
+ "value": ""
549
+ },
550
+ "source": {
551
+ "found": false,
552
+ "ring": 0,
553
+ "value": ""
554
+ }
555
+ },
556
+ {
557
+ "rust": {
558
+ "found": false,
559
+ "ring": 1,
560
+ "value": ""
561
+ },
562
+ "source": {
563
+ "found": false,
564
+ "ring": 1,
565
+ "value": ""
566
+ }
567
+ },
568
+ {
569
+ "rust": {
570
+ "found": false,
571
+ "ring": 0,
572
+ "value": ""
573
+ },
574
+ "source": {
575
+ "found": false,
576
+ "ring": 0,
577
+ "value": ""
578
+ }
579
+ },
580
+ {
581
+ "rust": {
582
+ "found": false,
583
+ "ring": 0,
584
+ "value": ""
585
+ },
586
+ "source": {
587
+ "found": false,
588
+ "ring": 0,
589
+ "value": ""
590
+ }
591
+ },
592
+ {
593
+ "rust": {
594
+ "found": false,
595
+ "ring": 1,
596
+ "value": ""
597
+ },
598
+ "source": {
599
+ "found": false,
600
+ "ring": 1,
601
+ "value": ""
602
+ }
603
+ },
604
+ {
605
+ "rust": {
606
+ "found": false,
607
+ "ring": 1,
608
+ "value": ""
609
+ },
610
+ "source": {
611
+ "found": false,
612
+ "ring": 1,
613
+ "value": ""
614
+ }
615
+ },
616
+ {
617
+ "rust": {
618
+ "found": false,
619
+ "ring": 0,
620
+ "value": ""
621
+ },
622
+ "source": {
623
+ "found": false,
624
+ "ring": 0,
625
+ "value": ""
626
+ }
627
+ },
628
+ {
629
+ "rust": {
630
+ "found": true,
631
+ "ring": 1,
632
+ "value": "414243"
633
+ },
634
+ "source": {
635
+ "found": true,
636
+ "ring": 1,
637
+ "value": "414243"
638
+ }
639
+ },
640
+ {
641
+ "rust": {
642
+ "found": true,
643
+ "ring": 0,
644
+ "value": "414243"
645
+ },
646
+ "source": {
647
+ "found": true,
648
+ "ring": 0,
649
+ "value": "414243"
650
+ }
651
+ },
652
+ {
653
+ "rust": {
654
+ "found": true,
655
+ "ring": 1,
656
+ "value": "414243"
657
+ },
658
+ "source": {
659
+ "found": true,
660
+ "ring": 1,
661
+ "value": "414243"
662
+ }
663
+ },
664
+ {
665
+ "rust": {
666
+ "found": true,
667
+ "ring": 0,
668
+ "value": "414243"
669
+ },
670
+ "source": {
671
+ "found": true,
672
+ "ring": 0,
673
+ "value": "414243"
674
+ }
675
+ },
676
+ {
677
+ "rust": {
678
+ "found": true,
679
+ "ring": 1,
680
+ "value": "31"
681
+ },
682
+ "source": {
683
+ "found": true,
684
+ "ring": 1,
685
+ "value": "31"
686
+ }
687
+ },
688
+ {
689
+ "rust": {
690
+ "found": true,
691
+ "ring": 0,
692
+ "value": "31"
693
+ },
694
+ "source": {
695
+ "found": true,
696
+ "ring": 0,
697
+ "value": "31"
698
+ }
699
+ },
700
+ {
701
+ "rust": {
702
+ "found": false,
703
+ "ring": 1,
704
+ "value": ""
705
+ },
706
+ "source": {
707
+ "found": false,
708
+ "ring": 1,
709
+ "value": ""
710
+ }
711
+ },
712
+ {
713
+ "rust": {
714
+ "found": false,
715
+ "ring": 0,
716
+ "value": ""
717
+ },
718
+ "source": {
719
+ "found": false,
720
+ "ring": 0,
721
+ "value": ""
722
+ }
723
+ },
724
+ {
725
+ "rust": {
726
+ "found": false,
727
+ "ring": 0,
728
+ "value": ""
729
+ },
730
+ "source": {
731
+ "found": false,
732
+ "ring": 0,
733
+ "value": ""
734
+ }
735
+ },
736
+ {
737
+ "rust": {
738
+ "found": false,
739
+ "ring": 1,
740
+ "value": ""
741
+ },
742
+ "source": {
743
+ "found": false,
744
+ "ring": 1,
745
+ "value": ""
746
+ }
747
+ },
748
+ {
749
+ "rust": {
750
+ "found": false,
751
+ "ring": 1,
752
+ "value": ""
753
+ },
754
+ "source": {
755
+ "found": false,
756
+ "ring": 1,
757
+ "value": ""
758
+ }
759
+ },
760
+ {
761
+ "rust": {
762
+ "found": false,
763
+ "ring": 0,
764
+ "value": ""
765
+ },
766
+ "source": {
767
+ "found": false,
768
+ "ring": 0,
769
+ "value": ""
770
+ }
771
+ },
772
+ {
773
+ "rust": {
774
+ "found": true,
775
+ "ring": 1,
776
+ "value": ""
777
+ },
778
+ "source": {
779
+ "found": true,
780
+ "ring": 1,
781
+ "value": ""
782
+ }
783
+ },
784
+ {
785
+ "rust": {
786
+ "found": true,
787
+ "ring": 0,
788
+ "value": ""
789
+ },
790
+ "source": {
791
+ "found": true,
792
+ "ring": 0,
793
+ "value": ""
794
+ }
795
+ },
796
+ {
797
+ "rust": {
798
+ "found": true,
799
+ "ring": 1,
800
+ "value": ""
801
+ },
802
+ "source": {
803
+ "found": true,
804
+ "ring": 1,
805
+ "value": ""
806
+ }
807
+ },
808
+ {
809
+ "rust": {
810
+ "found": true,
811
+ "ring": 0,
812
+ "value": ""
813
+ },
814
+ "source": {
815
+ "found": true,
816
+ "ring": 0,
817
+ "value": ""
818
+ }
819
+ },
820
+ {
821
+ "rust": {
822
+ "found": false,
823
+ "ring": 1,
824
+ "value": ""
825
+ },
826
+ "source": {
827
+ "found": false,
828
+ "ring": 1,
829
+ "value": ""
830
+ }
831
+ },
832
+ {
833
+ "rust": {
834
+ "found": false,
835
+ "ring": 0,
836
+ "value": ""
837
+ },
838
+ "source": {
839
+ "found": false,
840
+ "ring": 0,
841
+ "value": ""
842
+ }
843
+ },
844
+ {
845
+ "rust": {
846
+ "found": false,
847
+ "ring": 1,
848
+ "value": ""
849
+ },
850
+ "source": {
851
+ "found": false,
852
+ "ring": 1,
853
+ "value": ""
854
+ }
855
+ },
856
+ {
857
+ "rust": {
858
+ "found": false,
859
+ "ring": 0,
860
+ "value": ""
861
+ },
862
+ "source": {
863
+ "found": false,
864
+ "ring": 0,
865
+ "value": ""
866
+ }
867
+ },
868
+ {
869
+ "rust": {
870
+ "found": false,
871
+ "ring": 0,
872
+ "value": ""
873
+ },
874
+ "source": {
875
+ "found": false,
876
+ "ring": 0,
877
+ "value": ""
878
+ }
879
+ },
880
+ {
881
+ "rust": {
882
+ "found": false,
883
+ "ring": 1,
884
+ "value": ""
885
+ },
886
+ "source": {
887
+ "found": false,
888
+ "ring": 1,
889
+ "value": ""
890
+ }
891
+ },
892
+ {
893
+ "rust": {
894
+ "found": false,
895
+ "ring": 1,
896
+ "value": ""
897
+ },
898
+ "source": {
899
+ "found": false,
900
+ "ring": 1,
901
+ "value": ""
902
+ }
903
+ },
904
+ {
905
+ "rust": {
906
+ "found": false,
907
+ "ring": 0,
908
+ "value": ""
909
+ },
910
+ "source": {
911
+ "found": false,
912
+ "ring": 0,
913
+ "value": ""
914
+ }
915
+ },
916
+ {
917
+ "rust": {
918
+ "found": false,
919
+ "ring": 1,
920
+ "value": ""
921
+ },
922
+ "source": {
923
+ "found": false,
924
+ "ring": 1,
925
+ "value": ""
926
+ }
927
+ },
928
+ {
929
+ "rust": {
930
+ "found": false,
931
+ "ring": 0,
932
+ "value": ""
933
+ },
934
+ "source": {
935
+ "found": false,
936
+ "ring": 0,
937
+ "value": ""
938
+ }
939
+ },
940
+ {
941
+ "rust": {
942
+ "found": false,
943
+ "ring": 1,
944
+ "value": ""
945
+ },
946
+ "source": {
947
+ "found": false,
948
+ "ring": 1,
949
+ "value": ""
950
+ }
951
+ },
952
+ {
953
+ "rust": {
954
+ "found": false,
955
+ "ring": 0,
956
+ "value": ""
957
+ },
958
+ "source": {
959
+ "found": false,
960
+ "ring": 0,
961
+ "value": ""
962
+ }
963
+ },
964
+ {
965
+ "rust": {
966
+ "found": false,
967
+ "ring": 1,
968
+ "value": ""
969
+ },
970
+ "source": {
971
+ "found": false,
972
+ "ring": 1,
973
+ "value": ""
974
+ }
975
+ },
976
+ {
977
+ "rust": {
978
+ "found": false,
979
+ "ring": 0,
980
+ "value": ""
981
+ },
982
+ "source": {
983
+ "found": false,
984
+ "ring": 0,
985
+ "value": ""
986
+ }
987
+ },
988
+ {
989
+ "rust": {
990
+ "found": false,
991
+ "ring": 1,
992
+ "value": ""
993
+ },
994
+ "source": {
995
+ "found": false,
996
+ "ring": 1,
997
+ "value": ""
998
+ }
999
+ },
1000
+ {
1001
+ "rust": {
1002
+ "found": false,
1003
+ "ring": 0,
1004
+ "value": ""
1005
+ },
1006
+ "source": {
1007
+ "found": false,
1008
+ "ring": 0,
1009
+ "value": ""
1010
+ }
1011
+ },
1012
+ {
1013
+ "rust": {
1014
+ "found": false,
1015
+ "ring": 0,
1016
+ "value": ""
1017
+ },
1018
+ "source": {
1019
+ "found": false,
1020
+ "ring": 0,
1021
+ "value": ""
1022
+ }
1023
+ },
1024
+ {
1025
+ "rust": {
1026
+ "found": false,
1027
+ "ring": 1,
1028
+ "value": ""
1029
+ },
1030
+ "source": {
1031
+ "found": false,
1032
+ "ring": 1,
1033
+ "value": ""
1034
+ }
1035
+ },
1036
+ {
1037
+ "rust": {
1038
+ "found": false,
1039
+ "ring": 1,
1040
+ "value": ""
1041
+ },
1042
+ "source": {
1043
+ "found": false,
1044
+ "ring": 1,
1045
+ "value": ""
1046
+ }
1047
+ },
1048
+ {
1049
+ "rust": {
1050
+ "found": false,
1051
+ "ring": 0,
1052
+ "value": ""
1053
+ },
1054
+ "source": {
1055
+ "found": false,
1056
+ "ring": 0,
1057
+ "value": ""
1058
+ }
1059
+ },
1060
+ {
1061
+ "rust": {
1062
+ "found": true,
1063
+ "ring": 1,
1064
+ "value": "71"
1065
+ },
1066
+ "source": {
1067
+ "found": true,
1068
+ "ring": 1,
1069
+ "value": "71"
1070
+ }
1071
+ },
1072
+ {
1073
+ "rust": {
1074
+ "found": true,
1075
+ "ring": 0,
1076
+ "value": "71"
1077
+ },
1078
+ "source": {
1079
+ "found": true,
1080
+ "ring": 0,
1081
+ "value": "71"
1082
+ }
1083
+ },
1084
+ {
1085
+ "rust": {
1086
+ "found": true,
1087
+ "ring": 1,
1088
+ "value": "71"
1089
+ },
1090
+ "source": {
1091
+ "found": true,
1092
+ "ring": 1,
1093
+ "value": "71"
1094
+ }
1095
+ },
1096
+ {
1097
+ "rust": {
1098
+ "found": true,
1099
+ "ring": 0,
1100
+ "value": "71"
1101
+ },
1102
+ "source": {
1103
+ "found": true,
1104
+ "ring": 0,
1105
+ "value": "71"
1106
+ }
1107
+ },
1108
+ {
1109
+ "rust": {
1110
+ "found": false,
1111
+ "ring": 1,
1112
+ "value": ""
1113
+ },
1114
+ "source": {
1115
+ "found": false,
1116
+ "ring": 1,
1117
+ "value": ""
1118
+ }
1119
+ },
1120
+ {
1121
+ "rust": {
1122
+ "found": false,
1123
+ "ring": 0,
1124
+ "value": ""
1125
+ },
1126
+ "source": {
1127
+ "found": false,
1128
+ "ring": 0,
1129
+ "value": ""
1130
+ }
1131
+ },
1132
+ {
1133
+ "rust": {
1134
+ "found": false,
1135
+ "ring": 1,
1136
+ "value": ""
1137
+ },
1138
+ "source": {
1139
+ "found": false,
1140
+ "ring": 1,
1141
+ "value": ""
1142
+ }
1143
+ },
1144
+ {
1145
+ "rust": {
1146
+ "found": false,
1147
+ "ring": 0,
1148
+ "value": ""
1149
+ },
1150
+ "source": {
1151
+ "found": false,
1152
+ "ring": 0,
1153
+ "value": ""
1154
+ }
1155
+ }
1156
+ ],
1157
+ "source_report": "docs/research/qvm-info-lookup.json",
1158
+ "source_report_sha256": "58283587a81cce34bd55e83d050f5d7037bcc5dcd7bfbb9eab001c59c6c4e040"
1159
+ }
scripts/analyze_rust_info_lookup.py ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ import hashlib,json
3
+ from pathlib import Path
4
+ from rust_native_policy_support import binary,result,invoke
5
+ from analyze_qvm import write_json
6
+ def blob(s):return [0xffffffff] if s is None else [len(bytes.fromhex(s)),*bytes.fromhex(s)]
7
+ def encode(s):
8
+ a=s['input'];return [a['ring'],*blob(a['text']),*blob(a['key'])]
9
+ def project(s):return {k:s[k] for k in ['found','value','ring']}
10
+
11
+ def main():
12
+ b=binary();p=Path('docs/research/qvm-info-lookup.json');data=p.read_bytes();rows=[]
13
+ for s in json.loads(data)['probes']:rows.append({'source':project(s),'rust':result(b,'info',encode(s))})
14
+ write_json(Path('docs/research/rust-info-lookup.json'),{'source_report':str(p),'source_report_sha256':hashlib.sha256(data).hexdigest(),'probes':rows,'limits':'Rust matches96 original70503 key/value and selector cases, preserving first-match case folding, incomplete-pair rejection, empty values, embedded NUL and null early exits. Oversized logical inputs reject without changing the selector. Native userinfo retrieval, raw pointer aliases and fatal semantics remain open.'})
15
+ if __name__=='__main__':main()
scripts/test_rust_info_lookup.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-info-lookup.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-info-lookup.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
@@ -2712,3 +2712,16 @@ edge docs/research/qvm-info-lookup.json scripts/test_qvm_info_lookup.py
2712
  group qvm-info-lookup scripts/analyze_qvm_info_lookup.py
2713
  edge scripts/analyze_qvm_info_lookup.py scripts/analyze_qvm_resumer_audit.py
2714
  edge scripts/qvm_persistence_support.py scripts/analyze_qvm_resumer_audit.py
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2712
  group qvm-info-lookup scripts/analyze_qvm_info_lookup.py
2713
  edge scripts/analyze_qvm_info_lookup.py scripts/analyze_qvm_resumer_audit.py
2714
  edge scripts/qvm_persistence_support.py scripts/analyze_qvm_resumer_audit.py
2715
+ edge Cargo.toml scripts/analyze_rust_info_lookup.py
2716
+ edge Cargo.lock scripts/analyze_rust_info_lookup.py
2717
+ edge crates/urt-gameplay/Cargo.toml scripts/analyze_rust_info_lookup.py
2718
+ edge crates/urt-gameplay/src/lib.rs scripts/analyze_rust_info_lookup.py
2719
+ edge crates/urt-gameplay/src/native_policy.rs scripts/analyze_rust_info_lookup.py
2720
+ edge crates/urt-gameplay/src/bin/urt-native-policy.rs scripts/analyze_rust_info_lookup.py
2721
+ edge docs/research/qvm-info-lookup.json scripts/analyze_rust_info_lookup.py
2722
+ group rust-info-lookup scripts/analyze_rust_health_impulse.py
2723
+ group gameplay scripts/analyze_rust_info_lookup.py
2724
+ report scripts/analyze_rust_info_lookup.py docs/research/rust-info-lookup.json
2725
+ edge docs/research/rust-info-lookup.json scripts/test_rust_info_lookup.py
2726
+ group rust-info-lookup scripts/analyze_rust_info_lookup.py
2727
+ edge scripts/analyze_rust_info_lookup.py scripts/analyze_qvm_resumer_audit.py