-
Notifications
You must be signed in to change notification settings - Fork 0
feat(method): refuse non-lexical modality as unique content #150
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
198409d
86ab414
29da41b
2e9cf6c
00deb56
f9110e0
15518e0
cef63ce
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📝 Info: New crate satisfies workspace contract checks The new Was this helpful? React with 👍 or 👎 to provide feedback. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| [package] | ||
| name = "modality_source" | ||
| description = "Non-lexical modality is not unique content and not stopword deletion." | ||
| version.workspace = true | ||
| edition.workspace = true | ||
| rust-version.workspace = true | ||
| license.workspace = true | ||
| authors.workspace = true | ||
| repository.workspace = true | ||
| homepage.workspace = true | ||
| readme.workspace = true | ||
| keywords.workspace = true | ||
| categories.workspace = true | ||
| publish = false | ||
|
|
||
| [lints] | ||
| workspace = true |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| //! Fail-closed modality-source errors. | ||
|
|
||
| use std::fmt; | ||
|
|
||
| /// A fail-closed modality-source error. | ||
| #[derive(Clone, Copy, Debug, Eq, PartialEq)] | ||
| #[non_exhaustive] | ||
| pub enum ModalitySourceError { | ||
| /// Non-lexical modality was treated as unique latent content. | ||
| ModalityIsNotUniqueContent, | ||
| /// Non-lexical modality was treated as stopword deletion. | ||
| ModalityIsNotStopwordDeletion, | ||
| /// A recovery slice was empty or length-mismatched. | ||
| InvalidModalityPayload, | ||
| } | ||
|
|
||
| impl fmt::Display for ModalitySourceError { | ||
| fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
| let message = match self { | ||
| Self::ModalityIsNotUniqueContent => "non-lexical modality is not unique latent content", | ||
| Self::ModalityIsNotStopwordDeletion => "non-lexical modality is not stopword deletion", | ||
| Self::InvalidModalityPayload => "invalid modality-source payload", | ||
| }; | ||
| formatter.write_str(message) | ||
| } | ||
| } | ||
|
|
||
| impl std::error::Error for ModalitySourceError {} | ||
|
|
||
| #[cfg(test)] | ||
| mod tests { | ||
| use super::ModalitySourceError; | ||
|
|
||
| #[test] | ||
| fn error_messages_are_stable() { | ||
| for (error, message) in [ | ||
| ( | ||
| ModalitySourceError::ModalityIsNotUniqueContent, | ||
| "non-lexical modality is not unique latent content", | ||
| ), | ||
| ( | ||
| ModalitySourceError::ModalityIsNotStopwordDeletion, | ||
| "non-lexical modality is not stopword deletion", | ||
| ), | ||
| ( | ||
| ModalitySourceError::InvalidModalityPayload, | ||
| "invalid modality-source payload", | ||
| ), | ||
| ] { | ||
| assert_eq!(error.to_string(), message); | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,135 @@ | ||
| //! Non-lexical modality versus unique latent content. | ||
|
|
||
| use crate::ModalitySourceError; | ||
|
|
||
| /// Closed vocabulary of modality-related token treatments. | ||
| #[derive(Clone, Copy, Debug, Eq, PartialEq)] | ||
| pub enum ModalityKind { | ||
| /// Non-lexical modality channel, not unique document meaning. | ||
| NonLexicalModality, | ||
| /// Token treatment reserved for unique latent content. | ||
| UniqueContent, | ||
| } | ||
|
|
||
| impl ModalityKind { | ||
| /// Return the stable wire kind name. | ||
| #[must_use] | ||
| pub const fn wire_name(self) -> &'static str { | ||
| match self { | ||
| Self::NonLexicalModality => "modality", | ||
| Self::UniqueContent => "unique_content", | ||
| } | ||
| } | ||
|
|
||
| /// Parse a stable wire kind name. | ||
| /// | ||
| /// # Errors | ||
| /// | ||
| /// Returns [`ModalitySourceError::InvalidModalityPayload`] for unrecognized | ||
| /// names. | ||
| pub fn from_wire_name(name: &str) -> Result<Self, ModalitySourceError> { | ||
| match name { | ||
| "modality" => Ok(Self::NonLexicalModality), | ||
| "unique_content" => Ok(Self::UniqueContent), | ||
| _ => Err(ModalitySourceError::InvalidModalityPayload), | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /// Refuse to treat non-lexical modality as unique latent content. | ||
| /// | ||
| /// # Errors | ||
| /// | ||
| /// Returns [`ModalitySourceError::ModalityIsNotUniqueContent`] when `kind` is | ||
| /// [`ModalityKind::NonLexicalModality`]. | ||
| pub fn refuse_modality_as_unique_content(kind: ModalityKind) -> Result<(), ModalitySourceError> { | ||
| match kind { | ||
| ModalityKind::NonLexicalModality => Err(ModalitySourceError::ModalityIsNotUniqueContent), | ||
| ModalityKind::UniqueContent => Ok(()), | ||
| } | ||
| } | ||
|
|
||
| /// Refuse to treat non-lexical modality as stopword deletion. | ||
| /// | ||
| /// # Errors | ||
| /// | ||
| /// Returns [`ModalitySourceError::ModalityIsNotStopwordDeletion`] when `kind` | ||
| /// is [`ModalityKind::NonLexicalModality`]. | ||
| pub fn refuse_modality_as_stopword_deletion(kind: ModalityKind) -> Result<(), ModalitySourceError> { | ||
| match kind { | ||
| ModalityKind::NonLexicalModality => Err(ModalitySourceError::ModalityIsNotStopwordDeletion), | ||
| ModalityKind::UniqueContent => Ok(()), | ||
| } | ||
| } | ||
|
|
||
| /// Fraction of recovered modality kinds that match known truth. | ||
| /// | ||
| /// # Errors | ||
| /// | ||
| /// Returns [`ModalitySourceError::InvalidModalityPayload`] when either slice | ||
| /// is empty or the lengths differ. | ||
| pub fn identity_recovery_rate( | ||
| truth: &[ModalityKind], | ||
| decided: &[ModalityKind], | ||
| ) -> Result<f64, ModalitySourceError> { | ||
| if truth.is_empty() || truth.len() != decided.len() { | ||
| return Err(ModalitySourceError::InvalidModalityPayload); | ||
| } | ||
| let mut matches = 0_u32; | ||
| for (truth_kind, decided_kind) in truth.iter().zip(decided) { | ||
| if truth_kind == decided_kind { | ||
| matches += 1; | ||
| } | ||
| } | ||
| Ok(f64::from(matches) / truth.len() as f64) | ||
|
Comment on lines
+78
to
+84
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📝 Info: Branch coverage relies on integration tests, not unit tests alone The 100% branch-coverage contract (AGENTS.md #8) requires both branches of Was this helpful? React with 👍 or 👎 to provide feedback. |
||
| } | ||
|
Comment on lines
+71
to
+85
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📝 Info: identity_recovery_rate fail-closed and arithmetic verified
Was this helpful? React with 👍 or 👎 to provide feedback. |
||
|
|
||
| #[cfg(test)] | ||
| mod tests { | ||
| use super::{ | ||
| ModalityKind, identity_recovery_rate, refuse_modality_as_stopword_deletion, | ||
| refuse_modality_as_unique_content, | ||
| }; | ||
| use crate::ModalitySourceError; | ||
|
|
||
| #[test] | ||
| fn local_branches_cover_kinds_payloads_and_wire_names() { | ||
| assert_eq!( | ||
| refuse_modality_as_unique_content(ModalityKind::NonLexicalModality), | ||
| Err(ModalitySourceError::ModalityIsNotUniqueContent) | ||
| ); | ||
| assert_eq!( | ||
| refuse_modality_as_stopword_deletion(ModalityKind::NonLexicalModality), | ||
| Err(ModalitySourceError::ModalityIsNotStopwordDeletion) | ||
| ); | ||
| refuse_modality_as_unique_content(ModalityKind::UniqueContent).expect("unique"); | ||
| refuse_modality_as_stopword_deletion(ModalityKind::UniqueContent).expect("unique"); | ||
| for kind in [ | ||
| ModalityKind::NonLexicalModality, | ||
| ModalityKind::UniqueContent, | ||
| ] { | ||
| assert_eq!( | ||
| ModalityKind::from_wire_name(kind.wire_name()).expect("round-trip"), | ||
| kind | ||
| ); | ||
| } | ||
| assert_eq!( | ||
| ModalityKind::from_wire_name("stopword"), | ||
| Err(ModalitySourceError::InvalidModalityPayload) | ||
| ); | ||
| let matched = identity_recovery_rate( | ||
| &[ModalityKind::NonLexicalModality], | ||
| &[ModalityKind::NonLexicalModality], | ||
| ) | ||
| .expect("rate"); | ||
| assert!((matched - 1.0).abs() < f64::EPSILON); | ||
| assert_eq!( | ||
| identity_recovery_rate(&[], &[]), | ||
| Err(ModalitySourceError::InvalidModalityPayload) | ||
| ); | ||
| assert_eq!( | ||
| identity_recovery_rate(&[ModalityKind::NonLexicalModality], &[]), | ||
| Err(ModalitySourceError::InvalidModalityPayload) | ||
| ); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| #![forbid(unsafe_code)] | ||
| #![deny(missing_docs)] | ||
| #![allow(clippy::cast_precision_loss)] | ||
| //! Non-lexical modality is not unique latent content. | ||
| //! | ||
| //! Modality channels stay explicit method/background structure. They are | ||
| //! not unique document meaning and are not erased by a stopword list | ||
| //! (ADR 0004/0012). | ||
|
|
||
| mod error; | ||
| mod kind; | ||
|
|
||
| /// Fail-closed modality-source errors. | ||
| pub use error::ModalitySourceError; | ||
| /// Closed vocabulary of modality-related token treatments. | ||
| pub use kind::ModalityKind; | ||
| /// Fraction of recovered modality kinds that match known truth. | ||
| pub use kind::identity_recovery_rate; | ||
| /// Refuse to treat non-lexical modality as stopword deletion. | ||
| pub use kind::refuse_modality_as_stopword_deletion; | ||
| /// Refuse to treat non-lexical modality as unique latent content. | ||
| pub use kind::refuse_modality_as_unique_content; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| //! Integration contract for the `modality_source` package identity. | ||
|
|
||
| #[test] | ||
| fn package_identity_is_stable() { | ||
| let observed = std::hint::black_box(env!("CARGO_PKG_NAME")); | ||
| assert_eq!(observed, "modality_source"); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| //! Non-lexical modality is not unique content and not stopword deletion. | ||
|
|
||
| use modality_source::{ | ||
| ModalityKind, ModalitySourceError, identity_recovery_rate, | ||
| refuse_modality_as_stopword_deletion, refuse_modality_as_unique_content, | ||
| }; | ||
|
|
||
| #[test] | ||
| fn non_lexical_modality_cannot_become_unique_content_or_stopword_deletion() { | ||
| assert_eq!( | ||
| refuse_modality_as_unique_content(ModalityKind::NonLexicalModality), | ||
| Err(ModalitySourceError::ModalityIsNotUniqueContent) | ||
| ); | ||
| assert_eq!( | ||
| refuse_modality_as_stopword_deletion(ModalityKind::NonLexicalModality), | ||
| Err(ModalitySourceError::ModalityIsNotStopwordDeletion) | ||
| ); | ||
| refuse_modality_as_unique_content(ModalityKind::UniqueContent).expect("unique"); | ||
| refuse_modality_as_stopword_deletion(ModalityKind::UniqueContent).expect("unique"); | ||
| } | ||
|
|
||
| #[test] | ||
| fn recovered_kinds_match_known_truth_better_than_a_unique_content_collapse() { | ||
| let truth = [ | ||
| ModalityKind::NonLexicalModality, | ||
| ModalityKind::UniqueContent, | ||
| ModalityKind::NonLexicalModality, | ||
| ]; | ||
| let recovered = truth; | ||
| let collapsed = [ | ||
| ModalityKind::UniqueContent, | ||
| ModalityKind::UniqueContent, | ||
| ModalityKind::UniqueContent, | ||
| ]; | ||
| let recovered_rate = identity_recovery_rate(&truth, &recovered).expect("recovered"); | ||
| let collapsed_rate = identity_recovery_rate(&truth, &collapsed).expect("collapsed"); | ||
| let expected = { | ||
| let mut matches = 0_u32; | ||
| for (truth_kind, decided_kind) in truth.iter().zip(recovered.iter()) { | ||
| if truth_kind == decided_kind { | ||
| matches += 1; | ||
| } | ||
| } | ||
| f64::from(matches) / f64::from(u32::try_from(truth.len()).expect("len")) | ||
| }; | ||
| assert!((recovered_rate - expected).abs() < f64::EPSILON); | ||
| assert!(recovered_rate > collapsed_rate); | ||
| } | ||
|
|
||
| #[test] | ||
| fn empty_or_mismatched_kind_payloads_fail_closed() { | ||
| assert_eq!( | ||
| identity_recovery_rate(&[], &[]), | ||
| Err(ModalitySourceError::InvalidModalityPayload) | ||
| ); | ||
| assert_eq!( | ||
| identity_recovery_rate(&[ModalityKind::NonLexicalModality], &[]), | ||
| Err(ModalitySourceError::InvalidModalityPayload) | ||
| ); | ||
| assert_eq!( | ||
| identity_recovery_rate( | ||
| &[ | ||
| ModalityKind::NonLexicalModality, | ||
| ModalityKind::UniqueContent | ||
| ], | ||
| &[ModalityKind::NonLexicalModality] | ||
| ), | ||
| Err(ModalitySourceError::InvalidModalityPayload) | ||
| ); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
📝 Info: Historical changelog line still says 'ten' crates
CHANGELOG.md still reads "Rust 1.97.1 virtual Cargo workspace with ten explicit modular foundation crates." while README.md was updated to "eleven". This CHANGELOG line is a historical Task-1
Addedentry describing the original ten-crate foundation, so leaving it unchanged is arguably faithful to what was originally added rather than a defect. No test or contract script asserts a crate count against this text, so it does not break CI. Flagging only for editorial consistency consideration.(Refers to this code)
Was this helpful? React with 👍 or 👎 to provide feedback.