heimdall-consent: pin the one version rule in the golden vectors (4294967295 ok; 4294967296 and 01 refused)
Some checks failed
CultMesh QUIC native / Build win32-x64 (pull_request) Has been skipped
CultMesh QUIC native / Build linux-x64 (pull_request) Has been skipped
CultMesh QUIC native / Release native binaries (pull_request) Has been skipped
CultMesh portability and performance / ubuntu-latest one-command multiplayer onboarding (pull_request) Has been cancelled
CultMesh portability and performance / windows-latest one-command multiplayer onboarding (pull_request) Has been cancelled
CultMesh portability and performance / ubuntu-latest reactive semantics and leases (pull_request) Has been cancelled
CultMesh portability and performance / windows-latest reactive semantics and leases (pull_request) Has been cancelled
CultNet cross-runtime interop / C# / TypeScript / Rust / Python / Kotlin (pull_request) Has been cancelled
CultMesh QUIC native / Verify committed binaries match SHA256SUMS (pull_request) Has been cancelled
Some checks failed
CultMesh QUIC native / Build win32-x64 (pull_request) Has been skipped
CultMesh QUIC native / Build linux-x64 (pull_request) Has been skipped
CultMesh QUIC native / Release native binaries (pull_request) Has been skipped
CultMesh portability and performance / ubuntu-latest one-command multiplayer onboarding (pull_request) Has been cancelled
CultMesh portability and performance / windows-latest one-command multiplayer onboarding (pull_request) Has been cancelled
CultMesh portability and performance / ubuntu-latest reactive semantics and leases (pull_request) Has been cancelled
CultMesh portability and performance / windows-latest reactive semantics and leases (pull_request) Has been cancelled
CultNet cross-runtime interop / C# / TypeScript / Rust / Python / Kotlin (pull_request) Has been cancelled
CultMesh QUIC native / Verify committed binaries match SHA256SUMS (pull_request) Has been cancelled
Case one-version-rule runs version_ok/version_refused for notice_version, the sample id @N and terms_version; the Rust vector test handles both ops. README cites Heimdall PR #6 d6a8d42 for the rule. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
af0b1b6817
commit
420eb9e840
3 changed files with 35 additions and 2 deletions
|
|
@ -14,7 +14,7 @@ Entry points: `src/lib.rs`; golden vectors `tests/vectors/consent_golden.csv`, r
|
|||
| Ruling | Doc | Crate |
|
||||
|---|---|---|
|
||||
| Timestamps are Unix ms UTC, signed 64-bit | L98-99; `received_at` is collector-assigned, L75 | `i64` on `accepted_at`, `received_at`, `terms_accepted_at` |
|
||||
| Ids are non-empty opaque strings, `event_id` verbatim; every version field (`notice_version`, the `@N` of a sample id, `terms_version`) is a positive integer, no leading zeros, no sign, at most 4294967295 (Heimdall ruling 2026-11-07, one rule) | L100-103 | `check_version` is the single rule; `check_sample_id` and `MemberTerms::validate` call it; `notice_version: u32` with `validate()` refusing 0; golden vector `newcomer` carries `terms_version` 4294967295 |
|
||||
| Ids are non-empty opaque strings, `event_id` verbatim; every version field (`notice_version`, the `@N` of a sample id, `terms_version`) is a positive integer, no leading zeros, no sign, at most 4294967295 (Heimdall ruling 2026-11-07, one rule; doc line "Version rule" under Representation, Heimdall PR #6 commit d6a8d42) | L100-103 | `check_version` is the single rule; `check_sample_id` and `MemberTerms::validate` call it; `notice_version: u32` with `validate()` refusing 0; golden vector `newcomer` carries `terms_version` 4294967295, and case `one-version-rule` pins 4294967295 accepted, 4294967296 and `01` refused for `notice_version`, the sample id `@N` and `terms_version` |
|
||||
| Key parts joined with U+001F; empty part or part containing it refused | L104-105 | `key()` |
|
||||
| Tombstone is the exited `Answer` with `text_hash` (32 bytes); HMAC-SHA-256 keyed by a per-member salt held by the member-side service; the collector cannot compute it | L74, L132-152, L186-193 | `Answer.text_hash`; `redacted([u8; 32])` takes the service's output and refuses an answer with no `text` (L148-149); `validate()` requires 32 bytes and `exited` |
|
||||
| A reply with no established notice version or scope is stored with both absent, writes no acceptance, is excluded from every use | L87-94 | `notice_version`/`scope` optional and absent together (`validate()`); vector case `no-scope` |
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ fn golden_vectors() {
|
|||
_ => cases.push((f[0], vec![f])),
|
||||
}
|
||||
}
|
||||
assert_eq!(cases.len(), 9, "fixture shrank");
|
||||
assert_eq!(cases.len(), 10, "fixture shrank");
|
||||
for (name, rows) in cases {
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
let mut cache = new_cache(&dir);
|
||||
|
|
@ -185,6 +185,29 @@ fn golden_vectors() {
|
|||
assert_eq!((a.notice_version, Some(a.scope), a.accepted_at), (nv.unwrap(), scope(sc), ts), "{ctx}");
|
||||
assert_eq!(a.event_id, payload, "{ctx}");
|
||||
}
|
||||
"version_ok" | "version_refused" => {
|
||||
// member column names the field; payload is the version text as it arrives
|
||||
let ok = match member {
|
||||
"notice_version" => check_version(payload).is_ok_and(|v| {
|
||||
NoticeAcceptance {
|
||||
member_id: "m".into(),
|
||||
experiment_id: room.into(),
|
||||
notice_version: v,
|
||||
scope: Scope::Train,
|
||||
accepted_at: 1,
|
||||
event_id: "e".into(),
|
||||
}
|
||||
.validate()
|
||||
.is_ok()
|
||||
}),
|
||||
"sample_id" => check_sample_id(&format!("s@{payload}")).is_ok(),
|
||||
"terms_version" => {
|
||||
MemberTerms { member_id: "m".into(), terms_version: payload.into(), terms_accepted_at: 1 }.validate().is_ok()
|
||||
}
|
||||
other => panic!("unknown version field {other}"),
|
||||
};
|
||||
assert_eq!(ok, op == "version_ok", "{ctx} field {member} version {payload}");
|
||||
}
|
||||
other => panic!("unknown op {other}"),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
# reply_rejected: validate must refuse the answer (nothing stored). answer_revoked: stores an exited answer with no text; payload is the tombstone hash (empty means none). expect_winner: the stored answer's event_id and text must equal event and payload.
|
||||
# Replacement at one key: the later reply is the greater (received_at, event_id), event_id compared bytewise; input order never decides (doc L78-81 and Heimdall PR #6 comment 759).
|
||||
# terms: member field terms_version (payload) and terms_accepted_at (ts). expect_terms: the stored pair for that member reads back as payload and ts; expect_no_terms: the member has none. expect_*: payload is what must hold.
|
||||
# version_ok / version_refused: the member column names the field (notice_version, sample_id, terms_version), payload is the version text; a sample id is checked as s@<payload>. One rule for all three: positive integer, no leading zeros, at most 4294967295 (Heimdall PR #6 cafdc52).
|
||||
# Expected values are written by hand from docs/answer-collector-consent.md (Heimdall PR #6, doc commit 4e99bfa), not computed by the crate.
|
||||
versioned-key,reply,m1,room1,1,train,s1@1,first,100,e1
|
||||
versioned-key,reply,m1,room1,1,train,s1@2,second,200,e2
|
||||
|
|
@ -66,3 +67,12 @@ tie-greater-last,reply,m15,room1,,,s1@1,long-aa,500,aa
|
|||
tie-greater-last,reply,m15,room1,,,s1@1,short-z,500,z
|
||||
tie-greater-last,expect_winner,m14,room1,,,s1@1,lower-a,,a
|
||||
tie-greater-last,expect_winner,m15,room1,,,s1@1,short-z,,z
|
||||
one-version-rule,version_ok,notice_version,room1,,,,4294967295,,version_ok-notice_version-4294967295
|
||||
one-version-rule,version_refused,notice_version,room1,,,,4294967296,,version_refused-notice_version-4294967296
|
||||
one-version-rule,version_refused,notice_version,room1,,,,01,,version_refused-notice_version-01
|
||||
one-version-rule,version_ok,sample_id,room1,,,,4294967295,,version_ok-sample_id-4294967295
|
||||
one-version-rule,version_refused,sample_id,room1,,,,4294967296,,version_refused-sample_id-4294967296
|
||||
one-version-rule,version_refused,sample_id,room1,,,,01,,version_refused-sample_id-01
|
||||
one-version-rule,version_ok,terms_version,room1,,,,4294967295,,version_ok-terms_version-4294967295
|
||||
one-version-rule,version_refused,terms_version,room1,,,,4294967296,,version_refused-terms_version-4294967296
|
||||
one-version-rule,version_refused,terms_version,room1,,,,01,,version_refused-terms_version-01
|
||||
|
|
|
|||
|
Loading…
Reference in a new issue