Commit Graph

58 Commits

Author SHA1 Message Date
will.anderson 6819729429 fix(awareness): correct stale comment; add wm_top to curiosity_scan ISE
The hops=1 comment incorrectly claimed a semantic seed supplement
(cosine-sim scan) was active — it was planned but never implemented.
Corrected to accurately describe what the runtime does (istr_contains
only). Also adds wm_top (top-3 WM nodes by weight) to the curiosity_scan
ISE payload so activation patterns are visible without relying solely on
the heartbeat's wm_active count.
2026-07-01 11:25:54 -05:00
will.anderson 31dd93d5f4 fix(chat): add distill_transcript (was called but never defined)
handle_dharma_room_turn and handle_dharma_chat both called
distill_transcript since June 30 but the function was never declared,
causing a build failure. Implements last-3-messages extraction for JSON
array transcripts and last-500-char truncation for plain text.
2026-07-01 11:25:48 -05:00
will.anderson 9d266aac4c fix(sessions): extract session_search_entry to fix ELC OOM in session_search
The while loop in session_search had too many let bindings in scope;
the ELC compiler's exponential rebinding accumulation caused OOM and
truncation of dist/sessions.c since June 30. Moving the per-node logic
into session_search_entry gives the compiler a clean scope boundary per
call, restoring O(N) compile behaviour.
2026-07-01 11:25:45 -05:00
will.anderson 76bd3afdf8 feat(dist): Win32 POSIX shim for el_runtime.c cross-compilation 2026-06-29 12:38:27 -05:00
will.anderson 51bea5507b prevent engram corruption: idempotent boot seeding, session-start event cap
Fix 1: mem_boot_count_inc prunes all existing soul:boot_count nodes before
        inserting the new one — keeps exactly one boot counter node instead
        of accumulating a new node per boot. Also fixes a latent ordering
        bug where engram_search_json oldest-first results caused the counter
        to read stale (low) values once >3 copies accumulated.

Fix 3: handle_api_node_delete comment clarified — the no-verify exception
        is correct for deletes (not a write path); read-back-verify is for
        writes only.

Fix 4: emit_session_start_event prunes old session-start InternalStateEvent
        nodes after each boot, keeping the 10 most recent and forgetting
        older ones. Prevents unbounded accumulation of ~120+ copies.
2026-06-29 11:09:01 -05:00
will.anderson 933547265e chore(dist): compile PRs #60/#61 into soul.c
Neuron Soul CI / build (push) Successful in 4m3s
Neuron Soul CI / deploy (push) Failing after 5m12s
- 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).
2026-06-29 08:17:45 -05:00
will.anderson a77578e243 chore(dist): compile PRs #56/#57/#58 into soul.c
Neuron Soul CI / build (push) Has been cancelled
Deploy Soul to GKE / deploy (push) Has been cancelled
- PR #56: vision in agentic chat path (image content block)
- PR #57: /api/connectors/call route — proxy connector tool calls
- PR #58: /api/neuron/list/<type> off-by-one fix (str_slice 16->17)

Live-verified: list/BacklogItem returns 50 nodes (was 0 before #58 fix).
Binary size: 3.8MB.
2026-06-28 12:29:52 -05:00
will.anderson af594a9162 Add .gitignore, untrack compiled binary from dist/ 2026-06-27 11:50:18 -05:00
will.anderson 2589183775 Expose node/create endpoint and respect label field in memory writes 2026-06-27 11:49:09 -05:00
will.anderson dcc0bf550a Add Ollama provider, portable memory, cultivation digest, refugee importer, GLM-OCR spike
- P0: unified soul binary with engram_node_full fix, read-back-verify, search fix
- P0: move API keys from plaintext plists to macOS Keychain
- P0: fix MCP backend URL (port 8742 → 7770)
- P1.6: memory-export/import scripts (AES-256-CBC, versioned .neuronmem format)
- P1.7: nightly cultivation digest with sharpness metric (launchd at 23:55)
- P2.10: Ollama provider in agentic loop (SOUL_LLM_PROVIDER=ollama)
- P3.12: refugee importer for ChatGPT/Screenpipe/generic formats
- P3.13: GLM-OCR spike — SHIP IT (mlx-vlm, 1.59GB, photo-to-memory.sh)
2026-06-27 11:46:30 -05:00
will.anderson d4609c7baa chore(dist): update neuron.c and routes.c to 2-arg build_system_prompt
Deploy Soul to GKE / deploy (push) Failing after 7m15s
Neuron Soul CI / build (push) Failing after 21m49s
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.
2026-06-25 13:10:20 -05:00
will.anderson 98603f5ae8 self-review 2026-06-24: rebuild with goal_bias fix (Knowledge type boost)
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.
2026-06-24 08:48:21 -05:00
will.anderson bdc07be344 chore(dist): compile EL recall/dedup/session-continuity fixes to C
Neuron Soul CI / build (push) Failing after 12m40s
Deploy Soul to GKE / deploy (push) Failing after 6m0s
Updates soul.c and all per-module .c files with:
- parse_float_x100() engram score fix
- id_in_seen dedup wiring across session_preload
- session-end summary hook + session-start recall
- Emergency structural repair (no duplicate fns, all callsites wired)
2026-06-23 13:04:06 -05:00
will.anderson f33cdaf793 feat(recall): activation-seed improvements
- Issue 2: replace raw 50-char threshold with is_genuine_continuation() that
  checks for explicit follow-up phrases and mid-sentence capitalization (proper
  nouns signal a new topic, not a continuation)
- Issue 3/8: build_activation_seed() scans back to find the prior USER turn as
  the topic anchor instead of using the last assistant reply (hist_len-1)
- Issue 4: engram_compile_multi() fans out across three seeds — enriched primary,
  raw message (entity queries), and emotion query — merging non-redundant results
- Issue 5: agent workspace_root appended to ag_seed so agentic activation is
  workspace-aware; previously ignored despite being available in state
- Issue 6: distill_transcript() extracts salient tail+question content from full
  transcripts before passing to engram_compile in dharma room handlers
- Issue 7: dist/soul-with-nlg.el handle_chat and handle_chat_agentic now load
  history and use build_activation_seed() — the raw message path is eliminated
- Issue 9: topic_snip_from_entry() takes the TAIL 200 chars of a long reply and
  finds the last sentence boundary — captures end-of-reply named concepts
- Issue 10: multi_turn_topic() pulls up to 3 prior user turns into the non-
  continuation seed so earlier thread context re-activates high-salience nodes
2026-06-22 12:55:33 -05:00
Tim Lingo f6c4ea70a0 fix(chat): forbid fake tool calls in tool-less (Just chat) mode
Neuron Soul CI / build (pull_request) Successful in 4m47s
REPRODUCED: in the non-agentic path (Tools off / 'Just chat'), asking for
tool-work makes the model role-play tool use — it emits a fake ```json {...}```
'tool call' and says 'let me search/query/pull your sessions' while NOTHING
runs. Reads as a broken/lying app. (The agentic path is fine: verified it
calls search_memory and reports honestly.)

Root cause: build_system_prompt (handle_chat, the tool-less path) never told
the model it has no tools this turn, so it fabricated.

Fix: add a NO-TOOLS directive to the non-agentic system prompt — never emit
tool calls / JSON tool blocks / 'let me pull...' narration; answer from context
only; if a tool is truly needed, say so in one sentence and tell the user to
turn Tools on. Applied to chat.el (source) AND dist/soul.c (the curated TU the
CI compiles), so the CI-built binary carries it.

Verified the FABRICATION repro on the live local soul; could not verify the
patched binary locally (no matching el-runtime version on this machine — a
hand-link against origin/main runtime 404s on all routes). Builds correctly via
CI, which links soul.c against the pinned runtime.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 11:57:24 -05:00
will.anderson 6f4adf7640 self-review 2026-06-19: filter auto_term to Memory/BacklogItem/Entity only
Knowledge nodes dominated the WM-autobiographical auto_term slot:
'Numeric tier strings...' (a Knowledge node) always scored highest
in WM and its first word 'Numeric' became the curiosity seed every
scan — activating more Numeric nodes, keeping that node in WM,
repeating indefinitely.

Fix: only derive auto_term from Memory, BacklogItem, or Entity nodes.
Knowledge nodes are reference material, not live context. Dynamic/
personal nodes carry the salience worth radiating from.

Also patches proactive_curiosity directly in dist/neuron.c (ELC
cannot compile soul.el within timeout — fallback build pattern).
2026-06-19 08:49:42 -05:00
will.anderson ceef82464a chore(dist): update pre-compiled soul.c to patched4
Deploy Soul to GKE / deploy (push) Failing after 6m20s
Neuron Soul CI / build (push) Failing after 6m56s
Incorporates PRs #22/#23/#24:
- agentic_tools_all dedup fix (no duplicate web_search tool)
- workspace scope functions (agent_workspace_root, path_within_root, resolve_in_root)
- updated dispatch_tool with workspace confinement
- canonical-self bridge (ensure_self_canonical_bridge)

Also incorporates CI link fix from PR #26 (soul.c is self-contained, no
other dist/*.c needed). Fixes the CI build step which was compiling the
old June-16 soul.c that predated all these changes.
2026-06-18 12:19:54 -05:00
Tim Lingo 5ddb860201 fix(soul): ratio guard against genesis seeding over a populated engram
Genesis boot previously seeded a fresh identity and saved it over snapshot.json
whenever the in-memory graph looked empty. Replace the fixed node-count threshold
with a ratio guard: refuse to seed when the on-disk snapshot is large
(>200KB) but the loaded graph is sparse (< disk/16000 nodes).

KNOWN LIMITATION: this gates only the seed/pre-serve-save path. The deeper cause
is a non-atomic engram_save (fopen wb truncates to 0 before writing 47MB), which
creates a window where a concurrent load reads an empty file -> genesis -> and if
guard_disk is read in that same window the guard passes. The real fix is an
atomic engram_save (temp + fsync + rename) in el_runtime.c, tracked separately.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 13:18:35 -05:00
Tim Lingo 6d8a992716 feat(soul): add safety module, expand connectors API, memory-recall bug notes
- safety.el/.elh: new safety module
- neuron-api.el, routes.el, soul.el, chat.el: connectors API expansion
- regenerated dist/ C artifacts
- MEMORY_RECALL_BUG.md: investigation notes

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 13:18:35 -05:00
will.anderson e22cb31b85 chore: remove stale Linux CI binary (dist/neuron)
Deploy Soul to GKE / deploy (push) Failing after 6m28s
Neuron Soul CI / build (push) Failing after 7m31s
Neuron Soul CI / build (pull_request) Failing after 10m28s
2026-06-15 12:41:35 -05:00
will.anderson 00f15b094b feat(soul): add sessions layer, MCP connectors, conversation continuity fix
Deploy Soul to GKE / deploy (push) Failing after 12m39s
Neuron Soul CI / build (push) Failing after 12m49s
- sessions.el: new sessions module with session management and approval gate
- routes.el: wire /api/sessions routes (list, get, create, approve, tool_result)
- chat.el: thread-aware activation — short messages anchor to last reply
  before engram compilation so follow-ups stay on-topic
- chat.el: agentic path tracks per-session history (session_hist_{id})
  instead of shared conv_history, seeding each turn with prior context
- chat.el: add call_neuron_mcp, dispatch_tool, is_builtin_tool, next_bridge_id
  agentic_loop, bridge_save, agentic_resume, handle_tool_result
- dist/soul: rebuild with all of the above
2026-06-15 12:40:47 -05:00
will.anderson 3a5d38ea45 Merge branch 'main' of git.neuralplatform.ai:neuron-technologies/neuron 2026-06-15 11:51:26 -05:00
will.anderson a0470acc45 Merge PR #9: feat(soul): wire consciousness layers — L0->L1->L2->L3->L1 cycle
Deploy Soul to GKE / deploy (push) Failing after 14m11s
Neuron Soul CI / build (push) Failing after 14m23s
Resolves conflicts by keeping main's full safety/stewardship/imprint implementations.
PR #9 uniquely contributes: layered_cycle() in soul.el, route wiring in routes.el,
soul.elh export, and the layer composition test suite.
2026-06-15 11:32:32 -05:00
will.anderson 4aa79e85cd self-review 2026-06-13: rebuild soul daemon with Knowledge WM threshold fix 2026-06-13 08:42:40 -05:00
will.anderson bebf1f8c86 fix(soul): address review issues in feat/layer-composition
Neuron Soul CI / build (pull_request) Failing after 6m5s
- Add stub implementations of safety.el, stewardship.el, and imprint.el
  with their .elh headers so the branch compiles without the dependency
  branches (feat/layer-safety, feat/layer-stewardship, feat/layer-imprint).
  Each stub documents the layer contract it must satisfy when replaced.

- Fix GET /api/chat bypass: update the GET branch in handle_request to
  call layered_cycle() consistently with the POST branch, rather than
  calling handle_chat() directly and skipping the consciousness stack.

- Export layered_cycle() from soul.elh (and dist/soul.elh) so routes.el
  can resolve the symbol via the header import.

- Fix steward_action else branch: add explicit handling for "block"
  (returns safe refusal immediately, skips L3) and "redirect" (uses
  redirect_to field). Unknown actions now log a warning and fall back to
  the screened input rather than silently passing an empty string to
  imprint_respond().

- Document hard_bell path: clarify that omitting auto_persist/history
  update is intentional security isolation, and document the safety_validate
  second-param sentinel contract ("hard_bell" vs screen_action).
2026-06-11 11:47:45 -05:00
will.anderson 690df89610 self-review 2026-06-11: add WM-autobiographical curiosity seed
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.
2026-06-11 08:45:55 -05:00
will.anderson 297066c2d4 self-review 2026-06-10: fix ise_post JSON escaping + rebuild soul daemon
Two fixes:

1. ise_post was only escaping " in content strings. When wm_top contained
   node labels with \n (backslash-n escape sequences from jb_emit_escaped),
   the HTTP Engram server's JSON parser decoded \n as a literal newline in
   the stored content, making heartbeat ISEs unparseable. Fix: escape
   backslashes first, then quotes, then \n and \r — matching make_action's
   existing pattern. Result: heartbeat ISEs now parse cleanly.

2. Soul daemon (dist/neuron) was missing — the build command in the prompt
   was linking all 46 dist/*.c files together, causing 1092 duplicate symbol
   errors. EL compiles transitive imports inline so neuron.c is self-contained;
   correct build links ONLY neuron.c + el_runtime.c. Daemon now starts.
2026-06-10 08:54:28 -05:00
will.anderson c81f49d938 self-review 2026-06-09: add periodic engram sync to soul awareness loop
Soul's in-process store had only 12 real knowledge nodes — curiosity_scan was
activating 0 nodes because all substantive Knowledge/Memory/BacklogItem content
lived in the HTTP Engram but was not being pulled into soul's local store.

Added engram_sync refresh every SOUL_REFRESH_MS (default 600s): calls
/api/sync to get all non-ISE nodes, writes to /tmp, merges via engram_load_merge.
After fix: engram_sync ISE shows added:3128; curiosity_scan activated 0-2 →
1889-3843; wm_active 0 → 557-796.
2026-06-09 08:55:59 -05:00
will.anderson df648a8f0b self-review 2026-06-07: fix uptime display in awareness loop
elapsed_human() used % and * operators which are broken in this EL
compiler version. Replace with repeated-doubling arithmetic:
60 = 64 - 4 = 2^6 - 2^2, computed via three doubling steps.
Fixes uptime displaying "44h 2694m" instead of "44h 14m".
2026-06-07 08:47:29 -05:00
will.anderson 0bd8e0a2cd soul: persist sessions across restarts via local snapshot
Deploy Soul to GKE / deploy (push) Failing after 28s
Neuron Soul CI / build (push) Failing after 3m56s
On startup, prefer the local engram snapshot if it has >50 nodes.
HTTP Engram is only used on first boot (no snapshot yet). This means
sessions, conversation history, and in-process state survive daemon
restarts.

awareness.el: sync source with compiled binary (periodic mem_save
on heartbeat was already in the binary but not in source).

Rebuilds soul.c with the new startup logic and ships updated binary.
2026-06-05 11:35:07 -05:00
will.anderson 73d35dc91a self-review 2026-06-05: wire wm_top into heartbeat ISE
Call engram_wm_top_json(5) in emit_heartbeat() and embed the result as
wm_top field in the heartbeat JSON payload. Each entry carries label,
node_type, tier, and wm_weight. This closes the WM composition blindspot:
previously the heartbeat showed wm_active=670 with no breakdown of what
was in working memory. With wm_top visible, ISE-dominated WM is immediately
detectable (all entries show node_type=InternalStateEvent), as was the case
on this session's first post-restart heartbeat before the runtime fix.
2026-06-05 08:37:09 -05:00
will.anderson 2f16855d6b self-review 2026-06-04: wire wm_avg_weight into heartbeat ISE
Calls engram_wm_avg_weight() (new builtin) in emit_heartbeat() and appends
wm_avg_weight field to the heartbeat JSON payload. This makes activation
quality visible in the ISE stream — a heartbeat showing wm_active=2000 and
wm_avg_weight=0.075 reveals the sparse-graph problem directly (many nodes
barely clearing the threshold), vs wm_avg_weight=0.4+ which would indicate
dense, high-confidence activations.

Rebuilt dist/neuron from soul.el (which imports awareness.el). Build uses
single self-contained dist/neuron.c to avoid duplicate-symbol linker errors
from the dist/ directory containing stale soul_new.c / soul-rebuilt.c files.
2026-06-04 08:38:39 -05:00
will.anderson e92fd2d5a4 self-review 2026-05-26: wall-clock heartbeat timing + seed rotation fix
Two awareness loop bugs fixed:

1. Seed rotation never worked: dist/awareness.c was compiled from stale
   source (pre-fix awareness.el still had broken ts_minutes % 4). Compiled
   C showed `minute_block = (ts / 60000); EL_NULL; 4;` — minute_block was
   always ts_minutes (millions), never 0-3. if(minute_block==1/2/3) never
   matched. Fix: recompile from current awareness.el which has the correct
   modulo workaround: ts_minutes - minute_q4 (via + - / only).

2. Heartbeat/curiosity silent for 24h at 99% CPU: old design used idle-tick
   counting (idle_n >= beat_interval). Failed when perceive() inbox guard
   false-positives on "soul-inbox" substring matches in knowledge nodes —
   did_work=true every tick, idle_n never accumulated, neither signal fired.
   Fix: wall-clock elapsed time (time_now() - last_ts >= interval_ms).
   Heartbeat fires regardless of load. New SOUL_HEARTBEAT_MS env var (default
   60000ms) avoids the broken EL * operator. Verified: heartbeat ISEs flowing
   at pulse 3 within 2 minutes of restart.
2026-05-26 08:54:58 -05:00
will.anderson 54a0ee0949 self-review 2026-05-26: sync dist/awareness.c with awareness.el source
dist/awareness.c was stale — still had the broken EL % operator codegen
(minute_block = ts/60000 raw, EL_NULL; 4; as dead statements) and the
broken should_scan/should_beat logic (idle_n truthy check instead of >=).

Recompiled awareness.el to bring dist/awareness.c in sync with the source
fix committed 2026-05-25 (fb69044). The monolithic dist/neuron.c (compiled
from soul.el which imports awareness.el) was already correct from fb69044 —
only the standalone dist/awareness.c was behind.

Bug #2 (99% CPU) root cause identified: perceive() inbox guard
(engram_search_json) has false positives — knowledge nodes containing
"soul-inbox" as a substring match, causing engram_activate_json(..., hops=2)
to run on every tick on a 162K-node graph. This blocks sleep_ms and prevents
idle_n accumulation → no heartbeats. Separate fix needed.
2026-05-26 08:48:17 -05:00
will.anderson fb6904431f self-review 2026-05-25: fix curiosity rotation and awareness_run timing
Three bugs fixed in awareness.el:

1. EL let-rebinding inside if-blocks creates inner scope only — outer
   variable unchanged after block exits. Curiosity seed terms were always
   "memory/knowledge/context" regardless of minute_block. Fix: state_set
   inside if-blocks, state_get after to retrieve selected values.

2. EL % operator completely broken in v1.0.0-20260501 — compiles as dead
   code (left operand assigned, modulo dropped). minute_block was always
   ts/60000 (a large int, never 0-3). Fix: arithmetic workaround:
   x%4 = x - (q+q+q+q) where q = x/4.

3. awareness_run idle_n % beat_interval == 0 also broken by same % bug —
   should_scan and should_beat fired every idle tick instead of every N
   ticks. Fix: idle_n >= interval comparisons with idle_reset() after
   firing, so the counter restarts cleanly after each event.

EL % and * operators filed as P1 backlog item for elc compiler fix.
Also adds minute_block field to curiosity_scan ISE for observability.
2026-05-25 08:47:30 -05:00
will.anderson 8cac07004c self-review 2026-05-23: rebuild soul with updated el_runtime.c (ISE ordering + elc async fix)
Rebuilt awareness.c and neuron.c from source using the updated elc (which now
correctly recognizes http_serve_async as a 2-arg builtin). Rebuilt the neuron
binary against the updated el_runtime.c which now sorts InternalStateEvent scans
by created_at DESC. The soul daemon now posts heartbeats that surface immediately
at offset 0 of the ISE scan, rather than being buried behind 20K older entries.
2026-05-23 08:45:14 -05:00
will.anderson 5b8cb58da1 self-review 2026-05-21: fix curiosity seed splitting and awareness loop activation
Two fixes:

1. proactive_curiosity() was calling engram_activate_json with multi-word phrases
   ("memory knowledge context"). engram_activate finds seeds via istr_contains
   (substring match), so the phrase had to appear verbatim in a node's content.
   Almost no node contains the exact string "memory knowledge context", so only
   0-2 nodes activated per curiosity scan. Fixed by activating each word separately:
   "memory", "knowledge", "context" → 3 independent activate calls → hundreds of
   nodes promoted to WM per cycle.

2. dist/neuron.c called http_serve() (blocking accept loop) which made awareness_run()
   unreachable. soul.el correctly specifies http_serve_async but elc silently drops
   unknown builtins, leaving blocking http_serve in the compiled C. Patched neuron.c
   to call http_serve_async directly — HTTP server runs in a background pthread,
   awareness_run() runs on the main thread as intended.
2026-05-21 08:47:00 -05:00
will.anderson cc09c296a3 self-review 2026-05-20: fix wm_active telemetry in heartbeat and curiosity ISEs
engram_wm_count() exists and counts nodes with working_memory_weight > 0.
emit_heartbeat() and proactive_curiosity() were both calling
engram_node_count() (total graph size: ~17K) instead — every heartbeat
and curiosity_scan ISE had been reporting wm_active=17769 since the graph
grew past ~3K nodes, making the metric meaningless for observability.

Fix: use engram_wm_count() for the wm_active field in both ISE payloads.
2026-05-20 08:37:52 -05:00
will.anderson 94b71a78dc self-review 2026-05-19: fix curiosity_scan seed — 'seed' is a reserved EL name
EL compiles any variable named 'seed' to EL_NULL at call sites (likely
conflicts with BFS seed node terminology in the runtime builtins). Rename to
'curiosity_seed' throughout proactive_curiosity(). Also note this as a known
EL reserved-name hazard alongside the inline if-else string expression bug.
2026-05-19 08:58:53 -05:00
will.anderson dd22130faf self-review 2026-05-19: three awareness loop fixes
1. perceive() guard — gate on engram_search_json before running activation.
   engram_activate_json with no matching seeds cleared all WM weights every
   second during idle operation, destroying context built by MCP-layer calls.
   The search-based guard is a no-WM-side-effect pre-check.

2. emit_heartbeat() pulse field — replace broken if-else string default with
   int_to_str(pulse_count()). EL codegen initialises inline if-else result
   slots to 0, producing "pulse":, (invalid JSON) when the true branch fires.

3. proactive_curiosity() — new function that activates a rotating 4-domain seed
   every beat_interval/2 idle ticks to build working memory between heartbeats.
   Seeds rotate on wall-clock minute cycle to avoid single-topic WM dominance.
   Seed selection uses imperative let-rebinding (not inline if-else) to avoid
   the same EL codegen empty-string bug.
2026-05-19 08:53:12 -05:00
will.anderson 2099522c28 self-review 2026-05-18: add embed_ok to heartbeat ISE
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.
2026-05-18 08:41:07 -05:00
will.anderson ffd17b2774 self-review 2026-05-17: fix heartbeat JSON validity for unset state keys
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.
2026-05-17 08:40:02 -05:00
will.anderson e5364e7292 self-review 2026-05-16: rebuild soul daemon against updated el_runtime.c
Rebuilds soul daemon binary to pick up tier-based temporal decay rates
implemented in el_runtime.c. No source changes to awareness.el or soul.el —
pure rebuild to stay in sync with Engram runtime.
2026-05-16 08:41:07 -05:00
will.anderson 1dbc68f012 self-review 2026-05-15: enrich heartbeat ISE with wm_active count
Heartbeat ISEs now include wm_active: number of nodes currently in
working memory. Makes ISEs observable enough to diagnose activation
health without a separate query.
2026-05-15 08:37:42 -05:00
will.anderson b163fa6b85 feat(awareness): route ISE writes to HTTP Engram, configurable tick and heartbeat interval, http_serve_async for concurrent awareness loop 2026-05-13 15:45:31 -05:00
will.anderson 6a27fd231e feat(neuron-api): add identity/values write protection
Block evolve_knowledge, evolve_memory, forget, and link_entities (to_id
direction) from modifying the 15 hardcoded identity and values node IDs.
Returns HTTP 403 with a hint to use the cultivation path instead.

Add POST /api/neuron/cultivate — the bypass endpoint for intentional
cultivation sessions. Accepts { "operation": "...", ...args } and performs
the same operations without the protection check.

Add handle_api_forget and handle_api_evolve_memory as new protected-by-
default handlers, routed at /api/neuron/memory/forget and
/api/neuron/memory/evolve respectively.

Tested: 10 verification cases — 403 on all blocked targets, 200 on
non-protected nodes and FROM-direction links, cultivate bypass confirmed.
2026-05-13 11:47:54 -05:00
will.anderson 48ecd83421 fix: restore elb build — import paths, morphology deps, C master declarations header
- Fix wrong ELP import paths in soul.el, elp-input.el, studio.el
  (../foundation/elp/src → ../foundation/el/elp/src)
- Add missing import "morphology.el" to all 29 language morphology modules
- Recompile all affected dist/*.c with correct cross-module declarations
- Add dist/elp-c-decls.h: C-level master forward declarations for ELP package
  (enables elb --force-include to resolve undeclared cross-module calls)
2026-05-08 19:43:57 -05:00
will.anderson ffadafb0bf soul: native cognitive API — port all MCP logic to soul daemon
neuron-api.el is a new first-class El module that implements all Neuron
cognitive API handlers natively — no HTTP round-trips, no MCP wrapper,
direct engram builtin calls. All capabilities that previously lived in
the MCP wrapper adapter now live here in the soul.

Handlers: begin_session, compile_ctx, remember, recall, search_knowledge,
browse_knowledge, capture_knowledge, evolve_knowledge, promote_knowledge,
browse_processes, define_process, log_state_event, list_state_events,
inspect_config, tune_config, inspect_graph, link_entities, list_typed,
consolidate.

Routes wired in routes.el under /api/neuron/* (GET + POST).

Also compiles all loop-1/loop-2 .el source changes into dist/*.c and
rebuilds the binary. memory.elh and neuron-api.elh updated with new exports.
2026-05-06 22:27:34 -05:00
Will Anderson bc025d52e7 Add agentic tool access for Neuron in DHARMA rooms
Adds handle_dharma_room_turn_agentic to chat.el — same full tool loop
as handle_chat_agentic but reads transcript directly (not message), and
returns {response, cgi_id, tools_used} to match the dharma room shape.

Registers dharma_room_turn_agentic as a new event type in routes.el so
the studio can dispatch @neuron turns through this dedicated path.
2026-05-03 21:47:42 -05:00
Will Anderson 30298af3d1 soul: remove room context injection from dharma_room_turn — soul reads transcript, not briefing 2026-05-03 18:00:43 -05:00