Desk feed door: card has 16 keys (17 with raised_at); grammar test kills length and dash mutants

Soul on d08b888: CultLib main's card requires 16 keys, not 17. The
account-id grammar test now rejects 36 hex digits with no dash, a
37-character id and a dash off position. The reader-view test says it
pins mirror types only.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Eureka 2026-11-11 17:42:26 +00:00
commit ea4193e0e4
2 changed files with 21 additions and 3 deletions

View file

@ -326,7 +326,21 @@ fn every_account_id_in_the_fixtures_is_a_lowercase_d_format_uuid() {
assert!(request.deciders().iter().all(|decider| account_id(&decider.0)), "deciders");
}
assert!(record().answers.iter().all(|answer| account_id(&answer.answerer)), "answerer");
for shape in ["@heimdall:gamecult.org", "meta@gamecult.org", "heimdall", "7", "5F0C2B1E-8A4D-4C3B-9E7F-1A2B3C4D5E6F", "{5f0c2b1e-8a4d-4c3b-9e7f-1a2b3c4d5e6f}", ""] {
for shape in [
"@heimdall:gamecult.org",
"meta@gamecult.org",
"heimdall",
"7",
"5F0C2B1E-8A4D-4C3B-9E7F-1A2B3C4D5E6F",
"{5f0c2b1e-8a4d-4c3b-9e7f-1a2b3c4d5e6f}",
"",
// 36 hex digits and no dash: the length alone does not make an id.
"5f0c2b1e08a4d04c3b09e7f01a2b3c4d5e6f",
// 37 characters: a valid id with one more digit.
"5f0c2b1e-8a4d-4c3b-9e7f-1a2b3c4d5e6f0",
// A dash moved off its position.
"5f0c2b1e8-a4d-4c3b-9e7f-1a2b3c4d5e6f",
] {
assert!(!account_id(shape), "{shape} is not an account id");
}
}
@ -335,6 +349,10 @@ fn holds(bytes: &[u8], text: &str) -> bool {
bytes.windows(text.len()).any(|window| window == text.as_bytes())
}
/// This test pins MIRROR TYPES ONLY (`CardViewers`, `WithheldRecord`), the shapes proposed to CultLib.
/// It does not exercise Huginn's projection, which does not withhold ids yet. The tests on real list and
/// read responses land with `cut-desk-feed-listing` (r6).
///
/// A reader who is not a decider gets counts and no account id at all: neither UUID appears
/// anywhere in its fragments' bytes. A decider gets every id. (Proposed shapes; the build cut pins
/// the same on Huginn's real list and read responses.)

View file

@ -102,7 +102,7 @@ refuses any decider not in that form). That is the same grammar Huginn names for
handle is never one of them. Bifrost enforces the grammar; Huginn's door does not yet: it reads these
fields as `Short` (any text up to 200 bytes) and would accept `@x:server` or an email. A subject
is stored as `answerer` on an answer, so a wrong value would enter the mind. Refusing every other
shape at decode is owed by `cut-desk-feed-listing.r5`. The test
shape at decode is owed by `cut-desk-feed-listing.r6`. The test
`every_account_id_in_the_fixtures_is_a_lowercase_d_format_uuid` pins the grammar. The fixtures use
synthetic UUIDs.
@ -118,7 +118,7 @@ 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 drafted
as `desk-read-visibility-withheld-ids`.
- **CultLib cannot carry this yet.** The card has 17 required keys in closed map-mode, and
- **CultLib cannot carry this yet.** The card has 16 required keys in closed map-mode (17 once `raised_at` lands), and
`deciders` must hold at least one item. `answerer` is a required, non-null id. The proposal to
Libby (follow-up `cultlib-fork-card-reader-counts`):
- the card gains a required `decider_count` (an integer). A non-decider gets `deciders: []`; a