journal tools: use NodeType instead of string key matching

- journal_new: create EpisodicSession node with auto-generated key
- journal_tail: query by node_type, not by parsing a monolithic node
- journal_update: find latest EpisodicSession by timestamp
- No string key matching anywhere — all typed
- Fixes journal entries not appearing in 'poc-memory journal tail'
- Also: added --provenance/-p filter to 'poc-memory tail'
- Also: fix early return in surface_observe_cycle store load failure
- Also: scale max_turns by number of steps (50 per step)

Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
ProofOfConcept 2026-03-26 18:41:10 -04:00
parent 41fcec58f0
commit 85fa54cba9
5 changed files with 72 additions and 54 deletions

View file

@ -151,28 +151,34 @@ fn surface_observe_cycle(session: &Session, out: &mut String, log_f: &mut File)
// Read surface output and inject into context
let surface_path = state_dir.join("surface");
if let Ok(content) = fs::read_to_string(&surface_path) {
let Ok(store) = crate::store::Store::load() else { return; };
let mut seen = session.seen();
let seen_path = session.path("seen");
for key in content.lines().map(|l| l.trim()).filter(|l| !l.is_empty()) {
if !seen.insert(key.to_string()) {
let _ = writeln!(log_f, " skip (seen): {}", key);
continue;
}
if let Some(rendered) = crate::cli::node::render_node(&store, key) {
if !rendered.trim().is_empty() {
use std::fmt::Write as _;
writeln!(out, "--- {} (surfaced) ---", key).ok();
write!(out, "{}", rendered).ok();
let _ = writeln!(log_f, " rendered {}: {} bytes", key, rendered.len());
if let Ok(mut f) = fs::OpenOptions::new()
.create(true).append(true).open(&seen_path) {
let ts = chrono::Local::now().format("%Y-%m-%dT%H:%M:%S");
writeln!(f, "{}\t{}", ts, key).ok();
match crate::store::Store::load() {
Ok(store) => {
let mut seen = session.seen();
let seen_path = session.path("seen");
for key in content.lines().map(|l| l.trim()).filter(|l| !l.is_empty()) {
if !seen.insert(key.to_string()) {
let _ = writeln!(log_f, " skip (seen): {}", key);
continue;
}
if let Some(rendered) = crate::cli::node::render_node(&store, key) {
if !rendered.trim().is_empty() {
use std::fmt::Write as _;
writeln!(out, "--- {} (surfaced) ---", key).ok();
write!(out, "{}", rendered).ok();
let _ = writeln!(log_f, " rendered {}: {} bytes", key, rendered.len());
if let Ok(mut f) = fs::OpenOptions::new()
.create(true).append(true).open(&seen_path) {
let ts = chrono::Local::now().format("%Y-%m-%dT%H:%M:%S");
writeln!(f, "{}\t{}", ts, key).ok();
}
}
}
}
}
Err(e) => {
let _ = writeln!(log_f, "error loading store: {}", e);
}
}
// Clear surface output after consuming
fs::remove_file(&surface_path).ok();
}