From 7001057f14b875eb7a4f07254a2139ff4cd32d97 Mon Sep 17 00:00:00 2001 From: Eureka Date: Wed, 11 Nov 2026 20:03:32 +0000 Subject: [PATCH] Desk feed door: re-pin the CultLib vectors to d3025d3c (null answerer pinned on Revision and Retraction) Co-Authored-By: Claude Sonnet 5.5 --- .../huginn-mind/tests/desk_feed_fixtures.rs | 24 ++++++++++-------- .../tests/fixtures/desk-feed/README.md | 2 +- .../README.md | 10 +++++--- .../answer-counted.msgpack | Bin .../answer-refused-stale.msgpack | Bin .../answer-retraction.msgpack | Bin .../answer-revision.msgpack | Bin ...nswer-withheld-answerer-retraction.msgpack | Bin 0 -> 399 bytes .../answer-withheld-answerer-revision.msgpack | Bin 0 -> 424 bytes .../answer-withheld-answerer.msgpack | Bin .../card-operator-fork.msgpack | Bin .../card-raised-at-nil.msgpack | Bin .../card-withheld-deciders.msgpack | Bin ...y-closed-with-ruling-and-a-refusal.msgpack | Bin .../entry-open-counted.msgpack | Bin ...d-closed-with-ruling-and-a-refusal.msgpack | Bin .../entry-withheld-open-counted.msgpack | Bin docs/desk-feed-door.md | 17 +++++++------ 18 files changed, 30 insertions(+), 23 deletions(-) rename crates/huginn-mind/tests/fixtures/desk-feed/{cultlib-3a51bbab => cultlib-d3025d3c}/README.md (79%) rename crates/huginn-mind/tests/fixtures/desk-feed/{cultlib-3a51bbab => cultlib-d3025d3c}/answer-counted.msgpack (100%) rename crates/huginn-mind/tests/fixtures/desk-feed/{cultlib-3a51bbab => cultlib-d3025d3c}/answer-refused-stale.msgpack (100%) rename crates/huginn-mind/tests/fixtures/desk-feed/{cultlib-3a51bbab => cultlib-d3025d3c}/answer-retraction.msgpack (100%) rename crates/huginn-mind/tests/fixtures/desk-feed/{cultlib-3a51bbab => cultlib-d3025d3c}/answer-revision.msgpack (100%) create mode 100644 crates/huginn-mind/tests/fixtures/desk-feed/cultlib-d3025d3c/answer-withheld-answerer-retraction.msgpack create mode 100644 crates/huginn-mind/tests/fixtures/desk-feed/cultlib-d3025d3c/answer-withheld-answerer-revision.msgpack rename crates/huginn-mind/tests/fixtures/desk-feed/{cultlib-3a51bbab => cultlib-d3025d3c}/answer-withheld-answerer.msgpack (100%) rename crates/huginn-mind/tests/fixtures/desk-feed/{cultlib-3a51bbab => cultlib-d3025d3c}/card-operator-fork.msgpack (100%) rename crates/huginn-mind/tests/fixtures/desk-feed/{cultlib-3a51bbab => cultlib-d3025d3c}/card-raised-at-nil.msgpack (100%) rename crates/huginn-mind/tests/fixtures/desk-feed/{cultlib-3a51bbab => cultlib-d3025d3c}/card-withheld-deciders.msgpack (100%) rename crates/huginn-mind/tests/fixtures/desk-feed/{cultlib-3a51bbab => cultlib-d3025d3c}/entry-closed-with-ruling-and-a-refusal.msgpack (100%) rename crates/huginn-mind/tests/fixtures/desk-feed/{cultlib-3a51bbab => cultlib-d3025d3c}/entry-open-counted.msgpack (100%) rename crates/huginn-mind/tests/fixtures/desk-feed/{cultlib-3a51bbab => cultlib-d3025d3c}/entry-withheld-closed-with-ruling-and-a-refusal.msgpack (100%) rename crates/huginn-mind/tests/fixtures/desk-feed/{cultlib-3a51bbab => cultlib-d3025d3c}/entry-withheld-open-counted.msgpack (100%) diff --git a/crates/huginn-mind/tests/desk_feed_fixtures.rs b/crates/huginn-mind/tests/desk_feed_fixtures.rs index 24b359c..2b05ecc 100644 --- a/crates/huginn-mind/tests/desk_feed_fixtures.rs +++ b/crates/huginn-mind/tests/desk_feed_fixtures.rs @@ -5,7 +5,7 @@ //! //! No fixture written here carries a card: Huginn's types do not carry `raised_at`, `decider_count`, //! `answerer_count` or a nullable `answerer` yet. Those shapes are CultLib's own bytes, vendored at -//! one commit in `fixtures/desk-feed/cultlib-3a51bbab/` and checked below. +//! one commit in `fixtures/desk-feed/cultlib-d3025d3c/` and checked below. //! //! `cargo test -p huginn-mind --test desk_feed_fixtures` compares every file with what the //! encoders produce now. `HUGINN_WRITE_DESK_FIXTURES=1` rewrites them instead. @@ -255,8 +255,8 @@ fn every_account_id_in_the_fixtures_is_a_lowercase_d_format_uuid() { // ---- CultLib's bytes: the reader-count shapes, pinned at one commit. ---- -/// The CultLib commit the vendored vectors come from (#117 on #115). Re-pin: see the README beside them. -const CULTLIB_SHA: &str = "3a51bbabad244a56ec4521080530d88744001ce4"; +/// The CultLib commit the vendored vectors come from (#118 on #117 on #115). Re-pin: see the README beside them. +const CULTLIB_SHA: &str = "d3025d3c19674803ad32eb2335461b8cbc22bd28"; /// Each vendored vector and the SHA-256 of its bytes. const VENDORED: &[(&str, &str)] = &[ @@ -267,6 +267,8 @@ const VENDORED: &[(&str, &str)] = &[ ("answer-revision", "19d7289395ae68cbaf6de1c0a1ef6c843211b2caf9462e1d2268cd0883386315"), ("answer-retraction", "89156f41ec3ea54f5d47bd3318913ff013785f4727916875be97785935cb7735"), ("answer-withheld-answerer", "b66b4f921cdd374be04af3de34c59e254a5e542027ae8c57f196a3ea3406e427"), + ("answer-withheld-answerer-revision", "93f7c875f963a7cfeab2a5980b6d5ce81e6753fc9f3f8bf0d7353f3f388144b7"), + ("answer-withheld-answerer-retraction", "7d0cc555bf9b6f7c345b0da7c504bcd1ed7b46040ff51d1e57c84b2f56655213"), ("answer-refused-stale", "3183bc9c483f4a625332cda11ef22a9c8560868a7728b77daa63a1960a3cd3d6"), ("entry-open-counted", "b51f499e8dd0465cf5df9d68d8fccbe94dd1339fd3157969693dd0d4ecb2549b"), ("entry-withheld-open-counted", "62ccad7a9f41262d6e35d0247315d0bb75d1313b3c9dabe8a99d1aa1b844607f"), @@ -275,7 +277,7 @@ const VENDORED: &[(&str, &str)] = &[ ]; fn vendored(name: &str) -> Vec { - let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/fixtures/desk-feed/cultlib-3a51bbab").join(format!("{name}.msgpack")); + let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/fixtures/desk-feed/cultlib-d3025d3c").join(format!("{name}.msgpack")); std::fs::read(&path).unwrap_or_else(|error| panic!("{}: {error}", path.display())) } @@ -379,7 +381,7 @@ const RECORD_KEYS: [&str; 6] = ["schemaVersion", "fork_id", "options_hash", "cou #[test] fn the_vendored_cultlib_vectors_are_the_pinned_bytes() { assert_eq!(CULTLIB_SHA.len(), 40); - let dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/fixtures/desk-feed/cultlib-3a51bbab"); + let dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/fixtures/desk-feed/cultlib-d3025d3c"); let docs = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../../docs/desk-feed-door.md"); for path in [dir.join("README.md"), docs] { let text = std::fs::read_to_string(&path).unwrap_or_else(|error| panic!("{}: {error}", path.display())); @@ -420,8 +422,8 @@ fn the_cards_are_eighteen_keys_with_raised_at_and_decider_count() { } /// `answerer` is a string or nil on every answer; `Value::Nil` only when `named` is false. The bytes -/// null it on `Counted` and `Refused` only; nullable on all four variants is the ruling -/// `desk-reader-counts-shape`, and CultLib has no vector with a `Revision` or `Retraction` nulled. +/// null it on all four variants (`Counted`, `Revision`, `Retraction`, `Refused`), by ruling +/// `desk-reader-counts-shape` and now by vector. fn check_answer(answer: &Value, named: bool) { assert_eq!(answer.keys().len(), 16); assert_eq!(answer.keys()[13], "answerer"); @@ -434,12 +436,12 @@ fn check_answer(answer: &Value, named: bool) { #[test] fn the_answers_keep_sixteen_keys_and_answerer_is_a_string_or_nil() { - for (name, named) in [("answer-counted", true), ("answer-revision", true), ("answer-retraction", true), ("answer-refused-stale", true), ("answer-withheld-answerer", false)] { + for (name, named) in [("answer-counted", true), ("answer-revision", true), ("answer-retraction", true), ("answer-refused-stale", true), ("answer-withheld-answerer", false), ("answer-withheld-answerer-revision", false), ("answer-withheld-answerer-retraction", false)] { let bytes = vendored(name); assert_eq!(bytes[..3], [0xde, 0x00, 0x10], "{name}: header"); check_answer(&decode(&bytes), named); } - for (name, outcome) in [("answer-counted", "Counted"), ("answer-revision", "Revision"), ("answer-retraction", "Retraction"), ("answer-refused-stale", "Refused")] { + for (name, outcome) in [("answer-counted", "Counted"), ("answer-revision", "Revision"), ("answer-retraction", "Retraction"), ("answer-refused-stale", "Refused"), ("answer-withheld-answerer-revision", "Revision"), ("answer-withheld-answerer-retraction", "Retraction")] { assert_eq!(decode(&vendored(name)).get("outcome").str(), outcome); } } @@ -517,7 +519,9 @@ fn huginn_types_do_not_yet_carry_the_pinned_shapes() { } assert!(refused::(&vendored("card-operator-fork")).contains("raised_at")); assert!(refused::(&vendored("card-withheld-deciders")).contains("raised_at")); - assert!(refused::(&vendored("answer-withheld-answerer")).contains("string")); + for name in ["answer-withheld-answerer", "answer-withheld-answerer-revision", "answer-withheld-answerer-retraction"] { + assert!(refused::(&vendored(name)).contains("string"), "{name}"); + } // The record is the entry's last key: its bytes run from the `86` after the key to the end. let entry = vendored("entry-open-counted"); let key = [&[0xa6u8][..], b"record", &[0x86]].concat(); diff --git a/crates/huginn-mind/tests/fixtures/desk-feed/README.md b/crates/huginn-mind/tests/fixtures/desk-feed/README.md index 4b98b4f..c410ef3 100644 --- a/crates/huginn-mind/tests/fixtures/desk-feed/README.md +++ b/crates/huginn-mind/tests/fixtures/desk-feed/README.md @@ -38,7 +38,7 @@ lands (see `docs/desk-feed-door.md`). | `record-whole` | fragment | `gamecult.fork.record.v0` with all four answer variants (Counted, Revision, Refused, Retraction) by three accounts, answerer ids and notes whole: what the door sends today (5 keys, no `answerer_count`) | The reader-count shapes (`raised_at`, `decider_count`, `answerer_count`, nullable `answerer`) are -CultLib's own bytes, vendored unedited in `cultlib-3a51bbab/` (see its README for the pinned commit and +CultLib's own bytes, vendored unedited in `cultlib-d3025d3c/` (see its README for the pinned commit and each vector). They are not Huginn's output: Huginn's types do not carry those shapes yet. `cut-desk-feed-listing` and `cut-desk-feed-raised-at` replace them with entry-bearing fixtures the encoders write, after decoding these bytes into the real types. diff --git a/crates/huginn-mind/tests/fixtures/desk-feed/cultlib-3a51bbab/README.md b/crates/huginn-mind/tests/fixtures/desk-feed/cultlib-d3025d3c/README.md similarity index 79% rename from crates/huginn-mind/tests/fixtures/desk-feed/cultlib-3a51bbab/README.md rename to crates/huginn-mind/tests/fixtures/desk-feed/cultlib-d3025d3c/README.md index a3203a7..f29b828 100644 --- a/crates/huginn-mind/tests/fixtures/desk-feed/cultlib-3a51bbab/README.md +++ b/crates/huginn-mind/tests/fixtures/desk-feed/cultlib-d3025d3c/README.md @@ -1,7 +1,7 @@ # CultLib desk-feed vectors, vendored -Source: `GameCult/CultLib` at commit `3a51bbabad244a56ec4521080530d88744001ce4` (#117, on -`af914253` #115), file `contracts/cultnet/governance/fork-card-vectors.json`. Each `.msgpack` file is +Source: `GameCult/CultLib` at commit `d3025d3c19674803ad32eb2335461b8cbc22bd28` (#118, on +`3a51bbab` #117, on `af914253` #115), file `contracts/cultnet/governance/fork-card-vectors.json`. Each `.msgpack` file is the vector's `messagePackHex` decoded to bytes, nothing else changed. Do not edit them or rewrite them from Huginn's encoders: Huginn's own types do not carry these shapes yet (see `docs/desk-feed-door.md`). To re-pin, take the new commit's vectors and update the sha here, in @@ -13,9 +13,11 @@ from Huginn's encoders: Huginn's own types do not carry these shapes yet (see | `card-raised-at-nil` | `card.valid` `raised_at_nil` | `raised_at` nil, key kept | | `card-withheld-deciders` | `card.valid` `withheld_deciders` | empty `deciders`, `decider_count` 2 | | `answer-counted` | `deskAnswer.valid` `counted` | 16 keys (`DE 00 10`), `answerer` a string | -| `answer-revision` | `deskAnswer.valid` `revision` | a `Revision`, `answerer` a string (no CultLib vector nulls a Revision) | -| `answer-retraction` | `deskAnswer.valid` `retraction` | a `Retraction`, `answerer` a string (no CultLib vector nulls a Retraction) | +| `answer-revision` | `deskAnswer.valid` `revision` | a `Revision`, `answerer` a string | +| `answer-retraction` | `deskAnswer.valid` `retraction` | a `Retraction`, `answerer` a string | | `answer-withheld-answerer` | `deskAnswer.valid` `withheld_answerer` | `answerer` nil | +| `answer-withheld-answerer-revision` | `deskAnswer.valid` `withheld_answerer_revision` | a `Revision`, `answerer` nil | +| `answer-withheld-answerer-retraction` | `deskAnswer.valid` `withheld_answerer_retraction` | a `Retraction`, `answerer` nil | | `answer-refused-stale` | `deskAnswer.valid` `refused_stale` | a `Refused` answer, `answerer` a string | | `entry-open-counted` | `transport.entry.valid` `open_counted` | decider view: entry `83`, record `86`, `answerer_count` 1 | | `entry-withheld-open-counted` | `transport.entry.valid` `withheld_open_counted` | non-decider twin: `deciders` empty, `answerer` nil, count 1 | diff --git a/crates/huginn-mind/tests/fixtures/desk-feed/cultlib-3a51bbab/answer-counted.msgpack b/crates/huginn-mind/tests/fixtures/desk-feed/cultlib-d3025d3c/answer-counted.msgpack similarity index 100% rename from crates/huginn-mind/tests/fixtures/desk-feed/cultlib-3a51bbab/answer-counted.msgpack rename to crates/huginn-mind/tests/fixtures/desk-feed/cultlib-d3025d3c/answer-counted.msgpack diff --git a/crates/huginn-mind/tests/fixtures/desk-feed/cultlib-3a51bbab/answer-refused-stale.msgpack b/crates/huginn-mind/tests/fixtures/desk-feed/cultlib-d3025d3c/answer-refused-stale.msgpack similarity index 100% rename from crates/huginn-mind/tests/fixtures/desk-feed/cultlib-3a51bbab/answer-refused-stale.msgpack rename to crates/huginn-mind/tests/fixtures/desk-feed/cultlib-d3025d3c/answer-refused-stale.msgpack diff --git a/crates/huginn-mind/tests/fixtures/desk-feed/cultlib-3a51bbab/answer-retraction.msgpack b/crates/huginn-mind/tests/fixtures/desk-feed/cultlib-d3025d3c/answer-retraction.msgpack similarity index 100% rename from crates/huginn-mind/tests/fixtures/desk-feed/cultlib-3a51bbab/answer-retraction.msgpack rename to crates/huginn-mind/tests/fixtures/desk-feed/cultlib-d3025d3c/answer-retraction.msgpack diff --git a/crates/huginn-mind/tests/fixtures/desk-feed/cultlib-3a51bbab/answer-revision.msgpack b/crates/huginn-mind/tests/fixtures/desk-feed/cultlib-d3025d3c/answer-revision.msgpack similarity index 100% rename from crates/huginn-mind/tests/fixtures/desk-feed/cultlib-3a51bbab/answer-revision.msgpack rename to crates/huginn-mind/tests/fixtures/desk-feed/cultlib-d3025d3c/answer-revision.msgpack diff --git a/crates/huginn-mind/tests/fixtures/desk-feed/cultlib-d3025d3c/answer-withheld-answerer-retraction.msgpack b/crates/huginn-mind/tests/fixtures/desk-feed/cultlib-d3025d3c/answer-withheld-answerer-retraction.msgpack new file mode 100644 index 0000000000000000000000000000000000000000..4c676cf90209bf4f27a28e76711f37d12219a8e9 GIT binary patch literal 399 zcmZutJ5B>J6yyjTf`Z18?e%`L6*oXah$7AE#rw=!$=bp8263GzB0mrf677mxq~R>A z33N;`n$e6#dhhG({ME|_Tew5#wKX62(4y?-VN|1^Rbc!hy3vyEPO8%N$`l)A-E5G@ z%fB{}4TSQcLm!5b($8%mEw~wx)_62wW4j=2i~Ac44rDB?tm?P!Wc|vpwX`+%FLn__ zUp3&H<5gadQzeVMP7^LT%@|WCSSneKisz6Bk!LKQPP2k1sS+6`pjbiyA<38&#j|Xz zme{Y24cH$}M_^q+c;}R7gfYVSEgP4Vmy}Kp4kha4zlEWbPTu4kbX#dtsV;O5KexY= puHQiy8tZg;+FmcvL9lM`@aHA*RTp%?lu|~bARJ5akFQAq52m8`<7(w&Dhn5TZ!4ns~>om0dg7-k@A3L}WuiG)Sb3xJ4Sy zLQF!*E8e`3-n`Mw_u2WI?4}~jI58UkmW+LmC$B# zko(I&cfc!f`9q7=9YS(jYZo+NCIQ#VqH-(UI<6b+Zg3|3o`n_*MLUDe0C#q`3YJ0`MQK9Q@i@s?7>g*u5CjbgAcP6! zQTEI$Ejd2T(JqyCxE-pVK~W?3TdsPx0)sv2`kUi*SQg+u7-303X+YU69pog*2^nn+ za+I_G4Dsll*C3lhszS7`HTcz?BF%0Mt*f+=Zr%;2XuxUnV(|A@{)ZRj2p0GnM4mEF IzCD5c0OJjs_5c6? literal 0 HcmV?d00001 diff --git a/crates/huginn-mind/tests/fixtures/desk-feed/cultlib-3a51bbab/answer-withheld-answerer.msgpack b/crates/huginn-mind/tests/fixtures/desk-feed/cultlib-d3025d3c/answer-withheld-answerer.msgpack similarity index 100% rename from crates/huginn-mind/tests/fixtures/desk-feed/cultlib-3a51bbab/answer-withheld-answerer.msgpack rename to crates/huginn-mind/tests/fixtures/desk-feed/cultlib-d3025d3c/answer-withheld-answerer.msgpack diff --git a/crates/huginn-mind/tests/fixtures/desk-feed/cultlib-3a51bbab/card-operator-fork.msgpack b/crates/huginn-mind/tests/fixtures/desk-feed/cultlib-d3025d3c/card-operator-fork.msgpack similarity index 100% rename from crates/huginn-mind/tests/fixtures/desk-feed/cultlib-3a51bbab/card-operator-fork.msgpack rename to crates/huginn-mind/tests/fixtures/desk-feed/cultlib-d3025d3c/card-operator-fork.msgpack diff --git a/crates/huginn-mind/tests/fixtures/desk-feed/cultlib-3a51bbab/card-raised-at-nil.msgpack b/crates/huginn-mind/tests/fixtures/desk-feed/cultlib-d3025d3c/card-raised-at-nil.msgpack similarity index 100% rename from crates/huginn-mind/tests/fixtures/desk-feed/cultlib-3a51bbab/card-raised-at-nil.msgpack rename to crates/huginn-mind/tests/fixtures/desk-feed/cultlib-d3025d3c/card-raised-at-nil.msgpack diff --git a/crates/huginn-mind/tests/fixtures/desk-feed/cultlib-3a51bbab/card-withheld-deciders.msgpack b/crates/huginn-mind/tests/fixtures/desk-feed/cultlib-d3025d3c/card-withheld-deciders.msgpack similarity index 100% rename from crates/huginn-mind/tests/fixtures/desk-feed/cultlib-3a51bbab/card-withheld-deciders.msgpack rename to crates/huginn-mind/tests/fixtures/desk-feed/cultlib-d3025d3c/card-withheld-deciders.msgpack diff --git a/crates/huginn-mind/tests/fixtures/desk-feed/cultlib-3a51bbab/entry-closed-with-ruling-and-a-refusal.msgpack b/crates/huginn-mind/tests/fixtures/desk-feed/cultlib-d3025d3c/entry-closed-with-ruling-and-a-refusal.msgpack similarity index 100% rename from crates/huginn-mind/tests/fixtures/desk-feed/cultlib-3a51bbab/entry-closed-with-ruling-and-a-refusal.msgpack rename to crates/huginn-mind/tests/fixtures/desk-feed/cultlib-d3025d3c/entry-closed-with-ruling-and-a-refusal.msgpack diff --git a/crates/huginn-mind/tests/fixtures/desk-feed/cultlib-3a51bbab/entry-open-counted.msgpack b/crates/huginn-mind/tests/fixtures/desk-feed/cultlib-d3025d3c/entry-open-counted.msgpack similarity index 100% rename from crates/huginn-mind/tests/fixtures/desk-feed/cultlib-3a51bbab/entry-open-counted.msgpack rename to crates/huginn-mind/tests/fixtures/desk-feed/cultlib-d3025d3c/entry-open-counted.msgpack diff --git a/crates/huginn-mind/tests/fixtures/desk-feed/cultlib-3a51bbab/entry-withheld-closed-with-ruling-and-a-refusal.msgpack b/crates/huginn-mind/tests/fixtures/desk-feed/cultlib-d3025d3c/entry-withheld-closed-with-ruling-and-a-refusal.msgpack similarity index 100% rename from crates/huginn-mind/tests/fixtures/desk-feed/cultlib-3a51bbab/entry-withheld-closed-with-ruling-and-a-refusal.msgpack rename to crates/huginn-mind/tests/fixtures/desk-feed/cultlib-d3025d3c/entry-withheld-closed-with-ruling-and-a-refusal.msgpack diff --git a/crates/huginn-mind/tests/fixtures/desk-feed/cultlib-3a51bbab/entry-withheld-open-counted.msgpack b/crates/huginn-mind/tests/fixtures/desk-feed/cultlib-d3025d3c/entry-withheld-open-counted.msgpack similarity index 100% rename from crates/huginn-mind/tests/fixtures/desk-feed/cultlib-3a51bbab/entry-withheld-open-counted.msgpack rename to crates/huginn-mind/tests/fixtures/desk-feed/cultlib-d3025d3c/entry-withheld-open-counted.msgpack diff --git a/docs/desk-feed-door.md b/docs/desk-feed-door.md index a930172..12db576 100644 --- a/docs/desk-feed-door.md +++ b/docs/desk-feed-door.md @@ -20,7 +20,7 @@ This page is the wire contract for the consumer, Bifrost's `UnixSocketDeskDoor` `docs/desk-feed-design.md`). The golden bytes are in `crates/huginn-mind/tests/fixtures/desk-feed/`. Huginn's own encoders write them (`crates/huginn-mind/tests/desk_feed_fixtures.rs`), so a decoder that reads them reads the door. The reader-count shapes are CultLib's bytes, vendored in -`cultlib-3a51bbab/` (below). The document shapes inside the payload (`gamecult.fork.list.v0`, +`cultlib-d3025d3c/` (below). The document shapes inside the payload (`gamecult.fork.list.v0`, `gamecult.fork.entry.v0`, `gamecult.fork.card.v0`, `gamecult.fork.record.v0`, `gamecult.desk_answer.v0`, `gamecult.fork.refusal.v0`) are CultLib's (`contracts/cultnet/governance/fork-card.md`) and are not restated here. @@ -120,11 +120,12 @@ byte; both values are in the account-id format above. Any other reader is a non- Bifrost, withholds account ids from a non-decider and returns a count instead. Bifrost cannot do it, because the card is opaque to it. A decider sees the ids. The superseding ruling is in force: `eureka-substrate:ruling:desk-read-visibility-withheld-ids`. -- **The shape**, pinned to CultLib commit `3a51bbabad244a56ec4521080530d88744001ce4` (#117 "Fork card: - decider_count, answerer_count, nullable answerer (reader views)", on `af914253` #115 `raised_at`; +- **The shape**, pinned to CultLib commit `d3025d3c19674803ad32eb2335461b8cbc22bd28` (#118 "null-answerer vectors for + Revision and Retraction", additive over `3a51bbab` #117 "Fork card: decider_count, answerer_count, + nullable answerer (reader views)", on `af914253` #115 `raised_at`; ruling `eureka-substrate:ruling:desk-reader-counts-shape`). The bytes are CultLib's own vectors (`contracts/cultnet/governance/fork-card-vectors.json`, `messagePackHex`), vendored unedited in - `crates/huginn-mind/tests/fixtures/desk-feed/cultlib-3a51bbab/` (its README lists each file and + `crates/huginn-mind/tests/fixtures/desk-feed/cultlib-d3025d3c/` (its README lists each file and its vector name). Read off those bytes: - **Card:** 18 keys, header `DE 00 12` (map16): `schemaVersion` plus 17 fields, in this order: `fork_id, title, context, options, recommendation, depends, leans, flag, raised_in, raised_at, @@ -139,10 +140,10 @@ byte; both values are in the account-id format above. Any other reader is a non- between 1 and the number of answers (0 with no answers). - **Answer:** `gamecult.desk_answer.v0` keeps its 16 keys (header `DE 00 10`); `answerer` is a string or nil, nil only in a non-decider's view, with the key kept. The bytes pin a nil `answerer` - on two variants, `Counted` (`answer-withheld-answerer`) and `Refused` (the withheld entries). That - it is nullable on all four variants (`Counted`, `Revision`, `Retraction`, `Refused`) is the ruling - `eureka-substrate:ruling:desk-reader-counts-shape`, not a vector: CultLib's `revision` and - `retraction` vectors carry a string `answerer` and no CultLib vector has either nulled. Stored + on all four variants, `Counted` (`answer-withheld-answerer`), `Revision` + (`answer-withheld-answerer-revision`), `Retraction` (`answer-withheld-answerer-retraction`) and + `Refused` (the withheld entries), beside each variant's string-`answerer` vector; ruling + `eureka-substrate:ruling:desk-reader-counts-shape` is the reason, no longer the only evidence. Stored answers always carry it. - **Entry:** header `83` (`schemaVersion, card, record`). The view is read off `deciders`: a non-empty `deciders` names every answerer, an empty one names none.