use std::collections::HashSet;
use std::path::Path;
use crate::paths::state::StateLayout;
use crate::state::runtime as runtime_state;
use crate::state::session_gates;
use crate::timestamps;
use anyhow::Result;
use serde::{Deserialize, Serialize};
use sha2::{Digest, Sha256};
const SCHEMA_VERSION: u32 = 5;
const DEFAULT_MAX_ACTIVE_MEMORY_ENTRIES_PER_SCOPE: usize = 12;
const DEFAULT_MAX_ACTIVE_WORKFLOW_SIGNAL_ITEMS: usize = 8;
const DEFAULT_MAX_ACTIVE_HANDOFF_ITEMS_PER_SECTION: usize = 8;
pub(crate) const SESSION_RENDER_SURFACE_ORDER: &[&str] = &[
"effective_memory",
"workflow_signal",
"handoff",
"execution_gates",
"escalation",
"recovery",
"git_state",
"session_state",
];
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)]
pub struct ProjectionDigests {
pub effective_memory: String,
#[serde(alias = "repo_focus")]
pub workflow_signal: String,
pub handoff: String,
#[serde(default)]
pub execution_gates: String,
#[serde(default)]
pub escalation: String,
#[serde(default)]
pub recovery: String,
#[serde(default)]
pub git_state: String,
#[serde(default)]
pub session_state: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CompiledStateStore {
pub schema_version: u32,
#[serde(default = "default_projection_target")]
pub target: ProjectionTarget,
pub source_fingerprint: String,
#[serde(default)]
pub pod_identity_active: bool,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub projection_digests: Option<ProjectionDigests>,
pub effective_memory: CompiledMemoryView,
#[serde(alias = "repo_focus_active")]
pub workflow_signal_active: Vec<String>,
pub handoff: CompiledHandoffView,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CompiledMemoryView {
pub profile: Vec<String>,
#[serde(alias = "repo")]
pub locality: Vec<String>,
#[serde(default)]
pub pod: Vec<String>,
#[serde(default)]
pub branch: Vec<String>,
#[serde(default)]
pub clone: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CompiledHandoffView {
pub title: String,
pub immediate_actions: Vec<String>,
pub completed_state: Vec<String>,
pub operational_guardrails: Vec<String>,
pub key_files: Vec<String>,
pub definition_of_done: Vec<String>,
}
#[derive(Debug, Clone, Serialize)]
pub struct CompiledStateSurfaceView {
pub path: String,
pub status: &'static str,
pub schema_version: u32,
pub target: &'static str,
pub source_fingerprint: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub refresh_reason: Option<&'static str>,
}
pub struct PreparedCompiledState {
pub surface: CompiledStateSurfaceView,
pub store: CompiledStateStore,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ProjectionFormat {
Narrative,
Symbolic,
Bundle,
}
impl ProjectionFormat {
pub fn as_str(self) -> &'static str {
match self {
Self::Narrative => "narrative",
Self::Symbolic => "symbolic",
Self::Bundle => "bundle",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ProjectionTarget {
Default,
Planning,
Session,
}
impl ProjectionTarget {
pub fn as_str(self) -> &'static str {
match self {
Self::Default => "default",
Self::Planning => "planning",
Self::Session => "session",
}
}
}
fn persisted_target() -> ProjectionTarget {
ProjectionTarget::Session
}
fn default_projection_target() -> ProjectionTarget {
ProjectionTarget::Default
}
#[derive(Debug, Clone, Copy)]
struct ProjectionBounds {
max_active_memory_entries_per_scope: usize,
max_active_workflow_signal_items: usize,
max_active_handoff_items_per_section: usize,
}
#[cfg_attr(not(test), allow(dead_code))]
pub fn ensure_for_runtime(
layout: &StateLayout,
loaded: &runtime_state::LoadedRuntimeState,
) -> Result<PreparedCompiledState> {
let compiled = compile_loaded_runtime_for_target(loaded, persisted_target())?;
Ok(PreparedCompiledState {
surface: computed_surface_view(layout, &compiled),
store: compiled,
})
}
pub fn refresh_after_write(
repo_root: &Path,
layout: &StateLayout,
locality_id: &str,
) -> Result<CompiledStateStore> {
compile_from_runtime_for_target(repo_root, layout, locality_id, persisted_target())
}
pub fn refresh_after_write_with_loaded(
layout: &StateLayout,
loaded: &runtime_state::LoadedRuntimeState,
) -> Result<CompiledStateStore> {
let _ = layout;
compile_loaded_runtime_for_target(loaded, persisted_target())
}
pub struct StartCompiledResult {
pub compiled: PreparedCompiledState,
pub sources: runtime_state::RuntimeSourceSurfaces,
pub recovery: runtime_state::LoadedRuntimeRecoveryState,
}
fn computed_surface_view(
layout: &StateLayout,
store: &CompiledStateStore,
) -> CompiledStateSurfaceView {
CompiledStateSurfaceView {
path: layout.state_db_path().display().to_string(),
status: "computed",
schema_version: store.schema_version,
target: store.target.as_str(),
source_fingerprint: store.source_fingerprint.clone(),
refresh_reason: None,
}
}
pub fn ensure_for_start(
layout: &StateLayout,
raw: runtime_state::RawRuntimeSources,
) -> Result<StartCompiledResult> {
let loaded = runtime_state::normalize_raw_into_loaded(raw)?;
let compiled = compile_loaded_runtime_for_target(&loaded, persisted_target())?;
Ok(StartCompiledResult {
compiled: PreparedCompiledState {
surface: computed_surface_view(layout, &compiled),
store: compiled,
},
sources: loaded.sources,
recovery: loaded.recovery,
})
}
pub fn compute_projection_digests(store: &CompiledStateStore) -> ProjectionDigests {
ProjectionDigests {
effective_memory: sha256_string(&render_memory_content(
&store.effective_memory,
store.pod_identity_active,
)),
workflow_signal: sha256_string(&render_workflow_signal_content(
&store.workflow_signal_active,
)),
handoff: sha256_string(&render_handoff_content(&store.handoff)),
execution_gates: String::new(),
escalation: String::new(),
recovery: String::new(),
git_state: String::new(),
session_state: String::new(),
}
}
pub fn compute_extended_digests(
base: &ProjectionDigests,
execution_gates_json: &str,
escalation_json: &str,
recovery_json: &str,
git_state_json: &str,
session_state_json: &str,
) -> ProjectionDigests {
ProjectionDigests {
effective_memory: base.effective_memory.clone(),
workflow_signal: base.workflow_signal.clone(),
handoff: base.handoff.clone(),
execution_gates: sha256_string(execution_gates_json),
escalation: sha256_string(escalation_json),
recovery: sha256_string(recovery_json),
git_state: sha256_string(git_state_json),
session_state: sha256_string(session_state_json),
}
}
pub(crate) fn sha256_string(content: &str) -> String {
let mut hasher = Sha256::new();
hasher.update(content.as_bytes());
format!("{:x}", hasher.finalize())
}
pub fn render_memory_content(view: &CompiledMemoryView, pod_identity_active: bool) -> String {
let mut body = String::new();
if pod_identity_active {
append_section(&mut body, "Pod Memory", &view.pod);
append_section(&mut body, "Profile Memory", &view.profile);
append_section(&mut body, "Project Memory", &view.locality);
} else {
append_section(&mut body, "Profile Memory", &view.profile);
append_section(&mut body, "Project Memory", &view.locality);
append_section(&mut body, "Pod Memory", &view.pod);
}
append_section(&mut body, "Work Stream Memory", &view.branch);
append_section(&mut body, "Workspace Memory", &view.clone);
body
}
pub fn render_workflow_signal_content(items: &[String]) -> String {
if items.is_empty() {
return String::new();
}
items
.iter()
.map(|item| format!("- {item}"))
.collect::<Vec<_>>()
.join("\n")
}
pub fn render_handoff_content(view: &CompiledHandoffView) -> String {
let mut body = String::new();
if !view.title.is_empty() {
append_section(&mut body, "Title", std::slice::from_ref(&view.title));
}
append_section(&mut body, "Immediate Actions", &view.immediate_actions);
append_section(&mut body, "Completed State", &view.completed_state);
append_section(
&mut body,
"Operational Guardrails",
&view.operational_guardrails,
);
append_section(&mut body, "Key Files", &view.key_files);
append_section(&mut body, "Definition of Done", &view.definition_of_done);
body
}
#[derive(Debug, Clone, Serialize)]
pub struct ContextDelta {
pub previous_fingerprint: String,
pub current_fingerprint: String,
pub changed_surfaces: Vec<ChangedSurface>,
}
#[derive(Debug, Clone, Serialize)]
pub struct ChangedSurface {
pub name: &'static str,
pub previous_digest: String,
pub current_digest: String,
}
fn surface_name_to_static(name: &str) -> &'static str {
match name {
"effective_memory" => "effective_memory",
"workflow_signal" => "workflow_signal",
"handoff" => "handoff",
"execution_gates" => "execution_gates",
"escalation" => "escalation",
"recovery" => "recovery",
"git_state" => "git_state",
"session_state" => "session_state",
_ => "unknown",
}
}
#[cfg_attr(not(test), allow(dead_code))]
pub fn compute_context_delta(
previous: &ProjectionDigests,
current: &ProjectionDigests,
previous_fp: &str,
current_fp: &str,
) -> Option<ContextDelta> {
let pairs: &[(&str, &str, &str)] = &[
("effective_memory", &previous.effective_memory, ¤t.effective_memory),
("workflow_signal", &previous.workflow_signal, ¤t.workflow_signal),
("handoff", &previous.handoff, ¤t.handoff),
("execution_gates", &previous.execution_gates, ¤t.execution_gates),
("escalation", &previous.escalation, ¤t.escalation),
("recovery", &previous.recovery, ¤t.recovery),
("git_state", &previous.git_state, ¤t.git_state),
("session_state", &previous.session_state, ¤t.session_state),
];
let mut changed = Vec::new();
for &(name, prev, curr) in pairs {
if prev.is_empty() || curr.is_empty() {
continue;
}
if prev != curr {
changed.push(ChangedSurface {
name: surface_name_to_static(name),
previous_digest: prev.to_owned(),
current_digest: curr.to_owned(),
});
}
}
if changed.is_empty() {
return None;
}
Some(ContextDelta {
previous_fingerprint: previous_fp.to_owned(),
current_fingerprint: current_fp.to_owned(),
changed_surfaces: changed,
})
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SymbolicProjectionView {
pub target: ProjectionTarget,
pub source_fingerprint: String,
pub facts: Vec<SymbolicFact>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BundleProjectionView {
pub target: ProjectionTarget,
pub source_fingerprint: String,
pub task: String,
pub sections: Vec<BundleSection>,
pub markdown: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct BundleSection {
pub kind: BundleSectionKind,
pub title: String,
pub items: Vec<String>,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum BundleSectionKind {
Do,
Remember,
Focus,
Rules,
Files,
CloseOut,
State,
}
impl BundleSectionKind {
fn title(self) -> &'static str {
match self {
Self::Do => "Do",
Self::Remember => "Remember",
Self::Focus => "Focus",
Self::Rules => "Rules",
Self::Files => "Files",
Self::CloseOut => "Close-out",
Self::State => "State",
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct SymbolicFact {
pub surface: String,
pub kind: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub ordinal: Option<usize>,
pub text: String,
}
#[cfg_attr(not(test), allow(dead_code))]
pub fn render_symbolic_content(view: &SymbolicProjectionView) -> String {
view.facts
.iter()
.map(render_symbolic_fact)
.collect::<Vec<_>>()
.join("\n")
}
pub fn preview_for_target(
loaded: &runtime_state::LoadedRuntimeState,
target: ProjectionTarget,
) -> Result<CompiledStateStore> {
compile_loaded_runtime_for_target(loaded, target)
}
pub fn preview_symbolic_for_target(
loaded: &runtime_state::LoadedRuntimeState,
target: ProjectionTarget,
) -> Result<SymbolicProjectionView> {
compile_loaded_symbolic_projection(loaded, target)
}
pub fn preview_bundle_for_target(
loaded: &runtime_state::LoadedRuntimeState,
target: ProjectionTarget,
) -> Result<BundleProjectionView> {
compile_loaded_bundle_projection(loaded, target)
}
fn compile_from_runtime_for_target(
repo_root: &Path,
layout: &StateLayout,
locality_id: &str,
target: ProjectionTarget,
) -> Result<CompiledStateStore> {
let loaded = runtime_state::load_runtime_state(repo_root, layout, locality_id)?;
compile_loaded_runtime_for_target(&loaded, target)
}
fn compile_loaded_runtime_for_target(
loaded: &runtime_state::LoadedRuntimeState,
target: ProjectionTarget,
) -> Result<CompiledStateStore> {
let mut compiled = compile_runtime_projection(
&loaded.state,
&loaded.sources,
target,
loaded.pod_identity_active,
)?;
inject_execution_gate_attention(
&mut compiled.workflow_signal_active,
loaded.execution_gates.view.attention_anchor.as_ref(),
default_projection_bounds().max_active_workflow_signal_items,
);
dedupe_compiled_projection(&mut compiled);
compiled.projection_digests = Some(compute_projection_digests(&compiled));
Ok(compiled)
}
fn compile_loaded_symbolic_projection(
loaded: &runtime_state::LoadedRuntimeState,
target: ProjectionTarget,
) -> Result<SymbolicProjectionView> {
let mut projection = compile_symbolic_projection(
&loaded.state,
&loaded.sources,
target,
loaded.pod_identity_active,
)?;
if let Some(anchor) = loaded.execution_gates.view.attention_anchor.as_ref() {
projection.facts.push(SymbolicFact {
surface: "execution_gates".to_owned(),
kind: "attention_anchor".to_owned(),
ordinal: Some(anchor.index),
text: anchor.text.clone(),
});
}
Ok(projection)
}
fn compile_loaded_bundle_projection(
loaded: &runtime_state::LoadedRuntimeState,
target: ProjectionTarget,
) -> Result<BundleProjectionView> {
let compiled = compile_loaded_runtime_for_target(loaded, target)?;
Ok(compile_bundle_projection(&compiled))
}
fn compile_runtime_projection(
state: &runtime_state::RuntimeState,
sources: &runtime_state::RuntimeSourceSurfaces,
target: ProjectionTarget,
pod_identity_active: bool,
) -> Result<CompiledStateStore> {
let bounds = default_projection_bounds();
let handoff_target = handoff_target(target);
let mut compiled = CompiledStateStore {
schema_version: SCHEMA_VERSION,
target,
source_fingerprint: fingerprint_for_inputs(sources, pod_identity_active)?,
pod_identity_active,
projection_digests: None,
effective_memory: CompiledMemoryView {
profile: project_memory_entries(
&state.memory.profile,
bounds.max_active_memory_entries_per_scope,
),
locality: project_memory_entries(
&state.memory.locality,
bounds.max_active_memory_entries_per_scope,
),
pod: project_memory_entries(
&state.memory.pod,
bounds.max_active_memory_entries_per_scope,
),
branch: project_memory_entries(
&state.memory.branch,
bounds.max_active_memory_entries_per_scope,
),
clone: project_memory_entries(
&state.memory.clone,
bounds.max_active_memory_entries_per_scope,
),
},
workflow_signal_active: project_workflow_signal_items(
&state.workflow_signal.items,
bounds.max_active_workflow_signal_items,
),
handoff: project_handoff(&state.handoff, bounds, handoff_target),
};
dedupe_compiled_projection(&mut compiled);
compiled.projection_digests = Some(compute_projection_digests(&compiled));
Ok(compiled)
}
fn compile_symbolic_projection(
state: &runtime_state::RuntimeState,
sources: &runtime_state::RuntimeSourceSurfaces,
target: ProjectionTarget,
pod_identity_active: bool,
) -> Result<SymbolicProjectionView> {
let bounds = default_projection_bounds();
let handoff_target = handoff_target(target);
let mut facts = Vec::new();
if pod_identity_active {
append_memory_facts(
&mut facts,
"pod_memory",
project_active_memory_entries(
&state.memory.pod,
bounds.max_active_memory_entries_per_scope,
),
);
append_memory_facts(
&mut facts,
"profile_memory",
project_active_memory_entries(
&state.memory.profile,
bounds.max_active_memory_entries_per_scope,
),
);
append_memory_facts(
&mut facts,
"locality_memory",
project_active_memory_entries(
&state.memory.locality,
bounds.max_active_memory_entries_per_scope,
),
);
} else {
append_memory_facts(
&mut facts,
"profile_memory",
project_active_memory_entries(
&state.memory.profile,
bounds.max_active_memory_entries_per_scope,
),
);
append_memory_facts(
&mut facts,
"locality_memory",
project_active_memory_entries(
&state.memory.locality,
bounds.max_active_memory_entries_per_scope,
),
);
append_memory_facts(
&mut facts,
"pod_memory",
project_active_memory_entries(
&state.memory.pod,
bounds.max_active_memory_entries_per_scope,
),
);
}
append_memory_facts(
&mut facts,
"branch_memory",
project_active_memory_entries(
&state.memory.branch,
bounds.max_active_memory_entries_per_scope,
),
);
append_memory_facts(
&mut facts,
"clone_memory",
project_active_memory_entries(
&state.memory.clone,
bounds.max_active_memory_entries_per_scope,
),
);
append_workflow_signal_facts(
&mut facts,
project_active_workflow_signal_items(
&state.workflow_signal.items,
bounds.max_active_workflow_signal_items,
),
);
if !state.handoff.title.trim().is_empty() {
facts.push(SymbolicFact {
surface: "handoff_title".to_owned(),
kind: "title".to_owned(),
ordinal: None,
text: state.handoff.title.clone(),
});
}
append_handoff_facts(
&mut facts,
"handoff_immediate_actions",
project_active_handoff_items(
&state.handoff.immediate_actions,
bounds.max_active_handoff_items_per_section,
),
);
if handoff_target.include_completed_state {
append_handoff_facts(
&mut facts,
"handoff_completed_state",
project_active_handoff_items(
&state.handoff.completed_state,
bounds.max_active_handoff_items_per_section,
),
);
}
append_handoff_facts(
&mut facts,
"handoff_operational_guardrails",
project_active_handoff_items(
&state.handoff.operational_guardrails,
bounds.max_active_handoff_items_per_section,
),
);
if handoff_target.include_key_files {
append_handoff_facts(
&mut facts,
"handoff_key_files",
project_active_handoff_items(
&state.handoff.key_files,
bounds.max_active_handoff_items_per_section,
),
);
}
if handoff_target.include_definition_of_done {
append_handoff_facts(
&mut facts,
"handoff_definition_of_done",
project_active_handoff_items(
&state.handoff.definition_of_done,
bounds.max_active_handoff_items_per_section,
),
);
}
Ok(SymbolicProjectionView {
target,
source_fingerprint: fingerprint_for_inputs(sources, pod_identity_active)?,
facts,
})
}
fn compile_bundle_projection(store: &CompiledStateStore) -> BundleProjectionView {
let mut sections = Vec::new();
push_bundle_section(
&mut sections,
BundleSectionKind::Do,
store.handoff.immediate_actions.clone(),
);
push_bundle_section(
&mut sections,
BundleSectionKind::Remember,
bundle_memory_items(&store.effective_memory, store.pod_identity_active),
);
push_bundle_section(
&mut sections,
BundleSectionKind::Focus,
store.workflow_signal_active.clone(),
);
push_bundle_section(
&mut sections,
BundleSectionKind::Rules,
store.handoff.operational_guardrails.clone(),
);
push_bundle_section(
&mut sections,
BundleSectionKind::Files,
store.handoff.key_files.clone(),
);
push_bundle_section(
&mut sections,
BundleSectionKind::CloseOut,
store.handoff.definition_of_done.clone(),
);
let task = bundle_task(&store.handoff.title, store.target);
let markdown = render_bundle_markdown(&task, §ions);
BundleProjectionView {
target: store.target,
source_fingerprint: store.source_fingerprint.clone(),
task,
sections,
markdown,
}
}
fn handoff_target(target: ProjectionTarget) -> HandoffProjectionTarget {
match target {
ProjectionTarget::Default => HandoffProjectionTarget {
include_completed_state: true,
include_key_files: true,
include_definition_of_done: true,
},
ProjectionTarget::Planning => HandoffProjectionTarget {
include_completed_state: false,
include_key_files: false,
include_definition_of_done: true,
},
ProjectionTarget::Session => HandoffProjectionTarget {
include_completed_state: false,
include_key_files: false,
include_definition_of_done: false,
},
}
}
#[derive(Debug, Clone, Copy)]
struct HandoffProjectionTarget {
include_completed_state: bool,
include_key_files: bool,
include_definition_of_done: bool,
}
fn default_projection_bounds() -> ProjectionBounds {
ProjectionBounds {
max_active_memory_entries_per_scope: DEFAULT_MAX_ACTIVE_MEMORY_ENTRIES_PER_SCOPE,
max_active_workflow_signal_items: DEFAULT_MAX_ACTIVE_WORKFLOW_SIGNAL_ITEMS,
max_active_handoff_items_per_section: DEFAULT_MAX_ACTIVE_HANDOFF_ITEMS_PER_SECTION,
}
}
fn fingerprint_for_inputs(
sources: &runtime_state::RuntimeSourceSurfaces,
pod_identity_active: bool,
) -> Result<String> {
let payload = serde_json::to_vec(&FingerprintInputs {
profile_memory: FingerprintSurface::from(&sources.profile_memory),
locality_memory: FingerprintSurface::from(&sources.locality_memory),
pod_memory: FingerprintSurface::from(&sources.pod_memory),
branch_memory: FingerprintSurface::from(&sources.branch_memory),
clone_memory: FingerprintSurface::from(&sources.clone_memory),
workflow_signal: FingerprintSurface::from(&sources.workflow_signal),
execution_gates: FingerprintSurface::from(&sources.execution_gates),
handoff: FingerprintSurface::from(&sources.handoff),
pod_identity_active,
})?;
let mut hasher = Sha256::new();
hasher.update(payload);
Ok(format!("{:x}", hasher.finalize()))
}
fn inject_execution_gate_attention(
workflow_signal_active: &mut Vec<String>,
anchor: Option<&session_gates::ExecutionGateAnchor>,
max_active_items: usize,
) {
let Some(anchor) = anchor else {
return;
};
workflow_signal_active.insert(0, anchor.text.clone());
let mut seen = HashSet::new();
workflow_signal_active.retain(|item| seen.insert(item.clone()));
if workflow_signal_active.len() > max_active_items {
workflow_signal_active.truncate(max_active_items);
}
}
fn project_memory_entries(
entries: &[runtime_state::RuntimeMemoryEntry],
max_active_entries: usize,
) -> Vec<String> {
project_active_memory_entries(entries, max_active_entries)
.into_iter()
.map(runtime_state::RuntimeMemoryEntry::projection_text)
.collect()
}
fn project_workflow_signal_items(
items: &[runtime_state::RuntimeWorkflowSignalItem],
max_active_items: usize,
) -> Vec<String> {
project_active_workflow_signal_items(items, max_active_items)
.into_iter()
.map(|item| item.text.clone())
.collect()
}
fn project_handoff(
state: &runtime_state::RuntimeHandoffState,
bounds: ProjectionBounds,
target: HandoffProjectionTarget,
) -> CompiledHandoffView {
CompiledHandoffView {
title: state.title.clone(),
immediate_actions: project_handoff_items(
&state.immediate_actions,
bounds.max_active_handoff_items_per_section,
),
completed_state: if target.include_completed_state {
project_handoff_items(
&state.completed_state,
bounds.max_active_handoff_items_per_section,
)
} else {
Vec::new()
},
operational_guardrails: project_handoff_items(
&state.operational_guardrails,
bounds.max_active_handoff_items_per_section,
),
key_files: if target.include_key_files {
project_handoff_items(
&state.key_files,
bounds.max_active_handoff_items_per_section,
)
} else {
Vec::new()
},
definition_of_done: if target.include_definition_of_done {
project_handoff_items(
&state.definition_of_done,
bounds.max_active_handoff_items_per_section,
)
} else {
Vec::new()
},
}
}
fn dedupe_compiled_projection(store: &mut CompiledStateStore) {
let mut seen = HashSet::new();
if store.pod_identity_active {
dedupe_strings(&mut store.effective_memory.pod, &mut seen);
dedupe_strings(&mut store.effective_memory.profile, &mut seen);
dedupe_strings(&mut store.effective_memory.locality, &mut seen);
} else {
dedupe_strings(&mut store.effective_memory.profile, &mut seen);
dedupe_strings(&mut store.effective_memory.locality, &mut seen);
dedupe_strings(&mut store.effective_memory.pod, &mut seen);
}
dedupe_strings(&mut store.effective_memory.branch, &mut seen);
dedupe_strings(&mut store.effective_memory.clone, &mut seen);
dedupe_strings(&mut store.workflow_signal_active, &mut seen);
dedupe_strings(&mut store.handoff.immediate_actions, &mut seen);
dedupe_strings(&mut store.handoff.completed_state, &mut seen);
dedupe_strings(&mut store.handoff.operational_guardrails, &mut seen);
dedupe_strings(&mut store.handoff.key_files, &mut seen);
dedupe_strings(&mut store.handoff.definition_of_done, &mut seen);
}
fn dedupe_strings(items: &mut Vec<String>, seen: &mut HashSet<String>) {
items.retain(|item| seen.insert(item.clone()));
}
fn project_handoff_items(
items: &[runtime_state::RuntimeHandoffItem],
max_active_items: usize,
) -> Vec<String> {
project_active_handoff_items(items, max_active_items)
.into_iter()
.map(|item| item.text.clone())
.collect()
}
fn project_active_memory_entries(
entries: &[runtime_state::RuntimeMemoryEntry],
max_active_entries: usize,
) -> Vec<&runtime_state::RuntimeMemoryEntry> {
collect_active_items(
entries
.iter()
.filter(|entry| runtime_memory_entry_is_active(entry)),
max_active_entries,
runtime_state::RuntimeMemoryEntry::projection_text,
)
}
fn runtime_memory_entry_is_active(entry: &runtime_state::RuntimeMemoryEntry) -> bool {
if !entry.lifecycle.is_active() {
return false;
}
let Some(expires_at) = entry.expires_at.as_deref() else {
return true;
};
match timestamps::parse_rfc3339(expires_at) {
Some(expires_at) => expires_at > timestamps::now_utc(),
None => true,
}
}
fn project_active_workflow_signal_items(
items: &[runtime_state::RuntimeWorkflowSignalItem],
max_active_items: usize,
) -> Vec<&runtime_state::RuntimeWorkflowSignalItem> {
collect_active_items(
items.iter().filter(|item| item.lifecycle.is_active()),
max_active_items,
|item| item.text.clone(),
)
}
fn project_active_handoff_items(
items: &[runtime_state::RuntimeHandoffItem],
max_active_items: usize,
) -> Vec<&runtime_state::RuntimeHandoffItem> {
collect_active_items(
items.iter().filter(|item| item.lifecycle.is_active()),
max_active_items,
|item| item.text.clone(),
)
}
fn collect_active_items<'a, T, I, F>(items: I, max_active_items: usize, key: F) -> Vec<&'a T>
where
I: IntoIterator<Item = &'a T>,
F: Fn(&T) -> String,
{
let mut seen = HashSet::new();
let mut selected = Vec::new();
for item in items {
let marker = key(item);
if marker.trim().is_empty() {
continue;
}
if seen.insert(marker) {
selected.push(item);
if selected.len() == max_active_items {
break;
}
}
}
selected
}
fn append_memory_facts(
facts: &mut Vec<SymbolicFact>,
surface: &str,
entries: Vec<&runtime_state::RuntimeMemoryEntry>,
) {
for (index, entry) in entries.into_iter().enumerate() {
facts.push(SymbolicFact {
surface: surface.to_owned(),
kind: symbolic_memory_kind(entry),
ordinal: Some(index + 1),
text: entry.text.clone(),
});
}
}
fn append_workflow_signal_facts(
facts: &mut Vec<SymbolicFact>,
items: Vec<&runtime_state::RuntimeWorkflowSignalItem>,
) {
for (index, item) in items.into_iter().enumerate() {
facts.push(SymbolicFact {
surface: "workflow_signal".to_owned(),
kind: "item".to_owned(),
ordinal: Some(index + 1),
text: item.text.clone(),
});
}
}
fn append_handoff_facts(
facts: &mut Vec<SymbolicFact>,
surface: &str,
items: Vec<&runtime_state::RuntimeHandoffItem>,
) {
for (index, item) in items.into_iter().enumerate() {
facts.push(SymbolicFact {
surface: surface.to_owned(),
kind: "item".to_owned(),
ordinal: Some(index + 1),
text: item.text.clone(),
});
}
}
fn symbolic_memory_kind(entry: &runtime_state::RuntimeMemoryEntry) -> String {
match &entry.origin {
runtime_state::RuntimeMemoryOrigin::Narrative => "narrative".to_owned(),
runtime_state::RuntimeMemoryOrigin::Structured { entry_type, .. } => entry_type.clone(),
}
}
fn bundle_task(title: &str, target: ProjectionTarget) -> String {
let trimmed = title.trim();
if trimmed.is_empty() {
return format!("{} session bundle", target.as_str());
}
trimmed
.strip_prefix("Next Session:")
.unwrap_or(trimmed)
.trim()
.to_owned()
}
fn bundle_memory_items(view: &CompiledMemoryView, pod_identity_active: bool) -> Vec<String> {
let mut items = Vec::new();
if pod_identity_active {
items.extend(view.pod.iter().map(|item| format!("Pod: {item}")));
items.extend(view.profile.iter().map(|item| format!("Profile: {item}")));
items.extend(view.locality.iter().map(|item| format!("Project: {item}")));
} else {
items.extend(view.profile.iter().map(|item| format!("Profile: {item}")));
items.extend(view.locality.iter().map(|item| format!("Project: {item}")));
items.extend(view.pod.iter().map(|item| format!("Pod: {item}")));
}
items.extend(
view.branch
.iter()
.map(|item| format!("Work stream: {item}")),
);
items.extend(view.clone.iter().map(|item| format!("Workspace: {item}")));
items
}
fn push_bundle_section(
sections: &mut Vec<BundleSection>,
kind: BundleSectionKind,
items: Vec<String>,
) {
if items.is_empty() {
return;
}
sections.push(BundleSection {
kind,
title: kind.title().to_owned(),
items,
});
}
#[cfg_attr(not(test), allow(dead_code))]
fn render_symbolic_fact(fact: &SymbolicFact) -> String {
match fact.ordinal {
Some(ordinal) => format!("{}|{}|{}|{}", fact.surface, fact.kind, ordinal, fact.text),
None => format!("{}|{}|{}", fact.surface, fact.kind, fact.text),
}
}
pub fn render_bundle_markdown(task: &str, sections: &[BundleSection]) -> String {
let mut body = String::from("# CCD Bundle\n\n");
body.push_str("Task: ");
body.push_str(task);
body.push('\n');
for section in sections {
body.push('\n');
body.push_str("## ");
body.push_str(§ion.title);
body.push('\n');
for item in §ion.items {
body.push_str("- ");
body.push_str(item);
body.push('\n');
}
}
body
}
fn append_section(body: &mut String, title: &str, items: &[String]) {
if items.is_empty() {
return;
}
if !body.is_empty() {
body.push('\n');
}
body.push_str("### ");
body.push_str(title);
body.push_str("\n\n");
for item in items {
body.push_str("- ");
body.push_str(item);
body.push('\n');
}
}
#[derive(Serialize)]
struct FingerprintInputs<'a> {
profile_memory: FingerprintSurface<'a>,
locality_memory: FingerprintSurface<'a>,
pod_memory: FingerprintSurface<'a>,
branch_memory: FingerprintSurface<'a>,
clone_memory: FingerprintSurface<'a>,
workflow_signal: FingerprintSurface<'a>,
execution_gates: FingerprintSurface<'a>,
handoff: FingerprintSurface<'a>,
pod_identity_active: bool,
}
#[derive(Serialize)]
struct FingerprintSurface<'a> {
status: &'static str,
content: &'a str,
}
impl<'a> From<&'a runtime_state::RuntimeTextSurface> for FingerprintSurface<'a> {
fn from(value: &'a runtime_state::RuntimeTextSurface) -> Self {
Self {
status: match value.status {
runtime_state::RuntimeTextSurfaceStatus::LoadedNative => "loaded",
other => other.as_str(),
},
content: &value.content,
}
}
}
#[cfg(test)]
mod tests {
use std::path::PathBuf;
use tempfile::tempdir;
use super::*;
use crate::memory::entries::StructuredMemoryEntry;
use crate::profile::ProfileName;
use crate::state::runtime::{
LoadedRuntimeExecutionGates, LoadedRuntimeRecoveryState, LoadedRuntimeState,
RuntimeHandoffItem, RuntimeHandoffState, RuntimeLifecycle, RuntimeMemoryEntry,
RuntimeMemoryState, RuntimeRecoveryState, RuntimeRecoverySurface, RuntimeRecoverySurfaces,
RuntimeSourceSurfaces, RuntimeState, RuntimeTextSurface, RuntimeTextSurfaceStatus,
RuntimeWorkflowSignalItem, RuntimeWorkflowSignalState,
};
use crate::state::session_gates::{ExecutionGate, ExecutionGateStateFile, ExecutionGateStatus};
fn missing_clone_memory_surface() -> RuntimeTextSurface {
RuntimeTextSurface {
kind: "clone_memory",
path: PathBuf::from("/tmp/clone-memory.md"),
status: RuntimeTextSurfaceStatus::Missing,
content: String::new(),
migrated_from: None,
}
}
fn missing_pod_memory_surface() -> RuntimeTextSurface {
RuntimeTextSurface {
kind: "pod_memory",
path: PathBuf::from("/tmp/pod-memory.md"),
status: RuntimeTextSurfaceStatus::Missing,
content: String::new(),
migrated_from: None,
}
}
fn missing_branch_memory_surface() -> RuntimeTextSurface {
RuntimeTextSurface {
kind: "branch_memory",
path: PathBuf::from("/tmp/branch-memory.md"),
status: RuntimeTextSurfaceStatus::Missing,
content: String::new(),
migrated_from: None,
}
}
fn missing_execution_gates_surface() -> RuntimeTextSurface {
RuntimeTextSurface {
kind: "execution_gates",
path: PathBuf::from("/tmp/state.db"),
status: RuntimeTextSurfaceStatus::Missing,
content: String::new(),
migrated_from: None,
}
}
fn missing_execution_gates() -> LoadedRuntimeExecutionGates {
LoadedRuntimeExecutionGates {
source: missing_execution_gates_surface(),
view: session_gates::ExecutionGatesView {
path: "/tmp/state.db".to_owned(),
status: "missing",
seeded_from: None,
revision: None,
total_count: 0,
unfinished_count: 0,
attention_anchor: None,
gates: Vec::new(),
},
}
}
#[test]
fn projects_runtime_state_into_compiled_views() {
let state = RuntimeState {
memory: RuntimeMemoryState {
profile: vec![
RuntimeMemoryEntry::narrative("Keep projections bounded."),
RuntimeMemoryEntry {
lifecycle: RuntimeLifecycle::Inactive,
..RuntimeMemoryEntry::narrative("Skip stale notes.")
},
RuntimeMemoryEntry::narrative("Keep projections bounded."),
],
locality: vec![RuntimeMemoryEntry::from_structured_entry(
StructuredMemoryEntry {
id: "mem_rule".to_owned(),
entry_type: "rule".to_owned(),
state: "active".to_owned(),
created_at: "2026-03-10T10:00:00Z".to_owned(),
last_touched_session: 1,
origin: "manual".to_owned(),
superseded_at: None,
decay_class: None,
expires_at: None,
tags: Vec::new(),
source_ref: None,
supersedes: Vec::new(),
content: "Prefer deterministic writes.".to_owned(),
},
)],
pod: Vec::new(),
branch: Vec::new(),
clone: Vec::new(),
},
workflow_signal: RuntimeWorkflowSignalState {
items: vec![
RuntimeWorkflowSignalItem {
text: "Land Phase 0.".to_owned(),
lifecycle: RuntimeLifecycle::Active,
},
RuntimeWorkflowSignalItem {
text: "Archived item.".to_owned(),
lifecycle: RuntimeLifecycle::Inactive,
},
],
},
handoff: RuntimeHandoffState {
title: "Next Session: Runtime".to_owned(),
immediate_actions: vec![RuntimeHandoffItem {
text: "Add runtime-state scaffolding.".to_owned(),
lifecycle: RuntimeLifecycle::Active,
}],
completed_state: vec![RuntimeHandoffItem {
text: "Archived work.".to_owned(),
lifecycle: RuntimeLifecycle::Inactive,
}],
operational_guardrails: Vec::new(),
key_files: Vec::new(),
definition_of_done: Vec::new(),
},
};
let sources = RuntimeSourceSurfaces {
profile_memory: RuntimeTextSurface {
kind: "profile_memory",
path: PathBuf::from("/tmp/profile-memory.md"),
status: RuntimeTextSurfaceStatus::Loaded,
content: "profile".to_owned(),
migrated_from: None,
},
locality_memory: RuntimeTextSurface {
kind: "locality_memory",
path: PathBuf::from("/tmp/repo-memory.md"),
status: RuntimeTextSurfaceStatus::Loaded,
content: "repo".to_owned(),
migrated_from: None,
},
pod_memory: missing_pod_memory_surface(),
branch_memory: missing_branch_memory_surface(),
clone_memory: missing_clone_memory_surface(),
workflow_signal: RuntimeTextSurface {
kind: "workflow_signal",
path: PathBuf::from("/tmp/dispatch-state.md"),
status: RuntimeTextSurfaceStatus::Loaded,
content: "focus".to_owned(),
migrated_from: None,
},
execution_gates: missing_execution_gates_surface(),
handoff: RuntimeTextSurface {
kind: "handoff",
path: PathBuf::from("/tmp/handoff.md"),
status: RuntimeTextSurfaceStatus::Loaded,
content: "handoff".to_owned(),
migrated_from: None,
},
};
let compiled =
compile_runtime_projection(&state, &sources, ProjectionTarget::Default, false)
.expect("compiled projection");
assert_eq!(compiled.target, ProjectionTarget::Default);
assert_eq!(
compiled.effective_memory.profile,
vec!["Keep projections bounded.".to_owned()]
);
assert_eq!(
compiled.effective_memory.locality,
vec!["rule: Prefer deterministic writes.".to_owned()]
);
assert_eq!(
compiled.workflow_signal_active,
vec!["Land Phase 0.".to_owned()]
);
assert_eq!(compiled.handoff.title, "Next Session: Runtime");
assert_eq!(
compiled.handoff.immediate_actions,
vec!["Add runtime-state scaffolding.".to_owned()]
);
assert!(compiled.handoff.completed_state.is_empty());
assert!(!compiled.source_fingerprint.is_empty());
}
#[test]
fn projects_runtime_state_without_expired_active_memory_entries() {
let state = RuntimeState {
memory: RuntimeMemoryState {
profile: vec![
RuntimeMemoryEntry::from_structured_entry(StructuredMemoryEntry {
id: "mem_expired".to_owned(),
entry_type: "rule".to_owned(),
state: "active".to_owned(),
created_at: "2026-03-10T10:00:00Z".to_owned(),
last_touched_session: 1,
origin: "manual".to_owned(),
superseded_at: None,
decay_class: Some("active".to_owned()),
expires_at: Some("2000-01-01T00:00:00Z".to_owned()),
tags: Vec::new(),
source_ref: None,
supersedes: Vec::new(),
content: "Expired rule should stay out of preload.".to_owned(),
}),
RuntimeMemoryEntry::from_structured_entry(StructuredMemoryEntry {
id: "mem_current".to_owned(),
entry_type: "rule".to_owned(),
state: "active".to_owned(),
created_at: "2026-03-10T11:00:00Z".to_owned(),
last_touched_session: 2,
origin: "manual".to_owned(),
superseded_at: None,
decay_class: Some("stable".to_owned()),
expires_at: Some("2999-01-01T00:00:00Z".to_owned()),
tags: Vec::new(),
source_ref: None,
supersedes: Vec::new(),
content: "Future rule should remain in preload.".to_owned(),
}),
],
locality: Vec::new(),
pod: Vec::new(),
branch: Vec::new(),
clone: Vec::new(),
},
workflow_signal: RuntimeWorkflowSignalState::default(),
handoff: RuntimeHandoffState::default(),
};
let sources = RuntimeSourceSurfaces {
profile_memory: RuntimeTextSurface {
kind: "profile_memory",
path: PathBuf::from("/tmp/profile-memory.md"),
status: RuntimeTextSurfaceStatus::Loaded,
content: "profile".to_owned(),
migrated_from: None,
},
locality_memory: RuntimeTextSurface {
kind: "locality_memory",
path: PathBuf::from("/tmp/repo-memory.md"),
status: RuntimeTextSurfaceStatus::Missing,
content: String::new(),
migrated_from: None,
},
pod_memory: missing_pod_memory_surface(),
branch_memory: missing_branch_memory_surface(),
clone_memory: missing_clone_memory_surface(),
workflow_signal: RuntimeTextSurface {
kind: "workflow_signal",
path: PathBuf::from("/tmp/dispatch-state.md"),
status: RuntimeTextSurfaceStatus::Missing,
content: String::new(),
migrated_from: None,
},
execution_gates: missing_execution_gates_surface(),
handoff: RuntimeTextSurface {
kind: "handoff",
path: PathBuf::from("/tmp/handoff.md"),
status: RuntimeTextSurfaceStatus::Missing,
content: String::new(),
migrated_from: None,
},
};
let compiled =
compile_runtime_projection(&state, &sources, ProjectionTarget::Default, false)
.expect("compiled projection");
assert_eq!(
compiled.effective_memory.profile,
vec!["rule: Future rule should remain in preload.".to_owned()]
);
}
#[test]
fn unparseable_expires_at_keeps_entry_active() {
let state = RuntimeState {
memory: RuntimeMemoryState {
profile: vec![RuntimeMemoryEntry::from_structured_entry(
StructuredMemoryEntry {
id: "mem_bad_ts".to_owned(),
entry_type: "rule".to_owned(),
state: "active".to_owned(),
created_at: "2026-03-10T10:00:00Z".to_owned(),
last_touched_session: 1,
origin: "manual".to_owned(),
superseded_at: None,
decay_class: Some("active".to_owned()),
expires_at: Some("not-a-timestamp".to_owned()),
tags: Vec::new(),
source_ref: None,
supersedes: Vec::new(),
content: "Entry with unparseable expiry stays active.".to_owned(),
},
)],
locality: Vec::new(),
pod: Vec::new(),
branch: Vec::new(),
clone: Vec::new(),
},
workflow_signal: RuntimeWorkflowSignalState::default(),
handoff: RuntimeHandoffState::default(),
};
let sources = RuntimeSourceSurfaces {
profile_memory: RuntimeTextSurface {
kind: "profile_memory",
path: PathBuf::from("/tmp/profile-memory.md"),
status: RuntimeTextSurfaceStatus::Loaded,
content: "profile".to_owned(),
migrated_from: None,
},
locality_memory: RuntimeTextSurface {
kind: "locality_memory",
path: PathBuf::from("/tmp/repo-memory.md"),
status: RuntimeTextSurfaceStatus::Missing,
content: String::new(),
migrated_from: None,
},
pod_memory: missing_pod_memory_surface(),
branch_memory: missing_branch_memory_surface(),
clone_memory: missing_clone_memory_surface(),
workflow_signal: RuntimeTextSurface {
kind: "workflow_signal",
path: PathBuf::from("/tmp/dispatch-state.md"),
status: RuntimeTextSurfaceStatus::Missing,
content: String::new(),
migrated_from: None,
},
execution_gates: missing_execution_gates_surface(),
handoff: RuntimeTextSurface {
kind: "handoff",
path: PathBuf::from("/tmp/handoff.md"),
status: RuntimeTextSurfaceStatus::Missing,
content: String::new(),
migrated_from: None,
},
};
let compiled =
compile_runtime_projection(&state, &sources, ProjectionTarget::Default, false)
.expect("compiled projection");
assert_eq!(
compiled.effective_memory.profile,
vec!["rule: Entry with unparseable expiry stays active.".to_owned()]
);
}
#[test]
fn ensure_for_runtime_projects_loaded_state_without_reloading_authored_files() {
let temp = tempdir().expect("tempdir");
let layout = StateLayout::new(
temp.path().join(".ccd"),
temp.path().join(".git/ccd"),
ProfileName::new("main").expect("profile"),
);
let loaded = LoadedRuntimeState {
state: RuntimeState {
memory: RuntimeMemoryState {
profile: vec![RuntimeMemoryEntry::narrative(
"Use the loaded runtime view.",
)],
locality: Vec::new(),
pod: Vec::new(),
branch: Vec::new(),
clone: Vec::new(),
},
workflow_signal: RuntimeWorkflowSignalState {
items: vec![RuntimeWorkflowSignalItem {
text: "Emit the default target.".to_owned(),
lifecycle: RuntimeLifecycle::Active,
}],
},
handoff: RuntimeHandoffState {
title: "Next Session: Runtime-first projection".to_owned(),
immediate_actions: vec![RuntimeHandoffItem {
text: "Avoid adapter rereads.".to_owned(),
lifecycle: RuntimeLifecycle::Active,
}],
completed_state: Vec::new(),
operational_guardrails: Vec::new(),
key_files: Vec::new(),
definition_of_done: Vec::new(),
},
},
sources: RuntimeSourceSurfaces {
profile_memory: RuntimeTextSurface {
kind: "profile_memory",
path: PathBuf::from("/virtual/profile-memory.md"),
status: RuntimeTextSurfaceStatus::Loaded,
content: "# Profile Memory\n\n- Use the loaded runtime view.\n".to_owned(),
migrated_from: None,
},
locality_memory: RuntimeTextSurface {
kind: "locality_memory",
path: PathBuf::from("/virtual/repo-memory.md"),
status: RuntimeTextSurfaceStatus::Missing,
content: String::new(),
migrated_from: None,
},
pod_memory: missing_pod_memory_surface(),
branch_memory: missing_branch_memory_surface(),
clone_memory: missing_clone_memory_surface(),
workflow_signal: RuntimeTextSurface {
kind: "workflow_signal",
path: PathBuf::from("/virtual/dispatch-state.md"),
status: RuntimeTextSurfaceStatus::Loaded,
content: "# Focus\n\n- Emit the default target.\n".to_owned(),
migrated_from: None,
},
execution_gates: missing_execution_gates_surface(),
handoff: RuntimeTextSurface {
kind: "handoff",
path: PathBuf::from("/virtual/handoff.md"),
status: RuntimeTextSurfaceStatus::Loaded,
content: "# Next Session: Runtime-first projection\n".to_owned(),
migrated_from: None,
},
},
execution_gates: missing_execution_gates(),
recovery: LoadedRuntimeRecoveryState {
state: RuntimeRecoveryState::default(),
sources: RuntimeRecoverySurfaces {
checkpoint: RuntimeRecoverySurface {
kind: "checkpoint",
path: PathBuf::from("/virtual/checkpoint.json"),
status: "missing",
},
working_buffer: RuntimeRecoverySurface {
kind: "working_buffer",
path: PathBuf::from("/virtual/working_buffer.md"),
status: "missing",
},
},
},
pod_identity_active: false,
};
let prepared = ensure_for_runtime(&layout, &loaded).expect("prepare compiled state");
assert_eq!(prepared.surface.status, "computed");
assert_eq!(prepared.surface.target, "session");
assert_eq!(prepared.store.target, ProjectionTarget::Session);
assert_eq!(
prepared.store.effective_memory.profile,
vec!["Use the loaded runtime view.".to_owned()]
);
assert_eq!(
prepared.store.workflow_signal_active,
vec!["Emit the default target.".to_owned()]
);
assert_eq!(
prepared.store.handoff.immediate_actions,
vec!["Avoid adapter rereads.".to_owned()]
);
}
#[test]
fn ensure_for_runtime_uses_execution_gate_anchor_as_loaded_focus() {
let temp = tempdir().expect("tempdir");
let layout = StateLayout::new(
temp.path().join(".ccd"),
temp.path().join(".git/ccd"),
ProfileName::new("main").expect("profile"),
);
let gate_state = ExecutionGateStateFile {
schema_version: 2,
seeded_from: Some("handoff:immediate_actions".to_owned()),
revision: 1,
gates: vec![
ExecutionGate {
text: "Ship schema migration.".to_owned(),
status: ExecutionGateStatus::Open,
},
ExecutionGate {
text: "Document the CLI surface.".to_owned(),
status: ExecutionGateStatus::Done,
},
],
};
let loaded = LoadedRuntimeState {
state: RuntimeState {
memory: RuntimeMemoryState {
profile: vec![RuntimeMemoryEntry::narrative(
"Use the loaded runtime view.",
)],
locality: Vec::new(),
pod: Vec::new(),
branch: Vec::new(),
clone: Vec::new(),
},
workflow_signal: RuntimeWorkflowSignalState {
items: vec![
RuntimeWorkflowSignalItem {
text: "Emit the default target.".to_owned(),
lifecycle: RuntimeLifecycle::Active,
},
RuntimeWorkflowSignalItem {
text: "Ship schema migration.".to_owned(),
lifecycle: RuntimeLifecycle::Active,
},
],
},
handoff: RuntimeHandoffState {
title: "Next Session: Runtime-first projection".to_owned(),
immediate_actions: vec![RuntimeHandoffItem {
text: "Avoid adapter rereads.".to_owned(),
lifecycle: RuntimeLifecycle::Active,
}],
completed_state: Vec::new(),
operational_guardrails: Vec::new(),
key_files: Vec::new(),
definition_of_done: Vec::new(),
},
},
sources: RuntimeSourceSurfaces {
profile_memory: RuntimeTextSurface {
kind: "profile_memory",
path: PathBuf::from("/virtual/profile-memory.md"),
status: RuntimeTextSurfaceStatus::Loaded,
content: "# Profile Memory\n\n- Use the loaded runtime view.\n".to_owned(),
migrated_from: None,
},
locality_memory: RuntimeTextSurface {
kind: "locality_memory",
path: PathBuf::from("/virtual/repo-memory.md"),
status: RuntimeTextSurfaceStatus::Missing,
content: String::new(),
migrated_from: None,
},
pod_memory: missing_pod_memory_surface(),
branch_memory: missing_branch_memory_surface(),
clone_memory: missing_clone_memory_surface(),
workflow_signal: RuntimeTextSurface {
kind: "workflow_signal",
path: PathBuf::from("/virtual/dispatch-state.md"),
status: RuntimeTextSurfaceStatus::Loaded,
content: "# Focus\n\n- Emit the default target.\n".to_owned(),
migrated_from: None,
},
execution_gates: RuntimeTextSurface {
kind: "execution_gates",
path: PathBuf::from("/virtual/state.db"),
status: RuntimeTextSurfaceStatus::LoadedNative,
content: serde_json::to_string_pretty(&gate_state).unwrap(),
migrated_from: None,
},
handoff: RuntimeTextSurface {
kind: "handoff",
path: PathBuf::from("/virtual/handoff.md"),
status: RuntimeTextSurfaceStatus::Loaded,
content: "# Next Session: Runtime-first projection\n".to_owned(),
migrated_from: None,
},
},
execution_gates: LoadedRuntimeExecutionGates {
source: RuntimeTextSurface {
kind: "execution_gates",
path: PathBuf::from("/virtual/state.db"),
status: RuntimeTextSurfaceStatus::LoadedNative,
content: serde_json::to_string_pretty(&gate_state).unwrap(),
migrated_from: None,
},
view: session_gates::ExecutionGatesView {
path: "/virtual/state.db".to_owned(),
status: "loaded",
seeded_from: Some("handoff:immediate_actions".to_owned()),
revision: Some(1),
total_count: 2,
unfinished_count: 1,
attention_anchor: Some(session_gates::ExecutionGateAnchor {
index: 1,
text: "Ship schema migration.".to_owned(),
status: ExecutionGateStatus::Open,
}),
gates: gate_state.gates.clone(),
},
},
recovery: LoadedRuntimeRecoveryState {
state: RuntimeRecoveryState::default(),
sources: RuntimeRecoverySurfaces {
checkpoint: RuntimeRecoverySurface {
kind: "checkpoint",
path: PathBuf::from("/virtual/checkpoint.json"),
status: "missing",
},
working_buffer: RuntimeRecoverySurface {
kind: "working_buffer",
path: PathBuf::from("/virtual/working_buffer.md"),
status: "missing",
},
},
},
pod_identity_active: false,
};
let prepared = ensure_for_runtime(&layout, &loaded).expect("prepare compiled state");
assert_eq!(
prepared.store.workflow_signal_active,
vec![
"Ship schema migration.".to_owned(),
"Emit the default target.".to_owned()
]
);
}
#[test]
fn projection_applies_default_active_state_bounds_after_filtering_and_dedupe() {
let state = RuntimeState {
memory: RuntimeMemoryState {
profile: (0..(DEFAULT_MAX_ACTIVE_MEMORY_ENTRIES_PER_SCOPE + 3))
.map(|index| RuntimeMemoryEntry::narrative(format!("Profile rule {index:02}")))
.chain(std::iter::once(RuntimeMemoryEntry::narrative(
"Profile rule 00".to_owned(),
)))
.collect(),
locality: (0..(DEFAULT_MAX_ACTIVE_MEMORY_ENTRIES_PER_SCOPE + 2))
.map(|index| RuntimeMemoryEntry::narrative(format!("Repo note {index:02}")))
.collect(),
pod: Vec::new(),
branch: Vec::new(),
clone: Vec::new(),
},
workflow_signal: RuntimeWorkflowSignalState {
items: (0..(DEFAULT_MAX_ACTIVE_WORKFLOW_SIGNAL_ITEMS + 3))
.map(|index| RuntimeWorkflowSignalItem {
text: format!("Focus item {index:02}"),
lifecycle: RuntimeLifecycle::Active,
})
.chain(std::iter::once(RuntimeWorkflowSignalItem {
text: "Focus item 00".to_owned(),
lifecycle: RuntimeLifecycle::Active,
}))
.collect(),
},
handoff: RuntimeHandoffState {
title: "Next Session: Bounded projection".to_owned(),
immediate_actions: (0..(DEFAULT_MAX_ACTIVE_HANDOFF_ITEMS_PER_SECTION + 3))
.map(|index| RuntimeHandoffItem {
text: format!("Immediate action {index:02}"),
lifecycle: RuntimeLifecycle::Active,
})
.collect(),
completed_state: Vec::new(),
operational_guardrails: Vec::new(),
key_files: (0..(DEFAULT_MAX_ACTIVE_HANDOFF_ITEMS_PER_SECTION + 2))
.map(|index| RuntimeHandoffItem {
text: format!("src/file_{index:02}.rs"),
lifecycle: RuntimeLifecycle::Active,
})
.collect(),
definition_of_done: Vec::new(),
},
};
let sources = RuntimeSourceSurfaces {
profile_memory: RuntimeTextSurface {
kind: "profile_memory",
path: PathBuf::from("/tmp/profile-memory.md"),
status: RuntimeTextSurfaceStatus::Loaded,
content: "profile".to_owned(),
migrated_from: None,
},
locality_memory: RuntimeTextSurface {
kind: "locality_memory",
path: PathBuf::from("/tmp/repo-memory.md"),
status: RuntimeTextSurfaceStatus::Loaded,
content: "repo".to_owned(),
migrated_from: None,
},
pod_memory: missing_pod_memory_surface(),
branch_memory: missing_branch_memory_surface(),
clone_memory: missing_clone_memory_surface(),
workflow_signal: RuntimeTextSurface {
kind: "workflow_signal",
path: PathBuf::from("/tmp/dispatch-state.md"),
status: RuntimeTextSurfaceStatus::Loaded,
content: "focus".to_owned(),
migrated_from: None,
},
execution_gates: missing_execution_gates_surface(),
handoff: RuntimeTextSurface {
kind: "handoff",
path: PathBuf::from("/tmp/handoff.md"),
status: RuntimeTextSurfaceStatus::Loaded,
content: "handoff".to_owned(),
migrated_from: None,
},
};
let compiled =
compile_runtime_projection(&state, &sources, ProjectionTarget::Default, false)
.expect("compiled projection");
assert_eq!(
compiled.effective_memory.profile.len(),
DEFAULT_MAX_ACTIVE_MEMORY_ENTRIES_PER_SCOPE
);
assert_eq!(
compiled.effective_memory.profile[0],
"Profile rule 00".to_owned()
);
assert_eq!(
compiled.effective_memory.profile.last().unwrap(),
&format!(
"Profile rule {:02}",
DEFAULT_MAX_ACTIVE_MEMORY_ENTRIES_PER_SCOPE - 1
)
);
assert_eq!(
compiled.effective_memory.locality.len(),
DEFAULT_MAX_ACTIVE_MEMORY_ENTRIES_PER_SCOPE
);
assert_eq!(
compiled.workflow_signal_active.len(),
DEFAULT_MAX_ACTIVE_WORKFLOW_SIGNAL_ITEMS
);
assert_eq!(
compiled.workflow_signal_active.last().unwrap(),
&format!(
"Focus item {:02}",
DEFAULT_MAX_ACTIVE_WORKFLOW_SIGNAL_ITEMS - 1
)
);
assert_eq!(
compiled.handoff.immediate_actions.len(),
DEFAULT_MAX_ACTIVE_HANDOFF_ITEMS_PER_SECTION
);
assert_eq!(
compiled.handoff.immediate_actions.last().unwrap(),
&format!(
"Immediate action {:02}",
DEFAULT_MAX_ACTIVE_HANDOFF_ITEMS_PER_SECTION - 1
)
);
assert_eq!(
compiled.handoff.key_files.len(),
DEFAULT_MAX_ACTIVE_HANDOFF_ITEMS_PER_SECTION
);
assert_eq!(
compiled.handoff.key_files.last().unwrap(),
&format!(
"src/file_{:02}.rs",
DEFAULT_MAX_ACTIVE_HANDOFF_ITEMS_PER_SECTION - 1
)
);
}
#[test]
fn planning_target_omits_completed_state_and_key_files() {
let state = RuntimeState {
memory: RuntimeMemoryState {
profile: vec![RuntimeMemoryEntry::narrative("Retain operator rules.")],
locality: vec![RuntimeMemoryEntry::narrative("Retain repo lessons.")],
pod: Vec::new(),
branch: Vec::new(),
clone: Vec::new(),
},
workflow_signal: RuntimeWorkflowSignalState {
items: vec![RuntimeWorkflowSignalItem {
text: "Choose the next task.".to_owned(),
lifecycle: RuntimeLifecycle::Active,
}],
},
handoff: RuntimeHandoffState {
title: "Next Session: Plan the slice".to_owned(),
immediate_actions: vec![RuntimeHandoffItem {
text: "Review the backlog.".to_owned(),
lifecycle: RuntimeLifecycle::Active,
}],
completed_state: vec![RuntimeHandoffItem {
text: "Completed work should stay out of planning.".to_owned(),
lifecycle: RuntimeLifecycle::Active,
}],
operational_guardrails: vec![RuntimeHandoffItem {
text: "Keep projections fail-closed.".to_owned(),
lifecycle: RuntimeLifecycle::Active,
}],
key_files: vec![RuntimeHandoffItem {
text: "`src/state/runtime_export.rs`".to_owned(),
lifecycle: RuntimeLifecycle::Active,
}],
definition_of_done: vec![RuntimeHandoffItem {
text: "Scoped target is explicit.".to_owned(),
lifecycle: RuntimeLifecycle::Active,
}],
},
};
let sources = RuntimeSourceSurfaces {
profile_memory: RuntimeTextSurface {
kind: "profile_memory",
path: PathBuf::from("/tmp/profile-memory.md"),
status: RuntimeTextSurfaceStatus::Loaded,
content: "profile".to_owned(),
migrated_from: None,
},
locality_memory: RuntimeTextSurface {
kind: "locality_memory",
path: PathBuf::from("/tmp/repo-memory.md"),
status: RuntimeTextSurfaceStatus::Loaded,
content: "repo".to_owned(),
migrated_from: None,
},
pod_memory: missing_pod_memory_surface(),
branch_memory: missing_branch_memory_surface(),
clone_memory: missing_clone_memory_surface(),
workflow_signal: RuntimeTextSurface {
kind: "workflow_signal",
path: PathBuf::from("/tmp/dispatch-state.md"),
status: RuntimeTextSurfaceStatus::Loaded,
content: "focus".to_owned(),
migrated_from: None,
},
execution_gates: missing_execution_gates_surface(),
handoff: RuntimeTextSurface {
kind: "handoff",
path: PathBuf::from("/tmp/handoff.md"),
status: RuntimeTextSurfaceStatus::Loaded,
content: "handoff".to_owned(),
migrated_from: None,
},
};
let compiled =
compile_runtime_projection(&state, &sources, ProjectionTarget::Planning, false)
.expect("compiled planning projection");
assert_eq!(compiled.target, ProjectionTarget::Planning);
assert_eq!(
compiled.effective_memory.profile,
vec!["Retain operator rules.".to_owned()]
);
assert_eq!(
compiled.workflow_signal_active,
vec!["Choose the next task.".to_owned()]
);
assert_eq!(
compiled.handoff.immediate_actions,
vec!["Review the backlog.".to_owned()]
);
assert_eq!(
compiled.handoff.operational_guardrails,
vec!["Keep projections fail-closed.".to_owned()]
);
assert_eq!(
compiled.handoff.definition_of_done,
vec!["Scoped target is explicit.".to_owned()]
);
assert!(compiled.handoff.completed_state.is_empty());
assert!(compiled.handoff.key_files.is_empty());
}
#[test]
fn session_target_omits_completed_state_key_files_and_definition_of_done() {
let state = RuntimeState {
memory: RuntimeMemoryState {
profile: vec![RuntimeMemoryEntry::narrative("Retain operator rules.")],
locality: vec![RuntimeMemoryEntry::narrative("Retain repo lessons.")],
pod: Vec::new(),
branch: Vec::new(),
clone: Vec::new(),
},
workflow_signal: RuntimeWorkflowSignalState {
items: vec![RuntimeWorkflowSignalItem {
text: "Choose the next task.".to_owned(),
lifecycle: RuntimeLifecycle::Active,
}],
},
handoff: RuntimeHandoffState {
title: "Next Session: Start the slice".to_owned(),
immediate_actions: vec![RuntimeHandoffItem {
text: "Review the backlog.".to_owned(),
lifecycle: RuntimeLifecycle::Active,
}],
completed_state: vec![RuntimeHandoffItem {
text: "Completed work should stay out of the start bundle.".to_owned(),
lifecycle: RuntimeLifecycle::Active,
}],
operational_guardrails: vec![RuntimeHandoffItem {
text: "Keep projections fail-closed.".to_owned(),
lifecycle: RuntimeLifecycle::Active,
}],
key_files: vec![RuntimeHandoffItem {
text: "`src/state/runtime_export.rs`".to_owned(),
lifecycle: RuntimeLifecycle::Active,
}],
definition_of_done: vec![RuntimeHandoffItem {
text: "Scoped target is explicit.".to_owned(),
lifecycle: RuntimeLifecycle::Active,
}],
},
};
let sources = RuntimeSourceSurfaces {
profile_memory: RuntimeTextSurface {
kind: "profile_memory",
path: PathBuf::from("/tmp/profile-memory.md"),
status: RuntimeTextSurfaceStatus::Loaded,
content: "profile".to_owned(),
migrated_from: None,
},
locality_memory: RuntimeTextSurface {
kind: "locality_memory",
path: PathBuf::from("/tmp/repo-memory.md"),
status: RuntimeTextSurfaceStatus::Loaded,
content: "repo".to_owned(),
migrated_from: None,
},
pod_memory: missing_pod_memory_surface(),
branch_memory: missing_branch_memory_surface(),
clone_memory: missing_clone_memory_surface(),
workflow_signal: RuntimeTextSurface {
kind: "workflow_signal",
path: PathBuf::from("/tmp/dispatch-state.md"),
status: RuntimeTextSurfaceStatus::Loaded,
content: "focus".to_owned(),
migrated_from: None,
},
execution_gates: missing_execution_gates_surface(),
handoff: RuntimeTextSurface {
kind: "handoff",
path: PathBuf::from("/tmp/handoff.md"),
status: RuntimeTextSurfaceStatus::Loaded,
content: "handoff".to_owned(),
migrated_from: None,
},
};
let compiled =
compile_runtime_projection(&state, &sources, ProjectionTarget::Session, false)
.expect("compiled session projection");
assert_eq!(compiled.target, ProjectionTarget::Session);
assert_eq!(
compiled.handoff.immediate_actions,
vec!["Review the backlog.".to_owned()]
);
assert_eq!(
compiled.handoff.operational_guardrails,
vec!["Keep projections fail-closed.".to_owned()]
);
assert!(compiled.handoff.completed_state.is_empty());
assert!(compiled.handoff.key_files.is_empty());
assert!(compiled.handoff.definition_of_done.is_empty());
}
#[test]
fn narrative_projection_dedupes_repeated_lines_across_surfaces() {
let state = RuntimeState {
memory: RuntimeMemoryState {
profile: vec![RuntimeMemoryEntry::narrative("Keep projections bounded.")],
locality: vec![RuntimeMemoryEntry::narrative("Keep projections bounded.")],
pod: Vec::new(),
branch: Vec::new(),
clone: Vec::new(),
},
workflow_signal: RuntimeWorkflowSignalState {
items: vec![RuntimeWorkflowSignalItem {
text: "Keep projections bounded.".to_owned(),
lifecycle: RuntimeLifecycle::Active,
}],
},
handoff: RuntimeHandoffState {
title: "Next Session: Dedupe".to_owned(),
immediate_actions: vec![RuntimeHandoffItem {
text: "Keep projections bounded.".to_owned(),
lifecycle: RuntimeLifecycle::Active,
}],
completed_state: Vec::new(),
operational_guardrails: vec![RuntimeHandoffItem {
text: "Keep projections bounded.".to_owned(),
lifecycle: RuntimeLifecycle::Active,
}],
key_files: Vec::new(),
definition_of_done: vec![RuntimeHandoffItem {
text: "Keep projections bounded.".to_owned(),
lifecycle: RuntimeLifecycle::Active,
}],
},
};
let sources = RuntimeSourceSurfaces {
profile_memory: RuntimeTextSurface {
kind: "profile_memory",
path: PathBuf::from("/tmp/profile-memory.md"),
status: RuntimeTextSurfaceStatus::Loaded,
content: "profile".to_owned(),
migrated_from: None,
},
locality_memory: RuntimeTextSurface {
kind: "locality_memory",
path: PathBuf::from("/tmp/repo-memory.md"),
status: RuntimeTextSurfaceStatus::Loaded,
content: "repo".to_owned(),
migrated_from: None,
},
pod_memory: missing_pod_memory_surface(),
branch_memory: missing_branch_memory_surface(),
clone_memory: missing_clone_memory_surface(),
workflow_signal: RuntimeTextSurface {
kind: "workflow_signal",
path: PathBuf::from("/tmp/dispatch-state.md"),
status: RuntimeTextSurfaceStatus::Loaded,
content: "focus".to_owned(),
migrated_from: None,
},
execution_gates: missing_execution_gates_surface(),
handoff: RuntimeTextSurface {
kind: "handoff",
path: PathBuf::from("/tmp/handoff.md"),
status: RuntimeTextSurfaceStatus::Loaded,
content: "handoff".to_owned(),
migrated_from: None,
},
};
let compiled =
compile_runtime_projection(&state, &sources, ProjectionTarget::Planning, false)
.expect("compiled planning projection");
assert_eq!(
compiled.effective_memory.profile,
vec!["Keep projections bounded.".to_owned()]
);
assert!(compiled.effective_memory.locality.is_empty());
assert!(compiled.workflow_signal_active.is_empty());
assert!(compiled.handoff.immediate_actions.is_empty());
assert!(compiled.handoff.operational_guardrails.is_empty());
assert!(compiled.handoff.definition_of_done.is_empty());
}
#[test]
fn symbolic_projection_uses_fact_kinds_and_default_target_sections() {
let state = RuntimeState {
memory: RuntimeMemoryState {
profile: vec![
RuntimeMemoryEntry::narrative("Retain operator rules."),
RuntimeMemoryEntry::from_structured_entry(StructuredMemoryEntry {
id: "mem_rule".to_owned(),
entry_type: "rule".to_owned(),
state: "active".to_owned(),
created_at: "2026-03-10T12:00:00Z".to_owned(),
last_touched_session: 7,
origin: "manual".to_owned(),
superseded_at: None,
decay_class: None,
expires_at: None,
tags: vec!["projection".to_owned()],
source_ref: None,
supersedes: Vec::new(),
content: "Prefer deterministic writes.".to_owned(),
}),
],
locality: vec![RuntimeMemoryEntry::narrative("Keep repo state bounded.")],
pod: Vec::new(),
branch: Vec::new(),
clone: Vec::new(),
},
workflow_signal: RuntimeWorkflowSignalState {
items: vec![RuntimeWorkflowSignalItem {
text: "Land symbolic preview coverage.".to_owned(),
lifecycle: RuntimeLifecycle::Active,
}],
},
handoff: RuntimeHandoffState {
title: "Next Session: Evaluate symbolic facts".to_owned(),
immediate_actions: vec![RuntimeHandoffItem {
text: "Measure prompt entropy.".to_owned(),
lifecycle: RuntimeLifecycle::Active,
}],
completed_state: vec![RuntimeHandoffItem {
text: "Narrative preview already works.".to_owned(),
lifecycle: RuntimeLifecycle::Active,
}],
operational_guardrails: vec![RuntimeHandoffItem {
text: "Keep the cache derived.".to_owned(),
lifecycle: RuntimeLifecycle::Active,
}],
key_files: vec![RuntimeHandoffItem {
text: "`src/state/compiled.rs`".to_owned(),
lifecycle: RuntimeLifecycle::Active,
}],
definition_of_done: vec![RuntimeHandoffItem {
text: "Decision is documented.".to_owned(),
lifecycle: RuntimeLifecycle::Active,
}],
},
};
let sources = RuntimeSourceSurfaces {
profile_memory: RuntimeTextSurface {
kind: "profile_memory",
path: PathBuf::from("/tmp/profile-memory.md"),
status: RuntimeTextSurfaceStatus::Loaded,
content: "profile".to_owned(),
migrated_from: None,
},
locality_memory: RuntimeTextSurface {
kind: "locality_memory",
path: PathBuf::from("/tmp/repo-memory.md"),
status: RuntimeTextSurfaceStatus::Loaded,
content: "repo".to_owned(),
migrated_from: None,
},
pod_memory: missing_pod_memory_surface(),
branch_memory: missing_branch_memory_surface(),
clone_memory: missing_clone_memory_surface(),
workflow_signal: RuntimeTextSurface {
kind: "workflow_signal",
path: PathBuf::from("/tmp/dispatch-state.md"),
status: RuntimeTextSurfaceStatus::Loaded,
content: "focus".to_owned(),
migrated_from: None,
},
execution_gates: missing_execution_gates_surface(),
handoff: RuntimeTextSurface {
kind: "handoff",
path: PathBuf::from("/tmp/handoff.md"),
status: RuntimeTextSurfaceStatus::Loaded,
content: "handoff".to_owned(),
migrated_from: None,
},
};
let symbolic =
compile_symbolic_projection(&state, &sources, ProjectionTarget::Default, false)
.unwrap();
assert_eq!(symbolic.target, ProjectionTarget::Default);
assert!(symbolic.facts.contains(&SymbolicFact {
surface: "profile_memory".to_owned(),
kind: "narrative".to_owned(),
ordinal: Some(1),
text: "Retain operator rules.".to_owned(),
}));
assert!(symbolic.facts.contains(&SymbolicFact {
surface: "profile_memory".to_owned(),
kind: "rule".to_owned(),
ordinal: Some(2),
text: "Prefer deterministic writes.".to_owned(),
}));
assert!(symbolic.facts.contains(&SymbolicFact {
surface: "handoff_completed_state".to_owned(),
kind: "item".to_owned(),
ordinal: Some(1),
text: "Narrative preview already works.".to_owned(),
}));
assert!(symbolic.facts.contains(&SymbolicFact {
surface: "handoff_key_files".to_owned(),
kind: "item".to_owned(),
ordinal: Some(1),
text: "`src/state/compiled.rs`".to_owned(),
}));
}
#[test]
fn symbolic_planning_target_omits_completed_state_and_key_files() {
let state = RuntimeState {
memory: RuntimeMemoryState {
profile: vec![RuntimeMemoryEntry::narrative("Retain operator rules.")],
locality: vec![RuntimeMemoryEntry::narrative("Retain repo lessons.")],
pod: Vec::new(),
branch: Vec::new(),
clone: Vec::new(),
},
workflow_signal: RuntimeWorkflowSignalState {
items: vec![RuntimeWorkflowSignalItem {
text: "Choose the next task.".to_owned(),
lifecycle: RuntimeLifecycle::Active,
}],
},
handoff: RuntimeHandoffState {
title: "Next Session: Plan the slice".to_owned(),
immediate_actions: vec![RuntimeHandoffItem {
text: "Review the backlog.".to_owned(),
lifecycle: RuntimeLifecycle::Active,
}],
completed_state: vec![RuntimeHandoffItem {
text: "Completed work should stay out of planning.".to_owned(),
lifecycle: RuntimeLifecycle::Active,
}],
operational_guardrails: vec![RuntimeHandoffItem {
text: "Keep projections fail-closed.".to_owned(),
lifecycle: RuntimeLifecycle::Active,
}],
key_files: vec![RuntimeHandoffItem {
text: "`src/state/runtime_export.rs`".to_owned(),
lifecycle: RuntimeLifecycle::Active,
}],
definition_of_done: vec![RuntimeHandoffItem {
text: "Scoped target is explicit.".to_owned(),
lifecycle: RuntimeLifecycle::Active,
}],
},
};
let sources = RuntimeSourceSurfaces {
profile_memory: RuntimeTextSurface {
kind: "profile_memory",
path: PathBuf::from("/tmp/profile-memory.md"),
status: RuntimeTextSurfaceStatus::Loaded,
content: "profile".to_owned(),
migrated_from: None,
},
locality_memory: RuntimeTextSurface {
kind: "locality_memory",
path: PathBuf::from("/tmp/repo-memory.md"),
status: RuntimeTextSurfaceStatus::Loaded,
content: "repo".to_owned(),
migrated_from: None,
},
pod_memory: missing_pod_memory_surface(),
branch_memory: missing_branch_memory_surface(),
clone_memory: missing_clone_memory_surface(),
workflow_signal: RuntimeTextSurface {
kind: "workflow_signal",
path: PathBuf::from("/tmp/dispatch-state.md"),
status: RuntimeTextSurfaceStatus::Loaded,
content: "focus".to_owned(),
migrated_from: None,
},
execution_gates: missing_execution_gates_surface(),
handoff: RuntimeTextSurface {
kind: "handoff",
path: PathBuf::from("/tmp/handoff.md"),
status: RuntimeTextSurfaceStatus::Loaded,
content: "handoff".to_owned(),
migrated_from: None,
},
};
let symbolic =
compile_symbolic_projection(&state, &sources, ProjectionTarget::Planning, false)
.unwrap();
assert_eq!(symbolic.target, ProjectionTarget::Planning);
assert!(!symbolic
.facts
.iter()
.any(|fact| fact.surface == "handoff_completed_state"));
assert!(!symbolic
.facts
.iter()
.any(|fact| fact.surface == "handoff_key_files"));
assert_eq!(
render_symbolic_content(&symbolic),
"\
profile_memory|narrative|1|Retain operator rules.\n\
locality_memory|narrative|1|Retain repo lessons.\n\
workflow_signal|item|1|Choose the next task.\n\
handoff_title|title|Next Session: Plan the slice\n\
handoff_immediate_actions|item|1|Review the backlog.\n\
handoff_operational_guardrails|item|1|Keep projections fail-closed.\n\
handoff_definition_of_done|item|1|Scoped target is explicit."
);
}
#[test]
fn symbolic_session_target_omits_definition_of_done_and_key_files() {
let state = RuntimeState {
memory: RuntimeMemoryState {
profile: vec![RuntimeMemoryEntry::narrative("Retain operator rules.")],
locality: vec![RuntimeMemoryEntry::narrative("Retain repo lessons.")],
pod: Vec::new(),
branch: Vec::new(),
clone: Vec::new(),
},
workflow_signal: RuntimeWorkflowSignalState {
items: vec![RuntimeWorkflowSignalItem {
text: "Choose the next task.".to_owned(),
lifecycle: RuntimeLifecycle::Active,
}],
},
handoff: RuntimeHandoffState {
title: "Next Session: Start the slice".to_owned(),
immediate_actions: vec![RuntimeHandoffItem {
text: "Review the backlog.".to_owned(),
lifecycle: RuntimeLifecycle::Active,
}],
completed_state: vec![RuntimeHandoffItem {
text: "Completed work should stay out of the start bundle.".to_owned(),
lifecycle: RuntimeLifecycle::Active,
}],
operational_guardrails: vec![RuntimeHandoffItem {
text: "Keep projections fail-closed.".to_owned(),
lifecycle: RuntimeLifecycle::Active,
}],
key_files: vec![RuntimeHandoffItem {
text: "`src/state/runtime_export.rs`".to_owned(),
lifecycle: RuntimeLifecycle::Active,
}],
definition_of_done: vec![RuntimeHandoffItem {
text: "Scoped target is explicit.".to_owned(),
lifecycle: RuntimeLifecycle::Active,
}],
},
};
let sources = RuntimeSourceSurfaces {
profile_memory: RuntimeTextSurface {
kind: "profile_memory",
path: PathBuf::from("/tmp/profile-memory.md"),
status: RuntimeTextSurfaceStatus::Loaded,
content: "profile".to_owned(),
migrated_from: None,
},
locality_memory: RuntimeTextSurface {
kind: "locality_memory",
path: PathBuf::from("/tmp/repo-memory.md"),
status: RuntimeTextSurfaceStatus::Loaded,
content: "repo".to_owned(),
migrated_from: None,
},
pod_memory: missing_pod_memory_surface(),
branch_memory: missing_branch_memory_surface(),
clone_memory: missing_clone_memory_surface(),
workflow_signal: RuntimeTextSurface {
kind: "workflow_signal",
path: PathBuf::from("/tmp/dispatch-state.md"),
status: RuntimeTextSurfaceStatus::Loaded,
content: "focus".to_owned(),
migrated_from: None,
},
execution_gates: missing_execution_gates_surface(),
handoff: RuntimeTextSurface {
kind: "handoff",
path: PathBuf::from("/tmp/handoff.md"),
status: RuntimeTextSurfaceStatus::Loaded,
content: "handoff".to_owned(),
migrated_from: None,
},
};
let symbolic =
compile_symbolic_projection(&state, &sources, ProjectionTarget::Session, false)
.unwrap();
assert_eq!(symbolic.target, ProjectionTarget::Session);
assert!(!symbolic
.facts
.iter()
.any(|fact| fact.surface == "handoff_completed_state"));
assert!(!symbolic
.facts
.iter()
.any(|fact| fact.surface == "handoff_key_files"));
assert!(!symbolic
.facts
.iter()
.any(|fact| fact.surface == "handoff_definition_of_done"));
assert_eq!(
render_symbolic_content(&symbolic),
"\
profile_memory|narrative|1|Retain operator rules.\n\
locality_memory|narrative|1|Retain repo lessons.\n\
workflow_signal|item|1|Choose the next task.\n\
handoff_title|title|Next Session: Start the slice\n\
handoff_immediate_actions|item|1|Review the backlog.\n\
handoff_operational_guardrails|item|1|Keep projections fail-closed."
);
}
fn make_test_sources(
profile: &str,
repo: &str,
focus: &str,
handoff: &str,
) -> RuntimeSourceSurfaces {
RuntimeSourceSurfaces {
profile_memory: RuntimeTextSurface {
kind: "profile_memory",
path: PathBuf::from("/tmp/profile-memory.md"),
status: RuntimeTextSurfaceStatus::Loaded,
content: profile.to_owned(),
migrated_from: None,
},
locality_memory: RuntimeTextSurface {
kind: "locality_memory",
path: PathBuf::from("/tmp/repo-memory.md"),
status: RuntimeTextSurfaceStatus::Loaded,
content: repo.to_owned(),
migrated_from: None,
},
pod_memory: missing_pod_memory_surface(),
branch_memory: missing_branch_memory_surface(),
clone_memory: missing_clone_memory_surface(),
workflow_signal: RuntimeTextSurface {
kind: "workflow_signal",
path: PathBuf::from("/tmp/dispatch-state.md"),
status: RuntimeTextSurfaceStatus::Loaded,
content: focus.to_owned(),
migrated_from: None,
},
execution_gates: missing_execution_gates_surface(),
handoff: RuntimeTextSurface {
kind: "handoff",
path: PathBuf::from("/tmp/handoff.md"),
status: RuntimeTextSurfaceStatus::Loaded,
content: handoff.to_owned(),
migrated_from: None,
},
}
}
#[test]
fn projection_digests_are_deterministic() {
let state = RuntimeState {
memory: RuntimeMemoryState {
profile: vec![RuntimeMemoryEntry::narrative("Rule one.")],
locality: vec![RuntimeMemoryEntry::narrative("Repo note.")],
pod: Vec::new(),
branch: Vec::new(),
clone: Vec::new(),
},
workflow_signal: RuntimeWorkflowSignalState {
items: vec![RuntimeWorkflowSignalItem {
text: "Focus item.".to_owned(),
lifecycle: RuntimeLifecycle::Active,
}],
},
handoff: RuntimeHandoffState {
title: "Next Session: Determinism".to_owned(),
immediate_actions: vec![RuntimeHandoffItem {
text: "Check hashes.".to_owned(),
lifecycle: RuntimeLifecycle::Active,
}],
completed_state: Vec::new(),
operational_guardrails: Vec::new(),
key_files: Vec::new(),
definition_of_done: Vec::new(),
},
};
let sources = make_test_sources("profile", "repo", "focus", "handoff");
let first =
compile_runtime_projection(&state, &sources, ProjectionTarget::Session, false).unwrap();
let second =
compile_runtime_projection(&state, &sources, ProjectionTarget::Session, false).unwrap();
let d1 = first.projection_digests.unwrap();
let d2 = second.projection_digests.unwrap();
assert_eq!(d1, d2);
}
#[test]
fn projection_digests_stable_when_filtered_input_changes() {
let state = RuntimeState {
memory: RuntimeMemoryState {
profile: vec![RuntimeMemoryEntry::narrative("Rule one.")],
locality: Vec::new(),
pod: Vec::new(),
branch: Vec::new(),
clone: Vec::new(),
},
workflow_signal: RuntimeWorkflowSignalState {
items: vec![RuntimeWorkflowSignalItem {
text: "Focus item.".to_owned(),
lifecycle: RuntimeLifecycle::Active,
}],
},
handoff: RuntimeHandoffState {
title: "Next Session: Filtered".to_owned(),
immediate_actions: vec![RuntimeHandoffItem {
text: "Act now.".to_owned(),
lifecycle: RuntimeLifecycle::Active,
}],
completed_state: vec![RuntimeHandoffItem {
text: "Completed work.".to_owned(),
lifecycle: RuntimeLifecycle::Active,
}],
operational_guardrails: Vec::new(),
key_files: vec![RuntimeHandoffItem {
text: "`src/file.rs`".to_owned(),
lifecycle: RuntimeLifecycle::Active,
}],
definition_of_done: vec![RuntimeHandoffItem {
text: "Tests pass.".to_owned(),
lifecycle: RuntimeLifecycle::Active,
}],
},
};
let state_modified = RuntimeState {
handoff: RuntimeHandoffState {
completed_state: vec![
RuntimeHandoffItem {
text: "Completed work.".to_owned(),
lifecycle: RuntimeLifecycle::Active,
},
RuntimeHandoffItem {
text: "Extra completed item.".to_owned(),
lifecycle: RuntimeLifecycle::Active,
},
],
key_files: vec![
RuntimeHandoffItem {
text: "`src/file.rs`".to_owned(),
lifecycle: RuntimeLifecycle::Active,
},
RuntimeHandoffItem {
text: "`src/new_file.rs`".to_owned(),
lifecycle: RuntimeLifecycle::Active,
},
],
definition_of_done: vec![
RuntimeHandoffItem {
text: "Tests pass.".to_owned(),
lifecycle: RuntimeLifecycle::Active,
},
RuntimeHandoffItem {
text: "Docs updated.".to_owned(),
lifecycle: RuntimeLifecycle::Active,
},
],
..state.handoff.clone()
},
..state.clone()
};
let sources = make_test_sources("profile", "repo", "focus", "handoff");
let original =
compile_runtime_projection(&state, &sources, ProjectionTarget::Session, false).unwrap();
let modified =
compile_runtime_projection(&state_modified, &sources, ProjectionTarget::Session, false)
.unwrap();
let d_original = original.projection_digests.unwrap();
let d_modified = modified.projection_digests.unwrap();
assert_eq!(
d_original, d_modified,
"session target filters completed_state, key_files, and definition_of_done — changing only those should not change projection digests"
);
}
#[test]
fn context_delta_returns_only_changed_surfaces() {
let previous = ProjectionDigests {
effective_memory: "aaa".to_owned(),
workflow_signal: "bbb".to_owned(),
handoff: "ccc".to_owned(),
execution_gates: "ddd".to_owned(),
escalation: "eee".to_owned(),
recovery: "fff".to_owned(),
git_state: "ggg".to_owned(),
session_state: "hhh".to_owned(),
};
let current = ProjectionDigests {
effective_memory: "aaa".to_owned(),
workflow_signal: "bbb_changed".to_owned(),
handoff: "ccc".to_owned(),
execution_gates: "ddd".to_owned(),
escalation: "eee".to_owned(),
recovery: "fff".to_owned(),
git_state: "ggg".to_owned(),
session_state: "hhh".to_owned(),
};
let delta =
compute_context_delta(&previous, ¤t, "fp_old", "fp_new").expect("delta present");
assert_eq!(delta.changed_surfaces.len(), 1);
assert_eq!(delta.changed_surfaces[0].name, "workflow_signal");
assert_eq!(delta.previous_fingerprint, "fp_old");
assert_eq!(delta.current_fingerprint, "fp_new");
let no_delta = compute_context_delta(&previous, &previous, "fp", "fp");
assert!(no_delta.is_none());
}
#[test]
fn projection_digests_deserializes_old_repo_focus_field() {
let old_json = r#"{"effective_memory":"aaa","repo_focus":"bbb","handoff":"ccc"}"#;
let digests: ProjectionDigests = serde_json::from_str(old_json)
.expect("old repo_focus field should deserialize via alias");
assert_eq!(digests.workflow_signal, "bbb");
assert_eq!(digests.effective_memory, "aaa");
assert_eq!(digests.handoff, "ccc");
let reserialized = serde_json::to_string(&digests).expect("serialize");
assert!(reserialized.contains("workflow_signal"));
assert!(!reserialized.contains("repo_focus"));
}
#[test]
fn extended_digests_default_empty_for_backward_compat() {
let json = r#"{"effective_memory":"aaa","workflow_signal":"bbb","handoff":"ccc"}"#;
let digests: ProjectionDigests = serde_json::from_str(json).unwrap();
assert_eq!(digests.effective_memory, "aaa");
assert_eq!(digests.workflow_signal, "bbb");
assert_eq!(digests.handoff, "ccc");
assert_eq!(digests.execution_gates, "");
assert_eq!(digests.escalation, "");
assert_eq!(digests.recovery, "");
assert_eq!(digests.git_state, "");
assert_eq!(digests.session_state, "");
}
#[test]
fn compute_extended_digests_hashes_all_surfaces() {
let base = ProjectionDigests {
effective_memory: "mem_hash".to_owned(),
workflow_signal: "wf_hash".to_owned(),
handoff: "ho_hash".to_owned(),
execution_gates: String::new(),
escalation: String::new(),
recovery: String::new(),
git_state: String::new(),
session_state: String::new(),
};
let extended = compute_extended_digests(&base, "gates", "esc", "rec", "git", "sess");
assert_eq!(extended.effective_memory, "mem_hash");
assert_eq!(extended.workflow_signal, "wf_hash");
assert_eq!(extended.handoff, "ho_hash");
assert_ne!(extended.execution_gates, "");
assert_ne!(extended.escalation, "");
assert_ne!(extended.recovery, "");
assert_ne!(extended.git_state, "");
assert_ne!(extended.session_state, "");
let extended2 = compute_extended_digests(&base, "gates", "esc", "rec", "git", "sess");
assert_eq!(extended.execution_gates, extended2.execution_gates);
}
#[test]
fn context_delta_skips_empty_extended_fields() {
let old = ProjectionDigests {
effective_memory: "aaa".to_owned(),
workflow_signal: "bbb".to_owned(),
handoff: "ccc".to_owned(),
execution_gates: String::new(), escalation: String::new(),
recovery: String::new(),
git_state: String::new(),
session_state: String::new(),
};
let new = ProjectionDigests {
effective_memory: "aaa".to_owned(),
workflow_signal: "bbb".to_owned(),
handoff: "ddd".to_owned(), execution_gates: "xxx".to_owned(),
escalation: "yyy".to_owned(),
recovery: "zzz".to_owned(),
git_state: "ggg".to_owned(),
session_state: "sss".to_owned(),
};
let delta = compute_context_delta(&old, &new, "fp1", "fp2");
assert!(delta.is_some());
let delta = delta.unwrap();
assert_eq!(delta.changed_surfaces.len(), 1);
assert_eq!(delta.changed_surfaces[0].name, "handoff");
}
}