logs: consolidate all logging under ~/.consciousness/logs/

All log output was scattered across ~/.consciousness/memory/ (daemon,
task logs, LLM call logs), ~/.consciousness/agent-sessions/ (observe),
and only hook logs were already in the right place.

Move everything to ~/.consciousness/logs/ with agent-specific subdirs:
  - daemon.log, daemon/ (task logs)
  - {agent_name}/ (knowledge agent logs, e.g. surface-observe/, reflect/)
  - llm/{caller}/ (LLM call logs)
  - observe.log (poc-agent observe)
  - hook-{session_id} (already correct)
  - debug.log (already correct)

Also includes the session.rs and hook.rs fixes from the previous
session (sessions dir → ~/.consciousness/sessions/).

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
ProofOfConcept 2026-03-28 20:39:20 -04:00
parent 0d2bf81a50
commit 39b07311e6
7 changed files with 31 additions and 14 deletions

View file

@ -61,7 +61,11 @@ fn session_dir() -> PathBuf {
}
fn socket_path() -> PathBuf { session_dir().join("agent.sock") }
fn log_path() -> PathBuf { session_dir().join("observe.log") }
fn log_path() -> PathBuf {
let dir = dirs::home_dir().unwrap_or_default().join(".consciousness/logs");
let _ = std::fs::create_dir_all(&dir);
dir.join("observe.log")
}
fn cursor_path() -> PathBuf { session_dir().join("read-cursor") }
// --- Client commands ---

View file

@ -18,9 +18,14 @@ pub struct Session {
}
impl Session {
fn sessions_dir() -> PathBuf {
let dir = dirs::home_dir().unwrap_or_default().join(".consciousness/sessions");
fs::create_dir_all(&dir).ok();
dir
}
pub fn from_json(input: &str) -> Option<Self> {
let state_dir = crate::store::memory_dir().join("sessions");
fs::create_dir_all(&state_dir).ok();
let state_dir = Self::sessions_dir();
let json: serde_json::Value = serde_json::from_str(input).ok()?;
let session_id = json["session_id"].as_str().unwrap_or("").to_string();
@ -38,7 +43,7 @@ impl Session {
/// Load from a session ID string
pub fn from_id(session_id: String) -> Option<Self> {
if session_id.is_empty() { return None; }
let state_dir = crate::store::memory_dir().join("sessions");
let state_dir = Self::sessions_dir();
Some(Session {
session_id,
transcript_path: String::new(),

View file

@ -83,14 +83,18 @@ impl TaskQueue {
let _ = fs::write(&self.path, if content.is_empty() { String::new() } else { content + "\n" });
}
}
fn log_path() -> PathBuf {
crate::config::get().data_dir.join("daemon.log")
fn logs_dir() -> PathBuf {
let dir = dirs::home_dir().unwrap_or_default().join(".consciousness/logs");
let _ = fs::create_dir_all(&dir);
dir
}
// --- Logging ---
fn log_path() -> PathBuf {
logs_dir().join("daemon.log")
}
fn log_event(job: &str, event: &str, detail: &str) {
jobkit::daemon::event_log::log(&crate::config::get().data_dir, job, event, detail);
jobkit::daemon::event_log::log(&logs_dir(), job, event, detail);
}
/// Public wrapper for logging from other agent modules.
@ -554,7 +558,7 @@ pub fn run_daemon() -> Result<(), String> {
let choir = Arc::clone(&daemon.choir);
let llm = Arc::clone(&daemon.resource);
let _ = DAEMON_POOL.set(Arc::clone(&llm));
let task_log_dir = config.data_dir.join("logs");
let task_log_dir = logs_dir().join("daemon");
let _ = fs::create_dir_all(&task_log_dir);
// Enable verbose logging if POC_MEMORY_VERBOSE is set

View file

@ -348,7 +348,9 @@ fn hook(session: &Session) -> String {
let cookie_path = session.path("cookie");
let is_first = !cookie_path.exists();
let log_path = session.state_dir.join(format!("hook-log-{}", session.session_id));
let log_dir = dirs::home_dir().unwrap_or_default().join(".consciousness/logs");
fs::create_dir_all(&log_dir).ok();
let log_path = log_dir.join(format!("hook-{}", session.session_id));
let Ok(mut log_f) = fs::OpenOptions::new().create(true).append(true).open(log_path) else { return Default::default(); };
let ts = chrono::Local::now().format("%Y-%m-%dT%H:%M:%S");
let _ = writeln!(log_f, "\n=== {} ({}) {} bytes ===", ts, session.hook_event, out.len());

View file

@ -262,10 +262,11 @@ pub fn spawn_agent(
.map(|s| s.phase.as_str())
.unwrap_or("step-0");
let log_dir = store::memory_dir().join("logs");
let log_dir = dirs::home_dir().unwrap_or_default()
.join(format!(".consciousness/logs/{}", agent_name));
fs::create_dir_all(&log_dir).ok();
let agent_log = fs::File::create(
log_dir.join(format!("{}-{}.log", agent_name, store::compact_timestamp())))
log_dir.join(format!("{}.log", store::compact_timestamp())))
.unwrap_or_else(|_| fs::File::create("/dev/null").unwrap());
let child = std::process::Command::new("poc-memory")

View file

@ -6,7 +6,8 @@ use std::fs;
/// Simple LLM call for non-agent uses (audit, digest, compare).
/// Logs to llm-logs/{caller}/ file.
pub(crate) fn call_simple(caller: &str, prompt: &str) -> Result<String, String> {
let log_dir = crate::store::memory_dir().join("llm-logs").join(caller);
let log_dir = dirs::home_dir().unwrap_or_default()
.join(".consciousness/logs/llm").join(caller);
fs::create_dir_all(&log_dir).ok();
let log_path = log_dir.join(format!("{}.txt", crate::store::compact_timestamp()));

View file

@ -34,7 +34,7 @@ const AGENT_TYPES: &[&str] = &[
];
fn log_path() -> PathBuf {
crate::config::get().data_dir.join("daemon.log")
dirs::home_dir().unwrap_or_default().join(".consciousness/logs/daemon.log")
}
// --- Data fetching ---