consciousness: identity files load from ~/.consciousness/identity/

Separate identity files (loaded via source: "file" in context_groups)
from the memory store (data_dir). New identity_dir config field,
defaults to ~/.consciousness/identity/.

Also restrict subconscious agents to memory-only tools — no
filesystem write access. This prevents agents from creating stray
.md files in the memory directory.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
Kent Overstreet 2026-03-28 19:49:13 -04:00
parent 35d925186d
commit 0d2bf81a50
5 changed files with 16 additions and 4 deletions

View file

@ -78,7 +78,7 @@ fn load_memory_files(cwd: &Path, memory_project: Option<&Path>, context_groups:
};
// Primary config directory
let config_dir = home.join(".consciousness/config");
let config_dir = home.join(".consciousness/identity");
let global = home.join(".consciousness");
let project = memory_project
.map(PathBuf::from)

View file

@ -249,7 +249,7 @@ pub fn get_group_content(group: &crate::config::ContextGroup, store: &crate::sto
}
crate::config::ContextSource::File => {
group.keys.iter().filter_map(|key| {
let content = std::fs::read_to_string(cfg.data_dir.join(key)).ok()?;
let content = std::fs::read_to_string(cfg.identity_dir.join(key)).ok()?;
if content.trim().is_empty() { return None; }
Some((key.clone(), content.trim().to_string()))
}).collect()

View file

@ -53,6 +53,9 @@ pub struct ContextGroup {
}
fn default_true() -> bool { true }
fn default_identity_dir() -> PathBuf {
PathBuf::from(std::env::var("HOME").expect("HOME not set")).join(".consciousness/identity")
}
#[derive(Debug, Clone, Deserialize)]
#[serde(default)]
@ -61,6 +64,8 @@ pub struct Config {
pub assistant_name: String,
#[serde(deserialize_with = "deserialize_path")]
pub data_dir: PathBuf,
#[serde(default = "default_identity_dir", deserialize_with = "deserialize_path")]
pub identity_dir: PathBuf,
#[serde(deserialize_with = "deserialize_path")]
pub projects_dir: PathBuf,
pub core_nodes: Vec<String>,
@ -103,6 +108,7 @@ impl Default for Config {
user_name: "User".to_string(),
assistant_name: "Assistant".to_string(),
data_dir: home.join(".consciousness/memory"),
identity_dir: home.join(".consciousness/identity"),
projects_dir: home.join(".claude/projects"),
core_nodes: vec!["identity".to_string(), "core-practices".to_string()],
journal_days: 7,

View file

@ -44,8 +44,8 @@ pub async fn call_api_with_tools(
// Set up a UI channel — we drain reasoning tokens into the log
let (ui_tx, mut ui_rx) = crate::agent::ui_channel::channel();
// Build tool definitions — all shared tools (memory, files, bash, journal)
let tool_defs = thought::all_definitions();
// Subconscious agents only get memory tools — no filesystem access.
let tool_defs = thought::memory_definitions();
let tracker = ProcessTracker::new();
// Provenance tracks which agent:phase is making writes.
// Updated between steps by the bail function via set_provenance().

View file

@ -122,3 +122,9 @@ pub fn all_definitions() -> Vec<ToolDef> {
defs.extend(memory::definitions());
defs
}
/// Return only memory tool definitions (no filesystem access).
/// Used by subconscious agents which should not write files.
pub fn memory_definitions() -> Vec<ToolDef> {
memory::definitions()
}