- PR #60: inject operator home dir into system prompt (#30)
Adds OPERATOR IDENTITY section so the LLM correctly resolves
'my files/notes/desktop' to the actual running user's $HOME.
Prevents identity confusion between imprint author and operator.
- PR #61: plan-mode endpoint POST /api/chat {mode:'plan'} (#27)
Adds handle_chat_plan — returns {steps:[{id,title,detail}]} JSON.
Wired into all three /api/chat route handlers. Grounds the plan
via engram_compile (same as agentic path) for context awareness.
dist changes:
- soul.c: both PRs compiled in; build_system_prompt updated to
2-param signature (ctx, chat_mode); handle_chat_plan added
- chat.c/routes.c/chat.elh: individual module outputs updated
- elp-c-decls.h: remove stale 1-param build_system_prompt decl,
add handle_chat_plan declaration
- soul.elh.c: new soul header declarations file (from PR #60)
Compile verified: cc -O2 -DHAVE_CURL soul.c el_runtime.c -lcurl
Binary: 805K arm64, smoke test passes (port in use = expected).
neuron.c and routes.c were compiled against the old 1-arg soul interface.
chat.c already uses the 2-arg signature. The Windows cross-compile build
generates elp-c-decls.h from all dist/*.c files, causing a conflicting-types
error when both signatures appear. Recompile these modules against the
current soul API to eliminate the conflict.
Linked against dev runtime with is_knowledge fix that adds Knowledge
node type. Engram goal_bias now gives Knowledge nodes +0.3 boost on
technical queries, consistent with how Belief/DharmaSelf/Safety nodes
are already treated. Same el_runtime source as concurrent foundation/el
commit 16d62bd.
proactive_curiosity() now uses the top working-memory node's first label
word as a 4th activation seed alongside the 4 rotating fixed sets. This
breaks deterministic exploration that was reinforcing the same subgraph
every cycle and creates a self-referencing loop: curiosity radiates from
whatever is most salient right now, mirroring the brain's default-mode-
network resting-state dynamics. str_find_chars on " :([" extracts the
first meaningful word; sp > 3 guards against bracket-prefixed labels.
auto_term field added to curiosity_scan ISE for observability.
Ollama availability is a silent failure mode: when the embedding service
is down, semantic seed injection falls back to lexical-only activation with
no signal in the ISE stream. Add embed_ok field (0/1) to every heartbeat
by probing http://localhost:11434 — makes Ollama health visible without
a separate monitoring path.
state_get() returns "" for unset keys. Both soul.pulse and soul_boot_count
could be empty on first heartbeat cycle, producing invalid JSON like
{"event":"heartbeat","pulse":,"boot":,...}. Add defensive guards:
if str_eq(raw, "") { "0" } else { raw } for both fields.