CultLib/packages/cultnet-rs/examples/runtime_presence_vector.rs
Meta Vens d1a9edad3a Port gamecult.runtime_presence_health.v2 to cultnet-ts
The dual-proved runtime presence contract existed only in cultnet-rs, so no
TypeScript service could make a statement Odin admits as presence. Odin files
anything else away as an ordinary document and never produces a topology
correlation for it, which is why Heimdall could warm forever without being
promoted.

The port is what it should be: the same fields at the same key slots. The Rust
derive serialises a positional tuple indexed by those slots, so the TypeScript
side names the slots and fills the same 24. Both proofs cover one payload --
the complete record with both signature fields empty -- and the two signing
messages use the domain separation their respective identities already define.

Conformance is against vectors emitted by cultnet-rs, not a fixture written
for both sides at once, which would agree with itself and prove nothing:
`cargo run --example runtime_presence_vector -p cultnet-rs` regenerates them.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-07 21:42:54 +02:00

67 lines
2.9 KiB
Rust

//! Emit canonical bytes for one fixed runtime-presence record.
//!
//! This is the reference the TypeScript fork is tested against. The two forks
//! agree only if `gamecult.runtime_presence_health.v2` means the same bytes in
//! both, and the only way to know that is to have one produce the vector and
//! the other reproduce it. A fixture written by hand for both sides would agree
//! with itself and prove nothing.
use cultnet_rs::{GameCultRuntimeCapability, GameCultRuntimePresenceHealthRecord};
fn main() -> anyhow::Result<()> {
let record = GameCultRuntimePresenceHealthRecord {
schema_version: "gamecult.runtime_presence_health.v2".into(),
target: "heimdall".into(),
expected_projection_sha256: format!("sha256-{}", "a".repeat(64)),
plan_id: format!("sha256-{}", "b".repeat(64)),
incarnation_id: "service-incarnation-1".into(),
sealed_release_id: format!("sha256-{}", "c".repeat(64)),
activation_witness_sha256: format!("sha256-{}", "d".repeat(64)),
state_schema_generation: Some("v1".into()),
state_contract_sha256: Some(format!("sha256-{}", "e".repeat(64))),
runtime_id: "heimdall-yggdrasil".into(),
runtime_instance_id: format!("sha256-{}", "f".repeat(64)),
bound_endpoint: Some("http://127.0.0.1:14101".into()),
capabilities: vec![
GameCultRuntimeCapability {
capability: "heimdall.access".into(),
schema: "heimdall.access.v1".into(),
compatibility: "v1".into(),
capacity: 2,
},
GameCultRuntimeCapability {
capability: "zeta.runtime".into(),
schema: "zeta.runtime.v1".into(),
compatibility: "v1".into(),
capacity: 1,
},
],
health_contract: "heimdall.cultnet-rudp-provider-health".into(),
state: "warming".into(),
detail: "Heimdall candidate warming".into(),
write_lease_sha256: None,
signer_identity_id: "1".repeat(64),
publisher_sequence: 7,
observed_at_unix_millis: 1_757_000_000_000,
signature_algorithm: "ed25519".into(),
signature: Vec::new(),
activation_signer_identity_id: "2".repeat(64),
activation_signature: Vec::new(),
};
// The proof payload: both signature fields empty. This is what both keys
// sign, so it is the vector that matters most.
let proof = record.canonical_proof_payload()?;
println!("proof {}", hex(&proof));
// And the complete record, with both proofs filled, to pin the signed shape.
let mut signed = record;
signed.signature = vec![0x11; 64];
signed.activation_signature = vec![0x22; 64];
println!("signed {}", hex(&rmp_serde::to_vec(&signed)?));
Ok(())
}
fn hex(bytes: &[u8]) -> String {
bytes.iter().map(|byte| format!("{byte:02x}")).collect()
}