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 <noreply@anthropic.com>
This commit is contained in:
Meta Vens 2026-09-22 18:57:06 +02:00
commit 68c4f0e1b4
2 changed files with 7 additions and 4 deletions

View file

@ -217,7 +217,7 @@ impl<S: MindStore> Mind<S> {
}
/// Every commit receipt in the image, in receipt-id order.
pub fn receipts(&self) -> Result<Vec<HuginnCommitReceipt>, MindRefusal> {
pub(crate) fn receipts(&self) -> Result<Vec<HuginnCommitReceipt>, MindRefusal> {
self.image
.iter()
.filter(|envelope| envelope.r#type == HuginnCommitReceipt::TYPE)

View file

@ -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<S: MindStore>(mind: &Mind<S>) -> Result<u64, MindRefusal> {
let mut ordinals = mind.receipts()?.into_iter().map(|receipt| receipt.ordinal).collect::<Vec<_>>();
ordinals.sort_unstable();