This is an automated email from the ASF dual-hosted git repository.
zyxxoo pushed a commit to branch refactor/rust-rewrite-design
in repository https://gitbox.apache.org/repos/asf/hugegraph.git
The following commit(s) were added to refs/heads/refactor/rust-rewrite-design
by this push:
new c8c54f917 test(poc): add independent partition invariant oracle
c8c54f917 is described below
commit c8c54f91721fbdb651200a35b961bc2d0de6652b
Author: vaughn <[email protected]>
AuthorDate: Thu Sep 10 01:58:35 2026 +0800
test(poc): add independent partition invariant oracle
---
docs/rust-rewrite-partition-pilot.md | 4 ++++
tools/rust-partition-poc/Cargo.lock | 7 +++++++
tools/rust-partition-poc/Cargo.toml | 7 +++++++
tools/rust-partition-poc/README.md | 5 +++++
tools/rust-partition-poc/src/lib.rs | 35 ++++++++++++++++++++++++++++++++
tools/rust-partition-poc/src/lib_test.rs | 0
tools/rust-partition-poc/src/main.rs | 6 ++++++
7 files changed, 64 insertions(+)
diff --git a/docs/rust-rewrite-partition-pilot.md
b/docs/rust-rewrite-partition-pilot.md
index a20c668fc..9703dea03 100644
--- a/docs/rust-rewrite-partition-pilot.md
+++ b/docs/rust-rewrite-partition-pilot.md
@@ -45,3 +45,7 @@
- 产出包含输入、seed、配置、日志、差异和结论的报告。
试点通过后,复制模板到 Store Snapshot、事务和 Raft 成员变更;试点未通过时,暂停生产路径迁移。
+
+## 6. POC execution evidence (2026-09-10)
+
+A standalone invariant oracle was implemented at `tools/rust-partition-poc`.
It has no dependency on Java output or production PD code. Running `cargo test
--manifest-path tools/rust-partition-poc/Cargo.toml` produced **6 passed, 0
failed**. The suite detects dropped ranges, overlaps, version regression, stale
heartbeats, and verifies heartbeat idempotence. This is a model-level POC only;
cache invalidation, crash replay, restart recovery, Java differential replay,
and two-person review [...]
diff --git a/tools/rust-partition-poc/Cargo.lock
b/tools/rust-partition-poc/Cargo.lock
new file mode 100644
index 000000000..defe85931
--- /dev/null
+++ b/tools/rust-partition-poc/Cargo.lock
@@ -0,0 +1,7 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 4
+
+[[package]]
+name = "hugegraph-partition-poc"
+version = "0.1.0"
diff --git a/tools/rust-partition-poc/Cargo.toml
b/tools/rust-partition-poc/Cargo.toml
new file mode 100644
index 000000000..d2d4a79c9
--- /dev/null
+++ b/tools/rust-partition-poc/Cargo.toml
@@ -0,0 +1,7 @@
+[package]
+name = "hugegraph-partition-poc"
+version = "0.1.0"
+edition = "2021"
+
+[profile.release]
+ debug = true
diff --git a/tools/rust-partition-poc/README.md
b/tools/rust-partition-poc/README.md
new file mode 100644
index 000000000..ae94bf972
--- /dev/null
+++ b/tools/rust-partition-poc/README.md
@@ -0,0 +1,5 @@
+# Partition contract POC
+
+This standalone model is an independent invariant oracle, deliberately
separate from Java and any future Rust production implementation. `cargo test
--manifest-path tools/rust-partition-poc/Cargo.toml` runs six deterministic
checks: baseline validity, dropped range, overlap, version regression, stale
heartbeat, and idempotent heartbeat.
+
+The negative tests mutate the model input and must fail validation; they are
evidence that the oracle detects the first three required defect classes. Cache
loss, crash replay, and restart recovery remain integration tests against PD
and are still NO-GO until executed with logs and fixed seeds.
diff --git a/tools/rust-partition-poc/src/lib.rs
b/tools/rust-partition-poc/src/lib.rs
new file mode 100644
index 000000000..0fac1e6ba
--- /dev/null
+++ b/tools/rust-partition-poc/src/lib.rs
@@ -0,0 +1,35 @@
+#[derive(Clone, Debug, PartialEq, Eq)]
+pub struct Partition { pub start: u64, pub end: u64, pub version: u64 }
+
+pub fn validate(parts: &[Partition], max: u64) -> Result<(), &'static str> {
+ if parts.is_empty() || parts[0].start != 0 { return Err("gap-at-start"); }
+ for (i, p) in parts.iter().enumerate() {
+ if p.start >= p.end || p.end > max { return Err("invalid-range"); }
+ if i > 0 {
+ let prev = &parts[i - 1];
+ if prev.end != p.start { return Err("gap-or-overlap"); }
+ if p.version < prev.version { return Err("version-regression"); }
+ }
+ }
+ if parts.last().unwrap().end != max { return Err("gap-at-end"); }
+ Ok(())
+}
+
+pub fn apply_heartbeat(current: &mut Partition, incoming: Partition) ->
Result<(), &'static str> {
+ if incoming.start != current.start || incoming.end != current.end { return
Err("range-mismatch"); }
+ if incoming.version < current.version { return Err("stale-heartbeat"); }
+ *current = incoming;
+ Ok(())
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ fn base() -> Vec<Partition> { vec![Partition{start:0,end:10,version:1},
Partition{start:10,end:20,version:1}] }
+ #[test] fn baseline_is_valid() { assert!(validate(&base(), 20).is_ok()); }
+ #[test] fn catches_dropped_right_partition() { let mut x=base(); x.pop();
assert!(validate(&x,20).is_err()); }
+ #[test] fn catches_overlap() { let mut x=base(); x[1].start=9;
assert_eq!(validate(&x,20),Err("gap-or-overlap")); }
+ #[test] fn catches_version_regression() { let mut x=base();
x[1].version=0; assert_eq!(validate(&x,20),Err("version-regression")); }
+ #[test] fn rejects_stale_heartbeat() { let mut
c=Partition{start:0,end:10,version:2}; assert_eq!(apply_heartbeat(&mut
c,Partition{start:0,end:10,version:1}),Err("stale-heartbeat")); }
+ #[test] fn heartbeat_is_idempotent() { let mut
c=Partition{start:0,end:10,version:1}; let n=c.clone(); apply_heartbeat(&mut
c,n.clone()).unwrap(); apply_heartbeat(&mut c,n).unwrap();
assert_eq!(c.version,1); }
+}
diff --git a/tools/rust-partition-poc/src/lib_test.rs
b/tools/rust-partition-poc/src/lib_test.rs
new file mode 100644
index 000000000..e69de29bb
diff --git a/tools/rust-partition-poc/src/main.rs
b/tools/rust-partition-poc/src/main.rs
new file mode 100644
index 000000000..79161776f
--- /dev/null
+++ b/tools/rust-partition-poc/src/main.rs
@@ -0,0 +1,6 @@
+use hugegraph_partition_poc::{validate, Partition};
+fn main() {
+ let baseline = vec![Partition{start:0,end:10,version:1},
Partition{start:10,end:20,version:1}];
+ validate(&baseline, 20).expect("baseline oracle");
+ println!("PASS partition invariant oracle: {:?}", baseline);
+}