Persona's ruling (follow-up chat-mind-20261111T150417226Z-t167): a
reader is a decider when subject is in the call's deciders; any other
reader gets no decider or answerer ids, only counts, and Huginn does it
because the card is opaque to Bifrost. CultLib's closed card (deciders
minItems 1, no count) and non-null answerer cannot carry it yet, so the
doc names the proposal to Libby and the fixtures add clearly synthetic
card fragments and a proposed non-decider record, with a test that no
account id appears in a non-decider's bytes and a decider keeps them.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
subject, deciders and answerer are Bifrost UserAccount ids (lowercase
D-format, as Bifrost's validator requires and as Huginn names
RequestId). The fixtures used "7"/"12"; they now carry synthetic UUIDs,
and a test pins the grammar and refuses Matrix ids, emails and handles.
The doc states that Huginn's door does not refuse other shapes yet (owed
by cut-desk-feed-listing.r4) and that card.deciders echoes the ids.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Soul pass on 66e6fe8: document and fixture the read form of
fork_too_large (live on main; CultLib limitation 13 is stale), the
ResponseTooLarge 503 and a unit-variant Refused; say that only operation
messages have sorted keys, what failure diagnostics and the schema
catalog reply are, where forks come from, and that the listing gate is
not live (no receiver on a Mind with private questions before
cut-desk-feed-listing). Fixtures use a held fork id, synthetic record.
.gitattributes keeps .bin/.msgpack binary and .hex LF.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
docs/desk-feed-door.md states the list and read wire already on main
(frame, CultNet envelope, named MessagePack payload), the per-Mind
peer-checked socket, 503 for the addressed Mind only, the raw-answerer
trust boundary (Bifrost masks), raised_at as ruled by CultLib (card
bytes not pinned until the re-pinned card vectors land) and the planned
listing gate (default not listed).
crates/huginn-mind/tests/desk_feed_fixtures.rs writes the fixtures with
Huginn's own encoders and checks them; HUGINN_WRITE_DESK_FIXTURES=1
rewrites. No card bytes in any fixture.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
SourceQuery gains `texts` (one to eight, SOURCE_TEXTS_MAX) beside the
transitional `text`; check() refuses neither, both, more than eight and blank
entries, naming `texts`. SourceHit.score documents cosine versus reciprocal-rank
sum. Published request and response schemas regenerated. Cut
gamecult-chat:cut_spec:cut-source-query-texts.r1, commit 1.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Newest first by admission ordinal, cursor strictly below, counts over the showable set, limit 0 is
counts and stamp. Whole record to the peer-checked socket; the trust boundary is pinned in the
desk_door module doc and the DeskRequest/DeskResponse docs. Published schemas regenerated.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Types ForkCard/Record/Entry/List, ForkCursor and ForkLimit validated at decode, DeskRequest::Forks
gains status/cursor/limit flat, DeskResponse gains Forks and Fork, the daemon dispatches to
Mind::desk_forks/desk_fork (stubs). Vectors vendored at CultLib e57fbaee. The tests pin the rules
the next commit implements; DESK_READS_UNBUILT and its test are gone.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
envelope.rs cores are generic over service id, schema and payload; the mind's five functions and the desk's five instantiate them. desk_answer's attribution parameter is authority. huginn.desk_request.v1 and huginn.desk_response.v1 are derived and pinned.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The desk request, response, envelope instantiations and constants do not exist yet; these tests name them and do not compile.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
S11 applied with the sequential check off and seen to fail on it. Finding desk-wire-replay-id-map-not-injective.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Soul's S12 (a second converter that agrees on every legal key) applied and seen to fail. Finding desk-wire-second-converter-evades-grep.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Padded, cased and trailing-junk spellings added to the existing tables; Soul's S1, S8, S9, S10 each applied and seen to fail. Finding desk-wire-pass-through-unpinned.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Kills Soul's S2, S3 and S5 (each applied and seen to fail). Finding desk-wire-asof-and-gate-thinly-pinned.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Her vectors hold no over-long fork id (deviation recorded). Finding desk-wire-long-fork-id-body-invalid.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
answer_desk's (answerer, request_id) lookup is now bound_answer, pub(crate) in desk.rs, and
Mind::desk_answer asks it so the gate runs only when nothing is stored. Finding
desk-wire-gate-shadows-replay.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Vendors fork-card-vectors.json at CultLib 8ca1d184 and retires the options-hash file it contains.
answer_desk's dead-code allowance goes: desk_answer is its live caller. No card is built here.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
body_digest writes retracted for the illegal form only, so forms (i) and
(iii) no longer share a digest; desk_steps refuses a value that is no
illegal form as body invalid. Tests pin the three illegal goldens, the
200-byte target, choice and Refused.retracts bounds, case-sensitive
labels and fork_closed before bad_retraction.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
PipelineFacts::DeskAnswer gains counts, derived through counted_answer over the
read's Docs::at(image, as_of); the stored outcome name stays the write-time record.
DeskOutcome::Refused carries the retraction target as sent; the record's choice is a
Short kept as sent (a choice_invalid choice is no label), and an illegal retraction
form keeps its choice and note. body_sha256 form unchanged. Schemas regenerated.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A bound (answerer, request_id) replays its stored outcome without re-running
probe validation; a malformed id binds nothing and still meets the probe.
Comment on the choice bound now says a Short (200 bytes).
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
DeskBody::IllegalRetraction stores Refused bad_retraction after steps 4-6 (digest carries the form, so it never replays as a plain answer); a choice is any 1-200 byte text, stored Refused choice_invalid when no option label, grammar or not. claim_in_future compares against the whole-second received_at written to the record.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
DeskStamp carries answerer, attribution (Operator/Steward/Member per CultLib PR #72) and the decider
list; membership decides rule 5, the attribution never does. answer_desk and DeskStamp are crate-private.
The receipt names the operator only for the operator's account. counted_answer and R1 consider
options_hash. A stored answer keeps received_at, claim_in_future, request_id and a body digest;
the same (answerer, request_id) and body replays the stored outcome and writes nothing, another
body is request_id_conflict. Notes are Words (1..=4000 bytes, not blank); answered_at must be UTC.
The vector file is re-sliced byte for byte from PR #72 head 2dea6c56.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
NFC every string, JCS (struct fields in key order through serde_json), SHA-256,
lowercase hex; the seam stays the single owner. Libby's 15 vectors, A-G included,
run as tests; the test fixture hash is gone. Adds unicode-normalization.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>