cultnet-rs: kind-array refusal no longer quotes the value; README says delete carries ids

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Meta Vens 2026-10-16 05:55:05 +02:00
commit 0daa2f1017
3 changed files with 24 additions and 3 deletions

View file

@ -11,8 +11,9 @@ The contract is intentionally boring:
- `gamecult.networking.v0` maps the legacy C# union shape explicitly.
- schema discovery uses explicit catalog request/response messages; no inbound
auto-detect sludge.
- put/delete/snapshot travel only as raw messages that carry the canonical
MessagePack payload bytes; the receiver decodes them through registered types.
- put and snapshot travel only as raw messages that carry the canonical
MessagePack payload bytes; the receiver decodes them through registered
types. Delete carries ids.
- hello messages advertise `supportedMutationContracts`, so callers discover
which document types are read-only, which accept typed intents, which
authority owns the mutation, and which receipt documents prove the outcome.

View file

@ -1658,7 +1658,7 @@ fn require_legacy_optional_schema_kind_array(
"wire_message" => Ok(CultNetSchemaKind::WireMessage),
"document_payload" => Ok(CultNetSchemaKind::DocumentPayload),
"shared_contract" => Ok(CultNetSchemaKind::SharedContract),
_ => Err(anyhow!("{field_name} has unsupported schema kind {value}")),
_ => Err(anyhow!("{field_name} has an unsupported schema kind")),
})
.collect::<Result<Vec<_>>>()
.map(Some)

View file

@ -675,6 +675,26 @@ fn a_networking_schema_descriptor_with_a_repeated_key_is_refused_and_a_bad_kind_
assert!(text.contains("Kind") && !text.contains("CANARY"), "{text}");
}
#[test]
fn a_networking_catalog_request_with_a_bad_kind_element_is_refused_without_quoting_it() {
let union = rmpv::Value::Array(vec![
7.into(),
rmpv::Value::Array(vec![
"m".into(),
false.into(),
rmpv::Value::Nil,
rmpv::Value::Array(vec!["CANARY-s2x".into()]),
]),
]);
let bytes = rmp_serde::to_vec(&union).unwrap();
let text = on_stack(BIG, move || {
decode_cultnet_message_from_slice(&bytes, CultNetWireContract::GameCultNetworkingV0)
.map_err(|error| format!("{error:#}"))
})
.unwrap_err();
assert!(text.contains("Kinds") && !text.contains("CANARY"), "{text}");
}
#[test]
fn a_schema_version_that_is_not_shaped_like_a_schema_name_is_described_by_length() {
let long = format!("cultnet.{}.v0", "a".repeat(100));