From 68c4f0e1b4a3401ddfb6f6f57b6a69f008af9b66 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Tue, 22 Sep 2026 18:57:06 +0200 Subject: [PATCH] Narrow Mind::receipts to pub(crate) and true up head's doc Every caller of Mind::receipts lives inside huginn-mind (admission.rs, query.rs, receipt.rs); nothing outside the crate needs raw, unchecked receipt ordinals. Narrowing it to pub(crate) closes the only door that let a caller read ordinals without going through receipt::head's density check, which is what head's own doc claimed already held. Update that doc to say so explicitly instead of asserting a door was closed that was, in fact, still open. Co-Authored-By: Claude Sonnet 5 --- crates/huginn-mind/src/mind.rs | 2 +- crates/huginn-mind/src/receipt.rs | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/crates/huginn-mind/src/mind.rs b/crates/huginn-mind/src/mind.rs index 44e9772..93f76dc 100644 --- a/crates/huginn-mind/src/mind.rs +++ b/crates/huginn-mind/src/mind.rs @@ -217,7 +217,7 @@ impl Mind { } /// Every commit receipt in the image, in receipt-id order. - pub fn receipts(&self) -> Result, MindRefusal> { + pub(crate) fn receipts(&self) -> Result, MindRefusal> { self.image .iter() .filter(|envelope| envelope.r#type == HuginnCommitReceipt::TYPE) diff --git a/crates/huginn-mind/src/receipt.rs b/crates/huginn-mind/src/receipt.rs index e175b40..f08188d 100644 --- a/crates/huginn-mind/src/receipt.rs +++ b/crates/huginn-mind/src/receipt.rs @@ -193,9 +193,12 @@ pub(crate) fn candidate( /// never by counting receipts itself: admission takes `head(self)? + 1` for /// the next one, and `AdmissionIndex::build` (`query.rs`) calls it too, so /// `query` and `view` carry the same density check rather than trusting a -/// stored ordinal unchecked. `ordinal` stays display-only on the read side -/// until RS-3 makes it the order. A chain that is not dense refuses rather -/// than guessing, on both sides alike. +/// stored ordinal unchecked. `Mind::receipts` is `pub(crate)`, so this crate +/// is the only place raw ordinals can be read at all; that keeps this the +/// one door, rather than something a doc comment merely asks callers to +/// respect. `ordinal` stays display-only on the read side until RS-3 makes +/// it the order. A chain that is not dense refuses rather than guessing, on +/// both sides alike. pub(crate) fn head(mind: &Mind) -> Result { let mut ordinals = mind.receipts()?.into_iter().map(|receipt| receipt.ordinal).collect::>(); ordinals.sort_unstable();