feat(engine): add missions, reliability tracker, reflection executor, and provenance-aware policy

- Add Mission type and MissionManager for recurring thread scheduling
- Add ReliabilityTracker for per-capability success/failure/latency tracking
- Add reflection executor that spawns CodeAct threads for post-completion reflection
- Extend PolicyEngine with provenance-aware taint checking (LLM-generated data
  requires approval for financial/external-write effects)
- Extend Store trait with mission CRUD methods
- Add conversation surface tracking, compaction token fix, context memory injection
- Wire new modules through lib.rs re-exports and bridge adapters

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
This commit is contained in:
2026-03-23 20:21:08 -07:00
co-authored by Claude Opus 4.6
parent 65a32c81b5
commit 10098e7958
20 changed files with 1305 additions and 103 deletions
+2
View File
@@ -92,6 +92,7 @@ impl LlmBackend for LlmBridgeAdapter {
output_tokens: u64::from(response.output_tokens),
cache_read_tokens: u64::from(response.cache_read_input_tokens),
cache_write_tokens: u64::from(response.cache_creation_input_tokens),
cost_usd: 0.0,
},
});
}
@@ -144,6 +145,7 @@ impl LlmBackend for LlmBridgeAdapter {
output_tokens: u64::from(response.output_tokens),
cache_read_tokens: u64::from(response.cache_read_input_tokens),
cache_write_tokens: u64::from(response.cache_creation_input_tokens),
cost_usd: 0.0, // TODO: populate from provider cost data when available
},
})
}
+25
View File
@@ -10,6 +10,7 @@ use tokio::sync::RwLock;
use ironclaw_engine::{
CapabilityLease, DocId, EngineError, LeaseId, MemoryDoc, Project, ProjectId, Step, Thread,
ThreadEvent, ThreadId, ThreadState, Store,
types::mission::{Mission, MissionId, MissionStatus},
};
/// In-memory implementation of the engine's `Store` trait.
@@ -23,6 +24,7 @@ pub struct InMemoryStore {
projects: RwLock<HashMap<ProjectId, Project>>,
docs: RwLock<HashMap<DocId, MemoryDoc>>,
leases: RwLock<HashMap<LeaseId, CapabilityLease>>,
missions: RwLock<HashMap<MissionId, Mission>>,
}
impl InMemoryStore {
@@ -34,6 +36,7 @@ impl InMemoryStore {
projects: RwLock::new(HashMap::new()),
docs: RwLock::new(HashMap::new()),
leases: RwLock::new(HashMap::new()),
missions: RwLock::new(HashMap::new()),
}
}
}
@@ -184,4 +187,26 @@ impl Store for InMemoryStore {
}
Ok(())
}
// ── Mission ──────────────────────────────────────────────
async fn save_mission(&self, mission: &Mission) -> Result<(), EngineError> {
self.missions.write().await.insert(mission.id, mission.clone());
Ok(())
}
async fn load_mission(&self, id: MissionId) -> Result<Option<Mission>, EngineError> {
Ok(self.missions.read().await.get(&id).cloned())
}
async fn list_missions(&self, project_id: ProjectId) -> Result<Vec<Mission>, EngineError> {
Ok(self.missions.read().await.values().filter(|m| m.project_id == project_id).cloned().collect())
}
async fn update_mission_status(&self, id: MissionId, status: MissionStatus) -> Result<(), EngineError> {
if let Some(mission) = self.missions.write().await.get_mut(&id) {
mission.status = status;
}
Ok(())
}
}