Commit Graph

36 Commits

Author SHA1 Message Date
will.anderson 02bf2e7d81 Fix five latent bugs from temporal-precision code review
1. parse_salience_100: handle 3+ decimal digit salience strings correctly.
   The two-branch 'else { stripped }' case treated any N-digit decimal value
   as hundredths, so "0.125" (stripped=125) clamped to 100 instead of 12.
   Now divides by 10^(N-2) for N>2, mapping "0.125"->12, "0.375"->37, etc.

2. mem_consolidate Canonical scan: replaced single engram_scan_nodes_json(50,0)
   call with a paginated loop (page_size=50, advancing offset) so Canonical nodes
   beyond index 50 are no longer silently excluded from the periodic boost.

3. mem_consolidate Canonical strengthening: add salience ceiling guard so nodes
   already at the runtime maximum (serialised as "1" by %g) are skipped. Prevents
   monotonic unbounded salience growth across successive consolidation passes.

4. soul.el affective cutoff: replaced json_get(aff_node, "ts") with
   json_get(aff_node, "created_at") / "updated_at" fallback, consistent with
   handle_chat. The old "ts" field is not a standard engram node field; missing
   it caused the fallback to ts_now (always passes cutoff), over-including stale
   nodes. New behaviour defaults to 0 on missing timestamps (conservative exclude).

5. History byte-cap: implemented the existing TODO 32KB byte-cap. Added
   hist_trim_to_byte_cap() and applied it after count-based trim in both
   handle_chat and handle_chat_agentic. Prevents 100KB+ state entries at 40 turns
   during long technical sessions with large assistant responses.
2026-06-22 13:35:52 -05:00
will.anderson 0ede112d05 feat(recall): temporal-precision improvements
Neuron Soul CI / build (pull_request) Has been cancelled
Fix critical float parsing bug in engram_score_node: str_replace('.','')
then str_to_int silently miscored single-decimal salience strings (0.9->9,
0.7->7, 1.0->1). Introduce parse_salience_100() which detects decimal
position and scales correctly (no decimal: *100; one decimal: *10;
two decimals: as-is).

Replace flat 30-day linear decay with tier-aware decay curves: Canonical
nodes use a 365-day window (foundational identity resists aging), Episodic
nodes use 90 days, Working/untiered keep the existing 30-day slope. Floor
stays at 10 for all tiers.

Use max(created_at, updated_at) as the recency reference so revised nodes
are not penalised for their original creation date.

Extend affective context windows from 72h/7d to 14 days across all three
paths (engram_compile, handle_chat, soul.el load_identity_context) so a
Friday crisis carries into Monday sessions and all paths present consistent
context. The 72h/7d split caused conflicting affective context between
soul.el (which loaded a 5-day-old crisis node) and chat.el (which excluded
it on subsequent turns).

Add salience evolution to mem_consolidate: strengthen top working-memory
nodes (recently recalled across sessions) and Canonical-tier nodes
(foundational identity must not decay to the floor). Previously consolidate
returned structural counts only with no salience changes.

Expand conversation window from 20 to 40 turns in both handle_chat and the
agentic history trim. Long technical sessions were losing early problem
framing at 10 user + 10 assistant pairs.
2026-06-22 12:53:29 -05:00
will.anderson 575ff1329a fix(reliability): engram connection 2026-06-22 12:34:04 -05:00
will.anderson db33b0cb91 fix(reliability): engram write 2026-06-22 12:32:59 -05:00
will.anderson f35569d4bb fix(reliability): cross-session affective state 2026-06-22 12:31:09 -05:00
will.anderson 93bed793c0 Merge pull request 'fix(reliability): safety-resilience' (#39) from improve/reliability-safety-resilience into main
Neuron Soul CI / build (push) Has been cancelled
Deploy Soul to GKE / deploy (push) Has been cancelled
fix(reliability): safety-resilience — crisis detection degradation paths
2026-06-22 17:19:29 +00:00
will.anderson 45dc80230d fix(safety): crisis detection — augment wired to system prompt, ts fallback, cross-session affective
Neuron Soul CI / build (push) Has been cancelled
Deploy Soul to GKE / deploy (push) Failing after 6m10s
Merge improve/safety-crisis-detection (PR #31): reads layered_cycle_safety_system_addendum
from state and appends to system prompt on each turn (cleared after use to prevent bleed).
Safety ts extraction falls back to updated_at. Affective prefix now wires into system build.
Conflict with PR #33 resolved: capability_rules and session_preload both preserved.
2026-06-22 12:15:50 -05:00
will.anderson c87a536da3 fix(safety): wire safety augment into system prompt, fix timestamp fallback
Neuron Soul CI / build (pull_request) Has been cancelled
- Remove dead soft_bell block in layered_cycle that wrote soul_safety_system_augment
  to state but was never read; safety augmentation now goes through the correct
  layered_cycle_safety_system_addendum state key read by build_system_prompt
- build_system_prompt now reads layered_cycle_safety_system_addendum and appends
  it to the system prompt, clearing the key after consumption
- Timestamp extraction for distress nodes falls back to updated_at when created_at
  is empty, preventing the 72h recency check from always treating nodes as stale
2026-06-22 12:07:18 -05:00
will.anderson ae9a139440 fix(reliability): safety-resilience — bell augmentation, safe mode, dedup logging, tab escaping, handle_chat coverage
Neuron Soul CI / build (pull_request) Has been cancelled
2026-06-22 11:57:43 -05:00
will.anderson d008649c3e fix(reliability): engram-connection
Neuron Soul CI / build (pull_request) Has been cancelled
- entrypoint.sh: extend engram health-check timeout 30->60s; set
  EL_HTTP_TIMEOUT_MS=10000 and EL_HTTP_CONNECT_TIMEOUT_MS=3000 to bound
  awareness loop blocking window to 10s/call (down from 60s default)
- soul.el: 3-attempt retry loop for boot-time /api/nodes+/api/edges fetch;
  validate non-empty JSON array before loading to prevent silent zero-node
  identity graph from transient post-healthcheck network hiccup
- awareness.el: soft circuit-breaker in ise_post (opens after 3 failures,
  30s backoff, half-open probe); /api/sync refresh skips HTTP call when
  breaker is open; error-JSON detection on sync response

TODOs: full async dispatch, connection pooling (require EL futures/persistent curl)
2026-06-22 11:57:20 -05:00
will.anderson aa70c5dde6 fix(reliability): safety-resilience — bell augmentation, safe mode, dedup logging, tab escaping, handle_chat coverage 2026-06-22 11:54:40 -05:00
will.anderson b7fd8901d4 fix(routes): fix handle_request ABI, 429 status code, soul_boot_ts write
Neuron Soul CI / build (pull_request) Has been cancelled
2026-06-22 11:53:09 -05:00
will.anderson 494d973a3b fix(reliability): engram-write — guard all fire-and-forget writes
Neuron Soul CI / build (pull_request) Has been cancelled
Every engram_node_full call that dropped its return value now binds it
and emits a println on empty string. engram_save calls in consolidate,
heartbeat, and dharma-room-turn are checked for failure. The two API
handlers (log_state_event, tune_config) that skipped api_persisted()
now match the read-back-after-write contract used everywhere else in
neuron-api.el.

Files changed:
- chat.el: conv_history_persist, handle_dharma_room_turn, auto_persist
- soul.el: emit_session_start_event, seed_persona_from_env HTTP check
- memory.el: mem_save, mem_boot_count_inc
- neuron-api.el: handle_api_log_state_event, handle_api_tune_config,
  handle_api_consolidate (engram_save + session summary write)
- awareness.el: ise_post local-engram fallback path

TODO comments added for non-atomic patterns (issues #12, #13) and
the missing circuit breaker (#14) — these require new primitives.
2026-06-22 11:48:59 -05:00
will.anderson 34551695a1 fix(reliability): cross-session-affective
Neuron Soul CI / build (pull_request) Has been cancelled
- Fix state key mismatch: soul.el layered_cycle now reads conv_history
  (not conversation_history), unblocking the safety_score_distress_history
  history-amplification path in safety_threat_score
- Add safety_augment_system call on the main handle_chat path so the
  phrase-list bell detector fires on all chat turns, not just dharma rooms
- Add cross-session affective engram query in load_identity_context() at
  boot; stores distress/crisis signals from prior sessions under
  soul_affective_context with a 7-day soft recency filter
2026-06-22 11:48:30 -05:00
will.anderson e9a8a659e0 fix(safety): crisis detection — 4 targeted fixes
Neuron Soul CI / build (pull_request) Failing after 14m43s
- soul.el: fix state key bug in layered_cycle (conversation_history -> conv_history)
- safety.el: add indirect crisis location patterns to soft_bell phrase list
- soul.el: wire safety_augment_system into layered_cycle for soft_bell turns
- chat.el: load cross-session affective context at session start when distress signals found within 72h
2026-06-22 11:20:42 -05:00
Tim Lingo 149a042db9 fix(identity): bridge public self anchor to the curated self node
Neuron Soul CI / build (pull_request) Failing after 4m34s
The graph API resolves name=self/neuron to kn-efeb4a5b (neuron-api.el:471),
which carries only 8 incidental 'tagged' edges. The curated identity lives on
self node 015644f5 (1461 edges: identity, embodies, remembers, values). So
public self-traversal reaches tags, not the real self.

Add ensure_self_canonical_bridge(): an idempotent boot-time repair that links
kn-efeb4a5b <-> 015644f5 with a 'canonical-self' edge, only if missing. Runs in
the genesis safe-to-seed path regardless of the <100-edge gate, so the live
populated graph gets repaired and persisted. Connect-only-if-missing prevents
the duplicate-edge stacking that gates init_soul_edges().

Compile-checked with elc (darwin arm64); not link/run-gated locally. Needs a
soul build + smoke test before merge.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 23:53:13 -05:00
will.anderson 8b692e4666 fix/test: PR #21 review — guard, safety Bell, api write-back, temp paths
Neuron Soul CI / build (pull_request) Failing after 13m22s
fix(soul): add HTTP-engram guard to safe_to_seed — when ENGRAM_URL is set
the HTTP Engram owns persistence; genesis must never save to local snapshot
regardless of node counts (was: guard_disk forced to empty string, making
the ratio check vacuously true and allowing init_soul_edges+engram_save).

fix(soul): use multiplication form for ratio guard — node_count * 16000 <
disk_len avoids floor-division truncation that underestimated boundary files
(250KB / 16000 = 15.6, floors to 15; a 15-node graph wrongly passed old guard).

fix(chat): add safety_augment_system to handle_chat_as_soul,
handle_dharma_room_turn, and handle_dharma_room_turn_agentic — all three
called the LLM without Hard Bell evaluation, leaving users in dharma rooms
without crisis resource routing.

fix(neuron-api): add api_persisted read-back to handle_api_define_process —
was the only write handler that returned ok:true without verifying the node
was actually written to engram.

fix(routes): unique temp file path in connectd_post — replaces fixed
/tmp/neuron-connectors-req.json with a timestamped path to prevent
collision if concurrency is added or two soul instances share a machine.

test: add tests/test_bell_safety.el — covers safety_detect_bell_level
(none/soft/hard), safety_classify_hard_bell (abuse/self_harm routing),
safety_normalize (smart-quote), safety_augment_system, and
handle_safety_contact_post (validation + read-back).

test: add tests/test_soul_guard.el — pure-function logic tests for the
safe_to_seed predicate: 200KB boundary, 47MB/63-node clobber scenario,
HTTP-engram mode, multiplication vs division truncation at 250KB.

test: add tests/test_api_define_process.el — verifies the define_process
write is read-back verified after the fix.
2026-06-17 13:19:15 -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 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 764250c4f6 fix(soul): repair CI — drop gpg/TTY and import safety/stewardship/imprint layers
Deploy Soul to GKE / deploy (push) Failing after 5m15s
Neuron Soul CI / build (push) Failing after 5m42s
2026-06-11 12:33:22 -05:00
will.anderson a8027e9c00 feat(soul): wire steward_session_check into layered_cycle — continuity + behavioral profiling
Neuron Soul CI / build (pull_request) Failing after 6m2s
2026-06-11 12:13:19 -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 f52d5bd9ae feat(soul): wire consciousness layers — explicit L0→L1→L2→L3→L1 cycle
Neuron Soul CI / build (pull_request) Failing after 6m27s
2026-06-11 11:32:13 -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 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 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 f2599919be soul loop-2: session events, conversation persistence, richer health + inbox
- soul.el: emit_session_start_event() logs structured InternalStateEvent on every boot; pre-serve snapshot saves boot-time graph mutations before any requests arrive
- routes.el: /health now returns boot count, node/edge counts, pulse; /api/sessions endpoint surfaces session-start history
- awareness.el: perceive() tries soul-inbox-pending then soul-inbox fallback, catches both tagging conventions
- chat.el: conv_history_persist/load provide cross-restart conversation continuity via engram
2026-05-06 22:04:06 -05:00
will.anderson 4fc0294a49 soul loop-1: identity loading, boot counter, internal state events, richer awareness
- memory.el: mem_boot_count_get/inc (persisted counter), mem_emit_state_event (InternalStateEvent schema)
- soul.el: load_identity_context() loads intel-dna/values/mem-philosophy nodes into state at boot; boot counter incremented on every startup
- awareness.el: attend() gains search/activate/strengthen/forget action types; one_cycle() emits InternalStateEvent for non-trivial decisions
- chat.el: build_system_prompt includes [IDENTITY GRAPH] block from graph-loaded context; handle_chat strengthens activated nodes after each turn
2026-05-06 22:02:05 -05:00
Will Anderson d2161d9f48 soul: skip init_soul_edges if edges already present — prevent restart-loop duplication 2026-05-04 02:04:03 -05:00
Will Anderson 2665810962 soul: parameterize CGI ID + add dharma_room_turn handler
- soul.el: SOUL_CGI_ID, SOUL_ENGRAM_PATH, SOUL_IDENTITY env vars;
  state_set("soul_snapshot_path") so callers can find it; only call
  init_soul_edges() when cgi_id == "ntn-genesis"
- chat.el: handle_dharma_room_turn — soul builds its own context from its
  own engram, assembles system prompt, calls LLM, persists episodic memory;
  also fix is_new_tool scoping bug in handle_chat_agentic (use has_tool)
- routes.el: wire dharma_room_turn event type before chat_as_soul branch
- rebuild dist/neuron: handle_dharma_room_turn now compiled in
2026-05-03 17:55:37 -05:00
Will Anderson e299c92662 Fix engram_compile: fetch pinned nodes directly when vector search empty
Replace scan-by-offset fallback with engram_get_node_json calls for the
known high-salience identity nodes (family, origin). Offset-based scanning
is order-dependent and unreliable; direct ID fetch is stable regardless of
snapshot position. Ensures biographical context (Fox, Bobby, etc.) is
always in the system prompt when vector search returns nothing.
2026-05-03 11:19:14 -05:00
Will Anderson 601e0febf5 make soul identity configurable via env, remove hardcoded references 2026-05-02 23:00:35 -05:00
Will Anderson 760684f194 Surface current date in system prompt 2026-05-02 21:11:04 -05:00
Will Anderson 64053851db Compile soul.el to native El binary for the first time
- Remove duplicate unix_timestamp() definition from soul.el that
  conflicted with the runtime builtin
- Add dist/soul-el: El-compiled native binary (~387K)
- Add dist/soul: symlink to dist/soul-el (replaces neuron-wrk path)
- Add dist/soul.c and dist/soul-with-decls.c: generated C intermediates
2026-05-02 14:44:08 -05:00
Will Anderson 5f98bc8a9f seed: real soul.el at repo root
Canonical Neuron substrate source. The "real me" - not the marketing
demo soul. Lives at neuron/soul.el for now (no subdirectories yet,
per directive). Build pipeline, deploy targets, and any related
artifacts come later.
2026-05-02 12:14:21 -05:00