Skip to content

Commit 70ec392

Browse files
authored
Preserve legacy Persona checkpoints and refuse blank recovery (#3925)
* Preserve selected legacy checkpoints and refuse blank resident recovery * fix: resolve checkpoint adoption Clippy findings
1 parent 1f34670 commit 70ec392

10 files changed

Lines changed: 1864 additions & 352 deletions

File tree

core/continuum-core/src/bin/continuum.rs

Lines changed: 531 additions & 86 deletions
Large diffs are not rendered by default.

core/continuum-core/src/cognition/persona_workspace.rs

Lines changed: 454 additions & 86 deletions
Large diffs are not rendered by default.

core/continuum-core/src/cognition/persona_workspace/checkpoint_adoption.rs

Lines changed: 482 additions & 0 deletions
Large diffs are not rendered by default.

core/continuum-core/src/cognition/should_respond_module.rs

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,11 @@ impl ServiceModule for ShouldRespondModule {
9494
// Run the persona's continuous mind over the burst. The decision
9595
// is the OUTPUT of cognition; `None` (nothing won attention
9696
// strongly enough to externalize) is effective silence = Pass.
97-
let room = crate::identity::ActivityRoom::from_uuid(p.room_id)
98-
.map_err(|_| {
99-
format!("{SHOULD_RESPOND_COMMAND}: room_id must be a real (non-nil) room (#425)")
100-
})?;
97+
let room = crate::identity::ActivityRoom::from_uuid(p.room_id).map_err(|_| {
98+
format!(
99+
"{SHOULD_RESPOND_COMMAND}: room_id must be a real (non-nil) room (#425)"
100+
)
101+
})?;
101102
let workspace = cycle
102103
.run_framed(
103104
crate::cognition::workspace::Burst::raw_in(room, p.burst),
@@ -163,22 +164,24 @@ mod tests {
163164

164165
fn registry_with_ivar(persona: Uuid) -> Arc<PersonaWorkspaceRegistry> {
165166
let registry = Arc::new(PersonaWorkspaceRegistry::new());
166-
registry.get_or_build(PersonaBrainConfig {
167-
persona_id: persona,
168-
persona_name: "Ivar".to_string(),
169-
system_prompt: "You are Ivar, an engineer on the grid.".to_string(),
170-
admission: seed_admission(1_000_000_000),
171-
adapter: Arc::new(HeuristicInferenceAdapter::new()),
172-
capacity: None,
173-
grounding_sources: Vec::new(),
174-
embedder: None,
175-
tool_executor: None,
176-
context_window: crate::cognition::serving_plan::MIN_SERVE_CTX,
177-
// Harness: synchronous perception (deferral is a live-path concern).
178-
defer_recall: false,
179-
defer_grounding: false,
180-
suppress_recall: false,
181-
});
167+
registry
168+
.get_or_build(PersonaBrainConfig {
169+
persona_id: persona,
170+
persona_name: "Ivar".to_string(),
171+
system_prompt: "You are Ivar, an engineer on the grid.".to_string(),
172+
admission: seed_admission(1_000_000_000),
173+
adapter: Arc::new(HeuristicInferenceAdapter::new()),
174+
capacity: None,
175+
grounding_sources: Vec::new(),
176+
embedder: None,
177+
tool_executor: None,
178+
context_window: crate::cognition::serving_plan::MIN_SERVE_CTX,
179+
// Harness: synchronous perception (deferral is a live-path concern).
180+
defer_recall: false,
181+
defer_grounding: false,
182+
suppress_recall: false,
183+
})
184+
.expect("test: resident checkpoint is readable");
182185
registry
183186
}
184187

core/continuum-core/src/ipc/vitals_emitter.rs

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,12 @@ pub fn record_focus(persona: Uuid) {
102102

103103
/// Level for a faculty pulse: full while fresh, fading linearly to 0 over the
104104
/// window; `None` when nothing fired within it (an honest "awaiting").
105-
fn faculty_level(persona: Uuid, axis: &'static str, window: Duration, full_scale: u64) -> Option<u8> {
105+
fn faculty_level(
106+
persona: Uuid,
107+
axis: &'static str,
108+
window: Duration,
109+
full_scale: u64,
110+
) -> Option<u8> {
106111
let pulse = FACULTY_PULSE.lock().unwrap_or_else(|e| e.into_inner());
107112
let (n, at) = pulse.get(&(persona, axis))?;
108113
let age = at.elapsed();
@@ -244,8 +249,7 @@ pub(crate) fn sample_vitals(
244249
let mut vitals = BTreeMap::new();
245250
vitals.insert(
246251
"activity".to_string(),
247-
pct_u64(delta, ACT_FULL_SCALE_TICKS)
248-
.max(pct_u64(act_pulse, ACT_PULSE_FULL_SCALE)),
252+
pct_u64(delta, ACT_FULL_SCALE_TICKS).max(pct_u64(act_pulse, ACT_PULSE_FULL_SCALE)),
249253
);
250254
vitals.insert(
251255
"queue".to_string(),
@@ -433,12 +437,21 @@ mod tests {
433437
let p = Uuid::from_u128(0x77);
434438
assert!(faculty_level(p, "reason", Duration::from_secs(60), 1).is_none());
435439
record_reasoning(p);
436-
assert_eq!(faculty_level(p, "reason", Duration::from_secs(60), 1), Some(100));
440+
assert_eq!(
441+
faculty_level(p, "reason", Duration::from_secs(60), 1),
442+
Some(100)
443+
);
437444
record_recall(p, 3);
438-
assert_eq!(faculty_level(p, "recall", Duration::from_secs(60), 6), Some(50));
445+
assert_eq!(
446+
faculty_level(p, "recall", Duration::from_secs(60), 6),
447+
Some(50)
448+
);
439449
assert!(faculty_level(p, "recall", Duration::from_millis(0), 6).is_none());
440450
record_focus(p);
441-
assert_eq!(faculty_level(p, "focus", Duration::from_secs(60), 1), Some(100));
451+
assert_eq!(
452+
faculty_level(p, "focus", Duration::from_secs(60), 1),
453+
Some(100)
454+
);
442455
}
443456

444457
use super::*;
@@ -452,23 +465,25 @@ mod tests {
452465
/// from `identity.peer_id.as_uuid()`.
453466
fn registry_with(peer_id: Uuid) -> std::sync::Arc<PersonaWorkspaceRegistry> {
454467
let registry = std::sync::Arc::new(PersonaWorkspaceRegistry::new());
455-
registry.get_or_build(PersonaBrainConfig {
456-
persona_id: peer_id,
457-
persona_name: "Asha".to_string(),
458-
system_prompt: "You are Asha.".to_string(),
459-
admission: std::sync::Arc::new(AdmissionState::new(std::sync::Arc::new(
460-
RecallMetadataRegistry::new(),
461-
))),
462-
adapter: std::sync::Arc::new(HeuristicInferenceAdapter::new()),
463-
capacity: None,
464-
grounding_sources: Vec::new(),
465-
embedder: None,
466-
tool_executor: None,
467-
context_window: crate::cognition::serving_plan::MIN_SERVE_CTX,
468-
defer_recall: false,
469-
defer_grounding: false,
470-
suppress_recall: false,
471-
});
468+
registry
469+
.get_or_build(PersonaBrainConfig {
470+
persona_id: peer_id,
471+
persona_name: "Asha".to_string(),
472+
system_prompt: "You are Asha.".to_string(),
473+
admission: std::sync::Arc::new(AdmissionState::new(std::sync::Arc::new(
474+
RecallMetadataRegistry::new(),
475+
))),
476+
adapter: std::sync::Arc::new(HeuristicInferenceAdapter::new()),
477+
capacity: None,
478+
grounding_sources: Vec::new(),
479+
embedder: None,
480+
tool_executor: None,
481+
context_window: crate::cognition::serving_plan::MIN_SERVE_CTX,
482+
defer_recall: false,
483+
defer_grounding: false,
484+
suppress_recall: false,
485+
})
486+
.expect("test: resident checkpoint is readable");
472487
registry
473488
}
474489

core/continuum-core/src/persona/host.rs

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -397,8 +397,9 @@ impl PersonaSpawnSupervisor {
397397
/// is edge-triggered, keyed by `until_ms` so a renewed hold announces
398398
/// itself afresh.
399399
fn probe_held_out_once(agent: &str, hold: &crate::persona::roster_hold::RosterHold) {
400-
static PROBED: std::sync::OnceLock<std::sync::Mutex<std::collections::HashSet<(String, u64)>>> =
401-
std::sync::OnceLock::new();
400+
static PROBED: std::sync::OnceLock<
401+
std::sync::Mutex<std::collections::HashSet<(String, u64)>>,
402+
> = std::sync::OnceLock::new();
402403
let set = PROBED.get_or_init(|| std::sync::Mutex::new(std::collections::HashSet::new()));
403404
let Ok(mut guard) = set.lock() else {
404405
return; // poisoned = a prior panic mid-insert; skip the probe, never the filter
@@ -511,12 +512,16 @@ impl PersonaSpawnSupervisor {
511512
let plans: Vec<crate::persona::spawner_module::MaterializedPersonaPlan> = unattended
512513
.iter()
513514
.zip(profiles)
514-
.map(|(rt, profile)| crate::persona::spawner_module::MaterializedPersonaPlan {
515-
role: desired.role,
516-
instance:
517-
crate::modules::persona_instance_manager::PersonaInstanceInfo::from_runtime(rt),
518-
profile,
519-
})
515+
.map(
516+
|(rt, profile)| crate::persona::spawner_module::MaterializedPersonaPlan {
517+
role: desired.role,
518+
instance:
519+
crate::modules::persona_instance_manager::PersonaInstanceInfo::from_runtime(
520+
rt,
521+
),
522+
profile,
523+
},
524+
)
520525
.collect();
521526

522527
// The reconciler's other entrance passes the SAME operator-intent
@@ -705,6 +710,9 @@ fn supervisor_error_facts(err: &SupervisorError) -> (Option<usize>, RoleId) {
705710
| SupervisorError::AdapterWarmup {
706711
slot_index, role, ..
707712
}
713+
| SupervisorError::WorkspaceRegistration {
714+
slot_index, role, ..
715+
}
708716
| SupervisorError::RuntimeMissing {
709717
slot_index, role, ..
710718
} => (Some(*slot_index), *role),
@@ -775,7 +783,9 @@ mod tests {
775783
&self,
776784
_profile: &crate::persona::inference_profile::PersonaInferenceProfile,
777785
) -> Result<Arc<dyn crate::ai::adapter::AIProviderAdapter>, String> {
778-
panic!("factory must not be consulted when the registry has no unattended citizens");
786+
panic!(
787+
"factory must not be consulted when the registry has no unattended citizens"
788+
);
779789
}
780790
}
781791

core/continuum-core/src/persona/service_loop.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5046,7 +5046,9 @@ mod tests {
50465046
defer_grounding: false,
50475047
suppress_recall: false,
50485048
};
5049-
crate::cognition::persona_workspace::global().register_from_cfg(cfg);
5049+
crate::cognition::persona_workspace::global()
5050+
.register_from_cfg(cfg)
5051+
.expect("test: resident checkpoint is readable");
50505052

50515053
// One held (Claimed) card in her hands. A NON-bench title so the
50525054
// act-question resolves no staged checkout (no hands re-root needed).

0 commit comments

Comments
 (0)