From 7611d1bbf194be5057009fa7ccde2bd7496ad719 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Tue, 22 Sep 2026 03:19:30 +0200 Subject: [PATCH] Give the instance check a fixture pair that differs by separator alone F1: thought-cage, thought_cage and thought.cage are three legal Slug names, not one, so a comparison that folds `_` or `.` into `-` at Mind::require_instance answers one mind for another. Add the fixture pair and a mind opened under a separator-bearing name to require_instance_is_the_one_check_admission_and_the_daemon_share, and two mutation entries, D1L6 and D1L7, that fold each separator into `-`; both die against the new assertions. F4: fixtures.rs described Label's grammar on the CASED_INSTANCE comment as though it were Slug's. Corrected to say what Slug actually is at the pinned Epiphany revision: dot-joined labels, bounded to 64 bytes whole. Co-Authored-By: Claude Sonnet 5 --- crates/huginn-mind/src/fixtures.rs | 16 ++++++++++++---- crates/huginn-mind/src/mind.rs | 21 ++++++++++++++++++++- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/crates/huginn-mind/src/fixtures.rs b/crates/huginn-mind/src/fixtures.rs index 3c84a09..56ff119 100644 --- a/crates/huginn-mind/src/fixtures.rs +++ b/crates/huginn-mind/src/fixtures.rs @@ -30,11 +30,19 @@ pub(crate) const NEAR_INSTANCE: &str = "yggdrasix"; /// A foreign instance carrying `INSTANCE` whole as its prefix, so a prefix /// test admits it. pub(crate) const PREFIXED_INSTANCE: &str = "yggdrasil-two"; -/// A foreign instance differing from `INSTANCE` in case alone. A slug label is -/// `[A-Za-z0-9_-]{1,64}`, so this is a name a client may declare and a mind -/// may hold: two minds whose names differ only in case are two minds, and a -/// comparison that folds case answers one of them for the other. +/// A foreign instance differing from `INSTANCE` in case alone. A `Slug` is +/// dot-joined labels, each `[A-Za-z0-9_-]{1,64}`, bounded to 64 bytes whole +/// (`epiphany_pipeline::dotted_text`), so this is a name a client may declare +/// and a mind may hold: two minds whose names differ only in case are two +/// minds, and a comparison that folds case answers one of them for the other. pub(crate) const CASED_INSTANCE: &str = "Yggdrasil"; +/// Two foreign instances differing from `OTHER_INSTANCE` (`thought-cage`) in +/// their separator alone: `_` and `.` are both legal in a `Slug` beside `-` +/// (`_` inside a label, `.` joining labels), so `thought-cage`, `thought_cage` +/// and `thought.cage` are three names, not one, and a comparison that folds a +/// separator into another answers one of them for another. +pub(crate) const UNDERSCORE_INSTANCE: &str = "thought_cage"; +pub(crate) const DOTTED_INSTANCE: &str = "thought.cage"; pub(crate) const CAMPAIGN: &str = "eureka-state"; pub(crate) const REPO: &str = "GameCult/Epiphany"; pub(crate) const OTHER_REPO: &str = "GameCult/Huginn"; diff --git a/crates/huginn-mind/src/mind.rs b/crates/huginn-mind/src/mind.rs index 94dc6cb..5fda6bf 100644 --- a/crates/huginn-mind/src/mind.rs +++ b/crates/huginn-mind/src/mind.rs @@ -417,7 +417,8 @@ mod tests { #[test] fn require_instance_is_the_one_check_admission_and_the_daemon_share() { use crate::fixtures::{ - CASED_INSTANCE, NEAR_INSTANCE, OTHER_INSTANCE, PREFIXED_INSTANCE, now, provenance, seeded, + CASED_INSTANCE, DOTTED_INSTANCE, NEAR_INSTANCE, OTHER_INSTANCE, PREFIXED_INSTANCE, UNDERSCORE_INSTANCE, + now, opened, provenance, seeded, }; use crate::receipt::Faculty; @@ -445,6 +446,24 @@ mod tests { documents: vec![instance(OTHER_INSTANCE)], }; assert_eq!(mind.admit(batch, now()), crate::admission::PipelineAdmissionOutcome::Refused(foreign)); + + // `INSTANCE` ("yggdrasil") carries no separator, so no fold of `_` or + // `.` into `-` can ever equate a declared name with it; a mind whose + // own name carries one is required to tell the fold apart. Opened as + // `OTHER_INSTANCE` ("thought-cage"), a declared name that folds to the + // same string under such a comparison must still be refused. + let separated = opened(MemoryStore::new(), OTHER_INSTANCE); + assert_eq!(UNDERSCORE_INSTANCE.replace('_', "-"), OTHER_INSTANCE, "differs from OTHER_INSTANCE by `_` alone"); + assert_eq!(DOTTED_INSTANCE.replace('.', "-"), OTHER_INSTANCE, "differs from OTHER_INSTANCE by `.` alone"); + assert_ne!(UNDERSCORE_INSTANCE, OTHER_INSTANCE); + assert_ne!(DOTTED_INSTANCE, OTHER_INSTANCE); + for declared in [UNDERSCORE_INSTANCE, DOTTED_INSTANCE] { + assert_eq!( + separated.require_instance(&slug(declared)).err(), + Some(MindRefusal::ForeignInstance { declared: declared.into(), mind: OTHER_INSTANCE.into() }), + "{declared} is not {OTHER_INSTANCE}" + ); + } } #[test]