Merge eureka-substrate/mind-authority: RulingAuthority gains Mind; the query alias list derives from the enum
Soul s1 holds (eureka-substrate:verdict:cut-mind-authority.s1). Additive on the wire; the live upgrade must be daemon-first (follow-up mind-variant-daemon-first). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
commit
1686cc5491
8 changed files with 75 additions and 7 deletions
|
|
@ -38,3 +38,4 @@ verdict.claim-unproven-promise-none eureka-state:verdict:cut-3a.s2 epiphany.pipe
|
|||
finding.plausible-blocker-preexisting-kinds eureka-state:finding:cut-3a.s2.F4 epiphany.pipeline.finding.v2 EpiphanyPipelineFindingDocument 918da863616d706169676eac657572656b612d7374617465a776657264696374be657572656b612d73746174653a766572646963743a6375742d33612e7332a56c6162656ca24634a572616e676582a462617365a83566393832323864a468656164a83566393832323864aa636f6e666964656e6365a9506c61757369626c65a87365766572697479a7426c6f636b6572a5636c61696dd9214120646f74746564206c6162656c20636f6d706f7365732074776f206b6579732eaa696e76617269616e747391ab6d696e642d61646d697473a96c6f636174696f6e739183a470617468d9216372617465732f657572656b612d706970656c696e652f7372632f6c69622e7273a46c696e6501a8656e645f6c696e65c0b06661696c7572655f7363656e6172696fbc54776f20646f63756d656e747320636c61696d206f6e65206b65792ea865766964656e63659583a46b696e64a7436f6d6d616e64a76c6f6361746f72a178a6726573756c74a17983a46b696e64a84d75746174696f6ea76c6f6361746f72a178a6726573756c74a17983a46b696e64a550726f6265a76c6f6361746f72a178a6726573756c74a17983a46b696e64aa536f7572636552656164a76c6f6361746f72a178a6726573756c74a17983a46b696e64a743617074757265a76c6f6361746f72a178a6726573756c74a179aa707265636564656e747390a66f726967696eab5072654578697374696e67
|
||||
finding.severity-medium eureka-state:finding:cut-3a.s2.F4 epiphany.pipeline.finding.v2 EpiphanyPipelineFindingDocument 918da863616d706169676eac657572656b612d7374617465a776657264696374be657572656b612d73746174653a766572646963743a6375742d33612e7332a56c6162656ca24634a572616e676582a462617365a83566393832323864a468656164a83566393832323864aa636f6e666964656e6365a9436f6e6669726d6564a87365766572697479a64d656469756da5636c61696dd9214120646f74746564206c6162656c20636f6d706f7365732074776f206b6579732eaa696e76617269616e747391ab6d696e642d61646d697473a96c6f636174696f6e739183a470617468d9216372617465732f657572656b612d706970656c696e652f7372632f6c69622e7273a46c696e6501a8656e645f6c696e6509b06661696c7572655f7363656e6172696fbc54776f20646f63756d656e747320636c61696d206f6e65206b65792ea865766964656e63659183a46b696e64a454657374a76c6f6361746f72aa636172676f2074657374a6726573756c74a26f6baa707265636564656e747390a66f726967696eaa496e74726f6475636564
|
||||
finding.severity-low eureka-state:finding:cut-3a.s2.F4 epiphany.pipeline.finding.v2 EpiphanyPipelineFindingDocument 918da863616d706169676eac657572656b612d7374617465a776657264696374be657572656b612d73746174653a766572646963743a6375742d33612e7332a56c6162656ca24634a572616e676582a462617365a83566393832323864a468656164a83566393832323864aa636f6e666964656e6365a9436f6e6669726d6564a87365766572697479a34c6f77a5636c61696dd9214120646f74746564206c6162656c20636f6d706f7365732074776f206b6579732eaa696e76617269616e747391ab6d696e642d61646d697473a96c6f636174696f6e739183a470617468d9216372617465732f657572656b612d706970656c696e652f7372632f6c69622e7273a46c696e6501a8656e645f6c696e6509b06661696c7572655f7363656e6172696fbc54776f20646f63756d656e747320636c61696d206f6e65206b65792ea865766964656e63659183a46b696e64a454657374a76c6f6361746f72aa636172676f2074657374a6726573756c74a26f6baa707265636564656e747390a66f726967696eaa496e74726f6475636564
|
||||
ruling.authority-mind eureka-state:ruling:R8 epiphany.pipeline.ruling.v2 EpiphanyPipelineRulingDocument 918aa863616d706169676eac657572656b612d7374617465a56c6162656ca25238a57469746c65b9416e20696e7374616e6365206f776e7320697473206d696e64a7616e7377657273c0a663686f696365c0a672756c696e67ba416e20696e7374616e6365206f776e7320697473206d696e642eae6f70657261746f725f71756f7465c0a872756c65645f6f6eaa323032362d30392d3135aa707265636564656e74739185a47265706fb147616d6543756c742f4165746865726961a6636f6d6d6974d92861616161616161616161616161616161616161616161616161616161616161616161616161616161a46b696e64a652756c696e67a26964b363756c7463616368653a72756c696e673a5231ae7061796c6f61645f736861323536d94062626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262626262a9617574686f72697479a44d696e64
|
||||
|
|
|
|||
|
|
@ -439,6 +439,11 @@ macro_rules! unit_enums {
|
|||
($($name:ident { $($variant:ident),* $(,)? })*) => {$(
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, JsonSchema)]
|
||||
pub enum $name { $($variant),* }
|
||||
impl $name {
|
||||
/// The variants' spellings, in declaration order: the names the wire and
|
||||
/// `Debug` use.
|
||||
pub const NAMES: &'static [&'static str] = &[$(stringify!($variant)),*];
|
||||
}
|
||||
impl Bounded for $name {
|
||||
fn validate(&self, _field: &str) -> Result<(), PipelineRefusal> {
|
||||
Ok(())
|
||||
|
|
@ -472,7 +477,7 @@ unit_enums! {
|
|||
ClaimOutcome { Holds, Falsified, Unproven }
|
||||
FindingConfidence { Confirmed, Plausible }
|
||||
FindingSeverity { Blocker, High, Medium, Low }
|
||||
RulingAuthority { Operator, Standing, Defaulted }
|
||||
RulingAuthority { Operator, Standing, Defaulted, Mind }
|
||||
FindingOrigin { Introduced, PreExisting }
|
||||
}
|
||||
|
||||
|
|
@ -1269,6 +1274,39 @@ mod tests {
|
|||
ruling
|
||||
}
|
||||
|
||||
/// A ruling the Mind's own Self made: authority Mind, no operator quote,
|
||||
/// no question answered. Built from the ruling sample, not inserted into
|
||||
/// `samples()`, whose tests pick kinds by index.
|
||||
fn mind_ruling() -> PipelineRuling {
|
||||
let mut ruling = ruling_sample();
|
||||
(ruling.authority, ruling.operator_quote, ruling.answers, ruling.choice) = (RulingAuthority::Mind, None, None, None);
|
||||
ruling
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_ruling_with_authority_mind_keys_encodes_and_round_trips_like_any_ruling() -> Result<()> {
|
||||
let cache = schema_cache()?;
|
||||
let document = PipelineDocument::Ruling(mind_ruling());
|
||||
document.validate()?;
|
||||
let envelope = document.prepare(&cache)?;
|
||||
assert!(envelope.key.starts_with("eureka-state:ruling:"), "{}", envelope.key);
|
||||
assert_eq!(PipelineDocument::decode(&envelope)?, document);
|
||||
let json = serde_json::to_value(&document)?;
|
||||
assert_eq!(json["value"]["authority"], "Mind");
|
||||
assert_eq!(serde_json::from_value::<PipelineDocument>(json)?, document);
|
||||
let packed = rmp_serde::to_vec_named(&document)?;
|
||||
assert_eq!(rmp_serde::from_slice::<PipelineDocument>(&packed)?, document);
|
||||
let standing = PipelineDocument::Ruling(ruling_sample());
|
||||
assert_ne!(standing.prepare(&cache)?.payload, envelope.payload, "Mind is not a spelling of another authority");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unit_enum_names_are_the_variants_in_declaration_order() {
|
||||
assert_eq!(RulingAuthority::NAMES, ["Operator", "Standing", "Defaulted", "Mind"]);
|
||||
assert_eq!(FindingOrigin::NAMES, ["Introduced", "PreExisting"]);
|
||||
}
|
||||
|
||||
fn report_sample() -> PipelineCutReport {
|
||||
let PipelineDocument::CutReport(report) = samples().remove(5).0 else { unreachable!() };
|
||||
report
|
||||
|
|
@ -1340,6 +1378,7 @@ mod tests {
|
|||
f.severity = severity;
|
||||
out.push((format!("finding.severity-{name}"), D::Finding(f)));
|
||||
}
|
||||
out.push(("ruling.authority-mind".into(), D::Ruling(mind_ruling())));
|
||||
out
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1859,10 +1859,21 @@ mod tests {
|
|||
let mut quoted = ruling("R1");
|
||||
quoted.operator_quote = Some("all recommendations, go ahead".into());
|
||||
assert_eq!(refusal(admit(&mut mind, vec![D::Ruling(quoted.clone())])), MindRefusal::QuoteWithoutOperator { ruling: id("ruling", "R1") });
|
||||
quoted.authority = RulingAuthority::Mind;
|
||||
assert_eq!(refusal(admit(&mut mind, vec![D::Ruling(quoted.clone())])), MindRefusal::QuoteWithoutOperator { ruling: id("ruling", "R1") });
|
||||
assert!(mind.get(K::Ruling, &id("ruling", "R1")).unwrap().is_none(), "a refused batch leaves the store unchanged");
|
||||
quoted.authority = RulingAuthority::Operator;
|
||||
committed(admit(&mut mind, vec![D::Ruling(quoted)]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_mind_ruling_without_a_quote_is_admitted() {
|
||||
let mut mind = seeded();
|
||||
let mut own = ruling("R1");
|
||||
own.authority = RulingAuthority::Mind;
|
||||
committed(admit(&mut mind, vec![D::Ruling(own)]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_revision_requires_its_predecessors_supersession_in_the_batch() {
|
||||
let mut mind = seeded();
|
||||
|
|
|
|||
|
|
@ -1219,6 +1219,21 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
/// The alias domain and the enum agree: a Mind-authority ruling is
|
||||
/// selectable by its own word, and only by it.
|
||||
#[test]
|
||||
fn a_query_for_mind_authority_is_answered() {
|
||||
let mut mind = seeded();
|
||||
let mut own = ruling("R1");
|
||||
own.authority = RulingAuthority::Mind;
|
||||
committed(admit(&mut mind, vec![D::Ruling(own), D::Ruling(ruling("R2"))]));
|
||||
let by = |word: &str| mind.query(&with(of_kinds(&[K::Ruling]), any_of("authority", &[word]))).unwrap();
|
||||
assert_eq!(by("Mind").matched, 1);
|
||||
assert_eq!(by("Standing").matched, 1);
|
||||
let misspelt = with(of_kinds(&[K::Ruling]), any_of("authority", &["Minds"]));
|
||||
assert!(matches!(refused(&mind, &misspelt), MindRefusal::SelectionInvalid { value: Some(v), .. } if v == "Minds"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn an_unknown_schema_or_malformed_key_is_refused() {
|
||||
let mind = worked();
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
use std::collections::BTreeMap;
|
||||
|
||||
use cultnet_rs::{Row, RowSet, Selection};
|
||||
use eureka_pipeline::{OrgRepo, Label, PipelineDocument, PipelineKind, PipelineRef, ResolutionOutcome, Slug};
|
||||
use eureka_pipeline::{OrgRepo, Label, PipelineDocument, PipelineKind, PipelineRef, ResolutionOutcome, RulingAuthority, Slug};
|
||||
|
||||
use crate::docs::{CitationRole, Held, kind_of_id, kind_of_type};
|
||||
use crate::query::PipelineDocumentView;
|
||||
|
|
@ -43,7 +43,6 @@ const FACULTIES: [&str; 7] = ["SelfFaculty", "Imagination", "Hands", "Soul", "Li
|
|||
const SEVERITIES: [&str; 4] = ["Blocker", "High", "Medium", "Low"];
|
||||
const CONFIDENCES: [&str; 2] = ["Confirmed", "Plausible"];
|
||||
const ORIGINS: [&str; 2] = ["Introduced", "PreExisting"];
|
||||
const AUTHORITIES: [&str; 3] = ["Operator", "Standing", "Defaulted"];
|
||||
const CLAIM_OUTCOMES: [&str; 3] = ["Holds", "Falsified", "Unproven"];
|
||||
const OUTCOMES: [&str; 6] = ["Superseded", "Answered", "Fixed", "Deferred", "Recorded", "Withdrawn"];
|
||||
const BOOLEANS: [&str; 2] = ["true", "false"];
|
||||
|
|
@ -106,7 +105,7 @@ impl Alias {
|
|||
Self::Severity => Some(&SEVERITIES),
|
||||
Self::Confidence => Some(&CONFIDENCES),
|
||||
Self::Origin => Some(&ORIGINS),
|
||||
Self::Authority => Some(&AUTHORITIES),
|
||||
Self::Authority => Some(RulingAuthority::NAMES),
|
||||
Self::ClaimOutcome => Some(&CLAIM_OUTCOMES),
|
||||
Self::Outcome => Some(&OUTCOMES),
|
||||
Self::Root | Self::Repo | Self::Cut => None,
|
||||
|
|
|
|||
|
|
@ -75,7 +75,8 @@
|
|||
"enum": [
|
||||
"Operator",
|
||||
"Standing",
|
||||
"Defaulted"
|
||||
"Defaulted",
|
||||
"Mind"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1674,7 +1674,8 @@
|
|||
"enum": [
|
||||
"Operator",
|
||||
"Standing",
|
||||
"Defaulted"
|
||||
"Defaulted",
|
||||
"Mind"
|
||||
]
|
||||
},
|
||||
"SemanticQuery": {
|
||||
|
|
|
|||
|
|
@ -3702,7 +3702,8 @@
|
|||
"enum": [
|
||||
"Operator",
|
||||
"Standing",
|
||||
"Defaulted"
|
||||
"Defaulted",
|
||||
"Mind"
|
||||
]
|
||||
},
|
||||
"Sha": {
|
||||
|
|
|
|||
Loading…
Reference in a new issue