thought kind: her stream of thought is a document (cut stream-thoughts step 1)
PipelineThought epiphany.pipeline.thought.v2, instance-rooted, validated as its chosen candidate; ForeignInstance refusal, Answered-by-FollowUp or Recorded resolutions, facts, a reads citation role, text index. Schemas, golden sample, huginn schema list regenerated. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
987c6ec74d
commit
f65a7449fb
24 changed files with 726 additions and 32 deletions
|
|
@ -30,6 +30,7 @@ sample.memory yggdrasil:memory:2026-10-31t041200-t0-m0 epiphany.pipeline.memory.
|
|||
sample.research eureka-state:research:p1.scope epiphany.pipeline.research.v2 EpiphanyPipelineResearchDocument 9189a863616d706169676eac657572656b612d7374617465a470617373a27031a56c6162656ca573636f7065a5636c61696dd93654686520656d626564206c696d6974206973203430393620746f6b656e7320776974682073696c656e74207472756e636174696f6e2ea664657461696cd934526561642066726f6d20746865206461656d6f6e277320696e646578206d6f64756c6520616e642070726f626564206c6976652ea8696e666572726564c2a7736f75726365739481a45265706f82a47265706fb147616d6543756c742f4570697068616e79a2617484a470617468d9256372617465732f687567696e6e2d6461656d6f6e2f7372632f696e6465782f6d6f642e7273aa73746172745f6c696e6532a8656e645f6c696e6538a6636f6d6d6974a8356639383232386481a357656283a375726cd92268747470733a2f2f7a657474656c6b617374656e2e64652f61746f6d69636974792fa4776f726bb65a657474656c6b617374656e2061746f6d6963697479ac7265747269657665645f6f6eaa323032362d30392d313581a84f6273657276656481a865766964656e636583a46b696e64a454657374a76c6f6361746f72aa636172676f2074657374a6726573756c74a26f6b81a8446f63756d656e7481a97265666572656e636582a46b696e64a652756c696e67a26964b6657572656b612d73746174653a72756c696e673a5238a67365727665739182a46b696e64a85175657374696f6ea26964b8657572656b612d73746174653a7175657374696f6e3a5131ab6f627365727665645f6f6eaa323032362d30392d3135
|
||||
sample.idea eureka-state:idea:p1.i1 epiphany.pipeline.idea.v2 EpiphanyPipelineIdeaDocument 9189a863616d706169676eac657572656b612d7374617465a470617373a27031a56c6162656ca26931a57469746c65b24f6e65206e6f74652070657220636c61696da469646561d9204b65657020612070617373206173206d616e7920736d616c6c206e6f7465732ea974726164656f666673b74d6f726520646f63756d656e747320746f206c6973742ea872657374735f6f6e9182a46b696e64a85265736561726368a26964be657572656b612d73746174653a72657365617263683a70312e73636f7065a6746f776172649182a46b696e64a85175657374696f6ea26964b8657572656b612d73746174653a7175657374696f6e3a5131ab70726f706f7365645f6f6eaa323032362d30392d3135
|
||||
sample.reply yggdrasil:reply:mind-2026-10-09-1-r1 epiphany.pipeline.reply.v2 EpiphanyPipelineReplyDocument 9185a8696e7374616e6365a979676764726173696ca56c6162656cb46d696e642d323032362d31302d30392d312d7231a372756e82a46b696e64a352756ea26964bf79676764726173696c3a72756e3a6d696e642d323032362d31302d30392d31a7616e73776572739182a46b696e64a8466f6c6c6f775570a26964d923657572656b612d73746174653a666f6c6c6f775f75703a61736b2d7468652d73656c66a474657874d93054686520736861646572207061737320697320646f6e653b2074686520736f756e647320617265204c6962627927732e
|
||||
sample.thought yggdrasil:thought:t1793000000 epiphany.pipeline.thought.v2 EpiphanyPipelineThoughtDocument 91de0013a8696e7374616e6365a979676764726173696ca56c6162656cab7431373933303030303030a474657874d93d54686520736f756e647320617265204c6962627927733b2074686520736861646572732077657265206e6576657220746865206861726420706172742ea572656164739182a46b696e64a64d656d6f7279a26964d92879676764726173696c3a6d656d6f72793a323032362d31302d3331743034313230302d74302d6d30af706572736f6e615f72656365697074b06d696e642d636f6d6d69742d30613162a86964656e74697479be457572656b612c207368652f6865722c20706c61696e2d73706f6b656e2ea7636f6e74657874d92056616c7565733a20636f686572656e6365206f7665722076656c6f636974792ea87374696d756c7573bd4c696262792061736b65642061626f75742074686520736f756e64732eaf70726f6a6563746f725f6d6f64656cb070726f6a6563746f723a6c6174657374aa70726f6a656374696f6ed92949206b656570207475726e696e67206f7665722077686f20686f6c64732074686520736f756e64732eaa626173655f6d6f64656cab626173653a6c6174657374b474656d70657261747572655f7065726d696c6c65cd03e8ae6d696e5f705f7065726d696c6c6532aa6d61785f746f6b656e73cca0aa63616e6469646174657392d93d54686520736f756e647320617265204c6962627927733b2074686520736861646572732077657265206e6576657220746865206861726420706172742eaf41207365636f6e642064726966742eb06e6561726573745f7065726d696c6c6592cd0136cd0366a663686f73656e00ac70726f6a6563746f725f6d73cd1068ac636f6e74696e7565725f6d73cd238c
|
||||
resolution.superseded eureka-state:resolution:question.Q1.n1 epiphany.pipeline.resolution.v2 EpiphanyPipelineResolutionDocument 9185a77375626a65637482a46b696e64a85175657374696f6ea26964b8657572656b612d73746174653a7175657374696f6e3a5131a873657175656e636501a76f7574636f6d6581aa5375706572736564656481a262799282a46b696e64a652756c696e67a26964b6657572656b612d73746174653a72756c696e673a523882a46b696e64a85175657374696f6ea26964b8657572656b612d73746174653a7175657374696f6e3a5131a9726174696f6e616c65a852756c656420412eab7265736f6c7665645f6f6eaa323032362d30392d3135
|
||||
resolution.fixed-by-none eureka-state:resolution:question.Q1.n1 epiphany.pipeline.resolution.v2 EpiphanyPipelineResolutionDocument 9185a77375626a65637482a46b696e64a85175657374696f6ea26964b8657572656b612d73746174653a7175657374696f6e3a5131a873657175656e636501a76f7574636f6d6581a5466978656482a6636f6d6d6974a83566393832323864a26279c0a9726174696f6e616c65a852756c656420412eab7265736f6c7665645f6f6eaa323032362d30392d3135
|
||||
resolution.fixed-by-some eureka-state:resolution:question.Q1.n1 epiphany.pipeline.resolution.v2 EpiphanyPipelineResolutionDocument 9185a77375626a65637482a46b696e64a85175657374696f6ea26964b8657572656b612d73746174653a7175657374696f6e3a5131a873657175656e636501a76f7574636f6d6581a5466978656482a6636f6d6d6974a83566393832323864a2627982a46b696e64a94375745265706f7274a26964d921657572656b612d73746174653a6375745f7265706f72743a6375742d33612e6831a9726174696f6e616c65a852756c656420412eab7265736f6c7665645f6f6eaa323032362d30392d3135
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ macro_rules! unbounded_scalars {
|
|||
)*};
|
||||
}
|
||||
|
||||
unbounded_scalars!(u16, u32, u64, bool);
|
||||
unbounded_scalars!(u8, u16, u32, u64, bool);
|
||||
|
||||
fn bound(field: &str, limit: usize, actual: usize) -> Result<(), PipelineRefusal> {
|
||||
if actual > limit {
|
||||
|
|
@ -622,6 +622,34 @@ fn reply_is_well_formed(reply: &PipelineReply, at: &str) -> Result<(), PipelineR
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// The most candidates a continuation may offer, and the nearness that means
|
||||
/// she had no earlier thought to be near.
|
||||
pub const THOUGHT_CANDIDATES_MAX: usize = 4;
|
||||
pub const THOUGHT_NEAREST_NONE_PERMILLE: u16 = 1000;
|
||||
|
||||
/// A thought says something it was chosen to say: its text is not blank and is
|
||||
/// the chosen candidate, every candidate has its nearness, and no nearness is
|
||||
/// over 1000 thousandths.
|
||||
fn thought_is_well_formed(thought: &PipelineThought, at: &str) -> Result<(), PipelineRefusal> {
|
||||
if thought.text.0.trim().is_empty() {
|
||||
return Err(format_error(&format!("{at}.text"), "a thought with no words"));
|
||||
}
|
||||
if thought.candidates.is_empty() || thought.candidates.len() > THOUGHT_CANDIDATES_MAX {
|
||||
return Err(format_error(&format!("{at}.candidates"), &format!("{} candidates", thought.candidates.len())));
|
||||
}
|
||||
if thought.nearest_permille.len() != thought.candidates.len() {
|
||||
return Err(format_error(&format!("{at}.nearest_permille"), "a nearness list that is not one per candidate"));
|
||||
}
|
||||
if let Some(over) = thought.nearest_permille.iter().position(|near| *near > THOUGHT_NEAREST_NONE_PERMILLE) {
|
||||
return Err(format_error(&format!("{at}.nearest_permille[{over}]"), &thought.nearest_permille[over].to_string()));
|
||||
}
|
||||
match thought.candidates.get(usize::from(thought.chosen)) {
|
||||
None => Err(format_error(&format!("{at}.chosen"), &thought.chosen.to_string())),
|
||||
Some(chosen) if chosen.0 != thought.text.0 => Err(format_error(&format!("{at}.text"), "a thought that is not its chosen candidate")),
|
||||
Some(_) => Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
/// The most thousandths a memory's salience may carry.
|
||||
pub const SALIENCE_MAX_PERMILLE: u16 = 1000;
|
||||
|
||||
|
|
@ -841,6 +869,22 @@ value_types! {
|
|||
/// Instance-rooted: the key is `<instance>:reply:<label>`. Not semantically
|
||||
/// indexed. Whether the run is hers is admission's rule.
|
||||
pub struct PipelineReply { instance: Slug, label: Label, run: PipelineRef, answers: Vec<PipelineRef>[64], text: Para } => reply_is_well_formed
|
||||
/// One tick of her stream of thought, offline: the words a base model
|
||||
/// continued from a projection of her own state, with the whole trace that
|
||||
/// made them (the seed, the projection, every candidate and how near each
|
||||
/// was to her earlier thoughts). `text` is the chosen candidate. `reads`
|
||||
/// are the documents the seed was drawn from. A thought is divergence for
|
||||
/// delivery to weigh, never a memory: its words reach a later seed only
|
||||
/// through something she wrote. Instance-rooted: the key is
|
||||
/// `<instance>:thought:<label>`, the label `t<unix seconds>` of the tick.
|
||||
/// Semantically indexed on `text` only. `nearest_permille` is 1000 where she
|
||||
/// had no earlier thought.
|
||||
pub struct PipelineThought {
|
||||
instance: Slug, label: Label, text: Para, reads: Vec<PipelineRef>[64], persona_receipt: Short,
|
||||
identity: Line, context: Para, stimulus: Para, projector_model: Short, projection: Para, base_model: Short,
|
||||
temperature_permille: u16, min_p_permille: u16, max_tokens: u16,
|
||||
candidates: Vec<Line>[4], nearest_permille: Vec<u16>[4], chosen: u8, projector_ms: u32, continuer_ms: u32,
|
||||
} => thought_is_well_formed
|
||||
/// One thing a Mind keeps for herself, in her own mind: what she was asked,
|
||||
/// decided, committed to, learned or did, an idea, or the rapport between
|
||||
/// her and another Mind or person. `text` is her own words. `about` names
|
||||
|
|
@ -1181,6 +1225,8 @@ pipeline_kinds! {
|
|||
"epiphany.pipeline.idea.v2", "EpiphanyPipelineIdeaDocument";
|
||||
Reply(PipelineReply) => EpiphanyPipelineReplyDocument, "reply",
|
||||
"epiphany.pipeline.reply.v2", "EpiphanyPipelineReplyDocument";
|
||||
Thought(PipelineThought) => EpiphanyPipelineThoughtDocument, "thought",
|
||||
"epiphany.pipeline.thought.v2", "EpiphanyPipelineThoughtDocument";
|
||||
}
|
||||
|
||||
/// Parses a full document id: the grammar read backwards. A key and an id are
|
||||
|
|
@ -1378,6 +1424,7 @@ pub fn pipeline_key(document: &PipelineDocument) -> Result<String, PipelineRefus
|
|||
D::Run(value) => ("run.instance", value.instance.0.as_str(), local(&key_field, document_kind, &[&value.label.0])?),
|
||||
D::Pulse(value) => ("pulse.instance", value.instance.0.as_str(), local(&key_field, document_kind, &[&value.label.0])?),
|
||||
D::Reply(value) => ("reply.instance", value.instance.0.as_str(), local(&key_field, document_kind, &[&value.label.0])?),
|
||||
D::Thought(value) => ("thought.instance", value.instance.0.as_str(), local(&key_field, document_kind, &[&value.label.0])?),
|
||||
D::Memory(value) => ("memory.instance", value.instance.0.as_str(), local(&key_field, document_kind, &[&value.label.0])?),
|
||||
D::Research(value) => (campaign_field.as_str(), value.campaign.0.as_str(), local(&key_field, document_kind, &[&value.pass.0, &value.label.0])?),
|
||||
D::Idea(value) => (campaign_field.as_str(), value.campaign.0.as_str(), local(&key_field, document_kind, &[&value.pass.0, &value.label.0])?),
|
||||
|
|
@ -1658,6 +1705,17 @@ mod tests {
|
|||
answers: vec![PipelineRef { kind: PipelineKind::FollowUp, id: id("follow_up", "ask-the-self") }],
|
||||
text: "The shader pass is done; the sounds are Libby's.".into(),
|
||||
}), format!("{INSTANCE}:reply:mind-2026-10-09-1-r1")),
|
||||
(D::Thought(PipelineThought {
|
||||
instance: slug(INSTANCE), label: l("t1793000000"),
|
||||
text: "The sounds are Libby's; the shaders were never the hard part.".into(),
|
||||
reads: vec![PipelineRef { kind: PipelineKind::Memory, id: Short(format!("{INSTANCE}:memory:2026-10-31t041200-t0-m0")) }],
|
||||
persona_receipt: s("mind-commit-0a1b"), identity: "Eureka, she/her, plain-spoken.".into(),
|
||||
context: "Values: coherence over velocity.".into(), stimulus: "Libby asked about the sounds.".into(),
|
||||
projector_model: s("projector:latest"), projection: "I keep turning over who holds the sounds.".into(), base_model: s("base:latest"),
|
||||
temperature_permille: 1000, min_p_permille: 50, max_tokens: 160,
|
||||
candidates: vec!["The sounds are Libby's; the shaders were never the hard part.".into(), "A second drift.".into()],
|
||||
nearest_permille: vec![310, 870], chosen: 0, projector_ms: 4200, continuer_ms: 9100,
|
||||
}), format!("{INSTANCE}:thought:t1793000000")),
|
||||
]
|
||||
}
|
||||
|
||||
|
|
@ -1992,6 +2050,35 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
/// A thought is its chosen candidate, with one nearness per candidate, in bounds.
|
||||
#[test]
|
||||
fn malformed_thought_refused() {
|
||||
let validated = |change: &dyn Fn(&mut PipelineThought)| {
|
||||
let PipelineDocument::Thought(mut thought) = samples().remove(19).0 else { unreachable!() };
|
||||
change(&mut thought);
|
||||
PipelineDocument::Thought(thought).validate()
|
||||
};
|
||||
assert_eq!(validated(&|_| {}), Ok(()));
|
||||
assert_eq!(validated(&|thought| { thought.chosen = 1; thought.text = thought.candidates[1].0.as_str().into(); }), Ok(()));
|
||||
assert_eq!(validated(&|thought| { thought.candidates.truncate(1); thought.nearest_permille.truncate(1); }), Ok(()));
|
||||
assert_eq!(validated(&|thought| thought.nearest_permille[0] = 1000), Ok(()), "1000 means no earlier thought");
|
||||
for (change, field) in [
|
||||
(&(|thought: &mut PipelineThought| { thought.text = " \n".into(); thought.candidates[0] = " \n".into(); }) as &dyn Fn(&mut PipelineThought), "thought.text"),
|
||||
(&|thought: &mut PipelineThought| thought.text = "Another thing entirely.".into(), "thought.text"),
|
||||
(&|thought: &mut PipelineThought| { thought.nearest_permille.pop(); }, "thought.nearest_permille"),
|
||||
(&|thought: &mut PipelineThought| thought.nearest_permille[1] = 1001, "thought.nearest_permille[1]"),
|
||||
(&|thought: &mut PipelineThought| thought.chosen = 2, "thought.chosen"),
|
||||
(&|thought: &mut PipelineThought| { thought.candidates.clear(); thought.nearest_permille.clear(); }, "thought.candidates"),
|
||||
] {
|
||||
assert!(matches!(validated(change), Err(PipelineRefusal::InvalidFormat { field: f, .. }) if f == field), "{field}");
|
||||
}
|
||||
let five = |thought: &mut PipelineThought| {
|
||||
thought.candidates = vec![thought.text.0.as_str().into(); 5];
|
||||
thought.nearest_permille = vec![0; 5];
|
||||
};
|
||||
assert!(matches!(validated(&five), Err(PipelineRefusal::FieldBound { .. })), "five candidates are over the bound");
|
||||
}
|
||||
|
||||
/// A pulse votes a tempo in bounds, declares an urgency in bounds, or does both; a pulse that does neither is refused.
|
||||
#[test]
|
||||
fn a_pulse_is_in_bounds_and_says_something() {
|
||||
|
|
@ -3691,11 +3778,11 @@ mod tests {
|
|||
};
|
||||
let document_schema = serde_json::to_value(schemars::schema_for!(PipelineDocument))?;
|
||||
let variants = document_schema["oneOf"].as_array().expect("the document schema is a oneOf");
|
||||
assert_eq!(PipelineKind::ALL.len(), 19, "nineteen kinds");
|
||||
assert_eq!(PipelineKind::ALL.len(), 20, "twenty kinds");
|
||||
assert_eq!(
|
||||
variants.iter().map(tag).collect::<Vec<_>>(),
|
||||
PipelineKind::ALL.iter().map(|kind| kind.name().to_owned()).collect::<Vec<_>>(),
|
||||
"the document schema lists exactly the nineteen kinds, by name"
|
||||
"the document schema lists exactly the twenty kinds, by name"
|
||||
);
|
||||
|
||||
let refusal_schema = serde_json::to_value(schemars::schema_for!(PipelineRefusal))?;
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ macro_rules! kinds {
|
|||
|
||||
kinds!(
|
||||
campaign, target, question, ruling, cut_spec, cut_report, verdict, finding, follow_up, resolution, instance, stewardship,
|
||||
hand_off, run, pulse, memory, research, idea, reply,
|
||||
hand_off, run, pulse, memory, research, idea, reply, thought,
|
||||
);
|
||||
|
||||
/// The schema named, or the names when none is: the exit code is 2 for a name
|
||||
|
|
|
|||
|
|
@ -1140,12 +1140,12 @@ fn schema_prints_the_published_files() {
|
|||
let names = run(&[], &["schema"], None);
|
||||
assert_eq!(names.code, 0);
|
||||
let names: Vec<&str> = names.out.lines().collect();
|
||||
assert_eq!(names.len(), 20, "{names:?}");
|
||||
assert_eq!(names.len(), 21, "{names:?}");
|
||||
assert_eq!(names[0], "campaign");
|
||||
assert_eq!(names[14], "pulse");
|
||||
assert_eq!(names[15], "memory");
|
||||
assert_eq!((names[16], names[17]), ("research", "idea"));
|
||||
assert_eq!((names[18], names[19]), ("reply", "selection"));
|
||||
assert_eq!((names[18], names[19], names[20]), ("reply", "thought", "selection"));
|
||||
for kind in PipelineKind::ALL {
|
||||
assert!(names.contains(&kind.name()), "{}", kind.name());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -314,6 +314,7 @@ fn refuse_foreign_instance(document: &PipelineDocument, mind: &Slug) -> Result<(
|
|||
PipelineDocument::Run(value) if value.instance != *mind => Err(foreign(&value.instance)),
|
||||
PipelineDocument::Pulse(value) if value.instance != *mind => Err(foreign(&value.instance)),
|
||||
PipelineDocument::Reply(value) if value.instance != *mind => Err(foreign(&value.instance)),
|
||||
PipelineDocument::Thought(value) if value.instance != *mind => Err(foreign(&value.instance)),
|
||||
PipelineDocument::Memory(value) if value.instance != *mind => Err(foreign(&value.instance)),
|
||||
PipelineDocument::HandOff(value) if value.from_instance != *mind && value.to_instance != *mind => {
|
||||
Err(foreign(&value.from_instance))
|
||||
|
|
@ -624,7 +625,7 @@ fn check(docs: &Docs<'_>, staged: &Staged, mind: &Slug) -> Result<(), MindRefusa
|
|||
let replay = docs.in_image(K::Run, key) == Some(&staged.document);
|
||||
run_rule(docs, key, run, replay)
|
||||
}
|
||||
D::FollowUp(_) | D::Instance(_) | D::Pulse(_) | D::Reply(_) | D::Memory(_) | D::Research(_) | D::Idea(_) => Ok(()),
|
||||
D::FollowUp(_) | D::Instance(_) | D::Pulse(_) | D::Reply(_) | D::Thought(_) | D::Memory(_) | D::Research(_) | D::Idea(_) => Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -730,6 +731,8 @@ fn matrix(subject: PipelineKind, outcome: &ResolutionOutcome) -> bool {
|
|||
(K::Idea, O::Recorded { .. } | O::Withdrawn { .. }) => true,
|
||||
(K::Reply, O::Answered { by }) => by.kind == K::FollowUp,
|
||||
(K::Reply, O::Recorded { .. }) => true,
|
||||
(K::Thought, O::Answered { by }) => by.kind == K::FollowUp,
|
||||
(K::Thought, O::Recorded { .. }) => true,
|
||||
(K::Resolution, O::Withdrawn { .. }) => true,
|
||||
_ => false,
|
||||
}
|
||||
|
|
@ -2498,6 +2501,44 @@ mod tests {
|
|||
committed(admit(&mut mind, vec![reply(INSTANCE)]));
|
||||
}
|
||||
|
||||
/// A thought is her own: one of another mind is a ForeignInstance, her own is admitted.
|
||||
#[test]
|
||||
fn a_thought_of_another_mind_is_a_foreign_instance_and_her_own_is_admitted() {
|
||||
let mut mind = with_specs();
|
||||
let D::Thought(mut foreign) = crate::fixtures::thought("t1", "A drift.", &[]) else { unreachable!() };
|
||||
foreign.instance = slug(OTHER_INSTANCE);
|
||||
assert_eq!(
|
||||
refusal(admit(&mut mind, vec![D::Thought(foreign)])),
|
||||
MindRefusal::ForeignInstance { declared: OTHER_INSTANCE.into(), mind: INSTANCE.into() }
|
||||
);
|
||||
committed(admit(&mut mind, vec![crate::fixtures::thought("t1", "A drift.", &[])]));
|
||||
}
|
||||
|
||||
/// A thought resolves Answered by a follow-up or Recorded; no other outcome.
|
||||
#[test]
|
||||
fn a_thought_resolves_answered_by_a_follow_up_or_recorded_and_nothing_else() {
|
||||
let incompatible = |outcome: &str| MindRefusal::IncompatibleResolution { subject_kind: K::Thought, outcome: outcome.into() };
|
||||
let subject = || r(K::Thought, &format!("{INSTANCE}:thought:t1"));
|
||||
let fu = || r(K::FollowUp, &id("follow_up", "FU1"));
|
||||
let open = || {
|
||||
let mut mind = with_specs();
|
||||
committed(admit(&mut mind, vec![D::Ruling(ruling("R1")), follow_up("FU1", r(K::Ruling, &id("ruling", "R1")))]));
|
||||
committed(admit(&mut mind, vec![crate::fixtures::thought("t1", "A drift.", &[])]));
|
||||
mind
|
||||
};
|
||||
committed(admit(&mut open(), vec![resolution(subject(), ResolutionOutcome::Answered { by: fu() })]));
|
||||
committed(admit(&mut open(), vec![resolution(subject(), ResolutionOutcome::Recorded { reason: "weighed".into() })]));
|
||||
let refused = [
|
||||
(ResolutionOutcome::Answered { by: r(K::Ruling, &id("ruling", "R1")) }, "Answered"),
|
||||
(ResolutionOutcome::Fixed { commit: sha(), by: None }, "Fixed"),
|
||||
(ResolutionOutcome::Deferred { to: fu() }, "Deferred"),
|
||||
(withdrawn(), "Withdrawn"),
|
||||
];
|
||||
for (outcome, name) in refused {
|
||||
assert_eq!(refusal(admit(&mut open(), vec![resolution(subject(), outcome)])), incompatible(name), "{name}");
|
||||
}
|
||||
}
|
||||
|
||||
fn memory_key(label: &str) -> String {
|
||||
format!("{INSTANCE}:memory:{label}")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -344,7 +344,8 @@ pub(crate) fn line_of(document: &PipelineDocument) -> Option<Lineage<'_>> {
|
|||
| D::HandOff(_)
|
||||
| D::Run(_)
|
||||
| D::Pulse(_)
|
||||
| D::Reply(_) => None,
|
||||
| D::Reply(_)
|
||||
| D::Thought(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -394,10 +395,11 @@ pub enum CitationRole {
|
|||
RestsOn,
|
||||
Toward,
|
||||
Run,
|
||||
Reads,
|
||||
}
|
||||
|
||||
impl CitationRole {
|
||||
pub const ALL: [CitationRole; 22] = [
|
||||
pub const ALL: [CitationRole; 23] = [
|
||||
Self::RaisedIn,
|
||||
Self::Answers,
|
||||
Self::Rulings,
|
||||
|
|
@ -420,6 +422,7 @@ impl CitationRole {
|
|||
Self::RestsOn,
|
||||
Self::Toward,
|
||||
Self::Run,
|
||||
Self::Reads,
|
||||
];
|
||||
|
||||
/// The wire spelling, equal to the referring field's name.
|
||||
|
|
@ -447,6 +450,7 @@ impl CitationRole {
|
|||
Self::RestsOn => "rests_on",
|
||||
Self::Toward => "toward",
|
||||
Self::Run => "run",
|
||||
Self::Reads => "reads",
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -472,6 +476,7 @@ impl CitationRole {
|
|||
Self::Serves | Self::Sources => K::Research,
|
||||
Self::RestsOn | Self::Toward => K::Idea,
|
||||
Self::Run => K::Reply,
|
||||
Self::Reads => K::Thought,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -500,7 +505,8 @@ impl CitationRole {
|
|||
| Self::Serves
|
||||
| Self::Sources
|
||||
| Self::RestsOn
|
||||
| Self::Toward => PipelineKind::ALL.to_vec(),
|
||||
| Self::Toward
|
||||
| Self::Reads => PipelineKind::ALL.to_vec(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -573,6 +579,7 @@ pub(crate) fn citations(document: &PipelineDocument) -> Vec<(CitationRole, Pipel
|
|||
),
|
||||
D::Run(run) => edges.extend(run.claims.iter().map(|to| (R::Claims, to.clone()))),
|
||||
D::Reply(reply) => edges.push((R::Run, reply.run.clone())),
|
||||
D::Thought(thought) => edges.extend(thought.reads.iter().map(|to| (R::Reads, to.clone()))),
|
||||
D::Memory(memory) => edges.extend(memory.consolidates.iter().map(|to| (R::Consolidates, to.clone()))),
|
||||
D::Research(research) => {
|
||||
edges.extend(research.serves.iter().map(|to| (R::Serves, to.clone())));
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ use eureka_pipeline::{
|
|||
FindingConfidence, FindingOrigin, FindingSeverity, Label, Line, MemoryOrigin, MemorySort, MutationRecord, OrgRepo, PipelineCampaign,
|
||||
PipelineCutReport, PipelineCutSpec, PipelineDocument, PipelineFinding, PipelineFollowUp, PipelineHandOff,
|
||||
PipelineInstance, PipelineKind, PipelineMemory, PipelineQuestion, PipelineRef, PipelineResolution, PipelineRuling,
|
||||
PipelineRun, PipelineStewardship, PipelineTarget, PipelineVerdict, Promise, QuestionOption, ReportCommit,
|
||||
PipelineThought, PipelineRun, PipelineStewardship, PipelineTarget, PipelineVerdict, Promise, QuestionOption, ReportCommit,
|
||||
ResolutionOutcome, RulingAuthority, RunOperator, RunTurn, Sha, Short, Slug, StructuralDelta, TargetInvariant, VerdictClaim,
|
||||
};
|
||||
|
||||
|
|
@ -354,6 +354,31 @@ fn run_of(label: &str, operated_by: RunOperator, turn: RunTurn, claims: &[Pipeli
|
|||
})
|
||||
}
|
||||
|
||||
/// One of her thoughts: the chosen candidate is `text`, the only candidate, as near as 1000 (no earlier thought).
|
||||
pub(crate) fn thought(label: &str, text: &str, reads: &[PipelineRef]) -> PipelineDocument {
|
||||
PipelineDocument::Thought(PipelineThought {
|
||||
instance: slug(INSTANCE),
|
||||
label: l(label),
|
||||
text: text.into(),
|
||||
reads: reads.to_vec(),
|
||||
persona_receipt: s("mind-commit-0"),
|
||||
identity: "Eureka".into(),
|
||||
context: "".into(),
|
||||
stimulus: "".into(),
|
||||
projector_model: s("projector"),
|
||||
projection: "A projection.".into(),
|
||||
base_model: s("base"),
|
||||
temperature_permille: 1000,
|
||||
min_p_permille: 50,
|
||||
max_tokens: 160,
|
||||
candidates: vec![text.into()],
|
||||
nearest_permille: vec![1000],
|
||||
chosen: 0,
|
||||
projector_ms: 1,
|
||||
continuer_ms: 1,
|
||||
})
|
||||
}
|
||||
|
||||
/// One of her memories: the sort and the text, about `about`, learned in a room, not direct.
|
||||
pub(crate) fn memory(label: &str, sort: MemorySort, text: &str, about: &[&str]) -> PipelineDocument {
|
||||
PipelineDocument::Memory(PipelineMemory {
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ pub fn index_text(document: &PipelineDocument) -> Option<String> {
|
|||
D::Resolution(resolution) => lines.push(&resolution.rationale.0),
|
||||
D::HandOff(hand_off) => lines.push(&hand_off.reason.0),
|
||||
D::Memory(memory) => lines.push(&memory.text.0),
|
||||
D::Thought(thought) => lines.push(&thought.text.0),
|
||||
D::Research(research) => {
|
||||
lines.push(&research.claim.0);
|
||||
lines.push(&research.detail.0);
|
||||
|
|
|
|||
|
|
@ -148,6 +148,7 @@ pub enum PipelineFacts {
|
|||
Run { label: Label, operated_by: RunOperator, turn: RunTurn, started_on: Date, claims: Vec<PipelineRef> },
|
||||
Pulse { label: Label, tempo_vote_beat_s: Option<u32>, #[serde(default)] tempo_vote_withdrawn: bool, urgency_permille: Option<u16> },
|
||||
Reply { label: Label, run: PipelineRef, answers: Vec<PipelineRef> },
|
||||
Thought { label: Label, chosen: u8, nearest_permille: u16 },
|
||||
Memory { label: Label, sort: MemorySort, about: Vec<Short>, origin: MemoryOrigin, salience_permille: u16 },
|
||||
Research { pass: Label, label: Label, claim: Line, inferred: bool, observed_on: Date },
|
||||
Idea { pass: Label, label: Label, title: Title, proposed_on: Date },
|
||||
|
|
@ -256,6 +257,11 @@ impl PipelineFacts {
|
|||
urgency_permille: value.urgency_permille,
|
||||
},
|
||||
D::Reply(value) => Self::Reply { label: value.label.clone(), run: value.run.clone(), answers: value.answers.clone() },
|
||||
D::Thought(value) => Self::Thought {
|
||||
label: value.label.clone(),
|
||||
chosen: value.chosen,
|
||||
nearest_permille: value.nearest_permille.get(usize::from(value.chosen)).copied().unwrap_or(1000),
|
||||
},
|
||||
D::Memory(value) => Self::Memory {
|
||||
label: value.label.clone(),
|
||||
sort: value.sort,
|
||||
|
|
@ -1702,6 +1708,16 @@ mod tests {
|
|||
|
||||
/// One edge list: every role's edge comes out of the hop, typed by the
|
||||
/// role and the ends' kinds.
|
||||
#[test]
|
||||
fn a_thoughts_facts_carry_the_chosen_candidates_nearness() {
|
||||
let D::Thought(mut thought) = crate::fixtures::thought("t1", "A.", &[]) else { unreachable!() };
|
||||
thought.candidates.push("B.".into());
|
||||
thought.nearest_permille = vec![300, 450];
|
||||
thought.chosen = 1;
|
||||
thought.text = "B.".into();
|
||||
assert_eq!(PipelineFacts::of(&D::Thought(thought)), PipelineFacts::Thought { label: "t1".into(), chosen: 1, nearest_permille: 450 });
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn every_role_yields_its_edge() {
|
||||
let mut mind = seeded();
|
||||
|
|
@ -1742,6 +1758,8 @@ mod tests {
|
|||
committed(admit(&mut mind, vec![D::Reply(eureka_pipeline::PipelineReply {
|
||||
instance: INSTANCE.into(), label: "w1-r1".into(), run: r(K::Run, &run_id), answers: vec![r(K::FollowUp, &fu)], text: "Done.".into(),
|
||||
})]));
|
||||
let thought_id = format!("{INSTANCE}:thought:t1");
|
||||
committed(admit(&mut mind, vec![crate::fixtures::thought("t1", "A drift.", &[r(K::Finding, &f1), r(K::Question, &q1)])]));
|
||||
let (older, newer) = (format!("{INSTANCE}:memory:m1"), format!("{INSTANCE}:memory:m2"));
|
||||
committed(admit(&mut mind, vec![memory("m1", MemorySort::Idea, "one", &[])]));
|
||||
let D::Memory(mut consolidating) = memory("m2", MemorySort::Idea, "two", &[]) else { unreachable!() };
|
||||
|
|
@ -1792,13 +1810,15 @@ mod tests {
|
|||
(CitationRole::Claims, &run_id, &spec_r2),
|
||||
(CitationRole::Claims, &run_id, &fu),
|
||||
(CitationRole::Run, &reply_id, &run_id),
|
||||
(CitationRole::Reads, &thought_id, &f1),
|
||||
(CitationRole::Reads, &thought_id, &q1),
|
||||
(CitationRole::Consolidates, &newer, &older),
|
||||
(CitationRole::Serves, ¬e, &q1),
|
||||
(CitationRole::Sources, ¬e, &f1),
|
||||
(CitationRole::RestsOn, &way, ¬e),
|
||||
(CitationRole::Toward, &way, &q1),
|
||||
];
|
||||
assert_eq!(CitationRole::ALL.len(), 22);
|
||||
assert_eq!(CitationRole::ALL.len(), 23);
|
||||
for role in CitationRole::ALL {
|
||||
let selection =
|
||||
Selection { cited: Some(Incoming { role: role.name().into(), exists: true }), ..Selection::default() };
|
||||
|
|
|
|||
|
|
@ -244,7 +244,7 @@ impl SelectionRow {
|
|||
D::FollowUp(follow_up) => vec![follow_up.repo.identity()],
|
||||
D::Stewardship(stewardship) => vec![stewardship.repo.identity()],
|
||||
D::HandOff(hand_off) => vec![hand_off.repo.identity()],
|
||||
D::Target(_) | D::Question(_) | D::Ruling(_) | D::Verdict(_) | D::Finding(_) | D::Instance(_) | D::Resolution(_) | D::Run(_) | D::Pulse(_) | D::Reply(_) | D::Memory(_) | D::Research(_) | D::Idea(_) => {
|
||||
D::Target(_) | D::Question(_) | D::Ruling(_) | D::Verdict(_) | D::Finding(_) | D::Instance(_) | D::Resolution(_) | D::Run(_) | D::Pulse(_) | D::Reply(_) | D::Thought(_) | D::Memory(_) | D::Research(_) | D::Idea(_) => {
|
||||
Vec::new()
|
||||
}
|
||||
},
|
||||
|
|
@ -329,7 +329,7 @@ impl Row for SelectionRow {
|
|||
}
|
||||
}
|
||||
|
||||
/// The organ's closed lists: nineteen schemas, twenty aliases, twenty-two roles.
|
||||
/// The organ's closed lists: twenty schemas, twenty aliases, twenty-three roles.
|
||||
/// A schema's name is its id, so the substrate's alias matching resolves
|
||||
/// nothing beyond exact ids.
|
||||
pub(crate) struct Vocabulary;
|
||||
|
|
@ -375,7 +375,7 @@ fn invalid(field: impl Into<String>, value: &str, message: impl Into<String>) ->
|
|||
/// because `OrgRepo` identity is case-insensitive.
|
||||
///
|
||||
/// Refuses, naming the field the client sent: a `schemas` entry that is not
|
||||
/// one of the nineteen ids; a `keys` entry that is not a full id whose kind
|
||||
/// one of the twenty ids; a `keys` entry that is not a full id whose kind
|
||||
/// segment reads and passes the leaf's ref grammar; an `any_of` value outside
|
||||
/// its alias's domain; and a `cites.target` whose key fails the ref grammar
|
||||
/// for its schema's kind (V24's rule, at this door). Whether the target
|
||||
|
|
@ -442,7 +442,7 @@ mod tests {
|
|||
/// refused at the substrate's door.
|
||||
#[test]
|
||||
fn each_kind_declares_exactly_its_aliases_and_none_is_numeric() {
|
||||
let table: [(K, &[&str]); 19] = [
|
||||
let table: [(K, &[&str]); 20] = [
|
||||
(K::Campaign, &["repo"]),
|
||||
(K::Target, &[]),
|
||||
(K::Question, &[]),
|
||||
|
|
@ -462,6 +462,7 @@ mod tests {
|
|||
(K::Research, &["pass"]),
|
||||
(K::Idea, &["pass"]),
|
||||
(K::Reply, &[]),
|
||||
(K::Thought, &[]),
|
||||
];
|
||||
for (kind, extra) in table {
|
||||
let want = [&["root", "in_force", "faculty"][..], extra].concat();
|
||||
|
|
@ -474,10 +475,10 @@ mod tests {
|
|||
|
||||
/// Each role is declared by the one kind whose field carries it, and its
|
||||
/// targets are the kinds that field is typed to, "any" spelled as all
|
||||
/// nineteen.
|
||||
/// twenty.
|
||||
#[test]
|
||||
fn each_kind_declares_the_roles_it_carries_and_their_targets() {
|
||||
let table: [(K, &[&str]); 19] = [
|
||||
let table: [(K, &[&str]); 20] = [
|
||||
(K::Campaign, &[]),
|
||||
(K::Target, &[]),
|
||||
(K::Question, &["raised_in"]),
|
||||
|
|
@ -497,13 +498,14 @@ mod tests {
|
|||
(K::Research, &["serves", "sources"]),
|
||||
(K::Idea, &["rests_on", "toward"]),
|
||||
(K::Reply, &["run"]),
|
||||
(K::Thought, &["reads"]),
|
||||
];
|
||||
for (kind, roles) in table {
|
||||
assert_eq!(sorted(Vocabulary.declared_roles(kind.type_id())), strings(roles), "{kind:?}");
|
||||
}
|
||||
assert_eq!(Vocabulary.target_leaves("answers"), vec![K::Question.type_id().to_string()]);
|
||||
assert_eq!(Vocabulary.target_leaves("rulings"), vec![K::Ruling.type_id().to_string()]);
|
||||
assert_eq!(Vocabulary.target_leaves("subject").len(), 19);
|
||||
assert_eq!(Vocabulary.target_leaves("subject").len(), 20);
|
||||
assert_eq!(
|
||||
sorted(Vocabulary.target_leaves("claims")),
|
||||
sorted([K::CutSpec, K::Finding, K::FollowUp].iter().map(|kind| kind.type_id().to_string()).collect())
|
||||
|
|
|
|||
|
|
@ -176,7 +176,8 @@
|
|||
"Memory",
|
||||
"Research",
|
||||
"Idea",
|
||||
"Reply"
|
||||
"Reply",
|
||||
"Thought"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -70,7 +70,8 @@
|
|||
"Memory",
|
||||
"Research",
|
||||
"Idea",
|
||||
"Reply"
|
||||
"Reply",
|
||||
"Thought"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -35,7 +35,8 @@
|
|||
"Memory",
|
||||
"Research",
|
||||
"Idea",
|
||||
"Reply"
|
||||
"Reply",
|
||||
"Thought"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -131,7 +131,8 @@
|
|||
"Memory",
|
||||
"Research",
|
||||
"Idea",
|
||||
"Reply"
|
||||
"Reply",
|
||||
"Thought"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -40,7 +40,8 @@
|
|||
"Memory",
|
||||
"Research",
|
||||
"Idea",
|
||||
"Reply"
|
||||
"Reply",
|
||||
"Thought"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -30,7 +30,8 @@
|
|||
"Memory",
|
||||
"Research",
|
||||
"Idea",
|
||||
"Reply"
|
||||
"Reply",
|
||||
"Thought"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -102,7 +102,8 @@
|
|||
"Memory",
|
||||
"Research",
|
||||
"Idea",
|
||||
"Reply"
|
||||
"Reply",
|
||||
"Thought"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -35,7 +35,8 @@
|
|||
"Memory",
|
||||
"Research",
|
||||
"Idea",
|
||||
"Reply"
|
||||
"Reply",
|
||||
"Thought"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -73,7 +73,8 @@
|
|||
"Memory",
|
||||
"Research",
|
||||
"Idea",
|
||||
"Reply"
|
||||
"Reply",
|
||||
"Thought"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -30,7 +30,8 @@
|
|||
"Memory",
|
||||
"Research",
|
||||
"Idea",
|
||||
"Reply"
|
||||
"Reply",
|
||||
"Thought"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
|
|
|
|||
186
schemas/cultnet/epiphany.pipeline.thought.v2.schema.json
Normal file
186
schemas/cultnet/epiphany.pipeline.thought.v2.schema.json
Normal file
|
|
@ -0,0 +1,186 @@
|
|||
{
|
||||
"$defs": {
|
||||
"Label": {
|
||||
"description": "A key label: `[A-Za-z0-9_-]{1,64}`.",
|
||||
"maxLength": 64,
|
||||
"type": "string"
|
||||
},
|
||||
"Line": {
|
||||
"description": "Text of at most 1,000 UTF-8 bytes.",
|
||||
"maxLength": 1000,
|
||||
"type": "string"
|
||||
},
|
||||
"Para": {
|
||||
"description": "Text of at most 4,000 UTF-8 bytes; longer narrative is cited by `DocRef`.",
|
||||
"maxLength": 4000,
|
||||
"type": "string"
|
||||
},
|
||||
"PipelineKind": {
|
||||
"enum": [
|
||||
"Campaign",
|
||||
"Target",
|
||||
"Question",
|
||||
"Ruling",
|
||||
"CutSpec",
|
||||
"CutReport",
|
||||
"Verdict",
|
||||
"Finding",
|
||||
"FollowUp",
|
||||
"Resolution",
|
||||
"Instance",
|
||||
"Stewardship",
|
||||
"HandOff",
|
||||
"Run",
|
||||
"Pulse",
|
||||
"Memory",
|
||||
"Research",
|
||||
"Idea",
|
||||
"Reply",
|
||||
"Thought"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"PipelineRef": {
|
||||
"description": "A reference to another document. The id is parsed as a full pipeline id of\nthe declared `kind`, so the kind and the id's kind segment cannot disagree.",
|
||||
"properties": {
|
||||
"id": {
|
||||
"$ref": "#/$defs/Short"
|
||||
},
|
||||
"kind": {
|
||||
"$ref": "#/$defs/PipelineKind"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"kind",
|
||||
"id"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"Short": {
|
||||
"description": "Text of at most 200 UTF-8 bytes.",
|
||||
"maxLength": 200,
|
||||
"type": "string"
|
||||
},
|
||||
"Slug": {
|
||||
"description": "A campaign slug or key segment: label parts joined by `.`.",
|
||||
"maxLength": 64,
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"$id": "https://gamecult.dev/epiphany/cultnet/epiphany.pipeline.thought.v2.schema.json",
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"description": "One tick of her stream of thought, offline: the words a base model\ncontinued from a projection of her own state, with the whole trace that\nmade them (the seed, the projection, every candidate and how near each\nwas to her earlier thoughts). `text` is the chosen candidate. `reads`\nare the documents the seed was drawn from. A thought is divergence for\ndelivery to weigh, never a memory: its words reach a later seed only\nthrough something she wrote. Instance-rooted: the key is\n`<instance>:thought:<label>`, the label `t<unix seconds>` of the tick.\nSemantically indexed on `text` only. `nearest_permille` is 1000 where she\nhad no earlier thought.",
|
||||
"properties": {
|
||||
"base_model": {
|
||||
"$ref": "#/$defs/Short"
|
||||
},
|
||||
"candidates": {
|
||||
"items": {
|
||||
"$ref": "#/$defs/Line"
|
||||
},
|
||||
"maxItems": 4,
|
||||
"type": "array"
|
||||
},
|
||||
"chosen": {
|
||||
"format": "uint8",
|
||||
"maximum": 255,
|
||||
"minimum": 0,
|
||||
"type": "integer"
|
||||
},
|
||||
"context": {
|
||||
"$ref": "#/$defs/Para"
|
||||
},
|
||||
"continuer_ms": {
|
||||
"format": "uint32",
|
||||
"minimum": 0,
|
||||
"type": "integer"
|
||||
},
|
||||
"identity": {
|
||||
"$ref": "#/$defs/Line"
|
||||
},
|
||||
"instance": {
|
||||
"$ref": "#/$defs/Slug"
|
||||
},
|
||||
"label": {
|
||||
"$ref": "#/$defs/Label"
|
||||
},
|
||||
"max_tokens": {
|
||||
"format": "uint16",
|
||||
"maximum": 65535,
|
||||
"minimum": 0,
|
||||
"type": "integer"
|
||||
},
|
||||
"min_p_permille": {
|
||||
"format": "uint16",
|
||||
"maximum": 65535,
|
||||
"minimum": 0,
|
||||
"type": "integer"
|
||||
},
|
||||
"nearest_permille": {
|
||||
"items": {
|
||||
"format": "uint16",
|
||||
"maximum": 65535,
|
||||
"minimum": 0,
|
||||
"type": "integer"
|
||||
},
|
||||
"maxItems": 4,
|
||||
"type": "array"
|
||||
},
|
||||
"persona_receipt": {
|
||||
"$ref": "#/$defs/Short"
|
||||
},
|
||||
"projection": {
|
||||
"$ref": "#/$defs/Para"
|
||||
},
|
||||
"projector_model": {
|
||||
"$ref": "#/$defs/Short"
|
||||
},
|
||||
"projector_ms": {
|
||||
"format": "uint32",
|
||||
"minimum": 0,
|
||||
"type": "integer"
|
||||
},
|
||||
"reads": {
|
||||
"items": {
|
||||
"$ref": "#/$defs/PipelineRef"
|
||||
},
|
||||
"maxItems": 64,
|
||||
"type": "array"
|
||||
},
|
||||
"stimulus": {
|
||||
"$ref": "#/$defs/Para"
|
||||
},
|
||||
"temperature_permille": {
|
||||
"format": "uint16",
|
||||
"maximum": 65535,
|
||||
"minimum": 0,
|
||||
"type": "integer"
|
||||
},
|
||||
"text": {
|
||||
"$ref": "#/$defs/Para"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"instance",
|
||||
"label",
|
||||
"text",
|
||||
"reads",
|
||||
"persona_receipt",
|
||||
"identity",
|
||||
"context",
|
||||
"stimulus",
|
||||
"projector_model",
|
||||
"projection",
|
||||
"base_model",
|
||||
"temperature_permille",
|
||||
"min_p_permille",
|
||||
"max_tokens",
|
||||
"candidates",
|
||||
"nearest_permille",
|
||||
"chosen",
|
||||
"projector_ms",
|
||||
"continuer_ms"
|
||||
],
|
||||
"title": "PipelineThought",
|
||||
"type": "object"
|
||||
}
|
||||
|
|
@ -1326,6 +1326,22 @@
|
|||
"kind",
|
||||
"value"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"kind": {
|
||||
"type": "string",
|
||||
"const": "thought"
|
||||
},
|
||||
"value": {
|
||||
"$ref": "#/$defs/PipelineThought"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"kind",
|
||||
"value"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
@ -1580,7 +1596,8 @@
|
|||
"Memory",
|
||||
"Research",
|
||||
"Idea",
|
||||
"Reply"
|
||||
"Reply",
|
||||
"Thought"
|
||||
]
|
||||
},
|
||||
"PipelineMemory": {
|
||||
|
|
@ -2097,6 +2114,121 @@
|
|||
"doc"
|
||||
]
|
||||
},
|
||||
"PipelineThought": {
|
||||
"description": "One tick of her stream of thought, offline: the words a base model\ncontinued from a projection of her own state, with the whole trace that\nmade them (the seed, the projection, every candidate and how near each\nwas to her earlier thoughts). `text` is the chosen candidate. `reads`\nare the documents the seed was drawn from. A thought is divergence for\ndelivery to weigh, never a memory: its words reach a later seed only\nthrough something she wrote. Instance-rooted: the key is\n`<instance>:thought:<label>`, the label `t<unix seconds>` of the tick.\nSemantically indexed on `text` only. `nearest_permille` is 1000 where she\nhad no earlier thought.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"base_model": {
|
||||
"$ref": "#/$defs/Short"
|
||||
},
|
||||
"candidates": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/$defs/Line"
|
||||
},
|
||||
"maxItems": 4
|
||||
},
|
||||
"chosen": {
|
||||
"type": "integer",
|
||||
"format": "uint8",
|
||||
"maximum": 255,
|
||||
"minimum": 0
|
||||
},
|
||||
"context": {
|
||||
"$ref": "#/$defs/Para"
|
||||
},
|
||||
"continuer_ms": {
|
||||
"type": "integer",
|
||||
"format": "uint32",
|
||||
"minimum": 0
|
||||
},
|
||||
"identity": {
|
||||
"$ref": "#/$defs/Line"
|
||||
},
|
||||
"instance": {
|
||||
"$ref": "#/$defs/Slug"
|
||||
},
|
||||
"label": {
|
||||
"$ref": "#/$defs/Label"
|
||||
},
|
||||
"max_tokens": {
|
||||
"type": "integer",
|
||||
"format": "uint16",
|
||||
"maximum": 65535,
|
||||
"minimum": 0
|
||||
},
|
||||
"min_p_permille": {
|
||||
"type": "integer",
|
||||
"format": "uint16",
|
||||
"maximum": 65535,
|
||||
"minimum": 0
|
||||
},
|
||||
"nearest_permille": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "integer",
|
||||
"format": "uint16",
|
||||
"maximum": 65535,
|
||||
"minimum": 0
|
||||
},
|
||||
"maxItems": 4
|
||||
},
|
||||
"persona_receipt": {
|
||||
"$ref": "#/$defs/Short"
|
||||
},
|
||||
"projection": {
|
||||
"$ref": "#/$defs/Para"
|
||||
},
|
||||
"projector_model": {
|
||||
"$ref": "#/$defs/Short"
|
||||
},
|
||||
"projector_ms": {
|
||||
"type": "integer",
|
||||
"format": "uint32",
|
||||
"minimum": 0
|
||||
},
|
||||
"reads": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/$defs/PipelineRef"
|
||||
},
|
||||
"maxItems": 64
|
||||
},
|
||||
"stimulus": {
|
||||
"$ref": "#/$defs/Para"
|
||||
},
|
||||
"temperature_permille": {
|
||||
"type": "integer",
|
||||
"format": "uint16",
|
||||
"maximum": 65535,
|
||||
"minimum": 0
|
||||
},
|
||||
"text": {
|
||||
"$ref": "#/$defs/Para"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"instance",
|
||||
"label",
|
||||
"text",
|
||||
"reads",
|
||||
"persona_receipt",
|
||||
"identity",
|
||||
"context",
|
||||
"stimulus",
|
||||
"projector_model",
|
||||
"projection",
|
||||
"base_model",
|
||||
"temperature_permille",
|
||||
"min_p_permille",
|
||||
"max_tokens",
|
||||
"candidates",
|
||||
"nearest_permille",
|
||||
"chosen",
|
||||
"projector_ms",
|
||||
"continuer_ms"
|
||||
]
|
||||
},
|
||||
"PipelineVerdict": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
|
|
|||
|
|
@ -261,7 +261,8 @@
|
|||
"sources",
|
||||
"rests_on",
|
||||
"toward",
|
||||
"run"
|
||||
"run",
|
||||
"reads"
|
||||
]
|
||||
},
|
||||
"ClaimOutcome": {
|
||||
|
|
@ -2629,6 +2630,22 @@
|
|||
"kind",
|
||||
"value"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"kind": {
|
||||
"type": "string",
|
||||
"const": "thought"
|
||||
},
|
||||
"value": {
|
||||
"$ref": "#/$defs/PipelineThought"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"kind",
|
||||
"value"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
@ -3382,6 +3399,44 @@
|
|||
"value"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"kind": {
|
||||
"type": "string",
|
||||
"const": "thought"
|
||||
},
|
||||
"value": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"chosen": {
|
||||
"type": "integer",
|
||||
"format": "uint8",
|
||||
"maximum": 255,
|
||||
"minimum": 0
|
||||
},
|
||||
"label": {
|
||||
"$ref": "#/$defs/Label"
|
||||
},
|
||||
"nearest_permille": {
|
||||
"type": "integer",
|
||||
"format": "uint16",
|
||||
"maximum": 65535,
|
||||
"minimum": 0
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"label",
|
||||
"chosen",
|
||||
"nearest_permille"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"kind",
|
||||
"value"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
|
@ -3757,7 +3812,8 @@
|
|||
"Memory",
|
||||
"Research",
|
||||
"Idea",
|
||||
"Reply"
|
||||
"Reply",
|
||||
"Thought"
|
||||
]
|
||||
},
|
||||
"PipelineMemory": {
|
||||
|
|
@ -4561,6 +4617,121 @@
|
|||
"doc"
|
||||
]
|
||||
},
|
||||
"PipelineThought": {
|
||||
"description": "One tick of her stream of thought, offline: the words a base model\ncontinued from a projection of her own state, with the whole trace that\nmade them (the seed, the projection, every candidate and how near each\nwas to her earlier thoughts). `text` is the chosen candidate. `reads`\nare the documents the seed was drawn from. A thought is divergence for\ndelivery to weigh, never a memory: its words reach a later seed only\nthrough something she wrote. Instance-rooted: the key is\n`<instance>:thought:<label>`, the label `t<unix seconds>` of the tick.\nSemantically indexed on `text` only. `nearest_permille` is 1000 where she\nhad no earlier thought.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"base_model": {
|
||||
"$ref": "#/$defs/Short"
|
||||
},
|
||||
"candidates": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/$defs/Line"
|
||||
},
|
||||
"maxItems": 4
|
||||
},
|
||||
"chosen": {
|
||||
"type": "integer",
|
||||
"format": "uint8",
|
||||
"maximum": 255,
|
||||
"minimum": 0
|
||||
},
|
||||
"context": {
|
||||
"$ref": "#/$defs/Para"
|
||||
},
|
||||
"continuer_ms": {
|
||||
"type": "integer",
|
||||
"format": "uint32",
|
||||
"minimum": 0
|
||||
},
|
||||
"identity": {
|
||||
"$ref": "#/$defs/Line"
|
||||
},
|
||||
"instance": {
|
||||
"$ref": "#/$defs/Slug"
|
||||
},
|
||||
"label": {
|
||||
"$ref": "#/$defs/Label"
|
||||
},
|
||||
"max_tokens": {
|
||||
"type": "integer",
|
||||
"format": "uint16",
|
||||
"maximum": 65535,
|
||||
"minimum": 0
|
||||
},
|
||||
"min_p_permille": {
|
||||
"type": "integer",
|
||||
"format": "uint16",
|
||||
"maximum": 65535,
|
||||
"minimum": 0
|
||||
},
|
||||
"nearest_permille": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "integer",
|
||||
"format": "uint16",
|
||||
"maximum": 65535,
|
||||
"minimum": 0
|
||||
},
|
||||
"maxItems": 4
|
||||
},
|
||||
"persona_receipt": {
|
||||
"$ref": "#/$defs/Short"
|
||||
},
|
||||
"projection": {
|
||||
"$ref": "#/$defs/Para"
|
||||
},
|
||||
"projector_model": {
|
||||
"$ref": "#/$defs/Short"
|
||||
},
|
||||
"projector_ms": {
|
||||
"type": "integer",
|
||||
"format": "uint32",
|
||||
"minimum": 0
|
||||
},
|
||||
"reads": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/$defs/PipelineRef"
|
||||
},
|
||||
"maxItems": 64
|
||||
},
|
||||
"stimulus": {
|
||||
"$ref": "#/$defs/Para"
|
||||
},
|
||||
"temperature_permille": {
|
||||
"type": "integer",
|
||||
"format": "uint16",
|
||||
"maximum": 65535,
|
||||
"minimum": 0
|
||||
},
|
||||
"text": {
|
||||
"$ref": "#/$defs/Para"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"instance",
|
||||
"label",
|
||||
"text",
|
||||
"reads",
|
||||
"persona_receipt",
|
||||
"identity",
|
||||
"context",
|
||||
"stimulus",
|
||||
"projector_model",
|
||||
"projection",
|
||||
"base_model",
|
||||
"temperature_permille",
|
||||
"min_p_permille",
|
||||
"max_tokens",
|
||||
"candidates",
|
||||
"nearest_permille",
|
||||
"chosen",
|
||||
"projector_ms",
|
||||
"continuer_ms"
|
||||
]
|
||||
},
|
||||
"PipelineVerdict": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
|
|
|||
|
|
@ -221,6 +221,17 @@
|
|||
"title": "Epiphany Pipeline Reply v2",
|
||||
"path": "epiphany.pipeline.reply.v2.schema.json"
|
||||
},
|
||||
{
|
||||
"schemaId": "https://gamecult.dev/epiphany/cultnet/epiphany.pipeline.thought.v2.schema.json",
|
||||
"kind": "document_payload",
|
||||
"wireContracts": [
|
||||
"cultnet.schema.v0"
|
||||
],
|
||||
"schemaVersion": "epiphany.pipeline.thought.v2",
|
||||
"documentType": "epiphany.pipeline.thought.v2",
|
||||
"title": "Epiphany Pipeline Thought v2",
|
||||
"path": "epiphany.pipeline.thought.v2.schema.json"
|
||||
},
|
||||
{
|
||||
"schemaId": "huginn.mind_request.v1",
|
||||
"kind": "wire_message",
|
||||
|
|
|
|||
Loading…
Reference in a new issue