BP-2: move Huginn to CultLib 6251cbc and the RS-L leaf 4891f2e5
One pin move: huginn-mind pins cultcache-rs at 6251cbc and the leaf at 4891f2e5; huginn-daemon pins cultnet-rs at 6251cbc. cargo tree shows one cultcache-rs and one cultnet-rs per crate. Adopting RS-L, which the new leaf carries: - Campaign, cut-spec, question and ruling fixtures carry a Title; the question and ruling fixtures gain the new required title field. - The epoch literals in daemon and envelope tests move v1 -> v2. A store written at an earlier epoch is refused at open (ForeignEpoch); no key migration. - Derived stewardship, hand-off and resolution keys are now the lowercased OrgRepo::identity(); test key literals follow. - The two published wire schemas are regenerated (Title, OrgRepo bound and description); the byte-for-byte pin test passes. CultLib 6251cbc gives CultNetMessage::Error code and details; the four construction sites and one pattern in huginn-daemon take None and `..`. No behaviour change: None is skipped on the wire. mind 70 and daemon 18 pass. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
8c5f784606
commit
e770fb9f21
11 changed files with 108 additions and 50 deletions
8
Cargo.lock
generated
8
Cargo.lock
generated
|
|
@ -175,7 +175,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "cultcache-rs"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/GameCult/CultLib.git?rev=a0813c6eed24d30bf88073ef615b633c77ebfcd6#a0813c6eed24d30bf88073ef615b633c77ebfcd6"
|
||||
source = "git+https://github.com/GameCult/CultLib.git?rev=6251cbcd37c12ef3f0c1cc50063a03369225b7ac#6251cbcd37c12ef3f0c1cc50063a03369225b7ac"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"chrono",
|
||||
|
|
@ -193,7 +193,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "cultcache-rs-derive"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/GameCult/CultLib.git?rev=a0813c6eed24d30bf88073ef615b633c77ebfcd6#a0813c6eed24d30bf88073ef615b633c77ebfcd6"
|
||||
source = "git+https://github.com/GameCult/CultLib.git?rev=6251cbcd37c12ef3f0c1cc50063a03369225b7ac#6251cbcd37c12ef3f0c1cc50063a03369225b7ac"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
@ -203,7 +203,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "cultnet-rs"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/GameCult/CultLib.git?rev=a0813c6eed24d30bf88073ef615b633c77ebfcd6#a0813c6eed24d30bf88073ef615b633c77ebfcd6"
|
||||
source = "git+https://github.com/GameCult/CultLib.git?rev=6251cbcd37c12ef3f0c1cc50063a03369225b7ac#6251cbcd37c12ef3f0c1cc50063a03369225b7ac"
|
||||
dependencies = [
|
||||
"aes-gcm",
|
||||
"anyhow",
|
||||
|
|
@ -306,7 +306,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "epiphany-pipeline"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/GameCult/Epiphany.git?rev=b3ae787b7dc13e3677bd6f7d6b3867542a32f5c5#b3ae787b7dc13e3677bd6f7d6b3867542a32f5c5"
|
||||
source = "git+https://github.com/GameCult/Epiphany.git?rev=4891f2e59008efeb262197564eddaa75bc3c75ea#4891f2e59008efeb262197564eddaa75bc3c75ea"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"chrono",
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ path = "src/main.rs"
|
|||
anyhow = "1"
|
||||
base64 = "0.22"
|
||||
chrono = "0.4.44"
|
||||
cultnet-rs = { git = "https://github.com/GameCult/CultLib.git", rev = "a0813c6eed24d30bf88073ef615b633c77ebfcd6", package = "cultnet-rs" }
|
||||
cultnet-rs = { git = "https://github.com/GameCult/CultLib.git", rev = "6251cbcd37c12ef3f0c1cc50063a03369225b7ac", package = "cultnet-rs" }
|
||||
huginn-mind = { path = "../huginn-mind" }
|
||||
rmp-serde = "1"
|
||||
schemars = "1"
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ pub(crate) mod tests {
|
|||
AuthorityMap, CodeLocation, CutDelete, CutVerification, Date, DocRef, FileChange, Line, NegativeCheck,
|
||||
OrgRepo, PipelineCampaign, PipelineCutSpec, PipelineDocument, PipelineInstance, PipelineKind,
|
||||
PipelineQuestion, PipelineRuling, PipelineStewardship, QuestionOption, RulingAuthority, Sha, Short,
|
||||
StructuralDelta, VerificationTest,
|
||||
StructuralDelta, Title, VerificationTest,
|
||||
};
|
||||
use huginn_mind::wire::MindStatus;
|
||||
use huginn_mind::{Faculty, PipelineAdmissionBatch, PipelineProvenance, PipelineQuery, PipelineStatus, SemanticQuery};
|
||||
|
|
@ -154,6 +154,7 @@ pub(crate) mod tests {
|
|||
let question = PipelineDocument::Question(PipelineQuestion {
|
||||
campaign: slug(CAMPAIGN),
|
||||
label: "Q1".into(),
|
||||
title: Title("Who owns the state?".into()),
|
||||
question: "Who owns the state?".into(),
|
||||
options: vec![
|
||||
QuestionOption { label: "A".into(), text: "the organ".into() },
|
||||
|
|
@ -167,6 +168,7 @@ pub(crate) mod tests {
|
|||
let ruling = PipelineDocument::Ruling(PipelineRuling {
|
||||
campaign: slug(CAMPAIGN),
|
||||
label: "R1".into(),
|
||||
title: Title("An instance owns its mind".into()),
|
||||
answers: Some(Short(format!("{CAMPAIGN}:question:Q1"))),
|
||||
choice: Some("A".into()),
|
||||
ruling: "An instance owns its mind.".into(),
|
||||
|
|
@ -213,7 +215,7 @@ pub(crate) mod tests {
|
|||
}),
|
||||
PipelineDocument::Campaign(PipelineCampaign {
|
||||
slug: slug(CAMPAIGN),
|
||||
title: Short("Eureka pipeline state".into()),
|
||||
title: Title("Eureka pipeline state".into()),
|
||||
repos: vec![OrgRepo(REPO.into())],
|
||||
working_branch: Short("codex/eureka-pipeline-state".into()),
|
||||
target_doc: doc_ref(),
|
||||
|
|
@ -237,7 +239,7 @@ pub(crate) mod tests {
|
|||
campaign: slug(CAMPAIGN),
|
||||
cut: cut.into(),
|
||||
revision: 1,
|
||||
title: short(0),
|
||||
title: Title(short(0).0),
|
||||
repo: OrgRepo(REPO.into()),
|
||||
branch: short(1),
|
||||
base: sha(),
|
||||
|
|
@ -366,7 +368,7 @@ pub(crate) mod tests {
|
|||
status(&mut daemon),
|
||||
MindStatus {
|
||||
instance: slug(INSTANCE),
|
||||
schema_epoch: "epiphany.pipeline.epoch.v1".into(),
|
||||
schema_epoch: "epiphany.pipeline.epoch.v2".into(),
|
||||
documents: 1,
|
||||
receipts: 1,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -180,7 +180,7 @@ mod tests {
|
|||
(
|
||||
HuginnMindResponse::Whoami(MindStatus {
|
||||
instance: slug(INSTANCE),
|
||||
schema_epoch: "epiphany.pipeline.epoch.v1".into(),
|
||||
schema_epoch: "epiphany.pipeline.epoch.v2".into(),
|
||||
documents: 0,
|
||||
receipts: 0,
|
||||
}),
|
||||
|
|
@ -217,7 +217,7 @@ mod tests {
|
|||
let message = encode_request("m-3", &request, Some("eureka-state".into())).unwrap();
|
||||
assert_eq!(decode_request(&message).unwrap(), ("m-3".into(), request));
|
||||
|
||||
let foreign = CultNetMessage::Error { error: "not for you".into() };
|
||||
let foreign = CultNetMessage::Error { error: "not for you".into(), code: None, details: None };
|
||||
assert_eq!(decode_request(&foreign).unwrap_err().code, "not-an-operation-request");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -183,12 +183,14 @@ pub fn answer<S: MindStore, I: IndexSink<S>>(
|
|||
},
|
||||
CultNetMessage::SchemaCatalogRequest { .. } => match registry.create_catalog_response(&message) {
|
||||
Ok(response) => response,
|
||||
Err(error) => CultNetMessage::Error { error: format!("{error:#}") },
|
||||
Err(error) => CultNetMessage::Error { error: format!("{error:#}"), code: None, details: None },
|
||||
},
|
||||
_ => CultNetMessage::Error {
|
||||
error: format!(
|
||||
"{MIND_SERVICE_ID} answers cultnet.operation_request.v0 and cultnet.schema_catalog_request.v0"
|
||||
),
|
||||
code: None,
|
||||
details: None,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
@ -395,8 +397,8 @@ mod tests {
|
|||
// The sixth code, `not-an-operation-request`, is the codec's and is
|
||||
// pinned in `envelope::tests`: `answer` never produces it, because a
|
||||
// message of another family is answered with `Error` instead.
|
||||
let reply = answer(&mut daemon, ®istry, CultNetMessage::Error { error: "hello".into() }, now());
|
||||
let CultNetMessage::Error { error } = &reply else { panic!("expected an error, got {reply:?}") };
|
||||
let reply = answer(&mut daemon, ®istry, CultNetMessage::Error { error: "hello".into(), code: None, details: None }, now());
|
||||
let CultNetMessage::Error { error, .. } = &reply else { panic!("expected an error, got {reply:?}") };
|
||||
assert!(
|
||||
!error.is_empty() && error.contains("cultnet.operation_request.v0") && error.contains("cultnet.schema_catalog_request.v0"),
|
||||
"{error}"
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ publish.workspace = true
|
|||
[dependencies]
|
||||
anyhow = "1"
|
||||
chrono = "0.4.44"
|
||||
cultcache-rs = { git = "https://github.com/GameCult/CultLib.git", rev = "a0813c6eed24d30bf88073ef615b633c77ebfcd6", package = "cultcache-rs" }
|
||||
epiphany-pipeline = { git = "https://github.com/GameCult/Epiphany.git", rev = "b3ae787b7dc13e3677bd6f7d6b3867542a32f5c5", package = "epiphany-pipeline" }
|
||||
cultcache-rs = { git = "https://github.com/GameCult/CultLib.git", rev = "6251cbcd37c12ef3f0c1cc50063a03369225b7ac", package = "cultcache-rs" }
|
||||
epiphany-pipeline = { git = "https://github.com/GameCult/Epiphany.git", rev = "4891f2e59008efeb262197564eddaa75bc3c75ea", package = "epiphany-pipeline" }
|
||||
rmp-serde = "1"
|
||||
schemars = "1"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
|
|
|
|||
|
|
@ -758,7 +758,7 @@ mod tests {
|
|||
);
|
||||
committed(admit(&mut yggdrasil, vec![instance(INSTANCE), stewardship(INSTANCE, REPO)]));
|
||||
committed(admit(&mut thought_cage, vec![instance(OTHER_INSTANCE)]));
|
||||
let key = format!("{INSTANCE}:stewardship:GameCult_-Epiphany.n1");
|
||||
let key = format!("{INSTANCE}:stewardship:gamecult_-epiphany.n1");
|
||||
assert!(yggdrasil.envelope(K::Stewardship, &key).is_some());
|
||||
assert!(thought_cage.envelope(K::Stewardship, &key).is_none());
|
||||
assert_eq!(yggdrasil.envelopes().len(), 4);
|
||||
|
|
@ -1199,7 +1199,7 @@ mod tests {
|
|||
#[test]
|
||||
fn a_repo_is_stewarded_once_at_a_time_and_again_after_a_transfer() {
|
||||
let mut mind = seeded();
|
||||
let first = format!("{INSTANCE}:stewardship:GameCult_-Epiphany.n1");
|
||||
let first = format!("{INSTANCE}:stewardship:gamecult_-epiphany.n1");
|
||||
assert_eq!(
|
||||
refusal(admit(&mut mind, vec![stewardship_n(INSTANCE, REPO, 2)])),
|
||||
MindRefusal::AlreadyStewarded { repo: REPO.into() }
|
||||
|
|
@ -1215,10 +1215,10 @@ mod tests {
|
|||
// is a resolution of that record, sequence and all. The stewardship it
|
||||
// reads to derive that is an image document, so it is pinned.
|
||||
let (receipt_id, writes) = committed(admit(&mut mind, vec![hand_off(INSTANCE, OTHER_INSTANCE, REPO, &[])]));
|
||||
let away = format!("{INSTANCE}:hand_off:{OTHER_INSTANCE}.GameCult_-Epiphany.{}", date().0);
|
||||
let away = format!("{INSTANCE}:hand_off:{OTHER_INSTANCE}.gamecult_-epiphany.{}", date().0);
|
||||
assert_eq!(writes, vec![
|
||||
r(K::HandOff, &away),
|
||||
r(K::Resolution, &format!("{INSTANCE}:resolution:stewardship.GameCult_-Epiphany.n1.n1")),
|
||||
r(K::Resolution, &format!("{INSTANCE}:resolution:stewardship.gamecult_-epiphany.n1.n1")),
|
||||
]);
|
||||
let receipt = mind.receipts().unwrap().into_iter().find(|receipt| receipt.receipt_id == receipt_id).unwrap();
|
||||
let stewardship_envelope = mind.envelope(K::Stewardship, &first).unwrap().clone();
|
||||
|
|
@ -1242,9 +1242,9 @@ mod tests {
|
|||
let D::HandOff(mut back) = hand_off(OTHER_INSTANCE, INSTANCE, REPO, &[]) else { panic!() };
|
||||
back.handed_on = epiphany_pipeline::Date("2026-09-17".into());
|
||||
let (_, writes) = committed(admit(&mut mind, vec![D::HandOff(back)]));
|
||||
let again = format!("{INSTANCE}:stewardship:GameCult_-Epiphany.n2");
|
||||
let again = format!("{INSTANCE}:stewardship:gamecult_-epiphany.n2");
|
||||
assert_eq!(writes, vec![
|
||||
r(K::HandOff, &format!("{OTHER_INSTANCE}:hand_off:{INSTANCE}.GameCult_-Epiphany.2026-09-17")),
|
||||
r(K::HandOff, &format!("{OTHER_INSTANCE}:hand_off:{INSTANCE}.gamecult_-epiphany.2026-09-17")),
|
||||
r(K::Stewardship, &again),
|
||||
]);
|
||||
let Some(D::Stewardship(taken)) = mind.get(K::Stewardship, &again).unwrap() else { panic!() };
|
||||
|
|
@ -1264,9 +1264,9 @@ mod tests {
|
|||
let D::HandOff(mut back) = hand_off(OTHER_INSTANCE, INSTANCE, REPO, &[]) else { panic!() };
|
||||
back.handed_on = epiphany_pipeline::Date("2026-09-17".into());
|
||||
committed(admit(&mut mind, vec![D::HandOff(back)]));
|
||||
let first = format!("{INSTANCE}:stewardship:GameCult_-Epiphany.n1");
|
||||
let again = format!("{INSTANCE}:stewardship:GameCult_-Epiphany.n2");
|
||||
let withdrawal = format!("{INSTANCE}:resolution:stewardship.GameCult_-Epiphany.n1.n1");
|
||||
let first = format!("{INSTANCE}:stewardship:gamecult_-epiphany.n1");
|
||||
let again = format!("{INSTANCE}:stewardship:gamecult_-epiphany.n2");
|
||||
let withdrawal = format!("{INSTANCE}:resolution:stewardship.gamecult_-epiphany.n1.n1");
|
||||
assert_eq!(
|
||||
refusal(admit(&mut mind, vec![resolution(r(K::Resolution, &withdrawal), withdrawn())])),
|
||||
MindRefusal::WouldReinstateOverLater { subject: first, later: again.clone() }
|
||||
|
|
@ -1305,14 +1305,14 @@ mod tests {
|
|||
committed(admit(&mut mind, vec![hand_off(INSTANCE, OTHER_INSTANCE, REPO, &[])]));
|
||||
// Nothing later stands over the first assignment, so withdrawing the
|
||||
// withdrawal puts it back in force and the repo is this mind's again.
|
||||
let withdrawal = format!("{INSTANCE}:resolution:stewardship.GameCult_-Epiphany.n1.n1");
|
||||
let withdrawal = format!("{INSTANCE}:resolution:stewardship.gamecult_-epiphany.n1.n1");
|
||||
committed(admit(&mut mind, vec![resolution(r(K::Resolution, &withdrawal), withdrawn())]));
|
||||
let D::HandOff(mut again) = hand_off(INSTANCE, OTHER_INSTANCE, REPO, &[]) else { panic!() };
|
||||
again.handed_on = epiphany_pipeline::Date("2026-09-17".into());
|
||||
let (_, writes) = committed(admit(&mut mind, vec![D::HandOff(again)]));
|
||||
assert_eq!(writes, vec![
|
||||
r(K::HandOff, &format!("{INSTANCE}:hand_off:{OTHER_INSTANCE}.GameCult_-Epiphany.2026-09-17")),
|
||||
r(K::Resolution, &format!("{INSTANCE}:resolution:stewardship.GameCult_-Epiphany.n1.n2")),
|
||||
r(K::HandOff, &format!("{INSTANCE}:hand_off:{OTHER_INSTANCE}.gamecult_-epiphany.2026-09-17")),
|
||||
r(K::Resolution, &format!("{INSTANCE}:resolution:stewardship.gamecult_-epiphany.n1.n2")),
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
@ -1323,7 +1323,7 @@ mod tests {
|
|||
}
|
||||
|
||||
fn stewardship_key(sequence: u32) -> String {
|
||||
format!("{INSTANCE}:stewardship:GameCult_-Epiphany.n{sequence}")
|
||||
format!("{INSTANCE}:stewardship:gamecult_-epiphany.n{sequence}")
|
||||
}
|
||||
|
||||
/// Which assignment a hand-off's derived withdrawal names is a question of
|
||||
|
|
@ -1362,7 +1362,7 @@ mod tests {
|
|||
// carries a withdrawal -- of another hand-off. Sorting first, it is
|
||||
// what a match on the outcome alone would pick.
|
||||
committed(admit(&mut mind, vec![hand_off_on(INSTANCE, OTHER_INSTANCE, "2026-09-11")]));
|
||||
let withdrawal = format!("{INSTANCE}:resolution:stewardship.GameCult_-Epiphany.n11.n1");
|
||||
let withdrawal = format!("{INSTANCE}:resolution:stewardship.gamecult_-epiphany.n11.n1");
|
||||
committed(admit(&mut mind, vec![resolution(r(K::Resolution, &withdrawal), withdrawn())]));
|
||||
let (away, receipt_id) = &aways[1];
|
||||
assert_eq!(
|
||||
|
|
@ -1381,7 +1381,7 @@ mod tests {
|
|||
committed(admit(&mut mind, vec![hand_off_on(INSTANCE, OTHER_INSTANCE, "2026-09-16")]));
|
||||
committed(admit(&mut mind, vec![hand_off_on(OTHER_INSTANCE, INSTANCE, "2026-09-17")]));
|
||||
committed(admit(&mut mind, vec![hand_off_on(INSTANCE, OTHER_INSTANCE, "2026-09-18")]));
|
||||
let withdrawal = format!("{INSTANCE}:resolution:stewardship.GameCult_-Epiphany.n1.n1");
|
||||
let withdrawal = format!("{INSTANCE}:resolution:stewardship.gamecult_-epiphany.n1.n1");
|
||||
committed(admit(&mut mind, vec![resolution(r(K::Resolution, &withdrawal), withdrawn())]));
|
||||
let in_force = docs_of(&mind).stewardships_of(&slug(INSTANCE), &repo(REPO), None).iter().map(|(key, _)| key.to_string()).collect::<Vec<_>>();
|
||||
assert_eq!(in_force, vec![stewardship_key(1)]);
|
||||
|
|
@ -1394,7 +1394,7 @@ mod tests {
|
|||
fn a_reinstatement_is_blocked_by_an_assignment_in_its_own_batch() {
|
||||
let mut mind = seeded();
|
||||
committed(admit(&mut mind, vec![hand_off_on(INSTANCE, OTHER_INSTANCE, "2026-09-16")]));
|
||||
let withdrawal = format!("{INSTANCE}:resolution:stewardship.GameCult_-Epiphany.n1.n1");
|
||||
let withdrawal = format!("{INSTANCE}:resolution:stewardship.gamecult_-epiphany.n1.n1");
|
||||
assert_eq!(
|
||||
refusal(admit(&mut mind, vec![
|
||||
hand_off_on(OTHER_INSTANCE, INSTANCE, "2026-09-17"),
|
||||
|
|
@ -1464,12 +1464,12 @@ mod tests {
|
|||
let spec_ref = r(K::CutSpec, &id("cut_spec", "cut-1.r1"));
|
||||
let finding_ref = r(K::Finding, &id("finding", "cut-1.s1.F1"));
|
||||
let follow_up_ref = r(K::FollowUp, &id("follow_up", "FU-1"));
|
||||
let stewardship_ref = r(K::Stewardship, &format!("{INSTANCE}:stewardship:GameCult_-Epiphany.n1"));
|
||||
let stewardship_ref = r(K::Stewardship, &format!("{INSTANCE}:stewardship:gamecult_-epiphany.n1"));
|
||||
let campaign_ref = r(K::Campaign, &id("campaign", "self"));
|
||||
let report_ref = r(K::CutReport, &id("cut_report", "cut-1.h1"));
|
||||
let verdict_ref = r(K::Verdict, &id("verdict", "cut-1.s1"));
|
||||
let instance_ref = r(K::Instance, &format!("{INSTANCE}:instance:self"));
|
||||
let hand_off_ref = r(K::HandOff, &format!("{INSTANCE}:hand_off:{OTHER_INSTANCE}.GameCult_-Huginn.2026-09-16"));
|
||||
let hand_off_ref = r(K::HandOff, &format!("{INSTANCE}:hand_off:{OTHER_INSTANCE}.gamecult_-huginn.2026-09-16"));
|
||||
|
||||
// Accepted, one per resolvable kind.
|
||||
committed(admit(&mut world(), vec![target(2, &[INVARIANT]), resolution(target_ref.clone(), superseded(&[target_r2.clone()]))]));
|
||||
|
|
@ -1900,9 +1900,9 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn a_hand_off_derives_this_minds_side_only() {
|
||||
let key = format!("{INSTANCE}:hand_off:{OTHER_INSTANCE}.GameCult_-Epiphany.2026-09-16");
|
||||
let key = format!("{INSTANCE}:hand_off:{OTHER_INSTANCE}.gamecult_-epiphany.2026-09-16");
|
||||
let campaign_key = id("campaign", "self");
|
||||
let stewardship_key = format!("{INSTANCE}:stewardship:GameCult_-Epiphany.n1");
|
||||
let stewardship_key = format!("{INSTANCE}:stewardship:gamecult_-epiphany.n1");
|
||||
|
||||
let mut source = seeded();
|
||||
assert_eq!(
|
||||
|
|
@ -1923,7 +1923,7 @@ mod tests {
|
|||
let mut receiving = opened(MemoryStore::new(), OTHER_INSTANCE);
|
||||
committed(admit(&mut receiving, vec![instance(OTHER_INSTANCE)]));
|
||||
let (_, writes) = committed(admit(&mut receiving, vec![hand_off(INSTANCE, OTHER_INSTANCE, REPO, &[&campaign_key])]));
|
||||
let assigned = format!("{OTHER_INSTANCE}:stewardship:GameCult_-Epiphany.n1");
|
||||
let assigned = format!("{OTHER_INSTANCE}:stewardship:gamecult_-epiphany.n1");
|
||||
assert_eq!(writes, vec![r(K::HandOff, &key), r(K::Stewardship, &assigned)]);
|
||||
let Some(D::Stewardship(derived)) = receiving.get(K::Stewardship, &assigned).unwrap() else { panic!() };
|
||||
assert_eq!(derived.note, Line(key.clone()));
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ pub(crate) fn stewardship_n(instance: &str, repo_name: &str, sequence: u32) -> P
|
|||
pub(crate) fn campaign(repos: &[&str]) -> PipelineDocument {
|
||||
PipelineDocument::Campaign(PipelineCampaign {
|
||||
slug: slug(CAMPAIGN),
|
||||
title: s("Eureka pipeline state"),
|
||||
title: "Eureka pipeline state".into(),
|
||||
repos: repos.iter().map(|name| repo(name)).collect(),
|
||||
working_branch: s("codex/eureka-pipeline-state"),
|
||||
target_doc: doc_ref(),
|
||||
|
|
@ -163,6 +163,7 @@ pub(crate) fn question(label: &str, options: &[&str], recommended: &str) -> Pipe
|
|||
PipelineDocument::Question(PipelineQuestion {
|
||||
campaign: slug(CAMPAIGN),
|
||||
label: l(label),
|
||||
title: "Who owns the state?".into(),
|
||||
question: "Who owns the state?".into(),
|
||||
options: options.iter().map(|option| QuestionOption { label: l(option), text: "an option".into() }).collect(),
|
||||
recommended: l(recommended),
|
||||
|
|
@ -176,6 +177,7 @@ pub(crate) fn ruling(label: &str) -> PipelineRuling {
|
|||
PipelineRuling {
|
||||
campaign: slug(CAMPAIGN),
|
||||
label: l(label),
|
||||
title: "An instance owns its mind".into(),
|
||||
answers: None,
|
||||
choice: None,
|
||||
ruling: "An instance owns its mind.".into(),
|
||||
|
|
@ -191,7 +193,7 @@ pub(crate) fn cut_spec(cut: &str, revision: u32) -> PipelineCutSpec {
|
|||
campaign: slug(CAMPAIGN),
|
||||
cut: l(cut),
|
||||
revision,
|
||||
title: s("A cut"),
|
||||
title: "A cut".into(),
|
||||
repo: repo(REPO),
|
||||
branch: s("codex/eureka-pipeline-state"),
|
||||
base: sha(),
|
||||
|
|
|
|||
|
|
@ -643,7 +643,7 @@ mod tests {
|
|||
assert!(!eureka.contains(&"other-campaign:question:Q1".to_string()));
|
||||
assert_eq!(matching(PipelineQuery { campaign: Some(slug(INSTANCE)), ..Default::default() }), vec![
|
||||
format!("{INSTANCE}:instance:self"),
|
||||
format!("{INSTANCE}:stewardship:GameCult_-Epiphany.n1"),
|
||||
format!("{INSTANCE}:stewardship:gamecult_-epiphany.n1"),
|
||||
]);
|
||||
|
||||
// `repo`: a campaign lists its repos, five kinds name one, and a
|
||||
|
|
@ -655,7 +655,7 @@ mod tests {
|
|||
id("cut_spec", "cut-9.r1"),
|
||||
id("cut_report", "cut-9.h1"),
|
||||
id("follow_up", "FU-1"),
|
||||
format!("{INSTANCE}:stewardship:GameCult_-Epiphany.n1"),
|
||||
format!("{INSTANCE}:stewardship:gamecult_-epiphany.n1"),
|
||||
supersession.clone(),
|
||||
] {
|
||||
assert!(epiphany.contains(&expected), "{expected}");
|
||||
|
|
@ -714,7 +714,7 @@ mod tests {
|
|||
id("campaign", "self"),
|
||||
id("target", "r1"),
|
||||
format!("{INSTANCE}:instance:self"),
|
||||
format!("{INSTANCE}:stewardship:GameCult_-Epiphany.n1"),
|
||||
format!("{INSTANCE}:stewardship:gamecult_-epiphany.n1"),
|
||||
]);
|
||||
|
||||
// 201 questions over four batches at rising `now`s, with Q1 -- the id
|
||||
|
|
|
|||
|
|
@ -473,9 +473,9 @@
|
|||
]
|
||||
},
|
||||
"OrgRepo": {
|
||||
"description": "A GitHub repository as `Org/Repo`.",
|
||||
"description": "A GitHub repository as `Org/Repo`, at most 140 UTF-8 bytes (39 + 1 +\n100). The owner is 1 to 39 `[A-Za-z0-9-]` bytes with no leading or\ntrailing hyphen; the repo is 1 to 100 `[A-Za-z0-9._-]` bytes, is never\n`.` or `..`, and does not end in `.git`, ASCII-case-insensitively.\nIdentity is case-insensitive: `GameCult/Epiphany` and `gamecult/epiphany`\nare the same repository.",
|
||||
"type": "string",
|
||||
"maxLength": 200
|
||||
"maxLength": 140
|
||||
},
|
||||
"Para": {
|
||||
"description": "Text of at most 4,000 UTF-8 bytes; longer narrative is cited by `DocRef`.",
|
||||
|
|
@ -522,7 +522,7 @@
|
|||
"$ref": "#/$defs/DocRef"
|
||||
},
|
||||
"title": {
|
||||
"$ref": "#/$defs/Short"
|
||||
"$ref": "#/$defs/Title"
|
||||
},
|
||||
"working_branch": {
|
||||
"$ref": "#/$defs/Short"
|
||||
|
|
@ -730,7 +730,7 @@
|
|||
"maxItems": 32
|
||||
},
|
||||
"title": {
|
||||
"$ref": "#/$defs/Short"
|
||||
"$ref": "#/$defs/Title"
|
||||
},
|
||||
"verification": {
|
||||
"$ref": "#/$defs/CutVerification"
|
||||
|
|
@ -1313,11 +1313,15 @@
|
|||
},
|
||||
"recommended": {
|
||||
"$ref": "#/$defs/Label"
|
||||
},
|
||||
"title": {
|
||||
"$ref": "#/$defs/Title"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"campaign",
|
||||
"label",
|
||||
"title",
|
||||
"question",
|
||||
"options",
|
||||
"recommended",
|
||||
|
|
@ -1425,11 +1429,15 @@
|
|||
},
|
||||
"ruling": {
|
||||
"$ref": "#/$defs/Para"
|
||||
},
|
||||
"title": {
|
||||
"$ref": "#/$defs/Title"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"campaign",
|
||||
"label",
|
||||
"title",
|
||||
"ruling",
|
||||
"ruled_on",
|
||||
"precedents",
|
||||
|
|
@ -1862,6 +1870,12 @@
|
|||
"statement"
|
||||
]
|
||||
},
|
||||
"Title": {
|
||||
"description": "A title: 1 to 200 UTF-8 bytes, enforced by admission; JSON Schema\nlength counts characters. Holds at least one alphanumeric character,\nno control character, and no bidi control character (`U+061C`,\n`U+200E`, `U+200F`, `U+202A`-`U+202E`, `U+2066`-`U+2069`).",
|
||||
"type": "string",
|
||||
"maxLength": 200,
|
||||
"minLength": 1
|
||||
},
|
||||
"VerdictClaim": {
|
||||
"description": "The promise this claim measured, and the report's mutations it ran. An\n`Unproven` claim with a promise is one Soul could not reach.",
|
||||
"type": "object",
|
||||
|
|
|
|||
|
|
@ -1312,9 +1312,9 @@
|
|||
]
|
||||
},
|
||||
"OrgRepo": {
|
||||
"description": "A GitHub repository as `Org/Repo`.",
|
||||
"description": "A GitHub repository as `Org/Repo`, at most 140 UTF-8 bytes (39 + 1 +\n100). The owner is 1 to 39 `[A-Za-z0-9-]` bytes with no leading or\ntrailing hyphen; the repo is 1 to 100 `[A-Za-z0-9._-]` bytes, is never\n`.` or `..`, and does not end in `.git`, ASCII-case-insensitively.\nIdentity is case-insensitive: `GameCult/Epiphany` and `gamecult/epiphany`\nare the same repository.",
|
||||
"type": "string",
|
||||
"maxLength": 200
|
||||
"maxLength": 140
|
||||
},
|
||||
"Para": {
|
||||
"description": "Text of at most 4,000 UTF-8 bytes; longer narrative is cited by `DocRef`.",
|
||||
|
|
@ -1429,7 +1429,7 @@
|
|||
"$ref": "#/$defs/DocRef"
|
||||
},
|
||||
"title": {
|
||||
"$ref": "#/$defs/Short"
|
||||
"$ref": "#/$defs/Title"
|
||||
},
|
||||
"working_branch": {
|
||||
"$ref": "#/$defs/Short"
|
||||
|
|
@ -1637,7 +1637,7 @@
|
|||
"maxItems": 32
|
||||
},
|
||||
"title": {
|
||||
"$ref": "#/$defs/Short"
|
||||
"$ref": "#/$defs/Title"
|
||||
},
|
||||
"verification": {
|
||||
"$ref": "#/$defs/CutVerification"
|
||||
|
|
@ -2182,11 +2182,15 @@
|
|||
},
|
||||
"recommended": {
|
||||
"$ref": "#/$defs/Label"
|
||||
},
|
||||
"title": {
|
||||
"$ref": "#/$defs/Title"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"campaign",
|
||||
"label",
|
||||
"title",
|
||||
"question",
|
||||
"options",
|
||||
"recommended",
|
||||
|
|
@ -2297,6 +2301,30 @@
|
|||
"InvalidIdentity"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"DuplicateRepo": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"field": {
|
||||
"type": "string"
|
||||
},
|
||||
"repo": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"field",
|
||||
"repo"
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"DuplicateRepo"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
|
@ -2403,11 +2431,15 @@
|
|||
},
|
||||
"ruling": {
|
||||
"$ref": "#/$defs/Para"
|
||||
},
|
||||
"title": {
|
||||
"$ref": "#/$defs/Title"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"campaign",
|
||||
"label",
|
||||
"title",
|
||||
"ruling",
|
||||
"ruled_on",
|
||||
"precedents",
|
||||
|
|
@ -2857,6 +2889,12 @@
|
|||
"statement"
|
||||
]
|
||||
},
|
||||
"Title": {
|
||||
"description": "A title: 1 to 200 UTF-8 bytes, enforced by admission; JSON Schema\nlength counts characters. Holds at least one alphanumeric character,\nno control character, and no bidi control character (`U+061C`,\n`U+200E`, `U+200F`, `U+202A`-`U+202E`, `U+2066`-`U+2069`).",
|
||||
"type": "string",
|
||||
"maxLength": 200,
|
||||
"minLength": 1
|
||||
},
|
||||
"VerdictClaim": {
|
||||
"description": "The promise this claim measured, and the report's mutations it ran. An\n`Unproven` claim with a promise is one Soul could not reach.",
|
||||
"type": "object",
|
||||
|
|
|
|||
Loading…
Reference in a new issue