Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions STRUCTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ Unless specified otherwise, TypeScript paths are relative to `packages/plugin/`
- `src/hooks/magic-context/compaction-off-transition.ts`: Reconcile per-session compaction mode records and process off/on mode transitions.
- `src/hooks/magic-context/child-session-spawn.ts`: Enforce child session spawn choke point with schema fence validation.
- `src/shared/escalation-bands.ts`: Derive context limit escalation bands and threshold bounds.
- `src/features/magic-context/migrations.ts`: Versioned schema migrations v1–v78 (`LATEST_SUPPORTED_VERSION` in `storage-db.ts` must track the highest; `schema-version-fence.test.ts` asserts they stay in lockstep).
- `src/features/magic-context/migrations.ts`: Versioned schema migrations v1–v79 (`LATEST_SUPPORTED_VERSION` in `storage-db.ts` must track the highest; `schema-version-fence.test.ts` asserts they stay in lockstep). v79 adds content-bound memory episode evidence.
- `src/features/magic-context/message-index.ts`: FTS-backed raw-message index for `ctx_search`.
- `src/features/magic-context/search.ts`: Unified retrieval over memories, raw messages, git commits, and session/smart notes.
- `src/features/magic-context/session-project-storage.ts`: Persist session-to-project bindings and repair mis-scoped compartment chunk embeddings.
Expand All @@ -200,7 +200,7 @@ Unless specified otherwise, TypeScript paths are relative to `packages/plugin/`
- `crates/mc-module/src/session_resolver.rs`: Resolves incoming MCP facade requests to their backing project and session.
- `crates/mc-module/src/lib.rs`: Route subc client requests, implement MCP tool facade routing (supporting `agent_drops.append` queue drops with server-side range parsing and command-id idempotency checks), serve prompt guidance, manage durable pass tracing for transform passes, orchestrate `session.status`, `session.wrapup`, and `session.delete` operations (utilizing structured status fields, machine-readable dispositions, and process-local per-session latches under a `MAX_WRAPUP_REQUEST_BUDGET` deadline, with `session.delete` atomically removing session-owned rows from SQLite tables), track transform dispatch health metrics and heartbeat reporting, manage LRU-bounded `InFlight` snapshot caching, and coordinate bootstrap state imports using `StateImportCoordinator`.
- `crates/mc-module/src/historian_producer.rs`: Implement the Rust subc historian producer client using the wire v2 protocol with `OpenedRoute` targeting (channel and epoch routing).
- `crates/mc-store/src/lib.rs`: Define durable session schemas and migrations (including the `mc_reduce_command_ledger` table in migration 16 for idempotency, `mc_project_mural_artifacts` in migration 49 for project mural artifacts, and `raw_messages_deflate` in migration 50 on `mc_chunk_transcripts` for durable `ctx_expand` recovery), handle metadata, and run CAS transitions.
- `crates/mc-store/src/lib.rs`: Define durable session schemas and migrations (including the `mc_reduce_command_ledger` table in migration 16 for idempotency, `mc_project_mural_artifacts` in migration 49 for project mural artifacts, `raw_messages_deflate` in migration 50 on `mc_chunk_transcripts` for durable `ctx_expand` recovery, and content-bound memory evidence in migration 51), handle metadata, and run CAS transitions.
- `crates/mc-module/src/codec/`: Decode harness-specific JSON messages (OpenCode, Pi) into canonical `CkIngressMessage` values and encode them back using harness model codecs.
- `crates/mc-module/src/caveman.rs`: Age-tier caveman text compression ported to Rust.
- `crates/mc-module/src/divergence.rs`: Per-pass transform output divergence tracking and attribution.
Expand Down
66 changes: 65 additions & 1 deletion crates/mc-module/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ use mc_store::TagNumberRow;
use mc_store::{
canonical_root, validate_state_import_compartments, AuthoritySeedRow, DeferredExecuteState,
FacadeMutationOutcome, HistorianPhase, InsertMemoryInput, MappingUpdate, McStore, McStoreError,
ModuleDropSeedRow, ModuleMemoryMutationRow, ModuleMemoryRow, ModuleStateSyncError,
ModuleDropSeedRow, ModuleMemoryEvidenceRow, ModuleMemoryMutationRow, ModuleMemoryRow,
ModuleStateSyncError,
ModuleStateSyncRequest, ModuleStripSeedRow, ModuleWorkspaceMemberRow, ModuleWorkspaceRow,
NoteCasOutcome, NoteEvaluationInput, NoteInput, NoteNudgeAnchorSeed, NoteWriteInput,
PendingAgentDrop, PendingAgentDropSeedRow, PendingCompactionMarkerState,
Expand Down Expand Up @@ -1697,6 +1698,18 @@ struct ModuleMemoryWire {
mural_cue_at: Option<i64>,
#[serde(default)]
mural_cue_rejection_count: i64,
#[serde(default)]
evidence: Option<Vec<ModuleMemoryEvidenceWire>>,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: When a state-sync memory contains evidence: null, this field becomes None, so into_row treats it as omitted and preserves stale evidence instead of rejecting the malformed snapshot. Reject explicit null while accepting only an omitted field or an array, matching the cross-runtime contract.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At crates/mc-module/src/lib.rs, line 1702:

<comment>When a state-sync memory contains `evidence: null`, this field becomes `None`, so `into_row` treats it as omitted and preserves stale evidence instead of rejecting the malformed snapshot. Reject explicit `null` while accepting only an omitted field or an array, matching the cross-runtime contract.</comment>

<file context>
@@ -1699,7 +1699,7 @@ struct ModuleMemoryWire {
     mural_cue_rejection_count: i64,
     #[serde(default)]
-    evidence: Vec<ModuleMemoryEvidenceWire>,
+    evidence: Option<Vec<ModuleMemoryEvidenceWire>>,
 }
 
</file context>

}

#[derive(Debug, Clone, Deserialize)]
struct ModuleMemoryEvidenceWire {
content_hash: String,
source_session_id: String,
#[serde(default)]
source_message_id: Option<String>,
source_type: String,
observed_at: i64,
}

#[derive(Debug, Clone, Deserialize)]
Expand Down Expand Up @@ -1804,6 +1817,18 @@ impl ModuleMemoryWire {
mural_cue_hash: self.mural_cue_hash,
mural_cue_at: self.mural_cue_at,
mural_cue_rejection_count: self.mural_cue_rejection_count,
evidence: self.evidence.map(|evidence| {
evidence
.into_iter()
.map(|row| ModuleMemoryEvidenceRow {
content_hash: row.content_hash,
source_session_id: row.source_session_id,
source_message_id: row.source_message_id,
source_type: row.source_type,
observed_at: row.observed_at,
})
.collect()
}),
}
}
}
Expand Down Expand Up @@ -10423,6 +10448,7 @@ impl McHandler {
category,
content,
source_session_id: Some(conversation_key),
source_message_id: None,
source_type: Some("agent"),
importance: Some(50),
expires_at: None,
Expand Down Expand Up @@ -10464,6 +10490,24 @@ impl McHandler {
.update_memory_content(memory_project, id, content, now_ms())
.map_err(|error| error.to_string())?
.ok_or_else(|| format!("memory {id} was not found"))?;
tx.record_memory_evidence(
memory.id,
InsertMemoryInput {
project_path: memory_project,
route_project_root: Some(
facade_scope.route_project_root.as_str(),
),
category: &memory.category,
content,
source_session_id: Some(conversation_key),
source_message_id: None,
source_type: Some("agent"),
importance: memory.importance,
expires_at: memory.expires_at,
metadata_json: memory.metadata_json.as_deref(),
now_ms: now_ms(),
},
)?;
facade_text_response(
format!(
"Updated memory [ID: {}] in {}.",
Expand Down Expand Up @@ -10545,6 +10589,24 @@ impl McHandler {
)
.map_err(|error| error.to_string())?
.ok_or_else(|| format!("memory {target_id} was not found"))?;
tx.record_memory_evidence(
memory.id,
InsertMemoryInput {
project_path: memory_project,
route_project_root: Some(
facade_scope.route_project_root.as_str(),
),
category: &memory.category,
content,
source_session_id: Some(conversation_key),
source_message_id: None,
source_type: Some("agent"),
importance: memory.importance,
expires_at: memory.expires_at,
metadata_json: memory.metadata_json.as_deref(),
now_ms: now_ms(),
},
)?;
facade_text_response(
format!(
"Merged memories into [ID: {}] in {}; superseded [{}].",
Expand Down Expand Up @@ -16700,6 +16762,7 @@ mod tests {
category,
content,
source_session_id: Some(project),
source_message_id: None,
source_type: Some("test"),
importance: Some(50),
expires_at: None,
Expand Down Expand Up @@ -22330,6 +22393,7 @@ mod tests {
.any(|memory| memory.content == "second shared fact"));
let first = store.get_memory_full(project_rows[0].id).unwrap().unwrap();
assert_eq!(first.source_session_id.as_deref(), Some(key_a));
assert_eq!(first.source_type.as_deref(), Some("agent"));
assert!(store
.load_active_memories(key_a, now_ms())
.unwrap()
Expand Down
1 change: 1 addition & 0 deletions crates/mc-module/src/m0_compose.rs
Original file line number Diff line number Diff line change
Expand Up @@ -652,6 +652,7 @@ mod tests {
category: "CONSTRAINTS",
content: "must stay hidden",
source_session_id: None,
source_message_id: None,
source_type: Some("agent"),
importance: Some(50),
expires_at: None,
Expand Down
1 change: 1 addition & 0 deletions crates/mc-module/src/m1_compose.rs
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,7 @@ mod tests {
category,
content,
source_session_id: None,
source_message_id: None,
source_type: Some("tool"),
importance: Some(70),
expires_at: None,
Expand Down
1 change: 1 addition & 0 deletions crates/mc-module/src/memory_tool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,7 @@ mod tests {
category,
content,
source_session_id: None,
source_message_id: None,
source_type: Some("tool"),
importance: Some(50),
expires_at: None,
Expand Down
1 change: 1 addition & 0 deletions crates/mc-module/src/transform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13984,6 +13984,7 @@ pub(crate) mod tests {
category,
content,
source_session_id: None,
source_message_id: None,
source_type: Some("tool"),
importance: Some(70),
expires_at: None,
Expand Down
Loading
Loading