nmarshall commited on
Commit
20d7c36
·
1 Parent(s): 8d0c296

gameplay: port post-map client callbacks

Browse files
crates/urt-gameplay/src/bin/urt-native-policy.rs CHANGED
@@ -70,6 +70,35 @@ fn run() -> Result<String, String> {
70
  nested(&end)
71
  ))
72
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  _ => Err("unknown command".into()),
74
  }
75
  }
 
70
  nested(&end)
71
  ))
72
  }
73
+ "post" => {
74
+ if w.len() != 66 {
75
+ return Err("invalid post input".into());
76
+ }
77
+ let mut c = w[2..].iter().map(|v| *v as i32).collect::<Vec<_>>();
78
+ let mut calls = vec![];
79
+ post_map_clients(&mut c, w[0] as i32, |kind, j, c| {
80
+ let t = if kind == PostMapChild::First {
81
+ 246746
82
+ } else {
83
+ 246963
84
+ };
85
+ calls.push(vec![t, j as u32, c[j] as u32]);
86
+ if kind == PostMapChild::First {
87
+ if w[1] == 1 {
88
+ c[j] = 0
89
+ }
90
+ if w[1] == 2 && j + 1 < c.len() {
91
+ c[j + 1] = 2
92
+ }
93
+ }
94
+ })
95
+ .map_err(|e| format!("{e:?}"))?;
96
+ Ok(format!(
97
+ "{{\"calls\":{},\"after\":{}}}",
98
+ nested(&calls),
99
+ list(&c.iter().map(|v| *v as u32).collect::<Vec<_>>())
100
+ ))
101
+ }
102
  _ => Err("unknown command".into()),
103
  }
104
  }
crates/urt-gameplay/src/native_policy.rs CHANGED
@@ -138,3 +138,71 @@ mod breed_tests {
138
  assert_eq!(b, before);
139
  }
140
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
138
  assert_eq!(b, before);
139
  }
140
  }
141
+
142
+ #[derive(Clone, Copy, Debug, PartialEq, Eq)]
143
+ pub enum PostMapChild {
144
+ First,
145
+ Second,
146
+ }
147
+ /// Check connection at iteration entry; callbacks may change this or later slots.
148
+ /// Count/base pointer are held stable in this typed subset.
149
+ pub fn post_map_clients<F>(clients: &mut [i32], count: i32, mut callback: F) -> Result<(), Error>
150
+ where
151
+ F: FnMut(PostMapChild, usize, &mut [i32]),
152
+ {
153
+ let count = count.max(0) as usize;
154
+ if clients.len() > 64 || count > clients.len() {
155
+ return Err(Error::InvalidCount);
156
+ }
157
+ for j in 0..count {
158
+ if clients[j] == 2 {
159
+ callback(PostMapChild::First, j, clients);
160
+ callback(PostMapChild::Second, j, clients);
161
+ }
162
+ }
163
+ Ok(())
164
+ }
165
+ #[cfg(test)]
166
+ mod post_tests {
167
+ use super::*;
168
+ #[test]
169
+ fn second_call_survives_disconnect_and_later_activation() {
170
+ let mut c = [2, 0];
171
+ let mut calls = vec![];
172
+ post_map_clients(&mut c, 2, |kind, j, c| {
173
+ calls.push((kind, j, c[j]));
174
+ if kind == PostMapChild::First {
175
+ c[j] = 0;
176
+ if j == 0 {
177
+ c[1] = 2
178
+ }
179
+ }
180
+ })
181
+ .unwrap();
182
+ assert_eq!(
183
+ calls,
184
+ [
185
+ (PostMapChild::First, 0, 2),
186
+ (PostMapChild::Second, 0, 0),
187
+ (PostMapChild::First, 1, 2),
188
+ (PostMapChild::Second, 1, 0)
189
+ ]
190
+ );
191
+ }
192
+ #[test]
193
+ fn invalid_count_never_calls() {
194
+ let mut c = [2];
195
+ let mut called = false;
196
+ assert_eq!(
197
+ post_map_clients(&mut c, 2, |_, _, _| called = true),
198
+ Err(Error::InvalidCount)
199
+ );
200
+ assert!(!called);
201
+ assert_eq!(c, [2]);
202
+ assert_eq!(
203
+ post_map_clients(&mut c, -1, |_, _, _| called = true),
204
+ Ok(())
205
+ );
206
+ assert!(!called);
207
+ }
208
+ }
docs/FINDINGS.md CHANGED
@@ -1634,3 +1634,6 @@ RE-813–822 replaces the scoreboard decimal assumption with actual37914 executi
1634
 
1635
 
1636
  **RE-878:** 72 actual249007 cases recover signed live client-count iteration and connected-state2 gating. Each accepted client calls246746 then246963 unconditionally; a supplied first-child disconnect does not suppress its second child, and activation of a later slot affects subsequent dispatch. This uses level count34992524, not max-clients cvar34089604. Child bodies, native effects and callback changes to count/base pointer remain open. [Evidence](research/QVM_POST_MAP_CLIENTS.md).
 
 
 
 
1634
 
1635
 
1636
  **RE-878:** 72 actual249007 cases recover signed live client-count iteration and connected-state2 gating. Each accepted client calls246746 then246963 unconditionally; a supplied first-child disconnect does not suppress its second child, and activation of a later slot affects subsequent dispatch. This uses level count34992524, not max-clients cvar34089604. Child bodies, native effects and callback changes to count/base pointer remain open. [Evidence](research/QVM_POST_MAP_CLIENTS.md).
1637
+
1638
+
1639
+ **RE-879:** Rust matches all72 original249007 schedules and state snapshots, including disconnect-before-second-child and activation-before-later-scan cases. The bounded API accepts typed callbacks and validates the count before invoking them. Count/base remain stable; actual246746/246963 child bodies and engine integration remain open. [Evidence](research/RUST_POST_MAP_CLIENTS.md).
docs/PROVISIONAL_TODO.md CHANGED
@@ -1662,3 +1662,6 @@ RE-877: Rust matches all64 actual121987 fitness/selection/interbreed/mutation/re
1662
 
1663
 
1664
  RE-878: 72 actual249007 cases recover signed live client-count iteration and connected-state2 gating. Each accepted client calls246746 then246963 unconditionally; a supplied first-child disconnect does not suppress its second child, and activation of a later slot affects subsequent dispatch. This uses level count34992524, not max-clients cvar34089604. Child bodies, native effects and callback changes to count/base pointer remain open. Full runtime completion remains open. [Evidence](research/QVM_POST_MAP_CLIENTS.md).
 
 
 
 
1662
 
1663
 
1664
  RE-878: 72 actual249007 cases recover signed live client-count iteration and connected-state2 gating. Each accepted client calls246746 then246963 unconditionally; a supplied first-child disconnect does not suppress its second child, and activation of a later slot affects subsequent dispatch. This uses level count34992524, not max-clients cvar34089604. Child bodies, native effects and callback changes to count/base pointer remain open. Full runtime completion remains open. [Evidence](research/QVM_POST_MAP_CLIENTS.md).
1665
+
1666
+
1667
+ RE-879: Rust matches all72 original249007 schedules and state snapshots, including disconnect-before-second-child and activation-before-later-scan cases. The bounded API accepts typed callbacks and validates the count before invoking them. Count/base remain stable; actual246746/246963 child bodies and engine integration remain open. Full runtime completion remains open. [Evidence](research/RUST_POST_MAP_CLIENTS.md).
docs/RESEARCH_LEDGER.md CHANGED
@@ -2095,3 +2095,8 @@ Rust matches all64 actual121987 fitness/selection/interbreed/mutation/reset tran
2095
  ## 2026-10-28 — RE-878 Original post-map connected-client callbacks
2096
 
2097
  72 actual249007 cases recover signed live client-count iteration and connected-state2 gating. Each accepted client calls246746 then246963 unconditionally; a supplied first-child disconnect does not suppress its second child, and activation of a later slot affects subsequent dispatch. This uses level count34992524, not max-clients cvar34089604. Child bodies, native effects and callback changes to count/base pointer remain open. Focused `cargo xtask test-group qvm-post-map-clients` 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.
 
 
 
 
 
 
2095
  ## 2026-10-28 — RE-878 Original post-map connected-client callbacks
2096
 
2097
  72 actual249007 cases recover signed live client-count iteration and connected-state2 gating. Each accepted client calls246746 then246963 unconditionally; a supplied first-child disconnect does not suppress its second child, and activation of a later slot affects subsequent dispatch. This uses level count34992524, not max-clients cvar34089604. Child bodies, native effects and callback changes to count/base pointer remain open. Focused `cargo xtask test-group qvm-post-map-clients` 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.
2098
+
2099
+
2100
+ ## 2026-10-28 — RE-879 Rust post-map callback scheduling
2101
+
2102
+ Rust matches all72 original249007 schedules and state snapshots, including disconnect-before-second-child and activation-before-later-scan cases. The bounded API accepts typed callbacks and validates the count before invoking them. Count/base remain stable; actual246746/246963 child bodies and engine integration remain open. Focused `cargo xtask test-group rust-post-map-clients` 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
@@ -1699,3 +1699,6 @@ Purpose: turn the supplied installation into an evidence-backed specification of
1699
 
1700
 
1701
  - [x] RE-878 Original post-map connected-client callbacks ([evidence](research/QVM_POST_MAP_CLIENTS.md)).
 
 
 
 
1699
 
1700
 
1701
  - [x] RE-878 Original post-map connected-client callbacks ([evidence](research/QVM_POST_MAP_CLIENTS.md)).
1702
+
1703
+
1704
+ - [x] RE-879 Rust post-map callback scheduling ([evidence](research/RUST_POST_MAP_CLIENTS.md)).
docs/research/README.md CHANGED
@@ -1234,3 +1234,6 @@ The extension collector adds five focused tests for native tail calls, command-r
1234
 
1235
 
1236
  [RE-878: Original post-map connected-client callbacks](QVM_POST_MAP_CLIENTS.md).
 
 
 
 
1234
 
1235
 
1236
  [RE-878: Original post-map connected-client callbacks](QVM_POST_MAP_CLIENTS.md).
1237
+
1238
+
1239
+ [RE-879: Rust post-map callback scheduling](RUST_POST_MAP_CLIENTS.md).
docs/research/RUST_POST_MAP_CLIENTS.md ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ # Rust post-map callback scheduling
2
+
3
+ RE-879. Reproduce with `python3 scripts/analyze_rust_post_map_clients.py`; focused validation: `cargo xtask test-group rust-post-map-clients`. [Machine report](rust-post-map-clients.json).
4
+
5
+ Rust matches all72 original249007 schedules and state snapshots, including disconnect-before-second-child and activation-before-later-scan cases. The bounded API accepts typed callbacks and validates the count before invoking them. Count/base remain stable; actual246746/246963 child bodies and engine integration 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": 133,
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": 135,
2989
  "source_report": "docs/research/qvm-health-impulse.json",
2990
  "source_report_sha256": "625fd8064004ea6dbdf398d51d0af844d9c635ff04c0a0790886dddb6ab81e71"
2991
  }
docs/research/rust-post-map-clients.json ADDED
The diff for this file is too large to render. See raw diff
 
scripts/analyze_rust_post_map_clients.py ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 encode(s):
7
+ a=s['input'];return [a['count'],a['mutation'],*a['records']]
8
+ def project(s):return {k:s[k] for k in ['calls','after']}
9
+
10
+ def main():
11
+ b=binary();p=Path('docs/research/qvm-post-map-clients.json');data=p.read_bytes();rows=[]
12
+ for s in json.loads(data)['probes']:rows.append({'source':project(s),'rust':result(b,'post',encode(s))})
13
+ write_json(Path('docs/research/rust-post-map-clients.json'),{'source_report':str(p),'source_report_sha256':hashlib.sha256(data).hexdigest(),'probes':rows,'limits':'Rust matches all72 original249007 schedules and state snapshots, including disconnect-before-second-child and activation-before-later-scan cases. The bounded API accepts typed callbacks and validates the count before invoking them. Count/base remain stable; actual246746/246963 child bodies and engine integration remain open.'})
14
+ if __name__=='__main__':main()
scripts/test_rust_post_map_clients.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-post-map-clients.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-post-map-clients.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
@@ -2556,3 +2556,16 @@ report scripts/analyze_qvm_post_map_clients.py docs/research/qvm-post-map-client
2556
  edge docs/research/qvm-post-map-clients.json scripts/test_qvm_post_map_clients.py
2557
  group qvm-post-map-clients scripts/analyze_qvm_post_map_clients.py
2558
  edge scripts/analyze_qvm_post_map_clients.py scripts/analyze_qvm_resumer_audit.py
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2556
  edge docs/research/qvm-post-map-clients.json scripts/test_qvm_post_map_clients.py
2557
  group qvm-post-map-clients scripts/analyze_qvm_post_map_clients.py
2558
  edge scripts/analyze_qvm_post_map_clients.py scripts/analyze_qvm_resumer_audit.py
2559
+ edge Cargo.toml scripts/analyze_rust_post_map_clients.py
2560
+ edge Cargo.lock scripts/analyze_rust_post_map_clients.py
2561
+ edge crates/urt-gameplay/Cargo.toml scripts/analyze_rust_post_map_clients.py
2562
+ edge crates/urt-gameplay/src/lib.rs scripts/analyze_rust_post_map_clients.py
2563
+ edge crates/urt-gameplay/src/native_policy.rs scripts/analyze_rust_post_map_clients.py
2564
+ edge crates/urt-gameplay/src/bin/urt-native-policy.rs scripts/analyze_rust_post_map_clients.py
2565
+ edge docs/research/qvm-post-map-clients.json scripts/analyze_rust_post_map_clients.py
2566
+ group rust-post-map-clients scripts/analyze_rust_health_impulse.py
2567
+ group gameplay scripts/analyze_rust_post_map_clients.py
2568
+ report scripts/analyze_rust_post_map_clients.py docs/research/rust-post-map-clients.json
2569
+ edge docs/research/rust-post-map-clients.json scripts/test_rust_post_map_clients.py
2570
+ group rust-post-map-clients scripts/analyze_rust_post_map_clients.py
2571
+ edge scripts/analyze_rust_post_map_clients.py scripts/analyze_qvm_resumer_audit.py